_ "image/jpeg"
"image/png"
"io/ioutil"
- "log"
"math/rand"
"net"
"net/http"
import (
"github.com/fiorix/go-web/autogzip"
_ "github.com/go-sql-driver/mysql"
+ "github.com/golang/glog"
_ "github.com/mattn/go-sqlite3"
"github.com/rcrowley/go-metrics"
)
// Change the current working directory to the directory of the executable.
cwd, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
- log.Fatal(err)
+ glog.Fatal(err)
}
if err := os.Chdir(cwd); err != nil {
log.Fatal(err)
if resp, err := client.Do(req); err == nil {
password, err := ioutil.ReadAll(resp.Body)
if err != nil {
- log.Printf("ERROR: Failed to read password from metadata server: %q\n", err)
+ glog.Errorf("Failed to read password from metadata server: %q\n", err)
panic(err)
}
// The IP address of the database is found here:
// And 3306 is the default port for MySQL.
db, err = sql.Open("mysql", fmt.Sprintf("webtry:%s@tcp(173.194.83.52:3306)/webtry?parseTime=true", password))
if err != nil {
- log.Printf("ERROR: Failed to open connection to SQL server: %q\n", err)
+ glog.Errorf("ERROR: Failed to open connection to SQL server: %q\n", err)
panic(err)
}
} else {
- log.Printf("INFO: Failed to find metadata, unable to connect to MySQL server (Expected when running locally): %q\n", err)
+ glog.Infof("Failed to find metadata, unable to connect to MySQL server (Expected when running locally): %q\n", err)
// Fallback to sqlite for local use.
db, err = sql.Open("sqlite3", "./webtry.db")
if err != nil {
- log.Printf("ERROR: Failed to open: %q\n", err)
+ glog.Errorf("Failed to open: %q\n", err)
panic(err)
}
sql := `CREATE TABLE IF NOT EXISTS source_images (
)`
_, err = db.Exec(sql)
if err != nil {
- log.Printf("Info: status creating sqlite table for sources: %q\n", err)
+ glog.Infof("status creating sqlite table for sources: %q\n", err)
}
sql = `CREATE TABLE IF NOT EXISTS webtry (
)`
_, err = db.Exec(sql)
if err != nil {
- log.Printf("Info: status creating sqlite table for webtry: %q\n", err)
+ glog.Infof("status creating sqlite table for webtry: %q\n", err)
}
sql = `CREATE TABLE IF NOT EXISTS workspace (
)`
_, err = db.Exec(sql)
if err != nil {
- log.Printf("Info: status creating sqlite table for workspace: %q\n", err)
+ glog.Infof("status creating sqlite table for workspace: %q\n", err)
}
sql = `CREATE TABLE IF NOT EXISTS workspacetry (
)`
_, err = db.Exec(sql)
if err != nil {
- log.Printf("Info: status creating sqlite table for workspace try: %q\n", err)
+ glog.Infof("status creating sqlite table for workspace try: %q\n", err)
}
}
c := time.Tick(1 * time.Minute)
for _ = range c {
if err := db.Ping(); err != nil {
- log.Printf("ERROR: Database failed to respond: %q\n", err)
+ glog.Errorf("Database failed to respond: %q\n", err)
}
}
}()
rows, err := db.Query("SELECT id, image, create_ts FROM source_images ORDER BY create_ts DESC")
if err != nil {
- log.Printf("ERROR: Failed to open connection to SQL server: %q\n", err)
+ glog.Errorf("Failed to open connection to SQL server: %q\n", err)
panic(err)
}
for rows.Next() {
var image []byte
var create_ts time.Time
if err := rows.Scan(&id, &image, &create_ts); err != nil {
- log.Printf("Error: failed to fetch from database: %q", err)
+ glog.Errorf("failed to fetch from database: %q", err)
continue
}
filename := fmt.Sprintf("../../../inout/image-%d.png", id)
if _, err := os.Stat(filename); os.IsExist(err) {
- log.Printf("Skipping write since file exists: %q", filename)
+ glog.Infof("Skipping write since file exists: %q", filename)
continue
}
if err := ioutil.WriteFile(filename, image, 0666); err != nil {
- log.Printf("Error: failed to write image file: %q", err)
+ glog.Errorf("failed to write image file: %q", err)
}
}
}
// run is expected to not care what its current working directory is.
// Returns the stdout and stderr.
func doCmd(commandLine string) (string, error) {
- log.Printf("Command: %q\n", commandLine)
+ glog.Infof("Command: %q\n", commandLine)
programAndArgs := strings.SplitN(commandLine, " ", 2)
program := programAndArgs[0]
args := []string{}
}
cmd := exec.Command(program, args...)
message, err := cmd.CombinedOutput()
- log.Printf("StdOut + StdErr: %s\n", string(message))
+ glog.Infof("StdOut + StdErr: %s\n", string(message))
if err != nil {
- log.Printf("Exit status: %s\n", err.Error())
+ glog.Errorf("Exit status: %s\n", err)
return string(message), fmt.Errorf("Failed to run command.")
}
return string(message), nil
// reportError formats an HTTP error response and also logs the detailed error message.
func reportError(w http.ResponseWriter, r *http.Request, err error, message string) {
- log.Printf("Error: %s\n%s", message, err.Error())
+ glog.Errorf("%s\n%s", message, err)
w.Header().Set("Content-Type", "text/plain")
http.Error(w, message, 500)
}
Message: message,
Hash: hash,
}
- log.Printf("Error: %s\n%s", message, err.Error())
+ glog.Errorf("%s\n%s", message, err)
resp, err := json.Marshal(m)
if err != nil {
http.Error(w, "Failed to serialize a response", 500)
return
}
if _, err := db.Exec("INSERT INTO webtry (code, hash, width, height, gpu, source_image_id) VALUES(?, ?, ?, ?, ?, ?)", code, hash, width, height, gpu, source); err != nil {
- log.Printf("ERROR: Failed to insert code into database: %q\n", err)
+ glog.Errorf("Failed to insert code into database: %q\n", err)
}
if workspaceName != "" {
if _, err := db.Exec("INSERT INTO workspacetry (name, hash, width, height, gpu, source_image_id) VALUES(?, ?, ?, ?, ?, ?)", workspaceName, hash, width, height, gpu, source); err != nil {
- log.Printf("ERROR: Failed to insert into workspacetry table: %q\n", err)
+ glog.Errorf("Failed to insert into workspacetry table: %q\n", err)
}
}
}
// sourcesHandler serves up the PNG of a specific try.
func sourcesHandler(w http.ResponseWriter, r *http.Request) {
- log.Printf("Sources Handler: %q\n", r.URL.Path)
+ glog.Infof("Sources Handler: %q\n", r.URL.Path)
if r.Method == "GET" {
rows, err := db.Query("SELECT id, create_ts FROM source_images WHERE hidden=0 ORDER BY create_ts DESC")
var id int
var create_ts time.Time
if err := rows.Scan(&id, &create_ts); err != nil {
- log.Printf("Error: failed to fetch from database: %q", err)
+ glog.Errorf("failed to fetch from database: %q", err)
continue
}
sources = append(sources, Sources{Id: id})
width := bounds.Max.Y - bounds.Min.Y
height := bounds.Max.X - bounds.Min.X
if _, err := db.Exec("INSERT INTO source_images (image, width, height) VALUES(?, ?, ?)", b.Bytes(), width, height); err != nil {
- log.Printf("ERROR: Failed to insert sources into database: %q\n", err)
+ glog.Errorf("Failed to insert sources into database: %q\n", err)
http.Error(w, fmt.Sprintf("Failed to store image: %s.", err), 500)
return
}
// imageHandler serves up the PNG of a specific try.
func imageHandler(w http.ResponseWriter, r *http.Request) {
- log.Printf("Image Handler: %q\n", r.URL.Path)
+ glog.Infof("Image Handler: %q\n", r.URL.Path)
if r.Method != "GET" {
http.NotFound(w, r)
return
// recentHandler shows the last 20 tries.
func recentHandler(w http.ResponseWriter, r *http.Request) {
- log.Printf("Recent Handler: %q\n", r.URL.Path)
+ glog.Infof("Recent Handler: %q\n", r.URL.Path)
var err error
rows, err := db.Query("SELECT create_ts, hash FROM webtry ORDER BY create_ts DESC LIMIT 20")
var hash string
var create_ts time.Time
if err := rows.Scan(&create_ts, &hash); err != nil {
- log.Printf("Error: failed to fetch from database: %q", err)
+ glog.Errorf("failed to fetch from database: %q", err)
continue
}
recent = append(recent, Try{Hash: hash, CreateTS: create_ts.Format("2006-02-01")})
}
w.Header().Set("Content-Type", "text/html")
if err := recentTemplate.Execute(w, Recent{Tries: recent, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
- log.Printf("ERROR: Failed to expand template: %q\n", err)
+ glog.Errorf("Failed to expand template: %q\n", err)
}
}
if _, err := db.Exec("INSERT INTO workspace (name) VALUES(?)", name); err == nil {
return name, nil
} else {
- log.Printf("ERROR: Failed to insert workspace into database: %q\n", err)
+ glog.Errorf("Failed to insert workspace into database: %q\n", err)
}
}
return "", fmt.Errorf("Failed to create a new workspace")
source := 0
gpu := false
if err := db.QueryRow("SELECT code, width, height, gpu, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &gpu, &source); err != nil {
- log.Printf("ERROR: Code for hash is missing: %q\n", err)
+ glog.Errorf("Code for hash is missing: %q\n", err)
return code, width, height, source, gpu, err
}
return code, width, height, source, gpu, nil
}
func workspaceHandler(w http.ResponseWriter, r *http.Request) {
- log.Printf("Workspace Handler: %q\n", r.URL.Path)
+ glog.Infof("Workspace Handler: %q\n", r.URL.Path)
if r.Method == "GET" {
tries := []Try{}
match := workspaceLink.FindStringSubmatch(r.URL.Path)
var create_ts time.Time
var source int
if err := rows.Scan(&create_ts, &hash, &source); err != nil {
- log.Printf("Error: failed to fetch from database: %q", err)
+ glog.Errorf("failed to fetch from database: %q", err)
continue
}
tries = append(tries, Try{Hash: hash, Source: source, CreateTS: create_ts.Format("2006-02-01")})
}
w.Header().Set("Content-Type", "text/html")
if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, Code: code, Name: name, Hash: hash, Width: width, Height: height, GPU: gpu, Source: source, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
- log.Printf("ERROR: Failed to expand template: %q\n", err)
+ glog.Errorf("Failed to expand template: %q\n", err)
}
} else if r.Method == "POST" {
name, err := newWorkspace()
// iframeHandler handles the GET and POST of the main page.
func iframeHandler(w http.ResponseWriter, r *http.Request) {
- log.Printf("IFrame Handler: %q\n", r.URL.Path)
+ glog.Infof("IFrame Handler: %q\n", r.URL.Path)
if r.Method != "GET" {
http.NotFound(w, r)
return
// Expand the template.
w.Header().Set("Content-Type", "text/html")
if err := iframeTemplate.Execute(w, userCode{Code: code, Width: width, Height: height, GPU: gpu, Hash: hash, Source: source}); err != nil {
- log.Printf("ERROR: Failed to expand template: %q\n", err)
+ glog.Errorf("Failed to expand template: %q\n", err)
}
}
// tryInfoHandler returns information about a specific try.
func tryInfoHandler(w http.ResponseWriter, r *http.Request) {
- log.Printf("Try Info Handler: %q\n", r.URL.Path)
+ glog.Infof("Try Info Handler: %q\n", r.URL.Path)
if r.Method != "GET" {
http.NotFound(w, r)
return
func cleanCompileOutput(s, hash string) string {
old := "../../../cache/src/" + hash + ".cpp:"
- log.Printf("INFO: replacing %q\n", old)
+ glog.Infof("replacing %q\n", old)
return strings.Replace(s, old, "usercode.cpp:", -1)
}
// mainHandler handles the GET and POST of the main page.
func mainHandler(w http.ResponseWriter, r *http.Request) {
- log.Printf("Main Handler: %q\n", r.URL.Path)
+ glog.Infof("Main Handler: %q\n", r.URL.Path)
requestsCounter.Inc(1)
if r.Method == "GET" {
code := DEFAULT_SAMPLE
// Expand the template.
w.Header().Set("Content-Type", "text/html")
if err := indexTemplate.Execute(w, userCode{Code: code, Hash: hash, Source: source, Width: width, Height: height, GPU: gpu, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
- log.Printf("ERROR: Failed to expand template: %q\n", err)
+ glog.Errorf("Failed to expand template: %q\n", err)
}
} else if r.Method == "POST" {
w.Header().Set("Content-Type", "application/json")
// TODO Break out /c/ as it's own handler.
http.HandleFunc("/", autogzip.HandleFunc(mainHandler))
- log.Fatal(http.ListenAndServe(*port, nil))
+ glog.Fatal(http.ListenAndServe(*port, nil))
}