Esempio n. 1
0
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")
Esempio n. 2
0
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.")
Esempio n. 3
0
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.")
Esempio n. 4
0
def ticket_price():
    data = request.get_json()
    result = get_ticket_price(conn, data)
    if result is not None and len(result) > 0:
        return jsonify(result="success",
                       data=dict(price=float(str(result[0]))))
    else:
        raise JsonError("No ticket data is found")
Esempio n. 5
0
 def wrapper(*args, **kwargs):
     if (
         "user_type" not in session
         or session["user_type"] == "public"
         or (user_type is not None and session["user_type"] != user_type.value)
     ):
         raise JsonError("Please login to access this page!")
         # abort(401)
     return func(*args, **kwargs)
Esempio n. 6
0
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
Esempio n. 7
0
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!")
Esempio n. 8
0
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")
Esempio n. 9
0
def add_airport():
    data = request.get_json()
    airport_data = {}
    try:
        airport_data["airport_name"] = data["airport_name"]
        airport_data["city"] = data["city"]
    except KeyError as err:
        raise MissingKeyError(err.args[0])
    try:
        insert_into(conn, "Airport", **airport_data)
    except QueryDuplicateError as err:
        raise JsonError("The airport already exists!")
    return jsonify(result="success")
Esempio n. 10
0
def login(login_type: str):
    data = request.get_json()
    try:
        user_type = DataType(login_type)
        if not is_user(user_type):
            raise ValueError()
    except ValueError:
        raise JsonError("Invalid login method!")
    # If no error is thrown in check_login, our user is OK
    user_data_raw = check_login(conn, user_type, **data)

    user_data = handle_login_data(user_type, user_data_raw)

    return jsonify(result="success", user_data=user_data)
Esempio n. 11
0
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
Esempio n. 12
0
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")
Esempio n. 13
0
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
Esempio n. 14
0
def register(register_type: str):
    data = request.get_json()
    try:
        user_type = DataType(register_type)
        if not is_user(user_type):
            raise ValueError()
    except ValueError:
        raise JsonError("Invalid registration method!")

    if data is None:
        raise JsonError("Empty data fields!")

    try:
        hashed_password, salt = generate_hash(data["password"])

        if user_type is DataType.CUST:
            insert_into(
                conn,
                user_type.get_table(),
                email=data["email"],
                name=data["name"],
                password=hashed_password,
                salt=salt,
                phone_number=data["phone_number"],
                date_of_birth=data.get("date_of_birth", ""),
                passport_number=data.get("passport_number", ""),
                passport_expiration=data.get("passport_expiration", ""),
                passport_country=data.get("passport_country", "China"),
                street=data.get("street", ""),
                city=data.get("city", ""),
                state=data.get("state", ""),
            )
            session["email"] = data["email"]
        elif user_type is DataType.STAFF:
            insert_into(
                conn,
                user_type.get_table(),
                username=data["username"],
                password=hashed_password,
                salt=salt,
                first_name=data["first_name"],
                last_name=data["last_name"],
                date_of_birth=data["date_of_birth"],
                airline_name=data["airline_name"],
            )
            session["username"] = data["username"]
        elif user_type is DataType.AGENT:
            agent_id = insert_into(
                conn,
                user_type.get_table(),
                email=data["email"],
                password=hashed_password,
                salt=salt,
            )
            session["agent_id"] = agent_id
            session["agent_email"] = data["email"]
    except KeyError as err:
        raise MissingKeyError(err.args[0])
    except QueryKeyError as err:
        raise MissingKeyError(err.get_key())
    except QueryDuplicateError as err:
        raise ExistingRegisterError(err.key, err.value)

    session["user_type"] = user_type.value

    if user_type is DataType.AGENT:
        return jsonify(result="success", user_data=dict(agent_id=agent_id))
    else:
        return jsonify(result="success")