def _send_direct_message(consumer_key, consumer_secret, access_token_key, access_token_secret, status, screen_name): """ Send a twitter direct message using the given application authorization keys and access tokens. :param status: The actual message we are replying with. :param post: The SO post object to which we are replying. """ from solariat_bottle.utils.tweet import err_context, TwitterApiWrapper api = TwitterApiWrapper.init_with_settings(consumer_key, consumer_secret, access_token_key, access_token_secret) # Send a direct message. First follow user, then send actual message. if screen_name is None: raise Exception( "Need inbound DM we are answering to so we can get the targeted username." ) with err_context() as err_ctx: err_ctx.screen_name = screen_name err_ctx.status = status return api.send_direct_message(screen_name=screen_name, text=status)
def tw_retweet_status(consumer_key, consumer_secret, access_token_key, access_token_secret, status_id, screen_name=None): """ Do a retweet on twitter using the given application authorization keys and access tokens. :param status_id: The twitter id which we are retweeting :param screen_name: The user screen_name (optional) used solely for error handling """ from solariat_bottle.utils.tweet import err_context, TwitterApiWrapper from solariat_bottle.tasks.exceptions import TwitterCommunicationException api = TwitterApiWrapper.init_with_settings(consumer_key, consumer_secret, access_token_key, access_token_secret) if not status_id: raise TwitterCommunicationException( "Trying to retweet a post without a status_id.") with err_context() as err_ctx: err_ctx.screen_name = screen_name return api.retweet(id=status_id)
def tw_update_status(consumer_key, consumer_secret, access_token_key, access_token_secret, status, status_id=None, post=None, media=None): """ Send a twitter direct message using the given application authorization keys and access tokens. :param status: The actual message we are replying with. :param status_id: The twitter post id to which we are replying to :param post: The SO post object to which we are replying. """ import os from solariat_bottle.utils.tweet import err_context, TwitterApiWrapper api = TwitterApiWrapper.init_with_settings(consumer_key, consumer_secret, access_token_key, access_token_secret) with err_context() as err_ctx: err_ctx.status = status if post: err_ctx.screen_name = post.user_profile.user_name if media is not None: filename, f = get_file_from_media(media) kwargs = dict(status=status, in_reply_to_status_id=status_id) upload_result = api.media_upload(filename, file=f) logger.info(u"Uploaded media file %s", upload_result) media_id = upload_result.get( 'media_id_string') or upload_result.get('media_id') kwargs.update(media_ids=[media_id]) status = api.update_status(**kwargs) if f: try: f.close() os.unlink(f.name) except IOError: pass else: status = api.update_status(status=status, in_reply_to_status_id=status_id) return status # OK
def tw_destroy_friendship(consumer_key, consumer_secret, access_token_key, access_token_secret, screen_name): """ Do a twitter unfollow for the given screen name using the given application authorization keys and access tokens. :param screen_name: The twitter screen name which we want to unfollow """ from solariat_bottle.utils.tweet import err_context, TwitterApiWrapper api = TwitterApiWrapper.init_with_settings(consumer_key, consumer_secret, access_token_key, access_token_secret) with err_context() as err_ctx: err_ctx.screen_name = screen_name return api.destroy_friendship(screen_name=screen_name)
def tweepy_get_cursored(api, cursor=-1, method='followers_ids', process_data=lambda: None, channel=None, **call_params): """The base for cursored twitter api methods. :param api: should support `method` call :param cursor: cursor returned from previous api call :param method: the api method to be executed :param process_data: callback which applies to received data from api call :return: None :raises: exceptions from handle_tweepy_error """ from solariat_bottle.utils.tweet import err_context with err_context() as err_ctx: err_ctx.screen_name = channel.twitter_handle kwargs = {'cursor': cursor} kwargs.update(call_params) api_method = getattr(api, method) data, cursors = api_method(**kwargs) process_data(data, method=method) if data: (_, cursor) = cursors if cursor: params = { 'cursor': cursor, 'method': method, 'process_data': process_data, 'channel': channel } params.update(call_params) timer = io_pool.tools.Timer(10, tweepy_get_cursored, args=(api, ), kwargs=params) timer.start() else: process_data(None, method=method) return
def user_info(channel, user_id): from solariat_bottle.settings import LOGGER from solariat_bottle.db.user_profiles.user_profile import UserProfile try: user_profile = UserProfile.objects.get(native_id=user_id) return user_profile.platform_data except UserProfile.DoesNotExist: pass LOGGER.info( "Did not find user profile for id=%s in db. Fetching from twitter" % user_id) from solariat_bottle.utils.tweet import err_context, tweepy_user_to_user_profile api = get_twitter_api(channel) with err_context() as err_ctx: err_ctx.screen_name = user_id user = api.get_user(user_id) tweepy_user_to_user_profile(user) return user
def tw_count(channel, params=('followers_count', 'friends_count')): """ For the given input channel set the number of followers. """ from solariat_bottle.utils.tweet import err_context channel.reload() api = get_twitter_api(channel) with err_context() as err_ctx: err_ctx.screen_name = channel.twitter_handle err_ctx.channel = channel if channel.twitter_handle: user = api.get_user(screen_name=channel.twitter_handle) else: user = api.me() update = {"set__%s" % param: getattr(user, param) for param in params} update['w'] = 0 return channel.update(**update)
def _get_following_relations(channel, screen_name_or_id, clear_cache=False): from solariat_bottle.settings import LOGGER from solariat_bottle.db.user_profiles.user_profile import UserProfile from solariat_bottle.utils.tweet import err_context, CachedTwitterProxy platform = 'Twitter' def _ensure_user_profile(user_name, screen_id): try: up_id = SocialProfile.make_id(platform, user_name) return UserProfile.objects.get(up_id) except UserProfile.DoesNotExist: return UserProfile.objects.upsert( platform, dict(screen_name=user_name, user_id=screen_id)) # Query twitter for relations between brand (represented by channel token) and some screen name or id api = get_twitter_api(channel) api = CachedTwitterProxy(api, clear_cache=clear_cache) with err_context() as err_ctx: err_ctx.screen_name = screen_name_or_id try: user_id = int(screen_name_or_id) except ValueError: screen_name = screen_name_or_id brand_relations, queried_user_relations = api.show_friendship( target_screen_name=screen_name) else: brand_relations, queried_user_relations = api.show_friendship( target_id=user_id) # Update the relations on GSA db side aswell LOGGER.info("Got relationships information from twitter.") _ensure_user_profile(brand_relations.screen_name, brand_relations.id_str) # u_p_client = _ensure_user_profile(queried_user_relations.screen_name, queried_user_relations.id_str) _ensure_user_profile(queried_user_relations.screen_name, queried_user_relations.id_str) LOGGER.info("Upserted new user profiles from twitter data.") return brand_relations, queried_user_relations
def tw_scan_followers(channel, status_update, cursor=-1): """ On any switch of a channel to active, syncronize all the followers stored on the channel with actual twitter handles. """ from solariat_bottle.utils.tweet import err_context from . import _is_channel_active channel.reload() if not _is_channel_active(channel, status_update): channel.update(set__sync_status='idle') return if cursor == -1: channel.update(set__followers_synced=0, set__sync_status_followers='sync') api = get_twitter_api(channel) with err_context() as err_ctx: err_ctx.screen_name = channel.twitter_handle kwargs = {'cursor': cursor} if channel.twitter_handle: kwargs['screen_name'] = channel.twitter_handle data, cursors = api.followers_ids(**kwargs) if data: save_followers(channel, data) res = channel.update(inc__followers_synced=len(data)) (_, cursor) = cursors timer = io_pool.tools.Timer(10, tw_scan_followers, args=(channel, status_update), kwargs={'cursor': cursor}) timer.start() return res else: return channel.update(set__sync_status='idle')