Beispiel #1
0
class Like(db.Model):
    __tablename__ = 'Like'

    liker_id = db.Column(
        db.Integer,
        db.ForeignKey(
            'Customer.id',
            ondelete="CASCADE"
        ),
        primary_key=True
    )

    liker = relationship(
        'Customer',
        back_populates='likes'
    )

    restaurant_id = db.Column(
        db.Integer,
        db.ForeignKey(
            'Restaurant.id',
            ondelete="CASCADE"
        ),
        primary_key=True
    )

    restaurant = relationship(
        'Restaurant',
        back_populates='likes'
    )

    timestamp = db.Column(db.DateTime, default=datetime.datetime.utcnow)

    def __init__(self, *args, **kw):
        super(Like, self).__init__(*args, **kw)
class RestaurantRating(db.Model):
    MIN_VALUE = 0
    MAX_VALUE = 10

    __tablename__ = 'RestaurantRating'

    REVIEW_MAX_LENGTH = 200

    customer_id = db.Column(db.Integer,
                            db.ForeignKey('Customer.id'),
                            primary_key=True)

    customer = relationship('Customer', back_populates='ratings')

    restaurant_id = db.Column(db.Integer,
                              db.ForeignKey('Restaurant.id'),
                              primary_key=True)

    restaurant = relationship('Restaurant', back_populates='ratings')

    value = db.Column(db.SmallInteger, nullable=False)

    review = db.Column(db.String(length=REVIEW_MAX_LENGTH, ), nullable=True)

    timestamp = db.Column(db.DateTime, default=datetime.datetime.utcnow)

    def __init__(self, customer_id, restaurant_id, value: int, review=None):
        self.customer_id = customer_id
        self.restaurant_id = restaurant_id
        self.value = value
        self.review = review

    @staticmethod
    def check_value(value: int):
        if value < RestaurantRating.MIN_VALUE or value > RestaurantRating.MAX_VALUE:
            raise ValueError('Invalid value for rating!')

    @staticmethod
    def check_review(review: str):
        if len(review) > RestaurantRating.REVIEW_MAX_LENGTH:
            raise ValueError(
                'Review\'s length must not be greater than MAX_SIZE')

    def set_value(self, value):
        RestaurantRating.check_value(value)
        self.value = value

    def set_review(self, review):
        RestaurantRating.check_review(review)
        self.review = review

    def get_how_long_ago(self):
        return timeago.format(datetime.datetime.now(), self.timestamp)
Beispiel #3
0
class Authority(User):
    __tablename__ = 'Authority'

    id = db.Column(db.Integer,
                   db.ForeignKey('User.id', ondelete="CASCADE"),
                   primary_key=True)
    name = db.Column(db.Unicode(128))
    city = db.Column(db.Unicode(128))
    address = db.Column(db.Unicode(128))
    phone = db.Column(db.Unicode(128))

    __mapper_args__ = {
        'polymorphic_identity': 'authority',
    }

    def __init__(self, *args, **kw):
        super(Authority, self).__init__(*args, **kw)
        self._authenticated = False
class Table(db.Model):
    __tablename__ = 'Table'

    MIN_TABLE_CAPACITY = 1
    MAX_TABLE_CAPACITY = 15

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    restaurant_id = db.Column(db.Integer, db.ForeignKey('Restaurant.id', ondelete="CASCADE"))
    restaurant = relationship('Restaurant', back_populates="tables")
    capacity = db.Column(db.Integer)

    def __init__(self, capacity, restaurant):
        self.capacity = capacity
        self.restaurant = restaurant

    def set_capacity(self, capacity):
        if capacity < self.MIN_TABLE_CAPACITY or capacity > self.MAX_TABLE_CAPACITY:
            raise ValueError('You can\'t set a negative value, zero or greater than '
                             + str(self.MAX_TABLE_CAPACITY))
        self.capacity = capacity

    def set_restaurant(self, restaurant):
        self.restaurant = restaurant
class Operator(User):
    __tablename__ = 'Operator'

    id = db.Column(db.Integer,
                   db.ForeignKey('User.id', ondelete='CASCADE'),
                   primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'operator',
    }

    def __init__(self, *args, **kw):
        super(Operator, self).__init__(*args, **kw)
        self._authenticated = False

    def new_notifications(self):
        return 0
