Added 'imdb_api_access' app

removed 'new_episodes' page
changed series_count algorithm
This commit is contained in:
ayxan 2022-12-16 11:27:51 +04:00
parent 939f8ad578
commit 8ec01acc4c
20 changed files with 318 additions and 256 deletions

View File

@ -6,7 +6,7 @@ class User(AbstractUser):
first_name = None
last_name = None
email = models.EmailField('email', null=True, blank=True, unique=True)
imdb_api_key = models.CharField(max_length=15, blank=False, null=False)
imdb_api_key = models.CharField(max_length=15, blank=False, null=False, unique=True)
email_is_verified = models.BooleanField(default=False)
send_email = models.BooleanField(default=False)

View File

@ -3,7 +3,8 @@ from django.shortcuts import (render,
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from account.forms import ProfileEditingForm
from requests import get
from imdb_api_access._requests import get_request
from imdb_api_access.exceptions import *
from .send_otp import send_otp_view
@ -13,22 +14,19 @@ def profile_editing_view(request):
form = ProfileEditingForm(request.POST, instance=request.user)
if form.is_valid():
if 'imdb_api_key' in form.changed_data:
raw_data = get(f"https://imdb-api.com/en/API/Title/{request.POST['imdb_api_key']}/tt0110413")
if raw_data.status_code != 200:
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')
data = raw_data.json()
if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
messages.info(request, f"IMDB API: {data['errorMessage']}")
return redirect('profile-editing')
elif data['errorMessage'] == 'Invalid API Key':
except MaximumUsageError as e:
messages.info(request, str(e))
return redirect('profile-editing')
except APIError 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, f"IMDB API: {data['errorMessage']}")
messages.info(request, str(e))
return redirect('profile-editing')
if 'email' in form.changed_data:

View File

@ -4,7 +4,8 @@ from django.contrib import messages
from account.forms import RegisterForm
from django.contrib.auth import (login,
authenticate)
from requests import get
from imdb_api_access._requests import get_request
from imdb_api_access.exceptions import *
from django.shortcuts import render
from .send_otp import send_otp_view
@ -13,22 +14,19 @@ def register_view(request): # sourcery skip: extract-method
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
raw_data = get(f"https://imdb-api.com/en/API/Title/{request.POST['imdb_api_key']}/tt0110413")
if raw_data.status_code != 200:
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')
data = raw_data.json()
if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
messages.info(request, f"IMDB API: {data['errorMessage']}")
return redirect('register')
elif data['errorMessage'] == 'Invalid API Key':
except MaximumUsageError as e:
messages.info(request, str(e))
return redirect('register')
except APIError 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, f"IMDB API: {data['errorMessage']}")
messages.info(request, str(e))
return redirect('register')
to_email = form.cleaned_data.get('email')

View File

@ -13,6 +13,6 @@ def get_request(url: str) -> Union[StatusCodeError, APIError, MaximumUsageError,
if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
raise MaximumUsageError()
raise MaximumUsageError(data['errorMessage'])
raise APIError(data['errorMessage'])
return data

View File

@ -20,4 +20,4 @@ class MaximumUsageError(Exception):
self.message = message
def __str__(self) -> str:
return self.message
return f"IMDB API: {self.message}"

View File

@ -6,6 +6,6 @@ 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
new_episodes_count: int
last_season: int
last_episode: int

View File

@ -4,7 +4,6 @@ from .exceptions import *
from .new_series_model import NewSeries
from series.models import SeriesModel
from typing import (List,
Tuple,
Dict,
Union)
@ -15,49 +14,60 @@ class SeriesCounter:
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]:
def get_episode_count(self, series: SeriesModel, data_seasons: Dict) -> Union[StatusCodeError,
APIError,
MaximumUsageError,
Dict]:
# sourcery skip: aware-datetime-for-utc
now_date = datetime.strptime(datetime.strftime(datetime.utcnow(),'%d %b %Y'), '%d %b %Y')
new_episodes_count = 0
data_return = {
'new_episodes_count': 0,
'last_season': series.watched_season,
'last_episode': series.watched_episode
}
seasons = data_seasons['tvSeriesInfo']['seasons']
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}")
for season_number in seasons[seasons.index(str(series.watched_season)):]:
data_episodes = get_request(f"https://imdb-api.com/en/API/SeasonEpisodes/k_ae700oad/{series.imdb_id}/{season_number}")
episodes = data_episodes['episodes']
for episode_number in range(int(series.watched_episode) if season_number == str(series.watched_season) else 0, len(episodes)):
released_date = episodes[episode_number]['released'].replace('.', '')
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
data_return['last_season'] = int(season_number)
data_return['last_episode'] = episode_number+1
data_return['new_episodes_count'] += 1
return new_episodes_count, n, i+1 if new_episodes_count > 0 else 0, 0, 0
except ValueError: return data_return
return data_return
def find_new_series(self, series: List[NewSeries]) -> Union[MaximumUsageError, None]:
def find_new_series(self, series: List[SeriesModel]) -> 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]
try:
data = self.get_episode_count(s, data)
if data['new_episodes_count'] != s.new_episodes_count:
self.new_series_list.append(
NewSeries(series=s, **data)
)
)
except (StatusCodeError, APIError):
self.error_series.append(s)
def find_last_episode(self, series: SeriesModel) -> Union[MaximumUsageError,
StatusCodeError,
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)
return NewSeries(series=series, **data)

