Compare commits
8 Commits
87086cdce9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a48df0f44d | |||
| 9230c35be6 | |||
| adada84e9a | |||
| 8cb0554696 | |||
| 947d9f740c | |||
| c84ae1334e | |||
| 1abc910621 | |||
| 5895714fd5 |
+11
@@ -3,6 +3,17 @@ type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: python:3.10
|
||||
commands:
|
||||
- pip3 install poetry --quiet
|
||||
- poetry install --no-root --quiet
|
||||
- export SECRET_KEY=$(openssl rand -hex 32)
|
||||
- export DATABASE_URL=sqlite://$(mktemp)/db.sqlite3
|
||||
- poetry run ./manage.py test
|
||||
environment:
|
||||
ALLOWED_HOSTS: localhost,127.0.0.1
|
||||
DEBUG: True
|
||||
- name: deploy
|
||||
image: caprover/cli-caprover:2.2.3
|
||||
commands:
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
repos:
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: poetry
|
||||
name: poetry
|
||||
language: system
|
||||
entry: poetry check
|
||||
files: '^(pyproject.toml|poetry.lock)$'
|
||||
pass_filenames: false
|
||||
# - id: black
|
||||
# name: black
|
||||
# language: system
|
||||
# entry: poetry run black --target-version py39
|
||||
# types_or: [python, pyi]
|
||||
# require_serial: true
|
||||
# - id: isort
|
||||
# name: isort
|
||||
# language: system
|
||||
# entry: poetry run isort --profile black --python-version 39
|
||||
# types_or: [cython, pyi, python]
|
||||
# require_serial: true
|
||||
# - id: flake8
|
||||
# name: flake8
|
||||
# language: system
|
||||
# entry: poetry run flake8
|
||||
# types_or: [python]
|
||||
# files: "^.*\\.py$"
|
||||
# - id: mypy
|
||||
# name: mypy
|
||||
# language: system
|
||||
# entry: poetry run mypy --strict --python-version 3.9
|
||||
# types_or: [python, pyi]
|
||||
# files: "^.*\\.pyi?$"
|
||||
- id: test
|
||||
name: test
|
||||
language: system
|
||||
entry: poetry run ./manage.py test
|
||||
types_or: [python]
|
||||
files: "^.*\\.py$"
|
||||
pass_filenames: false
|
||||
@@ -14,7 +14,7 @@
|
||||
<p>Total score: {{ movie.score }}, seen by: {{ movie.seen_score }}.
|
||||
<ul>
|
||||
{% for vote in votes %}
|
||||
<li>{{vote.user.username}} {% if vote.seen %}(seen){% endif %} – {% if vote.vote == 1 %}👍{% elif vote.vote == 0 %}No opinion{% elif vote.vote == -1 %}👎{%endif%}{% if vote.comment is not None %} – {{vote.comment}}{% endif %}</li>
|
||||
<li>{{vote.user.username}} {% if vote.seen %}(seen){% endif %} – {% if vote.vote == 1 %}👍{% elif vote.vote == 0 %}No opinion{% elif vote.vote == -1 %}👎{%endif%}{% if vote.comment != "" %} – {{vote.comment}}{% endif %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
+5
-1
@@ -3,7 +3,8 @@ from django.contrib import admin
|
||||
from . import models
|
||||
|
||||
class MovieVoteInline(admin.StackedInline):
|
||||
model = models.MovieVote()
|
||||
model = models.MovieVote
|
||||
extra = 0
|
||||
|
||||
class MovieAdmin(admin.ModelAdmin):
|
||||
fields = [
|
||||
@@ -11,6 +12,9 @@ class MovieAdmin(admin.ModelAdmin):
|
||||
]
|
||||
readonly_fields = ("score",)
|
||||
list_display = ["name", "watched", "suggested_by", "score"]
|
||||
inlines = [
|
||||
MovieVoteInline
|
||||
]
|
||||
|
||||
@admin.display(description="Score")
|
||||
def score(self, instance):
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.1.5 on 2023-02-17 14:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('watchlist', '0007_alter_movie_csfd_id_alter_movie_imdb_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='movievote',
|
||||
name='comment',
|
||||
field=models.TextField(blank=True, default=''),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
+3
-3
@@ -29,11 +29,11 @@ class Movie(models.Model):
|
||||
|
||||
@property
|
||||
def score(self):
|
||||
return reduce(lambda result,v: result+v.vote, self.movievote_set.all(), 0)
|
||||
return reduce(lambda result,v: result+v.vote, self.movievote_set.filter(user__is_active=True).all(), 0)
|
||||
|
||||
@property
|
||||
def seen_score(self):
|
||||
return reduce(lambda result,v: result+int(v.seen), self.movievote_set.all(), 0)
|
||||
return reduce(lambda result,v: result+int(v.seen), self.movievote_set.filter(user__is_active=True).all(), 0)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -49,7 +49,7 @@ class MovieVote(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
vote = models.IntegerField(choices=Vote.choices, default=Vote.NOVOTE)
|
||||
seen = models.BooleanField(default=False, null=True)
|
||||
comment = models.TextField(null=True)
|
||||
comment = models.TextField(blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username}'s vote for {self.movie.name}"
|
||||
|
||||
@@ -68,7 +68,8 @@ class CSFDIDTest(TestCase):
|
||||
urls = [
|
||||
("https://www.csfd.cz/film/1-predevsim-nikomu-neublizim/recenze/", "1"),
|
||||
("https://www.csfd.cz/film/969361-velryba/prehled/", "969361"),
|
||||
("https://www.csfd.cz/film/370706-daredevil/galerie/?page=20", "370706")
|
||||
("https://www.csfd.cz/film/370706-daredevil/galerie/?page=20", "370706"),
|
||||
("https://www.csfd.cz/film/370706", "370706")
|
||||
]
|
||||
for url, result in urls:
|
||||
with self.subTest(url=url, result=result):
|
||||
|
||||
@@ -166,10 +166,10 @@ class VoteTests(TestCase):
|
||||
with self.subTest(comment=comment):
|
||||
response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"vote": "0", "comment": comment})
|
||||
mv = m.movievote_set.get(user=self.user)
|
||||
self.assertEqual(mv.comment, None if comment == "" else comment)
|
||||
self.assertEqual(mv.comment, comment)
|
||||
with self.subTest(comment=None):
|
||||
response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"vote": "0"})
|
||||
mv = m.movievote_set.get(user=self.user)
|
||||
self.assertEqual(mv.comment, None)
|
||||
self.assertEqual(mv.comment, "")
|
||||
|
||||
|
||||
|
||||
+4
-5
@@ -1,3 +1,4 @@
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponseRedirect, HttpResponseBadRequest, HttpResponseForbidden
|
||||
from django.views import generic
|
||||
from django.views.decorators.http import require_http_methods, require_safe, require_POST
|
||||
@@ -36,7 +37,7 @@ class DetailView(generic.DetailView):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
votes = self.object.movievote_set.all()
|
||||
votes = self.object.movievote_set.filter(user__is_active=True).all()
|
||||
user_vote = None
|
||||
if self.request.user.is_authenticated:
|
||||
user_vote = votes.filter(user=self.request.user).first()
|
||||
@@ -56,9 +57,7 @@ def vote(request, pk):
|
||||
user_vote.vote = request.POST['vote']
|
||||
user_vote.seen = request.POST.get('seen', False) == "on"
|
||||
comment = request.POST.get('comment', '').strip()
|
||||
if comment != '' or user_vote.comment is not None:
|
||||
if comment == '':
|
||||
comment = None
|
||||
if comment != '' or user_vote.comment != "":
|
||||
user_vote.comment = comment
|
||||
user_vote.save()
|
||||
return HttpResponseRedirect(reverse('watchlist:index'))
|
||||
@@ -72,7 +71,7 @@ class EditView(generic.DetailView):
|
||||
|
||||
def get_context_data(self, **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.filter(Q(is_active=True) | Q(id=self.object.suggested_by.id)).all() if self.request.user.has_perm("watchlist.moderate_movies") else None
|
||||
context["error"] = self.request.GET.get("error", None)
|
||||
return context
|
||||
|
||||
|
||||
Reference in New Issue
Block a user