Download server/static/static.go from lin7zhi/OpenList: direct link, hf CLI and curl.
- Browser
- Download file 7.42 kB
-
https://huggingface.co/spaces/lin7zhi/OpenList/resolve/main/server/static/static.go
- Command line
-
hf download hf://spaces/lin7zhi/OpenList/server/static/static.go
-
curl -L -o static.go https://huggingface.co/spaces/lin7zhi/OpenList/resolve/main/server/static/static.go
7.42 kB
| package static | |
| import ( | |
| "encoding/json" | |
| "errors" | |
| "fmt" | |
| "io" | |
| "io/fs" | |
| "net/http" | |
| "os" | |
| "strings" | |
| "github.com/OpenListTeam/OpenList/v4/drivers/base" | |
| "github.com/OpenListTeam/OpenList/v4/internal/conf" | |
| "github.com/OpenListTeam/OpenList/v4/internal/setting" | |
| "github.com/OpenListTeam/OpenList/v4/pkg/utils" | |
| "github.com/OpenListTeam/OpenList/v4/public" | |
| "github.com/gin-gonic/gin" | |
| ) | |
| type ManifestIcon struct { | |
| Src string `json:"src"` | |
| Sizes string `json:"sizes"` | |
| Type string `json:"type"` | |
| } | |
| type Manifest struct { | |
| Display string `json:"display"` | |
| Scope string `json:"scope"` | |
| StartURL string `json:"start_url"` | |
| Name string `json:"name"` | |
| Icons []ManifestIcon `json:"icons"` | |
| } | |
| var static fs.FS | |
| func initStatic() { | |
| utils.Log.Debug("Initializing static file system...") | |
| if conf.Conf.DistDir == "" { | |
| dist, err := fs.Sub(public.Public, "dist") | |
| if err != nil { | |
| utils.Log.Fatalf("failed to read dist dir: %v", err) | |
| } | |
| static = dist | |
| utils.Log.Debug("Using embedded dist directory") | |
| return | |
| } | |
| static = os.DirFS(conf.Conf.DistDir) | |
| utils.Log.Infof("Using custom dist directory: %s", conf.Conf.DistDir) | |
| } | |
| func replaceStrings(content string, replacements map[string]string) string { | |
| for old, new := range replacements { | |
| content = strings.Replace(content, old, new, 1) | |
| } | |
| return content | |
| } | |
| func initIndex(siteConfig SiteConfig) { | |
| utils.Log.Debug("Initializing index.html...") | |
| // dist_dir is empty and cdn is not empty, and web_version is empty or beta or dev or rolling | |
| if conf.Conf.DistDir == "" && conf.Conf.Cdn != "" && (conf.WebVersion == "" || conf.WebVersion == "beta" || conf.WebVersion == "dev" || conf.WebVersion == "rolling") { | |
| utils.Log.Infof("Fetching index.html from CDN: %s/index.html...", siteConfig.Cdn) | |
| resp, err := base.RestyClient.R(). | |
| SetHeader("Accept", "text/html"). | |
| Get(fmt.Sprintf("%s/index.html", siteConfig.Cdn)) | |
| if err != nil { | |
| utils.Log.Fatalf("failed to fetch index.html from CDN: %v", err) | |
| } | |
| if resp.StatusCode() != http.StatusOK { | |
| utils.Log.Fatalf("failed to fetch index.html from CDN, status code: %d", resp.StatusCode()) | |
| } | |
| conf.RawIndexHtml = string(resp.Body()) | |
| utils.Log.Info("Successfully fetched index.html from CDN") | |
| } else { | |
| utils.Log.Debug("Reading index.html from static files system...") | |
| indexFile, err := static.Open("index.html") | |
| if err != nil { | |
| if errors.Is(err, fs.ErrNotExist) { | |
| utils.Log.Fatalf("index.html not exist, you may forget to put dist of frontend to public/dist") | |
| } | |
| utils.Log.Fatalf("failed to read index.html: %v", err) | |
| } | |
| defer func() { | |
| _ = indexFile.Close() | |
| }() | |
| index, err := io.ReadAll(indexFile) | |
| if err != nil { | |
| utils.Log.Fatalf("failed to read dist/index.html") | |
| } | |
| conf.RawIndexHtml = string(index) | |
| utils.Log.Debug("Successfully read index.html from static files system") | |
| } | |
| utils.Log.Debug("Replacing placeholders in index.html...") | |
| // Construct the correct manifest path based on basePath | |
| manifestPath := "/manifest.json" | |
| if siteConfig.BasePath != "/" { | |
| manifestPath = siteConfig.BasePath + "/manifest.json" | |
| } | |
| replaceMap := map[string]string{ | |
| "cdn: undefined": fmt.Sprintf("cdn: '%s'", siteConfig.Cdn), | |
| "base_path: undefined": fmt.Sprintf("base_path: '%s'", siteConfig.BasePath), | |
| `href="/manifest.json"`: fmt.Sprintf(`href="%s"`, manifestPath), | |
| } | |
| conf.RawIndexHtml = replaceStrings(conf.RawIndexHtml, replaceMap) | |
| UpdateIndex() | |
| } | |
| func UpdateIndex() { | |
| utils.Log.Debug("Updating index.html with settings...") | |
| favicon := setting.GetStr(conf.Favicon) | |
| logo := strings.Split(setting.GetStr(conf.Logo), "\n")[0] | |
| title := setting.GetStr(conf.SiteTitle) | |
| customizeHead := setting.GetStr(conf.CustomizeHead) | |
| customizeBody := setting.GetStr(conf.CustomizeBody) | |
| mainColor := setting.GetStr(conf.MainColor) | |
| utils.Log.Debug("Applying replacements for default pages...") | |
| replaceMap1 := map[string]string{ | |
| "https://res.oplist.org/logo/logo.svg": favicon, | |
| "https://res.oplist.org/logo/logo.png": logo, | |
| "Loading...": title, | |
| "main_color: undefined": fmt.Sprintf("main_color: '%s'", mainColor), | |
| } | |
| conf.ManageHtml = replaceStrings(conf.RawIndexHtml, replaceMap1) | |
| utils.Log.Debug("Applying replacements for manage pages...") | |
| replaceMap2 := map[string]string{ | |
| "<!-- customize head -->": customizeHead, | |
| "<!-- customize body -->": customizeBody, | |
| } | |
| conf.IndexHtml = replaceStrings(conf.ManageHtml, replaceMap2) | |
| utils.Log.Debug("Index.html update completed") | |
| } | |
| func ManifestJSON(c *gin.Context) { | |
| // Get site configuration to ensure consistent base path handling | |
| siteConfig := getSiteConfig() | |
| // Get site title from settings | |
| siteTitle := setting.GetStr(conf.SiteTitle) | |
| // Get logo from settings, use the first line (light theme logo) | |
| logoSetting := setting.GetStr(conf.Logo) | |
| logoUrl := strings.Split(logoSetting, "\n")[0] | |
| // Use base path from site config for consistency | |
| basePath := siteConfig.BasePath | |
| // Determine scope and start_url | |
| // PWA scope and start_url should always point to our application's base path | |
| // regardless of whether static resources come from CDN or local server | |
| scope := basePath | |
| startURL := basePath | |
| manifest := Manifest{ | |
| Display: "standalone", | |
| Scope: scope, | |
| StartURL: startURL, | |
| Name: siteTitle, | |
| Icons: []ManifestIcon{ | |
| { | |
| Src: logoUrl, | |
| Sizes: "512x512", | |
| Type: "image/png", | |
| }, | |
| }, | |
| } | |
| c.Header("Content-Type", "application/json") | |
| c.Header("Cache-Control", "public, max-age=3600") // cache for 1 hour | |
| if err := json.NewEncoder(c.Writer).Encode(manifest); err != nil { | |
| utils.Log.Errorf("Failed to encode manifest.json: %v", err) | |
| c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate manifest"}) | |
| return | |
| } | |
| } | |
| func Static(r *gin.RouterGroup, noRoute func(handlers ...gin.HandlerFunc)) { | |
| utils.Log.Debug("Setting up static routes...") | |
| siteConfig := getSiteConfig() | |
| initStatic() | |
| initIndex(siteConfig) | |
| folders := []string{"assets", "images", "streamer", "static"} | |
| if conf.Conf.Cdn == "" { | |
| utils.Log.Debug("Setting up static file serving...") | |
| r.Use(func(c *gin.Context) { | |
| for _, folder := range folders { | |
| if strings.HasPrefix(c.Request.RequestURI, fmt.Sprintf("/%s/", folder)) { | |
| c.Header("Cache-Control", "public, max-age=15552000") | |
| } | |
| } | |
| }) | |
| for _, folder := range folders { | |
| sub, err := fs.Sub(static, folder) | |
| if err != nil { | |
| utils.Log.Fatalf("can't find folder: %s", folder) | |
| } | |
| utils.Log.Debugf("Setting up route for folder: %s", folder) | |
| r.StaticFS(fmt.Sprintf("/%s/", folder), http.FS(sub)) | |
| } | |
| } else { | |
| // Ensure static file redirected to CDN | |
| for _, folder := range folders { | |
| r.GET(fmt.Sprintf("/%s/*filepath", folder), func(c *gin.Context) { | |
| filepath := c.Param("filepath") | |
| c.Redirect(http.StatusFound, fmt.Sprintf("%s/%s%s", siteConfig.Cdn, folder, filepath)) | |
| }) | |
| } | |
| } | |
| utils.Log.Debug("Setting up catch-all route...") | |
| noRoute(func(c *gin.Context) { | |
| if c.Request.Method != "GET" && c.Request.Method != "POST" { | |
| c.Status(405) | |
| return | |
| } | |
| c.Header("Content-Type", "text/html") | |
| c.Status(200) | |
| if strings.HasPrefix(c.Request.URL.Path, "/@manage") { | |
| _, _ = c.Writer.WriteString(conf.ManageHtml) | |
| } else { | |
| _, _ = c.Writer.WriteString(conf.IndexHtml) | |
| } | |
| c.Writer.Flush() | |
| c.Writer.WriteHeaderNow() | |
| }) | |
| } | |