For playlist, remove TIDAL songs and redownload PL, the songs will be removed in the mirror image dl folder

This commit is contained in:
Richard Curzon
2022-04-16 09:09:12 -04:00
parent bb5be5e5fb
commit 2ebf80869c
4 changed files with 52 additions and 6 deletions
+2
View File
@@ -173,3 +173,5 @@ TIDALDL-PY/exe/resource
TIDALDL-PY/exe/tidal_dl_win.tar.gz
.github/workflows/continuous-integration-workflow copy.yml
TIDALDL-PY/tidal-gui.spec
.history/
.gitignore
+16
View File
@@ -140,3 +140,19 @@ pip3 install -r requirements.txt --user
python3 setup.py install
```
## Fork changes - Scenario and comments:
I would be content with TIDAL download feature, to give me off-line music on my device. I find playlists good for that.
But playlist changes are not done well. If I add 1 song to a 100 song playlist, the only way I can get it on my phone is: -
delete all 100 songs - download 101 songs. It's the time, the wear and tear on my device sd card... nope... don't like it at all.
But I see tidal-dl can create a "mirror image" of that playlist. And has some smarts: if I add a song to the playlist, download again, it will ONLY download that song. Cool. But - what if I delete a song?
Background: I use PC MediaMonkey for my non-TIDAL mp3s... it will download a music folder to my device... with MediaMonkey for Android and my home Wifi. Of course, MM can also see tidal-dl that "mirror image" playlist. And crucially: if there are adds/deletes, MM makes just the changes on my phone. Other files are untouched. Deletes are done too, smart!
But... now tidal-dl is the weak link. If I add 1 file to a playlist, and delete 1 file... it gives me the add... but it doesn't handle the delete. And the "mirror image" is not a mirror image any more.
So this is to fill that gap in my scenario. But the effect seems useful for other use-cases. SUMMARY: Suppose you download a playlist, on top of a previous download. If files are deleted on the playlist, they will also be deleted in the mirror image.
Also: some improved handling of the "onlyM4A" flag. If files have been renamed from mp4 to m4a, the SKIP download logic wasn't working. Now it's handled for the simple case at least.
+20 -1
View File
@@ -113,12 +113,31 @@ def __playlist__(conf, obj):
Printf.err(msg)
return
dictNewFiles = {}
for index, item in enumerate(tracks):
mag, album = API.getAlbum(item.album.id)
item.trackNumberOnPlaylist = index + 1
downloadTrack(item, album, obj)
downloadTrack(item, album, obj, dictNewFiles=dictNewFiles)
if conf.saveCovers and not conf.usePlaylistFolder:
__downloadCover__(conf, album)
if len(dictNewFiles) > 0:
targetDir = aigpy.path.getDirName(dictNewFiles[list(dictNewFiles.keys())[0]]) # trick to get the target directory
resFiles = aigpy.path.getFiles(targetDir)
killFiles = []
errFiles = []
for fname in resFiles:
if not os.path.basename(fname) in dictNewFiles:
try:
os.remove(fname)
killFiles.append(fname)
except:
errFiles.append(fname)
Printf.info("Orphan files deleted:\n" + "\n".join(killFiles))
Printf.info("Orphan files failed to delete (read-only?):\n" + "\n".join(errFiles))
for item in videos:
downloadVideo(item, None)
+14 -5
View File
@@ -341,8 +341,8 @@ def setCurVideoQuality(text):
break
Settings.save(CONF)
def skip(path, url):
if CONF.checkExist and isNeedDownload(path, url) is False:
def skip(finalpath, url):
if CONF.checkExist and isNeedDownload(finalpath, url) is False:
return True
return False
@@ -353,7 +353,7 @@ def convert(srcPath, stream):
return srcPath
def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, partSize=1048576):
def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, partSize=1048576, dictNewFiles=None):
try:
msg, stream = API.getStreamUrl(track.id, CONF.audioQuality)
if not aigpy.string.isNull(msg) or stream is None:
@@ -365,8 +365,16 @@ def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, pa
userProgress.updateStream(stream)
path = getTrackPath(CONF, track, stream, album, playlist)
if CONF.onlyM4a:
finalpath = path.replace(".mp4", ".m4a")
else:
finalpath = path
if not dictNewFiles is None:
dictNewFiles[os.path.basename(finalpath)] = finalpath # preserve full path to be used by caller
# check exist
if skip(path, stream.url):
if skip(finalpath, stream.url):
Printf.success(aigpy.path.getFileName(path) + " (skip:already exists!)")
return True, ""
@@ -383,7 +391,8 @@ def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, pa
# encrypted -> decrypt and remove encrypted file
encrypted(stream, path + '.part', path)
# convert
# convert to M4a if configured
# note from here to end, path will be = finalpath
path = convert(path, stream)
# contributors