diff --git a/README.md b/README.md index 7a46fd9..f2f5116 100644 --- a/README.md +++ b/README.md @@ -144,9 +144,13 @@ The current workflow could be described as following: ## Export To perform the export go to menu File>Export -Select the deck (**note**: export of "All decks" is not supported, you need to select a specific deck) and the export format "CrowdAnki JSON representation". +Select the deck and the export format "CrowdAnki JSON representation". After pressing the Export button - select directory where the result should be stored. +### Limitations: +* CrowdAnki won't allow you to do export of "All decks", you should use CrowdAnki snapshot instead. +* Export of a filtered deck is not supported, export the main deck instead and filter it again after importing. You don't have to delete existing filtered decks, as all cards are still part of the main deck. When exporting nested decks, filtered sub-decks are just ignored. + ## Import To perform the import go to menu File>"CrowdAnki: Import from disk" and select the directory where the deck is stored. diff --git a/crowd_anki/representation/deck_initializer.py b/crowd_anki/representation/deck_initializer.py index abdb4cd..a925d60 100644 --- a/crowd_anki/representation/deck_initializer.py +++ b/crowd_anki/representation/deck_initializer.py @@ -1,11 +1,17 @@ +from functional import seq + from .deck import Deck from .note import Note +from ..anki.adapters.anki_deck import AnkiDeck from ..anki.adapters.note_model_file_provider import NoteModelFileProvider def from_collection(collection, name, deck_metadata=None, is_child=False) -> Deck: anki_dict = collection.decks.byName(name) + if AnkiDeck(anki_dict).is_dynamic: + return None + deck = Deck(NoteModelFileProvider, anki_dict, is_child) deck.collection = collection deck._update_fields() @@ -18,8 +24,9 @@ def from_collection(collection, name, deck_metadata=None, is_child=False) -> Dec if Deck.DECK_NAME_DELIMITER not in child_name[len(name) + len(Deck.DECK_NAME_DELIMITER):]] - deck.children = [from_collection(collection, child_name, deck.metadata, True) - for child_name in direct_children] + deck.children = seq(direct_children) \ + .map(lambda child_name: from_collection(collection, child_name, deck.metadata, True)) \ + .filter(lambda it: it is not None).to_list() return deck diff --git a/test/representation/__init__.py b/test/representation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/representation/deck_initializer_spec.py b/test/representation/deck_initializer_spec.py new file mode 100644 index 0000000..f01d4fd --- /dev/null +++ b/test/representation/deck_initializer_spec.py @@ -0,0 +1,17 @@ +from expects import expect, be +from mamba import description, it +from unittest.mock import MagicMock + +from crowd_anki.representation import deck_initializer + +DYNAMIC_DECK = {'dyn': True} + +TEST_DECK = "test deck" + +with description("Initializer from deck") as self: + with it("should return None when trying to export dynamic deck"): + collection = MagicMock() + + collection.decks.byName.return_value = DYNAMIC_DECK + + expect(deck_initializer.from_collection(collection, TEST_DECK)).to(be(None))