diff --git a/pkg/api/server.go b/pkg/api/server.go index 9d3a038c3..dccf25144 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -251,6 +251,24 @@ func Start() { }) startThumbCache() + + // Serve static folders + customServedFolders := config.GetCustomServedFolders() + if customServedFolders != nil { + r.HandleFunc("/custom/*", func(w http.ResponseWriter, r *http.Request) { + r.URL.Path = strings.Replace(r.URL.Path, "/custom", "", 1) + + // map the path to the applicable filesystem location + var dir string + r.URL.Path, dir = customServedFolders.GetFilesystemLocation(r.URL.Path) + if dir != "" { + http.FileServer(http.Dir(dir)).ServeHTTP(w, r) + } else { + http.NotFound(w, r) + } + }) + } + // Serve the web app r.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) { ext := path.Ext(r.URL.Path) diff --git a/pkg/manager/config/config.go b/pkg/manager/config/config.go index f21493329..e332dd40c 100644 --- a/pkg/manager/config/config.go +++ b/pkg/manager/config/config.go @@ -47,6 +47,10 @@ const ScraperUserAgent = "scraper_user_agent" // i18n const Language = "language" +// served directories +// this should be manually configured only +const CustomServedFolders = "custom_served_folders" + // Interface options const SoundOnPreview = "sound_on_preview" const WallShowTitle = "wall_show_title" @@ -231,6 +235,12 @@ func GetMaxSessionAge() int { return viper.GetInt(MaxSessionAge) } +// GetCustomServedFolders gets the map of custom paths to their applicable +// filesystem locations +func GetCustomServedFolders() URLMap { + return viper.GetStringMapString(CustomServedFolders) +} + // Interface options func GetSoundOnPreview() bool { viper.SetDefault(SoundOnPreview, true) diff --git a/pkg/manager/config/urlmap.go b/pkg/manager/config/urlmap.go new file mode 100644 index 000000000..d7a26a42f --- /dev/null +++ b/pkg/manager/config/urlmap.go @@ -0,0 +1,21 @@ +package config + +import "strings" + +type URLMap map[string]string + +// GetFilesystemLocation returns the adjusted URL and the filesystem location +func (m URLMap) GetFilesystemLocation(url string) (string, string) { + root := m["/"] + for k, v := range m { + if k != "/" && strings.HasPrefix(url, k) { + return strings.TrimPrefix(url, k), v + } + } + + if root != "" { + return url, root + } + + return url, "" +} diff --git a/pkg/manager/config/urlmap_test.go b/pkg/manager/config/urlmap_test.go new file mode 100644 index 000000000..cdccf2254 --- /dev/null +++ b/pkg/manager/config/urlmap_test.go @@ -0,0 +1,28 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestURLMapGetFilesystemLocation(t *testing.T) { + // create the URLMap + urlMap := make(URLMap) + urlMap["/"] = "root" + urlMap["/foo"] = "bar" + + url, fs := urlMap.GetFilesystemLocation("/foo/bar") + assert.Equal(t, "/bar", url) + assert.Equal(t, urlMap["/foo"], fs) + + url, fs = urlMap.GetFilesystemLocation("/bar") + assert.Equal(t, "/bar", url) + assert.Equal(t, urlMap["/"], fs) + + delete(urlMap, "/") + + url, fs = urlMap.GetFilesystemLocation("/bar") + assert.Equal(t, "/bar", url) + assert.Equal(t, "", fs) +} diff --git a/ui/v2.5/src/components/Changelog/versions/v030.tsx b/ui/v2.5/src/components/Changelog/versions/v030.tsx index 1f3476fea..3ba7ec081 100644 --- a/ui/v2.5/src/components/Changelog/versions/v030.tsx +++ b/ui/v2.5/src/components/Changelog/versions/v030.tsx @@ -3,6 +3,7 @@ import ReactMarkdown from "react-markdown"; const markup = ` ### ✨ New Features +* Add support for custom served folders. * Add support for parent/child studios. ### 🎨 Improvements