Merge branch 'dev'

This commit is contained in:
Nathan Thomas 2024-01-24 16:06:38 -08:00
commit d00e6e2f48
5 changed files with 45 additions and 27 deletions

View File

@ -133,29 +133,23 @@ class DeezerDownloadable(Downloadable):
blowfish_key,
)
assert self.chunk_size == 2048 * 3
buf = bytearray()
async for data, _ in resp.content.iter_chunks():
buf += data
callback(len(data))
# Write data from server to tempfile because there's no
# efficient way to guarantee a fixed chunk size for all iterations
# in async
async with aiofiles.tempfile.TemporaryFile("wb+") as tmp:
async for chunk in resp.content.iter_chunks():
data, _ = chunk
await tmp.write(data)
callback(len(data))
await tmp.seek(0)
async with aiofiles.open(path, "wb") as audio:
while chunk := await tmp.read(self.chunk_size):
if len(chunk) >= 2048:
decrypted_chunk = (
self._decrypt_chunk(blowfish_key, chunk[:2048])
+ chunk[2048:]
)
else:
decrypted_chunk = chunk
await audio.write(decrypted_chunk)
async with aiofiles.open(path, "wb") as audio:
buflen = len(buf)
for i in range(0, buflen, self.chunk_size):
data = buf[i : min(i + self.chunk_size, buflen - 1)]
if len(data) >= 2048:
decrypted_chunk = (
self._decrypt_chunk(blowfish_key, data[:2048])
+ data[2048:]
)
else:
decrypted_chunk = data
await audio.write(decrypted_chunk)
@staticmethod
def _decrypt_chunk(key, data):

View File

@ -161,7 +161,7 @@ add_singles_to_folder = false
folder_format = "{albumartist} - {title} ({year}) [{container}] [{bit_depth}B-{sampling_rate}kHz]"
# Available keys: "tracknumber", "artist", "albumartist", "composer", "title",
# and "albumcomposer", "explicit"
track_format = "{tracknumber}. {artist} - {title}{explicit}"
track_format = "{tracknumber:02}. {artist} - {title}{explicit}"
# Only allow printable ASCII characters in filenames.
restrict_characters = false
# Truncate the filename if it is greater than this number of characters

View File

@ -7,6 +7,7 @@ from .. import progress
from ..client import Client
from ..config import Config
from ..db import Database
from ..exceptions import NonStreamableError
from ..filepath_utils import clean_filepath
from ..metadata import AlbumMetadata
from ..metadata.util import get_album_track_ids
@ -50,7 +51,14 @@ class PendingAlbum(Pending):
db: Database
async def resolve(self) -> Album | None:
resp = await self.client.get_metadata(self.id, "album")
try:
resp = await self.client.get_metadata(self.id, "album")
except NonStreamableError as e:
logger.error(
f"Album {self.id} not available to stream on {self.client.source} ({e})",
)
return None
meta = AlbumMetadata.from_album_resp(resp, self.client.source)
if meta is None:
logger.error(

View File

@ -7,6 +7,7 @@ from ..client import Client
from ..config import Config, QobuzDiscographyFilterConfig
from ..console import console
from ..db import Database
from ..exceptions import NonStreamableError
from ..metadata import ArtistMetadata
from .album import Album, PendingAlbum
from .media import Media, Pending
@ -180,8 +181,15 @@ class PendingArtist(Pending):
config: Config
db: Database
async def resolve(self) -> Artist:
resp = await self.client.get_metadata(self.id, "artist")
async def resolve(self) -> Artist | None:
try:
resp = await self.client.get_metadata(self.id, "artist")
except NonStreamableError as e:
logger.error(
f"Artist {self.id} not available to stream on {self.client.source} ({e})",
)
return None
meta = ArtistMetadata.from_resp(resp, self.client.source)
albums = [
PendingAlbum(album_id, self.client, self.config, self.db)

View File

@ -147,7 +147,14 @@ class PendingPlaylist(Pending):
db: Database
async def resolve(self) -> Playlist | None:
resp = await self.client.get_metadata(self.id, "playlist")
try:
resp = await self.client.get_metadata(self.id, "playlist")
except NonStreamableError as e:
logger.error(
f"Playlist {self.id} not available to stream on {self.client.source} ({e})",
)
return None
meta = PlaylistMetadata.from_resp(resp, self.client.source)
name = meta.name
parent = self.config.session.downloads.folder
@ -261,6 +268,7 @@ class PendingLastfmPlaylist(Pending):
if that fails.
Args:
----
query (str): Query to search
s (Status):
callback: function to call after each query completes