66__all__ = ['data_path' , 'profiles' , 'close_all' , 'Deck' , 'add_card' , 'add_fb_card' , 'find_cards' , 'find_card_ids' , 'find_notes' ,
77 'find_note_ids' , 'update_note' , 'update_fb_note' , 'get_note' , 'del_card' , 'sync' , 'anki_tools' ]
88
9- # %% ../nbs/00_core.ipynb 2
9+ # %% ../nbs/00_core.ipynb
1010import platform ,gc
1111from fastcore .utils import *
1212from contextlib import closing
2424from anki .notes import Note
2525from anki .collection_pb2 import OpChangesWithCount
2626
27- # %% ../nbs/00_core.ipynb 5
27+ # %% ../nbs/00_core.ipynb
2828def data_path ():
2929 "Return the default Anki data folder for this OS."
3030 syst = platform .system ()
@@ -33,18 +33,18 @@ def data_path():
3333 else 'Library/Application Support/Anki2' if syst == 'Darwin'
3434 else 'Anki2' )
3535
36- # %% ../nbs/00_core.ipynb 7
36+ # %% ../nbs/00_core.ipynb
3737def profiles ():
3838 "List available Anki profile names."
3939 dp = data_path ()
4040 if not dp .exists (): return []
4141 return [p .name for p in dp .iterdir () if (p / 'collection.anki2' ).exists ()]
4242
43- # %% ../nbs/00_core.ipynb 9
43+ # %% ../nbs/00_core.ipynb
4444# quiet down latency complaints
4545_backend .main_thread = lambda : None
4646
47- # %% ../nbs/00_core.ipynb 10
47+ # %% ../nbs/00_core.ipynb
4848@patch (cls_method = True )
4949def open (cls :Collection , profile = 'User 1' ):
5050 "Open a collection by profile name (creates if needed)."
@@ -57,7 +57,7 @@ def open(cls:Collection, profile='User 1'):
5757 col .profile_path = path
5858 return col
5959
60- # %% ../nbs/00_core.ipynb 13
60+ # %% ../nbs/00_core.ipynb
6161@patch (as_prop = True )
6262def _auth_path (self :Collection ): return self .profile_path / 'sync_auth.bin'
6363
@@ -75,7 +75,7 @@ def load_auth(self:Collection):
7575 auth .ParseFromString (p .read_bytes ())
7676 return auth
7777
78- # %% ../nbs/00_core.ipynb 15
78+ # %% ../nbs/00_core.ipynb
7979@patch
8080def sync (self :Collection , user = None , passw = None , media = True ):
8181 auth = self .load_auth ()
@@ -100,22 +100,22 @@ def sync(self:Collection, user=None, passw=None, media=True):
100100 self .reopen (after_full_sync = True )
101101 return result
102102
103- # %% ../nbs/00_core.ipynb 18
103+ # %% ../nbs/00_core.ipynb
104104def close_all ():
105105 "Close all open Anki backends (nuclear option for crash recovery)."
106106 for obj in gc .get_objects ():
107107 if isinstance (obj , RustBackend ):
108108 try : obj .close_collection (downgrade_to_schema11 = False )
109109 except : pass
110110
111- # %% ../nbs/00_core.ipynb 20
111+ # %% ../nbs/00_core.ipynb
112112@patch
113113def _repr_markdown_ (self :ModelManager ): return '\n ' .join ('- ' + m .name for m in self .all_names_and_ids ())
114114
115115@patch
116116def _repr_markdown_ (self :NotetypeNameId ): return f"**{ self .name } ** (id: { self .id } )"
117117
118- # %% ../nbs/00_core.ipynb 22
118+ # %% ../nbs/00_core.ipynb
119119@patch
120120def _repr_markdown_ (self :DeckManager ): return '\n ' .join ('- ' + d .name for d in self .all_names_and_ids ())
121121
@@ -126,10 +126,10 @@ def _repr_markdown_(self:DeckNameId): return f"**{self.name}** (id: {self.id})"
126126def _repr_markdown_ (self :DeckTreeNode ):
127127 return f"**{ self .name } **: { self .new_count } new, { self .learn_count } learn, { self .review_count } review"
128128
129- # %% ../nbs/00_core.ipynb 27
129+ # %% ../nbs/00_core.ipynb
130130ModelManager .__getitem__ = ModelManager .by_name
131131
132- # %% ../nbs/00_core.ipynb 29
132+ # %% ../nbs/00_core.ipynb
133133@patch
134134def _repr_markdown_ (self :Note ):
135135 fields = ' | ' .join (f"**{ k } **: { self [k ]} " for k in self ._fmap )
@@ -140,11 +140,11 @@ def __repr__(self:Note):
140140 fields = ', ' .join (f"{ k } ={ self [k ]!r} " for k in self ._fmap )
141141 return f"Note({ self .id } , { fields } , tags={ self .tags } )"
142142
143- # %% ../nbs/00_core.ipynb 31
143+ # %% ../nbs/00_core.ipynb
144144@patch
145145def _repr_markdown_ (self :OpChangesWithCount ): return f"✓ { self .count } change(s)"
146146
147- # %% ../nbs/00_core.ipynb 32
147+ # %% ../nbs/00_core.ipynb
148148class Deck :
149149 def __init__ (self , col , name ):
150150 self .col , self .name = col , name
@@ -162,11 +162,11 @@ def _repr_markdown_(self):
162162 n , l , r = self .due
163163 return f"**{ self .name } **: { n } new, { l } learn, { r } review"
164164
165- # %% ../nbs/00_core.ipynb 34
165+ # %% ../nbs/00_core.ipynb
166166@patch
167167def __getitem__ (self :DeckManager , name ): return Deck (self .col , name )
168168
169- # %% ../nbs/00_core.ipynb 35
169+ # %% ../nbs/00_core.ipynb
170170@patch
171171def add (self :Collection , model = 'Basic' , deck = 'Default' , tags = None , ** fields ):
172172 "Add a note with the given fields."
@@ -177,13 +177,13 @@ def add(self:Collection, model='Basic', deck='Default', tags=None, **fields):
177177 if res .count == 0 : raise ValueError ("Failed to add note" )
178178 return note
179179
180- # %% ../nbs/00_core.ipynb 38
180+ # %% ../nbs/00_core.ipynb
181181@patch
182182def add_deck (self :Collection , name ):
183183 "Create a deck (use :: for nesting)."
184184 return self .decks .add_normal_deck_with_name (name )
185185
186- # %% ../nbs/00_core.ipynb 45
186+ # %% ../nbs/00_core.ipynb
187187@patch
188188def __repr__ (self :ModelManager ): return f"ModelManager({ [m .name for m in self .all_names_and_ids ()]} )"
189189
@@ -209,49 +209,49 @@ def __repr__(self:Card): return f"Card({self.id}, nid={self.nid}, due={self.due}
209209@patch
210210def __repr__ (self :Deck ): return f"Deck({ self .name !r} , id={ self .id } )"
211211
212- # %% ../nbs/00_core.ipynb 48
212+ # %% ../nbs/00_core.ipynb
213213@patch
214214def __enter__ (self :Collection ): return self
215215
216216@patch
217217def __exit__ (self :Collection , * args ): self .close ()
218218
219- # %% ../nbs/00_core.ipynb 51
219+ # %% ../nbs/00_core.ipynb
220220def add_card (profile = 'User 1' , model = 'Basic' , deck = 'Default' , tags = None , ** fields ):
221221 "Add a card."
222222 with Collection .open (profile ) as col : return col .add (model = model , deck = deck , tags = tags or None , ** fields )
223223
224- # %% ../nbs/00_core.ipynb 54
224+ # %% ../nbs/00_core.ipynb
225225def add_fb_card (front :str , back :str , profile :str = 'User 1' , model :str = 'Basic' , deck :str = 'Default' , tags :str = None ):
226226 "Add a card with a `Front` and `Back` and return the id."
227227 return add_card (profile = profile , model = model , deck = deck , tags = tags , Front = front , Back = back ).id
228228
229- # %% ../nbs/00_core.ipynb 55
229+ # %% ../nbs/00_core.ipynb
230230def find_cards (query :str , profile :str = 'User 1' ):
231231 "Find cards matching query string. Returns list of Note objects."
232232 with Collection .open (profile ) as col : return [col .get_card (cid ) for cid in col .find_cards (query )]
233233
234- # %% ../nbs/00_core.ipynb 58
234+ # %% ../nbs/00_core.ipynb
235235@patch
236236def _repr_markdown_ (self :Card ):
237237 return f"Card { self .id } (nid: { self .nid } , due: { self .due } , ivl: { self .ivl } d, queue: { self .queue } )"
238238
239- # %% ../nbs/00_core.ipynb 60
239+ # %% ../nbs/00_core.ipynb
240240def find_card_ids (query :str , profile :str = 'User 1' ):
241241 "Find card ids matching query string."
242242 with Collection .open (profile ) as col : return col .find_cards (query )
243243
244- # %% ../nbs/00_core.ipynb 62
244+ # %% ../nbs/00_core.ipynb
245245def find_notes (query :str , profile :str = 'User 1' ):
246246 "Find notes matching query string. Returns list of Note objects."
247247 with Collection .open (profile ) as col : return [col .get_note (nid ) for nid in col .find_notes (query )]
248248
249- # %% ../nbs/00_core.ipynb 66
249+ # %% ../nbs/00_core.ipynb
250250def find_note_ids (query :str , profile :str = 'User 1' ):
251251 "Find note ids matching query string."
252252 with Collection .open (profile ) as col : return col .find_notes (query )
253253
254- # %% ../nbs/00_core.ipynb 68
254+ # %% ../nbs/00_core.ipynb
255255def update_note (note :int , profile :str = 'User 1' , tags :str = None , add_tags :str = None , ** fields ):
256256 "Update an existing note's fields and/or tags. Pass a Note object or note ID."
257257 with Collection .open (profile ) as col :
@@ -262,29 +262,29 @@ def update_note(note:int, profile:str='User 1', tags:str=None, add_tags:str=None
262262 col .update_note (note )
263263 return note
264264
265- # %% ../nbs/00_core.ipynb 72
265+ # %% ../nbs/00_core.ipynb
266266def update_fb_note (note_id :int , front :str = '' , back :str = '' , profile :str = 'User 1' , tags :str = None , add_tags :str = None ):
267267 "Update an existing note's front/back fields and/or tags. Pass a Note object or note ID."
268268 kw = {}
269269 if front : kw ['Front' ] = front
270270 if back : kw ['Back' ] = back
271271 return update_note (note_id , profile = profile , tags = tags , add_tags = add_tags , ** kw )
272272
273- # %% ../nbs/00_core.ipynb 74
273+ # %% ../nbs/00_core.ipynb
274274def get_note (note_id :int , profile :str = 'User 1' ):
275275 "Retrieve a note by ID."
276276 with Collection .open (profile ) as col : return col .get_note (note_id )
277277
278- # %% ../nbs/00_core.ipynb 76
278+ # %% ../nbs/00_core.ipynb
279279def del_card (notes :int , profile :str = 'User 1' ):
280280 "Delete card(s) by Note(s) or note id(s)."
281281 nids = [n if isinstance (n , int ) else n .id for n in listify (notes )]
282282 with Collection .open (profile ) as col : return col .remove_notes (nids )
283283
284- # %% ../nbs/00_core.ipynb 78
284+ # %% ../nbs/00_core.ipynb
285285def sync (profile :str = 'User 1' , user :str = None , passw :str = None , media :bool = True ):
286286 "Sync collection, handling open/close automatically."
287287 with Collection .open (profile ) as col : return col .sync (user = user , passw = passw , media = media )
288288
289- # %% ../nbs/00_core.ipynb 81
289+ # %% ../nbs/00_core.ipynb
290290def anki_tools (): print ('&`[add_fb_card, find_notes, find_note_ids, find_cards, find_card_ids, get_note, del_card, update_fb_note, sync]`' )
0 commit comments