
    Si2w                         d Z ddlZddlZddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZ dd
lmZmZmZmZmZmZ dZdZ dZ!dZ"dZ#dZ$dZ%dZ& G d d      Z'y)zscholarly.py    N)DictListUnion   )	Navigator)ProxyGenerator)find_dotenvload_dotenv)AuthorParser)PublicationParser_SearchScholarIterator)AuthorAuthorSourceCitesPerYearJournalPublicationPublicationSourcez4/citations?hl=en&view_op=search_authors&mauthors={0}z:/citations?hl=en&view_op=search_authors&mauthors=label:{0}z3/citations?hl=en&view_op=search_authors&mauthors={}z[-: #(),;]+z/scholar?hl=en&q={0}z/scholar?hl=en&cites={0}z)/citations?view_op=view_org&hl=en&org={0}zKhttps://scholar.google.com/citations?view_op=mandates_leaderboard_csv&hl=enc                   b   e Zd ZdZd Zed        ZdeddfdZ	 dCde	d	e	ddfd
Z
defdZdefdZ	 	 	 	 	 dDdededededededededefdZdeeef   fdZdEdededefdZdefdZg d dfd!ed"ed#edexs efd$Zd!edefd%Zed&efd'       Zd!edefd(Zd!efd)ZdFd*eded"ed#edef
d+Z d,efd-Z!d.e"e   fd/Z#d0edefd1Z$d0edefd2Z%d!edefd3Z&d!exs eddfd4Z'dEded5ede(fd6Z)d7efd8Z*	 	 dGd9ed:ed;efd<Z+	 	 	 	 	 dDd=ededededededededefd>Z,d? Z-dHd@ede.ee/f   fdAZ0dHdBZ1y)I
_Scholarlyz(Class that manages the API for scholarlyc                     t        t                      t        j                  j	                         | _        t               | _        | j                  j                  | _        d | _	        y N)
r
   r	   osenvironcopyenvr   _Scholarly__navlogger_journal_categoriesselfs    L/home/agent/.friday_env/lib/python3.12/site-packages/scholarly/_scholarly.py__init__z_Scholarly.__init__   s@    KM"::??$[
jj''#'     c                 \    | j                   | j                         | _         | j                   S r   )r   get_journal_categoriesr   s    r!   journal_categoriesz_Scholarly.journal_categories&   s+    ##+'+'B'B'DD$'''r#   num_retriesreturnNc                 8    | j                   j                  |      S )zSets the number of retries in case of errors

        :param num_retries: the number of retries
        :type num_retries: int
        )r   _set_retries)r    r'   s     r!   set_retriesz_Scholarly.set_retries,   s     zz&&{33r#   proxy_generatorsecondary_proxy_generatorc                 <    | j                   j                  ||       y)a,  Select which proxy method to use.

        See the available ProxyGenerator methods.

        This is used to get some pages that have strong anti-bot prevention.
        ``secondary_proxy_generator`` is used for other pages that do not have
        a strong anti-bot prevention. If not set, free proxies are used.

        :param proxy_generator: a proxy generator object, typically setup with
                               a premium proxy service (ScraperAPI or Luminati)
        :type proxy_generator: ProxyGenerator
        :param proxy_generator: a second proxy generator object, optional
        :type proxy_generator: ProxyGenerator

        :Example::

        .. testcode::

            pg = ProxyGenerator()
            pg.ScraperAPI(YOUR_SCRAPER_API_KEY)
            scholarly.use_proxy(pg)

        N)r   	use_proxy)r    r,   r-   s      r!   r/   z_Scholarly.use_proxy5   s    2 	

_.GHr#   enablec                 :    | j                   j                  |       y)zTEnable or disable the logger for google scholar.
        Enabled by default
        N)r   
set_logger)r    r0   s     r!   r2   z_Scholarly.set_loggerQ   s     	

