Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: experimental/webtry/webtry.go

Issue 656463002: add support for skfiddle width/height options (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add new db creation commands to the design documnt Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « experimental/webtry/templates/workspace.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/binary" 8 "encoding/binary"
9 "encoding/json" 9 "encoding/json"
10 "flag" 10 "flag"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 if err != nil { 150 if err != nil {
151 panic(err) 151 panic(err)
152 } 152 }
153 gypTemplate, err = template.ParseFiles(filepath.Join(cwd, "templates/tem plate.gyp")) 153 gypTemplate, err = template.ParseFiles(filepath.Join(cwd, "templates/tem plate.gyp"))
154 if err != nil { 154 if err != nil {
155 panic(err) 155 panic(err)
156 } 156 }
157 indexTemplate, err = htemplate.ParseFiles( 157 indexTemplate, err = htemplate.ParseFiles(
158 filepath.Join(cwd, "templates/index.html"), 158 filepath.Join(cwd, "templates/index.html"),
159 filepath.Join(cwd, "templates/titlebar.html"), 159 filepath.Join(cwd, "templates/titlebar.html"),
160 filepath.Join(cwd, "templates/sidebar.html"),
160 filepath.Join(cwd, "templates/content.html"), 161 filepath.Join(cwd, "templates/content.html"),
161 filepath.Join(cwd, "templates/headercommon.html"), 162 filepath.Join(cwd, "templates/headercommon.html"),
162 filepath.Join(cwd, "templates/footercommon.html"), 163 filepath.Join(cwd, "templates/footercommon.html"),
163 ) 164 )
164 if err != nil { 165 if err != nil {
165 panic(err) 166 panic(err)
166 } 167 }
167 iframeTemplate, err = htemplate.ParseFiles( 168 iframeTemplate, err = htemplate.ParseFiles(
168 filepath.Join(cwd, "templates/iframe.html"), 169 filepath.Join(cwd, "templates/iframe.html"),
169 filepath.Join(cwd, "templates/content.html"), 170 filepath.Join(cwd, "templates/content.html"),
170 filepath.Join(cwd, "templates/headercommon.html"), 171 filepath.Join(cwd, "templates/headercommon.html"),
171 filepath.Join(cwd, "templates/footercommon.html"), 172 filepath.Join(cwd, "templates/footercommon.html"),
172 ) 173 )
173 if err != nil { 174 if err != nil {
174 panic(err) 175 panic(err)
175 } 176 }
176 recentTemplate, err = htemplate.ParseFiles( 177 recentTemplate, err = htemplate.ParseFiles(
177 filepath.Join(cwd, "templates/recent.html"), 178 filepath.Join(cwd, "templates/recent.html"),
178 filepath.Join(cwd, "templates/titlebar.html"), 179 filepath.Join(cwd, "templates/titlebar.html"),
180 filepath.Join(cwd, "templates/sidebar.html"),
179 filepath.Join(cwd, "templates/headercommon.html"), 181 filepath.Join(cwd, "templates/headercommon.html"),
180 filepath.Join(cwd, "templates/footercommon.html"), 182 filepath.Join(cwd, "templates/footercommon.html"),
181 ) 183 )
182 if err != nil { 184 if err != nil {
183 panic(err) 185 panic(err)
184 } 186 }
185 workspaceTemplate, err = htemplate.ParseFiles( 187 workspaceTemplate, err = htemplate.ParseFiles(
186 filepath.Join(cwd, "templates/workspace.html"), 188 filepath.Join(cwd, "templates/workspace.html"),
187 filepath.Join(cwd, "templates/titlebar.html"), 189 filepath.Join(cwd, "templates/titlebar.html"),
190 filepath.Join(cwd, "templates/sidebar.html"),
188 filepath.Join(cwd, "templates/content.html"), 191 filepath.Join(cwd, "templates/content.html"),
189 filepath.Join(cwd, "templates/headercommon.html"), 192 filepath.Join(cwd, "templates/headercommon.html"),
190 filepath.Join(cwd, "templates/footercommon.html"), 193 filepath.Join(cwd, "templates/footercommon.html"),
191 ) 194 )
192 if err != nil { 195 if err != nil {
193 panic(err) 196 panic(err)
194 } 197 }
195 198
196 // The git command returns output of the format: 199 // The git command returns output of the format:
197 // 200 //
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 )` 248 )`
246 _, err = db.Exec(sql) 249 _, err = db.Exec(sql)
247 if err != nil { 250 if err != nil {
248 log.Printf("Info: status creating sqlite table for sourc es: %q\n", err) 251 log.Printf("Info: status creating sqlite table for sourc es: %q\n", err)
249 } 252 }
250 253
251 sql = `CREATE TABLE IF NOT EXISTS webtry ( 254 sql = `CREATE TABLE IF NOT EXISTS webtry (
252 code TEXT DEFAULT '' NOT NULL, 255 code TEXT DEFAULT '' NOT NULL,
253 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 256 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
254 hash CHAR(64) DEFAULT '' NOT NULL, 257 hash CHAR(64) DEFAULT '' NOT NULL,
258 width INTEGER DEFAULT 256 NOT NULL,
259 height INTEGER DEFAULT 256 NOT NULL,
255 source_image_id INTEGER DEFAULT 0 NOT NULL, 260 source_image_id INTEGER DEFAULT 0 NOT NULL,
256 261
257 PRIMARY KEY(hash) 262 PRIMARY KEY(hash)
258 )` 263 )`
259 _, err = db.Exec(sql) 264 _, err = db.Exec(sql)
260 if err != nil { 265 if err != nil {
261 log.Printf("Info: status creating sqlite table for webtr y: %q\n", err) 266 log.Printf("Info: status creating sqlite table for webtr y: %q\n", err)
262 } 267 }
263 268
264 sql = `CREATE TABLE IF NOT EXISTS workspace ( 269 sql = `CREATE TABLE IF NOT EXISTS workspace (
265 name CHAR(64) DEFAULT '' NOT NULL, 270 name CHAR(64) DEFAULT '' NOT NULL,
266 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 271 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
267 PRIMARY KEY(name) 272 PRIMARY KEY(name)
268 )` 273 )`
269 _, err = db.Exec(sql) 274 _, err = db.Exec(sql)
270 if err != nil { 275 if err != nil {
271 log.Printf("Info: status creating sqlite table for works pace: %q\n", err) 276 log.Printf("Info: status creating sqlite table for works pace: %q\n", err)
272 } 277 }
273 278
274 sql = `CREATE TABLE IF NOT EXISTS workspacetry ( 279 sql = `CREATE TABLE IF NOT EXISTS workspacetry (
275 name CHAR(64) DEFAULT '' NOT NULL, 280 name CHAR(64) DEFAULT '' NOT NULL,
276 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 281 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
277 hash CHAR(64) DEFAULT '' NOT NULL, 282 hash CHAR(64) DEFAULT '' NOT NULL,
283 width INTEGER DEFAULT 256 NOT NULL,
284 height INTEGER DEFAULT 256 NOT NULL,
278 hidden INTEGER DEFAULT 0 NOT NULL, 285 hidden INTEGER DEFAULT 0 NOT NULL,
279 source_image_id INTEGER DEFAULT 0 NOT NULL, 286 source_image_id INTEGER DEFAULT 0 NOT NULL,
280 287
281 FOREIGN KEY (name) REFERENCES workspace(name) 288 FOREIGN KEY (name) REFERENCES workspace(name)
282 )` 289 )`
283 _, err = db.Exec(sql) 290 _, err = db.Exec(sql)
284 if err != nil { 291 if err != nil {
285 log.Printf("Info: status creating sqlite table for works pace try: %q\n", err) 292 log.Printf("Info: status creating sqlite table for works pace try: %q\n", err)
286 } 293 }
287 } 294 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 // Titlebar is used in titlebar template expansion. 345 // Titlebar is used in titlebar template expansion.
339 type Titlebar struct { 346 type Titlebar struct {
340 GitHash string 347 GitHash string
341 GitInfo string 348 GitInfo string
342 } 349 }
343 350
344 // userCode is used in template expansion. 351 // userCode is used in template expansion.
345 type userCode struct { 352 type userCode struct {
346 Code string 353 Code string
347 Hash string 354 Hash string
355 Width int
356 Height int
348 Source int 357 Source int
349 Titlebar Titlebar 358 Titlebar Titlebar
350 } 359 }
351 360
352 // writeTemplate creates a given output file and writes the template 361 // writeTemplate creates a given output file and writes the template
353 // result there. 362 // result there.
354 func writeTemplate(filename string, t *template.Template, context interface{}) e rror { 363 func writeTemplate(filename string, t *template.Template, context interface{}) e rror {
355 f, err := os.Create(filename) 364 f, err := os.Create(filename)
356 if err != nil { 365 if err != nil {
357 return err 366 return err
358 } 367 }
359 defer f.Close() 368 defer f.Close()
360 return t.Execute(f, context) 369 return t.Execute(f, context)
361 } 370 }
362 371
363 // expandToFile expands the template and writes the result to the file. 372 // expandToFile expands the template and writes the result to the file.
364 func expandToFile(filename string, code string, t *template.Template) error { 373 func expandToFile(filename string, code string, t *template.Template) error {
365 » return writeTemplate(filename, t, userCode{Code: code, Titlebar: Titleba r{GitHash: gitHash, GitInfo: gitInfo}}) 374 » return writeTemplate(filename, t, userCode{
375 » » Code: code,
376 » » Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo},
377 » })
366 } 378 }
367 379
368 // expandCode expands the template into a file and calculates the MD5 hash. 380 // expandCode expands the template into a file and calculates the MD5 hash.
369 func expandCode(code string, source int) (string, error) { 381 // We include the width and height here so that a single hash can capture
382 // both the code and the supplied width/height parameters.
383 func expandCode(code string, source int, width, height int) (string, error) {
370 // in order to support fonts in the chroot jail, we need to make sure 384 // in order to support fonts in the chroot jail, we need to make sure
371 // we're using portable typefaces. 385 // we're using portable typefaces.
372 // TODO(humper): Make this more robust, supporting things like setTypef ace 386 // TODO(humper): Make this more robust, supporting things like setTypef ace
373 387
374 inputCodeLines := strings.Split(code, "\n") 388 inputCodeLines := strings.Split(code, "\n")
375 » outputCodeLines := []string{"DECLARE_bool(portableFonts);"} 389 » outputCodeLines := []string{"DECLARE_bool(portableFonts);", fmt.Sprintf( "// WxH: %d, %d", width, height)}
376 for _, line := range inputCodeLines { 390 for _, line := range inputCodeLines {
377 outputCodeLines = append(outputCodeLines, line) 391 outputCodeLines = append(outputCodeLines, line)
378 if strings.HasPrefix(strings.TrimSpace(line), "SkPaint p") { 392 if strings.HasPrefix(strings.TrimSpace(line), "SkPaint p") {
379 outputCodeLines = append(outputCodeLines, "FLAGS_portabl eFonts = true;") 393 outputCodeLines = append(outputCodeLines, "FLAGS_portabl eFonts = true;")
380 outputCodeLines = append(outputCodeLines, "sk_tool_utils ::set_portable_typeface(&p, \"Helvetica\", SkTypeface::kNormal);") 394 outputCodeLines = append(outputCodeLines, "sk_tool_utils ::set_portable_typeface(&p, \"Helvetica\", SkTypeface::kNormal);")
381 } 395 }
382 } 396 }
383 397
384 fontFriendlyCode := strings.Join(outputCodeLines, "\n") 398 fontFriendlyCode := strings.Join(outputCodeLines, "\n")
385 399
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 log.Printf("Error: %s\n%s", message, err.Error()) 458 log.Printf("Error: %s\n%s", message, err.Error())
445 resp, err := json.Marshal(m) 459 resp, err := json.Marshal(m)
446 if err != nil { 460 if err != nil {
447 http.Error(w, "Failed to serialize a response", 500) 461 http.Error(w, "Failed to serialize a response", 500)
448 return 462 return
449 } 463 }
450 w.Header().Set("Content-Type", "text/plain") 464 w.Header().Set("Content-Type", "text/plain")
451 w.Write(resp) 465 w.Write(resp)
452 } 466 }
453 467
454 func writeToDatabase(hash string, code string, workspaceName string, source int) { 468 func writeToDatabase(hash string, code string, workspaceName string, source int, width, height int) {
455 if db == nil { 469 if db == nil {
456 return 470 return
457 } 471 }
458 » if _, err := db.Exec("INSERT INTO webtry (code, hash, source_image_id) V ALUES(?, ?, ?)", code, hash, source); err != nil { 472 » if _, err := db.Exec("INSERT INTO webtry (code, hash, width, height, sou rce_image_id) VALUES(?, ?, ?, ?, ?)", code, hash, width, height, source); err != nil {
459 log.Printf("ERROR: Failed to insert code into database: %q\n", e rr) 473 log.Printf("ERROR: Failed to insert code into database: %q\n", e rr)
460 } 474 }
461 if workspaceName != "" { 475 if workspaceName != "" {
462 » » if _, err := db.Exec("INSERT INTO workspacetry (name, hash, sour ce_image_id) VALUES(?, ?, ?)", workspaceName, hash, source); err != nil { 476 » » if _, err := db.Exec("INSERT INTO workspacetry (name, hash, widt h, height, source_image_id) VALUES(?, ?, ?, ?, ?)", workspaceName, hash, width, height, source); err != nil {
463 log.Printf("ERROR: Failed to insert into workspacetry ta ble: %q\n", err) 477 log.Printf("ERROR: Failed to insert into workspacetry ta ble: %q\n", err)
464 } 478 }
465 } 479 }
466 } 480 }
467 481
468 type Sources struct { 482 type Sources struct {
469 Id int `json:"id"` 483 Id int `json:"id"`
470 } 484 }
471 485
472 // sourcesHandler serves up the PNG of a specific try. 486 // sourcesHandler serves up the PNG of a specific try.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 w.Header().Set("Content-Type", "text/html") 606 w.Header().Set("Content-Type", "text/html")
593 if err := recentTemplate.Execute(w, Recent{Tries: recent, Titlebar: Titl ebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil { 607 if err := recentTemplate.Execute(w, Recent{Tries: recent, Titlebar: Titl ebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
594 log.Printf("ERROR: Failed to expand template: %q\n", err) 608 log.Printf("ERROR: Failed to expand template: %q\n", err)
595 } 609 }
596 } 610 }
597 611
598 type Workspace struct { 612 type Workspace struct {
599 Name string 613 Name string
600 Code string 614 Code string
601 Hash string 615 Hash string
616 Width int
617 Height int
602 Source int 618 Source int
603 Tries []Try 619 Tries []Try
604 Titlebar Titlebar 620 Titlebar Titlebar
605 } 621 }
606 622
607 // newWorkspace generates a new random workspace name and stores it in the datab ase. 623 // newWorkspace generates a new random workspace name and stores it in the datab ase.
608 func newWorkspace() (string, error) { 624 func newWorkspace() (string, error) {
609 for i := 0; i < 10; i++ { 625 for i := 0; i < 10; i++ {
610 adj := workspaceNameAdj[rand.Intn(len(workspaceNameAdj))] 626 adj := workspaceNameAdj[rand.Intn(len(workspaceNameAdj))]
611 noun := workspaceNameNoun[rand.Intn(len(workspaceNameNoun))] 627 noun := workspaceNameNoun[rand.Intn(len(workspaceNameNoun))]
612 suffix := rand.Intn(1000) 628 suffix := rand.Intn(1000)
613 name := fmt.Sprintf("%s-%s-%d", adj, noun, suffix) 629 name := fmt.Sprintf("%s-%s-%d", adj, noun, suffix)
614 if _, err := db.Exec("INSERT INTO workspace (name) VALUES(?)", n ame); err == nil { 630 if _, err := db.Exec("INSERT INTO workspace (name) VALUES(?)", n ame); err == nil {
615 return name, nil 631 return name, nil
616 } else { 632 } else {
617 log.Printf("ERROR: Failed to insert workspace into datab ase: %q\n", err) 633 log.Printf("ERROR: Failed to insert workspace into datab ase: %q\n", err)
618 } 634 }
619 } 635 }
620 return "", fmt.Errorf("Failed to create a new workspace") 636 return "", fmt.Errorf("Failed to create a new workspace")
621 } 637 }
622 638
623 // getCode returns the code for a given hash, or the empty string if not found. 639 // getCode returns the code for a given hash, or the empty string if not found.
624 func getCode(hash string) (string, int, error) { 640 func getCode(hash string) (string, int, int, int, error) {
625 code := "" 641 code := ""
642 width := 0
643 height := 0
626 source := 0 644 source := 0
627 » if err := db.QueryRow("SELECT code, source_image_id FROM webtry WHERE ha sh=?", hash).Scan(&code, &source); err != nil { 645 » if err := db.QueryRow("SELECT code, width, height, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &source); err != nil {
628 log.Printf("ERROR: Code for hash is missing: %q\n", err) 646 log.Printf("ERROR: Code for hash is missing: %q\n", err)
629 » » return code, source, err 647 » » return code, width, height, source, err
630 } 648 }
631 » return code, source, nil 649 » return code, width, height, source, nil
632 } 650 }
633 651
634 func workspaceHandler(w http.ResponseWriter, r *http.Request) { 652 func workspaceHandler(w http.ResponseWriter, r *http.Request) {
635 log.Printf("Workspace Handler: %q\n", r.URL.Path) 653 log.Printf("Workspace Handler: %q\n", r.URL.Path)
636 if r.Method == "GET" { 654 if r.Method == "GET" {
637 tries := []Try{} 655 tries := []Try{}
638 match := workspaceLink.FindStringSubmatch(r.URL.Path) 656 match := workspaceLink.FindStringSubmatch(r.URL.Path)
639 name := "" 657 name := ""
640 if len(match) == 2 { 658 if len(match) == 2 {
641 name = match[1] 659 name = match[1]
642 rows, err := db.Query("SELECT create_ts, hash, source_im age_id FROM workspacetry WHERE name=? ORDER BY create_ts", name) 660 rows, err := db.Query("SELECT create_ts, hash, source_im age_id FROM workspacetry WHERE name=? ORDER BY create_ts", name)
643 if err != nil { 661 if err != nil {
644 reportError(w, r, err, "Failed to select.") 662 reportError(w, r, err, "Failed to select.")
645 return 663 return
646 } 664 }
647 for rows.Next() { 665 for rows.Next() {
648 var hash string 666 var hash string
649 var create_ts time.Time 667 var create_ts time.Time
650 var source int 668 var source int
651 if err := rows.Scan(&create_ts, &hash, &source); err != nil { 669 if err := rows.Scan(&create_ts, &hash, &source); err != nil {
652 log.Printf("Error: failed to fetch from database: %q", err) 670 log.Printf("Error: failed to fetch from database: %q", err)
653 continue 671 continue
654 } 672 }
655 tries = append(tries, Try{Hash: hash, Source: so urce, CreateTS: create_ts.Format("2006-02-01")}) 673 tries = append(tries, Try{Hash: hash, Source: so urce, CreateTS: create_ts.Format("2006-02-01")})
656 } 674 }
657 } 675 }
658 var code string 676 var code string
659 var hash string 677 var hash string
678 var width int
679 var height int
660 source := 0 680 source := 0
661 if len(tries) == 0 { 681 if len(tries) == 0 {
662 code = DEFAULT_SAMPLE 682 code = DEFAULT_SAMPLE
683 width = 256
684 height = 256
663 } else { 685 } else {
664 hash = tries[len(tries)-1].Hash 686 hash = tries[len(tries)-1].Hash
665 » » » code, source, _ = getCode(hash) 687 » » » code, width, height, source, _ = getCode(hash)
666 } 688 }
667 w.Header().Set("Content-Type", "text/html") 689 w.Header().Set("Content-Type", "text/html")
668 » » if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, C ode: code, Name: name, Hash: hash, Source: source, Titlebar: Titlebar{GitHash: g itHash, GitInfo: gitInfo}}); err != nil { 690 » » if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, C ode: code, Name: name, Hash: hash, Width: width, Height: height, Source: source, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
669 log.Printf("ERROR: Failed to expand template: %q\n", err ) 691 log.Printf("ERROR: Failed to expand template: %q\n", err )
670 } 692 }
671 } else if r.Method == "POST" { 693 } else if r.Method == "POST" {
672 name, err := newWorkspace() 694 name, err := newWorkspace()
673 if err != nil { 695 if err != nil {
674 http.Error(w, "Failed to create a new workspace.", 500) 696 http.Error(w, "Failed to create a new workspace.", 500)
675 return 697 return
676 } 698 }
677 http.Redirect(w, r, "/w/"+name, 302) 699 http.Redirect(w, r, "/w/"+name, 302)
678 } 700 }
679 } 701 }
680 702
681 // hasPreProcessor returns true if any line in the code begins with a # char. 703 // hasPreProcessor returns true if any line in the code begins with a # char.
682 func hasPreProcessor(code string) bool { 704 func hasPreProcessor(code string) bool {
683 lines := strings.Split(code, "\n") 705 lines := strings.Split(code, "\n")
684 for _, s := range lines { 706 for _, s := range lines {
685 if strings.HasPrefix(strings.TrimSpace(s), "#") { 707 if strings.HasPrefix(strings.TrimSpace(s), "#") {
686 return true 708 return true
687 } 709 }
688 } 710 }
689 return false 711 return false
690 } 712 }
691 713
692 type TryRequest struct { 714 type TryRequest struct {
693 Code string `json:"code"` 715 Code string `json:"code"`
716 Width int `json:"width"`
717 Height int `json:"height"`
694 Name string `json:"name"` // Optional name of the workspace the code is in. 718 Name string `json:"name"` // Optional name of the workspace the code is in.
695 Source int `json:"source"` // ID of the source image, 0 if none. 719 Source int `json:"source"` // ID of the source image, 0 if none.
696 } 720 }
697 721
698 // iframeHandler handles the GET and POST of the main page. 722 // iframeHandler handles the GET and POST of the main page.
699 func iframeHandler(w http.ResponseWriter, r *http.Request) { 723 func iframeHandler(w http.ResponseWriter, r *http.Request) {
700 log.Printf("IFrame Handler: %q\n", r.URL.Path) 724 log.Printf("IFrame Handler: %q\n", r.URL.Path)
701 if r.Method != "GET" { 725 if r.Method != "GET" {
702 http.NotFound(w, r) 726 http.NotFound(w, r)
703 return 727 return
704 } 728 }
705 match := iframeLink.FindStringSubmatch(r.URL.Path) 729 match := iframeLink.FindStringSubmatch(r.URL.Path)
706 if len(match) != 2 { 730 if len(match) != 2 {
707 http.NotFound(w, r) 731 http.NotFound(w, r)
708 return 732 return
709 } 733 }
710 hash := match[1] 734 hash := match[1]
711 if db == nil { 735 if db == nil {
712 http.NotFound(w, r) 736 http.NotFound(w, r)
713 return 737 return
714 } 738 }
715 var code string 739 var code string
716 » code, source, err := getCode(hash) 740 » code, width, height, source, err := getCode(hash)
717 if err != nil { 741 if err != nil {
718 http.NotFound(w, r) 742 http.NotFound(w, r)
719 return 743 return
720 } 744 }
721 // Expand the template. 745 // Expand the template.
722 w.Header().Set("Content-Type", "text/html") 746 w.Header().Set("Content-Type", "text/html")
723 » if err := iframeTemplate.Execute(w, userCode{Code: code, Hash: hash, Sou rce: source}); err != nil { 747 » if err := iframeTemplate.Execute(w, userCode{Code: code, Width: width, H eight: height, Hash: hash, Source: source}); err != nil {
724 log.Printf("ERROR: Failed to expand template: %q\n", err) 748 log.Printf("ERROR: Failed to expand template: %q\n", err)
725 } 749 }
726 } 750 }
727 751
728 type TryInfo struct { 752 type TryInfo struct {
729 Hash string `json:"hash"` 753 Hash string `json:"hash"`
730 Code string `json:"code"` 754 Code string `json:"code"`
755 Width int `json:"width"`
756 Height int `json:"height"`
731 Source int `json:"source"` 757 Source int `json:"source"`
732 } 758 }
733 759
734 // tryInfoHandler returns information about a specific try. 760 // tryInfoHandler returns information about a specific try.
735 func tryInfoHandler(w http.ResponseWriter, r *http.Request) { 761 func tryInfoHandler(w http.ResponseWriter, r *http.Request) {
736 log.Printf("Try Info Handler: %q\n", r.URL.Path) 762 log.Printf("Try Info Handler: %q\n", r.URL.Path)
737 if r.Method != "GET" { 763 if r.Method != "GET" {
738 http.NotFound(w, r) 764 http.NotFound(w, r)
739 return 765 return
740 } 766 }
741 match := tryInfoLink.FindStringSubmatch(r.URL.Path) 767 match := tryInfoLink.FindStringSubmatch(r.URL.Path)
742 if len(match) != 2 { 768 if len(match) != 2 {
743 http.NotFound(w, r) 769 http.NotFound(w, r)
744 return 770 return
745 } 771 }
746 hash := match[1] 772 hash := match[1]
747 » code, source, err := getCode(hash) 773 » code, width, height, source, err := getCode(hash)
748 if err != nil { 774 if err != nil {
749 http.NotFound(w, r) 775 http.NotFound(w, r)
750 return 776 return
751 } 777 }
752 m := TryInfo{ 778 m := TryInfo{
753 Hash: hash, 779 Hash: hash,
754 Code: code, 780 Code: code,
781 Width: width,
782 Height: height,
755 Source: source, 783 Source: source,
756 } 784 }
757 resp, err := json.Marshal(m) 785 resp, err := json.Marshal(m)
758 if err != nil { 786 if err != nil {
759 reportError(w, r, err, "Failed to serialize a response.") 787 reportError(w, r, err, "Failed to serialize a response.")
760 return 788 return
761 } 789 }
762 w.Header().Set("Content-Type", "application/json") 790 w.Header().Set("Content-Type", "application/json")
763 w.Write(resp) 791 w.Write(resp)
764 } 792 }
765 793
766 func cleanCompileOutput(s, hash string) string { 794 func cleanCompileOutput(s, hash string) string {
767 old := "../../../cache/src/" + hash + ".cpp:" 795 old := "../../../cache/src/" + hash + ".cpp:"
768 log.Printf("INFO: replacing %q\n", old) 796 log.Printf("INFO: replacing %q\n", old)
769 return strings.Replace(s, old, "usercode.cpp:", -1) 797 return strings.Replace(s, old, "usercode.cpp:", -1)
770 } 798 }
771 799
772 // mainHandler handles the GET and POST of the main page. 800 // mainHandler handles the GET and POST of the main page.
773 func mainHandler(w http.ResponseWriter, r *http.Request) { 801 func mainHandler(w http.ResponseWriter, r *http.Request) {
774 log.Printf("Main Handler: %q\n", r.URL.Path) 802 log.Printf("Main Handler: %q\n", r.URL.Path)
775 requestsCounter.Inc(1) 803 requestsCounter.Inc(1)
776 if r.Method == "GET" { 804 if r.Method == "GET" {
777 code := DEFAULT_SAMPLE 805 code := DEFAULT_SAMPLE
778 source := 0 806 source := 0
807 width := 256
808 height := 256
779 match := directLink.FindStringSubmatch(r.URL.Path) 809 match := directLink.FindStringSubmatch(r.URL.Path)
780 var hash string 810 var hash string
781 if len(match) == 2 && r.URL.Path != "/" { 811 if len(match) == 2 && r.URL.Path != "/" {
782 hash = match[1] 812 hash = match[1]
783 if db == nil { 813 if db == nil {
784 http.NotFound(w, r) 814 http.NotFound(w, r)
785 return 815 return
786 } 816 }
787 // Update 'code' with the code found in the database. 817 // Update 'code' with the code found in the database.
788 » » » if err := db.QueryRow("SELECT code, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &source); err != nil { 818 » » » if err := db.QueryRow("SELECT code, width, height, sourc e_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &source ); err != nil {
789 http.NotFound(w, r) 819 http.NotFound(w, r)
790 return 820 return
791 } 821 }
792 } 822 }
793 // Expand the template. 823 // Expand the template.
794 w.Header().Set("Content-Type", "text/html") 824 w.Header().Set("Content-Type", "text/html")
795 » » if err := indexTemplate.Execute(w, userCode{Code: code, Hash: ha sh, Source: source, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); er r != nil { 825 » » if err := indexTemplate.Execute(w, userCode{Code: code, Hash: ha sh, Source: source, Width: width, Height: height, Titlebar: Titlebar{GitHash: gi tHash, GitInfo: gitInfo}}); err != nil {
796 log.Printf("ERROR: Failed to expand template: %q\n", err ) 826 log.Printf("ERROR: Failed to expand template: %q\n", err )
797 } 827 }
798 } else if r.Method == "POST" { 828 } else if r.Method == "POST" {
799 w.Header().Set("Content-Type", "application/json") 829 w.Header().Set("Content-Type", "application/json")
800 buf := bytes.NewBuffer(make([]byte, 0, MAX_TRY_SIZE)) 830 buf := bytes.NewBuffer(make([]byte, 0, MAX_TRY_SIZE))
801 n, err := buf.ReadFrom(r.Body) 831 n, err := buf.ReadFrom(r.Body)
802 if err != nil { 832 if err != nil {
803 reportTryError(w, r, err, "Failed to read a request body .", "") 833 reportTryError(w, r, err, "Failed to read a request body .", "")
804 return 834 return
805 } 835 }
806 if n == MAX_TRY_SIZE { 836 if n == MAX_TRY_SIZE {
807 err := fmt.Errorf("Code length equal to, or exceeded, %d ", MAX_TRY_SIZE) 837 err := fmt.Errorf("Code length equal to, or exceeded, %d ", MAX_TRY_SIZE)
808 reportTryError(w, r, err, "Code too large.", "") 838 reportTryError(w, r, err, "Code too large.", "")
809 return 839 return
810 } 840 }
811 request := TryRequest{} 841 request := TryRequest{}
812 if err := json.Unmarshal(buf.Bytes(), &request); err != nil { 842 if err := json.Unmarshal(buf.Bytes(), &request); err != nil {
813 reportTryError(w, r, err, "Coulnd't decode JSON.", "") 843 reportTryError(w, r, err, "Coulnd't decode JSON.", "")
814 return 844 return
815 } 845 }
816 if hasPreProcessor(request.Code) { 846 if hasPreProcessor(request.Code) {
817 err := fmt.Errorf("Found preprocessor macro in code.") 847 err := fmt.Errorf("Found preprocessor macro in code.")
818 reportTryError(w, r, err, "Preprocessor macros aren't al lowed.", "") 848 reportTryError(w, r, err, "Preprocessor macros aren't al lowed.", "")
819 return 849 return
820 } 850 }
821 » » hash, err := expandCode(LineNumbers(request.Code), request.Sourc e) 851 » » hash, err := expandCode(LineNumbers(request.Code), request.Sourc e, request.Width, request.Height)
822 if err != nil { 852 if err != nil {
823 reportTryError(w, r, err, "Failed to write the code to c ompile.", hash) 853 reportTryError(w, r, err, "Failed to write the code to c ompile.", hash)
824 return 854 return
825 } 855 }
826 » » writeToDatabase(hash, request.Code, request.Name, request.Source ) 856 » » writeToDatabase(hash, request.Code, request.Name, request.Source , request.Width, request.Height)
827 err = expandGyp(hash) 857 err = expandGyp(hash)
828 if err != nil { 858 if err != nil {
829 reportTryError(w, r, err, "Failed to write the gyp file. ", hash) 859 reportTryError(w, r, err, "Failed to write the gyp file. ", hash)
830 return 860 return
831 } 861 }
832 » » cmd := "scripts/fiddle_wrapper " + hash 862 » » cmd := fmt.Sprintf("scripts/fiddle_wrapper %s --width %d --heigh t %d", hash, request.Width, request.Height)
833 if *useChroot { 863 if *useChroot {
834 cmd = "schroot -c webtry --directory=/ -- /skia_build/sk ia/experimental/webtry/" + cmd 864 cmd = "schroot -c webtry --directory=/ -- /skia_build/sk ia/experimental/webtry/" + cmd
835 } 865 }
836 if request.Source > 0 { 866 if request.Source > 0 {
837 » » » cmd += fmt.Sprintf(" image-%d.png", request.Source) 867 » » » cmd += fmt.Sprintf(" --source image-%d.png", request.Sou rce)
838 } 868 }
839 869
840 message, err := doCmd(cmd) 870 message, err := doCmd(cmd)
841 if err != nil { 871 if err != nil {
842 reportTryError(w, r, err, "Failed to run the code:\n"+me ssage, hash) 872 reportTryError(w, r, err, "Failed to run the code:\n"+me ssage, hash)
843 return 873 return
844 } 874 }
845 png, err := ioutil.ReadFile("../../../inout/" + hash + ".png") 875 png, err := ioutil.ReadFile("../../../inout/" + hash + ".png")
846 if err != nil { 876 if err != nil {
847 reportTryError(w, r, err, "Failed to open the generated PNG.", hash) 877 reportTryError(w, r, err, "Failed to open the generated PNG.", hash)
(...skipping 25 matching lines...) Expand all
873 http.HandleFunc("/sources/", autogzip.HandleFunc(sourcesHandler)) 903 http.HandleFunc("/sources/", autogzip.HandleFunc(sourcesHandler))
874 904
875 // Resources are served directly 905 // Resources are served directly
876 // TODO add support for caching/etags/gzip 906 // TODO add support for caching/etags/gzip
877 http.Handle("/res/", autogzip.Handle(http.FileServer(http.Dir("./")))) 907 http.Handle("/res/", autogzip.Handle(http.FileServer(http.Dir("./"))))
878 908
879 // TODO Break out /c/ as it's own handler. 909 // TODO Break out /c/ as it's own handler.
880 http.HandleFunc("/", autogzip.HandleFunc(mainHandler)) 910 http.HandleFunc("/", autogzip.HandleFunc(mainHandler))
881 log.Fatal(http.ListenAndServe(*port, nil)) 911 log.Fatal(http.ListenAndServe(*port, nil))
882 } 912 }
OLDNEW
« no previous file with comments | « experimental/webtry/templates/workspace.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698