Converter: cover real Ren'Py games better, add folder import and dry run
Checked against six real games (Ren'Py 7.5 and 8.x): - nested labels and named menus become jump anchors inside label bodies - call with arguments and labels with parameters (dynamically scoped) - frame-by-frame ATL images, Movie frames, layeredimage, camera, Shake, custom audio channels via register_channel, show text with expressions - generator expressions in Python, no SyntaxWarning noise from decompiled code Also: - app.import_dir converts an unpacked game folder without changing it - app.converter.analyze dry-runs the script part of the converter - imports use their own "importing" status so a worker restart can't hijack them Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
35033fb86c
commit
a97b46079e
18 files changed
+3456
-2695
No files matched your search
+21
-13
@@ -3,6 +3,7 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import select, update
|
||||
|
||||
@@ -41,34 +42,39 @@ async def claim() -> GameVersion | None:
|
||||
|
||||
|
||||
async def process(v: GameVersion) -> None:
|
||||
settings = get_settings()
|
||||
ok = await convert(v.id, upload_path(v.id), v.upload_name or "")
|
||||
if ok:
|
||||
remove_upload(v.id) # sources are not kept once converted
|
||||
|
||||
|
||||
async def convert(version_id: int, source: Path, filename: str) -> bool:
|
||||
"""Run the converter for a version and store the outcome. Returns success."""
|
||||
loop = asyncio.get_running_loop()
|
||||
work = settings.work_dir / str(v.id)
|
||||
work = get_settings().work_dir / str(version_id)
|
||||
|
||||
def progress(text: str) -> None:
|
||||
asyncio.run_coroutine_threadsafe(set_progress(v.id, text), loop)
|
||||
asyncio.run_coroutine_threadsafe(set_progress(version_id, text), loop)
|
||||
|
||||
log.info("converting version %s (%s)", v.id, v.upload_name)
|
||||
log.info("converting version %s (%s)", version_id, filename)
|
||||
try:
|
||||
result = await asyncio.to_thread(convert_archive, upload_path(v.id), v.upload_name or "",
|
||||
work, progress)
|
||||
result = await asyncio.to_thread(convert_archive, source, filename, work, progress)
|
||||
except Exception as e: # noqa: BLE001
|
||||
log.exception("version %s failed", v.id)
|
||||
log.exception("version %s failed", version_id)
|
||||
async with SessionLocal() as db:
|
||||
version = await db.get(GameVersion, v.id)
|
||||
version = await db.get(GameVersion, version_id)
|
||||
if version:
|
||||
version.status = "failed"
|
||||
version.progress = f"Ошибка: {e}"[:255]
|
||||
version.report = {"error": str(e)}
|
||||
await db.commit()
|
||||
return
|
||||
return False
|
||||
finally:
|
||||
shutil.rmtree(work, ignore_errors=True)
|
||||
|
||||
async with SessionLocal() as db:
|
||||
version = await db.get(GameVersion, v.id)
|
||||
version = await db.get(GameVersion, version_id)
|
||||
if version is None: # deleted while converting
|
||||
return
|
||||
return True
|
||||
version.status = "ready"
|
||||
version.progress = ""
|
||||
version.manifest = result.manifest
|
||||
@@ -81,9 +87,11 @@ async def process(v: GameVersion) -> None:
|
||||
read_bytes(result.cover_source))
|
||||
except OSError:
|
||||
pass
|
||||
if game and result.title and game.title == source.name:
|
||||
game.title = result.title
|
||||
await db.commit()
|
||||
remove_upload(v.id) # sources are not kept once converted
|
||||
log.info("version %s ready: %s", v.id, result.report.get("media"))
|
||||
log.info("version %s ready: %s", version_id, result.report.get("media"))
|
||||
return True
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
|
||||
Reference in new issue
Block a user