views.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. from datetime import datetime
  2. from django.contrib.auth import logout, login, update_session_auth_hash
  3. from django.contrib.auth.decorators import login_required
  4. from django.contrib.auth.forms import PasswordChangeForm
  5. from django.contrib.auth.models import User
  6. from django.core.paginator import Paginator
  7. from django.http.response import HttpResponse
  8. from django.shortcuts import render, get_object_or_404, redirect
  9. from django.urls.base import reverse
  10. from notifications.signals import notify
  11. from main.forms import StoryForm, EpicForm, RegisterForm, ProfileForm, \
  12. CommentForm, SprintForm
  13. from main.models import Story, Epic, Sprint, Comment, Project
  14. def register(request):
  15. if request.method == 'POST':
  16. form = RegisterForm(request.POST)
  17. if form.is_valid():
  18. user = form.save()
  19. login(request, user)
  20. return redirect("index")
  21. else:
  22. form = RegisterForm()
  23. return render(request, 'registration/register.html', {'form': form})
  24. @login_required
  25. def index(request):
  26. epics = Epic.objects.filter(closed=False)
  27. return render(request, 'index.html', {'current_sprint': Sprint.current(), 'epics': epics})
  28. @login_required
  29. def profile_update(request):
  30. if request.method == 'POST':
  31. user = get_object_or_404(User, username=request.user)
  32. form = ProfileForm(request.POST, instance=user)
  33. if form.is_valid():
  34. user = form.save()
  35. login(request, user)
  36. return redirect("index")
  37. else:
  38. user = get_object_or_404(User, username=request.user)
  39. form = ProfileForm(instance=user)
  40. return render(request, 'registration/register.html', {'form': form})
  41. @login_required
  42. def change_password(request):
  43. if request.method == 'POST':
  44. form = PasswordChangeForm(request.user, request.POST)
  45. if form.is_valid():
  46. user = form.save()
  47. update_session_auth_hash(request, user) # Important!
  48. return redirect('index')
  49. else:
  50. form = PasswordChangeForm(request.user)
  51. return render(request, 'registration/change_password.html', {'form': form})
  52. @login_required
  53. def logout(request):
  54. logout(request)
  55. return redirect("index")
  56. @login_required
  57. def backlog_editor(request):
  58. epics = Epic.objects.filter(closed=False)
  59. closed = Epic.objects.filter(closed=True)
  60. return render(request, 'backlog_editor.html', {'epics': epics, 'closed': closed})
  61. def sprint_end(request):
  62. current_sprint = Sprint.current()
  63. next_sprint = Sprint.next()
  64. if request.method == 'POST':
  65. current_sprint.retro = request.POST["retro"]
  66. current_sprint.closed = True
  67. current_sprint.save()
  68. return redirect("index")
  69. form = SprintForm(instance=current_sprint)
  70. return render(request, 'sprint_end.html', {'sprint': current_sprint, 'next_sprint': next_sprint, 'form': form})
  71. @login_required
  72. def story_index(request):
  73. sprints = Sprint.objects.all()
  74. users = User.objects.all()
  75. stories = Story.objects
  76. filters = request.GET
  77. if 'state' in filters and filters['state']:
  78. stories = stories.filter(closed=(filters['state'] == 'closed'))
  79. if 'sprint' in filters and filters['sprint']:
  80. if filters['sprint'] == "None":
  81. stories = stories.filter(sprints=None)
  82. else:
  83. stories = stories.filter(sprints__id=filters['sprint'])
  84. if 'author' in filters and filters['author']:
  85. stories = stories.filter(author_id=filters['author'])
  86. if 'assignee' in filters and filters['assignee']:
  87. stories = stories.filter(assignees__id=filters['assignee'])
  88. paginator = Paginator(stories.all(), 20)
  89. page = request.GET.get('page')
  90. stories = paginator.get_page(page)
  91. return render(request, 'story_index.html', {'stories': stories, 'sprints': sprints, 'users': users, 'pages': range(1, paginator.num_pages + 1)})
  92. @login_required
  93. def story_details(request, story_id):
  94. story = get_object_or_404(Story, id=story_id)
  95. return render(request, 'story_details.html', {'story': story})
  96. @login_required
  97. def story_create(request, epic_id=None):
  98. if request.method == 'POST':
  99. form = StoryForm(request.POST)
  100. if form.is_valid():
  101. story = form.save()
  102. return redirect("story_details", story.id)
  103. else:
  104. story = Story()
  105. if epic_id is not None:
  106. story.epic = get_object_or_404(Epic, id=epic_id)
  107. story.author = User.objects.get(username=request.user)
  108. form = StoryForm(instance=story)
  109. return render(request, 'story_form.html', {'form': form, 'current_sprint_id': Sprint.current().id})
  110. @login_required
  111. def story_edit(request, story_id):
  112. if request.method == 'POST':
  113. story = get_object_or_404(Story, id=story_id)
  114. form = StoryForm(request.POST, instance=story)
  115. if form.is_valid():
  116. form.save()
  117. return redirect("story_details", story.id)
  118. else:
  119. story = get_object_or_404(Story, id=story_id)
  120. form = StoryForm(instance=story)
  121. return render(request, 'story_form.html', {'form': form, 'current_sprint_id': Sprint.current().id})
  122. @login_required
  123. def story_delete(request, story_id):
  124. if request.method == 'POST':
  125. story = get_object_or_404(Story, id=story_id)
  126. story.delete()
  127. return redirect("index")
  128. else:
  129. story = get_object_or_404(Story, id=story_id)
  130. return render(request, 'deletion.html', {'object': story})
  131. @login_required
  132. def story_close(request, story_id):
  133. story = get_object_or_404(Story, id=story_id)
  134. story.close()
  135. if request.is_ajax():
  136. return HttpResponse(story.to_json())
  137. else:
  138. return redirect('epic_details', story.epic.id)
  139. @login_required
  140. def story_reaffect(request, story_id):
  141. story = get_object_or_404(Story, id=story_id)
  142. next_sprint = Sprint.next()
  143. story.sprints.add(next_sprint)
  144. story.save()
  145. if request.is_ajax():
  146. return HttpResponse(story.to_json())
  147. else:
  148. return redirect('story_details', story.id)
  149. @login_required
  150. def story_reopen(_, story_id):
  151. story = get_object_or_404(Story, id=story_id)
  152. story.reopen()
  153. return redirect('story_details', story_id)
  154. @login_required
  155. def epic_details(request, epic_id):
  156. epic = get_object_or_404(Epic, id=epic_id)
  157. return render(request, 'epic_details.html', {'epic': epic})
  158. @login_required
  159. def epic_create(request):
  160. if request.method == 'POST':
  161. form = EpicForm(request.POST)
  162. if form.is_valid():
  163. epic = form.save(commit=False)
  164. epic.author = User.objects.get(username=request.user)
  165. epic.save()
  166. return redirect("backlog_editor")
  167. else:
  168. form = EpicForm()
  169. return render(request, 'epic_form.html', {'form': form})
  170. @login_required
  171. def epic_edit(request, epic_id, from_=""):
  172. if request.method == 'POST':
  173. epic = get_object_or_404(Epic, id=epic_id)
  174. form = EpicForm(request.POST, instance=epic)
  175. if form.is_valid():
  176. form.save()
  177. if from_:
  178. return redirect(from_)
  179. else:
  180. return redirect("epic_details", epic.id)
  181. else:
  182. epic = get_object_or_404(Epic, id=epic_id)
  183. form = EpicForm(instance=epic)
  184. return render(request, 'epic_form.html', {'form': form})
  185. @login_required
  186. def epic_delete(request, epic_id):
  187. if request.method == 'POST':
  188. epic = get_object_or_404(Epic, id=epic_id)
  189. epic.delete()
  190. return redirect("index")
  191. else:
  192. epic = get_object_or_404(Epic, id=epic_id)
  193. return render(request, 'deletion.html', {'object': epic})
  194. @login_required
  195. def epic_value_update(request, epic_id):
  196. if request.method == 'POST':
  197. epic = get_object_or_404(Epic, id=epic_id)
  198. epic.value = request.POST["value"]
  199. epic.save()
  200. return redirect("backlog_editor")
  201. @login_required
  202. def epic_close(_, epic_id):
  203. epic = get_object_or_404(Epic, id=epic_id)
  204. epic.close()
  205. epic.save()
  206. return redirect("backlog_editor")
  207. @login_required
  208. def epic_reopen(_, epic_id):
  209. epic = get_object_or_404(Epic, id=epic_id)
  210. epic.reopen()
  211. return redirect("backlog_editor")
  212. @login_required
  213. def reports(request):
  214. return render(request, 'reports/report_index.html')
  215. @login_required
  216. def report_sprints(request):
  217. sprints = Sprint.objects.all()
  218. return render(request, 'reports/report_sprints.html', {'sprints': sprints})
  219. @login_required
  220. def report_projects(request):
  221. epics = Epic.objects.filter(closed=False)
  222. return render(request, 'reports/report_projects.html', {'epics': epics})
  223. def report_activity(request):
  224. projects_activity = {}
  225. for project in Project.objects.all():
  226. projects_activity[project] = {}
  227. projects_activity[project]["current"] = 0
  228. projects_activity[project]["sixmonths"] = 0
  229. epics_activity = {}
  230. for epic in Epic.objects.all():
  231. epics_activity[epic] = {}
  232. epics_activity[epic]["current"] = 0
  233. epics_activity[epic]["sixmonths"] = 0
  234. current = True
  235. for sprint in Sprint.objects.filter(date_end__lt = datetime.today()).order_by('-date_start')[:12]:
  236. for story in sprint.stories.all():
  237. if not story.epic:
  238. continue
  239. if current:
  240. projects_activity[story.epic.project]["current"] += story.weight
  241. epics_activity[story.epic]["current"] += story.weight
  242. projects_activity[story.epic.project]["sixmonths"] += story.weight
  243. epics_activity[story.epic]["sixmonths"] += story.weight
  244. current = False
  245. epics_activity_cleaned = {epic: act for epic, act in epics_activity.items() if act["sixmonths"] > 0 }
  246. return render(request, 'reports/report_activity.html', {'projects_activity': projects_activity, 'epics_activity': epics_activity_cleaned})
  247. @login_required
  248. def comment_post(request):
  249. form = CommentForm(request.POST)
  250. if form.is_valid():
  251. comment = form.save(commit=False)
  252. comment.author = request.user
  253. comment.save()
  254. obj = comment.content_object
  255. notify.send(request.user,
  256. recipient=obj.contributors(),
  257. action_object = obj,
  258. verb="{} a commenté <a href='{}#a-comment-{}'>{} #{}</a>".format(request.user.username,
  259. reverse('{}_details'.format(obj.model_name().lower()), args=(obj.id,)),
  260. comment.id,
  261. obj.model_name(),
  262. obj.id))
  263. return redirect(request.META['HTTP_REFERER'].split("#")[0] + "#a-comment-{}".format(comment.id))
  264. else:
  265. return redirect(request.META['HTTP_REFERER'])
  266. @login_required
  267. def comment_edit(request, comment_id):
  268. comment = get_object_or_404(Comment, id=comment_id)
  269. form = CommentForm(request.POST, instance=comment)
  270. if form.is_valid():
  271. form.save()
  272. return redirect(request.META['HTTP_REFERER'].split("#")[0] + "#a-comment-{}".format(comment_id))
  273. else:
  274. return redirect(request.META['HTTP_REFERER'])
  275. @login_required
  276. def comment_del(request, comment_id):
  277. comment = get_object_or_404(Comment, id=comment_id)
  278. comment.delete()
  279. return redirect(request.META['HTTP_REFERER'].split("#")[0] + "#a-comment-section")
  280. @login_required
  281. def search(request):
  282. qstr = request.GET["q"]
  283. results = []
  284. results += Epic.objects.filter(name__icontains=qstr)
  285. results += Story.objects.filter(name__icontains=qstr)
  286. results += Epic.objects.filter(description__icontains=qstr)
  287. results += Story.objects.filter(description__icontains=qstr)
  288. if len(results) == 1:
  289. r = results[0]
  290. if isinstance(r, Epic):
  291. return redirect("epic_details", r.id)
  292. else:
  293. return redirect("story_details", r.id)
  294. else:
  295. paginator = Paginator(results, 10)
  296. page = request.GET.get('page')
  297. results = paginator.get_page(page)
  298. return render(request, 'search_results.html', {'results': results, 'pages': range(1, paginator.num_pages + 1)})
  299. @login_required
  300. def notif_seen(request):
  301. pass
  302. @login_required
  303. def all_notif_seen(request):
  304. pass