import time
import pyupbit
import datetime

avail=[]
avail_buy_list=[]
buy_tricker=[]
access = "본인의 access 코드"
secret = "본인의 secret 코드"
buy_count = 0
sell_count = 0
krw_count = 0
krw_count2 = 0

# 로그인
upbit = pyupbit.Upbit(access, secret)[p]
print("autotrade start")

tricker = pyupbit.get_tickers(fiat="KRW")
avail_tricker = ["KRW-BTC","KRW-ETH","KRW-NEO","KRW-MTL","KRW-LTC","KRW-XRP","KRW-ETC",
"KRW-OMG","KRW-SNT","KRW-WAVES"]

df_ex = pyupbit.get_ohlcv("KRW-BTC", interval="day", count=1)
start_time = df_ex.index[0]

real_krw=upbit.get_balance("KRW")
#buy_krw = real_krw*0.2495

balance = upbit.get_balances()
for k in range(0,len(balance)):
    if balance[k]['currency'] == "KRW" or balance[k]['currency'] == "APENFT":
                continue
    buy_tricker.append("KRW-" + balance[k]['currency'])
    buy_count += 1
    krw_count += 1

# 하루에 최대 4종목만 거래함
if krw_count == 0:
    buy_krw = real_krw*0.2495
elif krw_count == 1:
    buy_krw = real_krw/3-0.0005
elif krw_count == 2:
    buy_krw = real_krw/2-0.0005
elif krw_count == 3:
    buy_krw = real_krw/1-0.0005

if buy_krw < 5025:
    sell_count = 4-buy_count
    buy_count = 4

print(len(balance))
print("buy_count : %d" % buy_count)
print("sell_count : %d" % sell_count)
print(buy_tricker)

while True:

    for i in tricker:
        print(i)
        print(pyupbit.get_current_price(i))
        df = pyupbit.get_ohlcv(i,count=4)
        close = df['close']
        print(close[2])
        time.sleep(0.1)

        # 전날 종가에 비해 1% 상승했을 때 그 종목 매수
        if pyupbit.get_current_price(i)>=1.009*close[2] and pyupbit.get_current_price(i)<=1.011*close[2] and (i in buy_tricker)!=True:
            avail_buy_list.append(i)
            krw=upbit.get_balance("KRW")
            if  krw>=5025 and buy_count<4:
                upbit.buy_market_order(i,buy_krw)
                print('buy: %s' % i)
                buy_count += 1
                buy_tricker.append(i)

        # avail.append(i)
        # 전날 종가에 비해 2% 상승했을 때 그 종목 매도
        coin = upbit.get_balance(i)
        if pyupbit.get_current_price(i)>=1.021*close[2] and coin>0:
            if upbit.sell_market_order(i,coin) != None:
                print('sell: %s' % i)
                sell_count += 1
                buy_tricker.remove(i)
            else:
                print('cant sell(잔액부족): %s' % i)
                sell_count += 1
                buy_tricker.remove(i)
        time.sleep(0.1)

    while buy_count>=4:
        for l in buy_tricker:

            print(l)
            print(pyupbit.get_current_price(l))
            df = pyupbit.get_ohlcv(l,count=4)
            close = df['close']
            print(close[2])
            time.sleep(0.1)
            coin = upbit.get_balance(l)
            if pyupbit.get_current_price(l)>=1.02*close[2] and coin>0:
                if upbit.sell_market_order(l,coin) != None:
                    print('sell: %s' % l)
                    sell_count += 1
                    buy_tricker.remove(l)
                else:
                    print('cant sell(잔액부족): %s' % l)
                    sell_count += 1
                    buy_tricker.remove(l)
            time.sleep(0.1)
        print("buy_count : %d" % buy_count)
        print("sell_count : %d" % sell_count)
        print(buy_tricker)

        if sell_count >= 4  or start_time + datetime.timedelta(days=1) >= datetime.datetime.now():
            break
        #print(upbit.get_balances())

    if start_time + datetime.timedelta(days=1) < datetime.datetime.now():

        buy_count=len(buy_tricker)
        krw_count2 = len(buy_tricker)
        sell_count=0
        start_time = start_time + datetime.timedelta(days=1)
        real_krw=upbit.get_balance("KRW")
        #buy_krw = real_krw*0.2495

        if krw_count2 == 0:
            buy_krw = real_krw*0.2495
        elif krw_count2 == 1:
            buy_krw = real_krw/3-0.0005
        elif krw_count2 == 2:
            buy_krw = real_krw/2-0.0005
        elif krw_count2 == 3:
            buy_krw = real_krw/1-0.0005

    print("buy_count : %d" % buy_count)
    print("sell_count : %d" % sell_count)
    print(buy_tricker)

#print(avail_buy_list)
#print(df.index[0])


import torch

import ConfigSpace
import ConfigSpace.hyperparameters as CSH

from autoPyTorch.components.preprocessing.preprocessor_base import PreprocessorBase

class PolynomialFeatures(PreprocessorBase):
    def __init__(self, hyperparameter_config):
        self.degree = hyperparameter_config['degree']
        self.interaction_only = hyperparameter_config['interaction_only']
        self.include_bias = hyperparameter_config['include_bias']
        self.preprocessor = None

    def fit(self, X, Y):
        import sklearn.preprocessing

        self.preprocessor = sklearn.preprocessing.PolynomialFeatures(
            degree=self.degree, interaction_only=self.interaction_only,
            include_bias=self.include_bias)

        self.preprocessor.fit(X, Y)

    def transform(self, X):
        if self.preprocessor is None:
            raise NotImplementedError()
        return self.preprocessor.transform(X)

    @staticmethod
    def get_hyperparameter_search_space(dataset_properties=None):
        degree = CSH.UniformIntegerHyperparameter("degree", lower=2, upper=3)
        interaction_only = CSH.CategoricalHyperparameter("interaction_only", [False, True])
        include_bias = CSH.CategoricalHyperparameter("include_bias", [True, False])

        cs = ConfigSpace.ConfigurationSpace()
        cs.add_hyperparameters([degree, interaction_only, include_bias])

        return cs


import datetime
import os
import uuid

class VMCastMaker:
    def __init__(self, title, uuid, description, language, baseserverurl, basepath):
        self.baseserverurl  = baseserverurl
        self.basepath       = basepath
        self.title          = title
        self.uuid           = uuid
        self.description    = description
        self.language       = language
        self.items          = []

    def init_feed(self):
        self.feed =  "<?xml version='1.0' encoding='utf-8'?>\n"
        self.feed += "   <rss version='2.0'>\n"
        self.feed += "   <channel>\n"
        self.feed += "        <title>" + self.title + "</title>\n"
        self.feed += "        <link>" + self.baseserverurl + "</link>\n"
        self.feed += "        <uuid>" +  self.uuid + "</uuid>\n"
        self.feed += "        <description>" + self.description + "</description>\n"
        self.feed += "        <language>" + self.language +"</language>\n"

    def add_item(self, title, description, link, uuid, dlurl, size):
        self.items.append({ 'title'         : title,
                            'description'   : description,
                            'link'          : link,
                            'uuid'          : uuid,
                            'dlurl'         : dlurl,
                            'size'          : size})

    def makeVMCast(self):
        for item in self.items:
            item_string =   "        <item>\n"
            item_string +=   "            <title>" + item['title'] + "</title>\n"
            item_string +=   "            <link>" + item['link'] + "</link>\n"
            item_string +=   "            <uuid>" + item['uuid'] + "</uuid>\n"
            item_string +=   "            <enclosure url='" + item['dlurl'] + "' length='" + item['size'] + "' type='application/enomalism2-xvm2'/>\n"
            item_string +=   "            <description>\n            <![CDATA[\n                " +item['description'] + "\n            ]]>\n            </description>\n"
            item_string +=   "            <pubDate>" + str(datetime.datetime.now()) + "</pubDate>\n"
            item_string +=   "        </item>\n"
            self.feed += item_string
        self.feed += "    </channel>\n</rss>"
        return self.feed

    def writeFeed(self, path="./rss.xml"):
        f = open(path, "w")
        f.write(self.makeVMCast())
        f.close()

    def parseDirectory(self, path="."):
        self.init_feed()
        self.items = []
        xvm2_files = [x for x in os.listdir(path) if x.endswith('.xvm2')]
        for xvm2_file in xvm2_files:
            size = os.path.getsize(path + "/" + xvm2_file)
            item_uuid = uuid.uuid3(uuid.NAMESPACE_URL, xvm2_file)
            self.add_item(xvm2_file.replace('.xvm2', ''),
                            'Auto imported vmcast',
                            self.baseserverurl,
                            str(item_uuid),
                            self.baseserverurl + "/" + xvm2_file,
                            str(size))


from cmath import e
import time
import pyautogui
import keyboard
from MrMineFunctions import clickChestInMiddleOfScreens, clickMouse

import generalFunctions
import MrMineMath
import mouseAndKeyboard
import positionsAndResolution
import fileHandling
import monsters
import bufflab

pyautogui.FAILSAFE = True

positions = positionsAndResolution.positions
fh = fileHandling

middleRowBottomLeftXValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.middleRowBottomLeft[0], positions.currentResolution[0], positions.originalResolution[0]))
middleRowBottomLeftYValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.middleRowBottomLeft[1], positions.currentResolution[0], positions.originalResolution[0]))

middleRowTopRightXValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.middleRowTopRight[0], positions.currentResolution[1], positions.originalResolution[1]))
middleRowTopRightYValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.middleRowTopRight[1], positions.currentResolution[1], positions.originalResolution[1]))

lowerThreeLeftXValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.lowerThreeRowsBottomLeft[0], positions.currentResolution[0], positions.originalResolution[0]))
lowerThreeLeftYValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.lowerThreeRowsBottomLeft[1], positions.currentResolution[0], positions.originalResolution[0]))

lowerThreeTopRightXValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.lowerThreeRowsTopRight[0], positions.currentResolution[1], positions.originalResolution[1]))
lowerThreeLeftXValue = int(MrMineMath.convertToCurrentResolutionPosition(positions.lowerThreeRowsTopRight[1], positions.currentResolution[1], positions.originalResolution[1]))

def miningMain():
    pass
    collectChestsInMineImproved()

def checkIfOre():
    print("Checking for ores...")
    oreConfidence = 0.85

    siliconPosition = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\siliconore.png", confidence = oreConfidence - 0.01)
    magnesiumPosition = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\magnesiumore.png", confidence = oreConfidence)
    titaniumPosition = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\titaniumore.png", confidence = oreConfidence)
    fishPosition = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\fishore.png", confidence = oreConfidence - 0.05)

    oreList = [siliconPosition, magnesiumPosition, titaniumPosition, fishPosition]
    foundOre = False

    for i in range(len(oreList)):
        pyautogui.failSafeCheck()
        if oreList[i] != None:
            foundOre = True
            print("Found ore!")
            #Clicking on red exclamation mark
            orePosition = pyautogui.center(oreList[i])
            pyautogui.moveTo(orePosition)
            for i in range(8):
                clickMouse()
    if not foundOre:
        print("Did not find any ores.")

    return foundOre

