diff --git a/drillsrs/cmd/import_.py b/drillsrs/cmd/import_.py index d65da96..2f5762c 100644 --- a/drillsrs/cmd/import_.py +++ b/drillsrs/cmd/import_.py @@ -1,6 +1,7 @@ import argparse import json import sys +import io from typing import IO, Any, Optional from dateutil.parser import parse as parse_date @@ -9,6 +10,41 @@ from drillsrs.cmd.command_base import CommandBase +def apkg_to_json(filepath: str) -> str: + try: + from anki_export import ApkgReader + except ImportError: + print("must install anki_export package") + exit() + try: + from lxml import etree + except ImportError: + print("must install lxml package") + exit() + with ApkgReader(filepath) as apkg: + temp = apkg.export() + temp = temp[list(temp)[0]] + ret = {"name": temp[1][3], "description": None, "tags": [], "cards": []} + for counter, anki_card in enumerate(temp[1:], start=1): + card = { + "active": False, + "activation_date": None, + "tags": [], + "user_answers": [], + } + card["id"] = counter + question = etree.HTML(anki_card[0]) + card["question"] = etree.tostring(question, encoding="unicode", method="text") + answer = etree.HTML(anki_card[1]) + card["answers"] = ( + [" "] + if answer is None + else [etree.tostring(answer, encoding="unicode", method="text")] + ) + ret["cards"].append(card) + return json.dumps(ret) + + def _import(handle: IO[Any]) -> None: with db.session_scope() as session: deck_obj = json.load(handle) @@ -48,9 +84,7 @@ def _import(handle: IO[Any]) -> None: card.user_answers.append(user_answer) if "activation_date" in card_obj: if card_obj["activation_date"]: - card.activation_date = parse_date( - card_obj["activation_date"] - ) + card.activation_date = parse_date(card_obj["activation_date"]) elif card.user_answers: card.activation_date = sorted( card.user_answers, key=lambda ua: ua.date @@ -70,11 +104,21 @@ def decorate_arg_parser(self, parser: argparse.ArgumentParser) -> None: nargs="?", help="path to import from; if omitted, standard input is used", ) + parser.add_argument( + "--anki", + action="store_true", + help="import anki deck", + ) def run(self, args: argparse.Namespace) -> None: path: Optional[str] = args.path + anki: Optional[bool] = args.anki if path: - with open(path, "r") as handle: + if anki: + handle = io.StringIO(apkg_to_json(path)) _import(handle) + else: + with open(path, "r") as handle: + _import(handle) else: _import(sys.stdin) diff --git a/setup.py b/setup.py index 55e90dd..2a2d4f5 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,10 @@ url="https://github.com/rr-/drill", packages=find_packages(), entry_points={"console_scripts": ["drill-srs = drillsrs.__main__:main"]}, - install_requires=["xdg", "python-dateutil", "sqlalchemy", "jinja2",], + install_requires=["xdg", "python-dateutil", "sqlalchemy", "jinja2"], + extras_require={ + "anki": ["lxml", "anki-export"], + }, package_dir={"drillsrs": "drillsrs"}, package_data={"drillsrs": ["data/*.*"]}, classifiers=[