Compare commits

..

No commits in common. "main" and "1.4" have entirely different histories.
main ... 1.4

1 changed files with 56 additions and 75 deletions

View File

@ -1,5 +1,4 @@
import os import os
import sys
import webbrowser import webbrowser
import threading import threading
import tkinter as tk import tkinter as tk
@ -10,7 +9,7 @@ import subprocess
import logging import logging
import requests import requests
logging.basicConfig( # 配置日志记录器 logging.basicConfig(
level=logging.INFO, level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s", format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[ handlers=[
@ -19,17 +18,6 @@ logging.basicConfig( # 配置日志记录器
], ],
) )
proxy = {"http": None, "https": None} # Requests代理设置
def format_size(size): # 格式化文件/目录大小
units = ["B", "KB", "MB", "GB", "TB"]
index = 0
while size >= 1024 and index < len(units) - 1:
size /= 1024.0
index += 1
return f"{size:.2f} {units[index]}"
class FolderScanner(threading.Thread): class FolderScanner(threading.Thread):
def __init__(self, start_path, queue, progress_queue): def __init__(self, start_path, queue, progress_queue):
@ -57,7 +45,7 @@ class FolderScanner(threading.Thread):
self.queue.put((folder_path, size, dirpath, "folder")) self.queue.put((folder_path, size, dirpath, "folder"))
scanned_items += 1 scanned_items += 1
self.update_progress(scanned_items, folder_path) self.update_progress(scanned_items, folder_path)
logging.info(f"扫描目录: {folder_path} 大小: {format_size(size)} ") logging.info(f"扫描目录: {folder_path} 大小: {size} 字节")
for filename in filenames: for filename in filenames:
file_path = os.path.join(dirpath, filename) file_path = os.path.join(dirpath, filename)
@ -65,7 +53,7 @@ class FolderScanner(threading.Thread):
self.queue.put((file_path, size, dirpath, "file")) self.queue.put((file_path, size, dirpath, "file"))
scanned_items += 1 scanned_items += 1
self.update_progress(scanned_items, file_path) self.update_progress(scanned_items, file_path)
logging.info(f"扫描文件: {file_path} 大小: {format_size(size)} ") logging.info(f"扫描文件: {file_path} 大小: {size} 字节")
def get_size(self, path): # 获取文件/目录大小 def get_size(self, path): # 获取文件/目录大小
total_size = 0 total_size = 0
@ -86,7 +74,7 @@ class App(tk.Tk):
def __init__(self, start_path): # 初始化 def __init__(self, start_path): # 初始化
super().__init__() super().__init__()
self.withdraw() self.withdraw()
self.title("目录扫描器 V1.4.3") self.title("目录扫描器 V1.4")
self.start_path = start_path self.start_path = start_path
self.queue = Queue() self.queue = Queue()
self.progress_queue = Queue() self.progress_queue = Queue()
@ -170,34 +158,26 @@ class App(tk.Tk):
def show_help(self): def show_help(self):
messagebox.showinfo( messagebox.showinfo(
"帮助", "帮助",
"1. 双击文件夹可以展开/折叠\n2. 双击文件可以直接打开\n3. 右键单击文件/文件夹可以打开、删除文件/文件夹、进入所在目录\n4. 点击左上角文件菜单可以重新选择目录进行扫描\n5. 点击左上角视图菜单可以根据目录/文件大小、目录/文件名排序、刷新列表\n", "1. 双击文件夹可以展开/折叠\n",
"2. 双击文件可以直接打开\n",
"3. 右键单击文件/文件夹可以打开、删除文件/文件夹、进入所在目录\n",
"4. 点击左上角文件菜单可以重新选择目录进行扫描\n",
"5. 点击左上角视图菜单可以根据目录/文件大小、目录/文件名排序、刷新列表\n",
) )
def show_update_log(self): def show_update_log(self):
repo_owner = "ahdoawhfo" messagebox.showinfo(
repo_name = "SpaceSniffer" "更新日志",
base_url = "https://git.a6.wiki/api/v1/repos" "V1.0 实现了基本的目录扫描、文件/目录大小统计功能\n",
"\n",
try: "V1.1 新增了重新选择目录扫描功能,新增了进度条显示\n",
# 发送 GET 请求获取最新的 Release "\n",
response = requests.get( "V1.2 新增了双击打开目录、文件的功能,实现了右键菜单\n",
f"{base_url}/{repo_owner}/{repo_name}/releases/latest", proxies=proxy "\n",
) "V1.3 优化了界面UI\n",
"\n",
if response.status_code == 200: "V1.4 新增了扫描日志、检查更新功能\n",
release_info = response.json() )
latest_version = release_info["tag_name"]
release_notes = release_info["body"]
messagebox.showinfo(
"更新日志", f"版本: {latest_version}\n\n{release_notes}"
)
else:
messagebox.showinfo(
"更新日志",
f"获取更新日志失败:{response.status_code}",
)
except requests.RequestException as e:
messagebox.showinfo("更新日志", f"获取更新日志时发生错误:{e}")
def show_log(self): def show_log(self):
log_content = self.read_log_file() # 从日志文件中读取日志内容 log_content = self.read_log_file() # 从日志文件中读取日志内容
@ -229,13 +209,16 @@ class App(tk.Tk):
def check_updates(self): def check_updates(self):
# 创建一个新的 UpdateManager 实例,不销毁程序 # 创建一个新的 UpdateManager 实例,不销毁程序
update_manager = UpdateManager(self, is_startup=False) update_manager = UpdateManager(self)
update_manager.check_latest_release() update_manager.check_latest_release()
def show_about(self): def show_about(self):
messagebox.showinfo( messagebox.showinfo(
"关于", "关于",
"一款开源的文件/目录扫描工具\n可以直观地展示目录的文件结构以及文件大小\n\n软件版本 V1.4.3\n作者 ahdoawhfo\n", "一款开源的文件/目录扫描工具\n",
"可以直观地展示目录的文件结构以及文件大小\n",
"软件版本 V1.4\n",
"作者 ahdoawhfo\n",
) )
def on_double_click(self, event): # V1.2 Update当双击的是文件时打开文件 def on_double_click(self, event): # V1.2 Update当双击的是文件时打开文件
@ -255,9 +238,17 @@ class App(tk.Tk):
self.start_path = new_path self.start_path = new_path
self.refresh_tree() self.refresh_tree()
def format_size(self, size): # 格式化文件/目录大小
units = ["B", "KB", "MB", "GB", "TB"]
index = 0
while size >= 1024 and index < len(units) - 1:
size /= 1024.0
index += 1
return f"{size:.2f} {units[index]}"
def populate_root(self): # 初始化根目录 def populate_root(self): # 初始化根目录
size = self.scanner.get_size(self.start_path) size = self.scanner.get_size(self.start_path)
formatted_size = format_size(size) formatted_size = self.format_size(size)
self.tree.insert( self.tree.insert(
"", "",
"end", "end",
@ -277,7 +268,7 @@ class App(tk.Tk):
return return
path, size, parent, tag = item path, size, parent, tag = item
formatted_size = format_size(size) formatted_size = self.format_size(size)
parent_iid = self.get_iid(parent) parent_iid = self.get_iid(parent)
if parent == self.start_path: if parent == self.start_path:
parent_iid = self.start_path parent_iid = self.start_path
@ -466,7 +457,8 @@ class App(tk.Tk):
def on_close(self): # 关闭程序 def on_close(self): # 关闭程序
if self.scanner.is_alive(): if self.scanner.is_alive():
self.scanner.join() self.scanner.join()
sys.exit(0) self.destroy()
root.destroy()
def set_window_size(self): # 设置窗口大小 def set_window_size(self): # 设置窗口大小
screen_width = self.winfo_screenwidth() screen_width = self.winfo_screenwidth()
@ -520,21 +512,20 @@ class ProgressWindow(tk.Toplevel): # 进度窗口
class UpdateManager: class UpdateManager:
def __init__(self, root=None, is_startup=True): def __init__(self, root):
self.root = root self.root = root
self.is_startup = is_startup
def check_latest_release(self): def check_latest_release(self):
# Gitea 仓库信息和当前软件版本 # Gitea 仓库信息和当前软件版本
repo_owner = "ahdoawhfo" repo_owner = "ahdoawhfo"
repo_name = "SpaceSniffer" repo_name = "SpaceSniffer"
base_url = "https://git.a6.wiki/api/v1/repos" base_url = "https://git.a6.wiki/api/v1/repos"
current_version = "1.4.3" # 替换成你的当前软件版本 current_version = "1.4" # 替换成你的当前软件版本
try: try:
# 发送 GET 请求获取最新的 Release # 发送 GET 请求获取最新的 Release
response = requests.get( response = requests.get(
f"{base_url}/{repo_owner}/{repo_name}/releases/latest", proxies=proxy f"{base_url}/{repo_owner}/{repo_name}/releases/latest"
) )
if response.status_code == 200: if response.status_code == 200:
@ -550,25 +541,18 @@ class UpdateManager:
# 打开浏览器到 release 页面 # 打开浏览器到 release 页面
release_url = release_info["html_url"] release_url = release_info["html_url"]
webbrowser.open_new(release_url) webbrowser.open_new(release_url)
if self.is_startup: if self.root:
return False self.destroy()
else: root.destroy()
return True
else: else:
if not self.is_startup: # 仅在用户点击检查更新时显示 self.show_message("检查更新", "当前版本已经是最新版本")
self.show_message("检查更新", "当前版本已经是最新版本")
return True
else: else:
if not self.is_startup: # 仅在用户点击检查更新时显示 self.show_message(
self.show_message( "检查更新",
"获取 Release 失败", f"获取最新 Release 失败:{response.status_code}",
f"获取最新 Release 失败:{response.status_code}", )
)
return True
except requests.RequestException as e: except requests.RequestException as e:
if not self.is_startup: # 仅在用户点击检查更新时显示 self.show_message("检查更新", f"请求最新 Release 时发生错误:{e}")
self.show_message("请求错误", f"请求最新 Release 时发生错误:{e}")
return True
def prompt_update(self, latest_version, release_notes): def prompt_update(self, latest_version, release_notes):
prompt_message = f"检查更新: {latest_version}\n\n更新说明:\n{release_notes}\n\n是否立即更新?" prompt_message = f"检查更新: {latest_version}\n\n更新说明:\n{release_notes}\n\n是否立即更新?"
@ -576,8 +560,7 @@ class UpdateManager:
return choice return choice
def show_message(self, title, message): def show_message(self, title, message):
if self.root: messagebox.showinfo(title, message)
messagebox.showinfo(title, message)
def clear_log_file(): def clear_log_file():
@ -585,23 +568,21 @@ def clear_log_file():
try: try:
with open(log_file, "w", encoding="utf-8") as f: with open(log_file, "w", encoding="utf-8") as f:
f.truncate(0) # 清空文件内容 f.truncate(0) # 清空文件内容
print(f"已清空日志文件 {log_file} 的内容")
except Exception as e: except Exception as e:
messagebox.showinfo("Error", f"清空日志文件内容时发生错误: {e}") print(f"清空日志文件内容时发生错误: {e}")
if __name__ == "__main__": if __name__ == "__main__":
clear_log_file() clear_log_file()
root = tk.Tk() root = tk.Tk()
root.withdraw() root.withdraw()
update_manager = UpdateManager(root, is_startup=True) app = UpdateManager(root)
proceed = update_manager.check_latest_release() app.check_latest_release()
if not proceed:
sys.exit(0)
messagebox.showinfo("提示", "请选择你要扫描的目录")
start_path = filedialog.askdirectory() start_path = filedialog.askdirectory()
if start_path: if start_path:
app = App(start_path) app = App(start_path)
app.mainloop() app.mainloop()
else: else:
messagebox.showinfo("提示", "没有选中任何目录,程序即将退出") messagebox.showinfo("提示", "没有选中任何目录,程序即将退出")
sys.exit(0) root.destroy()