f%r#   timeoutc                 :    | j                   j                  |       y)z+Set timeout period in seconds for scholarlyN)r   set_timeout)r    r3   s     r!   r5   z_Scholarly.set_timeoutW   s    

w'r#   r   querypatents	citationsyear_low	year_highsort_byinclude_last_yearstart_indexc	           
          | j                  t        j                  t        j                  j                  |            |||||||      }	| j                  j                  |	      S )a  Searches by query and returns a generator of Publication objects

        :param query: terms to be searched
        :type query: str
        :param patents: Whether or not to include patents, defaults to True
        :type patents: bool, optional
        :param citations: Whether or not to include citations, defaults to True
        :type citations: bool, optional
        :param year_low: minimum year of publication, defaults to None
        :type year_low: int, optional
        :param year_high: maximum year of publication, defaults to None
        :type year_high: int, optional
        :param sort_by: 'relevance' or 'date', defaults to 'relevance'
        :type sort_by: string, optional
        :param include_last_year: 'abstracts' or 'everything', defaults to 'abstracts' and only applies if 'sort_by' is 'date'
        :type include_last_year: string, optional
        :param start_index: starting index of list of publications, defaults to 0
        :type start_index: int, optional
        :returns: Generator of Publication objects
        :rtype: Iterator[:class:`Publication`]

        :Example::

        .. testcode::

            search_query = scholarly.search_pubs('Perception of physical stability and center of mass of 3D objects')
            scholarly.pprint(next(search_query)) # in order to pretty print the result

        :Output::

        .. testoutput::

            {'author_id': ['4bahYMkAAAAJ', 'ruUKktgAAAAJ', ''],
             'bib': {'abstract': 'Humans can judge from vision alone whether an object is '
                                 'physically stable or not. Such judgments allow observers '
                                 'to predict the physical behavior of objects, and hence '
                                 'to guide their motor actions. We investigated the visual '
                                 'estimation of physical stability of 3-D objects (shown '
                                 'in stereoscopically viewed rendered scenes) and how it '
                                 'relates to visual estimates of their center of mass '
                                 '(COM). In Experiment 1, observers viewed an object near '
                                 'the edge of a table and adjusted its tilt to the '
                                 'perceived critical angle, ie, the tilt angle at which '
                                 'the object',
                     'author': ['SA Cholewiak', 'RW Fleming', 'M Singh'],
                     'pub_year': '2015',
                     'title': 'Perception of physical stability and center of mass of 3-D '
                              'objects',
                     'venue': 'Journal of vision'},
             'citedby_url': '/scholar?cites=15736880631888070187&as_sdt=5,33&sciodt=0,33&hl=en',
             'eprint_url': 'https://jov.arvojournals.org/article.aspx?articleID=2213254',
             'filled': False,
             'gsrank': 1,
             'num_citations': 23,
             'pub_url': 'https://jov.arvojournals.org/article.aspx?articleID=2213254',
             'source': 'PUBLICATION_SEARCH_SNIPPET',
             'url_add_sclib': '/citations?hl=en&xsrf=&continue=/scholar%3Fq%3DPerception%2Bof%2Bphysical%2Bstability%2Band%2Bcenter%2Bof%2Bmass%2Bof%2B3D%2Bobjects%26hl%3Den%26as_sdt%3D0,33&citilm=1&json=&update_op=library_add&info=K8ZpoI6hZNoJ&ei=QhqhX66wKoyNy9YPociEuA0',
             'url_scholarbib': '/scholar?q=info:K8ZpoI6hZNoJ:scholar.google.com/&output=cite&scirp=0&hl=en'}

        )r7   r8   r9   r:   r;   r<   r=   )_construct_url
