api.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from django.db.models import F
  2. from django.db import transaction
  3. from django.utils.html import escape
  4. from misago.notifications.checksums import update_checksum
  5. from misago.notifications.utils import hash_trigger
  6. __all__ = [
  7. 'notify_user',
  8. 'read_user_notifications',
  9. 'read_all_user_alerts',
  10. 'assert_real_new_notifications_count',
  11. ]
  12. def notify_user(user, message, url, trigger=None, formats=None, sender=None,
  13. update_user=True):
  14. from misago.notifications.models import Notification
  15. message_escaped = escape(message)
  16. if formats:
  17. final_formats = {}
  18. for format, replace in formats.items():
  19. final_formats[format] = '<strong>%s</strong>' % escape(replace)
  20. message_escaped = message_escaped % final_formats
  21. new_notification = Notification(user=user,
  22. trigger=hash_trigger(trigger or message),
  23. url=url,
  24. message=message_escaped)
  25. if sender:
  26. new_notification.sender = sender
  27. new_notification.sender_username = sender.username
  28. new_notification.sender_slug = sender.slug
  29. new_notification.save()
  30. update_checksum(new_notification)
  31. new_notification.save(update_fields=['checksum'])
  32. user.new_notifications = F('new_notifications') + 1
  33. if update_user:
  34. user.save(update_fields=['new_notifications'])
  35. return new_notification
  36. def read_user_notifications(user, triggers, atomic=True):
  37. if user.is_authenticated() and user.new_notifications:
  38. if atomic:
  39. with transaction.atomic():
  40. _real_read_user_notifications(user, triggers)
  41. else:
  42. _real_read_user_notifications(user, triggers)
  43. def _real_read_user_notifications(user, triggers):
  44. if isinstance(triggers, basestring):
  45. triggers = [triggers]
  46. hashes = [hash_trigger(trigger) for trigger in triggers]
  47. update_qs = user.misago_notifications.filter(is_new=True)
  48. if len(hashes) == 1:
  49. update_qs = update_qs.filter(trigger=hashes[0])
  50. else:
  51. update_qs = update_qs.filter(trigger__in=hashes)
  52. updated = update_qs.update(is_new=False)
  53. if updated:
  54. user.new_notifications -= updated
  55. if user.new_notifications < 0:
  56. # Cos no. of changed rows returned via update()
  57. # isn't always accurate, lets keep it at 0
  58. # if user's curious about real count, he can
  59. # trigger count sync via loading list
  60. user.new_notifications = 0
  61. user.save(update_fields=['new_notifications'])
  62. def read_all_user_alerts(user):
  63. locked_user = user.lock()
  64. user.new_notifications = 0
  65. locked_user.new_notifications = 0
  66. locked_user.save(update_fields=['new_notifications'])
  67. locked_user.misago_notifications.update(is_new=False)
  68. def assert_real_new_notifications_count(user):
  69. if user.new_notifications:
  70. real_new_count = user.misago_notifications.filter(is_new=True).count()
  71. if real_new_count != user.new_notifications:
  72. user.new_notifications = real_new_count
  73. user.save(update_fields=['new_notifications'])