def collectChestsInMineImproved():
    #Main
    print("Checking for chests...")
    counter = 0
    generalFunctions.goToMrMineScreen()
    generalFunctions.goToSafeClickArea()
    maxCount = positions.amountOfChestsToBeClicked
    nothingToDoInARow = 0
    amountOfTriesBeforeSkip = 3

    yellowbackgroundConfidence = 0.85
    fh.replaceLineInFile(positions.userconfigFile, fh.getLineNumberFromFile(positions.gamestageFile, "skippedChestCollecting = True;"), "skippedChestCollecting = False;") #Resets it
    while counter < maxCount:
        if nothingToDoInARow > amountOfTriesBeforeSkip:
            fh.replaceLineInFile(positions.userconfigFile, fh.getLineNumberFromFile(positions.gamestageFile, "skippedChestCollecting = False;"), "skippedChestCollecting = True;") #If nothing to do then skips
            print("Nothing to do so skipping.")
            break
        pyautogui.failSafeCheck()
        checkIfRainShower()
        keyboard.press_and_release('space')
        time.sleep(1)
        foundOre = checkIfOre()
        if foundOre:
            continue #Skips most likely only one thing on floor skipping for better performance
        foundMonster = monsters.checkIfMonster()
        monsters.checkIfFightScreen()
        if foundMonster:
            continue #Skips most likely only one thing on floor skipping for better performance
        chestbackgroundcolor = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\smallchestbackgroundcolor.png", confidence = yellowbackgroundConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))

        if chestbackgroundcolor == None:
            nothingToDoInARow = nothingToDoInARow + 1
        else:
            nothingToDoInARow = 0 #reset counter if no background color was found
        iterateOverAllMinersOnAFloor(0)
        monsters.checkIfFightScreen()

        chestbackgroundcolor = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\smallchestbackgroundcolor.png", confidence = yellowbackgroundConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))

        print(chestbackgroundcolor)

        if chestbackgroundcolor != None:
            chestbackgroundcolor = pyautogui.center(chestbackgroundcolor)
            pyautogui.moveTo(chestbackgroundcolor)
            time.sleep(6)
            print("Yellow background detected below middle floor")
            collectChestBelowMiddle()
        counter = counter + 1
        print("Collecting chests from mine: " + str(counter + 1) + "/" + str(maxCount))
        print("Nothing to do count: " + str(nothingToDoInARow) + "/" + str(amountOfTriesBeforeSkip))

def collectChestsInMineWithImageRecognition():
    #Was used in version 0.7
    #Slower version but gives more precision
    #Ended with not using images for this as it slows down the performance alot
    print("Checking for chests...")
    counter = 0
    generalFunctions.goToMrMineScreen()
    generalFunctions.goToSafeClickArea()
    maxCount = positions.amountOfChestsToBeClicked * 5
    nothingToDoInARow = 0
    amountOfTriesBeforeSkip = 3
    foundChest = False
    while counter < maxCount:
        if nothingToDoInARow > amountOfTriesBeforeSkip:
            print("Nothing to do so skipping.")
            break

        chestbackgroundcolor = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\smallchestbackgroundcolor.png", confidence = chestConfidence - 0.1, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))

        pyautogui.failSafeCheck()
        keyboard.press_and_release('space')
        time.sleep(positions.defaultDelay)
        checkIfOre()
        monsters.checkIfMonster()
        monsters.checkIfFightScreen()

        chestConfidence = 0.6 #0.6 works really good
        grayscaleIsOn = False

        minerWithChestEarth = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\minerwithchestearth.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))

        earthchest1Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\earthchest1.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)
        earthchest2Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\earthchest2.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)
        earthchest3Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\earthchest3.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)
        earthchest4Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\earthchest4.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)

        moonchest1Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\moonchest1.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)
        moonchest2Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\moonchest2.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)
        moonchest3Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\moonchest3.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)
        moonchest4Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\moonchest4.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue), grayscale = grayscaleIsOn)

        goldchest1Position = None
        goldchest2Position = None
        goldchest3Position = None
        goldchest4Position = None

        #Can disable gold chest detection for better performance
        if fh.stringInFileExists(positions.userconfigFile, "goldchestDetection = True;"):
            print("goldchest = True")
            goldchest1Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\goldchest1.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))
            goldchest2Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\goldchest2.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))
            goldchest3Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\goldchest3.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))
            goldchest4Position = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\goldchest4.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))

        #chestleftside1 = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\chestleftside1.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))
        #chestleftside2 = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\chestleftside2.png", confidence = chestConfidence, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))

        chestbackgroundcolor = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\mine\\smallchestbackgroundcolor.png", confidence = chestConfidence - 0.1, region=(lowerThreeLeftXValue, lowerThreeLeftYValue, lowerThreeTopRightXValue, lowerThreeLeftXValue))

        #print(minerWithChestEarth)
        chestList = [
            earthchest1Position, earthchest2Position, earthchest3Position, earthchest4Position, moonchest1Position,
            moonchest2Position, moonchest3Position, moonchest4Position, goldchest1Position, goldchest2Position, goldchest3Position,
            goldchest4Position, minerWithChestEarth
        ] #chestleftside1, chestleftside2]
        correctXYToMoveTo = None
        for i in range(len(chestList)):
            if chestList[i] != None:
                print(chestList[i], i)
                correctXYToMoveTo = chestList[i]

        if correctXYToMoveTo != None: #Means it found something
            foundChest = True
            nothingToDoInARow = 0 # Resets when it has found a chest
            chestPosition = pyautogui.center(correctXYToMoveTo)
            pyautogui.moveTo(chestPosition[0], correctXYToMoveTo[1] + 50)
            clickMouse()
            clickChestInMiddleOfScreens()
        else:
            nothingToDoInARow = nothingToDoInARow + 1 #Did not find a a chest
            if chestbackgroundcolor != None: #Found yellow background
                print("Did not find chest on screen, but detected yellow background.")
                iterateOverAllMinersOnAFloor()
        print("Collecting chests from mine: " + str(counter + 1) + "/" + str(maxCount))
        print("Nothing to do count: " + str(nothingToDoInARow - 1) + "/" + str(amountOfTriesBeforeSkip))
        counter = counter + 1
    if not foundChest:
        print("Did not find any chests.")

def collectChestsInMineOldVersion():
    counter = 0
    generalFunctions.goToMrMineScreen()
    generalFunctions.goToSafeClickArea()
    maxCount = positions.amountOfChestsToBeClicked * 2
    while counter < maxCount:
        keyboard.press_and_release('space')
        time.sleep(positions.defaultDelay)
        iterateOverAllMinersOnAFloor()
        print("Collecting chests from mine: " + str(counter + 1) + "/" + str(maxCount))
        counter = counter + 1

def iterateOverAllMinersOnAFloor(modifier):

    '''
    Modifier can be 0\n
    If 0 then scans middle floor\n

    ------
    ------
    XXXXXX
    ------\n
    ------\n

    If modifier = 200
    then goes up one level

    ------
    XXXXXX
    ------
    ------
    ------

    If modifier = -200
    then goes down one level

    ------
    ------
    ------
    XXXXXX
    ------

    '''

    try:
        keyboard.press("left shift")
        for everyMiner in range(len(positions.minerPosistionList)):
            time.sleep(positions.defaultDelay)
            pyautogui.moveTo(MrMineMath.convertToCurrentResolutionPosition(positions.minerPosistionList[everyMiner], positions.currentResolution[0], positions.originalResolution[0]), MrMineMath.convertToCurrentResolutionPosition(positions.minerYpositionMiddleLevel - modifier, positions.currentResolution[1], positions.originalResolution[1]))
            mouseAndKeyboard.clickMouse()
        keyboard.release("left shift")
    except:
        keyboard.release("left shift") # should fix left shift getting stuck if causing an interrupt

def collectChestBelowMiddle():

    '''
    Function must be placed after it has checked once and 'tried' to collect chest.\n
    If yellow background is still there it means it's below middle level.\n
    '''

    for i in range(1, 3):
        iterateOverAllMinersOnAFloor(i * - 200)

def fastCollectChest(*args):
    bufflab.clickOneBuff(bufflab.lowestTierNuggetOfAttraction)
    generalFunctions.goToMrMineScreen()
    generalFunctions.goToSafeClickArea()
    amountOfIterations = 30
    pyautogui.moveTo(MrMineMath.convertToCurrentResolutionPosition(positions.minerPosistionList[4] - positions.currentResolution[0] / 100 * 3, positions.currentResolution[0], positions.originalResolution[0]), MrMineMath.convertToCurrentResolutionPosition(positions.minerYpositionMiddleLevel, positions.currentResolution[1], positions.originalResolution[1]))
    if args:
        amountOfIterations = args[0]
    for i in range(amountOfIterations):
        try:
            print("Fast collecting: " + str(i) + "/" + str(amountOfIterations))
            keyboard.press_and_release('space')
            keyboard.press("left shift")
            mouseAndKeyboard.clickMouse()
            keyboard.release("left shift") # should fix left shift getting stuck if causing an interrupt
        except KeyboardInterrupt:
            keyboard.release("left shift")
        except Exception as e:
            print(e)
            keyboard.release("left shift")

def fastCollectChestOld():
    generalFunctions.goToMrMineScreen()
    amountOfIterations = 30
    for i in range(amountOfIterations):
        try:
            print("Fast collecting: " + str(i) + "/" + str(amountOfIterations))
            keyboard.press_and_release('space')
            keyboard.press("left shift")
            for everyMiner in range(len(positions.minerPosistionList)):
                pyautogui.moveTo(MrMineMath.convertToCurrentResolutionPosition(positions.minerPosistionList[everyMiner], positions.currentResolution[0], positions.originalResolution[0]), MrMineMath.convertToCurrentResolutionPosition(positions.minerYpositionMiddleLevel, positions.currentResolution[1], positions.originalResolution[1]))
                mouseAndKeyboard.clickMouse()
            keyboard.release("left shift") # should fix left shift getting stuck if causing an interrupt
        except KeyboardInterrupt:
            keyboard.release("left shift")
        except Exception as e:
            print(e)
            keyboard.release("left shift")

def checkIfRainShower():
    print("Checking for rain shower buff.")
    mouseAndKeyboard.pressButton('esc')
    generalFunctions.goToMrMineScreen()
    generalFunctions.goToSafeClickArea()
    rainShowerConfidence = 0.7 #0.7 works
    time.sleep(0.5)
    rainShower = pyautogui.locateOnScreen(str(fh.getPathToCurrentDir()) + "images\\general\\rainingchest.png", confidence = rainShowerConfidence)
    if rainShower:
        print(rainShower)
        print("Detected rain shower!")
        fastCollectChest(150)
    else:
        print("No rain shower detected.")
    mouseAndKeyboard.pressButton('space')

#fastCollectChest()


from django.utils.translation import ugettext as _

# 1st party
from openlab.notifications.models import new
from openlab.olmarkdown import util as olmarkdown_util

# local
from .models import Thread, Message

def message_save(sender, **kwds):
    message = kwds['instance']
    created = kwds['created']

    if not created:
        # only generate notificaitons for newly generated messages
        return

    # Loop through everyone subscribed
    subscribers = list(message.thread.subscribers.all())
    mentioned_usernames = olmarkdown_util.get_username_mentions(
                message.olmarkdown_rendered)

    mentioned_users = []
    if mentioned_usernames:
        mentioned_users = User.objects.filter(
                username__in=mentioned_usernames)

    name = message.user.profile.desired_name
    msg = _(u"%s replied in a discussion which "
            "you have participated in") % name
    url = message.get_absolute_url()

    for user in subscribers:
        if user.username in mentioned_usernames:
            continue # skip, we'll do those later
        if message.user == user:
            continue # skip, its me!
        new(user, msg, url=url, actor=message.user, topic=message)

    msg = _(u"%s mentioned you in a comment") % name
    for user in mentioned_users:
        if message.user == user:
            continue # skip, its me!
        new(user, msg, url=url, actor=message.user, topic=message)

def thread_save(sender, **kwds):
    thread = kwds['instance']
    created = kwds['created']

    if not created:
        # only generate notificaitons / actions for newly created threads
        return

def trigger_thread_save(thread):

    projects = list(thread.project_set.all())
    teams = list(thread.team_set.all())

    # Note: "anything"  should almost certainly be a list of length 1
    anything = list(projects + teams)
    if thread.user:
        name = thread.user.profile.desired_name
    else:
        name = "Someone"

    if anything:
        verb = _(u"started a discussion about %s") % str(anything[0])
    else:
        verb = _(u"created a new discussion")

    msg = u" ".join([name, verb])

    # Distill down to teams
    for project in projects:
        if project.team:
            teams.append(project.team)

    # Distill down to users
    users = []
    for team in teams:
        users.extend(list(team.members.all()))
    for project in projects:
        users.append(project.user)

    url = thread.get_absolute_url()
    # Notify project creator and/or team members
    for user in users:
        if thread.user == user:
            continue # skip, its me!
        new(user, msg, url=url, actor=thread.user, topic=thread)


import math

import dgl
import dgl.function as fn
import dgl.nn.pytorch as dglnn
import dgl.ops as F
import numpy as np
import torch as th
import torch.nn as nn
from scipy import sparse

from .gnn_models import GATConv

class SemanticExpander(nn.Module):

    def __init__(self, input_dim, reducer, order):

        super().__init__()

        self.input_dim = input_dim
        self.order = order
        self.reducer = reducer
        self.GRUs = nn.ModuleList()
        for i in range(self.order):
            self.GRUs.append(nn.GRU(self.input_dim, self.input_dim, 1, True, True))

        if self.reducer == 'concat':
            self.Ws = nn.ModuleList()
            for i in range(1, self.order):
                self.Ws.append(nn.Linear(self.input_dim * (i+1), self.input_dim))

    def forward(self, feat):

        if len(feat.shape) < 3:
            return feat
        if self.reducer == 'mean':
            invar = th.mean(feat, dim=1)
        elif self.reducer == 'max':
            invar =  th.max(feat, dim=1)[0]
        elif self.reducer == 'concat':
            invar =  self.Ws[feat.size(1)-2](feat.view(feat.size(0), -1))
        var = self.GRUs[feat.size(1)-2](feat)[1].permute(1, 0, 2).squeeze()

        # return invar + var
        return 0.5 * invar + 0.5 * var

class MSHGNN(nn.Module):

    def __init__(self, input_dim, output_dim, dropout=0.0, activation=None, order=1, reducer='mean'):
        super().__init__()

        self.dropout = nn.Dropout(dropout)
        # self.gru = nn.GRUCell(2 * input_dim, output_dim)
        self.output_dim = output_dim
        self.activation = activation
        self.order = order

        conv1_modules = {'intra'+str(i+1) : GATConv(input_dim, output_dim, 8, dropout, dropout, residual=True) for i in range(self.order)}
        conv1_modules.update({'inter'     : GATConv(input_dim, output_dim, 8, dropout, dropout, residual=True)})
        self.conv1 = dglnn.HeteroGraphConv(conv1_modules, aggregate='sum')

        conv2_modules = {'intra'+str(i+1) : GATConv(input_dim, output_dim, 8, dropout, dropout, residual=True) for i in range(self.order)}
        conv2_modules.update({'inter'     : GATConv(input_dim, output_dim, 8, dropout, dropout, residual=True)})
        self.conv2 = dglnn.HeteroGraphConv(conv2_modules, aggregate='sum')

        self.lint = nn.Linear(output_dim, 1, bias=False)
        self.linq = nn.Linear(output_dim, output_dim)
        self.link = nn.Linear(output_dim, output_dim, bias=False)

    def forward(self, g, feat):

        with g.local_scope():

            h1 = self.conv1(g, (feat, feat))
            h2 = self.conv2(g.reverse(copy_edata=True), (feat, feat))
            h = {}
            for i in range(self.order):
                hl, hr = th.zeros(1, self.output_dim).to(self.lint.weight.device), th.zeros(1, self.output_dim).to(self.lint.weight.device)
                if 's'+str(i+1) in h1:
                    hl = h1['s'+str(i+1)]
                if 's'+str(i+1) in h2:
                    hr = h2['s'+str(i+1)]
                h['s'+str(i+1)] = hl + hr
                if len(h['s'+str(i+1)].shape) > 2:
                    h['s'+str(i+1)] = h['s'+str(i+1)].max(1)[0]
                h_mean = F.segment.segment_reduce(g.batch_num_nodes('s'+str(i+1)), feat['s'+str(i+1)], 'mean')
                h_mean = dgl.broadcast_nodes(g, h_mean, ntype='s'+str(i+1)) # adding mean maskes better
                # print(h['s'+str(i+1)].shape, h_mean.shape)
                h['s'+str(i+1)] =  h_mean + h['s'+str(i+1)]

        return h

class AttnReadout(nn.Module):
    def __init__(
        self,
        input_dim,
        hidden_dim,
        output_dim,
        feat_drop=0.0,
        activation=None,
        order=1,
        device=th.device('cpu')
    ):
        super().__init__()
        self.feat_drop = nn.Dropout(feat_drop)
        self.order = order
        self.device = device
        self.fc_u = nn.ModuleList()
        self.fc_v = nn.ModuleList()
        self.fc_e = nn.ModuleList()
        self.fc_p = nn.ModuleList()
        for i in range(self.order):
            self.fc_u.append(nn.Linear(input_dim, hidden_dim, bias=True))
            self.fc_v.append(nn.Linear(input_dim, hidden_dim, bias=False))
            self.fc_e.append(nn.Linear(hidden_dim, 1, bias=False))
        self.fc_out = (
            nn.Linear(input_dim, output_dim, bias=False)
            if output_dim != input_dim
            else None
        )
        self.activation = activation

    def forward(self, g, feats, last_nodess):

        rsts = []

        nfeats = []
        for i in range(self.order):
            feat = feats['s'+str(i+1)]
            feat = th.split(feat, g.batch_num_nodes('s'+str(i+1)).tolist())
            feats['s'+str(i+1)] = th.cat(feat, dim=0)
            nfeats.append(feat)
        feat_vs= th.cat(tuple(feats['s'+str(i+1)][last_nodess[i]].unsqueeze(1) for i in range(self.order)), dim=1)
        feats = th.cat([th.cat(tuple(nfeats[j][i] for j in range(self.order)), dim=0) for i in range(len(g.batch_num_nodes('s1')))], dim=0)
        batch_num_nodes = th.cat(tuple(g.batch_num_nodes('s'+str(i+1)).unsqueeze(1) for i in range(self.order)), dim=1).sum(1)

        idx = th.cat(tuple(th.ones(batch_num_nodes[j])*j for j in range(len(batch_num_nodes)))).long()
        for i in range(self.order):
            feat_u = self.fc_u[i](feats)
            feat_v = self.fc_v[i](feat_vs[:, i])[idx]
            e = self.fc_e[i](th.sigmoid(feat_u + feat_v))
            alpha = F.segment.segment_softmax(batch_num_nodes, e)

            feat_norm = feats * alpha
            rst = F.segment.segment_reduce(batch_num_nodes, feat_norm, 'sum')
            rsts.append(rst.unsqueeze(1))

            if self.fc_out is not None:
                rst = self.fc_out(rst)
            if self.activation is not None:
                rst = self.activation(rst)
        rst = th.cat(rsts, dim=1)

        return rst

class MSGIFSR(nn.Module):

    def __init__(self, num_items, datasets, embedding_dim, num_layers, dropout=0.0, reducer='mean', order=3, norm=True, extra=True, fusion=True, device=th.device('cpu')):
        super().__init__()

        self.embeddings = nn.Embedding(num_items, embedding_dim, max_norm=1)

        self.num_items = num_items
        self.register_buffer('indices', th.arange(num_items, dtype=th.long))
        self.embedding_dim = embedding_dim
        self.num_layers = num_layers
        self.layers   = nn.ModuleList()
        input_dim     = embedding_dim
        self.reducer  = reducer
        self.order    = order
        self.alpha    = nn.Parameter(th.Tensor(self.order))
        self.beta     = nn.Parameter(th.Tensor(1))
        self.norm     = norm
        self.expander = SemanticExpander(input_dim, reducer, order)

        self.device = device
        for i in range(num_layers):
            layer = MSHGNN(
                input_dim,
                embedding_dim,
                dropout=dropout,
                order=self.order,
                activation=nn.PReLU(embedding_dim)
            )
            self.layers.append(layer)

        self.readout = AttnReadout(
            input_dim,
            embedding_dim,
            embedding_dim,
            feat_drop=dropout,
            activation=None,
            order=self.order,
            device=self.device
        )
        input_dim += embedding_dim
        self.feat_drop = nn.Dropout(dropout)

        self.fc_sr = nn.ModuleList()
        for i in range(self.order):
            self.fc_sr.append(nn.Linear(input_dim, embedding_dim, bias=False))

        self.sc_sr = nn.ModuleList()
        for i in range(self.order):
            self.sc_sr.append(nn.Sequential(nn.Linear(embedding_dim, embedding_dim, bias=True),  nn.ReLU(), nn.Linear(embedding_dim, 2, bias=False), nn.Softmax(dim=-1)))
        self.input_dim = input_dim
        self.embedding_dim =embedding_dim

        # self.sr_trans1 = nn.Linear(embedding_dim, embedding_dim)
        # self.sr_trans2 = nn.Linear(embedding_dim, embedding_dim)
        self.reset_parameters()
        self.alpha.data = th.zeros(self.order)
        self.alpha.data[0] = th.tensor(1.0)
        # self.beta.data = th.zeros(1)
        self.beta.data = th.tensor(1.0)
        self.fusion = fusion
        self.extra = extra
        self.epoch = 0

    def inc_epoch(self):
        self.epoch += 1

    def reset_parameters(self):
        stdv = 1 / math.sqrt(self.embedding_dim)
        for weight in self.parameters():
            weight.data.uniform_(-stdv, stdv)

    def iid2rp(self, iid):
        tmp = th.sum(th.cat(tuple(th.unique(tmp, return_inverse=True)[1].unsqueeze(0) for tmp in th.unbind(iid, dim=0)), dim=0), dim=1)

        return tmp

    def residual(self, h1, res):

        for key in h1.keys():
            h1[key] += res[key]

        return h1

    def forward(self, mg):

        feats = {}
        for i in range(self.order):
            iid = mg.nodes['s' + str(i+1)].data['iid']
            feat = self.embeddings(iid)
            feat = self.feat_drop(feat)
            feat = self.expander(feat)
            if th.isnan(feat).any():
                feat = feat.masked_fill(feat != feat, 0)
            if self.norm:
                feat = nn.functional.normalize(feat, dim=-1)
            feats['s' + str(i+1)] = feat

        h = feats
        for idx, layer in enumerate(self.layers):
            h = layer(mg, h)

        last_nodes = []
        for i in range(self.order):
            if self.norm:
                h['s'+str(i+1)] = nn.functional.normalize(h['s'+str(i+1)], dim=-1)
            last_nodes.append(mg.filter_nodes(lambda nodes: nodes.data['last'] == 1, ntype='s'+str(i+1)))

        feat = h
        sr_g = self.readout(mg, feat, last_nodes)

        sr_l = th.cat([feat['s'+str(i+1)][last_nodes[i]].unsqueeze(1) for i in range(self.order)], dim=1)
        sr   = th.cat([sr_l, sr_g], dim=-1)# .view(sr_l.size(0), -1)
        sr   = th.cat([self.fc_sr[i](sr).unsqueeze(1) for i, sr in enumerate(th.unbind(sr, dim=1))], dim=1)
        if self.norm:
            sr = nn.functional.normalize(sr, dim=-1)

        target = self.embeddings(self.indices)

        if self.norm:
            target = nn.functional.normalize(target, dim=-1)

        if self.extra:
            logits = sr @ target.t()
            phi = self.sc_sr[0](sr).unsqueeze(-1)
            mask = th.zeros(phi.size(0), self.num_items).to(self.device)
            iids = th.split(mg.nodes['s1'].data['iid'], mg.batch_num_nodes('s1').tolist())
            for i in range(len(mask)):
                mask[i, iids[i]] = 1

            logits_in = logits.masked_fill(~mask.bool().unsqueeze(1), float('-inf'))
            logits_ex = logits.masked_fill(mask.bool().unsqueeze(1), float('-inf'))
            score     = th.softmax(12 * logits_in.squeeze(), dim=-1)
            score_ex  = th.softmax(12 * logits_ex.squeeze(), dim=-1)

            if th.isnan(score).any():
                score    = feat.masked_fill(score != score, 0)
            if th.isnan(score_ex).any():
                score_ex = score_ex.masked_fill(score_ex != score_ex, 0)
            assert not th.isnan(score).any()
            assert not th.isnan(score_ex).any()
            # print(score.shape, score_ex.shape)
            if self.order == 1:
                phi = phi.squeeze(1)
                score = (th.cat((score.unsqueeze(1), score_ex.unsqueeze(1)), dim=1) * phi).sum(1)
            else:
                score = (th.cat((score.unsqueeze(2), score_ex.unsqueeze(2)), dim=2) * phi).sum(2)
        else:
            # print("no extra ****************")
            logits = sr.squeeze() @ target.t()
            score  = th.softmax(12 * logits, dim=-1)

        if self.order > 1 and self.fusion:
            alpha = th.softmax(self.alpha.unsqueeze(0), dim=-1).view(1, self.alpha.size(0), 1)
            g = th.ones(score.size(0), score.size(1), 1).to(self.device)
            g = alpha.repeat(score.size(0), 1, 1)
            score = (score * g).sum(1)
        elif self.order > 1:
            score = score[:, 0]

        # print(score.shape)

        score = th.log(score)

        return score


from rest_framework.views import APIView, Request, Response, status
from movies.models import Movie
from movies.serializers import MovieOrderSerializer, MovieSerializer
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.shortcuts import get_object_or_404
from users.permissions import IsAuthenticatedOrReadOnly
from rest_framework.permissions import IsAuthenticated
from rest_framework.pagination import PageNumberPagination

class MovieView(APIView, PageNumberPagination):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly]

    def post(self, request: Request) -> Response:
        serializer = MovieSerializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        serializer.save(user=request.user)

        return Response(serializer.data, status.HTTP_201_CREATED)

    def get(self, request: Request) -> Response:
        # Busco os filmes e os ordeno pelo id
        movies = Movie.objects.order_by("id")
        result_page = self.paginate_queryset(movies, request)
        serializer = MovieSerializer(instance=result_page, many=True)
        return self.get_paginated_response(serializer.data)

class MovieIdView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly]

    def get(self, request: Request, movie_id: int) -> Response:
        movie = get_object_or_404(Movie, id=movie_id)
        serializer = MovieSerializer(instance=movie)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def delete(self, request: Request, movie_id: int) -> Response:
        movie = get_object_or_404(Movie, id=movie_id)
        movie.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

class MovieOrderView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]

    def post(self, request: Request, movie_id: int) -> Response:
        movie = get_object_or_404(Movie, id=movie_id)
        serializer = MovieOrderSerializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        serializer.save(user=request.user, movie=movie)

        return Response(serializer.data, status.HTTP_201_CREATED)


import hashlib
import logging
import os
import shutil
import sys
import urllib.request as urllib2

from gi import require_version

require_version("Gdk", "3.0")
require_version("Gtk", "3.0")
from gi.repository import Gdk, Gtk

from otrverwaltung3p import path as otrvpath
from otrverwaltung3p.gui.config_bindings import (
    CheckButtonBinding,
    ComboBoxEntryBinding,
    EntryBinding,
    RadioButtonsBinding,
    SpinbuttonBinding,
    TextbufferBinding,
)

import requests

progs = ["ffmpeg", "ffprobe", "ffmsindex", "mediainfo", "mkvmerge", "mpv"]

