예제 #1
0
class ScheduleConsFollowers(Followers,
                            metaclass=delegation_metaclass("_followers")):
    def __init__(
        self,
        user: User,
        followers: Followers,
        follow_schedule: FollowSchedule,
        unfollow_schedule: UnfollowSchedule,
        pgsql: PgsqlBase,
    ):
        self._followers = followers
        self._follow_schedule = follow_schedule
        self._unfollow_schedule = unfollow_schedule
        self._pgsql = pgsql
        self._user = user

    def users(self):
        return map(
            lambda u: ScheduleConsistentUser(u, self._follow_schedule, self.
                                             _unfollow_schedule, self._pgsql),
            self._followers.users(),
        )

    def update_followers(self, users):
        users = list(users)
        self._followers.update_followers(users)
        for u in users:
            self._follow_schedule.mark_fulfilled(u, self._user)
예제 #2
0
class ScheduleConsistentUser(User, metaclass=delegation_metaclass("_user")):
    # TODO: write tests ScheduleConsistentUser
    def __init__(
        self,
        user: User,
        follow_schedule: FollowSchedule,
        unfollow_schedule: UnfollowSchedule,
        pgsql: PgsqlBase,
    ):
        self._user = user
        self._pgsql = pgsql
        self._follow_schedule = follow_schedule
        self._unfollow_schedule = unfollow_schedule

    def following(self) -> "Following":
        return ScheduleConsFollowing(
            self,
            self._user.following(),
            self._follow_schedule,
            self._unfollow_schedule,
            self._pgsql,
        )

    def followers(self) -> "Followers":
        return ScheduleConsFollowers(
            self,
            self._user.followers(),
            self._follow_schedule,
            self._unfollow_schedule,
            self._pgsql,
        )
예제 #3
0
class CachedLazyUser(InstaUser, metaclass=delegation_metaclass("_lazy_user")):
    def __init__(self, insta_user: InstaUser, actions: Actions, db_user: User,
                 make_insta_user: Callable[[User], InstaUser]):
        self._lazy_user = LazyInstaUser(insta_user=insta_user,
                                        actions=actions,
                                        db_user=db_user)
        self._make_user = make_insta_user
        self._db_user = db_user

    def retrieve_followers(self):
        print("cached user retreiving followers")
        self.save_followers()
        return [self._make_user(u) for u in self._db_user.followers().users()]

    def retrieve_following(self):
        print("cached user retreiving following")
        self.save_following()
        return [self._make_user(u) for u in self._db_user.following().users()]
class RecursiveInstaUser(InstaUser, metaclass=delegation_metaclass("_target")):
    def __init__(
        self,
        user: InstaUser,
    ):
        self._target = user

    def save_followers(self):
        print(f"recursive save followers of {self.id()}")
        self._target.save_followers()
        followers = self._target.retrieve_followers()
        for i, f in enumerate(followers, 1):
            print(
                f"inner recursive save followers of {f.id()}. #{i} of {len(followers)}"
            )
            f.save_followers()

    def save_following(self):
        print(f"recursive save following of {self.id()}")
        self._target.save_following()
        followers = self._target.retrieve_followers()
        for i, f in enumerate(followers, 1):
            print(
                f"inner recursive save following of {f.id()}. #{i} of {len(followers)}"
            )
            f.save_following()

    def save_info(self):
        print(f"recursive save info of {self.id()}")
        self._target.save_info()
        self._target.save_followers()
        for f in self._target.retrieve_followers():
            print(f"inner recursive save info of {f.id()}")
            f.save_info()

    def save_posts_info(self):
        print(f"recursive save posts info of {self.id()}")
        self._target.save_posts_info()
        print(f"retreive followrs result {self._target.retrieve_followers()}")
        for f in self._target.retrieve_followers():
            print(f"inner recursive posts info of {f.id()}")
            f.save_posts_info()
예제 #5
0
class ScheduleConsFollowing(Following,
                            metaclass=delegation_metaclass("_following")):
    # TODO: write tests ScheduleConsistentFollowing
    def __init__(
        self,
        user: User,
        following: Following,
        follow_schedule: FollowSchedule,
        unfollow_schedule: UnfollowSchedule,
        pgsql: PgsqlBase,
    ):
        self._following = following
        self._follow_schedule = follow_schedule
        self._unfollow_schedule = unfollow_schedule
        self._pgsql = pgsql
        self._user = user

    def users(self):
        return map(
            lambda u: ScheduleConsistentUser(u, self._follow_schedule, self.
                                             _unfollow_schedule, self._pgsql),
            self._following.users(),
        )

    def update_following(self, users):
        users = list(users)
        self._following.update_following(users)
        for u in users:
            self._follow_schedule.mark_fulfilled(self._user, u)
        # TODO: mark all unfollow records as fulfilled for users not present

    def follow(self, user):
        self._following.follow(user)
        self._follow_schedule.mark_fulfilled(self._user, user)

    def unfollow(self, user):
        self._following.unfollow(user)
        self._unfollow_schedule.mark_fulfilled(self._user, user)

    def clean_up(self, target="fulfilled"):
        # TODO: implement unactive records removal
        pass
