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

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

Issue 236193011: Add /recent (Closed) Base URL: https://skia.googlesource.com/skia.git@all
Patch Set: stray print Created 6 years, 8 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
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/json" 8 "encoding/json"
9 "flag" 9 "flag"
10 "fmt" 10 "fmt"
11 _ "github.com/go-sql-driver/mysql" 11 _ "github.com/go-sql-driver/mysql"
12 _ "github.com/mattn/go-sqlite3" 12 _ "github.com/mattn/go-sqlite3"
13 htemplate "html/template" 13 htemplate "html/template"
14 "io/ioutil" 14 "io/ioutil"
15 "log" 15 "log"
16 "net/http" 16 "net/http"
17 "os" 17 "os"
18 "os/exec" 18 "os/exec"
19 "path/filepath" 19 "path/filepath"
20 "regexp" 20 "regexp"
21 "strings" 21 "strings"
22 "text/template" 22 "text/template"
23 "time"
23 ) 24 )
24 25
25 const ( 26 const (
26 RESULT_COMPILE = `c++ -DSK_GAMMA_SRGB -DSK_GAMMA_APPLY_TO_A8 -DSK_SCALAR _TO_FLOAT_EXCLUDED -DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=0 -D SK_SUPPORT_OPENCL=0 -DSK_FORCE_DISTANCEFIELD_FONTS=0 -DSK_SCALAR_IS_FLOAT -DSK_C AN_USE_FLOAT -DSK_SAMPLES_FOR_X -DSK_BUILD_FOR_UNIX -DSK_USE_POSIX_THREADS -DSK_ SYSTEM_ZLIB=1 -DSK_DEBUG -DSK_DEVELOPER=1 -I../../src/core -I../../src/images -I ../../tools/flags -I../../include/config -I../../include/core -I../../include/pa thops -I../../include/pipe -I../../include/effects -I../../include/ports -I../.. /src/sfnt -I../../include/utils -I../../src/utils -I../../include/images -g -fno -exceptions -fstrict-aliasing -Wall -Wextra -Winit-self -Wpointer-arith -Wno-unu sed-parameter -Wno-c++11-extensions -Werror -m64 -fno-rtti -Wnon-virtual-dtor -c ../../../cache/%s.cpp -o ../../../cache/%s.o` 27 RESULT_COMPILE = `c++ -DSK_GAMMA_SRGB -DSK_GAMMA_APPLY_TO_A8 -DSK_SCALAR _TO_FLOAT_EXCLUDED -DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=0 -D SK_SUPPORT_OPENCL=0 -DSK_FORCE_DISTANCEFIELD_FONTS=0 -DSK_SCALAR_IS_FLOAT -DSK_C AN_USE_FLOAT -DSK_SAMPLES_FOR_X -DSK_BUILD_FOR_UNIX -DSK_USE_POSIX_THREADS -DSK_ SYSTEM_ZLIB=1 -DSK_DEBUG -DSK_DEVELOPER=1 -I../../src/core -I../../src/images -I ../../tools/flags -I../../include/config -I../../include/core -I../../include/pa thops -I../../include/pipe -I../../include/effects -I../../include/ports -I../.. /src/sfnt -I../../include/utils -I../../src/utils -I../../include/images -g -fno -exceptions -fstrict-aliasing -Wall -Wextra -Winit-self -Wpointer-arith -Wno-unu sed-parameter -Wno-c++11-extensions -Werror -m64 -fno-rtti -Wnon-virtual-dtor -c ../../../cache/%s.cpp -o ../../../cache/%s.o`
27 LINK = `c++ -m64 -lstdc++ -lm -o ../../../inout/%s -Wl,--start -group ../../../cache/%s.o obj/experimental/webtry/webtry.main.o obj/gyp/libflag s.a libskia_images.a libskia_core.a libskia_effects.a obj/gyp/libjpeg.a obj/gyp/ libwebp_dec.a obj/gyp/libwebp_demux.a obj/gyp/libwebp_dsp.a obj/gyp/libwebp_enc. a obj/gyp/libwebp_utils.a libskia_utils.a libskia_opts.a libskia_opts_ssse3.a li bskia_ports.a libskia_sfnt.a -Wl,--end-group -lpng -lz -lgif -lpthread -lfontcon fig -ldl -lfreetype` 28 LINK = `c++ -m64 -lstdc++ -lm -o ../../../inout/%s -Wl,--start -group ../../../cache/%s.o obj/experimental/webtry/webtry.main.o obj/gyp/libflag s.a libskia_images.a libskia_core.a libskia_effects.a obj/gyp/libjpeg.a obj/gyp/ libwebp_dec.a obj/gyp/libwebp_demux.a obj/gyp/libwebp_dsp.a obj/gyp/libwebp_enc. a obj/gyp/libwebp_utils.a libskia_utils.a libskia_opts.a libskia_opts_ssse3.a li bskia_ports.a libskia_sfnt.a -Wl,--end-group -lpng -lz -lgif -lpthread -lfontcon fig -ldl -lfreetype`
28 DEFAULT_SAMPLE = `SkPaint p; 29 DEFAULT_SAMPLE = `SkPaint p;
29 p.setColor(SK_ColorRED); 30 p.setColor(SK_ColorRED);
30 p.setAntiAlias(true); 31 p.setAntiAlias(true);
31 p.setStyle(SkPaint::kStroke_Style); 32 p.setStyle(SkPaint::kStroke_Style);
32 p.setStrokeWidth(10); 33 p.setStrokeWidth(10);
33 34
34 canvas->drawLine(20, 20, 100, 100, p); 35 canvas->drawLine(20, 20, 100, 100, p);
35 ` 36 `
36 ) 37 )
37 38
38 var ( 39 var (
39 // codeTemplate is the cpp code template the user's code is copied into. 40 // codeTemplate is the cpp code template the user's code is copied into.
40 codeTemplate *template.Template = nil 41 codeTemplate *template.Template = nil
41 42
42 » // index is the main index.html page we serve. 43 » // indexTemplate is the main index.html page we serve.
43 » index *htemplate.Template = nil 44 » indexTemplate *htemplate.Template = nil
45
46 » // recentTemplate is a list of recent images.
47 » recentTemplate *htemplate.Template = nil
44 48
45 // db is the database, nil if we don't have an SQL database to store dat a into. 49 // db is the database, nil if we don't have an SQL database to store dat a into.
46 db *sql.DB = nil 50 db *sql.DB = nil
47 51
48 // directLink is the regex that matches URLs paths that are direct links . 52 // directLink is the regex that matches URLs paths that are direct links .
49 » directLink = regexp.MustCompile("^c/([a-a0-9]+)$") 53 » directLink = regexp.MustCompile("^/c/([a-f0-9]+)$")
54
55 » // imageLink is the regex that matches URLs paths that are direct links to PNGs.
56 » imageLink = regexp.MustCompile("^/i/([a-f0-9]+.png)$")
50 ) 57 )
51 58
52 // flags 59 // flags
53 var ( 60 var (
54 useChroot = flag.Bool("use_chroot", false, "Run the compiled code in the schroot jail.") 61 useChroot = flag.Bool("use_chroot", false, "Run the compiled code in the schroot jail.")
55 port = flag.String("port", ":8000", "HTTP service address (e.g., ': 8000')") 62 port = flag.String("port", ":8000", "HTTP service address (e.g., ': 8000')")
56 ) 63 )
57 64
58 // lineNumbers adds #line numbering to the user's code. 65 // lineNumbers adds #line numbering to the user's code.
59 func LineNumbers(c string) string { 66 func LineNumbers(c string) string {
(...skipping 14 matching lines...) Expand all
74 if err != nil { 81 if err != nil {
75 log.Fatal(err) 82 log.Fatal(err)
76 } 83 }
77 os.Chdir(cwd) 84 os.Chdir(cwd)
78 85
79 codeTemplate, err = template.ParseFiles(filepath.Join(cwd, "templates/te mplate.cpp")) 86 codeTemplate, err = template.ParseFiles(filepath.Join(cwd, "templates/te mplate.cpp"))
80 if err != nil { 87 if err != nil {
81 panic(err) 88 panic(err)
82 } 89 }
83 // Convert index.html into a template, which is expanded with the code. 90 // Convert index.html into a template, which is expanded with the code.
84 » index, err = htemplate.ParseFiles(filepath.Join(cwd, "templates/index.ht ml")) 91 » indexTemplate, err = htemplate.ParseFiles(filepath.Join(cwd, "templates/ index.html"))
85 if err != nil { 92 if err != nil {
86 panic(err) 93 panic(err)
87 } 94 }
95
96 recentTemplate, err = htemplate.ParseFiles(filepath.Join(cwd, "templates /recent.html"))
97 if err != nil {
98 panic(err)
99 }
88 100
89 // Connect to MySQL server. First, get the password from the metadata se rver. 101 // Connect to MySQL server. First, get the password from the metadata se rver.
90 // See https://developers.google.com/compute/docs/metadata#custom. 102 // See https://developers.google.com/compute/docs/metadata#custom.
91 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i nstance/attributes/password", nil) 103 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i nstance/attributes/password", nil)
92 if err != nil { 104 if err != nil {
93 panic(err) 105 panic(err)
94 } 106 }
95 client := http.Client{} 107 client := http.Client{}
96 req.Header.Add("X-Google-Metadata-Request", "True") 108 req.Header.Add("X-Google-Metadata-Request", "True")
97 if resp, err := client.Do(req); err == nil { 109 if resp, err := client.Do(req); err == nil {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 231
220 func writeToDatabase(hash string, code string) { 232 func writeToDatabase(hash string, code string) {
221 if db == nil { 233 if db == nil {
222 return 234 return
223 } 235 }
224 if _, err := db.Exec("INSERT INTO webtry (code, hash) VALUES(?, ?)", cod e, hash); err != nil { 236 if _, err := db.Exec("INSERT INTO webtry (code, hash) VALUES(?, ?)", cod e, hash); err != nil {
225 log.Printf("ERROR: Failed to insert code into database: %q\n", e rr) 237 log.Printf("ERROR: Failed to insert code into database: %q\n", e rr)
226 } 238 }
227 } 239 }
228 240
241 func cssHandler(w http.ResponseWriter, r *http.Request) {
242 http.ServeFile(w, r, "css/webtry.css")
243 }
244
245 // imageHandler serves up the PNG of a specific try.
246 func imageHandler(w http.ResponseWriter, r *http.Request) {
247 log.Printf("Image Handler: %q\n", r.URL.Path)
248 if r.Method != "GET" {
249 http.NotFound(w, r)
250 return
251 }
252 match := imageLink.FindStringSubmatch(r.URL.Path)
253 if len(match) != 2 {
254 http.NotFound(w, r)
255 return
256 }
257 filename := match[1]
258 http.ServeFile(w, r, fmt.Sprintf("../../../inout/%s", filename))
mtklein 2014/04/14 18:27:53 Doesn't this make you sort of wish the images were
jcgregorio 2014/04/14 18:43:46 Yeah yeah, I'm coming around to that idea :-)
259 }
260
261 type Try struct {
262 Hash string
263 CreateTS string
264 }
265
266 type Recent struct {
267 Tries []Try
268 }
269
270 // recentHandler shows the last 20 tries.
271 func recentHandler(w http.ResponseWriter, r *http.Request) {
272 log.Printf("Recent Handler: %q\n", r.URL.Path)
273
274 var err error
275 rows, err := db.Query("SELECT create_ts, hash FROM webtry ORDER BY creat e_ts DESC LIMIT 20")
276 if err != nil {
277 http.NotFound(w, r)
278 return
279 }
280 recent := []Try{}
281 for rows.Next() {
282 var hash string
283 var create_ts time.Time
284 if err := rows.Scan(&create_ts, &hash); err != nil {
285 log.Printf("Error: failed to fetch from database: %q", e rr)
286 continue
287 }
288 recent = append(recent, Try{Hash: hash, CreateTS: create_ts.Form at("2006-02-01")})
mtklein 2014/04/14 18:27:53 I've never seen this .Format method before. Cute!
jcgregorio 2014/04/14 18:43:46 Yeah, makes for very readable code. On 2014/04/14
289 }
290 if err := recentTemplate.Execute(w, Recent{Tries: recent}); err != nil {
291 log.Printf("ERROR: Failed to expand template: %q\n", err)
292 }
293 }
294
229 // mainHandler handles the GET and POST of the main page. 295 // mainHandler handles the GET and POST of the main page.
230 func mainHandler(w http.ResponseWriter, r *http.Request) { 296 func mainHandler(w http.ResponseWriter, r *http.Request) {
297 log.Printf("Main Handler: %q\n", r.URL.Path)
mtklein 2014/04/14 18:27:53 Leftover?
jcgregorio 2014/04/14 18:43:46 Actually useful to have in the logs. On 2014/04/1
231 if r.Method == "GET" { 298 if r.Method == "GET" {
232 code := DEFAULT_SAMPLE 299 code := DEFAULT_SAMPLE
233 directLink := regexp.MustCompile("^/c/([a-f0-9]+)$")
234 match := directLink.FindStringSubmatch(r.URL.Path) 300 match := directLink.FindStringSubmatch(r.URL.Path)
235 » » if len(match) == 2 { 301 » » if len(match) == 2 && r.URL.Path != "/" {
236 hash := match[1] 302 hash := match[1]
237 if db == nil { 303 if db == nil {
238 http.NotFound(w, r) 304 http.NotFound(w, r)
239 return 305 return
240 } 306 }
241 // Update 'code' with the code found in the database. 307 // Update 'code' with the code found in the database.
242 if err := db.QueryRow("SELECT code FROM webtry WHERE has h=?", hash).Scan(&code); err != nil { 308 if err := db.QueryRow("SELECT code FROM webtry WHERE has h=?", hash).Scan(&code); err != nil {
243 http.NotFound(w, r) 309 http.NotFound(w, r)
244 return 310 return
245 } 311 }
246 } 312 }
247 // Expand the template. 313 // Expand the template.
248 » » if err := index.Execute(w, userCode{UserCode: code}); err != nil { 314 » » if err := indexTemplate.Execute(w, userCode{UserCode: code}); er r != nil {
249 log.Printf("ERROR: Failed to expand template: %q\n", err ) 315 log.Printf("ERROR: Failed to expand template: %q\n", err )
250 } 316 }
251 } else if r.Method == "POST" { 317 } else if r.Method == "POST" {
252 w.Header().Set("Content-Type", "application/json") 318 w.Header().Set("Content-Type", "application/json")
253 b, err := ioutil.ReadAll(r.Body) 319 b, err := ioutil.ReadAll(r.Body)
254 if err != nil { 320 if err != nil {
255 reportError(w, r, err, "Failed to read a request body.") 321 reportError(w, r, err, "Failed to read a request body.")
256 return 322 return
257 } 323 }
258 code := string(b) 324 code := string(b)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 if err != nil { 371 if err != nil {
306 reportError(w, r, err, "Failed to serialize a response." ) 372 reportError(w, r, err, "Failed to serialize a response." )
307 return 373 return
308 } 374 }
309 w.Write(resp) 375 w.Write(resp)
310 } 376 }
311 } 377 }
312 378
313 func main() { 379 func main() {
314 flag.Parse() 380 flag.Parse()
315 381 » http.HandleFunc("/i/", imageHandler)
382 » http.HandleFunc("/recent/", recentHandler)
383 » http.HandleFunc("/css/", cssHandler)
316 http.HandleFunc("/", mainHandler) 384 http.HandleFunc("/", mainHandler)
317 log.Fatal(http.ListenAndServe(*port, nil)) 385 log.Fatal(http.ListenAndServe(*port, nil))
318 } 386 }
OLDNEW
« experimental/webtry/templates/recent.html ('K') | « experimental/webtry/templates/recent.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698