示例#1
0
class DancingClassCouple(db.Model, TrackModifications):
    __tablename__ = TABLE_DANCING_CLASS_COUPLE
    __table_args__ = (
        db.UniqueConstraint("dancing_class_id", "person_id", "partner_id", name="_dancing_class_couple_uc"),
    )
    id = db.Column(db.Integer(), primary_key=True)
    dancing_class_id = db.Column(db.Integer(), db.ForeignKey(f"{TABLE_DANCING_CLASS}.id", ondelete="CASCADE"),
                                 nullable=False)
    dancing_class = db.relationship("DancingClass", lazy=False)
    person_id = db.Column(db.Integer(), db.ForeignKey(f"{TABLE_DANCING_CLASS_PERSON}.id", ondelete="CASCADE"),
                          nullable=False)
    person = db.relationship("DancingClassPerson", foreign_keys=person_id, lazy=False)
    partner_id = db.Column(db.Integer(), db.ForeignKey(f"{TABLE_DANCING_CLASS_PERSON}.id", ondelete="CASCADE"),
                           nullable=False)
    partner = db.relationship("DancingClassPerson", foreign_keys=partner_id, lazy=False)

    def __repr__(self):
        return f"{self.person} - {self.partner}"

    def json(self):
        data = {
            "id": self.id,
            "lead": self.person.json(),
            "follow": self.partner.json(),
        }
        return data
示例#2
0
class Couple(db.Model, TrackModifications):
    __tablename__ = TABLE_COUPLE
    __table_args__ = (db.UniqueConstraint("lead_id",
                                          "follow_id",
                                          name="_lead_follow_uc"), )
    id = db.Column(db.Integer(), primary_key=True)
    lead_id = db.Column(
        db.Integer(), db.ForeignKey(f"{TABLE_PERSON}.id", ondelete="CASCADE"))
    lead = db.relationship("Person", foreign_keys=lead_id)
    follow_id = db.Column(
        db.Integer(), db.ForeignKey(f"{TABLE_PERSON}.id", ondelete="CASCADE"))
    follow = db.relationship("Person", foreign_keys=follow_id)

    def __repr__(self):
        return f"{self.lead}-{self.follow}"

    def json(self):
        data = {
            "id": self.id,
            "lead": {
                "id": self.lead.id,
                "full_name": self.lead.full_name,
            },
            "follow": {
                "id": self.follow.id,
                "full_name": self.follow.full_name,
            },
            "couple": f"{self.lead.full_name} & {self.follow.full_name}"
        }
        return data
示例#3
0
class Contact(BaseMixin, db.Model):
    """关注和被关注"""
    __tablename__ = 'contacts'
    to_id = db.Column(db.Integer)
    from_id = db.Column(db.Integer)

    __table_args__ = (
        db.UniqueConstraint('from_id', 'to_id', name='uk_from_to'),
        db.Index('idx_to_time_from', to_id, 'created_at', from_id),
        db.Index('idx_time_to_from', 'created_at', to_id, from_id),
    )

    @classmethod
    def __flush_event__(cls, target):
        rdb.delete(MC_KEY_CONTACT_N % (target.target_id, target.target_kind))

    @classmethod
    @cache(MC_KEY_CONTACT_N % ('{target_id}', '{target_kind}'))
    def get_count_by_target(cls, target_id, target_kind):
        return cls.query.filter_by(target_id=target_id,
                                   target_kind=target_kind).count()

    @classmethod
    def get(cls, user_id, target_id, target_kind):
        return cls.query.filter_by(user_id=user_id,
                                   target_id=target_id,
                                   target_kind=target_kind).first()
示例#4
0
class LoginModel(db.Model):
    __tablename__ = 'login'
    __table_args__ = {'schema': 'membership'}

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    login_name = db.Column(db.String(255), nullable=False)
    display_name = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(255))
    organization_id = db.Column(db.Integer,
                                db.ForeignKey('membership.organization.id'),
                                nullable=False)

    organization = db.relationship('OrganizationModel',
                                   foreign_keys=[organization_id])

    db.UniqueConstraint('email', 'login_name')

    @property
    def serialize(self):
        return {
            'id': str(self.id),
            'login_name': self.login_name,
            'display_name': self.display_name,
            'password': self.password,
            'email': self.email,
            'organization_id': str(self.organization_id),
        }
