Initial commit with README

This commit is contained in:
GVSADS
2026-01-25 17:01:16 +08:00
commit 246bbd8fd9
106 changed files with 2071 additions and 0 deletions

34
sys/kernel/AskDuc.md Normal file
View File

@@ -0,0 +1,34 @@
# MikOs 文档
## 1.文件目录结构
文件目录结构大多数借用Linux操作系统文件目录结构,但有有所不同,具体如下
文件结构:
|文件深度1|文件深度2|文件深度3|文件深度4|类型|文件解释|
|:-|:-|:-|:-|:-|:-|
|\_\_pycache\_\_/||||目录|Python导入文件|
|home||||目录|用户组文件|
|home/|root/|||目录|默认用户|
|home/|root/|PASSWD||文件|用户密码|
|home/|root/|Desktop||目录|用户桌面文件夹|
|sys/||||目录|操作系统文件|
|sys/|\_\_pycache\_\_/|||目录|Python导入文件|
|sys/|config/|||目录|操作系统配置|
|sys/|config/|config.json||目录|操作系统配置|
|sys/|images.mik/|||目录|操作系统桌面显示图标|
|sys/|kernel/|||目录|操作系统内核文件|
|sys/|kernel/|\_\_pycache\_\_/||目录|Python导入文件|
|sys/|kernel/|login.py||文件|操作系统登录程序|
|sys/|kernel/|main.pyw||文件|操作系统内核程序|
|sys/|kernel/|mount.py||文件|操作系统虚拟挂载程序|
|sys/|kernel/|tools.py||文件|操作系统辅助功能程序|
|sys/|kernel/|UI.py||文件|操作系统UI程序|
|sys/|lib/|||目录|操作系统级程序目录|
|sys/|tkinter.mik/|||目录|tkinter辅助程序和图标|
|sys/|ui.mik/|||目录|操作系统UI辅助程序和图标|
|sys/|wallpaper/|||目录|操作系统壁纸文件夹|
|usr/||||目录|功能文件|
|usr/|bin/|||目录|MikDos命令行程序|
|usr/|sbin/|||目录|MikDos命令行Root程序|
|usr/|local/|||目录|用户级程序|

183
sys/kernel/UI.py Normal file
View File