Beispiel #6
0
class Operator(User):
    __tablename__ = 'Operator'

    id = db.Column(db.Integer,
                   db.ForeignKey('User.id', ondelete='CASCADE'),
                   primary_key=True)
    restaurant = relationship('Restaurant',
                              uselist=False,
                              back_populates="owner")

    __mapper_args__ = {
        'polymorphic_identity': 'operator',
    }

    def __init__(self, *args, **kw):
        super(Operator, self).__init__(*args, **kw)
        self._authenticated = False

    def set_restaurant(self, restaurant):
        self.restaurant = restaurant

    def new_notifications(self):
        return 0
class User(UserMixin, db.Model):
    __tablename__ = 'User'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.Unicode(128), nullable=False, unique=True)
    password = db.Column(db.Unicode(128))
    is_active = db.Column(db.Boolean, default=True)
    is_admin = db.Column(db.Boolean, default=False)
    authenticated = db.Column(db.Boolean, default=True)
    is_anonymous = False
    type = db.Column(db.Unicode(128))

    __mapper_args__ = {'polymorphic_identity': 'user', 'polymorphic_on': type}

    def __init__(self, *args, **kw):
        super(User, self).__init__(*args, **kw)
        self.authenticated = False

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def set_email(self, email):
        self.email = email

    def is_authenticated(self):
        return self.authenticated

    def authenticate(self, password):
        checked = check_password_hash(self.password, password)
        self.authenticated = checked
        return self.authenticated

    def is_lha(self):
        return self.type == 'authority'

    def is_rest_operator(self):
        return self.type == 'operator'

    def is_customer(self):
        return self.type == 'customer'
Beispiel #8
0
class Reservation(db.Model):
    __tablename__ = 'Reservation'

    MAX_TIME_RESERVATION = 3

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, db.ForeignKey('User.id',
                                                  ondelete="CASCADE"))
    user = relationship('User', foreign_keys='Reservation.user_id')
    table_id = db.Column(db.Integer,
                         db.ForeignKey('Table.id', ondelete="CASCADE"))
    table = relationship('Table')
    restaurant_id = db.Column(db.Integer, db.ForeignKey('Restaurant.id'))
    restaurant = relationship("Restaurant", back_populates="reservations")
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)
    people_number = db.Column(db.Integer)
    start_time = db.Column(db.DateTime)
    end_time = db.Column(db.DateTime)
    is_confirmed = db.Column(db.Boolean, default=False)

    def __init__(self, user, table, restaurant, people_number, start_time):
        self.user = user
        self.table = table
        self.restaurant = restaurant
        self.people_number = people_number
        self.start_time = start_time
        self.set_end_time_by_avg_stay(restaurant.avg_stay)

    @staticmethod
    def check_time(start_time, end_time):
        actual_time = datetime.utcnow()
        if start_time >= end_time:
            raise ValueError('The start time cannot be greater than end_time')

    def set_end_time_by_avg_stay(self, avg_stay):
        if avg_stay is None or avg_stay == 0:
            self.end_time = self.start_time + timedelta(
                hours=self.MAX_TIME_RESERVATION)
        else:
            avg_stay = self.restaurant.avg_stay
            h_avg_stay = avg_stay // 60
            m_avg_stay = avg_stay - (h_avg_stay * 60)
            self.end_time = self.start_time + timedelta(hours=h_avg_stay,
                                                        minutes=m_avg_stay)

    def set_user(self, user):
        self.user = user

    def set_table(self, table):
        self.table = table

    def set_restaurant(self, restaurant):
        self.restaurant = restaurant

    def set_people_number(self, people_number):
        self.people_number = people_number

    def set_start_time(self, start_time):
        self.start_time = start_time
        self.set_end_time(start_time +
                          timedelta(hours=self.MAX_TIME_RESERVATION))

    def set_end_time(self, end_time):
        Reservation.check_time(self.start_time, end_time)
        self.end_time = end_time

    def set_is_confirmed(self):
        self.is_confirmed = True
