Add IMDB and CSFD id support to movies
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
232245d602
commit
75dbd6cadc
@ -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,6 +14,8 @@
|
|||||||
</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>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
<select class="form-select" id="suggested_by" name="suggested_by">
|
<select class="form-select" id="suggested_by" name="suggested_by">
|
||||||
{% if request.user.is_staff %}
|
{% if request.user.is_staff %}
|
||||||
{% for user in users %}
|
{% for user in users %}
|
||||||
@ -23,6 +26,32 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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>
|
||||||
<input type="submit" value="Submit" class="btn btn-primary">
|
<input type="submit" value="Submit" class="btn btn-primary">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -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>
|
||||||
|
@ -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"]
|
23
watchlist/migrations/0006_movie_csfd_id_movie_imdb_id.py
Normal file
23
watchlist/migrations/0006_movie_csfd_id_movie_imdb_id.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
@ -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]),
|
||||||
|
),
|
||||||
|
]
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user