Log/archive deleted data #84

Merged
Anna Sirota merged 5 commits from log-all-deletions into main 2024-04-19 16:25:53 +02:00
7 changed files with 41 additions and 70 deletions
Showing only changes of commit 127113d661 - Show all commits

View File

@ -1,9 +1,7 @@
from urllib.parse import urljoin, urlparse from urllib.parse import urlparse
import json import json
import logging import logging
from django.conf import settings
from django.contrib.sites.shortcuts import get_current_site
from django.template import Library, loader from django.template import Library, loader
from django.template.defaultfilters import stringfilter from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -22,22 +20,11 @@ register = Library()
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@register.filter
def absolutify(url: str, request=None) -> str:
"""Return an absolute URL."""
if url and url.startswith(('http://', 'https://')):
return url
proto = 'http' if settings.DEBUG else 'https'
domain = get_current_site(request).domain
return urljoin(f'{proto}://{domain}', url)
@register.simple_tag(takes_context=True) @register.simple_tag(takes_context=True)
def absolute_url(context, path: str) -> str: def absolute_url(context, path: str) -> str:
"""Return an absolute URL of a given path.""" """Return an absolute URL of a given path."""
request = context.get('request') request = context.get('request')
return absolutify(path, request=request) return utils.absolutify(path, request=request)
class PaginationRenderer: class PaginationRenderer:

20
notifications/admin.py Normal file
View File

@ -0,0 +1,20 @@
from django.contrib import admin
from notifications.models import Notification
class NotificationAdmin(admin.ModelAdmin):
readonly_fields = (
'recipient',
'action',
'email_sent',
'processed_by_mailer_at',
'read_at',
)
fields = readonly_fields
def get_queryset(self, request):
return Notification.objects.all()
admin.site.register(Notification, NotificationAdmin)

View File

@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model
from django.db import models from django.db import models
from constants.activity import Verb from constants.activity import Verb
from common.templatetags.common import absolutify from utils import absolutify
User = get_user_model() User = get_user_model()

View File

