Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/refactorize convoluted code #38

Merged
merged 4 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ sphinx = "^7.1.0"
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.ruff]
select = ["E", "F", "I001"]

[tool.mypy]
disallow_untyped_defs = true
warn_unused_ignores = true
Expand Down
16 changes: 11 additions & 5 deletions src/knuckles/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(
:type password: str
:param client: A unique string identifying the client application.
:type client: str
:param use_https: If the requests should be sended using HTTPS,
:param use_https: If the requests should be sent using HTTPS,
defaults to True
:type use_https: bool, optional
:param use_token: If the connection should send to the server the clean password
Expand All @@ -64,7 +64,9 @@ def __init__(
else:
self.url = f"http://{base_url}"

def generate_params(self, extra_params: dict[str, Any] = {}) -> dict[str, Any]:
def generate_params(
self, extra_params: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Generate the parameters for any request to the API.

This allows the user to change any variable in any time without issues.
Expand All @@ -84,9 +86,11 @@ def generate_params(self, extra_params: dict[str, Any] = {}) -> dict[str, Any]:
"v": "1.16.1",
"c": self.client,
"f": "json",
**extra_params,
}

if extra_params is not None:
params.update(extra_params)

# Add authentication based in the method selected by the user
if not self.use_token:
return {
Expand All @@ -101,7 +105,9 @@ def generate_params(self, extra_params: dict[str, Any] = {}) -> dict[str, Any]:

return {**params, "t": token, "s": salt}

def raw_request(self, endpoint: str, extra_params: dict[str, Any]) -> Response:
def raw_request(
self, endpoint: str, extra_params: dict[str, Any] | None = None
) -> Response:
"""Make a request to the Subsonic API.

:param endpoint: The endpoint where the request should be made,
Expand All @@ -122,7 +128,7 @@ def raw_request(self, endpoint: str, extra_params: dict[str, Any]) -> Response:
)

def json_request(
self, endpoint: str, extra_params: dict[str, Any] = {}
self, endpoint: str, extra_params: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Make a request to the Subsonic API and returns a JSON response.
Don't use with binary data endpoints.
Expand Down
34 changes: 17 additions & 17 deletions src/knuckles/bookmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,31 @@ def get_bookmarks(self) -> list[Bookmark]:

return [Bookmark(self.subsonic, **bookmark) for bookmark in response]

def get_bookmark(self, id: str) -> Bookmark | None:
def get_bookmark(self, id_: str) -> Bookmark | None:
"""Using the "getBookmarks" endpoint iterates over all the bookmarks
and find the one with the same ID.

:param id: The ID of the song of the bookmark to find.
:type id: str
:param id_: The ID of the song of the bookmark to find.
:type id_: str
:return: The found bookmark or None if no one is found.
:rtype: Bookmark | None
"""

bookmarks = self.get_bookmarks()

for bookmark in bookmarks:
if bookmark.song.id == id:
if bookmark.song.id == id_:
return bookmark

return None

def create_bookmark(
self, id: str, position: int, comment: str | None = None
self, id_: str, position: int, comment: str | None = None
) -> Bookmark:
"""Calls the "createBookmark" endpoint of the API.

:param id: The ID of the song of the bookmark.
:type id: str
:param id_: The ID of the song of the bookmark.
:type id_: str
:param position: The position in seconds of the bookmark.
:type position: int
:param comment: The comment of the bookmark, defaults to None.
Expand All @@ -63,21 +63,21 @@ def create_bookmark(
"""

self.api.json_request(
"createBookmark", {"id": id, "position": position, "comment": comment}
"createBookmark", {"id": id_, "position": position, "comment": comment}
)

# Fake the song structure given by in the API.
return Bookmark(self.subsonic, {"id": id}, position=position, comment=comment)
return Bookmark(self.subsonic, {"id": id_}, position=position, comment=comment)

def update_bookmark(
self, id: str, position: int, comment: str | None = None
self, id_: str, position: int, comment: str | None = None
) -> Bookmark:
"""Method that internally calls the create_bookmark method
as creating and updating a bookmark uses the same endpoint. Useful for having
more self-descriptive code.

:param id: The ID of the song of the bookmark.
:type id: str
:param id_: The ID of the song of the bookmark.
:type id_: str
:param position: The position in seconds of the bookmark.
:type position: int
:param comment: The comment of the bookmark, defaults to None.
Expand All @@ -86,18 +86,18 @@ def update_bookmark(
:rtype: Bookmark
"""

return self.create_bookmark(id, position, comment)
return self.create_bookmark(id_, position, comment)

def delete_bookmark(self, id: str) -> "Subsonic":
def delete_bookmark(self, id_: str) -> "Subsonic":
"""Calls the "deleteBookmark" endpoint of the API.

:param id: The ID of the song of the bookmark to delete.
:type id: str
:param id_: The ID of the song of the bookmark to delete.
:type id_: str
:return: The object itself to allow method chaining.
:rtype: Subsonic
"""

self.api.json_request("deleteBookmark", {"id": id})
self.api.json_request("deleteBookmark", {"id": id_})

return self.subsonic

Expand Down
55 changes: 35 additions & 20 deletions src/knuckles/browsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,67 +86,82 @@ def get_artists(self, music_folder_id: str | None = None) -> list[Artist]:

return artists

def get_artist(self, id: str) -> Artist:
def get_artist(self, id_: str) -> Artist:
"""Calls the "getArtist" endpoint of the API.

:param id: The ID of the artist to get.
:type id: str
:param id_: The ID of the artist to get.
:type id_: str
:return: An object with all the information
that the server has given about the album.
:rtype: Artist
"""

response = self.api.json_request("getArtist", {"id": id})["artist"]
response = self.api.json_request("getArtist", {"id": id_})["artist"]

return Artist(self.subsonic, **response)

def get_album(self, id: str) -> Album:
def get_album(self, id_: str) -> Album:
"""Calls the "getAlbum" endpoint of the API.

:param id: The ID of the album to get.
:type id: str
:param id_: The ID of the album to get.
:type id_: str
:return: An object with all the information
that the server has given about the album.
:rtype: Album
"""

response = self.api.json_request("getAlbum", {"id": id})["album"]
response = self.api.json_request("getAlbum", {"id": id_})["album"]

return Album(self.subsonic, **response)

def get_album_info(self, id: str) -> AlbumInfo:
def get_album_info(self, id_: str) -> AlbumInfo:
"""Calls to the "getAlbumInfo2" endpoint of the API.

:param id: The ID of the album to get its info.
:type id: str
:param id_: The ID of the album to get its info.
:type id_: str
:return: An object with all the extra info given by the server about the album.
:rtype: AlbumInfo
"""

response = self.api.json_request("getAlbumInfo2", {"id": id})["albumInfo"]
response = self.api.json_request("getAlbumInfo2", {"id": id_})["albumInfo"]

return AlbumInfo(self.subsonic, id, **response)
return AlbumInfo(self.subsonic, id_, **response)

def get_song(self, id: str) -> Song:
def get_song(self, id_: str) -> Song:
"""Calls to the "getSong" endpoint of the API.

:param id: The ID of the song to get.
:type id: str
:param id_: The ID of the song to get.
:type id_: str
:return: An object with all the information
that the server has given about the song.
:rtype: Song
"""

response = self.api.json_request("getSong", {"id": id})["song"]
response = self.api.json_request("getSong", {"id": id_})["song"]

return Song(self.subsonic, **response)

def get_artist_info(
self, id: str, count: int | None = None, include_not_present: bool | None = None
self,
id_: str,
count: int | None = None,
include_not_present: bool | None = None,
) -> ArtistInfo:
"""Calls the "getArtistInfo" endpoint of the API.

:param id_: The id of the artist to get its info
:type id_:
:param count:
:type count:
:param include_not_present:
:type include_not_present:
:return:
:rtype:
"""

response = self.api.json_request(
"getArtistInfo2",
{"id": id, "count": count, "includeNotPresent": include_not_present},
{"id": id_, "count": count, "includeNotPresent": include_not_present},
)["artistInfo2"]

return ArtistInfo(self.subsonic, id, **response)
return ArtistInfo(self.subsonic, id_, **response)
1 change: 0 additions & 1 deletion src/knuckles/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,3 @@ def get_code_error_exception(
return CodeError70
case _:
return UnknownErrorCode
return UnknownErrorCode
24 changes: 12 additions & 12 deletions src/knuckles/internet_radio.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,20 @@ def get_internet_radio_stations(

return [InternetRadioStation(self.subsonic, **station) for station in response]

def get_internet_radio_station(self, id: str) -> InternetRadioStation | None:
def get_internet_radio_station(self, id_: str) -> InternetRadioStation | None:
"""Using the "getInternetRadioStation" endpoint iterates over all the stations
and find the one with the same ID.

:param id: The ID of the station to find.
:type id: str
:param id_: The ID of the station to find.
:type id_: str
:return: The found internet radio station or None if no one is found.
:rtype: InternetRadioStation | None
"""

stations = self.get_internet_radio_stations()

for station in stations:
if station.id == id:
if station.id == id_:
return station

return None
Expand Down Expand Up @@ -75,12 +75,12 @@ def create_internet_radio_station(
return self.subsonic

def update_internet_radio_station(
self, id: str, stream_url: str, name: str, homepage_url: str | None = None
self, id_: str, stream_url: str, name: str, homepage_url: str | None = None
) -> "Subsonic":
"""Calls the "updateInternetRadioStation" endpoint ot the API.

:param id: The ID of the station to update.
:type id: str
:param id_: The ID of the station to update.
:type id_: str
:param stream_url: The new steam url of the station.
:type stream_url: str
:param name: The new name of the station.
Expand All @@ -95,7 +95,7 @@ def update_internet_radio_station(
self.api.json_request(
"updateInternetRadioStation",
{
"id": id,
"id": id_,
"streamUrl": stream_url,
"name": name,
"homepageUrl": homepage_url,
Expand All @@ -104,15 +104,15 @@ def update_internet_radio_station(

return self.subsonic

def delete_internet_radio_station(self, id: str) -> "Subsonic":
def delete_internet_radio_station(self, id_: str) -> "Subsonic":
"""Calls the "deleteInternetRadioStation" endpoint of the API.

:param id: The ID of the station to delete
:type id: str
:param id_: The ID of the station to delete
:type id_: str
:return: The object itself to allow method chaining.
:rtype: Subsonic
"""

self.api.json_request("deleteInternetRadioStation", {"id": id})
self.api.json_request("deleteInternetRadioStation", {"id": id_})

return self.subsonic
26 changes: 13 additions & 13 deletions src/knuckles/jukebox.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,21 @@ def status(self) -> Jukebox:

return Jukebox(self.subsonic, **response)

def set(self, id: str) -> Jukebox:
def set(self, id_: str) -> Jukebox:
"""Calls the "jukeboxControl" endpoint of the API with the action "set".

:param id: The ID of a song to set it in the jukebox.
:type id: str
:param id_: The ID of a song to set it in the jukebox.
:type id_: str
:return: An object with all the given information about the jukebox.
:rtype: Jukebox
"""

response = self.api.json_request("jukeboxControl", {"action": "set", "id": id})[
"jukeboxStatus"
]
response = self.api.json_request(
"jukeboxControl", {"action": "set", "id": id_}
)["jukeboxStatus"]

# Preset the song list as this call changes it in a predictable way
return Jukebox(self.subsonic, **response, entry=[{"id": id}])
return Jukebox(self.subsonic, **response, entry=[{"id": id_}])

def start(self) -> Jukebox:
"""Calls the "jukeboxControl" endpoint of the API with the action "start".
Expand Down Expand Up @@ -108,19 +108,19 @@ def skip(self, index: int, offset: float = 0) -> Jukebox:

return Jukebox(self.subsonic, **response)

def add(self, id: str) -> Jukebox:
def add(self, id_: str) -> Jukebox:
"""Calls the "jukeboxControl" endpoint of the API with the action "add".

:param id: The ID of a song to add it in the jukebox.
:type id: str
:param id_: The ID of a song to add it in the jukebox.
:type id_: str
:return: An object with all the given information about the jukebox.
Except the jukebox playlist.
:rtype: Jukebox
"""

response = self.api.json_request("jukeboxControl", {"action": "add", "id": id})[
"jukeboxStatus"
]
response = self.api.json_request(
"jukeboxControl", {"action": "add", "id": id_}
)["jukeboxStatus"]

return Jukebox(self.subsonic, **response)

Expand Down
Loading