rankmodel.py 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. roles = models.ManyToManyField('Role')
  21. class Meta:
  22. app_label = 'misago'
  23. def __unicode__(self):
  24. return unicode(_(self.name))
  25. def assign_rank(self, users=0, special_ranks=None):
  26. if not self.criteria or self.special or users == 0:
  27. # Rank cant be rolled in
  28. return False
  29. if self.criteria == "0":
  30. # Just update all fellows
  31. User.objects.exclude(rank__in=special_ranks).update(rank=self)
  32. else:
  33. # Count number of users to update
  34. if self.criteria[-1] == '%':
  35. criteria = int(self.criteria[0:-1])
  36. criteria = int(math.ceil(float(users / 100.0) * criteria))
  37. else:
  38. criteria = int(self.criteria)
  39. # Join special ranks
  40. if special_ranks:
  41. special_ranks = ','.join(special_ranks)
  42. # Run raw query
  43. cursor = connection.cursor()
  44. try:
  45. # Postgresql
  46. if (settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2'
  47. or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql'):
  48. if special_ranks:
  49. cursor.execute('''UPDATE misago_user
  50. FROM (
  51. SELECT id
  52. FROM misago_user
  53. WHERE rank_id NOT IN (%s)
  54. ORDER BY score DESC LIMIT %s
  55. ) AS updateable
  56. SET rank_id=%s
  57. WHERE id = updateable.id
  58. RETURNING *''' % (self.id, special_ranks, criteria))
  59. else:
  60. cursor.execute('''UPDATE misago_user
  61. FROM (
  62. SELECT id
  63. FROM misago_user
  64. ORDER BY score DESC LIMIT %s
  65. ) AS updateable
  66. SET rank_id=%s
  67. WHERE id = updateable.id
  68. RETURNING *''', [self.id, criteria])
  69. # MySQL, SQLite and Oracle
  70. if (settings.DATABASES['default']['ENGINE'] == 'django.db.backends.mysql'
  71. or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.sqlite3'
  72. or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.oracle'):
  73. if special_ranks:
  74. cursor.execute('''UPDATE misago_user
  75. SET rank_id=%s
  76. WHERE rank_id NOT IN (%s)
  77. ORDER BY score DESC
  78. LIMIT %s''' % (self.id, special_ranks, criteria))
  79. else:
  80. cursor.execute('''UPDATE misago_user
  81. SET rank_id=%s
  82. ORDER BY score DESC
  83. LIMIT %s''', [self.id, criteria])
  84. except Exception as e:
  85. print 'Error updating users ranking: %s' % e
  86. transaction.commit_unless_managed()
  87. return True