Package flumotion :: Package component :: Package bouncers :: Module icalbouncer
[hide private]

Source Code for Module flumotion.component.bouncers.icalbouncer

  1  # -*- Mode: Python -*- 
  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 twisted.internet import defer 
 27   
 28  from flumotion.common import keycards, config 
 29  from flumotion.component.bouncers import bouncer 
 30  from flumotion.common.keycards import KeycardGeneric 
 31  from datetime import datetime 
 32   
 33  __all__ = ['IcalBouncer'] 
 34   
 35  try: 
 36      # icalendar and dateutil modules needed for ical parsing 
 37      from icalendar import Calendar 
 38      from dateutil import rrule 
 39      HAS_ICAL = True 
 40  except: 
 41      HAS_ICAL = False 
 42   
43 -class IcalBouncer(bouncer.Bouncer):
44 45 logCategory = 'icalbouncer' 46 keycardClasses = (KeycardGeneric) 47 events = [] 48
49 - def do_setup(self):
50 if not HAS_ICAL: 51 return defer.fail( 52 config.ConfigError( 53 "Please install icalendar and dateutil modules")) 54 props = self.config['properties'] 55 self._icsfile = props['file'] 56 return self.parse_ics()
57
58 - def parse_ics(self):
59 if self._icsfile: 60 try: 61 icsStr = open(self._icsfile, "rb").read() 62 cal = Calendar.from_string(icsStr) 63 for event in cal.walk('vevent'): 64 dtstart = event.decoded('dtstart', '') 65 dtend = event.decoded('dtend', '') 66 if dtstart and dtend: 67 self.log("event parsed with start: %r end: %r", 68 dtstart, dtend) 69 recur = event.get('rrule', None) 70 tempEvent = {} 71 tempEvent["dtstart"] = dtstart 72 tempEvent["dtend"] = dtend 73 if recur: 74 # startRecur is a recurrence rule for the start of 75 # the event 76 startRecur = rrule.rrulestr(recur.ical(), 77 dtstart=dtstart) 78 tempEvent["recur"] = startRecur 79 self.events.append(tempEvent) 80 else: 81 self.log("event had either no dtstart or no dtend" 82 ", so ignoring") 83 return defer.succeed(None) 84 except IOError, e: 85 return defer.fail(config.ConfigError(str(e))) 86 except Exception, e: 87 return defer.fail(config.ConfigError(str(e))) 88 else: 89 return defer.fail(config.ConfigError("No ics file configured"))
90
91 - def do_authenticate(self, keycard):
92 self.debug('authenticating keycard') 93 94 # need to check if inside an event time 95 for event in self.events: 96 if event["dtstart"] < datetime.now() and \ 97 event["dtend"] > datetime.now(): 98 keycard.state = keycards.AUTHENTICATED 99 duration = event["dtend"] - datetime.now() 100 durationSecs = duration.days * 86400 + duration.seconds 101 keycard.duration = durationSecs 102 self.addKeycard(keycard) 103 self.info("autheticated login") 104 return keycard 105 elif "recur" in event: 106 # check if in a recurrence of this event 107 recurRule = event["recur"] 108 dtstart = recurRule.before(datetime.now()) 109 totalDuration = event["dtend"] - event["dtstart"] 110 dtend = dtstart + totalDuration 111 if dtend > datetime.now(): 112 keycard.state = keycards.AUTHENTICATED 113 duration = dtend - datetime.now() 114 durationSecs = duration.days * 86400 + duration.seconds 115 keycard.duration = durationSecs 116 self.addKeycard(keycard) 117 self.info("authenticated login") 118 return keycard 119 self.info("failed in authentication, outside hours") 120 return None
121