def timer_loop(self): while True: wakeups = [] now = datetime.datetime.utcnow() hour_from_now = now + datetime.timedelta(hours=1) for channel_id, timers in config.state.timers.items(): for name, dt in copy.copy(timers).items(): if dt <= now: self.send_message( channel_id, 'removing expired timer "%s" for %s' % (name, dt.strftime('%Y-%m-%d %H:%M:%S'))) del timers[name] config.state.save() elif dt <= hour_from_now: self.send_message( channel_id, '%s until %s' % (readable_rel(dt - now), name)) wakeups.append(dt) else: wakeups.append(dt - datetime.timedelta(hours=1)) wakeup = None if wakeups: wakeups.sort() wakeup = (wakeups[0] - now).total_seconds() with self.timer_condvar: self.timer_condvar.wait(wakeup)
def _stalk_list_buy_prices(cmd): current_time = datetime.datetime.now(datetime.timezone.utc) sunday = _date_to_sunday(current_time) cur = db.execute(''' SELECT username, expiration, price FROM price JOIN user ON user_id = user.id WHERE week_local = ? AND week_index = 0 ''', (str(sunday),)) prices = cur.fetchall() if not prices: cmd.reply('No turnip offers were recorded this week.') return current_time_str = str(current_time) current_prices = {} week_prices = collections.defaultdict(lambda: [None] * 13) for row in prices: user = row['username'] price = row['price'] if row['expiration'] > current_time_str: current_prices[user] = (price, row['expiration']) week_prices[user][0] = row['price'] output = [] for user, prices in week_prices.items(): line = '%s:' % user if user in current_prices: price, expiration = current_prices[user] expires_in = readable_rel(dateutil.parser.parse(expiration) - current_time) line += ' **%d** (expires in %s)' % (price, expires_in) line += ' <%s>' % _turnip_prophet(week_prices[user]) output.append(line) cmd.reply('\n'.join(output))
def _stalk_set_sell_price(cmd, price): if not price: _stalk_list_sale_prices(cmd) return user_id = cmd.sender['id'] current_time = datetime.datetime.now(datetime.timezone.utc) cur = db.execute('SELECT timezone FROM user WHERE id = ?', (user_id,)) res = cur.fetchone() if not res: cmd.reply('Could not add sale price. Have you registered a friend code?') return elif res['timezone'] is None: cmd.reply('Could not add sale price. Please register a time zone with !stalks tz') return user_time = current_time.astimezone(dateutil.tz.gettz(res['timezone'])) if (user_time.hour < 8 or user_time.hour >= 22): cmd.reply('Your shops are closed. Your current time zone is %s, where it is currently %s.' % (res['timezone'], user_time.strftime(time_format))) return elif user_time.weekday() == 6: cmd.reply('It is currently Sunday in your selected time zone, %s. Turnip offers cannot be submitted.' % res['timezone']) return try: value = int(price) except ValueError: cmd.reply('Could not parse sell value. Usage: !stalks sell 123') return week_local, week_index, expiration = _user_time_info(user_time) with db: db.execute(''' INSERT INTO price (user_id, week_local, week_index, expiration, price) VALUES (?, ?, ?, ?, ?) ON CONFLICT(user_id, expiration) DO UPDATE SET price = excluded.price ''', (user_id, week_local, week_index, expiration.astimezone(datetime.timezone.utc), value)) sunday = _date_to_sunday(current_time) with db: cur = db.execute('SELECT week_index, price FROM price WHERE user_id = ? AND week_local = ?', (user_id, str(sunday),)) week_price_rows = cur.fetchall() week_prices = [None] * 13 for row in week_price_rows: week_prices[row['week_index']] = row['price'] expires_in = readable_rel(expiration - user_time) cmd.reply('Sale price recorded at %d bells. Offer expires in %s.\n<%s>' % (value, expires_in, _turnip_prophet(week_prices))) _stalk_check_sell_triggers(cmd, price, expires_in)
def queue_info(cmd): if config.bot.twitter_post is None or config.bot.twitter_post[ 'channel'] != cmd.channel_id: return reply = 'queue length: %d' % len(config.state.twitter_queue) if len(config.state.twitter_queue) > 0: reply += '\nnext post: https://discord.com/channels/%s/%s/%s' % ( cmd.d['guild_id'], config.bot.twitter_post['channel'], config.state.twitter_queue[0]) if config.state.twitter_last_post_time: next_post_s = 12 * 60 * 60 - (time.time() - config.state.twitter_last_post_time) reply += '\nnext post in: ' + timer.readable_rel( datetime.timedelta(seconds=next_post_s)) cmd.reply(reply)
def _stalk_set_buy_price(cmd, price): if not price: _stalk_list_buy_prices(cmd) return user_id = cmd.sender['id'] current_time = datetime.datetime.now(datetime.timezone.utc) cur = db.execute('SELECT timezone FROM user WHERE id = ?', (user_id,)) res = cur.fetchone() if not res: cmd.reply('Could not add buy price. Have you registered a friend code?') return elif res['timezone'] is None: cmd.reply('Could not add buy price. Please register a time zone with !stalks tz') return try: value = int(price) except ValueError: cmd.reply('Could not parse buy value. Usage: !stalks buy 123') return user_tz = dateutil.tz.gettz(res['timezone']) user_time = current_time.astimezone(user_tz) # pretend it's sunday sunday = _date_to_sunday(user_time) user_sunday = datetime.datetime.combine(sunday, datetime.time(5), user_tz) # discard the calculated index and hardcode 0 for sunday/buy price week_local, _, expiration = _user_time_info(user_sunday) with db: db.execute(''' INSERT INTO price (user_id, week_local, week_index, expiration, price) VALUES (?, ?, ?, ?, ?) ON CONFLICT(user_id, expiration) DO UPDATE SET price = excluded.price ''', (user_id, week_local, 0, expiration.astimezone(datetime.timezone.utc), value)) turnip_prophet_url = _turnip_prophet([value] + [None] * 12) expiration_rel = expiration - user_time if expiration_rel.total_seconds() > 0: expires_in = readable_rel(expiration_rel) cmd.reply('Buy price recorded at %d bells. Offer expires in %s.\n<%s>' % (value, expires_in, turnip_prophet_url)) else: cmd.reply('Buy price recorded at %d bells.\n<%s>' % (value, turnip_prophet_url))
def _stalk_set_buy_price(cmd, price): if not price: _stalk_list_buy_prices(cmd) return user_id = cmd.sender['id'] current_time = datetime.datetime.now(datetime.timezone.utc) cur = db.execute('SELECT timezone FROM user WHERE id = ?', (user_id,)) res = cur.fetchone() if not res: cmd.reply('Could not add buy price. Have you registered a friend code?') return elif res['timezone'] is None: cmd.reply('Could not add buy price. Please register a time zone with !stalks tz') return user_time = current_time.astimezone(dateutil.tz.gettz(res['timezone'])) if user_time.weekday() != 6: cmd.reply('It is not currently Sunday in your selected time zone, %s. Turnip offers cannot be submitted.' % res['timezone']) return elif user_time.hour >= 12: cmd.reply('Turnips are not available on your island. Your current time zone is %s, where it is currently %s.' % (res['timezone'], user_time.strftime(time_format))) return try: value = int(price) except ValueError: cmd.reply('Could not parse buy value. Usage: !stalks buy 123') return # discard the calculated index and hardcode 0 for sunday/buy price week_local, _, expiration = _user_time_info(user_time) with db: db.execute(''' INSERT INTO price (user_id, week_local, week_index, expiration, price) VALUES (?, ?, ?, ?, ?) ON CONFLICT(user_id, expiration) DO UPDATE SET price = excluded.price ''', (user_id, week_local, 0, expiration.astimezone(datetime.timezone.utc), value)) expires_in = readable_rel(expiration - user_time) cmd.reply('Buy price recorded at %d bells. Offer expires in %s.\n<%s>' % (value, expires_in, _turnip_prophet([value] + [None] * 12)))