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

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

Issue 655323002: webtry: Switch from Go's log package to golang/glog. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add log_dir flag to daemon args list 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/setup/sys/webtry_init ('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"
11 "fmt" 11 "fmt"
12 htemplate "html/template" 12 htemplate "html/template"
13 "image" 13 "image"
14 _ "image/gif" 14 _ "image/gif"
15 _ "image/jpeg" 15 _ "image/jpeg"
16 "image/png" 16 "image/png"
17 "io/ioutil" 17 "io/ioutil"
18 "log"
19 "math/rand" 18 "math/rand"
20 "net" 19 "net"
21 "net/http" 20 "net/http"
22 "os" 21 "os"
23 "os/exec" 22 "os/exec"
24 "path/filepath" 23 "path/filepath"
25 "regexp" 24 "regexp"
26 "strings" 25 "strings"
27 "text/template" 26 "text/template"
28 "time" 27 "time"
29 ) 28 )
30 29
31 import ( 30 import (
32 "github.com/fiorix/go-web/autogzip" 31 "github.com/fiorix/go-web/autogzip"
33 _ "github.com/go-sql-driver/mysql" 32 _ "github.com/go-sql-driver/mysql"
33 "github.com/golang/glog"
34 _ "github.com/mattn/go-sqlite3" 34 _ "github.com/mattn/go-sqlite3"
35 "github.com/rcrowley/go-metrics" 35 "github.com/rcrowley/go-metrics"
36 ) 36 )
37 37
38 const ( 38 const (
39 DEFAULT_SAMPLE = `void draw(SkCanvas* canvas) { 39 DEFAULT_SAMPLE = `void draw(SkCanvas* canvas) {
40 SkPaint p; 40 SkPaint p;
41 p.setColor(SK_ColorRED); 41 p.setColor(SK_ColorRED);
42 p.setAntiAlias(true); 42 p.setAntiAlias(true);
43 p.setStyle(SkPaint::kStroke_Style); 43 p.setStyle(SkPaint::kStroke_Style);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 return strings.Join(ret, "\n") 135 return strings.Join(ret, "\n")
136 } 136 }
137 137
138 func init() { 138 func init() {
139 rand.Seed(time.Now().UnixNano()) 139 rand.Seed(time.Now().UnixNano())
140 140
141 // Change the current working directory to the directory of the executab le. 141 // Change the current working directory to the directory of the executab le.
142 var err error 142 var err error
143 cwd, err := filepath.Abs(filepath.Dir(os.Args[0])) 143 cwd, err := filepath.Abs(filepath.Dir(os.Args[0]))
144 if err != nil { 144 if err != nil {
145 » » log.Fatal(err) 145 » » glog.Fatal(err)
146 } 146 }
147 os.Chdir(cwd) 147 os.Chdir(cwd)
148 148
149 codeTemplate = template.Must(template.ParseFiles(filepath.Join(cwd, "tem plates/template.cpp"))) 149 codeTemplate = template.Must(template.ParseFiles(filepath.Join(cwd, "tem plates/template.cpp")))
150 gypTemplate = template.Must(template.ParseFiles(filepath.Join(cwd, "temp lates/template.gyp"))) 150 gypTemplate = template.Must(template.ParseFiles(filepath.Join(cwd, "temp lates/template.gyp")))
151 indexTemplate = htemplate.Must(htemplate.ParseFiles( 151 indexTemplate = htemplate.Must(htemplate.ParseFiles(
152 filepath.Join(cwd, "templates/index.html"), 152 filepath.Join(cwd, "templates/index.html"),
153 filepath.Join(cwd, "templates/titlebar.html"), 153 filepath.Join(cwd, "templates/titlebar.html"),
154 filepath.Join(cwd, "templates/sidebar.html"), 154 filepath.Join(cwd, "templates/sidebar.html"),
155 filepath.Join(cwd, "templates/content.html"), 155 filepath.Join(cwd, "templates/content.html"),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 // See https://developers.google.com/compute/docs/metadata#custom. 194 // See https://developers.google.com/compute/docs/metadata#custom.
195 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i nstance/attributes/password", nil) 195 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i nstance/attributes/password", nil)
196 if err != nil { 196 if err != nil {
197 panic(err) 197 panic(err)
198 } 198 }
199 client := http.Client{} 199 client := http.Client{}
200 req.Header.Add("X-Google-Metadata-Request", "True") 200 req.Header.Add("X-Google-Metadata-Request", "True")
201 if resp, err := client.Do(req); err == nil { 201 if resp, err := client.Do(req); err == nil {
202 password, err := ioutil.ReadAll(resp.Body) 202 password, err := ioutil.ReadAll(resp.Body)
203 if err != nil { 203 if err != nil {
204 » » » log.Printf("ERROR: Failed to read password from metadata server: %q\n", err) 204 » » » glog.Errorf("Failed to read password from metadata serve r: %q\n", err)
205 panic(err) 205 panic(err)
206 } 206 }
207 // The IP address of the database is found here: 207 // The IP address of the database is found here:
208 // https://console.developers.google.com/project/31977622648/ sql/instances/webtry/overview 208 // https://console.developers.google.com/project/31977622648/ sql/instances/webtry/overview
209 // And 3306 is the default port for MySQL. 209 // And 3306 is the default port for MySQL.
210 db, err = sql.Open("mysql", fmt.Sprintf("webtry:%s@tcp(173.194.8 3.52:3306)/webtry?parseTime=true", password)) 210 db, err = sql.Open("mysql", fmt.Sprintf("webtry:%s@tcp(173.194.8 3.52:3306)/webtry?parseTime=true", password))
211 if err != nil { 211 if err != nil {
212 » » » log.Printf("ERROR: Failed to open connection to SQL serv er: %q\n", err) 212 » » » glog.Errorf("ERROR: Failed to open connection to SQL ser ver: %q\n", err)
213 panic(err) 213 panic(err)
214 } 214 }
215 } else { 215 } else {
216 » » log.Printf("INFO: Failed to find metadata, unable to connect to MySQL server (Expected when running locally): %q\n", err) 216 » » glog.Infof("Failed to find metadata, unable to connect to MySQL server (Expected when running locally): %q\n", err)
217 // Fallback to sqlite for local use. 217 // Fallback to sqlite for local use.
218 db, err = sql.Open("sqlite3", "./webtry.db") 218 db, err = sql.Open("sqlite3", "./webtry.db")
219 if err != nil { 219 if err != nil {
220 » » » log.Printf("ERROR: Failed to open: %q\n", err) 220 » » » glog.Errorf("Failed to open: %q\n", err)
221 panic(err) 221 panic(err)
222 } 222 }
223 sql := `CREATE TABLE IF NOT EXISTS source_images ( 223 sql := `CREATE TABLE IF NOT EXISTS source_images (
224 id INTEGER PRIMARY KEY NOT NULL, 224 id INTEGER PRIMARY KEY NOT NULL,
225 image MEDIUMBLOB DEFAULT '' NOT NULL, -- forma tted as a PNG. 225 image MEDIUMBLOB DEFAULT '' NOT NULL, -- forma tted as a PNG.
226 width INTEGER DEFAULT 0 NOT NULL, 226 width INTEGER DEFAULT 0 NOT NULL,
227 height INTEGER DEFAULT 0 NOT NULL, 227 height INTEGER DEFAULT 0 NOT NULL,
228 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 228 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
229 hidden INTEGER DEFAULT 0 NOT NULL 229 hidden INTEGER DEFAULT 0 NOT NULL
230 )` 230 )`
231 _, err = db.Exec(sql) 231 _, err = db.Exec(sql)
232 if err != nil { 232 if err != nil {
233 » » » log.Printf("Info: status creating sqlite table for sourc es: %q\n", err) 233 » » » glog.Infof("status creating sqlite table for sources: %q \n", err)
234 } 234 }
235 235
236 sql = `CREATE TABLE IF NOT EXISTS webtry ( 236 sql = `CREATE TABLE IF NOT EXISTS webtry (
237 code TEXT DEFAULT '' NOT NULL, 237 code TEXT DEFAULT '' NOT NULL,
238 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 238 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
239 hash CHAR(64) DEFAULT '' NOT NULL, 239 hash CHAR(64) DEFAULT '' NOT NULL,
240 width INTEGER DEFAULT 256 NOT NULL, 240 width INTEGER DEFAULT 256 NOT NULL,
241 height INTEGER DEFAULT 256 NOT NULL, 241 height INTEGER DEFAULT 256 NOT NULL,
242 gpu BOOL DEFAULT 0 NOT NULL, 242 gpu BOOL DEFAULT 0 NOT NULL,
243 source_image_id INTEGER DEFAULT 0 NOT NULL, 243 source_image_id INTEGER DEFAULT 0 NOT NULL,
244 244
245 PRIMARY KEY(hash) 245 PRIMARY KEY(hash)
246 )` 246 )`
247 _, err = db.Exec(sql) 247 _, err = db.Exec(sql)
248 if err != nil { 248 if err != nil {
249 » » » log.Printf("Info: status creating sqlite table for webtr y: %q\n", err) 249 » » » glog.Infof("status creating sqlite table for webtry: %q\ n", err)
250 } 250 }
251 251
252 sql = `CREATE TABLE IF NOT EXISTS workspace ( 252 sql = `CREATE TABLE IF NOT EXISTS workspace (
253 name CHAR(64) DEFAULT '' NOT NULL, 253 name CHAR(64) DEFAULT '' NOT NULL,
254 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 254 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
255 PRIMARY KEY(name) 255 PRIMARY KEY(name)
256 )` 256 )`
257 _, err = db.Exec(sql) 257 _, err = db.Exec(sql)
258 if err != nil { 258 if err != nil {
259 » » » log.Printf("Info: status creating sqlite table for works pace: %q\n", err) 259 » » » glog.Infof("status creating sqlite table for workspace: %q\n", err)
260 } 260 }
261 261
262 sql = `CREATE TABLE IF NOT EXISTS workspacetry ( 262 sql = `CREATE TABLE IF NOT EXISTS workspacetry (
263 name CHAR(64) DEFAULT '' NOT NULL, 263 name CHAR(64) DEFAULT '' NOT NULL,
264 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 264 create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
265 hash CHAR(64) DEFAULT '' NOT NULL, 265 hash CHAR(64) DEFAULT '' NOT NULL,
266 width INTEGER DEFAULT 256 NOT NULL, 266 width INTEGER DEFAULT 256 NOT NULL,
267 height INTEGER DEFAULT 256 NOT NULL, 267 height INTEGER DEFAULT 256 NOT NULL,
268 gpu BOOL DEFAULT 0 NOT NULL, 268 gpu BOOL DEFAULT 0 NOT NULL,
269 hidden INTEGER DEFAULT 0 NOT NULL, 269 hidden INTEGER DEFAULT 0 NOT NULL,
270 source_image_id INTEGER DEFAULT 0 NOT NULL, 270 source_image_id INTEGER DEFAULT 0 NOT NULL,
271 271
272 FOREIGN KEY (name) REFERENCES workspace(name) 272 FOREIGN KEY (name) REFERENCES workspace(name)
273 )` 273 )`
274 _, err = db.Exec(sql) 274 _, err = db.Exec(sql)
275 if err != nil { 275 if err != nil {
276 » » » log.Printf("Info: status creating sqlite table for works pace try: %q\n", err) 276 » » » glog.Infof("status creating sqlite table for workspace t ry: %q\n", err)
277 } 277 }
278 } 278 }
279 279
280 // Ping the database to keep the connection fresh. 280 // Ping the database to keep the connection fresh.
281 go func() { 281 go func() {
282 c := time.Tick(1 * time.Minute) 282 c := time.Tick(1 * time.Minute)
283 for _ = range c { 283 for _ = range c {
284 if err := db.Ping(); err != nil { 284 if err := db.Ping(); err != nil {
285 » » » » log.Printf("ERROR: Database failed to respond: % q\n", err) 285 » » » » glog.Errorf("Database failed to respond: %q\n", err)
286 } 286 }
287 } 287 }
288 }() 288 }()
289 289
290 metrics.RegisterRuntimeMemStats(metrics.DefaultRegistry) 290 metrics.RegisterRuntimeMemStats(metrics.DefaultRegistry)
291 go metrics.CaptureRuntimeMemStats(metrics.DefaultRegistry, 1*time.Minute ) 291 go metrics.CaptureRuntimeMemStats(metrics.DefaultRegistry, 1*time.Minute )
292 292
293 // Start reporting metrics. 293 // Start reporting metrics.
294 // TODO(jcgregorio) We need a centrialized config server for storing thi ngs 294 // TODO(jcgregorio) We need a centrialized config server for storing thi ngs
295 // like the IP address of the Graphite monitor. 295 // like the IP address of the Graphite monitor.
296 addr, _ := net.ResolveTCPAddr("tcp", "skia-monitoring-b:2003") 296 addr, _ := net.ResolveTCPAddr("tcp", "skia-monitoring-b:2003")
297 go metrics.Graphite(metrics.DefaultRegistry, 1*time.Minute, "webtry", ad dr) 297 go metrics.Graphite(metrics.DefaultRegistry, 1*time.Minute, "webtry", ad dr)
298 298
299 writeOutAllSourceImages() 299 writeOutAllSourceImages()
300 } 300 }
301 301
302 func writeOutAllSourceImages() { 302 func writeOutAllSourceImages() {
303 // Pull all the source images from the db and write them out to inout. 303 // Pull all the source images from the db and write them out to inout.
304 rows, err := db.Query("SELECT id, image, create_ts FROM source_images OR DER BY create_ts DESC") 304 rows, err := db.Query("SELECT id, image, create_ts FROM source_images OR DER BY create_ts DESC")
305 305
306 if err != nil { 306 if err != nil {
307 » » log.Printf("ERROR: Failed to open connection to SQL server: %q\n ", err) 307 » » glog.Errorf("Failed to open connection to SQL server: %q\n", err )
308 panic(err) 308 panic(err)
309 } 309 }
310 for rows.Next() { 310 for rows.Next() {
311 var id int 311 var id int
312 var image []byte 312 var image []byte
313 var create_ts time.Time 313 var create_ts time.Time
314 if err := rows.Scan(&id, &image, &create_ts); err != nil { 314 if err := rows.Scan(&id, &image, &create_ts); err != nil {
315 » » » log.Printf("Error: failed to fetch from database: %q", e rr) 315 » » » glog.Errorf("failed to fetch from database: %q", err)
316 continue 316 continue
317 } 317 }
318 filename := fmt.Sprintf("../../../inout/image-%d.png", id) 318 filename := fmt.Sprintf("../../../inout/image-%d.png", id)
319 if _, err := os.Stat(filename); os.IsExist(err) { 319 if _, err := os.Stat(filename); os.IsExist(err) {
320 » » » log.Printf("Skipping write since file exists: %q", filen ame) 320 » » » glog.Infof("Skipping write since file exists: %q", filen ame)
321 continue 321 continue
322 } 322 }
323 if err := ioutil.WriteFile(filename, image, 0666); err != nil { 323 if err := ioutil.WriteFile(filename, image, 0666); err != nil {
324 » » » log.Printf("Error: failed to write image file: %q", err) 324 » » » glog.Errorf("failed to write image file: %q", err)
325 } 325 }
326 } 326 }
327 } 327 }
328 328
329 // Titlebar is used in titlebar template expansion. 329 // Titlebar is used in titlebar template expansion.
330 type Titlebar struct { 330 type Titlebar struct {
331 GitHash string 331 GitHash string
332 GitInfo string 332 GitInfo string
333 } 333 }
334 334
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 Message string `json:"message"` 407 Message string `json:"message"`
408 StdOut string `json:"stdout"` 408 StdOut string `json:"stdout"`
409 Img string `json:"img"` 409 Img string `json:"img"`
410 Hash string `json:"hash"` 410 Hash string `json:"hash"`
411 } 411 }
412 412
413 // doCmd executes the given command line string; the command being 413 // doCmd executes the given command line string; the command being
414 // run is expected to not care what its current working directory is. 414 // run is expected to not care what its current working directory is.
415 // Returns the stdout and stderr. 415 // Returns the stdout and stderr.
416 func doCmd(commandLine string) (string, error) { 416 func doCmd(commandLine string) (string, error) {
417 » log.Printf("Command: %q\n", commandLine) 417 » glog.Infof("Command: %q\n", commandLine)
418 programAndArgs := strings.SplitN(commandLine, " ", 2) 418 programAndArgs := strings.SplitN(commandLine, " ", 2)
419 program := programAndArgs[0] 419 program := programAndArgs[0]
420 args := []string{} 420 args := []string{}
421 if len(programAndArgs) > 1 { 421 if len(programAndArgs) > 1 {
422 args = strings.Split(programAndArgs[1], " ") 422 args = strings.Split(programAndArgs[1], " ")
423 } 423 }
424 cmd := exec.Command(program, args...) 424 cmd := exec.Command(program, args...)
425 message, err := cmd.CombinedOutput() 425 message, err := cmd.CombinedOutput()
426 » log.Printf("StdOut + StdErr: %s\n", string(message)) 426 » glog.Infof("StdOut + StdErr: %s\n", string(message))
427 if err != nil { 427 if err != nil {
428 » » log.Printf("Exit status: %s\n", err.Error()) 428 » » glog.Errorf("Exit status: %s\n", err)
429 return string(message), fmt.Errorf("Failed to run command.") 429 return string(message), fmt.Errorf("Failed to run command.")
430 } 430 }
431 return string(message), nil 431 return string(message), nil
432 } 432 }
433 433
434 // reportError formats an HTTP error response and also logs the detailed error m essage. 434 // reportError formats an HTTP error response and also logs the detailed error m essage.
435 func reportError(w http.ResponseWriter, r *http.Request, err error, message stri ng) { 435 func reportError(w http.ResponseWriter, r *http.Request, err error, message stri ng) {
436 » log.Printf("Error: %s\n%s", message, err.Error()) 436 » glog.Errorf("%s\n%s", message, err)
437 w.Header().Set("Content-Type", "text/plain") 437 w.Header().Set("Content-Type", "text/plain")
438 http.Error(w, message, 500) 438 http.Error(w, message, 500)
439 } 439 }
440 440
441 // reportTryError formats an HTTP error response in JSON and also logs the detai led error message. 441 // reportTryError formats an HTTP error response in JSON and also logs the detai led error message.
442 func reportTryError(w http.ResponseWriter, r *http.Request, err error, message, hash string) { 442 func reportTryError(w http.ResponseWriter, r *http.Request, err error, message, hash string) {
443 m := response{ 443 m := response{
444 Message: message, 444 Message: message,
445 Hash: hash, 445 Hash: hash,
446 } 446 }
447 » log.Printf("Error: %s\n%s", message, err.Error()) 447 » glog.Errorf("%s\n%s", message, err)
448 resp, err := json.Marshal(m) 448 resp, err := json.Marshal(m)
449 if err != nil { 449 if err != nil {
450 http.Error(w, "Failed to serialize a response", 500) 450 http.Error(w, "Failed to serialize a response", 500)
451 return 451 return
452 } 452 }
453 w.Header().Set("Content-Type", "text/plain") 453 w.Header().Set("Content-Type", "text/plain")
454 w.Write(resp) 454 w.Write(resp)
455 } 455 }
456 456
457 func writeToDatabase(hash string, code string, workspaceName string, source int, width, height int, gpu bool) { 457 func writeToDatabase(hash string, code string, workspaceName string, source int, width, height int, gpu bool) {
458 if db == nil { 458 if db == nil {
459 return 459 return
460 } 460 }
461 if _, err := db.Exec("INSERT INTO webtry (code, hash, width, height, gpu , source_image_id) VALUES(?, ?, ?, ?, ?, ?)", code, hash, width, height, gpu, so urce); err != nil { 461 if _, err := db.Exec("INSERT INTO webtry (code, hash, width, height, gpu , source_image_id) VALUES(?, ?, ?, ?, ?, ?)", code, hash, width, height, gpu, so urce); err != nil {
462 » » log.Printf("ERROR: Failed to insert code into database: %q\n", e rr) 462 » » glog.Errorf("Failed to insert code into database: %q\n", err)
463 } 463 }
464 if workspaceName != "" { 464 if workspaceName != "" {
465 if _, err := db.Exec("INSERT INTO workspacetry (name, hash, widt h, height, gpu, source_image_id) VALUES(?, ?, ?, ?, ?, ?)", workspaceName, hash, width, height, gpu, source); err != nil { 465 if _, err := db.Exec("INSERT INTO workspacetry (name, hash, widt h, height, gpu, source_image_id) VALUES(?, ?, ?, ?, ?, ?)", workspaceName, hash, width, height, gpu, source); err != nil {
466 » » » log.Printf("ERROR: Failed to insert into workspacetry ta ble: %q\n", err) 466 » » » glog.Errorf("Failed to insert into workspacetry table: % q\n", err)
467 } 467 }
468 } 468 }
469 } 469 }
470 470
471 type Sources struct { 471 type Sources struct {
472 Id int `json:"id"` 472 Id int `json:"id"`
473 } 473 }
474 474
475 // sourcesHandler serves up the PNG of a specific try. 475 // sourcesHandler serves up the PNG of a specific try.
476 func sourcesHandler(w http.ResponseWriter, r *http.Request) { 476 func sourcesHandler(w http.ResponseWriter, r *http.Request) {
477 » log.Printf("Sources Handler: %q\n", r.URL.Path) 477 » glog.Infof("Sources Handler: %q\n", r.URL.Path)
478 if r.Method == "GET" { 478 if r.Method == "GET" {
479 rows, err := db.Query("SELECT id, create_ts FROM source_images W HERE hidden=0 ORDER BY create_ts DESC") 479 rows, err := db.Query("SELECT id, create_ts FROM source_images W HERE hidden=0 ORDER BY create_ts DESC")
480 480
481 if err != nil { 481 if err != nil {
482 http.Error(w, fmt.Sprintf("Failed to query sources: %s." , err), 500) 482 http.Error(w, fmt.Sprintf("Failed to query sources: %s." , err), 500)
483 } 483 }
484 sources := make([]Sources, 0, 0) 484 sources := make([]Sources, 0, 0)
485 for rows.Next() { 485 for rows.Next() {
486 var id int 486 var id int
487 var create_ts time.Time 487 var create_ts time.Time
488 if err := rows.Scan(&id, &create_ts); err != nil { 488 if err := rows.Scan(&id, &create_ts); err != nil {
489 » » » » log.Printf("Error: failed to fetch from database : %q", err) 489 » » » » glog.Errorf("failed to fetch from database: %q", err)
490 continue 490 continue
491 } 491 }
492 sources = append(sources, Sources{Id: id}) 492 sources = append(sources, Sources{Id: id})
493 } 493 }
494 494
495 resp, err := json.Marshal(sources) 495 resp, err := json.Marshal(sources)
496 if err != nil { 496 if err != nil {
497 reportError(w, r, err, "Failed to serialize a response." ) 497 reportError(w, r, err, "Failed to serialize a response." )
498 return 498 return
499 } 499 }
(...skipping 23 matching lines...) Expand all
523 if err != nil { 523 if err != nil {
524 http.Error(w, fmt.Sprintf("Failed to decode image: %s.", err), 500) 524 http.Error(w, fmt.Sprintf("Failed to decode image: %s.", err), 500)
525 return 525 return
526 } 526 }
527 var b bytes.Buffer 527 var b bytes.Buffer
528 png.Encode(&b, m) 528 png.Encode(&b, m)
529 bounds := m.Bounds() 529 bounds := m.Bounds()
530 width := bounds.Max.Y - bounds.Min.Y 530 width := bounds.Max.Y - bounds.Min.Y
531 height := bounds.Max.X - bounds.Min.X 531 height := bounds.Max.X - bounds.Min.X
532 if _, err := db.Exec("INSERT INTO source_images (image, width, h eight) VALUES(?, ?, ?)", b.Bytes(), width, height); err != nil { 532 if _, err := db.Exec("INSERT INTO source_images (image, width, h eight) VALUES(?, ?, ?)", b.Bytes(), width, height); err != nil {
533 » » » log.Printf("ERROR: Failed to insert sources into databas e: %q\n", err) 533 » » » glog.Errorf("Failed to insert sources into database: %q\ n", err)
534 http.Error(w, fmt.Sprintf("Failed to store image: %s.", err), 500) 534 http.Error(w, fmt.Sprintf("Failed to store image: %s.", err), 500)
535 return 535 return
536 } 536 }
537 go writeOutAllSourceImages() 537 go writeOutAllSourceImages()
538 538
539 // Now redirect back to where we came from. 539 // Now redirect back to where we came from.
540 http.Redirect(w, r, r.Referer(), 302) 540 http.Redirect(w, r, r.Referer(), 302)
541 } else { 541 } else {
542 http.NotFound(w, r) 542 http.NotFound(w, r)
543 return 543 return
544 } 544 }
545 } 545 }
546 546
547 // imageHandler serves up the PNG of a specific try. 547 // imageHandler serves up the PNG of a specific try.
548 func imageHandler(w http.ResponseWriter, r *http.Request) { 548 func imageHandler(w http.ResponseWriter, r *http.Request) {
549 » log.Printf("Image Handler: %q\n", r.URL.Path) 549 » glog.Infof("Image Handler: %q\n", r.URL.Path)
550 if r.Method != "GET" { 550 if r.Method != "GET" {
551 http.NotFound(w, r) 551 http.NotFound(w, r)
552 return 552 return
553 } 553 }
554 match := imageLink.FindStringSubmatch(r.URL.Path) 554 match := imageLink.FindStringSubmatch(r.URL.Path)
555 if len(match) != 2 { 555 if len(match) != 2 {
556 http.NotFound(w, r) 556 http.NotFound(w, r)
557 return 557 return
558 } 558 }
559 filename := match[1] 559 filename := match[1]
560 w.Header().Set("Content-Type", "image/png") 560 w.Header().Set("Content-Type", "image/png")
561 http.ServeFile(w, r, fmt.Sprintf("../../../inout/%s", filename)) 561 http.ServeFile(w, r, fmt.Sprintf("../../../inout/%s", filename))
562 } 562 }
563 563
564 type Try struct { 564 type Try struct {
565 Hash string `json:"hash"` 565 Hash string `json:"hash"`
566 Source int 566 Source int
567 CreateTS string `json:"create_ts"` 567 CreateTS string `json:"create_ts"`
568 } 568 }
569 569
570 type Recent struct { 570 type Recent struct {
571 Tries []Try 571 Tries []Try
572 Titlebar Titlebar 572 Titlebar Titlebar
573 } 573 }
574 574
575 // recentHandler shows the last 20 tries. 575 // recentHandler shows the last 20 tries.
576 func recentHandler(w http.ResponseWriter, r *http.Request) { 576 func recentHandler(w http.ResponseWriter, r *http.Request) {
577 » log.Printf("Recent Handler: %q\n", r.URL.Path) 577 » glog.Infof("Recent Handler: %q\n", r.URL.Path)
578 578
579 var err error 579 var err error
580 rows, err := db.Query("SELECT create_ts, hash FROM webtry ORDER BY creat e_ts DESC LIMIT 20") 580 rows, err := db.Query("SELECT create_ts, hash FROM webtry ORDER BY creat e_ts DESC LIMIT 20")
581 if err != nil { 581 if err != nil {
582 http.NotFound(w, r) 582 http.NotFound(w, r)
583 return 583 return
584 } 584 }
585 recent := []Try{} 585 recent := []Try{}
586 for rows.Next() { 586 for rows.Next() {
587 var hash string 587 var hash string
588 var create_ts time.Time 588 var create_ts time.Time
589 if err := rows.Scan(&create_ts, &hash); err != nil { 589 if err := rows.Scan(&create_ts, &hash); err != nil {
590 » » » log.Printf("Error: failed to fetch from database: %q", e rr) 590 » » » glog.Errorf("failed to fetch from database: %q", err)
591 continue 591 continue
592 } 592 }
593 recent = append(recent, Try{Hash: hash, CreateTS: create_ts.Form at("2006-02-01")}) 593 recent = append(recent, Try{Hash: hash, CreateTS: create_ts.Form at("2006-02-01")})
594 } 594 }
595 w.Header().Set("Content-Type", "text/html") 595 w.Header().Set("Content-Type", "text/html")
596 if err := recentTemplate.Execute(w, Recent{Tries: recent, Titlebar: Titl ebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil { 596 if err := recentTemplate.Execute(w, Recent{Tries: recent, Titlebar: Titl ebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
597 » » log.Printf("ERROR: Failed to expand template: %q\n", err) 597 » » glog.Errorf("Failed to expand template: %q\n", err)
598 } 598 }
599 } 599 }
600 600
601 type Workspace struct { 601 type Workspace struct {
602 Name string 602 Name string
603 Code string 603 Code string
604 Hash string 604 Hash string
605 Width int 605 Width int
606 Height int 606 Height int
607 Source int 607 Source int
608 GPU bool 608 GPU bool
609 Tries []Try 609 Tries []Try
610 Titlebar Titlebar 610 Titlebar Titlebar
611 } 611 }
612 612
613 // newWorkspace generates a new random workspace name and stores it in the datab ase. 613 // newWorkspace generates a new random workspace name and stores it in the datab ase.
614 func newWorkspace() (string, error) { 614 func newWorkspace() (string, error) {
615 for i := 0; i < 10; i++ { 615 for i := 0; i < 10; i++ {
616 adj := workspaceNameAdj[rand.Intn(len(workspaceNameAdj))] 616 adj := workspaceNameAdj[rand.Intn(len(workspaceNameAdj))]
617 noun := workspaceNameNoun[rand.Intn(len(workspaceNameNoun))] 617 noun := workspaceNameNoun[rand.Intn(len(workspaceNameNoun))]
618 suffix := rand.Intn(1000) 618 suffix := rand.Intn(1000)
619 name := fmt.Sprintf("%s-%s-%d", adj, noun, suffix) 619 name := fmt.Sprintf("%s-%s-%d", adj, noun, suffix)
620 if _, err := db.Exec("INSERT INTO workspace (name) VALUES(?)", n ame); err == nil { 620 if _, err := db.Exec("INSERT INTO workspace (name) VALUES(?)", n ame); err == nil {
621 return name, nil 621 return name, nil
622 } else { 622 } else {
623 » » » log.Printf("ERROR: Failed to insert workspace into datab ase: %q\n", err) 623 » » » glog.Errorf("Failed to insert workspace into database: % q\n", err)
624 } 624 }
625 } 625 }
626 return "", fmt.Errorf("Failed to create a new workspace") 626 return "", fmt.Errorf("Failed to create a new workspace")
627 } 627 }
628 628
629 // getCode returns the code for a given hash, or the empty string if not found. 629 // getCode returns the code for a given hash, or the empty string if not found.
630 func getCode(hash string) (string, int, int, int, bool, error) { 630 func getCode(hash string) (string, int, int, int, bool, error) {
631 code := "" 631 code := ""
632 width := 0 632 width := 0
633 height := 0 633 height := 0
634 source := 0 634 source := 0
635 gpu := false 635 gpu := false
636 if err := db.QueryRow("SELECT code, width, height, gpu, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &gpu, &source); er r != nil { 636 if err := db.QueryRow("SELECT code, width, height, gpu, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &gpu, &source); er r != nil {
637 » » log.Printf("ERROR: Code for hash is missing: %q\n", err) 637 » » glog.Errorf("Code for hash is missing: %q\n", err)
638 return code, width, height, source, gpu, err 638 return code, width, height, source, gpu, err
639 } 639 }
640 return code, width, height, source, gpu, nil 640 return code, width, height, source, gpu, nil
641 } 641 }
642 642
643 func workspaceHandler(w http.ResponseWriter, r *http.Request) { 643 func workspaceHandler(w http.ResponseWriter, r *http.Request) {
644 » log.Printf("Workspace Handler: %q\n", r.URL.Path) 644 » glog.Infof("Workspace Handler: %q\n", r.URL.Path)
645 if r.Method == "GET" { 645 if r.Method == "GET" {
646 tries := []Try{} 646 tries := []Try{}
647 match := workspaceLink.FindStringSubmatch(r.URL.Path) 647 match := workspaceLink.FindStringSubmatch(r.URL.Path)
648 name := "" 648 name := ""
649 if len(match) == 2 { 649 if len(match) == 2 {
650 name = match[1] 650 name = match[1]
651 rows, err := db.Query("SELECT create_ts, hash, source_im age_id FROM workspacetry WHERE name=? ORDER BY create_ts", name) 651 rows, err := db.Query("SELECT create_ts, hash, source_im age_id FROM workspacetry WHERE name=? ORDER BY create_ts", name)
652 if err != nil { 652 if err != nil {
653 reportError(w, r, err, "Failed to select.") 653 reportError(w, r, err, "Failed to select.")
654 return 654 return
655 } 655 }
656 for rows.Next() { 656 for rows.Next() {
657 var hash string 657 var hash string
658 var create_ts time.Time 658 var create_ts time.Time
659 var source int 659 var source int
660 if err := rows.Scan(&create_ts, &hash, &source); err != nil { 660 if err := rows.Scan(&create_ts, &hash, &source); err != nil {
661 » » » » » log.Printf("Error: failed to fetch from database: %q", err) 661 » » » » » glog.Errorf("failed to fetch from databa se: %q", err)
662 continue 662 continue
663 } 663 }
664 tries = append(tries, Try{Hash: hash, Source: so urce, CreateTS: create_ts.Format("2006-02-01")}) 664 tries = append(tries, Try{Hash: hash, Source: so urce, CreateTS: create_ts.Format("2006-02-01")})
665 } 665 }
666 } 666 }
667 var code string 667 var code string
668 var hash string 668 var hash string
669 var width int 669 var width int
670 var height int 670 var height int
671 source := 0 671 source := 0
672 gpu := false 672 gpu := false
673 if len(tries) == 0 { 673 if len(tries) == 0 {
674 code = DEFAULT_SAMPLE 674 code = DEFAULT_SAMPLE
675 width = 256 675 width = 256
676 height = 256 676 height = 256
677 } else { 677 } else {
678 hash = tries[len(tries)-1].Hash 678 hash = tries[len(tries)-1].Hash
679 code, width, height, source, gpu, _ = getCode(hash) 679 code, width, height, source, gpu, _ = getCode(hash)
680 } 680 }
681 w.Header().Set("Content-Type", "text/html") 681 w.Header().Set("Content-Type", "text/html")
682 if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, C ode: code, Name: name, Hash: hash, Width: width, Height: height, GPU: gpu, Sourc e: source, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil { 682 if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, C ode: code, Name: name, Hash: hash, Width: width, Height: height, GPU: gpu, Sourc e: source, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
683 » » » log.Printf("ERROR: Failed to expand template: %q\n", err ) 683 » » » glog.Errorf("Failed to expand template: %q\n", err)
684 } 684 }
685 } else if r.Method == "POST" { 685 } else if r.Method == "POST" {
686 name, err := newWorkspace() 686 name, err := newWorkspace()
687 if err != nil { 687 if err != nil {
688 http.Error(w, "Failed to create a new workspace.", 500) 688 http.Error(w, "Failed to create a new workspace.", 500)
689 return 689 return
690 } 690 }
691 http.Redirect(w, r, "/w/"+name, 302) 691 http.Redirect(w, r, "/w/"+name, 302)
692 } 692 }
693 } 693 }
(...skipping 13 matching lines...) Expand all
707 Code string `json:"code"` 707 Code string `json:"code"`
708 Width int `json:"width"` 708 Width int `json:"width"`
709 Height int `json:"height"` 709 Height int `json:"height"`
710 GPU bool `json:"gpu"` 710 GPU bool `json:"gpu"`
711 Name string `json:"name"` // Optional name of the workspace the code is in. 711 Name string `json:"name"` // Optional name of the workspace the code is in.
712 Source int `json:"source"` // ID of the source image, 0 if none. 712 Source int `json:"source"` // ID of the source image, 0 if none.
713 } 713 }
714 714
715 // iframeHandler handles the GET and POST of the main page. 715 // iframeHandler handles the GET and POST of the main page.
716 func iframeHandler(w http.ResponseWriter, r *http.Request) { 716 func iframeHandler(w http.ResponseWriter, r *http.Request) {
717 » log.Printf("IFrame Handler: %q\n", r.URL.Path) 717 » glog.Infof("IFrame Handler: %q\n", r.URL.Path)
718 if r.Method != "GET" { 718 if r.Method != "GET" {
719 http.NotFound(w, r) 719 http.NotFound(w, r)
720 return 720 return
721 } 721 }
722 match := iframeLink.FindStringSubmatch(r.URL.Path) 722 match := iframeLink.FindStringSubmatch(r.URL.Path)
723 if len(match) != 2 { 723 if len(match) != 2 {
724 http.NotFound(w, r) 724 http.NotFound(w, r)
725 return 725 return
726 } 726 }
727 hash := match[1] 727 hash := match[1]
728 if db == nil { 728 if db == nil {
729 http.NotFound(w, r) 729 http.NotFound(w, r)
730 return 730 return
731 } 731 }
732 var code string 732 var code string
733 code, width, height, source, gpu, err := getCode(hash) 733 code, width, height, source, gpu, err := getCode(hash)
734 if err != nil { 734 if err != nil {
735 http.NotFound(w, r) 735 http.NotFound(w, r)
736 return 736 return
737 } 737 }
738 // Expand the template. 738 // Expand the template.
739 w.Header().Set("Content-Type", "text/html") 739 w.Header().Set("Content-Type", "text/html")
740 if err := iframeTemplate.Execute(w, userCode{Code: code, Width: width, H eight: height, GPU: gpu, Hash: hash, Source: source}); err != nil { 740 if err := iframeTemplate.Execute(w, userCode{Code: code, Width: width, H eight: height, GPU: gpu, Hash: hash, Source: source}); err != nil {
741 » » log.Printf("ERROR: Failed to expand template: %q\n", err) 741 » » glog.Errorf("Failed to expand template: %q\n", err)
742 } 742 }
743 } 743 }
744 744
745 type TryInfo struct { 745 type TryInfo struct {
746 Hash string `json:"hash"` 746 Hash string `json:"hash"`
747 Code string `json:"code"` 747 Code string `json:"code"`
748 Width int `json:"width"` 748 Width int `json:"width"`
749 Height int `json:"height"` 749 Height int `json:"height"`
750 GPU bool `json:"gpu"` 750 GPU bool `json:"gpu"`
751 Source int `json:"source"` 751 Source int `json:"source"`
752 } 752 }
753 753
754 // tryInfoHandler returns information about a specific try. 754 // tryInfoHandler returns information about a specific try.
755 func tryInfoHandler(w http.ResponseWriter, r *http.Request) { 755 func tryInfoHandler(w http.ResponseWriter, r *http.Request) {
756 » log.Printf("Try Info Handler: %q\n", r.URL.Path) 756 » glog.Infof("Try Info Handler: %q\n", r.URL.Path)
757 if r.Method != "GET" { 757 if r.Method != "GET" {
758 http.NotFound(w, r) 758 http.NotFound(w, r)
759 return 759 return
760 } 760 }
761 match := tryInfoLink.FindStringSubmatch(r.URL.Path) 761 match := tryInfoLink.FindStringSubmatch(r.URL.Path)
762 if len(match) != 2 { 762 if len(match) != 2 {
763 http.NotFound(w, r) 763 http.NotFound(w, r)
764 return 764 return
765 } 765 }
766 hash := match[1] 766 hash := match[1]
(...skipping 14 matching lines...) Expand all
781 if err != nil { 781 if err != nil {
782 reportError(w, r, err, "Failed to serialize a response.") 782 reportError(w, r, err, "Failed to serialize a response.")
783 return 783 return
784 } 784 }
785 w.Header().Set("Content-Type", "application/json") 785 w.Header().Set("Content-Type", "application/json")
786 w.Write(resp) 786 w.Write(resp)
787 } 787 }
788 788
789 func cleanCompileOutput(s, hash string) string { 789 func cleanCompileOutput(s, hash string) string {
790 old := "../../../cache/src/" + hash + ".cpp:" 790 old := "../../../cache/src/" + hash + ".cpp:"
791 » log.Printf("INFO: replacing %q\n", old) 791 » glog.Infof("replacing %q\n", old)
792 return strings.Replace(s, old, "usercode.cpp:", -1) 792 return strings.Replace(s, old, "usercode.cpp:", -1)
793 } 793 }
794 794
795 // mainHandler handles the GET and POST of the main page. 795 // mainHandler handles the GET and POST of the main page.
796 func mainHandler(w http.ResponseWriter, r *http.Request) { 796 func mainHandler(w http.ResponseWriter, r *http.Request) {
797 » log.Printf("Main Handler: %q\n", r.URL.Path) 797 » glog.Infof("Main Handler: %q\n", r.URL.Path)
798 requestsCounter.Inc(1) 798 requestsCounter.Inc(1)
799 if r.Method == "GET" { 799 if r.Method == "GET" {
800 code := DEFAULT_SAMPLE 800 code := DEFAULT_SAMPLE
801 source := 0 801 source := 0
802 width := 256 802 width := 256
803 height := 256 803 height := 256
804 gpu := false 804 gpu := false
805 match := directLink.FindStringSubmatch(r.URL.Path) 805 match := directLink.FindStringSubmatch(r.URL.Path)
806 var hash string 806 var hash string
807 if len(match) == 2 && r.URL.Path != "/" { 807 if len(match) == 2 && r.URL.Path != "/" {
808 hash = match[1] 808 hash = match[1]
809 if db == nil { 809 if db == nil {
810 http.NotFound(w, r) 810 http.NotFound(w, r)
811 return 811 return
812 } 812 }
813 // Update 'code' with the code found in the database. 813 // Update 'code' with the code found in the database.
814 if err := db.QueryRow("SELECT code, width, height, gpu, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &g pu, &source); err != nil { 814 if err := db.QueryRow("SELECT code, width, height, gpu, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &g pu, &source); err != nil {
815 http.NotFound(w, r) 815 http.NotFound(w, r)
816 return 816 return
817 } 817 }
818 } 818 }
819 // Expand the template. 819 // Expand the template.
820 w.Header().Set("Content-Type", "text/html") 820 w.Header().Set("Content-Type", "text/html")
821 if err := indexTemplate.Execute(w, userCode{Code: code, Hash: ha sh, Source: source, Width: width, Height: height, GPU: gpu, Titlebar: Titlebar{G itHash: gitHash, GitInfo: gitInfo}}); err != nil { 821 if err := indexTemplate.Execute(w, userCode{Code: code, Hash: ha sh, Source: source, Width: width, Height: height, GPU: gpu, Titlebar: Titlebar{G itHash: gitHash, GitInfo: gitInfo}}); err != nil {
822 » » » log.Printf("ERROR: Failed to expand template: %q\n", err ) 822 » » » glog.Errorf("Failed to expand template: %q\n", err)
823 } 823 }
824 } else if r.Method == "POST" { 824 } else if r.Method == "POST" {
825 w.Header().Set("Content-Type", "application/json") 825 w.Header().Set("Content-Type", "application/json")
826 buf := bytes.NewBuffer(make([]byte, 0, MAX_TRY_SIZE)) 826 buf := bytes.NewBuffer(make([]byte, 0, MAX_TRY_SIZE))
827 n, err := buf.ReadFrom(r.Body) 827 n, err := buf.ReadFrom(r.Body)
828 if err != nil { 828 if err != nil {
829 reportTryError(w, r, err, "Failed to read a request body .", "") 829 reportTryError(w, r, err, "Failed to read a request body .", "")
830 return 830 return
831 } 831 }
832 if n == MAX_TRY_SIZE { 832 if n == MAX_TRY_SIZE {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 http.HandleFunc("/iframe/", autogzip.HandleFunc(iframeHandler)) 900 http.HandleFunc("/iframe/", autogzip.HandleFunc(iframeHandler))
901 http.HandleFunc("/json/", autogzip.HandleFunc(tryInfoHandler)) 901 http.HandleFunc("/json/", autogzip.HandleFunc(tryInfoHandler))
902 http.HandleFunc("/sources/", autogzip.HandleFunc(sourcesHandler)) 902 http.HandleFunc("/sources/", autogzip.HandleFunc(sourcesHandler))
903 903
904 // Resources are served directly 904 // Resources are served directly
905 // TODO add support for caching/etags/gzip 905 // TODO add support for caching/etags/gzip
906 http.Handle("/res/", autogzip.Handle(http.FileServer(http.Dir("./")))) 906 http.Handle("/res/", autogzip.Handle(http.FileServer(http.Dir("./"))))
907 907
908 // TODO Break out /c/ as it's own handler. 908 // TODO Break out /c/ as it's own handler.
909 http.HandleFunc("/", autogzip.HandleFunc(mainHandler)) 909 http.HandleFunc("/", autogzip.HandleFunc(mainHandler))
910 » log.Fatal(http.ListenAndServe(*port, nil)) 910 » glog.Fatal(http.ListenAndServe(*port, nil))
911 } 911 }
OLDNEW
« no previous file with comments | « experimental/webtry/setup/sys/webtry_init ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698