From b87da3b032f031510e71207d1408eb75d7b10d52 Mon Sep 17 00:00:00 2001 From: Aykhan Date: Sat, 22 Jul 2023 18:39:29 +0400 Subject: [PATCH] Added InvalidAPIKey exception to imdb_api_access --- src/account/views/profile_editing.py | 7 ++++++- src/account/views/register.py | 6 +++++- src/imdb_api_access/_requests.py | 14 ++++++++++++- src/imdb_api_access/exceptions.py | 7 +++++++ src/imdb_api_access/series_counter.py | 30 ++++++++++++++++++--------- src/series/tasks.py | 9 +++++++- src/series/views/add_series.py | 12 ++++++++--- src/series/views/new_episodes.py | 14 ++++++++++++- src/series/views/update_series.py | 7 +++++-- 9 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/account/views/profile_editing.py b/src/account/views/profile_editing.py index 430e53e..1bd8e2f 100644 --- a/src/account/views/profile_editing.py +++ b/src/account/views/profile_editing.py @@ -16,21 +16,26 @@ def profile_editing_view(request): if 'imdb_api_key' in form.changed_data: try: get_request(f"https://imdb-api.com/en/API/Title/{request.POST['imdb_api_key']}/tt0110413") + except StatusCodeError: messages.info(request, 'Account not created. Please try again later') return redirect('profile-editing') + except MaximumUsageError as e: messages.info(request, str(e)) return redirect('profile-editing') - except APIError as e: + + except (APIError, InvalidAPIKey) as e: if e.message == 'Invalid API Key': form.add_error('imdb_api_key', 'Invalid API Key') return render(request, 'profile_editing.html', context={"form": form}) + messages.info(request, str(e)) return redirect('profile-editing') if 'email' in form.changed_data: to_email = form.cleaned_data.get('email') + if to_email is not None: if form.cleaned_data.get('send_email'): form.add_error('send_email', 'You must verify the email before enabling the send email feature') diff --git a/src/account/views/register.py b/src/account/views/register.py index 92b85c8..c3e5980 100644 --- a/src/account/views/register.py +++ b/src/account/views/register.py @@ -16,16 +16,20 @@ def register_view(request): # sourcery skip: extract-method if form.is_valid(): try: get_request(f"https://imdb-api.com/en/API/Title/{request.POST['imdb_api_key']}/tt0110413") + except StatusCodeError: messages.info(request, 'Account not created. Please try again later') return redirect('register') + except MaximumUsageError as e: messages.info(request, str(e)) return redirect('register') - except APIError as e: + + except (APIError, InvalidAPIKey) as e: if e.message == 'Invalid API Key': form.add_error('imdb_api_key', 'Invalid API Key') return render(request, 'register.html', context={"form": form}) + messages.info(request, str(e)) return redirect('register') diff --git a/src/imdb_api_access/_requests.py b/src/imdb_api_access/_requests.py index 2951184..7840a28 100644 --- a/src/imdb_api_access/_requests.py +++ b/src/imdb_api_access/_requests.py @@ -4,7 +4,14 @@ from typing import (Union, from .exceptions import * -def get_request(url: str) -> Union[StatusCodeError, APIError, MaximumUsageError, Dict]: +def get_request(url: str) -> Union[ + StatusCodeError, + APIError, + MaximumUsageError, + InvalidAPIKey, + Dict + ]: + raw_data = get(url, timeout=7) if raw_data.status_code != 200: @@ -14,5 +21,10 @@ def get_request(url: str) -> Union[StatusCodeError, APIError, MaximumUsageError, if data['errorMessage']: if 'Maximum usage' in data['errorMessage']: raise MaximumUsageError(data['errorMessage']) + + elif 'Upgrade your account to use the service' in data['errorMessage']: + raise InvalidAPIKey() + 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 index 2a2e80a..a2e815c 100644 --- a/src/imdb_api_access/exceptions.py +++ b/src/imdb_api_access/exceptions.py @@ -19,5 +19,12 @@ class MaximumUsageError(Exception): def __init__(self, message: str): self.message = message + def __str__(self) -> str: + return f"IMDB API: {self.message}" + +class InvalidAPIKey(Exception): + def __init__(self, message: str = 'Upgrade your imdb-api account to use the service'): + self.message = message + def __str__(self) -> str: return f"IMDB API: {self.message}" \ No newline at end of file diff --git a/src/imdb_api_access/series_counter.py b/src/imdb_api_access/series_counter.py index 9d4e569..22be6b3 100644 --- a/src/imdb_api_access/series_counter.py +++ b/src/imdb_api_access/series_counter.py @@ -14,11 +14,13 @@ class SeriesCounter: self.new_series_list: List[NewSeries] = [] self.error_series: List[SeriesModel] = [] - def get_episode_count(self, series: SeriesModel, data_seasons: Dict) -> Union[StatusCodeError, - APIError, - MaximumUsageError, - Dict]: - # sourcery skip: aware-datetime-for-utc + def get_episode_count(self, series: SeriesModel, data_seasons: Dict) -> Union[ + StatusCodeError, + APIError, + MaximumUsageError, + Dict + ]: + now_date = datetime.strptime(datetime.strftime(datetime.utcnow(),'%d %b %Y'), '%d %b %Y') data_return = { 'new_episodes_count': 0, @@ -46,10 +48,15 @@ class SeriesCounter: except ValueError: return data_return return data_return - def find_new_series(self, series: List[SeriesModel]) -> Union[MaximumUsageError, None]: + def find_new_series(self, series: List[SeriesModel]) -> Union[ + MaximumUsageError, + InvalidAPIKey, + 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) @@ -63,10 +70,13 @@ class SeriesCounter: except (StatusCodeError, APIError): self.error_series.append(s) - def find_last_episode(self, series: SeriesModel) -> Union[MaximumUsageError, - StatusCodeError, - APIError, - NewSeries]: + def find_last_episode(self, series: SeriesModel) -> Union[ + MaximumUsageError, + StatusCodeError, + InvalidAPIKey, + APIError, + NewSeries + ]: data = get_request(f"https://imdb-api.com/en/API/Title/{self.api_key}/{series.imdb_id}") data = self.get_episode_count(series, data) diff --git a/src/series/tasks.py b/src/series/tasks.py index a8882b9..eb92a43 100644 --- a/src/series/tasks.py +++ b/src/series/tasks.py @@ -2,7 +2,10 @@ from celery import shared_task from account.models import User from django.template.loader import render_to_string from imdb_api_access import SeriesCounter -from imdb_api_access import MaximumUsageError +from imdb_api_access import ( + MaximumUsageError, + InvalidAPIKey +) from django.core.mail import (EmailMessage, get_connection) # from celery.utils.log import get_task_logger @@ -22,6 +25,7 @@ def compose_email(user): try: series_counter.find_new_series(series) series_len = len(series_counter.new_series_list) + except MaximumUsageError as e: if series_len := len(series_counter.new_series_list): for updated_series in series_counter.new_series_list: @@ -37,6 +41,9 @@ def compose_email(user): ) return + except InvalidAPIKey: + return + if series_len: for updated_series in series_counter.new_series_list: update_series(updated_series) diff --git a/src/series/views/add_series.py b/src/series/views/add_series.py index a47308c..ff3f76b 100644 --- a/src/series/views/add_series.py +++ b/src/series/views/add_series.py @@ -26,12 +26,15 @@ class AddSeriesView(LoginRequiredMixin, CreateView): try: data = get_request(f"https://imdb-api.com/en/API/Title/{series.user.imdb_api_key}/{series.imdb_id}") + except StatusCodeError: messages.info(self.request, 'TV Series can not added. Please try again.') return redirect('add-series') - except MaximumUsageError as e: + + except (MaximumUsageError, InvalidAPIKey) as e: messages.info(self.request, str(e)) return redirect('add-series') + except APIError: form.add_error('imdb_id', 'ID is not correct.') return self.form_invalid(form) @@ -48,12 +51,15 @@ class AddSeriesView(LoginRequiredMixin, CreateView): try: data = get_request(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.watched_season}") + except StatusCodeError: messages.info(self.request, 'TV Series can not added. Please try again.') return redirect('add-series') - except MaximumUsageError as e: + + except (MaximumUsageError, InvalidAPIKey) as e: messages.info(self.request, str(e)) return redirect('add-series') + except APIError: form.add_error('imdb_id', 'ID is not correct.') return self.form_invalid(form) @@ -87,7 +93,7 @@ class AddSeriesView(LoginRequiredMixin, CreateView): messages.info(self.request, 'TV Series can not added. Please try again later.') return redirect('add-series') - except MaximumUsageError as e: + except (MaximumUsageError, InvalidAPIKey) as e: messages.info(self.request, str(e)) return redirect('homepage') diff --git a/src/series/views/new_episodes.py b/src/series/views/new_episodes.py index e0730f3..79803d7 100644 --- a/src/series/views/new_episodes.py +++ b/src/series/views/new_episodes.py @@ -3,7 +3,10 @@ from django.contrib.auth.decorators import login_required from django.contrib import messages from account.models import User from imdb_api_access import SeriesCounter -from imdb_api_access import MaximumUsageError +from imdb_api_access import ( + MaximumUsageError, + InvalidAPIKey +) @login_required(login_url='/account/login') @@ -11,10 +14,12 @@ def new_episodes_view(request): series = User.objects.get(id=request.user.id).series.filter(show=True).order_by('-id') series_counter = SeriesCounter(request.user.imdb_api_key) + try: series_counter.find_new_series(series) series_len = len(series_counter.new_series_list) error_series_len = len(series_counter.error_series) + except MaximumUsageError as e: if series_len := len(series_counter.new_series_list): for updated_series in series_counter.new_series_list: @@ -30,16 +35,23 @@ def new_episodes_view(request): f"Series could not be updated. {str(e)}") return redirect('homepage') + except InvalidAPIKey as e: + messages.info(request, + f"Series could not be updated: {str(e.message)}") + return redirect('homepage') + if series_len: for updated_series in series_counter.new_series_list: updated_series.series.last_season = updated_series.last_season updated_series.series.last_episode = updated_series.last_episode updated_series.series.new_episodes_count = updated_series.new_episodes_count updated_series.series.save() + if error_series_len: messages.warning(request, f"{series_len} series updated ({error_series_len} series could not be updated).") return redirect('homepage') + messages.warning(request, f"{series_len} series updated.") return redirect('homepage') diff --git a/src/series/views/update_series.py b/src/series/views/update_series.py index d46723e..d6bfca4 100644 --- a/src/series/views/update_series.py +++ b/src/series/views/update_series.py @@ -35,12 +35,15 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView): try: data = get_request(f"https://imdb-api.com/en/API/Title/{series.user.imdb_api_key}/{series.imdb_id}") + except StatusCodeError: messages.info(self.request, 'TV Series can not added. Please try again.') return redirect('update-series', self.kwargs.get('slug')) - except MaximumUsageError as e: + + except (MaximumUsageError, InvalidAPIKey) as e: messages.info(self.request, str(e)) return redirect('update-series', self.kwargs.get('slug')) + except APIError: form.add_error('imdb_id', 'ID is not correct.') return self.form_invalid(form) @@ -95,7 +98,7 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView): messages.info(self.request, 'TV Series can not updated. Please try again later.') return redirect('update-series', self.kwargs.get('slug')) - except MaximumUsageError as e: + except (MaximumUsageError, InvalidAPIKey) as e: messages.info(self.request, str(e)) return redirect('homepage')