Exemplo n.º 1
0
    def delete(self):
        """
        Train line disable API, **JWT required**

        The body should be a JSON dictionary including the following attribute(s):

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if deletion is successful
        - `error`: `str`, shown if `code != 0`
        - `result`: `str`, shown if `code == 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            train_name = body.get('train_name')
            train = session.query(Train).filter(
                Train.train_name == train_name,
                Train.available == True).first()
            if not train:
                return jsonify(code=12, error='停用失败,线路不存在或已停用')
            interval_list = session.query(Interval).filter(
                Interval.train_id == train.train_id,
                Interval.available == True).all()
            for interval in interval_list:
                interval.available = False
            train.available = False
            session.commit()
            return jsonify(code=0, result='线路停用成功')
        except:
            traceback.print_exc()
            session.rollback()
            return jsonify(code=12, error='停用失败,请联系运维人员')
        finally:
            session.close()
Exemplo n.º 2
0
    def post(self):
        """
        Sign-up API

        The body should be a JSON dictionary including the following attribute(s):
        - `username`: `str`
        - `real_name`: `str`
        - `password`: `str`
        - `id_card`: `str`
        - `phone_number`: `str`
        - `email`: `str`

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if sign-up is successful
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            if session.query(User).filter(
                    User.username == body.get('username')).first() is not None:
                return jsonify(error='Username already exists', code=406)
            new_user = User(**body)
            new_user.hash_password()
            session.add(new_user)
            session.commit()
            return jsonify(code=0)
        except:
            session.rollback()
            return jsonify(code=10,
                           error='Unexpected error when creating user')
        finally:
            session.close()
Exemplo n.º 3
0
    def get(self):
        """
        Payment API

        **argument**:
        - `order_id`: `int`

        **return**:
        `Purchase succeeded` or `Purchase failed` or `Already paid`
        """
        session = DBSession()
        try:
            order_id = request.args.get('order_id')
            current_order: Order = session.query(Order).filter(
                Order.order_id == order_id).first()
            if current_order.order_status == "paid":
                return "Already paid"
            current_order.order_status = "paid"
            session.commit()
            session.flush()
            current_ticket: Ticket = session.query(Ticket).filter(
                Ticket.ticket_id == current_order.ticket_id).first()
            current_ticket.available = True
            session.commit()
            session.flush()
            return "Purchase succeeded"
        except:
            session.rollback()
            return "Purchase failed"
        finally:
            session.close()
Exemplo n.º 4
0
    def patch(self):
        """
        Station modification API, **JWT required**

        The body should be a JSON dictionary including the following attribute(s):
        - `city_name`: `str`
        - `district_name`: `str`
        - `station_name`: `str`
        - `new_station_name`: `str`

        **return**: A JSON dictionary with values
        - `code`: `int`, equals to 0 if modification is successful
        - `result`: `str` for success message, shown if `code == 0`
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            city_name = body.get('city_name')
            district_name = body.get('district_name')
            station_name = body.get('station_name')
            new_station_name = body.get('new_station_name')
            current_station: Station = session.query(Station).filter(
                Station.station_name == station_name,
                Station.available == True).first()
            if not current_station:
                return jsonify(code=1, error="站点不存在")

            district = session.query(District).filter(
                District.district_name == district_name).first()
            if not district:
                city = session.query(City).filter(
                    City.city_name == city_name).first()
                new_district = District(district_name=district_name,
                                        city_id=city.city_id)
                session.add(new_district)
                session.commit()
                district = session.query(District).filter(
                    District.district_name == district_name).first()
            current_station.district_id = district.district_id
            if new_station_name:
                current_station.station_name = new_station_name
            session.commit()
            return jsonify(code=0, result="修改成功")
        except:
            session.rollback()
            return jsonify(code=1, error='修改失败')
        finally:
            session.close()
Exemplo n.º 5
0
    def patch(self):
        """
        User information update API, **JWT required**

        The body should be a JSON dictionary including the following attribute(s):
        - `username`: `str`
        - `password`: `str`
        - `real_name`: `str`
        - `email`: `str`
        - `phone_number`: `str`

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if update is successful
        - `error`: `str`, shown if `code != 0`
        - `result`: `str`, shown if `code == 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            user_id = get_jwt_identity()
            user = session.query(User).filter(User.user_id == user_id).first()
            if user is None:
                return jsonify(error='User not found', code=404)
            if user.username != body.get('username'):
                new_username = body.get('username')
                if session.query(User).filter(
                        User.username == new_username).first() is not None:
                    return jsonify(error='Username already exists', code=406)
                user.username = new_username
            user.real_name = body.get('real_name')
            user.email = body.get('email')
            user.phone_number = body.get('phone_number')
            new_password = body.get('password')
            if new_password:
                if 8 <= len(new_password) <= 30:
                    user.password = new_password
                    user.hash_password()
                else:
                    session.rollback()
                    return jsonify(code=1, error='密码长度错误')
            session.commit()
            return jsonify(code=0, result='用户信息修改成功')
        except:
            session.rollback()
            return jsonify(code=10, error='Update failed')
        finally:
            session.close()
Exemplo n.º 6
0
    def patch(self):
        """
        Train line price information update API for administrator, **JWT required**

        The body should be a JSON dictionary including the following attribute(s):
        - `interval_id`: `int`
        - `price`: `dict` containing:
            - `seat_type_1`, `str`
            - `seat_type_2`, `str`
            - `seat_type_3`, `str`
            - `seat_type_4`, `str`
            - `seat_type_5`, `str`
            - `seat_type_6`, `str`
            - `seat_type_7`, `str`

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if update is successful
        - `error`: `str`, shown if `code != 0`
        - `result`: `str`, shown if `code == 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            for raw_id, raw_price in body.get('price').items():
                seat_type_id = int(raw_id[-1])
                obj_price: Price = session.query(Price) \
                    .filter(Price.interval_id == body.get('interval_id'),
                            Price.seat_type_id == seat_type_id) \
                    .first()
                if obj_price:
                    price = float(raw_price)
                    if price > 0:
                        obj_price.price = price
                    else:
                        raise Exception('')
            session.commit()
            return jsonify(code=0, result='修改成功')
        except:
            session.rollback()
            traceback.print_exc()
            return jsonify(code=10, error='修改失败')
        finally:
            session.close()
