From de1db82da880ea83468c75a480032bff3bbbca2c Mon Sep 17 00:00:00 2001 From: nathom Date: Sat, 10 Apr 2021 16:05:31 -0700 Subject: [PATCH] Fix misc. pylint errors --- streamrip/__init__.py | 3 +++ streamrip/config.py | 43 +++++++++++++++++++++++------------------ streamrip/db.py | 12 ++++++++---- streamrip/downloader.py | 15 +++++++++----- streamrip/metadata.py | 34 +++++++++++++++++++++----------- 5 files changed, 68 insertions(+), 39 deletions(-) diff --git a/streamrip/__init__.py b/streamrip/__init__.py index 896a370..07e416c 100644 --- a/streamrip/__init__.py +++ b/streamrip/__init__.py @@ -1 +1,4 @@ +'''streamrip: the all in one music downloader. +''' + __version__ = "0.4" diff --git a/streamrip/config.py b/streamrip/config.py index d035ef4..568e28e 100644 --- a/streamrip/config.py +++ b/streamrip/config.py @@ -1,3 +1,5 @@ +'''A config class that manages arguments between the config file and CLI.''' + import copy import logging import os @@ -99,21 +101,27 @@ class Config: self._path = path if not os.path.isfile(self._path): - logger.debug(f"Creating yaml config file at '{self._path}'") + logger.debug("Creating yaml config file at '%s'", self._path) self.dump(self.defaults) else: self.load() def save(self): + """Save the config state to file.""" + self.dump(self.file) def reset(self): + """Reset the config file.""" + if not os.path.isdir(CONFIG_DIR): os.makedirs(CONFIG_DIR, exist_ok=True) self.dump(self.defaults) def load(self): + """Load infomation from the config files, making a deepcopy.""" + with open(self._path) as cfg: for k, v in yaml.load(cfg).items(): self.file[k] = v @@ -125,27 +133,18 @@ class Config: logger.debug("Config loaded") self.__loaded = True - def update_from_cli(self, **kwargs): - for category in (self.downloads, self.metadata, self.filters): - for key in category.keys(): - if kwargs.get(key) is None: - continue - - # For debugging's sake - og_value = category[key] - new_value = kwargs[key] or og_value - category[key] = new_value - - if og_value != new_value: - logger.debug("Updated %s config key from args: %s", key, new_value) - def dump(self, info): + """Given a state of the config, save it to the file. + + :param info: + """ with open(self._path, "w") as cfg: logger.debug("Config saved: %s", self._path) yaml.dump(info, cfg) @property def tidal_creds(self): + """Return a TidalClient compatible dict of credentials.""" creds = dict(self.file["tidal"]) logger.debug(creds) del creds["quality"] # should not be included in creds @@ -153,6 +152,7 @@ class Config: @property def qobuz_creds(self): + """Return a QobuzClient compatible dict of credentials.""" return { "email": self.file["qobuz"]["email"], "pwd": self.file["qobuz"]["password"], @@ -161,14 +161,19 @@ class Config: } def creds(self, source: str): + """Return a Client compatible dict of credentials. + + :param source: + :type source: str + """ if source == "qobuz": return self.qobuz_creds - elif source == "tidal": + if source == "tidal": return self.tidal_creds - elif source == "deezer": + if source == "deezer": return dict() - else: - raise InvalidSourceError(source) + + raise InvalidSourceError(source) def __getitem__(self, key): assert key in ("file", "defaults", "session") diff --git a/streamrip/db.py b/streamrip/db.py index cee20d6..3d0801b 100644 --- a/streamrip/db.py +++ b/streamrip/db.py @@ -1,3 +1,7 @@ +'''A simple wrapper over an sqlite database that stores +the downloaded media IDs. +''' + import logging import os import sqlite3 @@ -37,7 +41,7 @@ class MusicDB: :type item_id: str :rtype: bool """ - logger.debug(f"Checking database for ID {item_id}") + logger.debug("Checking database for ID %s", item_id) with sqlite3.connect(self.path) as conn: return ( conn.execute( @@ -52,7 +56,7 @@ class MusicDB: :param item_id: :type item_id: str """ - logger.debug(f"Adding ID {item_id}") + logger.debug("Adding ID %s", item_id) with sqlite3.connect(self.path) as conn: try: conn.execute( @@ -60,6 +64,6 @@ class MusicDB: (item_id,), ) conn.commit() - except sqlite3.Error as e: - if "UNIQUE" not in str(e): + except sqlite3.Error as err: + if "UNIQUE" not in str(err): raise diff --git a/streamrip/downloader.py b/streamrip/downloader.py index ee96feb..79126fb 100644 --- a/streamrip/downloader.py +++ b/streamrip/downloader.py @@ -1,3 +1,7 @@ +'''These classes parse information from Clients into a universal, +downloadable form. +''' + import logging import os import re @@ -90,6 +94,7 @@ class Track: :param kwargs: id, filepath_format, meta, quality, folder """ self.client = client + self.id = None self.__dict__.update(kwargs) # adjustments after blind attribute sets @@ -116,7 +121,7 @@ class Track: def load_meta(self): """Send a request to the client to get metadata for this Track.""" - assert hasattr(self, "id"), "id must be set before loading metadata" + assert self.id is not None, "id must be set before loading metadata" self.resp = self.client.get(self.id, media_type="track") self.meta = TrackMetadata( @@ -143,7 +148,7 @@ class Track: def _get_tracklist(resp, source): if source == "qobuz": return resp["tracks"]["items"] - elif source in ("tidal", "deezer"): + if source in ("tidal", "deezer"): return resp["tracks"] raise NotImplementedError(source) @@ -228,7 +233,7 @@ class Track: try: tqdm_download(dl_info, temp_file) # downloads file except NonStreamable: - logger.debug(f"Track is not downloadable {dl_info}") + logger.debug("Track is not downloadable %s", dl_info) click.secho("Track is not available for download", fg="red") return False @@ -569,6 +574,7 @@ class Tracklist(list): >>> tlist[2] IndexError """ + essence_regex = re.compile(r"([^\(]+)(?:\s*[\(\[][^\)][\)\]])*") def get(self, key: Union[str, int], default=None): if isinstance(key, str): @@ -681,8 +687,7 @@ class Tracklist(list): Used to group two albums that may be named similarly, but not exactly the same. """ - # fixme: compile this first - match = re.match(r"([^\(]+)(?:\s*[\(\[][^\)][\)\]])*", album) + match = Tracklist.essence_regex.match(album) if match: return match.group(1).strip().lower() diff --git a/streamrip/metadata.py b/streamrip/metadata.py index 9009514..745a70f 100644 --- a/streamrip/metadata.py +++ b/streamrip/metadata.py @@ -1,3 +1,5 @@ +'''Manages the information that will be embeded in the audio file. ''' + import json import logging import re @@ -55,6 +57,7 @@ class TrackMetadata: :param album: album dict from API :type album: Optional[dict] """ + self.title = None self.album = None self.albumartist = None self.composer = None @@ -201,7 +204,7 @@ class TrackMetadata: self.title = f"{work}: {self.title}" @property - def artist(self) -> Union[str, None]: + def artist(self) -> Optional[str]: """Returns the value to set for the artist tag. Defaults to `self.albumartist` if there is no track artist. @@ -213,6 +216,8 @@ class TrackMetadata: if self._artist is not None: return self._artist + return None + @artist.setter def artist(self, val: str): """Sets the internal artist variable to val. @@ -237,8 +242,13 @@ class TrackMetadata: if isinstance(self._genres, list): genres = re.findall(r"([^\u2192\/]+)", "/".join(self._genres)) no_repeats = [] - [no_repeats.append(g) for g in genres if g not in no_repeats] + + for genre in genres: + if genre not in no_repeats: + no_repeats.append(genre) + return ", ".join(no_repeats) + elif isinstance(self._genres, str): return self._genres @@ -264,9 +274,9 @@ class TrackMetadata: if hasattr(self, "_copyright"): if self._copyright is None: return None - cr = re.sub(r"(?i)\(P\)", PHON_COPYRIGHT, self._copyright) - cr = re.sub(r"(?i)\(C\)", COPYRIGHT, cr) - return cr + copyright = re.sub(r"(?i)\(P\)", PHON_COPYRIGHT, self._copyright) + copyright = re.sub(r"(?i)\(C\)", COPYRIGHT, copyright) + return copyright logger.debug("Accessed copyright tag before setting, return None") return None @@ -282,7 +292,7 @@ class TrackMetadata: self._copyright = val @property - def year(self) -> Union[str, None]: + def year(self) -> Optional[str]: """Returns the year published of the track. :rtype: str @@ -294,6 +304,8 @@ class TrackMetadata: if self.date is not None: return self.date[:4] + return None + @year.setter def year(self, val): """Sets the internal year variable to val. @@ -334,12 +346,12 @@ class TrackMetadata: container = container.lower() if container in ("flac", "vorbis"): return self.__gen_flac_tags() - elif container in ("mp3", "id3"): + if container in ("mp3", "id3"): return self.__gen_mp3_tags() - elif container in ("alac", "m4a", "mp4", "aac"): + if container in ("alac", "m4a", "mp4", "aac"): return self.__gen_mp4_tags() - else: - raise InvalidContainerError(f"Invalid container {container}") + + raise InvalidContainerError(f"Invalid container {container}") def __gen_flac_tags(self) -> Tuple[str, str]: """Generate key, value pairs to tag FLAC files. @@ -349,7 +361,7 @@ class TrackMetadata: for k, v in FLAC_KEY.items(): tag = getattr(self, k) if tag: - logger.debug(f"Adding tag {v}: {repr(tag)}") + logger.debug("Adding tag %s: %s", v, tag) yield (v, str(tag)) def __gen_mp3_tags(self) -> Tuple[str, str]: