def getRoomsByExample(): Test.dalManager.connect() # By ID room = RoomBase.getRooms(roomID=176) assert room.name == "4-1-021" # By other attributes roomEx = Factory.newRoom() roomEx.site = "prevessin" roomEx.comments = "res" rooms = RoomBase.getRooms(roomExample=roomEx) assert len(rooms) == 8 # 20 roomEx = Factory.newRoom() roomEx.capacity = 20 rooms = RoomBase.getRooms(roomExample=roomEx) assert len(rooms) == 26 roomEx = Factory.newRoom() roomEx.isReservable = True roomEx.setEquipment(["Video projector", "Wireless"]) rooms = RoomBase.getRooms(roomExample=roomEx) assert len(rooms) == 33 Test.dalManager.disconnect()
def getRoomsByExample(): Test.dalManager.connect() # By ID room = RoomBase.getRooms( roomID = 176 ) assert( room.name == '4-1-021' ) # By other attributes roomEx = Factory.newRoom() roomEx.site = 'prevessin' roomEx.comments = 'res' rooms = RoomBase.getRooms( roomExample = roomEx ) assert( len( rooms ) == 8 ) # 20 roomEx = Factory.newRoom() roomEx.capacity = 20 rooms = RoomBase.getRooms( roomExample = roomEx ) assert( len( rooms ) == 26 ) roomEx = Factory.newRoom() roomEx.isReservable = True roomEx.setEquipment( [ 'Video projector', 'Wireless' ] ) rooms = RoomBase.getRooms( roomExample = roomEx ) assert( len( rooms ) == 33 ) Test.dalManager.disconnect()
def listResv4User(user): dbi = DBMgr.getInstance() dbi.startRequest() Factory.getDALManager().connect() resvEx = ReservationBase() resvEx.createdBy = user allResv = CrossLocationQueries.getReservations( resvExample = resvEx) print "User %s has %s resevations created by him/her"%(user, len(allResv)) Factory.getDALManager().disconnect() dbi.endRequest()
def tmp(): from MaKaC.rb_factory import Factory from MaKaC.rb_room import RoomBase from indico.core.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 getBlockedDay(self, day): blockings = Factory.newRoomBlocking().getByDate(day) for bl in blockings: rbl = bl.getBlockedRoom(self) if rbl and rbl.active is not False: return rbl return None
def removeEquipment( equipmentName, *args, **kwargs ): from MaKaC.rb_location import Location location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) lst = EquipmentManager.getRoot() lst[location].remove( equipmentName ) Factory.getDALManager().getRoot()[_EQUIPMENT_LIST] = lst
def getNumberOfReservableRooms( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) room = Factory.newRoom() room.isReservable = True room.isActive = True return Room.countRooms( roomExample = room, location = location )
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 setPossibleEquipment( equipmentList, *args, **kwargs ): from MaKaC.rb_location import Location location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) lst = EquipmentManager.getRoot() lst[location] = equipmentList Factory.getDALManager().getRoot()[_EQUIPMENT_LIST] = lst # Force update
def setPossibleEquipment(equipmentList, *args, **kwargs): from MaKaC.rb_location import Location location = kwargs.get('location', Location.getDefaultLocation().friendlyName) lst = EquipmentManager.getRoot() lst[location] = equipmentList Factory.getDALManager().root[_EQUIPMENT_LIST] = lst # Force update
def removeEquipment(equipmentName, *args, **kwargs): from MaKaC.rb_location import Location location = kwargs.get('location', Location.getDefaultLocation().friendlyName) lst = EquipmentManager.getRoot() lst[location].remove(equipmentName) Factory.getDALManager().getRoot()[_EQUIPMENT_LIST] = lst
def insertEquipment( equipmentName, *args, **kwargs ): from MaKaC.rb_location import Location location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) lst = EquipmentManager.getRoot() if lst.get( location ) == None: lst[location] = [] lst[location].append( equipmentName ) Factory.getDALManager().getRoot()[_EQUIPMENT_LIST] = lst
def getPossibleEquipment( *args, **kwargs ): from MaKaC.rb_location import Location location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) lst = EquipmentManager.getRoot() if lst.get( location ) == None: lst[location] = [] Factory.getDALManager().getRoot()[_EQUIPMENT_LIST] = lst return lst[location]
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 insertEquipment(equipmentName, *args, **kwargs): from MaKaC.rb_location import Location location = kwargs.get('location', Location.getDefaultLocation().friendlyName) lst = EquipmentManager.getRoot() if lst.get(location) == None: lst[location] = [] lst[location].append(equipmentName) Factory.getDALManager().getRoot()[_EQUIPMENT_LIST] = lst
def getPossibleEquipment(*args, **kwargs): from MaKaC.rb_location import Location location = kwargs.get('location', Location.getDefaultLocation().friendlyName) lst = EquipmentManager.getRoot() if lst.get(location) == None: lst[location] = [] Factory.getDALManager().getRoot()[_EQUIPMENT_LIST] = lst return lst[location]
def setAttributes( attsList, *args, **kwargs ): location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) for at in attsList: errors = CustomAttributesManagerBase.checkAttribute( at ) if errors: raise str( errors ) dic = CustomAttributesManager.getRoot() dic[location] = attsList root = Factory.getDALManager().root root[_CUSTOM_ATTRIBUTES_LIST] = dic
def getAvailableRooms(): Test.dalManager.connect() from datetime import datetime roomEx = Factory.newRoom() roomEx.isActive = True roomEx.isReservable = True resvEx = Factory.newReservation() resvEx.startDT = datetime(2006, 12, 01, 10) resvEx.endDT = datetime(2006, 12, 14, 15) resvEx.repeatability = 0 # Daily rooms = RoomBase.getRooms(roomExample=roomEx, resvExample=resvEx, available=True) for room in rooms: print "\n=======================================\n" print room Test.dalManager.disconnect()
def reservation(self, locList): Factory.getDALManager().connect() resvEx = ReservationBase() resvEx.startDT = self._fromDT resvEx.endDT = self._toDT locList = filter(lambda loc: Location.parse(loc) is not None, locList) if self._fromDT or self._toDT: daysParam = (day.date() for day in rrule.rrule(rrule.DAILY, dtstart=self._fromDT, until=self._toDT)) else: # slow! daysParam = None for loc in sorted(locList): resvs = CrossLocationQueries.getReservations(location=loc, resvExample=resvEx, days=daysParam) for obj in self._process(resvs, filter=self._resvFilter): yield obj Factory.getDALManager().disconnect()
def do(): # Set equipment Test.dalManager.connect() em = Factory.getEquipmentManager() saved = ['a ', 'bbb', 'c'] em.setPossibleEquipment(saved) Test.dalManager.commit() Test.dalManager.disconnect() # Get equipment Test.dalManager.connect() loaded = em.getPossibleEquipment() assert(loaded == saved) Test.dalManager.disconnect()
def do(): # Set equipment Test.dalManager.connect() em = Factory.getEquipmentManager() saved = ['a ', 'bbb', 'c' ] em.setPossibleEquipment( saved ) Test.dalManager.commit() Test.dalManager.disconnect() # Get equipment Test.dalManager.connect() loaded = em.getPossibleEquipment() assert( loaded == saved ) Test.dalManager.disconnect()
def getRoomsByExampleDemo(): Test.dalManager.connect() roomEx = Factory.newRoom() roomEx.building = 513 roomEx.capacity = 20 rooms = CrossLocationQueries.getRooms( roomExample = roomEx ) for room in rooms: print "=============================" print room Test.dalManager.disconnect()
def getAvailableRooms(): Test.dalManager.connect() from datetime import datetime roomEx = Factory.newRoom() roomEx.isActive = True roomEx.isReservable = True resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 12, 01, 10 ) resvEx.endDT = datetime( 2006, 12, 14, 15 ) resvEx.repeatability = 0 # Daily rooms = RoomBase.getRooms( \ roomExample = roomEx, resvExample = resvEx, available = True ) for room in rooms: print "\n=======================================\n" print room Test.dalManager.disconnect()
def do(): # Set equipment Test.dalManager.connect() em = Factory.getEquipmentManager() saved = ["a ", "bbb", "c"] em.setPossibleEquipment(saved) Test.dalManager.commit() Test.dalManager.disconnect() # Get equipment Test.dalManager.connect() loaded = em.getPossibleEquipment() assert loaded == saved Test.dalManager.disconnect()
def changeCreator(oldUser, newUser): dbi = DBMgr.getInstance() dbi.startRequest() Factory.getDALManager().connect() # check if the users exist if AvatarHolder().getById(oldUser) is None: print "There is no user with id %s" % oldUser return if AvatarHolder().getById(newUser) is None: print "There is no user with id %s" % newUser return resvEx = ReservationBase() resvEx.createdBy = oldUser allResv4OldUser = CrossLocationQueries.getReservations(resvExample=resvEx) if allResv4OldUser == []: print "No reservations for user %s" % oldUser return # resvs = ReservationBase.getReservations() # allResv4OldUser = [x for x in allResv if x.createdBy == oldUser] if type(allResv4OldUser) is not list: allResv4OldUser = [allResv4OldUser] # Modify reservations for r in allResv4OldUser: r.createdBy = newUser #print r.createdBy, r.id # Update index userReservationsIndexBTree = Reservation.getUserReservationsIndexRoot() newUserResvs = userReservationsIndexBTree.get(newUser) if newUserResvs == None: newUserResvs = [] # New list of reservations for this room userReservationsIndexBTree.insert(newUser, newUserResvs) newUserResvs.extend(allResv4OldUser) userReservationsIndexBTree[newUser] = newUserResvs[:] if userReservationsIndexBTree.has_key(oldUser): userReservationsIndexBTree.pop(oldUser) userReservationsIndexBTree._p_changed = 1 # close DB connection Factory.getDALManager().commit() Factory.getDALManager().disconnect() dbi.endRequest() print "%s reservations have moved from creator %s to creator %s" % ( len(allResv4OldUser), oldUser, newUser)
def changeCreator(oldUser, newUser): dbi = DBMgr.getInstance() dbi.startRequest() Factory.getDALManager().connect() # check if the users exist if AvatarHolder().getById(oldUser) is None: print "There is no user with id %s"%oldUser return if AvatarHolder().getById(newUser) is None: print "There is no user with id %s"%newUser return resvEx = ReservationBase() resvEx.createdBy = oldUser allResv4OldUser = CrossLocationQueries.getReservations( resvExample = resvEx) if allResv4OldUser == []: print "No reservations for user %s"%oldUser return # resvs = ReservationBase.getReservations() # allResv4OldUser = [x for x in allResv if x.createdBy == oldUser] if type(allResv4OldUser) is not list: allResv4OldUser = [allResv4OldUser] # Modify reservations for r in allResv4OldUser: r.createdBy = newUser #print r.createdBy, r.id # Update index userReservationsIndexBTree = Reservation.getUserReservationsIndexRoot() newUserResvs = userReservationsIndexBTree.get( newUser ) if newUserResvs == None: newUserResvs = [] # New list of reservations for this room userReservationsIndexBTree.insert( newUser, newUserResvs ) newUserResvs.extend( allResv4OldUser ) userReservationsIndexBTree[newUser] = newUserResvs[:] if userReservationsIndexBTree.has_key(oldUser): userReservationsIndexBTree.pop(oldUser) userReservationsIndexBTree._p_changed = 1 # close DB connection Factory.getDALManager().commit() Factory.getDALManager().disconnect() dbi.endRequest() print "%s reservations have moved from creator %s to creator %s" % (len(allResv4OldUser), oldUser, newUser)
def search(self, location, name): Factory.getDALManager().connect() rooms = CrossLocationQueries.getRooms(location=location) def _search_rooms(name): return (room for room in rooms if name in room.getFullName()) for obj in self._process(_search_rooms(name)): yield obj Factory.getDALManager().rollback() Factory.getDALManager().disconnect()
def room(self, location, idlist): Factory.getDALManager().connect() rooms = CrossLocationQueries.getRooms(location=location) def _iterate_rooms(objIds): objIds = map(int, objIds) return (room for room in rooms if room.id in objIds) for obj in self._process(_iterate_rooms(idlist)): yield obj Factory.getDALManager().rollback() Factory.getDALManager().disconnect()
def handler(req, **params): ContextManager.destroy() logger = Logger.get("httpapi") path, query = req.URLFields["PATH_INFO"], req.URLFields["QUERY_STRING"] if req.method == "POST": # Convert POST data to a query string queryParams = dict(req.form) for key, value in queryParams.iteritems(): queryParams[key] = [str(value)] query = urllib.urlencode(remove_lists(queryParams)) else: # Parse the actual query string queryParams = parse_qs(query) dbi = DBMgr.getInstance() dbi.startRequest() minfo = HelperMaKaCInfo.getMaKaCInfoInstance() if minfo.getRoomBookingModuleActive(): Factory.getDALManager().connect() apiKey = get_query_parameter(queryParams, ["ak", "apikey"], None) cookieAuth = get_query_parameter(queryParams, ["ca", "cookieauth"], "no") == "yes" signature = get_query_parameter(queryParams, ["signature"]) timestamp = get_query_parameter(queryParams, ["timestamp"], 0, integer=True) noCache = get_query_parameter(queryParams, ["nc", "nocache"], "no") == "yes" pretty = get_query_parameter(queryParams, ["p", "pretty"], "no") == "yes" onlyPublic = get_query_parameter(queryParams, ["op", "onlypublic"], "no") == "yes" onlyAuthed = get_query_parameter(queryParams, ["oa", "onlyauthed"], "no") == "yes" # Get our handler function and its argument and response type hook, dformat = HTTPAPIHook.parseRequest(path, queryParams) if hook is None or dformat is None: raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND # Disable caching if we are not just retrieving data (or the hook requires it) if req.method == "POST" or hook.NO_CACHE: noCache = True ak = error = result = None ts = int(time.time()) typeMap = {} try: sessionUser = getSessionForReq(req).getUser() if cookieAuth else None if apiKey or not sessionUser: # Validate the API key (and its signature) ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp, path, query) if enforceOnlyPublic: onlyPublic = True # Create an access wrapper for the API key's user aw = buildAW(ak, req, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() is None: cacheKey = normalizeQuery( path, query, remove=("ak", "apiKey", "signature", "timestamp", "nc", "nocache", "oa", "onlyauthed") ) else: cacheKey = normalizeQuery( path, query, remove=("signature", "timestamp", "nc", "nocache", "oa", "onlyauthed") ) if signature: # in case the request was signed, store the result under a different key cacheKey = "signed_" + cacheKey else: # We authenticated using a session cookie. # Reject POST for security reasons (CSRF) if req.method == "POST": raise HTTPAPIError("Cannot POST when using cookie authentication", apache.HTTP_FORBIDDEN) aw = AccessWrapper() if not onlyPublic: aw.setUser(sessionUser) userPrefix = "user-" + sessionUser.getId() + "_" cacheKey = userPrefix + normalizeQuery( path, query, remove=("nc", "nocache", "ca", "cookieauth", "oa", "onlyauthed") ) # Bail out if the user requires authentication but is not authenticated if onlyAuthed and not aw.getUser(): raise HTTPAPIError("Not authenticated", apache.HTTP_FORBIDDEN) obj = None addToCache = not hook.NO_CACHE cache = GenericCache("HTTPAPI") cacheKey = RE_REMOVE_EXTENSION.sub("", cacheKey) if not noCache: obj = cache.get(cacheKey) if obj is not None: result, extra, ts, complete, typeMap = obj addToCache = False if result is None: # Perform the actual exporting res = hook(aw, req) if isinstance(res, tuple) and len(res) == 4: result, extra, complete, typeMap = res else: result, extra, complete, typeMap = res, {}, True, {} if result is not None and addToCache: ttl = HelperMaKaCInfo.getMaKaCInfoInstance().getAPICacheTTL() cache.set(cacheKey, (result, extra, ts, complete, typeMap), ttl) except HTTPAPIError, e: error = e if e.getCode(): req.status = e.getCode() if req.status == apache.HTTP_METHOD_NOT_ALLOWED: req.headers_out["Allow"] = "GET" if req.method == "POST" else "POST"
def handler(req, **params): ContextManager.destroy() logger = Logger.get('httpapi') path, query = req.URLFields['PATH_INFO'], req.URLFields['QUERY_STRING'] if req.method == 'POST': # Convert POST data to a query string queryParams = dict(req.form) for key, value in queryParams.iteritems(): queryParams[key] = [str(value)] query = urllib.urlencode(remove_lists(queryParams)) else: # Parse the actual query string queryParams = parse_qs(query) dbi = DBMgr.getInstance() dbi.startRequest() minfo = HelperMaKaCInfo.getMaKaCInfoInstance() if minfo.getRoomBookingModuleActive(): Factory.getDALManager().connect() apiKey = get_query_parameter(queryParams, ['ak', 'apikey'], None) cookieAuth = get_query_parameter(queryParams, ['ca', 'cookieauth'], 'no') == 'yes' signature = get_query_parameter(queryParams, ['signature']) timestamp = get_query_parameter(queryParams, ['timestamp'], 0, integer=True) noCache = get_query_parameter(queryParams, ['nc', 'nocache'], 'no') == 'yes' pretty = get_query_parameter(queryParams, ['p', 'pretty'], 'no') == 'yes' onlyPublic = get_query_parameter(queryParams, ['op', 'onlypublic'], 'no') == 'yes' onlyAuthed = get_query_parameter(queryParams, ['oa', 'onlyauthed'], 'no') == 'yes' # Get our handler function and its argument and response type hook, dformat = HTTPAPIHook.parseRequest(path, queryParams) if hook is None or dformat is None: raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND # Disable caching if we are not just retrieving data (or the hook requires it) if req.method == 'POST' or hook.NO_CACHE: noCache = True ak = error = result = None ts = int(time.time()) typeMap = {} try: session = None if cookieAuth: session = getSessionForReq(req) if not session.getUser(): # ignore guest sessions session = None if apiKey or not session: # Validate the API key (and its signature) ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp, path, query) if enforceOnlyPublic: onlyPublic = True # Create an access wrapper for the API key's user aw = buildAW(ak, req, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() is None: cacheKey = normalizeQuery(path, query, remove=('ak', 'apiKey', 'signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) else: cacheKey = normalizeQuery(path, query, remove=('signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) if signature: # in case the request was signed, store the result under a different key cacheKey = 'signed_' + cacheKey else: # We authenticated using a session cookie. if Config.getInstance().getCSRFLevel() >= 2: token = req.headers_in.get('X-CSRF-Token', get_query_parameter(queryParams, ['csrftoken'])) if session.csrf_token != token: raise HTTPAPIError('Invalid CSRF token', apache.HTTP_FORBIDDEN) aw = AccessWrapper() if not onlyPublic: aw.setUser(session.getUser()) userPrefix = 'user-' + session.getUser().getId() + '_' cacheKey = userPrefix + normalizeQuery(path, query, remove=('nc', 'nocache', 'ca', 'cookieauth', 'oa', 'onlyauthed', 'csrftoken')) # Bail out if the user requires authentication but is not authenticated if onlyAuthed and not aw.getUser(): raise HTTPAPIError('Not authenticated', apache.HTTP_FORBIDDEN) obj = None addToCache = not hook.NO_CACHE cache = GenericCache('HTTPAPI') cacheKey = RE_REMOVE_EXTENSION.sub('', cacheKey) if not noCache: obj = cache.get(cacheKey) if obj is not None: result, extra, ts, complete, typeMap = obj addToCache = False if result is None: # Perform the actual exporting res = hook(aw, req) if isinstance(res, tuple) and len(res) == 4: result, extra, complete, typeMap = res else: result, extra, complete, typeMap = res, {}, True, {} if result is not None and addToCache: ttl = HelperMaKaCInfo.getMaKaCInfoInstance().getAPICacheTTL() cache.set(cacheKey, (result, extra, ts, complete, typeMap), ttl) except HTTPAPIError, e: error = e if e.getCode(): req.status = e.getCode() if req.status == apache.HTTP_METHOD_NOT_ALLOWED: req.headers_out['Allow'] = 'GET' if req.method == 'POST' else 'POST'
error = e if e.getCode(): req.status = e.getCode() if req.status == apache.HTTP_METHOD_NOT_ALLOWED: req.headers_out['Allow'] = 'GET' if req.method == 'POST' else 'POST' if result is None and error is None: # TODO: usage page raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND else: if ak and error is None: # Commit only if there was an API key and no error for _retry in xrange(10): dbi.sync() if minfo.getRoomBookingModuleActive(): Factory.getDALManager().sync() normPath, normQuery = normalizeQuery(path, query, remove=('signature', 'timestamp'), separate=True) ak.used(_get_remote_ip(req), normPath, normQuery, not onlyPublic) try: if minfo.getRoomBookingModuleActive(): Factory.getDALManager().disconnect() dbi.endRequest(True) except ConflictError: pass # retry else: break else: # No need to commit stuff if we didn't use an API key # (nothing was written) if minfo.getRoomBookingModuleActive(): Factory.getDALManager().rollback()
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.bookedForId != None: if resvCandidate.bookedForId == None: continue if resvEx.bookedForId != resvCandidate.bookedForId: 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
class Room( Persistent, RoomBase, Fossilizable ): """ ZODB specific implementation. For documentation of methods see base class. """ fossilizes(IRoomMapFossil, IRoomCalendarFossil) __dalManager = Factory.getDALManager() vcList = [] def __init__(self): RoomBase.__init__( self ) self.customAtts = PersistentMapping() self.avaibleVC = [] self._nonBookableDates = [] def getNonBookableDates(self): try: if self._nonBookableDates: pass except AttributeError: self._nonBookableDates = [] self._p_changed = 1 return self._nonBookableDates def addNonBookableDate(self, udate): self._nonBookableDates.append(udate) self._p_changed = 1 def addNonBookableDateFromParams(self, params): nbd = NonBookableDate(params["startDate"], params["endDate"]) self._nonBookableDates.append(nbd) self._p_changed = 1 def clearNonBookableDates(self): self._nonBookableDates = [] self._p_changed = 1 def isNonBookableDay(self, day): for nbd in self.getNonBookableDates(): if nbd.doesDayOverlap(day): return True return False def getBlockedDay(self, day): blockings = Factory.newRoomBlocking().getByDate(day) for bl in blockings: rbl = bl.getBlockedRoom(self) if rbl and rbl.active is not False: return rbl return None def setAvailableVC(self, avc): self.avaibleVC = avc def getAvailableVC(self): try: return self.avaibleVC except: self.avaibleVC = [] return self.avaibleVC @staticmethod def getRoot(): return Room.__dalManager.getRoot(_ROOMS) def getAllManagers(self): managers = set([self.getResponsible()]) if self.customAtts.get('Simba List'): groups = GroupHolder().match({'name': self.customAtts['Simba List']}, exact=True, forceWithoutExtAuth=True) if not groups: groups = GroupHolder().match({'name': self.customAtts['Simba List']}, exact=True) if groups and len(groups) == 1: managers |= set(groups[0].getMemberList()) return list(managers) def insert( self ): """ Documentation in base class. """ RoomBase.insert( self ) roomsBTree = Room.getRoot() # Ensure ID if self.id == None: # Maximum ID + 1 if len( roomsBTree ) > 0: self.id = roomsBTree.maxKey() + 1 else: self.id = 1 # Can not use maxKey for 1st record in a tree # Add self to the BTree roomsBTree[self.id] = self Catalog.getIdx('user_room').index_obj(self.guid) def update( self ): """ Documentation in base class. """ RoomBase.update( self ) # Check Simba mailing list listName = self.customAtts.get( 'Simba List' ) if listName: from MaKaC.user import GroupHolder groups = GroupHolder().match( { 'name': listName }, forceWithoutExtAuth = True ) if not groups: groups = GroupHolder().match( { 'name': listName } ) if not groups: self.customAtts['Simba List'] = 'Error: unknown mailing list' # reindex - needed due to possible manager changes # super slow, though... Catalog.getIdx('user_room').unindex_obj(self.guid) Catalog.getIdx('user_room').index_obj(self.guid) self._p_changed = True def remove( self ): """ Documentation in base class. """ RoomBase.remove( self ) roomsBTree = Room.getRoot() del roomsBTree[self.id] if Catalog.getIdx('user_room').has_obj(self.guid): Catalog.getIdx('user_room').unindex_obj(self.guid) @classmethod def isAvatarResponsibleForRooms(cls, avatar): return Catalog.getIdx('user_room').get(avatar.getId()) is not None @classmethod def getUserRooms(cls, avatar): return Catalog.getIdx('user_room').get(avatar.getId()) # Typical actions @staticmethod def getRooms( *args, **kwargs ): """ Documentation in base class. """ roomsBTree = Room.getRoot() location = kwargs.get( 'location' ) if kwargs.get( 'allFast' ) == True: return [ room for room in roomsBTree.values() if room.isActive and (not location or room.locationName == location) ] if kwargs.get( 'reallyAllFast' ) == True: return [ room for room in roomsBTree.values() if (not location or room.locationName == location) ] if len( kwargs ) == 0: ret_lst = [] for room in roomsBTree.values(): ret_lst.append( room ) roomID = kwargs.get( 'roomID' ) roomName = kwargs.get( 'roomName' ) roomEx = kwargs.get( 'roomExample' ) resvEx = kwargs.get( 'resvExample' ) freeText = kwargs.get( 'freeText' ) available = kwargs.get( 'available' ) countOnly = kwargs.get( 'countOnly' ) minCapacity = kwargs.get( 'minCapacity' ) location = kwargs.get( 'location' ) ownedBy = kwargs.get( 'ownedBy' ) customAtts = kwargs.get( 'customAtts' ) # responsibleID = kwargs.get( 'responsibleID' ) pendingBlockings = kwargs.get( 'pendingBlockings' ) ret_lst = [] counter = 0 if roomID != None: return roomsBTree.get( roomID ) if roomName != None: for room in roomsBTree.itervalues(): if room.name == roomName: if location == None or room.locationName == location: return room return None for room in roomsBTree.itervalues(): # Apply all conditions ========= if location != None: if room.locationName != location: continue if roomEx != None: if not qbeMatch( roomEx, room, Room.__attrSpecialEqual, minCapacity = minCapacity ): continue if not room.__hasEquipment( roomEx.getEquipment() ): continue if freeText != None: if not room.__hasFreeText( freeText.split() ): continue if resvEx != None: resvEx.room = room aval = room.isAvailable( resvEx ) if aval != available: continue blockState = resvEx.getBlockingConflictState(ContextManager.get('currentUser')) if blockState == 'active': continue elif blockState == 'pending' and pendingBlockings: continue if ownedBy != None: if not room.isOwnedBy( ownedBy ): continue if customAtts is not None: if not hasattr(room, "customAtts"): continue discard = False for condition in customAtts: attName = condition["name"] allowEmpty = condition.get("allowEmpty", False) filter = condition.get("filter", None) if not attName in room.customAtts: discard = True break elif not allowEmpty and str(room.customAtts[attName]).strip() == "": discard = True break elif not filter(room.customAtts[attName]): discard = True break if discard: continue # All conditions are met: add room to the results counter += 1 if not countOnly: ret_lst.append( room ) #print "Found %d rooms." % counter if countOnly: return counter else: return ret_lst # Statistics ==================================== @staticmethod def countRooms( *args, **kwargs ): """ Documentation in base class. """ kwargs['countOnly'] = True return Room.getRooms( **kwargs ) @staticmethod def getNumberOfRooms( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) return Room.countRooms( location = location ) @staticmethod def getNumberOfActiveRooms( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) room = Factory.newRoom() room.isActive = True return Room.countRooms( roomExample = room, location = location ) @staticmethod def getNumberOfReservableRooms( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) room = Factory.newRoom() room.isReservable = True room.isActive = True return Room.countRooms( roomExample = room, location = location ) def getLocationName( self ): #from MaKaC.plugins.RoomBooking.default.factory import Factory #return Factory.locationName return self._locationName def setLocationName( self, locationName ): self._locationName = locationName def savePhoto( self, photoPath ): filePath = Config.getInstance().getRoomPhotosDir() fileName = self._doGetPhotoId( force = True ) + ".jpg" try: os.makedirs( filePath ) except: pass fullPath = os.path.join( filePath, fileName ) f = open( fullPath, "wb" ) f.write( photoPath.file.read() ) f.close() def saveSmallPhoto( self, photoPath ): filePath = Config.getInstance().getRoomSmallPhotosDir() fileName = self._doGetPhotoId( force = True ) + ".jpg" try: os.makedirs( filePath ) except: pass fullPath = os.path.join( filePath, fileName ) f = open( fullPath, "wb" ) f.write( photoPath.file.read() ) f.close() # ==== Private =================================================== def _getSafeLocationName( self ): if self.locationName == None: return None s = "" for i in xrange( 0, len( self.locationName ) ): code = ord( self.locationName[i] ) if ( code in xrange( ord( 'a' ), ord( 'z' ) + 1 ) ) or \ ( code in xrange( ord( 'A' ), ord( 'Z' ) + 1 ) ) or \ ( code in xrange( ord( '0' ), ord( '9' ) + 1 ) ): # Valid s += self.locationName[i] else: s += '_' # Replace all other characters with underscore return s def _doGetPhotoId( self, force = False ): photoId = "%s-%s-%s-%s" % ( str( self._getSafeLocationName() ), str( self.building ).strip(), str( self.floor ).strip(), str( self.roomNr ).strip() ) filePath = Config.getInstance().getRoomPhotosDir() fileName = photoId + ".jpg" fullPath = os.path.join( filePath, fileName ) from os.path import exists if exists( fullPath ) or force: return photoId else: return None def _doSetPhotoId( self ): """ For this plugin, photoId is always composed of location-building-floor-room.jpg """ pass def __hasFreeText( self, freeTextList ): # OR for freeText in freeTextList: freeText = freeText.lower() if self.__hasOneFreeText( freeText ): return True return False def __hasOneFreeText( self, freeText ): # Look for freeText in all string and int attributes for attrName in dir( self ): if attrName[0] == '_': continue attrType = eval( 'self.' + attrName + '.__class__.__name__' ) if attrType == 'str': attrVal = eval( 'self.' + attrName ) if attrVal.lower().find( freeText ) != -1: return True # Look for freeText in equipment if self.__hasEquipment( [ freeText ] ): return True # Look for freeText in responsible if self.responsibleId != None: user = self.getResponsible(); if freeText in user.getFullName().lower() or freeText in user.getEmail().lower(): return True # Look for freeText in custom attributes for value in self.customAtts.itervalues(): if value and ( freeText in value.lower() ): return True # Not found return False @staticmethod def __goodCapacity( val1, val2, minCapacity = None ): # Difference in capacity less than 20% if val1 < 1: val1 = 1 if not minCapacity: return abs( val1 - val2 ) / float( val1 ) <= 0.2 else: return val2 > val1 @classmethod def __attrSpecialEqual( cls, attrName, exampleVal, candidateVal, **kwargs ): if attrName in ( 'guid', 'locationName', 'name', 'photoId', 'needsAVCSetup' ): return True # Skip by stating they match if attrName in ( 'responsibleId', 'responsibleID' ): return exampleVal == candidateVal # Just exact string matching if attrName[0:7] == 'verbose': return True if attrName.find( 'capacity' ) != -1: minCapacity = kwargs.get( 'minCapacity' ) return cls.__goodCapacity( exampleVal, candidateVal, minCapacity ) if attrName == 'customAtts': # Check if all values in exampleVal are contained # in corresponding values of candidateVal for k, v in exampleVal.iteritems(): if v: # If value is specified if candidateVal.get( k ) == None: # Candidate does not have the attribute return False if not ( v in candidateVal[k] ): # Candidate's attribute value does not match example return False return True return None def __hasEquipment( self, requiredEquipmentList ): iHave = self.getEquipment() for reqEq in requiredEquipmentList: have = False for myEq in iHave: if myEq.lower().find( reqEq.lower() ) != -1: have = True break if not have: return False return True def getBookingUrl(self): """ Room booking URL """ return str(urlHandlers.UHRoomBookingBookingForm.getURL(target=self)) def getDetailsUrl(self): """ Room details URL """ return str(urlHandlers.UHRoomBookingRoomDetails.getURL(target=self)) def getMarkerDescription(self): """ Room description for the map marker """ infos = [] if self.capacity: infos.append("%s %s" % (self.capacity , _("people"))) if self.isReservable: infos.append(_("public")) else: infos.append(_("private")) if self.resvsNeedConfirmation: infos.append(_("needs confirmation")) else: infos.append(_("auto-confirmation")) if self.needsAVCSetup: infos.append(_("video conference")) return ", ".join(infos) def getTipPhotoURL(self): """ URL of the tip photo of the room """ from MaKaC.webinterface.urlHandlers import UHRoomPhoto photoId = self._doGetPhotoId() if not photoId: photoId = "NoPhoto" return str(UHRoomPhoto.getURL(photoId)) def getIsAutoConfirm(self): """ Has the room auto-confirmation of schedule? """ return not self.resvsNeedConfirmation locationName = property( getLocationName, setLocationName )
## 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_location import Location, MapAspect from MaKaC.plugins.RoomBooking.default.factory import Factory aspects = [ {'id': 0, 'name':'Meyrin', 'centerLatitude': 46.23456689405093, 'centerLongitude': 6.046686172485352, 'topLeftLatitude': '46.225660710473136', 'topLeftLongitude': '6.030035018920898', 'bottomRightLatitude': '46.2434716324829', 'bottomRightLongitude': '6.063294410705566', 'zoomLevel':15, 'defaultOnStartup': True}, {'id': 1, 'name':'PREVESSIN', 'centerLatitude': 46.259051447415175, 'centerLongitude': 6.057773351931246, 'topLeftLatitude': '46.2501492379416', 'topLeftLongitude': '6.041107177734375', 'bottomRightLatitude': '46.26795221179669', 'bottomRightLongitude': '6.074366569519043', 'zoomLevel':15, 'defaultOnStartup': False}, {'id': 2, 'name':'POINT 1', 'centerLatitude': 46.23573201283012, 'centerLongitude': 6.054509639707248, 'topLeftLatitude': '46.23350564968721', 'topLeftLongitude': '6.050344705581665', 'bottomRightLatitude': '46.23795828565159', 'bottomRightLongitude': '6.058659553527832', 'zoomLevel':17, 'defaultOnStartup': False}, {'id': 3, 'name':'POINT 2', 'centerLatitude': 46.25115822762375, 'centerLongitude': 6.020456314054172, 'topLeftLatitude': '46.24893249040227', 'topLeftLongitude': '6.016291379928589', 'bottomRightLatitude': '46.253383874525866', 'bottomRightLongitude': '6.024606227874756', 'zoomLevel':17, 'defaultOnStartup': False}, {'id': 4, 'name':'POINT 5', 'centerLatitude': 46.30958858268458, 'centerLongitude': 6.077267646724067, 'topLeftLatitude': '46.30736521774798', 'topLeftLongitude': '6.073100566864014', 'bottomRightLatitude': '46.31181185731005', 'bottomRightLongitude': '6.081415414810181', 'zoomLevel':17, 'defaultOnStartup': False}, {'id': 5, 'name':'POINT 6', 'centerLatitude': 46.29345231426436, 'centerLongitude': 6.1115119456917455, 'topLeftLatitude': '46.29122829396059', 'topLeftLongitude': '6.107347011566162', 'bottomRightLatitude': '46.295676244254715', 'bottomRightLongitude': '6.115661859512329', 'zoomLevel':17, 'defaultOnStartup': False}, {'id': 6, 'name':'POINT 8', 'centerLatitude': 46.24158691675184, 'centerLongitude': 6.097038745847385, 'topLeftLatitude': '46.2393607911537', 'topLeftLongitude': '6.092873811721802', 'bottomRightLatitude': '46.24381295202931', 'bottomRightLongitude': '6.101188659667969', 'zoomLevel':17, 'defaultOnStartup': False}, ] DBMgr.getInstance().startRequest() Factory.getDALManager().connect() location = Location.parse('CERN') for aspectData in aspects: aspect = MapAspect() aspect.updateFromDictionary(aspectData) location.addAspect(aspect) DBMgr.getInstance().endRequest()
'bottomRightLatitude': '46.295676244254715', 'bottomRightLongitude': '6.115661859512329', 'zoomLevel': 17, 'defaultOnStartup': False }, { 'id': 6, 'name': 'POINT 8', 'centerLatitude': 46.24158691675184, 'centerLongitude': 6.097038745847385, 'topLeftLatitude': '46.2393607911537', 'topLeftLongitude': '6.092873811721802', 'bottomRightLatitude': '46.24381295202931', 'bottomRightLongitude': '6.101188659667969', 'zoomLevel': 17, 'defaultOnStartup': False }, ] DBMgr.getInstance().startRequest() Factory.getDALManager().connect() location = Location.parse('CERN') for aspectData in aspects: aspect = MapAspect() aspect.updateFromDictionary(aspectData) location.addAspect(aspect) DBMgr.getInstance().endRequest()
class Room( Persistent, RoomBase ): """ ZODB specific implementation. For documentation of methods see base class. """ __dalManager = Factory.getDALManager() vcList = [] def __init__(self): RoomBase.__init__( self ) self.customAtts = PersistentMapping() self.avaibleVC = [] def setAvailableVC(self, avc): self.avaibleVC = avc def getAvailableVC(self): try: return self.avaibleVC except: self.avaibleVC = [] return self.avaibleVC @staticmethod def getRoot(): return Room.__dalManager.getRoot(_ROOMS) def insert( self ): """ Documentation in base class. """ RoomBase.insert( self ) roomsBTree = Room.getRoot() # Ensure ID if self.id == None: # Maximum ID + 1 if len( roomsBTree ) > 0: self.id = roomsBTree.maxKey() + 1 else: self.id = 1 # Can not use maxKey for 1st record in a tree # Add self to the BTree roomsBTree[self.id] = self def update( self ): """ Documentation in base class. """ RoomBase.update( self ) # Check Simba mailing list listName = self.customAtts.get( 'Simba List' ) if listName: from MaKaC.user import GroupHolder groups = GroupHolder().match( { 'name': listName }, forceWithoutExtAuth = True ) if not groups: groups = GroupHolder().match( { 'name': listName } ) if not groups: self.customAtts['Simba List'] = 'Error: unknown mailing list' self._p_changed = True def remove( self ): """ Documentation in base class. """ RoomBase.remove( self ) roomsBTree = Room.getRoot() del roomsBTree[self.id] from MaKaC.user import AvatarHolder AvatarHolder().invalidateRoomManagerIdList() # Typical actions @staticmethod def getRooms( *args, **kwargs ): """ Documentation in base class. """ roomsBTree = Room.getRoot() location = kwargs.get( 'location' ) if kwargs.get( 'allFast' ) == True: return [ room for room in roomsBTree.values() if room.isActive and (not location or room.locationName == location) ] if kwargs.get( 'reallyAllFast' ) == True: return [ room for room in roomsBTree.values() if (not location or room.locationName == location) ] if len( kwargs ) == 0: ret_lst = [] for room in roomsBTree.values(): ret_lst.append( room ) roomID = kwargs.get( 'roomID' ) roomName = kwargs.get( 'roomName' ) roomEx = kwargs.get( 'roomExample' ) resvEx = kwargs.get( 'resvExample' ) freeText = kwargs.get( 'freeText' ) available = kwargs.get( 'available' ) countOnly = kwargs.get( 'countOnly' ) minCapacity = kwargs.get( 'minCapacity' ) location = kwargs.get( 'location' ) ownedBy = kwargs.get( 'ownedBy' ) customAtts = kwargs.get( 'customAtts' ) # responsibleID = kwargs.get( 'responsibleID' ) ret_lst = [] counter = 0 if roomID != None: return roomsBTree.get( roomID ) if roomName != None: for room in roomsBTree.itervalues(): if room.name == roomName: if location == None or room.locationName == location: return room return None for room in roomsBTree.itervalues(): # Apply all conditions ========= if location != None: if room.locationName != location: continue if roomEx != None: if not qbeMatch( roomEx, room, Room.__attrSpecialEqual, minCapacity = minCapacity ): continue if not room.__hasEquipment( roomEx.getEquipment() ): continue if freeText != None: if not room.__hasFreeText( freeText.split() ): continue if resvEx != None: resvEx.room = room aval = room.isAvailable( resvEx ) if aval != available: continue if ownedBy != None: if not room.isOwnedBy( ownedBy ): continue if customAtts is not None: if not hasattr(room, "customAtts"): continue discard = False for condition in customAtts: attName = condition["name"] allowEmpty = condition.get("allowEmpty", False) filter = condition.get("filter", None) if not attName in room.customAtts: discard = True break elif not allowEmpty and str(room.customAtts[attName]).strip() == "": discard = True break elif not filter(room.customAtts[attName]): discard = True break if discard: continue # All conditions are met: add room to the results counter += 1 if not countOnly: ret_lst.append( room ) #print "Found %d rooms." % counter if countOnly: return counter else: return ret_lst # Statistics ==================================== @staticmethod def countRooms( *args, **kwargs ): """ Documentation in base class. """ kwargs['countOnly'] = True return Room.getRooms( **kwargs ) @staticmethod def getNumberOfRooms( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) return Room.countRooms( location = location ) @staticmethod def getNumberOfActiveRooms( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) room = Factory.newRoom() room.isActive = True return Room.countRooms( roomExample = room, location = location ) @staticmethod def getNumberOfReservableRooms( *args, **kwargs ): """ Documentation in base class. """ location = kwargs.get( 'location', Location.getDefaultLocation().friendlyName ) room = Factory.newRoom() room.isReservable = True room.isActive = True return Room.countRooms( roomExample = room, location = location ) def getLocationName( self ): #from MaKaC.plugins.RoomBooking.default.factory import Factory #return Factory.locationName return self._locationName def setLocationName( self, locationName ): self._locationName = locationName def savePhoto( self, photoPath ): filePath = Config.getInstance().getRoomPhotosDir() fileName = self._doGetPhotoId( force = True ) + ".jpg" try: os.makedirs( filePath ) except: pass fullPath = os.path.join( filePath, fileName ) f = open( fullPath, "wb" ) f.write( photoPath.file.read() ) f.close() def saveSmallPhoto( self, photoPath ): filePath = Config.getInstance().getRoomSmallPhotosDir() fileName = self._doGetPhotoId( force = True ) + ".jpg" try: os.makedirs( filePath ) except: pass fullPath = os.path.join( filePath, fileName ) f = open( fullPath, "wb" ) f.write( photoPath.file.read() ) f.close() # ==== Private =================================================== def _getSafeLocationName( self ): if self.locationName == None: return None s = "" for i in xrange( 0, len( self.locationName ) ): code = ord( self.locationName[i] ) if ( code in xrange( ord( 'a' ), ord( 'z' ) + 1 ) ) or \ ( code in xrange( ord( 'A' ), ord( 'Z' ) + 1 ) ) or \ ( code in xrange( ord( '0' ), ord( '9' ) + 1 ) ): # Valid s += self.locationName[i] else: s += '_' # Replace all other characters with underscore return s def _doGetPhotoId( self, force = False ): photoId = "%s-%s-%s-%s" % ( str( self._getSafeLocationName() ), str( self.building ).strip(), str( self.floor ).strip(), str( self.roomNr ).strip() ) filePath = Config.getInstance().getRoomPhotosDir() fileName = photoId + ".jpg" fullPath = os.path.join( filePath, fileName ) from os.path import exists if exists( fullPath ) or force: return photoId else: return None def _doSetPhotoId( self ): """ For this plugin, photoId is always composed of location-building-floor-room.jpg """ pass def __hasFreeText( self, freeTextList ): # OR for freeText in freeTextList: freeText = freeText.lower() if self.__hasOneFreeText( freeText ): return True return False def __hasOneFreeText( self, freeText ): # Look for freeText in all string and int attributes for attrName in dir( self ): if attrName[0] == '_': continue attrType = eval( 'self.' + attrName + '.__class__.__name__' ) if attrType == 'str': attrVal = eval( 'self.' + attrName ) if attrVal.lower().find( freeText ) != -1: return True # Look for freeText in equipment if self.__hasEquipment( [ freeText ] ): return True # Look for freeText in responsible if self.responsibleId != None: user = self.getResponsible(); if freeText in user.getFullName().lower() or freeText in user.getEmail().lower(): return True # Look for freeText in custom attributes for value in self.customAtts.itervalues(): if value and ( freeText in value.lower() ): return True # Not found return False @staticmethod def __goodCapacity( val1, val2, minCapacity = None ): # Difference in capacity less than 20% if val1 < 1: val1 = 1 if not minCapacity: return abs( val1 - val2 ) / float( val1 ) <= 0.2 else: return val2 > val1 @classmethod def __attrSpecialEqual( cls, attrName, exampleVal, candidateVal, **kwargs ): if attrName in ( 'guid', 'locationName', 'name', 'photoId', 'needsAVCSetup' ): return True # Skip by stating they match if attrName in ( 'responsibleId', 'responsibleID' ): return exampleVal == candidateVal # Just exact string matching if attrName[0:7] == 'verbose': return True if attrName.find( 'capacity' ) != -1: minCapacity = kwargs.get( 'minCapacity' ) return cls.__goodCapacity( exampleVal, candidateVal, minCapacity ) if attrName == 'customAtts': # Check if all values in exampleVal are contained # in corresponding values of candidateVal for k, v in exampleVal.iteritems(): if v: # If value is specified if candidateVal.get( k ) == None: # Candidate does not have the attribute return False if not ( v in candidateVal[k] ): # Candidate's attribute value does not match example return False return True return None def __hasEquipment( self, requiredEquipmentList ): iHave = self.getEquipment() for reqEq in requiredEquipmentList: have = False for myEq in iHave: if myEq.lower().find( reqEq.lower() ) != -1: have = True break if not have: return False return True
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 getRoot(): return Factory.getDALManager().getRoot(_EQUIPMENT_LIST)
class RoomBlocking(Persistent, RoomBlockingBase): __dalManager = Factory.getDALManager() def __init__(self): RoomBlockingBase.__init__(self) self.blockedRooms = PersistentList() self.allowed = PersistentList() @staticmethod def getRoot(): return RoomBlocking.__dalManager.getRoot(_ROOMBLOCKING) @staticmethod def getTotalCount(): return len(RoomBlocking.getRoot()['Blockings']) @staticmethod def getAll(): return [block for block in RoomBlocking.getRoot()['Blockings'].itervalues()] @staticmethod def getById(id): blockingsBTree = RoomBlocking.getRoot()['Blockings'] return blockingsBTree.get(id) @staticmethod def getByOwner(owner): idx = RoomBlocking.getRoot()['Indexes']['OwnerBlockings'] return idx.get(owner.id, []) @staticmethod def getByRoom(room, active=-1): idx = RoomBlocking.getRoot()['Indexes']['RoomBlockings'] blocks = idx.get(str(room.guid), []) return [block for block in blocks if active is block.active or active == -1] @staticmethod def getByDate(date): idx = RoomBlocking.getRoot()['Indexes']['DayBlockings'] return list(idx.getObjectsInDay(date)) @staticmethod def getByDateSpan(begin, end): idx = RoomBlocking.getRoot()['Indexes']['DayBlockings'] return list(idx.getObjectsInDays(begin, end)) def addAllowed(self, principal): """ Add a principal (Avatar, Group, CERNGroup or a RoomBlockingPrincipal) to the blocking's ACL """ if isinstance(principal, RoomBlockingPrincipal): self.allowed.append(principal) else: self.allowed.append(RoomBlockingPrincipal(principal)) def delAllowed(self, principal): """ Remove a principal (Avatar, Group, CERNGroup or a RoomBlockingPrincipal) from the blocking's ACL """ if isinstance(principal, RoomBlockingPrincipal): self.allowed.remove(principal) else: self.allowed.remove(RoomBlockingPrincipal(principal)) def getBlockedRoom(self, room): """ Get the BlockedRoom object for a certain room """ for br in self.blockedRooms: if br.roomGUID == str(room.guid): return br return None def notifyOwners(self): """ Send emails to all room owners who need to approve blockings. Every owner gets only a single email, containing all the affected rooms. """ notify_owners = defaultdict(list) for rb in self.blockedRooms: if rb.active is None and not rb.notificationSent: notify_owners[rb.room.responsibleId].append(rb) rb.notificationSent = True emails = [] for ownerId, roomBlockings in notify_owners.iteritems(): emails += RoomBlockingNotification.requestConfirmation(AvatarHolder().getById(ownerId), self, roomBlockings) for email in emails: GenericMailer.send(GenericNotification(email)) def insert(self): """ Insert a new blocking in the database, index it and reject colliding bookings """ self.createdDT = datetime.datetime.now() # Save blockingsBTree = RoomBlocking.getRoot()['Blockings'] # Ensure ID if self.id is None: # Maximum ID + 1 if len(blockingsBTree) > 0: self.id = blockingsBTree.maxKey() + 1 else: self.id = 1 # Can not use maxKey for 1st record in a tree # Add self to the BTree blockingsBTree[self.id] = self self._index() # Reject colliding bookings. for rb in self.blockedRooms: if rb.active: rb.approve(sendNotification=False) self.notifyOwners() def remove(self): """ Remove a blocking from the database """ self._unindex() blockingsBTree = RoomBlocking.getRoot()['Blockings'] del blockingsBTree[self.id] def update(self): """ Re-index a blocking and notify owners which haven't been notified before """ self._unindex() self._index() self.notifyOwners() def _index(self): # Update room => room blocking index (it maps to the BlockedRoom objects) rbi = RoomBlocking.getRoot()['Indexes']['RoomBlockings'] for rb in self.blockedRooms: roomBlockings = rbi.get(rb.roomGUID) if roomBlockings is None: roomBlockings = PersistentList() rbi[rb.roomGUID] = roomBlockings roomBlockings.append(rb) # Update owner => room blocking index obi = RoomBlocking.getRoot()['Indexes']['OwnerBlockings'] roomBlockings = obi.get(self._createdBy) if roomBlockings is None: roomBlockings = PersistentList() obi[self._createdBy] = roomBlockings roomBlockings.append(self) # Update day => room blocking index cdbi = RoomBlocking.getRoot()['Indexes']['DayBlockings'] cdbi.indexConf(self) def _unindex(self): # Update room => room blocking index rbi = RoomBlocking.getRoot()['Indexes']['RoomBlockings'] for rb in self.blockedRooms: roomBlockings = rbi.get(rb.roomGUID) if roomBlockings is not None and rb in roomBlockings: roomBlockings.remove(rb) # Update owner => room blocking index obi = RoomBlocking.getRoot()['Indexes']['OwnerBlockings'] roomBlockings = obi.get(self._createdBy) if roomBlockings is not None and self in roomBlockings: roomBlockings.remove(self) # Update day => room blocking index cdbi = RoomBlocking.getRoot()['Indexes']['DayBlockings'] cdbi.unindexConf(self) def __repr__(self): return '<RoomBlocking(%r, %r, %s)>' % (self.id, self.blockedRooms, self.allowed)
class Test( object ): dalManager = Factory.getDALManager() @staticmethod def do(): # Set equipment Test.dalManager.connect() em = Factory.getEquipmentManager() saved = ['a ', 'bbb', 'c' ] em.setPossibleEquipment( saved ) Test.dalManager.commit() Test.dalManager.disconnect() # Get equipment Test.dalManager.connect() loaded = em.getPossibleEquipment() assert( loaded == saved ) Test.dalManager.disconnect() @staticmethod def getRoomsByExample(): Test.dalManager.connect() # By ID room = RoomBase.getRooms( roomID = 176 ) assert( room.name == '4-1-021' ) # By other attributes roomEx = Factory.newRoom() roomEx.site = 'prevessin' roomEx.comments = 'res' rooms = RoomBase.getRooms( roomExample = roomEx ) assert( len( rooms ) == 8 ) # 20 roomEx = Factory.newRoom() roomEx.capacity = 20 rooms = RoomBase.getRooms( roomExample = roomEx ) assert( len( rooms ) == 26 ) roomEx = Factory.newRoom() roomEx.isReservable = True roomEx.setEquipment( [ 'Video projector', 'Wireless' ] ) rooms = RoomBase.getRooms( roomExample = roomEx ) assert( len( rooms ) == 33 ) Test.dalManager.disconnect() @staticmethod def getRoomsByFreeText(): Test.dalManager.connect() rooms = RoomBase.getRooms( freeText = 'meyrin vrvs' ) # 78828 assert( len( rooms ) == 12 ) Test.dalManager.disconnect() @staticmethod def getRoomsByExampleDemo(): Test.dalManager.connect() roomEx = Factory.newRoom() roomEx.building = 513 roomEx.capacity = 20 rooms = CrossLocationQueries.getRooms( roomExample = roomEx ) for room in rooms: print "=============================" print room Test.dalManager.disconnect() @staticmethod def stats(): Test.dalManager.connect() print "All rooms: %d" % RoomBase.getNumberOfRooms() print "Active rooms: %d" % RoomBase.getNumberOfActiveRooms() print "Reservable rooms: %d" % RoomBase.getNumberOfReservableRooms() Test.dalManager.disconnect() @staticmethod def getAvailableRooms(): Test.dalManager.connect() from datetime import datetime roomEx = Factory.newRoom() roomEx.isActive = True roomEx.isReservable = True resvEx = Factory.newReservation() resvEx.startDT = datetime( 2006, 12, 01, 10 ) resvEx.endDT = datetime( 2006, 12, 14, 15 ) resvEx.repeatability = 0 # Daily rooms = RoomBase.getRooms( \ roomExample = roomEx, resvExample = resvEx, available = True ) for room in rooms: print "\n=======================================\n" print room Test.dalManager.disconnect()
def handler(prefix, path): path = posixpath.join('/', prefix, path) ContextManager.destroy() clearCache() # init fossil cache logger = Logger.get('httpapi') if request.method == 'POST': # Convert POST data to a query string queryParams = dict((key, value.encode('utf-8')) for key, value in request.form.iteritems()) query = urllib.urlencode(queryParams) else: # Parse the actual query string queryParams = dict((key, value.encode('utf-8')) for key, value in request.args.iteritems()) query = request.query_string dbi = DBMgr.getInstance() dbi.startRequest() minfo = HelperMaKaCInfo.getMaKaCInfoInstance() if minfo.getRoomBookingModuleActive(): Factory.getDALManager().connect() apiKey = get_query_parameter(queryParams, ['ak', 'apikey'], None) cookieAuth = get_query_parameter(queryParams, ['ca', 'cookieauth'], 'no') == 'yes' signature = get_query_parameter(queryParams, ['signature']) timestamp = get_query_parameter(queryParams, ['timestamp'], 0, integer=True) noCache = get_query_parameter(queryParams, ['nc', 'nocache'], 'no') == 'yes' pretty = get_query_parameter(queryParams, ['p', 'pretty'], 'no') == 'yes' onlyPublic = get_query_parameter(queryParams, ['op', 'onlypublic'], 'no') == 'yes' onlyAuthed = get_query_parameter(queryParams, ['oa', 'onlyauthed'], 'no') == 'yes' oauthToken = 'oauth_token' in queryParams # Get our handler function and its argument and response type hook, dformat = HTTPAPIHook.parseRequest(path, queryParams) if hook is None or dformat is None: raise NotFound # Disable caching if we are not just retrieving data (or the hook requires it) if request.method == 'POST' or hook.NO_CACHE: noCache = True ak = error = result = None ts = int(time.time()) typeMap = {} responseUtil = ResponseUtil() try: used_session = None if cookieAuth: used_session = session if not used_session.user: # ignore guest sessions used_session = None if apiKey or oauthToken or not used_session: if not oauthToken: # Validate the API key (and its signature) ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp, path, query) if enforceOnlyPublic: onlyPublic = True # Create an access wrapper for the API key's user aw = buildAW(ak, onlyPublic) else: # Access Token (OAuth) at = OAuthUtils.OAuthCheckAccessResource() aw = buildAW(at, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() is None: cacheKey = normalizeQuery(path, query, remove=('_', 'ak', 'apiKey', 'signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) else: cacheKey = normalizeQuery(path, query, remove=('_', 'signature', 'timestamp', 'nc', 'nocache', 'oa', 'onlyauthed')) if signature: # in case the request was signed, store the result under a different key cacheKey = 'signed_' + cacheKey else: # We authenticated using a session cookie. if Config.getInstance().getCSRFLevel() >= 2: token = request.headers.get('X-CSRF-Token', get_query_parameter(queryParams, ['csrftoken'])) if used_session.csrf_protected and used_session.csrf_token != token: raise HTTPAPIError('Invalid CSRF token', 403) aw = AccessWrapper() if not onlyPublic: aw.setUser(used_session.user) userPrefix = 'user-' + used_session.user.getId() + '_' cacheKey = userPrefix + normalizeQuery(path, query, remove=('_', 'nc', 'nocache', 'ca', 'cookieauth', 'oa', 'onlyauthed', 'csrftoken')) # Bail out if the user requires authentication but is not authenticated if onlyAuthed and not aw.getUser(): raise HTTPAPIError('Not authenticated', 403) addToCache = not hook.NO_CACHE cache = GenericCache('HTTPAPI') cacheKey = RE_REMOVE_EXTENSION.sub('', cacheKey) if not noCache: obj = cache.get(cacheKey) if obj is not None: result, extra, ts, complete, typeMap = obj addToCache = False if result is None: # Perform the actual exporting res = hook(aw) if isinstance(res, tuple) and len(res) == 4: result, extra, complete, typeMap = res else: result, extra, complete, typeMap = res, {}, True, {} if result is not None and addToCache: ttl = HelperMaKaCInfo.getMaKaCInfoInstance().getAPICacheTTL() cache.set(cacheKey, (result, extra, ts, complete, typeMap), ttl) except HTTPAPIError, e: error = e if e.getCode(): responseUtil.status = e.getCode() if responseUtil.status == 405: responseUtil.headers['Allow'] = 'GET' if request.method == 'POST' else 'POST'
def getRoot(): return Factory.getDALManager().getRoot(_CUSTOM_ATTRIBUTES_LIST)
def handler(req, **params): ContextManager.destroy() logger = Logger.get('httpapi') path, query = req.URLFields['PATH_INFO'], req.URLFields['QUERY_STRING'] if req.method == 'POST': # Convert POST data to a query string queryParams = dict(req.form) for key, value in queryParams.iteritems(): queryParams[key] = [str(value)] query = urllib.urlencode(remove_lists(queryParams)) else: # Parse the actual query string queryParams = parse_qs(query) dbi = DBMgr.getInstance() dbi.startRequest() minfo = HelperMaKaCInfo.getMaKaCInfoInstance() if minfo.getRoomBookingModuleActive(): Factory.getDALManager().connect() mode = path.split('/')[1] apiKey = get_query_parameter(queryParams, ['ak', 'apikey'], None) signature = get_query_parameter(queryParams, ['signature']) timestamp = get_query_parameter(queryParams, ['timestamp'], 0, integer=True) no_cache = get_query_parameter(queryParams, ['nc', 'nocache'], 'no') == 'yes' pretty = get_query_parameter(queryParams, ['p', 'pretty'], 'no') == 'yes' onlyPublic = get_query_parameter(queryParams, ['op', 'onlypublic'], 'no') == 'yes' # Disable caching if we are not exporting if mode != 'export': no_cache = True # Get our handler function and its argument and response type func, dformat = HTTPAPIHook.parseRequest(path, queryParams) if func is None or dformat is None: raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND ak = error = result = None ts = int(time.time()) typeMap = {} try: # Validate the API key (and its signature) ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp, path, query) if enforceOnlyPublic: onlyPublic = True # Create an access wrapper for the API key's user aw = buildAW(ak, req, onlyPublic) # Get rid of API key in cache key if we did not impersonate a user if ak and aw.getUser() is None: cache_key = normalizeQuery(path, query, remove=('ak', 'apiKey', 'signature', 'timestamp', 'nc', 'nocache')) else: cache_key = normalizeQuery(path, query, remove=('signature', 'timestamp', 'nc', 'nocache')) if signature: # in case the request was signed, store the result under a different key cache_key = 'signed_' + cache_key obj = None addToCache = True cache = GenericCache('HTTPAPI') cache_key = RE_REMOVE_EXTENSION.sub('', cache_key) if not no_cache: obj = cache.get(cache_key) if obj is not None: result, extra, ts, complete, typeMap = obj addToCache = False if result is None: # Perform the actual exporting res = func(aw, req) if isinstance(res, tuple) and len(res) == 4: result, extra, complete, typeMap = res else: result, extra, complete, typeMap = res, {}, True, {} if result is not None and addToCache: ttl = HelperMaKaCInfo.getMaKaCInfoInstance().getAPICacheTTL() cache.set(cache_key, (result, extra, ts, complete, typeMap), ttl) except HTTPAPIError, e: error = e if e.getCode(): req.status = e.getCode() if req.status == apache.HTTP_METHOD_NOT_ALLOWED: req.headers_out[ 'Allow'] = 'GET' if req.method == 'POST' else 'POST'