def main( **kwargs ): location = kwargs.get( 'location', 'Universe' ) from MaKaC.rb_factory import Factory from MaKaC.common.db import DBMgr DBMgr.getInstance().startRequest() Factory.getDALManager().connect() initializeRoomBookingDB( location, force = True ) Factory.getDALManager().disconnect() DBMgr.getInstance().endRequest()
def main(**kwargs): location = kwargs.get('location', 'Universe') from MaKaC.rb_factory import Factory from MaKaC.common.db import DBMgr DBMgr.getInstance().startRequest() Factory.getDALManager().connect() initializeRoomBookingDB(location, force=True) Factory.getDALManager().disconnect() DBMgr.getInstance().endRequest()
def getReservations(): from MaKaC.rb_factory import Factory dalManager = Factory.getDALManager() dalManager.connect() amphitheatre = RoomBase.getRooms( roomName = 'IT AMPHITHEATRE' ) print "All reservations for IT AMPHITHEATRE: %d" % len( amphitheatre.getReservations() ) resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 9, 23, 0 ) resvEx.endDT = datetime( 2006, 9, 30, 23, 59 ) dalManager.disconnect()
def tmp(): from MaKaC.rb_factory import Factory from MaKaC.rb_room import RoomBase from MaKaC.common.db import DBMgr from BTrees.OOBTree import OOBTree DBMgr.getInstance().startRequest() Factory.getDALManager().connect() dayReservationsIndexBTree = OOBTree() raise str( dir( dayReservationsIndexBTree ) ) Factory.getDALManager().disconnect() DBMgr.getInstance().endRequest()
def disconnect(): """ Closes database connection. This method is called by Indico engine in the end of every HTTP request. """ from MaKaC.rb_factory import Factory return Factory.getDALManager().disconnect()
def getReservations(): from MaKaC.rb_factory import Factory from datetime import datetime dalManager = Factory.getDALManager() dalManager.connect() amphitheatre = RoomBase.getRooms( roomName = 'IT AMPHITHEATRE' ) print "All reservations for IT AMPHITHEATRE: %d" % len( amphitheatre.getReservations() ) resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 9, 23, 0 ) resvEx.endDT = datetime( 2006, 9, 30, 23, 59 ) reservations = amphitheatre.getLiveReservations( resvExample = resvEx ) dalManager.disconnect()
def connect(): """ Opens database connection. This method is called by Indico engine in the beginning of every HTTP request. """ from MaKaC.rb_factory import Factory return Factory.getDALManager().connect()
def getReservations2(): from MaKaC.rb_room import RoomBase Test.dalManager.connect() resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 12, 01, 10 ) resvEx.endDT = datetime( 2006, 12, 14, 15 ) resvEx.repeatability = 0 # Daily #ReservationBase.getReservations( \ # roomExample = roomEx, # resvExample = resvEx, # available = True ) resv = ReservationBase.getReservations( resvID = 363818 ) print resv r = Reservation() r.room = resv.room r.startDT = datetime( 2006, 10, 13, 8, 30 ) r.endDT = datetime( 2006, 10, 13, 17, 30 ) col = r.getCollisions() print col Test.dalManager.disconnect()
def getNumberOfLiveReservations(*args, **kwargs): """ Documentation in base class. """ location = kwargs.get('location', Location.getDefaultLocation().friendlyName) resvEx = Factory.newReservation() resvEx.isValid = True return Reservation.countReservations(resvExample=resvEx, archival=False, location=location)
def testIndexes(self): block = self._createTestBlocking() block2 = Factory.newRoomBlocking()() block2.startDate = date(2011, 1, 1) block2.endDate = date(2011, 1, 10) block2.createdByUser = self._avatar3 block2.message = 'Testing 2' self._blockRoom(block2, self._room1) block2.insert() # Test if all indexes work properly self.assertEqual(frozenset(RoomBlockingBase.getAll()), frozenset((block, block2))) self.assertTrue(RoomBlockingBase.getById(0) is None) self.assertEqual(RoomBlockingBase.getById(1), block) self.assertEqual(RoomBlockingBase.getById(2), block2) self.assertTrue(not RoomBlockingBase.getByOwner(self._dummy)) self.assertTrue(not RoomBlockingBase.getByOwner(self._avatar1)) self.assertEqual(frozenset(RoomBlockingBase.getByOwner(self._avatar2)), frozenset((block,))) self.assertEqual(frozenset(RoomBlockingBase.getByOwner(self._avatar3)), frozenset((block2,))) self.assertTrue(not RoomBlockingBase.getByRoom(self._room5)) self.assertEqual(frozenset(RoomBlockingBase.getByRoom(self._room1)), frozenset((block.getBlockedRoom(self._room1), block2.getBlockedRoom(self._room1)))) self.assertEqual(frozenset(RoomBlockingBase.getByRoom(self._room2)), frozenset((block.getBlockedRoom(self._room2),))) self.assertTrue(block2.getBlockedRoom(self._room2) is None) self.assertEqual(frozenset(RoomBlockingBase.getByDate(date(2010, 12, 31))), frozenset((block,))) self.assertEqual(frozenset(RoomBlockingBase.getByDate(date(2011, 1, 1))), frozenset((block, block2))) self.assertEqual(frozenset(RoomBlockingBase.getByDate(date(2011, 1, 2))), frozenset((block2,))) self.assertEqual(frozenset(RoomBlockingBase.getByDateSpan(date(2011, 1, 1), date(2011, 1, 2))), frozenset((block, block2))) self.assertEqual(frozenset(RoomBlockingBase.getByDateSpan(date(2011, 1, 2), date(2011, 2, 1))), frozenset((block2,))) self.assertTrue(not RoomBlockingBase.getByDateSpan(date(2011, 2, 1), date(2012, 1, 1))) # Remove a block block.remove() self.assertEqual(len(RoomBlockingBase.getAll()), 1) self.assertTrue(RoomBlockingBase.getById(block.id) is None) self.assertTrue(not RoomBlockingBase.getByOwner(self._avatar2)) self.assertEqual(frozenset(RoomBlockingBase.getByRoom(self._room1)), frozenset((block2.getBlockedRoom(self._room1),))) self.assertTrue(not RoomBlockingBase.getByRoom(self._room2)) self.assertTrue(not RoomBlockingBase.getByDate(date(2010, 12, 31))) self.assertEqual(frozenset(RoomBlockingBase.getByDate(date(2011, 1, 1))), frozenset((block2,))) self.assertEqual(frozenset(RoomBlockingBase.getByDate(date(2011, 1, 2))), frozenset((block2,))) # Add a blocked room br = self._blockRoom(block2, self._room2) block2.addBlockedRoom(br) # When adding a blocked room, update() may be (and is) required for it to beindexed block2.update() self.assertEqual(frozenset(RoomBlockingBase.getByRoom(self._room2)), frozenset((block2.getBlockedRoom(self._room2),))) self.assertEqual(frozenset(RoomBlockingBase.getByRoom(self._room1)), frozenset((block2.getBlockedRoom(self._room1),))) block2.delBlockedRoom(block2.getBlockedRoom(self._room1)) # Deletion has to update indexes immediately as the object will no longer be reachable from its parent block self.assertTrue(not RoomBlockingBase.getByRoom(self._room1)) block2.update() self.assertTrue(not RoomBlockingBase.getByRoom(self._room1))
def getReservations(): from MaKaC.rb_room import RoomBase Test.dalManager.connect() roomEx = Factory.newRoom() roomEx.name = 'TH AMPHITHEATRE' resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 12, 01, 10 ) resvEx.endDT = datetime( 2006, 12, 14, 15 ) #resvEx.bookedForName = 'Jean-Jacques Blais' resvs = ReservationBase.getReservations( resvExample = resvEx, rooms = [roomEx] ) for resv in resvs: print "=============================" print resv Test.dalManager.disconnect()
def _getAnswer( self ): minfo = info.HelperMaKaCInfo.getMaKaCInfoInstance() result = {} if minfo.getRoomBookingModuleActive(): locationNames = map(lambda l: l.friendlyName, Location.allLocations) for loc in locationNames: roomEx = Factory.newRoom() roomEx.isActive = self._isActive for room in CrossLocationQueries.getRooms( location = loc, roomExample=roomEx ): result[str(room.guid)] = "%s: %s" % (loc, room.getFullName()) return result
def index(req, **params): DBMgr.getInstance().startRequest() Factory.getDALManager().connect() ################### checking protection ################### # check if it is a machine that belongs to the CERN domain cernDomain = DomainHolder().getById(0) # id 0 means CERN if not cernDomain.belongsTo(get_remote_ip(req)): return "Only CERN users can access to this export resource" ################### checking params ################### if not (params.has_key("sd") and params.has_key("ed") and params.has_key("r")): return """Missing parameters. The request should be like this: http://indico.cern.ch/exportReservations.py?sd=2010-09-24&ed=2010-09-25&r=1,18,114,42""" try: sd = parseDate(params.get("sd"), "%Y-%m-%d") ed = parseDate(params.get("ed"), "%Y-%m-%d") except ValueError, e: return """The format for the dates (sd and ed) must be like this: YYYY-MM-DD"""
def index(req, **params): DBMgr.getInstance().startRequest() Factory.getDALManager().connect() ################### checking protection ################### # check if it is a machine that belongs to the CERN domain cernDomain = DomainHolder().getById(0) # id 0 means CERN if not cernDomain.belongsTo(_get_remote_ip(req)): return "Only CERN users can access to this export resource" ################### checking params ################### if not (params.has_key("sd") and params.has_key("ed") and params.has_key("r")): return """Missing parameters. The request should be like this: http://indico.cern.ch/exportReservations.py?sd=2010-09-24&ed=2010-09-25&r=1,18,114,42""" try: sd = parseDate(params.get("sd"), "%Y-%m-%d") ed = parseDate(params.get("ed"), "%Y-%m-%d") except ValueError, e: return """The format for the dates (sd and ed) must be like this: YYYY-MM-DD"""
def _createTestBlocking(self): block = Factory.newRoomBlocking()() block.startDate = date(2010, 12, 31) block.endDate = date(2011, 1, 1) block.createdByUser = self._avatar2 block.addAllowed(self._avatar4) block.message = 'Testing' self._blockRoom(block, self._room1) self._blockRoom(block, self._room2) self._blockRoom(block, self._room3) self._blockRoom(block, self._room4) self._blockRoom(block, self._room6) block.insert() return block
def getAverageOccupation(**kwargs): """ FINAL (not intented to be overriden) Returns float <0, 1> representing how often - on the avarage - the rooms are booked during the working hours. (1 == all the time, 0 == never). """ name = kwargs.get('location', Location.getDefaultLocation().friendlyName) # Get active, publically reservable rooms from MaKaC.rb_factory import Factory roomEx = Factory.newRoom() roomEx.isActive = True roomEx.isReservable = True rooms = CrossLocationQueries.getRooms(roomExample=roomEx, location=name) # Find collisions with last month period from MaKaC.rb_reservation import ReservationBase, RepeatabilityEnum resvEx = ReservationBase() now = datetime.now() resvEx.endDT = datetime(now.year, now.month, now.day, 17, 30) resvEx.startDT = resvEx.endDT - timedelta( 30, 9 * 3600) # - 30 days and 9 hours resvEx.repeatability = RepeatabilityEnum.daily collisions = resvEx.getCollisions(rooms=rooms) totalWorkingDays = 0 weekends = 0 for day in iterdays(resvEx.startDT, resvEx.endDT): if day.weekday() in [5, 6]: # Skip Saturday and Sunday weekends += 1 continue # if c.startDT is CERN Holiday: continue totalWorkingDays += 1 booked = timedelta(0) for c in collisions: if c.startDT.weekday() in [5, 6]: # Skip Saturday and Sunday continue # if c.startDT is CERN Holiday: continue booked = booked + (c.endDT - c.startDT) totalBookableTime = totalWorkingDays * 9 * len(rooms) # Hours bookedTime = booked.days * 24 + 1.0 * booked.seconds / 3600 # Hours if totalBookableTime > 0: return bookedTime / totalBookableTime else: return 0 # Error (no rooms in db)
def _getAnswer(self): minfo = info.HelperMaKaCInfo.getMaKaCInfoInstance() result = {} if minfo.getRoomBookingModuleActive(): locationNames = map(lambda l: l.friendlyName, Location.allLocations) for loc in locationNames: roomEx = Factory.newRoom() roomEx.isActive = self._isActive for room in CrossLocationQueries.getRooms(location=loc, roomExample=roomEx): result[str( room.guid)] = "%s: %s" % (loc, room.getFullName()) return result
def getLiveReservations(self, resvExample=None): """ FINAL (not intented to be overriden) Returns valid, non archival reservations of this room, meeting specified criteria. Look ReservationBase.getReservations for details. """ from MaKaC.rb_factory import Factory from MaKaC.rb_reservation import ReservationBase if resvExample is None: resvExample = Factory.newReservation() resvExample.isCancelled = False resvExample.isRejected = False return ReservationBase.getReservations(resvExample=resvExample, rooms=[self], archival=False)
def index(req, **params): DBMgr.getInstance().startRequest() Factory.getDALManager().connect() ################### checking protection ################### def getHostIP(req): import socket host = str(req.get_remote_host(apache.REMOTE_NOLOOKUP)) try: hostIP = socket.gethostbyname(host) minfo = HelperMaKaCInfo.getMaKaCInfoInstance() if minfo.useProxy(): # if we're behind a proxy, use X-Forwarded-For xff = req.headers_in.get("X-Forwarded-For",hostIP).split(", ")[-1] return socket.gethostbyname(xff) else: return hostIP except socket.gaierror, e: # in case host resolution fails raise HostnameResolveError("Error resolving host '%s' : %s" % (host, e))
def getLiveReservations( self, resvExample = None ): """ FINAL (not intented to be overriden) Returns valid, non archival reservations of this room, meeting specified criteria. Look ReservationBase.getReservations for details. """ from MaKaC.rb_factory import Factory from MaKaC.rb_reservation import ReservationBase if resvExample == None: resvExample = Factory.newReservation() resvExample.isCancelled = False resvExample.isRejected = False return ReservationBase.getReservations( resvExample = resvExample, rooms = [self], archival = False )
def getAverageOccupation( **kwargs ): """ FINAL (not intented to be overriden) Returns float <0, 1> representing how often - on the avarage - the rooms are booked during the working hours. (1 == all the time, 0 == never). """ name = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) # Get active, publically reservable rooms from MaKaC.rb_factory import Factory roomEx = Factory.newRoom() roomEx.isActive = True roomEx.isReservable = True rooms = CrossLocationQueries.getRooms( roomExample = roomEx, location = name ) # Find collisions with last month period from MaKaC.rb_reservation import ReservationBase, RepeatabilityEnum resvEx = ReservationBase() now = datetime.now() resvEx.endDT = datetime( now.year, now.month, now.day, 17, 30 ) resvEx.startDT = resvEx.endDT - timedelta( 30, 9 * 3600 ) # - 30 days and 9 hours resvEx.repeatability = RepeatabilityEnum.daily collisions = resvEx.getCollisions( rooms = rooms ) totalWorkingDays = 0 weekends = 0 for day in iterdays( resvEx.startDT, resvEx.endDT ): if day.weekday() in [5,6]: # Skip Saturday and Sunday weekends += 1 continue # if c.startDT is CERN Holiday: continue totalWorkingDays += 1 booked = timedelta( 0 ) for c in collisions: if c.startDT.weekday() in [5,6]: # Skip Saturday and Sunday continue # if c.startDT is CERN Holiday: continue booked = booked + ( c.endDT - c.startDT ) totalBookableTime = totalWorkingDays * 9 * len( rooms ) # Hours bookedTime = booked.days * 24 + 1.0 * booked.seconds / 3600 # Hours if totalBookableTime > 0: return bookedTime / totalBookableTime else: return 0 # Error (no rooms in db)
def getAverageOccupation(**kwargs): """ FINAL (not intented to be overriden) Returns float <0, 1> representing how often - on the avarage - the rooms are booked during the working hours. (1 == all the time, 0 == never). """ name = kwargs.get("location", Location.getDefaultLocation().friendlyName) # Get active, publically reservable rooms from MaKaC.rb_factory import Factory roomEx = Factory.newRoom() roomEx.isActive = True roomEx.isReservable = True rooms = CrossLocationQueries.getRooms(roomExample=roomEx, location=name) # Find collisions with last month period from MaKaC.rb_reservation import ReservationBase, RepeatabilityEnum resvEx = ReservationBase() resvEx.endDT = datetime.combine(date.today(), time(17, 30)) resvEx.startDT = resvEx.endDT.replace(hour=8) - timedelta(days=30) resvEx.repeatability = RepeatabilityEnum.daily collisions = resvEx.getCollisions(rooms=rooms) totalWorkingDays = sum(1 for day in iterdays(resvEx.startDT, resvEx.endDT) if day.weekday() not in (5, 6)) booked = timedelta() for c in collisions: if c.startDT.weekday() in (5, 6): # skip Saturday and Sunday continue booked += c.endDT - c.startDT totalBookableTime = totalWorkingDays * 9 * len(rooms) # Hours bookedTime = (booked.days * 86400 + booked.seconds) / 3600.0 if totalBookableTime > 0: return bookedTime / totalBookableTime else: return 0
def getByOwner(owner): return Factory.newRoomBlocking().getByOwner(owner)
def getById(id): return Factory.newRoomBlocking().getById(id)
def getAll(): return Factory.newRoomBlocking().getAll()
def getTotalCount(): return Factory.newRoomBlocking().getTotalCount()
def getRooms(*args, **kwargs): """ Returns list of rooms meeting specified conditions. It is 'query by example'. You specify conditions by creating the object and passing it to the method. All arguments are optional: roomID - just a shortcut. Will return ONE room (not a list) or None. roomName - just a shortcut. Will return ONE room (not a list) or None. roomExample - example RoomBase object. reservationExample - example ReservationBase object. Represents reservation period. available - Bool, true if room must be available, false if must be booked, None if do not care freeText - str, room will be found if this string will be found anywhere in the object i.e. in equipment list, comments, responsible etc. minCapacity - Bool, defaults to False. If True, then rooms of capacity >= will be found. Otherwise capacity it looks for rooms with capacity within 20% range. allFast - Bool, defaults to False. If True, ALL active rooms will be returned in ultra fast way, REGARDLESS of all other options. ownedBy - Avatar customAtts - for rooms with custom attributes. rooms with no .customAtts attributes will be filtered out if this parameter is present The customAtts attribute should be a list of dictionaries with the attributes "name", "allowEmpty", "filter". "name" -> the name of the custom attribute "allowEmpty" -> if we allow the custom attribute to be empty or not (empty = "" or string with only whitespaces) "filter" -> a function to which we will pass the value of the custom attribute and has to return True or False. If there is more than 1 dictionary in the list, it will be like doing an AND of the conditions they represent. (see example 6) Examples: # 1. Get all rooms rooms = RoomBase.getRooms() # 2. Get all rooms with capacity about 30 r = Factory.newRoom() r.capacity = 30 rooms = RoomBase.getRooms( roomExample = r ) # 3. Get all rooms reserved on the New Year 2007, # which have capacity about 30, are at Meyrin site and have 'jean' in comments. r = Factory.newRoom() r.capacity = 30 r.site = 'Meyrin' r.comments = 'jean' p = ReservationBase() p.startDT = datetime.datetime( 2007, 01, 01 ) p.endDT = datetime.datetime( 2007, 01, 01 ) p.repeatability = None rooms = RoomBase.getRooms( roomExample = r, reservationExample = p, available = False ) # 4. Get all rooms containing "sex" in their attributes rooms = RoomBase.getRooms( freeText = 'sex' ) # 5. Get room 'AT AMPHITHEATRE' oneRoom = RoomBase.getRooms( roomName = 'AT AMPHITHEATRE' ) #6. Get rooms with a H.323 IP defined rooms = RoomBase.getRooms ( customAtts = [{"name":'H323 IP', "allowEmpty":False, "filter": (lambda ip: validIP(ip))}]) """ # Simply redirect to the plugin from MaKaC.rb_factory import Factory return Factory.newRoom().getRooms(**kwargs)
def commit(): """ Commits the transaction. """ from MaKaC.rb_factory import Factory return Factory.getDALManager().commit()
def getByDate(date): return Factory.newRoomBlocking().getByDate(date)
roomIDs = params.get("r").strip().split(",") if roomIDs == "": return """At least one roomID must be specified (http://....?r=1,42,14,...)""" try: roomIDs = map(lambda x: int(x), roomIDs) except ValueError: return """Room IDs must be integers separated by commas (http://....?r=1,42,14,...)""" if len(roomIDs) > 10: return "One can only export 10 rooms at most" #################### process ################### rooms = [] for roomID in roomIDs: roomEx = Factory.newRoom() roomEx.id = roomID rooms.append(roomEx) resvEx = Factory.newReservation() resvEx.isCancelled = False resvEx.isRejected = False resvEx.startDT = datetime(sd.year, sd.month, sd.day, 0, 0) resvEx.endDT = datetime(ed.year, ed.month, ed.day, 23, 59) resvs = CrossLocationQueries.getReservations(location="CERN", resvExample=resvEx, rooms=rooms) collisions = [] for resv in resvs: for p in resv.splitToPeriods(endDT=resvEx.endDT, startDT=resvEx.startDT): collisions.append(Collision( ( p.startDT, p.endDT ), resv )) of = params.get("of", "csv")
def getReservations( *args, **kwargs ): """ Documentation in base class. """ resvID = kwargs.get( 'resvID' ) resvEx = kwargs.get( 'resvExample' ) rooms = kwargs.get( 'rooms' ) countOnly = kwargs.get( 'countOnly' ) archival = kwargs.get( 'archival' ) heavy = kwargs.get( 'heavy' ) location = kwargs.get( 'location' ) days = kwargs.get( 'days' ) ret_lst = [] counter = 0 root = Factory.getDALManager().getRoot() if resvID != None: return root[_RESERVATIONS].get( resvID ) resvCandidates = None alreadyRoomFiltered = False # If we filter by room but not by day, we can use the RoomReservations index if rooms and not days and len(rooms) <= 10: # Use room => room reservations index resvCandidates = set() for room in rooms: if location != None and room.locationName != location: continue # Skip rooms from different locations roomResvs = Reservation.getRoomReservationsIndexRoot().get( room.id ) if roomResvs != None: resvCandidates.update(roomResvs) alreadyRoomFiltered = True # If we don't have reservations yet but filter by creator, use the UserReservations index if resvCandidates == None and resvEx != None and resvEx.createdBy != None: resvCandidates = set(Reservation.getUserReservationsIndexRoot().get(resvEx.createdBy, [])) # If we want to filter by day, we can choose indexes. dayFilteredResvs = None if days and rooms: # If there's a room filter, too - use the RoomDayReservations index dayFilteredResvs = set() for key in ((room.id, day) for day in days for room in rooms): dayRoomResvs = Reservation.getRoomDayReservationsIndexRoot().get(key, []) dayFilteredResvs.update(dayRoomResvs) alreadyRoomFiltered = True elif days: # If we only filter by days, use the DayReservations index dayFilteredResvs = set() for day in days: dayResvs = Reservation.getDayReservationsIndexRoot().get(day, []) dayFilteredResvs.update(dayResvs) # If we have some day-filtered reservations, use that list or restrict the existing one if dayFilteredResvs is not None: if resvCandidates is None: resvCandidates = dayFilteredResvs else: # Intersection resvCandidates = dayFilteredResvs & resvCandidates # If we still have nothing, get all reservations and filter them later in the loop (slow!) if resvCandidates is None: resvCandidates = Reservation.getReservationsRoot().itervalues() for resvCandidate in resvCandidates: # Apply all conditions if archival != None: if resvCandidate.isArchival != archival: continue if location != None: # If location is specified, use only rooms from this location if not resvCandidate.locationName == location: continue if heavy != None: if resvCandidate.isHeavy != heavy: continue # Does the reservation overlap on the specified period? if resvEx != None: if resvEx.startDT != None and resvEx.endDT != None: if not resvCandidate.overlapsOn( resvEx.startDT, resvEx.endDT ): continue if rooms != None and not alreadyRoomFiltered: if resvCandidate.room not in rooms: continue if resvEx.createdDT != None: if resvEx.createdDT != resvCandidate.createdDT: continue if resvEx.bookedForName != None: if resvCandidate.bookedForName == None: continue if not containsExactly_OR_containsAny( resvEx.bookedForName, resvCandidate.bookedForName ): continue if resvEx.reason != None: if resvCandidate.reason == None: continue if not containsExactly_OR_containsAny( resvEx.reason, resvCandidate.reason ): continue if resvEx.contactEmail != None: if resvCandidate.contactEmail == None: continue if not resvEx.contactEmail in resvCandidate.contactEmail: continue if resvEx.contactPhone != None: if resvCandidate.contactPhone == None: continue if not resvEx.contactPhone in resvCandidate.contactPhone: continue if resvEx.createdBy != None: if resvCandidate.createdBy != resvEx.createdBy: continue if resvEx.rejectionReason != None: if resvCandidate.rejectionReason == None: continue if not resvEx.rejectionReason in resvCandidate.rejectionReason: continue if resvEx.isConfirmed != None: if not resvCandidate.isConfirmed == resvEx.isConfirmed: continue if resvEx.isRejected != None: if not resvCandidate.isRejected == resvEx.isRejected: continue if resvEx.isCancelled != None: if not resvCandidate.isCancelled == resvEx.isCancelled: continue if resvEx.usesAVC != None: if not resvCandidate.usesAVC == resvEx.usesAVC: continue if resvEx.needsAVCSupport != None: if not resvCandidate.needsAVCSupport == resvEx.needsAVCSupport: continue if resvEx.needsAssistance != None: if not resvCandidate.needsAssistance == resvEx.needsAssistance: continue # META-PROGRAMMING STYLE OF CHECKING ATTRIBUTES EQUALITY # ABANDONED DUE TO PERFORMANCE PROBLEMS # Are standard conditions met? (other attributes equality) #if not qbeMatch( resvEx, resvCandidate, Reservation.__attrSpecialEqual ): # continue # All conditions are met: add reservation to the results counter += 1 if not countOnly: ret_lst.append( resvCandidate ) #print "Found " + str( counter ) + " reservations." if not countOnly: return ret_lst else: return counter
def getByDateSpan(begin, end): return Factory.newRoomBlocking().getByDateSpan(begin, end)
def getByRoom(room, active=-1): return Factory.newRoomBlocking().getByRoom(room, active)
def getReservations( *args, **kwargs ): """ Documentation in base class. """ resvID = kwargs.get( 'resvID' ) resvEx = kwargs.get( 'resvExample' ) rooms = kwargs.get( 'rooms' ) countOnly = kwargs.get( 'countOnly' ) archival = kwargs.get( 'archival' ) heavy = kwargs.get( 'heavy' ) location = kwargs.get( 'location' ) days = kwargs.get( 'days' ) ret_lst = [] counter = 0 root = Factory.getDALManager().root if resvID != None: return root[_RESERVATIONS].get( resvID ) resvCandidates = None alreadyRoomFiltered = False if rooms and len( rooms ) <= 10: # Use room => room reservations index resvCandidates = [] for room in rooms: if location != None and room.locationName != location: continue # Skip rooms from different locations roomResvs = Reservation.getRoomReservationsIndexRoot().get( room.id ) if roomResvs != None: resvCandidates += roomResvs alreadyRoomFiltered = True if resvCandidates == None and resvEx != None and resvEx.createdBy != None: resvCandidates = Reservation.getUserReservationsIndexRoot().get( resvEx.createdBy ) if resvCandidates == None: resvCandidates = [] if days: resvsInDays = {} for day in days: dayResvs = Reservation.getDayReservationsIndexRoot().get( day ) if dayResvs: for resv in dayResvs: resvsInDays[resv] = None if resvCandidates == None: resvCandidates = resvsInDays.iterkeys() else: # Intersection new = [] for resv in resvCandidates: if resvsInDays.has_key( resv ): new.append( resv ) resvCandidates = new if resvCandidates == None: resvCandidates = Reservation.getReservationsRoot().itervalues() for resvCandidate in resvCandidates: # Apply all conditions if archival != None: if resvCandidate.isArchival != archival: continue if location != None: # If location is specified, use only rooms from this location if not resvCandidate.locationName == location: continue if heavy != None: if resvCandidate.isHeavy != heavy: continue # Does the reservation overlap on the specified period? if resvEx != None: if resvEx.startDT != None and resvEx.endDT != None: if not resvCandidate.overlapsOn( resvEx.startDT, resvEx.endDT ): continue if rooms != None and not alreadyRoomFiltered: if resvCandidate.room not in rooms: continue if resvEx.createdDT != None: if resvEx.createdDT != resvCandidate.createdDT: continue if resvEx.bookedForName != None: if resvCandidate.bookedForName == None: continue if not containsExactly_OR_containsAny( resvEx.bookedForName, resvCandidate.bookedForName ): continue if resvEx.reason != None: if resvCandidate.reason == None: continue if not containsExactly_OR_containsAny( resvEx.reason, resvCandidate.reason ): continue if resvEx.contactEmail != None: if resvCandidate.contactEmail == None: continue if not resvEx.contactEmail in resvCandidate.contactEmail: continue if resvEx.contactPhone != None: if resvCandidate.contactPhone == None: continue if not resvEx.contactPhone in resvCandidate.contactPhone: continue if resvEx.createdBy != None: if resvCandidate.createdBy != resvEx.createdBy: continue if resvEx.rejectionReason != None: if resvCandidate.rejectionReason == None: continue if not resvEx.rejectionReason in resvCandidate.rejectionReason: continue if resvEx.isConfirmed != None: if not resvCandidate.isConfirmed == resvEx.isConfirmed: continue if resvEx.isRejected != None: if not resvCandidate.isRejected == resvEx.isRejected: continue if resvEx.isCancelled != None: if not resvCandidate.isCancelled == resvEx.isCancelled: continue if resvEx.usesAVC != None: if not resvCandidate.usesAVC == resvEx.usesAVC: continue if resvEx.needsAVCSupport != None: if not resvCandidate.needsAVCSupport == resvEx.needsAVCSupport: continue # META-PROGRAMMING STYLE OF CHECKING ATTRIBUTES EQUALITY # ABANDONED DUE TO PERFORMANCE PROBLEMS # Are standard conditions met? (other attributes equality) #if not qbeMatch( resvEx, resvCandidate, Reservation.__attrSpecialEqual ): # continue # All conditions are met: add reservation to the results counter += 1 if not countOnly: ret_lst.append( resvCandidate ) #print "Found " + str( counter ) + " reservations." if not countOnly: return ret_lst else: return counter
def getNumberOfLiveReservations( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) resvEx = Factory.newReservation() resvEx.isValid = True return Reservation.countReservations( resvExample = resvEx, archival = False, location = location )
class Test( object ): dalManager = Factory.getDALManager() @staticmethod def getReservations(): from MaKaC.rb_room import RoomBase Test.dalManager.connect() roomEx = Factory.newRoom() roomEx.name = 'TH AMPHITHEATRE' resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 12, 01, 10 ) resvEx.endDT = datetime( 2006, 12, 14, 15 ) #resvEx.bookedForName = 'Jean-Jacques Blais' resvs = ReservationBase.getReservations( resvExample = resvEx, rooms = [roomEx] ) for resv in resvs: print "=============================" print resv Test.dalManager.disconnect() @staticmethod def getReservations2(): from MaKaC.rb_room import RoomBase Test.dalManager.connect() resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 12, 01, 10 ) resvEx.endDT = datetime( 2006, 12, 14, 15 ) resvEx.repeatability = 0 # Daily #ReservationBase.getReservations( \ # roomExample = roomEx, # resvExample = resvEx, # available = True ) resv = ReservationBase.getReservations( resvID = 363818 ) print resv r = Reservation() r.room = resv.room r.startDT = datetime( 2006, 10, 13, 8, 30 ) r.endDT = datetime( 2006, 10, 13, 17, 30 ) col = r.getCollisions() print col Test.dalManager.disconnect() @staticmethod def tmp(): from MaKaC.rb_factory import Factory from MaKaC.rb_room import RoomBase from MaKaC.common.db import DBMgr from BTrees.OOBTree import OOBTree DBMgr.getInstance().startRequest() Factory.getDALManager().connect() dayReservationsIndexBTree = OOBTree() raise str( dir( dayReservationsIndexBTree ) ) Factory.getDALManager().disconnect() DBMgr.getInstance().endRequest() @staticmethod def indexByDay(): from MaKaC.rb_location import CrossLocationDB from MaKaC.rb_room import RoomBase from MaKaC.common.db import DBMgr DBMgr.getInstance().startRequest() CrossLocationDB.connect() # resvEx = ReservationBase() # resvEx.isConfirmed = None # resvs = CrossLocationQueries.getReservations( resvExample = resvEx ) # print "There are " + str( len( resvs ) ) + " resvs to index..." # c = 0 # for resv in resvs: # resv._addToDayReservationsIndex() # c += 1 # if c % 100 == 0: # print c CrossLocationDB.commit() CrossLocationDB.disconnect() DBMgr.getInstance().endRequest() @staticmethod def rebuildRoomReservationsIndex(): from MaKaC.common.db import DBMgr from MaKaC.rb_location import CrossLocationDB from MaKaC.rb_room import RoomBase from MaKaC.plugins.RoomBooking.default.dalManager import DALManager from BTrees.OOBTree import OOBTree DBMgr.getInstance().startRequest() CrossLocationDB.connect() root = DALManager.root resvEx = ReservationBase() resvEx.isConfirmed = None allResvs = CrossLocationQueries.getReservations( resvExample = resvEx ) print "There are " + str( len( allResvs ) ) + " resvs and pre-resvs to index..." c = 0 root[_ROOM_RESERVATIONS_INDEX] = OOBTree() print "Room => Reservations Index branch created" for resv in allResvs: roomReservationsIndexBTree = root[_ROOM_RESERVATIONS_INDEX] resvs = roomReservationsIndexBTree.get( resv.room.id ) if resvs == None: resvs = [] # New list of reservations for this room roomReservationsIndexBTree.insert( resv.room.id, resvs ) resvs.append( resv ) roomReservationsIndexBTree[resv.room.id] = resvs c += 1 if c % 100 == 0: print c CrossLocationDB.commit() CrossLocationDB.disconnect() DBMgr.getInstance().endRequest() @staticmethod def play(): from MaKaC.rb_location import CrossLocationDB from MaKaC.rb_room import RoomBase from MaKaC.common.db import DBMgr DBMgr.getInstance().startRequest() CrossLocationDB.connect() roomEx = RoomBase() roomEx.isActive = False rooms = CrossLocationQueries.getRooms( roomExample = roomEx ) for r in rooms: print r CrossLocationDB.commit() CrossLocationDB.disconnect() DBMgr.getInstance().endRequest()
class Reservation( Persistent, ReservationBase ): """ ZODB specific implementation. For documentation of methods see base class. """ __dalManager = Factory.getDALManager() def __init__( self ): ReservationBase.__init__( self ) self._excludedDays = [] self.useVC = [] def getUseVC( self ): try: return self.useVC except: self.useVC = [] return self.useVC @staticmethod def getReservationsRoot( ): return Reservation.__dalManager.getRoot(_RESERVATIONS) @staticmethod def getRoomReservationsIndexRoot( ): return Reservation.__dalManager.getRoot(_ROOM_RESERVATIONS_INDEX) @staticmethod def getUserReservationsIndexRoot( ): return Reservation.__dalManager.getRoot(_USER_RESERVATIONS_INDEX) @staticmethod def getDayReservationsIndexRoot( ): return Reservation.__dalManager.getRoot(_DAY_RESERVATIONS_INDEX) def insert( self ): """ Documentation in base class. """ ReservationBase.insert( self ) resvBTree = Reservation.getReservationsRoot() # Ensure ID if self.id == None: # Maximum ID + 1 if len( resvBTree ) > 0: self.id = resvBTree.maxKey() + 1 else: self.id = 1 # Can not use maxKey for 1st record in a tree # Add self to the BTree resvBTree[self.id] = self # Update room => room reservations index roomReservationsIndexBTree = Reservation.getRoomReservationsIndexRoot() resvs = roomReservationsIndexBTree.get( self.room.id ) if resvs == None: resvs = [] # New list of reservations for this room roomReservationsIndexBTree.insert( self.room.id, resvs ) resvs.append( self ) roomReservationsIndexBTree[self.room.id] = resvs # Update user => user reservations index userReservationsIndexBTree = Reservation.getUserReservationsIndexRoot() resvs = userReservationsIndexBTree.get( self.createdBy ) if resvs == None: resvs = [] # New list of reservations for this room userReservationsIndexBTree.insert( self.createdBy, resvs ) resvs.append( self ) userReservationsIndexBTree[self.createdBy] = resvs # Update day => reservations index self._addToDayReservationsIndex() def update( self, udpateReservationIndex=True ): """ Documentation in base class. """ ReservationBase.update( self ) if udpateReservationIndex: self._removeFromDayReservationsIndex() self._addToDayReservationsIndex() self._p_changed = True # Warning: # createdBy, once assigned to rerservation, CAN NOT be changed later (index!) # room, once assigned to reservation, CAN NOT be changed later (index!) def remove( self ): """ Documentation in base class. """ resvBTree = Reservation.getReservationsRoot() del resvBTree[self.id] # Update room => room reservations index roomReservationsIndexBTree = Reservation.getRoomReservationsIndexRoot() resvs = roomReservationsIndexBTree[self.room.id] # must exist resvs.remove( self ) roomReservationsIndexBTree[self.room.id] = resvs #roomReservationsIndexBTree._p_changed = True - does not work here!! # Update user => user reservations index userReservationsIndexBTree = Reservation.getUserReservationsIndexRoot() resvs = userReservationsIndexBTree[self.createdBy] # must exist resvs.remove( self ) userReservationsIndexBTree[self.createdBy] = resvs # Update day => reservations index self._removeFromDayReservationsIndex() def _addToDayReservationsIndex( self ): dayReservationsIndexBTree = Reservation.getDayReservationsIndexRoot() for period in self.splitToPeriods(): day = period.startDT.date() resvs = dayReservationsIndexBTree.get( day ) if resvs == None: resvs = [] # New list of reservations for this day dayReservationsIndexBTree.insert( day, resvs ) resvs.append( self ) dayReservationsIndexBTree[day] = resvs def _removeFromDayReservationsIndex( self ): dayReservationsIndexBTree = Reservation.getDayReservationsIndexRoot() # Search for self in the whole index # (the key may have changed) days = [] for day, resvs in dayReservationsIndexBTree.iteritems(): if self in resvs: days.append( day ) for day in days: resvs = dayReservationsIndexBTree[day] resvs.remove( self ) dayReservationsIndexBTree[day] = resvs @staticmethod def getReservations( *args, **kwargs ): """ Documentation in base class. """ resvID = kwargs.get( 'resvID' ) resvEx = kwargs.get( 'resvExample' ) rooms = kwargs.get( 'rooms' ) countOnly = kwargs.get( 'countOnly' ) archival = kwargs.get( 'archival' ) heavy = kwargs.get( 'heavy' ) location = kwargs.get( 'location' ) days = kwargs.get( 'days' ) ret_lst = [] counter = 0 root = Factory.getDALManager().root if resvID != None: return root[_RESERVATIONS].get( resvID ) resvCandidates = None alreadyRoomFiltered = False if rooms and len( rooms ) <= 10: # Use room => room reservations index resvCandidates = [] for room in rooms: if location != None and room.locationName != location: continue # Skip rooms from different locations roomResvs = Reservation.getRoomReservationsIndexRoot().get( room.id ) if roomResvs != None: resvCandidates += roomResvs alreadyRoomFiltered = True if resvCandidates == None and resvEx != None and resvEx.createdBy != None: resvCandidates = Reservation.getUserReservationsIndexRoot().get( resvEx.createdBy ) if resvCandidates == None: resvCandidates = [] if days: resvsInDays = {} for day in days: dayResvs = Reservation.getDayReservationsIndexRoot().get( day ) if dayResvs: for resv in dayResvs: resvsInDays[resv] = None if resvCandidates == None: resvCandidates = resvsInDays.iterkeys() else: # Intersection new = [] for resv in resvCandidates: if resvsInDays.has_key( resv ): new.append( resv ) resvCandidates = new if resvCandidates == None: resvCandidates = Reservation.getReservationsRoot().itervalues() for resvCandidate in resvCandidates: # Apply all conditions if archival != None: if resvCandidate.isArchival != archival: continue if location != None: # If location is specified, use only rooms from this location if not resvCandidate.locationName == location: continue if heavy != None: if resvCandidate.isHeavy != heavy: continue # Does the reservation overlap on the specified period? if resvEx != None: if resvEx.startDT != None and resvEx.endDT != None: if not resvCandidate.overlapsOn( resvEx.startDT, resvEx.endDT ): continue if rooms != None and not alreadyRoomFiltered: if resvCandidate.room not in rooms: continue if resvEx.createdDT != None: if resvEx.createdDT != resvCandidate.createdDT: continue if resvEx.bookedForName != None: if resvCandidate.bookedForName == None: continue if not containsExactly_OR_containsAny( resvEx.bookedForName, resvCandidate.bookedForName ): continue if resvEx.reason != None: if resvCandidate.reason == None: continue if not containsExactly_OR_containsAny( resvEx.reason, resvCandidate.reason ): continue if resvEx.contactEmail != None: if resvCandidate.contactEmail == None: continue if not resvEx.contactEmail in resvCandidate.contactEmail: continue if resvEx.contactPhone != None: if resvCandidate.contactPhone == None: continue if not resvEx.contactPhone in resvCandidate.contactPhone: continue if resvEx.createdBy != None: if resvCandidate.createdBy != resvEx.createdBy: continue if resvEx.rejectionReason != None: if resvCandidate.rejectionReason == None: continue if not resvEx.rejectionReason in resvCandidate.rejectionReason: continue if resvEx.isConfirmed != None: if not resvCandidate.isConfirmed == resvEx.isConfirmed: continue if resvEx.isRejected != None: if not resvCandidate.isRejected == resvEx.isRejected: continue if resvEx.isCancelled != None: if not resvCandidate.isCancelled == resvEx.isCancelled: continue if resvEx.usesAVC != None: if not resvCandidate.usesAVC == resvEx.usesAVC: continue if resvEx.needsAVCSupport != None: if not resvCandidate.needsAVCSupport == resvEx.needsAVCSupport: continue # META-PROGRAMMING STYLE OF CHECKING ATTRIBUTES EQUALITY # ABANDONED DUE TO PERFORMANCE PROBLEMS # Are standard conditions met? (other attributes equality) #if not qbeMatch( resvEx, resvCandidate, Reservation.__attrSpecialEqual ): # continue # All conditions are met: add reservation to the results counter += 1 if not countOnly: ret_lst.append( resvCandidate ) #print "Found " + str( counter ) + " reservations." if not countOnly: return ret_lst else: return counter @staticmethod def countReservations( *args, **kwargs ): """ Documentation in base class. """ kwargs['countOnly'] = True return ReservationBase.getReservations( **kwargs ) # Excluded days management def getExcludedDays( self ): ReservationBase.getExcludedDays( self ) from copy import copy lst = copy( self._excludedDays ) lst.sort() return lst def setExcludedDays( self, excludedDays ): ReservationBase.setExcludedDays( self, excludedDays ) self._excludedDays = excludedDays def excludeDay( self, dayD ): """ Inserts dayD into list of excluded days. dayD should be of date type (NOT datetime). """ ReservationBase.excludeDay( self, dayD ) lst = self._excludedDays if not dayD in lst: lst.append( dayD ) self._excludedDays = lst # Force update def includeDay( self, dayD ): """ Inserts dayD into list of excluded days. dayD should be of date type (not datetime). """ ReservationBase.includeDay( self, dayD ) lst = self._excludedDays lst.remove( dayD ) self._excludedDays = lst # Force update def dayIsExcluded( self, dayD ): ReservationBase.dayIsExcluded( self, dayD ) return dayD in self.getExcludedDays() # Statistical @staticmethod def getNumberOfReservations( *args, **kwargs ): """ Returns total number of reservations in database. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) return Reservation.countReservations( location = location ) @staticmethod def getNumberOfLiveReservations( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) resvEx = Factory.newReservation() resvEx.isValid = True return Reservation.countReservations( resvExample = resvEx, archival = False, location = location ) @staticmethod def getNumberOfArchivalReservations( *args, **kwargs ): """ Returns number of archival reservations in database. Reservation is archival if it has end date in the past. Cancelled future reservations are not consider as archival. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) return Reservation.countReservations( archival = True, location = location ) # ==== Private =================================================== @classmethod def __attrSpecialEqual( cls, attrName, attrValExample, attrValCandidate ): # Skip checking for now, these must be checked another way if attrName in ( 'startDT', 'endDT', 'room', 'guid', 'locationName', 'isArchival', 'repeatability', 'weekDay', 'weekNumber' ): return True # Skip by stating they match if attrName[0:7] == 'verbose': return True if attrName == 'createdBy': return attrValExample == attrValCandidate # Just exact string matching if attrName in ['bookedForName', 'reason']: # "Must contain exactly" or must contain any attrValExample = attrValExample.strip().lower() if attrValExample[0] in ['"', "'"] and attrValExample[-1] in ['"', "'"]: attrValExample = attrValExample[1:-1] return attrValExample in attrValCandidate.lower() else: words = attrValExample.split() for word in words: if word in attrValCandidate.lower(): return True return None def _getLocationName( self ): if self.room == None: return None return self.room.locationName
def getRooms( *args, **kwargs ): """ Returns list of rooms meeting specified conditions. It is 'query by example'. You specify conditions by creating the object and passing it to the method. All arguments are optional: roomID - just a shortcut. Will return ONE room (not a list) or None. roomName - just a shortcut. Will return ONE room (not a list) or None. roomExample - example RoomBase object. reservationExample - example ReservationBase object. Represents reservation period. available - Bool, true if room must be available, false if must be booked, None if do not care freeText - str, room will be found if this string will be found anywhere in the object i.e. in equipment list, comments, responsible etc. minCapacity - Bool, defaults to False. If True, then rooms of capacity >= will be found. Otherwise capacity it looks for rooms with capacity within 20% range. allFast - Bool, defaults to False. If True, ALL active rooms will be returned in ultra fast way, REGARDLESS of all other options. ownedBy - Avatar customAtts - for rooms with custom attributes. rooms with no .customAtts attributes will be filtered out if this parameter is present The customAtts attribute should be a list of dictionaries with the attributes "name", "allowEmpty", "filter". "name" -> the name of the custom attribute "allowEmpty" -> if we allow the custom attribute to be empty or not (empty = "" or string with only whitespaces) "filter" -> a function to which we will pass the value of the custom attribute and has to return True or False. If there is more than 1 dictionary in the list, it will be like doing an AND of the conditions they represent. (see example 6) Examples: # 1. Get all rooms rooms = RoomBase.getRooms() # 2. Get all rooms with capacity about 30 r = Factory.newRoom() r.capacity = 30 rooms = RoomBase.getRooms( roomExample = r ) # 3. Get all rooms reserved on the New Year 2007, # which have capacity about 30, are at Meyrin site and have 'jean' in comments. r = Factory.newRoom() r.capacity = 30 r.site = 'Meyrin' r.comments = 'jean' p = ReservationBase() p.startDT = datetime.datetime( 2007, 01, 01 ) p.endDT = datetime.datetime( 2007, 01, 01 ) p.repeatability = None rooms = RoomBase.getRooms( roomExample = r, reservationExample = p, available = False ) # 4. Get all rooms containing "sex" in their attributes rooms = RoomBase.getRooms( freeText = 'sex' ) # 5. Get room 'AT AMPHITHEATRE' oneRoom = RoomBase.getRooms( roomName = 'AT AMPHITHEATRE' ) #6. Get rooms with a H.323 IP defined rooms = RoomBase.getRooms ( customAtts = [{"name":'H323 IP', "allowEmpty":False, "filter": (lambda ip: validIP(ip))}]) """ # Simply redirect to the plugin from MaKaC.rb_factory import Factory return Factory.newRoom().getRooms( **kwargs )
def rollback(): """ Rolls back the transaction. """ from MaKaC.rb_factory import Factory return Factory.getDALManager().rollback()
class Reservation(Persistent, ReservationBase, Observable): """ ZODB specific implementation. For documentation of methods see base class. """ __dalManager = Factory.getDALManager() def __init__(self): ReservationBase.__init__(self) self._excludedDays = [] self.useVC = [] self.resvHistory = ResvHistoryHandler() self.startEndNotification = None def getUseVC(self): try: return self.useVC except: self.useVC = [] return self.useVC def getResvHistory(self): try: return self.resvHistory except: self.resvHistory = ResvHistoryHandler() return self.resvHistory @staticmethod def getReservationsRoot(): return Reservation.__dalManager.getRoot(_RESERVATIONS) @staticmethod def getRoomReservationsIndexRoot(): return Reservation.__dalManager.getRoot(_ROOM_RESERVATIONS_INDEX) @staticmethod def getUserReservationsIndexRoot(): return Reservation.__dalManager.getRoot(_USER_RESERVATIONS_INDEX) @staticmethod def getDayReservationsIndexRoot(): return Reservation.__dalManager.getRoot(_DAY_RESERVATIONS_INDEX) @staticmethod def getRoomDayReservationsIndexRoot(): return Reservation.__dalManager.getRoot(_ROOM_DAY_RESERVATIONS_INDEX) def insert(self): """ Documentation in base class. """ ReservationBase.insert(self) resvBTree = Reservation.getReservationsRoot() # Ensure ID if self.id == None: # # Maximum ID + 1 # if len( resvBTree ) > 0: # self.id = resvBTree.maxKey() + 1 # else: # self.id = 1 # Can not use maxKey for 1st record in a tree #Faster version of the code above try: self.id = resvBTree.maxKey() + 1 except ValueError: self.id = 1 # Add self to the BTree resvBTree[self.id] = self # Update room => room reservations index roomReservationsIndexBTree = Reservation.getRoomReservationsIndexRoot() resvs = roomReservationsIndexBTree.get(self.room.id) if resvs == None: resvs = [] # New list of reservations for this room roomReservationsIndexBTree.insert(self.room.id, resvs) resvs.append(self) roomReservationsIndexBTree[self.room.id] = resvs # Update user => user reservations index userReservationsIndexBTree = Reservation.getUserReservationsIndexRoot() resvs = userReservationsIndexBTree.get(self.createdBy) if resvs == None: resvs = [] # New list of reservations for this room userReservationsIndexBTree.insert(self.createdBy, resvs) resvs.append(self) userReservationsIndexBTree[self.createdBy] = resvs # Update day => reservations index self._addToDayReservationsIndex() # Update room+day => reservations index self._addToRoomDayReservationsIndex() self._notify('reservationCreated') # Warning: # createdBy, once assigned to rerservation, CAN NOT be changed later (index!) # room, once assigned to reservation, CAN NOT be changed later (index!) def update(self): ReservationBase.update(self) self._notify('reservationUpdated') def getStartEndNotification(self): if hasattr(self, '_startEndNotification' ) and self._startEndNotification is not None: return self._startEndNotification self._startEndNotification = ReservationStartEndNotification(self) return self._startEndNotification def getLocalizedStartDT(self): tz = HelperMaKaCInfo.getMaKaCInfoInstance().getTimezone() return timezone(tz).localize(self._utcStartDT) def getLocalizedEndDT(self): tz = HelperMaKaCInfo.getMaKaCInfoInstance().getTimezone() return timezone(tz).localize(self._utcEndDT) def indexDayReservations(self): self._addToDayReservationsIndex() self._addToRoomDayReservationsIndex() self._p_changed = True def unindexDayReservations(self): self._removeFromDayReservationsIndex() self._removeFromRoomDayReservationsIndex() self._p_changed = True def remove(self): """ Documentation in base class. """ resvBTree = Reservation.getReservationsRoot() del resvBTree[self.id] # Update room => room reservations index roomReservationsIndexBTree = Reservation.getRoomReservationsIndexRoot() resvs = roomReservationsIndexBTree[self.room.id] # must exist resvs.remove(self) roomReservationsIndexBTree[ self.room. id] = resvs #roomReservationsIndexBTree._p_changed = True - does not work here!! # Update user => user reservations index userReservationsIndexBTree = Reservation.getUserReservationsIndexRoot() resvs = userReservationsIndexBTree[self.createdBy] # must exist resvs.remove(self) userReservationsIndexBTree[self.createdBy] = resvs # Update day => reservations index self._removeFromDayReservationsIndex() # Update room+day => reservations index self._removeFromRoomDayReservationsIndex() self._notify('reservationDeleted') def _addToDayReservationsIndex(self): dayReservationsIndexBTree = Reservation.getDayReservationsIndexRoot() for period in self.splitToPeriods(): day = period.startDT.date() resvs = dayReservationsIndexBTree.get(day) if resvs == None: resvs = [] # New list of reservations for this day dayReservationsIndexBTree.insert(day, resvs) resvs.append(self) dayReservationsIndexBTree[day] = resvs def _removeFromDayReservationsIndex(self): dayReservationsIndexBTree = Reservation.getDayReservationsIndexRoot() # For each of the periods, checks if it is in the index # and removes the entry for period in self.splitToPeriods(): day = period.startDT.date() resvs = dayReservationsIndexBTree.get(day) if resvs != None and self in resvs: resvs.remove(self) dayReservationsIndexBTree[day] = resvs def _addToRoomDayReservationsIndex(self): roomDayReservationsIndexBTree = Reservation.getRoomDayReservationsIndexRoot( ) for period in self.splitToPeriods(): day = period.startDT.date() key = (self.room.id, day) resvs = roomDayReservationsIndexBTree.get(key) if resvs is None: resvs = OOSet() resvs.add(self) roomDayReservationsIndexBTree[key] = resvs def _removeFromRoomDayReservationsIndex(self): roomDayReservationsIndexBTree = Reservation.getRoomDayReservationsIndexRoot( ) for period in self.splitToPeriods(): day = period.startDT.date() key = (self.room.id, day) resvs = roomDayReservationsIndexBTree.get(key) if resvs is not None and self in resvs: resvs.remove(self) roomDayReservationsIndexBTree[key] = resvs @staticmethod def getReservations(*args, **kwargs): """ Documentation in base class. """ resvID = kwargs.get('resvID') resvEx = kwargs.get('resvExample') rooms = kwargs.get('rooms') countOnly = kwargs.get('countOnly') archival = kwargs.get('archival') heavy = kwargs.get('heavy') location = kwargs.get('location') days = kwargs.get('days') ret_lst = [] counter = 0 root = Factory.getDALManager().getRoot() if resvID != None: return root[_RESERVATIONS].get(resvID) resvCandidates = None alreadyRoomFiltered = False # If we filter by room but not by day, we can use the RoomReservations index if rooms and not days and len(rooms) <= 10: # Use room => room reservations index resvCandidates = set() for room in rooms: if location != None and room.locationName != location: continue # Skip rooms from different locations roomResvs = Reservation.getRoomReservationsIndexRoot().get( room.id) if roomResvs != None: resvCandidates.update(roomResvs) alreadyRoomFiltered = True # If we don't have reservations yet but filter by creator, use the UserReservations index if resvCandidates == None and resvEx != None and resvEx.createdBy != None: resvCandidates = set( Reservation.getUserReservationsIndexRoot().get( resvEx.createdBy, [])) # If we want to filter by day, we can choose indexes. dayFilteredResvs = None if days and rooms: # If there's a room filter, too - use the RoomDayReservations index dayFilteredResvs = set() for key in ((room.id, day) for day in days for room in rooms): dayRoomResvs = Reservation.getRoomDayReservationsIndexRoot( ).get(key, []) dayFilteredResvs.update(dayRoomResvs) alreadyRoomFiltered = True elif days: # If we only filter by days, use the DayReservations index dayFilteredResvs = set() for day in days: dayResvs = Reservation.getDayReservationsIndexRoot().get( day, []) dayFilteredResvs.update(dayResvs) # If we have some day-filtered reservations, use that list or restrict the existing one if dayFilteredResvs is not None: if resvCandidates is None: resvCandidates = dayFilteredResvs else: # Intersection resvCandidates = dayFilteredResvs & resvCandidates # If we still have nothing, get all reservations and filter them later in the loop (slow!) if resvCandidates is None: resvCandidates = Reservation.getReservationsRoot().itervalues() for resvCandidate in resvCandidates: # Apply all conditions if archival != None: if resvCandidate.isArchival != archival: continue if location != None: # If location is specified, use only rooms from this location if not resvCandidate.locationName == location: continue if heavy != None: if resvCandidate.isHeavy != heavy: continue # Does the reservation overlap on the specified period? if resvEx != None: if resvEx.startDT != None and resvEx.endDT != None: if not resvCandidate.overlapsOn(resvEx.startDT, resvEx.endDT): continue if rooms != None and not alreadyRoomFiltered: if resvCandidate.room not in rooms: continue if resvEx.createdDT != None: if resvEx.createdDT != resvCandidate.createdDT: continue if resvEx.bookedForName != None: if resvCandidate.bookedForName == None: continue if not containsExactly_OR_containsAny( resvEx.bookedForName, resvCandidate.bookedForName): continue if resvEx.reason != None: if resvCandidate.reason == None: continue if not containsExactly_OR_containsAny( resvEx.reason, resvCandidate.reason): continue if resvEx.contactEmail != None: if resvCandidate.contactEmail == None: continue if not resvEx.contactEmail in resvCandidate.contactEmail: continue if resvEx.contactPhone != None: if resvCandidate.contactPhone == None: continue if not resvEx.contactPhone in resvCandidate.contactPhone: continue if resvEx.createdBy != None: if resvCandidate.createdBy != resvEx.createdBy: continue if resvEx.rejectionReason != None: if resvCandidate.rejectionReason == None: continue if not resvEx.rejectionReason in resvCandidate.rejectionReason: continue if resvEx.isConfirmed != None: if not resvCandidate.isConfirmed == resvEx.isConfirmed: continue if resvEx.isRejected != None: if not resvCandidate.isRejected == resvEx.isRejected: continue if resvEx.isCancelled != None: if not resvCandidate.isCancelled == resvEx.isCancelled: continue if resvEx.usesAVC != None: if not resvCandidate.usesAVC == resvEx.usesAVC: continue if resvEx.needsAVCSupport != None: if not resvCandidate.needsAVCSupport == resvEx.needsAVCSupport: continue if resvEx.needsAssistance != None: if not resvCandidate.needsAssistance == resvEx.needsAssistance: continue # META-PROGRAMMING STYLE OF CHECKING ATTRIBUTES EQUALITY # ABANDONED DUE TO PERFORMANCE PROBLEMS # Are standard conditions met? (other attributes equality) #if not qbeMatch( resvEx, resvCandidate, Reservation.__attrSpecialEqual ): # continue # All conditions are met: add reservation to the results counter += 1 if not countOnly: ret_lst.append(resvCandidate) #print "Found " + str( counter ) + " reservations." if not countOnly: return ret_lst else: return counter @staticmethod def countReservations(*args, **kwargs): """ Documentation in base class. """ kwargs['countOnly'] = True return ReservationBase.getReservations(**kwargs) # Excluded days management def getExcludedDays(self): ReservationBase.getExcludedDays(self) from copy import copy lst = copy(self._excludedDays) lst.sort() return lst def setExcludedDays(self, excludedDays): ReservationBase.setExcludedDays(self, excludedDays) self._excludedDays = excludedDays def excludeDay(self, dayD, unindex=False): """ Inserts dayD into list of excluded days. dayD should be of date type (NOT datetime). """ ReservationBase.excludeDay(self, dayD) lst = self._excludedDays if not dayD in lst: lst.append(dayD) self._excludedDays = lst # Force update if unindex: dayReservationsIndexBTree = Reservation.getDayReservationsIndexRoot( ) if dayReservationsIndexBTree.has_key(dayD): try: resvs = dayReservationsIndexBTree[dayD] resvs.remove(self) dayReservationsIndexBTree[dayD] = resvs except ValueError, e: Logger.get('RoomBooking').debug( "excludeDay: Unindexing a day (%s) which is not indexed" % dayD)
## License, or (at your option) any later version. ## ## Indico is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Indico;if not, see <http://www.gnu.org/licenses/>. from indico.core.db import DBMgr from MaKaC.rb_factory import Factory from MaKaC.rb_location import CrossLocationQueries DBMgr.getInstance().startRequest() Factory.getDALManager().connect() idontknow = "I don't know" rooms = CrossLocationQueries.getRooms( allFast = True ) for room in rooms: print "[%s][%s] %s"%(room.id, room.needsAVCSetup,room.getAvailableVC()) if room.needsAVCSetup: if not idontknow in room.getAvailableVC(): room.avaibleVC.append(idontknow) room.update() Factory.getDALManager().commit() Factory.getDALManager().disconnect() DBMgr.getInstance().endRequest()
## License, or (at your option) any later version. ## ## Indico is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Indico;if not, see <http://www.gnu.org/licenses/>. from MaKaC.common.db import DBMgr from MaKaC.rb_factory import Factory from MaKaC.rb_location import CrossLocationQueries DBMgr.getInstance().startRequest() Factory.getDALManager().connect() idontknow = "I don't know" rooms = CrossLocationQueries.getRooms( allFast = True ) for room in rooms: print "[%s][%s] %s"%(room.id, room.needsAVCSetup,room.getAvailableVC()) if room.needsAVCSetup: if not idontknow in room.getAvailableVC(): room.avaibleVC.append(idontknow) room.update() Factory.getDALManager().commit() Factory.getDALManager().disconnect() DBMgr.getInstance().endRequest()