2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								package main
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"http"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"io/ioutil"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"os"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"regexp"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"template"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-26 14:56:52 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								type Page struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Title string
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Body  []byte
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-26 14:56:52 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (p *Page) save() os.Error {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									filename := p.Title + ".txt"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return ioutil.WriteFile(filename, p.Body, 0600)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-26 14:56:52 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func loadPage(title string) (*Page, os.Error) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									filename := title + ".txt"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									body, err := ioutil.ReadFile(filename)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-26 14:56:52 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return &Page{Title: title, Body: body}, nil
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									p, err := loadPage(title)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										http.Redirect(w, r, "/edit/"+title, http.StatusFound)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									renderTemplate(w, "view", p)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func editHandler(w http.ResponseWriter, r *http.Request, title string) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									p, err := loadPage(title)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-26 14:56:52 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										p = &Page{Title: title}
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									renderTemplate(w, "edit", p)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									body := r.FormValue("body")
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-26 14:56:52 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									p := &Page{Title: title, Body: []byte(body)}
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									err := p.save()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										http.Error(w, err.String(), http.StatusInternalServerError)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									http.Redirect(w, r, "/view/"+title, http.StatusFound)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-26 14:56:52 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									t, err := template.ParseFile(tmpl+".html", nil)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										http.Error(w, err.String(), http.StatusInternalServerError)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									err = t.Execute(p, w)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										http.Error(w, err.String(), http.StatusInternalServerError)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const lenPath = len("/view/")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return func(w http.ResponseWriter, r *http.Request) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										title := r.URL.Path[lenPath:]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !titleValidator.MatchString(title) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											http.NotFound(w, r)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-30 13:19:33 +10:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										fn(w, r, title)
							 | 
						
					
						
							
								
									
										
										
										
											2010-04-28 12:36:39 +10:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func main() {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									http.HandleFunc("/view/", makeHandler(viewHandler))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									http.HandleFunc("/edit/", makeHandler(editHandler))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									http.HandleFunc("/save/", makeHandler(saveHandler))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									http.ListenAndServe(":8080", nil)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |