#!/usr/bin/env python3
# 本来是用C++写的,但在非deepin/UOS编译/运行就是下载不了https文件,只能用python重写
#########################################################################
# 作者:gfdgd xi
# 版本:2.4.0
# 感谢:感谢 deepin-wine 团队,提供了 deepin-wine 给大家使用,让我能做这个程序
# 基于 Python3 的 PyQt5 构建
#########################################################################
#################
# 引入所需的库
#################
import os
import shutil
import random
import sys
import json
import subprocess
import traceback
import requests
import webbrowser
programPath = os.path.split(os.path.realpath(__file__))[0]  # 返回 string
sys.path.append(f"{programPath}/../")
from Model import *
import globalenv
from PyQt5 import QtCore, QtGui, QtWidgets
programPath = os.path.split(os.path.realpath(__file__))[0]  # 返回 string
# UI 布局(自动生成)
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(693, 404)
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralWidget)
        self.verticalLayout_2.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setSpacing(6)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.localWineList = QtWidgets.QListView(self.centralWidget)
        self.localWineList.setObjectName("localWineList")
        self.horizontalLayout_2.addWidget(self.localWineList)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")
        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.addButton = QtWidgets.QPushButton(self.centralWidget)
        self.addButton.setObjectName("addButton")
        self.verticalLayout.addWidget(self.addButton)
        self.delButton = QtWidgets.QPushButton(self.centralWidget)
        self.delButton.setObjectName("delButton")
        self.verticalLayout.addWidget(self.delButton)
        spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem1)
        self.horizontalLayout_2.addLayout(self.verticalLayout)
        self.internetWineList = QtWidgets.QListView(self.centralWidget)
        self.internetWineList.setObjectName("internetWineList")
        self.horizontalLayout_2.addWidget(self.internetWineList)
        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setSpacing(6)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.unzip = QtWidgets.QCheckBox(self.centralWidget)
        self.unzip.setObjectName("unzip")
        self.horizontalLayout.addWidget(self.unzip)
        self.deleteZip = QtWidgets.QCheckBox(self.centralWidget)
        self.deleteZip.setChecked(True)
        self.deleteZip.setTristate(False)
        self.deleteZip.setObjectName("deleteZip")
        self.m_recommendWine = QtWidgets.QCheckBox(self.centralWidget)
        self.m_recommendWine.setChecked(True)
        self.m_recommendWine.setObjectName("recommendWine")
        self.horizontalLayout.addWidget(self.m_recommendWine)
        self.addOtherWine = QtWidgets.QPushButton(self.centralWidget)
        self.downloadWineFromCloudDisk = QtWidgets.QPushButton(self.centralWidget)
        self.horizontalLayout.addWidget(self.downloadWineFromCloudDisk)
        self.horizontalLayout.addWidget(self.addOtherWine)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.verticalLayout_2.addLayout(self.horizontalLayout)
        MainWindow.setCentralWidget(self.centralWidget)
        # 菜单栏
        _translate = QtCore.QCoreApplication.translate
        self.menu = MainWindow.menuBar()
        self.changeSources = self.menu.addMenu(_translate("MainWindow", "更换源"))
        self.gitlinkAction = QtWidgets.QAction(_translate("MainWindow", "Gitee 源(推荐)"))
        self.kgithubAction = QtWidgets.QAction(_translate("MainWindow", "Sourceforge 源"))
        self.ipv6Action = QtWidgets.QAction(_translate("MainWindow", "默认源"))
        self.githubAction = QtWidgets.QAction(_translate("MainWindow", "Github 源(国内访问不稳定)"))
        
        self.localAction = QtWidgets.QAction(_translate("MainWindow", "本地测试源(127.0.0.1)"))
        self.changeSources.addAction(self.ipv6Action)
        
        self.changeSources.addAction(self.kgithubAction)
        self.changeSources.addAction(self.gitlinkAction)
        self.changeSources.addAction(self.githubAction)
        self.changeSources.addAction(self.localAction)
        for i in [self.gitlinkAction, self.ipv6Action, self.localAction, self.kgithubAction, self.githubAction]:
            i.setCheckable(True)
        self.ipv6Action.setChecked(True)
        self.changeSourcesGroup = QtWidgets.QActionGroup(MainWindow)
        self.changeSourcesGroup.addAction(self.gitlinkAction)
        self.changeSourcesGroup.addAction(self.kgithubAction)
        self.changeSourcesGroup.addAction(self.ipv6Action)
        self.changeSourcesGroup.addAction(self.githubAction)
        self.changeSourcesGroup.addAction(self.localAction)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "下载 Wine"))
        self.addButton.setText(_translate("MainWindow", "<<"))
        self.delButton.setText(_translate("MainWindow", ">>"))
        self.unzip.setText(_translate("MainWindow", "不解压Wine资源文件"))
        self.deleteZip.setText(_translate("MainWindow", "删除下载的资源包,只解压保留(两个选项都选相互抵消)"))
        self.addOtherWine.setText(_translate("MainWindow", "导入 Wine 7z 包"))
        self.downloadWineFromCloudDisk.setText(_translate("MainWindow", "从网盘下载 Wine"))
        self.m_recommendWine.setText(_translate("MainWindow", "隐藏本机不可用 Wine"))