class PreferencesWindow(Gtk.Window, Gtk.Buildable):
    __gtype_name__ = "PreferencesWindow"

    def __init__(self):
        Gtk.Window.__init__(self)
        self.log = logging.getLogger(self.__class__.__name__)
        self.app = None
        self.builder = None
        self.css = b"""
                    .font_larger { font-size: larger; }
                    .font_smaller { font-size: smaller; }
                    .font_bold { font-weight: bold; }
                    """
        self.css_provider = Gtk.CssProvider()
        self.css_provider.load_from_data(self.css)
        self.example_filename = "James_Bond_007_09.01.06_20-15_ard_120_TVOON_DE.mpg.HQ.avi"
        self.example_cut_filename = "James_Bond_007_09.01.06_20-15_ard_120_TVOON_DE.mpg.HQ-cut.avi"
        self.filechooser_title_setup = {
            "entry_folder_new_otrkeys": "Ordner fÃ¼r neue otrkey-Dateien",
            "entry_folder_uncut_avis": "Ordner fÃ¼r ungeschnittene Avis",
            "entry_folder_cut_avis": "Ordner fÃ¼r geschnittene Avis",
            "entry_folder_trash_otrkeys": "MÃ¼llorder fÃ¼r otrkey-Dateien",
            "entry_folder_trash_avis": "MÃ¼llorder fÃ¼r Avis",
            "entry_folder_archive": "Archiv Ordner",
            "entry_prog_ffmpeg": "Ã–ffne ffmpeg",
            "entry_prog_ffprobe": "Ã–ffne ffprobe",
            "entry_prog_ffmsindex": "Ã–ffne ffmsindex",
            "entry_prog_mediainfo": "Ã–ffne mediainfo",
            "entry_prog_mkvmerge": "Ã–ffne mkvmerge",
            "entry_prog_mpv": "Ã–ffne mpv",
            "entry_prog_decoder": "Ã–ffne otrdecoder",
            "entry_folder_wineprefix": "Wineprefix fÃ¼r vdub.exe",
        }
        self.last_path = None

    def obj(self, objectname):
        return self.builder.get_object(objectname)

    def do_parser_finished(self, builder):
        self.builder = builder
        self.builder.connect_signals(self)

    def bind_config(self, app):
        self.app = app
        # If the stored decoder is not in the standard list (see PreferenceWindow.glade)
        # it will be prepended and set as active entry.
        entries = []
        if sys.platform == "linux":
            entries = ["intern-easydecoder"]
            if shutil.which("otrtool"):
                entries.append("otrtool")
            for entry in entries:
                self.obj("entry_prog_decoder").append(entry, entry)
        decoder_value = self.app.config.get("programs", "decoder")
        if decoder_value not in entries:
            self.obj("entry_prog_decoder").prepend(decoder_value, decoder_value)
            self.obj("entry_prog_decoder").set_active(0)

        # 1 Speicherorte
        for folder in [
            "folder_new_otrkeys",
            "folder_uncut_avis",
            "folder_cut_avis",
            "folder_trash_otrkeys",
            "folder_trash_avis",
            "folder_archive",
        ]:
            EntryBinding(self.obj("entry_" + folder), self.app.config, "general", folder)

        # 2 OTR-Einstellungen
        ComboBoxEntryBinding(self.obj("entry_prog_decoder"), self.app.config, "programs", "decoder")
        CheckButtonBinding(
            self.obj("check_verify_decoded"), self.app.config, "general", "verify_decoded",
        )
        EntryBinding(self.obj("entry_email"), self.app.config, "general", "email")
        EntryBinding(self.obj("entry_password"), self.app.config, "general", "password")
        RadioButtonsBinding(
            [self.obj(widget) for widget in ["radioPasswdStoreConf", "radioPasswdStoreWallet", "radioPasswdStoreNot"]],
            self.app.config,
            "general",
            "passwd_store",
        )
        CheckButtonBinding(
            self.obj("check_passwd_store_memory"), self.app.config, "general", "passwd_store_memory",
        )

        # 3 Schneiden
        ComboBoxEntryBinding(self.obj("combobox_avi"), self.app.config, "general", "cut_avis_by")
        ComboBoxEntryBinding(self.obj("combobox_hq"), self.app.config, "general", "cut_hqs_by")
        ComboBoxEntryBinding(self.obj("combobox_hd2"), self.app.config, "general", "cut_hd2_by")
        ComboBoxEntryBinding(self.obj("combobox_mp4"), self.app.config, "general", "cut_mp4s_by")
        ComboBoxEntryBinding(self.obj("combobox_man_avi"), self.app.config, "general", "cut_avis_man_by")
        ComboBoxEntryBinding(self.obj("combobox_man_hq"), self.app.config, "general", "cut_hqs_man_by")
        ComboBoxEntryBinding(self.obj("combobox_man_hd2"), self.app.config, "general", "cut_hd2_man_by")
        ComboBoxEntryBinding(self.obj("combobox_man_mp4"), self.app.config, "general", "cut_mp4s_man_by")
        ComboBoxEntryBinding(self.obj("h264_codec_cbox"), self.app.config, "general", "h264_codec")
        ComboBoxEntryBinding(self.obj("combobox_ac3"), self.app.config, "general", "merge_ac3s_by")
        CheckButtonBinding(self.obj("check_merge_ac3"), self.app.config, "general", "merge_ac3s")
        ComboBoxEntryBinding(
            self.obj("smkv_first_audio"),
            self.app.config,
            "smartmkvmerge",
            "first_audio_stream",
            data=["normalize_audio", self.obj("check_normalize_audio")],
        )
        ComboBoxEntryBinding(
            self.obj("smkv_second_audio"),
            self.app.config,
            "smartmkvmerge",
            "second_audio_stream",
            data=["normalize_audio", self.obj("check_normalize_audio")],
        )
        EntryBinding(self.obj("smkv_workingdir"), self.app.config, "smartmkvmerge", "workingdir")
        CheckButtonBinding(
            self.obj("check_normalize_audio"), self.app.config, "smartmkvmerge", "normalize_audio",
        )
        CheckButtonBinding(self.obj("smkv_mp4"), self.app.config, "smartmkvmerge", "remux_to_mp4")
        ComboBoxEntryBinding(
            self.obj("encoder_engine"), self.app.config, "smartmkvmerge", "encoder_engine",
        )

        # 4 Cutlist
        EntryBinding(self.obj("entry_server"), self.app.config, "general", "server")
        RadioButtonsBinding(
            [self.obj(widget) for widget in ["radio_size", "radio_filename"]],
            self.app.config,
            "general",
            "choose_cutlists_by",
        )
        CheckButtonBinding(
            self.obj("check_delete_cutlists"), self.app.config, "general", "delete_cutlists",
        )
        EntryBinding(
            self.obj("entry_cutlist_username"), self.app.config, "general", "cutlist_username",
        )
        CheckButtonBinding(
            self.obj("check_mplayer_fullscreen"), self.app.config, "general", "mplayer_fullscreen",
        )
        CheckButtonBinding(
            self.obj("check_prefer_mplayer"), self.app.config, "general", "prefer_mplayer",
        )
        CheckButtonBinding(
            self.obj("check_ignore_suggested"), self.app.config, "general", "ignore_suggested_filename",
        )
        EntryBinding(
            self.obj("entry_cutlist_comment"), self.app.config, "general", "cutlist_comment",
        )
        TextbufferBinding(
            self.obj("txtbuf_snippets"), self.app.config, "general", "snippets", self.obj,
        )

        # 5 Umbenennen
        CheckButtonBinding(self.obj("check_rename_cut"), self.app.config, "general", "rename_cut")
        EntryBinding(self.obj("entry_schema"), self.app.config, "general", "rename_schema")

        # 6 Hauptfenster
        SpinbuttonBinding(self.obj("spinbutton_iconsize"), self.app.config, "general", "icon_size")
        CheckButtonBinding(
            self.obj("check_use_internal_icons"), self.app.config, "general", "use_internal_icons",
        )
        CheckButtonBinding(
            self.obj("check_hide_archive_buttons"), self.app.config, "general", "hide_archive_buttons",
        )
        CheckButtonBinding(
            self.obj("check_sort_record_date"), self.app.config, "general", "sort_record_date",
        )
        ComboBoxEntryBinding(
            self.obj("entry_cut_default"), self.app.config, "general", "cut_action", data=["cut_default"],
        )
        CheckButtonBinding(
            self.obj("check_show_conclusiondialog_after_cutting"),
            self.app.config,
            "general",
            "show_conclusiondialog_after_cutting",
        )

        # 7 Cutinterface
        SpinbuttonBinding(
            self.obj("spinbtn_seeker"), self.app.config, "cutinterface", "seek_distance_default",
        )
        SpinbuttonBinding(self.obj("spinbtn_seek1"), self.app.config, "cutinterface", "seek1")
        SpinbuttonBinding(self.obj("spinbtn_seek2"), self.app.config, "cutinterface", "seek2")
        SpinbuttonBinding(self.obj("spinbutton_x"), self.app.config, "cutinterface", "resolution_x")
        SpinbuttonBinding(self.obj("spinbutton_y"), self.app.config, "cutinterface", "resolution_y")
        CheckButtonBinding(self.obj("check_vol_adjust_on"), self.app.config, "general", "vol_adjust_on")
        EntryBinding(self.obj("entry_vol_adjust"), self.app.config, "general", "vol_adjust")
        CheckButtonBinding(
            self.obj("check_alt_time_frame_conv"), self.app.config, "cutinterface", "alt_time_frame_conv",
        ),
        SpinbuttonBinding(
            self.obj("spinbutton_test_cut_offset_secs"), self.app.config, "cutinterface", "test_cut_offset_secs",
        )
        CheckButtonBinding(
            self.obj("check_autosearch_cutlist"), self.app.config, "cutinterface", "autosearch_cutlist",
        )
        CheckButtonBinding(
            self.obj("check_show_tooltips"), self.app.config, "cutinterface", "show_tooltips",
        )
        CheckButtonBinding(
            self.obj("check_mouse_hide_over_video"), self.app.config, "cutinterface", "mouse_hide_over_video",
        )
        CheckButtonBinding(
            self.obj("check_scrolling_inverted"), self.app.config, "cutinterface", "scrolling_inverted",
        )

        CheckButtonBinding(
            self.obj("check_not_force_search_cutlist_by_name"),
            self.app.config,
            "cutinterface",
            "not_force_search_cutlist_by_name",
        )

        # 8 Programme
        for prog in [
            "ffmpeg",
            "ffprobe",
            "ffmsindex",
            "x264",
            "mediainfo",
            "mkvmerge",
            "mpv",
            "vdub",
        ]:
            EntryBinding(self.obj("entry_prog_" + prog), self.app.config, "programs", prog)
        EntryBinding(
            self.obj("entry_prog_wineprefix"), self.app.config, "programs", "wineprefix",
        )

        def rename_schema_changed(value):
            new_name = self.app.rename_by_schema(self.example_cut_filename, value)
            self.obj("label_schema").set_label(f"{self.example_filename} wird zu {new_name}")

        if not self.app.config.keyring_available:
            self.obj("radioPasswdStoreWallet").set_sensitive(False)

        self.app.config.connect("general", "rename_schema", rename_schema_changed)
        # "initial rename"
        # remove?
        # rename_schema_changed(self.obj('entry_schema').get_text())

        for option in [
            "folder_new_otrkeys",
            "folder_trash_otrkeys",
            "folder_trash_avis",
            "folder_uncut_avis",
            "folder_cut_avis",
            "folder_archive",
        ]:
            self.app.config.connect("general", option, lambda value: self.app.show_section(self.app.section))

        self.app.config.connect(
            "general", "rename_cut", lambda value: self.obj("entry_schema").set_sensitive(value),
        )
        self.app.config.connect(
            "general", "merge_ac3s", lambda value: self.obj("combobox_ac3").set_sensitive(value),
        )
        self.app.config.connect(
            "general", "merge_ac3s", lambda value: self.obj("button_set_file_ac3").set_sensitive(value),
        )
        self.app.config.connect(
            "general", "merge_ac3s", lambda value: self.obj("label_ac3").set_sensitive(value),
        )
        self.app.config.connect(
            "general", "use_internal_icons", lambda value: self.obj("label_iconsize").set_sensitive(not value),
        )
        self.app.config.connect(
            "general", "use_internal_icons", lambda value: self.obj("spinbutton_iconsize").set_sensitive(not value),
        )
        self.app.config.connect(
            "general", "passwd_store", lambda value: self._radio_passwd_store_toggled(value),
        )

        # Initializing
        self.obj("entry_password").set_visibility(False)
        self.obj("entry_schema").set_sensitive(self.app.config.get("general", "rename_cut"))
        self.obj("combobox_ac3").set_sensitive(self.app.config.get("general", "merge_ac3s"))
        self.obj("label_iconsize").set_sensitive(not self.obj("check_use_internal_icons").get_active())
        self.obj("spinbutton_iconsize").set_sensitive(not self.obj("check_use_internal_icons").get_active())
        self._radio_passwd_store_toggled(self.app.config.get("general", "passwd_store"))

        # Show normalize_audio only if audio conversion to AAC is chosen
        first = "AAC" in self.app.config.get("smartmkvmerge", "first_audio_stream")
        second = "AAC" in self.app.config.get("smartmkvmerge", "second_audio_stream")
        if first or second:
            self.obj("check_normalize_audio").set_sensitive(True)
        else:
            self.obj("check_normalize_audio").set_sensitive(False)

        # Delete combobox entries "intern-vdub" if not installed and "vdub.exe" if not on Windows
        intern_vdub_available = False
        vdubexe_available = False
        if sys.platform == "linux":
            if otrvpath.get_internal_virtualdub_path("vdub.exe") is not None:
                intern_vdub_available = True
        elif sys.platform == "win32":
            vdub = self.app.config.get_program("vdub")
            if os.path.exists(vdub) and vdub.endswith(vdub.exe):
                vdubexe_available = True

        for widget_name in [
            "combobox_avi",
            "combobox_hq",
            "combobox_hd2",
            "combobox_mp4",
        ]:
            if not intern_vdub_available:
                self.obj(widget_name).remove(1)
            if not vdubexe_available:
                self.obj(widget_name).remove(2)

        # Hide some fields in tab "Programme"
        progs2 = ["wineprefix"]
        if sys.platform == "linux":
            progs2.append("vdub")
        for prog in progs2:
            for prefix in ["lbl_prog_", "entry_prog_", "btn_prog_", "lbl_check_"]:
                self.obj(prefix + prog).set_visible(False)

    # Signal handlers ###

    def on_entry_prog_changed(self, entry):
        entry_name = Gtk.Buildable.get_name(entry)
        prog_name = entry_name.rpartition("_")[2]  # name scheme is entry_prog_ffmpeg
        lbl_check = self.obj("lbl_check_" + prog_name)
        if os.path.exists(entry.get_text()):
            lbl_check.set_markup("âœ“")
        else:
            lbl_check.set_markup("âœ˜")
        return False

    def _on_btn_snippets_save_clicked(self, txtbuf):
        self.app.config.set("general", "snippets", txtbuf.props.text)
        self.obj("btn_snippets_save").set_sensitive(False)

    def _radio_passwd_store_toggled(self, value):
        if value == 2:  # radioPasswdStoreNot
            self.obj("check_passwd_store_memory").set_sensitive(True)
            self.obj("labelPasswdStoreMemory").set_sensitive(True)
            self.obj("entry_password").set_sensitive(False)
        else:
            self.obj("check_passwd_store_memory").set_sensitive(False)
            self.obj("labelPasswdStoreMemory").set_sensitive(False)
            self.obj("entry_password").set_sensitive(True)

    def _on_button_reset_size_moviewindow_clicked(self, widget):
        self.obj("spinbutton_x").set_value(800.0)
        self.obj("spinbutton_y").set_value(450.0)

    def _on_button_check_otr_credentials_clicked(self, entry):
        request_answer = ""
        if self.app.config.get("general", "password") != "" and internet_on():
            url = "http://www.onlinetvrecorder.com/webrecording/isuser.php"
            params = {
                "email": self.app.config.get("general", "email"),
                "pass": hashlib.md5(self.app.config.get("general", "password").encode("utf-8")).hexdigest(),
            }
            r = requests.get(url=url, params=params)
            request_answer = r.text
        if internet_on():
            if "yes" in request_answer:
                self.obj("checkOTRCredentials").modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse("#008000"))
                self.obj("OTRCredentialCheckResponse").set_markup("âœ“")
            else:
                self.obj("checkOTRCredentials").modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse("#c70002"))
                self.obj("OTRCredentialCheckResponse").set_markup("âœ˜")
        else:
            self.obj("checkOTRCredentials").modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse("#d87107"))
            self.obj("OTRCredentialCheckResponse").set_markup("ðŸ–§ Keine Internetverbindung!")

    def _on_button_set_file_clicked(self, entry, data=None):
        entry_name = Gtk.Buildable.get_name(entry)
        try:
            chooser_title = self.filechooser_title_setup[entry_name] + ":"
        except KeyError:
            chooser_title = "Datei auswÃ¤hlen:"

        if entry_name.startswith("entry_prog") or entry_name.startswith("combobox_"):
            chooser_action = Gtk.FileChooserAction.OPEN
        else:
            chooser_action = Gtk.FileChooserAction.SELECT_FOLDER

        chooser = Gtk.FileChooserDialog(
            title=chooser_title,
            parent=self,
            action=chooser_action,
            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK,),
        )
        chooser.set_transient_for(self)
        if isinstance(entry, Gtk.Entry):
            if entry_name.startswith("entry_prog"):
                self.last_path = None
            if os.path.exists(entry.get_text()) and self.last_path is None:
                chooser.set_current_folder(os.path.join(entry.get_text(), ".."))
            elif self.last_path is not None:
                chooser.set_current_folder(os.path.join(self.last_path, ".."))
            else:
                chooser.set_current_folder(os.path.expanduser("~"))

        if chooser.run() == Gtk.ResponseType.OK:
            if isinstance(entry, Gtk.ComboBoxText):
                entry.prepend(chooser.get_filename(), chooser.get_filename())
                entry.set_active(0)
            elif isinstance(entry, Gtk.Entry):
                entry.set_text(chooser.get_filename())
                self.last_path = entry.get_text()

        chooser.destroy()

    def _on_entry_prog_decoder_changed(self, widget, data=None):
        if "otrtool" in widget.get_active_text():
            self.obj("check_verify_decoded").set_sensitive(False)
        else:
            self.obj("check_verify_decoded").set_sensitive(True)

    def on_preferences_window_key_press_event(self, widget, event):
        keyname = Gdk.keyval_name(event.keyval).upper()
        if event.type == Gdk.EventType.KEY_PRESS:
            if keyname == "ESCAPE":
                self._on_preferences_button_close_clicked(None)
                return True

    def _on_preferences_button_close_clicked(self, widget, data=None):
        if self.obj("btn_snippets_save").get_sensitive():
            if not self.app.gui.question_box(
                "Die Snippets wurden nicht gespeichert\n\nWollen Sie das Fenster wirklich schlieÃŸen?"
            ):
                return
        self.hide()
        self.app.gui.start_directory_monitors(restart=True)
        self.app.show_section(self.app.section)
        try:
            # Update settings in Cutinterface
            self.app.gui.ci_instance.config_update()
        except AttributeError:
            pass

    def _on_preferences_window_delete_event(self, window, event):
        self._on_preferences_button_close_clicked(None)
        return True

