Skip to content

Commit

Permalink
store css files to 'media'
Browse files Browse the repository at this point in the history
  • Loading branch information
tatsumoto-ren committed Aug 29, 2024
1 parent 41a2a6d commit 2b02fe1
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 37 deletions.
11 changes: 7 additions & 4 deletions gomi/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import dataclasses
import re
from dataclasses import dataclass
from .consts import FONTS_DIR, NOTE_TYPES_DIR
from .consts import REPO_MEDIA_DIR, NOTE_TYPES_DIR


RE_MEDIA_IMPORT = re.compile(r"url\([\"']([\w_.]+\.(?:[ot]tf|woff\d?|css))[\"']\)", flags=re.IGNORECASE)


class ANTPError(Exception):
Expand Down Expand Up @@ -52,10 +55,10 @@ def select(items: list[str], msg: str = "Select item number: ") -> str | None:
return items[idx]


def get_used_fonts(template_css: str):
return re.findall(r"url\([\"'](\w+\.(?:[ot]tf|woff\d?))[\"']\)", template_css, re.IGNORECASE)
def find_referenced_media_files(template_css: str) -> frozenset[str]:
return frozenset(re.findall(RE_MEDIA_IMPORT, template_css))


def init():
for path in (NOTE_TYPES_DIR, FONTS_DIR):
for path in (NOTE_TYPES_DIR, REPO_MEDIA_DIR):
path.mkdir(exist_ok=True)
2 changes: 1 addition & 1 deletion gomi/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
README_FILENAME = "README.md"
THIS_DIR = pathlib.Path.cwd()
NOTE_TYPES_DIR = THIS_DIR / "templates"
FONTS_DIR = THIS_DIR / "fonts"
REPO_MEDIA_DIR = THIS_DIR / "media"
26 changes: 17 additions & 9 deletions gomi/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from typing import Any

from .ankiconnect import invoke, request_model_names
from .common import CardTemplate, NoteType, get_used_fonts, select
from .common import CardTemplate, NoteType, find_referenced_media_files, select
from .consts import (
NOTE_TYPES_DIR,
FRONT_FILENAME,
Expand All @@ -21,7 +21,7 @@
CSS_FILENAME,
README_FILENAME,
JSON_INDENT,
FONTS_DIR,
REPO_MEDIA_DIR,
)


Expand Down Expand Up @@ -102,18 +102,26 @@ def save_note_type(model: NoteType):
f.write(f"# {model.name}\n\n*Description and screenshots here.*")


def save_fonts(model: NoteType) -> None:
linked_fonts = get_used_fonts(model.css)
for font in linked_fonts:
if file_b64 := invoke("retrieveMediaFile", filename=font):
with open(os.path.join(FONTS_DIR, font), "bw") as f:
def save_media_imports(model: NoteType) -> None:
"""
Save fonts and CSS files referenced in the CSS template to the "media" folder.
"""
linked_media_files = find_referenced_media_files(model.css)
for file_name in linked_media_files:
if file_b64 := invoke("retrieveMediaFile", filename=file_name):
full_path = os.path.join(REPO_MEDIA_DIR, file_name)
with open(full_path, "bw") as f:
f.write(base64.b64decode(file_b64))
print(f"saved file: '{full_path}'")


def export_note_type():
def export_note_type() -> None:
"""
Select a note type in Anki and add save it to the hard drive.
"""
if model := select(request_model_names()):
print(f"Selected model: {model}")
template = fetch_template(model)
save_fonts(template)
save_note_type(template)
save_media_imports(template)
print("Done.")
39 changes: 22 additions & 17 deletions gomi/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

import json
import os
from typing import Any, Collection, Iterable
from typing import Any, Collection, Iterable, Sequence

from .ankiconnect import invoke, request_model_names
from .common import CardTemplate, NoteType, get_used_fonts, select
from .consts import NOTE_TYPES_DIR, CSS_FILENAME, FRONT_FILENAME, BACK_FILENAME, JSON_FILENAME, FONTS_DIR
from .common import CardTemplate, NoteType, find_referenced_media_files, select
from .consts import NOTE_TYPES_DIR, CSS_FILENAME, FRONT_FILENAME, BACK_FILENAME, JSON_FILENAME, REPO_MEDIA_DIR


