Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 package main | 1 package main |
| 2 | 2 |
| 3 import ( | 3 import ( |
| 4 "bytes" | 4 "bytes" |
| 5 "crypto/md5" | 5 "crypto/md5" |
| 6 "database/sql" | 6 "database/sql" |
| 7 "encoding/base64" | 7 "encoding/base64" |
| 8 "encoding/json" | 8 "encoding/json" |
| 9 "flag" | 9 "flag" |
| 10 "fmt" | 10 "fmt" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 "waterfall", "river", "breeze", "moon", "rain", "wind", "sea", " morning", | 91 "waterfall", "river", "breeze", "moon", "rain", "wind", "sea", " morning", |
| 92 "snow", "lake", "sunset", "pine", "shadow", "leaf", "dawn", "gli tter", | 92 "snow", "lake", "sunset", "pine", "shadow", "leaf", "dawn", "gli tter", |
| 93 "forest", "hill", "cloud", "meadow", "sun", "glade", "bird", "br ook", | 93 "forest", "hill", "cloud", "meadow", "sun", "glade", "bird", "br ook", |
| 94 "butterfly", "bush", "dew", "dust", "field", "fire", "flower", " firefly", | 94 "butterfly", "bush", "dew", "dust", "field", "fire", "flower", " firefly", |
| 95 "feather", "grass", "haze", "mountain", "night", "pond", "darkne ss", | 95 "feather", "grass", "haze", "mountain", "night", "pond", "darkne ss", |
| 96 "snowflake", "silence", "sound", "sky", "shape", "surf", "thunde r", | 96 "snowflake", "silence", "sound", "sky", "shape", "surf", "thunde r", |
| 97 "violet", "water", "wildflower", "wave", "water", "resonance", " sun", | 97 "violet", "water", "wildflower", "wave", "water", "resonance", " sun", |
| 98 "wood", "dream", "cherry", "tree", "fog", "frost", "voice", "pap er", | 98 "wood", "dream", "cherry", "tree", "fog", "frost", "voice", "pap er", |
| 99 "frog", "smoke", "star", | 99 "frog", "smoke", "star", |
| 100 } | 100 } |
| 101 | |
| 102 gitHash = "" | |
| 103 gitInfo = "" | |
| 101 ) | 104 ) |
| 102 | 105 |
| 103 // flags | 106 // flags |
| 104 var ( | 107 var ( |
| 105 useChroot = flag.Bool("use_chroot", false, "Run the compiled code in the schroot jail.") | 108 useChroot = flag.Bool("use_chroot", false, "Run the compiled code in the schroot jail.") |
| 106 port = flag.String("port", ":8000", "HTTP service address (e.g., ': 8000')") | 109 port = flag.String("port", ":8000", "HTTP service address (e.g., ': 8000')") |
| 107 ) | 110 ) |
| 108 | 111 |
| 109 // lineNumbers adds #line numbering to the user's code. | 112 // lineNumbers adds #line numbering to the user's code. |
| 110 func LineNumbers(c string) string { | 113 func LineNumbers(c string) string { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 } | 159 } |
| 157 workspaceTemplate, err = htemplate.ParseFiles( | 160 workspaceTemplate, err = htemplate.ParseFiles( |
| 158 filepath.Join(cwd, "templates/workspace.html"), | 161 filepath.Join(cwd, "templates/workspace.html"), |
| 159 filepath.Join(cwd, "templates/titlebar.html"), | 162 filepath.Join(cwd, "templates/titlebar.html"), |
| 160 filepath.Join(cwd, "templates/content.html"), | 163 filepath.Join(cwd, "templates/content.html"), |
| 161 ) | 164 ) |
| 162 if err != nil { | 165 if err != nil { |
| 163 panic(err) | 166 panic(err) |
| 164 } | 167 } |
| 165 | 168 |
| 169 // The git command returns output of the format: | |
| 170 // | |
| 171 // f672cead70404080a991ebfb86c38316a4589b23 2014-04-27 19:21:51 +0000 | |
| 172 // M include/core/SkDynamicAnnotations.h | |
|
mtklein
2014/04/28 15:06:20
Hey, I know this change...
| |
| 173 // M include/core/SkOnce.h | |
| 174 // M include/core/SkRefCnt.h | |
| 175 // | |
| 176 logOutput, err := doCmd(`git log --format=%H%x20%ai --name-status HEAD^. .HEAD`, true) | |
| 177 if err != nil { | |
| 178 panic(err) | |
| 179 } | |
| 180 logInfo := strings.Split(logOutput, " ") | |
| 181 gitHash = logInfo[0] | |
| 182 gitInfo = logInfo[1] + " " + logInfo[2] + " " + logInfo[0][0:6] | |
|
mtklein
2014/04/28 15:06:20
Looks like we just need the results of git log --f
jcgregorio
2014/04/28 15:11:57
Done.
| |
| 183 | |
| 166 // Connect to MySQL server. First, get the password from the metadata se rver. | 184 // Connect to MySQL server. First, get the password from the metadata se rver. |
| 167 // See https://developers.google.com/compute/docs/metadata#custom. | 185 // See https://developers.google.com/compute/docs/metadata#custom. |
| 168 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i nstance/attributes/password", nil) | 186 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i nstance/attributes/password", nil) |
| 169 if err != nil { | 187 if err != nil { |
| 170 panic(err) | 188 panic(err) |
| 171 } | 189 } |
| 172 client := http.Client{} | 190 client := http.Client{} |
| 173 req.Header.Add("X-Google-Metadata-Request", "True") | 191 req.Header.Add("X-Google-Metadata-Request", "True") |
| 174 if resp, err := client.Do(req); err == nil { | 192 if resp, err := client.Do(req); err == nil { |
| 175 password, err := ioutil.ReadAll(resp.Body) | 193 password, err := ioutil.ReadAll(resp.Body) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 214 hash CHAR(64) DEFAULT '' NOT NULL, | 232 hash CHAR(64) DEFAULT '' NOT NULL, |
| 215 hidden INTEGER DEFAULT 0 NOT NULL, | 233 hidden INTEGER DEFAULT 0 NOT NULL, |
| 216 | 234 |
| 217 FOREIGN KEY (name) REFERENCES workspace(name) | 235 FOREIGN KEY (name) REFERENCES workspace(name) |
| 218 )` | 236 )` |
| 219 _, err = db.Exec(sql) | 237 _, err = db.Exec(sql) |
| 220 log.Printf("Info: status creating sqlite table for workspace try : %q\n", err) | 238 log.Printf("Info: status creating sqlite table for workspace try : %q\n", err) |
| 221 } | 239 } |
| 222 } | 240 } |
| 223 | 241 |
| 242 // Titlebar is used in titlebar template expansion. | |
| 243 type Titlebar struct { | |
| 244 GitHash string | |
| 245 GitInfo string | |
| 246 } | |
| 247 | |
| 224 // userCode is used in template expansion. | 248 // userCode is used in template expansion. |
| 225 type userCode struct { | 249 type userCode struct { |
| 226 » Code string | 250 » Code string |
| 227 » Hash string | 251 » Hash string |
| 252 » Titlebar Titlebar | |
| 228 } | 253 } |
| 229 | 254 |
| 230 // expandToFile expands the template and writes the result to the file. | 255 // expandToFile expands the template and writes the result to the file. |
| 231 func expandToFile(filename string, code string, t *template.Template) error { | 256 func expandToFile(filename string, code string, t *template.Template) error { |
| 232 f, err := os.Create(filename) | 257 f, err := os.Create(filename) |
| 233 if err != nil { | 258 if err != nil { |
| 234 return err | 259 return err |
| 235 } | 260 } |
| 236 defer f.Close() | 261 defer f.Close() |
| 237 » return t.Execute(f, userCode{Code: code}) | 262 » return t.Execute(f, userCode{Code: code, Titlebar: Titlebar{GitHash: git Hash, GitInfo: gitInfo}}) |
| 238 } | 263 } |
| 239 | 264 |
| 240 // expandCode expands the template into a file and calculate the MD5 hash. | 265 // expandCode expands the template into a file and calculate the MD5 hash. |
| 241 func expandCode(code string) (string, error) { | 266 func expandCode(code string) (string, error) { |
| 242 h := md5.New() | 267 h := md5.New() |
| 243 h.Write([]byte(code)) | 268 h.Write([]byte(code)) |
| 244 hash := fmt.Sprintf("%x", h.Sum(nil)) | 269 hash := fmt.Sprintf("%x", h.Sum(nil)) |
| 245 // At this point we are running in skia/experimental/webtry, making cach e a | 270 // At this point we are running in skia/experimental/webtry, making cach e a |
| 246 // peer directory to skia. | 271 // peer directory to skia. |
| 247 // TODO(jcgregorio) Make all relative directories into flags. | 272 // TODO(jcgregorio) Make all relative directories into flags. |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 filename := match[1] | 383 filename := match[1] |
| 359 http.ServeFile(w, r, fmt.Sprintf("../../../inout/%s", filename)) | 384 http.ServeFile(w, r, fmt.Sprintf("../../../inout/%s", filename)) |
| 360 } | 385 } |
| 361 | 386 |
| 362 type Try struct { | 387 type Try struct { |
| 363 Hash string `json:"hash"` | 388 Hash string `json:"hash"` |
| 364 CreateTS string `json:"create_ts"` | 389 CreateTS string `json:"create_ts"` |
| 365 } | 390 } |
| 366 | 391 |
| 367 type Recent struct { | 392 type Recent struct { |
| 368 » Tries []Try | 393 » Tries []Try |
| 394 » Titlebar Titlebar | |
| 369 } | 395 } |
| 370 | 396 |
| 371 // recentHandler shows the last 20 tries. | 397 // recentHandler shows the last 20 tries. |
| 372 func recentHandler(w http.ResponseWriter, r *http.Request) { | 398 func recentHandler(w http.ResponseWriter, r *http.Request) { |
| 373 log.Printf("Recent Handler: %q\n", r.URL.Path) | 399 log.Printf("Recent Handler: %q\n", r.URL.Path) |
| 374 | 400 |
| 375 var err error | 401 var err error |
| 376 rows, err := db.Query("SELECT create_ts, hash FROM webtry ORDER BY creat e_ts DESC LIMIT 20") | 402 rows, err := db.Query("SELECT create_ts, hash FROM webtry ORDER BY creat e_ts DESC LIMIT 20") |
| 377 if err != nil { | 403 if err != nil { |
| 378 http.NotFound(w, r) | 404 http.NotFound(w, r) |
| 379 return | 405 return |
| 380 } | 406 } |
| 381 recent := []Try{} | 407 recent := []Try{} |
| 382 for rows.Next() { | 408 for rows.Next() { |
| 383 var hash string | 409 var hash string |
| 384 var create_ts time.Time | 410 var create_ts time.Time |
| 385 if err := rows.Scan(&create_ts, &hash); err != nil { | 411 if err := rows.Scan(&create_ts, &hash); err != nil { |
| 386 log.Printf("Error: failed to fetch from database: %q", e rr) | 412 log.Printf("Error: failed to fetch from database: %q", e rr) |
| 387 continue | 413 continue |
| 388 } | 414 } |
| 389 recent = append(recent, Try{Hash: hash, CreateTS: create_ts.Form at("2006-02-01")}) | 415 recent = append(recent, Try{Hash: hash, CreateTS: create_ts.Form at("2006-02-01")}) |
| 390 } | 416 } |
| 391 » if err := recentTemplate.Execute(w, Recent{Tries: recent}); err != nil { | 417 » if err := recentTemplate.Execute(w, Recent{Tries: recent, Titlebar: Titl ebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil { |
| 392 log.Printf("ERROR: Failed to expand template: %q\n", err) | 418 log.Printf("ERROR: Failed to expand template: %q\n", err) |
| 393 } | 419 } |
| 394 } | 420 } |
| 395 | 421 |
| 396 type Workspace struct { | 422 type Workspace struct { |
| 397 » Name string | 423 » Name string |
| 398 » Code string | 424 » Code string |
| 399 » Hash string | 425 » Hash string |
| 400 » Tries []Try | 426 » Tries []Try |
| 427 » Titlebar Titlebar | |
| 401 } | 428 } |
| 402 | 429 |
| 403 // newWorkspace generates a new random workspace name and stores it in the datab ase. | 430 // newWorkspace generates a new random workspace name and stores it in the datab ase. |
| 404 func newWorkspace() (string, error) { | 431 func newWorkspace() (string, error) { |
| 405 for i := 0; i < 10; i++ { | 432 for i := 0; i < 10; i++ { |
| 406 adj := workspaceNameAdj[rand.Intn(len(workspaceNameAdj))] | 433 adj := workspaceNameAdj[rand.Intn(len(workspaceNameAdj))] |
| 407 noun := workspaceNameNoun[rand.Intn(len(workspaceNameNoun))] | 434 noun := workspaceNameNoun[rand.Intn(len(workspaceNameNoun))] |
| 408 suffix := rand.Intn(1000) | 435 suffix := rand.Intn(1000) |
| 409 name := fmt.Sprintf("%s-%s-%d", adj, noun, suffix) | 436 name := fmt.Sprintf("%s-%s-%d", adj, noun, suffix) |
| 410 if _, err := db.Exec("INSERT INTO workspace (name) VALUES(?)", n ame); err == nil { | 437 if _, err := db.Exec("INSERT INTO workspace (name) VALUES(?)", n ame); err == nil { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 } | 477 } |
| 451 } | 478 } |
| 452 var code string | 479 var code string |
| 453 var hash string | 480 var hash string |
| 454 if len(tries) == 0 { | 481 if len(tries) == 0 { |
| 455 code = DEFAULT_SAMPLE | 482 code = DEFAULT_SAMPLE |
| 456 } else { | 483 } else { |
| 457 hash = tries[len(tries)-1].Hash | 484 hash = tries[len(tries)-1].Hash |
| 458 code, _ = getCode(hash) | 485 code, _ = getCode(hash) |
| 459 } | 486 } |
| 460 » » if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, C ode: code, Name: name, Hash: hash}); err != nil { | 487 » » if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, C ode: code, Name: name, Hash: hash, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil { |
| 461 log.Printf("ERROR: Failed to expand template: %q\n", err ) | 488 log.Printf("ERROR: Failed to expand template: %q\n", err ) |
| 462 } | 489 } |
| 463 } else if r.Method == "POST" { | 490 } else if r.Method == "POST" { |
| 464 name, err := newWorkspace() | 491 name, err := newWorkspace() |
| 465 if err != nil { | 492 if err != nil { |
| 466 http.Error(w, "Failed to create a new workspace.", 500) | 493 http.Error(w, "Failed to create a new workspace.", 500) |
| 467 return | 494 return |
| 468 } | 495 } |
| 469 http.Redirect(w, r, "/w/"+name, 302) | 496 http.Redirect(w, r, "/w/"+name, 302) |
| 470 } | 497 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 http.NotFound(w, r) | 597 http.NotFound(w, r) |
| 571 return | 598 return |
| 572 } | 599 } |
| 573 // Update 'code' with the code found in the database. | 600 // Update 'code' with the code found in the database. |
| 574 if err := db.QueryRow("SELECT code FROM webtry WHERE has h=?", hash).Scan(&code); err != nil { | 601 if err := db.QueryRow("SELECT code FROM webtry WHERE has h=?", hash).Scan(&code); err != nil { |
| 575 http.NotFound(w, r) | 602 http.NotFound(w, r) |
| 576 return | 603 return |
| 577 } | 604 } |
| 578 } | 605 } |
| 579 // Expand the template. | 606 // Expand the template. |
| 580 » » if err := indexTemplate.Execute(w, userCode{Code: code, Hash: ha sh}); err != nil { | 607 » » if err := indexTemplate.Execute(w, userCode{Code: code, Hash: ha sh, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil { |
| 581 log.Printf("ERROR: Failed to expand template: %q\n", err ) | 608 log.Printf("ERROR: Failed to expand template: %q\n", err ) |
| 582 } | 609 } |
| 583 } else if r.Method == "POST" { | 610 } else if r.Method == "POST" { |
| 584 w.Header().Set("Content-Type", "application/json") | 611 w.Header().Set("Content-Type", "application/json") |
| 585 buf := bytes.NewBuffer(make([]byte, 0, MAX_TRY_SIZE)) | 612 buf := bytes.NewBuffer(make([]byte, 0, MAX_TRY_SIZE)) |
| 586 n, err := buf.ReadFrom(r.Body) | 613 n, err := buf.ReadFrom(r.Body) |
| 587 if err != nil { | 614 if err != nil { |
| 588 reportTryError(w, r, err, "Failed to read a request body .", "") | 615 reportTryError(w, r, err, "Failed to read a request body .", "") |
| 589 return | 616 return |
| 590 } | 617 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 http.HandleFunc("/w/", workspaceHandler) | 693 http.HandleFunc("/w/", workspaceHandler) |
| 667 http.HandleFunc("/recent/", recentHandler) | 694 http.HandleFunc("/recent/", recentHandler) |
| 668 http.HandleFunc("/iframe/", iframeHandler) | 695 http.HandleFunc("/iframe/", iframeHandler) |
| 669 http.HandleFunc("/json/", tryInfoHandler) | 696 http.HandleFunc("/json/", tryInfoHandler) |
| 670 http.HandleFunc("/css/", cssHandler) | 697 http.HandleFunc("/css/", cssHandler) |
| 671 http.HandleFunc("/js/", jsHandler) | 698 http.HandleFunc("/js/", jsHandler) |
| 672 // TODO Break out /c/ as it's own handler. | 699 // TODO Break out /c/ as it's own handler. |
| 673 http.HandleFunc("/", mainHandler) | 700 http.HandleFunc("/", mainHandler) |
| 674 log.Fatal(http.ListenAndServe(*port, nil)) | 701 log.Fatal(http.ListenAndServe(*port, nil)) |
| 675 } | 702 } |
| OLD | NEW |