@@ -0,0 +1,183 @@
from tools import *
TasksFrame=""
ui_mik=""
tkinter_mik=""
master=""
def index(root,W,H):
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
width = W
height = H
left = (screenWidth - width) / 2
top = (screenHeight - height) / 2
root.geometry("%dx%d+%d+%d" % (width, height, left, top))
def index100(root,W,H):
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
width = W
height = H
left = (screenWidth - width) / 2
top = (screenHeight - height) / 2 - 100
root.geometry("%dx%d+%d+%d" % (width, height, left, top))
def index50(root,W,H):
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
width = W
height = H
left = (screenWidth - width) / 2
top = (screenHeight - height) / 2 - 50
root.geometry("%dx%d+%d+%d" % (width, height, left, top))
class Menu(tk.Frame):
def __init__(self,master):
if hasattr(master,"Widget"):
master=master.Widget
super().__init__(master,bg="#FFF",highlightbackground="#fed79e")
self.pack(fill=tk.X,anchor="sw",side="top")
self.subs=[]
def add_sub(self,label,menu=tk.Menu,font=("微软雅黑",10)):
sub=tk.Button(self,text=label+" "*3,bg="#FFF",fg="#000",font=font,bd=0)
sub.pack(side=tk.LEFT)
sub.config(command=lambda:self.Choose(sub,menu))
menu.config(bg="#FFF")
self.subs.append([sub,menu])
def Choose(self,subutton=tk.Button,menu=tk.Menu):
root_x = self.master.winfo_rootx()
root_y = self.master.winfo_rooty()
x = subutton.winfo_x() + root_x
y = subutton.winfo_y() + subutton.winfo_height() + root_y
menu.post(x, y)
class Window(tk.Toplevel):
def __init__(self,title="MikOs - NewWindow",geometry="700x500"):
super().__init__()
index(self,1000,600)
self.TasksFrame=TasksFrame
self.withdraw()
self.geometry(geometry)
self.overrideredirect(True)
self.config(bg="#FFF")
self.focus()
self.wm_attributes("-topmost",True)
self.Title=tk.Frame(self,bg="#FFF",highlightbackground="#fed79e")
self.Title.pack(fill=tk.X)
self.TitleTextSpace1=tk.Label(self.Title,text=" ",fg="#FFF",bg="#FFF")
self.TitleTextSpace1.pack(side=tk.LEFT)
self.TitleICOImage=ImageTk.PhotoImage(Image.open(tkinter_mik+"ICO.png"))
self.TitleICO=tk.Label(self.Title,image=self.TitleICOImage,fg="#FFF",bg="#FFF")
self.TitleICO.pack(side=tk.LEFT)
self.TitleTextSpace2=tk.Label(self.Title,text=" ",fg="#FFF",bg="#FFF")
self.TitleTextSpace2.pack(side=tk.LEFT)
self.TitleText=tk.Label(self.Title,text=title,bg="#FFF",fg="#000",font=("字魂59号-创粗黑",12))
self.TitleText.pack(side=tk.LEFT)
self.TitleTextSpace3=tk.Label(self.Title,text=" ",fg="#FFF",bg="#FFF")
self.TitleTextSpace3.pack(side=tk.LEFT)
self.Widget=tk.Frame(self,bg="#FFF",highlightbackground="#fed79e")
self.Widget.pack(fill="both",expand=True)
self.ExitImg = ImageTk.PhotoImage(Image.open(ui_mik+"close_100.png"))
self.Exit = tk.Button(self.Title, bg=self.Title.cget("bg"), bd=0, width=40, relief=tk.FLAT, activebackground="#C42B1C",image=self.ExitImg,command=self.destroy)
self.Exit.bind("<Enter>", lambda _: self.Exit.config(background="#dd0009"))
self.Exit.bind("<Leave>", lambda _: self.Exit.config(background=self.Title.cget("bg") if self.focus else "#797979"))
self.Exit.pack(fill=tk.Y, side=tk.RIGHT)
def ComMax():
self.wm_state("zoomed")
self.Max.config(image=self.MaxSmallImg,command=ComMaxSmall)
self.Title.bind("<Double-Button-1>", lambda event:ComMaxSmall())
def ComMaxSmall():
self.wm_state("normal")
self.Max.config(image=self.MaxImg,command=ComMax)
self.Title.bind("<Double-Button-1>", lambda event:ComMax())
self.EmbedParentWindow()
self.MaxImg = ImageTk.PhotoImage(Image.open(ui_mik+"fullwin_100.png"))
self.MaxSmallImg = ImageTk.PhotoImage(Image.open(ui_mik+"togglefull_100.png"))
self.Max = tk.Button(self.Title, bg=self.Title.cget("bg"), bd=0, width=40, relief=tk.FLAT, activebackground="#ebedf1",image=self.MaxImg,command=ComMax)
self.Max.bind("<Enter>", lambda _: self.Max.config(background="#f2efef"))
self.Max.bind("<Leave>", lambda _: self.Max.config(background=self.Title.cget("bg") if self.focus else "#797979"))
self.Max.pack(fill=tk.Y, side=tk.RIGHT)
self.Title.bind("<Double-Button-1>", lambda event:ComMax())
self.MinImg = ImageTk.PhotoImage(Image.open(ui_mik+"minisize_100.png"))
self.Min = tk.Button(self.Title, bg=self.Title.cget("bg"), bd=0, width=40, relief=tk.FLAT, activebackground="#ebedf1",image=self.MinImg,command=self.stateicon)
self.Min.bind("<Enter>", lambda _: self.Min.config(background="#f2efef"))
self.Min.bind("<Leave>", lambda _: self.Min.config(background=self.Title.cget("bg") if self.focus else "#797979"))
self.Min.pack(fill=tk.Y, side=tk.RIGHT)
if type(self.TasksFrame) == type(self.Title):
self.TaskICOImage=ImageTk.PhotoImage(Image.open(ui_mik+"text_file.png").resize([15,15]))
self.TaskICO=tk.Button(self.TasksFrame,image=self.TaskICOImage,bg=TasksFrame.cget("bg"),fg="#000",bd=0,command=self.statenor)
self.TaskICO.pack(side=tk.LEFT)
self.MoveBind()
self.EmbedParentWindow()
self.deiconify()
def MoveBind(self):
x=0
y=0
def start_move(event):
nonlocal x, y
x = event.x
y = event.y
def stop_move(event):
nonlocal x, y
x = None
y = None
def on_motion(event):
nonlocal x, y
deltax = event.x - x
deltay = event.y - y
self.geometry(f"+{self.winfo_x() + deltax}+{self.winfo_y() + deltay}")
self.update()
self.Title.bind("<ButtonPress-1>", start_move)
self.Title.bind("<ButtonRelease-1>", stop_move)
self.Title.bind("<B1-Motion>", on_motion)
self.TitleText.bind("<ButtonPress-1>", start_move)
self.TitleText.bind("<ButtonRelease-1>", stop_move)
self.TitleText.bind("<B1-Motion>", on_motion)
def destroy(self):
if type(self.TasksFrame) == type(self.Title):
self.TaskICO.destroy()
super().destroy()
def stateicon(self):
self.wm_overrideredirect(False)
self.wm_state("icon")
def statenor(self):
if self.wm_state() != "normal":
self.EmbedParentWindow()
self.wm_overrideredirect(True)
self.wm_state("normal")
self.wm_attributes("-topmost",True)
else:
self.stateicon()
@asyncs
def EmbedParentWindow(self):
#while True:
# if master:
# u32.SetParent(u32.GetParent(self.winfo_id()),master.winfo_id())
# time.sleep(1)
for i in range(10):
u32.SetParent(u32.GetParent(self.winfo_id()),master.winfo_id())

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

