diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2023-05-21 13:45:15 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2023-05-21 13:46:58 +0200 |
| commit | cef46aa5f5b9cac5c43bd842ed64580357718e86 (patch) | |
| tree | 233d183648c331ef7676dae1565e55962f29af6b | |
| parent | 6bd47783325a2c1833f8017abc6aa459c4d82538 (diff) | |
| download | WRMS-cef46aa5f5b9cac5c43bd842ed64580357718e86.tar.gz WRMS-cef46aa5f5b9cac5c43bd842ed64580357718e86.zip | |
implement the upload backend
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | TODO | 3 | ||||
| -rw-r--r-- | player.go | 4 | ||||
| -rw-r--r-- | upload.go | 83 | ||||
| -rw-r--r-- | web/client.html | 19 |
5 files changed, 109 insertions, 1 deletions
@@ -1 +1,2 @@ wrms +uploads @@ -6,7 +6,10 @@ ## Backends +- [ ] Split paralyze search - [X] Implement local storage backend + - [X] Implement upload + - [ ] Remove uploaded songs after were played - [X] Fix youtube search ## Configuration @@ -28,7 +28,9 @@ func NewPlayer(wrms *Wrms, backends []string) Player { case "dummy": b = &DummyBackend{} case "local": - b = NewLocalBackend(wrms.Config.localMusicDir) + b = NewLocalBackend(wrms.Config.LocalMusicDir) + case "upload": + b = NewUploadBackend(wrms.Config.UploadDir) default: llog.Error("Not supported backend %s", backend) } diff --git a/upload.go b/upload.go new file mode 100644 index 0000000..d7bbd20 --- /dev/null +++ b/upload.go @@ -0,0 +1,83 @@ +package main + +import ( + "bytes" + "fmt" + "net/http" + "os" + "path" + // "path/filepath" + "io/ioutil" + + "github.com/dhowden/tag" + "muhq.space/go/wrms/llog" +) + +type UploadBackend struct { + uploadDir string +} + +func NewUploadBackend(uploadDir string) *UploadBackend { + b := UploadBackend{uploadDir: uploadDir} + + dirInfo, err := os.Stat(uploadDir) + + if os.IsNotExist(err) { + os.Mkdir(uploadDir, 0750) + } else if !dirInfo.IsDir() { + llog.Fatal("upload directory %s exists and is not a directory", uploadDir) + } + + b.setupUploadRoute() + + return &b +} + +func (b *UploadBackend) upload(w http.ResponseWriter, r *http.Request) { + data, err := ioutil.ReadAll(r.Body) + if err != nil { + llog.Warning("Failed to read request body: %s", string(data)) + http.Error(w, "Failed to read request body", http.StatusInternalServerError) + return + } + + fileName := r.URL.Query().Get("song") + + f, err := os.Create(path.Join(b.uploadDir, fileName)) + if err != nil { + llog.Fatal("Failed to create uploaded song on disk") + } + + _, err = f.Write(data) + if err != nil { + llog.Fatal("Failed to write uploaded song on disk") + } + + f.Close() + + var song Song + dataReader := bytes.NewReader(data) + m, err := tag.ReadFrom(dataReader) + if err != nil { + llog.Warning("error reading tags from %s: %v", fileName, err) + song = NewSong(fileName, "Unknown", "upload", fileName) + } else { + song = NewSong(m.Title(), m.Artist(), "upload", fileName) + } + + wrms.AddSong(song) + wrms.Broadcast(Event{"add", []Song{song}}) + fmt.Fprintf(w, "Added uploaded song %s", string(fileName)) +} + +func (b *UploadBackend) setupUploadRoute() { + http.HandleFunc("/upload", b.upload) +} + +func (b *UploadBackend) Play(song *Song, player *Player) { + player.PlayUri("file://" + path.Join(b.uploadDir, song.Uri)) +} + +func (b *UploadBackend) Search(keyword string) []Song { + return nil +} diff --git a/web/client.html b/web/client.html index 87ca51a..a330c00 100644 --- a/web/client.html +++ b/web/client.html @@ -237,6 +237,18 @@ return false; } + {{if .HasUpload}} + function submitUpload() { + const form = new FormData(document.getElementById("uploadForm")); + const file = form.get("song"); + const params = new URLSearchParams(); + params.append("song", file.name); + const song = params.toString(); + new HttpClient().post("/upload?" + song, file, console.log); + return false; + } + {{end}} + function addSong(song) { new HttpClient().post("/add", JSON.stringify(song), console.log); } @@ -282,6 +294,13 @@ <input id="searchInput" name="pattern" type="text" value="Title/Artist/Album/..."> <button id="searchButton">Search</button> </form> + + {{if .HasUpload}} + <form id="uploadForm" onsubmit="return submitUpload()"> + <input id="uploadInput" name="song" type="file"> + <button id="uploadButton", type="submit">Upload</button> + </form> + {{end}} </div> <div id="searchResultsOverlay" style="display: none;"> |
