Skip to content

Commit

Permalink
Set the groundwork for ability to filter out deleted comments.
Browse files Browse the repository at this point in the history
Part of SEA-1634.
  • Loading branch information
cyrillkuettel committed Dec 10, 2024
1 parent 48c3dd5 commit ccb803a
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 28 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,5 @@ messages.xlsx

src/privatim/locale/de/LC_MESSAGES/privatim.mo
src/privatim/locale/fr/LC_MESSAGES/privatim.mo

.codebuddy/
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ repos:
exit 0;
else
echo "⚠️ Warning: setup.cfg was modified but requirements.txt was not!";
echo "Did you run \"make compile\" to re-generate the requirements.txt?";
echo "If you have added new dependencies, you need to run \"make compile\" to re-generate the requirements.txt. Otherwise, you can ignore thi warning";
exit 1;
fi;
fi'
Expand Down
52 changes: 52 additions & 0 deletions src/privatim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from email.headerregistry import Address

from privatim.mail import PostmarkMailer
from privatim.models.comment import COMMENT_DELETED_MSG
from privatim.orm.uuid_type import UUIDStr as UUIDStrType

from pyramid.settings import asbool
Expand All @@ -33,6 +34,7 @@
if TYPE_CHECKING:
from privatim.controls.controls import Button
from _typeshed.wsgi import WSGIApplication
from sqlalchemy.orm import Session
from privatim.cli.upgrade import UpgradeContext
from pyramid.interfaces import IRequest

Expand Down Expand Up @@ -472,4 +474,54 @@ def upgrade(context: 'UpgradeContext'): # type: ignore[no-untyped-def]
)
)

def check_visible_deleted_comments(session: 'Session') -> None:
"""
Check comments that have deletion text but are still visible
"""
query = """
SELECT id, content, deleted
FROM comments
WHERE content = '[Kommentar von Benutzer gelöscht]'
ORDER BY updated DESC
LIMIT 5;
"""
results = session.execute(text(query))

print("\nExamining supposedly deleted comments:")
print("-" * 50)
for id, content, deleted in results:
print(f"Comment ID: {id}")
print(f"Content: '{content}'")
print(f"Deleted flag: {deleted}")
print("-" * 50)

check_visible_deleted_comments(context.session)

# Get all available translations of the deleted message
translated_messages = {str(COMMENT_DELETED_MSG), # untranslated
'Comment deleted by user', # fallback English
'[Kommentar von Benutzer gelöscht]',
"[Commentaire supprimé par l'utilisateur]"
}
if context.add_column(
'comments',
Column(
'deleted',
Boolean,
nullable=False,
server_default='false',
),
):
# Update existing deleted comments using OR conditions for each
# translation. Double up single quotes for SQL escaping
escaped_messages = [msg.replace("'", "''")
for msg in translated_messages]
conditions = " OR ".join(f"content = '{msg}'"
for msg in escaped_messages)
query = """
UPDATE comments
SET deleted = true
WHERE """ + conditions # nosec[B608]
context.session.execute(text(query))

context.commit()
1 change: 1 addition & 0 deletions src/privatim/cli/find_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def recurse_directory(path: str) -> 'Iterator[str]':
entry.is_file()
and entry.name.endswith('.ini')
and entry.name != 'testing.ini'
and entry.name != 'e2e.ini'
):
yield entry.path
elif entry.is_dir():
Expand Down
2 changes: 1 addition & 1 deletion src/privatim/forms/widgets/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def image_source(self, field: 'UploadField') -> str | None:
return None

from privatim.forms.fields import IMAGE_MIME # type:ignore
if not field.data.get('mimetype', None) in IMAGE_MIME:
if field.data.get('mimetype', None) not in IMAGE_MIME:
return None

if not hasattr(field, 'object_data'):
Expand Down
2 changes: 1 addition & 1 deletion src/privatim/i18n/translation_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def _dugettext_policy(
and not hasattr(translated, '__html__')
# our plain TranslationString also implements __html__ but
# we don't want it to get interpolated into Markup
and not type(tstring) is TranslationString
and type(tstring) is not TranslationString
):
return Markup(translated)
return translated
Expand Down
11 changes: 6 additions & 5 deletions src/privatim/locale/de/LC_MESSAGES/privatim.po
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
"POT-Creation-Date: 2024-11-28 15:29+0100\n"
"POT-Creation-Date: 2024-12-10 15:19+0100\n"
"PO-Revision-Date: 2024-05-21 21:20+0200\n"
"Last-Translator: cyrill <[email protected]>\n"
"Language-Team: German <[email protected]>\n"
Expand Down Expand Up @@ -160,6 +160,11 @@ msgstr "Papierkorb"
msgid "Sign out"
msgstr "Abmelden"

#. type: ignore[has-type]
#: src/privatim/models/comment.py
msgid "Comment deleted by user"
msgstr "[Kommentar von Benutzer gelöscht]"

#: src/privatim/views/profile.py
msgid "Upload a photo..."
msgstr "Foto hochladen..."
Expand Down Expand Up @@ -433,10 +438,6 @@ msgstr ""
"Das Passwort muss mindestens 8 Zeichen lang sein und einen Grossbuchstaben, "
"einen Kleinbuchstaben, eine Ziffer und ein Sonderzeichen enthalten."

#: src/privatim/views/comment.py
msgid "Comment deleted by user"
msgstr "[Kommentar von Benutzer gelöscht]"

