Esempio n. 1
0
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')
Esempio n. 2
0
    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()
Esempio n. 3
0
    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()
Esempio n. 4
0
def pins(user=None, limit=5):
    user = None
    users = set()

    me = request.values.get('me')
    if me:
        users = redis.sdiff('users', 'users:%s:ugos' % me)
    else:
        users = redis.smembers('users')

    if users:
        # Filter by location.
        zipshort = redis.get('users:%s:zipshort' % me)
        users = users & redis.smembers('zipshort:%s' % zipshort)

        # Filter by sex. Yes, please.

        # This person wants my sex.
        sex_am = redis.get('users:%s:sex_am' % me)
        users = users & redis.smembers('sex_want:%s' % sex_am)

        # I want this person's sex.
        sex_want = redis.get('users:%s:sex_want' % me)
        users = users & redis.smembers('sex_am:%s' % sex_want)

        # Filter by users within my age range (+/- 10 years).
        try:
            age = int(redis.get('users:%s:birthyear' % me))
        except ValueError:
            pass
        else:
            geezers = redis.zrangebyscore('birthyears', '-inf', age - 11)
            premies = redis.zrangebyscore('birthyears', age + 11, '+inf')
            users = users - set(geezers) - set(premies)

        if users:
            users = list(users)
            random.shuffle(users)
            users = users[:limit]

    data = []
    remaining = len(users)
    for user in users:
        pins = get_pins(user)
        pins['remaining'] = remaining
        remaining -= 1
        data.append(pins)
        print user  # Nice to know.
    return data
Esempio n. 5
0
File: app.py Progetto: cvan/mula
def _generate_csv(precision):
    columns = ['timestamp'] + moods
    lines = [','.join(columns)]

    # Get sorted set in descending order by date.
    runs = redis.zrevrange('runs', 0, -1, 1)

    for run_timestamp, run_key in runs:
        # This is the value of the run which we key off of
        # (e.g., 20130116233651).
        run_key = str(int(run_key))

        line = [run_timestamp]

        for mood in moods:
            try:
                # Get the string of the mood count.
                count = redis.get('runs:%s:moods:%s:%s'
                                  % (run_key, precision, mood))
            except:
                pass
            count = count or 0
            line.append(str(count))

        lines.append(','.join(line))

    return '\n'.join(lines)
Esempio n. 6
0
def pins(user=None):
    user = None
    users = set()

    me = request.values.get('me')
    if me:
        users = redis.sdiff('users', 'users:%s:ugos' % me)
    else:
        users = redis.smembers('users')

    if users:
        # Filter by location.
        zipshort = redis.get('users:%s:zipshort' % me)
        users = users & redis.smembers('zipshort:%s' % zipshort)

        # Filter by sex. Yes, please.

        # This person wants my sex.
        sex_am = redis.get('users:%s:sex_am' % me)
        users = users & redis.smembers('sex_want:%s' % sex_am)

        # I want this person's sex.
        sex_want = redis.get('users:%s:sex_want' % me)
        users = users & redis.smembers('sex_am:%s' % sex_want)

        # Filter by users within my age range (+/- 10 years).
        try:
            age = int(redis.get('users:%s:birthyear' % me))
        except ValueError:
            pass
        else:
            geezers = redis.zrangebyscore('birthyears', '-inf', age - 11)
            premies = redis.zrangebyscore('birthyears', age + 11, '+inf')
            users = users - set(geezers) - set(premies)

        if users:
            users = list(users)
            random.shuffle(users)
            user = users[0]

    print user  # Nice to know.
    if user:
        pins = get_pins(user)
        pins['remaining'] = len(users)
        return pins
    else:
        return {}
Esempio n. 7
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'
    )
Esempio n. 8
0
File: app.py Progetto: cvan/mula
def _generate_html(precision):
    runs = []

    # Get sorted set in descending order by date.
    stored_runs = redis.zrevrange('runs', 0, -1, 1)

    for run_timestamp, run_key in stored_runs:
        # This is the value of the run which we key off of (e.g., 20130116233651).
        run_key = str(int(run_key))

        run = {'timestamp': run_timestamp, 'counts': []}

        for mood in moods:
            try:
                # Get the string of the mood count.
                count = redis.get('runs:%s:moods:%s:%s'
                                  % (run_key, precision, mood))
            except:
                # Maybe this key is not a set - or some other error occurred.
                pass
            count = count or 0
            run['counts'].append(int(count))

        for total in totals:
            try:
                # Get the string of the tally count.
                count = redis.get('runs:%s:totals:%s:%s'
                                  % (run_key, precision, total))
            except:
                # Maybe this key is not a set - or some other error occurred.
                pass
            count = count or 0
            run['counts'].append(int(count))

        runs.append(run)

    return {
        'precision': precision,
        'moods': moods,
        'totals': totals,
        'runs': runs
    }
