<commit_before>
import discord
from discord.ext import commands, tasks

import asyncio
from itertools import zip_longest
import logging
import sys
import traceback

import aiohttp
import dateutil.parser

from utilities import checks

errors_logger = logging.getLogger("errors")

def setup(bot):
	bot.add_cog(Twitch(bot))

class Twitch(commands.Cog):
	
	def __init__(self, bot):
		self.bot = bot
		self.check_streams.start().set_name("Twitch")
	
	def cog_unload(self):
		self.check_streams.cancel()
	
	async def initialize_database(self):
		await self.bot.connect_to_database()
		await self.bot.db.execute("CREATE SCHEMA IF NOT EXISTS twitch_notifications")
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.channels (
				channel_id		BIGINT, 
				user_name		TEXT, 
				user_id			TEXT, 
				PRIMARY KEY		(channel_id, user_id)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.filters (
				channel_id		BIGINT, 
				filter			TEXT, 
				PRIMARY KEY		(channel_id, filter)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.games (
				channel_id		BIGINT, 
				game_id			TEXT, 
				game_name		TEXT, 
				PRIMARY KEY		(channel_id, game_id)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.keywords (
				channel_id		BIGINT, 
				keyword			TEXT, 
				PRIMARY KEY		(channel_id, keyword)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.notifications (
				stream_id		TEXT, 
				channel_id		BIGINT, 
				message_id		BIGINT, 
				live			BOOL, 
				PRIMARY KEY		(stream_id, channel_id)
			)
			"""
		)
	
	@commands.group(invoke_without_command = True, case_insensitive = True)
	@checks.not_forbidden()
	async def twitch(self, ctx):
		'''Twitch'''
		await ctx.send_help(ctx.command)
	
	@twitch.group(invoke_without_command = True, case_insensitive = True)
	@checks.not_forbidden()
	async def add(self, ctx):
		'''Add Twitch channels, games, or keywords to follow'''
		await ctx.send_help(ctx.command)
	
	@add.command(name = "channel", aliases = ["stream"])
	@commands.check_any(checks.is_permitted(), checks.is_guild_owner())
	async def add_channel(self, ctx, username: str):
		'''Add a Twitch channel to follow'''
		if not (users_data := await ctx.bot.twitch_client.get_users(username)):
			await ctx.embed_reply(f"{ctx.bot.error_emoji} Channel not found")
			return
		
		user = users_data[0]
		inserted = await ctx.bot.db.fetchrow(
			"""
			INSERT INTO twitch_notifications.channels (channel_id, user_name, user_id)
			VALUES ($1, $2, $3)
			ON CONFLICT DO NOTHING
			RETURNING *
			""", 
			ctx.channel.id, username, user.id
		)
		if not inserted:
			await ctx.embed_reply(
				f"This text channel is already following the channel, `{user.display_name}`"
			)
			return
		await ctx.embed_reply(
			f"Added the Twitch channel, [`{user.display_name}`](https://www.twitch.tv/{user.login}), to this text channel\n"
			"I will now announce here when this Twitch channel goes live"
		)
	
	@add.command(name = "filter")
	@commands.check_any(checks.is_permitted(), checks.is_guild_owner())
	async def add_filter(self, ctx, *, string: str):
		'''Add string to filter Twitch stream titles by'''
		inserted = await ctx.bot.db.fetchrow(
			"""
			INSERT INTO twitch_notifications.filters (channel_id, filter)
			VALUES ($1, $2)
			ON CONFLICT DO NOTHING
			RETURNING *
			""", 
			ctx.channel.id, string
		)
		if not inserted:
			return await ctx.embed_reply(f"This text channel already has the filter, `{string}`")
		await ctx.embed_reply(f"Added the filter, `{string}`, to this text channel\n"
								"I will now filter all streams for this string in the title")
	
	@add.command(name = "game")
	@commands.check_any(checks.is_permitted(), checks.is_guild_owner())
	async def add_game(self, ctx, *, game: str):
		'''Add a Twitch game to follow'''
		# TODO: Add documentation on 100 limit
		if not (games := await ctx.bot.twitch_client.get_games(game)):
			await ctx.embed_reply(f"{ctx.bot.error_emoji} Game not found")
			return

		game = games[0]
		inserted = await ctx.bot.db.fetchrow(
			"""
			INSERT INTO twitch_notifications.games (channel_id, game_id, game_name)
			VALUES ($1, $2, $3)
			ON CONFLICT DO NOTHING
			RETURNING *
			""", 
			ctx.channel.id, game["id"], game["name"]
		)
		if not inserted:
			return await ctx.embed_reply(f"This text channel is already following the game, `{game['name']}`")
		await ctx.embed_reply(f"Added the game, [`{game['name']}`](https://www.twitch.tv/directory/game/{game['name']}), to this text channel\n"<commit_msg>[Discord] Improve twitch add filter command clarity<commit_after>
import discord
from discord.ext import commands, tasks

import asyncio
from itertools import zip_longest
import logging
import sys
import traceback

import aiohttp
import dateutil.parser

from utilities import checks

errors_logger = logging.getLogger("errors")

def setup(bot):
	bot.add_cog(Twitch(bot))

class Twitch(commands.Cog):
	
	def __init__(self, bot):
		self.bot = bot
		self.check_streams.start().set_name("Twitch")
	
	def cog_unload(self):
		self.check_streams.cancel()
	
	async def initialize_database(self):
		await self.bot.connect_to_database()
		await self.bot.db.execute("CREATE SCHEMA IF NOT EXISTS twitch_notifications")
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.channels (
				channel_id		BIGINT, 
				user_name		TEXT, 
				user_id			TEXT, 
				PRIMARY KEY		(channel_id, user_id)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.filters (
				channel_id		BIGINT, 
				filter			TEXT, 
				PRIMARY KEY		(channel_id, filter)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.games (
				channel_id		BIGINT, 
				game_id			TEXT, 
				game_name		TEXT, 
				PRIMARY KEY		(channel_id, game_id)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.keywords (
				channel_id		BIGINT, 
				keyword			TEXT, 
				PRIMARY KEY		(channel_id, keyword)
			)
			"""
		)
		await self.bot.db.execute(
			"""
			CREATE TABLE IF NOT EXISTS twitch_notifications.notifications (
				stream_id		TEXT, 
				channel_id		BIGINT, 
				message_id		BIGINT, 
				live			BOOL, 
				PRIMARY KEY		(stream_id, channel_id)
			)
			"""
		)
	
	@commands.group(invoke_without_command = True, case_insensitive = True)
	@checks.not_forbidden()
	async def twitch(self, ctx):
		'''Twitch'''
		await ctx.send_help(ctx.command)
	
	@twitch.group(invoke_without_command = True, case_insensitive = True)
	@checks.not_forbidden()
	async def add(self, ctx):
		'''Add Twitch channels, games, or keywords to follow'''
		await ctx.send_help(ctx.command)
	
	@add.command(name = "channel", aliases = ["stream"])
	@commands.check_any(checks.is_permitted(), checks.is_guild_owner())
	async def add_channel(self, ctx, username: str):
		'''Add a Twitch channel to follow'''
		if not (users_data := await ctx.bot.twitch_client.get_users(username)):
			await ctx.embed_reply(f"{ctx.bot.error_emoji} Channel not found")
			return
		
		user = users_data[0]
		inserted = await ctx.bot.db.fetchrow(
			"""
			INSERT INTO twitch_notifications.channels (channel_id, user_name, user_id)
			VALUES ($1, $2, $3)
			ON CONFLICT DO NOTHING
			RETURNING *
			""", 
			ctx.channel.id, username, user.id
		)
		if not inserted:
			await ctx.embed_reply(
				f"This text channel is already following the channel, `{user.display_name}`"
			)
			return
		await ctx.embed_reply(
			f"Added the Twitch channel, [`{user.display_name}`](https://www.twitch.tv/{user.login}), to this text channel\n"
			"I will now announce here when this Twitch channel goes live"
		)
	
	@add.command(name = "filter")
	@commands.check_any(checks.is_permitted(), checks.is_guild_owner())
	async def add_filter(self, ctx, *, string: str):
		'''Add string to filter Twitch stream titles by'''
		inserted = await ctx.bot.db.fetchrow(
			"""
			INSERT INTO twitch_notifications.filters (channel_id, filter)
			VALUES ($1, $2)
			ON CONFLICT DO NOTHING
			RETURNING *
			""", 
			ctx.channel.id, string
		)
		if not inserted:
			await ctx.embed_reply(f"This text channel already has the filter, `{string}`")
			return
		await ctx.embed_reply(f"Added the filter, `{string}`, to this text channel\n"
								"I will now filter all streams for this string in the title")
	
	@add.command(name = "game")
	@commands.check_any(checks.is_permitted(), checks.is_guild_owner())
	async def add_game(self, ctx, *, game: str):
		'''Add a Twitch game to follow'''
		# TODO: Add documentation on 100 limit
		if not (games := await ctx.bot.twitch_client.get_games(game)):
			await ctx.embed_reply(f"{ctx.bot.error_emoji} Game not found")
			return

		game = games[0]
		inserted = await ctx.bot.db.fetchrow(
			"""
			INSERT INTO twitch_notifications.games (channel_id, game_id, game_name)
			VALUES ($1, $2, $3)
			ON CONFLICT DO NOTHING
			RETURNING *
			""", 
			ctx.channel.id, game["id"], game["name"]
		)
		if not inserted:
			return await ctx.embed_reply(f"This text channel is already following the game, `{game['name']}`")
		await ctx.embed_reply(f"Added the game, [`{game['name']}`](https://www.twitch.tv/directory/game/{game['name']}), to this text channel\n"
{'fraction_non_alphanumeric': 0.12008061949718893, 'fraction_numerical': 0.0027580354301474487, 'mean_word_length': 3.728184553660983, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '198530', 'n_tokens_mistral': 3802, 'n_tokens_neox': 3312, 'n_words': 831}