func NewApp(instance wcg.Server) *server.App { app := server.NewApp("_debug") app.GET("/routes.txt", wcg.AnonymousHandler(func(res *wcg.Response, req *wcg.Request) { res.Header().Set("Content-Type", "text/plain") res.WriteString(fmt.Sprintf("%v", instance.Routes())) res.End() })) app.GET("/env.txt", middleware.Gate("debugger"), wcg.AnonymousHandler(func(res *wcg.Response, req *wcg.Request) { res.Header().Set("Content-Type", "text/plain") res.WriteString("[Environment Variable]\n") for _, v := range os.Environ() { res.WriteString(fmt.Sprintf(" %v\n", v)) } res.WriteString("\n") res.WriteString("[Http Header]\n") for k, vlist := range req.HTTPRequest().Header { for _, v := range vlist { res.WriteString(fmt.Sprintf(" %s=%s\n", k, v)) } } })) app.GET("/config.json", middleware.Gate("debugger"), wcg.AnonymousHandler(func(res *wcg.Response, req *wcg.Request) { res.WriteJSON(map[string]interface{}{ "wcg.DefaultLogConfig": wcg.DefaultLogConfig, }) })) return app }
func setupPage(app *server.App) { var Page = app.Page() gate := server.NewPageInstanceHandler(middleware.Gate("family")) Page.GET("/", gate, page.Title("テレビ予約一覧")) Page.GET("/keywords.html", gate, page.Title("キーワード一覧")) Page.GET("/exclusions.html", gate, page.Title("除外ルール一覧")) Page.GET("/channels.html", gate, page.Title("チャンネル一覧")) Page.GET("/configs.html", gate, page.Title("設定")) }
func setupAPIIEPGExclusions(app *server.App) { var AsyncAPI = app.AsyncAPI() var API = app.API() API.GET("/iepg/exclusions/", middleware.EntityAll(IEPGExclusion.Query().Cache(_CacheAllIEPGExclusions))) exclusionTask := AsyncAPI.Define("/iepg/exclusions/task/") exclusionTask.Queue.Rate = "1/s" exclusionTask.Queue.MaxConcurrentRequests = "1" exclusionTask.OnTrigger(middleware.Gate("family")) exclusionTask.OnMonitor(middleware.Gate("family")) exclusionTask.OnProcess(server.AsyncTaskHandler( func(req *wcg.Request, t *models.AsyncAPITask) (*models.AsyncAPITaskProgress, error) { var list []*pt.IEPG records := recentRecordsQuery().MustExecute(req).Data.([]pt.IEPG) for i := range records { list = append(list, &records[i]) } if err := applyExclusions(req, list); err != nil { return nil, err } IEPG.PutMulti().Cache(_CacheAllIEPGExclusions).MustUpdate(req, list) return nil, nil }, )) API.POST("/iepg/exclusions/", middleware.Gate("family"), middleware.ParseForm(func(v *validators.FormValidator) { v.Field("cid").Required() v.Field("sid").Required() v.Field("weekday").Required() v.Field("title_text").Required() v.Field("title_text_type").Required() }), middleware.EntityPost(IEPGExclusion.Put().Cache(_CacheAllIEPGExclusions)), ) API.DELETE("/iepg/exclusions/:id.json", middleware.Gate("family"), middleware.EntityDelete(IEPGExclusion.Delete().Cache(_CacheAllIEPGExclusions), "id")) }
func setupAPIChannels(app *server.App) { var API = app.API() API.GET("/channels/", middleware.EntityAll(Channel.Query().Cache(_CacheAllChannels))) API.POST("/channels/", middleware.Gate("family"), middleware.ParseForm(func(v *validators.FormValidator) { v.Field("cid").Required() v.Field("sid").Required() v.Field("name").Required() v.Field("iepg_station_id").Required() }), middleware.EntityPost(Channel.Put().Cache(_CacheAllChannels))) API.DELETE("/channels/:id.json", middleware.Gate("family"), middleware.EntityDelete(Channel.Delete().Cache(_CacheAllChannels), "id")) }
func setupAPIConfigs(app *server.App) { var API = app.API() API.GET("/configs/:userid/messenger.json", middleware.Gate("family"), validateUserID, requireMessengeOptIn, server.Handler( func(req *wcg.Request) response.Response { _, one := MessengerNotification.Get().Key(req.Param("userid")).UseDefaultIfNil(true).Cache(true).MustOne(req) return response.NewJSONResponse(one) }, )) API.PUT("/configs/:userid/messenger.json", middleware.Gate("family"), validateUserID, requireMessengeOptIn, middleware.ParseForm(nil), middleware.EntityPutOrCreate(MessengerNotification.Put(), "userid")) API.POST("/configs/:userid/messenger/notify/", middleware.Gate("family"), validateUserID, requireMessengeOptIn, server.Handler( func(req *wcg.Request) response.Response { content, err := createDailyNotificationContent(req) if err != nil { return response.InternalServerError(req, err) } err = messenger.NewMessengerClient(req).SendText(content.title + "\n" + strings.Join(content.lines, "\n")) if err != nil { req.Logger.Errorf("Failed to notify a message to messenger: %v", err) } return response.NewJSONResponse(map[string]interface{}{ "ok": true, }) }, )) }
package handlers import ( "lib/server" "lib/server/middleware" ) var AdminGate = middleware.Gate("hplink.admin") var AdminGatePage = server.NewPageInstanceHandler(AdminGate)
func setupAPIIEPGKeywords(app *server.App) { var API = app.API() API.GET("/iepg/keywords/", middleware.EntityAll(IEPGKeyword.Query().Cache(_CacheAllIEPGKeywords))) API.POST("/iepg/keywords/", middleware.Gate("family"), middleware.ParseForm(func(v *validators.FormValidator) { v.Field("keyword").Required() v.Field("category").Required() v.IntField("scope").Required() }), middleware.EntityPost(IEPGKeyword.Put().Cache(_CacheAllIEPGKeywords))) API.DELETE("/iepg/keywords/:id.json", middleware.Gate("family"), middleware.EntityDelete(IEPGKeyword.Delete().Cache(_CacheAllIEPGKeywords), "id")) API.POST("/iepg/keywords/preview/", middleware.Gate("family"), middleware.ParseForm(func(v *validators.FormValidator) { v.Field("keyword").Required() v.IntField("scope").Required() }), server.Handler( func(req *wcg.Request) response.Response { list, err := crawlKeyword(req, &pt.IEPGKeyword{ Keyword: req.Form("keyword"), Scope: pt.ParseIEPGCrawlerScope(req.Form("scope")), }) if err != nil { return response.InternalServerError(req, err) } return response.NewJSONResponse(map[string]interface{}{ "hits": list, }) }, )) var AsyncAPI = app.AsyncAPI() keywordCrawlTask := AsyncAPI.Define("/iepg/keywords/task/") keywordCrawlTask.Queue.Rate = "1/s" keywordCrawlTask.Queue.MaxConcurrentRequests = "1" keywordCrawlTask.OnTrigger(middleware.Gate("family")) keywordCrawlTask.OnMonitor(middleware.Gate("family")) keywordCrawlTask.OnProcess(server.AsyncTaskHandler( func(req *wcg.Request, t *models.AsyncAPITask) (*models.AsyncAPITaskProgress, error) { data := IEPGKeyword.Query().Cache(_CacheAllIEPGKeywords).MustExecute(req).Data if data == nil { return nil, nil } var keywords = data.([]pt.IEPGKeyword) req.Logger.Infof("Crawling %d keywords", len(keywords)) for _, key := range keywords { list, err := crawlKeyword(req, &key) if err != nil { return nil, err } IEPG.PutMulti().Cache(_CacheAllIEPGKeywords).MustUpdate(req, list) } return nil, nil }, )) keywordCrawlTask.ScheduleCron( "Crawl IEPG keywords", "every 1 hours", ) }
func setupAPIIEPGRecords(app *server.App) { var API = app.API() API.GET("/iepg/records/", middleware.EntityQuery(recentRecordsQuery())) API.GET("/iepg/records/:id.json", middleware.EntityGet(IEPG.Get().Cache(true), "id")) API.POST("/iepg/records/", middleware.Gate("family"), middleware.ParseForm(func(v *validators.FormValidator) { v.Field("program_title").Required() v.Field("start_at").Required() v.Field("end_at").Required() v.Field("category").Required() v.Field("cid").Required() v.Field("sid").Required() }), middleware.EntityPost( IEPG.Put(). SetField("Source", pt.IEPGSourceUser). Cache(_CacheRecentIEPGRecords), ), ) API.PUT("/iepg/records/:id.json", middleware.Gate("family"), middleware.ParseForm(func(v *validators.FormValidator) { v.Field("program_title").Required() v.Field("start_at").Required() v.Field("end_at").Required() v.Field("category").Required() v.Field("cid").Required() v.Field("sid").Required() }), requireIEPGOwner("id"), middleware.EntityPut( IEPG.Put(). SetField("Source", pt.IEPGSourceUser). Cache(_CacheRecentIEPGRecords), "id", ), ) API.POST("/iepg/records/:id/notification.json", middleware.Gate("family"), getIEPG("id", func(req *wcg.Request, iepg *pt.IEPG) response.Response { var msg string var configs []pt.MessengerNotification var err error t := req.Form("type") switch t { case "start": msg = fmt.Sprintf("[%s] 録画を開始しました。", iepg.ProgramTitle) configs, err = getMessengerNotificationOptInUsers(req, "OnStart") break case "end": msg = fmt.Sprintf("[%s] 録画を終了しました。", iepg.ProgramTitle) configs, err = getMessengerNotificationOptInUsers(req, "OnEnd") break default: return response.BadRequest(req, fmt.Errorf("`type` should be specified and must be one of 'start', 'end' (actual=%s)", t)) } if err != nil { return response.InternalServerError(req, err) } if req.Form("message") != "" { msg = fmt.Sprintf("%s\n%s", msg, req.Form("message")) } for _, cfg := range configs { client := messenger.NewMessengerClient(req) client.UserID = cfg.UserID err = client.SendText(msg) if err != nil { req.Logger.Warnf("Failed to send a messenger message: %v", err) } } return response.NewJSONResponse(true) }), ) API.DELETE("/iepg/records/:id.json", middleware.Gate("family"), requireIEPGOwner("id"), middleware.EntityDelete(IEPG.Delete().Cache(_CacheRecentIEPGRecords), "id")) // optin or optout for auto collected IEPGs API.PUT("/iepg/records/:id/opt-in/", middleware.Gate("family"), getIEPG("id", func(req *wcg.Request, iepg *pt.IEPG) response.Response { err := iepg.SetOptIn(req.Form("opt_in") == "1" || req.Form("opt_in") == "true") if err != nil { return response.BadRequest(req, fmt.Errorf("Could not configure opt-in field on the user created IEPG")) } IEPG.Put().Key(req.Param("id")).Cache(_CacheRecentIEPGRecords).MustUpdate(req, iepg) return response.NewJSONResponse(map[string]bool{ "ok": true, "opt_in": iepg.OptIn, "opt_out": iepg.OptOut, }) }), ) }