summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorHeinrich 'Henrik' Langos <gumbo2000@noreply@mills.io>2023-01-16 11:33:12 +0000
committerJames Mills <james@mills.io>2023-01-16 11:33:12 +0000
commit19a1141af3f1aa52c706e402af734797d5d929ff (patch)
tree6e50140550f92fe320b4d389d93d1b75b132fd24 /app
parent9952cc533ac093a9b8acf964642e42ae8962f768 (diff)
preserve-video-filename (#49)
This should fix issue #40 I have not made the `allowed_characters` configurable yet nor the `replacement_character`. Mostly because I couldn't decide if I should define those "globally" on a server basis, or on the library nodes. Feel free to modify, extend, rip apart. 😁 Reviewed-on: https://git.mills.io/prologic/tube/pulls/49 Co-authored-by: Heinrich 'Henrik' Langos <gumbo2000@noreply@mills.io> Co-committed-by: Heinrich 'Henrik' Langos <gumbo2000@noreply@mills.io>
Diffstat (limited to 'app')
-rw-r--r--app/app.go58
-rw-r--r--app/config.go32
2 files changed, 70 insertions, 20 deletions
diff --git a/app/app.go b/app/app.go
index f2d729a..9d0828b 100644
--- a/app/app.go
+++ b/app/app.go
@@ -21,6 +21,7 @@ import (
"git.mills.io/prologic/tube/templates"
"git.mills.io/prologic/tube/utils"
+ "github.com/cyphar/filepath-securejoin"
"github.com/dustin/go-humanize"
"github.com/fsnotify/fsnotify"
"github.com/gorilla/handlers"
@@ -148,8 +149,9 @@ func (a *App) Run() error {
for _, pc := range a.Config.Library {
pc.Path = filepath.Clean(pc.Path)
p := &media.Path{
- Path: pc.Path,
- Prefix: pc.Prefix,
+ Path: pc.Path,
+ Prefix: pc.Prefix,
+ PreserveUploadFilename: pc.PreserveUploadFilename,
}
err := a.Library.AddPath(p)
if err != nil {
@@ -215,6 +217,11 @@ func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) {
}
}
+func filenameWithoutExtension(path string) (stem string) {
+ var basename string = filepath.Base(path)
+ return basename[0:len(basename)-len(filepath.Ext(basename))]
+}
+
// HTTP handler for /upload
func (a *App) uploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
@@ -278,10 +285,49 @@ func (a *App) uploadHandler(w http.ResponseWriter, r *http.Request) {
return
}
- vf := filepath.Join(
- a.Library.Paths[targetLibraryPath].Path,
- fmt.Sprintf("%s.mp4", shortuuid.New()),
- )
+ // Here we set the final filename for the video file after transcoding.
+ var vf string
+ if a.Config.Server.PreserveUploadFilename ||
+ a.Library.Paths[targetLibraryPath].PreserveUploadFilename {
+ vf, err = securejoin.SecureJoin(
+ a.Library.Paths[targetLibraryPath].Path,
+ fmt.Sprintf("%s.mp4", filenameWithoutExtension(handler.Filename)),
+ )
+ } else {
+ vf, err = securejoin.SecureJoin(
+ a.Library.Paths[targetLibraryPath].Path,
+ fmt.Sprintf("%s.mp4", shortuuid.New()),
+ )
+ }
+ if err != nil {
+ err := fmt.Errorf("error creating file name in target library: %w", err)
+ log.Error(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ // If the (sanitized) original filename collides with an existing file,
+ // we try to add a shortuuid() to it until we find one that doesn't exist.
+ for _, err := os.Stat(vf) ; ! os.IsNotExist(err) ; _, err = os.Stat(vf) {
+ if err != nil {
+ log.Error(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ log.Warn("File '"+ vf + "' already exists.");
+ vf, err = securejoin.SecureJoin(
+ a.Library.Paths[targetLibraryPath].Path,
+ fmt.Sprintf("%s_%s.mp4", filenameWithoutExtension(vf), shortuuid.New()),
+ )
+ if err != nil {
+ err := fmt.Errorf("error creating file name in target library: %w", err)
+ log.Error(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ log.Warn("Using filename '" + vf + "' instead.");
+ }
+
+
thumbFn1 := fmt.Sprintf("%s.jpg", strings.TrimSuffix(tf.Name(), filepath.Ext(tf.Name())))
thumbFn2 := fmt.Sprintf("%s.jpg", strings.TrimSuffix(vf, filepath.Ext(vf)))
diff --git a/app/config.go b/app/config.go
index 2b11688..7d886c0 100644
--- a/app/config.go
+++ b/app/config.go
@@ -17,17 +17,19 @@ type Config struct {
// PathConfig settings for media library path.
type PathConfig struct {
- Path string `json:"path"`
- Prefix string `json:"prefix"`
+ Path string `json:"path"`
+ Prefix string `json:"prefix"`
+ PreserveUploadFilename bool `json:"preserve_upload_filename,omitempty"`
}
// ServerConfig settings for App Server.
type ServerConfig struct {
- Host string `json:"host"`
- Port int `json:"port"`
- StorePath string `json:"store_path"`
- UploadPath string `json:"upload_path"`
- MaxUploadSize int64 `json:"max_upload_size"`
+ Host string `json:"host"`
+ Port int `json:"port"`
+ StorePath string `json:"store_path"`
+ UploadPath string `json:"upload_path"`
+ PreserveUploadFilename bool `json:"preserve_upload_filename,omitempty"`
+ MaxUploadSize int64 `json:"max_upload_size"`
}
// ThumbnailerConfig settings for Transcoder
@@ -68,16 +70,18 @@ func DefaultConfig() *Config {
return &Config{
Library: []*PathConfig{
&PathConfig{
- Path: "videos",
- Prefix: "",
+ Path: "videos",
+ Prefix: "",
+ PreserveUploadFilename: false,
},
},
Server: &ServerConfig{
- Host: "0.0.0.0",
- Port: 8000,
- StorePath: "tube.db",
- UploadPath: "uploads",
- MaxUploadSize: 104857600,
+ Host: "0.0.0.0",
+ Port: 8000,
+ StorePath: "tube.db",
+ UploadPath: "uploads",
+ PreserveUploadFilename: false,
+ MaxUploadSize: 104857600,
},
Thumbnailer: &ThumbnailerConfig{
Timeout: 60,