Files

160 lines
5.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ==============================================
# =============== Linux系统API ===============
# ==============================================
import os
import shlex
import subprocess
from PySide2.QtCore import QStandardPaths as Qsp
from umi_log import logger
from umi_about import UmiAbout
# ==================== 快捷方式 ====================
class _Shortcut:
@staticmethod
def _getPath(position): # 获取路径
# 桌面
if position == "desktop":
return Qsp.writableLocation(Qsp.DesktopLocation)
# 开始菜单
if position == "startMenu":
return Qsp.writableLocation(Qsp.ApplicationsLocation)
# 开机自启 TODO
elif position == "startup":
raise ValueError("Linux 暂不支持自动添加开机自启。请手动设置。")
# 创建快捷方式返回成功与否的字符串。position取值
# desktop 桌面
# startMenu 开始菜单
# startup 开机自启
@staticmethod
def createShortcut(position):
if position == "startup": # TODO
return "[Warning] Linux 暂不支持自动添加开机自启。请手动设置。\nAutomatically adding startup functions is not supported at this time. Please set it manually."
try:
lnkName = UmiAbout["name"]
appPath = UmiAbout["app"]["path"]
appDir = UmiAbout["app"]["dir"]
if not appPath:
return f"[Error] 未找到程序入口文件。请尝试手动创建快捷方式。\n[Error] Umi-OCR app path not exist. Please try creating a shortcut manually.\n\n{appPath}"
lnkPathBase = _Shortcut._getPath(position)
lnkPathBase = os.path.join(lnkPathBase, lnkName)
lnkPath = lnkPathBase + ".desktop"
i = 1
while os.path.exists(lnkPath): # 快捷方式已存在
lnkPath = lnkPathBase + f" ({i}).desktop" # 添加序号
i += 1
except Exception as e:
return f"[Error] 无法获取应用信息。\n[Error] Unable to obtain application information.\n\n{e}"
# 快捷方式 文件内容
desktop_entry = f"""
[Desktop Entry]
Version={UmiAbout["version"]["string"]}
Type=Application
Name={lnkName}
Exec={appPath}
Path={appDir}
Icon={appDir}/UmiOCR-data/qt_res/images/icons/umiocr.ico
Terminal=false
"""
try:
with open(lnkPath, "w") as f:
f.write(desktop_entry)
os.chmod(lnkPath, 0o755) # 赋予执行权限
logger.info(f"创建快捷方式: {lnkPath}")
return "[Success]"
except Exception as e:
return f"[Error] 创建快捷方式失败。\n[Error] Failed to create shortcut.\n {lnkPath}: {e}"
# 删除快捷方式,返回删除文件的个数
@staticmethod
def deleteShortcut(position):
try:
appName = UmiAbout["name"]
lnkDir = _Shortcut._getPath(position)
except Exception:
logger.error("无法获取应用信息", exc_info=True, stack_info=True)
return 0
num = 0
for fileName in os.listdir(lnkDir):
try:
lnkPath = os.path.join(lnkDir, fileName)
if not os.path.isfile(lnkPath): # 排除非文件
continue
if fileName.startswith(appName) and fileName.endswith(".desktop"):
os.remove(lnkPath)
num += 1
logger.info(f"删除快捷方式: {lnkPath}")
except Exception:
logger.error(
f"删除快捷方式失败。 lnkPath: {lnkPath}",
exc_info=True,
stack_info=True,
)
continue
return num
# ==================== 硬件控制 ====================
class _HardwareCtrl:
# 关机
@staticmethod
def shutdown():
# TODO: sudo权限
os.system("sudo shutdown -h now")
# 休眠
@staticmethod
def hibernate():
os.system("sudo systemctl hibernate")
# ==================== 对外接口 ====================
class Api:
# 快捷方式。接口: createShortcut deleteShortcut
# 参数:快捷方式位置, desktop startMenu startup
Shortcut = _Shortcut()
# 硬件控制。接口: shutdown hibernate
HardwareCtrl = _HardwareCtrl()
# TODO: 根据系统及硬件,判断最适合的渲染器类型
@staticmethod
def getOpenGLUse():
return "AA_UseOpenGLES" # 默认使用GLES。
# return "AA_UseSoftwareOpenGL" # 如果不兼容?则使用软渲染
# 键值转键名
@staticmethod
def getKeyName(key):
# 传入 pynput 按键事件对象,返回键名字符串
if not isinstance(key, str):
key = str(key)
if not key: # 错误,未获取键值
return "unknown"
if key.startswith("'") and key.endswith("'"): # 去除自带引号
key = key[1:-1]
if key.startswith("Key."): # 修饰建
key = key[4:]
if not key: # 再检查一次
return "unknown"
return key
# 让系统运行一个程序,不堵塞当前进程
@staticmethod
def runNewProcess(path, args=""):
# TODO: 测试、完善
command_line = [path] + shlex.split(args)
subprocess.Popen(command_line)
# 用系统默认应用打开一个文件或目录,不堵塞当前进程
@staticmethod
def startfile(path):
os.startfile(path)