Ejemplo n.º 1
0
class ReturnTime(db.Model):
    __tablename__ = "return_time"
    id = db.Column(db.Integer, primary_key=True)
    accepted_return_time = db.Column(db.DateTime, nullable=False)
    location = db.Column(db.String(120), nullable=False)

    request_id = db.Column(db.Integer, db.ForeignKey('return_request.id'))
    request = db.relationship(
        'ReturnRequest',
        backref=db.backref(
            'will_be_returned_on',
            lazy='dynamic',
            cascade="all, delete-orphan",
        ),
    )

    def __init__(self, return_time, request, location):
        self.accepted_return_time = return_time
        self.request = request
        self.location = location

    def confirmReturned(self):
        # The item should be marked as available again.
        tx = self.request.transaction
        tx.is_complete = True
        tx.is_with_rentee = False
        tx.listed_item.is_available = True

        # All return request objects should be deleted.
        db.session.delete(self.request)
        db.session.commit()
        return True

    def __repr__(self):
        tx = self.request.transaction
        item = tx.listed_item
        return "{0} will return {1}'s {2} on {3} at {4}".format(
            tx.rentee.username,
            item.owner.username,
            item.item_type.name,
            self.accepted_return_time,
            self.location,
        )
Ejemplo n.º 2
0
class BlogCategory(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(128), unique=True)
    slug = db.Column(db.String(128), unique=True, index=True)

    order = db.Column(db.SmallInteger, default=0)

    description = db.Column(db.Text, nullable=True)

    parent_id = db.Column(db.Integer,
                          db.ForeignKey('blog_category.id'),
                          index=True)
    parent = db.relationship(lambda: BlogCategory,
                             remote_side=id,
                             backref=db.backref('sub_categories',
                                                lazy='dynamic'))
    __mapper_args__ = {'order_by': order}

    def __repr__(self):
        return '%s' % self.title
Ejemplo n.º 3
0
class ProposedReturnTime(db.Model):
    __tablename__ = "proposed_return_time"
    id = db.Column(db.Integer, primary_key=True)
    location = db.Column(db.String(80), nullable=False)
    proposed_timestamp = db.Column(db.DateTime, nullable=False)
    can_pickup_until = db.Column(db.DateTime, nullable=False)

    request_id = db.Column(db.Integer, db.ForeignKey('return_request.id'))
    request = db.relationship(
        'ReturnRequest',
        backref=db.backref('times_to_return',
                           lazy='dynamic',
                           cascade="all, delete-orphan"),
    )

    def __init__(self, start, stop, request, location):
        self.location = location
        self.proposed_timestamp = start
        self.can_pickup_until = stop
        self.request = request

    def returnOn(self, return_time):
        r = ReturnTime(
            return_time=return_time,
            request=self.request,
            location=self.location,
        )
        return r

    def __repr__(self):
        tx = self.request.transaction
        item = tx.listed_item
        return ("{0} is available to recieve {1} from {2}"
                " between {3} and {4} at {5}".format(
                    item.owner.username,
                    item.item_type.name,
                    tx.rentee.username,
                    self.proposed_timestamp,
                    self.can_pickup_until,
                    self.location,
                ))
Ejemplo n.º 4
0
class BlogPost(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(128), unique=True)
    slug = db.Column(db.String(128), unique=True, index=True)

    content = db.Column(db.Text())
    created = db.Column(db.DateTime,
                        server_default=db.func.now(),
                        onupdate=db.func.now())
    modified = db.Column(db.DateTime, server_default=db.func.now())

    category_id = db.Column(db.Integer,
                            db.ForeignKey('blog_category.id'),
                            index=True)
    category = db.relationship(lambda: BlogCategory,
                               backref=db.backref('posts', lazy='dynamic'))

    excerpt = db.Column(db.Text, nullable=True)

    tags = db.Column(ARRAY(db.String(64)), nullable=True, index=True)

    def __repr__(self):
        return self.title
