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
@@ -0,0 +1,48 @@
|
||||
"""Import an already unpacked game from a folder on the server.
|
||||
|
||||
python -m app.import_dir /games/Some-Game [--title "Name"] [--owner admin]
|
||||
|
||||
The folder is only read; the converted copy goes to the blob store like an upload.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.db import SessionLocal
|
||||
from app.models import Game, GameVersion, Role, User
|
||||
from app.worker import convert
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("path", type=Path)
|
||||
ap.add_argument("--title")
|
||||
ap.add_argument("--owner", help="username; defaults to the first admin")
|
||||
args = ap.parse_args()
|
||||
if not args.path.is_dir():
|
||||
raise SystemExit(f"{args.path} is not a directory")
|
||||
|
||||
async with SessionLocal() as db:
|
||||
stmt = select(User).join(Role).order_by(User.id)
|
||||
stmt = stmt.where(User.username == args.owner) if args.owner else stmt.where(Role.name == "admin")
|
||||
owner = await db.scalar(stmt.limit(1))
|
||||
if owner is None:
|
||||
raise SystemExit("owner not found")
|
||||
game = Game(title=args.title or args.path.name, created_by_id=owner.id)
|
||||
db.add(game)
|
||||
await db.flush()
|
||||
version = GameVersion(game_id=game.id, owner_id=owner.id, name="Оригинал",
|
||||
upload_name=args.path.name, status="importing")
|
||||
db.add(version)
|
||||
await db.commit()
|
||||
game_id, version_id = game.id, version.id
|
||||
|
||||
ok = await convert(version_id, args.path, args.path.name)
|
||||
print(f"game {game_id}, version {version_id}: {'ready' if ok else 'failed'}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in new issue
Block a user