def delete_friendship(self, friend_a_id, friend_b_id): """ Delete Friend :param friend_a_id: user id :param friend_b_id: user id """ self.session.query(Friend) \ .filter(sa.or_( sa.and_( Friend.friend_a_id == friend_a_id, Friend.friend_b_id == friend_b_id ), sa.and_( Friend.friend_a_id == friend_b_id, Friend.friend_b_id == friend_a_id ) ) ) \ .delete() try: self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error deleting friendship") return None
def commit_changes(self): """Commit changes in session object to database""" try: self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") raise exceptions.ServerError("Error updating user info")
def get_places_around_point(point, radius, place_type): """ Find, using Google Nearby Places API, all places of place_type within specified radius from point. :param point: centre point, type Point :param radius: radius in metres :param place_type: place type to find :return: list of places around point """ base_request = GM_PLACES_URL.format( point.lat, point.long, radius, place_type, GM_API_KEY ) response = requests.get(base_request).json() if not response: logger.log_error( f"Invalid response from Google API. Request URL: {base_request}" ) raise ServerError("Unable to reach Google Maps API (Places).") places = _json_extract_places(response) while "next_page_token" in response: time.sleep(1) response = requests.get( base_request + "&pagetoken=" + quote(response["next_page_token"]) ).json() if not response: logger.log_error( f"Invalid response from Google API. Request URL: {base_request}" ) raise ServerError("Unable to reach Google Maps API (Places).") places.extend(_json_extract_places(response)) return places
def __init__(self, db_url): """Set up engine and session""" try: self.engine = sqlalchemy.create_engine(db_url) except sqlalchemy.exc.SQLAlchemyError as e: logger.log_error(f"Cannot create db engine. {str(e)}") self.base = models.base self.metadata = models.base.metadata self._SessionMaker = sqlalchemy.orm.sessionmaker(bind=self.engine)
def get_distance_matrix(origins, destinations, mode): """ Use Google Distance Matrix API to request distance matrix between origins and destinations, using specified mode of transportation. Given that Google Distance Matrix API is limited in the number of elements it can return in any single request, this function calculates how many requests are needed to include all elements of the matrix with size (origins * destinations), and places multiple requests if needed. :param origins: list of origin Points :param destinations: list of destination Points :param mode: mode of transportation :return: distance matrix of dimension len(origins) * len(destinations) """ dist_matrix = [[None] * len(destinations) for _ in range(len(origins))] no_requests = math.ceil( len(origins) * len(destinations) / DISTANCE_MATRIX_MAX_ELEMENTS ) start = 0 for i in range(no_requests): cutoff = min( start + math.ceil(len(destinations) / no_requests), len(destinations) ) origins_list = [ ",".join([str(origin.lat), str(origin.long)]) # stringify coords for origin in origins ] dest_list = [ ",".join([str(dest.lat), str(dest.long)]) for dest in destinations[start:cutoff] ] request = GM_TRAVEL_TIME_URL.format( quote("|".join(origins_list)), # Google format: x1,y1|x2,y2|xn,yn quote("|".join(dest_list)), mode, GM_API_KEY ) response = requests.get(request).json() if not response["rows"]: logger.log_error( f"Invalid response from Google API. Request URL: {request}" ) raise ServerError("Error retrieving distance information") for row_idx, row in enumerate(response["rows"]): for el_idx, element in enumerate(row["elements"]): if element["status"] != "OK": dist_matrix[row_idx][el_idx] = sys.maxsize else: dist_matrix[row_idx][el_idx] = element["duration"]["value"] if i < no_requests - 1: start = cutoff time.sleep(1) # sleep before next request return dist_matrix
def add_place(self, place): """ Add Place to database :param place: Place object """ self.session.add(place) try: self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error while adding place: {str(e)}") self.session.rollback() return None
def delete_userinvite(self, userinvite): """ Delete UserInvite from database :param userinvite: UserInvite object """ self.session.delete(userinvite) try: self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error deleting invite") return None
def add_userinvites(self, userinvites): """ Add multiple UserInvite objects to a database :param userinvites: UserInvite objects """ try: self.session.bulk_save_objects(userinvites) self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error inviting users") return None
def add_userinvite(self, userinvite): """ Add UserInvite to database :param userinvite: UserInvite object """ self.session.add(userinvite) try: self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error inviting user.") return None
def delete_user(self, user): """ Delete user from database :param user: User object """ self.session.delete(user) try: self.session.commit() except SQLAlchemyError as e: self.session.rollback() logger.log_error(f"Database Error: {str(e)}") raise exceptions.ServerError("Error deleting user") return None
def delete_event(self, event): """ Delete event from database :param event: Event object """ self.session.delete(event) try: self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error deleting event.") return None
def add_event(self, event): """ Add event to database :param event: Event object """ self.session.add(event) try: self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error creating event.") return None
def add_friendinvites(self, friendinvites): """ Add multiple FriendInvite objects to a database :param userinvites: sequence of FriendInvite objects """ try: self.session.bulk_save_objects(friendinvites) self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error adding invites") return None
def add_user(self, user): """ Add user to database :param user: User object """ self.session.add(user) try: self.session.commit() except SQLAlchemyError as e: self.session.rollback() if isinstance(e, IntegrityError): raise exceptions.InputError("Email address in use.") else: logger.log_error(f"Database Error: {str(e)}") raise exceptions.ServerError("Error adding user") return None
def add_friendship(self, friend_a_id, friend_b_id): """ Add friendship to db. :param friend_a_id: user id :param friend_b_id: user id :return: both Friend objects (Friendship is reflexive) """ a_to_b = Friend(friend_a_id=friend_a_id, friend_b_id=friend_b_id, creation_date=datetime.datetime.utcnow()) b_to_a = Friend(friend_a_id=friend_b_id, friend_b_id=friend_a_id, creation_date=datetime.datetime.utcnow()) try: self.session.bulk_save_objects([a_to_b, b_to_a]) self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error adding friendship") return (a_to_b, b_to_a)
def add_friendship_from_invite(self, friendinvite): """ Add friendship to db from friendinvite passed in and remove friendinvite from db. :param friendinvite: FriendInvite object :return: both Friend objects """ a_to_b = Friend(friend_a_id=friendinvite.requesting_id, friend_b_id=friendinvite.requested_id, creation_date=datetime.datetime.utcnow()) b_to_a = Friend(friend_a_id=friendinvite.requested_id, friend_b_id=friendinvite.requesting_id, creation_date=datetime.datetime.utcnow()) try: self.session.bulk_save_objects([a_to_b, b_to_a]) self.session.delete(friendinvite) self.session.commit() except SQLAlchemyError as e: logger.log_error(f"Database Error: {str(e)}") self.session.rollback() raise exceptions.ServerError("Error adding friendship") return (a_to_b, b_to_a)