Beispiel #9
0
class Restaurant(db.Model):
    __tablename__ = 'Restaurant'

    MAX_STRING_LENGTH = 100

    # taken from Google Maps bounds
    MAX_LAT = 90
    MIN_LAT = -90
    MAX_LON = 180
    MIN_LON = -180

    MAX_PHONE_LEN = 25

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(length=MAX_STRING_LENGTH))
    address = db.Column(db.String(length=MAX_STRING_LENGTH))
    city = db.Column(db.String(length=MAX_STRING_LENGTH))
    lat = db.Column(db.Float)
    lon = db.Column(db.Float)
    phone = db.Column(db.String(length=MAX_PHONE_LEN))
    menu_type = db.Column(db.String(length=MAX_STRING_LENGTH))
    measures = db.Column(db.Unicode(), default="")
    is_open = db.Column(db.Boolean, default=False)
    owner_id = db.Column(
        db.Integer,
        db.ForeignKey('Operator.id'),
    )
    avg_stay = db.Column(db.Integer, )
    owner = relationship('Operator', back_populates='restaurant')
    reservations = relationship("Reservation", back_populates="restaurant")
    tables = relationship("Table", back_populates="restaurant")
    availabilities = relationship("RestaurantAvailability",
                                  back_populates="restaurant")
    ratings = relationship('RestaurantRating', back_populates='restaurant')
    likes = relationship('Like', back_populates='restaurant')

    def __init__(self, name, address, city, lat, lon, phone, menu_type):
        Restaurant.check_phone_number(phone)
        self.name = name
        self.address = address
        self.city = city
        self.lat = lat
        self.lon = lon
        self.phone = phone
        self.menu_type = menu_type
        self.avg_stay = 0
        # this can be set to False by LHA
        self.is_open = True

    @staticmethod
    def check_phone_number(phone):
        if len(phone) > Restaurant.MAX_PHONE_LEN or len(phone) <= 0:
            raise ValueError("Invalid phone number")

    @staticmethod
    def check_string_attribute(string_attribute):
        if len(string_attribute) > Restaurant.MAX_STRING_LENGTH or len(
                string_attribute) <= 0:
            raise ValueError("Invalid attribute length")

    def set_name(self, name):
        Restaurant.check_string_attribute(name)
        self.name = name

    def set_address(self, address):
        Restaurant.check_string_attribute(address)
        self.address = address
        location = geolocator.geocode(address + " " + self.city)
        lat = 0
        lon = 0
        if location is not None:
            lat = location.latitude
            lon = location.longitude
        self.set_lat(lat)
        self.set_lon(lon)

    def set_city(self, city):
        Restaurant.check_string_attribute(city)
        self.city = city
        location = geolocator.geocode(self.address + " " + city)
        lat = 0
        lon = 0
        if location is not None:
            lat = location.latitude
            lon = location.longitude
        self.set_lat(lat)
        self.set_lon(lon)

    def set_lat(self, lat):
        if self.MIN_LAT <= lat <= self.MAX_LAT:
            self.lat = lat
        else:
            raise ValueError("Invalid latitude value")

    def set_lon(self, lon):
        if self.MIN_LON <= lon <= self.MAX_LON:
            self.lon = lon
        else:
            raise ValueError("Invalid longitude value")

    def set_phone(self, phone):
        Restaurant.check_phone_number(phone)
        self.phone = phone

    def set_menu_type(self, menu_type):
        Restaurant.check_string_attribute(menu_type)
        self.menu_type = menu_type

    def set_measures(self, measure):
        self.measures = measure

    def set_is_open(self, is_open):
        self.is_open = is_open

    def likes_count(self):
        return len(self.likes)

    def set_avg_stay(self, avg_stay):
        self.avg_stay = avg_stay

    def is_open_date(self, when=datetime.datetime.now()):
        for av in self.availabilities:
            if av.day == av.week_days[when.weekday()]:
                if av.start_time < when.time() < av.end_time:
                    return True and self.is_open

        return False
