# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+from __future__ import absolute_import
+
from collections import Counter, OrderedDict
import datetime
import random
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import Q
+from django.utils.encoding import python_2_unicode_compatible
from django.utils.functional import cached_property
+from django.utils import six
+from django.utils.six import add_metaclass
+from django.utils.six.moves import filter
from patchwork.parser import extract_tags, hash_patch
+@python_2_unicode_compatible
class Person(models.Model):
email = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, null=True, blank=True)
user = models.ForeignKey(User, null=True, blank=True,
on_delete=models.SET_NULL)
- def __unicode__(self):
- if self.name:
- return u'%s <%s>' % (self.name, self.email)
- else:
- return self.email
-
def link_to_user(self, user):
self.name = user.profile.name()
self.user = user
+ def __str__(self):
+ if self.name:
+ return '%s <%s>' % (self.name, self.email)
+ else:
+ return self.email
+
class Meta:
verbose_name_plural = 'People'
+@python_2_unicode_compatible
class Project(models.Model):
linkname = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, unique=True)
send_notifications = models.BooleanField(default=False)
use_tags = models.BooleanField(default=True)
- def __unicode__(self):
- return self.name
-
def is_editable(self, user):
if not user.is_authenticated():
return False
return []
return list(Tag.objects.all())
+ def __str__(self):
+ return self.name
+
class Meta:
ordering = ['linkname']
+@python_2_unicode_compatible
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True, related_name='profile')
primary_project = models.ForeignKey(Project, null=True, blank=True)
def name(self):
if self.user.first_name or self.user.last_name:
- names = filter(bool, [self.user.first_name, self.user.last_name])
- return u' '.join(names)
+ names = list(filter(
+ bool, [self.user.first_name, self.user.last_name]))
+ return ' '.join(names)
return self.user.username
def contributor_projects(self):
action_required=True).values('pk').query)
return qs
- def __unicode__(self):
+ def __str__(self):
return self.name()
models.signals.post_save.connect(_user_saved_callback, sender=User)
+@python_2_unicode_compatible
class State(models.Model):
name = models.CharField(max_length=100)
ordering = models.IntegerField(unique=True)
action_required = models.BooleanField(default=True)
- def __unicode__(self):
+ def __str__(self):
return self.name
class Meta:
ordering = ['ordering']
+@add_metaclass(models.SubfieldBase)
class HashField(models.CharField):
- __metaclass__ = models.SubfieldBase
def __init__(self, algorithm='sha1', *args, **kwargs):
self.algorithm = algorithm
import hashlib
def _construct(string=''):
+ if isinstance(string, six.text_type):
+ string = string.encode('utf-8')
return hashlib.new(self.algorithm, string)
self.construct = _construct
self.n_bytes = len(hashlib.new(self.algorithm).hexdigest())
except ImportError:
modules = {'sha1': 'sha', 'md5': 'md5'}
- if algorithm not in modules.keys():
+ if algorithm not in modules:
raise NameError("Unknown algorithm '%s'" % algorithm)
self.construct = __import__(modules[algorithm]).new
return 'char(%d)' % self.n_bytes
+@python_2_unicode_compatible
class Tag(models.Model):
name = models.CharField(max_length=20)
pattern = models.CharField(
max_length=2, unique=True, help_text='Short (one-or-two letter)'
' abbreviation for the tag, used in table column headers')
- def __unicode__(self):
- return self.name
-
@property
def attr_name(self):
return 'tag_%d_count' % self.id
+ def __str__(self):
+ return self.name
+
class Meta:
ordering = ['abbrev']
return self.get_queryset().with_tag_counts(project)
+@python_2_unicode_compatible
class Patch(models.Model):
project = models.ForeignKey(Project)
msgid = models.CharField(max_length=255)
objects = PatchManager()
- def __unicode__(self):
- return self.name
-
def commit_message(self):
"""Retrieve the commit message."""
return Comment.objects.filter(patch=self, msgid=self.msgid)
unique[ctx] = check
- return unique.values()
+ return list(unique.values())
@property
def check_count(self):
def get_absolute_url(self):
return ('patchwork.views.patch.patch', (), {'patch_id': self.id})
+ def __str__(self):
+ return self.name
+
class Meta:
verbose_name_plural = 'Patches'
ordering = ['date']
order=max_order + 1)
bp.save()
- class Meta:
- unique_together = [('owner', 'name')]
-
def public_url(self):
if not self.public:
return None
'bundlename': self.name,
})
+ class Meta:
+ unique_together = [('owner', 'name')]
+
class BundlePatch(models.Model):
patch = models.ForeignKey(Patch)
self.id, self.context, self.get_state_display())
def __unicode__(self):
- return ('%s (%s)' % (self.context, self.get_state_display()))
+ return '%s (%s)' % (self.context, self.get_state_display())
class EmailConfirmation(models.Model):
super(EmailConfirmation, self).save()
+@python_2_unicode_compatible
class EmailOptout(models.Model):
email = models.CharField(max_length=200, primary_key=True)
- def __unicode__(self):
- return self.email
-
@classmethod
def is_optout(cls, email):
email = email.lower().strip()
return cls.objects.filter(email=email).count() > 0
+ def __str__(self):
+ return self.email
+
class PatchChangeNotification(models.Model):
patch = models.OneToOneField(Patch, primary_key=True)