papers-cli 2.14.1__tar.gz → 2.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {papers_cli-2.14.1 → papers_cli-2.15}/PKG-INFO +4 -2
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/_version.py +2 -2
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/bib.py +11 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/extract.py +61 -3
- {papers_cli-2.14.1 → papers_cli-2.15}/papers_cli.egg-info/PKG-INFO +4 -2
- {papers_cli-2.14.1 → papers_cli-2.15}/papers_cli.egg-info/requires.txt +1 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/pyproject.toml +2 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/requirements.txt +2 -1
- {papers_cli-2.14.1 → papers_cli-2.15}/.gitattributes +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/.github/FUNDING.yml +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/.github/workflows/pypi.yml +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/.github/workflows/tests.yml +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/.gitignore +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/LICENSE +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/README.md +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/__init__.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/__main__.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/config.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/duplicate.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/encoding.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/filename.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/latexenc.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers/utils.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers_cli.egg-info/SOURCES.txt +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers_cli.egg-info/dependency_links.txt +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers_cli.egg-info/entry_points.txt +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/papers_cli.egg-info/top_level.txt +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/setup.cfg +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/setup.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/__init__.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/common.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/config.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/download.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/downloadedpapers/.gitignore +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/downloadedpapers/bg-8-515-2011.txt +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_add.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_biblio.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_duplicates.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_encoding.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_extract.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_filecheck.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_install.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_list.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_misc.py +0 -0
- {papers_cli-2.14.1 → papers_cli-2.15}/tests/test_undo.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: papers-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.15
|
|
4
4
|
Summary: utilities to keep your PDF library organized
|
|
5
5
|
Author-email: Mahé Perrette <mahe.perrette@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -17,6 +17,8 @@ Requires-Dist: bibtexparser
|
|
|
17
17
|
Requires-Dist: scholarly
|
|
18
18
|
Requires-Dist: rapidfuzz
|
|
19
19
|
Requires-Dist: normality
|
|
20
|
+
Requires-Dist: bs4
|
|
21
|
+
Dynamic: license-file
|
|
20
22
|
|
|
21
23
|
[](https://github.com/perrette/papers/actions)
|
|
22
24
|
[]()
|
|
@@ -420,6 +420,17 @@ class Biblio:
|
|
|
420
420
|
|
|
421
421
|
def add_pdf(self, pdf, attachments=None, search_doi=True, search_fulltext=True, scholar=False, doi=None, **kw):
|
|
422
422
|
|
|
423
|
+
if str(pdf).startswith("http"):
|
|
424
|
+
# if pdf is a URL, download it
|
|
425
|
+
import requests, tempfile
|
|
426
|
+
response = requests.get(pdf)
|
|
427
|
+
if response.status_code == 200:
|
|
428
|
+
pdf = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf').name
|
|
429
|
+
with open(pdf, 'wb') as f:
|
|
430
|
+
f.write(response.content)
|
|
431
|
+
else:
|
|
432
|
+
raise ValueError(f"Failed to download PDF from {pdf}")
|
|
433
|
+
|
|
423
434
|
if doi:
|
|
424
435
|
bibtex = fetch_bibtex_by_doi(doi)
|
|
425
436
|
else:
|
|
@@ -14,6 +14,10 @@ from papers import logger
|
|
|
14
14
|
from papers.encoding import family_names
|
|
15
15
|
from bibtexparser.customization import convert_to_unicode
|
|
16
16
|
|
|
17
|
+
from bs4 import BeautifulSoup
|
|
18
|
+
from urllib.parse import urljoin
|
|
19
|
+
|
|
20
|
+
|
|
17
21
|
my_etiquette = Etiquette('papers', papers.__version__, 'https://github.com/perrette/papers', 'mahe.perrette@gmail.com')
|
|
18
22
|
work = Works(etiquette=my_etiquette)
|
|
19
23
|
|
|
@@ -265,12 +269,22 @@ def fetch_bibtex_by_arxiv(arxiv_id):
|
|
|
265
269
|
else:
|
|
266
270
|
return f"Error: Unable to fetch BibTeX (HTTP {response.status_code})"
|
|
267
271
|
|
|
268
|
-
# @cached('crossref-bibtex.json')
|
|
269
272
|
def fetch_bibtex_by_doi(doi):
|
|
270
273
|
if "arxiv" in doi.lower():
|
|
271
274
|
return fetch_bibtex_by_arxiv(doi.split("arXiv.")[1])
|
|
272
|
-
|
|
273
|
-
|
|
275
|
+
try:
|
|
276
|
+
json_data = fetch_crossref_by_doi(doi)
|
|
277
|
+
return crossref_to_bibtex(json_data['message'])
|
|
278
|
+
except DOIRequestError as error:
|
|
279
|
+
pass
|
|
280
|
+
|
|
281
|
+
try:
|
|
282
|
+
return fetch_bibtex_on_journal_website(doi)
|
|
283
|
+
except:
|
|
284
|
+
pass
|
|
285
|
+
|
|
286
|
+
raise DOIRequestError(f"Unable to fetch BibTeX for DOI {doi}")
|
|
287
|
+
|
|
274
288
|
|
|
275
289
|
@cached('crossref-json.json')
|
|
276
290
|
def fetch_json_by_doi(doi):
|
|
@@ -477,3 +491,47 @@ def fetch_entry(e):
|
|
|
477
491
|
ValueError('no author nor title field')
|
|
478
492
|
db = bibtexparser.loads(bibtex)
|
|
479
493
|
return db.entries[0]
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
############### HERE A HACK DESIGNED FOR THE ESD JOURNAL ################
|
|
498
|
+
# That journal often provides DOI that are not yet registered in crossref
|
|
499
|
+
# so we need to fetch the bibtex from the journal website
|
|
500
|
+
# Thanks Le Chat for near-instantaneous and elegantly designed code
|
|
501
|
+
|
|
502
|
+
def fetch_html(url):
|
|
503
|
+
response = requests.get(url)
|
|
504
|
+
response.raise_for_status() # Raise an error for bad status codes
|
|
505
|
+
return response.text
|
|
506
|
+
|
|
507
|
+
def find_bibtex_links(html_content, base_url):
|
|
508
|
+
soup = BeautifulSoup(html_content, 'html.parser')
|
|
509
|
+
|
|
510
|
+
for link in soup.find_all('a', href=True):
|
|
511
|
+
href = link['href']
|
|
512
|
+
if href.endswith('.bib'):
|
|
513
|
+
full_url = urljoin(base_url, href)
|
|
514
|
+
yield full_url
|
|
515
|
+
|
|
516
|
+
def download_bibtex(url):
|
|
517
|
+
response = requests.get(url)
|
|
518
|
+
response.raise_for_status()
|
|
519
|
+
return response.text
|
|
520
|
+
|
|
521
|
+
def parse_bibtex(bibtex_content, target_doi):
|
|
522
|
+
bib_database = bibtexparser.loads(bibtex_content)
|
|
523
|
+
for entry in bib_database.entries:
|
|
524
|
+
if (entry.get('doi', '') or entry.get('DOI', '')).lower() == target_doi.lower():
|
|
525
|
+
return entry
|
|
526
|
+
return None
|
|
527
|
+
|
|
528
|
+
def fetch_bibtex_on_journal_website(doi):
|
|
529
|
+
base_url = f"https://doi.org/{doi}"
|
|
530
|
+
html_content = fetch_html(base_url)
|
|
531
|
+
for bibtex_url in find_bibtex_links(html_content, base_url):
|
|
532
|
+
bibtex_content = download_bibtex(bibtex_url)
|
|
533
|
+
bibtex_entry = parse_bibtex(bibtex_content, doi)
|
|
534
|
+
if bibtex_entry:
|
|
535
|
+
return bibtex_entry
|
|
536
|
+
|
|
537
|
+
raise DOIRequestError("No matching BibTeX entry found for the given DOI.")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: papers-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.15
|
|
4
4
|
Summary: utilities to keep your PDF library organized
|
|
5
5
|
Author-email: Mahé Perrette <mahe.perrette@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -17,6 +17,8 @@ Requires-Dist: bibtexparser
|
|
|
17
17
|
Requires-Dist: scholarly
|
|
18
18
|
Requires-Dist: rapidfuzz
|
|
19
19
|
Requires-Dist: normality
|
|
20
|
+
Requires-Dist: bs4
|
|
21
|
+
Dynamic: license-file
|
|
20
22
|
|
|
21
23
|
[](https://github.com/perrette/papers/actions)
|
|
22
24
|
[]()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|