@@ -196,6 +196,95 @@ def list_downloads(lid):
196196 print (row )
197197
198198
199+ def sync_cards ():
200+ """Lazy tail sync of cards."""
201+ index = match_tails ()
202+ print (f"{ index } " )
203+
204+
205+ def match_tails (match_size = 5 , max_pages = 100 ):
206+ """Find a tail match between local and trle databases based ids."""
207+ local = []
208+ trle = []
209+
210+ local_offset = 0
211+ trle_offset = 0
212+
213+ def get_local_page_and_extend (offset ):
214+ con = database_make_connection ()
215+ page = get_local_page (offset , con )['levels' ]
216+ con .close ()
217+ local .extend (page )
218+ return len (page )
219+
220+ def get_trle_page_and_extend (offset ):
221+ page = get_trle_page (offset )['levels' ]
222+ trle .extend (page )
223+ return len (page )
224+
225+ def ensure_data (index_local , index_trle ):
226+ """Ensure enough items are available from each database."""
227+ nonlocal local_offset , trle_offset
228+
229+ # Load local pages if needed
230+ while index_local + match_size > len (local ):
231+ local_offset += 1
232+ print (f"Loading local page at offset { local_offset } " )
233+ if local_offset >= max_pages or get_local_page_and_extend (local_offset ) == 0 :
234+ return False
235+
236+ # Load trle pages if needed
237+ while index_trle + match_size > len (trle ):
238+ trle_offset += 1
239+ print (f"Loading trle page at offset { trle_offset } " )
240+ if trle_offset >= max_pages or get_trle_page_and_extend (trle_offset ) == 0 :
241+ return False
242+
243+ return True
244+
245+ def ids_match (offset_local , offset_trle ):
246+ """Compare sequences of trle_ids from both lists."""
247+ if not ensure_data (offset_local , offset_trle ):
248+ return False
249+
250+ for i in range (match_size ):
251+ try :
252+ local_id = int (local [offset_local + i ]['trle_id' ])
253+ trle_id = int (trle [offset_trle + i ]['trle_id' ])
254+ if local_id != trle_id :
255+ return False
256+ except IndexError :
257+ return False
258+ return True
259+
260+ # Load initial data
261+ get_local_page_and_extend (local_offset )
262+ get_trle_page_and_extend (trle_offset )
263+
264+ i = 0
265+ while True :
266+ if i + match_size > len (local ):
267+ # Try to load more local data
268+ if not ensure_data (i , 0 ):
269+ break
270+
271+ for j in range (len (trle ) - match_size + 1 ):
272+ if ids_match (i , j ):
273+ print (f"Match found at local[{ i } ] and trle[{ j } ]" )
274+ return (i , j )
275+ i += 1
276+
277+ # If we run out of trle data, load more
278+ if len (trle ) - match_size < 1 :
279+ added = get_trle_page_and_extend (trle_offset + 1 )
280+ trle_offset += 1
281+ if added == 0 or trle_offset >= max_pages :
282+ break
283+
284+ print ("❌ No match found after paging." )
285+ return None
286+
287+
199288def get_local_page (offset , con ):
200289 """Pass down API to get a TRLE page from the database."""
201290 return tombll_read .trle_page (offset , con , sort_latest_first = True )
@@ -491,6 +580,9 @@ def update_tombll_json_to_database(data, level_id, con):
491580 elif (sys .argv [1 ] == "-u" and number_of_argument == 3 ):
492581 update_level (sys .argv [2 ])
493582
583+ elif (sys .argv [1 ] == "-sc" and number_of_argument == 2 ):
584+ sync_cards ()
585+
494586 elif (sys .argv [1 ] == "-ld" and number_of_argument == 3 ):
495587 list_downloads (sys .argv [2 ])
496588
0 commit comments