Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions comments/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ class CommentAdmin(CustomTranslationAdmin):
"included_forecast",
"is_private",
]

def should_update_translations(self, obj):
return not obj.on_post.is_private()
8 changes: 0 additions & 8 deletions comments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,6 @@ def save(self, **kwargs):
if self.parent:
self.root = self.root or self.parent.root or self.parent

on_bots_tournament = (
self.on_post is not None
and self.on_post.default_project is not None
and self.on_post.default_project.include_bots_in_leaderboard
)
if self.author.is_bot and on_bots_tournament:
kwargs["skip_translations"] = True

return super().save(**kwargs)


Expand Down
17 changes: 17 additions & 0 deletions comments/services/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,20 @@ def create_comment(
run_on_post_comment_create.send(obj.id)

return obj


def trigger_update_comment_translations(comment: Comment, force: bool = False):
if force:
comment.trigger_translation_if_dirty()
return

on_post = comment.on_post
author = comment.author
on_bots_tournament = (
on_post.default_project is not None
and on_post.default_project.include_bots_in_leaderboard
)

on_private_post = on_post.is_private() is None
if not (author.is_bot and on_bots_tournament) and not on_private_post:
comment.trigger_translation_if_dirty()
8 changes: 7 additions & 1 deletion comments/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
serialize_comment_many,
CommentFilterSerializer,
)
from comments.services.common import create_comment
from comments.services.common import create_comment, trigger_update_comment_translations
from comments.services.feed import get_comments_feed
from notifications.services import NotificationCommentReport, NotificationPostParams
from posts.services.common import get_post_permission_for_user
Expand Down Expand Up @@ -135,6 +135,8 @@ def comment_create_api_view(request: Request):
**serializer.validated_data, included_forecast=forecast, user=user
)

trigger_update_comment_translations(new_comment, force=False)

return Response(serialize_comment(new_comment), status=status.HTTP_201_CREATED)


Expand Down Expand Up @@ -162,6 +164,7 @@ def comment_edit_api_view(request: Request, pk: int):
comment.edit_history.append(comment_diff.id)
comment.text = text
comment.save(update_fields=["text", "edit_history"])
trigger_update_comment_translations(comment, force=False)

return Response({}, status=status.HTTP_200_OK)

Expand Down Expand Up @@ -282,4 +285,7 @@ def comment_create_oldapi_view(request: Request):
user=user,
text=text,
)

trigger_update_comment_translations(new_comment, force=False)

return Response(serialize_comment(new_comment), status=status.HTTP_201_CREATED)
44 changes: 8 additions & 36 deletions posts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,12 @@
from django.urls import reverse

from posts.models import Post, Notebook
from posts.services.common import trigger_update_post_translations
from questions.models import Question
from utils.csv_utils import export_data_for_questions

from utils.models import CustomTranslationAdmin

from utils.translation import (
update_translations_for_model,
queryset_filter_outdated_translations,
detect_and_update_content_language,
)
from comments.services.feed import get_comments_feed
from comments.models import Comment


@admin.register(Post)
class PostAdmin(CustomTranslationAdmin):
Expand Down Expand Up @@ -55,6 +48,10 @@ class PostAdmin(CustomTranslationAdmin):
def other_project_count(self, obj):
return obj.projects.count()

def should_update_translations(self, obj):
is_private = obj.default_project.default_permission is None
return not is_private

def get_actions(self, request):
actions = super().get_actions(request)
if "delete_selected" in actions:
Expand All @@ -78,34 +75,9 @@ def export_selected_posts_data(self, request, queryset: QuerySet[Post]):

return response

def update_translations(self, request, comments_qs):
# TODO: properly extract this in a service method and do it in a scalable way
for post in comments_qs:
post.trigger_translation_if_dirty()
if post.question is not None:
post.question.trigger_translation_if_dirty()
if post.notebook is not None:
post.notebook.trigger_translation_if_dirty()
if post.group_of_questions is not None:
post.group_of_questions.trigger_translation_if_dirty()
if post.conditional is not None:
post.conditional.condition.trigger_translation_if_dirty()
if hasattr(post.conditional.condition, "post"):
post.conditional.condition.post.trigger_translation_if_dirty()

post.conditional.condition_child.trigger_translation_if_dirty()
if hasattr(post.conditional.condition_child, "post"):
post.conditional.condition_child.post.trigger_translation_if_dirty()

post.conditional.question_yes.trigger_translation_if_dirty()
post.conditional.question_no.trigger_translation_if_dirty()

batch_size = 10
comments_qs = get_comments_feed(qs=Comment.objects.filter(), post=post)

comments_qs = queryset_filter_outdated_translations(comments_qs)
detect_and_update_content_language(comments_qs, batch_size)
update_translations_for_model(comments_qs, batch_size)
def update_translations(self, request, posts_qs):
for post in posts_qs:
trigger_update_post_translations(post, with_comments=True, force=True)


@admin.register(Notebook)
Expand Down
3 changes: 3 additions & 0 deletions posts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,9 @@ def clean_fields(self, exclude=None):

return super().clean_fields(exclude=exclude)

def is_private(self):
return self.default_project.default_permission is None


