views.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. from datetime import datetime
  2. import json
  3. from django.contrib.auth import logout, login, update_session_auth_hash
  4. from django.contrib.auth.decorators import login_required
  5. from django.contrib.auth.forms import PasswordChangeForm
  6. from django.contrib.auth.models import User
  7. from django.core import serializers
  8. from django.core.paginator import Paginator
  9. from django.http.response import HttpResponse, HttpResponseRedirect
  10. from django.shortcuts import render, get_object_or_404, redirect
  11. from main.forms import StoryForm, EpicForm, RegisterForm, ProfileForm, \
  12. CommentForm, SprintForm
  13. from main.models import Story, Epic, Sprint, Comment, Project
  14. @login_required
  15. def index(request):
  16. epics = Epic.objects.filter(closed=False)
  17. return render(request, 'index.html', {'current_sprint': Sprint.current(), 'epics': epics})
  18. def register(request):
  19. if request.method == 'POST':
  20. form = RegisterForm(request.POST)
  21. if form.is_valid():
  22. user = form.save()
  23. login(request, user)
  24. return redirect("index")
  25. else:
  26. form = RegisterForm()
  27. return render(request, 'registration/register.html', {'form': form})
  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, 'com_pack': com_pack(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.closed = True
  135. story.save()
  136. return render(request, 'epic_details.html', {'epic': story.epic})
  137. def story_close_ajax(_, story_id):
  138. story = get_object_or_404(Story, id=story_id)
  139. story.closed = True
  140. story.save()
  141. return HttpResponse(story.to_json())
  142. @login_required
  143. def story_close_from_sprintend(_, story_id):
  144. story = get_object_or_404(Story, id=story_id)
  145. story.closed = True
  146. story.save()
  147. return redirect("sprint_end")
  148. @login_required
  149. def story_reaffect_ajax(_, story_id):
  150. story = get_object_or_404(Story, id=story_id)
  151. next_sprint = Sprint.next()
  152. story.sprints.add(next_sprint)
  153. story.save()
  154. return HttpResponse(story.to_json())
  155. @login_required
  156. def story_reopen(_, story_id):
  157. story = get_object_or_404(Story, id=story_id)
  158. story.closed = False
  159. story.save()
  160. return redirect('story_details.html', {'story_id': story_id})
  161. @login_required
  162. def epic_details(request, epic_id):
  163. epic = get_object_or_404(Epic, id=epic_id)
  164. return render(request, 'epic_details.html', {'epic': epic, 'com_pack': com_pack(epic)})
  165. @login_required
  166. def epic_create(request):
  167. if request.method == 'POST':
  168. form = EpicForm(request.POST)
  169. if form.is_valid():
  170. epic = form.save(commit=False)
  171. epic.author = User.objects.get(username=request.user)
  172. epic.save()
  173. return redirect("backlog_editor")
  174. else:
  175. form = EpicForm()
  176. return render(request, 'epic_form.html', {'form': form})
  177. @login_required
  178. def epic_edit(request, epic_id, from_=""):
  179. if request.method == 'POST':
  180. epic = get_object_or_404(Epic, id=epic_id)
  181. form = EpicForm(request.POST, instance=epic)
  182. if form.is_valid():
  183. form.save()
  184. if from_:
  185. return redirect(from_)
  186. else:
  187. return redirect("epic_details", epic.id)
  188. else:
  189. epic = get_object_or_404(Epic, id=epic_id)
  190. form = EpicForm(instance=epic)
  191. return render(request, 'epic_form.html', {'form': form})
  192. @login_required
  193. def epic_delete(request, epic_id):
  194. if request.method == 'POST':
  195. epic = get_object_or_404(Epic, id=epic_id)
  196. epic.delete()
  197. return redirect("index")
  198. else:
  199. epic = get_object_or_404(Epic, id=epic_id)
  200. return render(request, 'deletion.html', {'object': epic})
  201. @login_required
  202. def epic_value_update(request, epic_id):
  203. if request.method == 'POST':
  204. epic = get_object_or_404(Epic, id=epic_id)
  205. epic.value = request.POST["value"]
  206. epic.save()
  207. return redirect("backlog_editor")
  208. @login_required
  209. def epic_close(_, epic_id):
  210. epic = get_object_or_404(Epic, id=epic_id)
  211. epic.closed = True
  212. epic.save()
  213. return redirect("backlog_editor")
  214. @login_required
  215. def epic_reopen(_, epic_id):
  216. epic = get_object_or_404(Epic, id=epic_id)
  217. epic.closed = False
  218. epic.save()
  219. return redirect("backlog_editor")
  220. @login_required
  221. def reports(request):
  222. return render(request, 'reports/report_index.html')
  223. @login_required
  224. def report_sprints(request):
  225. sprints = Sprint.objects.all()
  226. return render(request, 'reports/report_sprints.html', {'sprints': sprints})
  227. @login_required
  228. def report_projects(request):
  229. epics = Epic.objects.filter(closed=False)
  230. return render(request, 'reports/report_projects.html', {'epics': epics})
  231. def report_activity(request):
  232. projects_activity = {}
  233. for project in Project.objects.all():
  234. projects_activity[project] = {}
  235. projects_activity[project]["current"] = 0
  236. projects_activity[project]["sixmonths"] = 0
  237. epics_activity = {}
  238. for epic in Epic.objects.all():
  239. epics_activity[epic] = {}
  240. epics_activity[epic]["current"] = 0
  241. epics_activity[epic]["sixmonths"] = 0
  242. current = True
  243. for sprint in Sprint.objects.filter(date_end__lt = datetime.today()).order_by('-date_start')[:12]:
  244. for story in sprint.stories.all():
  245. if not story.epic:
  246. continue
  247. if current:
  248. projects_activity[story.epic.project]["current"] += story.weight
  249. epics_activity[story.epic]["current"] += story.weight
  250. projects_activity[story.epic.project]["sixmonths"] += story.weight
  251. epics_activity[story.epic]["sixmonths"] += story.weight
  252. current = False
  253. epics_activity_cleaned = {epic: act for epic, act in epics_activity.items() if act["sixmonths"] > 0 }
  254. return render(request, 'reports/report_activity.html', {'projects_activity': projects_activity, 'epics_activity': epics_activity_cleaned})
  255. def com_pack(obj):
  256. pack = {}
  257. pack['obj'] = obj
  258. pack['comments'] = {c: CommentForm(instance=c, prefix="{}".format(c.id)) for c in obj.comments()}
  259. pack['empty_form'] = CommentForm(prefix="new")
  260. return pack
  261. @login_required
  262. def comment_post(request, obj_uuid):
  263. comment = Comment()
  264. comment.obj_uuid = obj_uuid
  265. comment.author = get_object_or_404(User, username=request.user)
  266. comment.content = request.POST["new-content"]
  267. comment.save()
  268. return redirect(request.META['HTTP_REFERER'].split("#")[0] + "#a-comment-{}".format(comment.id))
  269. @login_required
  270. def comment_edit(request, comment_id):
  271. comment = get_object_or_404(Comment, id=comment_id)
  272. comment.content = request.POST["{}-content".format(comment_id)]
  273. comment.save()
  274. return redirect(request.META['HTTP_REFERER'].split("#")[0] + "#a-comment-{}".format(comment.id))
  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)})