Loading poolpay/fints/__main__.py +67 −3 Changes for poolpay/fints/__main__.py: 67 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from typing import Annotated import minisign import typer from dulwich import porcelain from pyrage import encrypt as age_encrypt from pyrage import x25519 from sqlalchemy import select Loading Loading @@ -97,13 +98,25 @@ def export( help="If the export should be signed with the jakob minisign key." ), ] = False, file: Annotated[ Path | None, typer.Option( help="The file to write the output to (STDOUT if not provided).", ), ] = None, signature_file: Annotated[ Path | None, typer.Option( help="The file to write the detached signature to, if --sign is given (STDERR if not provided)", ), ] = None, ) -> None: """ Export all relevant transactions as messages to be applied in a running PoolPay instance via the Wire server. Produces output in JSONL format or as an ASCII-armored age blob to STDOUT. Produces output in JSONL format or as an ASCII-armored age blob to STDOUT or --file, if provided. If signing is requested, produces detached signature to STDERR. If signing is requested, produces detached signature to STDERR or --signature-file, if provided. """ base_selection = select(Transaction) selection = ( Loading @@ -127,6 +140,9 @@ def export( ] payload = _encrypt_if_requested("\n".join(str(m) for m in messages), encrypt) if file: file.write_text(payload) else: print(payload, end="") if sign: Loading @@ -135,16 +151,64 @@ def export( # something, so we encrypt the key with an empty string as password. key.decrypt("") signature = key.sign(payload.encode("utf-8")) armored_signature = bytes(signature).decode("utf-8") print(bytes(signature).decode("utf-8"), file=sys.stderr) if signature_file: signature_file.write_text(armored_signature) else: print(armored_signature, file=sys.stderr) @app.command() def list() -> None: """ List all transactions """ for transaction in Transaction.get_all(): print(transaction) @app.command() def commit( repo: Annotated[ Path, typer.Option(help="Path to the Git repository which holds the data") ] = Path(__file__).parents[3] / "c2", force: Annotated[ bool, typer.Option(help="Continue even if the sync retrieves no new transactions"), ] = False, push: Annotated[ bool, typer.Option(help="If git push should be run") ] = False, ) -> None: """ Sync, export if the sync yielded new transactions, git commit """ new_transactions = sync() if not new_transactions and not force: raise typer.Exit(1) file = repo / "messages.jsonl.age" signature_file = repo / "messages.jsonl.age.minisig" export(encrypt=True, sign=True, file=file, signature_file=signature_file) porcelain.add(repo, paths=(file, signature_file)) t = len(new_transactions) if t == 0: message = "Export all currently stored transactions" elif t == 1: message = "Add one new transaction" else: message = f"Add {t} new transactions" porcelain.commit(repo, message=message, author="Jakob Moser <jakob@fsco.li>") if push: porcelain.push(repo) if __name__ == "__main__": try: db.open(_guess_db_path()) Loading Loading
poolpay/fints/__main__.py +67 −3 Changes for poolpay/fints/__main__.py: 67 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from typing import Annotated import minisign import typer from dulwich import porcelain from pyrage import encrypt as age_encrypt from pyrage import x25519 from sqlalchemy import select Loading Loading @@ -97,13 +98,25 @@ def export( help="If the export should be signed with the jakob minisign key." ), ] = False, file: Annotated[ Path | None, typer.Option( help="The file to write the output to (STDOUT if not provided).", ), ] = None, signature_file: Annotated[ Path | None, typer.Option( help="The file to write the detached signature to, if --sign is given (STDERR if not provided)", ), ] = None, ) -> None: """ Export all relevant transactions as messages to be applied in a running PoolPay instance via the Wire server. Produces output in JSONL format or as an ASCII-armored age blob to STDOUT. Produces output in JSONL format or as an ASCII-armored age blob to STDOUT or --file, if provided. If signing is requested, produces detached signature to STDERR. If signing is requested, produces detached signature to STDERR or --signature-file, if provided. """ base_selection = select(Transaction) selection = ( Loading @@ -127,6 +140,9 @@ def export( ] payload = _encrypt_if_requested("\n".join(str(m) for m in messages), encrypt) if file: file.write_text(payload) else: print(payload, end="") if sign: Loading @@ -135,16 +151,64 @@ def export( # something, so we encrypt the key with an empty string as password. key.decrypt("") signature = key.sign(payload.encode("utf-8")) armored_signature = bytes(signature).decode("utf-8") print(bytes(signature).decode("utf-8"), file=sys.stderr) if signature_file: signature_file.write_text(armored_signature) else: print(armored_signature, file=sys.stderr) @app.command() def list() -> None: """ List all transactions """ for transaction in Transaction.get_all(): print(transaction) @app.command() def commit( repo: Annotated[ Path, typer.Option(help="Path to the Git repository which holds the data") ] = Path(__file__).parents[3] / "c2", force: Annotated[ bool, typer.Option(help="Continue even if the sync retrieves no new transactions"), ] = False, push: Annotated[ bool, typer.Option(help="If git push should be run") ] = False, ) -> None: """ Sync, export if the sync yielded new transactions, git commit """ new_transactions = sync() if not new_transactions and not force: raise typer.Exit(1) file = repo / "messages.jsonl.age" signature_file = repo / "messages.jsonl.age.minisig" export(encrypt=True, sign=True, file=file, signature_file=signature_file) porcelain.add(repo, paths=(file, signature_file)) t = len(new_transactions) if t == 0: message = "Export all currently stored transactions" elif t == 1: message = "Add one new transaction" else: message = f"Add {t} new transactions" porcelain.commit(repo, message=message, author="Jakob Moser <jakob@fsco.li>") if push: porcelain.push(repo) if __name__ == "__main__": try: db.open(_guess_db_path()) Loading