rankmodel.py 4.2 KB

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