<commit_before>import asyncio
import discord
import re
import os
import random
import string
import json
import time
import html
import codecs
from   random import shuffle
from   discord.ext import commands
from   Cogs import Settings
from   Cogs import DisplayName
from   Cogs import Nullify


class CardsAgainstHumanity:

    # Init with the bot reference, and a reference to the deck file
    def __init__(self, bot, file = None):
        self.bot = bot
        self.games = []
        self.maxBots = 5 # Max number of bots that can be added to a game - don't count toward max players
        self.maxPlayers = 10 # Max players for ranjom joins
        self.maxDeadTime = 3600 # Allow an hour of dead time before killing a game
        self.checkTime = 300 # 5 minutes between dead time checks
        self.winAfter = 10 # 10 wins for the game
        self.botWaitMin = 5 # Minimum number of seconds before the bot makes a decision (default 5)
        self.botWaitMax = 30 # Max number of seconds before a bot makes a decision (default 30)
        self.charset = "1234567890"
        self.botName = '<NAME>'
        self.minMembers = 3
        self.loopsleep = 0.05
        if file == None:
            file = "deck.json"
        # Let's load our deck file
        # Can be found at http://www.crhallberg.com/cah/json
        if os.path.exists(file):
            f = open(file,'r')
            filedata = f.read()
            f.close()

            self.deck = json.loads(filedata)
        else:
            # File doesn't exist - create a placeholder
            self.deck = {}
        self.bot.loop.create_task(self.checkDead())

    def cleanJson(self, json):
        json = html.unescape(json)
        # Clean out html formatting
        json = json.replace('_','[blank]')
        json = json.replace('<br>','\n')
        json = json.replace('<br/>','\n')
        json = json.replace('<i>', '*')
        json = json.replace('</i>', '*')
        return json


    async def checkDead(self):
        while not self.bot.is_closed:
            # Wait first - then check
            await asyncio.sleep(self.checkTime)
            for game in self.games:
                gameTime = game['Time']
                currentTime = int(time.time())
                timeRemain  = currentTime - gameTime
                if timeRemain > self.maxDeadTime:
                    # Game is dead - quit it and alert members
                    for member in game['Members']:
                        if member['IsBot']:
                            # Clear pending tasks and set to None
                            if not member['Task'] == None:
                                task = member['Task']
                                if not task.done():
                                    task.cancel()
                                member['Task'] = None
                            continue
                        msg = "Game id: *{}* has been closed due to inactivity.".format(game['ID'])
                        await self.bot.send_message(member['User'], msg)
                
                    # Set running to false
                    game['Running'] = False
                    self.games.remove(game)

    async def checkPM(self, message):
        # Checks if we're talking in PM, and if not - outputs an error
        if message.channel.is_private:
            # PM
            return True
        else:
            # Not in PM
            await self.bot.send_message(message.channel, 'Cards Against Humanity commands must be run in PM.')
            return False


    def randomID(self, length = 8):
        # Create a random id that doesn't already exist
        while True:
            # Repeat until found
            newID = ''.join(random.choice(self.charset) for i in range(length))
            exists = False
            for game in self.games:
                if game['ID'] == newID:
                    exists = True
                    break
            if not exists:
                break
        return newID

    def randomBotID(self, game, length = 4):
        # Returns a random id for a bot that doesn't already exist
        while True:
            # Repeat until found
            newID = ''.join(random.choice(self.charset) for i in range(length))
            exists = False
            for member in game['Members']:
                if member['ID'] == newID:
                    exists = True
                    break
            if not exists:
                break
        return newID

    def userGame(self, user):
        # Returns the game the user is currently in
        if not type(user) is str:
            # Assume it's a discord.Member/User
            user = user.id

        for game in self.games:
            for member in game['Members']:
                if member['ID'] == user:
                    # Found our user
                    return game
        return None

    def gameForID(self, id):
        # Returns the game with the passed id
        for game in self.games:
            if game['ID'] == id:
                return game
        return None

    async def removeMember(self, user, game = None):
        if not type(user) is str:
            # Assume it's a discord.Member/User
            user = user.id
        outcome  = False
        removed  = None
        if not game:
            game = self.userGame(user)
        if game:
            for member in game['Members']:
                if member['ID'] == user:
                    removed = member
                    outcome = True
                    judgeChanged = False
                    # Reset judging flag to retrigger actions
                    game['Judging'] = False
                    # Get current Judge
                    judge = game['Members'][game['Judge']]
                    game['Members'].remove(member)
                    # Check if we're removing the current judge                    
                    if judge == member:
                        # Judge will change
                        judgeChanged = True
                        # Find out if our member was the last in line
                        if game['Judge'] >= len(game['Members']):
                            game['Judge'] = 0
                        # Reset judge var
                        judge = game['Members'][game['Judge']]
                    else:
                        # Judge didn't change - so let's reset judge index
                        index = game['Members'].index(judge)
                        game['Judge'] = index
                        
                    if member['Creator']:
                        # We're losing the game creator - pick a new one
                        for newCreator in game['Members']:
                            if not newCreator['IsBot']:
                                newCreator['Creator'] = True
                                break
                    
                    # Remove submissions
                    for sub in game['Submitted']:
                        # Remove deleted member and new judge's submissions
                        if sub['By'] == member or sub['By'] == judge:<commit_msg>Inform the new creator of their promotion<commit_after>import asyncio
import discord
import re
import os
import random
import string
import json
import time
import html
import codecs
from   random import shuffle
from   discord.ext import commands
from   Cogs import Settings
from   Cogs import DisplayName
from   Cogs import Nullify