Ejemplo n.º 5
0
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, unique=True, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    first_name = db.Column(db.String(20))
    last_name = db.Column(db.String(20))
    gender = db.Column(db.String(20))
    birth_date = db.Column(db.Date())
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    image_file = db.Column(db.String(30))
    bio = db.Column(db.String(240))
    travels = db.relationship('Travel',
                              backref='traveler',
                              lazy='dynamic',
                              cascade='all, delete-orphan',
                              passive_deletes=True)
    followed = db.relationship('Follow',
                               foreign_keys=[Follow.follower_id],
                               backref=db.backref('follower', lazy='joined'),
                               lazy='dynamic',
                               cascade='all, delete-orphan',
                               passive_deletes=True)
    followers = db.relationship('Follow',
                                foreign_keys=[Follow.followed_id],
                                backref=db.backref('followed', lazy='joined'),
                                lazy='dynamic',
                                cascade='all, delete-orphan',
                                passive_deletes=True)
    subscribed_travels = db.relationship('Subscribe',
                                         backref=db.backref('subscriber',
                                                            lazy='joined'),
                                         lazy='dynamic',
                                         cascade='all, delete-orphan',
                                         passive_deletes=True)

    def __repr__(self):
        return f"User('{self.username}', '{self.email}', '{self.image_file}')"

    def to_json(self):
        json_user = {
            'id': self.id,
            'username': self.username,
            'followers': len(self.followers.all()),
            'followed': len(self.followed.all()),
            'subscribed_travels': len(self.subscribed_travels.all()),
            'bio': self.bio,
            'first_name': self.first_name,
            'last_name': self.last_name
        }
        return json_user

    def get_posts_as_list(self):
        userPosts = [i.to_json() for i in self.travels]
        return userPosts

    def get_posts_as_list_with_sub(self, other_user):
        userPosts = [
            i.to_json_with_sub_check(other_user) for i in self.travels
        ]
        return userPosts

    def getfollowers(self):
        userfollowers = [i.to_json() for i in self.followers]
        return userfollowers

    def getfollowings(self):
        userfollowed = [i.to_json() for i in self.followed]
        return userfollowed
Ejemplo n.º 6
0
class Travel(db.Model):
    id = db.Column(db.Integer, primary_key=True, unique=True)
    title = db.Column(db.Text, nullable=False)
    date_posted = db.Column(db.DateTime,
                            nullable=False,
                            default=datetime.utcnow)
    user_id = db.Column(db.Integer,
                        db.ForeignKey('user.id', ondelete='CASCADE'),
                        nullable=False)
    start_date = db.Column(db.DateTime, nullable=False)
    end_date = db.Column(db.DateTime, nullable=False)
    country = db.Column(db.Text, nullable=False)
    city = db.Column(db.Text, nullable=False)
    latitude = db.Column(db.Text, nullable=False)
    longitude = db.Column(db.Text, nullable=False)
    content = db.Column(db.Text, nullable=False)
    subscribed_users = db.relationship('Subscribe',
                                       backref=db.backref('post',
                                                          lazy='joined'),
                                       lazy='dynamic',
                                       cascade='all, delete-orphan',
                                       passive_deletes=True)

    def __repr__(self):
        return f"Travel('{self.date_posted}')"

    def to_json(self):
        json_travel = {
            'city': self.city,
            'country': self.country,
            'content': self.content,
            'title': self.title,
            'userid': self.user_id,
            'id': self.id,
            'start_date': self.start_date,
            'end_date': self.end_date,
            'date_posted': self.date_posted,
            'latitude': self.latitude,
            'longitude': self.longitude,
            'username': self.traveler.username,
            'profile_pic': self.traveler.image_file
        }
        return json_travel

    def to_json_with_sub_check(self, checkusersub):
        sub = self.subscribed_users.filter_by(
            subscriber_id=checkusersub).first()
        if not sub:
            isSub = False
        else:
            isSub = True
        json_travel = {
            'city': self.city,
            'country': self.country,
            'content': self.content,
            'title': self.title,
            'userid': self.user_id,
            'id': self.id,
            'isSub': isSub,
            'start_date': self.start_date,
            'end_date': self.end_date,
            'date_posted': self.date_posted,
            'latitude': self.latitude,
            'longitude': self.longitude,
            'username': self.traveler.username,
            'profile_pic': self.traveler.image_file
        }
        return json_travel
