Skip to content

Marking and managing music tracks for review

whatdoineed2do edited this page Sep 18, 2021 · 5 revisions

I buy a lot of digital albums for which I don't know the majority of the tracks - I simply throw all of these into the server and play. Inevitably, I find many tracks that are not my taste and want to remove them from the server's library.

The server provides means to "mark" a track for attention, whether that's to delete, reencode, review etc and this is achieved via the REST call "http://server:3689/api/library/tracks/{id}?usermark=1" - it is not currently available via the official web ui but can be added the queue list or now playing modal via a simply patch below.

With the tracks marked, I have a cronjob that periodically finds all marked tracks and moves them to special 'review' directory in the server's library path - the same crontjob removes files from the 'review' directory that are older than 30days.

Accompanying the cronjob is a smartpl that allows us to easily see the tracks that have been marked for review (and subsequent delete).

The following assume that the library's music directory is /export/music

  • crontab script
#!/bin/bash

TRGT=/export/music/_delete/
DIRT=$(curl -s "http://localhost:3689/api/search?type=tracks&expression=usermark+>+0" | jq .tracks.items[].path | tr "\n" " ")

if [ -z $DIRT ]; then
    exit 0
fi

sudo touch $DIRT
sudo mv $DIRT $TRGT
find $TRGT -type f -mtime +30 -delete
  • smartpl
"_Delete / Review Tracks" {
  path starts with "/export/music/_delete/"
  order by time_modified desc
}
  • webui patch
diff --git a/web-src/src/components/ModalDialogQueueItem.vue b/web-src/src/components/ModalDialogQueueItem.vue
index 98238314..904f2821 100644
--- a/web-src/src/components/ModalDialogQueueItem.vue
+++ b/web-src/src/components/ModalDialogQueueItem.vue
@@ -62,6 +62,16 @@
                     <span v-if="item.bitrate"> | {{ item.bitrate }} Kb/s</span>
                   </span>
                 </p>
+                <p>
+                  <span class="heading">Usermark</span>
+                  <span class="title is-6">{{ this.usermark }}</span>
+                </p>
+                <div class="buttons">
+                  <a class="button is-small is-danger" @click="usermark_update(1)">Mark to delete</a>
+                  <a class="button is-small is-warning" @click="usermark_update(2)">Mark to rexcode</a>
+                  <a class="button is-small is-warning" @click="usermark_update(4)">Mark to review</a>
+                  <a v-if="this.usermark > 0" class="button is-small is-success" @click="usermark_update(0)">Mark reset</a>
+                </div>
               </div>
             </div>
             <footer class="card-footer">
@@ -93,6 +103,7 @@ export default {
 
   data () {
     return {
+      usermark: -1,
       spotify_track: {}
     }
   },
@@ -147,6 +158,20 @@ export default {
     open_spotify_album: function () {
       this.$emit('close')
       this.$router.push({ path: '/music/spotify/albums/' + this.spotify_track.album.id })
+    },
+
+    usermark_update (value) {
+      const newvalue = value === 0 ? 0 : value | this.usermark
+      webapi.library_track_set_usermark(this.track_id, newvalue).then(() => {
+        this.usermark = newvalue
+      })
+    }
+  },
+
+  computed: {
+    track_id () {
+      const item = this.$store.state.queue.items.find((elem) => elem.id === this.item.id)
+      return (item === undefined) ? -1 : item.track_id
     }
   },
 
@@ -160,6 +185,11 @@ export default {
         })
       } else {
         this.spotify_track = {}
+        webapi.library_track(this.track_id).then((response) => {
+          this.usermark = response.data.usermark
+        }).catch(() => {
+          this.usermark = -1
+        })
       }
     }
   }
diff --git a/web-src/src/webapi/index.js b/web-src/src/webapi/index.js
index d9dc344f..c0ed7e00 100644
--- a/web-src/src/webapi/index.js
+++ b/web-src/src/webapi/index.js
@@ -388,6 +388,13 @@ export default {
     })
   },
 
+  library_track_set_usermark (trackId, flag) {
+    return axios.put('/api/library/tracks/' + trackId, undefined, { params: { usermark: flag } }).then((response) => {
+      store.dispatch('add_notification', { text: flag === 0 ? 'Track Review Reset' : 'Track Review Updated', type: flag === 0 ? 'success' : 'info', timeout: 1500 })
+      return Promise.resolve(response)
+    })
+  },
+
   library_files (directory = undefined) {
     const filesParams = { directory: directory }
     return axios.get('./api/library/files', {

Clone this wiki locally