_PUBSEARCHformatrequestsutilsquoter   search_publications)
r    r6   r7   r8   r9   r:   r;   r<   r=   urls
             r!   search_pubsz_Scholarly.search_pubs[   sb    D !!*"3"3HNN4H4H4O"PZa,5T]*1EVdo " q zz--c22r#   publication_idc                      | j                   t        j                  t        |            fi |}| j                  j                  |      S )a  Searches by Google Scholar publication id and returns a generator of Publication objects.

        :param publication_id: Google Scholar publication id
        :type publication_id: int or str

        For the remaining parameters, see documentation of `search_pubs`.
        )r?   _CITEDBYSEARCHrA   strr   rE   )r    rH   kwargsrF   s       r!   search_citedbyz_Scholarly.search_citedby   sA     "d!!."7"7N8K"LWPVWzz--c22r#   	pub_titlefilledc                     t         j                  t        j                  j	                  |            }| j
                  j                  ||      S )a&  Search by scholar query and return a single Publication container object

        :param pub_title: Title of the publication to search
        :type pub_title: string
        :param filled: Whether the application should be filled with additional information
        :type filled: bool
        )r@   rA   rB   rC   rD   r   search_publication)r    rN   rO   rF   s       r!   search_single_pubz_Scholarly.search_single_pub   s:      4 4Y ?@zz,,S&99r#   namec                     t         j                  t        j                  j	                  |            }| j
                  j                  |      S )a%  Search by author name and return a generator of Author objects

        :Example::

            .. testcode::

                search_query = scholarly.search_author('Marty Banks, Berkeley')
                scholarly.pprint(next(search_query))

        :Output::

        .. testoutput::

            {'affiliation': 'Professor of Vision Science, UC Berkeley',
             'citedby': 21074,
             'email_domain': '@berkeley.edu',
             'filled': False,
             'interests': ['vision science', 'psychology', 'human factors', 'neuroscience'],
             'name': 'Martin Banks',
             'scholar_id': 'Smr99uEAAAAJ',
             'source': 'SEARCH_AUTHOR_SNIPPETS',
             'url_picture': 'https://scholar.google.com/citations?view_op=medium_photo&user=Smr99uEAAAAJ'}
        )_AUTHSEARCHrA   rB   rC   rD   r   search_authors)r    rS   rF   s      r!   search_authorz_Scholarly.search_author   s8    0   !5!5d!;<zz((--r#   citedbyobjectsortbypublication_limitc                     |d   dk(  r:t        | j                        }|j                  ||||      }|du rt        d      |S |d   dk(  r&t	        | j                        }|j                  |      }|S )a  Fills the object according to its type.
        If the container type is Author it will fill the additional author fields
        If it is Publication it will fill it accordingly.

        :param object: the Author or Publication object that needs to get filled
        :type object: Author or Publication
        :param sections: the sections that the user wants filled for an Author object. This can be: ['basics', 'indices', 'counts', 'coauthors', 'publications', 'public_access']
        :type sections: list
        :param sortby: if the object is an author, select the order of the citations in the author page. Either by 'citedby' or 'year'. Defaults to 'citedby'.
        :type sortby: string
        :param publication_limit: if the object is an author, select the max number of publications you want you want to fill for the author. Defaults to no limit.
        :type publication_limit: int

        Note:  For Author objects, if 'public_access' is filled prior to 'publications',
        only the total counts from the Public Access section of the author's profile page is filled.
        If 'public_access' is filled along with 'publications' or afterwards for the first time,
        the publication entries are also marked whether they satisfy public access mandates or not.
        container_typer   FzIncorrect inputr   )r   r   fill
ValueErrorr   )r    rY   sectionsrZ   r[   author_parserpublication_parsers          r!   r^   z_Scholarly.fill   s    ( "#x/(4M"''&BSTF !233  $%6!24::!>',,V4Fr#   c                     |d   dk(  r&t        | j                        }|j                  |      S | j                  j	                  d       y)zReturns a bibtex entry for a publication that has either Scholar source
        or citation source

        :param object: The Publication object for the bibtex exportation
        :type object: Publication
        r]   r   +Object not supported for bibtex exportationN)r   r   bibtexr   warning)r    rY   rb   s      r!   re   z_Scholarly.bibtex   sH     "#}4!24::!>%,,V44KK MNr#   cites_per_yearc                     g }||}}d}t        | d      D ]2  }|| |   z   dk  r|| |   z  }|}| |   }|j                  ||f       |}4 |dkD  r|j                  ||f       |S )Nr   T)reverse  )sortedappend)rg   year_endyearsy_hiy_lorunning_countys          r!   _bin_citations_by_yearz!_Scholarly._bin_citations_by_year   s    xd5 	A~a00D8!22 .q 1dD\*	 1LL$&r#   c                 &   |d   dk7  r| j                   j                  d       y|d   dk  r$t        | j                        j	                  |      S | j                   j                  d|d   d	   |d          t        t        j                  j                         j                        }|d
   t        j                  k(  r4| j                  |       | j                  |j                  di       |      }n:	 t        |d   d         }t#        t%        ||dz
  d      t%        ||dz
  d            }| j'                  ||      S # t         $ rI | j                   j                  d|d   d	          t        | j                        j	                  |      cY S w xY w)zSearches Google Scholar for other articles that cite this Publication
        and returns a Publication generator.

        :param object: The Publication object for the bibtex exportation
        :type object: Publication
        r]   r   rd   Nnum_citationsrj   zSSince the paper titled %s has %d citations (>1000), fetching it on an annual basis.bibtitlesourcerg   pub_yearzXUnknown publication year for paper %s, may result in incorrect number of citedby papers.r   )r   rf   r   r   rX   debugintdatetimedatetodayyearr   AUTHOR_PUBLICATION_ENTRYr^   rs   getKeyErrorziprange_citedby_long)r    rY   rm   rn   r9   s        r!   rX   z_Scholarly.citedby  s    "#}4KK MN/"d*$TZZ088@@ <=CE]7=SU[\kUl	n x}}**,112(0IIIIIf//

;KR0PRZ[EEve}Z89 h
B7xRSUW9XYE!!&//  E## %9:@-:PR(4<<VDDEs   3D> >AFFc              #   J  K   t        j                  d|d         }|j                         dd  }|D ]l  \  }}| j                  |||      }|j                  r=|j                  dkD  r.| j
                  j                  d|d   d   |j                  |       |E d {    n y 7 w)	Nzcites=[\d+,]*citedby_url   )rH   r9   r:   rj   zThe paper titled %s has %d citations in the year %d. Due to the limitation in Google Scholar, fetching only 1000 results from that year.rv   rw   )researchgrouprM   total_resultsr   warn)r    rY   rn   mpub_idro   rp   sub_citationss           r!   r   z_Scholarly._citedby_long6  s     IIovm'<=12 	%JD$ //vPT`d/eM**0K0Kd0R   "34:5M'4JMLgLgimo %$$	% %s   BB#B!B#idc                 >    | j                   j                  ||||      S )uH  Search by author id and return a single Author object
        :param sortby: select the order of the citations in the author page. Either by 'citedby' or 'year'. Defaults to 'citedby'.
        :type sortby: string
        :param publication_limit: if the object is an author, select the max number of publications you want you want to fill for the author. Defaults to no limit.
        :type publication_limit: int

        :Example::

            .. testcode::

                search_query = scholarly.search_author_id('EmD_lTEAAAAJ')
                scholarly.pprint(search_query)

        :Output::

            .. testoutput::

                {'affiliation': 'Institut du radium, University of Paris',
                 'citedby': 2208,
                 'filled': False,
                 'interests': [],
                 'name': 'Marie Skłodowska-Curie',
                 'scholar_id': 'EmD_lTEAAAAJ',
                 'source': 'AUTHOR_PROFILE_PAGE',
                 'url_picture': 'https://scholar.googleusercontent.com/citations?view_op=view_photo&user=EmD_lTEAAAAJ&citpid=3'}
        )r   search_author_id)r    r   rO   rZ   r[   s        r!   r   z_Scholarly.search_author_idB  s     6 zz**2vv?PQQr#   keywordc                     t        j                  t        d|      }t        j	                  t
        j                  j                  |            }| j                  j                  |      S )a  Search by keyword and return a generator of Author objects

        :param keyword: keyword to be searched
        :type keyword: str

        :Example::

        .. testcode::

            search_query = scholarly.search_keyword('Haptics')
            scholarly.pprint(next(search_query))

        :Output::

        .. testoutput::

            {'affiliation': 'Postdoctoral research assistant, University of Bremen',
             'citedby': 56666,
             'email_domain': '@collision-detection.com',
             'filled': False,
             'interests': ['Computer Graphics',
                           'Collision Detection',
                           'Haptics',
                           'Geometric Data Structures'],
             'name': 'Rene Weller',
             'scholar_id': 'lHrs3Y4AAAAJ',
             'source': 'SEARCH_AUTHOR_SNIPPETS',
             'url_picture': 'https://scholar.google.com/citations?view_op=medium_photo&user=lHrs3Y4AAAAJ'}
        _)
