class BotometerResult: """Holds Botometer result and avoids repeating the request to their API""" def __init__(self, user_id): kwargs = authentication.botometer.copy() kwargs["wait_on_rate_limit"] = True self.botometer = Botometer(**kwargs) self.status = BotometerStatus.PENDING self._probability = None self.user_id = user_id def run(self): self.status = BotometerStatus.RUNNING try: result = self.botometer.check_account(self.user_id) except NoTimelineError: self.status = BotometerStatus.UNAVAILABLE self._probability = 0.0 # let's assume it's not a bot else: self.status = BotometerStatus.READY self._probability = result.get("cap", {}).get("universal") @property def probability(self): if self._probability is not None: return self._probability if self.status is BotometerStatus.PENDING: self.run() return self._probability
class BotometerResult: """Holds Botometer result and avoids repeating the request to their API""" def __init__(self): kwargs = authentication.botometer.copy() kwargs["wait_on_rate_limit"] = True self.botometer = Botometer(**kwargs) self.status = BotometerStatus.PENDING self._probability = None self.user_id = None def _get_result(self): try: result = self.botometer.check_account(self.user_id) except NoTimelineError: self.status = BotometerStatus.UNAVAILABLE else: self._probability = result.get("cap", {}).get("universal") self.status = BotometerStatus.READY @property def probability(self): if not self.user_id: raise RuntimeError("Cannot use Botometer without an account ID") if self.status is BotometerStatus.PENDING: self._get_result() return self.probability if self.status is BotometerStatus.UNAVAILABLE: return 0.0 # let's assume it's not a bot return self._probability
def botometer(follower): kwargs = authentication.botometer.copy() kwargs["wait_on_rate_limit"] = True api = Botometer(**kwargs) try: result = api.check_account(follower) except NoTimelineError: return 0.5 # user with no post, let's toss a coin return result.get("cap", {}).get("universal")
class User(models.User): """A wrapper for Tweepy native User model, including custom methods to check idle accounts and bots""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) authentication = Authentication() self.botometer = Botometer(wait_on_ratelimit=True, **authentication.botometer) self._botometer_result = None @classmethod def parse(cls, api, data): """This is how Tweepy instantiate User models from the API result""" return super(User, cls).parse(api, data) def last_status_before(self, **kwargs): """Takes any kwarg compatible with Python's `timedelta` and says whether the user's last tweet is older than the `timedelta` defined by these kwargs""" if not getattr(self, "status", None): return False return self.status.created_at < datetime.now() - timedelta(**kwargs) @property def botometer_result(self): if self._botometer_result: return self._botometer_result result = self.botometer.check_account(self.id) self._botometer_result = result.get("cap", {}).get("universal") return self.botometer_result def is_bot(self, threshold=0.75): if self.protected or not self.botometer_result: return False return self.botometer_result > threshold