def ReadLocalInformation():
    try:
        global localJsonList
        file = open(f"{programPath}/winelist.json", "r")
        localJsonList = json.loads(file.read())
        nmodel = QtGui.QStandardItemModel(window)
        for i in localJsonList:
            item = QtGui.QStandardItem(i)
            nmodel.appendRow(item)
        ui.localWineList.setModel(nmodel)
        file.close()
    except:
        print("新建空列表")
        try:
            with open(f"{programPath}/winelist.json", "w") as file:
                file.write("[]")
        except:
            traceback.print_exc()
            QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())

def InstallOtherWine():
    path = QtWidgets.QFileDialog.getOpenFileName(window, "选择 Wine 运行器 Wine 7z 包", os.getenv("~"), "Wine 运行器 Wine 7z 包(*.7z);;全部文件(*.*)")
    if path[0] == "" or not path[1]:
        return
    try:
        # 写入配置文件
        rfile = open(f"{programPath}/winelist.json", "r")
        list = json.loads(rfile.read())
        rfile.close()
        name = os.path.splitext(os.path.basename(path[0]))[0]
        removeSymbol = ["(", ")", "(", ")", " ", "!", "@", "#", 
                        "$", "%", "^", "&", "*", "=", "[", "]",
                        "{", "}", "\\", "/", "|", "?",
                        "<", ">", "·", "「", ";", ":", ":",
                        "?", "《", "》", ",", "。", ",", ".",
                        "`", "~", "~", "、"]
        for i in removeSymbol:
            name.replace(i, "")
        unpackPath = f"{programPath}/{name}"
        shellCommand = f"""mkdir -p \"{unpackPath}\"
7z x -y \"{path[0]}\" -o\"{unpackPath}\"
"""
        shellFile = open("/tmp/depein-wine-runner-wine-install.sh", "w")
        shellFile.write(shellCommand)
        shellFile.close()
        OpenTerminal("bash /tmp/depein-wine-runner-wine-install.sh")
        # C++ 版注释:不直接用 readwrite 是因为不能覆盖写入
        file = open(f"{programPath}/winelist.json", "w")
        list.append(name)
        file.write(json.dumps(list))
        file.close()
    except:
        traceback.print_exc()
        QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
    ReadLocalInformation()

def ChangeSources():
    global urlSources
    global internetWineSource
    sources = [ui.ipv6Action, ui.kgithubAction, ui.gitlinkAction, ui.githubAction, ui.localAction]
    for i in range(0, len(sources)):
        if sources[i].isChecked():
            urlSources = internetWineSourceList[i]
            internetWineSource = internetWineSourceList[i]
            # 读取信息
            ReadLocalInformation()
            ReadInternetInformation()
            break
    print(urlSources)

