models.py 4.1 KB

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