feat: add paperforge setup CLI command, one-click install script, sync __version__ to 1.4.0, detect local version from pip metadata

This commit is contained in:
Research Assistant 2026-04-27 21:34:03 +08:00
parent 94f00e990a
commit 0505fd2fda
6 changed files with 1607 additions and 8 deletions

View file

@ -1,3 +1,3 @@
"""paperforge — PaperForge Lite package."""
__version__ = "1.0.0"
__version__ = "1.4.0"

View file

@ -219,6 +219,9 @@ def build_parser() -> argparse.ArgumentParser:
# update
sub.add_parser("update", help="Update PaperForge Lite to the latest version")
# setup wizard
sub.add_parser("setup", help="Run the setup wizard (Textual-based)")
return parser
@ -358,6 +361,11 @@ def main(argv: list[str] | None = None) -> int:
return run_update(vault)
if args.command == "setup":
from paperforge.setup_wizard import main as run_setup
return run_setup(sys.argv[2:])
print(f"Error: unknown command {args.command}", file=sys.stderr)
return 1

1521
paperforge/setup_wizard.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -265,11 +265,15 @@ def update_via_zip(vault: Path) -> bool:
def run_update(vault: Path) -> int:
"""运行更新检查与安装"""
local_cfg = vault / "paperforge.json"
if not local_cfg.exists():
logger.error("未找到 paperforge.json")
return 1
local = json.loads(local_cfg.read_text(encoding="utf-8")).get("version", "unknown")
try:
from importlib.metadata import version as _pkg_ver
local = _pkg_ver("paperforge")
except Exception:
local_cfg = vault / "paperforge.json"
if local_cfg.exists():
local = json.loads(local_cfg.read_text(encoding="utf-8")).get("version", "unknown")
else:
local = "unknown"
remote = _remote_version()
logger.info("%s", "=" * 50)
logger.info("PaperForge Lite 更新")

View file

@ -0,0 +1,66 @@
param([switch]$Force)
$ErrorActionPreference = "Stop"
$RepoUrl = "https://github.com/LLLin000/PaperForge.git"
Write-Host "=== PaperForge Lite 一键安装 ===" -ForegroundColor Cyan
Write-Host ""
# 检查 Python
try {
$py = (Get-Command python -ErrorAction Stop).Source
Write-Host "[OK] Python: $((python --version))" -ForegroundColor Green
} catch {
Write-Host "[FAIL] 未找到 Python请先安装 https://www.python.org/downloads/" -ForegroundColor Red
exit 1
}
# 检查 pip
try {
python -m pip --version >$null 2>&1
Write-Host "[OK] pip 可用" -ForegroundColor Green
} catch {
Write-Host "[FAIL] pip 不可用,请检查 Python 安装" -ForegroundColor Red
exit 1
}
# 检查是否已安装
$installed = $false
try {
$ver = python -c "import paperforge; print('ok')" 2>$null
if ($ver -eq "ok") { $installed = $true }
} catch {}
if ($installed -and -not $Force) {
$current = python -c "import json, urllib.request; r=json.loads(urllib.request.urlopen('https://api.github.com/repos/LLLin000/PaperForge/releases/latest').read()); print(r['tag_name'])" 2>$null
Write-Host "[i] 已安装 ($current). 使用 -Force 参数重新安装" -ForegroundColor Yellow
Write-Host " 更新命令: paperforge update" -ForegroundColor Yellow
exit 0
}
Write-Host "正在安装 PaperForge Lite..." -ForegroundColor Yellow
python -m pip install "git+$RepoUrl" --upgrade
if ($LASTEXITCODE -ne 0) {
Write-Host "[FAIL] 安装失败" -ForegroundColor Red
exit 1
}
Write-Host "[OK] 安装成功!" -ForegroundColor Green
Write-Host ""
# 验证
try {
python -c "import paperforge; print(f'PaperForge Lite {paperforge.__version__}')" 2>$null
} catch {
python -c "import paperforge; print('PaperForge Lite 已安装')"
}
Write-Host ""
Write-Host "下一步: 运行 setup 向导配置你的 Vault" -ForegroundColor Cyan
Write-Host " paperforge setup" -ForegroundColor White
Write-Host ""
Write-Host "常用命令:" -ForegroundColor Cyan
Write-Host " paperforge sync 同步 Zotero" -ForegroundColor White
Write-Host " paperforge ocr 运行 OCR" -ForegroundColor White
Write-Host " paperforge update 检查更新" -ForegroundColor White
Write-Host ""

View file

@ -1501,10 +1501,10 @@ def _find_vault() -> Path | None:
return None
def main() -> int:
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="PaperForge Lite 安装向导")
parser.add_argument("--vault", type=Path, default=None, help="Vault 路径(可选,默认当前目录)")
args = parser.parse_args()
args = parser.parse_args(argv)
if args.vault:
vault = args.vault.resolve()