#: src/privatim/views/comment.py
msgid "Successfully deleted comment"
msgstr "Kommentar erfolgreich gelöscht"
Expand Down
11 changes: 6 additions & 5 deletions src/privatim/locale/fr/LC_MESSAGES/privatim.po
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
"POT-Creation-Date: 2024-11-28 15:29+0100\n"
"POT-Creation-Date: 2024-12-10 15:19+0100\n"
"PO-Revision-Date: 2024-04-11 15:53+0200\n"
"Last-Translator: cyrill <[email protected]>\n"
"Language-Team: French <[email protected]>\n"
Expand Down Expand Up @@ -157,6 +157,11 @@ msgstr "Poubelle"
msgid "Sign out"
msgstr "Se déconnecter"

#. type: ignore[has-type]
#: src/privatim/models/comment.py
msgid "Comment deleted by user"
msgstr "[Commentaire supprimé par l'utilisateur]"

#: src/privatim/views/profile.py
msgid "Upload a photo..."
msgstr "Télécharger une photo..."
Expand Down Expand Up @@ -432,10 +437,6 @@ msgstr ""
"spécial. une lettre majuscule, une lettre minuscule, un chiffre et un "
"caractère spécial."

#: src/privatim/views/comment.py
msgid "Comment deleted by user"
msgstr "[Commentaire supprimé par l'utilisateur]"

#: src/privatim/views/comment.py
msgid "Successfully deleted comment"
msgstr "Commentaire supprimé avec succès"
Expand Down
11 changes: 6 additions & 5 deletions src/privatim/locale/privatim.pot
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
"POT-Creation-Date: 2024-11-28 15:29+0100\n"
"POT-Creation-Date: 2024-12-10 15:19+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down Expand Up @@ -161,6 +161,11 @@ msgstr ""
msgid "Sign out"
msgstr ""

#. type: ignore[has-type]
#: ./src/privatim/models/comment.py
msgid "Comment deleted by user"
msgstr ""

#: ./src/privatim/views/profile.py
msgid "Upload a photo..."
msgstr ""
Expand Down Expand Up @@ -428,10 +433,6 @@ msgid ""
"letter, one lower case letter, one digit and one special character."
msgstr ""

#: ./src/privatim/views/comment.py
msgid "Comment deleted by user"
msgstr ""

#: ./src/privatim/views/comment.py
msgid "Successfully deleted comment"
msgstr ""
Expand Down
7 changes: 7 additions & 0 deletions src/privatim/models/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
from privatim.orm.meta import UUIDStrPK, UUIDStr
from sqlalchemy import Text, ForeignKey, Index, and_, select
from privatim.models import SearchableMixin
from privatim.i18n import _
from pyramid.authorization import Allow, Authenticated


from typing import TYPE_CHECKING, Optional, TypeVar, Iterator
if TYPE_CHECKING:
from privatim.models import User
Expand All @@ -18,6 +20,9 @@
T = TypeVar('T', bound='Base')


COMMENT_DELETED_MSG = _('Comment deleted by user') # type: ignore[has-type]


class Comment(Base, SearchableMixin):

__tablename__ = 'comments'
Expand Down Expand Up @@ -45,6 +50,8 @@ def __init__(
created: Mapped[datetime] = mapped_column(default=utcnow)
updated: Mapped[datetime] = mapped_column(default=utcnow, onupdate=utcnow)

deleted: Mapped[bool] = mapped_column(default=False, nullable=False)

# Author of the comment. Nullable to be somewhat more resilient for
# deleted users
user_id: Mapped[UUIDStr] = mapped_column(
Expand Down
16 changes: 9 additions & 7 deletions src/privatim/views/activities.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,19 +131,17 @@ def activities_view(request: 'IRequest') -> 'RenderDataOrRedirect':
end_date = form.end_date.data

start_datetime = (
datetime.combine(start_date, time.min, tzinfo=ZoneInfo("UTC"))
datetime.combine(start_date, time.min, tzinfo=ZoneInfo('UTC'))
if start_date
else None
)
end_datetime = (
datetime.combine(end_date, time.max, tzinfo=ZoneInfo("UTC"))
datetime.combine(end_date, time.max, tzinfo=ZoneInfo('UTC'))
if end_date
else None
)

activities: list[Activity] = []

# Query construction for Consultations
if include_consultations:
consultation_query = select(Consultation).options(
joinedload(Consultation.creator),
Expand All @@ -158,7 +156,6 @@ def activities_view(request: 'IRequest') -> 'RenderDataOrRedirect':
session.execute(consultation_query).unique().scalars().all()
)

# Query construction for Meetings
if include_meetings:
meeting_query = select(Meeting)
meeting_query = maybe_apply_date_filter(
Expand All @@ -167,9 +164,14 @@ def activities_view(request: 'IRequest') -> 'RenderDataOrRedirect':
activities.extend(
session.execute(meeting_query).unique().scalars().all()
)
# Query construction for Comments

if include_comments:
comment_query = select(Comment).options(joinedload(Comment.user))
comment_query = (
select(Comment)
.options(joinedload(Comment.user))
.filter(~Comment.deleted)
)

comment_query = maybe_apply_date_filter(
comment_query, start_datetime, end_datetime, Comment.updated
)
Expand Down
6 changes: 3 additions & 3 deletions src/privatim/views/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
HTTPForbidden)
from privatim.i18n import _
from privatim.i18n import translate
from privatim.models.comment import Comment

from privatim.models.comment import Comment, COMMENT_DELETED_MSG

from typing import TYPE_CHECKING
if TYPE_CHECKING:
Expand All @@ -18,7 +17,8 @@ def delete_comment_view(
context: Comment, request: 'IRequest'
) -> 'MixedDataOrRedirect':
assert context.target_type == 'consultations'
context.content = translate(_('Comment deleted by user'))
context.content = translate(_(COMMENT_DELETED_MSG))
context.deleted = True
message = _('Successfully deleted comment')
request.messages.add(message, 'success')

Expand Down

0 comments on commit ccb803a

Please sign in to comment.