class GetInfo():
    arch = subprocess.getoutput("dpkg --print-architecture").replace("\n", "").replace(" ", "")
    isBinfmt = os.path.exists("/proc/sys/fs/binfmt_misc")
    isBox64 = not os.system("which box64 > /dev/null") >> 8 or not os.system("which spark-box64 > /dev/null") >> 8
    isBox86 = not os.system("which box86 > /dev/null") >> 8 or not os.system("which spark-box86 > /dev/null") >> 8
    isLat = not os.system("which lat-i386-static > /dev/null") >> 8 or not os.system("which latx-i386 > /dev/null") >> 8
    isLati386Runtime = os.path.exists("/usr/gnemul/latx-i386") or os.path.exists("/usr/gnemul/lat-i386")
    isLatamd64Runtime = os.path.exists("/usr/gnemul/latx-x86_64") or os.path.exists("/usr/gnemul/lat-x86_64")
    isQemuUseri386Runtime = os.path.exists("/usr/lib/i386-linux-gnu/ld-linux.so.2")
    isQemuUseramd64Runtime = os.path.exists("/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2")
    isQemuUser = not os.system("which qemu-i386-static > /dev/null") >> 8 and (not "amd64" in arch) and (not "i386" in arch)
    pageSize = subprocess.getoutput("getconf PAGESIZE").replace(" ", "").replace("\n", "")
    is4kPageSize = (pageSize == "4096")
    is8kPageSize = (pageSize == "8096")
    is16kPageSize = (pageSize == "16192")
    is32kPageSize = (pageSize == "32384")
    is64kPageSize = (pageSize == "64768")
    isLoongarch = (arch == "loong64") or (arch == "loongarch64")
    isProot = os.path.exists("/storage")
    isAndroid = os.path.exists("/data")
    isTermux = os.path.exists("/data")
    glibcVersion = "2.28"

    def __init__(self):
        self.getGlibcVersion()

    def getGlibcVersion(self):
        version = None
        glibcPath = ""
        glibcPathList = [
            "/usr/lib/i386-linux-gnu/ld-linux.so.2",
            "/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
            "/usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3",
            "/usr/lib/arm-linux-gnueabi/ld-linux.so.3",
            "/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1",
            "/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1",
            "/usr/lib/riscv64-linux-gnu/ld-linux-riscv64-lp64d.so.1",
            "/usr/lib/mips64el-linux-gnuabi64/ld.so.1",
            "/usr/lib/powerpc64le-linux-gnu/ld64.so.2",
            "/usr/lib/loongarch64-linux-gnu/ld-linux-loongarch-lp64d.so.1",
            "/usr/lib/loongarch64-linux-gnu/ld.so.1",
            "/usr/lib/ld-linux.so.2",
            "/usr/lib/ld-linux-x86-64.so.2",
            "/usr/lib/ld-linux-armhf.so.3",
            "/usr/lib/ld-linux.so.3",
            "/usr/lib/ld-linux-aarch64.so.1",
            "/usr/lib/ld-linux-aarch64.so.1",
            "/usr/lib/ld-linux-riscv64-lp64d.so.1",
            "/usr/lib/ld.so.1",
            "/usr/lib/ld64.so.2",
            "/usr/lib/ld-linux-loongarch-lp64d.so.1",
            "/usr/lib64/ld.so.1",
            "/usr/lib64/ld-linux.so.2",
            "/usr/lib64/ld-linux-x86-64.so.2",
            "/usr/lib64/ld-linux-armhf.so.3",
            "/usr/lib64/ld-linux.so.3",
            "/usr/lib64/ld-linux-aarch64.so.1",
            "/usr/lib64/ld-linux-aarch64.so.1",
            "/usr/lib64/ld-linux-riscv64-lp64d.so.1",
            "/usr/lib64/ld.so.1",
            "/usr/lib64/ld64.so.2",
            "/usr/lib64/ld-linux-loongarch-lp64d.so.1",
            "/usr/lib64/ld.so.1"
        ]
        for i in glibcPathList:
            if (os.path.exists(i)):
                glibcPath = i
                break
        if glibcPath != "":
            glibcStr = subprocess.getoutput("strings " + glibcPath + " | grep GLIBC_")
            newestVersion = "1.0"
            for i in glibcStr.splitlines():
                i = i.replace("GLIBC_", "")
                # 判断是不是版本号行
                try:
                    int(i[0])
                except:
                    # 非版本号行
                    continue
                if (self.compareVersion(newestVersion, i) == -1):
                    newestVersion = i
            version = newestVersion
        if (version == None):
            version = "2.28"  # 默认值
        self.glibcVersion = version
        return version
    
    def compareVersion(self, version1: str, version2: str):
        # 判断是不是版本号
        if (type(version1) != str or type(version2) != str):
            return -2
        if ((not "." in version1) or (not "." in version2)):
            return -2
        if (version1 == version2):
            return 0
        version1List = version1.split(".")
        version2List = version2.split(".")
        for i in range(len(version1List)):
            # 判断 version2List 是否有该长度
            try:
                version2List[i]
            except:
                return 1
            try:
                version1 = int(version1List[i])
                version2 = int(version2List[i])
            except:
                continue
            if (version1 > version2):
                return 1
            if (version1 < version2):
                return -1
        if (len(version1List) < len(version2List)):
            return -1
        return 0

    def checkTag(self, data: str):
        result = False
        no = False
        if (len(data) > 0 and data[0] == "!"):
            no = True
            data = data[1:]
        if (data == self.arch):
            result = True
        if (data == "binfmt" and self.isBinfmt):
            result = True
        if (data == "box86" and self.isBox86):
            result = True
        if (data == "box64" and self.isBox64):
            result = True
        if (data == "lat" and self.isLat):
            result = True
        if (data == "lat-i386" and self.isLati386Runtime):
            result = True
        if (data == "lat-x86_64" and self.isLatamd64Runtime):
            result = True
        if (data == "qemu-user" and self.isQemuUser):
            result = True
        if (data == "qemu-user-i386" and self.isQemuUseri386Runtime):
            result = True
        if (data == "qemu-user-amd64" and self.isQemuUseramd64Runtime):
            result = True
        if (data == "kernel-4k-pagesize" and self.is4kPageSize):
            result = True
        if (data == "loong64-kernel-4k-pagesize" and self.isLoongarch and self.is4kPageSize):
            result = True
        if (data == "loong64-kernel-8k-pagesize" and self.isLoongarch and self.is8kPageSize):
            result = True
        if (data == "loong64-kernel-16k-pagesize" and self.isLoongarch and self.is16kPageSize):
            result = True
        if (data == "loong64-kernel-32k-pagesize" and self.isLoongarch and self.is32kPageSize):
            result = True
        if (data == "loong64-kernel-64k-pagesize" and self.isLoongarch and self.is64kPageSize):
            result = True
        if (data == "proot" and self.isProot):
            result = True
        if (data == "android" and self.isAndroid):
            result = True
        if (data == "termux" and self.isTermux):
            result = True
        try:
            if (self.compareVersion(self.glibcVersion, data) == 1 or 
                self.compareVersion(self.glibcVersion, data) == 0):
                result = True
        except:
            # 如果检查 tag 出现问题,强制返回符合条件
            return True
        if (os.path.exists(data)):
            result = True
        if (no):
            result = not result
        return result

    def checkList(self, data:list):
        succeed = 0
        for i in data:
            if (type(i) == list):
                succeed += self.checkList(i)
                continue
            if (self.checkTag(i)):
                succeed += 1
        return succeed == len(data)

    def check(self, data: list):
        for i in data:
            if ("all" == i):
                return True
            if (type(i) == list):
                result = self.checkList(i)
                if (result):
                    return True
                continue
            if (self.checkTag(i)):
                return True
        return False