r   sub_KEYWORDSEARCH_PATTERN_KEYWORDSEARCHrA   rB   rC   rD   r   rV   )r    r   reg_keywordrF   s       r!   search_keywordz_Scholarly.search_keyword_  sK    > ff3S'B##HNN$8$8$EFzz((--r#   keywordsc                     d |D        }|D cg c]$  }dt         j                  j                  |      z   & }}dj                  |      }t        j                  |      }| j                  j                  |      S c c}w )a  Search by keywords and return a generator of Author objects

        :param keywords: a list of keywords to be searched
        :type keyword: List[str]

        :Example::

        .. testcode::

            search_query = scholarly.search_keywords(['crowdsourcing', 'privacy'])
            scholarly.pprint(next(search_query))

        :Output::

        .. testoutput::
                {'affiliation': 'Cornell University',
                 'citedby': 40976,
                 'email_domain': '',
                 'filled': False,
                 'interests': ['Crowdsourcing',
                               'privacy',
                               'social computing',
                               'game theory',
                               'user-generated content'],
                 'name': 'Arpita Ghosh',
                 'scholar_id': '_cMw1IUAAAAJ',
                 'source': 'SEARCH_AUTHOR_SNIPPETS',
                 'url_picture': 'https://scholar.google.com/citations?view_op=medium_photo&user=_cMw1IUAAAAJ'}

        c              3   R   K   | ]  }t        j                  t        d |       ! yw)r   N)r   r   r   ).0r   s     r!   	<genexpr>z-_Scholarly.search_keywords.<locals>.<genexpr>  s     ]5sGD]s   %'zlabel:+)rB   rC   rD   join_KEYWORDSEARCHBASErA   r   rV   )r    r   reg_keywordsr   formated_keywordsrF   s         r!   search_keywordsz_Scholarly.search_keywords  st    > ^T\]S_`Xhnn&:&:7&CC``HH%67 ''(9:zz((-- as   )A:rF   c                 8    | j                   j                  |      S )a  Search by custom URL and return a generator of Publication objects
        URL should be of the form '/scholar?q=...'

        A typical use case is to generate the URL by first typing in search
        parameters in the Advanced Search dialog box and then use the URL here
        to programmatically fetch the results.

        :param url: custom url to seach for the publication
        :type url: string
        )r   rE   r    rF   s     r!   search_pubs_custom_urlz!_Scholarly.search_pubs_custom_url  s     zz--c22r#   c                 8    | j                   j                  |      S )zSearch by custom URL and return a generator of Author objects
        URL should be of the form '/citation?q=...'

        :param url: url for the custom author url
        :type url: string
        )r   rV   r   s     r!   search_author_custom_urlz#_Scholarly.search_author_custom_url  s     zz((--r#   c                 b   |d   dk7  r| j                   j                  d       y|d   t        j                  k(  rAd|j	                         vr| j                  |      }| j                  j                  |d         S |d   t        j                  k(  r| j                  j                  |d         S y)z
        Search google scholar for related articles to a specific publication.

        :param object: Publication object used to get the related articles
        :type object: Publication
        r]   r   zNot a publication objectNrx   url_related_articles)	r   rf   r   r   keysr^   r   rE   PUBLICATION_SEARCH_SNIPPET)r    rY   s     r!   get_related_articlesz_Scholarly.get_related_articles  s     "#}4KK :;(0III%V[[]:6*::11&9O2PQQH!2!M!MM::11&9O2PQQ Nr#   c                 z   d|vr| j                   j                  d       yt        j                  |      }|d   dk(  rt	        |d         j
                  |d<   n|d   dk(  rt        | j                        }t        |d         j
                  |d<   |j                  |d   k(  rd|d<   nd	|d<   d
|v r-|d
   D ]%  }d	|d<   |d= t        |d         j
                  |d<   ' d|v r(|d   D ]   }t	        |d         j
                  |d<   |d= " |d= t        t        j                  |      j                  d             y)zPretty print an Author or Publication container object

        :param object: Publication or Author container object
        :type object: Author or Publication
        r]   z Not a scholarly container objectNr   rx   r   rO   TF	coauthorspublicationszutf-8)r   rf   r   deepcopyr   rS   r   r   r   	_sectionsprintpprintpformatencode)r    rY   to_printparsercoauthorpublications         r!   r   z_Scholarly.pprint  sh    6)KK BC==($%6!28H3E!F!K!KHX&'83!$**-F!-hx.@!A!F!FHX8H#55%)"%*"h& ( 5 OH).HX& !12)5hx6H)I)N)NHX&O
 )#+N#; 6K,=k(>S,T,Y,YK)#$456 %&fnnX&--g67r#   
