def test_createSession(self): test_url = '/conference/{wcksafe}/session' # Ensure default profile is created url = '/profile' res = urlfetch.fetch(self.urlbase + url, method='GET') self.assertEqual(res.status_code, 200) # Create conference and get websafe key conf = Conference( name='Test Conference', organizerUserId=json.loads(res.content)['mainEmail'] ) wck = conf.put() sleep(0.1) wcksafe = wck.urlsafe() test_url = test_url.format(wcksafe=wcksafe) # Ensure no sessions exist yet self.assertEqual(0, len(Session.query().fetch(5))) # Test endpoint params = { 'name': 'TEST Session', 'date': '2015-8-10', 'startTime': '9:10', 'conferenceKey': wcksafe } response = urlfetch.fetch(self.urlbase + test_url, payload=json.dumps(params), method=urlfetch.POST, headers={'Content-Type': 'application/json'}) self.assertEqual(response.status_code, 200)
def test_getSessionsBySpeaker(self): # Create two conferences conf = Conference(name='Test Conference A') wckA = conf.put() wckAsafe = wckA.urlsafe() conf = Conference(name='Test Conference B') wckB = conf.put() wckBsafe = wckB.urlsafe() # Add 4 sessions among conferences with three having particular speaker propsA = {'name': 'Monkey Business', 'date': date(2015,8,8), 'parent': wckA, 'conferenceKey': wckAsafe, 'typeOfSession': 'lecture', 'startTime': time(18,15)} propsB = {'name': 'Monkey Business', 'date': date(2015,9,12), 'parent': wckB, 'conferenceKey': wckBsafe, 'typeOfSession': 'workshop', 'startTime': time(12,15)} # Add two to first created conference Session(speaker=['Sarah', 'Frodo'], **propsA).put() Session(speaker=['Frodo'], **propsA).put() # Add two to second created conference Session(speaker=['Saruman'], **propsB).put() Session(speaker=['Gollum', 'Frodo'], **propsB).put() # Test the endpoint url = '/speaker/{0}'.format('Frodo') res = urlfetch.fetch(self.urlbase + url) self.assertEqual(res.status_code, 200) self.assertEqual(len(json.loads(res.content)['items']), 3)
def getMarketableConferences(self, request): """Find the conferences that is in progress and not yet fully booked""" mtoday = datetime.now().date() # Get conferences with seats available conf_inprogress_seatsavail = set( Conference.query().filter( Conference.seatsAvailable > 0).fetch(keys_only=True)) # Get conferences where open end date is more or equal than today conf_inprogress_enddate = set( Conference.query().filter(Conference.endDate >= mtoday).fetch( keys_only=True)) # Get conferences where open start date is less than or equal to today conf_inprogress_startdate = set( Conference.query().filter(Conference.startDate <= mtoday).fetch( keys_only=True)) # return a set with conferences common in all queries conf_inprogress_keys = conf_inprogress_seatsavail\ & conf_inprogress_startdate\ & conf_inprogress_enddate conf_inprogress = ndb.get_multi(conf_inprogress_keys) return MarketableConferenceForms(items=[ MarketableConferenceForm(name=getattr(data, "name"), topics=getattr(data, "topics"), city=getattr(data, "city"), seatsAvailable=getattr(data, "seatsAvailable"), endDate=str(getattr(data, "endDate"))) for data in conf_inprogress])
def match_or_send_to_waiting_room(call, schedule): # Refreshing database object flush_transaction() call.reload() if call.matched: other = call.conference.call_set.exclude(pk=call.pk)[0] data = send_to_conference_room(call, schedule, other, initial=False) if data: return data matchcall = find_match(schedule, call) if matchcall: conf = Conference() conf.maxcapacity = 2 conf.datecreated = as_date(schedule) conf.save() call.conference = conf call.matched = True call.save() matchcall.conference = conf matchcall.matched = True matchcall.save() data = send_to_conference_room(call, schedule, matchcall, initial=True) if data: return data if call.user.profile.any_match: call.user.profile.any_match = False call.user.profile.save() return render_to_response("twilioresponse.xml", { 'say' :"We are very sorry - We could not find you a match today, but tomorrow we'll do our best to compensate it! We wish you an awesome day!", 'hangup' : True }) #Check if we have exceeded the waiting redirect limits elif call.retries >= REDIRECT_LIMIT: # The user has reached the limit of redials, so hang up logger.debug("LIMIT RETRIES - Ask to try to match with any person") any_match = "We could not find any matches. If you'd like us to try to match you with Anyone please press any number now." goodbye = "We wish you an Amazing day! Good bye!" return render_to_response("twilioresponse.xml", { 'any_match' :any_match, 'schedule': schedule, 'hangup': True, 'goodbye' : goodbye }) call.retries = call.retries + 1 call.save() # Send user to private conference (Conferencename=Username) or send them to the waiting room they were at return send_to_waiting_room( HOLD_LIMIT , schedule , call.user.username , False , "Please bare with us - we'll find the best match for you!")
def _createConferenceObject(self, conferenceForm): """Create conference object, returns ConferenceForm.""" user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') data = formToDict(conferenceForm, exclude=('websafeKey', 'organizerDisplayName')) # add default values for those missing for df in DEFAULTS: if data[df] in (None, []): data[df] = DEFAULTS[df] # add organizerUserId before checking the required fields data['organizerUserId'] = user_id = getUserId(user) # check required fields for key in Conference.required_fields_schema: if not data[key]: raise endpoints.BadRequestException("Conference '%s' field required" % key) # convert dates from strings to Date objects; set month based on start_date try: data['startDate'] = datetime.strptime(data['startDate'][:10], "%Y-%m-%d").date() data['endDate'] = datetime.strptime(data['endDate'][:10], "%Y-%m-%d").date() except (TypeError, ValueError): raise endpoints.BadRequestException("Invalid date format. Please use 'YYYY-MM-DD'") if data['startDate'] > data['endDate']: raise endpoints.BadRequestException("start date must be before end date") data['month'] = data['startDate'].month # set seatsAvailable to be same as maxAttendees on creation if data["maxAttendees"] > 0: data["seatsAvailable"] = data["maxAttendees"] # generate Profile Key based on user ID and Conference # ID based on Profile key get Conference key from ID p_key = ndb.Key(Profile, user_id) c_id = Conference.allocate_ids(size=1, parent=p_key)[0] c_key = ndb.Key(Conference, c_id, parent=p_key) data['key'] = c_key # create Conference, send email to organizer confirming # creation of Conference & return (modified) ConferenceForm conf = Conference(**data) conf.put() taskqueue.add( params={'email': user.email(), 'conferenceInfo': repr(conferenceForm)}, url='/tasks/send_confirmation_email' ) return conf.toForm()
def get(self, conf_handle = None): request = self.wsgi_request response = self.wsgi_response c = self.context if conf_handle: conf_id = Conference.get_id_from_url_title(conf_handle) c.conf = Conference.get(conf_id) if c.conf: return self.render_stuff('/index.html') self.set_body("Please enter a valid conference handle..") return self.render()
def _createConferenceObject(self, request): """Create or update Conference object, returning ConferenceForm/request.""" # preload necessary data items user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') user_id = getUserId(user) if not request.name: raise endpoints.BadRequestException("Conference 'name' field required") # copy ConferenceForm/ProtoRPC Message into dict data = {field.name: getattr(request, field.name) for field in request.all_fields()} del data['websafeKey'] del data['organizerDisplayName'] # add default values for those missing (both data model & outbound Message) for df in DEFAULTS: if data[df] in (None, []): data[df] = DEFAULTS[df] setattr(request, df, DEFAULTS[df]) # convert dates from strings to Date objects; set month based on start_date if data['startDate']: data['startDate'] = datetime.strptime(data['startDate'][:10], "%Y-%m-%d").date() data['month'] = data['startDate'].month else: data['month'] = 0 if data['endDate']: data['endDate'] = datetime.strptime(data['endDate'][:10], "%Y-%m-%d").date() # set seatsAvailable to be same as maxAttendees on creation # both for data model & outbound Message if data["maxAttendees"] > 0: data["seatsAvailable"] = data["maxAttendees"] setattr(request, "seatsAvailable", data["maxAttendees"]) # make Profile Key from user ID p_key = ndb.Key(Profile, user_id) # allocate new Conference ID with Profile key as parent c_id = Conference.allocate_ids(size=1, parent=p_key)[0] # make Conference key from ID c_key = ndb.Key(Conference, c_id, parent=p_key) data['key'] = c_key data['organizerUserId'] = request.organizerUserId = user_id # create Conference & return (modified) ConferenceForm conference = Conference(**data) conference.put() return request
def get(self, id = None): request = self.wsgi_request response = self.wsgi_response c = self.context response.headers['content-type'] = 'application/json' if id is None: #get all the confs confs = [x.to_json(encode = False) for x in Conference.get_all()] self.set_body(json.dumps(confs)) else: conf = Conference.get(id) self.set_body(conf.to_json()) return self.render()
def getConferencesNotSoldOutInAmsterdam(self, request): """ Only show conferences in Amsterdam that are not sold out """ in_amsterdam = Conference.query( Conference.city == 'Amsterdam') not_sold_out = Conference.query( Conference.seatsAvailable > 0) confs = self._intersectQueries(in_amsterdam, not_sold_out) names = self._getConferenceOrganisers(confs) return ConferenceForms( items=[self._copyConferenceToForm( conf, names[conf.organizerUserId]) for conf in confs])
def filterPlayground(self, request): """Filter Playground""" q = Conference.query() q = q.filter(Conference.city == "London") q = q.filter(Conference.topics == "Medical Innovations") q = q.filter(Conference.month == 6) return ConferenceForms(items=[self._copyConferenceToForm(conf, "") for conf in q])
def queryConferences(self, request): """Queries conferences for results.""" conferences = Conference.query() return ConferenceForms( items = [self._copyConferenceToForm(conf, "")\ for conf in conferences])
def cache_announcement(): """ Create Announcement & assign to memcache; used by memcache cron job & putAnnouncement(). :return: announcement string """ confs = Conference.query(ndb.AND( Conference.seatsAvailable <= 5, Conference.seatsAvailable > 0) ).fetch(projection=[Conference.name]) client = memcache.Client() if confs: # If there are almost sold out conferences, # format announcement and set it in memcache announcement = ANNOUNCEMENT_TPL % ( ', '.join(conf.name for conf in confs)) client.add(MEMCACHE_ANNOUNCEMENTS_KEY, announcement) else: # If there are no sold out conferences, # delete the memcache announcements entry announcement = "" client.delete(MEMCACHE_ANNOUNCEMENTS_KEY) return announcement
def getConferencesWithSpace(self, request): ''' Get a list of conferences with seats available. ''' q = Conference.query() q = q.filter(Conference.seatsAvailable > 0) q = q.order(Conference.seatsAvailable) return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q])
def filterPlayground(self, request): """Return conferences based on query.""" # define query conferences = Conference.query() # filter by city field = "city" operator = "=" value = "London" f = ndb.FilterNode(field, operator, value) conferences = conferences.filter(f) # add another filter, by topic field = "topics" operator = "=" value = "Medical Innovations" f = ndb.FilterNode(field, operator, value) conferences = conferences.filter(f) # and filter by month conferences = conferences.filter(Conference.maxAttendees > 10) # order by conference name conferences = conferences.order(Conference.name) # return set of ConferenceForm objects per Conference return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in conferences] )
def _createConferenceObject(self, request): """Create or update Conference object, returning ConferenceForm/request.""" user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') user_id = getUserId(user) if not request.name: raise endpoints.BadRequestException("Conference 'name' field required") data = {field.name: getattr(request, field.name) for field in request.all_fields()} del data['websafeKey'] del data['organizerDisplayName'] for df in DEFAULTS: if data[df] in (None, []): data[df] = DEFAULTS[df] setattr(request, df, DEFAULTS[df]) if data['startDate']: data['startDate'] = datetime.strptime(data['startDate'][:10], "%Y-%m-%d").date() data['month'] = data['startDate'].month else: data['month'] = 0 if data['endDate']: data['endDate'] = datetime.strptime(data['endDate'][:10], "%Y-%m-%d").date() if data["maxAttendees"] > 0: data["seatsAvailable"] = data["maxAttendees"] p_key = ndb.Key(Profile, user_id) c_id = Conference.allocate_ids(size=1, parent=p_key)[0] c_key = ndb.Key(Conference, c_id, parent=p_key) data['key'] = c_key data['organizerUserId'] = request.organizerUserId = user_id Conference(**data).put() taskqueue.add(params={'email': user.email(), 'conferenceInfo': repr(request)}, url='/tasks/send_confirmation_email' ) return request
def post(self, id = None): request = self.wsgi_request response = self.wsgi_response c = self.context param_dict = dict( title = request.params.title, conf_id = request.params.conf_id, desc = request.params.desc, venue = request.params.venue, talk_type = request.params.talk_type, start_date = parse(request.params.start_date), end_date = parse(request.params.end_date), duration = request.params.duration, speaker_title = request.params.speaker_title) content = param_dict session = Session(**param_dict) session = session.save() conf = Conference.get(session.conf_id) if conf: conf.add_session(session) self.set_body(session.to_json()) response.headers['content-type'] = 'application/json' return self.render()
def filterPlayground(self, request): q = Conference.query() # simple filter usage: # q = q.filter(Conference.city == "San Francisco") # advanced filter building and usage field = "city" operator = "=" value = "London" field2 = "topics" operator2 = "=" value2 = "Medical Innovations" f = ndb.query.FilterNode(field, operator, value) g = ndb.query.FilterNode(field2, operator2, value2) q = q.filter(f) q = q.filter(g) q = q.order(Conference.name) q = q.filter(Conference.maxAttendees > 30) #r = q.filter(g) # TODO # add 2 filters: # 1: city equals to London # 2: topic equals "Medical Innovations" return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q] )
def _createSessionObject(self, request): """Create or update Session object, returning SessionForm/request.""" user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') user_id = getUserId(user) if not request.name: raise endpoints.BadRequestException("Session 'name' field required") # copy SessionForm/ProtoRPC Message into dict data = {field.name: getattr(request, field.name) for field in request.all_fields()} del data['websafeKey'] # del data['organizerDisplayName'] # add default values for those missing (both data model & outbound Message) for df in DEFAULTS_SESSION: if data[df] in (None, []): data[df] = DEFAULTS_SESSION[df] setattr(request, df, DEFAULTS_SESSION[df]) # Getting a TEMP conference key for the moment q = Conference.query() cons = q.get() c_key = cons.key s_id = Session.allocate_ids(size=1, parent=c_key)[0] s_key = ndb.Key(Session, s_id, parent=c_key) data['key'] = s_key Session(**data).put() return request
def testUnregisterFromConference(self): """ TEST: Unregister user for selected conference.""" self.initDatabase() # verify database fixture self.login() prof = ndb.Key(Profile, self.getUserId()).get() conf = Conference.query(Conference.name == 'room #2').get() assert conf and conf.seatsAvailable == 1 and len(prof.conferenceKeysToAttend) == 0, \ "This shouldn't fail. Maybe someone messed with database fixture" prof.conferenceKeysToAttend.append(conf.key) prof.put() container = CONF_GET_REQUEST.combined_message_class( websafeConferenceKey=conf.key.urlsafe(), ) # unregister conference r = self.api.unregisterFromConference(container) # re-fetch profile and conference, then check if user was properly unregistered prof = prof.key.get() conf = conf.key.get() assert r.data, 'Returned an invalid response' assert len(prof.conferenceKeysToAttend) == 0, "Failed to remove conference from user's conferenceKeysToAttend" assert conf.seatsAvailable == 2, 'Failed to increment available seats'
def getSessionsBySpeaker(self, request): """Given a speaker, return all sessions given by this particular speaker, across all conferences""" # make sure user is logged in user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException("Authorization required") user_id = getUserId(user) # get speaker value from form request sessionSpeakerOfInterest = request.speaker # store all session objects across all conferences where this speaker is presenting all_sessions = [] # query for conferences conferences = Conference.query() for conf in conferences: ck = getattr(conf, "key") wsck = ck.urlsafe() # For each conference, get Sessions for the Conference filtered by Speaker sessions = Session.query(Session.websafeConferenceKey == wsck) sessions = sessions.filter(Session.speaker == sessionSpeakerOfInterest) for session in sessions: all_sessions.append(session) # return sessions in all conferences return SessionForms(items=[self._copySessionToForm(session) for session in all_sessions])
def getConferencesByPopularity(self, request): """Return conferences by popularity""" # fetch conference from key conf = Conference.query().fetch() # Check that conference exists if not conf: raise endpoints.NotFoundException("No conference found with this key: %s" % request.websafeConferenceKey) conf_list = [] for c in conf: count = Profile.query().filter(Profile.conferenceKeysToAttend == c.key.urlsafe()).count() conf_list.append({"conf": c, "count": count}) conf_list = sorted(conf_list, key=lambda conf: conf["count"], reverse=True) # need to fetch organiser displayName from profiles # get all keys and use get_multi for speed organisers = [(ndb.Key(Profile, c.organizerUserId)) for c in conf] profiles = ndb.get_multi(organisers) # put display names in a dict for easier fetching names = {} for profile in profiles: names[profile.key.id()] = profile.displayName # return individual ConferenceForm object per Conference return ConferenceForms( items=[self._copyConferenceToForm(c["conf"], names[c["conf"].organizerUserId]) for c in conf_list] )
def filterPlayground(self, request): q = Conference.query() # simple filter usage: # q = q.filter(Conference.city == "London") # advanced filter building and usage # field = "city" # operator = "=" # value = "London" # f = ndb.query.FilterNode(field, operator, value) # q = q.filter(f) # TODO # add 2 filters: # 1: city equals to London q = q.filter(Conference.city == "London") # 2: topic equals "Medical Innovations" q = q.filter(Conference.topics == "Medical Innovations") q.order(Conference.name) q = q.filter(Conference.maxAttendees > 8) return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q] )
def getSessionsByDateAndCity(self, request): """Return all sessions in given city on given date.""" # Expect date in format YYYY-MM-DD try: date = datetime.strptime(request.date, '%Y-%m-%d').date() except ValueError: raise endpoints.BadRequestException('Invalid date - ' 'must be in YYYY-MM-DD format') # get just the keys for conferences in city conf_keys = Conference.query(Conference.city==request.city)\ .fetch(keys_only=True) # get all sessions for conferences in city, filter on date # (Guido's advice in http://stackoverflow.com/questions/12440333/ # ndb-query-on-multiple-parents-given-a-cursor) # need to do multiple ancestor queries, do asynchronously futures = [] for c_key in conf_keys: futures.append(Session.query(ancestor=c_key)\ .filter(Session.date==date)\ .fetch_async()) sess = [] for f in futures: sess.extend(f.get_result()) return SessionForms( items=[self._copySessionToForm(s) for s in sess] )
def getNotRegisteredWishlist(self, request): """Returns all sesssions on a users wishlist where the user is not registered for the conference.""" prof = self._getProfileFromUser() wishlist = prof.wishList wishlist_keys = [ndb.Key(urlsafe=wish) for wish in wishlist] # Get conferences attending. attending_wsk = prof.conferenceKeysToAttend attending_keys = [ndb.Key(urlsafe=wsk) for wsk in attending_wsk] # Get the parent conferenes of all sessions in the query. conf_keys = [session_key.parent() for session_key in wishlist_keys] # Query confreences with wishlist session as child. q = Conference.query() q = q.filter(Conference.key.IN([key for key in conf_keys])) # Query conferences that do not include those being attended. for key in attending_keys: q = q.filter(Conference.key != key) return ConferenceForms( items=[self._copyConferenceToForm(conference, "") for conference in q])
def testGetAnnouncement(self): """ TEST: Return Announcement from memcache.""" self.initDatabase() # Verify database fixture confs = Conference.query(ndb.AND( Conference.seatsAvailable <= 5, Conference.seatsAvailable > 0) ).fetch() assert len(confs) == 1 and confs[0].name == 'room #2' and None == memcache.get(MEMCACHE_ANNOUNCEMENTS_KEY), \ "This shouldn't fail. Maybe someone messed with database fixture" # Since an announcement was never set `getAnnouncement()` should return an empty StringMessage response = self.api.getAnnouncement(message_types.VoidMessage()) assert response.data == '', 'Expected an empty string since no announcement was set' # set announcement request = webapp2.Request.blank('/crons/set_announcement') response = request.get_response(main.app) # validate http status assert response.status_int == 204, 'Invalid response expected 204 but got %d' % response.status_int # Verify room #2 is listed in the announcement response = self.api.getAnnouncement(message_types.VoidMessage()) assert 'room #2' in response.data, 'Announcement is missing a conference'
def get(self, confid, secret): """Download all speakers and proposals for a conference""" # Super-Reviewers committee = [] if confid == 'droidcon-2016': committee = ['*****@*****.**', '*****@*****.**'] # get conference conference = Conference.get_by_id(confid) # check if the provided secret is correct if conference.secret != secret: self.response.http_status_message(403) return speakers = Speaker.query() proposals = Proposal.query(ancestor=conference.key) reviews = Review.query() speakers_dict = [dict(s.to_dict(), **dict(id=s.key.id())) for s in speakers] proposals_dict = [] # create a fast lookup table - reviews by parent reviews_by_parent = {} for r in reviews: parent = r.key.parent() rlist = reviews_by_parent[parent] if rlist is None: rlist = [] rlist.append(r) reviews_by_parent[parent] = rlist # crete a fast lookup table - speaker by key speakers_by_id = {} for s in speakers: speakers_by_key[s.key] = s for p in proposals: p_dict = p.to_dict() p_dict['id'] = p.key.id() p_r = {} p_sum = 0 for r in reviews_by_parent[p.key]: p_r[r.key.id()] = r.to_dict() if r.rating: if r.key.id() in committee: # double the rating! p_sum = p_sum + r.rating p_sum = p_sum + r.rating s = speakers_by_key[p.speaker] if s is not None: p_dict['speaker-email'] = s.email p_dict['speaker-name'] = s.name p_dict['speaker-surname'] = s.surname if s.rating: p_sum = p_sum + s.rating p_dict['reviews'] = p_r p_dict['rating'] = p_sum proposals_dict.append(p_dict) self.response.headers['Content-Type'] = 'application/json' obj = { 'speakers': speakers_dict, 'proposals': proposals_dict, } self.response.out.write(json.dumps(obj, cls=DatastoreEncoder))
def _cacheAnnouncement(): """Create Announcement & assign to memcache; used by memcache cron job & putAnnouncement(). """ confs = Conference.query(ndb.AND( Conference.seatsAvailable <= 5, Conference.seatsAvailable > 0) ).fetch(projection=[Conference.name]) if confs: print "We are going to set the announcement" # If there are almost sold out conferences, # format announcement and set it in memcache announcement = '%s %s' % ( 'Last chance to attend! The following conferences ' 'are nearly sold out:', ', '.join(conf.name for conf in confs)) memcache.set(MEMCACHE_ANNOUNCEMENTS_KEY, announcement) print "The announcement has been set." else: print "We are going to delete the announcement from memcache" # If there are no sold out conferences, # delete the memcache announcements entry announcement = "" memcache.delete(MEMCACHE_ANNOUNCEMENTS_KEY) print "The announcement has been deleted from memcache" return announcement
def _getQuery(self, request): """Return formatted query from the submitted filters.""" q = Conference.query() inequality_filter, filters = self._formatFilters(request.filters) # If exists, sort on inequality filter first if not inequality_filter: q = q.order(Conference.name) else: q = q.order(ndb.GenericProperty(inequality_filter)) q = q.order(Conference.name) for filtr in filters: if filtr["field"] in ["month", "maxAttendees"]: filtr["value"] = int(filtr["value"]) formatted_query = ndb.query.FilterNode(filtr["field"], filtr["operator"], filtr["value"]) q = q.filter(formatted_query) return q
def testGetProfile(self): """ TEST: Get user's profile """ self.initDatabase() try: # only logged in users have a profile self.api.getProfile(message_types.VoidMessage()) assert False, 'UnauthorizedException should of been thrown' except UnauthorizedException: pass # login and retrieve the profile self.login() prof = ndb.Key(Profile, self.getUserId()).get() # Add conferences to conferenceKeysToAttend so we can verify the returned keys are web safe keys = Conference.query().fetch(keys_only=True) prof.conferenceKeysToAttend = keys prof.put() r = self.api.getProfile(message_types.VoidMessage()) assert r.mainEmail == '*****@*****.**', 'Returned an invalid user profile' assert len(r.conferenceKeysToAttend) > 0, 'Returned an invalid number of conference keys' # verify that all keys are urlsafe websafeKeys = [key.urlsafe() for key in keys] for websafeKey in r.conferenceKeysToAttend: assert websafeKey in websafeKeys, 'Returned an invalid key'
def filterPlayground(self, request): q = Conference.query() # advanced filter building and usage field = "city" operator = "=" value = "London" f = ndb.query.FilterNode(field, operator, value) q = q.filter(f) # TODO # add 2 filters: # 1: city equals to London # 2: topic equals "Medical Innovations" field = "topics" operation = "=" value = "Medical Innovations" f = ndb.query.FilterNode(field, operator, value) q = q.filter(f) q = q.order(Conference.maxAttendees) return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q] )
def getConferencesCreated(self, request): """Return conferences created by user.""" # make sure user is authed user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') user_id = getUserId(user) # create ancestor query for all key matches for this user confs = Conference.query(ancestor=ndb.Key(Profile, user_id)) prof = ndb.Key(Profile, user_id).get() # return set of ConferenceForm objects per Conference return ConferenceForms(items=[ self._copyConferenceToForm(conf, getattr(prof, 'displayName')) for conf in confs ])
def getUpcomingConferences(self, request): """Get upcoming conferences""" conferences = Conference.query(Conference.startDate >= datetime.today()) \ .order(Conference.startDate) \ .fetch(limit=10) # limit number of conferences to 10 organizer_keys = [ndb.Key(Profile, conference.organizerUserId) for conference in conferences] profiles = ndb.get_multi(organizer_keys) organizer_dict = {profile.key.id(): profile.displayName for profile in profiles} return ConferenceForms( items=[self._copyConferenceToForm(conference, organizer_dict[conference.organizerUserId]) for conference in conferences] )
def getConferencesCreated(self, requset): user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization Required') #Make Profile Key p_key = ndb.Key(Profile, getUserID(user)) #create ancestor query for this user conferences = Conference.query(ancestor=p_key) # get the user profile and display name prof = p_key.get() displayName = getattr(prof, 'displayName') # return set of ConferenceForm objects per Conference return ConferenceForms(items=[ self._copyConferenceToForm(conf, displayName) for conf in conferences ])
def getNextConference(self, request): """Get next conference to start from user's current time""" # Query conferences q = Conference.query() # filter away past conferences q = q.filter(Conference.startDate >= datetime.today()) # order by date q = q.order(Conference.startDate) # get earliest conference conf = q.get() if not conf: raise endpoints.NotFoundException( 'No conference found') # get organizer profile for display name prof = conf.key.parent().get() # return ConferenceForm return self._copyConferenceToForm(conf, getattr(prof, 'displayName'))
def getWebSafeKeys(self, request): """Get websafe keys for all conferences""" # Query all conferences for their websafe keys items = [] query = Conference.query() for conf in query.fetch(): temp = conf.key.parent().get() items.append([conf.name, conf.key.urlsafe(), temp.displayName]) # Create and send message with all the keys, names, and organizers keys = [] wsk = WebSafeKeys() for i in items: temp = WebSafeKeyQuery(name=i[0], key=i[1], organizer=i[2]) keys.append(temp) wsk.items = keys wsk.check_initialized() return wsk
def getlowReg(self, request): """Return conferences that are less than half full.""" # create list to stored conferences to be returned and then # fetch all conferences confsToReturn = [] confs = Conference.query() # loop through all conferences adding matching entries to the list for c in confs: maxAttendees = c.maxAttendees seatsAvailable = c.seatsAvailable if seatsAvailable > maxAttendees / 2: confsToReturn += [c] return ConferenceForms(items=[ self._copyConferenceToForm( conf, getattr(conf.key.parent().get(), 'displayName')) for conf in confsToReturn ])
def getNoSessions(self, request): """Return conferences that have no sessions.""" # create list to stored conferences to be returned and then # fetch all conferences confsToReturn = [] confs = Conference.query() # loop through all conferences adding matching conferences # with no sessions for c in confs: sessions = Session.query(ancestor=c.key) if sessions.count() == 0: confsToReturn += [c] return ConferenceForms(items=[ self._copyConferenceToForm( conf, getattr(conf.key.parent().get(), 'displayName')) for conf in confsToReturn ])
def filterPlayground(self, request): q = Conference.query() # simple filter usage: # q = q.filter(Conference.city == "Paris") q = q.filter(Conference.city == "London") #q = q.filter(Conference.topics == "Medical Innovations") #q = q.filter(Conference.month == 6) # TODO # add 2 filters: # 1: city equals to London # 2: topic equals "Medical Innovations" return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q])
def getConferencesCreated(self, request): """Return conferences created by user.""" user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') p_key = ndb.Key(Profile, getUserId(user)) conferences = Conference.query(ancestor=p_key) prof = p_key.get() displayName = getattr(prof, 'displayName') return ConferenceForms( items=[self._copyConferenceToForm(conf, displayName) for conf in conferences] )
def getConferencesCreated(self, request): """Return conferences created by user.""" # Getting and Verifying current user user = getUser() # get the user_id (email) user_id = getUserId(user) # create ancestor query for all key matches for this user conferences = Conference.query(ancestor=ndb.Key(Profile, user_id)) prof = ndb.Key(Profile, user_id).get() # return one or many ConferenceForm objects return ConferenceForms( items = [self._copyConferenceToForm( conf, getattr(prof, 'displayName')) for conf in conferences])
def filterPlayground(self, request): q = Conference.query() # city equals to London q = q.filter(Conference.city == "London") # order by conference name q = q.order(Conference.name) # advanced filter building and usage # field = "city" # operator = "=" # value = "London" # f = ndb.query.FilterNode(field, operator, value) # q = q.filter(f) return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q])
def filterPlayground(self, request): q = Conference.query() # TODO # add 2 filters: # 1: city equals to London q = q.filter(Conference.city == "London") # 2: topic equals "Medical Innovations" q = q.filter(Conference.topics == "Medical Innovations") # 3: order by conference name q = q.order(Conference.name) # first for month of June q = q.filter(Conference.maxAttendees > 10) return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q])
def getConferencesByTopic(self, request): """Return all conferences on a given topic""" confs = Conference.query() confs = confs.filter(Conference.topics == request.topic) # get organizers organisers = [ndb.Key(Profile, conf.organizerUserId) for conf in confs] profiles = ndb.get_multi(organisers) # put display names in a dict for easier fetching names = {} for profile in profiles: names[profile.key.id()] = profile.displayName # return set of ConferenceForm objects per Conference return ConferenceForms(items=[self._copyConferenceToForm( conf, names[conf.organizerUserId])\ for conf in confs] )
def get_conferences_created(self, request): """Return conferences created by user.""" # make sure user is authed user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') # make profile key p_key = ndb.Key(Profile, get_user_id(user)) # create ancestor query for this user conferences = Conference.query(ancestor=p_key) # get the user profile and display name prof = p_key.get() displayName = getattr(prof, 'displayName') # return set of ConferenceForm objects per Conference return ConferenceForms(items=[ self._copy_conference_to_form(conf, displayName) for conf in conferences ])
def filterPlayground(self, request): """Return conferences created by user.""" # make sure user is authed user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') #delete everything in users wishlist prof = self._getProfileFromUser() # get user Profile #print "******* %s" ,prof.wishListSessionKeys prof.wishListSessionKeys[:] = [] conferences = Conference.query() conferences = conferences.filter(Conference.city == "London") # return set of ConferenceForm objects per Conference return ConferenceForms(items=[ self._copyConferenceToForm(conf, "") for conf in conferences ])
def getConferencesCreated(self, request): """Return conferences created by user.""" # make sure user is authed user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') user_id = getUserId(user) # Create an instance of a Key for an id(user email) of a kind(Profile) p_key = ndb.Key(Profile, user_id) # query conferences with ancestor user conferences = Conference.query(ancestor=p_key) # get the user profile and display name prof = p_key.get() displayName = getattr(prof, 'displayName') # return set of ConferenceForm objects per Conference return ConferenceForms( items=[self._copyConferenceToForm(conf, displayName) for conf in conferences] )
def get_user_id(user, id_type="email"): """ Get user id :param user: :param id_type: :return: """ if id_type == "email": return user.email() if id_type == "oauth": """A workaround implementation for getting userid.""" auth = os.getenv('HTTP_AUTHORIZATION') bearer, token = auth.split() token_type = 'id_token' if 'OAUTH_USER_ID' in os.environ: token_type = 'access_token' url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?%s=%s' % (token_type, token)) user = {} wait = 1 for i in range(3): resp = urlfetch.fetch(url) if resp.status_code == 200: user = json.loads(resp.content) break elif resp.status_code == 400 and 'invalid_token' in resp.content: url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?%s=%s' % ('access_token', token)) else: time.sleep(wait) wait += i return user.get('user_id', '') if id_type == "custom": # implement your own user_id creation and getting algorythm # this is just a sample that queries datastore for an existing profile # and generates an id if profile does not exist for an email profile = Conference.query(Conference.organizerUserId == user.email()) if profile: return profile.id() else: return str(uuid.uuid1().get_hex())
def getSessionByCity(self, request): """Given a city, return all sessions across all conferences in the city.""" # get all the conferences in the city c = Conference.query() c = c.filter(Conference.city == request.city) conferences = c.fetch() logging.debug(conferences) # get all the websafeConferenceKeys for the conferences confWebKeys = [conf.key.urlsafe() for conf in conferences] logging.debug(confWebKeys) # find all the sessions matching any of the conferences that matched the city, across all conferences sessions = Session.query() sessions = sessions.filter(Session.webSafeConfId.IN(confWebKeys)) # return set of SessionForm objects one per Session return SessionForms( items=[self._copySessionToForm(sesn) for sesn in sessions])
def _cacheAnnouncement(): """Create Announcement & assign to memcache. """ confs = Conference.query( ndb.AND(Conference.seatsAvailable <= 5, Conference.seatsAvailable > 0)).fetch( projection=[Conference.name]) if confs: # If there are almost sold out conferences, # format announcement and set it in memcache announcement = '%s %s' % ( 'Last chance to attend! The following conferences ' 'are nearly sold out:', ', '.join(conf.name for conf in confs)) memcache.set(MEMCACHE_ANNOUNCEMENTS_KEY, announcement) else: # If there are no sold out conferences, # delete the memcache announcements entry announcement = "" memcache.delete(MEMCACHE_ANNOUNCEMENTS_KEY) return announcement
def _cacheAnnouncement(): """Create Announcement & assign to memcache; used by memcache cron job & putAnnouncement(). """ confs = Conference.query( ndb.AND(Conference.seatsAvailable <= 5, Conference.seatsAvailable > 0)).fetch( projection=[Conference.name]) if confs: # If there are almost sold out conferences, # format announcement and set it in memcache announcement = ANNOUNCEMENT_TPL % (', '.join(conf.name for conf in confs)) memcache.set(MEMCACHE_ANNOUNCEMENTS_KEY, announcement) else: # If there are no sold out conferences, # delete the memcache announcements entry announcement = "" memcache.delete(MEMCACHE_ANNOUNCEMENTS_KEY) return announcement
def filterPlayground(self, request): q = Conference.query() # simple filter usage: q = q.filter(Conference.city == "London") q = q.filter(Conference.topics == "Medical Innovations") q = q.order(Conference.name) # advanced filter building and usage # field = "city" # operator = "=" # value = "London" # f = ndb.query.FilterNode(field, operator, value) # q = q.filter(f) # TODO # add 2 filters: # 1: city equals to London # 2: topic equals "Medical Innovations" return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q])
def getSessionByCity(self, request): """Returns all sessions for a given city, across all conferences""" # Create a list to hold all of the sessions found. results = [] # Create conference query conferences = Conference.query() # Filter conferences by city conferences = conferences.filter(Conference.city == request.city) # Create ancestor query to find session for each conference. for conf in conferences: # Create an ancestor query to get the sessions for this conference sessions = Session.query(ancestor=conf.key) # Add each session in the query to the results list for s in sessions: # print s.name results.append(s) # Return set of SessionForm objects return SessionForms( sessions=[self._copySessionToForm(s) for s in results])
def filterPlayground(self, request): q = Conference.query() # simple filter usage: # q = q.filter(Conference.city == "Paris") # advanced filter building and usage # field = "city" # operator = "=" # value = "London" # f = ndb.query.FilterNode(field, operator, value) # q = q.filter(f) q = q.filter(Conference.city == "London") q = q.filter(Conference.maxAttendees > 10) q = q.order(Conference.name) return ConferenceForms( items=[self._copyConferenceToForm(conf, "") for conf in q])
def _cacheAnnouncement(): confs = Conference.query( ndb.AND(Conference.seatsAvailable <= 5, Conference.seatsAvailable > 0)).fetch( projection=[Conference.name]) if confs: #announcement = '%s %s' % ( # 'Last chance to attend! The following conferences ' # 'are nearly sold out:', # ', '.join(conf.name for conf in confs)) #-------------------OR----------------------- announcement = ANNOUNCEMENT_TPL % (', '.join(conf.name for conf in confs)) memcache.set(MEMCACHE_ANNOUNCEMENTS_KEY, announcement) else: announcement = "" memcache.delete(MEMCACHE_ANNOUNCEMENTS_KEY) return announcement
def filterPlayground(self, request): q = Conference.query() # simple filter q = q.filter(Conference.city == "London") # Equivalent through ndb # field = "city" # operator = "=" # value = "London" # f = ndb.query.FilterNode(field, operator, value) # q = q.filter(f) q = q.filter(Conference.topics == "Medical Innovations") q = q.order(Conference.name) q = q.filter(Conference.maxAttendees > 10) return ConferenceForms( items=[self._copy_conference_to_form(conf, "") for conf in q])
def getRecentConferences(self, request): """Query for conferences in future 30 days""" today = datetime.now() one_month = timedelta(days=30) one_month = today - one_month c = Conference.query() c = c.filter(Conference.startDate >= one_month) # need to fetch organiser displayName from profiles # get all keys and use get_multi for speed organisers = [(ndb.Key(Profile, conf.organizerUserId)) for conf in c] profiles = ndb.get_multi(organisers) # put display names in a dict for easier fetching names = {} for profile in profiles: names[profile.key.id()] = profile.displayName # return individual ConferenceForm object per Conference return ConferenceForms( items=[self._copyConferenceToForm(conf, names[conf.organizerUserId]) for conf in c] )
def get_created(self, request): """ Return Conferences created by the requesting User :param request: Void RPC Message :return: ConferenceForms containing user-created ConferenceForm's """ if not isinstance(request, message_types.VoidMessage): raise endpoints.BadRequestException() # make sure user is auth'd user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') user_id = get_user_id(user) # create ancestor query for all key matches for this user confs = Conference.query(ancestor=ndb.Key(Profile, user_id)) prof = ndb.Key(Profile, user_id).get() # return set of ConferenceForm objects per Conference return ConferenceForms( items=[conf.to_form(getattr(prof, 'displayName')) for conf in confs] )
def _cacheAnnouncement(): """Create Announcement & assign to memcache; used by memcache cron job & putAnnouncement(). """ confs = Conference.query(ndb.AND( Conference.seatsAvailable <= 5, Conference.seatsAvailable > 0) ).fetch(projection=[Conference.name]) if confs: announcement = '%s %s' % ( 'Last chance to attend! The following conferences ' 'are nearly sold out:', ', '.join(conf.name for conf in confs)) memcache.set(MEMCACHE_ANNOUNCEMENTS_KEY, announcement) else: announcement = "" memcache.delete(MEMCACHE_ANNOUNCEMENTS_KEY) return announcement
def getConferenceAndSessionByKeyword(self, request): """Get conference and session by keyword.""" keyword = request.keyword # Pass all query, keyword, seleted field to function _keywordFinder() # get the result list back. all_c = Conference.query().fetch() field_c = ['name', 'description', 'topics'] c_list = self._keywordFinder(all_c, keyword, *field_c) all_s = Session.query().fetch() field_s = ['sessionName', 'highlights', 'conferenceBelongTo'] s_list= self._keywordFinder(all_s, keyword, *field_s) return ConferenceFormAndSessionForm( c_data=ConferenceForms( items=[self._copyConferenceToForm(c) for c in c_list] ), s_data=SessionForms( items=[self._copySessionToForm(s) for s in s_list] ) )