new_episodes added

This commit is contained in:
ayxan 2022-09-01 07:13:27 +04:00
parent d8fe62b23e
commit ad2d78a766
12 changed files with 229 additions and 52 deletions

View File

@ -2,7 +2,7 @@
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block title %} Profil Güncəllə {% endblock title %} {% block title %} Edit Profile {% endblock title %}
{% block content %} {% block content %}

View File

@ -2,6 +2,7 @@ from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib import messages from django.contrib import messages
from account.forms import ProfileEditingForm from account.forms import ProfileEditingForm
from requests import get
@login_required(login_url='/') @login_required(login_url='/')
@ -9,8 +10,25 @@ def profile_editing_view(request):
if request.method == 'POST': if request.method == 'POST':
form = ProfileEditingForm(request.POST, instance=request.user) form = ProfileEditingForm(request.POST, instance=request.user)
if form.is_valid(): if form.is_valid():
form.save() raw_data = get(f"https://imdb-api.com/en/API/Title/{request.POST['imdb_api_key']}/tt0110413")
if raw_data.status_code != 200:
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':
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']}")
return redirect('profile-editing')
form.save()
messages.success(request, 'Profile Updated') messages.success(request, 'Profile Updated')
return redirect('homepage') return redirect('homepage')

View File

@ -16,15 +16,14 @@ def register_view(request):
return redirect('register') return redirect('register')
data = raw_data.json() data = raw_data.json()
if 'Maximum usage' in data['errorMessage']:
messages.info(request, f"IMDB API: {data['errorMessage']}")
return redirect('register')
if data['errorMessage'] == 'Invalid API Key':
form.add_error('imdb_api_key', 'Invalid API Key')
return render(request, 'register.html', context={"form": form})
if data['errorMessage']: 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':
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, f"IMDB API: {data['errorMessage']}")
return redirect('register') return redirect('register')

View File

@ -12,7 +12,7 @@
<style> <style>
.btn:hover { .btn:hover {
background: #fff; background: #fff;
color: #218838; color: #0B5ED7;
} }
</style> </style>
<input type="submit" value="Add" class="btn btn-primary mt-3 mb-5"> <input type="submit" value="Add" class="btn btn-primary mt-3 mb-5">

View File

@ -10,8 +10,8 @@
<table class="table" style="margin-bottom: 1.5rem;"> <table class="table" style="margin-bottom: 1.5rem;">
<thead> <thead>
<tr> <tr>
<th scope="col">Title</th> <th scope="col">Title ({{series.paginator.count}})</th>
<th scope="col">Season, Episode</th> <th scope="col">Season - Episode</th>
<th scope="col">Show</th> <th scope="col">Show</th>
</tr> </tr>
</thead> </thead>
@ -25,11 +25,9 @@
<br> <br>
<a class="btn mr-1 update-btn" style="padding: 0;" href="{% url 'update-series' s.slug %}"> <a class="btn mr-1 update-btn" style="padding: 0;" href="{% url 'update-series' s.slug %}">
<img src="{% static 'icons/edit.png' %}" width="21px" height="21px"> <img src="{% static 'icons/edit.png' %}" width="21px" height="21px">
<!-- <i class="fa fa-edit fa-lg" style="font-size: 19px;"></i> -->
</a> </a>
<a class="btn delete-btn" href="{% url 'delete-series' s.slug %}"> <a class="btn delete-btn" href="{% url 'delete-series' s.slug %}">
<img src="{% static 'icons/trash.png' %}" width="24px" height="24px"> <img src="{% static 'icons/trash.png' %}" width="24px" height="24px">
<!-- <i class="fa fa-trash fa-lg" style="font-size: 19px;"></i> -->
</a> </a>
</th> </th>
<td>{{s.last_season}} - {{s.last_episode}}</td> <td>{{s.last_season}} - {{s.last_episode}}</td>
@ -45,28 +43,38 @@
</tbody> </tbody>
</table> </table>
<nav aria-label="Page navigation example"> <div style="float: left;">
<ul class="pagination justify-content-end"> <button type="button" class="btn btn-outline-primary">
{% if series.has_previous %} <a href="/series/new-episodes/" style="text-decoration: none; color: inherit;">New Episodes</a>
<li class="page-item"> </button>
<a class="page-link" href="?page=1">First Page</a> </div>
</li>
<li class="page-item">
<a class="page-link" href="?page={{series.previous_page_number}}"><</a>
</li>
{% endif %}
<li class="page-item"><a class="page-link" href="#">{{series.number}}</a></li> <div style="float: right;">
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end">
{% if series.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1"><<</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{series.previous_page_number}}"><</a>
</li>
{% endif %}
{% if series.has_next %} {% if series.paginator.count > 5 %}
<li class="page-item"> <li class="page-item"><a class="page-link" href="#">{{series.number}}</a></li>
<a class="page-link" href="?page={{series.next_page_number}}">></a> {% endif %}
</li>
<li class="page-item"> {% if series.has_next %}
<a class="page-link" href="?page={{series.paginator.num_pages}}">Last Page</a> <li class="page-item">
</li> <a class="page-link" href="?page={{series.next_page_number}}">></a>
{% endif %} </li>
</ul> <li class="page-item">
</nav> <a class="page-link" href="?page={{series.paginator.num_pages}}">>></a>
</li>
{% endif %}
</ul>
</nav>
</div>
{% endblock content %} {% endblock content %}

View File

@ -0,0 +1,40 @@
{% extends 'base.html' %}
{% load static %}
{% block title %} New Episodes of The Series {% endblock title %}
{% block content %}
<table class="table" style="margin-bottom: 1.5rem;">
<thead>
<tr>
<th scope="col">Title ({{series.paginator.count}})</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 s, d in data %}
<tr>
<th scope="row">
<a href="https://www.imdb.com/title/{{s.imdb_id}}/" style="text-decoration: none;" target="_blank">
{{s.title}}
</a>
<br>
<a class="btn mr-1 update-btn" style="padding: 0;" href="{% url 'update-series' s.slug %}">
<img src="{% static 'icons/edit.png' %}" width="21px" height="21px">
</a>
<a class="btn delete-btn" href="{% url 'delete-series' s.slug %}">
<img src="{% static 'icons/trash.png' %}" width="24px" height="24px">
</a>
</th>
<td>{{s.last_season}} - {{s.last_episode}}</td>
<td>{{d.last_season}} - {{d.last_episode}}</td>
<td>{{d.count}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock content %}