fromauthorc                     t         j                  t        j                  j	                  |            }| j
                  j                  ||      S )a(  
        Search by organization name and return a list of possible disambiguations

        :Example::
            .. testcode::
                search_query = scholarly.search_org('ucla')
                print(search_query)

        :Output::
            .. testoutput::
                [{'Organization': 'University of California, Los Angeles',
                  'id': '14108176128635076915'},
                 {'Organization': 'Universidad Centroccidental Lisandro Alvarado',
                  'id': '9670678584336165373'}
                ]
        )rU   rA   rB   rC   rD   r   search_organization)r    rS   r   rF   s       r!   
search_orgz_Scholarly.search_org  s:    $   !5!5d!;<zz--c:>>r#   organization_idc                 b    t         j                  |      }| j                  j                  |      S )a>  
        Search for authors in an organization and return a generator of Authors

        ``organization_id`` can be found from the organization name using
        ``search_org``. Alternatively, they can be found in the ``Author`` object.

        The returned authors are typically in the decreasing order of total citations.
        The authors must have a verified email address and set their affiliation
        appropriately to appear on this list.

        :param organization_id: unique integer id for each organization
        :type organization_id: integer
        )
_ORGSEARCHrA   r   rV   )r    r   rF   s      r!   search_author_by_organizationz(_Scholarly.search_author_by_organization  s)     0zz((--r#   filename	overwriteinclude_linksc                 H   |s-t         j                  j                  |      rt        | d      | j                  j                  t        d      }|r| j                  j                  d      }|j                  ddd      }|j                  dd	
      D ]  }|j                  dd
      j                  d   }|j                  j                  }|dk7  r|j                  d   }	n|j                  dd }d}	d|v r!|j                  d| dd| d|	 d| d      }|j                  | d| d|	 d| d      } 	 t        |d      5 }
