尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

python-AEL-update

python-AEL-update # -*- coding: utf-8 -*- ael_updater.py - ADS AEL 插件在线更新工具 作用: 1. 读取本地 AEL 脚本中的版本关键字 (AEL_UPDATE_DATE) 2. 从远程固定文件夹获取同名新版 AEL, 读取其版本关键字 3. 比较版本: 本地 远程 可更新 (把远程 AEL 复制/下载并覆盖本地) 4. 提供 tkinter 弹窗: 显示 当前版本 / 最新版本, 带 更新 和 确认 按钮 远程文件夹支持三种写法 (在 AEL 的 SP_UPD_REMOTE 配置): - HTTP(S): http://192.168.1.100/updates (用 urllib 下载) - 网络共享: \\\\server\\share\\updates (UNC 路径, 直接复制) - 本机路径: D:\\updates (直接复制) 命令行用法: python ael_updater.py gui local_ael [remote] # 弹窗模式 (AEL 调用) python ael_updater.py check local_ael [remote] # 仅检查, 打印状态 python ael_updater.py update local_ael [remote] # 直接更新 (无弹窗) python ael_updater.py --help 只用标准库, 兼容 ADS 自带 Python 3.8.8 (含 tkinter)。 importosimportreimportsysimporturllib.requestimporturllib.error# 版本关键字: AEL 脚本中形如 decl AEL_UPDATE_DATE 2026-08-30;KEYWORDAEL_UPDATE_DATE# 默认远程目录 (仅当命令行没传 remote 时使用; 留空则必须由命令行/AEL 传入)REMOTE# 远程获取超时 (秒)FETCH_TIMEOUT30# ---------------------------------------------------------------------------# 工具函数# ---------------------------------------------------------------------------deffind_date(text):在 AEL 源码文本中查找版本关键字的值。找不到返回 。patre.compile(r\bdecl\sre.escape(KEYWORD)r\s*\s*([^]*))mpat.search(text)returnm.group(1).strip()ifmelsedefread_local_date(path):读取本地 AEL 文件的版本关键字值。try:withopen(path,r,encodingutf-8,errorsreplace)asf:returnfind_date(f.read())exceptException:returndeffetch_remote(path,remote):从远程目录获取与本地同名的新版 AEL, 返回 (bytes, 来源描述)。 remote 支持 http(s):// 或文件系统路径 (UNC / 本机)。 filenameos.path.basename(path)ifnotfilename:raiseValueError(无法从本地路径得到文件名: %s%path)lowremote.strip().lower()iflow.startswith(http://)orlow.startswith(https://):urlremote.rstrip(/)/filename requrllib.request.Request(url,headers{User-Agent:ADS-AEL-Updater/1.0})withurllib.request.urlopen(req,timeoutFETCH_TIMEOUT)asresp:returnresp.read(),urlelse:srcos.path.join(remote,filename)withopen(src,rb)asf:returnf.read(),srcdefcompare_dates(a,b):比较两个版本值。返回: -1 a 旧于 b (需要更新) 0 相等 1 a 新于 b a(aor).strip()b(bor).strip()ifnotaandnotb:return0ifnota:return-1# 本地无版本 视为旧ifnotb:return1# 1) 尝试按日期 (YYYY-MM-DD / YYYY/MM/DD)try:importdatetime da_parse_date(a)db_parse_date(b)ifdaisnotNoneanddbisnotNone:return-1ifdadbelse(1ifdadbelse0)exceptException:pass# 2) 尝试按数值try:nafloat(a)nbfloat(b)return-1ifnanbelse(1ifnanbelse0)exceptException:pass# 3) 字符串字典序return-1ifabelse(1ifabelse0)def_parse_date(s):importdatetime ss.strip()forfmtin(%Y-%m-%d,%Y/%m/%d,%Y%m%d,%Y-%m-%d %H:%M:%S):try:returndatetime.datetime.strptime(s,fmt)exceptValueError:continuereturnNonedefstatus_text(local,remote):根据两个版本值生成状态说明。ccompare_dates(local,remote)ifc0:return发现新版本点击\更新\完成升级。ifc0:return已是最新版本。return本地版本比远程更新。# ---------------------------------------------------------------------------# tkinter 弹窗# ---------------------------------------------------------------------------defrun_gui(local_path,remote):版本检查 弹窗。本地较旧且远程可读时允许点击更新。importtkinterastkfromtkinterimportttk,messagebox localread_local_date(local_path)latesterrremote_dataNoneifnotremoteornotremote.strip():err远程目录未配置请先在 AEL 配置 SP_UPD_REMOTE。else:try:remote_data,srcfetch_remote(local_path,remote)latestfind_date(remote_data.decode(utf-8,replace))ifnotlatest:err(远程文件读取成功但未找到 %s 关键字。%KEYWORD)excepturllib.error.HTTPErrorase:err无法获取远程文件 (HTTP %s): %s%(e.code,e.reason)exceptExceptionase:err无法获取远程文件: %s%e need(noterr)andcompare_dates(local,latest)0roottk.Tk()root.title(ADS 插件更新检查)root.resizable(False,False)framettk.Frame(root,padding15)frame.pack(fillboth,expandTrue)ttk.Label(frame,text当前版本: %s%(localor(未找到))).grid(row0,column0,stickyw,pady4)ttk.Label(frame,text最新版本: %s%(latestor(未知))).grid(row1,column0,stickyw,pady4)iferr:status错误: errelse:statusstatus_text(local,latest)ttk.Label(frame,textstatus,foreground#c00000iferrelse#1a7a00).grid(row2,column0,stickyw,pady(8,4))defdo_update():nonlocalremote_dataifremote_dataisNone:returntry:withopen(local_path,wb)asf:f.write(remote_data)root.destroy()messagebox.showinfo(更新完成,新版本已覆盖到:\n%s\n\n请重启 ADS 以完成加载。%local_path)exceptExceptionase:messagebox.showerror(更新失败,无法覆盖本地文件: %s%e)btn_framettk.Frame(frame)btn_frame.grid(row3,column0,pady(14,0))upd_btnttk.Button(btn_frame,text更新,commanddo_update)upd_btn.pack(sideleft,padx6)ifnotneed:upd_btn.configure(statedisabled)ttk.Button(btn_frame,text确认,commandroot.destroy).pack(sideleft,padx6)root.mainloop()return0# ---------------------------------------------------------------------------# 无弹窗模式 (调试 / 命令行)# ---------------------------------------------------------------------------defmode_check(local_path,remote):localread_local_date(local_path)try:data,srcfetch_remote(local_path,remote)latestfind_date(data.decode(utf-8,replace))errexceptExceptionase:latesterrstr(e)print(CURRENT%s%(localor))print(LATEST%s%(latestor))print(STATUS%s%(erroriferrelse(updateifcompare_dates(local,latest)0elseok)))iferr:print(ERROR%s%err)return0defmode_update(local_path,remote):localread_local_date(local_path)data,srcfetch_remote(local_path,remote)latestfind_date(data.decode(utf-8,replace))ifcompare_dates(local,latest)0:withopen(local_path,wb)asf:f.write(data)print(UPDATED from %s to %s - %s%(local,latest,local_path))else:print(NO_UPDATE current%s latest%s%(local,latest))return0defusage():print(__doc__)print(用法:)print( python ael_updater.py gui local_ael [remote])print( python ael_updater.py check local_ael [remote])print( python ael_updater.py update local_ael [remote])defmain(argvNone):argvargvifargvisnotNoneelsesys.argv[1:]ifnotargvorargv[0]in(-h,--help,help):usage()return0modeargv[0]local_pathargv[1]iflen(argv)1elseremoteargv[2]iflen(argv)2elseREMOTEifnotlocal_pathornotos.path.isfile(local_path):print(错误: 本地 AEL 文件不存在: %s%local_path)return1ifmodegui:returnrun_gui(local_path,remote)ifmodecheck:returnmode_check(local_path,remote)ifmodeupdate:returnmode_update(local_path,remote)usage()return1if__name____main__:sys.exit(main())
返回列表