Add IMDB and CSFD id support to movies
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Michal Kunc 2023-02-10 15:21:28 +01:00
parent 232245d602
commit 75dbd6cadc
7 changed files with 128 additions and 13 deletions

View File

@ -1,6 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<div class="container-lg"> <div class="container-lg">
{% if error %}<div class="alert alert-warning">{{error}}</div>{% endif %}
<form action="{% url 'watchlist:delete' movie.id %}" method="post"> <form action="{% url 'watchlist:delete' movie.id %}" method="post">
{% csrf_token %} {% csrf_token %}
<input type="submit" value="Delete movie" class="btn btn-danger"> <input type="submit" value="Delete movie" class="btn btn-danger">
@ -13,15 +14,43 @@
</div> </div>
<div> <div>
<label class="form-label" for="suggested_by" name="suggested_by">Suggested by</label> <label class="form-label" for="suggested_by" name="suggested_by">Suggested by</label>
<select class="form-select" id="suggested_by" name="suggested_by"> <div class="row">
{% if request.user.is_staff %} <div class="col-auto">
{% for user in users %} <select class="form-select" id="suggested_by" name="suggested_by">
<option value="{{ user.username }}" {% if user.username == movie.suggested_by.username %} selected {% endif %} >{{user.username}}</option> {% if request.user.is_staff %}
{% endfor %} {% for user in users %}
{% else %} <option value="{{ user.username }}" {% if user.username == movie.suggested_by.username %} selected {% endif %} >{{user.username}}</option>
<option value="{{ movie.suggested_by.username }} disabled">{{movie.suggested_by.username}}</option> {% endfor %}
{% endif %} {% else %}
</select> <option value="{{ movie.suggested_by.username }} disabled">{{movie.suggested_by.username}}</option>
{% endif %}
</select>
</div>
</div>
</div>
<div>
<label class="form-label" for="imdb_id">IMDB id</label>
<div class="row">
<div class="col-auto">
<input class="form-control" id="imdb_id" name="imdb_id" {% if movie.imdb_id %}value="{{movie.imdb_id}}"{%endif%}>
<div class="form-text">ID like <code>tt5580390</code> or whole URL.</div>
</div>
<div class="col-3">
<a class="btn btn-secondary" href="https://www.imdb.com/find/?q={{movie.name}}" referrerpolicy="no-referrer" target="_blank">Search</a>
</div>
</div>
</div>
<div>
<label class="form-label" for="csfd_id">ČSFD id</label>
<div class="row">
<div class="col-auto">
<input class="form-control" id="csfd_id" name="csfd_id" {% if movie.csfd_id %}value="{{movie.csfd_id}}"{%endif%}>
<div class="form-text">ID like <code>277495</code> or whole URL.</div>
</div>
<div class="col-3">
<a class="btn btn-secondary" href="https://www.csfd.cz/hledat/?q={{movie.name}}" referrerpolicy="no-referrer" target="_blank">Search</a>
</div>
</div>
</div> </div>
<input type="submit" value="Submit" class="btn btn-primary"> <input type="submit" value="Submit" class="btn btn-primary">
</form> </form>

View File

@ -3,7 +3,10 @@
<div class="container-lg"> <div class="container-lg">
<h1 class="display-1">{{ movie.name }}</h1> <h1 class="display-1">{{ movie.name }}</h1>
<p class="text-secondary">Suggested by: {{movie.suggested_by.username}}</p> <p class="text-secondary">Suggested by: {{movie.suggested_by.username}}</p>
<div class="mb-2">{% if request.user.is_staff or movie.suggested_by == request.user %}<a class="btn btn-sm btn-danger" href="{% url 'watchlist:edit' movie.id %}">Edit</a>{% endif %}<a class="btn btn-sm btn-secondary" href="https://www.imdb.com/find/?q={{movie.name}}" referrerpolicy="no-referrer" target="_blank">IMDB</a><a class="btn btn-sm btn-secondary" href="https://www.csfd.cz/hledat/?q={{movie.name}}" referrerpolicy="no-referrer" target="_blank">ČSFD</a></div> <div class="mb-2">
{% if request.user.is_staff or movie.suggested_by == request.user %}<a class="btn btn-sm btn-danger" href="{% url 'watchlist:edit' movie.id %}">Edit</a>{% endif %}
<a class="btn btn-sm btn-secondary" href="{% if movie.imdb_id %}https://www.imdb.com/title/{{movie.imdb_id}}/{%else%}https://www.imdb.com/find/?q={{movie.name}}{%endif%}" referrerpolicy="no-referrer" target="_blank">IMDB{% if movie.imdb_id == '' %}*{%endif%}</a>
<a class="btn btn-sm btn-secondary" href="{% if movie.csfd_id %}https://www.csfd.cz/film/{{movie.csfd_id}}{%else%}https://www.csfd.cz/hledat/?q={{movie.name}}{%endif%}" referrerpolicy="no-referrer" target="_blank">ČSFD{% if movie.csfd_id == '' %}*{%endif%}</a></div>
<h2>Votes</h2> <h2>Votes</h2>
{% if votes|length == 0 %} {% if votes|length == 0 %}
<p>Nobody voted yet, be first...</p> <p>Nobody voted yet, be first...</p>

