From 3c096aac4148bcb1d420124b96b5f22b0b22351f Mon Sep 17 00:00:00 2001
From: rubenwardy
Date: Sat, 8 Jun 2024 11:12:42 +0100
Subject: [PATCH] Add language to reviews
---
app/blueprints/packages/reviews.py | 21 ++++++++++--
app/models/threads.py | 5 ++-
.../packages/review_create_edit.html | 1 +
migrations/versions/097ce5d114d9_.py | 34 +++++++++++++++++++
4 files changed, 57 insertions(+), 4 deletions(-)
create mode 100644 migrations/versions/097ce5d114d9_.py
diff --git a/app/blueprints/packages/reviews.py b/app/blueprints/packages/reviews.py
index a3d0ba75..52464e78 100644
--- a/app/blueprints/packages/reviews.py
+++ b/app/blueprints/packages/reviews.py
@@ -18,14 +18,15 @@ from collections import namedtuple
import typing
from flask import render_template, request, redirect, flash, url_for, abort, jsonify
-from flask_babel import gettext, lazy_gettext
+from flask_babel import gettext, lazy_gettext, get_locale
from flask_login import current_user, login_required
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SubmitField, RadioField
-from wtforms.validators import InputRequired, Length
+from wtforms.validators import InputRequired, Length, DataRequired
+from wtforms_sqlalchemy.fields import QuerySelectField
from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank, \
- Permission, AuditSeverity, PackageState
+ Permission, AuditSeverity, PackageState, Language
from app.tasks.webhooktasks import post_discord_webhook
from app.utils import is_package_page, add_notification, get_int_or_abort, is_yes, is_safe_url, rank_required, \
add_audit_log, has_blocked_domains, should_return_json
@@ -41,8 +42,21 @@ def list_reviews():
return render_template("packages/reviews_list.html", pagination=pagination, reviews=pagination.items)
+def get_default_language():
+ locale = get_locale()
+ if locale:
+ return Language.query.filter_by(id=locale.language).first()
+
+ return None
+
class ReviewForm(FlaskForm):
title = StringField(lazy_gettext("Title"), [InputRequired(), Length(3, 100)])
+ language = QuerySelectField(lazy_gettext("Language"), [DataRequired()],
+ allow_blank=True,
+ query_factory=lambda: Language.query.order_by(db.asc(Language.title)),
+ get_pk=lambda a: a.id,
+ get_label=lambda a: a.title,
+ default=get_default_language)
comment = TextAreaField(lazy_gettext("Comment"), [InputRequired(), Length(10, 2000)])
rating = RadioField(lazy_gettext("Rating"), [InputRequired()],
choices=[("5", lazy_gettext("Yes")), ("3", lazy_gettext("Neutral")), ("1", lazy_gettext("No"))])
@@ -88,6 +102,7 @@ def review(package):
db.session.add(review)
review.rating = int(form.rating.data)
+ review.language = form.language.data
thread = review.thread
if not thread:
diff --git a/app/models/threads.py b/app/models/threads.py
index 8d7ebaf8..2df33d2f 100644
--- a/app/models/threads.py
+++ b/app/models/threads.py
@@ -176,7 +176,7 @@ class ThreadReply(db.Model):
class PackageReview(db.Model):
id = db.Column(db.Integer, primary_key=True)
- package_id = db.Column(db.Integer, db.ForeignKey("package.id"), nullable=True)
+ package_id = db.Column(db.Integer, db.ForeignKey("package.id"), nullable=False)
package = db.relationship("Package", foreign_keys=[package_id], back_populates="reviews")
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
@@ -184,6 +184,9 @@ class PackageReview(db.Model):
author_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
author = db.relationship("User", foreign_keys=[author_id], back_populates="reviews")
+ language_id = db.Column(db.String, db.ForeignKey("language.id"), nullable=True, default=None)
+ language = db.relationship("Language", foreign_keys=[language_id])
+
rating = db.Column(db.Integer, nullable=False)
thread = db.relationship("Thread", uselist=False, back_populates="review")
diff --git a/app/templates/packages/review_create_edit.html b/app/templates/packages/review_create_edit.html
index a3e7f57d..20563714 100644
--- a/app/templates/packages/review_create_edit.html
+++ b/app/templates/packages/review_create_edit.html
@@ -52,6 +52,7 @@
{{ render_field(form.title) }}
+ {{ render_field(form.language, hint=_("What language are you writing your review in?")) }}
{{ render_field(form.comment, label="", class_="m-0", fieldclass="form-control markdown", data_enter_submit="1") }}
{{ render_submit_field(form.btn_submit) }}
diff --git a/migrations/versions/097ce5d114d9_.py b/migrations/versions/097ce5d114d9_.py
new file mode 100644
index 00000000..c61d4d71
--- /dev/null
+++ b/migrations/versions/097ce5d114d9_.py
@@ -0,0 +1,34 @@
+"""empty message
+
+Revision ID: 097ce5d114d9
+Revises: 1fe2e44cf565
+Create Date: 2024-06-08 09:59:23.084979
+
+"""
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects import postgresql
+
+# revision identifiers, used by Alembic.
+revision = "097ce5d114d9"
+down_revision = "1fe2e44cf565"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ with op.batch_alter_table("package_review", schema=None) as batch_op:
+ batch_op.add_column(sa.Column("language_id", sa.String(), nullable=True, default=None))
+ batch_op.alter_column("package_id",
+ existing_type=sa.INTEGER(),
+ nullable=False)
+ batch_op.create_foreign_key("package_review_language", "language", ["language_id"], ["id"])
+
+
+def downgrade():
+ with op.batch_alter_table("package_review", schema=None) as batch_op:
+ batch_op.drop_constraint("package_review_language", type_="foreignkey")
+ batch_op.alter_column("package_id",
+ existing_type=sa.INTEGER(),
+ nullable=True)
+ batch_op.drop_column("language_id")