def getNewDeletedEvents(self, timestamp): """ Get a list of the core information for events deleted at or after the given timestamp. Uses :func:`~app.DAOs.EventDAO.EventDAO.getNewDeletedEvents` as well as: * :func:`~app.handlers.EventHandler._validateTimestamp` * :func:`~app.handlers.EventHandler._buildTinyEventResponse` :param timestamp: Time used to look for events that have been deleted at or after. ("%Y-%m-%d %H:%M:%S") :type timestamp: str :returns JSON Response Object: JSON containing limit-defined number of events dismissed by a user. """ if not isinstance(timestamp, str) or not _validateTimestamp(datestring=timestamp): return jsonify(Error='Invalid timestamp: ' + str(timestamp)), 400 events = EventDAO().getNewDeletedEvents(timestamp=timestamp) if not events: response = {'events': None} else: event_list = [] for row in events: event_entry = _buildTinyEventResponse(event_tuple=row) event_list.append(event_entry) response = {'events': event_list} return jsonify(response)
def setRecommendation(self, uid, eid, recommendstatus): """Set an eventuserinteractions entry that states if the specified event has been recommended to the user or not. Uses :func:`~app.DAOs.EventDAO.EventDAO.setRecommendation` as well as :func:`~app.handlers.EventHandler._validate_uid_eid` :param uid: User ID :type uid: int :param eid: Event ID. :type eid: int :param recommendstatus: qualitative result of recommendation calculation. Currently accepted recommendstatus: ["R", "N"] :type recommendstatus: str :returns JSON Response Object: JSON containing post response. """ try: _validate_uid_eid(uid=uid, eid=eid) except ValueError as ve: return jsonify(Error=str(ve)), 400 if not isinstance(recommendstatus, str) or recommendstatus not in RECOMMENDATION_TYPES: return jsonify(Error='Invalid recommendstatus = ' + str(recommendstatus)), 400 uid_eid_pair = EventDAO().setRecommendation(uid=uid, eid=eid, recommendstatus=recommendstatus) try: return jsonify({"uid": uid_eid_pair[0], "eid": uid_eid_pair[1]}), 201 except TypeError: return jsonify(Error=str(uid_eid_pair)), 400
def setEventStatus(self, uid, eid, estatus): """Set the estatus of an event entry to the specified value. Uses :func:`~app.DAOs.EventDAO.EventDAO.setEventStatus` as well as :func:`~app.handlers.EventHandler._validate_uid_eid` :param uid: User ID :type uid: int :param eid: Event ID. :type eid: int :param estatus: New status for event. Current Accepted statuses: ['active', 'deleted'] :type estatus: str :returns JSON Response Object: JSON containing successful post response. """ try: _validate_uid_eid(uid=uid, eid=eid) except ValueError as ve: return jsonify(Error=str(ve)), 400 if not isinstance(estatus, str) or estatus not in ESTATUS_TYPES: return jsonify(Error='Invalid estatus = ' + str(estatus)), 400 uid_eid_pair = EventDAO().setEventStatus(eid=eid, estatus=estatus, uid=uid) try: return jsonify({"eid": uid_eid_pair[0]}), 201 except TypeError: return jsonify(Error=str(uid_eid_pair)), 400
def getUpcomingRecommendedEventsSegmented(self, uid, offset, limit=20): """Return the upcoming, active, recommended event entries specified by offset and limit parameters. Uses :func:`~app.DAOs.EventDAO.EventDAO.getUpcomingRecommendedEventsSegmented` as well as: * :func:`~app.handlers.SharedValidationFunctions.validate_offset_limit` * :func:`~app.handlers.EventHandler._buildCoreEventResponse` :param uid: User ID :type uid: int :param offset: Number of result rows to ignore from top of query results. :type offset: int :param limit: Max number of result rows to return. Default=20. :type limit: int :returns JSON Response Object: JSON containing limit-defined number of events recommended to a user that have not ended. """ if not isinstance(uid, int) or not uid > 0: return jsonify(Error="Invalid uid: " + str(uid)), 400 try: SVF.validate_offset_limit(offset=offset, limit=limit) except ValueError as ve: return jsonify(Error=str(ve)), 400 events = EventDAO().getUpcomingRecommendedEventsSegmented(uid=uid, offset=offset, limit=limit) if not events: response = {'events': None} else: event_list = [] for row in events: # TODO: consider re-developing Response builders for more flexibility. event_entry = _buildCoreEventResponse(event_tuple=row) event_entry['itype'] = row[11] event_list.append(event_entry) response = {'events': event_list} return jsonify(response)
def getEventsCreatedAfterTimestamp(self, timestamp, uid): """ Get the upcoming active event IDs that a user has not interacted with, along with the tags for that event. Uses :func:`~app.DAOs.EventDAO.EventDAO.getEventIDsCreatedAfterTimestamp` as well as: * :func:`~app.handlers.TagHandler.TagHandler.safeGetTagsByEventID` * :func:`~app.handlers.EventHandler._validateTimestamp` :param timestamp: ISO formatted timestamp string. ("%Y-%m-%d %H:%M:%S") :type timestamp: str :param uid: the user's ID. :type uid: int :returns JSON Response Object: json response with event IDs and tags for each event. """ if not isinstance(timestamp, str) or not _validateTimestamp(datestring=timestamp): return jsonify(Error='Invalid timestamp: ' + str(timestamp)), 400 if not isinstance(uid, int) or not uid > 0: return jsonify(Error="Invalid uid: " + str(uid)), 400 event_ids = EventDAO().getEventIDsCreatedAfterTimestamp(uid=uid, timestamp=timestamp) if not event_ids: response = {'events': None} else: event_list = [] for row in event_ids: event_entry = {"eid": row[0], "tags": TagHandler().safeGetTagsByEventID(eid=row[0])} event_list.append(event_entry) response = {'events': event_list} return jsonify(response)
def getEventByIDWithInteraction(self, eid, uid): """Return the event entry belonging to the specified eid, plus the user interaction entry for the given uid. Uses :func:`~app.DAOs.EventDAO.EventDAO.getEventInteractionByUserID` as well as :func:`~app.handlers.EventHandler.getEventByID` :param eid: Event ID :type eid: int :param uid: User ID :type uid: int :returns JSON Response Object: json response with event IDs and tags for each event. """ if not isinstance(uid, int) or not uid > 0: return jsonify(Error="Invalid uid: " + str(uid)), 400 if not isinstance(eid, int) or not eid > 0: return jsonify(Error="Invalid eid: " + str(eid)), 400 event_response = self.getEventByID(eid=eid, no_json=True) # If it's not a dictionary, it is an error JSON. if not isinstance(event_response, dict): return event_response # TODO: consider moving this to User Handler/Dao user_interaction = EventDAO().getEventInteractionByUserID(eid=eid, uid=uid) # If no interaction found, object is None; replace with None tuple if not user_interaction: user_interaction = [None, None] event_response["itype"] = user_interaction[0] event_response["recommendstatus"] = user_interaction[1] return jsonify(event_response)
def getAllPastEventsSegmented(self, offset, limit=20): """Get all events whose end dates are equal to or less than the current timestamp of the database. Uses :func:`~app.DAOs.EventDAO.EventDAO.getAllPastEventsSegmented` as well as: * :func:`~app.handlers.SharedValidationFunctions.validate_offset_limit` * :func:`~app.handlers.EventHandler._buildCoreEventResponse` :param offset: Number of results to skip from top of list. :type offset: int :param limit: Number of results to return. Default = 20. :type limit: int :returns JSON Response Object: JSON Response Object containing success or error response. """ try: SVF.validate_offset_limit(offset=offset, limit=limit) except ValueError as ve: return jsonify(Error=str(ve)), 400 events = EventDAO().getAllPastEventsSegmented(offset=offset, limit=limit) if not events: response = {'events': None} else: event_list = [] for row in events: event_entry = _buildCoreEventResponse(event_tuple=row) event_list.append(event_entry) response = {'events': event_list} return jsonify(response)
def setInteraction(self, uid, eid, itype): """Set an eventuserinteractions entry that states the user has interacted with the specified event. Uses :func:`~app.DAOs.EventDAO.EventDAO.setInteraction` as well as: * :func:`~app.handlers.EventHandler._validate_uid_eid` * :func:`~app.handlers.EventHandler._validateItype` * :func:`~app.handlers.TagHandler.TagHandler.buildCoreUserTagResponse` * :func:`~app.DAOs.EventDAO.EventDAO.getEventByID` * :func:`~app.handlers.EventHandler._buildTinyEventResponse` :param uid: User ID :type uid: int :param eid: Event ID. :type eid: int :param itype: type of interaction. Currently accepted interactions: ["following", "unfollowed", "dismissed"] :type itype: str :returns JSON Response Object: JSON containing post response. """ try: _validate_uid_eid(uid=uid, eid=eid) except ValueError as ve: return jsonify(Error=str(ve)), 400 if not isinstance(itype, str) or not _validateItype(itype=itype): return jsonify(Error="Invalid itype: " + str(itype)), 400 # dao = EventDAO() result = EventDAO().setInteraction(uid=uid, eid=eid, itype=itype) # TODO: Implement a better way to do this error handling. try: new_usertags = [] for row in result: new_usertags.append(TagHandler().buildCoreUserTagResponse(tag_tuple=row)) # Calling this within the try block, because if the setInteraction call fails, # psql will block all transactions until current one finishes, and will cause # a 500 error instead of the intended 400 below. event = EventDAO().getEventByID(eid=eid) tiny_event = _buildTinyEventResponse(event_tuple=event) response = {} response['tags'] = new_usertags response['event'] = tiny_event return jsonify(response), 201 except TypeError: return jsonify(Error=str(result)), 400
def createEvent(self, json, uid): """Attempt to create an event. Uses :func:`~app.DAOs.EventDAO.EventDAO.createEvent` as well as: * :func:`~app.handlers.TagHandler.TagHandler.unpackTags` * :func:`~app.handlers.WebsiteHandler.WebsiteHandler.validateWebsites` :param uid: User ID. :type uid: int :param json: JSON object with the following keys: * roomid * etitle * edescription * estart * eend * photourl * websites * tags :type json: JSON :returns JSON Response Object: JSON Response Object containing success or error response. """ for key in CREATEEVENTKEYS: if key not in json: return jsonify(Error='Missing credentials from submission: ' + key), 400 try: _validateEventParameters(json=json, uid=uid) tags = TagHandler().unpackTags(json_tags=json['tags']) WebsiteHandler().validateWebsites(list_of_websites=json['websites']) except ValueError as e: return jsonify(Error=str(e)), 400 except KeyError as ke: return jsonify(Error="Missing Key in JSON: " + str(ke)), 400 if len(tags) < 3 or len(tags) > 10: return jsonify(Error="Improper number of unique tags provided: " + str(len(tags))), 400 eid = EventDAO().createEvent(ecreator=uid, roomid=json['roomid'], etitle=json['etitle'], edescription=json['edescription'], estart=json['estart'], eend=json['eend'], photourl=json['photourl'], tags=tags, websites=json['websites']) try: eid = eid[0] except TypeError: return jsonify(Error=str(eid)), 400 return jsonify({"eid": eid}), 201
def getUpcomingRecommendedEventsByKeywordSegmented(self, uid, searchstring, offset, limit=20): """Return the upcoming, recommended, active event entries specified by offset and limit parameters. Uses :func:`~app.DAOs.EventDAO.EventDAO.getUpcomingRecommendedEventsByKeywordSegmented` as well as: * :func:`~app.handlers.SharedValidationFunctions.validate_offset_limit` * :func:`~app.handlers.SharedValidationFunctions.processSearchString` * :func:`~app.handlers.EventHandler._buildCoreEventResponse` :param uid: User ID :type uid: int :param searchstring: String to use as search criteria for recommended events. Search terms must be separated by whitespaces. :type searchstring: str :param offset: Number of result rows to ignore from top of query results. :type offset: int :param limit: Max number of result rows to return. Default=20. :type limit: int :returns JSON Response Object: JSON containing limit-defined number of recommended events that have not ended and match search criteria. """ if not isinstance(uid, int) or not uid > 0: return jsonify(Error="Invalid uid: " + str(uid)), 400 try: SVF.validate_offset_limit(offset=offset, limit=limit) # Process keywords to be filtered and separated by pipes. keywords = SVF.processSearchString(searchstring=searchstring) except ValueError as ve: return jsonify(Error=str(ve)), 400 events = EventDAO().getUpcomingRecommendedEventsByKeywordSegmented(uid=uid, keywords=keywords, offset=offset, limit=limit) if not events: response = {'events': None} else: event_list = [] for row in events: # TODO: consider re-developing Response builders for more flexibility. event_entry = _buildCoreEventResponse(event_tuple=row) event_entry['itype'] = row[11] event_list.append(event_entry) response = {'events': event_list} return jsonify(response)
def getEventByID(self, eid, no_json=False): """Return the event entry belonging to the specified eid. Uses :func:`~app.DAOs.EventDAO.EventDAO.getEventByID` as well as :func:`~app.handlers.EventHandler._buildCoreEventResponse` :param eid: Event ID :type eid: int :param no_json: States whether or not to return the successful response as a dictionary. :type no_json: bool :returns JSON Response Object: JSON Response Object containing success or error response. """ if not isinstance(eid, int) or not eid > 0: return jsonify(Error="Invalid eid: " + str(eid)), 400 event = EventDAO().getEventByID(eid) if not event: return jsonify(Error='Event does not exist: eid=' + str(eid)), 404 else: response = _buildEventResponse(event_tuple=event) if no_json: return response return jsonify(response)