AnkiNoteTemplate/antp/exporter.py

109 lines
3.6 KiB
Python
Raw Normal View History

2021-04-20 10:32:25 +00:00
# Exporter exports note types from Anki to ../templates/
2021-11-27 11:54:42 +00:00
# Copyright: Ren Tatsumoto <tatsu at autistici.org>
# License: GNU GPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
2021-04-20 10:32:25 +00:00
2021-04-20 13:23:50 +00:00
import base64
2021-04-20 07:54:06 +00:00
import json
2021-04-20 09:25:54 +00:00
import random
import shutil
from os import DirEntry
2021-11-27 11:54:42 +00:00
from typing import Any
2021-04-20 07:54:06 +00:00
from .ankiconnect import invoke, request_model_names
2021-11-27 11:54:42 +00:00
from .common import NoteType, CardTemplate, get_used_fonts, select
from .consts import *
2021-04-20 07:54:06 +00:00
2021-11-27 11:54:42 +00:00
def fetch_card_templates(model_name: str) -> list[CardTemplate]:
return [
CardTemplate(name, val["Front"], val["Back"])
for name, val in invoke("modelTemplates", modelName=model_name).items()
]
2021-04-20 07:54:06 +00:00
2021-11-27 11:54:42 +00:00
def fetch_template(model_name: str) -> NoteType:
return NoteType(
name=model_name,
fields=invoke("modelFieldNames", modelName=model_name),
css=invoke("modelStyling", modelName=model_name)["css"],
templates=fetch_card_templates(model_name),
)
2021-04-20 07:54:06 +00:00
2021-11-27 11:54:42 +00:00
def select_model_dir_path(model_name: str) -> str:
dir_path = os.path.join(NOTE_TYPES_DIR, model_name)
dir_content = os.listdir(NOTE_TYPES_DIR)
2021-04-20 09:25:54 +00:00
2021-11-27 11:54:42 +00:00
if model_name in dir_content:
2021-04-20 12:35:49 +00:00
ans = input("Template with this name already exists. Overwrite [y/N]? ")
2021-04-20 09:25:54 +00:00
if ans.lower() != 'y':
2021-04-20 13:23:19 +00:00
while os.path.basename(dir_path) in dir_content:
2021-11-27 11:54:42 +00:00
dir_path = os.path.join(NOTE_TYPES_DIR, f"{model_name}_{random.randint(0, 9999)}")
2021-04-20 09:25:54 +00:00
return dir_path
def write_card_templates(model_dir_path: str, templates: list[CardTemplate]) -> None:
2021-11-27 11:54:42 +00:00
for template in templates:
dir_path = os.path.join(model_dir_path, template.name)
2021-11-27 11:54:42 +00:00
if not os.path.isdir(dir_path):
os.mkdir(dir_path)
for filename, content in zip((FRONT_FILENAME, BACK_FILENAME), (template.front, template.back)):
with open(os.path.join(dir_path, filename), 'w') as f:
f.write(content)
def format_export(model: NoteType) -> dict[str, Any]:
return {
"modelName": model.name,
"inOrderFields": model.fields,
"cardTemplates": [template.name for template in model.templates]
}
def remove_deleted_templates(model_dir_path: str, templates: list[str]) -> None:
for entry in os.scandir(model_dir_path):
entry: DirEntry
if entry.is_dir() and entry.name not in templates:
shutil.rmtree(entry.path)
2021-11-27 11:54:42 +00:00
def save_note_type(model: NoteType):
dir_path = select_model_dir_path(model.name)
json_path = os.path.join(dir_path, JSON_FILENAME)
css_path = os.path.join(dir_path, CSS_FILENAME)
readme_path = os.path.join(dir_path, README_FILENAME)
if not os.path.isdir(dir_path):
os.mkdir(dir_path)
with open(json_path, 'w') as f:
2021-11-27 14:57:24 +00:00
json.dump(format_export(model), f, indent=JSON_INDENT, ensure_ascii=False)
2021-11-27 11:54:42 +00:00
with open(css_path, 'w') as f:
f.write(model.css)
2021-04-20 09:25:54 +00:00
2021-11-27 11:54:42 +00:00
write_card_templates(dir_path, model.templates)
remove_deleted_templates(dir_path, [template.name for template in model.templates])
2021-04-20 09:25:54 +00:00
2021-11-27 11:54:42 +00:00
if not os.path.isfile(readme_path):
with open(readme_path, 'w') as f:
f.write(f"# {model.name}\n\n*Description and screenshots here.*")
2021-04-20 09:25:54 +00:00
2021-11-27 11:54:42 +00:00
def save_fonts(model: NoteType) -> None:
linked_fonts = get_used_fonts(model.css)
2021-04-20 13:23:50 +00:00
for font in linked_fonts:
2021-11-27 11:54:42 +00:00
if file_b64 := invoke("retrieveMediaFile", filename=font):
with open(os.path.join(FONTS_DIR, font), 'bw') as f:
f.write(base64.b64decode(file_b64))
2021-04-20 13:23:50 +00:00
2021-04-20 07:54:06 +00:00
def export_note_type():
if model := select(request_model_names()):
2021-11-27 11:54:42 +00:00
print(f"Selected model: {model}")
template = fetch_template(model)
save_fonts(template)
save_note_type(template)
print("Done.")