annotate gpp/bio/models.py @ 274:2a3285e32062

For #114, another CSS tweak.
author Brian Neal <bgneal@gmail.com>
date Sun, 26 Sep 2010 19:18:55 +0000
parents 75ea1a8be7f2
children d424b8bae71d
rev   line source
gremmie@1 1 """
gremmie@1 2 Contains models for the bio application.
gremmie@1 3 I would have picked profile for this application, but that is already taken, apparently.
gremmie@1 4 """
gremmie@1 5
gremmie@1 6 import os.path
gremmie@1 7
gremmie@1 8 from django.db import models
bgneal@259 9 from django.contrib.auth.models import User
gremmie@1 10 from django.conf import settings
bgneal@54 11 from django.core.cache import cache
gremmie@1 12
bgneal@128 13 from core.markup import SiteMarkup
bgneal@124 14
bgneal@215 15 # These are the secondary user status enumeration values.
bgneal@215 16 (STA_ACTIVE, # User is a full member in good standing.
bgneal@215 17 STA_RESIGNED, # User has voluntarily asked to be removed.
bgneal@215 18 STA_REMOVED, # User was removed for bad behavior.
bgneal@215 19 STA_SUSPENDED, # User is temporarily suspended; e.g. a stranger tripped
bgneal@215 20 # the spam filter.
bgneal@215 21 STA_SPAMMER, # User has been removed for spamming.
bgneal@215 22 STA_STRANGER, # New member, isn't fully trusted yet. Their comments and
bgneal@215 23 # forum posts are scanned for spam. They can have their
bgneal@215 24 # accounts deactivated by moderators for spamming.
bgneal@215 25 ) = range(6)
bgneal@147 26
bgneal@147 27 USER_STATUS_CHOICES = (
bgneal@147 28 (STA_ACTIVE, "Active"),
bgneal@147 29 (STA_RESIGNED, "Resigned"),
bgneal@147 30 (STA_REMOVED, "Removed"),
bgneal@147 31 (STA_SUSPENDED, "Suspended"),
bgneal@147 32 (STA_SPAMMER, "Spammer"),
bgneal@215 33 (STA_STRANGER, "Stranger")
bgneal@147 34 )
bgneal@147 35
bgneal@204 36
bgneal@204 37 class Badge(models.Model):
bgneal@204 38 """This model represents badges that users can earn."""
bgneal@204 39 image = models.ImageField(upload_to='badges')
bgneal@204 40 name = models.CharField(max_length=64)
bgneal@204 41 description = models.TextField(blank=True)
bgneal@204 42 order = models.IntegerField()
bgneal@204 43 numeric_id = models.IntegerField(db_index=True)
bgneal@204 44
bgneal@204 45 class Meta:
bgneal@204 46 ordering = ('order', )
bgneal@204 47
bgneal@204 48 def __unicode__(self):
bgneal@204 49 return self.name
bgneal@204 50
bgneal@204 51 def get_absolute_url(self):
bgneal@204 52 return self.image.url
bgneal@204 53
bgneal@204 54 def html(self):
bgneal@204 55 """Returns a HTML img tag representation of the badge."""
bgneal@204 56 if self.image:
bgneal@204 57 return u'<img src="%s" alt="%s" title="%s" />' % (
bgneal@204 58 self.get_absolute_url(), self.name, self.name)
bgneal@204 59 return u''
bgneal@204 60 html.allow_tags = True
bgneal@204 61
bgneal@204 62
gremmie@1 63 def avatar_file_path_for_user(username, filename):
gremmie@1 64 return os.path.join(settings.AVATAR_DIR, 'users', username, filename)
gremmie@1 65
gremmie@1 66 def avatar_file_path(instance, filename):
gremmie@1 67 return avatar_file_path_for_user(instance.user.username, filename)
gremmie@1 68
gremmie@1 69
gremmie@1 70 class UserProfile(models.Model):
gremmie@1 71 """model to represent additional information about users"""
gremmie@1 72
bgneal@259 73 user = models.ForeignKey(User, unique=True)
gremmie@1 74 location = models.CharField(max_length=128, blank=True)
gremmie@1 75 birthday = models.DateField(blank=True, null=True,
gremmie@1 76 help_text='Optional; the year is not shown to others')
gremmie@1 77 occupation = models.CharField(max_length=128, blank=True)
gremmie@1 78 interests = models.CharField(max_length=255, blank=True)
gremmie@1 79 profile_text = models.TextField(blank=True)
gremmie@1 80 profile_html = models.TextField(blank=True)
gremmie@1 81 hide_email = models.BooleanField(default=True)
gremmie@1 82 signature = models.TextField(blank=True)
gremmie@1 83 signature_html = models.TextField(blank=True)
gremmie@1 84 avatar = models.ImageField(upload_to=avatar_file_path, blank=True)
bgneal@70 85 time_zone = models.CharField(max_length=64, blank=True,
bgneal@70 86 default='US/Pacific')
bgneal@120 87 use_24_time = models.BooleanField(default=False)
bgneal@96 88 forum_post_count = models.IntegerField(default=0)
bgneal@215 89 status = models.IntegerField(default=STA_STRANGER,
bgneal@147 90 choices=USER_STATUS_CHOICES)
bgneal@147 91 status_date = models.DateTimeField(auto_now_add=True)
bgneal@204 92 badges = models.ManyToManyField(Badge, through="BadgeOwnership")
gremmie@1 93
gremmie@1 94 def __unicode__(self):
gremmie@1 95 return self.user.username
gremmie@1 96
gremmie@1 97 class Meta:
gremmie@1 98 ordering = ('user__username', )
gremmie@1 99
gremmie@1 100 def save(self, *args, **kwargs):
bgneal@128 101 sm = SiteMarkup()
bgneal@128 102 self.profile_html = sm.convert(self.profile_text)
bgneal@128 103 self.signature_html = sm.convert(self.signature)
gremmie@1 104 super(UserProfile, self).save(*args, **kwargs)
bgneal@54 105 cache.delete('avatar_' + self.user.username)
bgneal@138 106
bgneal@138 107 @models.permalink
bgneal@138 108 def get_absolute_url(self):
bgneal@138 109 return ('bio-view_profile', (), {'username': self.user.username})
bgneal@138 110
bgneal@204 111 def badge_ownership(self):
bgneal@204 112 if hasattr(self, '_badges'):
bgneal@204 113 return self._badges
bgneal@204 114 self._badges = BadgeOwnership.objects.filter(profile=self).select_related(
bgneal@204 115 "badge")
bgneal@204 116 return self._badges
bgneal@204 117
bgneal@215 118 def is_stranger(self):
bgneal@215 119 """Returns True if this user profile status is STA_STRANGER."""
bgneal@215 120 return self.status == STA_STRANGER
bgneal@215 121
bgneal@215 122 def user_is_active(self):
bgneal@215 123 """Returns the profile's user is_active status. This function exists
bgneal@215 124 for the admin.
bgneal@215 125 """
bgneal@215 126 return self.user.is_active
bgneal@215 127 user_is_active.boolean = True
bgneal@215 128 user_is_active.short_description = "Is Active"
bgneal@215 129
bgneal@223 130 def search_title(self):
bgneal@223 131 full_name = self.user.get_full_name()
bgneal@223 132 if full_name:
bgneal@223 133 return u"%s (%s)" % (self.user.username, full_name)
bgneal@223 134 return self.user.username
bgneal@223 135
bgneal@223 136 def search_summary(self):
bgneal@223 137 return u"\n".join((self.location, self.occupation, self.interests,
bgneal@223 138 self.profile_text, self.signature))
bgneal@223 139
bgneal@138 140
bgneal@138 141 class UserProfileFlag(models.Model):
bgneal@138 142 """This model represents a user flagging a profile as inappropriate."""
bgneal@259 143 user = models.ForeignKey(User)
bgneal@138 144 profile = models.ForeignKey(UserProfile)
bgneal@138 145 flag_date = models.DateTimeField(auto_now_add=True)
bgneal@138 146
bgneal@138 147 def __unicode__(self):
bgneal@138 148 return u"%s's profile flagged by %s" % (self.profile.user.username,
bgneal@138 149 self.user.username)
bgneal@138 150
bgneal@138 151 class Meta:
bgneal@138 152 ordering = ('flag_date', )
bgneal@138 153
bgneal@138 154 def get_profile_url(self):
bgneal@138 155 return '<a href="%s">Profile</a>' % self.profile.get_absolute_url()
bgneal@138 156 get_profile_url.allow_tags = True
bgneal@204 157
bgneal@204 158
bgneal@204 159 class BadgeOwnership(models.Model):
bgneal@204 160 """This model represents the ownership of badges by users."""
bgneal@204 161 profile = models.ForeignKey(UserProfile)
bgneal@204 162 badge = models.ForeignKey(Badge)
bgneal@204 163 count = models.IntegerField(default=1)
bgneal@204 164
bgneal@204 165 class Meta:
bgneal@204 166 verbose_name_plural = "badge ownership"
bgneal@204 167 ordering = ('badge__order', )
bgneal@204 168
bgneal@204 169 def __unicode__(self):
bgneal@204 170 if self.count == 1:
bgneal@204 171 return u"%s owns 1 %s" % (self.profile.user.username,
bgneal@204 172 self.badge.name)
bgneal@204 173 else:
bgneal@204 174 return u"%s owns %d %s badges" % (self.profile.user.username,
bgneal@204 175 self.count, self.badge.name)
bgneal@204 176
bgneal@204 177 def badge_count_str(self):
bgneal@204 178 if self.count == 1:
bgneal@204 179 return u"1 %s" % self.badge.name
bgneal@204 180 return u"%d %ss" % (self.count, self.badge.name)