Use filelocks on unix systems

This commit is contained in:
7x11x13
2024-06-23 19:57:06 -04:00
parent a077939be7
commit a2c4b509e2
4 changed files with 37 additions and 36 deletions

View File

@@ -55,14 +55,15 @@ scdl me -f
-r Download all reposts of user
-c Continue if a downloaded file already exists
--force-metadata This will set metadata on already downloaded track
-o [offset] Begin with a custom offset
-o [offset] Start downloading a playlist from the [offset]th track (starting with 1)
--addtimestamp Add track creation timestamp to filename,
which allows for chronological sorting
(Deprecated. Use --name-format instead.)
--addtofile Add artist to filename if missing
--debug Set log level to DEBUG
--error Set log level to ERROR
--download-archive [file] Keep track of track IDs in an archive file,
and skip already-downloaded files
--error Set log level to ERROR
--extract-artist Set artist tag from title instead of username
--hide-progress Hide the wget progress bar
--hidewarnings Hide Warnings. (use with precaution)
@@ -70,16 +71,16 @@ scdl me -f
--min-size [min-size] Skip tracks smaller than size (k/m/g)
--no-playlist-folder Download playlist tracks into main directory,
instead of making a playlist subfolder
--onlymp3 Download only the streamable mp3 file,
even if track has a Downloadable file
--onlymp3 Download only mp3 files
--path [path] Use a custom path for downloaded files
--remove Remove any files not downloaded from execution
--sync [file] Compare an archive file to a playlist and downloads/removes any changed tracks
--flac Convert original files to .flac
--sync [file] Compares an archive file to a playlist and downloads/removes any changed tracks
--flac Convert original files to .flac. Only works if the original file is lossless quality
--no-album-tag On some player track get the same cover art if from the same album, this prevent it
--original-art Download original cover art
--original-art Download original cover art, not just 500x500 JPEG
--original-name Do not change name of original file downloads
--no-original Do not download original file; only mp3 or m4a
--original-metadata Do not change metadata of original file downloads
--no-original Do not download original file; only mp3, m4a, or opus
--only-original Only download songs with original file available
--name-format [format] Specify the downloaded file name format
--playlist-name-format [format] Specify the downloaded file name format, if it is being downloaded as part of a playlist
@@ -88,6 +89,7 @@ scdl me -f
--overwrite Overwrite file if it already exists
--strict-playlist Abort playlist downloading if one track fails to download
--no-playlist Skip downloading playlists
--opus Prefer downloading opus streams over mp3 streams
```

View File

@@ -1,3 +1,3 @@
# -*- encoding: utf-8 -*-
"""Python Soundcloud Music Downloader."""
__version__ = "v2.9.2"
__version__ = "v2.9.3"

View File

@@ -68,15 +68,15 @@ Options:
--opus Prefer downloading opus streams over mp3 streams
"""
import atexit
import base64
import cgi
import configparser
import contextlib
import itertools
import logging
import math
import mimetypes
from typing import Optional, TypedDict
from typing import List, Optional, TypedDict
mimetypes.init()
@@ -92,16 +92,7 @@ import urllib.parse
import warnings
from dataclasses import asdict
if os.name == "nt":
import filelock
FileLockTimeout = filelock.Timeout
else:
class FileLockTimeout(Exception):
pass
import filelock
import mutagen
import mutagen.flac
import mutagen.id3
@@ -148,12 +139,26 @@ class PlaylistInfo(TypedDict):
id: int
title: str
file_lock_dirs: List[pathlib.Path] = []
def clean_up_locks():
for dir in file_lock_dirs:
for lock in dir.glob("*.scdl.lock"):
try:
lock.unlink(True)
except Exception:
pass
atexit.register(clean_up_locks)
def get_filelock(path: pathlib.Path, timeout: int = 10):
if os.name == "nt":
return filelock.FileLock(str(path) + ".scdl.lock", timeout=timeout)
else:
return contextlib.nullcontext()
path = path.resolve()
file_lock_dirs.append(path.parent)
lock_path = str(path) + ".scdl.lock"
return filelock.FileLock(lock_path, timeout=timeout)
def main():
@@ -712,7 +717,7 @@ def download_original_file(
shutil.move(temp.name, os.path.join(os.getcwd(), filename))
if kwargs.get("flac") and can_convert(filename):
logger.info("Converting to .flac...")
newfilename = limit_filename_length(filename[:-4], ".flac")
newfilename = sanitize_str(filename[:-4], ".flac")
commands = ["ffmpeg", "-i", filename, newfilename, "-loglevel", "error"]
logger.debug(f"Commands: {commands}")
@@ -760,7 +765,6 @@ def download_hls(
transcoding = None
ext = None
# ordered in terms of preference best -> worst
valid_presets = [("mp3", ".mp3")]
@@ -836,7 +840,7 @@ def download_track(
# Get user_id from the client
client_user_id = client.get_me().id if client.auth_token else None
lock = get_filelock(f"{track.id}", 0)
lock = get_filelock(pathlib.Path(f"./{track.id}"), 0)
# Downloadable track
downloaded_original = False
@@ -854,7 +858,7 @@ def download_track(
client, track, title, playlist_info, **kwargs
)
downloaded_original = True
except FileLockTimeout:
except filelock.Timeout:
logger.debug(f"Could not acquire lock: {lock}. Skipping")
return
@@ -866,7 +870,7 @@ def download_track(
filename, is_already_downloaded = download_hls(
client, track, title, playlist_info, **kwargs
)
except FileLockTimeout:
except filelock.Timeout:
logger.debug(f"Could not acquire lock: {lock}. Skipping")
return
@@ -1118,11 +1122,6 @@ def set_metadata(
audio.save()
def limit_filename_length(name: str, ext: str, max_bytes=255):
while len(name.encode("utf-8")) + len(ext.encode("utf-8")) > max_bytes:
name = name[:-1]
return name + ext
def is_ffmpeg_available():
"""
Returns true if ffmpeg is available in the operating system

View File

@@ -29,7 +29,7 @@ setup(
"clint",
"pathvalidate",
"soundcloud-v2>=1.3.10",
"filelock>=3.0.0; platform_system=='Windows'",
"filelock>=3.0.0",
],
extras_require={"test": ["coveralls", "pytest", "pytest-dotenv", "music-tag"]},
url="https://github.com/flyingrub/scdl",