Index: experimental/webtry/webtry.go |
diff --git a/experimental/webtry/webtry.go b/experimental/webtry/webtry.go |
index fb53b593e36e0e3d67ca6c413d20bdc47b4adfa9..02c245a2444a03b1c87806ef5b36716dbf123385 100644 |
--- a/experimental/webtry/webtry.go |
+++ b/experimental/webtry/webtry.go |
@@ -9,12 +9,15 @@ import ( |
"flag" |
"fmt" |
_ "github.com/go-sql-driver/mysql" |
+ _ "github.com/mattn/go-sqlite3" |
+ htemplate "html/template" |
"io/ioutil" |
"log" |
"net/http" |
"os" |
"os/exec" |
"path/filepath" |
+ "regexp" |
"strings" |
"text/template" |
) |
@@ -22,6 +25,14 @@ import ( |
const ( |
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 -DSK_SUPPORT_OPENCL=0 -DSK_FORCE_DISTANCEFIELD_FONTS=0 -DSK_SCALAR_IS_FLOAT -DSK_CAN_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/pathops -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-unused-parameter -Wno-c++11-extensions -Werror -m64 -fno-rtti -Wnon-virtual-dtor -c ../../../cache/%s.cpp -o ../../../cache/%s.o` |
LINK = `c++ -m64 -lstdc++ -lm -o ../../../inout/%s -Wl,--start-group ../../../cache/%s.o obj/experimental/webtry/webtry.main.o obj/gyp/libflags.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 libskia_ports.a libskia_sfnt.a -Wl,--end-group -lpng -lz -lgif -lpthread -lfontconfig -ldl -lfreetype` |
+ DEFAULT_SAMPLE = `SkPaint p; |
+p.setColor(SK_ColorRED); |
+p.setAntiAlias(true); |
+p.setStyle(SkPaint::kStroke_Style); |
+p.setStrokeWidth(10); |
+ |
+canvas->drawLine(20, 20, 100, 100, p); |
+` |
) |
var ( |
@@ -29,10 +40,13 @@ var ( |
codeTemplate *template.Template = nil |
// index is the main index.html page we serve. |
- index []byte |
+ index *htemplate.Template = nil |
// db is the database, nil if we don't have an SQL database to store data into. |
db *sql.DB = nil |
+ |
+ // directLink is the regex that matches URLs paths that are direct links. |
+ directLink = regexp.MustCompile("^c/([a-a0-9]+)$") |
) |
// flags |
@@ -53,6 +67,7 @@ func LineNumbers(c string) string { |
} |
func init() { |
+ |
// Change the current working directory to the directory of the executable. |
var err error |
cwd, err := filepath.Abs(filepath.Dir(os.Args[0])) |
@@ -65,7 +80,8 @@ func init() { |
if err != nil { |
panic(err) |
} |
- index, err = ioutil.ReadFile(filepath.Join(cwd, "templates/index.html")) |
+ // Convert index.html into a template, which is expanded with the code. |
+ index, err = htemplate.ParseFiles(filepath.Join(cwd, "templates/index.html")) |
if err != nil { |
panic(err) |
} |
@@ -93,6 +109,19 @@ func init() { |
panic(err) |
} |
} else { |
+ // 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) |
+ panic(err) |
+ } |
+ sql := `CREATE TABLE webtry ( |
+ code TEXT DEFAULT '' NOT NULL, |
+ create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, |
+ hash CHAR(64) DEFAULT '' NOT NULL, |
+ PRIMARY KEY(hash) |
+ )` |
+ db.Exec(sql) |
log.Printf("INFO: Failed to find metadata, unable to connect to MySQL server (Expected when running locally): %q\n", err) |
} |
} |
@@ -109,7 +138,7 @@ func expandToFile(filename string, code string, t *template.Template) error { |
return err |
} |
defer f.Close() |
- return t.Execute(f, struct{ UserCode string }{UserCode: code}) |
+ return t.Execute(f, userCode{UserCode: code}) |
} |
// expandCode expands the template into a file and calculate the MD5 hash. |
@@ -128,6 +157,7 @@ func expandCode(code string) (string, error) { |
type response struct { |
Message string `json:"message"` |
Img string `json:"img"` |
+ Hash string `json:"hash"` |
} |
// doCmd executes the given command line string in either the out/Debug |
@@ -199,7 +229,25 @@ func writeToDatabase(hash string, code string) { |
// mainHandler handles the GET and POST of the main page. |
func mainHandler(w http.ResponseWriter, r *http.Request) { |
if r.Method == "GET" { |
- w.Write(index) |
+ code := DEFAULT_SAMPLE |
+ directLink := regexp.MustCompile("^/c/([a-f0-9]+)$") |
+ match := directLink.FindStringSubmatch(r.URL.Path) |
+ if len(match) == 2 { |
+ hash := match[1] |
+ if db == nil { |
+ http.NotFound(w, r) |
+ return |
+ } |
+ // Update 'code' with the code found in the database. |
+ if err := db.QueryRow("SELECT code FROM webtry WHERE hash=?", hash).Scan(&code); err != nil { |
+ http.NotFound(w, r) |
+ return |
+ } |
+ } |
+ // Expand the template. |
+ if err := index.Execute(w, userCode{UserCode: code}); err != nil { |
+ log.Printf("ERROR: Failed to expand template: %q\n", err) |
+ } |
} else if r.Method == "POST" { |
w.Header().Set("Content-Type", "application/json") |
b, err := ioutil.ReadAll(r.Body) |
@@ -251,6 +299,7 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { |
m := response{ |
Message: message, |
Img: base64.StdEncoding.EncodeToString([]byte(png)), |
+ Hash: hash, |
} |
resp, err := json.Marshal(m) |
if err != nil { |