views.py 12 KB

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