<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.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.charset = "1234567890"
        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()
            """#filedata = filedata.encode()
            filedata = self.cleanJson(filedata)
            f = open(file,'w', encoding='utf-16')
            f.write(filedata)
            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)
        #json = json.encode('utf-8', 'replace')
        json = json.replace('_','[blank]')
        json = json.replace('<br>','\n')
        json = json.replace('<i>', '*')
        json = json.replace('</i>', '*')
        return json


    async def checkDead(self):
        # 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']:
                    msg = "Game id: *{}* has been closed due to inactivity.".format(game['ID'])
                    await self.bot.send_message(member['User'], msg)
                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 userGame(self, user):
        # Returns the game the user is currently in
        for game in self.games:
            for member in game['Members']:
                if member['User'] == 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

    def removeMember(self, user, game = None):
        if game:
            for member in game['Members']:
                if member['User'] == user:
                    game['Members'].remove(member)
                    self.checkGame(game)
                    return game
            return None
        game = self.userGame(user)
        if game:
            for member in game['Members']:
                if member['User'] == user:
                    game['Members'].remove(member)
                    self.checkGame(game)
                    return game
        return None

    def checkGame(self, game):
        if not len(game['Members']):
            # Game is empty - remove it
            self.games.remove(game)

    ################################################
    
    async def showPlay(self, user):
        # Creates an embed and displays the current game stats
        stat_embed = discord.Embed(color=discord.Color.teal())
        game = self.userGame(user)
        if not game:
            return
        # add the game id
        stat_embed.set_author(name='Cards Against Humanity - id: {}'.format(game['ID']))
        # Get the judge's name
        if game['Members'][game['Judge']]['User'] == user:
            judge = '**YOU**'
        else:
            judge = DisplayName.name(game['Members'][game['Judge']]['User'])
        stat_embed.add_field(name="Judge", value=judge, inline=True)
        # Get the Black Card
        try:
            blackCard = '**{}**'.format(game['BlackCard']['Text'])
        except Exception:
            blackCard = 'None.'
        stat_embed.add_field(name="Black Card", value=blackCard, inline=True)
        await self.bot.send_message(user, embed=stat_embed)
        
    async def showHand(self, user):
        # Shows the user's hand in an embed
        stat_embed = discord.Embed(color=discord.Color.teal())
        game = self.userGame(user)
        if not game:
            return
        stat_embed.set_author(name='{} - Hand'.format(DisplayName.name(user)))
        i = 0
        for member in game['Members']:
            if member['ID'] == user.id:
                # Got our user
                for card in member['Hand']:
                    i += 1
                    stat_embed.add_field(name='', value='{}. {}'.format(i, card['Text']), inline=False)
        await self.bot.send_message(user, embed=stat_embed)
                              
    async def showOptions(self, ctx, user):
        # Shows the judgement options
        stat_embed = discord.Embed(color=discord.Color.teal())
        game = self.userGame(user)
        if not game:
            return
        # Add title
        stat_embed.set_author(name='JUDGEMENT TIME!')
        if game['Members'][game['Judge']]['User'] == user:
            judge = '**YOU**'
        else:
            judge = DisplayName.name(game['Members'][game['Judge']]['User'])
        # Add Judge
        stat_embed.add_field(name="Judge", value=judge, inline=True)
        # Add black card
        stat_embed.add_field(name="Black Card", value='**{}**'.format(game['BlackCard']['Text']), inline=True)
        i = 0
        for sub in game['Submitted']:
            i+=1
            stat_embed.add_field(name='', value='{}. {}'.format(i, ' - '.join(sub['Cards'])), inline=False)
        #stat_embed.add_field(name="Cards Submitted", value=msg, inline=True)
        await self.bot.send_message(user, embed=stat_embed)
        
    async def drawCard(self, game):
        # Draws a random unused card and shuffles the deck if needed
        totalDiscard = len(game['Discard'])
        for member in game['Members']:
            totalDiscard += len(member['Hand'])
        if totalDiscard >= len(self.deck['whiteCards']):<commit_msg>Update CardsAgainstHumanity.py<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.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.charset = "1234567890"
        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()
            """#filedata = filedata.encode()
            filedata = self.cleanJson(filedata)
            f = open(file,'w', encoding='utf-16')
            f.write(filedata)
            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)
        #json = json.encode('utf-8', 'replace')
        json = json.replace('_','[blank]')
        json = json.replace('<br>','\n')
        json = json.replace('<i>', '*')
        json = json.replace('</i>', '*')
        return json


    async def checkDead(self):
        # 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']:
                    msg = "Game id: *{}* has been closed due to inactivity.".format(game['ID'])
                    await self.bot.send_message(member['User'], msg)
                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 userGame(self, user):
        # Returns the game the user is currently in
        for game in self.games:
            for member in game['Members']:
                if member['User'] == 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

    def removeMember(self, user, game = None):
        if game:
            for member in game['Members']:
                if member['User'] == user:
                    game['Members'].remove(member)
                    self.checkGame(game)
                    return game
            return None
        game = self.userGame(user)
        if game:
            for member in game['Members']:
                if member['User'] == user:
                    game['Members'].remove(member)
                    self.checkGame(game)
                    return game
        return None

    def checkGame(self, game):
        if not len(game['Members']):
            # Game is empty - remove it
            self.games.remove(game)

    ################################################
    
    async def showPlay(self, user):
        # Creates an embed and displays the current game stats
        stat_embed = discord.Embed(color=discord.Color.teal())
        game = self.userGame(user)
        if not game:
            return
        # add the game id
        stat_embed.set_author(name='Cards Against Humanity - id: {}'.format(game['ID']))
        # Get the judge's name
        if game['Members'][game['Judge']]['User'] == user:
            judge = '**YOU**'
        else:
            judge = DisplayName.name(game['Members'][game['Judge']]['User'])
        stat_embed.add_field(name="Judge", value=judge, inline=True)
        # Get the Black Card
        try:
            blackCard = '**{}**'.format(game['BlackCard']['Text'])
        except Exception:
            blackCard = 'None.'
        stat_embed.add_field(name="Black Card", value=blackCard, inline=True)
        await self.bot.send_message(user, embed=stat_embed)
        
    async def showHand(self, user):
        # Shows the user's hand in an embed
        stat_embed = discord.Embed(color=discord.Color.teal())
        game = self.userGame(user)
        if not game:
            return
        stat_embed.set_author(name='{} - Hand'.format(DisplayName.name(user)))
        i = 0
        for member in game['Members']:
            if member['ID'] == user.id:
                # Got our user
                for card in member['Hand']:
                    i += 1
                    stat_embed.add_field(name=' ', value='{}. {}'.format(i, card['Text']), inline=False)
        await self.bot.send_message(user, embed=stat_embed)
                              
    async def showOptions(self, ctx, user):
        # Shows the judgement options
        stat_embed = discord.Embed(color=discord.Color.teal())
        game = self.userGame(user)
        if not game:
            return
        # Add title
        stat_embed.set_author(name='JUDGEMENT TIME!')
        if game['Members'][game['Judge']]['User'] == user:
            judge = '**YOU**'
        else:
            judge = DisplayName.name(game['Members'][game['Judge']]['User'])
        # Add Judge
        stat_embed.add_field(name="Judge", value=judge, inline=True)
        # Add black card
        stat_embed.add_field(name="Black Card", value='**{}**'.format(game['BlackCard']['Text']), inline=True)
        i = 0
        for sub in game['Submitted']:
            i+=1
            stat_embed.add_field(name=' ', value='{}. {}'.format(i, ' - '.join(sub['Cards'])), inline=False)
        #stat_embed.add_field(name="Cards Submitted", value=msg, inline=True)
        await self.bot.send_message(user, embed=stat_embed)
        
    async def drawCard(self, game):
        # Draws a random unused card and shuffles the deck if needed
        totalDiscard = len(game['Discard'])
        for member in game['Members']:
            totalDiscard += len(member['Hand'])
        if totalDiscard >= len(self.deck['whiteCards']):
{'fraction_non_alphanumeric': 0.12052692333808651, 'fraction_numerical': 0.004074149521287432, 'mean_word_length': 1.8295869356388088, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5081175', 'n_tokens_mistral': 4165, 'n_tokens_neox': 3963, 'n_words': 1146}