import datetime
from django.shortcuts import get_object_or_404
from django.template.loader import render_to_string
+from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.conf import settings
from django.core.mail import EmailMessage
-from django.db.models import Max
+from django.db.models import Max, Q, F
from django.db.utils import IntegrityError
from patchwork.forms import MultiplePatchForm
from patchwork.models import Bundle, Project, BundlePatch, UserProfile, \
- PatchChangeNotification, EmailOptout
+ PatchChangeNotification, EmailOptout, EmailConfirmation
def get_patch_ids(d, prefix = 'patch_id'):
ids = []
else:
return '-' + self.order
- def query(self):
+ def apply(self, qs):
q = self.order_map[self.order]
if self.reversed:
q = '-' + q
- return q
+
+ orders = [q]
+
+ # if we're using a non-default order, add the default as a secondary
+ # ordering. We reverse the default if the primary is reversed.
+ (default_name, default_reverse) = self.default_order
+ if self.order != default_name:
+ q = self.order_map[default_name]
+ if self.reversed ^ default_reverse:
+ q = '-' + q
+ orders.append(q)
+
+ return qs.order_by(*orders)
bundle_actions = ['create', 'add', 'remove']
def set_bundle(user, project, action, data, patches, context):
bundle = None
if action == 'create':
bundle_name = data['bundle_name'].strip()
+ if '/' in bundle_name:
+ return ['Bundle names can\'t contain slashes']
+
if not bundle_name:
return ['No bundle name was specified']
for (recipient, notifications) in groups:
notifications = list(notifications)
+ projects = set([ n.patch.project.linkname for n in notifications ])
def delete_notifications():
- PatchChangeNotification.objects.filter(
- pk__in = notifications).delete()
+ pks = [ n.pk for n in notifications ]
+ PatchChangeNotification.objects.filter(pk__in = pks).delete()
if EmailOptout.is_optout(recipient.email):
delete_notifications()
'site': Site.objects.get_current(),
'person': recipient,
'notifications': notifications,
+ 'projects': projects,
}
+
subject = render_to_string(
'patchwork/patch-change-notification-subject.text',
context).strip()
delete_notifications()
return errors
+
+def do_expiry():
+ # expire any pending confirmations
+ q = (Q(date__lt = datetime.datetime.now() - EmailConfirmation.validity) |
+ Q(active = False))
+ EmailConfirmation.objects.filter(q).delete()
+
+ # expire inactive users with no pending confirmation
+ pending_confs = EmailConfirmation.objects.values('user')
+ users = User.objects.filter(
+ is_active = False,
+ last_login = F('date_joined')
+ ).exclude(
+ id__in = pending_confs
+ )
+
+ # delete users
+ users.delete()
+
+
+