|
j                  |       ddd       |S # 1 sw Y   |S xY w# t        $ r  | j                   j#                  d|       Y |S w xY w# |c cY S xY w)z@
        Download the CSV file of the current mandates.
        zc already exists. Either provide a different filename or allow overwriting by setting overwrite=TrueF)premiumz-/citations?hl=en&view_op=mandates_leaderboardzFunder,zFunder,Policy,Cached,r   td	gsc_mlt_tclass_spangs_ahrefcachedNi ,"z",wzError writing mandates as %s)r   pathexistsr_   r   	_get_page_MANDATES_URL	_get_soupreplacefind_allfindatextopenwriteIOErrorr   error)r    r   r   r   r   soupagencyr   rS   policyfs              r!   download_mandates_csvz _Scholarly.download_mandates_csv  s   
 rww~~h7z *7 7 8 8 zz##M5#A::''(WXD<<	+BAFD--[-A RVF;==fExx}}8##XXf-F!;;t,DF$;<<!D6$r&6(RS6TUD<<4&
tfAfXQvha4PQDR	h$ 
 K
 K  	HKK<hGK	H KsB   9E. E!E. !E+&E. +E. .%FF FF F!baseurlc	                    |}	|dj                  |      nd}
|dj                  |      nd}dj                  dt        |      z
        }dj                  dt        |      z
        }d}|dkD  rd	j                  |      nd}|d