Beispiel #10
0
class Reservation(db.Model):
    __tablename__ = 'Reservation'

    MAX_TIME_RESERVATION = 3

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    user_id = db.Column(db.Integer)
    table_id = db.Column(db.Integer)
    restaurant_id = db.Column(db.Integer)

    timestamp = db.Column(db.DateTime, default=datetime.utcnow)
    people_number = db.Column(db.Integer)
    start_time = db.Column(db.DateTime)
    end_time = db.Column(db.DateTime)
    is_confirmed = db.Column(db.Boolean, default=False)

    def serialize(self):
        def r(v):
            if type(v) == datetime:
                return v.__str__()
            else:
                return v

        return dict([(k, r(v)) for k, v in self.__dict__.items()
                     if k[0] != '_'])

    def __init__(self, user_id, table_id, restaurant_id, people_number,
                 start_time):
        self.user_id = user_id
        self.table_id = table_id
        self.restaurant_id = restaurant_id
        self.people_number = people_number
        self.start_time = start_time
        self.end_time = self.start_time + timedelta(
            hours=self.MAX_TIME_RESERVATION)
        # self.set_end_time_by_avg_stay(restaurant_id.avg_stay)

    @staticmethod
    def check_time(start_time, end_time):
        actual_time = datetime.utcnow()
        if start_time >= end_time:
            raise ValueError('The start time cannot be greater than end_time')

    """    
    def set_end_time_by_avg_stay(self, avg_stay):
        if avg_stay is None or avg_stay == 0:
            self.end_time = self.start_time + timedelta(hours=self.MAX_TIME_RESERVATION)
        else:
            avg_stay = self.restaurant_id.avg_stay
            h_avg_stay = avg_stay//60
            m_avg_stay = avg_stay - (h_avg_stay*60)
            self.end_time = self.start_time + timedelta(hours=h_avg_stay, minutes=m_avg_stay)
    """

    def set_user_id(self, user_id):
        self.user_id = user_id

    def set_table_id(self, table_id):
        self.table_id = table_id

    def set_restaurant_id(self, restaurant_id):
        self.restaurant_id = restaurant_id

    def set_people_number(self, people_number):
        self.people_number = people_number

    def set_start_time(self, start_time):
        self.start_time = start_time
        self.set_end_time(start_time +
                          timedelta(hours=self.MAX_TIME_RESERVATION))

    def set_end_time(self, end_time):
        Reservation.check_time(self.start_time, end_time)
        self.end_time = end_time

    def set_is_confirmed(self):
        self.is_confirmed = True
Beispiel #11
0
class Customer(User):
    SOCIAL_CODE_LENGTH = 16

    __tablename__ = 'Customer'

    MAX_PHONE_LEN = 25

    id = db.Column(db.Integer,
                   db.ForeignKey('User.id', ondelete="CASCADE"),
                   primary_key=True)
    firstname = db.Column(db.Unicode(128))
    lastname = db.Column(db.Unicode(128))
    birthdate = db.Column(db.Date)
    social_number = db.Column(db.Unicode(SOCIAL_CODE_LENGTH), default="")
    health_status = db.Column(db.Boolean, default=False)
    phone = db.Column(db.String(length=MAX_PHONE_LEN))
    likes = relationship('Like', back_populates='liker')
    ratings = relationship('RestaurantRating', back_populates='customer')
    last_notification_read_time = db.Column(db.DateTime,
                                            default=datetime.utcnow)

    __mapper_args__ = {
        'polymorphic_identity': 'customer',
    }

    def __init__(self, *args, **kw):
        super(Customer, self).__init__(*args, **kw)
        self._authenticated = False

    @staticmethod
    def check_phone_number(phone):
        if len(phone) > Customer.MAX_PHONE_LEN or len(phone) <= 0:
            raise ValueError("Invalid phone number")

    def set_phone(self, phone):
        Customer.check_phone_number(phone)
        self.phone = phone

    def set_firstname(self, name):
        self.firstname = name

    def set_lastname(self, name):
        self.lastname = name

    def set_birthday(self, birthday):
        self.birthdate = birthday

    def set_health_status(self, status):
        self.health_status = status

    @staticmethod
    def check_social_number(social_number):
        if len(social_number) != Customer.SOCIAL_CODE_LENGTH:
            raise ValueError("Invalid Social Number length")

    def set_social_number(self, social_number):
        Customer.check_social_number(social_number)
        self.social_number = social_number

    def set_last_notification_read_time(self, read_time):
        self.last_notification_read_time = read_time

    def new_notifications(self):
        return 0
