def settings(self, request): """Reads/writes config service location. Accessible only by admins.""" settings = common.ConfigSettings.fetch() or common.ConfigSettings() delta = {} if request.service_hostname is not None: delta['service_hostname'] = request.service_hostname if request.trusted_config_account is not None: try: delta['trusted_config_account'] = auth.Identity.from_bytes( request.trusted_config_account) except ValueError as ex: raise endpoints.BadRequestException( 'Invalid trusted_config_account %s: %s' % (request.trusted_config_account, ex.message)) changed = settings.modify(**delta) if changed: logging.warning('Updated config settings') settings = common.ConfigSettings.fetch() or settings return ConfigSettingsMessage( service_hostname=settings.service_hostname, trusted_config_account=(settings.trusted_config_account.to_bytes() if settings.trusted_config_account else None))
def _populate_rpc(message_class, entity_dict, field_map, name=None): if name is None: name = message_class.__name__ result = message_class() for field, (functor, required) in field_map.iteritems(): # "normal" case: fields match and all is well if field in entity_dict: # just pass the argument if no functor is supplied if functor is None: functor = lambda x: x value = entity_dict[field] # values of None are to be omitted if value is not None: value = functor(value) setattr(result, field, value) # ignore optional absent fields; raise exception for required absent fields elif required: raise endpoints.BadRequestException( '%s is missing required field %s.' % (name, field)) return result
def _createSpeakerObject(self, request): """Create or update a Speaker object""" user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') user_id = getUserId(user) if not request.name: raise endpoints.BadRequestException( "Speaker 'name' field required") data = { field.name: getattr(request, field.name) for field in request.all_fields() } s_id = Speaker.allocate_ids(size=1)[0] s_key = ndb.Key(Speaker, s_id) data['key'] = s_key Speaker(**data).put() return request
def user_add(self, request): try: u_obj = Users.objects.get(users_name=request.users_name, users_email=request.users_email) except Users.DoesNotExist: u = Users(users_name=request.users_name, users_lastname=request.users_lastname, users_firstname=request.users_firstname, users_email=request.users_email, users_password=request.users_password, users_path_local_avatar=request.users_path_local_avatar, users_path_web_avatar=request.users_path_web_avatar, users_time_zone=request.users_time_zone, users_birthday=str(request.users_birthday), users_sex=request.users_sex, fk_users_type=UsersType.objects.get(users_type_id=1), users_delete=0) u.save() u = Users.objects.get(users_email=request.users_email) return WebResponse(response='id %s' % str(u.users_id)) else: raise endpoints.BadRequestException('eMail %s exist!' % (request.users_email, ))
def list(self, request): """Provides a list of available tasks.""" state = request.state.name.lower() uses = sum( [request.name is not None, bool(request.tag), state != 'all']) if uses > 1: raise endpoints.BadRequestException( 'Only one of name, tag (1 or many) or state can be used.') # get the tasks items, cursor_str, sort, state = task_result.get_tasks( request.name, request.tag, request.cursor, request.limit, request.sort, state) return swarming_rpcs.TaskList( cursor=cursor_str, items=[ message_conversion.task_result_summary_from_dict( utils.to_json_encodable(item)) for item in items ], limit=request.limit, sort=sort, state=state)
def new_game(self, request): """Creates new game""" user = User.query(User.name == request.user_name).get() p_key = ndb.Key(User, user.name) c_id = Game.allocate_ids(size=1, parent=p_key)[0] c_key = ndb.Key(Game, c_id, parent=p_key) # check if user is registered if not user: raise endpoints.NotFoundException( 'A User with that name does not exist!') # register game in the datastore try: game = Game.new_game(user.key, c_key, user.name) except ValueError: raise endpoints.BadRequestException('Maximum must be greater ' 'than minimum!') # Use a task queue to update the average attempts remaining. # This operation is not needed to complete the creation of a new game # so it is performed out of sequence. # taskqueue.add(url='/tasks/cache_average_attempts') return game.to_form('Good luck playing hangman')
def _postToSparkpost(self, payload): """ Post to Sparkpost API. Return True/False status """ payload_json = json.dumps(payload) headers = { 'Authorization': SPARKPOST_SECRET, 'Content-Type': 'application/json', } url = 'https://api.sparkpost.com/api/v1/transmissions?num_rcpt_errors=3' try: result = urlfetch.Fetch(url, headers=headers, payload=payload_json, method=2) except: raise endpoints.BadRequestException('urlfetch error: Unable to POST to SparkPost') return False data = json.loads(result.content) # Determine status from SparkPost, return True/False if 'errors' in data: return False if data['results']['total_accepted_recipients'] != 1: return False return True
def create_game(user_name, misses_allowed): """Create a game""" user = User.get_by_name(user_name) secret_word = secret_word_generator() current_solution = ''.join(['_' for l in secret_word]) # Check if misses_allowed exists and if so make sure it's a number if misses_allowed: if not misses_allowed.isnumeric(): msg = 'Error, only numbers are allowed in misses_allowed' raise endpoints.BadRequestException(msg) else: misses_allowed = int(misses_allowed) else: misses_allowed = 5 game = Game.create_game(user=user.key, misses_allowed=misses_allowed, secret_word=secret_word, current_solution=current_solution) return game.game_state('A new game of Hangman has been created!')
def addSessionToWishlist(self, request): """Adds a session to a user's wishlist""" user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization required') # fetch and check session session = ndb.Key(urlsafe=request.websafeSessionKey).get() # check that session exists if not session: raise endpoints.NotFoundException( 'No session found with key: %s' % request.websafeSessionKey) # fetch profile prof = self._getProfileFromUser() # check if session already added to wishlist if session.key in prof.sessionWishlist: raise endpoints.BadRequestException( 'Session already saved to wishlist: %s' % request.websafeSessionKey) # append to user profile's wishlist prof.sessionWishlist.append(session.key) prof.put() return self._copySessionToForm(session)
def createArticle(self, request): """Create new Article object, returning ArticleForm/request.""" for required in ['title', 'content']: if not getattr(request, required): raise endpoints.BadRequestException( "Article '%s' field required" % required) # copy ArticleForm/ProtoRPC Message into dict data = { field.name: getattr(request, field.name) for field in request.all_fields() } if data['view'] == None: del data['view'] else: data['view'] = str(data['view']) author = self._getAuthorFromUser() data['authorName'] = author.displayName article_id = Article.allocate_ids(size=1, parent=author.key)[0] article_key = ndb.Key(Article, article_id, parent=author.key) data['key'] = article_key # create Article article_key = Article(**data).put() # send email to author confirming creation of Article taskqueue.add(params={ 'email': author.mainEmail, 'ArticleInfo': repr(request) }, url='/tasks/send_confirmation_email') return self._copyArticleToForm(article_key.get(), author=author)
def terminate(self, request): """Asks a bot to terminate itself gracefully. The bot will stay in the DB, use 'delete' to remove it from the DB afterward. This request returns a pseudo-taskid that can be waited for to wait for the bot to turn down. """ # TODO(maruel): Disallow a terminate task when there's one currently # pending or if the bot is considered 'dead', e.g. no contact since 10 # minutes. logging.info('%s', request) bot_key = bot_management.get_info_key(request.bot_id) get_or_raise(bot_key) # raises 404 if there is no such bot try: # Craft a special priority 0 task to tell the bot to shutdown. properties = task_request.TaskProperties( dimensions={u'id': request.bot_id}, execution_timeout_secs=0, grace_period_secs=0, io_timeout_secs=0) now = utils.utcnow() request = task_request.TaskRequest( created_ts=now, expiration_ts=now + datetime.timedelta(days=1), name='Terminate %s' % request.bot_id, priority=0, properties=properties, tags=['terminate:1'], user=auth.get_current_identity().to_bytes()) assert request.properties.is_terminate posted_request = task_request.make_request(request, acl.is_bot_or_admin()) except (datastore_errors.BadValueError, TypeError, ValueError) as e: raise endpoints.BadRequestException(e.message) result_summary = task_scheduler.schedule_request(posted_request) return swarming_rpcs.TerminateResponse( task_id=task_pack.pack_result_summary_key(result_summary.key))
def list_shelves(self, request): """Lists enabled or all shelves based on any shelf attribute.""" self.check_xsrf_token(self.request_state) if request.page_size <= 0: raise endpoints.BadRequestException( 'The value for page_size must be greater than 0.') query, sort_options, returned_fields = ( search_utils.set_search_query_options(request.query)) if not query: query = search_utils.to_query(request, shelf_model.Shelf) offset = search_utils.calculate_page_offset( page_size=request.page_size, page_number=request.page_number) search_results = shelf_model.Shelf.search( query_string=query, query_limit=request.page_size, offset=offset, sort_options=sort_options, returned_fields=returned_fields) total_pages = search_utils.calculate_total_pages( page_size=request.page_size, total_results=search_results.number_found) shelves_messages = [] for document in search_results.results: message = search_utils.document_to_message(document, shelf_messages.Shelf()) message.shelf_request = shelf_messages.ShelfRequest() message.shelf_request.urlsafe_key = document.doc_id message.shelf_request.location = message.location shelves_messages.append(message) return shelf_messages.ListShelfResponse( shelves=shelves_messages, total_results=search_results.number_found, total_pages=total_pages)
def _formatMultiFilters(self, filters): """Parse, check validity and format user supplied filters.""" formatted_filters = [] inequality_filters = [] for f in filters: filtr = { field.name: getattr(f, field.name) for field in f.all_fields() } try: filtr["field"] = FIELDS[filtr["field"]] filtr["operator"] = OPERATORS[filtr["operator"]] except KeyError: raise endpoints.BadRequestException( "Filter contains invalid field or operator.") # Every operation except "=" is an inequality if filtr["operator"] != "=": inequality_filters.append(filtr) else: formatted_filters.append(filtr) return (inequality_filters, formatted_filters)
def querySessionTime(self, request): """Return sessions given a conference object, time and type""" # get conference object from Datastore conf = self._getDataStoreObject(request.websafeConferenceKey) # query sessions using ancestor conf Key, order sessions by start time sessions = Session.query(ancestor=conf.key).order(Session.startTime) # filter sessions by time (before/after/equal certain time) if (request.operator and request.time): node = ndb.query.FilterNode( 'startTime', OPERATORS[request.operator], datetime(1970, 01, 01, request.time, 00)) sessions = sessions.filter(node) else: raise endpoints.BadRequestException("You need to define both " "operator and time") # only return session types that are not equal to what the user provided return SessionForms( items=[self._copySessionToForm(x) for x in sessions if x.sessionType != request.sessionType] )
def _createSpeakerObject(self, request): """Create or update Speaker object, returning SpeakerForm/request.""" # preload necessary data items user = endpoints.get_current_user() #check if logged in if not user: raise endpoints.UnauthorizedException('Authorization required') #check if the user specified a name if not request.name: raise endpoints.BadRequestException( "Speaker 'name' field required") data = { field.name: getattr(request, field.name) for field in request.all_fields() } #delete, doesn't exist in model del data['websafeKey'] Speaker(**data).put() return request
def heartbeat(self, request): """Heartbeat check-in for devices.""" if not request.device_id: raise endpoints.BadRequestException(_NO_DEVICE_ID_MSG) user_email = user_lib.get_user_email() device = device_model.Device.get(chrome_device_id=request.device_id) is_enrolled = False start_assignment = False if device: if device.enrolled: is_enrolled = True if device.assigned_user == user_email: if device.onboarded: device.loan_resumes_if_late(user_email) else: start_assignment = True else: device.loan_assign(user_email) start_assignment = True else: try: device = device_model.Device.create_unenrolled( request.device_id, user_email) except device_model.DeviceCreationError as e: raise endpoints.NotFoundException(str(e)) device.record_heartbeat() silent_onboarding = config_model.Config.get('silent_onboarding') return chrome_messages.HeartbeatResponse( is_enrolled=is_enrolled, start_assignment=start_assignment, silent_onboarding=silent_onboarding, )
def getConferenceSessionsByType(self, request): """Given a conference, return all sessions of a specified type (eg lecture, keynote, workshop)""" user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException( 'You must be logged in to call this method.') user_id = getUserId(user) conf_key = ndb.Key(urlsafe=request.websafeConferenceKey) # verify websafekey points to Conference entity. if conf_key.kind() != 'Conference': raise endpoints.BadRequestException( 'websafeKey must point to Conference entity.') sessions = Session.query(ancestor=conf_key) q = Session.query(ancestor=ndb.Key( urlsafe=request.websafeConferenceKey)) q = q.filter(request.type == Session.typeOfSession) return SessionForms( items=[self._copySessionToForm(sess) for sess in q])
def new_game(self, request): """Creates new game""" if 1 > request.attempts or request.attempts > 14: raise endpoints.BadRequestException( 'Attempts should not be less than 1 or ' 'greater than 14!') user = User.query(User.name == request.user_name).get() if not user: raise endpoints.NotFoundException( 'A User with that name does not exist!') try: target = self.pickaWord() game = Game.new_game(user.key, request.attempts, target[0], target[1], [ '{} created a new game'.format(user.name), ]) except: print 'mark 1: something wrong with creating a new game' # Use a task queue to update the average attempts remaining. # This operation is not needed to complete the creation of a new game # so it is performed out of sequence. taskqueue.add(url='/tasks/cache_average_attempts') return game.to_form('Good luck playing Hangman!')
def get_board(self, request): """One of the players, creates the game and gets the game-id and gives that ID to the other player in order to play between each other""" try: player = Player.query(Player.name == request.player_name).get() game = gameutils.get_by_urlsafe(request.urlsafe_key, Game) board = Board.query(Board.player == player.key and Board.game == game.key).get() if not board: raise endpoints.NotFoundException( 'The Players Board for the selected game is not found') gameutils.log_board_on_console(board) except ValueError: raise endpoints.BadRequestException( 'please verify the information ' 'of the second player') # Use a task queue to update the average attempts remaining. # This operation is not needed to complete the creation of a new game # so it is performed out of sequence. return StringMessage(message='Board Found and printed in the console'. format(request.player_name))
def _getKeyForSpeaker(self, request): """ This function gets the key for an existing speaker that has been requested. """ if not request.name: raise endpoints.BadRequestException("Speaker 'name' field \ required") # creates new key for Speaker spkr_key = Speaker().key # for all noted speakers, make a query notedSpeakersQuery = Speaker.query() # lists noted speakers notedSpeakers = [] for ns in notedSpeakersQuery: notedSpeakers.append(ns.name) # When no speaker is found with a name, a NotFoundException is raised. if request.name not in notedSpeakers: raise endpoints.NotFoundException( 'No speaker found with name: %s' % request.name) # Otherwise, have its key returned. else: spkr_key = Speaker.query(Speaker.name == request.name).get().key return spkr_key
def _format_filters(self, filters, QUERY_FIELDS): """Parse, check validity and format user supplied filters. Returns: equality_filters (list): All equality filters inequality_filters (map): Map with key = field, and value = list of filters for that field inequality_fields (set): Set of fields with at least one inequality filter """ equality_filters = [] inequality_filters = {} inequality_fields = set([]) for f in filters: filtr = {field.name: getattr(f, field.name) for field in f.all_fields()} # Get the real fields and operators try: filtr["field"] = QUERY_FIELDS[filtr["field"]] filtr["operator"] = QUERY_OPERATORS[filtr["operator"]] except KeyError: raise endpoints.BadRequestException("Filter contains invalid field or operator.") # Every operation except "=" is an inequality if filtr["operator"] != "=": f = filtr["field"] inequality_fields.add(f) if f not in inequality_filters: inequality_filters[f] = [] inequality_filters[f].append(filtr) else: equality_filters.append(filtr) return (equality_filters, inequality_filters, inequality_fields)
def CreateGame(self, newGame): currentUser = endpoints.get_current_user() user = UserInfo.query(UserInfo.user == currentUser).get(keys_only=True) if (user is None): raise endpoints.BadRequestException("User does not exist") newGame.host = currentUser newGame.currentRound = 1 newGame.submissions = [] newGame.status = 0 blackDeck = BlackCard.query(BlackCard.cardSetId.IN( newGame.cardSets)).fetch() whiteDeck = WhiteCard.query(WhiteCard.cardSetId.IN( newGame.cardSets)).fetch() random.shuffle(blackDeck) random.shuffle(whiteDeck) newGame.blackDeck = [blackCard.idNum for blackCard in blackDeck] newGame.whiteDeck = [whiteCard.idNum for whiteCard in whiteDeck] gameKey = newGame.put() player = Player() player.gameId = gameKey.id() player.user = currentUser player.hand = [] player.score = 0 player.position = -1 player.alert = NO_ALERTS player.isCzar = False player.put() return newGame
def GetWordData(cls, request, response, func): """Gets the information about a word from some source.""" word_list = request.get("word_list", '') if not word_list: raise endpoints.BadRequestException("No word list was specified") entity = WordList.get_by_id(word_list) if not entity: raise endpoints.NotFoundException( "Word list {} was not found".format(word_list)) words = entity.words futures = {} foundWords = [] notFoundWords = [] for word in words: futures[word] = func(word) for word in futures: try: futures[word].get_result() foundWords.append(word) except Exception as e: notFoundWords.append(word) message = str(e) if len(message) < 100: response.write( "<p>error when adding word {}: {}</p>".format( word, message)) else: response.write( "<p>error when adding word {}: error too big to display" .format(word)) response.write("<h1>Total Words Processed = {}</h1>".format( len(words))) response.write("<h2>Successfully Added = {}</h2>".format( len(foundWords))) response.write("<h2>Words with errors = {}</h2>".format( len(notFoundWords)))
def _createWishListObject(self, request): """Create or update Session object, returning SessionForm/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.session_key: raise endpoints.BadRequestException("'session_key' field required") data = {} # generate Profile Key based on user ID and Conference # ID based on Profile key get Conference key from ID u_key = ndb.Key(Profile, user_id) w_sid = WishList.allocate_ids(size=1, parent=u_key)[0] w_key = ndb.Key(WishList, w_sid, parent=u_key) data['key'] = w_key data['user_id'] = user_id data['session_key'] = request.session_key WishList(**data).put() return self._copyWishListToForm(w_key.get())
def getConferenceSessions(self, request): """Given a conference, return all sessions.""" # Ensure that user is authed user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException('Authorization Required') # Retrieve the Conference key try: c_key = ndb.Key(urlsafe=request.websafeConferenceKey) except Exception: raise endpoints.BadRequestException( 'The websafeConferenceKey given is invalid.') # Verify that the Conference exists conf = c_key.get() if not conf: raise endpoints.NotFoundException( 'No conference found for the key provided: %s' % request.websafeConferenceKey) # Store the Sessions that are ancestors of the Conference sessions = Session.query(ancestor=c_key) # Return a SessionForm for each Session return SessionForms(items=[ self._copyConferenceSessionToForm(sesh) for sesh in sessions ])
def _getSessionQuery(self, request, conferenceKey=False): """Return formatted query from the submitted filters.""" if conferenceKey: wsck = request.websafeConferenceKey c_key = ndb.Key(urlsafe=wsck) if c_key.kind() == 'Conference': # create ancestor query for all key matches for this conference s = Session.query(ancestor=c_key) else: raise endpoints.BadRequestException( "Could not return session query.\n" "conference key: %s" % wsck) else: s = Session.query() try: inequality_filter, filters = self._formatFilters(request.filters, filter_type='session') # If exists, sort on inequality filter first if not inequality_filter: s = s.order(Session.name) else: s = s.order(ndb.GenericProperty(inequality_filter)) s = s.order(Session.name) for filtr in filters: if filtr["field"] in ["duration"]: filtr["value"] = int(filtr["value"]) if filtr["field"] in ["startDateTime"]: filtr["value"] = datetime.strptime(filtr["value"], "%Y-%m-%d %H:%M:%S") formatted_query = ndb.query.FilterNode(filtr["field"], filtr["operator"], filtr["value"]) s = s.filter(formatted_query) except AttributeError: # filter is missing, return s without filter return s return s
def check_request(request): # Need to make sure these fields are present in the request required_fields = ['to', 'sender', 'subject', 'body'] email_fields = ['to', 'cc', 'bcc'] for req_field in required_fields: # Make sure the attribute is in the object # and is not none or empty string, else, raise exception attr = getattr(request, req_field, None) if not attr or attr is None or attr == "": message = "Nothing set for the %s field" % req_field logging.error(message) raise endpoints.BadRequestException(message) else: logging.info("Got field %s with value %s" % (req_field, attr)) for email_field in email_fields: # Verify that these address follow the format for e-mails # Some e-mail providers accept non valid addresses and some don't # Need to conform with least common denominator attr = getattr(request, email_field, None) for address in attr: check_email(address, email_field) # The sender field is not repeatable, so # need to check it separately here check_email(request.sender, 'sender')
def _createSessionObject(self, request): """ Create a new Session object, returning SessionForm/request. """ # make sure that the user is authed user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException("Authorization required") user_id = getUserId(user, id_type="oauth") # get the conference model wsck = request.websafeConferenceKey conf = ndb.Key(urlsafe=wsck).get() # check that conference exists if not conf: raise endpoints.NotFoundException( "No conference found with key: %s" % request.websafeConferenceKey) # check if the user is the organizer of the conference if user_id != conf.organizerUserId: raise endpoints.ForbiddenException( "Only the owner can update the conference.") # check wether the "name" field is filled by 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() } # add default values for those missing (both data model & outbound Message) for df in SESSION_DEFAULTS: if data[df] in (None, []): data[df] = SESSION_DEFAULTS[df] #setattr(request, df, SESSION_DEFAULTS[df]) # convert sessionType from enum to string if data["typeOfSession"]: data["typeOfSession"] = str(data["typeOfSession"]) # convert date from strings to Date objects if data["date"]: # date data["date"] = datetime.strptime(data["date"][:10], "%Y-%m-%d").date() # check if the date is during the conference period conf_start_date = getattr(conf, "startDate") conf_end_date = getattr(conf, "endDate") if conf_start_date and conf_end_date: if data["date"] < conf_start_date or data[ "date"] > conf_end_date: raise endpoints.BadRequestException("Invallid date") # convert time from strings to time objects if data["startTime"]: # time data["startTime"] = datetime.strptime(data["startTime"][:8], "%H:%M:%S").time() # compute the endTime using the duration field if data["duration"] and data["startTime"]: endTime_minute = (data["startTime"].minute + data["duration"]) % 60 endTime_hour = data["startTime"].hour \ + (data["startTime"].minute + data["duration"]) / 60 data["endTime"] = time(endTime_hour, endTime_minute) # delete unused fields del [data["duration"]] del [data["websafeConferenceKey"]] del [data["wssk"]] # make conference Key from the websafe conference key c_key = ndb.Key(urlsafe=wsck) # allocate new Session ID with the conference key as parent s_id = Session.allocate_ids(size=1, parent=c_key)[0] # make Session key from ID s_key = ndb.Key(Session, s_id, parent=c_key) data["key"] = s_key # creates the Session object and put onto the cloud datastore Session(**data).put() # add task to queue to update featured speaker taskqueue.add(params={"websafeConferenceKey": wsck}, url="/tasks/set_featured_speaker") # return the original Session Form return self._copySessionToForm(s_key.get())
def _createConferenceObject(self, request): """ Create or update Conference object, returning ConferenceForm/request. """ # make sure user is authed user = endpoints.get_current_user() if not user: raise endpoints.UnauthorizedException("Authorization required") user_id = getUserId(user, id_type="oauth") # check wether the 'name' field is filled by 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"]: # start date data["startDate"] = datetime.strptime(data["startDate"][:10], "%Y-%m-%d").date() data["month"] = data["startDate"].month else: data["month"] = 0 if data["endDate"]: # end date 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 # creates the conference object and put onto the cloud datastore Conference(**data).put() # send confirmation email taskqueue.add(params={ "email": user.email(), "conferenceInfo": repr(request) }, url="/tasks/send_confirmation_email") # return the (updated) ConferenceForm return request
def _createSessionObject(self, request): """Create a Session object, returning SessionForm/request.""" # Getting and Verifying current user user = getUser() # get the user_id (email) user_id = getUserId(user) # Check that the 'name' field if filed checkField(request.name, 'name') # Check that the 'parentKey' field if filed checkField(request.parentKey, 'parentKey') # Attempt to retrieve the Conference or raise an exception try: _key = ndb.Key(urlsafe=request.parentKey) except Exception: raise endpoints.BadRequestException( 'The parentKey given is invalid.') # Retrieve the Conference Obj conf = _key.get() # Verify that the current user created the conference if user_id != conf.organizerUserId: raise endpoints.ForbiddenException( 'Only the conference creator can add a session to it.') # Check speakerKey and save them speakers = [] if request.speakerKey: for speakerKey in request.speakerKey: try: speaker = ndb.Key(urlsafe=speakerKey).get() speakers.append(speaker) except Exception: raise endpoints.BadRequestException( 'Check the speakerKey it is invalid.') # Copy SessionForm/ProtoRPC Message into dict data = ({field.name: getattr(request, field.name) for field in request.all_fields()}) # If values not given for Session defaults, add defaults for df in SESSION_DEFAULTS: if data[df] in (None, []): data[df] = SESSION_DEFAULTS[df] setattr(request, df, SESSION_DEFAULTS[df]) # Converting the date info from strings to Date objects # setting the object month to the start dates month if data['date']: data['date'] = (datetime.strptime( data['date'][:10], "%Y-%m-%d").date()) data['month'] = data['date'].month else: data['month'] = conf.month # Convert startTime from string to Time object if data['startTime']: data['startTime'] = (datetime.strptime( data['startTime'][:5], "%H:%M").time()) # Convert typeOfSession to string if data['typeOfSession']: data['typeOfSession'] = str(data['typeOfSession']) # Create a session id for the Session, # create the relationship with parent key. s_id = Session.allocate_ids(size=1, parent=_key)[0] # Create the session key s_key = ndb.Key(Session, s_id, parent=_key) # Fill the session key data['key'] = s_key # Check that the speaker was passed if speakers: # Query the session for instance of speakers s = Session.query( ancestor=ndb.Key(urlsafe=request.parentKey)) # Setting none as featured featured = None # Number of session instance_count = 0 for spkr in data['speakerKey']: i_count = s.filter(Session.speakerKey == spkr).count() if i_count >= instance_count: featured = spkr minSessions = i_count # Advise of the featured Speaker using the taskQueue if featured: taskqueue.add( params = { 'websafeConferenceKey': request.parentKey, 'websafeSpeakerKey' : featured}, url = '/tasks/set_featured_speaker', method = 'GET') # Store in the DataStore Session(**data).put() # Send an email to the conference organizer taskqueue.add( params = { 'email' : user.email(), 'subject' : 'You Created a New Session for %s!' % conf.name, 'body' : 'Here are the details for new Session:', 'info' : repr(request)}, url = '/tasks/send_confirmation_email') return request