def new():
    glade_filename = otrvpath.getdatapath("ui", "PreferencesWindow.glade")
    builder = Gtk.Builder()
    builder.add_from_file(glade_filename)
    window = builder.get_object("preferences_window")
    # window.app = app
    # window.gui = gui
    return window

def internet_on():
    # Check if online
    try:
        # google.com ip
        urllib2.urlopen("http://216.58.192.142", timeout=1)
        return True
    except urllib2.URLError:
        return False


import json
from textbook_exchange.models import Textbook, Class
from unidecode import unidecode
import os

#keep this script in main directory (with manage.py) for this path to work;
#else, you can update with your own path as needed
script_dir = os.path.dirname("__file__")
rel_path = "class_data.json"
abs_file_path = os.path.join(script_dir, rel_path)

def mkflt(str_in):
    if str_in:
        return float(str_in)
    else:
        return 0

def mkint(str_in):
    if str_in:
        return int(str_in)
    else:
        return 0

def u_ify(book):
    book['Title'] = unidecode(book['Title'])
    book['Author'] = unidecode(str(book['Author']))
    return book

with open(abs_file_path, encoding='utf-8') as data_file:
    json_data = json.loads(data_file.read())

    for book_data in json_data:
        book_data = u_ify(book_data)

        try:
            class_obj = Class.objects.get(class_info=book_data['Dept']+book_data['Course']+"-"+book_data['Sect'])
            setattr(class_obj, "class_term", book_data['Term'])
            setattr(class_obj, "department", book_data['Dept'])
            setattr(class_obj, "course_code", book_data['Course'])
            setattr(class_obj, "section_number", book_data['Sect'])
            setattr(class_obj, "professor", book_data['Instructor'])
            setattr(class_obj, 'class_title', book_data['ClassTitle'])
            class_obj.save()
        except:
            class_obj = Class.create(**book_data)

        lower_title=book_data['Title'].lower()
        if "inclusive access" not in lower_title and "ebook" not in lower_title and "access card" not in lower_title and "access code" not in lower_title and "websam" not in lower_title:
            try:
                book_obj = Textbook.objects.get(bookstore_isbn=book_data['ISBN'])
                setattr(book_obj, "isbn13", book_data['ISBN13'])
                setattr(book_obj, "isbn10", book_data['ISBN10'])
                setattr(book_obj, "title", unidecode(book_data['Title']))
                setattr(book_obj, "author", unidecode(str(book_data['Author'])))
                setattr(book_obj, "req_type", book_data['Req Type'])
                setattr(book_obj, "cover_photo_url", book_data['Image Links'])
                setattr(book_obj, "bookstore_new_price", float(book_data['New'].replace('$', '').strip()))
                setattr(book_obj, "bookstore_used_price", float(book_data['Used'].replace('$', '').strip()))
                setattr(book_obj, "publisher", book_data['Publisher'])
                setattr(book_obj, "date", book_data['Publish Year'])
                setattr(book_obj, "description", book_data['Description'])
                setattr(book_obj, "page_count", mkint(book_data['Page Count']))
                setattr(book_obj, "google_rating", mkflt(book_data['Google Rating']))
                setattr(book_obj, "num_reviews", mkint(book_data['Number of Ratings']))
                book_obj.save()
            except:
                book_obj = Textbook.create(**book_data)

            book_obj.class_objects.add(class_obj)


import os
import sys
import argparse
import configparser

def environment(
        arg_parser: argparse.ArgumentParser
) -> tuple:
    """Return args, config section, and common properties such as name of ffmpeg executable"""
    arg_parser.add_argument('--ffmpeg', help='path to ffmpeg executable')
    args = arg_parser.parse_args(sys.argv[1:])
    config_parser = configparser.ConfigParser()
    config_parser.read(os.path.expanduser('~/.whimsical_recipes'))
    config = config_parser['GoPro Dual Hero3'] if 'GoPro Dual Hero3' in config_parser else dict()
    ffmpeg = config.get('Ffmpeg', 'ffmpeg') if args.ffmpeg is None else args.ffmpeg
    return args, config, dict(ffmpeg=ffmpeg)

def ask_go(
        target: str,
        replace_default: str
) -> tuple:
    """Ask user whether to override existing target file"""
    if os.path.exists(target):
        if replace_default is None:
            replace = None
            while replace not in ('y', 'Y', 'n', 'N'):
                replace = input('Replace [y|Y|n|N] ? ')
                if replace == 'y':
                    go = True
                if replace == 'Y':
                    go = True
                    replace_default = True
                if replace == 'n':
                    go = False
                if replace == 'N':
                    go = False
                    replace_default = False
        else:
            go = replace_default
    else:
        go = True
    return go, replace_default


from django.conf.urls import url

from .views import (
    SoldItemListAPIView,
    ItemListAPIView,
    SaleMarginListAPIView
    )

urlpatterns = [
    url(r'^$', SoldItemListAPIView.as_view(),
        name='list-sales'),
    url(r'^margin/', SaleMarginListAPIView.as_view(),
        name='sale-margin'),
    url(r'^items/(?P<pk>[0-9]+)/$', ItemListAPIView.as_view(),
        name='list-sold-items'),
]


import os
import math
import linecache
import numpy as np
from typing import Dict

from .outfermi import OutFermi

