The Fisrt Updated

This commit is contained in:
2026-01-25 13:54:16 +08:00
commit 4c90aec977
19 changed files with 1037 additions and 0 deletions

702
tools.py Normal file
View File

@@ -0,0 +1,702 @@
#550W 工具箱
#所需模块
#UI库
import tkinter.filedialog as tf
import tkinter.messagebox as tm
import tkinter.constants as Keys
import tkinter.ttk as ttk
import tkinter as tk
import os
os.environ["PYGAME_HIDE_SUPPORT_PROMPT"]=""#阻止pygame-print
import pygame
try:
pygame.mixer.init()
except:
print("PyGame InIt Error")
#系统库
import tempfile
import sys,os
from io import BytesIO
import platform
import getpass
import psutil
import shutil
import traceback
import winreg
import wmi
try:
import winshell,win32con,win32api,win32gui
except:
pass
#文件库
import configparser
import zipfile
import json
#编码库
import binascii
import hashlib
import base64
import uuid
import re
#进程库
from threading import Thread
import asyncio
import subprocess
#时间库
import datetime,time
#图像库
from PIL import Image,ImageTk,ImageDraw
import cv2
#网页库
import urllib
import requests
import flask
import flask_socketio
#数学库
import random
import numpy
import math
import copy
#音频库
#基础变量
temp=os.environ["temp"]
#Windows管理接口
WindowsManagementInterface=wmi.WMI()
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE'
}
def webpost(url,data):
response = requests.post(url,data=data,headers={'Content-Type': 'application/x-www-form-urlencoded'})
return response
def webget(url):
response = requests.get(url,headers=headers)
return response
#UUID
def GUUID():
return str(uuid.uuid3(uuid.NAMESPACE_DNS, str(random.randint(0, 10000000000000000000))))
# 读/写/添
def openw(file, write, mode="1", encoding="UTF-8"):
if mode == "1" or mode == 1:
with open(file, "w", encoding=encoding) as f:
f.write(write)
elif mode == "2" or mode == 2:
with open(file, "wb") as f:
f.write(write)
def opena(file, write, mode="1", encoding="UTF-8"):
if mode == "1" or mode == 1:
with open(file, "a", encoding=encoding) as f:
f.write(write)
elif mode == "2" or mode == 2:
with open(file, "ab") as f:
f.write(write)
def openr(file, mode="1", encoding="UTF-8"):
if mode == "1" or mode == 1:
with open(file, "r", encoding=encoding) as f:
read = f.read()
elif mode == "2" or mode == 2:
with open(file, "rb") as f:
read = f.read()
return read
def MakeTempFile(write):
tmp_file = tempfile.NamedTemporaryFile(delete=True)
tmp_file.write(write)
tmp_file.close()
return tmp_file
def MakeTempFileNF(write):
tmp_file = tempfile.NamedTemporaryFile(delete=True)
tmp_file.write(write)
return tmp_file
def MakeTempFilePattern(suffix=".tmp",delete=True):
with tempfile.NamedTemporaryFile(suffix='.png', delete=delete) as tmp_file:
return tmp_file
#MP3播放
def MP3Play(mp3_path,volume=10,sleep=-1):
pygame.mixer.music.load(mp3_path) # 加载音乐
pygame.mixer.music.set_volume(volume)# 设置音量大小0~1的浮点数
pygame.mixer.music.play() # 播放音频
if sleep == -1:
time.sleep(get_duration_wave(mp3_path))
else:
time.sleep(sleep)
#MP3时间获取
def get_duration_wave(file_path):
with wave.open(file_path, "r") as audio_file:
frame_rate = audio_file.getframerate()
n_frames = audio_file.getnframes()
duration = n_frames / float(frame_rate)
return duration
#时间格式化
def TimeFormat(s,end=""):
return time.strftime("[%Y/%m/%d %H:%M:%S]: "+str(s)+end, time.localtime())
def TimeFormatStr(s="%Y/%m/%d %H:%M:%S",end=""):
return time.strftime(s+end, time.localtime())
def TimeFormatv(make_uuid=True):
return datetime.datetime.now().strftime("%Y年%m月%d日-%H时%M分%S秒%f"+"-"+str(uuid.uuid3(uuid.NAMESPACE_DNS, str(random.randint(0, 10000000000000000000)))))
def Is_TrueColorCode(code):
pattern = re.compile(r'^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})$')
return bool(pattern.match(code))
#Base64转图片
def base64_to_image(base64_str: str) -> Image.Image:
base64_data = re.sub("^data:image/.+;base64,", "", base64_str)
byte_data = base64.b64decode(base64_data)
image_data = BytesIO(byte_data)
img = Image.open(image_data)
return img
#图片转Base64
def image_to_base64(image: Image.Image, fmt="png") -> str:
output_buffer = BytesIO()
image.save(output_buffer, format=fmt)
byte_data = output_buffer.getvalue()
base64_str = base64.b64encode(byte_data).decode("utf-8")
return f"data:image/{fmt};base64," + base64_str
#返回"没有文件"错误类型
def ReturnFileNotFoundError(InFo,file):
ERROR=FileNotFoundError(InFo)
ERROR.filename=file
#判断ini文件是否正确
def IS_INI(ini_file):
#创建ConfigParser对象
config = configparser.ConfigParser()
#读取INI文件
try:
#尝试读取
config.read(ini_file)
except configparser.Error as e:
#报错
return False
else:
#没有报错
return True
#ini转字典
def INI2DICT(ini_file):
#创建ConfigParser对象
config = configparser.ConfigParser()
#读取INI文件
config.read(ini_file)
#创建二级字典
config_dict = {}
#遍历INI文件的sections
for section in config.sections():
#创建子字典
section_dict = {}
#遍历每个section中的options
for option in config.options(section):
#将选项和值添加到子字典中
section_dict[option] = config.get(section, option)
#将子字典添加到二级字典中
config_dict[section] = section_dict
#返回文件
return config_dict
import binascii
import os
temp=os.environ["temp"]
def chunk_string(s, n):
return [s[i:i+n] for i in range(0, len(s), n)]
def four_split(s):
a=[0,0,0,0]
a[1]=s[0]
a[3]=s[1]
a[0]=s[2]
a[2]=s[3]
s=""
for i in a:
s+=i
return s
def R_four_split(s):
a=[0,0,0,0]
a[0]=s[1]
a[1]=s[3]
a[2]=s[0]
a[3]=s[2]
s=""
for i in a:
s+=i
return s
def CBDF(file,dllfile):
f=open(file,"rb")
get=f.read()
f.close()
s_hex=get.hex()
s_hex=s_hex[::-1]
s_hex=chunk_string(s_hex,4)
ret=""
for i in s_hex:
if len(i) == 4:
ret+=four_split(i)
else:
ret+=i
hexgo=binascii.a2b_hex(ret)
f=open(dllfile,"wb")
f.write(hexgo)
f.close()
def CBDS(s,encoding="UTF-8"):
s=bytes(s,encoding=encoding)
s_hex=s.hex()
s_hex=s_hex[::-1]
s_hex=chunk_string(s_hex,4)
ret=""
for i in s_hex:
if len(i) == 4:
ret+=four_split(i)
else:
ret+=i
hexgo=binascii.a2b_hex(ret)
return hexgo
def CBDMS(s,encoding="UTF-8"):
s=bytes(s,encoding=encoding)
s_hex=s.hex()
s_hex=s_hex[::-1]
s_hex=chunk_string(s_hex,4)
ret=""
for i in s_hex:
if len(i) == 4:
ret+=four_split(i)
else:
ret+=i
return ret
def GBDMS(s):
ret=""
s_hex=chunk_string(s,4)
for i in s_hex:
if len(i) == 4:
ret+=R_four_split(i)
else:
ret+=i
ret=ret[::-1]
hexgo = binascii.a2b_hex(ret).decode("utf-8")
return hexgo
def GBDS(s,encoding="utf-8"):
s_hex = s.hex()
ret=""
s_hex=chunk_string(s_hex,4)
for i in s_hex:
if len(i) == 4:
ret+=R_four_split(i)
else:
ret+=i
ret=ret[::-1]
hexgo = binascii.a2b_hex(ret).decode(encoding)
return hexgo
def GBDF(dllfile):
f = open(dllfile, "rb")
get = f.read()
f.close()
s_hex = get.hex()
ret=""
s_hex=chunk_string(s_hex,4)
for i in s_hex:
if len(i) == 4:
ret+=R_four_split(i)
else:
ret+=i
ret=ret[::-1]
hexgo = binascii.a2b_hex(ret)
return hexgo
def WriteToFile(content, filename):
with open(filename, "wb") as f:
f.write(content)
#信息结构体
class InFo:
def __init__(self):
pass
#异步装饰器
def asyncs(f):
def wrapper(*args, **kwargs):
thr = Thread(target = f, args = args, kwargs = kwargs)
thr.start()
return wrapper
#获取多个文件MD5(自匹配)
def GetFilesMD5(*file_paths):
md5_list = []
for file_path in file_paths:
md5_list.append(GetFileMD5(file_path))
return md5_list
def GetFileMD5(file_name):
"""
计算文件的md5
:param file_name:
:return:
"""
m = hashlib.md5()
with open(file_name,'rb') as fobj:
while True:
data = fobj.read(4096)
if not data:
break
m.update(data)
return m.hexdigest()
def GetStrMD5(content):
"""
计算字符串md5
:param content:
:return:
"""
m = hashlib.md5(content)
return m.hexdigest()
def GetDirFileMD5(Dir):
"""
计算文件夹所有文件(二枝树算法)
:param Dir:
:return list:
"""
MD5S=[]
if not os.path.isdir(Dir):
#No Use raise
return FileNotFoundError()
for i in os.listdir(Dir):
if os.path.isfile(os.path.normpath(Dir+"/"+i)):
MD5S.append({"FileName":os.path.normpath(Dir+"/"+i),"Type":"File","MD5":GetFileMD5(os.path.normpath(Dir+"/"+i))})
if os.path.isdir(os.path.normpath(Dir+"/"+i)):
MD5S.append({"FileName":os.path.normpath(Dir+"/"+i),"Type":"Dir","ChildRen":GetDirFileMD5(os.path.normpath(Dir+"/"+i))})
return MD5S
def IsDirFileMD5(MD5List,Dir,Bind=lambda x:None,sleep=0):
for i in MD5List:
s=copy.deepcopy(i)
s["ChildRen"]="Pass"
Bind(s["FileName"])
time.sleep(sleep)
if i["Type"]=="File":
if not os.path.isfile(i["FileName"]):
return False,1,i["FileName"]
if not GetFileMD5(i["FileName"]) == i["MD5"]:
return False,2,i["FileName"]
if i["Type"]=="Dir":
if not os.path.isdir(i["FileName"]):
return False,3,i["FileName"]
Thing=IsDirFileMD5(i["ChildRen"],i["FileName"],Bind,sleep)
if not Thing[0]:
return False,4,i["FileName"],Thing
return (True,1)
#获取字节对应的大小
def ConvertSize(size_bytes):
if size_bytes == 0:
return "0B"
size_names = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
i = 0
while size_bytes >= 1024 and i < len(size_names) - 1:
size_bytes /= 1024
i += 1
return str(size_bytes)+str(size_names[i])
#获取所有可用的摄像头设备
def get_available_cameras():
camera_list = []
index = 0
while True:
cap = cv2.VideoCapture(index)
if not cap.read()[0]:
break
else:
camera_list.append(index)
cap.release()
index += 1
return camera_list
#模块组启动程序
class Mod:#模块组结构体
def __init__(self,ChasteGlobalVariables,GlobalVariables,name):
#初始化模块组启动类
#模块组基础配置
self.path="./Module/"+name+"/"
self.path_config=self.path+"config.ini"
self.PersonalGlobal=copy.copy(ChasteGlobalVariables)
self.Global=GlobalVariables
#判断模块组是否存在
if not os.path.isdir(self.path):#如果不存在
raise ReturnFileNotFoundError("Mod Is Not Found",self.path)
#判断模块组配置文件是否存在
if not os.path.isfile(self.path_config):
raise ReturnFileNotFoundError("Mod config.ini Is Not Found",self.path_config)
#判断模块组配置文件是否正确
if not IS_INI(self.path_config):
raise configparser.Error("INI is Error")
self.config=INI2DICT(self.path_config)
#如果模块组配置文件没有所需值
if not "CONFIG" in self.config:
raise configparser.Error("INI is Error")
if not "entry" in self.config["CONFIG"] or not "decode" in self.config["CONFIG"] or not "library" in self.config["CONFIG"]:
raise configparser.Error("INI is Error")
#转存模块组配置文件
self.Entry=self.config["CONFIG"]["entry"]#入口文件
self.Decode=self.config["CONFIG"]["decode"]#解码方式(使用正常编码还是BoxTools.Mod加密编码),Encoding必须是UTF-8,因为Python只支持UTF-8编码
self.Library=self.config["CONFIG"]["library"]+"/"#其他的Py文件,入口文件会调用(子模块)
#判断模块组配置文件转存数据是否正确
if not os.path.isfile(self.path+self.Entry):
raise ReturnFileNotFoundError("Mod Entry Is Not Found",self.path+self.Entry)
if not (self.Decode.lower() == "python" or self.Decode.lower() == "mod"):
raise configparser.Error("INI Decode is Not Found")
if self.Library != "" and not os.path.isdir(self.path+self.Library):
raise ReturnFileNotFoundError("Mod Library Is Not Found",self.Library)
def RunMain(self):
#启动主模块
#读取主模块
#判断加密类型
if self.Decode.lower() == "python":#如果是Python加密类型
code=openr(self.path+self.Entry)#直接读取
elif self.Decode.lower() == "mod":#如果是Mod加密类型
code=GBDS(self.path+self.Entry)#解码读取
else:#没有这个类型
raise UnicodeDecodeError("Decode Is Not Found")#报编码错误
#App.py是和Main.py和所有Mod同步的文件
#这个文件本意是为了让Vs-Code的高亮提示正常显示,但是,不能纳入正常代码运行
#App.py可以理解为"Vs-Code Module Start 高亮修复"
code=code.replace("from App import *","")#删除App.py导入代码(高亮提示修复)
#把Mod启动类添加到Global里面
#创建信息类
Mod_InFo=InFo()
#把数据存到信息类
Mod_InFo.path=self.path
Mod_InFo.path_config=self.path_config
Mod_InFo.config=self.config
Mod_InFo.Entry=self.Entry
Mod_InFo.Decode=self.Decode
Mod_InFo.Library=self.Library
Mod_InFo.code=code
Mod_InFo.RunSub=self.RunSub
Mod_InFo.Global=self.Global
Mod_InFo.PersonalGlobal=self.PersonalGlobal
#存到Global
Global=self.PersonalGlobal
Global["Mod_InFo"]=Mod_InFo
#通过exec启动
exec(code,Global)
def RunSub(self,GlobalVariables,name):
#启动副模块
#读取副模块
#判断加密类型
if self.Decode.lower() == "python":#如果是Python加密类型
code=openr(self.path+self.Library+name)#直接读取
elif self.Decode.lower() == "mod":#如果是Mod加密类型
code=GBDS(self.path+self.Library+name)#解码读取
else:#没有这个类型
raise UnicodeDecodeError("Decode Is Not Found")#报编码错误
#App.py是和Main.py和所有Mod同步的文件
#这个文件本意是为了让Vs-Code的高亮提示正常显示,但是,不能纳入正常代码运行
#App.py可以理解为"Vs-Code Module Start 高亮修复"
code=code.replace("from App import *","")#删除App.py导入代码(高亮提示修复)
#把Mod启动类添加到Global里面
#创建信息类
Mod_InFo=InFo()
#把数据存到信息类
Mod_InFo.path=self.path
Mod_InFo.path_config=self.path_config
Mod_InFo.config=self.config
Mod_InFo.Entry=self.Entry
Mod_InFo.Decode=self.Decode
Mod_InFo.Library=self.Library
Mod_InFo.code=code
Mod_InFo.RunSub=self.RunSub
Mod_InFo.file=self.path+self.Library+name
Mod_InFo.Global=self.Global
Mod_InFo.PersonalGlobal=self.PersonalGlobal
#存到Global
GlobalVariables=self.PersonalGlobal
GlobalVariables["Mod_InFo"]=Mod_InFo
#通过exec启动
exec(code,GlobalVariables)
class Mod_Var():
def __init__(self):
self.Global={}
class FileVarToVar():
def __init__(self,Var):
N2={}
if not type(Var) == type({}):
raise TypeError("Var Not Is Dict")
for i in Var:
if len(i) > 2:
if not i[0:2] == "__":
if not i[-2:] == "__":
N2[i]=Var[i]
self.Global=N2
ToolsGlobalVar=FileVarToVar(globals())
ToolsGlobal=ToolsGlobalVar.Global
def add_to_startup(name,file_path=""):
#By IvanHanloth
if file_path == "":
file_path = os.path.realpath(sys.argv[0])
auth="IvanHanloth"
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run",winreg.KEY_SET_VALUE, winreg.KEY_ALL_ACCESS|winreg.KEY_WRITE|winreg.KEY_CREATE_SUB_KEY)#By IvanHanloth
winreg.SetValueEx(key, name, 0, winreg.REG_SZ, file_path)
winreg.CloseKey(key)
def remove_from_startup(name):
auth="IvanHanloth"
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run", winreg.KEY_SET_VALUE, winreg.KEY_ALL_ACCESS|winreg.KEY_WRITE|winreg.KEY_CREATE_SUB_KEY)#By IvanHanloth
try:
winreg.DeleteValue(key, name)
except FileNotFoundError:
print(f"{name} not found in startup.")
else:
print(f"{name} removed from startup.")
winreg.CloseKey(key)
def install_font(font_path):
# 获取字体文件的目录和文件名
directory, filename = os.path.split(font_path)
# 注册字体
font_reg_key = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts", 0, win32con.KEY_ALL_ACCESS)
win32api.RegSetValueEx(font_reg_key, filename, 0, win32con.REG_SZ, font_path)
win32api.RegCloseKey(font_reg_key)
# 刷新系统的字体缓存
win32gui.SendMessageTimeout(win32con.HWND_BROADCAST, win32con.WM_FONTCHANGE, 0, 0, win32con.SMTO_ABORTIFHUNG, 100)
def uninstall_font(font_name):
# 删除注册表中对应的字体键值
font_reg_key = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts", 0, win32con.KEY_ALL_ACCESS)
win32api.RegDeleteKeyEx(font_reg_key, font_name, win32con.KEY_ALL_ACCESS)
win32api.RegCloseKey(font_reg_key)
# 刷新系统的字体缓存
win32gui.SendMessageTimeout(win32con.HWND_BROADCAST, win32con.WM_FONTCHANGE, 0, 0, win32con.SMTO_ABORTIFHUNG, 100)
def create_lnk(bin_path: str, name: str, desc: str):
try:
shortcut = os.path.join(winshell.desktop(), name + ".lnk")
winshell.CreateShortcut(
Path=shortcut,
Target=bin_path,
Icon=(bin_path, 0),
Description=desc
)
return True
except ImportError as err:
print("Well, do nothing as 'winshell' lib may not available on current os")
print("error detail %s" % str(err))
return False
def create_app_registry_entry(display_name, publisher, remark,
install_location, exe_path, icon_path,
uninstall_path, version, EstimatedSize,
ModifyPath, ProductID, RegOwner,
RegCompany, HelpLink, HelpTelephone,
URLUpdateInfo, URLInfoAbout, VersionMajor,
VersionMinor, NoModify, NoRepair):
#将App注册到系统
#请使用管理员方式运行
#display_name = App名称
#publisher = 发布者名称
#remark = 备注
#install_location = App目录
#exe_path = App可执行文件路径
#icon_path = App图标
#uninstall_path = App卸载可执行文件路径
#version = App显示版本
#EstimatedSize = App文件估摸大小(字节)
#ModifyPath = App修复系统可执行文件路径
#ProductID = App产品ID
#RegOwner = App注册拥有者
#RegCompany = App注册公司
#HelpLink = App网站链接
#HelpTelephone = App技术支持电话
#URLUpdateInfo = App软件更新下载链接
#URLInfoAbout = App主页链接
#VersionMajor(DWORD) = App主版本号
#VersionMinor(DWORD) = App副版本号
#NoModify(DWORD) = 如果卸载程序没有修改应用程序的选项(写1)
#NoRepair(DWORD) = 如果卸载程序没有修复应用程序的选项(写1)
# 打开软件注册表项
software_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE")
app_key = winreg.CreateKey(software_key, "Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + display_name)
# 设置注册表项的值
winreg.SetValueEx(app_key, "DisplayName", 0, winreg.REG_SZ, display_name)
winreg.SetValueEx(app_key, "Comments", 0, winreg.REG_SZ, remark)
winreg.SetValueEx(app_key, "Publisher", 0, winreg.REG_SZ, publisher)
winreg.SetValueEx(app_key, "InstallLocation", 0, winreg.REG_SZ, install_location)
winreg.SetValueEx(app_key, "UninstallString", 0, winreg.REG_SZ, exe_path)
winreg.SetValueEx(app_key, "QuietUninstallString", 0, winreg.REG_SZ, uninstall_path)
winreg.SetValueEx(app_key, "DisplayIcon", 0, winreg.REG_SZ, icon_path)
winreg.SetValueEx(app_key, "DisplayVersion", 0, winreg.REG_SZ, version)
winreg.SetValueEx(app_key, "EstimatedSize", 0, winreg.REG_DWORD, EstimatedSize)
winreg.SetValueEx(app_key, "ModifyPath", 0, winreg.REG_SZ, ModifyPath)
winreg.SetValueEx(app_key, "ProductID", 0, winreg.REG_SZ, ProductID)
winreg.SetValueEx(app_key, "RegOwner", 0, winreg.REG_SZ, RegOwner)
winreg.SetValueEx(app_key, "RegCompany", 0, winreg.REG_SZ, RegCompany)
winreg.SetValueEx(app_key, "HelpLink", 0, winreg.REG_SZ, HelpLink)
winreg.SetValueEx(app_key, "HelpTelephone", 0, winreg.REG_SZ, HelpTelephone)
winreg.SetValueEx(app_key, "URLUpdateInfo", 0, winreg.REG_SZ, URLUpdateInfo)
winreg.SetValueEx(app_key, "URLInfoAbout", 0, winreg.REG_SZ, URLInfoAbout)
winreg.SetValueEx(app_key, "VersionMajor", 0, winreg.REG_DWORD, VersionMajor)
winreg.SetValueEx(app_key, "VersionMinor", 0, winreg.REG_DWORD, VersionMinor)
winreg.SetValueEx(app_key, "NoModify", 0, winreg.REG_DWORD, NoModify)
winreg.SetValueEx(app_key, "NoRepair", 0, winreg.REG_DWORD, NoRepair)
# 关闭注册表项
winreg.CloseKey(app_key)
winreg.CloseKey(software_key)