示例#5
0
class OrganizationModel(db.Model):
    __tablename__ = 'organization'
    __table_args__ = {'schema': 'membership'}

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(50), nullable=False)
    is_master = db.Column(db.Boolean, nullable=False)

    db.UniqueConstraint('name')

    @property
    def serialize(self):
        return {
            'id': str(self.id),
            'name': self.name,
            'is_master': str(self.is_master),
        }
示例#6
0
class DancingClassPerson(db.Model, TrackModifications):
    __tablename__ = TABLE_DANCING_CLASS_PERSON
    __table_args__ = (db.UniqueConstraint("dancing_class_id", "person_id", name="_dancing_class_person_uc"),)
    id = db.Column(db.Integer(), primary_key=True)
    dancing_class_id = db.Column(db.Integer(), db.ForeignKey(f"{TABLE_DANCING_CLASS}.id", ondelete="CASCADE"),
                                 nullable=False)
    dancing_class = db.relationship("DancingClass", lazy=False)
    person_id = db.Column(db.Integer(), db.ForeignKey(f"{TABLE_PERSON}.id", ondelete="CASCADE"), nullable=False)
    person = db.relationship("Person", lazy=False)
    passed_triage = db.Column(db.Boolean, nullable=False, default=True)
    notes = db.Column(db.String(256), nullable=True)
    dancing_class_couples_leads = db.relationship("DancingClassCouple", foreign_keys="DancingClassCouple.person_id",
                                                  cascade="all, delete, delete-orphan", lazy=False)
    dancing_class_couples_follows = db.relationship("DancingClassCouple", foreign_keys="DancingClassCouple.partner_id",
                                                    cascade="all, delete, delete-orphan", lazy=False)

    def __repr__(self):
        return f"{self.person} - {self.dancing_class}"

    @property
    def partners(self):
        return [dcc.partner.person for dcc in self.dancing_class_couples_leads] + \
               [dcc.person.person for dcc in self.dancing_class_couples_follows]

    def json(self):
        data = {
            "id": self.id,
            "person": {
                "id": self.person.id,
            },
            "email": self.person.email,
            "full_name": self.person.full_name,
            "student_number": self.person.student_number,
            "passed_triage": self.passed_triage,
            "notes": self.notes,
        }
        return data
示例#7
0
class Contact(BaseMixin, db.Model):
    __tablename__ = "contacts"
    to_id = db.Column(db.Integer)
    from_id = db.Column(db.Integer)

    __table_args__ = (
        db.UniqueConstraint("from_id", "to_id", name="uk_from_to"),
        db.Index("idx_to_time_from", to_id, "created_at", from_id),
        db.Index("idx_time_to_from", "created_at", to_id, from_id),
    )

    def update(self, **kwargs):
        # Contact表不应该被更新
        raise NotImplementedError("contact table can`t update ")

    @classmethod
    def create(cls, **kwargs):
        ok, obj = super().create(**kwargs)
        cls.clear_mc(obj, 1)
        if ok:
            from .feed import feed_to_followers

            feed_to_followers(obj.from_id, obj.to_id)
            # from handler.tasks import feed_to_followers

            # feed_to_followers.delay(obj.from_id, obj.to_id)
        return ok, obj

    def delete(self):
        super().delete()
        self.clear_mc(self, -1)
        from handler.tasks import remove_user_posts_from_feed

        remove_user_posts_from_feed.delay(self.from_id, self.to_id)

    @classmethod
    @cache(MC_KEY_FOLLOW_ITEM.format("{from_id}", "{to_id}"))
    def get_follow_item(cls, from_id, to_id):
        return cls.query.filter_by(from_id=from_id, to_id=to_id).first()

    @classmethod
    @cache(MC_KEY_FOLLOWING.format("{user_id}", "{page}"))
    def get_following_ids(cls, user_id, page=1):
        query = cls.query.with_entities(cls.to_id).filter_by(from_id=user_id)
        following = query.paginate(page, PER_PAGE)
        following.items = [id for id, in following.items]
        del following.query
        return following

    @classmethod
    @cache(MC_KEY_FOLLOWERS.format("{user_id}", "{page}"))
    def get_follower_ids(cls, user_id, page=1):
        query = cls.query.with_entities(cls.from_id).filter_by(to_id=user_id)
        follower = query.paginate(page, PER_PAGE)
        follower.items = [id for id, in follower.items]
        del follower.query
        return follower

    @classmethod
    def clear_mc(cls, target, amount):
        to_id = target.to_id
        from_id = target.from_id

        st = userFollowStats.get_or_create(to_id)
        follower_count = st.follower_count or 0
        st.follower_count = follower_count + amount
        st.save()
        st = userFollowStats.get_or_create(from_id)
        following_count = st.following_count or 0
        st.following_count = following_count + amount
        st.save()

        rdb.delete(MC_KEY_FOLLOW_ITEM.format(from_id, to_id))

        for user_id, total, mc_key in (
            (to_id, follower_count, MC_KEY_FOLLOWERS),
            (from_id, following_count, MC_KEY_FOLLOWING),
        ):
            pages = math.ceil((max(total, 0) or 1) / PER_PAGE)
            for p in range(1, pages + 1):
                rdb.delete(mc_key.format(user_id, p))