# 下面内容均翻译自 C++ 版本
def ReadInternetInformation():
    global internetJsonList
    # C++ 版本是用 curl 的,考虑到 Python 用 requests 反而方便,于是不用 curl
    try:
        text = requests.get(f"{internetWineSource}/information.json").text
        print(text)
        internetJsonList = json.loads(text)
    except:
        traceback.print_exc()
        QtWidgets.QMessageBox.critical(window, "错误", "无法连接服务器!")
        return
    nmodel = QtGui.QStandardItemModel(window)
    newinternetJsonList = []
    for i in internetJsonList:
        if (ui.m_recommendWine.isChecked() and not systemInfo.check(i[2])):
            continue
        item = QtGui.QStandardItem(i[0])
        nmodel.appendRow(item)
        newinternetJsonList.append(i)
    ui.internetWineList.setModel(nmodel)
    internetJsonList = newinternetJsonList
    
class DownloadThread(QtCore.QThread):
    MessageBoxInfo = QtCore.pyqtSignal(str)
    MessageBoxError = QtCore.pyqtSignal(str)
    ChangeDialog = QtCore.pyqtSignal(QtWidgets.QProgressDialog, int, int, int)
    Finish = QtCore.pyqtSignal()
    def __init__(self, progressDialog: QtWidgets.QProgressDialog, 
        url: str, savePath: str, fileName: str, view: QtWidgets.QListView, deleteZip: bool, 
        unzip: bool, localList) -> None:
        self.dialog = progressDialog
        self.fileUrl = url
        self.fileSavePath = savePath
        self.fileSaveName = fileName
        self.localView = view
        self.downloadDeleteZip = deleteZip
        self.downloadUnzip = unzip
        self.localJsonList = localList
        super().__init__()

    def ReadLocalInformation(self):
        global localJsonList
        try:
            file = open(f"{programPath}/winelist.json", "r");
            nmodel = QtGui.QStandardItemModel()
            localJsonList = json.loads(file.read())
            for i in localJsonList:
                nmodel.appendRow(QtGui.QStandardItem(i))
            self.localView.setModel(nmodel)
            file.close()
        except:
            traceback.print_exc()
            QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())

    def run(self):
        try:
            # 创建文件夹
            dir = QtCore.QDir()
            savePath = f"{programPath}/{self.fileSaveName}"
            # 文件下载
            timeout = 0
            f = requests.get(self.fileUrl, stream=True)
            allSize = int(f.headers["content-length"])  # 文件总大小
            bytesRead = 0
            with open(savePath, "wb") as filePart:
                for chunk in f.iter_content(chunk_size=1024):
                    if chunk:
                        #progressbar.update(int(part / show))
                        filePart.write(chunk)
                        bytesRead += 1024
                        self.ChangeDialog.emit(self.dialog, int(bytesRead / allSize * 100), int(bytesRead / 1024 / 1024), int(allSize / 1024 / 1024))
            # 写入配置文件
            rfile = open(f"{programPath}/winelist.json", "r")
            list = json.loads(rfile.read())
            rfile.close()
            # C++ 版注释:不直接用 readwrite 是因为不能覆盖写入
            file = open(f"{programPath}/winelist.json", "w")
            list.append(self.fileSaveName.replace(".7z", ""))
            file.write(json.dumps(list))
            file.close()
            # 读取配置文件
            self.ReadLocalInformation()
            self.localJsonList = list
            # 解压文件
            shellCommand = ""
            if self.downloadUnzip:
                path = f"{programPath}/{self.fileSaveName.replace('.7z', '')}"
                shellCommand += f"""mkdir -p \"{path}\"
7z x -y \"{savePath}\" -o\"{path}\"
"""
            if self.downloadDeleteZip:
                shellCommand += f"rm -rf \"{savePath}\"\n"
            shellFile = open("/tmp/depein-wine-runner-wine-install.sh", "w")
            shellFile.write(shellCommand)
            shellFile.close()
            #process = QtCore.QProcess()
            #command = ["deepin-terminal", "-e", "bash", "/tmp/depein-wine-runner-wine-install.sh"]
            #process.start(f"{programPath}/../launch.sh", command)
            #process.waitForFinished()
            OpenTerminal("bash /tmp/depein-wine-runner-wine-install.sh")
            self.Finish.emit()
        except:
            traceback.print_exc()
            self.MessageBoxError.emit(traceback.format_exc())
            self.ChangeDialog.emit(self.dialog, 100, 100, 100)
            self.Finish.emit()

