mirror of
https://github.com/Ascyii/typstar.git
synced 2026-01-01 05:24:24 -05:00
fix(anki): anki api concurrency issues
This commit is contained in:
@@ -13,9 +13,12 @@ class AnkiConnectError(Exception):
|
||||
|
||||
class AnkiConnectApi:
|
||||
url: str
|
||||
api_key: str
|
||||
|
||||
def __init__(self, url="http://127.0.0.1:8765"):
|
||||
def __init__(self, url: str, api_key: str):
|
||||
self.url = url
|
||||
self.api_key = api_key
|
||||
self.semaphore = asyncio.Semaphore(2) # increase in case Anki implements multithreading
|
||||
|
||||
async def push_flashcards(self, cards: List[Flashcard]):
|
||||
add = []
|
||||
@@ -33,15 +36,17 @@ class AnkiConnectApi:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
data = {
|
||||
"action": action,
|
||||
"version": 6,
|
||||
"key": self.api_key,
|
||||
"params": params,
|
||||
"version": 6,
|
||||
}
|
||||
try:
|
||||
async with session.post(url=self.url, json=data) as response:
|
||||
result = await response.json(encoding="utf-8")
|
||||
if err := result["error"]:
|
||||
raise AnkiConnectError(err)
|
||||
return result["result"]
|
||||
async with self.semaphore:
|
||||
async with session.post(url=self.url, json=data) as response:
|
||||
result = await response.json(encoding="utf-8")
|
||||
if err := result["error"]:
|
||||
raise AnkiConnectError(err)
|
||||
return result["result"]
|
||||
except aiohttp.ClientError as e:
|
||||
raise AnkiConnectError(f"Could not connect to Anki: {e}")
|
||||
|
||||
@@ -73,5 +78,8 @@ class AnkiConnectApi:
|
||||
await self._update(cards)
|
||||
|
||||
async def _update(self, cards: List[Flashcard]):
|
||||
await asyncio.gather(*(self._update_note_model(card) for card in cards),
|
||||
*(self._store_media(card) for card in cards))
|
||||
results = await asyncio.gather(*(self._update_note_model(card) for card in cards),
|
||||
*(self._store_media(card) for card in cards), return_exceptions=True)
|
||||
for result in results:
|
||||
if isinstance(result, Exception):
|
||||
raise result
|
||||
|
||||
@@ -13,10 +13,10 @@ from anki.typst_compiler import TypstCompiler
|
||||
cli = typer.Typer(name="typstar-anki")
|
||||
|
||||
|
||||
async def export_flashcards(root_dir, typst_cmd):
|
||||
async def export_flashcards(root_dir, typst_cmd, anki_url, anki_key):
|
||||
parser = FlashcardParser()
|
||||
compiler = TypstCompiler(root_dir, typst_cmd)
|
||||
api = AnkiConnectApi()
|
||||
api = AnkiConnectApi(anki_url, anki_key)
|
||||
|
||||
# parse flashcards
|
||||
flashcards = parser.parse_directory(root_dir)
|
||||
@@ -36,8 +36,11 @@ async def export_flashcards(root_dir, typst_cmd):
|
||||
@cli.command()
|
||||
def cmd(root_dir: Annotated[
|
||||
str, typer.Option(help="Directory scanned for flashcards and passed over to typst compile command")] = os.getcwd(),
|
||||
typst_cmd: Annotated[str, typer.Option(help="Typst command used for flashcard compilation")] = "typst"):
|
||||
asyncio.run(export_flashcards(root_dir, typst_cmd))
|
||||
typst_cmd: Annotated[str, typer.Option(help="Typst command used for flashcard compilation")] = "typst",
|
||||
anki_url: Annotated[str, typer.Option(help="Url for Anki-Connect")] = "http://127.0.0.1:8765",
|
||||
anki_key: Annotated[str, typer.Option(help="Api key for Anki-Connect")] = None,
|
||||
):
|
||||
asyncio.run(export_flashcards(root_dir, typst_cmd, anki_url, anki_key))
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
Reference in New Issue
Block a user