def read_css(model_dir_name: str) -> str:
Expand Down Expand Up @@ -66,22 +66,27 @@ def send_note_type(model: NoteType):
invoke("createModel", **template_json)


def available_fonts(required_fonts: Collection[str]) -> Iterable[str]:
"""Filter required fonts and leave only those available on disk."""
for file in os.listdir(FONTS_DIR):
if file in required_fonts:
yield file


def store_fonts(fonts: list[str]):
for file in available_fonts(fonts):
invoke("storeMediaFile", filename=file, path=os.path.join(FONTS_DIR, file))


def import_note_type():
def save_files_to_anki_col(file_names: frozenset[str]) -> None:
"""
Take a list of files and save them to Anki's 'collection.media' folder.
The files should exist in the "media" folder on disk.
"""
for file_name in file_names:
full_path = os.path.join(REPO_MEDIA_DIR, file_name)
if not os.path.isfile(full_path):
print(f"not found on disk: '{full_path}'")
continue
invoke("storeMediaFile", filename=file_name, path=full_path)
print(f"saved file in Anki collection: '{file_name}'")


def import_note_type() -> None:
"""
Select a note type and add it to the currently opened Anki profile using AnkiConnect.
"""
if model_dir_name := select(os.listdir(NOTE_TYPES_DIR)):
print(f"Selected model: {model_dir_name}")
model = read_model(model_dir_name)
store_fonts(get_used_fonts(model.css))
send_note_type(model)
save_files_to_anki_col(find_referenced_media_files(model.css))
print("Done.")
6 changes: 3 additions & 3 deletions gomi/overwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import os

from .ankiconnect import request_model_names
from .common import get_used_fonts, select
from .common import find_referenced_media_files, select
from .consts import NOTE_TYPES_DIR
from .importer import read_model, store_fonts
from .importer import read_model, save_files_to_anki_col
from .updater import send_note_type


Expand All @@ -19,7 +19,7 @@ def overwrite_note_type():
print(f"Writing templates from {model_name_on_disk} onto {model_name_in_anki}...")

model = models_on_disk[model_name_on_disk]
store_fonts(get_used_fonts(model.css))
save_files_to_anki_col(find_referenced_media_files(model.css))
send_note_type(model.rename(model_name_in_anki))

print("Done.")
6 changes: 3 additions & 3 deletions gomi/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from typing import Any

from .ankiconnect import invoke, request_model_names
from .common import NoteType, get_used_fonts, select
from .common import NoteType, find_referenced_media_files, select
from .consts import NOTE_TYPES_DIR
from .importer import read_model, store_fonts
from .importer import read_model, save_files_to_anki_col


def format_templates(model: NoteType) -> dict[str, Any]:
Expand Down Expand Up @@ -40,6 +40,6 @@ def update_note_type():
if model_name := select(updatable_models):
print(f"Selected note type: {model_name}")
model = models_on_disk[model_name]
store_fonts(get_used_fonts(model.css))
save_files_to_anki_col(find_referenced_media_files(model.css))
send_note_type(model)
print("Done.")
19 changes: 19 additions & 0 deletions tests/test_find_referenced_media.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from gomi.common import find_referenced_media_files

EXAMPLE = """
@charset "UTF-8";
@import url("_ajt_japanese_24.7.14.1.css");
@font-face {
font-family: "KanjiStrokeOrders";
src: url("_kso.woff2");
}
@font-face {
font-family: "Local Mincho";
src: url("_yumin.woff2");
}
"""


def test_find_referenced_media() -> None:
result = find_referenced_media_files(EXAMPLE)
assert result == {"_ajt_japanese_24.7.14.1.css", "_kso.woff2", "_yumin.woff2"}

0 comments on commit 2b02fe1

Please sign in to comment.