class CardsAgainstHumanity:

    # Init with the bot reference, and a reference to the deck file
    def __init__(self, bot, file = None):
        self.bot = bot
        self.games = []
        self.maxBots = 5 # Max number of bots that can be added to a game - don't count toward max players
        self.maxPlayers = 10 # Max players for ranjom joins
        self.maxDeadTime = 3600 # Allow an hour of dead time before killing a game
        self.checkTime = 300 # 5 minutes between dead time checks
        self.winAfter = 10 # 10 wins for the game
        self.botWaitMin = 5 # Minimum number of seconds before the bot makes a decision (default 5)
        self.botWaitMax = 30 # Max number of seconds before a bot makes a decision (default 30)
        self.charset = "1234567890"
        self.botName = '<NAME>'
        self.minMembers = 3
        self.loopsleep = 0.05
        if file == None:
            file = "deck.json"
        # Let's load our deck file
        # Can be found at http://www.crhallberg.com/cah/json
        if os.path.exists(file):
            f = open(file,'r')
            filedata = f.read()
            f.close()

            self.deck = json.loads(filedata)
        else:
            # File doesn't exist - create a placeholder
            self.deck = {}
        self.bot.loop.create_task(self.checkDead())

    def cleanJson(self, json):
        json = html.unescape(json)
        # Clean out html formatting
        json = json.replace('_','[blank]')
        json = json.replace('<br>','\n')
        json = json.replace('<br/>','\n')
        json = json.replace('<i>', '*')
        json = json.replace('</i>', '*')
        return json


    async def checkDead(self):
        while not self.bot.is_closed:
            # Wait first - then check
            await asyncio.sleep(self.checkTime)
            for game in self.games:
                gameTime = game['Time']
                currentTime = int(time.time())
                timeRemain  = currentTime - gameTime
                if timeRemain > self.maxDeadTime:
                    # Game is dead - quit it and alert members
                    for member in game['Members']:
                        if member['IsBot']:
                            # Clear pending tasks and set to None
                            if not member['Task'] == None:
                                task = member['Task']
                                if not task.done():
                                    task.cancel()
                                member['Task'] = None
                            continue
                        msg = "Game id: *{}* has been closed due to inactivity.".format(game['ID'])
                        await self.bot.send_message(member['User'], msg)
                
                    # Set running to false
                    game['Running'] = False
                    self.games.remove(game)

    async def checkPM(self, message):
        # Checks if we're talking in PM, and if not - outputs an error
        if message.channel.is_private:
            # PM
            return True
        else:
            # Not in PM
            await self.bot.send_message(message.channel, 'Cards Against Humanity commands must be run in PM.')
            return False


    def randomID(self, length = 8):
        # Create a random id that doesn't already exist
        while True:
            # Repeat until found
            newID = ''.join(random.choice(self.charset) for i in range(length))
            exists = False
            for game in self.games:
                if game['ID'] == newID:
                    exists = True
                    break
            if not exists:
                break
        return newID

    def randomBotID(self, game, length = 4):
        # Returns a random id for a bot that doesn't already exist
        while True:
            # Repeat until found
            newID = ''.join(random.choice(self.charset) for i in range(length))
            exists = False
            for member in game['Members']:
                if member['ID'] == newID:
                    exists = True
                    break
            if not exists:
                break
        return newID

    def userGame(self, user):
        # Returns the game the user is currently in
        if not type(user) is str:
            # Assume it's a discord.Member/User
            user = user.id

        for game in self.games:
            for member in game['Members']:
                if member['ID'] == user:
                    # Found our user
                    return game
        return None

    def gameForID(self, id):
        # Returns the game with the passed id
        for game in self.games:
            if game['ID'] == id:
                return game
        return None

    async def removeMember(self, user, game = None):
        if not type(user) is str:
            # Assume it's a discord.Member/User
            user = user.id
        outcome  = False
        removed  = None
        if not game:
            game = self.userGame(user)
        if game:
            for member in game['Members']:
                if member['ID'] == user:
                    removed = member
                    outcome = True
                    judgeChanged = False
                    # Reset judging flag to retrigger actions
                    game['Judging'] = False
                    # Get current Judge
                    judge = game['Members'][game['Judge']]
                    game['Members'].remove(member)
                    # Check if we're removing the current judge                    
                    if judge == member:
                        # Judge will change
                        judgeChanged = True
                        # Find out if our member was the last in line
                        if game['Judge'] >= len(game['Members']):
                            game['Judge'] = 0
                        # Reset judge var
                        judge = game['Members'][game['Judge']]
                    else:
                        # Judge didn't change - so let's reset judge index
                        index = game['Members'].index(judge)
                        game['Judge'] = index
                        
                    if member['Creator']:
                        # We're losing the game creator - pick a new one
                        for newCreator in game['Members']:
                            if not newCreator['IsBot']:
                                newCreator['Creator'] = True
                                await self.bot.send_message(newCreator['User'], 'The creator of this game left.  **YOU** are now the creator.')
                                break
                    
                    # Remove submissions
                    for sub in game['Submitted']:
                        # Remove deleted member and new judge's submissions
                        if sub['By'] == member or sub['By'] == judge:
{'fraction_non_alphanumeric': 0.08221915920055134, 'fraction_numerical': 0.00523776705720193, 'mean_word_length': 1.2790953353227579, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3280845', 'n_tokens_mistral': 3673, 'n_tokens_neox': 3384, 'n_words': 1240}