diff --git a/graphql/schema/types/config.graphql b/graphql/schema/types/config.graphql index b0b8898b2..87bf3ae54 100644 --- a/graphql/schema/types/config.graphql +++ b/graphql/schema/types/config.graphql @@ -414,7 +414,7 @@ input ConfigInterfaceInput { "True if we should send notifications to the desktop" notificationsEnabled: Boolean - "True if 'Open Org File' in scene details is shown" + "True if 'Open in Ext. Player' button in scene details is shown" showOpenExternal: Boolean } @@ -487,7 +487,7 @@ type ConfigInterfaceResult { "Whether to use Stash Hosted Funscript" useStashHostedFunscript: Boolean - "Show 'Open Org File' in scene details" + "Show 'Open in Ext. Player' button in scene details" showOpenExternal: Boolean } diff --git a/internal/api/routes_scene.go b/internal/api/routes_scene.go index 8a5c4f023..a3fa766aa 100644 --- a/internal/api/routes_scene.go +++ b/internal/api/routes_scene.go @@ -5,6 +5,7 @@ import ( "context" "errors" "net/http" + "net/url" "os" "strconv" "strings" @@ -104,8 +105,9 @@ func (rs sceneRoutes) StreamDirect(w http.ResponseWriter, r *http.Request) { func (rs sceneRoutes) StreamOrgDirect(w http.ResponseWriter, r *http.Request) { scene := r.Context().Value(sceneKey).(*models.Scene) // check if it's funscript - aStr := strings.Split(chi.URLParam(r, "streamOrgFile"), ".") - // aStr := strings.Split(r.RequestURI, ".") + streamOrgFile := chi.URLParam(r, "streamOrgFile") + aStr := strings.Split(streamOrgFile, ".") + // aStr usually is the primary file, but can be .srt or other file format. if strings.ToLower(aStr[len(aStr)-1]) == "funscript" { // it's a funscript request rs.Funscript(w, r) @@ -113,20 +115,29 @@ func (rs sceneRoutes) StreamOrgDirect(w http.ResponseWriter, r *http.Request) { } // return 404 if the scene does not have a primary file - f := scene.Files.Primary() - if f == nil { + primaryFile := scene.Files.Primary() + if primaryFile == nil { w.WriteHeader(http.StatusNotFound) if _, err := w.Write([]byte("Primary file not found for streaming original file.")); err != nil { logger.Warnf("[scene] error getting primary file for streaming original: $v", err) } return } - // Also return 404 if the actual video file cannot be found - if _, err := os.Stat(f.Path); errors.Is(err, os.ErrNotExist) { + pathBase := primaryFile.Path[:len(primaryFile.Path)-len(primaryFile.Basename)] // remove filename from the path. + f, err := url.PathUnescape(streamOrgFile) + if err != nil { w.WriteHeader(http.StatusNotFound) return } - http.ServeFile(w, r, f.Path) + f = pathBase + f + // Also return 404 if the actual file cannot be found + if _, err := os.Stat(f); errors.Is(err, os.ErrNotExist) { + w.WriteHeader(http.StatusNotFound) + return + } + + utils.ServeStaticFile(w, r, f) + // http.ServeFile(w, r, f.Path) } func (rs sceneRoutes) StreamMp4(w http.ResponseWriter, r *http.Request) {