// Modified from https://github.com/arina999999997/elichika/blob/463b37a0d69dbe68fff7112fe87105cfb2e260d6/router/router.go package router import ( "honoka-chan/internal/constant" commonschema "honoka-chan/internal/schema/common" "honoka-chan/internal/session" "net/http" "os" "path/filepath" "strings" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" ) type HandlerInfo struct { Method string Path string Handlers []gin.HandlerFunc } type SpecialGroupSetup = func(*gin.RouterGroup) type GroupInfo struct { InitialHandlers []gin.HandlerFunc Handlers map[string]HandlerInfo SpecialSetups []SpecialGroupSetup } var ( groups = map[string]*GroupInfo{} templates []string ) func initGroup(g string) { _, exist := groups[g] if exist { return } groups[g] = &GroupInfo{ InitialHandlers: []gin.HandlerFunc{}, Handlers: map[string]HandlerInfo{}, SpecialSetups: []SpecialGroupSetup{}, } } func (g *GroupInfo) AddInitialHandler(handler gin.HandlerFunc) { g.InitialHandlers = append(g.InitialHandlers, handler) } func (g *GroupInfo) AddHandler(method, path string, handlers ...gin.HandlerFunc) { _, exist := g.Handlers[method+path] if exist { panic("Multiple handler for path and method: " + method + " " + path) } g.Handlers[method+path] = HandlerInfo{ Method: method, Path: path, Handlers: handlers, } } func (g *GroupInfo) AddSpecialSetup(specialGroupSetup SpecialGroupSetup) { g.SpecialSetups = append(g.SpecialSetups, specialGroupSetup) } func AddInitialHandler(group string, handler gin.HandlerFunc) { initGroup(group) groups[group].AddInitialHandler(handler) } func AddHandler(group, method, path string, handlers ...gin.HandlerFunc) { initGroup(group) groups[group].AddHandler(method, path, handlers...) } func AddSpecialSetup(group string, specialGroupSetup SpecialGroupSetup) { initGroup(group) groups[group].AddSpecialSetup(specialGroupSetup) } func AddTemplates(path string) { templates = append(templates, path) } func SifRouter(r *gin.Engine) { // Static r.Static("/static", "static") var files []string _ = filepath.Walk("static/templates", func(path string, info os.FileInfo, err error) error { if strings.HasSuffix(path, ".html") { files = append(files, path) } return nil }) r.LoadHTMLFiles(files...) // favicon r.StaticFile("/favicon.ico", "static/images/favicon.ico") // session store := cookie.NewStore([]byte("llsif")) r.Use(sessions.Sessions("llsif", store)) // manga r.GET("/manga", func(ctx *gin.Context) { ctx.HTML(http.StatusOK, "common/manga.html", gin.H{}) }) notFoundHandler := func(ctx *gin.Context) { ss := session.Attach(ctx) defer ss.Finalize() ss.Respond(commonschema.ErrorResp{ ResponseData: commonschema.ErrorData{ ErrorCode: constant.ErrorCodeUnknown, }, ReleaseInfo: []any{}, StatusCode: 600, }) } r.NoRoute(notFoundHandler) r.NoMethod(notFoundHandler) // router for groupPath, groupInfo := range groups { groupApi := r.Group(groupPath, groupInfo.InitialHandlers...) for _, handlerInfo := range groupInfo.Handlers { switch handlerInfo.Method { case "POST": groupApi.POST(handlerInfo.Path, handlerInfo.Handlers...) case "GET": groupApi.GET(handlerInfo.Path, handlerInfo.Handlers...) case "PUT": groupApi.PUT(handlerInfo.Path, handlerInfo.Handlers...) case "DELETE": groupApi.DELETE(handlerInfo.Path, handlerInfo.Handlers...) default: panic("Must be GET, POST, PUT or DELETE") } } for _, specialSetup := range groupInfo.SpecialSetups { specialSetup(groupApi) } } }