def test_select_all_tables(self): for data_type in DataType: query( self.conn, BASIC_SELECT.format(table=data_type.get_table(), predicates=""), )
def ticket_purchase(): data = request.get_json() if session["user_type"] in (DataType.CUST.value, DataType.AGENT.value): ticket_data = {} now = datetime.now() try: # only the booking agent can set the email ticket_data["email"] = (session["email"] if session["user_type"] == DataType.CUST.value else data["email"]) ticket_data["card_type"] = data["card_type"] ticket_data["card_number"] = data["card_number"] ticket_data["name_on_card"] = data["name_on_card"] ticket_data["exp_date"] = data["exp_date"] ticket_data["airline_name"] = data["airline_name"] ticket_data["flight_number"] = int(data["flight_number"]) ticket_data["dep_date"] = data["dep_date"] ticket_data["dep_time"] = data["dep_time"] if "agent_id" in session: ticket_data["booking_agent_id"] = session["agent_id"] # ticket_data["purchase_date"] = now.strftime("%Y-%m-%d") # ticket_data["purchase_time"] = now.strftime("%H:%M:%S") ticket_data["sold_price"] = get_ticket_price(conn, data) except KeyError as err: raise MissingKeyError(err.args[0]) except ValueError as err: raise JsonError("The flight number should be a number!") result = query( conn, "SELECT * FROM Flight WHERE (flight_number, dep_date, dep_time)=(%(flight_number)s, %(dep_date)s, %(dep_time)s) AND dep_date > UTC_DATE() OR (dep_date = UTC_DATE() AND dep_time > UTC_TIME())", args=ticket_data, ) if len(result) == 0: raise JsonError( "Cannot purchase a ticket for a flight in the past!") result = insert_into(conn, "Ticket", **ticket_data) if "booking_agent_id" in ticket_data: insert_into( conn, "Book", ticket_ID=result, booking_agent_id=ticket_data["booking_agent_id"], commission=float( query( conn, "SELECT sold_price FROM Ticket WHERE ticket_id={}". format(result), FetchMode.ONE, )[0]) * 0.1, ) return jsonify(result="success") else: raise JsonError( "Only customers or booking agents can purchase tickets.")
def add_feedback(): data = request.get_json() if "email" not in session or session["user_type"] != DataType.CUST.value: raise JsonError("Only customers are allowed to add feedbacks!") try: feedback_data = dict( flight_number=data["flight_number"], dep_date=data["dep_date"], dep_time=data["dep_time"], comment=data.get("comment", ""), email=session["email"], rating=data["rating"], ) except KeyError as err: raise MissingKeyError(err.args[0]) result = query( conn, "SELECT * FROM Ticket WHERE (flight_number, dep_date, dep_time, email)=(%(flight_number)s, %(dep_date)s, %(dep_time)s, %(email)s) AND dep_date < UTC_DATE() OR (dep_date = UTC_DATE() AND dep_time < UTC_TIME())", args=feedback_data, ) if result == 0: raise JsonError( "You need to take the flight first before giving feedbacks!") try: insert_into(conn, "Feedback", **feedback_data) except QueryDuplicateError: raise JsonError("You have already given feedback for this flight!") return jsonify(result="success")
def create_flight(): data = request.get_json() flight_data: Dict[str, Any] = {} result = None try: flight_data["flight_number"] = data["flight_number"] flight_data["dep_date"] = data["dep_date"] flight_data["dep_time"] = data["dep_time"] flight_data["arr_date"] = data["arr_date"] flight_data["arr_time"] = data["arr_time"] flight_data["dep_airport"] = data["dep_airport"] flight_data["arr_airport"] = data["arr_airport"] flight_data["plane_ID"] = data["plane_ID"] flight_data["status"] = data["status"] flight_data["base_price"] = data["base_price"] except KeyError as err: raise MissingKeyError(err.args[0]) try: if convert( flight_data["dep_date"], flight_data["dep_time"]) >= convert( flight_data["arr_date"], flight_data["arr_time"]): raise JsonError( "The arrival time needs to be after the arrival time!") except ValueError as err: raise JsonError("The date format is in valid: {}".format(err.args[0])) try: flight_data["airline_name"] = query( conn, STAFF_AIRLINE, FetchMode.ONE, args=dict(username=session["username"]))[0] except QueryError: raise JsonError( "An unknown error occurs when finding your airline name.") try: result = insert_into(conn, "Flight", **flight_data) except QueryDuplicateError as err: raise JsonError( "The flight with the same flight number and departure datetime already exists!" ) except QueryError as err: if err.get_error_code() == 1452: # Foreign key constraint if "plane_ID" in err.get_error_message(): raise JsonError("The plane ID is invalid!") if err.get_error_code() == 1292: match = time_value_err_pattern.match(err.get_error_message()) if match is not None: raise JsonError("The time value {} for {} is invalid!".format( match.group(1), match.group(2))) print(err) raise JsonError( "Failed to create the new flight! Please contact the maintainer.") if result is not None: return jsonify(result="success") else: raise JsonError("Failed due to an unknown error.")
def change_status(): data = request.get_json() flight_data = {} try: flight_data["flight_number"] = data["flight_number"] flight_data["dep_date"] = data["dep_date"] flight_data["dep_time"] = data["dep_time"] flight_data["status"] = data["status"] except KeyError as err: raise MissingKeyError(err.args[0]) try: flight_data["airline_name"] = query( conn, STAFF_AIRLINE, FetchMode.ONE, args=dict(username=session["username"]))[0] except QueryError: raise JsonError( "An unknown error occurs when finding your airline name.") result = query(conn, UPDATE_STATUS, args=flight_data) return jsonify(result="success")
def session_fetch(): data = request.get_json() user_data_raw = None user_type = DataType(session["user_type"]) try: if user_type is DataType.CUST: user_data_raw = query( conn, CHECK_CUST_LOGIN, fetch_mode=FetchMode.ONE, args=dict(email=session["email"]), ) elif user_type is DataType.STAFF: user_data_raw = query( conn, CHECK_STAFF_LOGIN, fetch_mode=FetchMode.ONE, args=dict(username=session["username"]), ) elif user_type is DataType.AGENT: user_data_raw = query( conn, CHECK_AGENT_LOGIN, fetch_mode=FetchMode.ONE, args=dict(email=session["agent_email"], booking_agent_id=session["agent_id"]), ) except KeyError as err: raise JsonError("The user session is invalid! Please login.") if user_data_raw is not None: try: return jsonify( result="success", user_data=handle_login_data(user_type, user_data_raw), ) except IndexError as err: raise JsonError("The user might have been removed!") else: raise JsonError("There is no session associated with this user!")
def test_insert(self): result = insert_into( self.conn, DataType.AGENT.get_table(), email="[email protected]", password=self.hashed_password, salt=self.salt, ) self.assertEqual(result, 2) result = insert_into( self.conn, DataType.AGENT.get_table(), email="[email protected]", password=self.hashed_password, salt=self.salt, ) self.assertEqual(result, 3) insert_into( self.conn, DataType.CUST.get_table(), email="[email protected]", name="test", password=self.hashed_password, salt=self.salt, ) result = query( self.conn, BASIC_SELECT.format( table=DataType.CUST.get_table(), predicates="", ), FetchMode.ONE, ) expected = ( "[email protected]", "test", "a4b615e9e91c8f444965e4fdefa62b88e3d69eab56323baa687d01f58266", "e3c20862d1859ff9db1882882ffc99d4", None, None, None, None, None, None, None, None, None, ) self.assertEqual(result, expected)
def check_login(conn: Connection, login_type: DataType, **kwargs: str): try: data = {} try: if login_type is DataType.STAFF: data["username"] = kwargs["username"] else: data["email"] = kwargs["email"] if login_type is DataType.AGENT: data["booking_agent_id"] = kwargs["booking_agent_id"] data["password"] = kwargs["password"] except KeyError as err: raise MissingKeyError(key=err.args[0]) if login_type is DataType.CUST: result = query(conn, CHECK_CUST_LOGIN, FetchMode.ONE, 1, data) elif login_type is DataType.STAFF: result = query(conn, CHECK_STAFF_LOGIN, FetchMode.ONE, 1, data) elif login_type is DataType.AGENT: result = query(conn, CHECK_AGENT_LOGIN, FetchMode.ONE, 1, data) else: raise JsonError("Invalid login method!") except QueryKeyError as err: raise MissingKeyError(err.get_key()) if result is None: raise JsonError("The input information doesn't match any existing users!") if login_type == DataType.CUST or login_type == DataType.AGENT: hashed_password, salt = result[2], result[3] else: hashed_password, salt = result[1], result[2] if not check_hash(kwargs["password"], hashed_password, salt): raise JsonError("The input information or the password does not match!") return result
def get_ticket_price(conn: Connection, data: Dict[str, Any]): ticket_data = {} try: ticket_data["flight_number"] = int(data["flight_number"]) ticket_data["dep_date"] = data["dep_date"] ticket_data["dep_time"] = data["dep_time"] except KeyError as err: raise MissingKeyError(err.args[0]) except ValueError as err: raise JsonError("The flight number should be a number!") try: result = query( conn, TICKET_PRICE.format(flight_number=ticket_data["flight_number"]), FetchMode.ONE, args=ticket_data, ) except IntegrityError: raise JsonError("The flight is invalid!") return result
def add_airplane(): data = request.get_json() airplane_data = {} try: airplane_data["plane_ID"] = data["plane_ID"] airplane_data["seat_capacity"] = data["seat_capacity"] except KeyError as err: raise MissingKeyError(err.args[0]) try: airplane_data["airline_name"] = query( conn, STAFF_AIRLINE, FetchMode.ONE, args=dict(username=session["username"]))[0] except QueryError: raise JsonError( "An unknown error occurs when finding your airline name.") try: insert_into(conn, "Airplane", **airplane_data) except QueryDuplicateError as err: raise JsonError("The airplane already exists!") return jsonify(result="success")
def do_search( conn: Connection, data: Dict[str, Any], session: Dict[str, Any], filter: str, use_public: bool, ): if data is None: data = {} try: filter_type = FilterType(filter) except ValueError: raise JsonError( 'The requested filter "{filter}" does not exist!'.format( filter=filter)) user_type = None if "user_type" in session: user_type = DataType(session["user_type"]) if not have_access_to_filter(user_type, filter_type): raise JsonError("You don't have the permission to use this filter!") filter_data = data.get("filter_data", {}) # Some users are not allowed to set these fields if user_type is not DataType.CUST: filter_data["is_customer"] = False if user_type is not DataType.AGENT: filter_data["agent_id"] = None if user_type is not DataType.STAFF: filter_data["username"] = None filter_data["is_staff"] = False if user_type is DataType.CUST: filter_data["emails"] = [session["email"]] filter_data["is_customer"] = True elif user_type is DataType.AGENT: filter_data["emails"] = [session["agent_email"]] elif user_type is DataType.STAFF: filter_data["airline_name"] = query( conn, STAFF_AIRLINE, FetchMode.ONE, args=dict(username=session["username"]))[0] # The staff member needs to be able to filter by customer emails, and thus we add this to them filter_data["is_staff"] = True try: result = query_by_filter(conn, filter_type, **filter_data, **session) except QueryKeyError as err: raise MissingKeyError(key=err.get_key()) except TypeError as err: if (err.args[0] == "query_by_filter() got multiple values for keyword argument 'email'" ): raise JsonError( "Malformed request! Are you attempting to pass your email address?" ) raise err return result
def query_by_filter(conn: Connection, filter: FilterType, **kwargs): sql, values = get_filter_query(filter, **kwargs) return query(conn, sql, args=values)