class Report(object):
    COLUMN_PER_LINE = 5 # REPORT中每行出现几个 eigen energies

    def __init__(self, report_path:str):
        self.report_path = report_path

    def _search_aim(self, aim_content:str):
        '''
        Description
        -----------
            1. 查询REPORT文件中是否存在特定的内容(aim_content)，并确定所在的行数

        Parameters
        ----------
            1. aim_content: str
                - 特定的内容

        Return
        ------
            1. idxs_lst: List[int]
        '''
        with open(self.report_path, "r") as f:
            lines_lst = f.readlines()

        idxs_lst = []
        for tmp_idx, tmp_line in enumerate(lines_lst, 1):
            if aim_content in tmp_line:
                idxs_lst.append(tmp_idx)

        return idxs_lst

    def get_num_bands(self):
        '''
        Description
        -----------
            1. 得到能带数 (每个kpoint的本征态)

        Return
        ------
            1. num_bands: int
                - 能带的数目
        '''
        ### Step 1. 查询得到 `NUM_BAND` 所在的行
        aim_content = "NUM_BAND"
        idx_num_bands = self._search_aim(aim_content=aim_content)[0]
        #print(idx_num_bands)
        ### Step 2. 提取能带的数目
        specific_line = linecache.getline(self.report_path, idx_num_bands)
        num_bands = int( specific_line.split()[-1] )

        return num_bands

    def get_num_kpts(self):
        '''
        Description
        -----------
            1. 得到Kpoint的数目

        Return
        ------
            1. num_kpts: int
                - kpoints 的数目
        '''
        ### Step 1. 查询得到 `NUM_KPT` 所在的行
        aim_content = "NUM_KPT"
        idx_num_kpts = self._search_aim(aim_content=aim_content)[0]

        ### Step 2. 提取kpoints的数目
        specific_line = linecache.getline(self.report_path, idx_num_kpts)
        num_kpts = int( specific_line.split()[-1] )

        return num_kpts

    def get_eigen_energies(self):
        '''
        Description
        -----------
            1. 得到的本征值未减去费米能级

        Return
        ------
            1. spin2eigen_energies: Dict[str, np.ndarray]
                - np.ndarray 一维: kpoint
                - np.ndarray 二维: 某kpoint的本征能量
        '''
        ### Step 1.
        ###     1. 初始化 `spin2eigen_energies`
        ###     2. 得到kpoints的数目 `num_kpts`
        ###     3. 得到bands的数目 `num_bands`
        ###     4. 得到 `idx_eigen_start_lst`
        spin2eigen_energies = {"up":[], "down":[]}
        num_kpts = self.get_num_kpts()
        num_bands = self.get_num_bands()
        aim_content_eigen = "eigen energies, in eV"
        idxs_eigen_start_lst = self._search_aim(
                                aim_content=aim_content_eigen)

        ### Step 2. 读取 REPORT 文件
        with open(self.report_path, "r") as f:
            lines_lst = f.readlines()

        ### Step 3. 得到每个kpoint的本征能量
        num_lines_for_band = int( np.ceil(num_bands / self.COLUMN_PER_LINE) )
        for tmp_idx, tmp_idx_eigen_start in enumerate(idxs_eigen_start_lst):
            tmp_eigen_energies_ = lines_lst[tmp_idx_eigen_start : tmp_idx_eigen_start+num_lines_for_band]
            tmp_eigen_energies = [float(eigen) for tmp_5_eigen in tmp_eigen_energies_ for eigen in tmp_5_eigen.split()]
            tmp_eigen_energies_array = np.array( tmp_eigen_energies )

            if tmp_idx < num_kpts:
                spin2eigen_energies["up"].append(tmp_eigen_energies_array)
            else:
                spin2eigen_energies["down"].append(tmp_eigen_energies_array)

        ### Step 4. 将 spin2igen_energies 的 values 变为 np.ndarray 形式
        spin2eigen_energies.update(
                        {"up": np.array( spin2eigen_energies["up"] )}
                        )
        spin2eigen_energies.update(
                        {"down": np.array( spin2eigen_energies["down"] )}
                        )

        ### Step 5. 当 ispin 打开时，自旋向上和向下的(kpoints, eigen_states)应该相等
        if spin2eigen_energies["down"].size != 0:
            assert (spin2eigen_energies["up"].shape != spin2eigen_energies["down"])

        return spin2eigen_energies

    def get_in_atom(self):
        '''
        Description
        -----------
            1. 得到输入的结构

        Return
        ------
            1. in_atom_name: str
                - basename
                - e.g. "atom.config"
        '''
        aim_conetent_inatom = "IN.ATOM"
        idx_inatom = self._search_aim(aim_content=aim_conetent_inatom)[0]
        in_atom_name = linecache.getline(self.report_path, idx_inatom).split()[-1]

        return in_atom_name

    def _is_metal(self,
                out_fermi_path:str,
                efermi_tol:float=1e-4,
                ):
        '''
        Description
        -----------
            1. Check if the bandstructure indicates a metal by looking if the fermi
            level crosses a band.

        Parameters
        ----------
            1. out_fermi_path: str
                - OUT.FERMI 的路径
            2. efermi_tol: float
                - The tolerance of fermi level

        Return
        ------
            1. mark: bool
                - True: 是金属
                - False: 不是金属
        '''
        ### Step 1. 得到费米能级
        ### Step 1.1. 判断是否存在 OUT.FERMI 文件
        if not os.path.exists(out_fermi_path):
            raise("当前目录下不存在 OUT.FERMI 文件，无法读取费米能级！")
        ### Step 1.2. 从 OUT.FERMI 中读取费米能级
        out_fermi_object = OutFermi(out_fermi_path=out_fermi_path)
        efermi_ev = out_fermi_object.get_efermi()

        ### Step 2. 判断是否有能带穿过费米能级 (check if the fermi level crosses a band)
        spin2eigen_energies:Dict[str, np.ndarray] = self.get_eigen_energies()
        for tmp_spin in list( spin2eigen_energies.keys() ): # ["up", "down"]
            ### engen_energies_T
            ###     - 一维：
            ###     - 二维：
            eigen_energis_T = spin2eigen_energies[tmp_spin].T
            for idx_band in range(eigen_energis_T.shape[0]):
                if np.any(eigen_energis_T[idx_band, :] - efermi_ev < -efermi_tol) and \
                    np.any(eigen_energis_T[idx_band, :] - efermi_ev > efermi_tol):
                    return True
        return False

    def get_cbm(self, out_fermi_path:str):
        '''
        Description
        -----------
            1. 得到导带顶的 idx_kpt, idx_band, idx_spin, energy

        Return
        ------
            1. Union[Dict, None]
            2. cbm_dict: { "energies": List[float], "spins": List[str], "kpts": List[int], bands: List[int] }
                - "energies":
                - "spins":
                - "kpts":
                - "bands":
                - 是列表形式，因为有时候会共享 cbm
                - e.g.  {'energies': [-0.3426], 'kpts': [19], 'bands': [53], 'spins': ['up']}
            3. 当体系是金属的时候返回 None

        Note
        ----
            1. idx_kpt 与 idx_band 均是从 1 开始的 (REPORT的输出信息就是从 1 开始的)
        '''
        ### Step 1. 判断体系是否是半导体
        if self._is_metal(out_fermi_path=out_fermi_path):
            #print("本材料体系是金属")
            #raise SystemExit
            return None

        ### Step 2. 得到体系的费米能级
        out_fermi_object = OutFermi(out_fermi_path=out_fermi_path)
        efermi_ev = out_fermi_object.get_efermi()

        ### Step 3. 得到本征能量
        spin2eigen_energies:Dict[str, np.ndarray] = self.get_eigen_energies()

        ### Step 4. 找到 cbm 的能量、自旋、kpoint、能带
        cbm_energy = float("inf")   # energy
        cbm_kpt = 0     # kpoints 的索引
        cbm_band = 0    # band 的索引
        cbm_spin = None # 自旋: Optional["up"|"down"]
        for tmp_spin in list( spin2eigen_energies.keys() ): # ["up", "down"]
            for idx_row, idx_col in zip( *np.where(spin2eigen_energies[tmp_spin] >= efermi_ev) ):
                # idx_row:index for kpoints ; idx_col: index for band
                if spin2eigen_energies[tmp_spin][idx_row][idx_col] < cbm_energy:
                    cbm_energy = round( float(spin2eigen_energies[tmp_spin][idx_row][idx_col]), 4)
                    cbm_kpt = idx_row + 1
                    cbm_band = idx_col + 1
                    cbm_spin = tmp_spin

        ### Step 5. Get all other band sharing the cbm
        cbm_dict = {
                "energies": [cbm_energy],
                "kpts": [cbm_kpt],
                "bands": [cbm_band],
                "spins": [cbm_spin],
        }
        for tmp_spin in list( spin2eigen_energies.keys() ):
            for idx_band in range(spin2eigen_energies["up"].shape[1]):
                try:
                    if math.fabs( spin2eigen_energies[tmp_spin][cbm_kpt][idx_band] - cbm_energy) < 0.001:
                        cbm_dict["energies"].append(cbm_energy)
                        cbm_dict["kpts"].append(cbm_kpt)
                        cbm_dict["bands"].append(idx_band + 1)
                        cbm_dict["spins"].append(tmp_spin)
                except: # spin2eigen_energies["down"] 为空时，会触发 `IndexError`
                    pass

        return cbm_dict

    def get_vbm(self, out_fermi_path:str):
        '''
        Description
        -----------
            1. 得到半导体的vbm

        Return
        ------
            1. Union[Dict, None]
            2. vbm_dict: Dict
                - e.g. {'energies': [-1.9866], 'kpts': [29], 'bands': [52], 'spins': ['up']}
            3. 当体系是金属的时候返回 None
        '''
        ### Step 1. 判断体系是否是半导体
        if self._is_metal(out_fermi_path=out_fermi_path):
            #print("本材料体系是金属")
            #raise SystemExit
            return None

        ### Step 2. 得到体系的费米能级
        out_fermi_object = OutFermi(out_fermi_path=out_fermi_path)
        efermi_ev = out_fermi_object.get_efermi()

        ### Step 3. 得到本征能量
        spin2eigen_energies:Dict[str, np.ndarray] = self.get_eigen_energies()

        ### Step 4. 得到 vbm 的能量、自旋、kpoint、能带
        vbm_energy = -float("inf")
        vbm_kpt = 0
        vbm_band = 0
        vbm_spin = None
        for tmp_spin in list( spin2eigen_energies.keys() ):
            for idx_row, idx_col in zip( *np.where(spin2eigen_energies[tmp_spin] <= efermi_ev) ):
                # idx_row:indx of kpoints ; idx_col: index of band
                if spin2eigen_energies[tmp_spin][idx_row][idx_col] > vbm_energy:
                    vbm_energy = round( float(spin2eigen_energies[tmp_spin][idx_row][idx_col]), 4 )
                    vbm_kpt = idx_row + 1
                    vbm_band = idx_col + 1
                    vbm_spin = tmp_spin

        ### Step 5. Get all othr band sharing the vbm
        vbm_dict = {
            "energies": [vbm_energy],
            "kpts": [vbm_kpt],
            "bands": [vbm_band],
            "spins": [vbm_spin],
        }
        for tmp_spin in list( spin2eigen_energies.keys() ):
            for idx_band in range(spin2eigen_energies["up"].shape[1]):
                try:
                    if math.fabs( spin2eigen_energies[tmp_spin][vbm_kpt][idx_band] - vbm_energy) < 0.001:
                        vbm_dict["energies"].append(vbm_energy)
                        vbm_dict["spins"].append(tmp_spin)
                        vbm_dict["bands"].append(idx_band)
                        vbm_dict["kpts"].append(vbm_kpt)
                except: # spin2eigen_energies["down"] 为空时，会触发 `IndexError`
                    pass

        return vbm_dict

    def get_bandgap(self, out_fermi_path:str):
        '''
        Description
        -----------
            1. 得到 bandgap

        Paramter
        --------
            1. out_fermi_path: str
                - OUT.FERMI 的绝对路径

        Return
        ------
            1. bandgap: float
                - unit: eV
        '''
        ### Step 1. 得到 CBM 和 VBM
        ### (在 `self.get_cbm()`` 和 `self.get_vbm()` 中判断是金属 or 半导体)
        vbm_dict = self.get_vbm(out_fermi_path=out_fermi_path)
        cbm_dict = self.get_cbm(out_fermi_path=out_fermi_path)

        ### Step 2. 得到带隙的大小
        bandgap = cbm_dict["energies"][0] - vbm_dict["energies"][0]

        return bandgap

    def get_bandgap_type(self, out_fermi_path:str):
        '''
        Description
        -----------
            1. 得到带隙类型

        Return
        ------
            1. int:
                - 0: 间接带隙
                - 1: 直接带隙
        '''
        ### Step 1. 得到 CBM 和 VBM
        ### (在 `self.get_cbm()`` 和 `self.get_vbm()` 中判断是金属 or 半导体)
        vbm_dict = self.get_vbm(out_fermi_path=out_fermi_path)
        cbm_dict = self.get_cbm(out_fermi_path=out_fermi_path)

        ### Step 2. 得到带的类型
        intersection, idx_1_lst, idx_2_lst = np.intersect1d(
                                                vbm_dict["kpts"],
                                                cbm_dict["kpts"],
                                                return_indices=True,
                                                )

        if intersection.size == 0:
            return 0    # 间接带隙
        else:
            return 1    # 直接带隙


# Created by Dennis Willsch (d.willsch@fz-juelich.de)
# Modified by Gabriele Cavallaro (g.cavallaro@fz-juelich.de)
#         and Madita Willsch (m.willsch@fz-juelich.de)

import sys
import re
import json
import os
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as cols
from sklearn.metrics import roc_auc_score,average_precision_score,precision_recall_curve,roc_curve,accuracy_score,auc

np.set_printoptions(precision=4, suppress=True)

def kernel(xn, xm, gamma=-1): # here (xn.shape: NxD, xm.shape: ...xD) -> Nx...
    if gamma == -1:
        return xn @ xm.T
    xn = np.atleast_2d(xn)
    xm = np.atleast_2d(xm)
    return np.exp(-gamma * np.sum((xn[:,None] - xm[None,:])**2, axis=-1)) # (N,1,D) - (1,...,D) -> (N,...,D) -> (N,...); see Hsu guide.pdf for formula

# B = base
# K = number of qubits per alpha
# E = shift of exponent
# decode binary -> alpha
def decode(binary, B=10, K=3, E=0):
    N = len(binary) // K
    Bvec = float(B) ** (np.arange(K)-E)
    return np.fromiter(binary,float).reshape(N,K) @ Bvec

# encode alpha -> binary with B and K (for each n, the binary coefficients an,k such that sum_k an,k B**k is closest to alphan)
def encode(alphas, B=10, K=3, E=0): # E allows for encodings with floating point numbers (limited precision of course)
    N = len(alphas)
    Bvec = float(B) ** (np.arange(K)-E) # B^(0-E) B^(1-E) B^(2-E) ... B^(K-1-E)
    allvals = np.array(list(map(lambda n : np.fromiter(bin(n)[2:].zfill(K),float,K), range(2**K)))) @ Bvec # [[0,0,0],[0,0,1],...] @ [1, 10, 100]
    return ''.join(list(map(lambda n : bin(n)[2:].zfill(K),np.argmin(np.abs(allvals[:,None] - alphas), axis=0))))

def encode_as_vec(alphas, B=10, K=3, E=0):
    return np.fromiter(encode(alphas,B,K,E), float)

def loaddataset(datakey):
    dataset = np.loadtxt(datakey, dtype=float, skiprows=1)
    return dataset[:,2:], dataset[:,1]  # data, labels

def save_json(filename, var):
    with open(filename,'w') as f:
        f.write(str(json.dumps(var, indent=4, sort_keys=True, separators=(',', ': '), ensure_ascii=False)))

def eval_classifier(x, alphas, data, label, gamma, b=0): # evaluates the distance to the hyper plane according to 16.5.32 on p. 891 (Numerical Recipes); sign is the assigned class; x.shape = ...xD
    return np.sum((alphas * label)[:,None] * kernel(data, x, gamma), axis=0) + b

def eval_on_sv(x, alphas, data, label, gamma, C):
    return np.sum((alphas * (C-alphas) * label)[:,None] * kernel(data, x, gamma), axis=0)

def eval_offset_search(alphas, data, label, gamma, C, useavgforb=True): # search for the best offset
    maxacc=0
    b1=-9
    for i in np.linspace(-9,9,500):
        acc = accuracy_score(label,np.sign(eval_classifier(data, alphas, data, label, gamma, i)))
        if acc > maxacc:
            maxacc = acc
            b1=i
    maxacc=0
    b2=9
    reversed_space=np.linspace(-9,9,500)[::-1]
    for i in reversed_space:
        acc = accuracy_score(label,np.sign(eval_classifier(data, alphas, data, label, gamma, i)))
        if acc > maxacc:
            maxacc = acc
            b2=i
    return (b1+b2)/2