View File

@ -6,6 +6,8 @@
{% block content %} {% block content %}
{% include 'components/message.html' %}
<form enctype="multipart/form-data" method="POST"> <form enctype="multipart/form-data" method="POST">
{% csrf_token %} {% csrf_token %}
{{form|crispy}} {{form|crispy}}

View File

@ -4,7 +4,8 @@ from series import views
urlpatterns = [ urlpatterns = [
path('', views.homepage_view, name='homepage'), path('', views.homepage_view, name='homepage'),
path('series/add', views.AddSeriesView.as_view(), name='add-series'), path('series/add/', views.AddSeriesView.as_view(), name='add-series'),
path('series/update/<slug:slug>', views.UpdateSeriesView.as_view(), name='update-series'), path('series/update/<slug:slug>', views.UpdateSeriesView.as_view(), name='update-series'),
path('series/delete/<slug:slug>', views.SeriesDeleteView.as_view(), name='delete-series'), path('series/delete/<slug:slug>', views.SeriesDeleteView.as_view(), name='delete-series'),
path('series/new-episodes/', views.new_episodes_view, name='new-episodes'),
] ]

View File

@ -2,3 +2,4 @@ from .homepage import homepage_view
from .add_series import AddSeriesView from .add_series import AddSeriesView
from .update_series import UpdateSeriesView from .update_series import UpdateSeriesView
from .delete_series import SeriesDeleteView from .delete_series import SeriesDeleteView
from .new_episodes import new_episodes_view

View File