def MessageBoxInfo(info):
    QtWidgets.QMessageBox.information(window, "提示", info)

def MessageBoxError(info):
    QtWidgets.QMessageBox.critical(window, "错误", info)

def ChangeDialog(dialog: QtWidgets.QProgressDialog, value, downloadBytes, totalBytes):
    dialog.setValue(value)
    dialog.setLabelText(f"{downloadBytes}MB/{totalBytes}MB")

def DownloadFinish():
    ui.centralWidget.setEnabled(True)

class QT:
    thread = None

def on_addButton_clicked():
    choose = ui.internetWineList.currentIndex().row()
    if choose < 0:
        QtWidgets.QMessageBox.information(window, "提示", "您未选中任何项,无法继续")
        return
    downloadName = internetJsonList[choose][1]
    ReadLocalInformation()
    for i in localJsonList:
        if i == internetJsonList[choose][0]:
            QtWidgets.QMessageBox.information(window, "提示", "您已经安装了这个Wine了!无需重复安装!")
            return
    if(ui.deleteZip.isChecked() + ui.unzip.isChecked() == 2):
        ui.deleteZip.setChecked(False)
        ui.unzip.setChecked(False)
    #downloadUrl = internetWineSource + downloadName
    if "://" in downloadName:
        downloadUrl = downloadName
    else:
        downloadUrl = internetWineSource + downloadName
    dialog = QtWidgets.QProgressDialog()
    cancel = QtWidgets.QPushButton("取消")
    cancel.setDisabled(True)
    dialog.setWindowIcon(QtGui.QIcon(f"{programPath}/../deepin-wine-runner.svg"))
    dialog.setCancelButton(cancel)
    dialog.setWindowTitle(f"正在下载“{internetJsonList[choose][0]}”")
    saveName = os.path.basename(internetJsonList[choose][1])
    if os.path.split(os.path.basename(internetJsonList[choose][1]))[0] == "":
        saveName = os.path.basename(internetJsonList[choose][0]) + ".7z"
    QT.thread = DownloadThread(
        dialog, 
        downloadUrl, 
        "", 
        saveName,
        ui.localWineList,
        ui.deleteZip.isChecked(),
        not ui.unzip.isChecked(),
        localJsonList
        )
    QT.thread.MessageBoxInfo.connect(MessageBoxInfo)
    QT.thread.MessageBoxError.connect(MessageBoxError)
    QT.thread.ChangeDialog.connect(ChangeDialog)
    QT.thread.Finish.connect(DownloadFinish)
    ui.centralWidget.setDisabled(True)
    QT.thread.start()