View File

@ -6,4 +6,4 @@ class MovieEditForm(forms.ModelForm):
class Meta: class Meta:
model = models.Movie model = models.Movie
fields = ["name", "suggested_by", "watched"] fields = ["name", "suggested_by", "watched", "imdb_id", "csfd_id"]

View File

@ -0,0 +1,23 @@
# Generated by Django 4.1.5 on 2023-02-10 12:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('watchlist', '0005_movievote_comment'),
]
operations = [
migrations.AddField(
model_name='movie',
name='csfd_id',
field=models.IntegerField(null=True),
),
migrations.AddField(
model_name='movie',
name='imdb_id',
field=models.CharField(blank=True, max_length=32),
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 4.1.5 on 2023-02-10 13:26
from django.db import migrations, models
import watchlist.models
class Migration(migrations.Migration):
dependencies = [
('watchlist', '0006_movie_csfd_id_movie_imdb_id'),
]
operations = [
migrations.AlterField(
model_name='movie',
name='csfd_id',
field=models.CharField(blank=True, default='', max_length=32, validators=[watchlist.models.validate_imdb_id]),
preserve_default=False,
),
migrations.AlterField(
model_name='movie',
name='imdb_id',
field=models.CharField(blank=True, max_length=32, validators=[watchlist.models.validate_csfd_id]),
),
]

View File

@ -1,8 +1,19 @@
import re
from functools import reduce from functools import reduce
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib import admin from django.contrib import admin
IMDB_ID_RE = re.compile(r'(?P<id>tt\d{7,})')
CSFD_ID_RE = re.compile(r'(?P<id>\d+)')
def validate_imdb_id(v: str) -> bool:
return IMDB_ID_RE.match(v)
def validate_csfd_id(v: str) -> bool:
return CSFD_ID_RE.match(v)
class Movie(models.Model): class Movie(models.Model):
class Meta: class Meta:
@ -13,6 +24,8 @@ class Movie(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
suggested_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) suggested_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
watched = models.BooleanField(default=False) watched = models.BooleanField(default=False)
imdb_id = models.CharField(max_length=32, blank=True, validators=[validate_csfd_id])
csfd_id = models.CharField(max_length=32, blank=True, validators=[validate_imdb_id])
@property @property
def score(self): def score(self):

View File

@ -71,6 +71,7 @@ class EditView(generic.DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["users"] = User.objects.all() if self.request.user.has_perm("watchlist.moderate_movies") else None context["users"] = User.objects.all() if self.request.user.has_perm("watchlist.moderate_movies") else None
context["error"] = self.request.GET.get("error", None)
return context return context
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -84,7 +85,28 @@ class EditView(generic.DetailView):
if not self.can_edit_movie(request): if not self.can_edit_movie(request):
return HttpResponseForbidden("You cannot edit this object.") return HttpResponseForbidden("You cannot edit this object.")
if "name" in request.POST: if "name" in request.POST:
self.object.name = request.POST["name"] name = request.POST["name"]
if name == '':
return HttpResponseRedirect(reverse('watchlist:edit', args=(kwargs["pk"],)) + "?error=Invalid%20name")
self.object.name = name
if "imdb_id" in request.POST:
if request.POST["imdb_id"] == '':
if self.object.imdb_id != '':
self.object.imdb_id = ''
else:
match = models.IMDB_ID_RE.search(request.POST["imdb_id"])
if not match:
return HttpResponseRedirect(reverse('watchlist:edit', args=(kwargs["pk"],)) + "?error=Invalid%20IMDB%20ID")
self.object.imdb_id = match.group()
if "csfd_id" in request.POST:
if request.POST["csfd_id"] == '':
if self.object.csfd_id != '':
self.object.csfd_id = ''
else:
match = models.CSFD_ID_RE.search(request.POST["csfd_id"])
if not match:
return HttpResponseRedirect(reverse('watchlist:edit', args=(kwargs["pk"],)) + "?error=Invalid%20CSFD%20ID")
self.object.csfd_id = match.group()
if "suggested_by" in request.POST: if "suggested_by" in request.POST:
if request.user.has_perm('watchlist.moderate_movies'): if request.user.has_perm('watchlist.moderate_movies'):
new_suggestor = User.objects.filter(username=request.POST["suggested_by"]).first() new_suggestor = User.objects.filter(username=request.POST["suggested_by"]).first()
@ -105,7 +127,7 @@ def submit(request):
return HttpResponseForbidden("You can't add new movies.") return HttpResponseForbidden("You can't add new movies.")
movie = models.Movie(name=request.POST["name"], suggested_by=request.user, watched=False) movie = models.Movie(name=request.POST["name"], suggested_by=request.user, watched=False)
movie.save() movie.save()
return HttpResponseRedirect(reverse("watchlist:index")) return HttpResponseRedirect(reverse("watchlist:edit", args=(movie.id,)))
@login_required @login_required
@require_POST @require_POST