Ejemplo n.º 7
0
class Building(db.Model, DictBase):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String, nullable=False)
    title_info = db.Column(db.String)
    address = db.Column(db.String, nullable=False)
    year_build_start = db.Column(db.Integer, nullable=False)
    year_build_end = db.Column(db.Integer, nullable=False)
    latitude = db.Column(db.Float, nullable=False)
    longitude = db.Column(db.Float, nullable=False)

    architects = db.relationship('Architect',
                                 secondary=building_architect,
                                 backref=db.backref('buildings', lazy='dynamic'))
    styles = db.relationship('Style',
                             secondary=building_style,
                             backref=db.backref('buildings', lazy='dynamic'))

    leading_img_path = db.Column(db.String, nullable=False)
    images = db.relationship('BuildingImage', backref=db.backref('building'))

    text = db.Column(db.Text, nullable=False)

    station_id = db.Column(db.Integer, db.ForeignKey('metro_station.id'), nullable=False)
    station = db.relationship('MetroStation', backref=db.backref('buildings', lazy='dynamic'))

    district_id = db.Column(db.Integer, db.ForeignKey('district.id'), nullable=False)
    district = db.relationship('District', backref=db.backref('buildings', lazy='dynamic'))

    text_facts = db.relationship('BuildingTextFact', backref=db.backref('building'))
    number_facts = db.relationship('BuildingNumberFact', backref=db.backref('building'))

    def __str__(self):
        return self.title

    def to_dict(self):
        result = dictonify(self.__dict__)
        result.update({
            'images': [
                {
                    'id': image.id,
                    'name': image.name,
                    'path': image.path
                } for image in self.images
            ],
            'architects': [
                {
                    'id': architect.id,
                    'name': architect.surname
                } for architect in self.architects
            ],
            'styles': [
                {
                    'id': style.id,
                    'name': style.name,
                    'path': style.building_img_path,
                } for style in self.styles
            ],
            'number_facts': [
                {
                    'id': fact.id,
                    'number': fact.number,
                    'name': fact.name
                } for fact in self.number_facts
            ],
            'text_facts': [
                {
                    'id': fact.id,
                    'text': fact.text
                } for fact in self.text_facts
            ]

        })
        return result