예제 #6
0
class PgActionsWithExpiration(Actions,
                              metaclass=delegation_metaclass("_origin")):
    def __init__(self, pgsql, expiration_period: timedelta):
        self._expiration_period = expiration_period
        self._pgsql = pgsql
        self._origin = PgActions(pgsql)

    def followers_explored(self, user_id):
        rows = self._pgsql.exec(
            "SELECT date_taken FROM actions WHERE user_id = %s AND action_type = 'followers_explored'"
            " ORDER BY date_taken DESC LIMIT 1",
            (user_id, ),
        )
        return rows and rows[0].date_taken >= (datetime.today() -
                                               self._expiration_period).date()

    def following_explored(self, user_id):
        rows = self._pgsql.exec(
            "SELECT date_taken FROM actions WHERE user_id = %s AND action_type = 'following_explored'"
            " ORDER BY date_taken DESC LIMIT 1",
            (user_id, ),
        )
        return rows and rows[0].date_taken >= (datetime.today() -
                                               self._expiration_period).date()

    def info_saved(self, user_id):
        rows = self._pgsql.exec(
            "SELECT date_taken FROM actions WHERE user_id = %s AND action_type = 'info_saved'"
            " ORDER BY date_taken DESC LIMIT 1",
            (user_id, ),
        )
        return rows and rows[0].date_taken >= (datetime.today() -
                                               self._expiration_period).date()

    def posts_info_saved(self, user_id):
        rows = self._pgsql.exec(
            "SELECT date_taken FROM actions WHERE user_id = %s AND action_type = 'posts_info_saved'"
            " ORDER BY date_taken DESC LIMIT 1",
            (user_id, ),
        )
        return rows and rows[0].date_taken >= (datetime.today() -
                                               self._expiration_period).date()
예제 #7
0
class CachedInstaUser(InstaUser, metaclass=delegation_metaclass("_origin")):
    def __init__(self, user: InstaUser, db_user: User, actions: Actions,
                 make_user: Callable[[User], InstaUser]):
        self._origin = user
        self._db_user = db_user
        self._actions = actions
        self._make_user = make_user

    def id(self) -> int:
        return self._origin.id()

    def retrieve_followers(self):
        if self._actions.followers_explored(self.id()):
            return [self._make_user(u) for u in self._db_user.followers().users()]
        return self._origin.retrieve_followers()

    def retrieve_following(self):
        if self._actions.following_explored(self.id()):
            return [self._make_user(u) for u in self._db_user.following().users()]
        return self._origin.retrieve_following()
예제 #8
0
class LazyInstaUser(InstaUser, metaclass=delegation_metaclass("_user")):
    def __init__(self, insta_user: InstaUser, actions: Actions, db_user: User):
        self._user = insta_user
        self._actions = actions
        self._db_user = db_user

    def id(self) -> int:
        return self._user.id()

    def save_followers(self):
        if not self._actions.followers_explored(self.id()):
            print(f"Lazy user: saving followers of {self.id()}")
            self._user.save_followers()
            self._actions.mark_followers_explored(self.id())
        else:
            print(f"Lazy user: skipping save followers of {self.id()}")

    def save_following(self):
        if not self._actions.following_explored(self.id()):
            print(f"Lazy user: saving following of {self.id()}")
            self._user.save_following()
            self._actions.mark_following_explored(self.id())
        else:
            print(f"Lazy user: skipping save following of {self.id()}")

    def save_info(self):
        if not self._actions.info_saved(self.id()):
            print(f"Lazy user: saving info of {self.id()}")
            self._user.save_info()
            self._actions.mark_info_saved(self.id())
        else:
            print(f"Lazy user: skipping save info of {self.id()}")

    def save_posts_info(self):
        if not self._actions.posts_info_saved(self.id()):
            print(f"Lazy user: saving posts info of {self.id()}")
            self._user.save_posts_info()
            self._actions.mark_posts_info_saved(self.id())
        else:
            print(f"Lazy user: skipping save posts info of {self.id()}")