@ -5,6 +5,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect
from requests import get from requests import get
from datetime import datetime
class AddSeriesView(LoginRequiredMixin, CreateView): class AddSeriesView(LoginRequiredMixin, CreateView):
@ -28,11 +29,10 @@ class AddSeriesView(LoginRequiredMixin, CreateView):
return redirect('add-series') return redirect('add-series')
data = raw_data.json() data = raw_data.json()
if 'Maximum usage' in data['errorMessage']:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('add-series')
if data['errorMessage']: if data['errorMessage']:
if 'Maximum usage' in data['errorMessage']:
messages.info(self.request, f"IMDB API: {data['errorMessage']}")
return redirect('add-series')
form.add_error('imdb_id', 'ID is not correct.') form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form) return self.form_invalid(form)
@ -49,13 +49,31 @@ class AddSeriesView(LoginRequiredMixin, CreateView):
if raw_data.status_code != 200: if raw_data.status_code != 200:
messages.info(self.request, 'TV Series can not added. Please try again.') messages.info(self.request, 'TV Series can not added. Please try again.')
return redirect('add-series') return redirect('add-series')
episodes = raw_data.json()['episodes'] 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')
form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form)
episodes = data['episodes']
episodes_count = len(episodes) episodes_count = len(episodes)
if series.last_episode > episodes_count: if series.last_episode > episodes_count:
form.add_error('last_episode', 'The episode number is not correct.') form.add_error('last_episode', 'The episode number is not correct.')
return self.form_invalid(form) return self.form_invalid(form)
released_date = episodes[int(series.last_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.')
return self.form_invalid(form)
series.save() series.save()
form.save_m2m() form.save_m2m()
return super().form_valid(form) return super().form_valid(form)

View File

@ -0,0 +1,68 @@
from django.shortcuts import (render,
redirect)
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from account.models import User
from requests import get
from datetime import datetime
from django.core.paginator import Paginator
def get_request(request, link):
raw_data = get(link)
if raw_data.status_code != 200:
messages.info(request, "Can't search for TV Series. Please try again.")
return redirect('homepage')
data = raw_data.json()
if data['errorMessage']:
messages.info(request, f"IMDB API: {data['errorMessage']}")
return redirect('homepage')
return data
def episode_counter(request, s, data):
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(s.last_season)):]:
data = get_request(request, f"https://imdb-api.com/en/API/SeasonEpisodes/{request.user.imdb_api_key}/{s.imdb_id}/{n}")
if type(data) is not dict: return data
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: return new_episodes_count, last_n, last_i+1
last_i = i
new_episodes_count += 1
last_n = n
return new_episodes_count, n, i+1
@login_required(login_url='/account/login')
def new_episodes_view(request):
series = User.objects.get(id=request.user.id).series.filter(show=True).order_by('-id')
series_new_episodes = []
for s in series:
data = get_request(request, f"https://imdb-api.com/en/API/Title/{request.user.imdb_api_key}/{s.imdb_id}")
if type(data) is not dict: return data
data = episode_counter(request, s, data)
if type(data) is not list: return data
if data[0]:
series_new_episodes.append([s,
{'count': data[0],
'last_season': data[1],
'last_episode': data[2]}
])
if series_new_episodes:
page = request.GET.get('page')
paginator = Paginator(series_new_episodes, 1)
return render(request, 'new_episodes.html', context={'data': paginator.get_page(page)})
messages.warning(request, "There are no new episodes of any series :(")
return redirect('homepage')

View File

@ -6,6 +6,7 @@ from django.contrib import messages
from django.shortcuts import (get_object_or_404, from django.shortcuts import (get_object_or_404,
redirect) redirect)
from requests import get from requests import get
from datetime import datetime
class UpdateSeriesView(LoginRequiredMixin, UpdateView): class UpdateSeriesView(LoginRequiredMixin, UpdateView):
@ -24,18 +25,22 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView):
series = form.save(commit=False) series = form.save(commit=False)
series.user = self.request.user series.user = self.request.user
if not {'imdb_id', 'last_season', 'last_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}") 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: if raw_data.status_code != 200:
messages.info(self.request, 'TV Series can not updated. Please try again.') messages.info(self.request, 'TV Series can not updated. Please try again.')
return redirect('add-series') return redirect('update-series', self.kwargs.get('slug'))
data = raw_data.json() data = raw_data.json()
if 'Maximum usage' in data['errorMessage']:
messages.info(self.request, f"IMDB Key: {data['errorMessage']}")
return redirect('add-series')
if data['errorMessage']: 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'))
form.add_error('imdb_id', 'ID is not correct.') form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form) return self.form_invalid(form)
@ -51,15 +56,32 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView):
raw_data = get(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.last_season}") 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: if raw_data.status_code != 200:
messages.info(self.request, 'TV Series can not added. Please try again.') messages.info(self.request, 'TV Series can not added. Please try again.')
return redirect('add-series') return redirect('update-series', self.kwargs.get('slug'))
episodes = raw_data.json()['episodes'] 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'))
form.add_error('imdb_id', 'ID is not correct.')
return self.form_invalid(form)
episodes = data['episodes']
episodes_count = len(episodes) episodes_count = len(episodes)
if series.last_episode > episodes_count: if series.last_episode > episodes_count:
form.add_error('last_episode', 'The episode number is not correct.') form.add_error('last_episode', 'The episode number is not correct.')
return self.form_invalid(form) return self.form_invalid(form)
released_date = episodes[int(series.last_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.')
return self.form_invalid(form)
series.save() series.save()
form.save_m2m() form.save_m2m()
return super().form_valid(form) return super().form_valid(form)