models.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from django.conf import settings
  2. from django.db import models, connection, transaction
  3. from django.utils.translation import ugettext_lazy as _
  4. class Rank(models.Model):
  5. """
  6. Misago User Rank
  7. Ranks are ready style/title pairs that are assigned to users either by admin (special ranks) or as result of user activity.
  8. """
  9. name = models.CharField(max_length=255)
  10. name_slug = models.CharField(max_length=255,null=True,blank=True)
  11. description = models.TextField(null=True,blank=True)
  12. style = models.CharField(max_length=255,null=True,blank=True)
  13. title = models.CharField(max_length=255,null=True,blank=True)
  14. special = models.BooleanField(default=False)
  15. as_tab = models.BooleanField(default=False)
  16. on_index = models.BooleanField(default=False)
  17. order = models.IntegerField(default=0)
  18. criteria = models.CharField(max_length=255,null=True,blank=True)
  19. def __unicode__(self):
  20. return unicode(_(self.name))
  21. def assign_rank(self, users=0, special_ranks=None):
  22. if not self.criteria or self.special or users == 0:
  23. # Rank cant be rolled in
  24. return False
  25. if self.criteria == "0":
  26. # Just update all fellows
  27. User.objects.exclude(rank__in=special_ranks).update(rank=self)
  28. else:
  29. # Count number of users to update
  30. if self.criteria[-1] == '%':
  31. criteria = int(self.criteria[0:-1])
  32. criteria = int(math.ceil(float(users / 100.0)* criteria))
  33. else:
  34. criteria = int(self.criteria)
  35. # Join special ranks
  36. if special_ranks:
  37. special_ranks = ','.join(special_ranks)
  38. # Run raw query
  39. cursor = connection.cursor()
  40. try:
  41. # Postgresql
  42. if (settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2'
  43. or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql'):
  44. if special_ranks:
  45. cursor.execute('''UPDATE users_user
  46. FROM (
  47. SELECT id
  48. FROM users_user
  49. WHERE rank_id NOT IN (%s)
  50. ORDER BY score DESC LIMIT %s
  51. ) AS updateable
  52. SET rank_id=%s
  53. WHERE id = updateable.id
  54. RETURNING *''' % (self.id, special_ranks, criteria))
  55. else:
  56. cursor.execute('''UPDATE users_user
  57. FROM (
  58. SELECT id
  59. FROM users_user
  60. ORDER BY score DESC LIMIT %s
  61. ) AS updateable
  62. SET rank_id=%s
  63. WHERE id = updateable.id
  64. RETURNING *''', [self.id, criteria])
  65. # MySQL, SQLite and Oracle
  66. if (settings.DATABASES['default']['ENGINE'] == 'django.db.backends.mysql'
  67. or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.sqlite3'
  68. or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.oracle'):
  69. if special_ranks:
  70. cursor.execute('''UPDATE users_user
  71. SET rank_id=%s
  72. WHERE rank_id NOT IN (%s)
  73. ORDER BY score DESC
  74. LIMIT %s''' % (self.id, special_ranks, criteria))
  75. else:
  76. cursor.execute('''UPDATE users_user
  77. SET rank_id=%s
  78. ORDER BY score DESC
  79. LIMIT %s''', [self.id, criteria])
  80. except Exception as e:
  81. print 'Error updating users ranking: %s' % e
  82. transaction.commit_unless_managed()
  83. return True