Newer
Older
GVM / backend.py
import platform
import requests
from os import popen,remove,mkdir
import shutil
from time import sleep
import re
import pathlib
import json
import tkinter.filedialog as fd

def getArch() -> str :
    arch = platform.machine()

    if arch in ['x86_64','AMD64'] :
        return 'x86_64'
    elif arch in ['arm64','aarch64'] :
        return 'arm64'

OS = platform.system()

if OS == 'Linux' :
    APPDATA = f"{pathlib.Path.home()}/.gvm_data/"
elif OS == 'Windows' :
    APPDATA =f"{pathlib.Path.home()}\\AppData\\Roaming\\GVM\\"

FIRSTOPEN = not pathlib.Path(f"{APPDATA}settings.json").exists()

if FIRSTOPEN :
    try :
        mkdir(APPDATA)
    except :
        pass
    finally :
        open(f"{APPDATA}settings.json",'w').write(json.dumps({'appPath':'','token':''}))
            

SETTINGS = json.load(open(f"{APPDATA}settings.json",'r'))

def updateSettings(appPath: str, token: str) -> None :
    global APP_PATH
    global TOKEN
    APP_PATH = appPath
    TOKEN = token

APP_PATH: str = SETTINGS['appPath']
WIN_COMP: str = APP_PATH.replace('/','\\')
TOKEN: str = SETTINGS['token']

ARCH = getArch()

def requestGitHubInfo() -> list :
    if len(TOKEN) > 0 :
        response = requests.get("https://api.github.com/repos/godotengine/godot/releases?per_page=100",headers={"Accept":"application/vnd.github+json","Authorization":f"Bearer {TOKEN}","X-GitHub-Api-Version":"2022-11-28"})
    else :
        return []

    return response.json()

# Get the versions of the Godot Engine and sort them from latest to oldest

def verOptions() -> list:
    tag_list = []
    response = requestGitHubInfo()

    if type(response) == dict :
        return ['No options available']

    for i in response :
       tag_list.append(i['tag_name'])
    
    tag_list.sort(reverse=True)

    if tag_list != [] :
        tag_list.pop()
    else :
        tag_list.append('No options available')

    return tag_list

def downloadGodot(cur_version: str,mono: str) -> int :

    if not pathlib.Path(APP_PATH).exists() :
        return 1

    response = requestGitHubInfo()

    if type(response) == dict :
        return 1

    VERSION = cur_version

    response.sort(key=lambda x: x['tag_name'],reverse=True)

    ASSETS = getAssets(response, VERSION)

    if ASSETS != [] :
        for asset in ASSETS :
            if OS == 'Linux' :
                regex: list = re.findall("linux|x11",asset['name']) + re.findall("x86_64|64",asset['name'])
                
                if mono != 'no_mono' :
                    regex += re.findall(mono,asset['name'])
                    monoCatch = ""
                    monoGoal = ['mono']
                else :
                    monoCatch = "|mono"
                    monoGoal = []


                if re.findall(f"server|headless{monoCatch}",asset['name']) == [] and regex in [['linux','x86_64']+monoGoal,['x11','64']+monoGoal] :#(asset['name'].find('linux') > 0 or asset['name'].find('x11') > 0) and (asset['name'].find(ARCH) > 0 or asset['name'].find('64') > 0) and asset['name'].find('server') == -1:
                    popen(f"curl -Lo {APP_PATH}/Godot.zip {asset['browser_download_url']}")
                    sleep(10)
                    popen(f"unzip -d {APP_PATH} {APP_PATH}/Godot.zip")
                    sleep(10)
                    remove(f"{APP_PATH}/Godot.zip")
                    return 0
            elif OS == 'Windows' :

                if mono != 'no_mono' :
                    monoGoal = ['mono']
                else :
                    monoGoal = []

                if ['win','arm64'] + monoGoal == re.findall('win',asset['name']) + re.findall('arm64',asset['name']) + re.findall('mono',asset['name']) :
                    popen(f"curl -Lo {APP_PATH}/Godot.zip {asset['browser_download_url']}")
                    sleep(10)
                    popen(f"tar -xf {APP_PATH}/Godot.zip -C {APP_PATH}")
                    sleep(10)
                    remove(f"{APP_PATH}/Godot.zip")
                    return 0
                elif ['win64'] + monoGoal == re.findall('win64',asset['name']) + re.findall('mono',asset['name']) :
                    popen(f"curl -Lo {APP_PATH}/Godot.zip {asset['browser_download_url']}")
                    sleep(10)
                    popen(f"tar -xf {APP_PATH}/Godot.zip -C {APP_PATH}")
                    sleep(10)
                    remove(f"{APP_PATH}/Godot.zip")
                    return 0
            else :
                return 1
    else :
        return 1

def getAssets(response: list, tag: str) -> list :

    for i in response :
        if i['tag_name'] == tag :
            return i['assets']
        else :
            continue
    
    return []

def launch(cur_version: str, mono: str) -> int :

    if not pathlib.Path(APP_PATH).exists() :
        return 1

    VERSION = cur_version.split('-')[0]

    file = getFile(VERSION,mono)

    if file.exists() and not file.is_dir() :
        popen(f"{file.as_posix()}")
        return 0
    elif file.exists() and file.is_dir() :
        for exe in file.iterdir() :
            if re.findall('exe|x86_64|64',exe.name) and exe.is_file() :
                popen(f"{exe.as_posix()}")
    else :
        return 1

def getFile(cur_version: str, mono: str) -> pathlib.Path | int :

    if not pathlib.Path(APP_PATH).exists() :
        return 1

    VERSION = cur_version.split('-')[0]

    appDir = pathlib.Path(APP_PATH)

    if mono == 'no_mono' :
        for i in appDir.iterdir() :
            if re.findall(f"{VERSION}-|{VERSION}_",i.name) in [[f"{VERSION}-"],[f"{VERSION}_"]] and i.is_file() :
                return i
    else :
        for i in appDir.iterdir() :
            if re.findall(f"{VERSION}-|{VERSION}_",i.name) + re.findall('mono',i.name) in [[f"{VERSION}-",'mono'],[f"{VERSION}_",'mono']] and i.is_dir() :
                return i
    
    return 1

def suddenSet(appPath: str, token: str) -> None :
    open(f"{APPDATA}settings.json",'w').write(json.dumps({'appPath':appPath,'token':token}))
    updateSettings(appPath,token)

def checkSettings() -> bool :
    settings = json.load(open(f"{APPDATA}settings.json",'r'))

    if settings['appPath'] == '' or settings['token'] == '' :
        return False
    else :
        return True

def removeGodot(cur_version: str, mono: str) -> int :
    if not pathlib.Path(APP_PATH).exists() :
        return 1

    VERSION = cur_version.split('-')[0]

    file = getFile(VERSION,mono)

    if file.exists() :
        if file.is_file() :
            remove(f"{file.as_posix()}")
        else :
            shutil.rmtree(file.as_posix())
        return 0
    else :
        return 1