mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-17 15:43:28 +02:00
ruff: enable EM lint
This commit is contained in:
@@ -51,7 +51,8 @@ def init_engine(
|
||||
if db_config is None:
|
||||
url = os.getenv("DATABASE_URL")
|
||||
if not url:
|
||||
raise RuntimeError("DB config or `DATABASE_URL` must be provided")
|
||||
msg = "DB config or `DATABASE_URL` must be provided"
|
||||
raise RuntimeError(msg)
|
||||
else:
|
||||
url = build_db_url(
|
||||
db_config.user,
|
||||
@@ -76,15 +77,15 @@ def init_engine(
|
||||
|
||||
def get_engine() -> Engine:
|
||||
if engine is None:
|
||||
raise RuntimeError("Engine not initialized. Call init_engine(...) first.")
|
||||
msg = "Engine not initialized. Call init_engine(...) first."
|
||||
raise RuntimeError(msg)
|
||||
return engine
|
||||
|
||||
|
||||
def get_session() -> Generator[Session, Any, None]:
|
||||
if SessionLocal is None:
|
||||
raise RuntimeError(
|
||||
"Session factory not initialized. Call init_engine(...) first."
|
||||
)
|
||||
msg = "Session factory not initialized. Call init_engine(...) first."
|
||||
raise RuntimeError(msg)
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
|
||||
@@ -12,7 +12,8 @@ class GenericIndexer(ABC):
|
||||
if name:
|
||||
self.name = name
|
||||
else:
|
||||
raise ValueError("indexer name must not be None")
|
||||
msg = "indexer name must not be None"
|
||||
raise ValueError(msg)
|
||||
|
||||
@abstractmethod
|
||||
def search(self, query: str, is_tv: bool) -> list[IndexerQueryResult]:
|
||||
|
||||
@@ -132,7 +132,8 @@ def follow_redirects_to_final_torrent_url(
|
||||
if 300 <= response.status_code < 400:
|
||||
redirect_url = response.headers.get("Location")
|
||||
if not redirect_url:
|
||||
raise RuntimeError("Redirect response without Location header")
|
||||
msg = "Redirect response without Location header"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
# Resolve relative redirects against the last URL
|
||||
current_url = urljoin(current_url, redirect_url)
|
||||
@@ -144,10 +145,12 @@ def follow_redirects_to_final_torrent_url(
|
||||
response.raise_for_status() # Raise an exception for bad status codes
|
||||
return current_url
|
||||
else:
|
||||
raise RuntimeError("Exceeded maximum number of redirects")
|
||||
msg = "Exceeded maximum number of redirects"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
log.debug(f"An error occurred during the request for {initial_url}: {e}")
|
||||
raise RuntimeError(f"An error occurred during the request: {e}") from e
|
||||
msg = f"An error occurred during the request: {e}"
|
||||
raise RuntimeError(msg) from e
|
||||
|
||||
return current_url
|
||||
|
||||
@@ -45,7 +45,8 @@ class MovieRepository:
|
||||
stmt = select(Movie).where(Movie.id == movie_id)
|
||||
result = self.db.execute(stmt).unique().scalar_one_or_none()
|
||||
if not result:
|
||||
raise NotFoundError(f"Movie with id {movie_id} not found.")
|
||||
msg = f"Movie with id {movie_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return MovieSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(f"Database error while retrieving movie {movie_id}: {e}")
|
||||
@@ -71,9 +72,8 @@ class MovieRepository:
|
||||
)
|
||||
result = self.db.execute(stmt).unique().scalar_one_or_none()
|
||||
if not result:
|
||||
raise NotFoundError(
|
||||
f"Movie with external_id {external_id} and provider {metadata_provider} not found."
|
||||
)
|
||||
msg = f"Movie with external_id {external_id} and provider {metadata_provider} not found."
|
||||
raise NotFoundError(msg)
|
||||
return MovieSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
@@ -130,9 +130,10 @@ class MovieRepository:
|
||||
except IntegrityError as e:
|
||||
self.db.rollback()
|
||||
log.error(f"Integrity error while saving movie {movie.name}: {e}")
|
||||
raise ConflictError(
|
||||
msg = (
|
||||
f"Movie with this primary key or unique constraint violation: {e.orig}"
|
||||
) from e
|
||||
)
|
||||
raise ConflictError(msg) from e
|
||||
except SQLAlchemyError as e:
|
||||
self.db.rollback()
|
||||
log.error(f"Database error while saving movie {movie.name}: {e}")
|
||||
@@ -151,7 +152,8 @@ class MovieRepository:
|
||||
movie = self.db.get(Movie, movie_id)
|
||||
if not movie:
|
||||
log.warning(f"Movie with id {movie_id} not found for deletion.")
|
||||
raise NotFoundError(f"Movie with id {movie_id} not found.")
|
||||
msg = f"Movie with id {movie_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
self.db.delete(movie)
|
||||
self.db.commit()
|
||||
log.info(f"Successfully deleted movie with id: {movie_id}")
|
||||
@@ -212,7 +214,8 @@ class MovieRepository:
|
||||
try:
|
||||
movie = self.db.get(Movie, movie_id)
|
||||
if not movie:
|
||||
raise NotFoundError(f"movie with id {movie_id} not found.")
|
||||
msg = f"movie with id {movie_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
movie.library = library
|
||||
self.db.commit()
|
||||
except SQLAlchemyError as e:
|
||||
@@ -233,9 +236,8 @@ class MovieRepository:
|
||||
result = self.db.execute(stmt)
|
||||
if result.rowcount == 0:
|
||||
self.db.rollback()
|
||||
raise NotFoundError(
|
||||
f"movie request with id {movie_request_id} not found."
|
||||
)
|
||||
msg = f"movie request with id {movie_request_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
self.db.commit()
|
||||
# Successfully deleted movie request with id: {movie_request_id}
|
||||
except SQLAlchemyError as e:
|
||||
@@ -395,9 +397,8 @@ class MovieRepository:
|
||||
try:
|
||||
request = self.db.get(MovieRequest, movie_request_id)
|
||||
if not request:
|
||||
raise NotFoundError(
|
||||
f"Movie request with id {movie_request_id} not found."
|
||||
)
|
||||
msg = f"Movie request with id {movie_request_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return MovieRequestSchema.model_validate(request)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
@@ -422,7 +423,8 @@ class MovieRepository:
|
||||
)
|
||||
result = self.db.execute(stmt).unique().scalar_one_or_none()
|
||||
if not result:
|
||||
raise NotFoundError(f"Movie for torrent_id {torrent_id} not found.")
|
||||
msg = f"Movie for torrent_id {torrent_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return MovieSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
@@ -450,7 +452,8 @@ class MovieRepository:
|
||||
"""
|
||||
db_movie = self.db.get(Movie, movie_id)
|
||||
if not db_movie:
|
||||
raise NotFoundError(f"Movie with id {movie_id} not found.")
|
||||
msg = f"Movie with id {movie_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
|
||||
updated = False
|
||||
if name is not None and db_movie.name != name:
|
||||
|
||||
@@ -47,9 +47,8 @@ class MovieRequestBase(BaseModel):
|
||||
@model_validator(mode="after")
|
||||
def ensure_wanted_quality_is_eq_or_gt_min_quality(self) -> "MovieRequestBase":
|
||||
if self.min_quality.value < self.wanted_quality.value:
|
||||
raise ValueError(
|
||||
"wanted_quality must be equal to or lower than minimum_quality."
|
||||
)
|
||||
msg = "wanted_quality must be equal to or lower than minimum_quality."
|
||||
raise ValueError(msg)
|
||||
return self
|
||||
|
||||
|
||||
|
||||
@@ -218,9 +218,10 @@ class MovieService:
|
||||
return False
|
||||
|
||||
else:
|
||||
raise ValueError(
|
||||
msg = (
|
||||
"Either external_id and metadata_provider or movie_id must be provided"
|
||||
)
|
||||
raise ValueError(msg)
|
||||
|
||||
def get_all_available_torrents_for_movie(
|
||||
self, movie: Movie, search_query_override: str = None
|
||||
@@ -462,7 +463,8 @@ class MovieService:
|
||||
:raises ValueError: If the movie request is not authorized.
|
||||
"""
|
||||
if not movie_request.authorized:
|
||||
raise ValueError("Movie request is not authorized")
|
||||
msg = "Movie request is not authorized"
|
||||
raise ValueError(msg)
|
||||
|
||||
log.info(f"Downloading approved movie request {movie_request.id}")
|
||||
|
||||
@@ -663,7 +665,8 @@ class MovieService:
|
||||
source_directory.rename(new_source_path)
|
||||
except Exception as e:
|
||||
log.error(f"Failed to rename {source_directory} to {new_source_path}: {e}")
|
||||
raise Exception("Failed to rename directory") from e
|
||||
msg = "Failed to rename directory"
|
||||
raise Exception(msg) from e
|
||||
|
||||
video_files, subtitle_files, all_files = get_files_for_import(
|
||||
directory=new_source_path
|
||||
|
||||
@@ -24,7 +24,8 @@ class NotificationRepository:
|
||||
result = self.db.get(Notification, id)
|
||||
|
||||
if not result:
|
||||
raise NotFoundError(f"Notification with id {id} not found.")
|
||||
msg = f"Notification with id {id} not found."
|
||||
raise NotFoundError(msg)
|
||||
|
||||
return NotificationSchema.model_validate(result)
|
||||
|
||||
@@ -69,9 +70,8 @@ class NotificationRepository:
|
||||
self.db.commit()
|
||||
except IntegrityError as e:
|
||||
log.error(f"Could not save notification, Error: {e}")
|
||||
raise ConflictError(
|
||||
f"Notification with id {notification.id} already exists."
|
||||
) from None
|
||||
msg = f"Notification with id {notification.id} already exists."
|
||||
raise ConflictError(msg) from None
|
||||
return
|
||||
|
||||
def mark_notification_as_read(self, id: NotificationId) -> None:
|
||||
@@ -88,6 +88,7 @@ class NotificationRepository:
|
||||
stmt = delete(Notification).where(Notification.id == id)
|
||||
result = self.db.execute(stmt)
|
||||
if result.rowcount == 0:
|
||||
raise NotFoundError(f"Notification with id {id} not found.")
|
||||
msg = f"Notification with id {id} not found."
|
||||
raise NotFoundError(msg)
|
||||
self.db.commit()
|
||||
return
|
||||
|
||||
@@ -102,9 +102,8 @@ class QbittorrentDownloadClient(AbstractDownloadClient):
|
||||
log.error(
|
||||
f"Failed to download torrent, API-Answer isn't 'Ok.'; API Answer: {answer}"
|
||||
)
|
||||
raise RuntimeError(
|
||||
f"Failed to download torrent, API-Answer isn't 'Ok.'; API Answer: {answer}"
|
||||
)
|
||||
msg = f"Failed to download torrent, API-Answer isn't 'Ok.'; API Answer: {answer}"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
log.info(f"Successfully processed torrent: {indexer_result.title}")
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ class SabnzbdDownloadClient(AbstractDownloadClient):
|
||||
if not response["status"]:
|
||||
error_msg = response
|
||||
log.error(f"Failed to add NZB to SABnzbd: {error_msg}")
|
||||
raise RuntimeError(f"Failed to add NZB to SABnzbd: {error_msg}")
|
||||
msg = f"Failed to add NZB to SABnzbd: {error_msg}"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
# Generate a hash for the NZB (using title and download URL)
|
||||
nzo_id = response["nzo_ids"][0]
|
||||
|
||||
@@ -79,11 +79,13 @@ class DownloadManager:
|
||||
# Use the usenet flag from the indexer result to determine the client type
|
||||
if indexer_result.usenet:
|
||||
if not self._usenet_client:
|
||||
raise RuntimeError("No usenet download client configured")
|
||||
msg = "No usenet download client configured"
|
||||
raise RuntimeError(msg)
|
||||
return self._usenet_client
|
||||
else:
|
||||
if not self._torrent_client:
|
||||
raise RuntimeError("No torrent download client configured")
|
||||
msg = "No torrent download client configured"
|
||||
raise RuntimeError(msg)
|
||||
return self._torrent_client
|
||||
|
||||
def download(self, indexer_result: IndexerQueryResult) -> Torrent:
|
||||
|
||||
@@ -52,7 +52,8 @@ class TorrentRepository:
|
||||
def get_torrent_by_id(self, torrent_id: TorrentId) -> TorrentSchema:
|
||||
result = self.db.get(Torrent, torrent_id)
|
||||
if result is None:
|
||||
raise NotFoundError(f"Torrent with ID {torrent_id} not found.")
|
||||
msg = f"Torrent with ID {torrent_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return TorrentSchema.model_validate(result)
|
||||
|
||||
def delete_torrent(
|
||||
|
||||
@@ -51,7 +51,8 @@ class TvRepository:
|
||||
)
|
||||
result = self.db.execute(stmt).unique().scalar_one_or_none()
|
||||
if not result:
|
||||
raise NotFoundError(f"Show with id {show_id} not found.")
|
||||
msg = f"Show with id {show_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return ShowSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(f"Database error while retrieving show {show_id}: {e}")
|
||||
@@ -78,9 +79,8 @@ class TvRepository:
|
||||
)
|
||||
result = self.db.execute(stmt).unique().scalar_one_or_none()
|
||||
if not result:
|
||||
raise NotFoundError(
|
||||
f"Show with external_id {external_id} and provider {metadata_provider} not found."
|
||||
)
|
||||
msg = f"Show with external_id {external_id} and provider {metadata_provider} not found."
|
||||
raise NotFoundError(msg)
|
||||
return ShowSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
@@ -178,9 +178,8 @@ class TvRepository:
|
||||
return ShowSchema.model_validate(db_show)
|
||||
except IntegrityError as e:
|
||||
self.db.rollback()
|
||||
raise ConflictError(
|
||||
f"Show with this primary key or unique constraint violation: {e.orig}"
|
||||
) from e
|
||||
msg = f"Show with this primary key or unique constraint violation: {e.orig}"
|
||||
raise ConflictError(msg) from e
|
||||
except SQLAlchemyError as e:
|
||||
self.db.rollback()
|
||||
log.error(f"Database error while saving show {show.name}: {e}")
|
||||
@@ -197,7 +196,8 @@ class TvRepository:
|
||||
try:
|
||||
show = self.db.get(Show, show_id)
|
||||
if not show:
|
||||
raise NotFoundError(f"Show with id {show_id} not found.")
|
||||
msg = f"Show with id {show_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
self.db.delete(show)
|
||||
self.db.commit()
|
||||
except SQLAlchemyError as e:
|
||||
@@ -217,7 +217,8 @@ class TvRepository:
|
||||
try:
|
||||
season = self.db.get(Season, season_id)
|
||||
if not season:
|
||||
raise NotFoundError(f"Season with id {season_id} not found.")
|
||||
msg = f"Season with id {season_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return SeasonSchema.model_validate(season)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(f"Database error while retrieving season {season_id}: {e}")
|
||||
@@ -274,9 +275,8 @@ class TvRepository:
|
||||
result = self.db.execute(stmt)
|
||||
if result.rowcount == 0:
|
||||
self.db.rollback()
|
||||
raise NotFoundError(
|
||||
f"SeasonRequest with id {season_request_id} not found."
|
||||
)
|
||||
msg = f"SeasonRequest with id {season_request_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
self.db.commit()
|
||||
except SQLAlchemyError as e:
|
||||
self.db.rollback()
|
||||
@@ -304,9 +304,8 @@ class TvRepository:
|
||||
)
|
||||
result = self.db.execute(stmt).unique().scalar_one_or_none()
|
||||
if not result:
|
||||
raise NotFoundError(
|
||||
f"Season number {season_number} for show_id {show_id} not found."
|
||||
)
|
||||
msg = f"Season number {season_number} for show_id {show_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return SeasonSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
@@ -403,7 +402,8 @@ class TvRepository:
|
||||
try:
|
||||
show = self.db.get(Show, show_id)
|
||||
if not show:
|
||||
raise NotFoundError(f"Show with id {show_id} not found.")
|
||||
msg = f"Show with id {show_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
show.library = library
|
||||
self.db.commit()
|
||||
except SQLAlchemyError as e:
|
||||
@@ -514,9 +514,8 @@ class TvRepository:
|
||||
request = self.db.get(SeasonRequest, season_request_id)
|
||||
if not request:
|
||||
log.warning(f"Season request with id {season_request_id} not found.")
|
||||
raise NotFoundError(
|
||||
f"Season request with id {season_request_id} not found."
|
||||
)
|
||||
msg = f"Season request with id {season_request_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return SeasonRequestSchema.model_validate(request)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
@@ -542,7 +541,8 @@ class TvRepository:
|
||||
)
|
||||
result = self.db.execute(stmt).unique().scalar_one_or_none()
|
||||
if not result:
|
||||
raise NotFoundError(f"Show for season_id {season_id} not found.")
|
||||
msg = f"Show for season_id {season_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
return ShowSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(f"Database error retrieving show by season_id {season_id}: {e}")
|
||||
@@ -563,7 +563,8 @@ class TvRepository:
|
||||
"""
|
||||
db_show = self.db.get(Show, show_id)
|
||||
if not db_show:
|
||||
raise NotFoundError(f"Show with id {show_id} not found.")
|
||||
msg = f"Show with id {show_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
|
||||
stmt = (
|
||||
select(Season)
|
||||
@@ -612,7 +613,8 @@ class TvRepository:
|
||||
"""
|
||||
db_season = self.db.get(Season, season_id)
|
||||
if not db_season:
|
||||
raise NotFoundError(f"Season with id {season_id} not found.")
|
||||
msg = f"Season with id {season_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
|
||||
stmt = (
|
||||
select(Episode)
|
||||
@@ -660,7 +662,8 @@ class TvRepository:
|
||||
"""
|
||||
db_show = self.db.get(Show, show_id)
|
||||
if not db_show:
|
||||
raise NotFoundError(f"Show with id {show_id} not found.")
|
||||
msg = f"Show with id {show_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
|
||||
updated = False
|
||||
if name is not None and db_show.name != name:
|
||||
@@ -705,7 +708,8 @@ class TvRepository:
|
||||
"""
|
||||
db_season = self.db.get(Season, season_id)
|
||||
if not db_season:
|
||||
raise NotFoundError(f"Season with id {season_id} not found.")
|
||||
msg = f"Season with id {season_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
|
||||
updated = False
|
||||
if name is not None and db_season.name != name:
|
||||
@@ -735,7 +739,8 @@ class TvRepository:
|
||||
"""
|
||||
db_episode = self.db.get(Episode, episode_id)
|
||||
if not db_episode:
|
||||
raise NotFoundError(f"Episode with id {episode_id} not found.")
|
||||
msg = f"Episode with id {episode_id} not found."
|
||||
raise NotFoundError(msg)
|
||||
|
||||
updated = False
|
||||
if title is not None and db_episode.title != title:
|
||||
|
||||
@@ -69,9 +69,8 @@ class SeasonRequestBase(BaseModel):
|
||||
@model_validator(mode="after")
|
||||
def ensure_wanted_quality_is_eq_or_gt_min_quality(self) -> "SeasonRequestBase":
|
||||
if self.min_quality.value < self.wanted_quality.value:
|
||||
raise ValueError(
|
||||
"wanted_quality must be equal to or lower than minimum_quality."
|
||||
)
|
||||
msg = "wanted_quality must be equal to or lower than minimum_quality."
|
||||
raise ValueError(msg)
|
||||
return self
|
||||
|
||||
|
||||
|
||||
@@ -223,9 +223,8 @@ class TvService:
|
||||
except NotFoundError:
|
||||
return False
|
||||
else:
|
||||
raise ValueError(
|
||||
"External ID and metadata provider or Show ID must be provided"
|
||||
)
|
||||
msg = "External ID and metadata provider or Show ID must be provided"
|
||||
raise ValueError(msg)
|
||||
|
||||
def get_all_available_torrents_for_a_season(
|
||||
self, season_number: int, show_id: ShowId, search_query_override: str = None
|
||||
@@ -511,9 +510,8 @@ class TvService:
|
||||
:raises ValueError: If the season request is not authorized.
|
||||
"""
|
||||
if not season_request.authorized:
|
||||
raise ValueError(
|
||||
f"Season request {season_request.id} is not authorized for download"
|
||||
)
|
||||
msg = f"Season request {season_request.id} is not authorized for download"
|
||||
raise ValueError(msg)
|
||||
|
||||
log.info(f"Downloading approved season request {season_request.id}")
|
||||
|
||||
@@ -633,9 +631,8 @@ class TvService:
|
||||
import_file(target_file=target_video_file, source_file=file)
|
||||
return True
|
||||
else:
|
||||
raise Exception(
|
||||
f"Could not find any video file for episode {episode_number} of show {show.name} S{season.number}"
|
||||
)
|
||||
msg = f"Could not find any video file for episode {episode_number} of show {show.name} S{season.number}"
|
||||
raise Exception(msg)
|
||||
|
||||
def import_season(
|
||||
self,
|
||||
@@ -654,7 +651,8 @@ class TvService:
|
||||
season_path.mkdir(parents=True, exist_ok=True)
|
||||
except Exception as e:
|
||||
log.warning(f"Could not create path {season_path}: {e}")
|
||||
raise Exception(f"Could not create path {season_path}") from e
|
||||
msg = f"Could not create path {season_path}"
|
||||
raise Exception(msg) from e
|
||||
|
||||
for episode in season.episodes:
|
||||
try:
|
||||
@@ -896,7 +894,8 @@ class TvService:
|
||||
source_directory.rename(new_source_path)
|
||||
except Exception as e:
|
||||
log.error(f"Failed to rename {source_directory} to {new_source_path}: {e}")
|
||||
raise Exception("Failed to rename source directory") from e
|
||||
msg = "Failed to rename source directory"
|
||||
raise Exception(msg) from e
|
||||
|
||||
video_files, subtitle_files, all_files = get_files_for_import(
|
||||
directory=new_source_path
|
||||
|
||||
Reference in New Issue
Block a user