Skip to content

Commit

Permalink
Merge pull request #32 from kutu-dev/feat/get-cover-art
Browse files Browse the repository at this point in the history
Implement and test the getCoverArt endpoint
  • Loading branch information
kutu-dev authored Sep 30, 2023
2 parents 091103a + b25c296 commit 8e91ab6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 2 deletions.
40 changes: 38 additions & 2 deletions src/knuckles/media_retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,44 @@ def hls(self, id: str) -> str:
def get_captions(self) -> None:
...

def get_cover_art(self) -> None:
...
def get_cover_art(self, id: str, file_or_directory_path: Path, size: int) -> Path:
"""Calls the "getCoverArt" endpoint of the API.
:param id: The id of the cover art to download.
:type id: str
:param file_or_directory_path: If a directory path is passed the file will be
inside of it with the filename being the name of the user and
a guessed file extension, if not the file will be saved
directly in the given path.
:type file_or_directory_path: Path
:param size: The size of the image to be scale to in a square.
:type size: int
:return Returns the given path
:rtype Path
"""

response = self.api.raw_request("getCoverArt", {"id": id, "size": size})
response.raise_for_status()

if file_or_directory_path.is_dir():
file_extension = guess_extension(
response.headers["content-type"].partition(";")[0].strip()
)

filename = id + file_extension if file_extension else id

download_path = Path(
file_or_directory_path,
filename,
)
else:
download_path = file_or_directory_path

with open(download_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)

return download_path

def get_lyrics(self) -> None:
...
Expand Down
62 changes: 62 additions & 0 deletions tests/api/test_media_retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,68 @@ def test_hls(subsonic: Subsonic, song: dict[str, Any]) -> None:
assert parse.parse_qs(stream_url.query)["id"][0] == song["id"]


@responses.activate
def test_get_cover_art_with_a_given_filename(
tmp_path: Path,
output_cover_art_filename: str,
placeholder_data: str,
mock_download_file: MockDownload,
subsonic: Subsonic,
song: dict[str, Any],
cover_art_content_type: str,
cover_art_size: int,
) -> None:
responses.add(
mock_download_file(
"getCoverArt",
{"id": song["coverArt"], "size": cover_art_size},
tmp_path,
cover_art_content_type,
)
)

download_path = subsonic.media_retrieval.get_cover_art(
song["coverArt"], tmp_path / output_cover_art_filename, cover_art_size
)

# Check if the file data has been unaltered
with open(tmp_path / output_cover_art_filename, "r") as file:
assert placeholder_data == file.read()

assert download_path == tmp_path / output_cover_art_filename


@responses.activate
def test_get_cover_art_without_a_given_filename(
tmp_path: Path,
default_cover_art_filename: str,
placeholder_data: str,
mock_download_file: MockDownload,
subsonic: Subsonic,
song: dict[str, Any],
cover_art_content_type: str,
cover_art_size: int,
) -> None:
responses.add(
mock_download_file(
"getCoverArt",
{"id": song["coverArt"], "size": cover_art_size},
tmp_path,
cover_art_content_type,
)
)

download_path = subsonic.media_retrieval.get_cover_art(
song["coverArt"], tmp_path, cover_art_size
)

# Check if the file data has been unaltered
with open(tmp_path / default_cover_art_filename, "r") as file:
assert placeholder_data == file.read()

assert download_path == tmp_path / default_cover_art_filename


@responses.activate
def test_get_avatar_with_a_given_filename(
tmp_path: Path,
Expand Down
20 changes: 20 additions & 0 deletions tests/mocks/media_retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ def avatar_content_type() -> str:
return "image/png"


@pytest.fixture
def default_cover_art_filename(song: dict[str, Any]) -> str:
return f"{song['coverArt']}.png"


@pytest.fixture
def output_cover_art_filename() -> str:
return "output.png"


@pytest.fixture
def cover_art_content_type() -> str:
return "image/png"


@pytest.fixture
def cover_art_size() -> int:
return 512


@pytest.fixture
def mock_download_file(
placeholder_data: str,
Expand Down

0 comments on commit 8e91ab6

Please sign in to comment.