Series table added to home page
| @@ -16,10 +16,18 @@ 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': |             if data['errorMessage'] == 'Invalid API Key': | ||||||
|                 form.add_error('imdb_api_key', 'Invalid API Key') |                 form.add_error('imdb_api_key', 'Invalid API Key') | ||||||
|                 return render(request, 'register.html', context={"form": form}) |                 return render(request, 'register.html', context={"form": form}) | ||||||
|  |  | ||||||
|  |             if data['errorMessage']: | ||||||
|  |                 messages.info(request, f"IMDB API: {data['errorMessage']}") | ||||||
|  |                 return redirect('register') | ||||||
|  |  | ||||||
|             form.save() |             form.save() | ||||||
|             username = form.cleaned_data.get('username') |             username = form.cleaned_data.get('username') | ||||||
|             password = form.cleaned_data.get('password1') |             password = form.cleaned_data.get('password1') | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ from .base import * | |||||||
|  |  | ||||||
| DEBUG = True | DEBUG = True | ||||||
|  |  | ||||||
| ALLOWED_HOSTS = [] | ALLOWED_HOSTS = ['*'] | ||||||
|  |  | ||||||
| DATABASES = { | DATABASES = { | ||||||
|     'default': { |     'default': { | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| {% extends 'base.html' %} | {% extends 'base.html' %} | ||||||
|  | {% load static %} | ||||||
|  |  | ||||||
| {% block title %} Home Page {% endblock title %} | {% block title %} Home Page {% endblock title %} | ||||||
|  |  | ||||||
| @@ -6,4 +7,66 @@ | |||||||
|  |  | ||||||
| {% include 'components/message.html' %} | {% include 'components/message.html' %} | ||||||
|  |  | ||||||
|  | <table class="table" style="margin-bottom: 1.5rem;"> | ||||||
|  |     <thead> | ||||||
|  |         <tr> | ||||||
|  |             <th scope="col">Title</th> | ||||||
|  |             <th scope="col">Season, Episode</th> | ||||||
|  |             <th scope="col">Show</th> | ||||||
|  |         </tr> | ||||||
|  |     </thead> | ||||||
|  |     <tbody> | ||||||
|  |         {% for s in series %} | ||||||
|  |             <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"> | ||||||
|  |                         <!-- <i class="fa fa-edit fa-lg" style="font-size: 19px;"></i> --> | ||||||
|  |                     </a> | ||||||
|  |                     <a class="btn delete-btn" href="{% url 'delete-series' s.slug %}"> | ||||||
|  |                         <img src="{% static 'icons/trash.png' %}" width="24px" height="24px"> | ||||||
|  |                         <!-- <i class="fa fa-trash fa-lg" style="font-size: 19px;"></i> --> | ||||||
|  |                     </a> | ||||||
|  |                 </th> | ||||||
|  |                 <td>{{s.last_season}} - {{s.last_episode}}</td> | ||||||
|  |                 <td> | ||||||
|  |                     {% if s.show %} | ||||||
|  |                         <img src="{% static 'icons/true-check-button.png' %}" width="22px" height="22px"> | ||||||
|  |                     {% else %} | ||||||
|  |                         <img src="{% static 'icons/false-check-button.png' %}" width="22px" height="22px"> | ||||||
|  |                     {% endif %} | ||||||
|  |                 </td> | ||||||
|  |             </tr> | ||||||
|  |         {% endfor %} | ||||||
|  |     </tbody> | ||||||
|  | </table> | ||||||
|  |  | ||||||
|  | <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">First Page</a> | ||||||
|  |             </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> | ||||||
|  |  | ||||||
|  |         {% if series.has_next %} | ||||||
|  |             <li class="page-item"> | ||||||
|  |                 <a class="page-link" href="?page={{series.next_page_number}}">></a> | ||||||
|  |             </li> | ||||||
|  |             <li class="page-item"> | ||||||
|  |                 <a class="page-link" href="?page={{series.paginator.num_pages}}">Last Page</a> | ||||||
|  |             </li> | ||||||
|  |         {% endif %} | ||||||
|  |     </ul> | ||||||
|  | </nav> | ||||||
|  |  | ||||||
| {% endblock content %} | {% endblock content %} | ||||||
| @@ -28,6 +28,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']: | ||||||
|             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) | ||||||
| @@ -41,8 +45,13 @@ class AddSeriesView(LoginRequiredMixin, CreateView): | |||||||
|             form.add_error('last_season', 'The season number is not correct.') |             form.add_error('last_season', 'The season number is not correct.') | ||||||
|             return self.form_invalid(form) |             return self.form_invalid(form) | ||||||
|  |  | ||||||
|         data = get(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.last_season}").json() |         raw_data = get(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.last_season}") | ||||||
|         episodes_count = len(data['episodes']) |         if raw_data.status_code != 200: | ||||||
|  |             messages.info(self.request, 'TV Series can not added. Please try again.') | ||||||
|  |             return redirect('add-series') | ||||||
|  |         episodes = raw_data.json()['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) | ||||||
|   | |||||||
| @@ -1,7 +1,13 @@ | |||||||
| from django.shortcuts import render | from django.shortcuts import render | ||||||
| from django.contrib.auth.decorators import login_required | from django.contrib.auth.decorators import login_required | ||||||
|  | from django.core.paginator import Paginator | ||||||
|  | from account.models import User | ||||||
|  |  | ||||||
|  |  | ||||||
| @login_required(login_url='/account/login') | @login_required(login_url='/account/login') | ||||||
| def homepage_view(request): | def homepage_view(request): | ||||||
|     return render(request, 'homepage.html') |     series = User.objects.get(id=request.user.id).series.all().order_by('-id') | ||||||
|  |     page = request.GET.get('page') | ||||||
|  |     paginator = Paginator(series, 5) | ||||||
|  |  | ||||||
|  |     return render(request, 'homepage.html', context={'series': paginator.get_page(page)}) | ||||||
| @@ -31,6 +31,10 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView): | |||||||
|             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 Key: {data['errorMessage']}") | ||||||
|  |             return redirect('add-series') | ||||||
|  |  | ||||||
|         if data['errorMessage']: |         if data['errorMessage']: | ||||||
|             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) | ||||||
| @@ -44,8 +48,13 @@ class UpdateSeriesView(LoginRequiredMixin, UpdateView): | |||||||
|             form.add_error('last_season', 'The season number is not correct.') |             form.add_error('last_season', 'The season number is not correct.') | ||||||
|             return self.form_invalid(form) |             return self.form_invalid(form) | ||||||
|  |  | ||||||
|         data = get(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.last_season}").json() |         raw_data = get(f"https://imdb-api.com/en/API/SeasonEpisodes/{series.user.imdb_api_key}/{series.imdb_id}/{series.last_season}") | ||||||
|         episodes_count = len(data['episodes']) |         if raw_data.status_code != 200: | ||||||
|  |             messages.info(self.request, 'TV Series can not added. Please try again.') | ||||||
|  |             return redirect('add-series') | ||||||
|  |         episodes = raw_data.json()['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) | ||||||
|   | |||||||
| @@ -13,23 +13,44 @@ footer { | |||||||
| } | } | ||||||
|  |  | ||||||
| .div-right { | .div-right { | ||||||
|     margin-top: 1rem; |     margin-top: 0.45rem; | ||||||
|     margin-right: 1.5rem; |     margin-right: 1.5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| footer div span a { | footer div span a { | ||||||
|     color: inherit; |     color: inherit; | ||||||
|     text-decoration: none; |     text-decoration: none; | ||||||
|  |     font-size: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .contact-links{ | .contact-links { | ||||||
|     border: 0; |     border: 0; | ||||||
|     padding-top: 4px; |  | ||||||
|     padding-bottom: 4px; |  | ||||||
|     padding-left: 8px; |  | ||||||
|     padding-right: 8px; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| .contact-icons{ | .contact-img { | ||||||
|     font-size: 23px; |     width: 33px; | ||||||
|  |     height: 33px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media only screen and (max-width: 520px) { | ||||||
|  |     .div-left { | ||||||
|  |         margin-top: 1.35rem; | ||||||
|  |         margin-left: 0.6rem; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     .div-right { | ||||||
|  |         margin-top: 0.65rem; | ||||||
|  |         margin-right: 0.2rem; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     footer div span a { | ||||||
|  |         color: inherit; | ||||||
|  |         text-decoration: none; | ||||||
|  |         font-size: 0.8rem; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .contact-img { | ||||||
|  |         width: 23px; | ||||||
|  |         height: 23px; | ||||||
|  |     } | ||||||
| } | } | ||||||
							
								
								
									
										21
									
								
								src/static/css/navbar.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,21 @@ | |||||||
|  | .logo { | ||||||
|  |     width: 48px; | ||||||
|  |     height: 50px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .logo-link { | ||||||
|  |     padding-top: 2px; | ||||||
|  |     padding-bottom: 2px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media only screen and (max-width: 510px) { | ||||||
|  |     .logo { | ||||||
|  |         width: 44px; | ||||||
|  |         height: 44px; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .logo-link { | ||||||
|  |         padding-top: 0; | ||||||
|  |         padding-bottom: 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								src/static/icons/edit.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 9.8 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/static/icons/email.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 5.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/static/icons/false-check-button.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 16 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/static/icons/github.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 25 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/static/icons/linkedin.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 7.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/static/icons/trash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 8.8 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/static/icons/true-check-button.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 17 KiB | 
| @@ -10,7 +10,6 @@ | |||||||
|  |  | ||||||
|     <!-- Bootstrap CSS --> |     <!-- Bootstrap CSS --> | ||||||
|     <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> |     <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> | ||||||
|     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"> |  | ||||||
|      |      | ||||||
|     <title>{% block title %}{% endblock title %}</title> |     <title>{% block title %}{% endblock title %}</title> | ||||||
| </head> | </head> | ||||||
|   | |||||||
| @@ -11,14 +11,14 @@ | |||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <div class="div-right" style="float: right;"> |     <div class="div-right" style="float: right;"> | ||||||
|         <a class="btn btn-outline-light btn-floating m-1 contact-links" target="_blank" href="https://github.com/Ayxan-z" role="button"> |         <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"> | ||||||
|             <i class="fab fa-github contact-icons"></i> |             <img class="contact-img" src="{% static 'icons/github.png' %}"> | ||||||
|         </a> |         </a> | ||||||
|         <a class="btn btn-outline-light btn-floating m-1 contact-links" 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/ayxan-shahsuvarov-59a314187" role="button"> | ||||||
|             <i class="fab fa-linkedin-in contact-icons"></i> |             <img class="contact-img" src="{% static 'icons/linkedin.png' %}" style="background-color: white;"> | ||||||
|         </a> |         </a> | ||||||
|         <a class="btn btn-outline-light btn-floating m-1 contact-links" target="_blank" href="mailto:ayxan.shahsuvarov1@gmail.com" role="button"> |         <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"> | ||||||
|             <i class="fa fa-envelope contact-icons"></i> |             <img class="contact-img" src="{% static 'icons/email.png' %}" style="background-color: white;"> | ||||||
|         </a> |         </a> | ||||||
|     </div> |     </div> | ||||||
| </footer> | </footer> | ||||||
| @@ -1,10 +1,12 @@ | |||||||
| {% load static %} | {% load static %} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | <link rel="stylesheet" href="{% static 'css/navbar.css' %}"> | ||||||
|  |  | ||||||
| <nav class="navbar navbar-expand-lg bg-dark navbar-dark"> | <nav class="navbar navbar-expand-lg bg-dark navbar-dark"> | ||||||
|     <div class="container-fluid"> |     <div class="container-fluid"> | ||||||
|         <a class="navbar-brand" href="/" style="padding-top: 2px; padding-bottom: 2px;"> |         <a class="logo-link navbar-brand" href="/"> | ||||||
|             <img src="{% static 'icons/retro-tv.png' %}" width="55px" height="55px"> |             <img class="logo" src="{% static 'icons/retro-tv.png' %}"> | ||||||
|         </a> |         </a> | ||||||
|         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> |         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> | ||||||
|             <span class="navbar-toggler-icon"></span> |             <span class="navbar-toggler-icon"></span> | ||||||
|   | |||||||
 ayxan
					ayxan