Ingen beskrivning

views.py 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. from django.shortcuts import render
  2. from counter.models import Counter, Reset
  3. from babel.dates import format_timedelta, format_datetime
  4. from datetime import datetime, timedelta
  5. from django import forms
  6. from django.http import HttpResponseRedirect
  7. from django.core import serializers
  8. from django.core.mail import EmailMessage
  9. from graphos.renderers import gchart
  10. from graphos.sources.simple import SimpleDataSource
  11. from graphos.sources.model import ModelDataSource
  12. import random
  13. import math
  14. from django.utils import timezone
  15. class resetCounterForm(forms.ModelForm):
  16. class Meta:
  17. model = Reset
  18. fields = ['reason', 'counter']
  19. def home(request):
  20. # JSS above this limit will not be displayed on the col graph
  21. JSS_limit = 7
  22. # Display counters
  23. counters = Counter.objects.all()
  24. lastResets = []
  25. # Calculates infos for each counter
  26. maxJSS = 0
  27. timezero = timedelta(0)
  28. for counter in counters:
  29. lastReset = Reset.objects.filter(
  30. counter=counter).order_by('-timestamp')
  31. if (lastReset.count() == 0):
  32. # This person never had the seum
  33. counter.lastReset = Reset()
  34. counter.lastReset.delta = timezero
  35. counter.lastReset.noSeum = True
  36. counter.CSSclass = "warning"
  37. else:
  38. counter.lastReset = lastReset[0]
  39. counter.lastReset.noSeum = False
  40. counter.lastReset.delta = datetime.now(
  41. ) - counter.lastReset.timestamp.replace(tzinfo=None)
  42. if ((counter.lastReset.delta.total_seconds()) / (24 * 3600) <
  43. JSS_limit):
  44. # Less than 7 JSS -> display on graph
  45. lastResets.append(
  46. [counter.trigramme,
  47. {'v': (counter.lastReset.delta.total_seconds()) /
  48. (24 * 3600),
  49. 'f': str(round(
  50. (counter.lastReset.delta.total_seconds()) /
  51. (24 * 3600), 1))}])
  52. # Updating the max JSS displayed on the graph to compute scale
  53. if (counter.lastReset.delta.total_seconds() / (24 * 3600) >
  54. maxJSS):
  55. maxJSS = (counter.lastReset.delta.total_seconds() /
  56. (24 * 3600))
  57. # Defining CSS attributes for the counter
  58. counter.CSSclass = "primary"
  59. counter.opacity = 0.3 + 0.7 * \
  60. math.exp(-(counter.lastReset.delta.total_seconds()) /
  61. (7 * 24 * 3600))
  62. # Computing the total number of resets for this counter
  63. counter.seumCount = Reset.objects.filter(
  64. counter=counter).count()
  65. counter.lastReset.formatted_delta = format_timedelta(
  66. counter.lastReset.delta, locale='fr', threshold=1)
  67. counter.isHidden = "hidden"
  68. counters = sorted(counters, key=lambda t: t.lastReset.delta)
  69. # Column graph
  70. if (len(lastResets) == 0):
  71. noGraph = True
  72. col_chart = None
  73. else:
  74. noGraph = False
  75. lastResets.sort(key=lambda x: x[1]['v'])
  76. lastResets.insert(0, ['Trigramme', 'Jours sans seum'])
  77. col_data = SimpleDataSource(lastResets)
  78. col_chart = gchart.ColumnChart(col_data, options={
  79. 'title': '',
  80. 'legend': 'none',
  81. 'vAxis': {
  82. 'viewWindow': {
  83. 'max': max(maxJSS, 1),
  84. 'min': 0
  85. },
  86. 'ticks': [1, 2, 3, 4, 5, 6, 7],
  87. 'title': 'Jours sans seum'
  88. },
  89. 'hAxis': {'title': 'Trigramme'},
  90. })
  91. # Timeline graph
  92. # Data pre-processing
  93. resets = Reset.objects.filter(
  94. timestamp__gte=timezone.now() - timedelta(days=1))
  95. if (resets.count() == 0):
  96. noTimeline = True
  97. line_chart = None
  98. else:
  99. noTimeline = False
  100. for reset in resets:
  101. reset.timestamp = {
  102. 'v': reset.timestamp.timestamp(),
  103. 'f': "Il y a " + format_timedelta(datetime.now() -
  104. reset.timestamp.replace(
  105. tzinfo=None),
  106. locale='fr', threshold=1)
  107. }
  108. reset.Seum = {
  109. 'v': 0, 'f': reset.counter.trigramme + " : " + reset.reason}
  110. # Drawing the graph
  111. line_data = ModelDataSource(resets, fields=['timestamp', 'Seum'])
  112. line_chart = gchart.LineChart(line_data, options={
  113. 'lineWidth': 0,
  114. 'pointSize': 10,
  115. 'title': '',
  116. 'vAxis': {'ticks': []},
  117. 'hAxis': {
  118. 'ticks': [
  119. {'v': (datetime.now() - timedelta(days=1)
  120. ).timestamp(), 'f': 'Il y a 24 h'},
  121. {'v': datetime.now().timestamp(), 'f': 'Présent'}
  122. ]
  123. },
  124. 'legend': 'none',
  125. 'height': 90
  126. })
  127. return render(request, 'homeTemplate.html', {
  128. 'counters': counters,
  129. 'col_chart': col_chart,
  130. 'line_chart': line_chart,
  131. 'noTimeline': noTimeline,
  132. 'noGraph': noGraph
  133. })
  134. def resetCounter(request):
  135. # Update Form counter
  136. if (request.method == 'POST'):
  137. # create a form instance and populate it with data from the request:
  138. data = dict(request.POST)
  139. counter = Counter.objects.get(pk=int(data['counter'][0]))
  140. reset = Reset()
  141. reset.counter = counter
  142. reset.reason = data['reason'][0]
  143. reset.timestamp = datetime.now()
  144. reset.save()
  145. # We send the emails only to those who have an email address
  146. emails = [u[0] for u in Counter.objects.all().values_list('email')
  147. if u[0] != 'null@localhost']
  148. # Now send emails to everyone
  149. email_to_send = EmailMessage(counter.name + ' a le seum',
  150. data['reason'][0] + '''
  151. --
  152. SeumBook™ - http://seum.merigoux.ovh
  153. P.S. : Pour ne plus recevoir ces messages, envoie un mail à denis.merigoux@gmail.com''',
  154. 'SeumMan <seum@merigoux.ovh>', emails, [],
  155. reply_to=emails)
  156. email_to_send.send()
  157. return HttpResponseRedirect(data['redirect'][0])
  158. def counter(request, id_counter):
  159. counter = Counter.objects.get(pk=id_counter)
  160. resets = Reset.objects.filter(counter=counter).order_by('-timestamp')
  161. timezero = timedelta(0)
  162. # Display
  163. if (resets.count() == 0):
  164. counter.lastReset = Reset()
  165. counter.lastReset.delta = timezero
  166. counter.lastReset.noSeum = True
  167. else:
  168. counter.lastReset = resets[0]
  169. counter.lastReset.noSeum = False
  170. counter.lastReset.delta = datetime.now(
  171. ) - counter.lastReset.timestamp.replace(tzinfo=None)
  172. counter.lastReset.formatted_delta = format_timedelta(
  173. counter.lastReset.delta, locale='fr', threshold=1)
  174. counter.seumCount = Reset.objects.filter(
  175. counter=counter).count()
  176. for reset in resets:
  177. reset.date = format_datetime(
  178. reset.timestamp, locale='fr',
  179. format="EEEE dd MMMM Y 'à' HH:mm:ss").capitalize()
  180. # Timeline graph
  181. # Data pre-processing
  182. resets_graph = resets
  183. for reset in resets_graph:
  184. reset.timestamp = {
  185. 'v': reset.timestamp.timestamp(),
  186. 'f': "Il y a " + format_timedelta(
  187. datetime.now() - reset.timestamp.replace(tzinfo=None),
  188. locale='fr', threshold=1)
  189. }
  190. reset.Seum = {'v': 0, 'f': reset.reason}
  191. # Drawing the graph
  192. data = ModelDataSource(resets, fields=['timestamp', 'Seum'])
  193. chart = gchart.LineChart(data, options={
  194. 'lineWidth': 0,
  195. 'pointSize': 10,
  196. 'title': '',
  197. 'vAxis': {'ticks': []},
  198. 'hAxis': {'ticks': [{
  199. 'v': datetime(2016, 3, 9, 23, 0, 0, 0).timestamp(),
  200. 'f': 'ADD des X2013'
  201. }, {
  202. 'v': datetime.now().timestamp(),
  203. 'f': 'Présent'}
  204. ]},
  205. 'legend': 'none',
  206. 'height': 90
  207. })
  208. return render(request, 'counterTemplate.html', {'counter': counter, 'chart': chart, 'resets': resets})