def on_delButton_clicked():
    if QtWidgets.QMessageBox.question(window, "提示", "你确定要删除吗?") == QtWidgets.QMessageBox.No:
        return
    if ui.localWineList.currentIndex().row() < 0:
        QtWidgets.QMessageBox.information(window, "提示", "您未选择任何项")
        return
    try:
        name = f"{programPath}/{localJsonList[ui.localWineList.currentIndex().row()]}"
        dir = QtCore.QDir(name)
        dir.removeRecursively()
        QtCore.QFile.remove(name + ".7z")
        del localJsonList[ui.localWineList.currentIndex().row()]
        file = open(f"{programPath}/winelist.json", "w")
        file.write(json.dumps(localJsonList))
        file.close()
        ReadLocalInformation()
        QtWidgets.QMessageBox.information(window, "提示", "删除成功!")
    except:
        traceback.print_exc()
        QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())

def on_downloadWineFromCloudDisk_clicked():
    QtWidgets.QMessageBox.information(window, "提示", "即将在浏览器打开下载页面\n访问密码为 2061")
    webbrowser.open_new_tab("http://ctfile.gfdgdxi.top/d/31540479-61624693-080e74?p=2061")

# 获取当前语言
def get_now_lang()->"获取当前语言":
    return os.getenv('LANG')


localJsonList = []
internetJsonList = []
internetWineSourceList = [
    "http://wine.wine-runner.gfdgdxi.top/",
    "http://wine.wine-runner.gfdgdxi.top/sourceforge",
    "https://gitee.com/gfdgd-xi/wine-mirrors-websize/raw/master/",
    "https://github.com/gfdgd-xi/wine-mirrors-websize/raw/master/",
    "http://127.0.0.1/wine-mirrors/"  # 本地测试源
    ]

if (__name__ == "__main__"):
    app = QtWidgets.QApplication(sys.argv)
else:
    app = globalenv.get_value("app")
# 读取翻译
if not get_now_lang() == "zh_CN.UTF-8":
    trans = QtCore.QTranslator()
    trans.load(f"{programPath}/../LANG/installwine-en_US.qm")
    app.installTranslator(trans)
# 获取信息
systemInfo = GetInfo()
# 窗口构建
window = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
window.setWindowIcon(QtGui.QIcon(f"{programPath}/../deepin-wine-runner.svg"))
ui.setupUi(window)
if (__name__ == "__main__"):
    window.show()
# 隐藏选项
ui.unzip.setVisible(False)
ui.deleteZip.setVisible(False)
# 判断机器所在国家并自动分配源
try:
    isChina = requests.get("https://ip.useragentinfo.com/json").json()["country"] == "中国"
    print("IsChina", isChina)
    if isChina:
        internetWineSource = internetWineSourceList[0]
        ui.ipv6Action.setChecked(True)
    else:
        internetWineSource = internetWineSourceList[1]
        ui.kgithubAction.setChecked(True)
except:
    traceback.print_exc()
    print("IsChina", False)
    # 请求失败,默认使用国际源
    internetWineSource = internetWineSourceList[1]
    ui.kgithubAction.setChecked(True)
# 连接信号
ui.addButton.clicked.connect(on_addButton_clicked)
ui.delButton.clicked.connect(on_delButton_clicked)
ui.downloadWineFromCloudDisk.clicked.connect(on_downloadWineFromCloudDisk_clicked)
ui.addOtherWine.clicked.connect(InstallOtherWine)
ui.changeSourcesGroup.triggered.connect(ChangeSources)
ui.m_recommendWine.clicked.connect(ReadInternetInformation)
## 加载内容
# 设置列表双击不会编辑
ui.localWineList.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
ui.internetWineList.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
# 读取信息
ReadLocalInformation()
ReadInternetInformation()
# 图标
ui.centralWidget.setWindowIcon(QtGui.QIcon(f"{programPath}/../deepin-wine-runner.svg"))
if (__name__ == "__main__"):
    app.exec_()