Trees | Indices | Help |
---|
|
1 # -*- Mode: Python; test-case-name: flumotion.test.test_icalbouncer -*- 2 # vi:si:et:sw=4:sts=4:ts=4 3 # 4 # Flumotion - a streaming media server 5 # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 6 # All rights reserved. 7 8 # This file may be distributed and/or modified under the terms of 9 # the GNU General Public License version 2 as published by 10 # the Free Software Foundation. 11 # This file is distributed without any warranty; without even the implied 12 # warranty of merchantability or fitness for a particular purpose. 13 # See "LICENSE.GPL" in the source distribution for more information. 14 15 # Licensees having purchased or holding a valid Flumotion Advanced 16 # Streaming Server license may use this file in accordance with the 17 # Flumotion Advanced Streaming Server Commercial License Agreement. 18 # See "LICENSE.Flumotion" in the source distribution for more information. 19 20 # Headers in this file shall remain intact. 21 22 """ 23 A bouncer that only lets in during an event scheduled with an ical file. 24 """ 25 26 from datetime import datetime, timedelta 27 28 from twisted.internet import defer 29 30 from flumotion.common import keycards, messages, errors 31 from flumotion.common import log, documentation 32 from flumotion.common import eventcalendar 33 from flumotion.common.i18n import N_, gettexter 34 from flumotion.component.base import scheduler 35 from flumotion.component.bouncers.algorithms import base 36 37 __all__ = ['IcalBouncerAlgorithm'] 38 __version__ = "$Rev$" 39 T_ = gettexter() 40 4143 44 logCategory = 'icalbouncer' 45 events = [] 46 maxKeyCardDuration = timedelta(days=1) 47 507252 self.props = self.args['properties'] 53 self.iCalScheduler = None 54 self.subscriptionToken = None 55 self.check_properties(component) 56 self.setup(component)5759 60 def missingModule(moduleName): 61 m = messages.Error(T_(N_( 62 "To use the iCalendar bouncer you need to have " 63 "the '%s' module installed.\n"), moduleName), 64 mid='error-python-%s' % moduleName) 65 documentation.messageAddPythonInstall(m, moduleName) 66 component.addMessage(m)67 68 if not eventcalendar.HAS_ICALENDAR: 69 missingModule('icalendar') 70 if not eventcalendar.HAS_DATEUTIL: 71 missingModule('dateutil')74 self._icsfile = self.props['file'] 75 76 try: 77 handle = open(self._icsfile, 'r') 78 except IOError, e: 79 m = messages.Error(T_(N_( 80 "Failed to open iCalendar file '%s'. " 81 "Check permissions on that file."), self._icsfile), 82 mid='error-icalbouncer-file') 83 component.addMessage(m) 84 raise errors.ComponentSetupHandledError() 85 86 try: 87 self.iCalScheduler = scheduler.ICalScheduler(handle) 88 except (ValueError, IndexError, KeyError), e: 89 m = messages.Error(T_(N_( 90 "Error parsing ical file '%s'."), self._icsfile), 91 debug=log.getExceptionMessage(e), 92 mid="error-icalbouncer-file") 93 component.addMessage(m) 94 raise errors.ComponentSetupHandledError() 95 self.subscriptionToken = \ 96 self.iCalScheduler.subscribe(self._do_nothing, self._eventEnded)9799 self.debug('authenticating keycard') 100 101 # need to check if inside an event time 102 cal = self.iCalScheduler.getCalendar() 103 now = datetime.now(eventcalendar.UTC) 104 eventInstances = cal.getActiveEventInstances() 105 if not eventInstances: 106 keycard.state = keycards.REFUSED 107 self.info("failed in authentication, outside hours") 108 return None 109 last_end = now 110 while eventInstances: 111 # decorate-sort-undecorate to get the event ending last 112 instance = max([(ev.end, ev) for ev in eventInstances])[1] 113 duration = instance.end - now 114 115 if duration > self.maxKeyCardDuration: 116 duration = self.maxKeyCardDuration 117 break 118 if last_end == instance.end: 119 break 120 eventInstances = cal.getActiveEventInstances(instance.end) 121 last_end = instance.end 122 123 durationSecs = duration.days * 86400 + duration.seconds 124 keycard.duration = durationSecs 125 keycard.state = keycards.AUTHENTICATED 126 self.info("authenticated login, duration %d seconds", 127 durationSecs) 128 return keycard129131 # we might not have an iCalScheduler, if something went wrong 132 # during do_setup or do_check 133 if self.iCalScheduler: 134 self.iCalScheduler.cleanup() 135 if self.subscriptionToken: 136 self.iCalScheduler.unsubscribe(self.subscriptionToken) 137 self.subscriptionToken = None138140 self.debug("_eventEnded") 141 if not event.start < datetime.now(eventcalendar.UTC) < event.end: 142 return 143 cal = self.iCalScheduler.getCalendar() 144 eventInstances = cal.getActiveEventInstances() 145 if not eventInstances: 146 self.debug("We're now outside hours, revoking all keycards") 147 self._expire_all_keycards()148 151 154
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Tue Sep 28 13:55:28 2010 | http://epydoc.sourceforge.net |