k(  r,|dk(  rd}nE|dk(  rd}n=| j                  j                  d       y|dk7  r| j                  j                  d       y|	|
z   |z   |z   |z   |z   |z   S )z(Construct URL from requested parameters.Nz&as_ylo={0}r   z&as_yhi={0}z&as_vis={0}r   z&as_sdt={0},33r   z
&start={0}r~   	abstractsz	&scisbd=1
everythingz	&scisbd=2zTInvalid option for 'include_last_year', available options: 'everything', 'abstracts'	relevancezDInvalid option for 'sort_by', available options: 'relevance', 'date')rA   r|   r   r{   )r    r   r7   r8   r9   r:   r;   r<   r=   rF   yr_loyr_hirZ   starts                 r!   r?   z_Scholarly._construct_url;  s    2:2F$$X.B3<3H$$Y/b!((S^);<	"))!c'l*:;4?!O##K0f K/$"l2$!!"xy#KKde U{U"Y.86AEIIr#   c                    | j                   j                  d      }i }|j                  dd      D ]B  }d|d   vr|d   j                  d      d   }i ||j                  <   |||j                     d	<   D |D ]y  }||   d	   }|d
k(  r| j                   j                  d|       }|j                  dd      D ]5  }d| d|d   vr|d   j                  d      d   ||   |j                  <   7 { |S )zE
        Get a dict of journal categories and subcategories.
        z)/citations?view_op=top_venues&hl=en&vq=enr   gs_md_lir   zvq=r   z&vq=r   Nen'/citations?view_op=top_venues&hl=en&vq=r   )r   r   r   splitr   )r    r   
categoriescategoryvqsubcategorys         r!   r%   z!_Scholarly.get_journal_categoriesY  s9    zz##$OP
c*= 	1HHV,,&!''/2B(*Jx}}%.0Jx}}%d+	1 # 	^HH%d+B4x::''*QRTQU(VWD#}}S}D ^bT|{6'::9DV9L9R9RSY9Z[\9]
8$[%5%56^	^ r#   include_commentsc           
         	 | j                   |   }	 ||   }d| }| j                  j                  |      }|j                  dd      }|j                  dd      }	|j                  dd      }
|j                  dd	      }i }t	        ||	|
|      D ]  \  }}}}|d
   }d}|rY| j                  j                  |      }	 |j                  dd      d   j                  d      D ]  }||j
                  dz   z  } 	 t        |j
                  t        |j
                        t        |j
                        ||      |t        |j
                  d d       <    |S # t        $ r Y hw xY w# t        $ r# t        d|d|d|j                               w xY w# t        $ r& t        d|| j                   j                               w xY w)Nr   r   	gsc_mvt_pr   	gsc_mvt_tr   zgs_ibl gsc_mp_anchorr   gs_iblr   r   ulgsc_mlhd_listr   liz; )rS   h5_index	h5_medianurl_citationscommentrz   zInvalid subcategory: z for z. Choose one from z(Invalid category: %s. Choose one from %s)r&   r   r   r   r   r   
