import discord
import random
import datetime
import time
import re
import operator
import asyncio
import traceback
from pymongo import MongoClient
from discord.ext import tasks
import os

client = discord.Client()
mongo_URL = os.environ["MONGO_URL"]
connection = MongoClient(mongo_URL)
db = connection.get_database("Erin")

prefix = "용왕님 "
prefix2 = "용왕님"

isPlaying = False

@client.event
async def on_ready():
    print(client.user.id)
    print("ready")
    #game = discord.Game("베타테스트")
    Daily.start()
    await client.change_presence(status=discord.Status.online)
    #, activity=game

@client.event
async def on_error(event, *args, **kwargs):
    appInfo = await client.application_info()
    owner = appInfo.owner
    if len(args) > 0:
        await owner.send("{0} : {1}\n{2} 에러\n에러메세지 : {3}".format(args[0].author.display_name, args[0].content, event, traceback.format_exc()))
        return None
    else:
        await owner.send("{0}에러\n{1}".format(event, traceback.format_exc()))
        return None

@client.event
async def on_message(message):
    if message.author.bot:
        return None
    if type(message.channel) == discord.DMChannel:
        appInfo = await client.application_info()
        owner = appInfo.owner
        await owner.send("{0} : {1}".format(message.author.name, message.content))
        return None
    collection = db.Point
    try:
        if message.guild.name == "『카르멘』𝓒𝓐𝓡𝓜𝓔𝓝":
            utcnow = datetime.datetime.utcnow()
            time_gap = datetime.timedelta(hours=9)
            now = utcnow + time_gap
            collection.update_one({"_id": message.author.id}, {
                "$setOnInsert": {"!name": message.author.display_name, "lotto": [], "count": 0, "point": 0, "daily": False,
                                "dailyCount": 0, "caution": [], "!creation_Date": now}}, upsert=True)
            collection.update_one({"_id": message.author.id}, {"$set": {"!name": message.author.display_name, "!creation_Date": now}, "$inc": {"point": random.randrange(0, 2)}}, upsert=True)

            if message.channel.category.name.startswith("SNS"):
                for i in message.role_mentions:
                    if i.name.startswith(message.channel.name):
                        tmp_topic = re.findall("게시물 \[\d+\]", message.channel.topic)[0]
                        number = int(re.findall("\d+", tmp_topic)[0]) + 1
                        _topic = message.channel.topic.replace(tmp_topic, "게시물 [%s]" % str(number))
                        try:
                            await message.channel.edit(topic=_topic)
                        except TypeError:
                            pass
                        return None
    except discord.errors.HTTPException:
        appInfo = await client.application_info()
        owner = appInfo.owner
        await owner.send("그 투매니 어쩌구 에러\n{}".format(traceback.format_exc()))
        return None

    talk = ""
    if message.content.startswith(prefix):
        talk = message.content[len(prefix):]
    elif message.content.startswith(prefix2):
        talk = message.content[len(prefix2):]
    else:
        return None

    if talk.startswith("초기화"):
        utcnow = datetime.datetime.utcnow()
        time_gap = datetime.timedelta(hours=9)
        now = utcnow + time_gap
        #users = collection.find()
        #for i in users:
            #collection.update_one(i, {"$set" : {"!creation_Date": now}}, upsert=True)
        await message.channel.send("초기화 되었습니다")
        return None
    if talk.startswith("안녕"):
        Chat = ["안녕", "응?", "왜?", "어?", "왜 불러?"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("뭐해"):
        Chat = [" 생각", "유튜브 봐", "내 생각", "그냥 있어"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("심심해"):
        Chat = ["내 생각 하면 되지", "나두", "나랑 놀자"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if "바보" in ''.join(talk) or "멍청이" in ''.join(talk):
        Chat = [";;", "너는?", "멍청이", "너가 더", "응."]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("보고싶었어"):
        Chat = ["나도", "나도 보고 싶었어", "ㅇ0ㅇ!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("사랑해"):
        Chat = ["나도 사랑해", "응", "!", "어머나", "나도 날 사랑해" , "(•᷄⌓•᷅ )"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("좋아해"):
        Chat = ["나도", "!", "나도 내가 좋아"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("사귀자"):
        Chat = ["친구부터 천천히 알아가자", "난 지금의 우리가 좋아",
                "아빠가 안된대", "엄마가 안된대", "가족이 반대해"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("결혼하자"):
        Chat = ["우리 너무 이른 거 같아", "나 마음의 시간이 필요해",
                "미안", "아 잠시만 불 안 끄고 왔어 가볼게"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("헤어져"):
        Chat = ["우리 사이에 그런 게 어딨어..",
                "우리가 그럴 만한 사이였니?", "그래"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("반가워"):
        Chat = ["그래", "반가워", "나도"]
        await message.channel.send(Chat[random.randrange(0, len(Chat))])
        return None
    if talk.startswith("손"):
        Chat = ["발", "절", "손"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("물어"):
        Chat = ["내가 왜?" , "싫어", "어딜?"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("배고파"):
        Chat = ["나도", "돼지", "밥은 먹었어?", "뭐라도 먹어"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("졸려"):
        Chat = ["나도 졸려", "그럼 자", "나랑 잘래?"]
        await message.channel.send(Chat[random.randrange(0, len(Chat))])
        return None
    if talk.startswith("누구"):
        Chat = ["날 몰라?", "실망이야", "바보", "멍청이", "나는야 카르멘 서버의 서버 봇!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("자기소개"):
        Chat = ["나는야 카르멘 서버의 멋진 서버봇! 어때 완전 멋찌지?"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("몇살?") or talk.startswith("나이"):
        Chat = ["나 하유님이랑 동갑", "비밀", "나 몇 살 같아?", "2살"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("성별"):
        Chat = ["나 여자같아 남자같아?", "당연히 여자 아냐?", "그 물어봐야 아니?"]
        await message.channel.send(Chat[random.randrange(0, len(Chat))])
        return None
    if talk.startswith("뭐 먹지?"):
        Chat = ["나도 몰라", "먹고 싶은 거 먹어", "나:heart:"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("여보세요"):
        Chat = ["어디야?", "여보세요?", "나 불렀어?", "응 여보"]
        await message.channel.send(Chat[random.randrange(0, len(Chat))])
        return None
    if talk.startswith("화내"):
        msg = await message.channel.send("😠")
        await asyncio.sleep(5)
        try:
            await msg.delete()
        except discord.errors.NotFound:
            return None
        return None
    if talk.startswith("이름"):
        await message.channel.send("'아름다운' 이라는 뜻을 가진 라틴어 '에일린' 에서 따왔어")
        return None
    if talk.startswith("카르멘"):
        Chat = ["rpg게임을 모티브로한 멋있는 친목 서버지" , "지금 여기 잖아"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("하유"):
        Chat = ["이 서버 주인, 카르멘 서버 겜마이지"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("청월") or talk.startswith("서하린"):
        Chat = ["미술관장이시지, 예쁜 분, 내 외형을 만들어 주셨어"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("고래"):
        Chat = ["음악관장이시지", "바보"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("피아"):
        Chat = ["1년 임시 대신관이야", "엄청 귀여우셔"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("한울"):
        Chat = ["기사단장이지, 국방의 의무를 다하시는 중","^^7"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("시낚") or talk.startswith("시나기") or talk.startswith("시간낚시꾼"):
        Chat = ["군대간 친구 자리를 지키는 1년 임시 기사단장"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("개발팀"):
        Chat = ["내 부모님들이잖아", "내 가족이지", "날 만들어주셨어"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("윤세연"):
        Chat = ["1년 잠수타시는 대신관이자 개발팀!", "곧 오실 거야.."]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("상런쳐") or talk.startswith("상런처") or talk.startswith("발사통") or talk.startswith("런처") or talk.startswith("런쳐"):
        await message.channel.send("에린이 아빠에요")
        await asyncio.sleep(1)
        await message.channel.send("안녕해요")
        await asyncio.sleep(1)
        await message.channel.send("반갑다요?")
        return None
    if talk.startswith("안내팀"):
        Chat = ["우리 게임 tutorial진행해주는 팀!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("밤연"):
        Chat = ["귀여우시고 목소리 예쁘신 안내팀!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("유연"):
        await message.channel.send("안내팀의 노예지")
        await asyncio.sleep(1)
        await message.channel.send("빠져나갈 수 없어 그는..")
        return None
    if talk.startswith("기획팀"):
        Chat = ["우리 서버 이벤트 기획하는 팀!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("세라") or talk.startswith("율아") or talk.startswith("민율아"):
        Chat = ["귀여운 기획팀 분이야!", "율아님 귀엽지", "율아님 섹시하지", "율아님 섹시하고 깜찍하고 발랄하고 예쁘고 기엽고 매력적이고 이쁘고 에린이꺼❤"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("여림") or talk.startswith("유령"):
        if random.randrange(0, 2) == 0:
            await message.channel.send("기획팀을 나가게 된다면 꼭 그에게 고백하겠어!")
            await asyncio.sleep(1)
            await message.channel.send("해치웠나?")
            return None
        Chat = ["여리미눈 도니 됴아>_<"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("디자인팀"):
        Chat = ["우리 게임에 쓰이는 모든 그림을 맡아주는 팀!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("라호"):
        Chat = ["배경을 도맡아 그려주시는 디자인팀의 금손!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("온점") or talk.startswith("와드") or talk.startswith("담이"):
        Chat = ["귀여운 분", "디자인팀이셔"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if talk.startswith("queens"):
        Chat = ["도트 찍으시는 금손 디자인팀 분!"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None

    if talk.startswith("가온"):
        Chat = ["금수저"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None
    if "푸" in ''.join(talk) and "딩" in ''.join(talk):
        Chat = ["🍮", "푸딩은 맛나"]
        await message.channel.send(Chat[random.randrange(0, len(Chat))])
        return None
    if talk.startswith("몽쉘"):
        Chat = ["몽쉘 맛있지"]
        await message.channel.send(Chat [random.randrange(0, len(Chat))])
        return None

    if talk.startswith("노라조"):
        Chat = ["https://www.youtube.com/watch?v=2CGc9Ly11yo","https://www.youtube.com/watch?v=ao58vQDMVlQ",
                "https://www.youtube.com/watch?v=JBoqPoqA8mM",
                "https://www.youtube.com/watch?v=AX3nSbKHDQU", "https://www.youtube.com/watch?v=YEYDPgfY-bE"]
        await message.channel.send("이분이랑 노는건 어때?")
        await message.channel.send(Chat[random.randrange(0, len(Chat))])
        return None

    if talk.startswith("나<@") or talk.startswith("나 <@"):
        await message.channel.send("https://www.youtube.com/watch?v=5lSBWirWJgY")
        return None

    if talk.startswith("시간") or talk.startswith("시간은"):
        utcnow = datetime.datetime.utcnow()
        time_gap = datetime.timedelta(hours=9)
        now = utcnow + time_gap
        await message.channel.send(str(now.year) + "년 " + str(now.month) + "월 " + str(now.day) + "일 | " + str(now.hour) + ":" + str(now.minute) + ":" + str(now.second))
        return None

    if talk.startswith("춤"):
        dance = ["ㄴㅇ0ㅇㄱ", "ㄴ'^'ㄱ", "ㄴ( ᐛ )ㄱ", "ㄴ(ｏ`皿′ｏ)ㄱ", "ㄴ(≧▽≦)ㄱ", "ㄴ(。•́︿•̀。)ㄱ", "ㄴ( ･ㅂ･)ㄱ"]
        msg = await message.channel.send(dance[random.randrange(0, len(dance))])
        i = 0
        while i < 5:
            await asyncio.sleep(0.5)
            table = str.maketrans('ㄴㄱ', 'ㄱㄴ')
            await msg.edit(content=msg.content.translate(table))
            i += 1
        return None

    if talk.startswith("랩"):
        rap = ["상처를 치료해줄 사람 어디 없나\n가만히 놔두다간 끊임없이 덧나\n사랑도 사람도 너무나도 겁나\n혼자인게 무서워 난 잊혀질까 두려워"]
        msg = rap[random.randrange(0, len(rap))]
        i = 1
        chat = await message.channel.send(msg[0])
        temp = chat.content
        for i in msg[1:]:
            temp += i
            await chat.edit(content=temp)

    if talk.startswith("도움말") or talk.startswith("명령어"):
        await Help(message)
        return None

    if talk.startswith("사진"):
        await message.channel.send(file=discord.File("에린님.png"))
        return None

    if talk.startswith("로또"):
        await Lotto(message, talk)
        return None

    if talk.startswith("경고"):
        await Caution(message, talk)
        return None

    if talk.startswith("포인트"):
        await Point(message, talk)
        return None

    if talk.startswith("출석"):
        user = collection.find({"_id" : message.author.id})[0]
        if user.get("daily"):
            await message.channel.send("이미 출석했어")
            return None

        count = user.get("dailyCount")
        point = random.randrange(10, 300)
        pointmsg = str(point)
        count += 1
        if count % 50 == 0:
            point += 1000
            pointmsg += " + 1000(%d0일 누적)" % ((count / 50) * 5)
        elif count % 10 == 0:
            point += 100
            pointmsg += " + 100(%d0일 누적)" % (count / 10)
        collection.update_one({"_id" : message.author.id}, {"$inc" : {"point" : point, "dailyCount" : 1}, "$set" : {"daily" : True}})

        embed = discord.Embed(title="%-6s" % message.author.display_name, colour=discord.Colour.red())
        embed.add_field(name="포인트", value=pointmsg, inline=False)
        embed.add_field(name="출석일수", value=count, inline=False)
        embed.add_field(name="총포인트", value=user.get("point") + point, inline=False)
        await message.channel.send(embed=embed)
        return None

    if talk.startswith("닉네임"):
        job = " |" + message.author.display_name.split("|")[1]
        member = message.guild.get_member(message.author.id)
        try:
            await member.edit(nick=talk[4:] + job)
            await message.channel.send(talk[4:] + job + "으로 바꿨어")
        except discord.errors.Forbidden:
            await message.channel.send("너 이름은 못바꿔")
        return None

    if talk.startswith("고양이"):
        #embed = discord.Embed( title="타이틀",description="내용",colour=discord.Colour.red())
        embed = discord.Embed()
        urlBase = 'https://loremflickr.com/320/240?lock='
        randomNum = random.randrange(1, 30977)
        urlF = urlBase + str(randomNum)
        embed.set_image(url=urlF)
        await message.channel.send(embed=embed)
        return None

    if talk.startswith("검색"):
        _url = str(talk[3:].encode("UTF-8"))
        _url = _url.replace("\\x", "%")
        _url = _url.replace("'", "")
        _url = _url[1:]
        _url = "https://search.naver.com/search.naver?sm=top_hty&fbm=1&ie=utf8&query={0}".format(_url)
        embed = discord.Embed(title="검색 결과", colour=discord.Colour.red())
        embed.add_field(name="검색", value=_url, inline=False)
        embed.set_image(url="https://s.pstatic.net/static/www/mobile/edit/2016/0705/mobile_212852414260.png")
        await message.channel.send(embed=embed)
        return None

    if talk.startswith("프로필"):
        embed = discord.Embed()
        embed.set_image(url=message.author.avatar_url)
        await message.channel.send(embed=embed)
        return None

    if talk.startswith("sns"):
        await Sns(message, talk)
        return None

    if talk.startswith("구매"):
        await Buy(message, talk)
        return None

    if talk.startswith("id") or talk.startswith("ID"):
        await message.channel.send(message.author.mention + "님의 ID는 \n" + "```" + str(message.author.id) + "```")
        return None

    if talk.startswith("삭") or talk.startswith("청") or talk.startswith("지"):#삭제 청소 지워
        def is_me(m):
            if m.author == message.author:
                if not m.content == message.content:
                    return True
        try:
            talk = talk.split(" ")
            _limit = int(talk[1])
        except (IndexError, ValueError):
            _limit = 100
        await message.add_reaction("⏳")
        await message.channel.purge(limit=_limit+1, check=is_me)
        await message.clear_reactions()
        await message.add_reaction("✅")
        await asyncio.sleep(5)
        try:
            await message.delete()
        except discord.errors.NotFound:
            return None
        return None

    if talk.startswith("팔로우생성"):
        if (message.channel.permissions_for(message.author).value & 0x00000008) != 0x00000008:
            await message.channel.send("권한이 없어")
            return None
        await message.channel.send(talk[6:])
        return None
    if talk.startswith("수정"):
        if (message.channel.permissions_for(message.author).value & 0x00000008) != 0x00000008:
            await message.channel.send("권한이 없어")
            return None
        messages = await message.channel.history(limit=100, oldest_first=False).flatten()
        for m in messages:
            if m.author.bot:
                await m.edit(content=talk[2:])
                await message.add_reaction("✅")
                return None
        return None

    if talk.startswith("가위바위보"):
        def check(m):
            return m.author == message.author and (m.content == "가위" or m.content == "바위" or m.content == "보")
        await message.channel.send("가위 바위 보!")
        try:
            msg = await client.wait_for('message', timeout=10.0, check=check)
        except asyncio.TimeoutError:
            await message.channel.send("너무 오래걸려ㅡnㅡ")
        else:
            rsp_list = ["가위", "바위", "보"]
            rsp = rsp_list[random.randint(0, 2)] # 0 = 가위, 1 = 바위, 2 = 보

            result = ""
            if msg.content == rsp:
                result = "무승부"
            else:
                if rsp == "가위":
                    result = "승리" if msg.content == "바위" else "패배"
                elif rsp == "바위":
                    result = "승리" if msg.content == "보" else "패배"
                elif rsp == "보":
                    result = "승리" if msg.content == "가위" else "패배"

            embed = discord.Embed(title="가위바위보", colour=discord.Colour.red())
            embed.add_field(name=message.author.display_name, value=msg.content, inline=False)
            embed.add_field(name="에린", value=rsp, inline=False)
            embed.set_footer(text=result)
            await message.channel.send(embed=embed)

    if talk.startswith("역할삭제"):
        if (message.channel.permissions_for(message.author).value & 0x00000008) != 0x00000008:
            await message.channel.send("권한이 없어")
            return None
        role = message.guild.get_role(int(re.findall("\d+", talk.split(" ")[1])[0]))
        snsChannel = discord.utils.get(client.get_all_channels(), guild__name=message.guild.name, name=role.name.split("팔로워")[0])
        tmp_topic = re.findall("팔로워 \[\d+\]", snsChannel.topic)[0]
        for user in role.members:
            await user.remove_roles(role)
        _topic = snsChannel.topic.replace(tmp_topic, "팔로워 [0]")
        await message.add_reaction("✅")
        try:
            await snsChannel.edit(topic=_topic)
        except TypeError:
            pass
        return None

    global isPlaying
    if talk.startswith("구구단"):
        if isPlaying:
            await message.channel.send("이미 진행중인 게임이 있습니다.")
            return None
        await GuGuDan(message)
        return None

    if talk.startswith("369") or talk.startswith("삼육구"):
        if isPlaying:
            await message.channel.send("이미 진행중인 게임이 있습니다.")
            return None
        await ThreeSixNine(message)
        return None

    if talk.startswith("더게임오브데스") or talk.startswith("더 게임 오브 데스"):
        if isPlaying:
            await message.channel.send("이미 진행중인 게임이 있습니다.")
            return None
        await TheGameOfDeth(message)
        return None

    if talk.startswith("스탯"):
        await Stat(message, talk)
        return None

    if talk.startswith("대결") or talk.startswith("PVP") :
        if isPlaying:
            await message.channel.send("이미 진행중인 게임이 있어")
            return None
        await PVP(message, talk)
        return None

    if talk.startswith("능력치"):
        collection = db.Stat
        embed = discord.Embed(title="{0}님의 능력치".format(message.author.display_name), colour=discord.Colour.red())
        player = collection.find({"_id": message.author.id})[0]
        if talk.startswith("능력치 <@"):
            user_ID = int(re.findall("\d+", talk)[0])
            if not list(collection.find({"_id": user_ID})):
                await message.channel.send("능력치가 없어")
                return None
            embed = discord.Embed(title="{0}님의 능력치".format(message.guild.get_member(user_ID).display_name), colour=discord.Colour.red())
            player = collection.find({"_id" : user_ID})[0]
        else:
            if not list(collection.find({"_id": message.author.id})):
                await message.channel.send("능력치가 없어")
                return None
        embed.add_field(name="공격력", value=player.get("STR"), inline=True)
        embed.add_field(name="마력", value=player.get("INT"), inline=True)
        embed.add_field(name="체력", value=player.get("HP"), inline=True)
        embed.add_field(name="방어력", value=player.get("DEF"), inline=True)
        await message.channel.send(content=message.author.mention, embed=embed)
        return None

async def Lotto(message, talk):
    lotto_Talk = talk.split(" ")
    collection = db.Point
    if lotto_Talk[1] == "초기화":
        all = collection.find()
        for x in all:
            collection.update_one(x, {"$min": {"count" : 0,  "lotto": []}}, upsert=True)
        await message.channel.send("로또를 초기화했습니다")
        return None

    try:
        lotto_List = collection.find({"_id": message.author.id})[0].get("lotto")
        count = collection.find({"_id": message.author.id})[0].get("count")
    except IndexError:
        collection.insert_one({"_id": message.author.id, "count": 0, "lotto": []})
        lotto_List = []
        count = 0

    if  lotto_Talk[1] == "랜덤":
        try:
            lotto = int(lotto_Talk[2])
            lotto / 10
        except (ValueError, ZeroDivisionError):
            await message.channel.send("0을 제외한 숫자를 써주세요 \nex) 에린아 로또 랜덤 5")
            return None
        if count > 10 or count + int(lotto_Talk[2]) > 10:
            await message.channel.send("로또는 10개까지만 구매하실 수 있습니다")
            await message.channel.send("<@" + str(message.author.id) + "> 님의 로또 수 : " + str(count))
            return None
        _count = int(lotto_Talk[2])
        for i in range(1, _count + 1):
            while True:
                a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
                lotto = ""
                for j in range(0, 6):
                    index = random.randint(0, len(a) - 1)
                    lotto = lotto + str(a[index])
                    del a[index]
                if lotto in lotto_List:
                    continue
                await message.channel.send(lotto)
                lotto_List.append(lotto)
                break

        collection.update_one({"_id": message.author.id}, {"$set": {"_id": message.author.id, "Count": count + _count, "lotto": lotto_List}},upsert=True)
        return None

    if lotto_Talk[1] =="선택":
        if count + 1 > 10:
            await message.channel.send("로또는 하루에 10개까지만 구매하실 수 있습니다")
            await message.channel.send(str(message.author.name) + "님의 로또 수 : " + str(count))
            return None
        try:
            lotto = int(lotto_Talk[2])
            lotto / 10
        except ValueError:
            await message.channel.send("서로다른 숫자 6자리를 입력해주세요.")
            return None
        lotto = str(lotto)
        if not len(lotto) == 6:
            await message.channel.send("0을 제외한 숫자 6자리를 입력해주세요.")
            return None
        lotto_str = ""
        for i in lotto:
            for j in lotto_str:
                if j == i:
                    await message.channel.send("서로다른 숫자 6자리를 입력해주세요.")
                    return None
            lotto_str += i
        for l in lotto_List:
            if l == lotto:
                await message.channel.send("이미 등록된 번호입니다")
                await message.channel.send("<@" + str(message.author.id) + "> 님의 로또 : " + str(lotto_List))
                return None
        lotto_List.append(lotto)
        collection.update_one({"_id": message.author.id}, {"$set": {"_id": message.author.id, "Count": count + 1, "lotto": lotto_List}},upsert=True)
        await message.channel.send(lotto + "\n로또를 입력했습니다")
        return None

    if lotto_Talk[1] == "확인":
        await message.channel.send(str(message.author.name)+ " 님의 로또 : \n" + str(lotto_List))
        return None

    if lotto_Talk[1] == "전체":
        embed = discord.Embed(title="로또 전체", colour=discord.Colour.red())
        embed.set_footer(text="1등하구싶다")
        f = collection.find()
        for line in f:
            User = client.get_user(int(line.get("_id")))
            embed.add_field(name=User.display_name, value= collection.find({"_id" : line.get("_id")})[0].get("lotto"), inline=False)
        await message.channel.send(embed=embed)

async def Caution(message, talk):
    caution_Talk = talk.split(" ")

    #에린아 경고
    if len(caution_Talk) < 2:
        cautionMessage = ""
        with open("Caution.txt", 'r') as f:
            for line in f:
                if (line.startswith(str(message.author.id))):
                    cautionMessage += "{0}월 {1}일 경고\n".format(line[19], line[20:len(line) - 1])
        if cautionMessage == "":
            await message.channel.send(message.author.name + "님은 경고가 없습니다")
            return None
        embed = discord.Embed(title="{0}님의 경고".format(message.author.name), colour=discord.Colour.red())
        embed.add_field(name="경고", value=cautionMessage, inline=False)
        await message.channel.send(embed=embed)
        return None

    if caution_Talk[1].startswith("<@"):
        cautionMessage = ""
        User_ID = int(re.findall("\d+", caution_Talk[1])[0])
        with open("Caution.txt", 'r') as f:
            for line in f:
                if (line.startswith(str(User_ID))):
                    cautionMessage += "{0}월 {1}일 경고\n".format(line[19], line[20:len(line) - 1])
        if cautionMessage == "":
            await message.channel.send(message.guild.get_member(User_ID).name + "님은 경고가 없습니다")
            return None
        embed = discord.Embed(title="{0}님의 경고".format(message.guild.get_member(User_ID).name), colour=discord.Colour.red())
        embed.add_field(name="경고", value=cautionMessage, inline=False)
        await message.channel.send(embed=embed)

    if caution_Talk[1] == "지급":
        if (message.channel.permissions_for(message.author).value & 0x00000008) != 0x00000008:
            await message.channel.send("권한이 없어")
            return None
        User_ID = re.findall("\d+", caution_Talk[2])
        with open("Caution.txt", 'a') as f:
            now = datetime.datetime.now()
            for i in range(0, int(caution_Talk[3])):
                f.write(User_ID[0] + " " + str(now.month) + str(now.day) + "\n")
        User = client.get_user(int(User_ID[0]))
        await message.channel.send("{0}에게 경고를 {1}회 줬어".format(User.name, caution_Talk[3]))
        return None

async def Point(message, talk):
    point_Talk = talk.split(" ")
    collection = db.Point

    if len(point_Talk) < 2:
        point = collection.find({"_id": message.author.id})[0].get("point")
        embed = discord.Embed(title=message.author.display_name, colour=discord.Colour.red())
        embed.add_field(name="포인트", value="{0} 포인트".format(point), inline=False)
        await message.channel.send(embed=embed)
        return None

    if point_Talk[1].startswith("<@"):
        User_ID = int(re.findall("\d+", point_Talk[1])[0])
        point = collection.find({"_id": User_ID})[0].get("point")
        embed = discord.Embed(title=client.get_user(User_ID).display_name, colour=discord.Colour.red())
        embed.add_field(name="포인트", value="{0} 포인트".format(point), inline=False)
        await message.channel.send(embed=embed)
        return None

    if point_Talk[1] == "지급":
        if (message.channel.permissions_for(message.author).value & 0x00000008) != 0x00000008:
            await message.channel.send("권한이 없어")
            return None
        User_ID = int(re.findall("\d+", point_Talk[2])[0])
        collection.update_one({"_id": message.author.id}, {"$inc" : {"point" : int(point_Talk[3])}})
        await message.channel.send("{0}에게 {1}포인트 지급했어".format(client.get_user(User_ID).name, int(point_Talk[3])))
        return None

    if point_Talk[1] == "반환":
        if (message.channel.permissions_for(message.author).value & 0x00000008) != 0x00000008:
            await message.channel.send("권한이 없어")
            return None
        User_ID = int(re.findall("\d+", point_Talk[2])[0])
        collection.update_one({"_id": User_ID}, {"$inc": {"point": -int(point_Talk[3])}})
        await message.channel.send("{0}에게 {1}포인트를 반환했어".format(client.get_user(User_ID).name, point_Talk[3]))
        return None

    if point_Talk[1] == "선물":
        User_ID = int(re.findall("\d+", point_Talk[2])[0])
        User = collection.find({"_id": User_ID})
        if collection.find({"_id" : message.author.id})[0].get("point") <= int(point_Talk[3]):
            await message.channel.send("포인트가 부족해")
            return None

        collection.update_one({"_id" : message.author.id}, {"$inc" : {"point" : - int(point_Talk[3])}})
        collection.update_one({"_id": User_ID}, {"$inc": {"point": int(point_Talk[3])}})
        await message.channel.send("{0}에게 {1}포인트를 선물했어".format(client.get_user(User_ID).name, point_Talk[3]))
        return None

    if point_Talk[1] == "순위":
        point_List = collection.find().sort([("point" , -1)]).limit(10)
        embed = discord.Embed(title="포인트 순위", colour=discord.Colour.red())
        rank = 1
        for i in point_List:
            embed.add_field(name=str(rank) + "등 " + i.get("!name"), value=str(i.get("point")) + " 포인트", inline=False)
            rank += 1
        await message.channel.send(embed=embed)
        return None

    if point_Talk[1] == "상점":
        embed = discord.Embed()
        embed.set_author(name="1.경고 면제권", icon_url=message.guild.icon_url)
        embed.set_thumbnail(url= message.guild.icon_url)
        embed.add_field(name="경고 면제권이다", value="10,000 point", inline=False)
        shopMessage = await message.channel.send(embed=embed)
        await shopMessage.add_reaction("◀")
        await shopMessage.add_reaction("▶")
        return None

async def Buy(message, talk):
    buyTalk = talk.split(" ")
    if len(buyTalk) == 1:
        await Point(message, "포인트 상점")
        return None

    if buyTalk[1].startswith("경고"):
        cautions = []
        with open("Caution.txt", 'r') as f:
            for line in f:
                cautions.append(line)

        for caution in cautions:
            if caution.startswith(str(message.author.id)):
                cautions.remove(caution)
                break
        else:
            await message.channel.send("받은 경고가 없어")
            return None
        datalist = []
        with open("Point.pkl", "rb") as f:
            while True:
                try:
                    data = pickle.load(f)
                except EOFError:
                    break
                datalist.append(data)
            datalist = dict(datalist)
        if datalist.get(message.author.id) == None or datalist.get(message.author.id) < 10000:
            await message.channel.send("포인트가 부족해")
            return None

        with open("Point.pkl", "ab") as f:
            point1 = datalist.get(message.author.id)
            if point1 == None:
                point1 = 0
            pickle.dump([message.author.id, point1 - 10000], f)
        with open("Caution.txt", 'w') as f:
            for line in cautions:
                f.write(line)
        caution = caution.replace("\n", "")
        await message.channel.send("{0}월 {1}일 경고가 면제됐어".format(caution[19], caution[20:len(line) - 1]))
        return None
    return None

async def Sns(message, talk):
    sns_Talk = talk.split(" ")
    if sns_Talk[1] == "개설":
        if (message.channel.permissions_for(message.author).value & 0x00000008) != 0x00000008:
            await message.channel.send("권한이 없어")
            return None
        try:
            category = discord.utils.get(client.get_all_channels(), guild__name=message.guild.name, name="SNS")
            if len(discord.utils.get(client.get_all_channels(), guild__name=message.guild.name, name="SNS").channels) >= 20:
                count = 2
                while True:
                    category = discord.utils.get(client.get_all_channels(), guild__name=message.guild.name, name="SNS" + str(count))
                    if category == None:
                        if count == 2:
                            position = discord.utils.get(client.get_all_channels(), guild__name=message.guild.name, name="SNS").position + 1
                        else:
                            position = discord.utils.get(client.get_all_channels(), guild__name=message.guild.name, name="SNS" + str(count - 1)).position
                        category = await message.guild.create_category(name="SNS"+str(count))
                        await category.edit(position=position)
                        await category.create_text_channel(name="♥sns팔로우")
                    if len(category.channels) >= 20:
                        continue
                    break
            role = await message.guild.create_role(name="{0}팔로워".format(sns_Talk[2]), mentionable=True)
            topic = ""
            try:
                i = 3
                while True:
                    topic += sns_Talk[i] + " "
                    i+= 1
            except IndexError:
                pass
            new_Channel = await discord.Guild.create_text_channel(message.guild, name=sns_Talk[2],category=category, topic="{0}\n팔로워 [{1}]\n게시물 [0]".format(topic, 0))
        except IndexError:
            await message.channel.send("잘못 입력했어\nex)에린아 sns 개설 {채널이름} {소개}")
    return None

@client.event
async def on_voice_state_update(member, before, after):
    try:
        if member.voice.channel.category.name == "여관" or member.voice.channel.category.name == "• 방생성 •":
            await asyncio.sleep(1)
            if after.channel.name == "check in" or after.channel.name == "띠로링 ㅣ🚪":
                if member in after.channel.members:
                    if member.guild.name == "『카르멘』𝓒𝓐𝓡𝓜𝓔𝓝":
                        newChannel = await after.channel.category.create_voice_channel(name=str(random.randint(100,999)) + "호")
                    else:
                        newChannel = await after.channel.category.create_voice_channel(name="또로롱")
                    await newChannel.set_permissions(member, manage_channels=True)
                    await member.move_to(newChannel)
            elif after.channel.name == "private check in":
                if member in discord.utils.get(client.get_all_channels(), guild__name=member.guild.name, name="private check in").members:
                    newChannel = await after.channel.category.create_voice_channel(name="비밀방", reason="하바유보")
                    await newChannel.set_permissions(member.guild.get_role(629963963446198292), view_channel=False)
                    await newChannel.set_permissions(member, manage_channels=True)
                    await member.move_to(newChannel)
    except (AttributeError, TypeError):
        None
    try:
        if before.channel.category.name == "여관" or before.channel.category.name == "• 방생성 •":
            if before.channel.name != "check in" and len(before.channel.members) == 0 and before.channel.name != "private check in" and before.channel.name != "띠로링 ㅣ🚪":
                await before.channel.delete()
    except (AttributeError, discord.errors.NotFound):
        return None

async def GuGuDan(message):
    global isPlaying
    isPlaying = True
    embed = discord.Embed(title="구구단을 외자", colour=discord.Colour.red())
    embed.add_field(name="게임 방법", value="\"에린아 참가\"를 입력해서 구구단을 외자에 참가해\n공격은 숫자 두개를 말하면 되고, ex)3 7\n방어는 두 수를 곱한 수를 말하면 돼 ex)21")
    await message.channel.send(embed=embed)
    Players = []
    def checkPlayer(m):
        return not m.author.mention in Players and m.content == "에린아 참가"
    try:
        while True:
            msg = await client.wait_for('message', timeout=10.0,check=checkPlayer)
            Players.append(msg.author.mention)
            await msg.add_reaction("✅")
            if len(Players) == 2:
                break
    except asyncio.TimeoutError:
        await message.channel.send("시간 초과")
        isPlaying = False
        return None
    playerIndex = random.randint(0, 1)
    currentPlayer = Players[playerIndex]
    def check(m):
        answer = list(map(int, m.content.split(" ")))
        return m.author.mention in Players and m.author.mention == currentPlayer and 1 <= answer[0] and answer[1] <= 9
    def check2(m):
        answer = list(map(int, m.content.split(" ")))
        return m.author.mention in Players and m.author.mention == currentPlayer
    embed = discord.Embed(title="구구단을 외자", colour=discord.Colour.red())
    embed.add_field(name="게임 시작", value="선공은 " + currentPlayer + "!!")
    embedMessage = await message.channel.send(embed=embed)
    timeOut = 5.0
    while True:
        try:
            msg = await client.wait_for('message', timeout=timeOut, check=check)
            answer = list(map(int, msg.content.split(" ")))
            await msg.delete()
            rightAnswer = answer[0] * answer[1]
            playerIndex = int(not playerIndex)
            currentPlayer = Players[playerIndex]
            embed.clear_fields()
            embed.add_field(name="{} * {} = ?".format(answer[0], answer[1]), value=currentPlayer)
            embed.set_footer(text="시간제한 : {}초".format(timeOut))
            await embedMessage.edit(embed=embed)
            msg = await client.wait_for('message', timeout=timeOut, check=check2)
            if int(msg.content) == rightAnswer:
                await msg.add_reaction("✅")
                timeOut -= 0.5
                if timeOut < 1:
                    timeOut = 1
                await asyncio.sleep(1)
                await msg.delete()
                embed.clear_fields()
                embed.add_field(name="공격", value=currentPlayer)
                embed.set_footer(text="시간제한 : {}초".format(timeOut))
                await embedMessage.edit(embed=embed)
                continue
            else:
                embed.clear_fields()
                embed.add_field(name="승리", value=Players[int(not playerIndex)])
                embed.add_field(name="패배", value=currentPlayer)
                embed.set_footer(text="정답 : {}".format(rightAnswer))
                await embedMessage.edit(embed=embed)
                break
        except asyncio.TimeoutError:
            embed.clear_fields()
            embed.add_field(name="승리", value=Players[int(not playerIndex)])
            embed.add_field(name="패배", value=currentPlayer)
            embed.set_footer(text="시간 초과")
            await embedMessage.edit(embed=embed)
            break
        except ValueError:
            embed.clear_fields()
            embed.add_field(name="승리", value=Players[int(not playerIndex)])
            embed.add_field(name="패배", value=currentPlayer)
            embed.set_footer(text="다른 값 입력")
            await embedMessage.edit(embed=embed)
            break
    isPlaying = False
    return None

async def ThreeSixNine(message):
    global isPlaying
    isPlaying = True
    embed = discord.Embed(title="369", colour=discord.Colour.red())
    embed.add_field(name="게임 방법", value="\"에린아 참가\"를 입력해서 369에 참가해\n1부터 순서대로 숫자를 입력하면 돼 ex)1\n숫자에 3, 6, 9가 들어가면 들어간 횟수만큼 짝을 입력해 ex)3 -> 짝, 36 -> 짝짝")
    await message.channel.send(embed=embed)
    Players = []
    def checkPlayer(m):
        return not m.author.mention in Players and m.content == "에린아 참가"
    try:
        while True:
            msg = await client.wait_for('message', timeout=10.0,check=checkPlayer)
            Players.append(msg.author.mention)
            await msg.add_reaction("✅")
    except asyncio.TimeoutError:
        if len(Players) < 2:
            await message.channel.send("인원이 부족해.")
            isPlaying = False
            return None
        pass
    currentPlayer = Players[0]
    def check(m):
        return m.author.mention in Players and m.author.mention == currentPlayer
    embed = discord.Embed(title="369", colour=discord.Colour.red())
    order = ""
    num = 1
    for p in Players:
        order += "{0}. {1}".format(num, p)
        num += 1
    embed.add_field(name="게임 시작", value="순서는\n " + order)
    embedMessage = await message.channel.send(embed=embed)
    timeOut = 5.0
    num = 0
    Answer = 1
    JJack = 0
    JJackTF = False
    await asyncio.sleep(1)
    while True:
        try:
            embed.clear_fields()
            embed.add_field(name="이번 순서", value=currentPlayer)
            embed.set_footer(text="시간제한 : {}초".format(timeOut))
            await embedMessage.edit(embed=embed)
            msg = await client.wait_for('message', timeout=timeOut, check=check)
            for i in [3, 6, 9]:
                if str(i) in str(Answer):
                    JJack += 1
                    JJackTF = True
            if (JJackTF and msg.content == ("짝" * JJack)) or (msg.content == str(Answer)):
                await msg.add_reaction("✅")
                timeOut -= 0.5
                if timeOut < 1:
                    timeOut = 1
                await asyncio.sleep(1)
                await msg.delete()
                num += 1
                if num >= len(Players):
                    num = 0
                currentPlayer = Players[num]
                Answer += 1
                JJack = 0
                JJackTF = False
                continue
            else:
                embed.clear_fields()
                embed.add_field(name="패배", value=currentPlayer)
                embed.set_footer(text="")
                await embedMessage.edit(embed=embed)
                break
        except asyncio.TimeoutError:
            embed.clear_fields()
            embed.add_field(name="패배", value=currentPlayer)
            embed.set_footer(text="시간 초과")
            await embedMessage.edit(embed=embed)
            break
        except ValueError:
            embed.clear_fields()
            embed.add_field(name="패배", value=currentPlayer)
            embed.set_footer(text="다른 값 입력")
            await embedMessage.edit(embed=embed)
            break
    isPlaying = False
    return None

async def TheGameOfDeth(message):
    global isPlaying
    isPlaying = True
    embed = discord.Embed(title="더 게임 오브 데스", colour=discord.Colour.red())
    embed.add_field(name="게임 방법", value="\"에린아 참가\"를 입력해서 더 게임 오브 데스에 참가해\n술래는 숫자를 입력해 ex)3" +
                    "\n술래가 입력을 마치면 모든 사람들은 다른 사람을 멘션해 ex)@에린\n술래부터 시작해서 멘션당한 사람에게 넘어가면서 카운트하고 술래가 입력한 숫자에서 멈춘 사람이 패배야")
    embed.add_field(name="주의사항", value="술래는 5초안에 숫자를 입력해야해\n멘션후 메세지에 ✅이모지가 있어야해")
    await message.channel.send(embed=embed)
    Players = []
    def checkPlayer(m):
        return not m.author.mention in Players and m.content == "에린아 참가"
    try:
        while True:
            msg = await client.wait_for('message', timeout=10.0,check=checkPlayer)
            Players.append(msg.author.mention)
            await msg.add_reaction("✅")
    except asyncio.TimeoutError:
        if len(Players) < 2:
            await message.channel.send("인원이 부족해.")
            isPlaying = False
            return None
        pass
    def check(m):
        return m.author.mention in Players
    def check2(m):
        return m.author.mention in Players and m.mentions[0].mention in Players and m.content != m.author.mention
    embed = discord.Embed(title="더 게임 오브 데쓰", colour=discord.Colour.red())
    embed.add_field(name="게임 시작", value="신이난다~")
    embedMessage = await message.channel.send(embed=embed)
    await asyncio.sleep(1)
    embed.clear_fields()
    embed.add_field(name="게임 시작", value="재미난다~")
    await embedMessage.edit(embed=embed)
    await asyncio.sleep(1)
    embed.clear_fields()
    embed.add_field(name="게임 시작", value="더 게임 오브 데쓰~")
    await embedMessage.edit(embed=embed)
    tagger = Players[random.randrange(0, len(Players))]
    await asyncio.sleep(1)
    try:
        embed.clear_fields()
        embed.add_field(name="술래", value=tagger)
        await embedMessage.edit(embed=embed)
        msg = await client.wait_for('message', timeout=10, check=check)
        count = int(msg.content)
        await msg.delete()
        embed.clear_fields()
        embed.add_field(name="횟수 : {}".format(count), value="다른 사람을 멘션해줘")
        await embedMessage.edit(embed=embed)
        playerChoice = {}
        for i in range(0, len(Players)):
            msg = await client.wait_for('message', timeout=10, check=check2)
            playerChoice[msg.author.mention] = msg.mentions[0].mention
            await msg.add_reaction("✅")

        for j in range(0, count):
            embed.clear_fields()
            embed.add_field(name="카운트 시작", value="{} -> {}".format(tagger, playerChoice[tagger]))
            embed.set_footer(text="횟수 : {}/{}".format(j+1, count))
            await embedMessage.edit(embed=embed)
            tagger = playerChoice[tagger]
            await asyncio.sleep(1)
        embed.add_field(name="패배", value=tagger)
        await embedMessage.edit(embed=embed)
    except asyncio.TimeoutError:
        embed.clear_fields()
        embed.add_field(name="오류", value="ㅡnㅡ")
        embed.set_footer(text="시간 초과")
        await embedMessage.edit(embed=embed)
    except ValueError:
        embed.clear_fields()
        embed.add_field(name="오류", value="ㅡnㅡ")
        embed.set_footer(text="시간 초과")
        await embedMessage.edit(embed=embed)
    isPlaying = False
    return None

async def PVP(message, talk):
    global isPlaying
    isPlaying = True
    PVP_Talk = talk.split(" ")
    collection = db.Stat
    player1_id = message.author.id
    player2_id = int(re.findall("\d+", PVP_Talk[1])[0])
    player1 = message.guild.get_member(player1_id)
    player2 = message.guild.get_member(player2_id)
    if not list(collection.find({"_id": player1_id})) or not list(collection.find({"_id": player2_id})):
        await message.channel.send("스탯이 없어")
        return None
    def switch(value):
        # 공 - 마 - 체 - 방
        return {
            0: ["공격력", "STR"],
            1: ["마력", "INT"],
            2: ["체력", "HP"],
            3: ["방어력", "DEF"]
        }.get(value)
    embed = discord.Embed(title="{0}님과 {1}님의 대결".format(player1.display_name, player2.display_name), colour=discord.Colour.red())
    embedMessage = await message.channel.send(embed=embed)
    player1_Stat = collection.find({"_id": player1_id})[0]
    player2_Stat = collection.find({"_id": player2_id})[0]
    winCount = 0 #양수면 player1승리, 음수면 player2승리, 0이면 무승부
    for i in range(0, 4):
        title, stat = switch(i)
        embed.add_field(name=title, value="승자 : ", inline=False)
        embed.add_field(name=player1.display_name, value="{0} : {1}".format(title, player1_Stat.get(stat)), inline=True)
        embed.add_field(name=player2.display_name, value="{0} : {1}".format(title, player2_Stat.get(stat)), inline=True)
        await embedMessage.edit(embed=embed)
        if player1_Stat.get(stat) > player2_Stat.get(stat):
            winCount += 1
            winPlayer = player1
        else:
            winCount -= 1
            winPlayer = player2
        await asyncio.sleep(1)
        embed.set_field_at(i, name=title, value="승자 : {0}".format(winPlayer.display_name), inline=False)
        embed.remove_field(i + 1)
        embed.remove_field(i + 1)
        await embedMessage.edit(embed=embed)
        await asyncio.sleep(1)
    if winCount == 0:
        await message.channel.send("무승부")
    elif winCount > 0:
        await message.channel.send("{} 승리".format(player1.mention))
    else:
        await message.channel.send("{} 승리".format(player2.mention))

    isPlaying = False

async def Stat(message, talk):
    #순서는 공격력 - 마력 - 체력 - 방어력
    stat_Talk = talk.split(" ")
    collection = db.Stat
    if len(stat_Talk) < 2:
        embed = discord.Embed(title="{0}님의 스탯".format(message.author.display_name), colour=discord.Colour.red())
        player = collection.find({"_id": message.author.id})[0]
        embed.add_field(name="힘", value=player.get("str"), inline=False)
        embed.add_field(name="체력", value=player.get("hp"), inline=False)
        embed.add_field(name="지능", value=player.get("int"), inline=False)
        embed.add_field(name="마력", value=player.get("mp"), inline=False)
        embed.add_field(name="신성", value=player.get("fth"), inline=False)
        embed.add_field(name="리듬감", value=player.get("ryt"), inline=False)
        embed.add_field(name="손재주", value=player.get("dex"), inline=False)
        embed.set_footer(text="스탯포인트 : {}".format(player.get("!statPoint")))
        await message.channel.send(content=message.author.mention, embed=embed)
        return None

    if stat_Talk[1] == "생성":
        if not list(collection.find({"_id" : message.author.id})):
            utcnow = datetime.datetime.utcnow()
            time_gap = datetime.timedelta(hours=9)
            now = utcnow + time_gap
            collection.update_one({"_id": message.author.id}, {
                "$setOnInsert": {"!name": message.author.display_name, "!creation_Date": now, "!statPoint" : 0, "STR": 0, "INT": 0,
                                 "HP": 0, "DEF": 0, "str": 0, "int": 0, "hp": 0, "mp": 0, "fth" : 0, "ryt" : 0, "dex" : 0}}, upsert=True)#fth : 신성력, ryt : 리듬감, dex : 손재주
            await message.add_reaction("✅")
            return None
        else:
            await message.channel.send("이미 생성되었어")
            return None

    if not list(collection.find({"_id": message.author.id})):
        await message.channel.send("스탯이 없어\n'에린아 스탯 생성' 으로 스탯을 만들어")
        return None

    collection.update_one({"_id": message.author.id}, {"$set": {"!name": message.author.display_name}}, upsert=True)
    if stat_Talk[1] == "힘" or stat_Talk[1] == "체력" or stat_Talk[1] == "지능" or stat_Talk[1] == "마력" or stat_Talk[1] == "신성력" or stat_Talk[1] == "리듬감" or stat_Talk[1] == "손재주":
        if len(stat_Talk) == 2:
            sp = 1
        else:
            sp = int(stat_Talk[2])
        def switch(value):
            #공 - 마 - 체 - 방
            return {
                "힘": ["str", [10, 0, 5, 5]],
                "체력": ["hp", [0, 0, 10, 10]],
                "지능": ["int", [10, 5, 0, 5]],
                "마력": ["mp", [5, 10, 0, 5]],
                "신성력": ["fth", [10, 5, 5, 0]],
                "리듬감": ["ryt", [10, 10, 0, 0]],
                "손재주": ["dex", [10, 0, 10, 0]]
            }.get(value)
        stat, statList = switch(stat_Talk[1])
        player = collection.find({"_id": message.author.id})[0]
        if player.get("!statPoint") < sp:
            await message.channel.send("스탯포인트가 부족해\n스탯포인트 : " + str(player.get("!statPoint")))
            return None
        collection.update_one({"_id": message.author.id}, {"$inc": {stat: sp}}, upsert=True)
        collection.update_one({"_id": message.author.id}, {"$inc": {"STR": statList[0] * sp}}, upsert=True)
        collection.update_one({"_id": message.author.id}, {"$inc": {"INT": statList[1] * sp}}, upsert=True)
        collection.update_one({"_id": message.author.id}, {"$inc": {"HP": statList[2] * sp}}, upsert=True)
        collection.update_one({"_id": message.author.id}, {"$inc": {"DEF": statList[3] * sp}}, upsert=True)
        collection.update_one({"_id": message.author.id}, {"$inc": {"!statPoint": -sp}}, upsert=True)
        await message.add_reaction("✅")
        return None

    if stat_Talk[1].startswith("<@"):
        user_ID = int(re.findall("\d+", stat_Talk[1])[0])
        if not list(collection.find({"_id": user_ID})):
            await message.channel.send("스탯이 없어")
            return None
        embed = discord.Embed(title="{0}님의 스탯".format(message.guild.get_member(user_ID).display_name), colour=discord.Colour.red())
        player = collection.find({"_id" : user_ID})[0]
        embed.add_field(name="힘", value=player.get("str"), inline=False)
        embed.add_field(name="체력", value=player.get("hp"), inline=False)
        embed.add_field(name="지능", value=player.get("int"), inline=False)
        embed.add_field(name="마력", value=player.get("mp"), inline=False)
        embed.add_field(name="신성", value=player.get("fth"), inline=False)
        embed.add_field(name="리듬감", value=player.get("ryt"), inline=False)
        embed.add_field(name="손재주", value=player.get("dex"), inline=False)
        embed.set_footer(text="스탯포인트 : {}".format(player.get("!statPoint")))
        await message.channel.send(content=message.guild.get_member(user_ID).mention,embed=embed)
        return None

@client.event
async def on_reaction_add(reaction, user):
    if user.bot:
        return None
    try:
        count = int(reaction.message.embeds[0].author.name[0])
        if reaction.emoji == "◀":
            count -= 1
        elif reaction.emoji == "▶":
            count += 1

        if count < 1 or count > 3:
            return None

        if count == 1:
            embed = discord.Embed()
            embed.set_author(name="1.경고 면제권", icon_url=reaction.message.guild.icon_url)
            embed.set_thumbnail(url=reaction.message.guild.icon_url)
            embed.add_field(name="경고 면제권이다", value="10,000 point", inline=False)
            await reaction.message.clear_reactions()
            await reaction.message.edit(embed=embed)
            await reaction.message.edit(embed=embed)
            await reaction.message.add_reaction("◀")
            await reaction.message.add_reaction("▶")

        if count == 2:
            embed = discord.Embed()
            embed.set_author(name="2.로또 10개", icon_url=reaction.message.guild.icon_url)
            embed.set_thumbnail(url=reaction.message.guild.icon_url)
            embed.add_field(name="로또 10개다", value="1,000,000,000,000 point", inline=False)
            await reaction.message.clear_reactions()
            await reaction.message.edit(embed=embed)
            await reaction.message.add_reaction("◀")
            await reaction.message.add_reaction("▶")

        if count == 3:
            embed = discord.Embed()
            embed.set_author(name="3.하유님 바부", icon_url=reaction.message.guild.icon_url)
            embed.set_thumbnail(url=reaction.message.guild.icon_url)
            embed.add_field(name="멍청이 'u'", value="메롱메롱", inline=False)
            await reaction.message.edit(embed=embed)
            await reaction.message.clear_reactions()
            await reaction.message.add_reaction("◀")
            await reaction.message.add_reaction("▶")
    except (TypeError, IndexError):
        return None
    return None

async def Reaction(payload, user, msg, tf):
    if msg.content.startswith("__SNS 팔로우__"):
        follow = msg.content.split("\n")
        for i in follow:
            i = i.split(":")
            if str(payload.emoji) == i[0]:
                role = user.guild.get_role(int(re.findall("\d+", i[1])[0]))
                snsChannel = discord.utils.get(client.get_all_channels(), guild__name=user.guild.name, name=role.name.split("팔로워")[0])
                tmp_topic = re.findall("팔로워 \[\d+\]", snsChannel.topic)[0]
                if tf:
                    count = 0
                    for c in msg.reactions:
                        if payload.emoji.name == c.emoji:
                            count = c.count
                    if role in user.roles:
                        return None
                    await user.add_roles(role)
                else:
                    count = 0
                    for c in msg.reactions:
                        if payload.emoji.name == c.emoji:
                            count = c.count
                    if not role in user.roles:
                        return None
                    await user.remove_roles(role)
                _topic = snsChannel.topic.replace(tmp_topic, "팔로워 [%s]" % str(count))
                try:
                    await snsChannel.edit(topic=_topic)
                except TypeError:
                    pass
        return None

@client.event
async def on_raw_reaction_add(payload):
    if payload.member.bot:
        return None
    channel = discord.utils.get(client.get_all_channels(), id=payload.channel_id)
    if not channel.category.name.startswith("SNS"):
        return None
    msg = await channel.fetch_message(payload.message_id)
    await Reaction(payload, payload.member, msg, True)
    return None

@client.event
async def on_raw_reaction_remove(payload):
    channel = discord.utils.get(client.get_all_channels(), id=payload.channel_id)
    user = discord.utils.get(client.get_all_members(), id=payload.user_id)
    msg = await channel.fetch_message(payload.message_id)
    await Reaction(payload, user, msg, False)
    return None

@tasks.loop(seconds=60*60)
async def Daily():
    #로또 초기화
    utcnow = datetime.datetime.utcnow()
    time_gap = datetime.timedelta(hours=9)
    now = utcnow + time_gap
    if now.hour == 0:
        collection = db.Point
        users = collection.find()
        for i in users:
            if not i.get("daily"):
                collection.update_one(i, {"$set": {"dailyCount": 0}})
            collection.update_one(i , {"$set" : {"count" : 0, "daily" : False}})
        await discord.utils.get(client.get_all_channels(), guild__name="『카르멘』𝓒𝓐𝓡𝓜𝓔𝓝", name="봇-test").send("에린 초기화")
        #await discord.utils.get(client.get_all_members(), guild__name="『카르멘』𝓒𝓐𝓡𝓜𝓔𝓝", id=740063353010913310).send("보고싶어")

async def Help(message):
    embed = discord.Embed(title= "에린이 도움말",colour=discord.Colour.red())
    embed.add_field(name="로또", value="에린아 로또 랜덤 <숫자> : 로또를 <숫자>번 랜덤으로 뽑습니다.\n"
                                     "에린아 로또 선택 <숫자> : <숫자> 번호 로또를 구매합니다\n"
                                     "에린아 로또 확인 : 본인의 로또 번호를 확인합니다", inline=False)
    embed.add_field(name="포인트", value="에린아 포인트 : 자신의 포인트를 확인합니다.\n"
                                     "에린아 출석 : 한번 출석에 10~300의 포인트를 받습니다. 누적되면 추가로 포인트를 얻습니다.\n"
                                     "에린아 포인트 순위 : 서버 내 포인트 순위를 확인합니다.\n"
                                     "에린아 포인트 선물 <멘션> <포인트> :<멘션>에게 <포인트>만큼 포인트를 선물합니다", inline=False)
    embed.add_field(name="기타 기능", value="에린아 삭제 <갯수>, 에린아 초대, 에린아 닉네임 <변경할닉네임>, 에린아 구구단, 에린아 가위바위보, 에린아 검색 <내용>, 에린아 고양이, 에린아 시간, 에린아 369", inline=False)
    await message.channel.send(embed=embed)
    return

access_token = os.environ["BOT_TOKEN"]
client.run(access_token)


from flask import request, jsonify
from flask_login import current_user
from flask_migrate import current
from flask_restful import Resource
from models.user import User
from repositories.audit import AuditRepository
from repositories.function import FunctionRepository
from repositories.submission import SubmissionRepository
from repositories.user import UserRepository
from schemas.submission import SubmissionSchema
from tools.find_nonmatching import calculate_score
from utils import error_message_response, error_response
import json
import logging

submissions_schema = SubmissionSchema(many=True)
submission_schema = SubmissionSchema()

class SubmissionResource(Resource):
    def get(self, submission: int):
        return submission_schema.dump(SubmissionRepository.get(submission))

    def delete(self, submission: int):
        subm = SubmissionRepository.get(submission)
        if not subm or subm.is_deleted:
            return error_message_response('Submission not found.')
        if current_user is None or not current_user.is_authenticated:
            return error_message_response('Not logged in.')
        if subm.owner != current_user.id:
            return error_message_response('This submission does not belong to you.')
        AuditRepository.create(current_user.id, f'Deleted submission {submission}')
        SubmissionRepository.delete(subm)
        return 'ok'

class FunctionSubmissions(Resource):
    def get(self, function: int):
        return submissions_schema.dump(SubmissionRepository.get_for_function(function)), 200

    def post(self, function: int):
        data = request.get_json()
        if data is None:
            return error_message_response('Invalid request')

        try:
            owner = None
            if current_user is not None and current_user.is_authenticated:
                # If this are the details of the current user, use them
                if current_user.username == data['username'] and current_user.email == data['email']:
                    owner = current_user.id

            if owner is None and data['username'] is not None and data['username'] != '':
                user = UserRepository.get_by_name_and_email(
                    username=data['username'], email=data['email'])
                if user is None:
                    # Need to create this user
                    user = UserRepository.create_anonymous(
                        username=data['username'], email=data['email'])

                owner = user.id

            # Change the best_score of the function if this one is better
            func = FunctionRepository.get_internal(int(function))

            compiled = json.loads(data['compiled'])
            compiled_asm = ''
            separator = ''
            for line in compiled['asm']:
                compiled_asm += separator + line['text']
                separator = '\n'

            # Calculate the score on the server
            score = calculate_score(func.asm, compiled_asm)

            if score < func.best_score:
                func.best_score = score
            if score == 0:
                func.is_matched = True
            if not func.has_code_try:
                func.has_code_try = True

            submission = SubmissionRepository.create(
                function, owner, data['code'], score, data['is_equivalent'], data['parent'], data['compiled'], data['comments'])
            FunctionRepository.set_has_equivalent_try(function, SubmissionRepository.has_equivalent_submission(function))
            return submission, 200
        except Exception as e:
            return error_response(e)

class LatestSubmissionsResource(Resource):
    def get(self):
        return submissions_schema.dump(SubmissionRepository.get_latest())

class EquivalentResource(Resource):
    def post(self, submission: int):
        data = request.get_json()
        if data is None:
            return error_message_response('Invalid request')
        try:
            if current_user is None or not current_user.is_authenticated:
                return error_message_response('Not logged in.')
            subm = SubmissionRepository.get(submission)
            if not subm:
                return error_message_response('Submission does not exist.')
            is_equivalent = data['is_equivalent'] == 'true'
            AuditRepository.create(current_user.id, f'Set submission {submission} to equivalent: {is_equivalent}')
            SubmissionRepository.set_equivalent(subm, is_equivalent)
            FunctionRepository.set_has_equivalent_try(subm.function, SubmissionRepository.has_equivalent_submission(subm.function))
            return 'ok'
        except Exception as e:
            return error_response(e)


import os
import glob
import shutil
import random
import argparse
import time

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
from tensorflow.keras.models import load_model

import models
import data
from constants import *

base_dir = 'generative_model_default'
# base_dir = 'generative_model_3_cpu'
# base_dir = 'generative_model_seed_grids'
base_dir = 'generative_model_new'
step_index = -1
index = 0
run = True
def press(event):
    global index
    global step_index
    global run
    if event.key == 'd':
        index += 1
    elif event.key == 'a':
        index -= 1
    elif event.key == 'w':
        step_index += 1
    elif event.key == 's':
        step_index -= 1
    if event.key == 'q':
        run = False

def show_grids(v):
    global index
    global step_index
    global run

    all_files = list()
    step_dirs = glob.glob(os.path.join(base_dir, 'step*'))

    def extract_step_num(d):
        d = d.split('/')[-1]
        d = d[4:]
        if d.startswith('_'):
            d = d[1:]
        try:
            return int(d)
        except:
            return 0

    step_dirs.sort(key=extract_step_num)
    for i, step_dir in enumerate(step_dirs):
        if step_dir.endswith('step_{}'.format(v)) or step_dir.endswith('step{}'.format(v)):
            step_index = i
        grid_files = glob.glob(os.path.join(step_dir, 'grids/grid_*.csv'.format(v)))
        density_files = glob.glob(os.path.join(step_dir, 'results/density_*.csv'.format(v)))
        target_density_files = glob.glob(os.path.join(step_dir, 'target_densities/artificial_curve_*.csv'))
        if len(target_density_files) == 0:
            target_density_files = glob.glob(os.path.join(step_dir, 'artificial_metrics/artificial_metric_*.csv'))
        grid_files.sort()
        density_files.sort()
        target_density_files.sort()
        if len(target_density_files) == 0:
            all_step_files = list(zip(grid_files, density_files))
        else:
            all_step_files = list(zip(grid_files, density_files, target_density_files))
        if len(all_step_files) != 0:
            all_files.append(all_step_files)

    predictor_model = None
    print('Attempting to load predictor model...')
    try:
        predictor_model = load_model(os.path.join(base_dir, 'model_saves/predictor_step_{}.hdf5'.format(v)),
                                     custom_objects={'binary_sigmoid': models.binary_sigmoid})
        print('Loaded successfully')
    except:
        print("Couldn't load predictor_model")

    fig = plt.figure(figsize=(10, 4))
    fig.canvas.mpl_connect('key_press_event', press)
    fig.tight_layout(rect=[0, 0.03, 1, 0.95])
    while run:
        s = step_index % len(all_files)
        i = index % len(all_files[s])
        files = all_files[s][i]
        target_density_file = None
        if len(files) == 2:
            grid_file, density_file = files
        else:
            grid_file, density_file, target_density_file = files

        df = pd.read_csv(density_file, index_col=0)
        relative_humidity = np.arange(41) * STEP_SIZE

        grid = np.genfromtxt(grid_file, delimiter=',')
        density = np.append(df['0'][:N_ADSORP], 1)
        target_density = None
        if target_density_file:
            target_density = np.insert(np.genfromtxt(target_density_file), 0, 0)
            target_density = np.cumsum(target_density)
        predicted_density = None
        if predictor_model:
            predicted_density = np.insert(predictor_model.predict(np.array([grid]))[0], 0, 0)
            predicted_density = np.cumsum(predicted_density)

        fig.suptitle('Step {}, Grid {}'.format(s, i))

        ax = plt.subplot(1, 2, 1)
        ax.clear()
        ax.set_title('Grid (Black = Solid, White = Pore)')
        ax.set_yticks(np.linspace(0, 20, 5))
        ax.set_xticks(np.linspace(0, 20, 5))
        ax.pcolor(1 - grid, cmap='Greys', vmin=0.0, vmax=1.0)
        ax.set_aspect('equal')

        ax = plt.subplot(1, 2, 2)
        ax.clear()
        ax.set_title('Adsorption Curve')
        ax.plot(relative_humidity, density, label='DFT')
        if predicted_density is not None:
            ax.plot(relative_humidity, predicted_density, label='Predictor')
        if target_density is not None:
            ax.plot(relative_humidity, target_density, label='Target')
        ax.set_xlim(0, 1)
        ax.set_ylim(0, 1)
        ax.set_xlabel('Relative Humidity')
        ax.set_ylabel('Proportion of Pores filled')
        ax.set_aspect('equal')
        ax.legend()

        plt.show()
        plt.waitforbuttonpress(timeout=-1)

def show_validation():
    model_step = input('Model step: ')
    model_dir = os.path.join(base_dir, 'model_saves')
    predictor_file = os.path.join(model_dir, 'predictor_step_{}.hdf5'.format(model_step))
    generator_file = os.path.join(model_dir, 'generator_step_{}.hdf5'.format(model_step))

    try:
        print('Loading predictor model')
        predictor = load_model(predictor_file, custom_objects={'worst_abs_loss': models.worst_abs_loss})
        predictor.summary()
    except Exception as e:
        print('Unable to load predictor model: {}'.format(e))
        return

    try:
        print('Loading generator model')
        generator = load_model(generator_file, custom_objects={'binary_sigmoid': models.binary_sigmoid})
        generator.summary()
    except Exception as e:
        print('Unable to load generator model: {}'.format(e))
        return

    validation_dir = os.path.join(base_dir, 'validation')
    try:
        os.makedirs(validation_dir, exist_ok=False)
    except FileExistsError:
        shutil.rmtree(validation_dir)
        os.makedirs(validation_dir, exist_ok=False)

    grids_dir = os.path.join(validation_dir, 'grids')
    densities_dir = os.path.join(validation_dir, 'results')
    target_densities_dir = os.path.join(validation_dir, 'target_densities')

    os.makedirs(grids_dir, exist_ok=True)
    # First create grids that have increasing pore size
    # 0x0, 1x1, 2x2, 3x3, ..., 20x20
    print('Creating baseline grids (0x0, 1x1, ..., 20x20)')
    for i in range(GRID_SIZE+1):
        grid = np.zeros((GRID_SIZE, GRID_SIZE), dtype=int)
        grid[:i, :i] = 1
        path = os.path.join(grids_dir, 'grid_%04d.csv'%i)
        np.savetxt(path, grid, fmt='%i', delimiter=',')
    # Then evaluate those grids
    os.system('./fast_dft {}'.format(validation_dir))

    grids = list()
    target_densities = list()
    metadata = list()
    # Then create grids using generator
    # ---------------------------------
    # First use the curves from the 0x0, 1x1, 2x2, ..., 20x20 grids
    # For each nxn grid curve, we use latent codes that vary in one dimension
    # from 0 to 1 for each dimension 0 to `boost_dim`
    print('Creating from generator')
    density_diffs = list()
    densities_dir = os.path.join(validation_dir, 'results')
    density_files = glob.glob(os.path.join(densities_dir, 'density_*.csv'))
    density_files.sort()
    latent_codes = list()
    boost_dim = 5
    for i, density_file in enumerate(density_files):
        density = np.genfromtxt(density_file, delimiter=',', skip_header=1, max_rows=N_ADSORP)[:, 1]
        density[0] = 0
        density = np.append(density, 1.0)
        diffs = np.diff(density)
        for boost_dim_ind in range(boost_dim):
            for step in np.linspace(0.0, 1.0, num=5):
                latent_code = [0.5] * boost_dim
                latent_code[boost_dim_ind] = step
                density_diffs.append(diffs)
                latent_codes.append(latent_code)
                metadata.append({'size': i, 'lc': latent_code,
                                 'boost_dim_ind': boost_dim_ind, 'step': float(step)})
                target_densities.append(density)
    density_diffs = np.array(density_diffs)
    latent_codes = np.array(latent_codes)
    print('Generating {} grids...'.format(len(density_diffs)), end='', flush=True)
    start = time.time()
    new_grids = generator.predict([density_diffs, latent_codes])
    durr = time.time() - start
    print(' Done.\tTook {:.3f} seconds ({:.2f}ms per grid)'.format(durr, durr/len(new_grids)*1000))
    grids.extend(new_grids)

    # Now just create some random grids
    num_new_grids = 500
    artificial_curves, latent_codes = data.make_generator_input(num_new_grids, boost_dim, allow_squeeze=True, as_generator=False)
    artificial_curves = list(zip(artificial_curves, latent_codes))
    artificial_curves.sort(key=lambda x: np.sum(np.cumsum(x[0])), reverse=True)
    artificial_curves, latent_codes = list(zip(*artificial_curves))
    artificial_curves = np.array(artificial_curves)
    latent_codes = np.array(latent_codes)
    print('Generating {} grids...'.format(len(artificial_curves)), end='', flush=True)
    start = time.time()
    new_grids = generator.predict([artificial_curves, latent_codes])
    durr = time.time() - start
    print(' Done. Took {:.3f} seconds ({:.2f}ms per grid)'.format(durr, durr/len(new_grids)*1000))
    grids.extend(new_grids)
    metadata += [{'num': i, 'area': np.sum(np.cumsum(ac)), 'lc': lc}
                    for i, (ac, lc) in enumerate(zip(artificial_curves, latent_codes))]

    # Save the new grids
    shutil.rmtree(grids_dir)
    shutil.rmtree(densities_dir)
    os.makedirs(grids_dir, exist_ok=True)
    for i, grid in enumerate(grids):
        path = os.path.join(grids_dir, 'grid_%04d.csv'%i)
        np.savetxt(path, grid, fmt='%i', delimiter=',')
    # Evaluate densities
    print('Evaluating generated grids')
    start = time.time()
    os.system('./fast_dft {}'.format(validation_dir))
    durr = time.time() - start
    print('Done. Took {:.3f} seconds ({:.2f}ms per grid)'.format(durr, durr/len(grids)*1000))

    density_files = glob.glob(os.path.join(densities_dir, 'density_*.csv'))
    density_files.sort()
    densities = list()
    for density_file in density_files:
        density = np.genfromtxt(density_file, delimiter=',', skip_header=1, max_rows=N_ADSORP)[:, 1]
        density = np.append(density, 1)
        density[0] = 0
        densities.append(density)

    for artificial_curve in artificial_curves:
        density = np.insert(np.cumsum(artificial_curve), 0, 0)
        target_densities.append(density)

    print('Predicting curves')
    predicted_diffs = predictor.predict(np.array(grids))
    predicted_densities = list()
    for predicted_diff in predicted_diffs:
        predicted_density = np.insert(np.cumsum(predicted_diff), 0, 0)
        predicted_densities.append(predicted_density)

    all_info = list(zip(metadata, grids, densities, target_densities, predicted_densities))

    global index

    fig = plt.figure(figsize=(10, 4))
    fig.canvas.mpl_connect('key_press_event', press)
    fig.tight_layout(rect=[0, 0.03, 1, 0.95])

    def setup_plt(md, grid, density, t_density, p_density):
        if 'size' in md and 'lc' in md:
            s = md['size']
            l = md['lc']
            fig.suptitle('Grid {}x{}, lc {}'.format(s, s, l))
        elif 'num' in md and 'area' in md and 'lc' in md:
            i = md['num']
            a = md['area']
            l = md['lc']
            fig.suptitle('Grid {}/{}, lc {}, area {:.3f}'.format(i, num_new_grids,
                                                                 np.array2string(l, precision=2),
                                                                 a))

        ax = plt.subplot(1, 2, 1)
        ax.clear()
        ax.set_title('Grid (Black = Solid, White = Pore)')
        ax.set_yticks(np.linspace(0, 20, 5))
        ax.set_xticks(np.linspace(0, 20, 5))
        ax.pcolor(1 - grid, cmap='Greys', vmin=0.0, vmax=1.0)
        ax.set_aspect('equal')

        ax = plt.subplot(1, 2, 2)
        ax.clear()
        ax.set_title('Adsorption Curve')
        relative_humidity = np.arange(41) * STEP_SIZE
        ax.plot(relative_humidity, density, label='DFT')
        ax.plot(relative_humidity, p_density, label='Predictor')
        ax.plot(relative_humidity, t_density, label='Target')
        ax.set_xlim(0, 1)
        ax.set_ylim(0, 1)
        ax.set_xlabel('Relative Humidity')
        ax.set_ylabel('Proportion of Pores filled')
        ax.set_aspect('equal')
        ax.legend()

    while run:
        i = index % len(all_info)

        setup_plt(*all_info[i])

        plt.show()
        plt.waitforbuttonpress(timeout=-1)

    # Get errors
    print('Calculating errors')
    generator_errs = list()
    predictor_errs = list()
    cross_errs = list()
    for md, grid, density, t_density, p_density in all_info:
        generator_err = np.sum(np.abs(density - t_density)) / (N_ADSORP + 1)
        predictor_err = np.sum(np.abs(density - p_density)) / (N_ADSORP + 1)
        cross_err = np.sum(np.abs(t_density - p_density)) / (N_ADSORP + 1)
        generator_errs.append(generator_err)
        predictor_errs.append(predictor_err)
        cross_errs.append(cross_err)

    baseline_generator_errs = dict()
    baseline_predictor_errs = dict()
    baseline_cross_errs = dict()

    areas = list()
    random_generator_errs = list()
    random_predictor_errs = list()
    random_cross_errs = list()

    for md, g_err, p_err, c_err in zip(metadata, generator_errs, predictor_errs, cross_errs):
        if 'boost_dim_ind' in md and 'step' in md:
            b = md['boost_dim_ind']
            s = md['step']
            k = (b, s)
            if k in baseline_generator_errs:
                baseline_generator_errs[k].append(g_err)
            else:
                baseline_generator_errs[k] = [g_err]
            if k in baseline_predictor_errs:
                baseline_predictor_errs[k].append(p_err)
            else:
                baseline_predictor_errs[k] = [p_err]
            if k in baseline_cross_errs:
                baseline_cross_errs[k].append(c_err)
            else:
                baseline_cross_errs[k] = [c_err]
        elif 'num' in md and 'area' in md and 'lc' in md:
            i = md['num']
            a = md['area']
            l = md['lc']
            areas.append(a)
            random_generator_errs.append(g_err)
            random_predictor_errs.append(p_err)
            random_cross_errs.append(c_err)

    def plot_baseline(baseline_err, title):
        k = list(baseline_err.keys())
        sizes = len(baseline_err[k[0]])
        labels = ['Grid {}x{}'.format(s, s) for s in range(sizes)]
        x = np.arange(sizes)
        offsets = np.linspace(-0.4, 0.4, num=len(k))
        w = offsets[1] - offsets[0]
        for i, (s, l) in enumerate(zip(k, labels)):
            offset = offsets[i]
            errs = baseline_err[s]
            plt.bar(x + offset, errs, w, label=k)
        plt.ylim(0, 1)
        plt.xticks(x, labels, rotation=90)
        plt.title(title)
        plt.show()
        plt.waitforbuttonpress(timeout=-1)

    plot_baseline(baseline_generator_errs, 'Generator Errors')
    plot_baseline(baseline_predictor_errs, 'Predictor Errors')
    plot_baseline(baseline_cross_errs, 'Cross Errors')

    plt.plot(areas, random_generator_errs, label='Generator Errors')
    plt.plot(areas, random_predictor_errs, label='Predictor Errors')
    plt.plot(areas, random_cross_errs, label='Cross Errors')
    plt.legend()
    plt.title('Errors')
    plt.xlabel('Area under adsorption curve')
    plt.ylabel('Error (unsigned area between curves)')
    plt.ylim(0, 1)
    plt.show()
    plt.waitforbuttonpress(timeout=-1)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("v", nargs="?", help="Show the grids/results of step v",
                        type=int, default=-1)
    args = parser.parse_args()
    v = args.v
    if v >= 0:
        show_grids(v)
    else:
        show_validation()


from datetime import datetime
from elasticsearch import Elasticsearch
import json
from pprint import pprint

es = Elasticsearch()

def get_graphs(search_terms):
    graphs = {"graph_data":[]}
    graphs["graph_data"].append(get_types())
    return graphs

def get_types():
    query = {
              "size": 0,
              "aggregations": {
                "movie_type": {
                  "terms": {
                    "field": "kind.keyword"
                  }
                }
              }
            }
    res = es.search(index="movies", body=query)
    result = {"graph":"pie", "name": "Film Type", "data":[]}
    data = [
        {
            "name": "Germany",
            "value": 8940000
        },
        {
            "name": "USA",
            "value": 5000000
        },
        {
            "name": "France",
            "value": 7200000
        },
        {
            "name": "UK",
            "value": 6200000
        }
    ]
    for item in res["aggregations"]["movie_type"]["buckets"]:
        result["data"].append({"name":item["key"], "value":item["doc_count"]})

    return result


import requests
import json
from labels import labels
import cv2

def get_label(img):
	lbls = [l.lower() for l in labels]

	lbls = set(lbls)

	url = "https://eastus.api.cognitive.microsoft.com/vision/v3.0/tag?language=en"

	payload = {}
	files = [
	  ('', cv2.imencode('.jpg', img)[1])
	]
	headers = {
	  'Ocp-Apim-Subscription-Key': '[API KEY]'
	}

	response = requests.request("POST", url, headers=headers, data = payload, files = files)

	res = json.loads(response.text)

	print(res)

	for t in res['tags']:
		if t['name'] in lbls:
			return t['name']

if __name__ == '__main__':
	get_label(cv2.imread('test.png'))


# import library
import requests
from bs4 import BeautifulSoup
import re
import time
import os
import psutil

# get url from user and separate website by languages (English, Chinese, Japanese)
def get_info():
    '''
    Get user's information of website and language.
    Args: NA
    Returns:
        (str) url - user's input of url
        (str) lang - user's input of language
    '''

    while True:
            try:
                url = input('\nPlease enter the website:\n')
                # request for a webpage
                res = requests.get(url)
                #check requests ststus
                if res.status_code == 200:
                    break
                else:
                    print('Please try another website.')
            except:
                print('Please enter a valid website.')
                continue

    while True:
        try:
            lang = input('\nPlease select the language of result (English, Chinese or Japanese):\n').lower()
            if lang in ['english', 'chinese', 'japanese']:
                break
            else:
                print('Please enter a valid language.')
        except:
            continue
    return url, lang

def get_html_text(url):
    '''
    Get html from website and get rid of html tag, and then convert to beautifulsoup object.
    Args:
        (str) url - website url
    Returns:
        (str) text - text without html tags
    '''

    res = requests.get(url)
    # get html from url
    html_text = res.text
    # change to beautifulsoup object
    soup = BeautifulSoup(html_text, 'html.parser')
    # get rid of extra spaces and line breaks and change to string separete by space
    text = ' '.join(soup.stripped_strings)
    return text

def text_process_en(text):
    '''
    Function for process if the selected language is English.
    Args:
        (str) text - text without html tags
    Returns:
        (list) list - a list containing each word
    '''

    # get rid of punctuations and special characters
    clean_text = re.sub(r"[^a-zA-Z0-9]+", ' ', text)
    # get rid of numbers
    clean_text = re.sub(r'\d+', '', clean_text)

    # change text to a list of words
    list =  clean_text.split()
    return list

def text_process_jp(text):
    '''
    Function for process if the selected language is Japanese.
    Args:
        (str) text - text without html tags
    Returns:
        (list) list - a list containing each hanzi
    '''

    # get rid of punctuations and special characters
    punctuation_jp = '[!"#$%&()*+,-./:;<=>?@[\\]：^_`{|}~「」〔〕“”〈〉『』【】＆＊・（）＄＃＠。、？！｀＋￥％]'
    clean_text = re.sub(punctuation_jp, "", text)
    # get rid of English characters and numbers
    clean_text = re.sub("[A-Za-z0-9]", '',clean_text)
    # get rid of spaces
    clean_text = clean_text.replace(' ', '')

    # change text to a list of hanzi
    list = []
    for i in clean_text:
        list.append(i)
    return list

def text_process_ch(text):
    '''
    Function for process if the selected language is Chinese.
    Args:
        (str) text - text without html tags
    Returns:
        (list) list - a list containing each hanzi
    '''

    # get rid of punctuations and special characters
    punctuation_ch = '[！？。＂＃＄％＆＇/（）＊＋，－／|():：；＜＝＞＠［＼］＾＿｀｛｜｝～｟｠｢｣､、·〃》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏.]'
    clean_text = re.sub(punctuation_ch, '',text)
    # get rid of English characters and numbers
    clean_text = re.sub("[A-Za-z0-9]", '',clean_text)
    # get rid of spaces
    clean_text = clean_text.replace(' ', '')

    # change text to a list of hanzi
    list = []
    for i in clean_text:
        list.append(i)
    return list

def sorted_result(list):
    '''
    Function to sort the words by frequency.
    Args:
        (list) list - a list containing each word (English) or hanzi (Chinese, Japanese)
    Returns:
        (dic) result - a dictionary containing each word (English) or hanzi (Chinese, Japanese) and it's frequency
    '''

    # create a dictionary to store words and it's frenquency
    dic = {}
    for word in list:
        if word in dic:
            dic[word] += 1
        else:
            dic[word] = 1

    # list containing sorted the words by frenquency
    list_sort = sorted(dic, key = dic.get, reverse = True)
    # create a dictionary to show sorted results
    result = {}
    for i in list_sort:
        result[i] = dic[i]
    return result

def export_csv(result_dic):
    '''
    Function to export the result to a csv file.
    Args:
        (dic) result_dic - a dictionary containing each word (English) or hanzi (Chinese, Japanese) and it's frequency
    Returns:
        NA
    '''

    with open('data.csv', 'w', encoding = 'utf-8') as f:
        for key in result_dic:
            f.write('%s, %i\n' % (key, result_dic[key]))

# def of memory and time?

def main():
    while True:
        url, lang = get_info()
        # check start time
        start = time.time()
        # check start memory
        pid = os.getpid()
        p = psutil.Process(pid)
        info_start = p.memory_full_info().uss/1024

        soup = get_html_text(url)
        if lang == 'english':
            list_en = text_process_en(soup)
            result = sorted_result(list_en)
            export_csv(result)
        elif lang == 'japanese':
            list_jp = text_process_jp(soup)
            result = sorted_result(list_jp)
            export_csv(result)
        else:
            list_ch = text_process_ch(soup)
            result = sorted_result(list_ch)
            export_csv(result)

        print('The result file was generated.')
        # check end time and calculate running time
        end = time.time()
        print('running time: %s seconds' % str(end - start))
        # check end memory
        info_end = p.memory_full_info().uss/1024
        print('running memory: %s KB' % str(info_end - info_start))

        while True:
            try:
                restart = input('\nWould you like to restart? Enter yes or no (Please change the saved file name if you want to restart).\n').lower()
                if restart in ['yes', 'no']:
                    break
                else:
                    print('Please enter a valid input.')
            except:
                continue

        if restart != 'yes':
            break

if __name__ == "__main__":
    main()


import argparse
import json
import logging
import time
import signal
from os import getpid
import http1

import utils
import notifications

### GLOBAL VARIABLES ###
running = True

### LOGGING CONF ###
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(filename)s:%(lineno)d - %(levelname)s: %(message)s'
)
logger = logging.getLogger('imapmanager')

def signal_handler(_signal, _frame):
    global running
    running = False
    logger.info('Ending signal handled, ending the script...')

def main():
    logger.info('--------------------')

    # Check python3 is used
    utils.check_python_version()

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    # Parse arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--conf', '-c', dest='config_path')
    args = parser.parse_args()

    # Open conf and load parameters
    config = utils.open_and_load_config(args)

    level = logging.getLevelName(config.get(utils.SECTION_DEFAULT_NAME, utils.LOG_LEVEL_NAME))
    logger.setLevel(level)

    api_url = config.get(utils.SECTION_DEFAULT_NAME, utils.API_URL_NAME)
    id_servers = config.get(utils.SECTION_DEFAULT_NAME, utils.ID_SERVERS_NAME).split(',')
    polling_interval = config.get(utils.SECTION_DEFAULT_NAME, utils.POLLING_INTERVAL_NAME)
    zones_desired = set()
    for zone in set(config.items(utils.SECTION_ZONES_NAME)):
        zones_desired.add(zone[1])

    last_status = False
    logger.info('Calling kimsufi API on url=%s with PID=%d', api_url, getpid())
    while running:
        server_found = False
        try:
            response = http1.get(api_url)
            if response.status == 200:
                struct = json.loads(response.body)
                for item in struct:
                    zones = [z['datacenter'] for z in item['datacenters'] if z['availability'] not in ('unavailable', 'unknown')]
                    if set(zones).intersection(zones_desired) and item['hardware'] in id_servers:
                        server_found = True
                        if not last_status:
                            logger.info('Found available server, sending notifications...')
                            notifications.send_notifications(config, True)
                            last_status = True
                        else:
                            logger.debug('Notification already sent, passing...')
                        # Do not iterate on other items as we already found an available server
                        break
                if not server_found:
                    logger.debug('No server available')
                    if last_status:
                        logger.info('Server not available anymore')
                        notifications.send_notifications(config, False)
                        last_status = False
            else:
                logger.error('Calling API: status=%d msg=%s', response.status, response.message)
        except Exception as exc:
            logger.error('Calling API: err=%s', str(exc))
        finally:
            # If signal occurs during process, there is no need to sleep
            if running:
                time.sleep(float(polling_interval))

    logger.info('kimsufi script ended.')

if __name__ == '__main__':
    main()


import cv2
import os
import numpy as np
# from keras import preprocessing
# from keras_vggface.vggface import VGGFace
import time
import sys
import matplotlib.pyplot as plt
import card

#ReadNetfromCaffe
#Config path
protoPath = os.path.join(os.getcwd(),'face_detector','deploy.prototxt.txt')
#Net path
modelPath = os.path.join(os.getcwd(),'face_detector','res10_300x300_ssd_iter_140000.caffemodel')
detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)

#CNN
embedder = cv2.dnn.readNetFromTorch(os.path.join(os.getcwd(),'openface.nn4.small2.v1.t7'))
# vgg_features = VGGFace(model="resnet50", include_top=False, input_shape=(224, 224, 3), pooling='avg')
def get_embedding(img):
    blob = img_blob(img)
    detector.setInput(blob)
    detections = detector.forward()
    face_detected = False
    h,w ,c= img.shape
    if len(detections)>0:
        #Assume only one face
        i  = np.argmax(detections[0, 0, :, 2])

        box = detections[0,0,i,3:7] * np.array([w, h, w, h])
        startX, startY, endX, endY = box.astype("int")

        id_face = img[startY:endY, startX:endX]
        id_face_blur = cv2.GaussianBlur(id_face, (5,5), 1)
        sharp_kernel = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])
        id_face = cv2.filter2D(id_face_blur,-1,sharp_kernel)

        plt.imshow(cv2.cvtColor(id_face,cv2.COLOR_BGR2RGB))
        plt.show()

        id_face2 = face_blob(id_face)

        # embedded = vgg_features.predict(id_face2)
        embedder.setInput(id_face2)
        embedded = embedder.forward()
        face_detected = True

    # cv2.imshow(winname='face',mat=id_face)

    return face_detected, embedded

def selfie():
    #Number of pictures taken
    NUMBER = 5
    embedded_selfie = []
    frames = []

    cap = cv2.VideoCapture(0)
    if cap.isOpened() == False:
        print("Can't connect to camera")
        return None

    #Is it capturing
    capturing = False
    #Time capturing started
    starttime = 0
    sec = 0
    while(cap.isOpened()):

        ret, frame = cap.read()
        if ret == True:
            cv2.imshow('Frame', frame)
            cv2.waitKey(1)
            if capturing and len(frames)<NUMBER:
                delta = time.time()-starttime
                if sec >= 3:
                    sec=0
                    starttime = starttime+3
                    print('Capturing')
                    frames.append(frame)

                elif delta>sec:
                    print(str(3-sec)+'...')
                    sec += 1
                if len(frames) == 5:
                    break
            #Selfie on y key

            elif cv2.waitKey(1) == ord('y'):
                capturing = True
                starttime=time.time()
                print('Y')
            #Exit on q key
            elif cv2.waitKey(1) & 0xFF == ord('q'):
                break
    cap.release()
    cv2.destroyAllWindows()
    if len(frames) > 0:
        for img in frames:
            face_detected, embedded = get_embedding(img)
            if face_detected:
                embedded_selfie.append(embedded)

    return embedded_selfie

def id_card(path):
    id = cv2.imread(path)
    card_detect, id = card.extract_photo(id)
    if card_detect:
        face_detected, embedded_id = get_embedding(id)
        if not face_detected:
            print("No face detected")
            return None
        return embedded_id
    else:
        print("No card detected")
        return None

def img_blob(img):
    img = img.astype(np.float32)
    resized_img = cv2.resize(img,(300,300))
    # subtract image with RGB mean
    resized_img[:,:,0] -= 104.0
    resized_img[:,:,1] -= 177.0
    resized_img[:,:,2] -= 123.0

    resized_img = np.transpose(resized_img, [2, 0, 1])
    resized_img = np.array([resized_img])

    return resized_img

def face_blob(img):
    img = img*(1/255.0)
    swapRB = img[:,:,::-1]
    # resized_img = cv2.resize(swapRB,(224,224))
    # resized_img[:,:,0] += 93.5940
    # resized_img[:,:,1] += 103.8827
    # resized_img[:,:,2] += 129.1863
    # resized_img = np.asarray((resized_img,))
    resized_img = cv2.resize(swapRB, (96,96))
    resized_img = np.transpose(resized_img, [2, 0, 1])
    resized_img = np.array([resized_img])
    return resized_img

def compare_face(embedded_id,embedded_selfies,threshold=0.85):
    if len(embedded_id) == 0 or len(embedded_selfies) == 0:
        euclidean_distance = np.empty((0))
    matches = 0
    for embedded_img in embedded_selfies: #(1,128)
        euclidean_distance2 = np.linalg.norm(embedded_img[0]-embedded_id[0])
        euclidean_distance1 = np.sqrt(np.mean((embedded_img[0]-embedded_id[0])**2))
        print(euclidean_distance2)
        if euclidean_distance2 <= threshold:
            matches +=1
    return matches > len(embedded_selfies)/2

def main():
    embedded_id = id_card(sys.argv[1])
    if not embedded_id is None:
        embedded_selfies = selfie()
        if len(embedded_selfies) == 0:
            print("No face detected in selfies")
            return
        if embedded_selfies != []:
            matched = compare_face(embedded_id,embedded_selfies)
            if matched:
                print("Pass")
            else:
                print("Try Again")
        else:
            print('no face detected')

if __name__ == '__main__':
    main()