def inlinebutton_timezone(update: Update, context: CallbackContext, query: CallbackQuery, args: List[str]): continents = sorted( set([x.partition('/')[0] for x in pytz.common_timezones])) location = args[0] if location == 'region_selection': reply = get_timezone_region_markup(continents) query.edit_message_text('Choose your region') query.edit_message_reply_markup(reply) elif location in pytz.all_timezones: redis.set(f'chat:{query.message.chat_id}:settings:timezone', location) tz = timezone(location) local_time = query.message.date.astimezone(tz).strftime('%X') reply = InlineKeyboardMarkup([[ (InlineKeyboardButton('Change timezone', callback_data='timezone:region_selection')) ]]) query.edit_message_text( f'Timezone of this chat was set to {location}. ' f'Looks like it was {local_time} when you sent the last /timezone command. ' 'If this is incorrect, please execute /timezone again or click the button below.' ) query.edit_message_reply_markup(reply) elif location in continents: zones = [x for x in pytz.all_timezones if x.startswith(location)] reply = InlineKeyboardMarkup([[ InlineKeyboardButton(x.partition('/')[2], callback_data=':'.join(['timezone', x])) ] for x in zones] + [[(InlineKeyboardButton( '« Back', callback_data='timezone:region_selection'))]], ) query.edit_message_text('Choose your timezone') query.edit_message_reply_markup(reply)
def handle_delete_last_command(update: Update, context: CallbackContext): chat_id = update.message.chat_id queue_size = redis.get(f'chat:{chat_id}:queue_size') if queue_size is None: queue_size = 0 queue_size = int(queue_size) if queue_size <= 0: context.bot.send_message(chat_id=chat_id, text='Queue is empty') return queue_size -= 1 tweet_text = redis.get(f'chat:{chat_id}:queue:{queue_size}:text') or '' tg_attachment_id = redis.get( f'chat:{chat_id}:queue:{queue_size}:tg_attachment_id') redis.delete(f'chat:{chat_id}:queue:{queue_size}:text') redis.delete(f'chat:{chat_id}:queue:{queue_size}:tg_attachment_id') redis.set(f'chat:{chat_id}:queue_size', queue_size) context.bot.send_message( chat_id=chat_id, text="I've deleted your latest tweet. This was the text: " + tweet_text) if tg_attachment_id: context.bot.send_message(chat_id=chat_id, text='It also had an attachment')
def inlinebutton_tweet_time(update: Update, context: CallbackContext, query: CallbackQuery, args: List[str]): try: tweet_time = datetime.strptime(':'.join(args), '%H:%M').strftime("%H:%M") except ValueError: query.edit_message_text( "Sorry, I didn't understand that time. Time must be in format %H:%M" ) return redis.set(f'chat:{query.message.chat_id}:settings:tweet_time', tweet_time) query.edit_message_text(f'I will tweet at {tweet_time}')
def run(): # When the run started. timestamp = datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S') redis_timestamp = datetime.datetime.today().strftime('%Y%m%d%H%M%S') print timestamp # Sorted Set. # key: runs # score: redis_timestamp # value: timestamp redis.zadd('runs', timestamp, redis_timestamp) if settings.MOCK: counts = {} counts['exact'] = {'composed': 1, 'elated': 8, 'energetic': 2, 'tired': 1, 'depressed': 6, 'anxious': 4, 'confident': 1, 'agreeable': 5} counts['fuzzy'] = {'composed': 10, 'elated': 80, 'energetic': 20, 'tired': 10, 'depressed': 60, 'anxious': 40, 'confident': 10, 'agreeable': 50} # # TODO: Add total analyzed, etc. # else: counts = process_tweets(search_terms) print counts for mood in moods: for precision, sub_counts in counts.iteritems(): # Set. # key: runs:<redis_timestamp>:<precision [exact or fuzzy]>:<mood> # value: <count> redis.set('runs:%s:moods:%s:%s' % (redis_timestamp, precision, mood), sub_counts.get(mood, 0)) for total in totals: for precision, sub_counts in counts.iteritems(): # Set. # key: runs:<redis_timestamp>:<precision [exact or fuzzy]>:<total> # value: <count> redis.set('runs:%s:totals:%s:%s' % (redis_timestamp, precision, total), sub_counts.get(total, 0))
def handle_authorize_command(update: Update, context: CallbackContext): chat_id = update.message.chat_id auth = get_twitter_auth() if not update.message: return try: _, oauth_token, oauth_verifier = update.message.text.split() except ValueError: context.bot.send_message( chat_id=chat_id, text= 'Invalid authentication details. Expected OAUTH_TOKEN OAUTH_VERIFIER. ' 'If you want to start authorization, click on /start') return auth.request_token = { 'oauth_token': oauth_token, 'oauth_token_secret': oauth_verifier, } try: access_token, access_token_secret = auth.get_access_token( oauth_verifier) except tweepy.TweepError: context.bot.send_message( chat_id=chat_id, text='I was unable to get an access token. Try again: /start') return redis.set(f'chat:{chat_id}:oauth:access_token', access_token) redis.set(f'chat:{chat_id}:oauth:access_token_secret', access_token_secret) if not redis.get(f'chat:{chat_id}:settings:timezone'): redis.set(f'chat:{chat_id}:settings:timezone', 'UTC') tz = redis.get(f'chat:{chat_id}:settings:timezone') if not redis.get(f'chat:{chat_id}:settings:tweet_time'): redis.set(f'chat:{chat_id}:settings:tweet_time', '12:00') tweet_time = redis.get(f'chat:{chat_id}:settings:tweet_time') context.bot.send_message( chat_id=chat_id, text="You're all set! If you want to, you can test if " "everything works by posting a tweet: /test_tweet") context.bot.send_message( chat_id=chat_id, text= f'I will tweet at {tweet_time} ({tz}). You can change that: /tweet_time, /timezone' )
def handle_messages(update: Update, context: CallbackContext): chat_id = update.message.chat_id if not redis.get(f'chat:{chat_id}:oauth:access_token'): context.bot.send_message( chat_id=chat_id, text='You need to set me up first. Click on /start') return text = update.message.text or update.message.caption or '' if len(text) > TWEET_CHARACTER_LIMIT: context.bot.send_message( chat_id=chat_id, text= f'Sorry, your text exceeds the limit of {TWEET_CHARACTER_LIMIT} characters.' ) queue_size = redis.get(f'chat:{chat_id}:queue_size') if queue_size is None: queue_size = 0 queue_size = int(queue_size) if queue_size >= MAX_QUEUE_SIZE: context.bot.send_message( chat_id=chat_id, text='You have exceeded the maximum queue size.') redis.set(f'chat:{chat_id}:queue:{queue_size}:text', text) if update.message.document: redis.set(f'chat:{chat_id}:queue:{queue_size}:tg_attachment_id', update.message.document.file_id) elif update.message.photo: redis.set(f'chat:{chat_id}:queue:{queue_size}:tg_attachment_id', find_largest_photo(update.message.photo).file_id) queue_size += 1 redis.set(f'chat:{chat_id}:queue_size', queue_size) tweet_time = redis.get(f'chat:{chat_id}:settings:tweet_time') context.bot.send_message( chat_id=chat_id, text= f'Ok, I will tweet that at {tweet_time}! You now have {queue_size} tweet(s) in your queue.' )
def loop(): now = datetime.now() logging.debug(f'Running with timestamp {now}') for key in redis.keys('*:settings:tweet_time'): chat_id = key.split(':')[1] desired_time = redis.get(key).split(':') desired_hour = int(desired_time[0]) desired_minute = int(desired_time[1]) local_now = now.astimezone(timezone(redis.get(f'chat:{chat_id}:settings:timezone') or 'UTC')) if desired_hour != local_now.hour or desired_minute != local_now.minute: continue queue_size = redis.get(f'chat:{chat_id}:queue_size') or 0 queue_size = int(queue_size) if queue_size <= 0: continue queue_size -= 1 tweet_text = redis.get(f'chat:{chat_id}:queue:0:text') tg_attachment_id = redis.get(f'chat:{chat_id}:queue:0:tg_attachment_id') twitter = get_twitter_api(chat_id) if not tg_attachment_id: try: status = twitter.update_status(tweet_text) except tweepy.error.TweepError as e: logging.warning(f'Unable to tweet for chat:{chat_id}:queue:{queue_size} (without attachment) ' f'Reason: {e.reason}') telegram_updater.bot.send_message(chat_id=chat_id, text=e.reason) telegram_updater.bot.send_message(chat_id=chat_id, text='Sorry, I was unable to post your daily tweet. ' 'This is your tweet:') telegram_updater.bot.send_message(chat_id=chat_id, text=tweet_text) telegram_updater.bot.send_message(chat_id=chat_id, text='You may delete it from the queue: /delete_last') return else: # download telegram photo logging.debug('Downloading telegram attachment') file = telegram_updater.bot.getFile(tg_attachment_id) filename = FILE_STORAGE_PATH / tg_attachment_id file.download(filename) try: status = twitter.update_with_media(filename, tweet_text) except tweepy.error.TweepError as e: logging.warning(f'Unable to tweet for chat:{chat_id}:queue:{queue_size} (with attachment). ' f'Reason: {e.reason}') telegram_updater.bot.send_message(chat_id=chat_id, text=e.reason) telegram_updater.bot.send_message(chat_id=chat_id, text='Sorry, I was unable to post your daily tweet. ' 'This is your tweet, and it contained one attachment:') telegram_updater.bot.send_message(chat_id=chat_id, text=tweet_text) telegram_updater.bot.send_message(chat_id=chat_id, text='You may delete it from the queue: /delete_last') return finally: filename.unlink(missing_ok=True) logging.debug('Deleting stored tweet and attachment id') # Move all elements in the queue one for i in range(queue_size): k0 = f'chat:{chat_id}:queue:{i}:text' k1 = f'chat:{chat_id}:queue:{i+1}:text' l0 = f'chat:{chat_id}:queue:{i}:tg_attachment_id' l1 = f'chat:{chat_id}:queue:{i + 1}:tg_attachment_id' redis.set(k0, redis.get(k1) or '') redis.set(l0, redis.get(l1) or '') # The last element is now duplicated; delete it redis.delete(f'chat:{chat_id}:queue:{queue_size}:text') redis.delete(f'chat:{chat_id}:queue:{queue_size}:tg_attachment_id') tweet_url = build_tweet_url(status) logging.info(f'Tweeted: {tweet_url} for chat_id {chat_id}') telegram_updater.bot.send_message(chat_id=chat_id, text=f'I just tweeted this: {tweet_url}\n' f'\n' f'Tweets in queue: {queue_size}') if queue_size <= 0: telegram_updater.bot.send_message(chat_id=chat_id, text="Your queue is now empty. I will not tweet " "tomorrow if you won't give me new stuff!") redis.set(f'chat:{chat_id}:queue_size', queue_size)
def put(self, user): """Update a single user.""" sex_am = request.form.get('sex_am') if sex_am in ('guy', 'gal'): previous = redis.get('users:%s:sex_am' % user) if previous and previous != sex_am: redis.srem('sex_am:%s' % previous, user) redis.set('users:%s:sex_am' % user, sex_am) redis.sadd('sex_am:%s' % sex_am, user) sex_want = request.form.get('sex_want') if sex_want in ('guy', 'gal'): previous = redis.get('users:%s:sex_want' % user) if previous and previous != sex_want: redis.srem('sex_want:%s' % previous, user) redis.set('users:%s:sex_want' % user, sex_want) redis.sadd('sex_want:%s' % sex_want, user) zipcode = request.form.get('zip', '') zipshort = zipcode[:2] previous = redis.get('users:%s:zip' % user) if previous and previous != zipcode: redis.srem('zip:%s' % previous, user) redis.set('users:%s:zip' % user, zipcode) previous = redis.get('users:%s:zipshort' % user) if previous and previous != zipshort: redis.srem('zipshort:%s' % previous, user) redis.set('users:%s:zipshort' % user, zipshort) redis.sadd('zip:%s' % zipcode, user) redis.sadd('zipshort:%s' % zipshort, user) birthday = request.form.get('birthday', '') birthyear = birthday.split('-')[0] previous = redis.get('users:%s:birthyear' % user) if previous and previous != birthyear: redis.srem('birthyears:%s' % previous, user) redis.set('users:%s:birthday' % user, birthday) redis.set('users:%s:birthyear' % user, birthyear) redis.sadd('users:%s:birthday' % birthday, user) redis.sadd('users:%s:birthyear' % birthyear, user) # Birthyear is the score. redis.zadd('birthyears', user, birthyear) return Response()