@ -62,6 +62,7 @@ class RatingAdmin(admin.ModelAdmin):
fields = ('status',) + readonly_fields fields = ('status',) + readonly_fields
list_display = ( list_display = (
'date_created', 'date_created',
'extension',
'user', 'user',
'ip_address', 'ip_address',
'score', 'score',

View File

@ -7,9 +7,7 @@ from django.utils.translation import gettext_lazy as _
from django.urls import reverse from django.urls import reverse
from common.model_mixins import CreatedModifiedMixin, TrackChangesMixin from common.model_mixins import CreatedModifiedMixin, TrackChangesMixin
from common.templatetags import common
from constants.base import RATING_STATUS_CHOICES, RATING_SCORE_CHOICES from constants.base import RATING_STATUS_CHOICES, RATING_SCORE_CHOICES
from utils import send_mail
User = get_user_model() User = get_user_model()
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -139,46 +137,6 @@ class Rating(CreatedModifiedMixin, TrackChangesMixin, models.Model):
qs = Rating.objects.filter(reply_to__in=ratings) qs = Rating.objects.filter(reply_to__in=ratings)
return {r.reply_to_id: r for r in qs} return {r.reply_to_id: r for r in qs}
def send_notification_email(self):
if self.reply_to:
# It's a reply.
reply_url = common.url(
'extensions.ratings.detail',
self.extension.slug,
self.reply_to.pk,
add_prefix=False,
)
data = {
'name': self.extension.name,
'reply': self.text,
'rating_url': common.absolutify(reply_url),
}
recipients = [self.reply_to.user.email]
subject = 'Blender Extensions: Developer Reply: %s' % self.extension.name
template = 'ratings/emails/reply_review.ltxt'
perm_setting = 'reply'
else:
# It's a new rating.
rating_url = common.url(
'extensions.ratings.detail', self.extension.slug, self.pk, add_prefix=False
)
data = {
'name': self.extension.name,
'rating': self,
'rating_url': common.absolutify(rating_url),
}
recipients = [author.email for author in self.extension.authors.all()]
subject = 'Blender Extensions: New User Rating: %s' % self.extension.name
template = 'ratings/emails/new_rating.txt'
perm_setting = 'new_review'
send_mail(
subject,
template,
data,
recipient_list=recipients,
perm_setting=perm_setting,
)
def post_save(sender, instance, created, **kwargs): def post_save(sender, instance, created, **kwargs):
if kwargs.get('raw'): if kwargs.get('raw'):
return return
@ -194,10 +152,6 @@ class Rating(CreatedModifiedMixin, TrackChangesMixin, models.Model):
else: else:
log.info(f'{action} rating: {instance.pk}') log.info(f'{action} rating: {instance.pk}')
# For new ratings and new replies we want to send an email.
if created:
instance.send_notification_email()
def get_report_url(self): def get_report_url(self):
return reverse( return reverse(
'abuse:report-ratings', 'abuse:report-ratings',

View File

@ -10,8 +10,7 @@ from django.utils.translation import gettext_lazy as _
import common.help_texts import common.help_texts
from extensions.models import Extension from extensions.models import Extension
from common.model_mixins import CreatedModifiedMixin, RecordDeletionMixin from common.model_mixins import CreatedModifiedMixin, RecordDeletionMixin
from common.templatetags.common import absolutify from utils import absolutify, send_mail
from utils import send_mail
from constants.base import EXTENSION_TYPE_CHOICES from constants.base import EXTENSION_TYPE_CHOICES
from constants.reviewers import CANNED_RESPONSE_CATEGORY_CHOICES from constants.reviewers import CANNED_RESPONSE_CATEGORY_CHOICES

View File

@ -1,4 +1,5 @@
from typing import Optional from typing import Optional
from urllib.parse import urljoin
import datetime import datetime
import itertools import itertools
import logging import logging
@ -12,7 +13,9 @@ from urllib.parse import (
urlencode as urllib_urlencode, urlencode as urllib_urlencode,
) )
from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import validate_ipv46_address from django.core.validators import validate_ipv46_address
from django.http import HttpRequest from django.http import HttpRequest
@ -45,8 +48,7 @@ def urlencode(items):
def utc_millesecs_from_epoch(for_datetime=None): def utc_millesecs_from_epoch(for_datetime=None):
""" """Returns millesconds from the Unix epoch in UTC.
Returns millesconds from the Unix epoch in UTC.
If `for_datetime` is None, the current datetime will be used. If `for_datetime` is None, the current datetime will be used.
""" """
@ -70,8 +72,7 @@ def slugify(s: str):
def urlparams(url_, hash=None, **query): def urlparams(url_, hash=None, **query):
""" """Add a fragment and/or query parameters to a URL.
Add a fragment and/or query parameters to a URL.
New query params will be appended to existing parameters, except duplicate New query params will be appended to existing parameters, except duplicate
names, which will be replaced. names, which will be replaced.
@ -96,8 +97,7 @@ def send_mail(*args, **kwargs):
def chunked(seq, n): def chunked(seq, n):
""" """Yield successive n-sized chunks from seq.
Yield successive n-sized chunks from seq.
>>> for group in chunked(range(8), 3): >>> for group in chunked(range(8), 3):
... print group ... print group
@ -179,3 +179,13 @@ def _remove_port_nr(remote_addr: str) -> str:
return ipv6_with_port_match.group(1) return ipv6_with_port_match.group(1)
return remote_addr return remote_addr
def absolutify(url: str, request=None) -> str:
"""Return an absolute URL."""
if url and url.startswith(('http://', 'https://')):
return url
proto = 'http' if settings.DEBUG else 'https'
domain = get_current_site(request).domain
return urljoin(f'{proto}://{domain}', url)