Няма описание

counter.py 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from datetime import datetime, timedelta
  2. from copy import copy
  3. from django.contrib.auth.decorators import login_required
  4. from django.core.mail import EmailMessage
  5. from django.core.urlresolvers import reverse
  6. from django.db.models import Count, Prefetch
  7. from django.http import HttpResponseRedirect
  8. from django.shortcuts import render
  9. from django.template.loader import render_to_string
  10. from django.utils.translation import ugettext as _, get_language
  11. import arrow
  12. from babel.dates import format_timedelta, format_datetime
  13. from graphos.renderers import gchart
  14. from graphos.sources.model import ModelDataSource
  15. from counter.models import *
  16. from counter.utils import parseSeumReason
  17. @login_required
  18. def get(request, id_counter):
  19. try:
  20. myCounter = Counter.objects.get(user__id=request.user.id)
  21. except Counter.DoesNotExist:
  22. return HttpResponseRedirect(reverse('login'))
  23. counter = Counter.objects.prefetch_related(
  24. # we get the related resets annotated with their number of likes
  25. Prefetch('resets', queryset=Reset.objects.select_related('who', 'counter').annotate(likes_count=Count('likes'))),
  26. 'resets__likes'
  27. ).get(pk=id_counter)
  28. resets = list(counter.resets.order_by('-timestamp'))
  29. # Display
  30. if len(resets) == 0:
  31. counter.lastReset = Reset()
  32. counter.lastReset.delta = timedelta(0)
  33. counter.lastReset.noSeum = True
  34. seumFrequency = _('unknown')
  35. else:
  36. firstReset = copy(resets[-1])
  37. counter.lastReset = resets[0]
  38. counter.lastReset.noSeum = False
  39. if counter.lastReset.who is None or counter.lastReset.who == counter:
  40. counter.lastReset.selfSeum = True
  41. else:
  42. counter.lastReset.selfSeum = False
  43. counter.lastReset.formatted_delta = arrow.Arrow.fromdatetime(counter.lastReset.timestamp).humanize(locale=get_language())
  44. counter.seumCount = len(resets)
  45. seumFrequency = format_timedelta((datetime.now() - firstReset.timestamp.replace(tzinfo=None)) / counter.seumCount,
  46. locale=get_language(), threshold=1)
  47. counter.lastLikes = list(counter.lastReset.likes.all())
  48. counter.alreadyLiked = myCounter.id in [l.liker.id for l in counter.lastLikes]
  49. counter.likes_count = len(counter.lastLikes)
  50. if counter.likes_count > 0:
  51. counter.likersString = ", ".join(like.liker.trigramme for like in counter.lastLikes)
  52. for reset in resets:
  53. if reset.who is None or reset.who.id == reset.counter.id:
  54. reset.selfSeum = True
  55. else:
  56. reset.selfSeum = False
  57. reset.date = reset.timestamp
  58. # Timeline graph
  59. # Data pre-processing
  60. if not counter.lastReset.noSeum:
  61. resets_graph = resets
  62. for reset in resets_graph:
  63. reset.timestamp = {
  64. 'v': reset.timestamp.timestamp(),
  65. 'f': arrow.Arrow.fromdatetime(reset.timestamp).humanize(locale=get_language())
  66. }
  67. if reset.selfSeum:
  68. reset.Seum = {'v': 0, 'f': reset.reason}
  69. else:
  70. reset.Seum = {'v': 0, 'f': _('From %(who)s: %(reason)s') % {'who': reset.who.trigramme, 'reason': reset.reason}}
  71. # Drawing the graph
  72. data = ModelDataSource(resets, fields=['timestamp', 'Seum'])
  73. chart = gchart.LineChart(data, options={
  74. 'lineWidth': 0,
  75. 'pointSize': 10,
  76. 'title': '',
  77. 'vAxis': {'ticks': []},
  78. 'hAxis': {'ticks': [{
  79. 'v': firstReset.timestamp.timestamp(),
  80. 'f': arrow.Arrow.fromdatetime(firstReset.timestamp).humanize(locale=get_language())
  81. }, {
  82. 'v': datetime.now().timestamp(),
  83. 'f': 'Présent'}
  84. ]},
  85. 'legend': 'none',
  86. 'height': 90
  87. })
  88. else:
  89. chart = None
  90. return render(request, 'counterTemplate.html', {
  91. 'counter': counter,
  92. 'chart': chart,
  93. 'resets': resets,
  94. 'seumFrequency': seumFrequency,
  95. 'myCounter': myCounter,
  96. })
  97. @login_required
  98. def reset_counter(request):
  99. # Update Form counter
  100. if request.method == 'POST':
  101. # create a form instance and populate it with data from the request:
  102. data = dict(request.POST)
  103. who = Counter.objects.get(pk=int(data['who'][0]))
  104. reason = data['reason'][0]
  105. if 'counter' in data.keys():
  106. counter = Counter.objects.get(pk=int(data['counter'][0]))
  107. else:
  108. try:
  109. counter = Counter.objects.get(trigramme=data['trigramme'][0])
  110. except Counter.DoesNotExist:
  111. return HttpResponseRedirect(data['redirect'][0])
  112. reset = Reset(counter=counter, who=who, reason=data['reason'][0])
  113. # we check that the seumer is the autenticated user
  114. if reset.who.user is None or reset.who.user != request.user:
  115. return HttpResponseRedirect(data['redirect'][0])
  116. reset.save()
  117. # Now we deal with the hashtags
  118. keywords = parseSeumReason(reason)
  119. Hashtag.objects.bulk_create([Hashtag(reset=reset, keyword=keyword) for keyword in keywords])
  120. # We send the emails only to those who want
  121. emails = [u['email'] for u in Counter.objects.filter(email_notifications=True).values('email')]
  122. # Now send emails to everyone
  123. if reset.who is None or reset.who == counter:
  124. selfSeum = True
  125. else:
  126. selfSeum = False
  127. text_of_email = render_to_string(
  128. 'seumEmail.txt', {'reason': data['reason'][0],
  129. 'name': counter.name,
  130. 'who': reset.who,
  131. 'selfSeum': selfSeum,
  132. })
  133. email_to_send = EmailMessage(
  134. '[SeumBook] ' + counter.trigramme + ' a le seum',
  135. text_of_email,
  136. 'SeumMan <seum@merigoux.ovh>', emails, [],
  137. reply_to=emails)
  138. email_to_send.send(fail_silently=True)
  139. return HttpResponseRedirect(data['redirect'][0])