diff --git a/.gitignore b/.gitignore index eda6bef..ac69a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,4 @@ Backup-codes-series.notification.txt celerybeat-schedule databasepostgresql_env SeriesRobot.pem -certbot -imdb_api_access \ No newline at end of file +certbot \ No newline at end of file diff --git a/src/imdb_api_access/__init__.py b/src/imdb_api_access/__init__.py new file mode 100644 index 0000000..35d2270 --- /dev/null +++ b/src/imdb_api_access/__init__.py @@ -0,0 +1,2 @@ +from .series_counter import SeriesCounter +from .exceptions import * \ No newline at end of file diff --git a/src/imdb_api_access/_requests.py b/src/imdb_api_access/_requests.py new file mode 100644 index 0000000..e06f593 --- /dev/null +++ b/src/imdb_api_access/_requests.py @@ -0,0 +1,18 @@ +from requests import get +from typing import (Union, + Dict) +from .exceptions import * + + +def get_request(url: str) -> Union[StatusCodeError, APIError, MaximumUsageError, Dict]: + raw_data = get(url) + + if raw_data.status_code != 200: + raise StatusCodeError(raw_data.status_code) + data = raw_data.json() + + if data['errorMessage']: + if 'Maximum usage' in data['errorMessage']: + raise MaximumUsageError() + raise APIError(data['errorMessage']) + return data \ No newline at end of file diff --git a/src/imdb_api_access/exceptions.py b/src/imdb_api_access/exceptions.py new file mode 100644 index 0000000..16704b7 --- /dev/null +++ b/src/imdb_api_access/exceptions.py @@ -0,0 +1,23 @@ +from typing import Union + + +class StatusCodeError(Exception): + def __init__(self, status_code: Union[int, str] = 404) -> None: + self.status_code = status_code + + def __str__(self) -> str: + return f"request response status code: {self.status_code}" + +class APIError(Exception): + def __init__(self, message: str = 'Unknown Error') -> None: + self.message = message + + def __str__(self) -> str: + return f"IMDB API: {self.message}" + +class MaximumUsageError(Exception): + def __init__(self, message: str): + self.message = message + + def __str__(self) -> str: + return self.message \ No newline at end of file diff --git a/src/imdb_api_access/new_series_model.py b/src/imdb_api_access/new_series_model.py new file mode 100644 index 0000000..2ce725c --- /dev/null +++ b/src/imdb_api_access/new_series_model.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass +from series.models import SeriesModel +from typing import Optional + + +@dataclass +class NewSeries: + series: SeriesModel + new_episodes_count: Optional[int] = None + last_season: Optional[int] = None + last_episode: Optional[int] = None \ No newline at end of file diff --git a/src/imdb_api_access/series_counter.py b/src/imdb_api_access/series_counter.py new file mode 100644 index 0000000..1e92ceb --- /dev/null +++ b/src/imdb_api_access/series_counter.py @@ -0,0 +1,63 @@ +from ._requests import get_request +from datetime import datetime +from .exceptions import * +from .new_series_model import NewSeries +from series.models import SeriesModel +from typing import (List, + Tuple, + Dict, + Union) + + +class SeriesCounter: + def __init__(self, api_key: str) -> None: + self.api_key = api_key + self.new_series_list: List[NewSeries] = [] + self.error_series: List[SeriesModel] = [] + + def get_episode_count(self, series: SeriesModel, data: Dict) -> Union[StatusCodeError, APIError, MaximumUsageError, Tuple]: + # sourcery skip: aware-datetime-for-utc + now_date = datetime.strptime(datetime.strftime(datetime.utcnow(),'%d %b %Y'), '%d %b %Y') + new_episodes_count = 0 + + for n in data['tvSeriesInfo']['seasons'][data['tvSeriesInfo']['seasons'].index(str(series.last_season)):]: + data = get_request(f"https://imdb-api.com/en/API/SeasonEpisodes/{self.api_key}/{series.imdb_id}/{n}") + + episodes = data['episodes'] + for i in range(int(series.last_episode) if n == str(series.last_season) else 0, len(episodes)): + released_date = episodes[i]['released'].replace('.', '') + try: + episode_date = datetime.strptime(released_date, '%d %b %Y') + if (episode_date - now_date).days > 0: + raise ValueError + except ValueError: + try: + return new_episodes_count, int(last_n)+1, last_i+1 if new_episodes_count > 0 else 0, 0, 0 + except UnboundLocalError: + return new_episodes_count, int(n), last_i+1 if new_episodes_count > 0 else 0, 0, 0 + + last_i = i + new_episodes_count += 1 + last_n = n + + return new_episodes_count, n, i+1 if new_episodes_count > 0 else 0, 0, 0 + + def find_new_series(self, series: List[NewSeries]) -> Union[MaximumUsageError, None]: + for s in series: + try: + data = get_request(f"https://imdb-api.com/en/API/Title/{self.api_key}/{s.imdb_id}") + + except (StatusCodeError, APIError): + self.error_series.append(s) + + else: + data = self.get_episode_count(s, data) + if data[0]: + self.new_series_list.append( + NewSeries( + series=s, + new_episodes_count=data[0], + last_season=data[1], + last_episode=data[2] + ) + ) \ No newline at end of file diff --git a/src/series/templates/new_episodes.html b/src/series/templates/new_episodes.html index e9123b4..67600a7 100644 --- a/src/series/templates/new_episodes.html +++ b/src/series/templates/new_episodes.html @@ -17,31 +17,31 @@
- {% for s, d in data %} + {% for d in data %}