41
sys/kernel/login.py Normal file
View File

@@ -0,0 +1,41 @@
from tools import *
class login(tk.Frame):
def __init__(self,master,bg="./sys/wallpaper/森林1.png",width=1000,height=900,callback=lambda x,y:print(x,y),e=True):
super().__init__(master=master)
self.bg=bg
self.width=width
self.height=height
self.callback=callback
self.e=e
self.pack(fill="both",expand=True)
self.layer = tk.Canvas(self)
self.layer.pack(fill="both",expand=True)
self.tranimg = Image.open('./sys/wallpaper/translucent.png')
self.tranimg = self.tranimg.resize((width-20,height-20))
self.tranimg = ImageTk.PhotoImage(self.tranimg)
self.bgimg = Image.open(bg)
self.bgimg = self.bgimg.resize((width,height))
self.bgimg = ImageTk.PhotoImage(self.bgimg)
self.layer.create_image(0, 0, anchor='nw', image=self.bgimg)
self.layer.create_image(width//2,height//2, image=self.tranimg)
add_xy=0
for i in ["black","dark gray","gray","gray","light gray","white"]:
text=self.layer.create_text(245+add_xy,105+add_xy, text="Welcome to MikOS",font=('arial',25),fill=i)
#(self.layer.bbox(text)[2] - self.layer.bbox(text)[0])
self.layer.move(text, self.width//2-(self.layer.bbox(text)[2] - self.layer.bbox(text)[0])+27.5+add_xy, 0+add_xy)
add_xy+=0.5
self.button = tk.Button(self, text="登录", bg="sky blue", command=self.login,width = 15,overrelief='sunken',bd=4,cursor="hand2",activebackground="sky blue")
self.button.update()
self.button.place(x=self.winfo_width()//2-self.button.winfo_width()//2, y=180, anchor="center")
def login(self):
username="root"
userpwd="ROOT"
if self.e:
self.destroy()
self.callback(username,userpwd)

124
sys/kernel/main.pyw Normal file
View File

@@ -0,0 +1,124 @@
#导入模块
from tools import *
import login
import mount
import UI
#操作系统核心
class System:
def __init__(self):
#临时
self.username="root"
#将程序工作目录改到系统根目录
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
self.ReadConfig()
mount.endMount(self.DiskSite+":")#取消挂载虚拟磁盘,以防止过去的过期记录影响正常挂载
if not mount.Mount("\\".join(os.getcwd().split("\\")[:-2]),self.DiskSite+":"):#挂载虚拟磁盘如果返回值为False表示错误加not变为True运行If语句内容
print("EFI: Error, Mount DiskSite "+self.DiskSite+" not true")#输出虚拟磁盘挂载错误信息
os._exit(0)#补上的,如果运行失败程序需要停止运行
os.chdir(self.DiskSite+":")#将目录转移至虚拟磁盘
self.root = tk.Tk()
self.root.title('MikOS')
# 通过config.json个性化窗口
for i in self.config["res"]["set"]:
if i == "full":
self.root.state("zoomed")
elif i == "overrideredirect":
self.root.overrideredirect(True)
else:
print(f"Error: {i} no know")
UI.index(self.root,self.width,self.height)
self.root.update()
self.StartSysApp("explorer","__init__.mia")
self.root.protocol("WM_DELETE_WINDOW",self.CloseEvent)
self.root.mainloop()
def ReadConfig(self):
#获取配置文件
self.config=json.loads(openr("../config/config.json")) #全部配置句柄
self.width=self.config["res"]["width"] #窗口长
self.height=self.config["res"]["height"] #窗口宽
self.chicun=str(self.width)+"x"+str(self.height) #窗口长宽(可直接应用到self.root.geometry)
self.EFI=self.config["EFI"] #引导(EFI)配置句柄
self.Kernel=self.config["Kernel"] #内核(Kernel)配置句柄
self.DOS=self.config["DOS"] #命令行(DOS)配置句柄
self.DiskSite=self.EFI["DiskSite"] #虚拟磁盘挂载地址
self.BootSite=self.EFI["BootSite"] #操作系统程序文件所在
self.SysAppSite=self.BootSite+self.Kernel["SysAppSite"] #系统级程序文件所在
self.NorAppSite=self.Kernel["NorAppSite"] #全局用户级程序文件所在
self.ui_mik=self.BootSite+self.Kernel["ui"] #MikOs窗口图标文件所在
self.images_mik=self.BootSite+self.Kernel["images"] #MikOs桌面图标文件所在
self.tkinter_mik=self.BootSite+self.Kernel["tkinter"] #MikOs-Tkinter支持文件所在
UI.ui_mik=self.ui_mik #将MikOs窗口图标文件所在注册到UI
UI.tkinter_mik=self.tkinter_mik #将MikOs-Tkinter支持文件所在注册到UI
self.UsersSite=self.Kernel["UsersSite"] #用户组文件所在
self.bg=self.BootSite+self.config["bg"]["sys"] #桌面壁纸
self.suffixs=self.config["suffixs"] #文件图标后缀关联
self.filesuffixs=self.config["filesuffixs"] #文件名称图标关联(无后缀但需显示图标文件)(如:MakeFile)
self.color=self.config["color"] #主题色配置句柄
self.SysFileSuffixMapping=self.config["SysFileSuffixMapping"] #文件功能后缀关联
def CloseEvent(self):#关闭事件
if tm.askokcancel('MikOS:提示','确认要关闭MikOS吗?'):
os._exit(0)
def ERROR(self,WrongDevice,IOFlowErrorMessage,DebuggerApp,MemoryAddresss,EndMemoryAddress):
ERROR=tk.Frame(self.root,bg="#000")
ERROR.place(x=0,y=0)
def Text(text):
tk.Label(ERROR,text=text,fg="#FFF",bg="#000",font=("Moder DOS 437",15)).pack(anchor="sw")
def FText():
tk.Label(ERROR,text="",bg="#000",font=("Moder DOS 437",15)).pack(anchor="sw")
Text("There are some problems with your MikOS,")
Text("This may come from MikOs itself or some of its settings,")
Text("Python version problems, Or because of your own external operating system,")
Text("In short, MikOs has an error, We are not sure if the program can still run normally,")
Text("So we interrupted the program, But there may be some subprograms that have not")
Text("stopped completely, We can only do it here, the following are some error prompts")
FText()
Text(f'Error({WrongDevice}): "{IOFlowErrorMessage}"')
Text(f"Debugger Called: <{DebuggerApp}>")
Text("Specific Error Points:")
for i in MemoryAddresss:Text(f"{i[0]} : {i[1]} ()")
Text(f"Error Terminated At {{EndMemoryAddress}} Memory Pointer")
FText()
Text("Operating System Has Been Terminated")
FText()
Text("Kernel version:")
Text(f"MikOS Kernel V{self.Kernel['VerSion']} / EFI Boot System V{self.EFI['VerSion']}")
FText()
FText()
FText()
def StartSysApp(self,appname,file,*args,**kw):
self.global_dict=globals()
self.global_dict["args"]=args
self.global_dict["kw"]=kw
self.global_dict["app_info"]={"path":self.SysAppSite+"/"+appname+"/"}
self.global_dict["OperatingSystemHandle"]=self
code=openr(self.global_dict["app_info"]["path"]+file)
exec(code,self.global_dict)
def StartApp(self,appname,file,*args,**kw):
self.global_dict=globals()
self.global_dict["args"]=args
self.global_dict["kw"]=kw
self.global_dict["app_info"]={"path":self.NorAppSite+"/"+appname+"/"}
self.global_dict["OperatingSystemHandle"]=self
code=openr(self.global_dict["app_info"]["path"]+file)
exec(code,self.global_dict)
def StartFile(self,File=str,*args):
if os.path.isfile(File):
if (suffix := File.split(".")[-1].lower()) in self.SysFileSuffixMapping:
self.StartSysApp(self.SysFileSuffixMapping[suffix],"__init__.mia",f=File,*args)
#免登录
#login.login(root,bg=BootSite+config["bg"]["login"],width=root.winfo_width(),height=root.winfo_height(),callback=verifylogin)
System()
s=tk.Tk()#堵塞进程
s.withdraw()
s.mainloop()

16
sys/kernel/mount.py Normal file
View File

@@ -0,0 +1,16 @@
import os
def Mount(dir,Note):
get=os.popen(f"subst {Note} {dir}").read()
if get==f"无效参数 - {Note}\n":
return "error:Note"
elif get==f"找不到路径 - {dir}\n":
return "error:dir"
else:
return True
def endMount(Note):
get=os.popen(f"subst {Note} /d").read()
if get==f"无效参数 - {Note}\n":
return "error:Note"
else:
return True

321
sys/kernel/tools.py Normal file
View File

@@ -0,0 +1,321 @@
#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 ctypes
import wmi
u32=ctypes.windll.user32
#文件库
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 pystray
#时间库
import datetime,time
#图像库
from PIL import Image,ImageTk,ImageDraw
import cv2
#网页库
import urllib
import flask
import flask_socketio
#数学库
import random
import numpy
import math
import copy
#音频库
import pyaudio
import wave
#基础变量
temp=os.environ["temp"]
#Windows管理接口
WindowsManagementInterface=wmi.WMI()
#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 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
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 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_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