def post_entity_tweet( view_set_obj: Union[ActionViewSet, QuoteViewSet]) -> None: """Função que posta um tweet de uma entidade (ação ou declaração). Args: view_set_obj (Union[ActionViewSet, QuoteViewSet]): O ViewSet da entidade. """ api = TwitterApi( consumer_key=settings.TWITTER_API_KEY, consumer_secret=settings.TWITTER_API_SECRET_KEY, access_token_key=settings.TWITTER_API_TOKEN, access_token_secret=settings.TWITTER_API_SECRET_TOKEN, ) entity_name = view_set_obj.__class__.__name__.split("ViewSet")[0].lower() infos = _get_random_entity(view_set_obj=view_set_obj) if isinstance(view_set_obj, QuoteViewSet): infos["description"] = f'"{infos["description"]}"' try: api.PostUpdate(status=( f"{infos['description']}\n\nMais informações: " f"http://bolsonaro-api.herokuapp.com/{entity_name}s/{infos['id']}/" )) logger.info("%s tweet postado com sucesso. ID da entidade: %s", entity_name, infos["id"]) except TwitterError as error: logger.error("Erro ao postar no twitter: %s", error.message)
def update_twitter(self): from django.conf import settings from meegloo.core.models import OAuthToken from meegloo.urlshortening.helpers import shorten from meegloo.social.helpers import format_tweet from twitter import Api oauth_creds = getattr(settings, 'OAUTH_CREDENTIALS').get('TWITTER') logger = logging.getLogger() try: token = self.author.oauth_tokens.get(site='twitter') except OAuthToken.DoesNotExist: logger.debug('No OAuth token for %s' % self.author.username) return api = Api(consumer_key=oauth_creds.get('CONSUMER_KEY'), consumer_secret=oauth_creds.get('CONSUMER_SECRET'), access_token_key=token.token, access_token_secret=token.secret) tags = self.get_twitter_tags() tags = ['#%s' % t for t in self.tags.values_list('slug', flat = True)] + \ ['#%s' % t for t in tags] url = shorten(self, self.stream.part_of.network, self.author) tweet = format_tweet(self.text, tags, url) try: api.PostUpdate(tweet) except Exception, ex: logger.error('Unable to post tweet', exc_info=ex)
class Tweet(): def __init__(self): """ Get twitter configuration and create the twitter Api """ ### load the json to get twitter config # check if the file exists if os.path.isfile(CONFIG_FILE): tmp_json = json.load(open(CONFIG_FILE)) # test if tweeting is enabled or not.... if not tmp_json['twitter']['enable']: print("We don't want to tweet!") return consumer_key = tmp_json['twitter']['consumer_key'] consumer_secret = tmp_json['twitter']['consumer_secret'] access_token_key = tmp_json['twitter']['access_token'] access_token_secret = tmp_json['twitter']['access_token_secret'] else: raise Exception( "Twitter oauth configuration : unable to open or read file '{0}')" .format(CONFIG_FILE)) return ### Connect to twitter try: self.api = Api(consumer_key=consumer_key, consumer_secret=consumer_secret, access_token_key=access_token, access_token_secret=access_token_secret) self.api.VerifyCredentials() except TwitterError: raise Exception( "Unable to log in the twitter account : {0}".format( traceback.format_exc())) def publish(self, message, nb_try=0): """ Just tweet """ try: status = self.api.PostUpdate(message) except TwitterError as e: # duplicate message error... # let's try to add some random data at the end if e[0][0]['code'] == 187: if nb_try == 0: message_addon = "Enjoy." elif nb_try == 1: message_addon = "Have fun." elif nb_try == 2: message_addon = ":)" elif nb_try == 3: message_addon = ";)" elif nb_try == 4: message_addon = ":D" else: raise Exception( "Too much duplicates for this message (3)....") new_message = "{0}. {1}".format(message, message_addon) self.publish(new_message, nb_try + 1) except: print("Unable to tweet : {0}".format(traceback.format_exc()))
def update_twitter(self, author): from django.conf import settings from meegloo.core.models import OAuthToken from meegloo.urlshortening.helpers import shorten from meegloo.social.helpers import format_tweet from twitter import Api oauth_creds = getattr(settings, 'OAUTH_CREDENTIALS').get('TWITTER') logger = logging.getLogger() api = Api(consumer_key=oauth_creds.get('CONSUMER_KEY'), consumer_secret=oauth_creds.get('CONSUMER_SECRET'), access_token_key=oauth_creds.get('BOT_TOKEN'), access_token_secret=oauth_creds.get('BOT_SECRET')) try: username = '******' + author.oauth_tokens.get(site='twitter').username except OAuthToken.DoesNotExist: username = author.get_full_name() or author.username tags = self.get_twitter_tags(author) url = shorten(self, self.network, author) text = '%s - Covered by %s' % (self.name, username) tweet = format_tweet(text, tags, url) try: api.PostUpdate(tweet) except Exception, ex: logger.error('Unable to post tweet', exc_info=ex)
def twittear(tweet_local_id): from twitter import Api from tw.models import Credential, Tweet tweet = Tweet.objects.get(id=tweet_local_id) if tweet.tweet_id is None: twitter_user = tweet.user user_credentials = Credential.objects.get(twitter_user=twitter_user) api = Api(user_credentials.consumer_key, user_credentials.consumer_secret, user_credentials.access_token_key, user_credentials.access_token_secret) files = [] if tweet.image1: files.append(tweet.image1.path) if tweet.image2: files.append(tweet.image2.path) if tweet.image3: files.append(tweet.image3.path) if tweet.image4: files.append(tweet.image4.path) result = api.PostUpdate(status=tweet.text, media=files) tweet.tweet_id = result.id tweet.pub_datetime = datetime.utcfromtimestamp( result.created_at_in_seconds) tweet.published = True tweet.save()
def _send_message(self, message, **kwargs): try: api = Api(consumer_key=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, access_token_key=autosubliminal.TWITTERKEY, access_token_secret=autosubliminal.TWITTERSECRET) api.PostUpdate(text_type(message[:280])) return True except Exception: log.exception('%s notification failed', self.name) return False
def save_model(self, request, obj, form, change): """ Sends a tweet with the title/short_url if applicable. """ super(TweetableAdminMixin, self).save_model(request, obj, form, change) if Api and request.POST.get("send_tweet", False): auth_settings = get_auth_settings() obj.set_short_url() message = truncatechars(obj, 140 - len(obj.short_url) - 1) api = Api(*auth_settings) api.PostUpdate("%s %s" % (message, obj.short_url))
def tweet(text): if len(text) > 140 or not text: return from twitter import Api from django.conf import settings api = Api(getattr(settings, 'DO_TWITTER_CONSUMER_KEY'), getattr(settings, 'DO_TWITTER_CONSUMER_SECRET'), getattr(settings, 'TWITTER_ACCESS_TOKEN_KEY'), getattr(settings, 'TWITTER_ACCESS_TOKEN_SECRET')) return api.PostUpdate(text)
def send_tweets(Type=None): global Twitter,T_status if not T_status: print "Twitter login attempt.." Twitter = TwitterApi( consumer_key = RajivPySms.CREDENTIALS['twitter']['consumer_key'], consumer_secret = RajivPySms.CREDENTIALS['twitter']['consumer_secret'], access_token_key = RajivPySms.CREDENTIALS['twitter']['access_token_key'], access_token_secret = RajivPySms.CREDENTIALS['twitter']['access_token_secret'] ) T_status = True prepare_data(Type) print "tweeting",Type Twitter.PostUpdate(DATA[Type])
class TwitterLog: DEBUG = 10 INFO = 20 WARNING = 30 ERROR = 40 CRITICAL = 50 def __init__(self, consumer_key, consumer_secret, access_key, access_secret, log_level=None): self.log_level = log_level or self.INFO self.api = Api(consumer_key, consumer_secret, access_key, access_secret) if not self.api.VerifyCredentials(): raise ValueError( "Could not log in to Twitter with the keys provided.") def debug(self, message): self.log(message, self.DEBUG) def info(self, message): self.log(message, self.INFO) def warning(self, message): self.log(message, self.WARNING) def error(self, message): self.log(message, self.ERROR) def critical(self, message): self.log(message, self.CRITICAL) def log(self, message, level): "Post the first 140 characters if the level is at least the log level" if level >= self.log_level: self.api.PostUpdate(message[:140])
class Tweeter(object): def __init__(self): creds = { 'consumer_key': os.environ.get('consumer_key'), 'consumer_secret': os.environ.get('consumer_secret'), 'access_token_key': os.environ.get('access_token_key'), 'access_token_secret': os.environ.get('access_token_secret') } for name, cred in creds.iteritems(): if cred is None: raise Exception( 'Misconfiguration error, Twitter creds missing %s' % name) self.api = Api(**creds) def tweet(self, to, message): try: tweet_body = '@%s %s' % (to, message) self.api.PostUpdate(tweet_body) print 'Posted: %s' % tweet_body except TwitterError as e: print 'Unable to post: %s' % str(e)
class Twitter: def __init__(self, mention=False): self.api = Api( settings.TWITTER_CONSUMER_KEY, settings.TWITTER_CONSUMER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_SECRET, ) self._bill = None @property def bill(self): if self._bill: return self._bill try: self._bill = ( Bill.select() .where(Bill.tweet == "") .order_by(Bill.created_at.desc()) .get() ) except Bill.DoesNotExist: pass return self._bill @property def hashtags(self): for keyword in self.bill.keywords.split(","): words = "".join(w.capitalize() for w in keyword.strip().split(" ")) yield f"#{words}" def publish(self): message = " ".join((self.bill.name, self.bill.url, " ".join(self.hashtags))) tweet = self.api.PostUpdate(message) self.bill.tweet = tweet.id self.bill.save()
def twitter_post(post_id): """ announce track and artist on twitter """ logger.debug("twittering new post") from twitter import Api post = Post.objects.get(pk=post_id) user = User.objects.get(id=15) user_auth = user.social_auth.filter(provider="twitter") message = """%s on %s http://angry-planet.com%s""" % ( post.title, post.feed.title, post.get_absolute_url()) for account in user_auth: access_token = urlparse.parse_qs(account.extra_data['access_token']) oauth_token = access_token['oauth_token'][0] oauth_access = access_token['oauth_token_secret'][0] twitter = Api(consumer_key=settings.TWITTER_CONSUMER_KEY, consumer_secret=settings.TWITTER_CONSUMER_SECRET, access_token_key=oauth_token, access_token_secret=oauth_access) result = twitter.PostUpdate(message) logger.debug("twitter said: %s", result) logger.debug("done twittering post")
class Twitter: def __init__(self): # Create API object self.api = Api(consumer_key=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, access_token_key=ACCESS_TOKEN, access_token_secret=ACCESS_TOKEN_SECRET) def get_direct_messages(self): data = self.api.GetDirectMessages() for message in data: pprint(message) def get_post(self): for tweet in self.api.GetUserTimeline( user_id="spacex"): # since_id=1111 print(f"{tweet.user.name}:{tweet.text}:{tweet.entities}") def create_post(self, text, file): if file: res = self.api.UploadMediaSimple(file) print(res) self.api.PostUpdate(text, media=file)
def draw_image(api: twitter.Api, status: twitter.models.Status): if not os.path.exists(config.WORKING_DIRECTORY): os.makedirs(config.WORKING_DIRECTORY) with Image.new("RGB", (1024, 1024)) as im: draw = ImageDraw.Draw(im) # random.seed(time.time()) r = random.random() * 255 g = random.random() * 255 b = random.random() * 255 for x in range(0, im.size[0]): for y in range(0, im.size[0]): im.putpixel((x, y), (int(random.random() * r), int(random.random() * g), int(random.random() * b))) # draw.line((0, 0) + im.size, fill=128) # draw.line((0, im.size[1], im.size[0], 0), fill=128) # αℓєχιѕ єνєℓуη 🏳️⚧️ 🏳️🌈 # Zero Width Joiner (ZWJ) does not seem to be supported, need to find a font that works with it to confirm it fnt = ImageFont.truetype(config.FONT_PATH, config.FONT_SIZE) length = int(config.IMAGE_NAME_OFFSET_MULTIPLIER * len(config.IMAGE_NAME)) draw.multiline_text((im.size[0] - length, im.size[1] - 50), config.IMAGE_NAME, font=fnt, fill=(int(255 - r), int(255 - g), int(255 - b))) # write to file like object # output = io.BytesIO() # Why does the PostUpdate not work with general bytesio? im.save(config.TEMPORARY_IMAGE_PATH, config.TEMPORARY_IMAGE_FORMAT) new_status = "@{user}".format(user=status.user.screen_name) if config.REPLY: api.PostUpdate(in_reply_to_status_id=status.id, status=new_status, media=config.TEMPORARY_IMAGE_PATH) os.remove(config.TEMPORARY_IMAGE_PATH) # Remove temporary file
class Moody: """ Enables moody_py Twitter functionality by using python-twitter wrapper for Twitter API. """ def __init__(self): """ Initializes python-twitter wrapper with the Twitter API credentials """ self.api = Api(consumer_key=os.environ["consumer_key"], consumer_secret=os.environ["consumer_secret"], access_token_key=os.environ["access_token_key"], access_token_secret=os.environ["access_token_secret"]) self.redis_search_engine = Redis() logging.info('App name: ' + self.redis_search_engine.get_string('app:name')) def verify_credentials(self): """ Verifies if the given tokens are valid :return: A boolean value stating if the credentials are valid """ try: user = self.api.VerifyCredentials() logging.info('Successfully verified ' + user.screen_name) return True except TwitterError as e: logging.error('Error verifying credentials: %s', e.message[0]['message']) return False def validate_request(self, twitter_request, authorization_header): """ Validates a request by matching the authorization header :param twitter_request: Request received on routing endpoints :param authorization_header: Header containing the authorization details :return: Boolean True if validation is successful False otherwise """ received_passkey = authorization_header.split(" ")[1] user_passkey = self.redis_search_engine.get_string( 'user:'******'Error validating request for user %s', twitter_request.requested_by) return False def tweet(self, twitter_request): """ Posts a tweet to a Twitter account. :param twitter_request: TwitterRequest containing necessary tweet information :return: TwitterResponse stating if the tweet has been posted """ twitter_content = twitter_request.content if twitter_content is None or len(twitter_content) == 0: return TwitterResponse( description='Twitter content to post cannot be empty!') try: status = self.api.PostUpdate(twitter_content) logging.info('Posted twit with status: %s', status) return TwitterResponse(status) except TwitterError as e: logging.error('Error posting twit: %s', e.message[0]['message']) return TwitterResponse( description='Fatal error while posting tweet. ' + e.message[0]['message']) def mood(self, twitter_request): """ Resolves a genre based on the YahooWeather condition code :param twitter_request: TwitterRequest containing necessary YahooWeather condition code :return: a genre for a given YahooWeather condition code """ genre_list = self.redis_search_engine.get_genre_list( twitter_request.content) genre = utils.get_random_from_collection(genre_list) logging.info('Resolved genre %s for YahooWeather condition code %s', genre, twitter_request.content) return genre
ME = Twitter.VerifyCredentials().screen_name print "Current user is @" + ME if tweet_list[0] == '-g': user_list = tweet_list[1:] if user_list: for user in user_list: print print "Recent tweets from " + user + ":" print "===================" + "=" * (len(user) + 1) tweets = Twitter.GetUserTimeline(user[1:]) #count = 0 for tweet in tweets: #if count == 5: break; print "$", tweet.text #count += 1 else: print print "Recent tweets from friends:" print "===========================" for tweet in Twitter.GetFriendsTimeline(): if tweet.user.screen_name != ME: print "@" + tweet.user.screen_name + ":", tweet.text else: for tweet in tweet_list: Twitter.PostUpdate(tweet) print 'Tweeting:', tweet print "Tweeted successfully!" else: print "Oops!. No tweets found in the tweet_stack!" #"""
def say_hello(api: twitter.Api, status: twitter.models.Status): new_status = "@{user} Hello {name}".format(name=status.user.name, user=status.user.screen_name) if config.REPLY: api.PostUpdate(in_reply_to_status_id=status.id, status=new_status)
def process_tweet(tweet_id, timestamp, image_url, style_url, username, complete): img_data = requests.get(image_url).content with open('image.jpg', 'wb') as handler: handler.write(img_data) style_data = requests.get(style_url).content with open('style.jpg', 'wb') as handler: handler.write(style_data) height = 512 width = 512 content_image = Image.open('image.jpg') content_image = content_image.resize((height, width)) content_image style_image_path = 'style.jpg' style_image = Image.open(style_image_path) style_image = style_image.resize((height, width)) style_image content_array = np.asarray(content_image, dtype='float32') content_array = np.expand_dims(content_array, axis=0) print(content_array.shape) style_array = np.asarray(style_image, dtype='float32') style_array = np.expand_dims(style_array, axis=0) print(style_array.shape) content_array[:, :, :, 0] -= 103.939 content_array[:, :, :, 1] -= 116.779 content_array[:, :, :, 2] -= 123.68 content_array = content_array[:, :, :, ::-1] style_array[:, :, :, 0] -= 103.939 style_array[:, :, :, 1] -= 116.779 style_array[:, :, :, 2] -= 123.68 style_array = style_array[:, :, :, ::-1] content_image = backend.variable(content_array) style_image = backend.variable(style_array) combination_image = backend.placeholder((1, height, width, 3)) input_tensor = backend.concatenate([content_image, style_image, combination_image], axis=0) model = VGG16(input_tensor=input_tensor, weights='imagenet', include_top=False) layers = dict([(layer.name, layer.output) for layer in model.layers]) layers content_weight = 0.025 style_weight = 5.25 total_variation_weight = 1.0 loss = backend.variable(0.) def content_loss(content, combination): return backend.sum(backend.square(combination - content)) layer_features = layers['block2_conv2'] content_image_features = layer_features[0, :, :, :] combination_features = layer_features[2, :, :, :] loss += content_weight * content_loss(content_image_features, combination_features) def gram_matrix(x): features = backend.batch_flatten(backend.permute_dimensions(x, (2, 0, 1))) gram = backend.dot(features, backend.transpose(features)) return gram def style_loss(style, combination): S = gram_matrix(style) C = gram_matrix(combination) channels = 3 size = height * width return backend.sum(backend.square(S - C)) / (4. * (channels ** 2) * (size ** 2)) feature_layers = ['block1_conv2', 'block2_conv2', 'block3_conv3', 'block4_conv3', 'block5_conv3'] for layer_name in feature_layers: layer_features = layers[layer_name] style_features = layer_features[1, :, :, :] combination_features = layer_features[2, :, :, :] sl = style_loss(style_features, combination_features) loss += (style_weight / len(feature_layers)) * sl def total_variation_loss(x): a = backend.square(x[:, :height-1, :width-1, :] - x[:, 1:, :width-1, :]) b = backend.square(x[:, :height-1, :width-1, :] - x[:, :height-1, 1:, :]) return backend.sum(backend.pow(a + b, 1.25)) loss += total_variation_weight * total_variation_loss(combination_image) grads = backend.gradients(loss, combination_image) outputs = [loss] outputs += grads f_outputs = backend.function([combination_image], outputs) def eval_loss_and_grads(x): x = x.reshape((1, height, width, 3)) outs = f_outputs([x]) loss_value = outs[0] grad_values = outs[1].flatten().astype('float64') return loss_value, grad_values class Evaluator(object): def __init__(self): self.loss_value = None self.grads_values = None def loss(self, x): assert self.loss_value is None loss_value, grad_values = eval_loss_and_grads(x) self.loss_value = loss_value self.grad_values = grad_values return self.loss_value def grads(self, x): assert self.loss_value is not None grad_values = np.copy(self.grad_values) self.loss_value = None self.grad_values = None return grad_values evaluator = Evaluator() x = np.random.uniform(0, 255, (1, height, width, 3)) - 128. iterations = 10 for i in range(iterations): print('Start of iteration', i) start_time = time.time() x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x.flatten(), fprime=evaluator.grads, maxfun=20) print('Current loss value:', min_val) end_time = time.time() print('Iteration %d completed in %ds' % (i, end_time - start_time)) x = x.reshape((height, width, 3)) x = x[:, :, ::-1] x[:, :, 0] += 103.939 x[:, :, 1] += 116.779 x[:, :, 2] += 123.68 x = np.clip(x, 0, 255).astype('uint8') result = Image.fromarray(x) result.save(tweet_id+'.jpg') s3 = boto3.client('s3') bucket_name = "mlstylephoto" filename = tweet_id+'.jpg' s3.upload_file(filename, bucket_name, filename) html = """ <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>MLstylephoto</title> <meta name="description" content="Machine Learning Styled Photos"> <meta name="author" content="Parker Erickson"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <script> (adsbygoogle = window.adsbygoogle || []).push({ google_ad_client: "ca-pub-7458822905226900", enable_page_level_ads: true }); </script> </head> <body> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="#">MLStylePhoto</a> </div> <ul class="nav navbar-nav"> <li class="active"><a href="/">Home</a></li> <li><a href="/gallery.html">Gallery</a></li> <li><a href="/howitworks.html">How It Works</a></li> <li><a href="/contact.html">Contact</a></li> </ul> </div> </nav> <img src="""+filename+"""> </body> </html>""" html_name = tweet_id+".html" Html_file= open(html_name,"w") Html_file.write(html) Html_file.close() s3.upload_file(html_name, bucket_name, html_name, ExtraArgs={'ContentType': "text/html", 'ACL': "public-read"} ) # Twitter Cred Loading api = Api(config.consumer_key, config.consumer_secret, config.access_token_key, config.access_token_secret) # Forming Tweet status_options = ["Hope you like it, @","Voila, @", "There you go, @","It's a thing of beauty @"] from random import randint a = (randint(0, 3)) api.PostUpdate(in_reply_to_status_id = tweet_id, status = status_options[a]+username+"! " "http://mlstylephoto.s3-website.us-east-2.amazonaws.com/"+html_name) # Updating Completeness in Database with conn.cursor() as cur: cur.execute("""UPDATE Queue SET Complete = 1 WHERE Tweet_ID ="""+tweet_id) conn.commit() os.remove(Html_file) os.remove(filename) os.remove(image.jpg) os.remove(style.jpg)
def post_tweet(status: str, session: Api) -> bool: try: session.PostUpdate(status=status) return True except TwitterError: return False
def search_text(api: twitter.Api, status: twitter.models.Status, INFO_QUIET: int = logging.INFO + 1, VERBOSE: int = logging.DEBUG - 1): # Broken For Some Reason # select id, text from trump where text COLLATE utf8mb4_unicode_ci like '%sleepy%joe%' order by id desc limit 10; # select count(id) from trump where text COLLATE utf8mb4_unicode_ci like '%sleepy%joe%'; # select id, text from trump where lower(text) COLLATE utf8mb4_unicode_ci like lower('%sleepy%joe%') order by id desc limit 10; # select count(id) from trump where lower(text) COLLATE utf8mb4_unicode_ci like lower('%sleepy%joe%'); # print(status.tweet_mode) if status.tweet_mode == "extended": status_text = status.full_text else: status_text = status.text # This Variable Is Useful For Debugging Search Queries And Exploits original_phrase = get_search_keywords(text=status_text) repo: Dolt = Dolt(config.ARCHIVE_TWEETS_REPO_PATH) phrase = convert_search_to_query(phrase=original_phrase) search_results: dict = database.search_tweets( search_phrase=phrase, repo=repo, table=config.ARCHIVE_TWEETS_TABLE, hide_deleted_tweets=config.HIDE_DELETED_TWEETS, only_deleted_tweets=config.ONLY_DELETED_TWEETS) # Print Out 10 Found Search Results To Debug Logger loop_count = 0 for result in search_results: logger.debug( "Example Tweet For Phrase \"{search_phrase}\": {tweet_id} - {tweet_text}" .format(search_phrase=original_phrase, tweet_id=result["id"], tweet_text=result["text"])) loop_count += 1 if loop_count >= 10: break # Check To Make Sure Results Found if len(search_results) < 1: no_tweets_found_status = "@{user} No results found for \"{search_phrase}\"".format_map( SafeDict(user=status.user.screen_name)) possibly_truncated_no_tweets_found_status: str = truncate_if_needed( original_phrase=original_phrase, new_status=no_tweets_found_status) if config.REPLY: api.PostUpdate(in_reply_to_status_id=status.id, status=possibly_truncated_no_tweets_found_status) logger.log( INFO_QUIET, "Sending Status: {new_status}".format( new_status=possibly_truncated_no_tweets_found_status)) logger.debug("Status Length: {length}".format( length=len(possibly_truncated_no_tweets_found_status))) return search_post_response = search_results[0] failed_account_lookup: bool = False try: author = get_username_by_id( api=api, author_id=search_post_response["twitter_user_id"]) except TwitterError: author = database.retrieveAccountInfo( repo=repo, account_id=search_post_response["twitter_user_id"] )[0]["twitter_handle"] failed_account_lookup: bool = True if search_post_response["isDeleted"] == 0 and not failed_account_lookup: url = "https://twitter.com/{screen_name}/statuses/{status_id}".format( status_id=search_post_response["id"], screen_name=author) else: url = "{website_root}/tweet/{status_id}".format( website_root=config.WEBSITE_ROOT, status_id=search_post_response["id"]) count: int = database.count_tweets( search_phrase=phrase, account_id=search_post_response["twitter_user_id"], repo=repo, table=config.ARCHIVE_TWEETS_TABLE, hide_deleted_tweets=config.HIDE_DELETED_TWEETS, only_deleted_tweets=config.ONLY_DELETED_TWEETS) logger.debug("Count For Phrase \"{search_phrase}\": {count}".format( search_phrase=original_phrase, count=count)) if count == 1: word_times = "time" else: word_times = "times" new_status = "@{user} @{screen_name} has tweeted about \"{search_phrase}\" {search_count} {word_times}. The latest example is at {status_link}".format_map( SafeDict(user=status.user.screen_name, status_link=url, screen_name=author, search_count=count, word_times=word_times)) possibly_truncated_status: str = truncate_if_needed( original_phrase=original_phrase, new_status=new_status) # CHARACTER_LIMIT if config.REPLY: api.PostUpdates(in_reply_to_status_id=status.id, status=possibly_truncated_status, continuation='\u2026') logger.log( INFO_QUIET, "Sending Status: {new_status}".format( new_status=possibly_truncated_status)) logger.debug("Status Length: {length}".format( length=len(possibly_truncated_status)))
class Moody: """ Enables moody_py Twitter functionality by using python-twitter wrapper for Twitter API. """ def __init__(self): """ Initializes python-twitter wrapper with the Twitter API credentials """ self.api = Api(consumer_key=credentials["consumer_key"], consumer_secret=credentials["consumer_secret"], access_token_key=credentials["access_token_key"], access_token_secret=credentials["access_token_secret"]) def verify_credentials(self): """ Verifies if the given tokens are valid :return: A boolean value stating if the credentials are valid """ try: self.api.VerifyCredentials() logging.info('Successfully verified') return True except TwitterError as e: logging.error('Error verifying credentials: %s', e.message[0]['message']) return False def tweet(self, twitter_post, instruction): """ Posts a twit on the moody_py account :param twitter_post: TwitterPost object containing relevant twit information :param instruction: models.Instruction what kind of tweet to post :return: TwitterResponse: Twitter response object. """ if instruction is None: logging.error('Instruction parameter missing') return TwitterResponse(description='Instruction parameter missing') if instruction == Instruction.PROCESS_WEATHER_DATA: twit_content = "{}, {} {} C {}".format(twitter_post.post_text, twitter_post.condition, twitter_post.temperature, twitter_post.youtube_url) if instruction == Instruction.PROCESS_ARTIST: twit_content = "Requested: {} {}".format(twitter_post.post_text, twitter_post.youtube_url) if instruction == Instruction.PROCESS_INSTAGRAM_POST: twit_content = twitter_post.post_text if twitter_post.post_text is None or twitter_post.youtube_url is None: return TwitterResponse( description='Twitter post text or youtube_url not resolved!') try: status = self.api.PostUpdate(twit_content) logging.info('Posted twit with status: %s', status) return TwitterResponse(status) except TwitterError as e: logging.error('Error posting twit: %s', e.message[0]['message']) return TwitterResponse( description='Fatal error while posting tweet')
def TweetMessages(): """ Send Tweets from Tweets Messages :return: """ try: from urllib.request import urlopen except: from urllib2 import urlopen import re try: from twitter.twitter_utils import URL_REGEXP from twitter import Api except: from urlmarker import URL_REGEXP logging.error("Error with python-twitter module not found") import random findRequest = TwitterMessages.query( TwitterMessages.strMessageStatus == "Ready") thisTwitterMessagesList = findRequest.fetch() findRequest = TwitterSettings.query() thisTwitterSettingsList = findRequest.fetch() if (len(thisTwitterSettingsList) > 0): thisTwitterSetting = thisTwitterSettingsList[0] else: thisTwitterSetting = TwitterSettings() try: myapi = Api( consumer_key=thisTwitterSetting.strConsumerAPI, consumer_secret=thisTwitterSetting.strConsumerSecret, access_token_key=thisTwitterSetting.strAccessTokenKey, access_token_secret=thisTwitterSetting.strAccessTokenSecret) if len(thisTwitterMessagesList) > 0: thisMessage = random.SystemRandom().choice(thisTwitterMessagesList) else: thisMessage = TwitterMessages() shortener = ShortenURL() urls = re.findall(URL_REGEXP, thisMessage.strMessage) for url in urls: thisMessage.strMessage = thisMessage.strMessage.replace( url, shortener.Shorten(url), 1) myapi.PostUpdate(status=thisMessage.strMessage) thisMessage.writeMessageStatus(strinput="Sent") vstrThisDateTime = datetime.datetime.now() vstrThisDate = datetime.date(year=vstrThisDateTime.year, month=vstrThisDateTime.month, day=vstrThisDateTime.day) vstrThisTime = datetime.time(hour=vstrThisDateTime.hour, minute=vstrThisDateTime.minute, second=vstrThisDateTime.second) thisMessage.writeDateSent(strinput=vstrThisDate) thisMessage.writeTimeSent(strinput=vstrThisTime) thisMessage.put() except: logging.info("We are getting an Error While Sending Twitter Messages")
class BBot(Twins): def __init__(self, username, password, path_to_is_duplicate_list, consumer_key, consumer_secret, access_token, access_token_secret): super(BBot, self).__init__(username, password) self.path_to_is_duplicate_list = path_to_is_duplicate_list self.api = Api(consumer_key=consumer_key, consumer_secret=consumer_secret, access_token_key=access_token, access_token_secret=access_token_secret) is_duplicate = defaultdict(lambda: False) with open(path_to_is_duplicate_list) as fp: for line in fp: is_duplicate[line.rstrip()] = True self.is_duplicate = is_duplicate def post_tweet(self, notification_id, text): if not self.is_duplicate[notification_id]: try: self.api.PostUpdate(text) self.update_is_duplicate(notification_id) except Exception as e: print(e) def update_is_duplicate(self, notification_id): """ 一度通知したことのあるお知らせDirctionaryの更新 """ self.is_duplicate[notification_id] = True def save_is_duplicate(self): """ 一度通知をしたことのあるお知らせのお知らせIDを保存する """ with open(self.path_to_is_duplicate_list, 'w') as fp: for idx in self.is_duplicate.keys(): print(idx, file=fp) def get_course_notifications(self): target_list = ['学群授業', '大学院授業'] watch_keyword_list = [ '休講', '変更', '修正', '訂正', '案内', '決定', '重要', '平成29年度' ] def is_target(d): """ 科目情報に関するリンクかどうかを判定 """ for target in target_list: if d.text.startswith(target): return target return False def get_attrib(d): """ URLからパラメータを抜き出す """ _raw = d.attrib['href'].split('?')[1] return _raw.split('&') def to_dict(attrib_list): """ パラメータのリストをDictionaryに変換 """ return dict(map(lambda attr: attr.split('='), attrib_list)) r = self.req("KJW0001100-flow") for d in pq(r.text)("a"): if d.text is None: continue target = is_target(d) if target: attrib_list = get_attrib(d) attrib_dict = to_dict(attrib_list) self.req("KJW0001100-flow") rr = self.get(attrib_dict) for dd in pq(rr.text)("a"): title = dd.text dd_attrib_list = get_attrib(dd) dd_attrib_dict = to_dict(dd_attrib_list) watch_keyword_query = '|'.join(watch_keyword_list) watch_keyword_query = r'{}'.format(watch_keyword_query) if not search(watch_keyword_query, title): continue if search(r'学内限定', title): continue if dd_attrib_dict['_eventId'] == 'confirm': self.req("KJW0001100-flow") self.get(attrib_dict) rrr = self.get(dd_attrib_dict) body = pq(rrr.text)("div.keiji-naiyo") if not title or not body: continue tweet = '#' + target + ' ' + title + '\n' + body.text() tweet = tweet[:140] notification_id = dd_attrib_dict['seqNo'] self.post_tweet(notification_id, tweet) span = random() * 20 sleep(span) self.save_is_duplicate()
class GomiPeopleBot(object): """ゴミピープルBotクラス.""" def __init__(self, consumer_key: str, consumer_secret: str, access_token_key: str, access_token_secret: str, model_filepath: str, cuda: bool = False, logger: Optional[Logger] = None): """コンストラクタ. Parameters ---------- consumer_key : str TwitterのConsumer Key consumer_secret : str TwitterのConsumer Secret access_token_key : str TwitterのAccess Token access_token_secret : str TwitterのAccess Token Secret model_filepath : str モデルファイルパス cuda : bool, default False CUDAの利用するか否かのフラグ(デフォルト:利用しない) logger : Optional[logging.Logger], default None ロガー """ self.twitter_api = TwitterAPI(consumer_key=consumer_key, consumer_secret=consumer_secret, access_token_key=access_token_key, access_token_secret=access_token_secret) self.logger = logger if logger else self.create_logger() self.model_filepath = model_filepath self.cuda = cuda self.gp_generator: Optional[GenerateGPText] = None self.steady_tweets = self.load_steady_tweets() self.tz = timezone(timedelta(hours=+9), 'Asia/Tokyo') @staticmethod def create_logger() -> Logger: """ロガーの生成. Returns ------- Logger ロガー """ handler = logging.StreamHandler() formatter = logging.Formatter( "[%(asctime)s][%(levelname)s] in %(filename)s: %(message)s") handler.setFormatter(formatter) logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) logger.addHandler(handler) return logger def get_latest_status_id(self) -> Optional[str]: """自身の直近の返信ツイートのIDを取得する. Returns ------- Optional[str] 自身の直近の返信ツイートのID """ statuses = self.twitter_api.GetUserTimeline(count=20) if len(statuses) == 0: return None for status in statuses: # 返信しているツイートを見つけたらそのIDを返す if status.in_reply_to_status_id is not None: return cast(str, status.id_str) else: # 返信しているツイートがなければ最新の自身のツイートIDを返す return cast(str, statuses[0].id_str) def load_steady_tweets(self, path: str = "./steady_tweets.yml" ) -> List[Dict[str, str]]: """定常ツイートを読み込む. Parameters ---------- path : str, optional 定常ツイートを格納したYamlファイルパス(デフォルト:./steady_tweets.yml) Returns ------- List[Dict[str, str]] 定常ツイート情報 """ with open(path) as fp: return cast(List[Dict[str, str]], yaml.safe_load(fp)["tweets"]) def generate_text(self, max_length: int) -> str: """ゴミピープルテキストの生成. Parameters ---------- max_length : int テキストの最大長 Returns ------- str 生成したゴミピープルテキスト """ if self.gp_generator is None: self.gp_generator = GenerateGPText(self.model_filepath, self.cuda) texts: List[str] = [] scores: List[float] = [] for _ in range(N_GENERATE_TEXT): text, avg_weight, std_weight = self.gp_generator(max_length) texts.append(text) # 重みの平均が大きく、分散が小さいほどスコアを高くする scores.append(avg_weight / std_weight if std_weight > 0 else 0.0) return cast(str, texts[np.argmax(scores)]) def do_mentions(self, now: datetime, latest_status_id: Optional[str]) -> bool: """ユーザへのリプライを行う. Parameters ---------- now : datetime.datetime 現在日時 latest_status_id : Optional[str] 最後にリプライしたツイートのID Returns ------- bool 定常ツイートした場合はTrue、しなかった場合はFalse Notes ----- * MENTION_MINUTEで指定した分間隔でリプライする """ if int(now.strftime("%M")) % MENTION_MINUTE != 0: return False random.seed() # Botへのリプライを取得 self.logger.info(f"Latest status id: {latest_status_id}") statuses = self.twitter_api.GetMentions(count=100, since_id=latest_status_id) if len(statuses) == 0: self.logger.info("No reply.") return False if latest_status_id is None and len(statuses) > 0: self.logger.info("No latest status ID") return False # ユーザIDとツイートIDのマッピングを記憶する # -> 同じユーザから複数ツイートあっても1ツイート分しか記憶しない tweet_id_map: Dict[str, str] = { st.user.screen_name: st.id_str for st in statuses } targets = list(tweet_id_map.items()) if len(targets) > MAX_N_MENTIONS: # MAX_N_MENTIONSで指定した数よりリプライが多ければリプライをランダムに抽出 targets = random.sample(targets, MAX_N_MENTIONS) for screen_name, id_str in targets: # リプライ対象のツイートごとにテキストを生成してツイート text_prefix = f"@{screen_name} " text = self.generate_text(TWEET_MAX_LENGTH - len(text_prefix)) self.post(text_prefix + text, id_str) return True def do_steady_tweets(self, now: datetime) -> bool: """定常ツイートを行う. Parameters ---------- now : datetime.datetime 現在日時 Returns ------- bool 定常ツイートした場合はTrue、しなかった場合はFalse """ for tweet in self.steady_tweets: if now.strftime(tweet["type"]) == tweet["dt"]: self.post(tweet["text"]) return True return False def post(self, text: Optional[str], mention_id: Optional[str] = None) -> str: """ツイート. Parameters ---------- text : Optional[str] ツイートするテキスト mention_id : Optional[str], optional リプライ先のツイートID Returns ------- str ツイートのID Raises ------ ValueError ツイートするテキストが空の場合 """ if text is None or len(text) == 0: raise ValueError("Tweet is empty.") result = self.twitter_api.PostUpdate(status=text, in_reply_to_status_id=mention_id) return cast(str, result.id_str) def main(self, force: bool = False) -> None: """main関数. Parameters ---------- force : bool, default False 強制的に通常ツイートを行うかどうかのフラグ(デフォルト:強制しない) """ self.logger.info("Start tweet.") now = datetime.now().astimezone(self.tz) try: # 定常ツイート if not force and self.do_steady_tweets(now): # 定常ツイートした場合は終了 self.logger.info("Successfully steady tweet.") return # 通常ツイート if force or int(now.strftime("%M")) % NORMAL_MINUTE == 0: self.post(self.generate_text(TWEET_MAX_LENGTH)) self.logger.info("Successfully tweet.") return # リプライ latest_status_id = self.get_latest_status_id() if self.do_mentions(now, latest_status_id): # リプライした場合は終了 self.logger.info("Successfully replies.") return self.logger.info("No action.") except Exception: self.logger.error("Failed to tweet.") self.logger.error(traceback.format_exc()) raise return