Ejemplo n.º 8
0
class Organisation(db.Model):
    """ Describes an Organisation """

    __tablename__ = "organisations"

    # Columns
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(512), nullable=False, unique=True)
    slug = db.Column(db.String(255), nullable=False, unique=True)
    logo = db.Column(db.String)  # URL of a logo
    description = db.Column(db.String)
    url = db.Column(db.String)
    type = db.Column(db.Integer, default=OrganisationType.FREE.value, nullable=False)
    subscription_tier = db.Column(db.Integer)

    managers = db.relationship(
        User,
        secondary=organisation_managers,
        backref=db.backref("organisations", lazy="joined"),
    )
    campaign = db.relationship(
        Campaign, secondary=campaign_organisations, backref="organisation"
    )

    def create(self):
        """ Creates and saves the current model to the DB """
        db.session.add(self)
        db.session.commit()

    @classmethod
    def create_from_dto(cls, new_organisation_dto: NewOrganisationDTO):
        """ Creates a new organisation from a DTO """
        new_org = cls()

        new_org.name = new_organisation_dto.name
        new_org.slug = new_organisation_dto.slug or slugify(new_organisation_dto.name)
        new_org.logo = new_organisation_dto.logo
        new_org.description = new_organisation_dto.description
        new_org.url = new_organisation_dto.url
        new_org.type = OrganisationType[new_organisation_dto.type].value
        new_org.subscription_tier = new_organisation_dto.subscription_tier

        for manager in new_organisation_dto.managers:
            user = User.get_by_username(manager)

            if user is None:
                raise NotFound(f"User {manager} Not Found")

            new_org.managers.append(user)

        new_org.create()
        return new_org

    def update(self, organisation_dto: OrganisationDTO):
        """ Updates Organisation from DTO """

        for attr, value in organisation_dto.items():
            if attr == "type" and value is not None:
                value = OrganisationType[organisation_dto.type].value
            if attr == "managers":
                continue

            try:
                is_field_nullable = self.__table__.columns[attr].nullable
                if is_field_nullable and value is not None:
                    setattr(self, attr, value)
                elif value is not None:
                    setattr(self, attr, value)
            except KeyError:
                continue

        if organisation_dto.managers:
            self.managers = []
            # Need to handle this in the loop so we can take care of NotFound users
            for manager in organisation_dto.managers:
                new_manager = User.get_by_username(manager)

                if new_manager is None:
                    raise NotFound(f"User {manager} Not Found")

                self.managers.append(new_manager)

        db.session.commit()

    def delete(self):
        """ Deletes the current model from the DB """
        db.session.delete(self)
        db.session.commit()

    def can_be_deleted(self) -> bool:
        """ An Organisation can be deleted if it doesn't have any projects or teams """
        return len(self.projects) == 0 and len(self.teams) == 0

    @staticmethod
    def get(organisation_id: int):
        """
        Gets specified organisation by id
        :param organisation_id: organisation ID in scope
        :return: Organisation if found otherwise None
        """
        return Organisation.query.get(organisation_id)

    @staticmethod
    def get_organisation_by_name(organisation_name: str):
        """Get organisation by name
        :param organisation_name: name of organisation
        :return: Organisation if found else None
        """
        return Organisation.query.filter_by(name=organisation_name).first()

    @staticmethod
    def get_organisation_name_by_id(organisation_id: int):
        """Get organisation name by id
        :param organisation_id:
        :return: Organisation name
        """
        return Organisation.query.get(organisation_id).name

    @staticmethod
    def get_all_organisations():
        """ Gets all organisations"""
        return Organisation.query.order_by(Organisation.name).all()

    @staticmethod
    def get_organisations_managed_by_user(user_id: int):
        """ Gets organisations a user can manage """
        query_results = (
            Organisation.query.join(organisation_managers)
            .filter(
                (organisation_managers.c.organisation_id == Organisation.id)
                & (organisation_managers.c.user_id == user_id)
            )
            .order_by(Organisation.name)
            .all()
        )
        return query_results

    def as_dto(self, omit_managers=False):
        """ Returns a dto for an organisation """
        organisation_dto = OrganisationDTO()
        organisation_dto.organisation_id = self.id
        organisation_dto.name = self.name
        organisation_dto.slug = self.slug
        organisation_dto.logo = self.logo
        organisation_dto.description = self.description
        organisation_dto.url = self.url
        organisation_dto.managers = []
        organisation_dto.type = OrganisationType(self.type).name
        organisation_dto.subscription_tier = self.subscription_tier

        if omit_managers:
            return organisation_dto

        for manager in self.managers:
            org_manager_dto = OrganisationManagerDTO()
            org_manager_dto.username = manager.username
            org_manager_dto.picture_url = manager.picture_url
            organisation_dto.managers.append(org_manager_dto)

        return organisation_dto
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    first_name = db.Column(db.String(20))
    last_name = db.Column(db.String(20))
    gender = db.Column(db.String(20), nullable=False)
    birth_date = db.Column(db.Date())
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    image_file = db.Column(db.String(20),
                           nullable=False,
                           default='default.jpg')
    posts = db.relationship('Posts',
                            foreign_keys=[Posts.user_id],
                            backref=db.backref('user', lazy='joined'),
                            lazy='dynamic',
                            cascade='all, delete-orphan')
    followed = db.relationship('Follow',
                               foreign_keys=[Follow.follower_id],
                               backref=db.backref('follower', lazy='joined'),
                               lazy='dynamic',
                               cascade='all, delete-orphan')
    followers = db.relationship('Follow',
                                foreign_keys=[Follow.followed_id],
                                backref=db.backref('followed', lazy='joined'),
                                lazy='dynamic',
                                cascade='all, delete-orphan')
    subscriptions = db.relationship('Subscribed',
                                    foreign_keys=[Subscribed.user_id],
                                    backref=db.backref('user', lazy='joined'),
                                    lazy='dynamic',
                                    cascade='all, delete-orphan')
    notifications = db.relationship('Notification',
                                    foreign_keys=[Notification.user_id],
                                    backref=db.backref('user', lazy='joined'),
                                    lazy='dynamic',
                                    cascade='all, delete-orphan')

    def __repr__(self):
        return f"User('{self.username}', '{self.email}', '{self.image_file}')"

    def follow(self, user):
        if not self.is_following(user):
            f = Follow(follower=self, followed=user)
            db.session.add(f)
            db.session.commit()

    def unfollow(self, user):
        f = self.followed.filter_by(followed_id=user.id).first()
        if f:
            db.session.delete(f)
            db.session.commit()

    def is_following(self, user):
        if user.id is None:
            return False

        return self.followed.filter_by(followed_id=user.id).first() is not None

    def is_followed_by(self, user):
        if user.id is None:
            return False

        return self.followers.filter_by(
            follower_id=user.id).first() is not None

    def subscribe(self, post):
        if not self.is_subscribed(post):
            s = Subscribed(user_id=self.id, post_id=post.id)
            db.session.add(s)
            db.session.commit()

    def unsubscribe(self, post):
        s = self.subscriptions.filter_by(post_id=post.id).first()
        if s:
            db.session.delete(s)
            db.session.commit()

    def is_subscribed(self, post):
        if post.id is None:
            return False

        return self.subscriptions.filter_by(
            post_id=post.id).first() is not None
