func init() { // BASE_URL, AUTH_USER and AUTH_PASS, AWS_S3_BASE_URL are not required or else wercker tests would fail baseURL = os.Getenv("BASE_URL") authUser = os.Getenv("AUTH_USER") authPass = os.Getenv("AUTH_PASS") s3BaseURL = os.Getenv("AWS_S3_BASE_URL") if awsAuth, err := aws.EnvAuth(); err != nil { // not required or else wercker tests would fail log.Println(err) } else { // TODO(jrubin) allow region to be chosen by env variable s3Data := s3.New(awsAuth, aws.USWest2) s3Bucket = s3Data.Bucket(os.Getenv("AWS_S3_BUCKET_NAME")) } m = martini.Classic() m.Use(gzip.All()) m.Use(render.Renderer()) m.Get("/", func() string { return "hello, world" }) m.Post( "/v1/transcribe", auth.Basic(authUser, authPass), strict.Accept("application/json"), strict.ContentType("application/x-www-form-urlencoded"), binding.Bind(transcribeData{}), binding.ErrorHandler, handleTranscribe, ) m.Post( "/v1/transcribe/process", strict.ContentType("application/x-www-form-urlencoded"), binding.Bind(telapi.TranscribeCallbackData{}), binding.ErrorHandler, handleTranscribeProcess, ) m.Post( "/v1/transcribe/upload", auth.Basic(authUser, authPass), strict.Accept("application/json"), binding.MultipartForm(transcribeUploadData{}), binding.ErrorHandler, handleTranscribeUpload, ) m.Router.NotFound(strict.MethodNotAllowed, strict.NotFound) }
// NewServer spaws a new Vertigo server func NewServer() *martini.ClassicMartini { helpers := template.FuncMap{ // unescape unescapes HTML of s. // Used in templates such as "/post/display.tmpl" "unescape": func(s string) template.HTML { return template.HTML(s) }, // title renders post's Title as the HTML document's title. "title": func(t interface{}) string { post, exists := t.(Post) if exists { return post.Title } return Settings.Name }, // description renders page description. // If none is defined, returns "Blog in Go" instead. "description": func() string { if Settings.Description == "" { return "Blog in Go" } return Settings.Description }, // updated checks if post has been updated. "updated": func(p Post) bool { if p.Updated > p.Created { return true } return false }, // date calculates unix date from d and offset in format: Monday, January 2, 2006 3:04PM (-0700 GMT) "date": func(d int64, offset int) string { return time.Unix(d, 0).UTC().In(time.FixedZone("", offset)).Format("Monday, January 2, 2006 3:04PM (-0700 GMT)") }, // env returns environment variable of s. "env": func(s string) string { return os.Getenv(s) }, // timezones returns all 416 valid IANA timezone locations. "timezones": func() [416]timezone.Timezone { return timezone.Locations }, } m := martini.Classic() store := sessions.NewCookieStore([]byte(Settings.CookieHash)) m.Use(sessions.Sessions("user", store)) m.Use(Sessionchecker()) m.Use(strict.Strict) m.Use(martini.Static("public", martini.StaticOptions{ SkipLogging: true, // Adds 7 day Expire header for static files. Expires: func() string { return time.Now().Add(time.Hour * 168).UTC().Format("Mon, Jan 2 2006 15:04:05 GMT") }, })) m.Use(render.Renderer(render.Options{ Layout: "layout", Funcs: []template.FuncMap{helpers}, // Specify helper function maps for templates to access. })) m.Get("/", Homepage) m.Get("/rss", ReadFeed) m.Group("/post", func(r martini.Router) { // Please note that `/new` route has to be before the `/:slug` route. Otherwise the program will try // to fetch for Post named "new". // For now I'll keep it this way to streamline route naming. r.Get("/new", ProtectedPage, func(res render.Render) { res.HTML(200, "post/new", nil) }) r.Get("/:slug", ReadPost) r.Get("/:slug/edit", ProtectedPage, EditPost) r.Post("/:slug/edit", ProtectedPage, strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, UpdatePost) r.Get("/:slug/delete", ProtectedPage, DeletePost) r.Get("/:slug/publish", ProtectedPage, PublishPost) r.Get("/:slug/unpublish", ProtectedPage, UnpublishPost) r.Post("/new", ProtectedPage, strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, CreatePost) r.Post("/search", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Search{}), binding.ErrorHandler, SearchPost) }) m.Group("/user", func(r martini.Router) { r.Get("", ProtectedPage, ReadUser) //r.Post("/delete", strict.ContentType("application/x-www-form-urlencoded"), ProtectedPage, binding.Form(User{}), DeleteUser) r.Get("/settings", ProtectedPage, ReadSettings) r.Post("/settings", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Vertigo{}), binding.ErrorHandler, ProtectedPage, UpdateSettings) r.Post("/installation", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Vertigo{}), binding.ErrorHandler, UpdateSettings) r.Get("/register", SessionRedirect, func(res render.Render) { res.HTML(200, "user/register", nil) }) r.Post("/register", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(User{}), binding.ErrorHandler, CreateUser) r.Get("/recover", SessionRedirect, func(res render.Render) { res.HTML(200, "user/recover", nil) }) r.Post("/recover", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(User{}), RecoverUser) r.Get("/reset/:id/:recovery", SessionRedirect, func(res render.Render) { res.HTML(200, "user/reset", nil) }) r.Post("/reset/:id/:recovery", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(User{}), ResetUserPassword) r.Get("/login", SessionRedirect, func(res render.Render) { res.HTML(200, "user/login", nil) }) r.Post("/login", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(User{}), LoginUser) r.Get("/logout", LogoutUser) }) m.Group("/api", func(r martini.Router) { r.Get("", func(res render.Render) { res.HTML(200, "api/index", nil) }) r.Get("/settings", ProtectedPage, ReadSettings) r.Post("/settings", strict.ContentType("application/json"), binding.Json(Vertigo{}), binding.ErrorHandler, ProtectedPage, UpdateSettings) r.Post("/installation", strict.ContentType("application/json"), binding.Json(Vertigo{}), binding.ErrorHandler, UpdateSettings) r.Get("/users", ReadUsers) r.Get("/user/logout", LogoutUser) r.Get("/user/:id", ReadUser) //r.Delete("/user", DeleteUser) r.Post("/user", strict.ContentType("application/json"), binding.Json(User{}), binding.ErrorHandler, CreateUser) r.Post("/user/login", strict.ContentType("application/json"), binding.Json(User{}), binding.ErrorHandler, LoginUser) r.Post("/user/recover", strict.ContentType("application/json"), binding.Json(User{}), RecoverUser) r.Post("/user/reset/:id/:recovery", strict.ContentType("application/json"), binding.Json(User{}), ResetUserPassword) r.Get("/posts", ReadPosts) r.Get("/post/:slug", ReadPost) r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, ProtectedPage, CreatePost) r.Get("/post/:slug/publish", ProtectedPage, PublishPost) r.Get("/post/:slug/unpublish", ProtectedPage, UnpublishPost) r.Post("/post/:slug/edit", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, ProtectedPage, UpdatePost) r.Get("/post/:slug/delete", ProtectedPage, DeletePost) r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, ProtectedPage, CreatePost) r.Post("/post/search", strict.ContentType("application/json"), binding.Json(Search{}), binding.ErrorHandler, SearchPost) }) m.Router.NotFound(strict.MethodNotAllowed, func(res render.Render) { res.HTML(404, "404", nil) }) return m }