Basic email template for notifications #96

Merged
Anna Sirota merged 14 commits from notification-templates into main 2024-05-02 14:04:24 +02:00
9 changed files with 55 additions and 38 deletions
Showing only changes of commit d1984abbc9 - Show all commits

View File

@ -353,7 +353,7 @@ class Extension(CreatedModifiedMixin, RatingMixin, TrackChangesMixin, models.Mod
"""Return True if given user is listed as a maintainer."""
if user is None or user.is_anonymous:
return False
return self.authors.filter(maintainer__user_id=user.pk).exists()
return user in self.authors.all()
def can_rate(self, user) -> bool:
"""Return True if given user can rate this extension.
@ -368,6 +368,10 @@ class Extension(CreatedModifiedMixin, RatingMixin, TrackChangesMixin, models.Mod
).exists()
)
def suspicious_files(self):
versions = self.versions.all()
return [v.file for v in versions if not v.file.validation.is_ok]
@classmethod
def get_lookup_field(cls, identifier):
lookup_field = 'pk'

View File

@ -5,11 +5,7 @@
{% block page_title %}{{ extension.name }}{% endblock page_title %}
{% block content %}
{% if extension.latest_version %}
{% with latest=extension.latest_version %}
{% include "files/components/scan_details.html" with file=latest.file %}
{% endwith %}
{% endif %}
{% include "files/components/scan_details.html" with suspicious_files=extension.suspicious_files %}
{% has_maintainer extension as is_maintainer %}
{% with latest=extension.latest_version %}
@ -55,7 +51,7 @@
{% if extension.versions.listed|length > 1 %}
<p>
<a href="{{ extension.get_versions_url }}" class="d-block mt-3">
See all changelogs
See all versions
</a>
</p>
{% endif %}

View File

@ -12,13 +12,11 @@
<h3>Tags</h3>
<ul>
{% for list_tag in tags %}
{% if list_tag.versions.all|length %}
<li class="{% if tag == list_tag %}is-active{% endif %}">
<a href="{% url "extensions:by-tag" tag_slug=list_tag.slug %}" title="{{ list_tag.name }}">
{{ list_tag.name }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>

View File

@ -4,6 +4,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.db import transaction
from django.shortcuts import get_object_or_404, reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
@ -42,7 +43,12 @@ class ExtensionDetailView(ExtensionQuerysetMixin, DetailView):
* maintainers should be able to preview their yet unlisted add-ons;
* staff should be able to preview yet unlisted add-ons;
"""
return self.get_extension_queryset()
return self.get_extension_queryset().prefetch_related(
'authors',
'versions',
'versions__file',
'versions__file__validation',
)
def get_object(self, queryset=None):
"""Record a page view when returning the Extension object."""
@ -353,6 +359,7 @@ class DraftExtensionView(
):
template_name = 'extensions/draft_finalise.html'
form_class = VersionForm
msg_awaiting_review = _('Extension is ready for initial review')
@property
def success_message(self) -> str:
@ -418,7 +425,7 @@ class DraftExtensionView(
user=self.request.user,
extension=extension_form.instance,
type=ApprovalActivity.ActivityType.AWAITING_REVIEW,
message="initial submission",
message=self.msg_awaiting_review,
).save()
return super().form_valid(form)
except forms.ValidationError as e:

View File

@ -66,6 +66,14 @@ class DraftMixin:
"""If the extension is incomplete, returns the FinalizeDraftView"""
def dispatch(self, request, *args, **kwargs):
if (
'slug' in kwargs
and Extension.objects.filter(
slug=kwargs['slug'], status=Extension.STATUSES.APPROVED
).first()
):
return super().dispatch(request, *args, **kwargs)
extension = (
Extension.objects.listed_or_authored_by(user_id=self.request.user.pk)
.filter(status=Extension.STATUSES.INCOMPLETE)

View File

@ -104,7 +104,15 @@ class SearchView(ListedExtensionsView):
| Q(versions__tags__name__icontains=token)
)
queryset = queryset.filter(search_query).distinct()
return queryset
return queryset.prefetch_related(
'authors',
'preview_set',
'preview_set__file',
'ratings',
'versions',
'versions__file',
'versions__tags',
)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -121,9 +129,9 @@ class SearchView(ListedExtensionsView):
# Determine which tags to list depending on the context.
if context.get('type'):
tag_type_id = self._get_type_id_by_slug()
context['tags'] = Tag.objects.filter(type=tag_type_id)
context['tags'] = Tag.objects.filter(type=tag_type_id).exclude(versions=None)
elif context.get('tag'):
tag_type_id = context['tag'].type
context['tags'] = Tag.objects.filter(type=tag_type_id)
context['tags'] = Tag.objects.filter(type=tag_type_id).exclude(versions=None)
return context

View File

@ -1,21 +1,19 @@
{% load common i18n %}
{# FIXME: we might want to rephrase is_moderator in terms of Django's (group) permissions #}
{% if perms.files.view_file or request.user.is_moderator %}
{% with file_validation=file.validation %}
{% if file_validation and not file_validation.is_ok %}
{% if suspicious_files %}
<section>
<div class="card pb-3 pt-4 px-4 mb-3 ext-detail-download-danger">
<h3>&nbsp;{% trans "Suspicious upload" %}</h3>
{% blocktrans asvar alert_text %}Scan of the {{ file }} indicates malicious content.{% endblocktrans %}
{% blocktrans asvar alert_text %}Scan of the {{ suspicious_files.0 }} indicates malicious content.{% endblocktrans %}
<h4>
{{ alert_text }}
{% if perms.files.view_file %}{# Moderators don't necessarily have access to the admin #}
{% url 'admin:files_file_change' file.pk as admin_file_url %}
{% url 'admin:files_file_change' suspicious_files.0.pk as admin_file_url %}
<a href="{{ admin_file_url }}" target="_blank">{% trans "See details" %}</a>
{% endif %}
</h4>
</div>
</section>
{% endif %}
{% endwith %}
{% endif %}

View File

@ -1,10 +1,8 @@
{% load common i18n %}
{# FIXME: we might want to rephrase is_moderator in terms of Django's (group) permissions #}
{% if perms.files.view_file or request.user.is_moderator %}
{% with file_validation=file.validation %}
{% if file_validation and not file_validation.is_ok %}
{% blocktrans asvar alert_text %}Scan of the {{ file }} indicates malicious content.{% endblocktrans %}
{% if suspicious_files %}
{% blocktrans asvar alert_text %}Scan of the {{ suspicious_files.0 }} indicates malicious content.{% endblocktrans %}
<b class="text-danger pt-2" title="{{ alert_text }}"></b>
{% endif %}
{% endwith %}
{% endif %}

View File

@ -22,7 +22,7 @@
<span>{{ extension.review_activity.all.last.date_created|naturaltime_compact }}</span>
</a>
{% endif %}
{% include "files/components/scan_details_flag.html" with file=extension.latest_version.file %}
{% include "files/components/scan_details_flag.html" with suspicious_files=extension.suspicious_files %}
</td>
<td>
<a href="{{ extension.get_review_url }}" class="text-decoration-none">