source: indico/indico/MaKaC/services/implementation/collaboration.py @ e9b1d7

hello-world-walkthroughipv6v0.98-seriesv0.98.2v0.98.3v0.99v1.0v1.1
Last change on this file since e9b1d7 was e9b1d7, checked in by Pedro Ferreira <jose.pedro.ferreira@…>, 16 months ago

[FIX] VSO - Relative dates now disregard HH:MM

  • Modified from days to always start at 00:00 on date.
  • Modified to days to always end at 23:59 on date.
  • Property mode set to 100644
File size: 21.4 KB
Line 
1# -*- coding: utf-8 -*-
2##
3##
4## This file is part of CDS Indico.
5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
6##
7## CDS Indico is free software; you can redistribute it and/or
8## modify it under the terms of the GNU General Public License as
9## published by the Free Software Foundation; either version 2 of the
10## License, or (at your option) any later version.
11##
12## CDS Indico is distributed in the hope that it will be useful, but
13## WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15## General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20
21from datetime import timedelta
22from MaKaC.services.implementation.base import ParameterManager, AdminService
23from MaKaC.services.interface.rpc.common import NoReportError
24from MaKaC.services.implementation.conference import ConferenceModifBase
25from MaKaC.plugins.Collaboration.base import CollaborationException, CollaborationServiceException
26from MaKaC.webinterface.rh.collaboration import RCCollaborationAdmin,\
27    RCCollaborationPluginAdmin, RCVideoServicesManager, RCVideoServicesUser
28from MaKaC.i18n import _
29from MaKaC.common.indexes import IndexesHolder
30from MaKaC.plugins import PluginsHolder
31from MaKaC.common.timezoneUtils import nowutc, setAdjustedDate
32from MaKaC.common.utils import parseDateTime
33from MaKaC.plugins.Collaboration.collaborationTools import CollaborationTools
34from MaKaC.webinterface.user import UserListModificationBase,\
35    UserModificationBase
36from MaKaC.common.fossilize import fossilize
37
38
39## Base classes
40class CollaborationBase(ConferenceModifBase):
41    """ This base class stores the _CSBookingManager attribute
42        so that inheriting classes can use it.
43    """
44    def _checkParams(self):
45        ConferenceModifBase._checkParams(self) #sets self._target = self._conf = the Conference object
46        self._checkCollaborationEnabled()
47        self._CSBookingManager = self._conf.getCSBookingManager()
48
49    def _checkCollaborationEnabled(self):
50        """ Checks if the Collaboration plugin system is active
51        """
52        if not PluginsHolder().hasPluginType("Collaboration"):
53            raise CollaborationServiceException("Collaboration plugin system is not active")
54
55    def _checkCanManagePlugin(self, plugin):
56        isAdminOnlyPlugin = CollaborationTools.isAdminOnlyPlugin(plugin)
57
58        hasAdminRights = RCCollaborationAdmin.hasRights(self) or \
59                         RCCollaborationPluginAdmin.hasRights(self, None, [plugin])
60
61        if not hasAdminRights and isAdminOnlyPlugin:
62            raise CollaborationException(_("Cannot acces service of admin-only plugin if user is not admin, for event: ") + str(self._conf.getId()) + _(" with the service ") + str(self.__class__) )
63
64        elif not hasAdminRights and not RCVideoServicesManager.hasRights(self, [plugin]):
65            #we check if it's an event creator / manager (this will call ConferenceModifBase._checkProtection)
66            CollaborationBase._checkProtection(self)
67
68    def process(self):
69        try:
70            return ConferenceModifBase.process(self)
71        except CollaborationException, e:
72            raise CollaborationServiceException(e.getMsg(), str(e.getInner()))
73
74class CollaborationBookingModifBase(CollaborationBase):
75    """ Base class for services that are passed a booking id.
76        It is stored in self._bookingId
77    """
78    def _checkParams(self):
79        CollaborationBase._checkParams(self)
80        if self._params.has_key('bookingId'):
81            self._bookingId = self._params['bookingId']
82            booking = self._CSBookingManager.getBooking(self._bookingId)
83            if booking == None:
84                raise NoReportError(_("The booking that you are trying to modify does not exist. Maybe it was already deleted, please refresh the page."))
85
86            self._bookingType = booking.getType()
87            self._bookingPlugin = booking.getPlugin()
88        else:
89            raise CollaborationException(_("Booking id not set when trying to modify a booking on meeting ") + str(self._conf.getId()) + _(" with the service ") + str(self.__class__) )
90
91    def _checkProtection(self):
92        CollaborationBase._checkCanManagePlugin(self, self._bookingType)
93
94class CollaborationAdminBookingModifBase(CollaborationBookingModifBase):
95    """ Base class for services on booking objects that can only be requested by Server Admins,
96        Video Services Admins, or Plugin admins, such as accept or reject a request, etc.
97    """
98
99    def _checkProtection(self):
100        if not RCCollaborationAdmin.hasRights(self) and not RCCollaborationPluginAdmin.hasRights(self, None, [self._bookingPlugin]):
101            raise CollaborationException(_("You don't have the rights to perform this operation on this booking"))
102
103class AdminCollaborationBase(AdminService):
104    """ Base class for admin services in the Video Services Overview page, not directed towards a specific booking.
105    """
106
107    def _checkParams(self):
108        AdminService._checkParams(self)
109        if not PluginsHolder().hasPluginType("Collaboration"):
110            raise CollaborationServiceException(_("Collaboration plugin system is not active"))
111
112    def _checkProtection(self):
113        if not RCCollaborationAdmin.hasRights(self, None):
114            AdminService._checkProtection(self)
115
116##! End of base classes
117
118class CollaborationBookingModif(CollaborationBookingModifBase):
119    """ Specific to check the authorised users and groups creating, editing and removing.
120        It is different to CollaborationBookingModifBase because:
121        * CollaborationBookingModif: people that can create, edit, remove
122        * CollaborationBookingModifBase: people that can start, stop, sync, etc
123    """
124    def _checkProtection(self):
125        CollaborationBookingModifBase._checkProtection(self)
126        if not RCVideoServicesUser.hasRights(self, None, self._bookingType):
127            raise CollaborationException(_("You dot have access to modify a %s booking")%self._bookingType)
128
129class CollaborationCreateCSBooking(CollaborationBase, CollaborationBookingModif):
130    """ Adds a new booking
131    """
132    def _checkParams(self):
133        CollaborationBase._checkParams(self)
134
135        if 'type' in self._params:
136            self._bookingType = self._params['type']
137        else:
138            raise CollaborationException(_("type parameter not set when trying to create a booking on meeting ") + str(self._conf.getId() ))
139
140        if 'bookingParams' in self._params:
141            pm = ParameterManager(self._params)
142            self._bookingParams = pm.extract("bookingParams", pType=dict, allowEmpty = True)
143        else:
144            raise CollaborationException(_("Custom parameters for plugin ") + str(self._type) + _(" not set when trying to create a booking on meeting ") + str(self._conf.getId() ))
145
146    def _checkProtection(self):
147        CollaborationBookingModif._checkProtection(self)
148
149    def _getAnswer(self):
150        return fossilize(self._CSBookingManager.createBooking(self._bookingType, bookingParams = self._bookingParams),
151                         None, tz = self._conf.getTimezone())
152
153class CollaborationRemoveCSBooking(CollaborationBookingModif):
154    """ Removes a booking
155    """
156
157    def _getAnswer(self):
158        return fossilize(self._CSBookingManager.removeBooking(self._bookingId),
159                         None, tz = self._conf.getTimezone())
160
161
162class CollaborationEditCSBooking(CollaborationBookingModif):
163    """ Edits a booking
164    """
165    def _checkParams(self):
166        CollaborationBookingModif._checkParams(self)
167
168        if self._params.has_key('bookingParams'):
169            pm = ParameterManager(self._params)
170            self._bookingParams = pm.extract("bookingParams", pType=dict, allowEmpty = True)
171        else:
172            raise CollaborationException(_("Custom parameters for booking ") + str(self._bookingId) + _(" not set when trying to edit a booking on meeting ") + str(self._conf.getId() ))
173
174    def _getAnswer(self):
175        return fossilize(self._CSBookingManager.changeBooking(self._bookingId, self._bookingParams),
176                         None, tz = self._conf.getTimezone())
177
178
179class CollaborationStartCSBooking(CollaborationBookingModifBase):
180    """ Performs server-side actions when a booking is started
181    """
182    def _getAnswer(self):
183        return fossilize(self._CSBookingManager.startBooking(self._bookingId),
184                         None, tz = self._conf.getTimezone())
185
186class CollaborationStopCSBooking(CollaborationBookingModifBase):
187    """ Performs server-side actions when a booking is stopped
188    """
189    def _getAnswer(self):
190        return fossilize(self._CSBookingManager.stopBooking(self._bookingId),
191                                  timezone = self._conf.getTimezone())
192
193class CollaborationConnectCSBooking(CollaborationBookingModifBase):
194    """ Performs server-side actions when a booking is connected
195    """
196    def _getAnswer(self):
197        return fossilize(self._CSBookingManager.connectBooking(self._bookingId),
198                                  timezone = self._conf.getTimezone())
199
200class CollaborationCheckCSBookingStatus(CollaborationBookingModifBase):
201    """ Performs server-side actions when a booking's status is checked
202    """
203    def _getAnswer(self):
204        return fossilize(self._CSBookingManager.checkBookingStatus(self._bookingId),
205                         None, tz = self._conf.getTimezone())
206
207class CollaborationAcceptCSBooking(CollaborationAdminBookingModifBase):
208    """ Performs server-side actions when a booking / request is accepted
209    """
210    def _getAnswer(self):
211        return fossilize(self._CSBookingManager.acceptBooking(self._bookingId, self.getAW().getUser()),
212                                  None, tz = self._conf.getTimezone())
213
214class CollaborationRejectCSBooking(CollaborationAdminBookingModifBase):
215    """ Performs server-side actions when a booking / request is rejected
216    """
217    def _checkParams(self):
218        CollaborationAdminBookingModifBase._checkParams(self)
219        self._reason = self._params.get("reason", "")
220
221    def _getAnswer(self):
222        return fossilize(self._CSBookingManager.rejectBooking(self._bookingId, self._reason),
223                                  None, tz = self._conf.getTimezone())
224
225class CollaborationChangePluginManagersBase(CollaborationBase):
226    """ Base class for adding and removing plugin managers in an event
227        self._plugin will be a string with the plugin name.
228    """
229
230    def _checkParams(self):
231        CollaborationBase._checkParams(self)
232        if self._params.has_key('plugin'):
233            self._plugin = self._params['plugin']
234        else:
235            raise CollaborationException(_("Plugin name not set when trying to add or remove a manager on event: ") + str(self._conf.getId()) + _(" with the service ") + str(self.__class__) )
236
237        if CollaborationTools.getCollaborationPluginType().hasPlugin(self._plugin) and CollaborationTools.isAdminOnlyPlugin(self._plugin):
238            raise CollaborationException(_("Tried to add or remove a manager for an admin-only plugin on event : ") + str(self._conf.getId()) + _(" with the service ") + str(self.__class__) )
239
240    def _checkProtection(self):
241        if not RCVideoServicesManager.hasRights(self):
242            CollaborationBase._checkProtection(self)
243
244class CollaborationAddPluginManager(CollaborationChangePluginManagersBase, UserListModificationBase):
245    """ Adds a user as Plugin Manager for an event and plugin
246    """
247
248    def _checkParams(self):
249        CollaborationChangePluginManagersBase._checkParams(self)
250        UserListModificationBase._checkParams(self)
251
252    def _getAnswer(self):
253        existingManagerIds = set([u.getId() for u in self._CSBookingManager.getPluginManagers(self._plugin)])
254        for u in self._avatars:
255            if not u.getId() in existingManagerIds:
256                self._CSBookingManager.addPluginManager(self._plugin, u)
257
258        return True
259
260
261class CollaborationRemovePluginManager(CollaborationChangePluginManagersBase, UserModificationBase):
262    """ Removes a user as Plugin Manager for an event and plugin
263    """
264
265    def _checkParams(self):
266        CollaborationChangePluginManagersBase._checkParams(self)
267        UserModificationBase._checkParams(self)
268
269    def _getAnswer(self):
270        self._CSBookingManager.removePluginManager(self._plugin, self._targetUser)
271        return True
272
273
274class CollaborationBookingIndexQuery(AdminCollaborationBase):
275    """ Performs a query to the Collaboration index of bookings / request objects.
276    """
277
278    def _checkProtection(self):
279        if not RCCollaborationPluginAdmin.hasRights(self, None, "any"):
280            AdminCollaborationBase._checkProtection(self)
281
282    def _checkParams(self):
283        AdminCollaborationBase._checkParams(self)
284        user = self.getAW().getUser()
285        if user: #someone is logged in. if not, AdminCollaborationBase's _checkProtection will take care of it
286            self._tz = user.getTimezone()
287
288            try:
289                self._page = self._params.get("page", None)
290                self._resultsPerPage = self._params.get("resultsPerPage", None)
291                self._indexName = self._params['indexName']
292                self._viewBy = self._params['viewBy']
293                self._orderBy = self._params['orderBy']
294
295                minKey = None
296                maxKey = None
297                if self._params['sinceDate']:
298                    minKey = setAdjustedDate(parseDateTime(self._params['sinceDate'].strip()), tz = self._tz)
299                if self._params['toDate']:
300                    maxKey = setAdjustedDate(parseDateTime(self._params['toDate'].strip()), tz = self._tz)
301                if self._params['fromTitle']:
302                    minKey = self._params['fromTitle'].strip()
303                if self._params['toTitle']:
304                    maxKey = self._params['toTitle'].strip()
305
306                """ For relative dates, create a diff timedelta for resetting to
307                    00:00 at the start of range and 23:59 at the end.
308                """
309                if self._params['fromDays']:
310                    try:
311                        fromDays = int(self._params['fromDays'])
312                    except ValueError, e:
313                        raise CollaborationException(_("Parameter 'fromDays' is not an integer"), inner = e)
314                    now = nowutc()
315                    diff = timedelta(hours = now.hour, minutes = now.minute, seconds = now.second)
316                    minKey = now - diff - timedelta(days = fromDays)
317                if self._params['toDays']:
318                    try:
319                        toDays = int(self._params['toDays'])
320                    except ValueError, e:
321                        raise CollaborationException(_("Parameter 'toDays' is not an integer"), inner = e)
322                    now = nowutc()
323                    diff = timedelta(days = 1) - \
324                           timedelta(hours = now.hour, minutes = now.minute, seconds = (now.second + 1))
325                    maxKey = now + diff + timedelta(days = toDays)
326
327                self._minKey = minKey
328                self._maxKey = maxKey
329
330                self._onlyPending = self._params['onlyPending']
331                categoryId = self._params['categoryId'].strip()
332                if categoryId:
333                    self._categoryId = categoryId
334                else:
335                    self._categoryId = None
336                conferenceId = self._params['conferenceId'].strip()
337                if conferenceId:
338                    self._conferenceId = conferenceId
339                else:
340                    self._conferenceId = None
341
342            except KeyError, e:
343                raise CollaborationException(_("One of the necessary parameters to query the booking index is missing"), inner = e)
344
345    def _getAnswer(self):
346        ci = IndexesHolder().getById('collaboration')
347
348        return ci.getBookings(self._indexName,
349                              self._viewBy,
350                              self._orderBy,
351                              self._minKey,
352                              self._maxKey,
353                              tz = self._tz,
354                              onlyPending = self._onlyPending,
355                              conferenceId = self._conferenceId,
356                              categoryId = self._categoryId,
357                              pickle = True,
358                              dateFormat='%a %d %b %Y',
359                              page = self._page,
360                              resultsPerPage = self._resultsPerPage)
361
362class CollaborationCustomPluginService(CollaborationBase):
363    """ Class to support plugin-defined services.
364        Plugins have to call 'collaboration.pluginService' and
365        specify a 'plugin' and 'service' arguments.
366        Then they have to create a class that inherits from
367        CollaborationPluginServiceBase with the same name
368        as the 'service' argument, plus 'Service' at the end.
369        The classes can have _checkParams, _checkProtetion methods,
370        and must have a _getAnswer method.
371        They will have the following attributes available:
372        _params, _aw, _conf, _target, _CSBookingManager.
373    """
374
375    def _checkParams(self):
376        CollaborationBase._checkParams(self)
377
378        self._pluginName = self._params.get('plugin', None)
379        if not self._pluginName:
380            raise CollaborationException(_("No 'plugin' paramater in CollaborationPluginService"))
381
382        serviceName = self._params.get('service', None)
383        if not serviceName:
384            raise CollaborationException(_("No 'service' paramater in CollaborationPluginService"))
385
386        self._serviceClass = CollaborationTools.getServiceClass(self._pluginName, serviceName)
387        if not self._serviceClass:
388            raise CollaborationException(_("Service " + str(serviceName) + _("Service not found for plugin ") + str(self._pluginName) + _("in CollaborationPluginService")))
389
390    def _checkProtection(self):
391        CollaborationBase._checkCanManagePlugin(self, self._pluginName)
392
393    def _getAnswer(self):
394        serviceObject = self._serviceClass(self._params, self._aw)
395        serviceObject._checkParams()
396        serviceObject._checkProtection()
397        return serviceObject._getAnswer()
398
399
400class CollaborationPluginServiceBase(CollaborationBase):
401    """ Base class that plugin-defined services need to inherit from.
402        The _params and _aw attributes will be available for them,
403        and also _target and _conf and _CSBookingManager from CollaborationBase.
404        If they implement a _checkParams method, they need to call
405        their parent's (this class's) method first.
406        This class _checkParam method calls CollaborationBase's
407    """
408
409    def __init__(self, params, aw):
410        self._params = params
411        self._aw = aw
412
413    def _checkParams(self):
414        CollaborationBase._checkParams(self)
415
416    def _checkProtection(self):
417        pass
418
419    def _getAnswer(self):
420        raise CollaborationException("No answer was returned")
421
422class CollaborationPluginServiceBookingModifBase(CollaborationPluginServiceBase):
423
424    def __init__(self, params, aw):
425        CollaborationPluginServiceBase.__init__(self, params, aw)
426        self._booking = None
427
428    def _checkParams(self):
429        CollaborationPluginServiceBase._checkParams(self)
430        bookingId = self._params.get("booking", None)
431        if bookingId:
432            self._booking = self._CSBookingManager.getBooking(bookingId)
433        else:
434            raise CollaborationException(_("Service " + str(self.__class__.__name__) + _(" was called without a 'booking' parameter ")))
435
436
437class CollaborationCreateTestCSBooking(CollaborationCreateCSBooking):
438    """ Service that creates a 'test' booking for performance test.
439        Avoids to use any of the plugins except DummyPlugin
440    """
441    def _checkParams(self):
442        CollaborationBase._checkParams(self)
443
444        if 'bookingParams' in self._params:
445            pm = ParameterManager(self._params)
446            self._bookingParams = pm.extract("bookingParams", pType=dict, allowEmpty = True)
447        else:
448            raise CollaborationException(_("Custom parameters for plugin ") + str(self._type) + _(" not set when trying to create a booking on meeting ") + str(self._conf.getId() ))
449
450    def _getAnswer(self):
451        return fossilize(self._CSBookingManager.createTestBooking(bookingParams = self._bookingParams),
452                         None, tz = self._conf.getTimezone())
453
454class CollaborationMakeMeModeratorCSBooking(CollaborationBookingModifBase):
455    """ Service that creates a 'test' booking for performance test.
456        Avoids to use any of the plugins except DummyPlugin
457    """
458    def _getAnswer(self):
459        return fossilize(self._CSBookingManager.makeMeModeratorBooking(self._bookingId, fossilize(self.getAW().getUser())),
460                                  None, tz = self._conf.getTimezone())
461
462
463methodMap = {
464    "createCSBooking": CollaborationCreateCSBooking,
465    "removeCSBooking": CollaborationRemoveCSBooking,
466    "editCSBooking": CollaborationEditCSBooking,
467    "startCSBooking": CollaborationStartCSBooking,
468    "stopCSBooking": CollaborationStopCSBooking,
469    "connectCSBooking": CollaborationConnectCSBooking,
470    "checkCSBookingStatus": CollaborationCheckCSBookingStatus,
471    "acceptCSBooking": CollaborationAcceptCSBooking,
472    "rejectCSBooking": CollaborationRejectCSBooking,
473    "bookingIndexQuery": CollaborationBookingIndexQuery,
474    "addPluginManager": CollaborationAddPluginManager,
475    "removePluginManager": CollaborationRemovePluginManager,
476    "pluginService": CollaborationCustomPluginService,
477    "makeMeModerator": CollaborationMakeMeModeratorCSBooking
478}
Note: See TracBrowser for help on using the repository browser.