44from math import ceil
55from time import localtime , strftime , time
66
7+ from urllib .parse import parse_qs , urlparse
8+
79from tqdm import tqdm
810
911from pybliometrics .exception import ScopusQueryError
@@ -53,13 +55,18 @@ def __init__(self,
5355 ab_ref_retrieval = (api == 'AbstractRetrieval' ) and (params ['view' ] == 'REF' )
5456 # Check if object retrieval
5557 obj_retrieval = (api == 'ObjectRetrieval' )
58+ # Check if serial title search (special pagination)
59+ serial_search = (api == 'SerialTitleSearch' )
5660
5761 if fname .exists () and not self ._refresh :
5862 self ._mdate = mod_ts
5963 if search_request :
6064 self ._json = [loads (line ) for line in
6165 fname .read_text ().split ("\n " ) if line ]
6266 self ._n = len (self ._json )
67+ elif serial_search :
68+ self ._json = loads (fname .read_text ())
69+ self ._n = len (self ._json ['serial-metadata-response' ].get ('entry' , []))
6370 elif obj_retrieval :
6471 self ._object = fname .read_bytes ()
6572 else :
@@ -73,6 +80,11 @@ def __init__(self,
7380 data = _get_all_refs (url , params , verbose , resp , ** kwds )
7481 self ._json = data
7582 data = [data ]
83+ elif serial_search :
84+ entries = _get_all_serial_results (url , params , verbose , resp , ** kwds )
85+ self ._json = {'serial-metadata-response' : {'entry' : entries }}
86+ self ._n = len (entries )
87+ data = [self ._json ]
7688 elif search_request :
7789 # Get number of results
7890 res = resp .json ()
@@ -210,3 +222,34 @@ def _get_all_refs(url: str, params: dict, verbose: bool, resp: dict, **kwds) ->
210222 print (f'Total data: { len (parse_content .chained_get (data , ["abstracts-retrieval-response" , "references" , "reference" ]))} ' )
211223
212224 return data
225+
226+
227+ def _get_all_serial_results (url : str , params : dict , verbose : bool , resp , ** kwds ) -> list :
228+ """Get all results for `SerialTitleSearch` with pagination."""
229+ res = resp .json ()
230+ data = res .get ('serial-metadata-response' , {}).get ('entry' , [])
231+
232+ # Check for 'next' link to determine if pagination is needed
233+ links = res .get ('serial-metadata-response' , {}).get ('link' , [])
234+ next_link = next ((l for l in links if l .get ('@ref' ) == 'next' ), None )
235+ last_link = next ((l for l in links if l .get ('@ref' ) == 'last' ), None )
236+
237+ if not next_link or not last_link :
238+ return data
239+
240+ # Calculate total from last link (start + count)
241+ last_url = last_link .get ('@href' , '' )
242+ parsed = parse_qs (urlparse (last_url ).query )
243+ last_start = int (parsed .get ('start' , [0 ])[0 ])
244+ count = int (parsed .get ('count' , [params ['count' ]])[0 ])
245+ n_total = last_start + count
246+ n_chunks = ceil (n_total / count )
247+
248+ for i in tqdm (range (1 , n_chunks ), disable = not verbose , initial = 1 , total = n_chunks ):
249+ params ['start' ] = i * count
250+ resp = get_content (url , 'SerialTitleSearch' , params , ** kwds )
251+ res = resp .json ()
252+ entries = res .get ('serial-metadata-response' , {}).get ('entry' , [])
253+ data .extend (entries )
254+
255+ return data
0 commit comments