Ejemplo n.º 10
0
class Message(db.Model):
    __tablename__ = "Messages"

    id = Column(Integer, primary_key=True, autoincrement=True)
    subject = Column(String(128), unique=True, nullable=False)
    body = Column(Text, nullable=False)
    created_at = Column(Integer, default=lambda: int(time()), nullable=False)
    is_read = Column(Boolean, default=False)
    # CONSIDER: maybe I don't need this field and can delegate it to the mapper table
    owner = Column(Integer, ForeignKey("Users.id"), nullable=False, index=True)

    sender = db.relationship("User", back_populates="messages_sent")
    recipients = db.relationship(
        "User",
        secondary=recipients,
        primaryjoin=(recipients.c.m_id == id),
        # messages_received will be set on User model
        backref=db.backref("messages_received", lazy="dynamic"),
    )

    @classmethod
    def filter_by(cls, params: Dict[str, Any] = None) -> List["Message"]:
        """Return messages based on prams, if params is None return all messages."""
        query = cls.query
        if params is None:
            params = {}

        recipient = params.pop("recipient", None)
        query_params = [getattr(cls, k) == v for k, v in params.items() if hasattr(cls, k)]
        if recipient is not None:
            query = query.join(recipients, recipients.c.m_id == cls.id)
            query_params.append(recipients.c.r_id == recipient)

        return query.filter(*query_params).all()

    @classmethod
    def find_by_id(cls, m_id: str) -> Optional["Message"]:
        # TODO: figure out how to add that message is read by recipient

        return cls.query.get(m_id)

    @classmethod
    def create(cls, subject: str, body: str, owner: int) -> "Message":
        return cls(subject=subject, body=body, owner=owner, created_at=int(time()), is_read=False)

    def delete(self, user: User) -> bool:
        try:
            if user in self.recipients:
                self.recipients.remove(user)
            elif self.owner == user.id:
                db.session.delete(self)
            db.session.commit()
            return True
        except SQLAlchemyError:
            # TODO: send email to support team or devops
            db.session.rollback()
            raise DeleteError(
                {
                    "message": (
                        "Deleting a message failed due to the internal error. "
                        "Support team is notified."
                    )
                }
            )
        #
        raise ValidationError(
            {"message": "Message can be deleted only by a recipient or by a sender"}
        )

    def save(self):
        try:
            db.session.add(self)
            db.session.commit()
        except SQLAlchemyError:
            db.session.rollback()
            raise SaveError(
                {
                    "message": (
                        "Sending a message failed due to internal error. "
                        "Support team is notified."
                    )
                }
            )
