De-avatarify most of room booking (except room owner)
[cds-indico.git] / indico / modules / rb / controllers / user / rooms.py
bloba856ee7fdb5d88ae5a84a18c180a4afa0a202ac3
1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 from datetime import date, datetime, timedelta, time
19 from dateutil.relativedelta import relativedelta
20 from flask import request, session
21 from sqlalchemy import func
22 from werkzeug.datastructures import MultiDict
24 from indico.core.errors import IndicoError
25 from indico.modules.rb.controllers import RHRoomBookingBase
26 from indico.modules.rb.controllers.decorators import requires_location, requires_room
27 from indico.modules.rb.forms.rooms import SearchRoomsForm
28 from indico.modules.rb.models.locations import Location
29 from indico.modules.rb.models.reservation_occurrences import ReservationOccurrence
30 from indico.modules.rb.models.reservations import RepeatMapping, RepeatFrequency, Reservation
31 from indico.modules.rb.models.rooms import Room
32 from indico.modules.rb.models.equipment import EquipmentType
33 from indico.modules.rb.statistics import calculate_rooms_occupancy, compose_rooms_stats
34 from indico.modules.rb.views.user.rooms import (WPRoomBookingSearchRooms, WPRoomBookingMapOfRooms,
35 WPRoomBookingMapOfRoomsWidget, WPRoomBookingRoomDetails,
36 WPRoomBookingRoomStats, WPRoomBookingSearchRoomsResults)
37 from indico.web.forms.base import FormDefaults
38 from MaKaC.common.cache import GenericCache
41 class RHRoomBookingMapOfRooms(RHRoomBookingBase):
42 def _checkParams(self):
43 RHRoomBookingBase._checkParams(self, request.args)
44 self._room_id = request.args.get('roomID')
46 def _process(self):
47 return WPRoomBookingMapOfRooms(self, roomID=self._room_id).display()
50 class RHRoomBookingMapOfRoomsWidget(RHRoomBookingBase):
51 def __init__(self, *args, **kwargs):
52 RHRoomBookingBase.__init__(self, *args, **kwargs)
53 self._cache = GenericCache('MapOfRooms')
55 def _checkParams(self):
56 RHRoomBookingBase._checkParams(self, request.args)
57 self._room_id = request.args.get('roomID')
59 def _process(self):
60 key = str(sorted(dict(request.args, lang=session.lang, user=session.user.id).items()))
61 html = self._cache.get(key)
62 if not html:
63 default_location = Location.default_location
64 aspects = [a.to_serializable() for a in default_location.aspects]
65 buildings = default_location.get_buildings()
66 html = WPRoomBookingMapOfRoomsWidget(self,
67 aspects=aspects,
68 buildings=buildings,
69 room_id=self._room_id,
70 default_repeat='{}|0'.format(int(RepeatFrequency.NEVER)),
71 default_start_dt=datetime.combine(date.today(),
72 Location.working_time_start),
73 default_end_dt=datetime.combine(date.today(),
74 Location.working_time_end),
75 repeat_mapping=RepeatMapping.mapping).display()
76 self._cache.set(key, html, 3600)
77 return html
80 class RHRoomBookingSearchRooms(RHRoomBookingBase):
81 menu_item = 'roomSearch'
83 def _get_form_data(self):
84 return request.form
86 def _checkParams(self):
87 defaults = FormDefaults(location=Location.default_location)
88 self._form = SearchRoomsForm(self._get_form_data(), obj=defaults)
89 if (not session.user or not Room.user_owns_rooms(session.user)) and not hasattr(self, 'search_criteria'):
90 # Remove the form element if the user has no rooms and we are not using a shortcut
91 del self._form.is_only_my_rooms
93 def _is_submitted(self):
94 return self._form.is_submitted()
96 def _process(self):
97 form = self._form
98 if self._is_submitted() and form.validate():
99 rooms = Room.find_with_filters(form.data, session.user)
100 return WPRoomBookingSearchRoomsResults(self, self.menu_item, rooms=rooms).display()
101 equipment_locations = {eq.id: eq.location_id for eq in EquipmentType.find()}
102 return WPRoomBookingSearchRooms(self, form=form, errors=form.error_list, rooms=Room.find_all(),
103 equipment_locations=equipment_locations).display()
106 class RHRoomBookingSearchRoomsShortcutBase(RHRoomBookingSearchRooms):
107 """Base class for searches with predefined criteria"""
108 search_criteria = {}
110 def _is_submitted(self):
111 return True
113 def _get_form_data(self):
114 return MultiDict(self.search_criteria)
117 class RHRoomBookingSearchMyRooms(RHRoomBookingSearchRoomsShortcutBase):
118 menu_item = 'myRoomList'
119 search_criteria = {
120 'is_only_my_rooms': True,
121 'location': None
125 class RHRoomBookingRoomDetails(RHRoomBookingBase):
126 @requires_location
127 @requires_room
128 def _checkParams(self):
129 self._calendar_start = datetime.combine(date.today(), time())
130 self._calendar_end = datetime.combine(date.today(), time(23, 59))
131 try:
132 preview_months = int(request.args.get('preview_months', '0'))
133 except (TypeError, ValueError):
134 preview_months = 0
135 self._calendar_end += timedelta(days=31 * preview_months)
137 def _get_view(self, **kwargs):
138 return WPRoomBookingRoomDetails(self, **kwargs)
140 def _process(self):
141 occurrences = ReservationOccurrence.find_all(
142 Reservation.room_id == self._room.id,
143 ReservationOccurrence.start_dt >= self._calendar_start,
144 ReservationOccurrence.end_dt <= self._calendar_end,
145 ReservationOccurrence.is_valid,
146 _join=Reservation,
147 _eager=ReservationOccurrence.reservation
150 return self._get_view(room=self._room, start_dt=self._calendar_start, end_dt=self._calendar_end,
151 occurrences=occurrences).display()
154 class RHRoomBookingRoomStats(RHRoomBookingBase):
155 def _checkParams(self):
156 self._room = Room.get(request.view_args['roomID'])
157 self._occupancy_period = request.args.get('period', 'pastmonth')
158 self._end = date.today()
159 if self._occupancy_period == 'pastmonth':
160 self._end = self._end - relativedelta(days=1)
161 self._start = self._end - relativedelta(days=29)
162 elif self._occupancy_period == 'thisyear':
163 self._start = date(self._end.year, 1, 1)
164 elif self._occupancy_period == 'sinceever':
165 self._start = Reservation.query.with_entities(func.min(Reservation.start_dt)).one()[0].date()
166 else:
167 raise IndicoError('Invalid period specified')
169 def _process(self):
170 return WPRoomBookingRoomStats(self,
171 room=self._room,
172 period=self._occupancy_period,
173 occupancy=calculate_rooms_occupancy([self._room], self._start, self._end),
174 stats=compose_rooms_stats([self._room])).display()