PageRenderTime 25ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/apps/seating/views.py

https://github.com/dotKom/studlan
Python | 310 lines | 294 code | 15 blank | 1 comment | 2 complexity | 01b68538a3721328dfbb42de5548dadf MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. from datetime import datetime
  3. from bs4 import BeautifulSoup
  4. from django.contrib import messages
  5. from django.contrib.auth.decorators import login_required, permission_required
  6. from django.core.exceptions import ObjectDoesNotExist
  7. from django.http import HttpResponse
  8. from django.shortcuts import get_object_or_404, redirect, render
  9. from django.utils.translation import ugettext as _
  10. from django.views.decorators.http import require_POST, require_safe
  11. from reportlab.lib import pagesizes
  12. from reportlab.pdfgen.canvas import Canvas as PdfCanvas
  13. from apps.lan.models import Attendee, LAN
  14. from apps.seating.models import Seat, Seating
  15. @require_safe
  16. def main(request):
  17. lans = LAN.objects.filter(end_date__gt=datetime.now()).order_by('-start_date')
  18. if lans.count() == 1:
  19. next_lan = lans[0]
  20. return redirect('seating_details', lan_id=next_lan.id)
  21. else:
  22. return redirect('seating_lan_list')
  23. @require_safe
  24. def lan_list(request):
  25. context = {}
  26. context['upcoming_lans'] = LAN.objects.filter(end_date__gte=datetime.now()).order_by('start_date')
  27. context['previous_lans'] = LAN.objects.filter(end_date__lt=datetime.now()).order_by('-start_date')
  28. return render(request, 'seating/lan_list.html', context)
  29. @require_safe
  30. def main_filtered(request, lan_id):
  31. lan = get_object_or_404(LAN, pk=lan_id)
  32. context = {}
  33. seating = Seating.objects.filter(lan=lan)
  34. seatings = Seating.objects.all()
  35. context['seatings'] = seatings
  36. context['seating'] = seating
  37. context['active'] = 'all'
  38. context['lan'] = lan
  39. breadcrumbs = (
  40. (lan, lan.get_absolute_url()),
  41. (_(u'Seating'), ''),
  42. )
  43. context['breadcrumbs'] = breadcrumbs
  44. return render(request, 'seating/seating.html', context)
  45. @require_safe
  46. def seating_details(request, lan_id, seating_id=None, seat_id=None):
  47. lan = get_object_or_404(LAN, pk=lan_id)
  48. seatings = Seating.objects.filter(lan=lan)
  49. if not seating_id:
  50. if seatings:
  51. seating = seatings[0]
  52. return redirect(seating)
  53. else:
  54. return render(request, 'seating/seating.html')
  55. seating = get_object_or_404(Seating, pk=seating_id, lan=lan)
  56. seats = seating.get_total_seats()
  57. dom = BeautifulSoup(seating.layout.template, 'html.parser')
  58. seat_counter = 0
  59. for tag in dom.find_all('a'):
  60. seat_counter += 1
  61. seat_qs = seats.filter(placement=seat_counter)
  62. if not seat_qs.exists():
  63. continue
  64. seat = seat_qs[0]
  65. children = tag.find_all('rect')
  66. children[0]['seat-number'] = seat.pk
  67. children[0]['seat-display'] = seat.placement
  68. if not seat.user:
  69. children[0]['class'] = ' seating-node-free'
  70. children[0]['status'] = 'free'
  71. else:
  72. if seat.user == request.user:
  73. children[0]['class'] = ' seating-node-self'
  74. children[0]['status'] = 'mine'
  75. else:
  76. children[0]['class'] = ' seating-node-occupied'
  77. children[0]['status'] = 'occupied'
  78. children[0]['seat-user'] = unicode(seat.user.username)
  79. # Separate title element for chrome support
  80. title = dom.new_tag('title')
  81. title.string = unicode(seat.user.username)
  82. tag.append(title)
  83. dom.encode('utf-8')
  84. context = {}
  85. context['lan'] = lan
  86. context['seatings'] = seatings
  87. context['seating'] = seating
  88. context['seat'] = seat_id
  89. if request.user.is_authenticated:
  90. context['user_ticket_types'] = seating.ticket_types.filter(ticket__user=request.user)
  91. context['hide_sidebar'] = True
  92. context['template'] = dom.__str__
  93. context['breadcrumbs'] = (
  94. (lan, lan.get_absolute_url()),
  95. (_(u'Seating'), ''),
  96. )
  97. return render(request, 'seating/seating.html', context)
  98. @require_POST
  99. @login_required()
  100. def take_seat(request, seating_id):
  101. seating = get_object_or_404(Seating, pk=seating_id)
  102. lan = seating.lan
  103. if not seating.is_open():
  104. messages.error(request, _(u'The seating is closed.'))
  105. return redirect(seating)
  106. seat_id = get_post_seat_id(request, seating)
  107. if not seat_id:
  108. return redirect(seating)
  109. seat = get_object_or_404(Seat, pk=seat_id)
  110. siblings = list(Seating.objects.filter(lan=lan))
  111. occupied = seating.get_user_registered()
  112. for sibling in siblings:
  113. occupied = occupied + sibling.get_user_registered()
  114. try:
  115. attendee = Attendee.objects.get(user=request.user, lan=lan)
  116. except ObjectDoesNotExist:
  117. attendee = None
  118. if (attendee and attendee.has_paid) or lan.has_ticket(request.user):
  119. if not seating.ticket_types or (lan.has_ticket(request.user) and lan.has_ticket(request.user).ticket_type in seating.ticket_types.all()):
  120. if not seat.user:
  121. if request.user in occupied:
  122. old_seats = Seat.objects.filter(user=request.user)
  123. for os in old_seats:
  124. if os.seating.lan == lan:
  125. os.user = None
  126. os.save()
  127. seat.user = request.user
  128. seat.save()
  129. messages.success(request, _(u'You have reserved your seat.'))
  130. else:
  131. messages.error(request, _(u'That seat is already taken.'))
  132. else:
  133. messages.warning(request, _(u'Your ticket does not work in this seating area.'))
  134. else:
  135. messages.warning(request, _(u'You need a ticket before reserving a seat.'))
  136. return redirect(lan)
  137. return redirect(seating)
  138. @require_POST
  139. @login_required()
  140. def leave_seat(request, seating_id):
  141. seating = get_object_or_404(Seating, pk=seating_id)
  142. if not seating.is_open():
  143. messages.error(request, _(u'The seating is closed.'))
  144. return redirect(seating)
  145. seat_id = get_post_seat_id(request, seating)
  146. if not seat_id:
  147. return redirect(seating)
  148. seat = get_object_or_404(Seat, pk=seat_id)
  149. if seat.user == request.user:
  150. seat.user = None
  151. seat.save()
  152. messages.success(request, _(u'You have unreserved your seat.'))
  153. else:
  154. messages.error(request, _(u'This is not your seat.'))
  155. return redirect(seating)
  156. def get_post_seat_id(request, seating):
  157. seat_id_str = request.POST.get('seat')
  158. if not seat_id_str:
  159. messages.error(request, _(u'No seat was specified.'))
  160. return None
  161. try:
  162. seat_id = int(seat_id_str)
  163. except ValueError:
  164. messages.error(request, _(u'Illegal seat.'))
  165. return None
  166. return seat_id
  167. @require_safe
  168. @permission_required('seating.export_seating')
  169. def seating_list(request, seating_id):
  170. seating = get_object_or_404(Seating, pk=seating_id)
  171. lan = get_object_or_404(LAN, id=seating.lan.id)
  172. seats = list(Seat.objects.filter(seating=seating).order_by('placement'))
  173. response = HttpResponse(content_type='application/pdf')
  174. response['Content-Disposition'] = 'attachment; filename=' + seating.title + '.pdf'
  175. page_size = pagesizes.A4
  176. page_width, page_height = page_size
  177. page_width_center = page_width / 2
  178. p = PdfCanvas(response, pagesize=page_size)
  179. cursor_top = page_height - 120
  180. left_col_offset = 50
  181. right_col_offset = 300
  182. # 1 is left, 2 is right
  183. page_side = 1
  184. cursor = cursor_top
  185. new_page = True
  186. x_offset = left_col_offset
  187. page_num = 1
  188. for seat in seats:
  189. if cursor < 70:
  190. # Flip to right side or new page
  191. cursor = cursor_top
  192. if page_side == 1:
  193. page_side = 2
  194. x_offset = right_col_offset
  195. else:
  196. page_side = 1
  197. x_offset = left_col_offset
  198. new_page = True
  199. page_num += 1
  200. p.showPage()
  201. if new_page:
  202. new_page = False
  203. p.setFont('Times-Roman', 25)
  204. p.drawCentredString(page_width_center, page_height - 60, lan.title)
  205. p.setFont('Times-Roman', 20)
  206. p.drawCentredString(page_width_center, page_height - 90, seating.title)
  207. p.setFont('Helvetica', 14)
  208. p.drawCentredString(page_width_center, 40, '{0} {1}'.format(_(u'Page'), page_num))
  209. # For seat text
  210. p.setFont('Helvetica', 14)
  211. occupant = unicode(seat.user) if seat.user else ''
  212. p.drawString(x_offset, cursor, u'{0} {1}: {2}'.format(_(u'Seat'), seat.placement, occupant))
  213. cursor -= 20
  214. p.showPage()
  215. p.save()
  216. return response
  217. @require_safe
  218. @permission_required('seating.export_seating')
  219. def seating_map(request, seating_id):
  220. seating = get_object_or_404(Seating, pk=seating_id)
  221. lan = get_object_or_404(LAN, id=seating.lan.id)
  222. seats = list(Seat.objects.filter(seating=seating).order_by('placement'))
  223. response = HttpResponse(content_type='application/pdf')
  224. response['Content-Disposition'] = 'attachment; filename=' + seating.title + '.pdf'
  225. page_size = pagesizes.A4
  226. page_width, page_height = page_size
  227. page_width_center = page_width / 2
  228. page_height_center = page_height / 2
  229. p = PdfCanvas(response, pagesize=page_size)
  230. new_page = True
  231. y_offset = page_height_center
  232. for seat in seats:
  233. p.setFont('Times-Roman', 40)
  234. p.drawCentredString(page_width_center, y_offset + 310, lan.title)
  235. p.setFont('Times-Roman', 35)
  236. text = _(u'%(seating)s, seat %(seat)d') % {'seating': seating.title, 'seat': seat.placement}
  237. p.drawCentredString(page_width_center, y_offset + 250, text)
  238. if seat.user:
  239. p.setFont('Helvetica', 40)
  240. occupant = unicode(seat.user)
  241. else:
  242. p.setFont('Helvetica', 40)
  243. occupant = _(u'(Available)')
  244. p.drawCentredString(page_width_center, y_offset + 150, occupant)
  245. if new_page:
  246. new_page = False
  247. y_offset = 0
  248. else:
  249. new_page = True
  250. y_offset = page_height_center
  251. p.showPage()
  252. p.showPage()
  253. p.save()
  254. return response