Beispiel #12
0
class User(db.Model):
    __tablename__ = 'User'

    SERIALIZE_LIST = ['id', 'email', 'is_active', 'authenticated', 'is_anonymous', 'type']

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.Unicode(128), nullable=False, unique=True)
    password = db.Column(db.Unicode(128))
    is_active = db.Column(db.Boolean, default=True)
    is_admin = db.Column(db.Boolean, default=False)
    authenticated = db.Column(db.Boolean, default=True)
    is_anonymous = False
    type = db.Column(db.Unicode(128))

    __mapper_args__ = {
        'polymorphic_identity': 'user',
        'polymorphic_on': type
    }

    def __init__(self, *args, **kw):
        super(User, self).__init__(*args, **kw)
        self.authenticated = False

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def set_email(self, email):
        self.email = email

    def is_authenticated(self):
        return self.authenticated

    def authenticate(self, password):
        checked = check_password_hash(self.password, password)
        self.authenticated = checked
        return self.authenticated

    def is_lha(self):
        return self.type == 'authority'

    def is_rest_operator(self):
        return self.type == 'operator'

    def is_customer(self):
        return self.type == 'customer'

    # def encode_auth_token(self, user_id):
    #     """
    #     Generates the Auth Token
    #     :return: string
    #     """
    #     try:
    #         payload = {
    #             "iss": JWT_ISSUER,
    #             "iat": datetime.datetime.utcnow(),
    #             "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=JWT_LIFETIME_SECONDS),
    #             "sub": str(user_id),
    #         }
    #         return jwt.encode(
    #             payload,
    #             JWT_SECRET,
    #             algorithm=JWT_ALGORITHM
    #         )
    #     except Exception as e:
    #         return e
    #
    # @staticmethod
    # def decode_auth_token(auth_token):
    #     """
    #     Decodes the auth token
    #     :param auth_token:
    #     :return: integer|string
    #     """
    #     try:
    #         return jwt.decode(auth_token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
    #     except jwt.ExpiredSignatureError:
    #         return 'Signature expired. Please log in again.'
    #     except jwt.InvalidTokenError:
    #         return 'Invalid token. Please log in again.'

    def serialize(self):
        return dict([(k, self.__getattribute__(k)) for k in self.SERIALIZE_LIST])
Beispiel #13
0
class Customer(User):
    __tablename__ = 'Customer'

    MAX_PHONE_LEN = 25
    SOCIAL_CODE_LENGTH = 16
    LIST = [
        'firstname', 'lastname', 'birthdate', 'social_number', 'health_status',
        'phone'
    ]

    id = db.Column(db.Integer,
                   db.ForeignKey('User.id', ondelete="CASCADE"),
                   primary_key=True)
    firstname = db.Column(db.Unicode(128))
    lastname = db.Column(db.Unicode(128))
    birthdate = db.Column(db.Date)
    social_number = db.Column(db.Unicode(SOCIAL_CODE_LENGTH), default="")
    health_status = db.Column(db.Boolean, default=False)
    health_status_change_datetime = db.Column(db.DateTime,
                                              default=datetime.utcnow)
    phone = db.Column(db.String(length=MAX_PHONE_LEN))
    last_notification_read_time = db.Column(db.DateTime,
                                            default=datetime.utcnow)

    __mapper_args__ = {
        'polymorphic_identity': 'customer',
    }

    def __init__(self, *args, **kw):
        super(Customer, self).__init__(*args, **kw)
        self._authenticated = False

    @staticmethod
    def check_phone_number(phone):
        if len(phone) > Customer.MAX_PHONE_LEN or len(phone) <= 0:
            raise ValueError("Invalid phone number")

    def set_phone(self, phone):
        Customer.check_phone_number(phone)
        self.phone = phone

    def set_firstname(self, name):
        self.firstname = name

    def set_lastname(self, name):
        self.lastname = name

    def set_birthday(self, birthday):
        self.birthdate = birthday

    def set_health_status(self, status):
        self.health_status = status
        if self.health_status:
            self.health_status_change_datetime = datetime.utcnow()

    @staticmethod
    def check_social_number(social_number):
        if len(social_number) != Customer.SOCIAL_CODE_LENGTH:
            raise ValueError("Invalid Social Number length")

    def set_social_number(self, social_number):
        Customer.check_social_number(social_number)
        self.social_number = social_number

    def set_last_notification_read_time(self, read_time):
        self.last_notification_read_time = read_time

    def serialize(self):
        p_ser = dict([(k, self.__getattribute__(k))
                      for k in self.SERIALIZE_LIST])
        c_ser = dict([(k, self.__getattribute__(k)) for k in self.LIST])
        return dict(c_ser, **p_ser)