annotate gpp/bio/models.py @ 505:a5d11471d031

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