def add_penalty_game(request, game_id): game = TournamentGame.objects.get(id=game_id) headers = {"X-Auth-Token": settings.PANTHEON_ADMIN_TOKEN} data = { "jsonrpc": "2.0", "method": "addPenaltyGame", "params": { "eventId": settings.PANTHEON_EVENT_ID, "players": [x.player.pantheon_id for x in game.game_players.all()], }, "id": make_random_letters_and_digit_string(), } response = requests.post(settings.PANTHEON_URL, json=data, headers=headers) if response.status_code == 500: return HttpResponse("addPenaltyGame. 500 response") content = response.json() if content.get("error"): return HttpResponse("addPenaltyGame. Pantheon error: {}".format( content.get("error"))) handler = TournamentHandler() handler.init(tournament=Tournament.objects.get(id=settings.TOURNAMENT_ID), lobby="", game_type="", destination="") player_names = handler.get_players_message_string( [x.player for x in game.game_players.all()]) handler.create_notification(TournamentNotification.GAME_PENALTY, {"player_names": player_names}) handler.check_round_was_finished() return redirect(request.META.get("HTTP_REFERER"))
def __init__(self): super(DiscordClient, self).__init__() self.channels_dict = {} self.bg_task = self.loop.create_task(self.send_notifications()) tournament = Tournament.objects.get(id=settings.TOURNAMENT_ID) self.tournament_handler = TournamentHandler() self.tournament_handler.init( tournament, settings.TOURNAMENT_PRIVATE_LOBBY, settings.TOURNAMENT_GAME_TYPE, TournamentHandler.DISCORD_DESTINATION, )
def finish_game_api(request): api_token = request.POST.get("api_token") if api_token != settings.TOURNAMENT_API_TOKEN: return HttpResponse(status=403) message = request.POST.get("message") handler = TournamentHandler() handler.init(tournament=Tournament.objects.get(id=settings.TOURNAMENT_ID), lobby="", game_type="", destination="") handler.game_pre_end(message) return JsonResponse({"success": True})
from django.conf import settings from django.core.management.base import BaseCommand from django.db.models import Q from django.utils.translation import activate from telegram import ParseMode, Update from telegram.error import BadRequest, ChatMigrated, NetworkError, TelegramError, TimedOut, Unauthorized from telegram.ext import CallbackContext, CommandHandler, Defaults, Filters, MessageHandler, Updater from telegram.utils.helpers import escape_markdown from online.handler import TournamentHandler from online.models import TournamentGame, TournamentNotification from tournament.models import Tournament from utils.logs import set_up_logging logger = logging.getLogger("tournament_bot") tournament_handler = TournamentHandler() class Command(BaseCommand): def handle(self, *args, **options): set_up_logging(TournamentHandler.TELEGRAM_DESTINATION) bot = TelegramBot() bot.init() class TelegramBot: def init(self): if not settings.TELEGRAM_ADMIN_USERNAME or not settings.TELEGRAM_ADMIN_USERNAME.startswith("@"): logger.error("Telegram admin username should starts with @") return
def handle(self, *args, **options): set_up_logging() tournament_id = settings.TOURNAMENT_ID lobby = settings.TOURNAMENT_PRIVATE_LOBBY game_type = settings.TOURNAMENT_GAME_TYPE if not tournament_id or not lobby or not game_type: print('Tournament wasn\'t configured properly') return tournament = Tournament.objects.get(id=tournament_id) global tournament_handler tournament_handler = TournamentHandler(tournament, lobby, game_type) updater = Updater(token=settings.TELEGRAM_TOKEN) dispatcher = updater.dispatcher def stop_and_restart(): """Gracefully stop the Updater and replace the current process with a new one""" updater.stop() os.execl(sys.executable, sys.executable, *sys.argv) def restart(bot, update): message = 'Bot is restarting...' logger.info(message) update.message.reply_text(message) Thread(target=stop_and_restart).start() start_handler = CommandHandler('me', set_tenhou_nickname, pass_args=True) log_handler = CommandHandler('log', set_game_log, pass_args=True) status_handler = CommandHandler('status', get_tournament_status) help_handler = CommandHandler('help', help_bot) # admin commands dispatcher.add_handler( CommandHandler('restart', restart, filters=Filters.user(username='******'))) dispatcher.add_handler( CommandHandler('prepare_next_round', prepare_next_round, filters=Filters.user(username='******'))) dispatcher.add_handler( CommandHandler('start_failed_games', start_failed_games, filters=Filters.user(username='******'))) dispatcher.add_handler( CommandHandler('start_games', start_games, filters=Filters.user(username='******'))) dispatcher.add_handler( CommandHandler('close_registration', close_registration, filters=Filters.user(username='******'))) dispatcher.add_handler(start_handler) dispatcher.add_handler(log_handler) dispatcher.add_handler(status_handler) dispatcher.add_handler(help_handler) dispatcher.add_error_handler(error_callback) dispatcher.add_handler( MessageHandler(Filters.status_update.new_chat_members, new_chat_member)) logger.info('Starting the bot...') updater.start_polling() updater.idle()
class DiscordClient(discord.Client): CONFIRMATION_EN = "confirmation_en" CONFIRMATION_RU = "confirmation_ru" NOTIFICATIONS_EN = "notifications_en" NOTIFICATIONS_RU = "notifications_ru" GENERAL_EN = "general_en" GENERAL_RU = "general_ru" GAME_LOGS = "game_logs" REQUIRED_CHANNELS = [ CONFIRMATION_EN, CONFIRMATION_RU, NOTIFICATIONS_EN, NOTIFICATIONS_RU, GAME_LOGS, GENERAL_EN, GENERAL_RU, ] guild = None channels_dict = None def __init__(self): super(DiscordClient, self).__init__() self.channels_dict = {} self.bg_task = self.loop.create_task(self.send_notifications()) tournament = Tournament.objects.get(id=settings.TOURNAMENT_ID) self.tournament_handler = TournamentHandler() self.tournament_handler.init( tournament, settings.TOURNAMENT_PRIVATE_LOBBY, settings.TOURNAMENT_GAME_TYPE, TournamentHandler.DISCORD_DESTINATION, ) async def on_ready(self): self.guild = discord.utils.get(self.guilds, name=settings.DISCORD_GUILD_NAME) for channel in self.guild.channels: self.channels_dict[channel.name] = channel.id logger.info( f'"{self.user}" has connected to {self.guild.name} (id: {self.guild.id}) guild' ) logger.info(f"found {len(self.guild.channels)} channels") for required_channel in self.REQUIRED_CHANNELS: if required_channel not in self.channels_dict: raise AssertionError( f"Guild doesn't have required #{required_channel} channel") async def on_message(self, message: Message): if message.author == self.user: return channel_name = message.channel.name if channel_name == DiscordClient.CONFIRMATION_EN or channel_name == DiscordClient.CONFIRMATION_RU: await self.confirm_participation(message) return if channel_name == DiscordClient.GAME_LOGS: await self.add_game_log(message) return if message.content == "!status": await self.get_status(message) return if message.content == "!help": await self.get_help(message) return async def get_help(self, message: Message): self.activate_language(message.channel.name) m = "" m += _("1. Tournament lobby:\n <%(lobby_link)s> \n") % { "lobby_link": self.tournament_handler.get_lobby_link() } m += _("2. Tournament statistics:\n <%(rating_link)s> \n") % { "rating_link": self.tournament_handler.get_rating_link() } # m += _("2.1. Team statistics:\n <%(rating_link)s>/team \n") % { # "rating_link": self.tournament_handler.get_rating_link() # } m += _("3. Current games:\n <%(current_games_link)s> \n") % { "current_games_link": f"https://tenhou.net/wg/?{settings.TOURNAMENT_PUBLIC_LOBBY[:5]}" } await message.channel.send(m) async def add_game_log(self, message: Message): _, success = self.tournament_handler.add_game_log(message.content) emoji = success and "\N{THUMBS UP SIGN}" or "\N{NO ENTRY SIGN}" await message.add_reaction(emoji) async def get_status(self, message: Message): self.activate_language(message.channel.name) response = self.tournament_handler.get_tournament_status() await message.channel.send(response) async def confirm_participation(self, message: Message): self.activate_language(message.channel.name) tenhou_nickname = message.content ds_nickname = message.author.name response = self.tournament_handler.confirm_participation_in_tournament( tenhou_nickname, discord_username=ds_nickname) await self.replay(message.channel, message.author, response) async def send_notifications(self): await self.wait_until_ready() if not self.channels_dict: print("no dicts") await asyncio.sleep(5) while not self.is_closed(): notification = TournamentNotification.objects.filter( is_processed=False, destination=TournamentNotification.DISCORD).last() if not notification: await asyncio.sleep(2) continue extra_kwargs = { "confirmation_channel": self.channel_mention(DiscordClient.CONFIRMATION_EN) } message = self.tournament_handler.get_notification_text( "en", notification, extra_kwargs) channel = self.get_channel( self.channels_dict[DiscordClient.NOTIFICATIONS_EN]) await channel.send(message) extra_kwargs = { "confirmation_channel": self.channel_mention(DiscordClient.CONFIRMATION_RU) } message = self.tournament_handler.get_notification_text( "ru", notification, extra_kwargs) channel = self.get_channel( self.channels_dict[DiscordClient.NOTIFICATIONS_RU]) await channel.send(message) notification.is_processed = True notification.save() logger.info(f"notification id={notification.id} sent") await asyncio.sleep(2) async def replay(self, channel, user, message): m = f"{user.mention}\n{message}" await channel.send(m) def channel_mention(self, channel_name): return f"<#{self.channels_dict[channel_name]}>" def activate_language(self, channel_name: str): lang = "en" if channel_name.endswith("_ru"): lang = "ru" activate(lang) return lang