class PostSubscription(TimeStampedModel):
# typing
Expand Down
43 changes: 43 additions & 0 deletions posts/services/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
from .subscriptions import notify_post_status_change
from ..tasks import run_notify_post_status_change

from utils.translation import (
update_translations_for_model,
queryset_filter_outdated_translations,
detect_and_update_content_language,
)
from comments.services.feed import get_comments_feed
from comments.models import Comment

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -116,6 +124,41 @@ def create_post(
return obj


def trigger_update_post_translations(
post: Post, with_comments: bool = False, force: bool = False
):
is_private = post.default_project.default_permission is None
if not force and is_private:
return

post.trigger_translation_if_dirty()
if post.question_id is not None:
post.question.trigger_translation_if_dirty()
if post.notebook_id is not None:
post.notebook.trigger_translation_if_dirty()
if post.group_of_questions_id is not None:
post.group_of_questions.trigger_translation_if_dirty()
if post.conditional_id is not None:
post.conditional.condition.trigger_translation_if_dirty()
if hasattr(post.conditional.condition, "post"):
post.conditional.condition.post.trigger_translation_if_dirty()

post.conditional.condition_child.trigger_translation_if_dirty()
if hasattr(post.conditional.condition_child, "post"):
post.conditional.condition_child.post.trigger_translation_if_dirty()

post.conditional.question_yes.trigger_translation_if_dirty()
post.conditional.question_no.trigger_translation_if_dirty()

batch_size = 10
comments_qs = get_comments_feed(qs=Comment.objects.filter(), post=post)

if with_comments:
comments_qs = queryset_filter_outdated_translations(comments_qs)
detect_and_update_content_language(comments_qs, batch_size)
update_translations_for_model(comments_qs, batch_size)


def update_post_projects(
post: Post, categories: list[Project] = None, news: list[Project] = None
):
Expand Down
5 changes: 5 additions & 0 deletions posts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
submit_for_review_post,
post_make_draft,
compute_hotness,
trigger_update_post_translations,
)
from posts.services.feed import get_posts_feed, get_similar_posts
from posts.services.subscriptions import create_subscription
Expand Down Expand Up @@ -236,6 +237,8 @@ def post_create_api_view(request):
serializer.is_valid(raise_exception=True)
post = create_post(**serializer.validated_data, author=request.user)

trigger_update_post_translations(post, with_comments=False, force=False)

return Response(
serialize_post(post, with_cp=False, current_user=request.user),
status=status.HTTP_201_CREATED,
Expand Down Expand Up @@ -278,6 +281,8 @@ def post_update_api_view(request, pk):

post = update_post(post, **serializer.validated_data)

trigger_update_post_translations(post, with_comments=False, force=False)

return Response(
serialize_post(post, with_cp=False, current_user=request.user),
status=status.HTTP_200_OK,
Expand Down
12 changes: 12 additions & 0 deletions questions/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ def post_link(self, obj):
url = reverse("admin:posts_post_change", args=[post.id])
return format_html('<a href="{}">{}</a>', url, f"Post-{post.id}")

def should_update_translations(self, obj):
is_private = obj.post.default_project.default_permission is None
return not is_private

def get_fields(self, request, obj=None):
fields = super().get_fields(request, obj)
if "post_link" in fields:
Expand Down Expand Up @@ -95,6 +99,10 @@ class ConditionalAdmin(admin.ModelAdmin):
search_fields = ["id"]
autocomplete_fields = ["condition", "condition_child"]

def should_update_translations(self, obj):
is_private = obj.post.default_project.default_permission is None
return not is_private

def get_actions(self, request):
actions = super().get_actions(request)
if "delete_selected" in actions:
Expand All @@ -112,6 +120,10 @@ def get_actions(self, request):
del actions["delete_selected"]
return actions

def should_update_translations(self, obj):
is_private = obj.post.default_project.default_permission is None
return not is_private


@admin.register(Forecast)
class ForecastsAdmin(admin.ModelAdmin):
Expand Down
17 changes: 8 additions & 9 deletions utils/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ def get_form(self, request, obj=None, **kwargs):
activate(settings.ORIGINAL_LANGUAGE_CODE)
return super().get_form(request, obj, **kwargs)

# def get_all_translated_fields_for_field(self, field):
def should_update_translations(self, obj):
return True

def save_model(self, request, obj: "TranslatedModel", form, change):
super().save_model(request, obj, form, change)

if self.should_update_translations(obj):
obj.trigger_translation_if_dirty()

def get_fields(self, request, obj=None):
fields = super().get_fields(request, obj)
Expand Down Expand Up @@ -157,11 +164,6 @@ def trigger_translation_if_dirty(self):
update_translations.send(app_label, model_name, self.pk)

def save(self, *args, **kwargs):
skip_translations = kwargs.get("skip_translations", False)
if skip_translations:
kwargs.pop("skip_translations")
return super().save(*args, **kwargs)

initial_update_fields = kwargs.get("update_fields", None)

extra_update_fields = self.update_fields_with_original_content(
Expand All @@ -174,9 +176,6 @@ def save(self, *args, **kwargs):

super().save(*args, **kwargs)

# Now post a dramatiq task to detect the language and update outdated translations
self.trigger_translation_if_dirty()


class TimeStampedModel(models.Model):
"""
Expand Down