async def user_month(bot, channel_id, args, user_id, **kwargs): if len(args) > 0: user_id = await utils.twitch_lookup_user_id( bot.ahttp, bot.db, utils.safe_username(args[0])) from_date = datetime.utcnow().replace( day=1, hour=0, minute=0, second=0, microsecond=0, ) r = await bot.db.fetchone( '''SELECT count(message) as msgs, sum(word_count) as words FROM twitch_chatlog WHERE channel_id=%s AND user_id=%s AND created_at>=%s AND type=1 GROUP BY user_id;''', ( channel_id, user_id, from_date, )) if not r: r = { 'msgs': 0, 'words': 0, } return { 'user.chat_stats.month_msgs': utils.pluralize(r['msgs'], 'message'), 'user.chat_stats.month_msgs_num': r['msgs'], 'user.chat_stats.month_words': utils.pluralize(r['words'], 'word'), 'user.chat_stats.month_words_num': r['words'], }
async def user_stream(bot, channel_id, args, user_id, **kwargs): if len(args) > 0: user_id = await utils.twitch_lookup_user_id( bot.ahttp, bot.db, utils.safe_username(args[0])) r = await bot.db.fetchone( '''SELECT count(message) as msgs, sum(word_count) as words FROM twitch_chatlog WHERE channel_id=%s AND user_id=%s AND created_at>=%s AND type=1 GROUP BY user_id;''', ( channel_id, user_id, bot.channels_check[channel_id]['went_live_at'], )) if not r: r = { 'msgs': 0, 'words': 0, } return { 'user.chat_stats.stream_msgs': utils.pluralize(r['msgs'], 'message'), 'user.chat_stats.stream_msgs_num': r['msgs'], 'user.chat_stats.stream_words': utils.pluralize(r['words'], 'word'), 'user.chat_stats.stream_words_num': r['words'], }
async def accountage(bot, user_id, display_name, args, **kwargs): uid = user_id user = display_name if len(args) > 0: user = utils.safe_username(args[0]) uid = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, user) if not uid: uid = user_id user = display_name data = await utils.twitch_request( bot.ahttp, 'https://api.twitch.tv/helix/users', params={'id': uid}, ) if not data or not data['data']: raise Send_error('Found no data on {}'.format(user, )) created_at = parse(data['data'][0]['created_at']).replace(tzinfo=None) return { 'accountage': utils.seconds_to_pretty(dt1=datetime.utcnow(), dt2=created_at), 'accountage_date': created_at.strftime('%Y-%m-%d'), 'accountage_datetime': created_at.strftime('%Y-%m-%d %H:%M:%S UTC'), }
async def cmd_points(bot, channel_id, cmd, user, user_id, display_name, args, **kwargs): user = display_name if len(args) > 0: user = utils.safe_username(args[0]) uid = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, user) if not uid: user = display_name else: user_id = uid data = await bot.db.fetchone( ''' SELECT points, points_rank, total_point_users FROM twitch_user_channel_points p, (SELECT user_id, ROW_NUMBER() OVER (ORDER BY points DESC) AS points_rank FROM twitch_user_channel_points WHERE channel_id=%s) as r, (SELECT count(user_id) as total_point_users FROM twitch_user_channel_points WHERE channel_id=%s) as t where p.channel_id=%s AND p.user_id=%s and r.user_id=p.user_id ''', ( channel_id, channel_id, channel_id, user_id, )) if not data: raise Send_error('Unknown user') return data
async def stream_watchtime(bot, channel_id, user_id, args, **kwargs): if len(args) > 0: user_id = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, utils.safe_username(args[0])) r = await bot.db.fetchone( 'SELECT time FROM twitch_stream_watchtime WHERE channel_id=%s AND stream_id=%s AND user_id=%s', ( channel_id, bot.channels_check[channel_id]['stream_id'], user_id, ) ) time = 0 if r: time = r['time'] total_live_seconds = bot.channels_check[channel_id]['uptime'] usertime = time if (usertime > total_live_seconds) or ((total_live_seconds - usertime) <= 60): usertime = total_live_seconds p = 0 if total_live_seconds > 0: p = usertime / total_live_seconds return { 'user.stream_watchtime': utils.seconds_to_pretty(usertime), 'user.stream_watchtime_percent': '{:.0%}'.format(p), }
async def followage(bot, user_id, display_name, channel_id, channel, args, **kwargs): uid = user_id user = display_name if len(args) > 0: user = utils.safe_username(args[0]) uid = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, user) if not uid: uid = user_id user = display_name data = await utils.twitch_request( bot.ahttp, 'https://api.twitch.tv/helix/users/follows', params={ 'from_id': uid, 'to_id': channel_id, }) if not data['data']: raise Send_error('{} does not follow {}'.format(user, channel)) followed_at = parse(data['data'][0]['followed_at']).replace(tzinfo=None) return { 'followage': utils.seconds_to_pretty(dt1=datetime.utcnow(), dt2=followed_at), 'followage_date': followed_at.strftime('%Y-%m-%d'), 'followage_datetime': followed_at.strftime('%Y-%m-%d %H:%M:%S UTC'), }
async def user(bot, display_name, args, **kwargs): user = display_name if len(args) > 0: user = utils.safe_username(args[0]) user_id = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, user) if not user_id: user = display_name return { 'user': user, }
async def gambling_stats(bot, channel_id, cmd, user, user_id, display_name, args, **kwargs): user = display_name if len(args) > 0: user = utils.safe_username(args[0]) uid = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, user) if not uid: user = display_name else: user_id = uid data = await bot.db.fetchone( ''' SELECT * FROM twitch_gambling_stats WHERE channel_id=%s and user_id=%s ''', ( channel_id, user_id, )) r = { 'gambling_stats.slots_wins': 0, 'gambling_stats.slots_loses': 0, 'gambling_stats.slots_total_games': 0, 'gambling_stats.slots_win_percent': '0%', 'gambling_stats.roulette_wins': 0, 'gambling_stats.roulette_loses': 0, 'gambling_stats.roulette_total_games': 0, 'gambling_stats.roulette_win_percent': '0%', } if not data: return r slots_total = data['slots_wins'] + data['slots_loses'] slots_win_percent = '{:.1%}'.format(data['slots_wins']/slots_total) \ if slots_total > 0 else '0%' r['gambling_stats.slots_wins'] = data['slots_wins'] r['gambling_stats.slots_loses'] = data['slots_loses'] r['gambling_stats.slots_total_games'] = slots_total r['gambling_stats.slots_win_percent'] = slots_win_percent roulette_total = data['roulette_wins'] + data['roulette_loses'] roulette_win_percent = '{:.1%}'.format(data['roulette_wins']/roulette_total) \ if roulette_total > 0 else '0%' r['gambling_stats.roulette_wins'] = data['roulette_wins'] r['gambling_stats.roulette_loses'] = data['roulette_loses'] r['gambling_stats.roulette_total_games'] = roulette_total r['gambling_stats.roulette_win_percent'] = roulette_win_percent return r
async def permit_manager(bot, cmd, args, channel, channel_id, var_args, **kwargs): if len(args) < 1: raise Send_error('Invalid syntax, use: !{} <user>'.format(cmd)) user = utils.safe_username(args[0]) user_id = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, user) if not user_id: raise Send_error('Unknown user') time = int(var_args['permit'][0]) if 'permit' in var_args and var_args['permit'] else 60 key = 'tbot:filter:permit:{}:{}'.format( channel_id, user_id, ) permit = await bot.redis.setex(key, time, '1') bot.send("PRIVMSG", target='#'+channel, message='@{}, you will not receive a timeout for the next {}'.format( user, utils.seconds_to_pretty(time) if time > 60 else '{} seconds'.format(time), )) raise Send_break()
async def cmd_give_points(bot, channel_id, cmd, user, user_id, display_name, args, **kwargs): if len(args) < 2: raise Send_error(f'Syntax: !{cmd} <user> <amount>') data = await bot.db.fetchone( ''' SELECT points_name FROM twitch_channel_point_settings WHERE channel_id=%s ''', (channel_id, )) if not data: raise Send_error('Channel point settings has not been setup') points = await get_user_points(channel_id, user_id) try: give_points = str_bet_to_int(args[1], points) except: raise Send_error(f'Syntax: !{cmd} <user> <amount>') if give_points > points: raise Send_error(f'You only have {points} {data["points_name"]}') if give_points < 1: raise Send_error(f'Must at least give 1 {data["points_name"]}') to_uid = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, utils.safe_username(args[0])) if not to_uid: raise Send_error('Unknown user') if user_id == to_uid: raise Send_error(f'Can\'t give {data["points_name"]} to yourself') await asyncio.wait([ add_user_points(channel_id, user_id, user, -give_points), add_user_points(channel_id, to_uid, args[0], give_points), ]) msg = f'{display_name} gave {give_points} {data["points_name"]} to {args[0]}' return { 'give_points': msg, }
async def handler(bot, channel_id, user_id, args, display_name, **kwargs): user = display_name if len(args) > 0: user = utils.safe_username(args[0]) uid = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, user) if not uid: user = display_name else: user_id = uid r = await bot.db.fetchone( 'SELECT * FROM twitch_user_stats WHERE channel_id=%s AND user_id=%s', ( channel_id, user_id, )) if not r: return { 'user.streams_row': '0', 'user.streams_total': '0', 'user.streams_row_peak': '0', 'user.streams_row_peak_date': 'unknown date', 'user.streams_row_text': '{} has been here for 0 streams in a row'.format(user, ) } msg = '{} has been here for {} in a row'.format( user, utils.pluralize(r['streams_row'], 'stream')) if r['streams_row'] < r['streams_row_peak']: msg += ' (Peak: {}, {})'.format(r['streams_row_peak'], r['streams_row_peak_date'].isoformat()) msg += ' and a total of {}'.format(utils.pluralize(r['streams'], 'stream')) return { 'user.streams_row': utils.pluralize(r['streams_row'], 'stream'), 'user.streams_total': utils.pluralize(r['streams'], 'stream'), 'user.streams_row_peak': utils.pluralize(r['streams_row_peak'], 'stream'), 'user.streams_row_peak_date': r['streams_row_peak_date'].isoformat(), 'user.streams_row_text': msg, }
async def channel_watchtime(bot, channel_id, user_id, args, **kwargs): if len(args) > 0: user_id = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, utils.safe_username(args[0])) r = await bot.db.fetchone(''' SELECT sum(tw.time) as time, min(ts.started_at) as date FROM twitch_stream_watchtime tw, twitch_streams ts WHERE tw.channel_id=%s AND tw.user_id=%s AND tw.stream_id=ts.stream_id ''', ( channel_id, user_id, ) ) return { 'user.channel_watchtime': utils.seconds_to_pretty(r['time'] if r else 0), 'user.channel_watchtime_since': r['date'].strftime('%Y-%m-%d') if r else 'Unknown', }
async def user_chat_stats(bot, channel_id, user_id, args, **kwargs): if len(args) > 0: uid = await utils.twitch_lookup_user_id(bot.ahttp, bot.db, utils.safe_username(args[0])) if uid: user_id = uid r = await bot.db.fetchone( 'SELECT * FROM twitch_user_chat_stats WHERE channel_id=%s AND user_id=%s', ( channel_id, user_id, )) if not r: r = { 'chat_messages': 0, 'bans': 0, 'timeouts': 0, 'deletes': 0, 'purges': 0, } return { 'user.chat_stats.total_msgs': utils.pluralize(r['chat_messages'], 'message'), 'user.chat_stats.total_msgs_num': r['chat_messages'], 'user.chat_stats.bans': utils.pluralize(r['bans'], 'time'), 'user.chat_stats.bans_num': r['bans'], 'user.chat_stats.timeouts': utils.pluralize(r['timeouts'], 'time'), 'user.chat_stats.timeouts_num': r['timeouts'], 'user.chat_stats.deletes': utils.pluralize(r['deletes'], 'time'), 'user.chat_stats.deletes_num': r['deletes'], 'user.chat_stats.purges': utils.pluralize(r['purges'], 'time'), 'user.chat_stats.purges_num': r['purges'], }
async def cmd_add_points(bot, channel_id, cmd, user, user_id, display_name, args, **kwargs): if len(args) < 2: raise Send_error(f'Syntax: !{cmd} <user> <amount>') try: points = int(args[1]) except: raise Send_error(f'Syntax: !{cmd} <user> <amount>') data = await bot.db.fetchone( ''' SELECT points_name, ignore_users FROM twitch_channel_point_settings WHERE channel_id=%s; ''', (channel_id, )) if not data: raise Send_error('Channel point settings has not been setup') if args[0].lower() == 'all': await give_points_channel(channel_id, points, json.loads(data['ignore_users'])) user_count = len(bot.channels_check[channel_id]['users']) msg = f'Added {points} {data["points_name"]} to {user_count} viewers' else: to_uid = await utils.twitch_lookup_user_id( bot.ahttp, bot.db, utils.safe_username(args[0])) if not to_uid: raise Send_error('Unknown user') p = await add_user_points(channel_id, to_uid, args[0], points) msg = f'{args[0]} now has {p} {data["points_name"]}' return { 'add_points': msg, }