def eval_offset_MM(alphas, data, label, gamma, C, useavgforb=True): # evaluates offset b according to 16.5.37 (Mangasarian-Musicant variant) NOTE: does not seem to work with integer/very coarsely spaced alpha!
    return np.sum(alphas*label)

def eval_offset_avg(alphas, data, label, gamma, C, useavgforb=True): # evaluates offset b according to 16.5.33
    cross = eval_classifier(data, alphas, data, label, gamma) # cross[i] = sum_j aj yj K(xj, xi) (error in Numerical Recipes)
    if useavgforb:
        return np.sum(alphas * (C-alphas) * (label - cross)) / np.sum(alphas * (C-alphas))
        #return np.sum(label - cross) / num_sv
    else:  # this is actually not used, but we did a similar-in-spirit implementation in eval_finaltraining_avgscore.py
        if np.isclose(np.sum(alphas * (C-alphas)),0):
            print('no support vectors found, discarding this classifer')
            return np.nan
        bcandidates = [np.sum(alphas * (C-alphas) * (label - cross)) / np.sum(alphas * (C-alphas))]  # average according to NR should be the first candidate
        crosssorted = np.sort(cross)
        crosscandidates = -(crosssorted[1:] + crosssorted[:-1])/2  # each value between f(xi) and the next higher f(xj) is a candidate
        bcandidates += sorted(crosscandidates, key=lambda x:abs(x - bcandidates[0]))  # try candidates closest to the average first
        bnumcorrect = [(label == np.sign(cross + b)).sum() for b in bcandidates]
        return bcandidates[np.argmax(bnumcorrect)]

def eval_acc_auroc_auprc(label, score):  # score is the distance to the hyper plane (output from eval_classifier)
    precision,recall,_ = precision_recall_curve(label, score)
    return accuracy_score(label,np.sign(score)), roc_auc_score(label,score), auc(recall,precision)

################ This I/O functions are provided by http://hyperlabelme.uv.es/index.html ################

def dataread(filename):
    lasttag = 'description:'
    # Open file and locate lasttag
    f = open(filename, 'r')
    nl = 1
    for line in f:
        if line.startswith(lasttag): break
        nl += 1
    f.close()

    # Read data
    data = np.loadtxt(filename, delimiter=',', skiprows=nl)
    Y = data[:, 0]
    X = data[:, 1:]
    # Separate train/test
    Xtest = X[Y < 0, :]
    X = X[Y >= 0, :]
    Y = Y[Y >= 0, None]

    return X, Y, Xtest

def datawrite(path,method, dataset, Yp):
    filename = '{0}{1}_predictions.txt'.format(path, dataset)
    res = True
    try:
        with open(filename, mode='w') as f:
            f.write('{0} {1}'.format(method, dataset))
            for v in Yp:
                f.write(' {0}'.format(str(v)))
            f.write('\n')
    except Exception as e:
        print('Error', e)
        res = False
    return res

################

def write_samples(X, Y,path):
    f = open(path,"w")
    f.write("id label data \n")
    for i in range(0,X.shape[0]):
        f.write(str(i)+" ")
        if(Y[i]==1):
            f.write("-1 ")
        else:
            f.write("1 ")
        for j in range(0,X.shape[1]):
            f.write(str(X[i,j])+" ")
        f.write("\n")
    f.close()


from setuptools import setup, find_packages
import re
from pathlib import Path

here = Path(__file__).parent
version = re.search(
    r'__version__ = "(.+?)"',
    (here / "stort" / "__init__.py").read_text("utf8"),
).group(1)

setup(
    name="stort",
    description="A simple Torch trainer.",
    version=version,
    author="Simon J. Larsen",
    author_email="simonhffh@gmail.com",
    license="MIT",
    packages=find_packages(),
    include_package_data=True,
    install_requires=[
        "torch>=2.0.0,<2.1.0",
        "torchvision>=0.15.0,<0.16.0",
        "pytorch-ignite>=0.4.12",
        "kornia>=0.7.0",
        "wandb>=0.15.12",
        "tqdm>=4.66.1",
        "pydantic>=2.4.2",
    ],
    entry_points={"console_scripts": ["stort=stort.cli:cli"]},
)


import random as ran
import sys
import pygame as pg
import time

WIDTH, HEIGHT = 1600, 900
r_w = ran.randint(0, WIDTH)
r_h = ran.randint(0, HEIGHT)

def cheak_b(obj_rct: pg.Rect):
    """
    引数:こうかとんRect or 爆弾Rect
    戻り値:タプル(横方向判定結果, 縦方向判定結果)
    画面外ならTrue 画面内ならFalse
    """
    y, t = True, True
    if obj_rct.left < 0 or WIDTH < obj_rct.right:
        y = False
    if obj_rct.top < 0 or HEIGHT < obj_rct.bottom:
        t = False
    return y, t

def main():
    pg.display.set_caption("逃げろ！こうかとん")
    screen = pg.display.set_mode((WIDTH, HEIGHT))
    bg_img = pg.image.load("ex02/fig/pg_bg.jpg")
    kk_img = pg.image.load("ex02/fig/3.png")
    kk_img = pg.transform.rotozoom(kk_img, 0, 2.0)
    kk_img2 = pg.transform.flip(kk_img, True, False)

    """こうかとんの向き"""
    kk_dct = {
        (0, 0):kk_img,
        (-5, 0):kk_img,
        (-5, -5):pg.transform.rotozoom(kk_img, -45, 1.0),
        (-5, +5):pg.transform.rotozoom(kk_img, 45, 1.0),
        (5, 0):kk_img2,
        (5, -5):pg.transform.rotozoom(kk_img2, 45, 1.0),
        (0, -5):pg.transform.rotozoom(kk_img2, 90, 1.0),
        (5, 5):pg.transform.rotozoom(kk_img2, -45, 1.0),
        (0, 5):pg.transform.rotozoom(kk_img2, -90, 1.0)
    }

    """爆弾"""
    bom_img = pg.Surface((20, 20))
    pg.draw.circle(bom_img, (255, 0, 0), (10, 10), 10)
    bom_img.set_colorkey((0, 0, 0))
    bom_rct = bom_img.get_rect()
    bom_rct.center = (r_w, r_h)
    key_d = {
        pg.K_UP:(0, -5),
        pg.K_DOWN:(0, 5),
        pg.K_LEFT:(-5, 0),
        pg.K_RIGHT:(5, 0)
    }
    accs = [a for a in range(1, 11)] #加速度リスト
    bb_imgs = []
    for r in range(1, 11):
        bom_img = pg.Surface((20*r, 20*r))
        pg.draw.circle(bom_img, (255, 0, 0), (10*r, 10*r), 10*r)
        bom_img.set_colorkey((0, 0, 0))
        bb_imgs.append(bom_img)

    """こうかとん"""
    kk_rct = kk_img.get_rect()
    kk_rct.center = (900, 400)

    vx, vy = 5, 5
    clock = pg.time.Clock()
    tmr = 0
    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                return

        """キーボード操作"""
        key_lst = pg.key.get_pressed()
        sum_v = [0, 0]
        for key, mv in key_d.items():
            if key_lst[key]:
                sum_v[0] += mv[0]
                sum_v[1] += mv[1]

        """爆弾の加速、拡大"""
        avx, avy =vx*accs[min(tmr//500, 9)], vy*accs[min(tmr//500, 9)]
        bom_img = bb_imgs[min(tmr//500, 9)]

        """移動値"""
        kk_rct.move_ip(sum_v[0], sum_v[1])
        bom_rct.move_ip(avx, avy)

        """表示"""
        screen.blit(bg_img, [0, 0])
        screen.blit(kk_dct[tuple(sum_v)], kk_rct) # 追記1こうかとん画像切り替え
        screen.blit(bom_img, bom_rct)
        pg.display.update()

        # 画面外チェック
        cheak_kk = cheak_b(kk_rct)
        if cheak_kk != (True, True):
            kk_rct.move_ip(-sum_v[0], -sum_v[1])
        cheak_bom = cheak_b(bom_rct)
        if cheak_bom[0] == False:
            vx *= -1
        if cheak_bom[1] == False:
            vy *= -1

        # 衝突判定
        if kk_rct.colliderect(bom_rct):
            screen.blit(bg_img, [0, 0])
            kk_img3 =pg.image.load("ex02/fig/8.png")
            kk_img3_1 =pg.transform.rotozoom(kk_img3, 0, 2.0)
            screen.blit(kk_img3_1, kk_rct)
            screen.blit(bom_img, bom_rct)
            pg.display.update()
            time.sleep(2)
            return

        tmr += 1
        clock.tick(50)

if __name__ == "__main__":
    pg.init()
    main()
    pg.quit()
    sys.exit()


import tkinter as tk
from tkinter import *
from turtle import bgcolor
from tkinter.filedialog import askopenfilename,asksaveasfilename
from turtle import width
import moviepy.editor as me

filename=''

def convert():
        global filename
        filetypes=(("Audio files","*.mp3 , *.waw , *.ogg"),("All files","*.*"))
        video=me.VideoFileClip(filename)
        audio=video.audio
        file=asksaveasfilename(filetypes=filetypes)
        audio.write_audiofile(f'{file}{format.get()}')
        label5=Label(root,text="Done",font=("Arial",18),fg="gold")
        label5.pack()
        label5.place(x=450,y=300)
def select():
    global filename
    filetypes = (
        ('video files', '*.WEBM , *.MPG, *.MP2 , *.MPEG , *.MPE , *.MPV , *.MP4 , *.M4P , *.M4V , *.AVI , *.WMV , *.MOV , *.QT , *.FLV , *.SWF , *.AVCHD'),
        ('All files', '*.*')
    )
    filename=askopenfilename(filetypes=filetypes)
    label3.config(text="File Selected",fg="green",background = "black")
    label4=Label(root,text="Select Audio format :-",font=("Arial",18,),fg ="dark goldenrod" , background= "black")
    label4.pack()
    label4.place(x=100,y=460)
    options=[".mp3",".ogg",".wav"]
    format.set(".mp3")
    menu=OptionMenu(root,format,*options)
    menu["bg"] = "dark goldenrod"
    menu.pack()
    menu.place(x=350,y=460)
    button3=Button(root,text="Export",font=("Harlow Solid",14,"bold"),command=convert,width=20,height=1,background="dark goldenrod")
    button3.pack()
    button3.place(x=110,y=530)
    button4=Button(root,text="Quit",font=("Harlow Solid",14 ,"bold"),command=quit,width=20,height=1,background="dark goldenrod")
    button4.pack()
    button4.place(x=110,y=580)

root=Tk()
root.geometry("455x650")
root.minsize(455,650)
root.maxsize(455,650)
root["bg"] = "black"
photo = PhotoImage(file="logo.png")
new_label = Label(image=photo)
new_label["bg"] = "black"
new_label.pack()

label2=Label(root,text="Select Video file to Convert",font=("Arial",16),fg = "dark goldenrod" , background = "black")
label2.pack()
label2.place(x=105,y=330)
button1=Button(root,text="Select",font=("Harlow Solid",14,"bold"),command=select,width=20,height=1,background="dark goldenrod")
button1.pack()
button1.place(x=110,y=365)

label3=Label(root,font=("Footlight MT",18,"bold"))
label3["bg"] = "black"
label3.pack()
label3.place(x=150,y=410)
format=StringVar()
root.mainloop()

root.mainloop()