Ejemplo n.º 11
0
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    first_name = db.Column(db.String(20))
    last_name = db.Column(db.String(20))
    gender = db.Column(db.String(20), nullable=False)
    birth_date = db.Column(db.Date())
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    image_file = db.Column(db.String(20),
                           nullable=False,
                           default='default.jpg')
    travels = db.relationship('Travel',
                              backref='traveler',
                              lazy='dynamic',
                              cascade='all, delete-orphan')
    followed = db.relationship('Follow',
                               foreign_keys=[Follow.follower_id],
                               backref=db.backref('follower', lazy='joined'),
                               lazy='dynamic',
                               cascade='all, delete-orphan')

    followers = db.relationship('Follow',
                                foreign_keys=[Follow.followed_id],
                                backref=db.backref('followed', lazy='joined'),
                                lazy='dynamic',
                                cascade='all, delete-orphan')
    subcribed_posts = db.relationship('Subscriptions',
                                      backref='subcribed_posts',
                                      lazy='dynamic',
                                      cascade='all, delete-orphan')
    notifications = db.relationship('Notifications',
                                    backref='notifications',
                                    lazy='dynamic',
                                    cascade='all, delete-orphan')

    def __repr__(self):
        return f"User('{self.username}', '{self.email}', '{self.image_file}')"

    def update(self, data):
        for attr in data:
            setattr(self, attr, data[attr])
        db.session.commit()

    def follow(self, user):
        if not self.is_following(user):
            f = Follow(follower=self, followed=user)
            db.session.add(f)
            db.session.commit()

    def unfollow(self, user):
        f = self.followed.filter_by(followed_id=user.id).first()
        if f:
            db.session.delete(f)
            db.session.commit()

    def is_following(self, user):
        if user.id is None:
            return False
        return self.followed.filter_by(followed_id=user.id).first() is not None

    def is_followed_by(self, user):
        if user.id is None:
            return False
        return self.followers.filter_by(
            follower_id=user.id).first() is not None

# def get_followers(self):
#    User.query.join(User.followers).filter_by(followed_id=self.id).all()

    def is_subscribed(self, post):
        if post.id is None:
            return False
        return self.subcribed_posts.filter_by(
            post_id=post.id).first() is not None

    def subscribe(self, post):
        if not self.is_subscribed(post):
            f = Subscriptions(user_id=self.id, post_id=post.id)
            db.session.add(f)
            db.session.commit()

    def unsubscribe(self, post):
        found_post = self.subcribed_posts.filter_by(post_id=post.id).first()
        if found_post:
            db.session.delete(found_post)
            db.session.commit()

    '''
    def show_notification(self, notification):
        found_notification = self.notifications.filter_by(
            notification_id = notification.notification_id).first()
        if found_notification.showed:
            Notifications.update().where(
                notification_id == found_notification.notification_id).values(showed=True)
    '''

    def delete_notification(self, notification):
        found_notification = self.notifications.filter_by(
            notification_id=notification.notification_id).first()
        if found_notification:
            db.session.delete(found_notification)
            db.session.commit()
Ejemplo n.º 12
0
class Posts(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.Text, nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    start_date = db.Column(db.DateTime, nullable=False)
    end_date = db.Column(db.DateTime, nullable=False)
    country = db.Column(db.Text, nullable=False)
    city = db.Column(db.Text, nullable=False)
    latitude = db.Column(db.Integer, nullable=False)
    longitude = db.Column(db.Integer, nullable=False)
    content = db.Column(db.Text, nullable=False)
    subscribers = db.relationship('Subscribe', foreign_keys=[Subscribe.post_id], backref=db.backref('post', lazy='joined'),
                               lazy='dynamic', cascade='all, delete-orphan')

    def __repr__(self):
        return f"Posts('{self.date_posted}')"