feat: allow creating a package with multiple decks.

This commit is contained in:
redxef 2025-03-17 16:38:02 +01:00
parent 4a129b60a3
commit cc7f8283bb
Signed by: redxef
GPG key ID: 7DAC3AA211CBD921

View file

@ -55,7 +55,8 @@ def load_notes(
@click.option('--destructive/--no-destructive', 'destructive', type=bool, default=False, help='Perform write operations, which may end in data loss')
@click.option('--autogenerate/--no-autogenerate', 'autogenerate', type=bool, default=False, help='Generate missing ids, should probably be used with --destructive, to always use the same ones.')
@click.option('--debug/--no-debug', 'debug', type=bool, default=False, help="Debug mode, don't write files")
@click.argument('path', type=click.Path(path_type=pathlib.Path, dir_okay=True))
@click.option('--multi', 'multi', type=click.Path(path_type=pathlib.Path))
@click.argument('paths', type=click.Path(path_type=pathlib.Path, dir_okay=True), nargs=-1)
def main(
*,
name: str | None,
@ -69,54 +70,62 @@ def main(
destructive: bool,
autogenerate: bool,
debug: bool,
path: pathlib.Path,
multi: pathlib.Path | None,
paths: list[pathlib.Path],
):
match = RE_DIRNAME.match(path.name)
if match:
model_name = model_name or match.group(1)
name = name or match.group(1)
model_id = model_id or int(match.group(2))
deck_id = deck_id or int(match.group(3))
else:
model_name = model_name or path.name
name = name or path.name
if model_id is None:
if autogenerate:
model_id = random.randrange(1 << 30, 1 << 31)
else:
raise click.ClickException('model_id could not be derived from directory name and is not explicitly set, or autogenerate enabled')
if deck_id is None:
if autogenerate:
deck_id = random.randrange(1 << 30, 1 << 31)
else:
raise click.ClickException('deck_id could not be derived from directory name and is not explicitly set, or autogenerate enabled')
if destructive:
new_path = path.parent / f'{path.name}.{model_id}.{deck_id}'
if not debug:
path.rename(new_path)
path = new_path
model = genanki.Model(
model_id,
model_name,
fields=[dict(name=x) for x in fields],
templates=[
{
'name': template_name,
'qfmt': question_format,
'afmt': answer_format,
},
],
)
notes: list[genanki.Note] = load_notes(path=path, model=model)
deck = genanki.Deck(
deck_id,
name,
)
for n in notes:
deck.add_note(n)
click.echo(f'added {len(notes)} notes')
if not debug:
genanki.Package(deck).write_to_file(path.parent / (path.name + '.apkg'))
decks = []
for path in paths:
match = RE_DIRNAME.match(path.name)
if match:
model_name = model_name or match.group(1)
name = name or match.group(1)
model_id = model_id or int(match.group(2))
deck_id = deck_id or int(match.group(3))
else:
model_name = model_name or path.name
name = name or path.name
if model_id is None:
if autogenerate:
model_id = random.randrange(1 << 30, 1 << 31)
else:
raise click.ClickException('model_id could not be derived from directory name and is not explicitly set, or autogenerate enabled')
if deck_id is None:
if autogenerate:
deck_id = random.randrange(1 << 30, 1 << 31)
else:
raise click.ClickException('deck_id could not be derived from directory name and is not explicitly set, or autogenerate enabled')
if destructive:
new_path = path.parent / f'{path.name}.{model_id}.{deck_id}'
if not debug:
path.rename(new_path)
path = new_path
model = genanki.Model(
model_id,
model_name,
fields=[dict(name=x) for x in fields],
templates=[
{
'name': template_name,
'qfmt': question_format,
'afmt': answer_format,
},
],
)
notes: list[genanki.Note] = load_notes(path=path, model=model)
deck = genanki.Deck(
deck_id,
name,
)
for n in notes:
deck.add_note(n)
click.echo(f'added {len(notes)} notes')
decks += [deck]
if not debug:
genanki.Package(deck).write_to_file(path.parent / (path.name + '.apkg'))
if not debug and multi:
if multi.suffix != '.apkg':
click.echo('WARNING: destination file does not have extension ".apkg"')
genanki.Package(decks).write_to_file(multi)