models.py 4.1 KB

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