Skip to content
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
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def th_function(self):
"""This function will always be called in a thread"""
try:
self.this_call_might_fail()
except Exception as e:
print(f"Error while ...: {e}")
except Exception:
logger.exception(f"Error while ...")
GLib.idle_add(self.on_failed)
else:
utils.get_favourites()
Expand All @@ -65,14 +65,14 @@ threading.Thread(target=self.th_function, args=()).start()
### Error Handling

- Always include appropriate exception handling for external API calls
- Use descriptive error messages or at least write the error to the console
- Use descriptive error messages or at least write the error to the console using a logger
- Provide fallback behavior when operations fail

```python
try:
self.this_call_might_fail()
except Exception as e:
print(e)
except Exception:
logger.exception("<Description>")
```

### Signals and memory management
Expand Down
2 changes: 1 addition & 1 deletion src/lib/discord_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def disconnect_function() -> None:
set_activity(track, offset_ms)
else:
state = State.DISCONNECTED
logger.error("Connection with discord IPC lost.")
logger.exception("Connection with discord IPC lost.")


if has_pypresence:
Expand Down
24 changes: 12 additions & 12 deletions src/lib/player_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(
Gst.init(None)

version_str = Gst.version_string()
print(f"GStreamer version: {version_str}")
logger.info(f"GStreamer version: {version_str}")

self.pipeline = Gst.Pipeline.new("dash-player")

Expand All @@ -87,7 +87,7 @@ def __init__(
self.playbin.connect("about-to-finish", self.play_next_gapless)
self.gapless_enabled = True
else:
print("Could not create playbin3 element, trying playbin...")
logger.error("Could not create playbin3 element, trying playbin...")
self.playbin = Gst.ElementFactory.make("playbin", "playbin")
self.gapless_enabled = False

Expand Down Expand Up @@ -211,8 +211,8 @@ def _setup_audio_sink(self, sink_type: AudioSink) -> None:
raise RuntimeError("Failed to create audio bin")

self.playbin.set_property("audio-sink", audio_bin)
except GLib.Error as e:
print(f"Error creating pipeline: {e}")
except GLib.Error:
logger.exception("Error creating pipeline")
self.playbin.set_property(
"audio-sink", Gst.ElementFactory.make("autoaudiosink", None)
)
Expand Down Expand Up @@ -248,8 +248,8 @@ def _on_bus_eos(self, *args) -> None:
def _on_bus_error(self, bus: Any, message: Any) -> None:
"""Handle pipeline errors."""
err, debug = message.parse_error()
print(f"Error: {err.message}")
print(f"Debug info: {debug}")
logger.error(f"Error: {err.message}")
logger.error(f"Debug info: {debug}")

# Use string compare instead of error codes (Seems be just generic error)
if "Internal data stream error" in err.message and "not-linked" in debug:
Expand Down Expand Up @@ -337,7 +337,7 @@ def play_this(
tracks: List[Track] = self.get_track_list(thing)

if not tracks:
print("No tracks found to play")
logger.info("No tracks found to play")
return

self._tracks_to_play = tracks[index:] + tracks[:index]
Expand Down Expand Up @@ -472,8 +472,8 @@ def _play_track_thread(self, track: Track, gapless=False) -> None:
music_url = urls

GLib.idle_add(self._play_track_url, track, music_url, gapless)
except Exception as e:
print(f"Error getting track URL: {e}")
except Exception:
logger.exception("Error getting track URL")

def apply_replaygain_tags(self):
"""Apply ReplayGain normalization tags to the current track if enabled."""
Expand All @@ -500,7 +500,7 @@ def apply_replaygain_tags(self):

if rgtags:
rgtags.set_property("tags", tags)
print(f"Applied RG Tags: {tags}")
logger.info("Applied RG Tags")
# Save replaygain tags for every song to avoid missing tags when
# toggling the option
self.most_recent_rg_tags = f"tags={tags}"
Expand All @@ -513,7 +513,7 @@ def _play_track_url(self, track, music_url, gapless=False):
self.playbin.set_property("volume", self.playbin.get_property("volume"))
self.playbin.set_property("uri", music_url)

print(music_url)
logger.info(music_url)

if gapless:
self.next_track = track
Expand Down Expand Up @@ -659,7 +659,7 @@ def _update_slider_callback(self):
"""Update playback slider and duration."""
self.update_timer = None
if not self.duration:
logger.warn("Duration missing, trying again")
logger.warning("Duration missing, trying again")
self.duration = self.query_duration()
self.emit("update-slider")
return self.playing
Expand Down
11 changes: 7 additions & 4 deletions src/lib/secret_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@
import tidalapi
from gi.repository import Secret, Xdp

import logging
logger = logging.getLogger(__name__)


class SecretStore:
def __init__(self, session: tidalapi.Session) -> None:
super().__init__()

print("initializing secret store")
logger.info("initializing secret store")

self.version = "0.0"
self.session: tidalapi.Session = session
Expand All @@ -53,7 +56,7 @@ def __init__(self, session: tidalapi.Session) -> None:
service, Secret.COLLECTION_DEFAULT, Secret.CollectionFlags.NONE
)
if collection and collection.get_locked():
print("Collection is locked, attempting to unlock")
logger.info("Collection is locked, attempting to unlock")
service.unlock_sync([collection])

password = Secret.password_lookup_sync(self.schema, {}, None)
Expand All @@ -62,8 +65,8 @@ def __init__(self, session: tidalapi.Session) -> None:
json_data = json.loads(password)
self.token_dictionary = json_data

except Exception as error:
print("Failed to load secret store, resetting", error)
except Exception:
logger.exception("Failed to load secret store, resetting")

self.token_dictionary = {}

Expand Down
48 changes: 34 additions & 14 deletions src/lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import subprocess
import threading
import uuid
import logging
from gettext import gettext as _
from pathlib import Path
from typing import Any, List
Expand All @@ -34,6 +35,8 @@
from ..pages import HTAlbumPage, HTArtistPage, HTMixPage, HTPlaylistPage
from .cache import HTCache

logger = logging.getLogger(__name__)

favourite_mixes: List[Mix] = []
favourite_tracks: List[Track] = []
favourite_artists: List[Artist] = []
Expand Down Expand Up @@ -246,16 +249,16 @@ def get_favourites() -> None:
favourite_mixes = user.favorites.mixes()
playlist_and_favorite_playlists = user.playlist_and_favorite_playlists()
user_playlists = user.playlists()
except Exception as e:
print(e)
except Exception:
logger.exception("Error while getting Favourites")

print(f"Favorite Artists: {len(favourite_artists)}")
print(f"Favorite Tracks: {len(favourite_tracks)}")
print(f"Favorite Albums: {len(favourite_albums)}")
print(f"Favorite Playlists: {len(favourite_playlists)}")
print(f"Favorite Mixes: {len(favourite_mixes)}")
print(f"Playlist and Favorite Playlists: {len(playlist_and_favorite_playlists)}")
print(f"User Playlists: {len(user_playlists)}")
logger.info(f"Favorite Artists: {len(favourite_artists)}")
logger.info(f"Favorite Tracks: {len(favourite_tracks)}")
logger.info(f"Favorite Albums: {len(favourite_albums)}")
logger.info(f"Favorite Playlists: {len(favourite_playlists)}")
logger.info(f"Favorite Mixes: {len(favourite_mixes)}")
logger.info(f"Playlist and Favorite Playlists: {len(playlist_and_favorite_playlists)}")
logger.info(f"User Playlists: {len(user_playlists)}")


def is_favourited(item: Any) -> bool:
Expand Down Expand Up @@ -479,7 +482,7 @@ def open_tidal_uri(uri: str) -> None:
page = HTPlaylistPage(content_id).load()
navigation_view.push(page)
case _:
print(f"Unsupported content type: {content_type}")
logger.warning(f"Unsupported content type: {content_type}")
return False


Expand Down Expand Up @@ -560,8 +563,8 @@ def get_image_url(item: Any, dimensions: int = 320) -> str | None:
try:
picture_url = item.image(dimensions=dimensions)
response = requests.get(picture_url)
except Exception as e:
print(e)
except Exception:
logger.exception("Could not get image")
return None
if response.status_code == 200:
picture_data = response.content
Expand Down Expand Up @@ -643,8 +646,8 @@ def get_video_cover_url(item: Any, dimensions: int = 320) -> str | None:
try:
video_url = item.video(dimensions=dimensions)
response = requests.get(video_url)
except Exception as e:
print(e)
except Exception:
logger.exception("Could not get video")
return None
if response.status_code == 200:
picture_data = response.content
Expand Down Expand Up @@ -761,3 +764,20 @@ def replace(match_obj: Any) -> str:
replaced_text = re.sub(pattern, replace, escaped_text)

return replaced_text

def setup_logging():
global CACHE_DIR

log_to_file = os.getenv("LOG_TO_FILE")
log_level = os.getenv("LOG_LEVEL", "INFO").upper()

handlers = []
if log_to_file:
handlers.append(logging.FileHandler(CACHE_DIR + "/high-tide.log"))
handlers.append(logging.StreamHandler())

logging.basicConfig(
level=getattr(logging, log_level, logging.INFO),
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
handlers=handlers,
)
1 change: 1 addition & 0 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self) -> None:
self.create_action("log-out", self.on_logout_action)

utils.init()
utils.setup_logging()

self.settings: Gio.Settings = Gio.Settings.new("io.github.nokse22.high-tide")

Expand Down
7 changes: 5 additions & 2 deletions src/mpris.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

from .lib import utils

import logging
logger = logging.getLogger(__name__)


class Server:
def __init__(self, con, path):
Expand Down Expand Up @@ -72,8 +75,8 @@ def on_method_call(
invocation.return_value(variant)
else:
invocation.return_value(None)
except Exception as e:
print(e)
except Exception:
logger.exception("MPRIS Error")


class MPRIS(Server):
Expand Down
5 changes: 4 additions & 1 deletion src/new_playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

from gi.repository import Adw, GObject, Gtk

import logging
logger = logging.getLogger(__name__)


@Gtk.Template(resource_path="/io/github/nokse22/high-tide/ui/new_playlist.ui")
class NewPlaylistWindow(Adw.Dialog):
Expand Down Expand Up @@ -54,7 +57,7 @@ def on_create_button_clicked_func(self, *args) -> None:

def on_title_text_inserted_func(self, *args) -> None:
playlist_title: str = self.playlist_name_entry.get_text()
print(f"!{playlist_title}!")
logger.info(f"!{playlist_title}!")
if playlist_title != "":
self.create_button.set_sensitive(True)
return
Expand Down
2 changes: 1 addition & 1 deletion src/pages/artist_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _load_async(self) -> None:
try:
self.artist = utils.get_artist(self.id)
except Exception as e:
logger.error(f"Failed to load artist with id {self.id}: {e}")
logger.exception(f"Failed to load artist with id {self.id}: {e}")
self.artist = None
return # can't continue if artist is missing

Expand Down
7 changes: 5 additions & 2 deletions src/pages/explore_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
from .generic_page import HTGenericPage
from .search_page import HTSearchPage

import logging
logger = logging.getLogger(__name__)


class HTExplorePage(HTGenericPage):
"""A page to display the explore page"""
Expand All @@ -36,8 +39,8 @@ class HTExplorePage(HTGenericPage):
def _load_async(self) -> None:
try:
self.page = utils.session.explore()
except Exception as e:
print(e)
except Exception:
logger.exception("Error while loading Explore page")
self.tries += 1
if self.tries < 5:
self._load_async()
Expand Down
7 changes: 5 additions & 2 deletions src/pages/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
from ..widgets import (HTAutoLoadWidget, HTCardWidget, HTCarouselWidget,
HTTracksListWidget)

import logging
logger = logging.getLogger(__name__)


class Page(Adw.NavigationPage, IDisconnectable):
"""Base class for all types of pages in the High Tide application.
Expand Down Expand Up @@ -94,8 +97,8 @@ def _loaded():
def _load():
try:
self._load_async()
except Exception as e:
print(e)
except Exception:
logger.exception("Error while getting Page")
return

GLib.idle_add(_loaded)
Expand Down
5 changes: 4 additions & 1 deletion src/widgets/auto_load_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
from .card_widget import HTCardWidget
from .generic_track_widget import HTGenericTrackWidget

import logging
logger = logging.getLogger(__name__)


@Gtk.Template(
resource_path="/io/github/nokse22/high-tide/ui/widgets/auto_load_widget.ui"
Expand Down Expand Up @@ -73,7 +76,7 @@ def set_items(self, items: list) -> None:
items (list): the list of items
"""
if len(self.items) > 0:
print("You can't set items for HTAutoLoadWidget twice")
logger.warning("You can't set items for HTAutoLoadWidget twice")
return

self.items = items
Expand Down
5 changes: 4 additions & 1 deletion src/widgets/generic_track_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
from ..disconnectable_iface import IDisconnectable
from ..lib import utils

import logging
logger = logging.getLogger(__name__)


@Gtk.Template(
resource_path="/io/github/nokse22/high-tide/ui/widgets/generic_track_widget.ui"
Expand Down Expand Up @@ -169,7 +172,7 @@ def _add_to_playlist(self, action, parameter):
if isinstance(selected_playlist, UserPlaylist):
selected_playlist.add([self.track.id])

print(f"Added to playlist: {selected_playlist.name}")
logger.info(f"Added to playlist: {selected_playlist.name}")

def _copy_share_url(self, *args):
utils.share_this(self.track)
Loading