Skip to content

Commit

Permalink
Merge pull request #38 from kutu-dev/feat/refactorize-convoluted-code
Browse files Browse the repository at this point in the history
Feat/refactorize convoluted code
  • Loading branch information
kutu-dev authored Oct 7, 2023
2 parents 9daaaf2 + 78fd34a commit a7c6114
Show file tree
Hide file tree
Showing 56 changed files with 492 additions and 459 deletions.
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

0 comments on commit a7c6114

Please sign in to comment.