Index: experimental/webtry/webtry.go |
diff --git a/experimental/webtry/webtry.go b/experimental/webtry/webtry.go |
index a895b0117843088b2785d4d45639ea7db53249d7..73e9fda993d6697dd404572827499e0828ccb56d 100644 |
--- a/experimental/webtry/webtry.go |
+++ b/experimental/webtry/webtry.go |
@@ -67,6 +67,9 @@ var ( |
// imageLink is the regex that matches URLs paths that are direct links to PNGs. |
imageLink = regexp.MustCompile("^/i/([a-f0-9]+.png)$") |
+ // tryInfoLink is the regex that matches URLs paths that are direct links to data about a single try. |
+ tryInfoLink = regexp.MustCompile("^/json/([a-f0-9]+)$") |
+ |
// workspaceLink is the regex that matches URLs paths for workspaces. |
workspaceLink = regexp.MustCompile("^/w/([a-z0-9-]+)$") |
@@ -382,6 +385,7 @@ func recentHandler(w http.ResponseWriter, r *http.Request) { |
type Workspace struct { |
Name string |
Code string |
+ Hash string |
Tries []Try |
} |
@@ -402,12 +406,13 @@ func newWorkspace() (string, error) { |
} |
// getCode returns the code for a given hash, or the empty string if not found. |
-func getCode(hash string) string { |
+func getCode(hash string) (string, error) { |
code := "" |
if err := db.QueryRow("SELECT code FROM webtry WHERE hash=?", hash).Scan(&code); err != nil { |
log.Printf("ERROR: Code for hash is missing: %q\n", err) |
+ return code, err |
} |
- return code |
+ return code, nil |
} |
func workspaceHandler(w http.ResponseWriter, r *http.Request) { |
@@ -434,12 +439,14 @@ func workspaceHandler(w http.ResponseWriter, r *http.Request) { |
} |
} |
var code string |
+ var hash string |
if len(tries) == 0 { |
code = DEFAULT_SAMPLE |
} else { |
- code = getCode(tries[len(tries)-1].Hash) |
+ hash = tries[len(tries)-1].Hash |
+ code, _ = getCode(hash) |
} |
- if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, Code: code, Name: name}); err != nil { |
+ if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, Code: code, Name: name, Hash: hash}); err != nil { |
log.Printf("ERROR: Failed to expand template: %q\n", err) |
} |
} else if r.Method == "POST" { |
@@ -465,7 +472,7 @@ func hasPreProcessor(code string) bool { |
type TryRequest struct { |
Code string `json:"code"` |
- Name string `json:"name"` |
+ Name string `json:"name"` // Optional name of the workspace the code is in. |
} |
// iframeHandler handles the GET and POST of the main page. |
@@ -486,8 +493,8 @@ func iframeHandler(w http.ResponseWriter, r *http.Request) { |
return |
} |
var code string |
- // Load 'code' with the code found in the database. |
- if err := db.QueryRow("SELECT code FROM webtry WHERE hash=?", hash).Scan(&code); err != nil { |
+ code, err := getCode(hash) |
+ if err != nil { |
http.NotFound(w, r) |
return |
} |
@@ -497,14 +504,51 @@ func iframeHandler(w http.ResponseWriter, r *http.Request) { |
} |
} |
+type TryInfo struct { |
+ Hash string `json:"hash"` |
+ Code string `json:"code"` |
+} |
+ |
+// 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) |
+ if r.Method != "GET" { |
+ http.NotFound(w, r) |
+ return |
+ } |
+ match := tryInfoLink.FindStringSubmatch(r.URL.Path) |
+ if len(match) != 2 { |
+ http.NotFound(w, r) |
+ return |
+ } |
+ hash := match[1] |
+ code, err := getCode(hash) |
+ if err != nil { |
+ http.NotFound(w, r) |
+ return |
+ } |
+ m := TryInfo{ |
+ Hash: hash, |
+ Code: code, |
+ } |
+ resp, err := json.Marshal(m) |
+ if err != nil { |
+ reportError(w, r, err, "Failed to serialize a response.") |
+ return |
+ } |
+ w.Header().Set("Content-Type", "application/json") |
+ w.Write(resp) |
+} |
+ |
// 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) |
if r.Method == "GET" { |
code := DEFAULT_SAMPLE |
match := directLink.FindStringSubmatch(r.URL.Path) |
+ var hash string |
if len(match) == 2 && r.URL.Path != "/" { |
- hash := match[1] |
+ hash = match[1] |
if db == nil { |
http.NotFound(w, r) |
return |
@@ -516,7 +560,7 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { |
} |
} |
// Expand the template. |
- if err := indexTemplate.Execute(w, userCode{UserCode: code}); err != nil { |
+ if err := indexTemplate.Execute(w, userCode{UserCode: code, Hash: hash}); err != nil { |
log.Printf("ERROR: Failed to expand template: %q\n", err) |
} |
} else if r.Method == "POST" { |
@@ -602,8 +646,10 @@ func main() { |
http.HandleFunc("/w/", workspaceHandler) |
http.HandleFunc("/recent/", recentHandler) |
http.HandleFunc("/iframe/", iframeHandler) |
+ http.HandleFunc("/json/", tryInfoHandler) |
http.HandleFunc("/css/", cssHandler) |
http.HandleFunc("/js/", jsHandler) |
+ // TODO Break out /c/ as it's own handler. |
http.HandleFunc("/", mainHandler) |
log.Fatal(http.ListenAndServe(*port, nil)) |
} |