Esempio n. 9
0
def handle_timezone_command(update: Update, context: CallbackContext):
    continents = sorted(
        set([x.partition('/')[0] for x in pytz.common_timezones]))
    current_timezone = redis.get(
        f'chat:{update.message.chat_id}:settings:timezone')
    reply = get_timezone_region_markup(continents)
    context.bot.send_message(
        chat_id=update.message.chat_id,
        text=f'Your current timezone is set to "{current_timezone}". '
        'If you want to change it, choose your region',
        reply_markup=reply)
Esempio n. 10
0
def handle_clock_command(update: Update, context: CallbackContext):
    chat_id = update.message.chat_id
    current_timezone = redis.get(f'chat:{chat_id}:settings:timezone')
    if not current_timezone:
        context.bot.send_message(
            chat_id=chat_id,
            text="Sorry to interrupt you, but you need to set a /timezone")
        return
    tz = timezone(current_timezone)
    msg_sent_date = update.message.date.astimezone(tz)
    context.bot.send_message(
        chat_id=update.message.chat_id,
        text=f'I received your message at {msg_sent_date}')
Esempio n. 11
0
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.'
    )
Esempio n. 12
0
    def delete(self, user):
        """Delete a single user."""

        redis.srem('users', user)

        sets = ['sex_am', 'sex_want', 'zip', 'zipshort', 'birthday', 'birthyear']
        for key in sets:
            value = redis.get('users:%s:%s' % (user, key))
            if value is not None:
                redis.srem('%s:%s' % (key, value), user)

        keys = ['sex_am', 'sex_want', 'ugos', 'zip', 'zipshort', 'birthday', 'birthyears']
        for key in keys:
            redis.delete('users:%s:%s' % (user, key))

        redis.zrem('birthyears', user)

        return Response()
Esempio n. 13
0
def handle_tweet_time_command(update: Update, context: CallbackContext):
    chat_id = update.message.chat_id

    buttons = []
    for hour in range(24):
        buttons.append([
            InlineKeyboardButton(f'{hour:02}:{minute:02}',
                                 callback_data=f'tweet_time:{hour}:{minute}')
            for minute in range(0, 60, 15)
        ])
    buttons.append([InlineKeyboardButton('Cancel', callback_data=f'cancel')])
    reply = InlineKeyboardMarkup(buttons, one_time_keyboard=True)
    tweet_time = redis.get(f'chat:{chat_id}:settings:tweet_time')
    context.bot.send_message(
        chat_id=update.message.chat_id,
        text=
        f'Your current tweet time is {tweet_time}. Do you want to change it?',
        reply_markup=reply)
Esempio n. 14
0
    def delete(self, user):
        """Delete a single user."""

        redis.srem('users', user)

        sets = [
            'sex_am', 'sex_want', 'zip', 'zipshort', 'birthday', 'birthyear'
        ]
        for key in sets:
            value = redis.get('users:%s:%s' % (user, key))
            if value is not None:
                redis.srem('%s:%s' % (key, value), user)

        keys = [
            'sex_am', 'sex_want', 'ugos', 'zip', 'zipshort', 'birthday',
            'birthyears'
        ]
        for key in keys:
            redis.delete('users:%s:%s' % (user, key))

        redis.zrem('birthyears', user)

        return Response()
Esempio n. 15
0
 def get_data(user):
     data = {}
     for field in ('sex_am', 'sex_want', 'zip', 'birthday'):
         data[field] = redis.get('users:%s:%s' % (user, field))
     return data
Esempio n. 16
0
 def get_data(user):
     data = {}
     for field in ('sex_am', 'sex_want', 'zip', 'birthday'):
         data[field] = redis.get('users:%s:%s' % (user, field))
     return data
Esempio n. 17
0
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)