Exemplo n.º 7
0
    def delete(self):
        """
        Station deletion API, **JWT required**

        The body should be a JSON dictionary including the following attribute(s):
        - `station_name`: `str`

        **return**: A JSON dictionary with values
        - `code`: `int`, equals to 0 if deletion is successful
        - `result`: `str` for success message, shown if `code == 0`
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            station_name = body.get('station_name')
            # Find if the station exists
            station: Station = session.query(Station).filter(
                Station.station_name == station_name,
                Station.available == True).first()
            if not station:
                return jsonify(code=1, error="站点不存在或已删除")
            # Check if the station has train passing
            interval = session.query(Interval).filter(
                or_(Interval.dep_station == station.station_id,
                    Interval.arv_station == station.station_id)).first()
            if interval:
                return jsonify(code=2, error="站点仍有火车经过")
            station.available = False
            session.commit()
            return jsonify(code=0, result="删除成功")
        except:
            session.rollback()
            return jsonify(code=10, error='操作失败,请联系运维人员')
        finally:
            session.close()
Exemplo n.º 8
0
                    }

                    new_interval = Interval(**info)
                    session.add(new_interval)
                    session.commit()
                    session.flush()
                    interval_id = new_interval.interval_id
                    interval_id_list.append(interval_id)

                    # Add Price
                    seat_type_id = 1
                    for price in interval_info[6:]:
                        if price != '-':
                            price_obj = Price(interval_id=interval_id, seat_type_id=seat_type_id, price=float(price))
                            session.add(price_obj)
                            session.commit()
                        seat_type_id += 1

                for inv_i, interval_id in enumerate(interval_id_list):
                    interval = session.query(Interval).filter(Interval.interval_id == interval_id).first()
                    interval.next_id = interval_id_list[inv_i + 1] if inv_i < len(interval_id_list) - 1 else None
                    interval.prev_id = interval_id_list[inv_i - 1] if inv_i > 0 else None
                    session.commit()

        except:
            traceback.print_exc()
            with open("error.txt", "a+") as f:
                f.write(filename + "\n")
            session.rollback()
            continue
Exemplo n.º 9
0
    def post(self):
        """
        Train line creation API, **JWT required**

        The body should be a JSON dictionary including the following attribute(s):
        - `train_name`: `str`
        - `line`: `list` of dictionaries containing:
            - `dep_station`: `str`
            - `arv_station`: `str`
            - `dep_time`: `str`
            - `arv_time`: `str`
            - `price`: `dict` containing at least one of:
                - `seat_type_1`, `str`
                - `seat_type_2`, `str`
                - `seat_type_3`, `str`
                - `seat_type_4`, `str`
                - `seat_type_5`, `str`
                - `seat_type_6`, `str`
                - `seat_type_7`, `str`

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if creation is successful
        - `error`: `str`, shown if `code != 0`
        - `result`: `str`, shown if `code == 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            train_name = body.get('train_name')
            if not train_name:
                return jsonify(code=11, error='火车名为空')
            train: Train = session.query(Train).filter(
                Train.train_name == train_name).first()
            if train:
                return jsonify(code=11, error='火车名已存在!')
            new_train = Train(train_name=train_name)
            session.add(new_train)
            session.commit()
            session.flush()

            train_id = new_train.train_id
            interval_id_list = []
            interval_list = body.get('line')
            seat_type_list = []
            for interval_info in interval_list:
                dep_station = session.query(Station.station_id) \
                    .filter(Station.station_name == interval_info['dep_station'], Station.available == True) \
                    .first() \
                    .station_id
                arv_station = session.query(Station.station_id) \
                    .filter(Station.station_name == interval_info['arv_station'], Station.available == True) \
                    .first() \
                    .station_id
                dep_datetime = None
                arv_datetime = None
                if 'dep_time' in interval_info.keys(
                ) and interval_info['dep_time']:
                    dep_datetime = time(
                        *list(map(int, interval_info['dep_time'].split(':'))))
                if 'arv_time' in interval_info.keys(
                ) and interval_info['arv_time']:
                    arv_datetime = time(
                        *list(map(int, interval_info['arv_time'].split(':'))))
                new_interval = Interval(train_id=train_id,
                                        dep_station=dep_station,
                                        arv_station=arv_station,
                                        dep_datetime=dep_datetime,
                                        arv_datetime=arv_datetime)
                session.add(new_interval)
                session.commit()
                session.flush()

                interval_id = new_interval.interval_id
                interval_id_list.append(interval_id)
                price_dict = interval_info['price']
                for k, v in price_dict.items():
                    seat_type_id = int(k[-1])
                    if seat_type_id not in seat_type_list:
                        seat_type_list.append(seat_type_id)
                    if not v:
                        continue
                    seat_price = max(0.01, abs(float(v)))
                    new_price = Price(interval_id=interval_id,
                                      seat_type_id=seat_type_id,
                                      price=seat_price)
                    session.add(new_price)
                session.commit()
            session.execute(func.add_seats(seat_type_list, train_id))

            for index, interval_id in enumerate(interval_id_list):
                interval = session.query(Interval).filter(
                    Interval.interval_id == interval_id).first()
                interval.next_id = interval_id_list[
                    index + 1] if index < len(interval_id_list) - 1 else None
                interval.prev_id = interval_id_list[index -
                                                    1] if index > 0 else None
                session.commit()
            return jsonify(code=0, result='线路添加成功')
        except:
            traceback.print_exc()
            session.rollback()
            return jsonify(code=12, error='添加失败,请检查输入是否合法')
        finally:
            session.close()
Exemplo n.º 10
0
    def post(self):
        """
        Station addition API, **JWT required**

        The body should be a JSON dictionary including the following attribute(s):
        - `province_name`: `str`
        - `city_name`: `str`
        - `district_name`: `str`
        - `station_name`: `str`

        **return**: A JSON dictionary with values
        - `code`: `int`, equals to 0 if addition is successful
        - `result`: `str` for success message, shown if `code == 0`
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            body = request.get_json()
            province_name = body.get('province_name')
            city_name = body.get('city_name')
            district_name = body.get('district_name')
            station_name = body.get('station_name')
            station = session.query(Station) \
                .filter(Station.station_name == station_name) \
                .first()
            exist_flag = False
            if station:
                if station.available:
                    return jsonify(code=1, error="站点已存在!")
                else:
                    district = session.query(District) \
                        .filter(District.district_id == station.district_id) \
                        .first()
                    if district.district_name == district_name:
                        station.available = True
                        session.commit()
                        return jsonify(code=0,
                                       result='站点{}添加成功'.format(station_name))
                    exist_flag = True
            province = session.query(Province).filter(
                Province.province_name == province_name).first()
            if province is None:
                new_province = Province(province_name=province_name)
                session.add(new_province)
                session.commit()
                province = session.query(Province).filter(
                    Province.province_name == province_name).first()
            city = session.query(City).filter(
                City.city_name == city_name).first()
            if city is None:
                new_city = City(city_name=city_name,
                                province_id=province.province_id)
                session.add(new_city)
                session.commit()
                city = session.query(City).filter(
                    City.city_name == city_name).first()
            district = session.query(District).filter(
                District.district_name == district_name).first()
            if district is None:
                new_district = District(district_name=district_name,
                                        city_id=city.city_id)
                session.add(new_district)
                session.commit()
                district = session.query(District).filter(
                    District.district_name == district_name).first()
            if exist_flag:
                station.district_id = district.district_id
                station.available = True
            else:
                station = Station(station_name=station_name,
                                  district_id=district.district_id)
                session.add(station)
            session.commit()
            return jsonify(code=0, result='站点{}添加成功'.format(station_name))
        except:
            traceback.print_exc()
            session.rollback()
            return jsonify(code=1, error='添加失败,站点已存在或地址信息有误。')
        finally:
            session.close()
Exemplo n.º 11
0
    def delete(self):
        """
        Ticket refund API, **JWT required**

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if deletion is successful
        - `result`: `str`, shown if `code == 0`
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            user_id = get_jwt_identity()
            body = request.get_json()
            order_id = body.get('order_id')
            # The delete function is to set the order status "cancelled", set ticket available false,
            # and released the occupied seat.
            current_order: Order = session.query(Order).filter(
                Order.order_id == order_id).first()
            # print(current_order.user_id, user_id)
            if int(user_id) != int(current_order.user_id):
                return jsonify(code=100, error='非法退票操作!')
            current_order.order_status = "cancelled"
            session.commit()
            session.flush()
            current_ticket: Ticket = session.query(Ticket).filter(
                Ticket.ticket_id == current_order.ticket_id).first()
            current_ticket.available = False
            session.commit()
            session.flush()
            first_interval = current_ticket.first_interval
            last_interval = current_ticket.last_interval
            current_seat: Seat = session.query(Seat).filter(
                Seat.seat_id == current_ticket.seat_id).first()
            train_id = session.query(Train.train_id).join(
                Interval, Interval.train_id == Train.train_id).filter(
                    Interval.interval_id == first_interval,
                    Interval.available == True,
                    Train.available == True).first()

            # Here to release the seat
            train_name = session.query(Train.train_name).filter(
                Train.train_id == train_id,
                Train.available == True).first().train_name
            interval_list = get_interval_list(train_name, session)
            # successive_train_rec = get_interval_list(train_name, session)
            # interval_list = session.query(successive_train_rec.c.interval_id) \
            #     .order_by(successive_train_rec.c.interval_id) \
            #     .all()
            first_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == first_interval) \
                .first() \
                .interval_no
            last_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == last_interval) \
                .first() \
                .interval_no
            current_seat.occupied = bin(
                int(current_seat.occupied, 2)
                & int('0' * (last_index - first_index + 1), 2) <<
                (40 - last_index))[2:].zfill(40)
            session.commit()
            session.flush()
            return jsonify(code=0, result="操作成功,票已失效")
        except:
            session.rollback()
            return jsonify(code=10, error='操作失败,请联系管理员')
        finally:
            session.close()
Exemplo n.º 12
0
    def post(self):
        """
        Train order API, **JWT required**

        **return**: A JSON dictionary with values:
        - `code`: `int`, equals to 0 if order is successful
        - `result`: `dict` with values, shown if `code == 0`:
            - `order_id`: `int`
        - `error`: `str`, shown if `code != 0`
        """
        session = DBSession()
        try:
            user_id = get_jwt_identity()
            body = request.get_json()
            first_interval = int(body.get('first_interval'))
            last_interval = int(body.get('last_interval'))
            seat_class = body.get('seat_class')
            train_name = body.get('train_name')
            # successive_train_rec = get_interval_list(train_name, session)
            interval_list = get_interval_list(train_name, session)
            # interval_list = session.query(successive_train_rec.c.interval_id) \
            #     .order_by(successive_train_rec.c.interval_id) \
            #     .all()
            first_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == first_interval) \
                .first() \
                .interval_no
            last_index = session.query(interval_list.c.interval_no) \
                .filter(interval_list.c.interval_id == last_interval) \
                .first() \
                .interval_no
            seat = session.query(Seat) \
                .join(Train, Train.train_id == Seat.train_id) \
                .filter(Train.train_name == train_name,
                        Seat.seat_type_id == seat_class,
                        func.cast(func.substring(Seat.occupied, first_index, last_index - first_index + 1),
                                  BIGINT) == 0) \
                .first()
            if seat is None:
                return jsonify(code=404, error='当前区间无余票!')
            seat.occupied = bin(
                int(seat.occupied, 2)
                | int('1' * (last_index - first_index + 1), 2) <<
                (40 - last_index))[2:].zfill(40)
            new_ticket = Ticket(first_interval=first_interval,
                                last_interval=last_interval,
                                seat_id=seat.seat_id,
                                available=False)
            session.add(new_ticket)
            session.commit()
            session.flush()
            price = session.query(func.sum(Price.price).label('price')) \
                .join(interval_list, Price.interval_id == interval_list.c.interval_id) \
                .filter(Price.seat_type_id == seat_class, interval_list.c.interval_no <= last_index,
                        interval_list.c.interval_no >= first_index) \
                .first()
            new_order = Order(order_status='unpaid',
                              user_id=user_id,
                              ticket_id=new_ticket.ticket_id,
                              price=price)
            session.add(new_order)
            session.commit()
            session.flush()
            return jsonify(code=0, result={'order_id': new_order.order_id})
        except:
            session.rollback()
            return jsonify(code=10, error='订票失败')
        finally:
            session.close()