/reelcam/models/follow.py
https://gitlab.com/cimh/rc-api · Python · 355 lines · 209 code · 43 blank · 103 comment · 18 complexity · 37181d834e2272095079b0a45df93228 MD5 · raw file
- # -*- coding: utf-8 -*-
- from tornado import gen
- from datetime import timedelta
- from api_engine import s
- from api_engine.enums import FOLLOW_STATUS
- from .base import BaseModel, BaseCustomID
- from ..mappers.follow import FollowEntryMappingType
- class Follow(BaseCustomID, BaseModel):
- """
- Follow Model.
- """
- mapper = FollowEntryMappingType
- custom_id_attrs = ['_from', '_to']
- def _mapped_fields(self):
- """
- :return:
- """
- return dict(id=str(),
- _from=str(),
- _to=str(),
- message=str(),
- status=FOLLOW_STATUS.not_follow,
- modify_ts=str(),
- first_request_ts=None,
- last_request_ts=None,
- _to_is_hidden=None,
- _from_is_hidden=None)
- def get_data(self):
- """
- :return:
- """
- return {
- 'from': self._from,
- 'message': self.message,
- 'to': self._to,
- 'status': self.status,
- 'ts': self.ts_from_YmdHMS(self.modify_ts)
- }
- @classmethod
- def _validation_schema(cls):
- """
- :return:
- """
- return dict(_from=dict(required=True, type='string'),
- _to=dict(required=True, type='string'))
- def get_req_data(self):
- """
- :return:
- """
- return dict(id=self.id,
- user_id=self._from,
- message=self.message)
- @classmethod
- @gen.coroutine
- def _create(cls, user, followed_user):
- """
- :param user:
- :param followed_user:
- :return:
- """
- assert user.id != followed_user.id
- data = dict(_from=user.id,
- _to=followed_user.id,
- status=FOLLOW_STATUS.not_follow,
- modify_ts=cls.now_YmdHMS())
- follow = cls(data)
- r = yield follow.save()
- raise gen.Return(r)
- def is_follow(self):
- """
- :return:
- """
- return self.status == FOLLOW_STATUS.follow
- def is_disfollow(self):
- """
- :return:
- """
- return self.status == FOLLOW_STATUS.disfollow
- def is_request(self):
- """
- :return:
- """
- return self.status == FOLLOW_STATUS.request
- def is_not_follow(self):
- """
- :return:
- """
- return self.status == FOLLOW_STATUS.not_follow
- @gen.coroutine
- def set_follow(self):
- """
- :return:
- """
- User = s().M.model('User')
- if self.status is FOLLOW_STATUS.follow:
- return
- self.status = FOLLOW_STATUS.follow
- self.first_request_ts = None
- self.last_request_ts = None
- r = yield self.save()
- user_from, user_to = yield [User.get_one(_id=self._from), User.get_one(_id=self._to)]
- user_from.followed = set(user_from.followed)
- user_from.followed.add(user_to.id)
- user_from.followed = list(user_from.followed)
- user_to.followers = set(user_to.followers)
- user_to.followers.add(user_from.id)
- user_to.followers = list(user_to.followers)
- user_from, user_to = yield [user_from.save(), user_to.save()]
- raise gen.Return(r)
- @gen.coroutine
- def set_disfollow(self):
- """
- :return:
- """
- User = s().M.model('User')
- self.status = FOLLOW_STATUS.disfollow
- self.first_request_ts = None
- self.last_request_ts = None
- r = yield self.save()
- user_from, user_to = yield [User.get_one(_id=self._from), User.get_one(_id=self._to)]
- user_from.followed = set(user_from.followed)
- user_from.followed.discard(user_to.id)
- user_from.followed = list(user_from.followed)
- user_to.followers = set(user_to.followers)
- user_to.followers.discard(user_from.id)
- user_to.followers = list(user_to.followers)
- yield [user_from.save(), user_to.save()]
- raise gen.Return(r)
- @gen.coroutine
- def set_not_follow(self):
- """
- :return:
- """
- User = s().M.model('User')
- self.status = FOLLOW_STATUS.not_follow
- self.first_request_ts = None
- self.last_request_ts = None
- r = yield self.save()
- user_from, user_to = yield [User.get_one(_id=self._from), User.get_one(_id=self._to)]
- user_from.followed = set(user_from.followed)
- user_from.followed.discard(user_to.id)
- user_from.followed = list(user_from.followed)
- user_to.followers = set(user_to.followers)
- user_to.followers.discard(user_from.id)
- user_to.followers = list(user_to.followers)
- yield [user_from.save(), user_to.save()]
- raise gen.Return(r)
- @gen.coroutine
- def set_request(self):
- """
- :return:
- """
- self.status = FOLLOW_STATUS.request
- if self.first_request_ts is None:
- self.first_request_ts = self.now_YmdHMS()
- self.last_request_ts = self.now_YmdHMS()
- r = yield self.save()
- e_data = self.get_data()
- e_data.update(dict(follow_request_id=self.id), scope=self.default_scope)
- s().h("follow:follow", e_data, self._from, self._to)
- raise gen.Return(r)
- @gen.coroutine
- def disfollow(self):
- """
- :return:
- """
- if not self.is_follow():
- raise gen.Return(self)
- yield self.set_disfollow()
- e_data = self.get_data()
- e_data.update(dict(follow_request_id=self.id))
- s().e('follow:disfollow', sender=self.ctx.request_user, notify_sender=True,
- users=[(yield self.get_user_from())], data=e_data)
- raise gen.Return(self)
- @gen.coroutine
- def undisfollow(self):
- """
- :return:
- """
- if not self.is_disfollow():
- raise gen.Return(self)
- yield self.set_follow()
- e_data = self.get_data()
- e_data.update(dict(follow_request_id=self.id))
- s().e('follow:undisfollow', sender=self.ctx.request_user, notify_sender=True,
- users=[(yield self.get_user_from())], data=e_data)
- raise gen.Return(self)
- @gen.coroutine
- def unfollow(self):
- """
- :return:
- """
- if not self.is_follow():
- raise gen.Return(self)
- yield self.set_not_follow()
- e_data = self.get_data()
- e_data.update(dict(follow_request_id=self.id))
- s().e('follow:unfollow', sender=self.ctx.request_user, notify_sender=True,
- users=[(yield self.get_user_to())], data=e_data)
- raise gen.Return(self)
- @gen.coroutine
- def accept(self):
- """
- :return:
- """
- if not self.is_request():
- raise gen.Return(self)
- yield self.set_follow()
- e_data = self.get_data()
- e_data.update(dict(follow_request_id=self.id))
- s().e('follow:accept', sender=self.ctx.request_user, notify_sender=True,
- users=[(yield self.get_user_from())], data=e_data)
- raise gen.Return(self)
- @gen.coroutine
- def discard(self):
- """
- :return:
- """
- if not self.is_request():
- raise gen.Return(self)
- self.status = FOLLOW_STATUS.not_follow
- yield self.save()
- e_data = self.get_data()
- e_data.update(dict(follow_request_id=self.id))
- s().e('follow:discard', sender=self.ctx.request_user, notify_sender=True,
- users=[(yield self.get_user_from())], data=e_data)
- raise gen.Return(self)
- @gen.coroutine
- def follow(self, follow, user_from, user_to):
- """
- :param follow:
- :param user_from:
- :param user_to:
- :return:
- """
- assert user_from.id != user_to.id
- if follow.is_follow():
- raise gen.Return(follow)
- if follow.is_disfollow() or user_to.follow_approve and follow.is_not_follow():
- yield follow.set_request()
- elif follow.is_not_follow():
- yield follow.set_follow()
- elif self.is_request():
- yield self.set_request()
- e_data = self.get_data()
- e_data.update(dict(follow_request_id=self.id))
- s().e('follow:follow', sender=self.ctx.request_user, notify_sender=True,
- users=[(yield self.get_user_to())], data=e_data)
- raise gen.Return(follow)
- def can_retry_request(self):
- """
- :return:
- """
- if not self.is_request():
- return False
- try:
- first_request_ts = self.dt_from_YmdHMS(self.first_request_ts)
- last_request_ts = self.dt_from_YmdHMS(self.last_request_ts)
- except (TypeError, ValueError):
- return True
- # @TODO: check this
- return (self.now_dt() - first_request_ts) < timedelta(weeks=1) and \
- (self.now_dt() - last_request_ts) > timedelta(days=1) or \
- (self.now_dt() - last_request_ts) > timedelta(weeks=1)
- @gen.coroutine
- def get_user_from(self):
- """
- :return:
- """
- User = s().M.model('User', self.ctx)
- user = yield User.get_one(_id=self._from)
- raise gen.Return(user)
- @gen.coroutine
- def get_user_to(self):
- """
- :return:
- """
- User = s().M.model('User', self.ctx)
- user = yield User.get_one(_id=self._to)
- raise gen.Return(user)
- @classmethod
- @gen.coroutine
- def delete_user(cls, user_id):
- """
- :param user_id:
- :return:
- """
- r = yield cls.mapper._delete_user(user_id)
- raise gen.Return(r)