示例#8
0
class Contact(BaseMixin, db.Model):
    __tablename__ = 'contacts'
    to_id = db.Column(db.Integer)
    from_id = db.Column(db.Integer)

    __table_args__ = (
        db.UniqueConstraint('from_id', 'to_id', name='uk_from_to'),
        db.Index('idx_to_time_from', to_id, 'created_at', from_id),
        db.Index('idx_time_to_from', 'created_at', to_id, from_id),
    )

    def update(self, **kwargs):
        raise NotAllowedException

    @classmethod
    def create(cls, **kwargs):
        ok, obj = super().create(**kwargs)
        cls.clear_mc(obj, 1)  # amount = 1
        if ok:
            from handler.tasks import feed_to_followers
            feed_to_followers.delay(obj.from_id, obj.to_id)
        return ok, obj

    def delete(self):
        super().delete()
        self.clear_mc(self, -1)
        from handler.tasks import remove_user_posts_from_feed
        remove_user_posts_from_feed.delay(self.from_id, self.to_id)

    @classmethod
    @cache(MC_KEY_FOLLOWERS % ('{user_id}', '{page}'))
    def get_follower_ids(cls, user_id, page=1):
        query = cls.query.with_entities(cls.from_id).filter_by(to_id=user_id)
        followers = query.paginate(page, PER_PAGE)
        followers.items = [id for id, in followers.items]
        del followers.query  # fix 'TypeError: can't pickle _thread.lock objects'
        return followers

    @classmethod
    @cache(MC_KEY_FOLLOWING % ('{user_id}', '{page}'))
    def get_following_ids(cls, user_id, page=1):
        query = cls.query.with_entities(cls.to_id).filter_by(from_id=user_id)
        following = query.paginate(page, PER_PAGE)
        following.items = [id for id, in following.items]
        del following.query
        return following

    @classmethod
    @cache(MC_KEY_FOLLOW_ITEM % ('{from_id}', '{to_id}'))
    def get_follow_item(cls, from_id, to_id):
        return cls.query.filter_by(from_id=from_id, to_id=to_id).first()

    @classmethod
    def clear_mc(cls, target, amount):
        to_id = target.to_id
        from_id = target.from_id

        st = userFollowStats.get_or_create(to_id)
        follower_count = st.follower_count or 0
        st.follower_count = follower_count + amount
        st.save()

        st = userFollowStats.get_or_create(from_id)
        following_count = st.following_count or 0
        st.following_count = following_count + amount
        st.save()  # `class:BaseMixin:save`

        rdb.delete(MC_KEY_FOLLOW_ITEM % (from_id, to_id))

        # should be `follower_count + amount`, `following_count + amount`?
        for user_id, total, mc_key in ((to_id, follower_count,
                                        MC_KEY_FOLLOWERS),
                                       (from_id, following_count,
                                        MC_KEY_FOLLOWING)):
            pages = math.ceil((max(total, 0) or 1) / PER_PAGE)
            for p in range(1, pages + 1):
                rdb.delete(mc_key % (user_id, p))