IndexErrorr   r|   r   r_   r   )r    r   r   r   catsubcatrF   r   ranksnames	h5indices	h5mediansresultrankrS   h5indexh5medianr  r  cmts                       r!   get_journalsz_Scholarly.get_journalss  s   $	s))(3C }[)?xHzz++C0d;?d;? MM#6LMM	 MM&MB	 58yR[5\ ;1D$$+FOM G'#zz33MB!'+}}T/}'RST'U'^'^_c'd 9 '388D= 89 3:tyyCFw||CTDGDVHUBI	3;F3tyy"~./;"   * ! !  } Ydfnpspxpxpz!{||} 	sGSWSjSjSoSoSqrr	ssB   F B-E)  <E<AE) 	E&#E) %E&&E) ),FF /Gc                    | j                  |||      }	 t        |d      5 }t        j                  |      }g ddg|z  z   }|j	                  |       |j                         D ];  \  }	}
|
d   |
d   |
d   g|
j                  dd      g|z  z   }|j	                  |       = 	 d	d	d	       |S # 1 sw Y   |S xY w# t        $ r  | j                  j                  d
|       Y |S w xY w# |c cY S xY w)zB
        Save a list of journals to a file in CSV format.
        r   )r   zh5-indexz	h5-medianCommentrS   r  r  r  r   NzError writing journals as %s)
r  r   csvwriterwriterowitemsr   r   r   r   )r    r   r   r   r   journalsr   
csv_writerheaderr  journalrows               r!   save_journals_csvz_Scholarly.save_journals_csv  s    $$X{<LM	h$ - ZZ]
AYKP`D``##F+%-^^%5 -MD'"6?GJ,?AUVZaZeZefoqsZtYu  wG  ZG  GC'',-	- O- O  	HKK<hGO	H OsA   B9 B B,"B9 ,B61B9 6B9 9%C"C% !C""C% %C,r   )TTNNr   r   r   )F)FrX   r   )FT)EnglishNF)2__name__
__module____qualname____doc__r"   propertyr&   r|   r+   r   r/   boolr2   r5   rK   r   rG   r   rM   r   rR   rW   dictr   r   r^   re   staticmethodr   rs   rX   r   r   r   r   r   r   r   r   r   listr   r   r   r?   r%   r   r   r  r    r#   r!   r   r      s-   2( ( (
4s 4T 4 ?CI I-;IGKI8& &(3 (
 15<@:E-8'(E3E3)-E3#E369E3  #E3 58E3 (+	E3
 "%E3
 ,BE3N	3U38_ 	3	:3 	: 	:GX 	:.# .6 +-I`a 4 c Z] flf{p{ <[ 3  |  $"0k "0,B "0H
%K 
%R3 R Rc Rjm Rtz R:!.c !.F#.S	 #.J3# 30F 3.C .& .R; R9O R$!8V2{ !8T !8F?s ? ? ?*.S ." FK37 c  d  -1 F <@?C=H0;*+	Jc JD J"&J9<J"%J7:J +.J %(	J 03	J<4%sSW %sdhilnuiudv %sNr#   r   )(r%  rB   r   r   r   r  r   r}   typingr   r   r   
_navigatorr   _proxy_generatorr   dotenvr	   r
   ra   r   rb   r   r   
data_typesr   r   r   r   r   r   rU   r   r   r   r@   rJ   r   r   r   r+  r#   r!   <module>r1     sq      	 	  
   	 $ $ ! , + ' I c cDMJ & #
+8
]N
 N
r#   