View File

@ -10,14 +10,26 @@ class SeriesModel(models.Model):
title = models.CharField(max_length=35, blank=False, null=False)
imdb_id = models.CharField(max_length=10, validators=[MinLengthValidator(9)],
blank=False, null=False)
last_season = models.IntegerField(validators=[
watched_season = models.IntegerField(validators=[
MaxValueValidator(30),
MinValueValidator(1)
], blank=False, null=False)
last_episode = models.IntegerField(validators=[
watched_episode = models.IntegerField(validators=[
MaxValueValidator(60),
MinValueValidator(1)
], blank=False, null=False)
last_season = models.IntegerField(validators=[
MaxValueValidator(30),
MinValueValidator(1)],
default=1)
last_episode = models.IntegerField(validators=[
MaxValueValidator(60),
MinValueValidator(1)],
default=1)
new_episodes_count = models.IntegerField(validators=[
MaxValueValidator(200),
MinValueValidator(0)],
default=0)
show = models.BooleanField(default=True)
slug = AutoSlugField(populate_from='title', unique=True)

View File

@ -5,78 +5,61 @@ from datetime import datetime
from django.template.loader import render_to_string
from django.core.mail import EmailMessage
from celery.utils.log import get_task_logger
from imdb_api_access import SeriesCounter
from imdb_api_access import MaximumUsageError
logger = get_task_logger(__name__)
# logger = get_task_logger(__name__)
def get_request(link):
raw_data = get(link)
if raw_data.status_code == 200:
data = raw_data.json()
if not data['errorMessage']:
return data
logger.info(f"error message: {data['errorMessage']}\nlink: {link}")
return None
logger.info(f"status code: {raw_data.status_code}\nlink: {link}")
def update_series(updated_series):
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
def episode_counter(imdb_api_key, s, data):
now_date = datetime.strptime(datetime.strftime(datetime.utcnow(),'%d %b %Y'), '%d %b %Y')
new_episodes_count = 0
def send_email(user):
series = user.series.filter(show=True).order_by('-id')
for n in data['tvSeriesInfo']['seasons'][data['tvSeriesInfo']['seasons'].index(str(s.last_season)):]:
data = get_request(f"https://imdb-api.com/en/API/SeasonEpisodes/{imdb_api_key}/{s.imdb_id}/{n}")
if data is None: return None
episodes = data['episodes']
for i in range(int(s.last_episode) if n == str(s.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
@shared_task(name='send_emails')
def send_feedback_email_task():
users = User.objects.filter(send_email=True)
for user in users:
series = user.series.filter(show=True).order_by('-id')
series_new_episodes = []
for s in series:
data = get_request(f"https://imdb-api.com/en/API/Title/{user.imdb_api_key}/{s.imdb_id}")
if data is None:
series_new_episodes = []
break
data = episode_counter(user.imdb_api_key, s, data)
if data is None:
series_new_episodes = []
break
if data[0]:
series_new_episodes.append([s,
{'count': data[0],
'last_season': data[1],
'last_episode': data[2]}
])
if series_new_episodes:
message = render_to_string('new_episodes_verification.html', {
series_counter = SeriesCounter(user.imdb_api_key)
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:
update_series(updated_series)
updated_series.save()
message = render_to_string('new_episodes_notification.html', {
'user': user,
'data': series_new_episodes
'new_series_list': series_counter.new_series_list,
'error_series_list': series_counter.error_series,
'maximum_usage': str(e)
})
email = EmailMessage(
'New Episodes!', message, to=[user.email]
)
email.send()
return
return
if series_len:
for updated_series in series_counter.new_series_list:
update_series(updated_series)
updated_series.series.save()
message = render_to_string('new_episodes_notification.html', {
'user': user,
'new_series_list': series_counter.new_series_list,
'error_series_list': series_counter.error_series,
'maximum_usage': ''
})
email = EmailMessage(
'New Episodes!', message, to=[user.email]
)
email.send()
return
@shared_task(name='send_emails')
def send_feedback_email_task():
users = User.objects.filter(send_email=True)
for user in users: send_email(user)

View File

@ -12,7 +12,9 @@
<thead>
<tr>
<th scope="col">Title ({{series.paginator.count}})</th>
<th scope="col">Season - Episode</th>
<th scope="col">Watched</th>
<th scope="col">Last</th>
<th scope="col">Unwatched</th>
<th scope="col">Show</th>
</tr>
</thead>
@ -31,11 +33,19 @@
<img class="trash-icon" src="{% static 'icons/trash.png' %}" width="24px" height="24px">
</a>
</th>
<td>
<a href="https://www.imdb.com/title/{{s.imdb_id}}/episodes?season={{s.last_season}}" style="text-decoration: none;" target="_blank">
{{s.watched_season}} - {{s.watched_episode}}
</a>
</td>
<td>
<a href="https://www.imdb.com/title/{{s.imdb_id}}/episodes?season={{s.last_season}}" style="text-decoration: none;" target="_blank">
{{s.last_season}} - {{s.last_episode}}
</a>
</td>
<td>
{{s.new_episodes_count}}
</td>
<td>
{% if s.show %}
<img src="{% static 'icons/true-check-button.png' %}" width="22px" height="22px">
@ -51,7 +61,13 @@
<div style="margin-bottom: 8.5rem;">
<div class="btn-new-episode">
<button type="button" class="btn btn-outline-primary">
<a href="/series/new-episodes/" style="text-decoration: none; color: inherit;">New Episodes</a>
<a href="/" style="text-decoration: none; color: inherit;">All</a>
</button>
<button type="button" class="btn btn-outline-primary" style="margin-left: 4px;">
<a href="?new=true" style="text-decoration: none; color: inherit;">Unwatched</a>
</button> <br>
<button type="button" class="btn btn-outline-primary" style="margin-top: 4.7%; margin-bottom: 77%;">
<a href="/series/new-episodes/" style="text-decoration: none; color: inherit;">Update</a>
</button>
</div>

View File

@ -1,51 +0,0 @@
{% extends 'base.html' %}
{% load static %}
{% block title %} New Episodes of The Series {% endblock title %}
{% block content %}
<link rel="stylesheet" href="{% static 'css/new_episodes.css' %}">
<div class="table-div">
<table class="table">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Watched Season - Episode</th>
<th scope="col">Last Season - Episode</th>
<th scope="col">Number of New Episodes</th>
</tr>
</thead>
<tbody>
{% for d in data %}
<tr>
<th scope="row">
<a href="https://www.imdb.com/title/{{s.imdb_id}}/" style="text-decoration: none;" target="_blank">
{{d.series.title}}
</a>
<br>
<a class="btn mr-1 update-btn" style="padding: 0;" href="{% url 'update-series' d.series.slug %}">
<img class="edit-icon" src="{% static 'icons/edit.png' %}" width="21px" height="21px">
</a>
<a class="btn delete-btn" href="{% url 'delete-series' d.series.slug %}">
<img class="trash-icon" src="{% static 'icons/trash.png' %}" width="24px" height="24px">
</a>
</th>
<td>
<a href="https://www.imdb.com/title/{{d.series.imdb_id}}/episodes?season={{d.series.last_season}}" style="text-decoration: none;" target="_blank">
{{d.series.last_season}} - {{d.series.last_episode}}
</a>
</td>
<td>
<a href="https://www.imdb.com/title/{{d.series.imdb_id}}/episodes?season={{d.last_season}}" style="text-decoration: none;" target="_blank">
{{d.last_season}} - {{d.last_episode}}
</a>
</td>
<td>{{d.new_episodes_count}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock content %}

View File

@ -0,0 +1,36 @@
{% autoescape off %}
Hi {{ user.username }},
There are new episodes of the series you recorded.
{% if maximum_usage %}
Some series could not be updated ({{maximum_usage}})
{% for s in new_series_list %}
{{s.series.title}}: watched - {{s.series.watched_season}}-{{s.series.watched_episode}}
last - {{s.last_season}}-{{s.last_episode}}
new episodes count - {{s.new_episodes_count}}
{% endfor %}
{% else %}
{% if error_series_list %}
Some series could not be updated:
{% for e in error_series_list %}
e.title
{% endfor %}
{% for s in new_series_list %}
{{s.series.title}}: watched - {{s.series.watched_season}}-{{s.series.watched_episode}}
last - {{s.last_season}}-{{s.last_episode}}
new episodes count - {{s.new_episodes_count}}
{% endfor %}
{% else %}
{% for s in new_series_list %}
{{s.series.title}}: watched - {{s.series.watched_season}}-{{s.series.watched_episode}}
last - {{s.last_season}}-{{s.last_episode}}
new episodes count - {{s.new_episodes_count}}
{% endfor %}
{% endif %}
{% endif %}
{% endautoescape %}

View File

@ -1,9 +0,0 @@
{% autoescape off %}
Hi {{ user.username }},
There are new episodes of the series you recorded.
{% for s, d in data %}
{{d.count}} episodes of {{s.title}} you haven't watched (watched episode: {{s.last_season}} - {{s.last_episode}}).
{% endfor %}
{% endautoescape %}

View File

@ -4,15 +4,17 @@ from django.urls import reverse_lazy, reverse
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.shortcuts import redirect
from requests import get
from datetime import datetime
from imdb_api_access import SeriesCounter
from imdb_api_access._requests import get_request
from imdb_api_access.exceptions import *
class AddSeriesView(LoginRequiredMixin, CreateView):
login_url = reverse_lazy('login')
template_name = 'add_series.html'
model = SeriesModel
fields = ('title', 'imdb_id', 'last_season', 'last_episode', 'show')
fields = ('title', 'imdb_id', 'watched_season', 'watched_episode', 'show')
def get_success_url(self):
messages.success(self.request, 'Series Added')
@ -22,58 +24,73 @@ class AddSeriesView(LoginRequiredMixin, CreateView):
series = form.save(commit=False)
series.user = self.request.user
raw_data = get(f"https://imdb-api.com/en/API/Title/{series.user.imdb_api_key}/{series.imdb_id}")
if raw_data.status_code != 200:
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')
data = raw_data.json()
if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('add-series')
except MaximumUsageError:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('add-series')
except APIError:
form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form)
if not data['tvSeriesInfo']:
form.add_error('imdb_id', 'This is not a TV series id.')
return self.form_invalid(form)
seasons = data['tvSeriesInfo']['seasons']
if str(series.last_season) not in seasons:
form.add_error('last_season', 'The season number is not correct.')
if str(series.watched_season) not in seasons:
form.add_error('watched_season', 'The season number is not correct.')
return self.form_invalid(form)
raw_data = get(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.last_season}")
if raw_data.status_code != 200:
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')
data = raw_data.json()
if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('add-series')
except MaximumUsageError:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('add-series')
except APIError:
form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form)
episodes = data['episodes']
episodes = data['episodes']
episodes_count = len(episodes)
if series.last_episode > episodes_count:
form.add_error('last_episode', 'The episode number is not correct.')
if series.watched_episode > episodes_count:
form.add_error('watched_episode', 'The episode number is not correct.')
return self.form_invalid(form)
released_date = episodes[int(series.last_episode) - 1]['released'].replace('.', '')
released_date = episodes[int(series.watched_episode) - 1]['released'].replace('.', '')
now_date = datetime.strptime(datetime.strftime(datetime.utcnow(),'%d %b %Y'), '%d %b %Y')
try:
last_episode_date = datetime.strptime(released_date, '%d %b %Y')
if (last_episode_date - now_date).days > 0:
watched_episode_date = datetime.strptime(released_date, '%d %b %Y')
if (watched_episode_date - now_date).days > 0:
raise ValueError
except ValueError:
form.add_error('last_episode', 'This episode has not been published yet.')
form.add_error('watched_episode', 'This episode has not been published yet.')
return self.form_invalid(form)
series_counter = SeriesCounter(self.request.user.imdb_api_key)
try:
new_series = series_counter.find_last_episode(series)
series.last_season = new_series.last_season
series.last_episode = new_series.last_episode
series.new_episodes_count = new_series.new_episodes_count
except (StatusCodeError, APIError):
messages.info(self.request, 'TV Series can not added. Please try again later.')
return redirect('add-series')
except MaximumUsageError as e:
messages.info(self.request, str(e))
return redirect('homepage')
series.save()
form.save_m2m()
return super().form_valid(form)

View File

@ -7,7 +7,7 @@ from django.contrib import messages
class SeriesDeleteView(LoginRequiredMixin, DeleteView):
login_url = reverse_lazy('login')
template_name = 'article_deletion_confirmation.html'
template_name = 'series_deletion_confirmation.html'
def get_success_url(self):
messages.success(self.request, 'Series Deleted')

View File

@ -2,13 +2,19 @@ from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from account.models import User
from django.db.models import Q
@login_required(login_url='/account/login')
def homepage_view(request):
user = User.objects.get(id=request.user.id)
series_true = user.series.filter(show=True).order_by('-id')
series_false = user.series.filter(show=False).order_by('-id')
if request.GET.get('new') == 'true':
series_true = user.series.filter(~Q(new_episodes_count=0), show=True).order_by('-id')
series_false = user.series.filter(~Q(new_episodes_count=0), show=False).order_by('-id')
else:
series_true = user.series.filter(show=True).order_by('-id')
series_false = user.series.filter(show=False).order_by('-id')
page = request.GET.get('page')
paginator = Paginator(list(series_true) + list(series_false), 5)

View File

@ -1,5 +1,4 @@
from django.shortcuts import (render,
redirect)
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from account.models import User
@ -14,10 +13,41 @@ def new_episodes_view(request):
series_counter = SeriesCounter(request.user.imdb_api_key)
try:
series_counter.find_new_series(series)
except MaximumUsageError as e: ...
# messages.warning(request, f"{e} (some series could not be updated)")
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:
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.save()
messages.warning(request,
f"{series_len} series updated (some series could not be updated). {str(e)}")
return redirect('homepage')
if series_counter.new_series_list:
return render(request, 'new_episodes.html', context={'data': series_counter.new_series_list})
messages.warning(request, "There are no new episodes of any series :(")
messages.warning(request,
f"Series could not be updated. {str(e)}")
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')
if error_series_len:
messages.warning(request,
f"{error_series_len} series could not be updated.")
return redirect('homepage')
messages.warning(request, "0 series updated :(")
return redirect('homepage')

View File

@ -5,14 +5,16 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.shortcuts import (get_object_or_404,
redirect)
from requests import get
from datetime import datetime
from imdb_api_access._requests import get_request
from imdb_api_access import SeriesCounter
from imdb_api_access.exceptions import *
class UpdateSeriesView(LoginRequiredMixin, UpdateView):
login_url = reverse_lazy('login')
template_name = 'update_series.html'
fields = ('title', 'imdb_id', 'last_season', 'last_episode', 'show')
fields = ('title', 'imdb_id', 'watched_season', 'watched_episode', 'show')
def get_object(self):
return get_object_or_404(SeriesModel, slug=self.kwargs.get('slug'), user=self.request.user)
@ -25,22 +27,20 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView):
series = form.save(commit=False)
series.user = self.request.user
if not {'imdb_id', 'last_season', 'last_episode'} & set(form.changed_data):
if not {'imdb_id', 'watched_season', 'watched_episode'} & set(form.changed_data):
series.save()
form.save_m2m()
return super().form_valid(form)
raw_data = get(f"https://imdb-api.com/en/API/Title/{series.user.imdb_api_key}/{series.imdb_id}")
if raw_data.status_code != 200:
messages.info(self.request, 'TV Series can not updated. Please try again.')
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'))
data = raw_data.json()
if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
messages.info(self.request, f"IMDB Key: {data['errorMessage']}")
return redirect("update-series", self.kwargs.get('slug'))
except MaximumUsageError:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('update-series', self.kwargs.get('slug'))
except APIError:
form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form)
@ -49,39 +49,55 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView):
return self.form_invalid(form)
seasons = data['tvSeriesInfo']['seasons']
if str(series.last_season) not in seasons:
form.add_error('last_season', 'The season number is not correct.')
if str(series.watched_season) not in seasons:
form.add_error('watched_season', 'The season number is not correct.')
return self.form_invalid(form)
raw_data = get(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.last_season}")
if raw_data.status_code != 200:
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('update-series', self.kwargs.get('slug'))
data = raw_data.json()
if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('update-series', self.kwargs.get('slug'))
except MaximumUsageError:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('update-series', self.kwargs.get('slug'))
except APIError:
form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form)
episodes = data['episodes']
episodes = data['episodes']
episodes_count = len(episodes)
if series.last_episode > episodes_count:
form.add_error('last_episode', 'The episode number is not correct.')
if series.watched_episode > episodes_count:
form.add_error('watched_episode', 'The episode number is not correct.')
return self.form_invalid(form)
released_date = episodes[int(series.last_episode) - 1]['released'].replace('.', '')
released_date = episodes[int(series.watched_episode) - 1]['released'].replace('.', '')
now_date = datetime.strptime(datetime.strftime(datetime.utcnow(),'%d %b %Y'), '%d %b %Y')
try:
last_episode_date = datetime.strptime(released_date, '%d %b %Y')
if (last_episode_date - now_date).days > 0:
raise ValueError
except ValueError:
form.add_error('last_episode', 'This episode has not been published yet.')
form.add_error('watched_episode', 'This episode has not been published yet.')
return self.form_invalid(form)
series_counter = SeriesCounter(self.request.user.imdb_api_key)
try:
new_series = series_counter.find_last_episode(series)
series.last_season = new_series.last_season
series.last_episode = new_series.last_episode
series.new_episodes_count = new_series.new_episodes_count
except (StatusCodeError, APIError):
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:
messages.info(self.request, str(e))
return redirect('homepage')
series.save()
form.save_m2m()
return super().form_valid(form)

View File

@ -14,7 +14,7 @@
<a class="btn btn-outline-light btn-floating m-1 contact-links" style="padding: 2px 4px 2px 4px;" target="_blank" href="https://github.com/Ayxan-z" role="button">
<img class="contact-img" src="{% static 'icons/github.png' %}">
</a>
<a class="btn btn-outline-light btn-floating m-1 contact-links" style="padding: 5px 6px 5px 6px;" target="_blank" href="https://www.linkedin.com/in/ayxan-shahsuvarov-59a314187" role="button">
<a class="btn btn-outline-light btn-floating m-1 contact-links" style="padding: 5px 6px 5px 6px;" target="_blank" href="https://www.linkedin.com/in/aykhan-shahsuvarov-59a314187/" role="button">
<img class="contact-img" src="{% static 'icons/linkedin.png' %}" style="background-color: white;">
</a>
<a class="btn btn-outline-light btn-floating m-1 contact-links" style="padding: 6px 7px 6px 7px;" target="_blank" href="mailto:ayxan.shahsuvarov1@gmail.com" role="button">