예제 #1
0
    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
예제 #2
0
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")
예제 #3
0
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
예제 #4
0
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
예제 #5
0
def create_botometer(mashape_key, twitter_api_auth):
    try:
        bom = Botometer(wait_on_rate_limit=True,
                        mashape_key=mashape_key,
                        **twitter_api_auth)
    except tweepy.TweepError:
        error(config_complete_path, 'Failed to connect to Botometer API')
    return bom
예제 #6
0
def create_botometer(mashape_key, twitter_api_auth):
    try:
        # 8HK07BkyjOmshRCv6uHzqpJm73eSp1TUxNVjsnKYKn25VJG2rL
        bom = Botometer(
            wait_on_rate_limit=True,
            mashape_key="bd3376f8eemsh4ffa96f56d33b33p16f69cjsn802fbb18ba09",
            **twitter_api_auth)
    except tweepy.TweepError:
        error(config_complete_path, 'Failed to connect to Botometer API')
    return bom
예제 #7
0
    def set_up_botometer(self) -> Botometer:
        botometer_api: Botometer = object.__new__(Botometer)
        try:
            botometer_api: Botometer = Botometer(wait_on_ratelimit=True,
                                                 rapidapi_key=self.api_key,
                                                 **self.twitter_app_auth)

        except Exception as e:
            logger.error(e)
        return botometer_api
예제 #8
0
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
예제 #9
0
mashape_key = "e7b7a5ab38msh5ddc881afcc3bdcp101997jsn03924e682235"
twitter_app_auth = {
    'consumer_key': C_KEY,
    'consumer_secret': C_SECRET,
    'access_token': A_TOKEN,
    'access_token_secret': A_TOKEN_SECRET,
}

auth = tweepy.OAuthHandler(C_KEY, C_SECRET)
auth.set_access_token(A_TOKEN, A_TOKEN_SECRET)
api = tweepy.API(auth,
                 wait_on_rate_limit=True,
                 wait_on_rate_limit_notify=True,
                 compression=True)
botometer = Botometer(wait_on_ratelimit=True,
                      mashape_key=mashape_key,
                      **twitter_app_auth)

# User is exactly the user object from the request.
# Scores contains the overall classification results.
# The english score uses all six categories of features
# The universal score omits sentiment and content features, both of which are English-specific.
# Categories gives subscores for each of the six feature classes.

# Content, sentiment = English specific features
# Language independent features = Friend, network, temporal, user


def get_bom_scores():
    accounts = []
    scores = {}
예제 #10
0
botometer_key = apis.botometer_api()

twitter_app_auth = {
    'consumer_key': twitter_api['consumer_key'],
    'consumer_secret': twitter_api['consumer_secret'],
    'access_token': twitter_api['access_token'],
    'access_token_secret': twitter_api['access_secret'],
}
'''
    Botometer implementation from https://github.com/IUNetSci/botometer-python

    Details at https://rapidapi.com/OSoMe/api/Botometer%20Pro/details
'''

bom = Botometer(wait_on_ratelimit=True,
                rapidapi_key=botometer_key,
                **twitter_app_auth)


# Check a single account by screen name or id
def get_user_account(user, id=True):

    if id:
        user = int(user)

    return bom.check_account(user)


def get_accounts(users, folder, id=True):

    collected = fx.get_fnames(folder)
예제 #11
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     authentication = Authentication()
     self.botometer = Botometer(wait_on_ratelimit=True,
                                **authentication.botometer)
     self._botometer_result = None
예제 #12
0
def get_friends_bot_likelihood_scores(api: botometer.Botometer,
                                      friends: list) -> list:
    """Get bot likelihood scores for Twitter friends.

    https://github.com/IUNetSci/botometer-python/blob/master/botometer/__init__.py#L140

    Args:
        api (botometer.Botometer): A botometer.Botometer object authenticated to the Botometer and Twitter API.
        friends (list): A list containing a Twitter account's friends (represented as IDs).

    Returns:
        list: A list containing the bot likelihood scores for each Twitter friend.
    """
    loguru.logger.info(
        "Getting Twitter friends bot likelihood scores from Botometer.")
    # Initialise list containing each friend's bot likelihood score
    # List contains dictionaries with the bot likelihood scores for each friend
    friends_bot_likelihood_scores = []
    try:
        # Get all friends bot likelihood scores from the Botometer API
        # Retry 3 times for each friend if an exception occurs
        for friend_id, results in api.check_accounts_in(accounts=friends,
                                                        full_user_object=False,
                                                        retries=3):
            # A TweepyError or NoTimelineError can occur when Botometer checks a friend
            # https://github.com/IUNetSci/botometer-python/blob/master/botometer/__init__.py#L153
            # When these occur the result is a dictionary containing an error message:
            # {"error": err_msg}
            # Check first if this type of result has been returned
            error_msg = results.get("error", None)
            if error_msg:
                # Error message has been returned as the result
                # Log a warning message
                loguru.logger.warning(
                    f"Botometer returned the following error for friend with ID: {friend_id}.\n{error_msg}"
                )
            # Got a successful response for this friend from the Botometer API
            else:
                # Example JSON response: https://github.com/IUNetSci/botometer-python#botometer-v4
                # Drop cap and raw_scores keys and values from the dictionary
                # As they are not required and to save memory
                results.pop("cap")
                results.pop("raw_scores")
                # Get friend's Twitter username (screen name)
                friend_username = results["user"]["user_data"]["screen_name"]
                loguru.logger.success(
                    f"Got bot likelihood results from Botometer for friend: @{friend_username}, {friend_id}"
                )
                # Add friend's bot likelihood results to the list
                loguru.logger.debug(
                    f"Adding bot likelihood results for friend: @{friend_username}, {friend_id} to the list."
                )
                friends_bot_likelihood_scores.append(results)
        # Check if the list has one or more results
        if bool(friends_bot_likelihood_scores):
            # The list contains at least one or more results
            loguru.logger.debug(
                "The friends bot likelihood scores list has one or more results."
            )
            return friends_bot_likelihood_scores
        else:
            # The list contains no results, log a terminating error
            loguru.logger.exception(
                "Failed to get any friends bot likelihood results.")
    # The `check_accounts_in` method can raise the following exceptions once all retires have been exhausted:
    # requests: ConnectionError, HTTPError, Timeout
    ## https://github.com/IUNetSci/botometer-python/blob/master/botometer/__init__.py#L159
    # Standard Python Exception
    ## https://github.com/IUNetSci/botometer-python/blob/master/botometer/__init__.py#L164
    # If one of these occur, the application should return the friend bot likelihood scores it has collected
    # up to the point of failure. As long as it has not failed on the first attempt (as the list would be empty)
    except (
            botometer.ConnectionError,
            botometer.HTTPError,
            botometer.Timeout,
            Exception,
    ) as err:
        loguru.logger.warning(
            f"An exception occurred and all retries to Botometer have been exhausted.\n{err}"
        )
        # Check if the list has one or more results
        if bool(friends_bot_likelihood_scores):
            # The list contains at least one or more results
            loguru.logger.debug(
                "The friends bot likelihood scores list has one or more results."
            )
            return friends_bot_likelihood_scores
        else:
            # The list contains no results, log a terminating error
            loguru.logger.exception(
                f"Failed to get any friends bot likelihood results.\n{err}")