papers-cli 2.14.1__tar.gz → 2.14.3__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.
Files changed (45) hide show
  1. {papers_cli-2.14.1 → papers_cli-2.14.3}/PKG-INFO +4 -2
  2. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/_version.py +2 -2
  3. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/bib.py +12 -2
  4. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/extract.py +64 -3
  5. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers_cli.egg-info/PKG-INFO +4 -2
  6. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers_cli.egg-info/requires.txt +1 -0
  7. {papers_cli-2.14.1 → papers_cli-2.14.3}/pyproject.toml +2 -0
  8. {papers_cli-2.14.1 → papers_cli-2.14.3}/requirements.txt +2 -1
  9. {papers_cli-2.14.1 → papers_cli-2.14.3}/.gitattributes +0 -0
  10. {papers_cli-2.14.1 → papers_cli-2.14.3}/.github/FUNDING.yml +0 -0
  11. {papers_cli-2.14.1 → papers_cli-2.14.3}/.github/workflows/pypi.yml +0 -0
  12. {papers_cli-2.14.1 → papers_cli-2.14.3}/.github/workflows/tests.yml +0 -0
  13. {papers_cli-2.14.1 → papers_cli-2.14.3}/.gitignore +0 -0
  14. {papers_cli-2.14.1 → papers_cli-2.14.3}/LICENSE +0 -0
  15. {papers_cli-2.14.1 → papers_cli-2.14.3}/README.md +0 -0
  16. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/__init__.py +0 -0
  17. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/__main__.py +0 -0
  18. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/config.py +0 -0
  19. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/duplicate.py +0 -0
  20. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/encoding.py +0 -0
  21. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/filename.py +0 -0
  22. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/latexenc.py +0 -0
  23. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers/utils.py +0 -0
  24. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers_cli.egg-info/SOURCES.txt +0 -0
  25. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers_cli.egg-info/dependency_links.txt +0 -0
  26. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers_cli.egg-info/entry_points.txt +0 -0
  27. {papers_cli-2.14.1 → papers_cli-2.14.3}/papers_cli.egg-info/top_level.txt +0 -0
  28. {papers_cli-2.14.1 → papers_cli-2.14.3}/setup.cfg +0 -0
  29. {papers_cli-2.14.1 → papers_cli-2.14.3}/setup.py +0 -0
  30. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/__init__.py +0 -0
  31. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/common.py +0 -0
  32. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/config.py +0 -0
  33. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/download.py +0 -0
  34. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/downloadedpapers/.gitignore +0 -0
  35. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/downloadedpapers/bg-8-515-2011.txt +0 -0
  36. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_add.py +0 -0
  37. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_biblio.py +0 -0
  38. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_duplicates.py +0 -0
  39. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_encoding.py +0 -0
  40. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_extract.py +0 -0
  41. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_filecheck.py +0 -0
  42. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_install.py +0 -0
  43. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_list.py +0 -0
  44. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_misc.py +0 -0
  45. {papers_cli-2.14.1 → papers_cli-2.14.3}/tests/test_undo.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: papers-cli
3
- Version: 2.14.1
3
+ Version: 2.14.3
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
  [![test](https://github.com/perrette/papers/workflows/CI/badge.svg?query=branch%3Amaster)](https://github.com/perrette/papers/actions)
22
24
  [![python](https://img.shields.io/badge/python-3.9-blue.svg)]()
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.14.1'
21
- __version_tuple__ = version_tuple = (2, 14, 1)
20
+ __version__ = version = '2.14.3'
21
+ __version_tuple__ = version_tuple = (2, 14, 3)
@@ -420,11 +420,21 @@ 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:
426
437
  bibtex = extract_pdf_metadata(pdf, search_doi, search_fulltext, scholar=scholar)
427
-
428
438
  bib = bibtexparser.loads(bibtex)
429
439
  entry = bib.entries[0]
430
440
 
@@ -881,4 +891,4 @@ def clean_filesdir(biblio, interactive=True, ignore_files=None, ignore_folders=N
881
891
 
882
892
  break
883
893
 
884
- return removed_files
894
+ return removed_files
@@ -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
- json_data = fetch_crossref_by_doi(doi)
273
- return crossref_to_bibtex(json_data['message'])
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, as_string=True)
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,50 @@ 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, as_string=False):
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
+ if as_string:
536
+ return bibtex_content
537
+ else:
538
+ return bibtex_entry
539
+
540
+ raise DOIRequestError("No matching BibTeX entry found for the given DOI.")
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: papers-cli
3
- Version: 2.14.1
3
+ Version: 2.14.3
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
  [![test](https://github.com/perrette/papers/workflows/CI/badge.svg?query=branch%3Amaster)](https://github.com/perrette/papers/actions)
22
24
  [![python](https://img.shields.io/badge/python-3.9-blue.svg)]()
@@ -5,3 +5,4 @@ bibtexparser
5
5
  scholarly
6
6
  rapidfuzz
7
7
  normality
8
+ bs4
@@ -23,6 +23,7 @@ dependencies = [
23
23
  "scholarly",
24
24
  "rapidfuzz",
25
25
  "normality",
26
+ "bs4",
26
27
  ]
27
28
  dynamic = ["version"]
28
29
 
@@ -65,6 +66,7 @@ deps =
65
66
  rapidfuzz
66
67
  unidecode
67
68
  normality
69
+ bs4
68
70
  pytest
69
71
  pytest-cov
70
72
  depends =
@@ -4,4 +4,5 @@ crossrefapi
4
4
  bibtexparser < 2.0.0
5
5
  scholarly
6
6
  rapidfuzz
7
- normality
7
+ normality
8
+ bs4
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