papers-cli 2.5__tar.gz → 2.6__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.5 → papers_cli-2.6}/PKG-INFO +1 -1
- {papers_cli-2.5 → papers_cli-2.6}/papers/__main__.py +9 -1
- {papers_cli-2.5 → papers_cli-2.6}/papers/_version.py +2 -2
- {papers_cli-2.5 → papers_cli-2.6}/papers/bib.py +8 -5
- {papers_cli-2.5 → papers_cli-2.6}/papers/utils.py +14 -1
- {papers_cli-2.5 → papers_cli-2.6}/papers_cli.egg-info/PKG-INFO +1 -1
- {papers_cli-2.5 → papers_cli-2.6}/.gitattributes +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/.github/workflows/tests.yml +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/.gitignore +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/LICENSE +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/README.md +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers/__init__.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers/config.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers/duplicate.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers/encoding.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers/extract.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers/filename.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers/latexenc.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers_cli.egg-info/SOURCES.txt +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers_cli.egg-info/dependency_links.txt +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers_cli.egg-info/entry_points.txt +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers_cli.egg-info/requires.txt +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/papers_cli.egg-info/top_level.txt +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/pyproject.toml +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/requirements.txt +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/setup.cfg +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/setup.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/__init__.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/common.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/config.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/download.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/downloadedpapers/.gitignore +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/downloadedpapers/bg-8-515-2011.txt +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_add.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_biblio.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_duplicates.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_encoding.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_extract.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_filecheck.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_install.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_list.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_misc.py +0 -0
- {papers_cli-2.5 → papers_cli-2.6}/tests/test_undo.py +0 -0
|
@@ -18,7 +18,7 @@ from papers.encoding import parse_file, format_file, family_names, format_entrie
|
|
|
18
18
|
from papers.config import bcolors, Config, search_config, CONFIG_FILE, CONFIG_FILE_LOCAL, DATA_DIR, CONFIG_FILE_LEGACY, BACKUP_DIR
|
|
19
19
|
from papers.duplicate import list_duplicates, list_uniques, edit_entries
|
|
20
20
|
from papers.bib import Biblio, FUZZY_RATIO, DEFAULT_SIMILARITY, entry_filecheck, backupfile as backupfile_func, isvalidkey
|
|
21
|
-
from papers.utils import move, checksum, ansi_link as link
|
|
21
|
+
from papers.utils import move, checksum, ansi_link as link, view_pdf
|
|
22
22
|
from papers import __version__
|
|
23
23
|
|
|
24
24
|
|
|
@@ -799,6 +799,12 @@ def listcmd(parser, o, config):
|
|
|
799
799
|
biblio.db.entries.remove(e)
|
|
800
800
|
savebib(biblio, config)
|
|
801
801
|
|
|
802
|
+
elif o.open:
|
|
803
|
+
for e in entries:
|
|
804
|
+
for f in biblio.get_files(e):
|
|
805
|
+
logger.info(f"opening {f} ...")
|
|
806
|
+
view_pdf(f)
|
|
807
|
+
|
|
802
808
|
elif o.field:
|
|
803
809
|
# entries = [{k:e[k] for k in e if k in o.field+['ID','ENTRYTYPE']} for e in entries]
|
|
804
810
|
for e in entries:
|
|
@@ -823,6 +829,7 @@ def listcmd(parser, o, config):
|
|
|
823
829
|
info.append(bcolors.WARNING+" | ".join(keywords)+bcolors.ENDC)
|
|
824
830
|
infotag = '('+', '.join(info)+')' if info else ''
|
|
825
831
|
print(key(e), tit, infotag)
|
|
832
|
+
|
|
826
833
|
else:
|
|
827
834
|
print(format_entries(entries))
|
|
828
835
|
|
|
@@ -1096,6 +1103,7 @@ def get_parser(config=None):
|
|
|
1096
1103
|
grp.add_argument('--add-files', nargs='+', help='add files to the selected entries (only one entry must be listed)')
|
|
1097
1104
|
grp.add_argument('--rename', action='store_true', help='rename added file(s) into files folder. Used together with --add-files')
|
|
1098
1105
|
grp.add_argument('--copy', action='store_true', help='copy added file(s) into files folder. Used together with --add-files --rename')
|
|
1106
|
+
grp.add_argument('-o', '--open', action='store_true', help='open attachments (if any)')
|
|
1099
1107
|
|
|
1100
1108
|
# grp.add_argument('--merge-duplicates', action='store_true')
|
|
1101
1109
|
|
|
@@ -199,7 +199,7 @@ class DuplicateKeyError(ValueError):
|
|
|
199
199
|
class Biblio:
|
|
200
200
|
"""
|
|
201
201
|
The bibtex object that we operate on, which is mainly used to read and write to dynamically, and can then send the changes to be stored in a specified bibtex file on disk.
|
|
202
|
-
"""
|
|
202
|
+
"""
|
|
203
203
|
def __init__(self, db=None, filesdir=None, key_field='ID', nameformat=NAMEFORMAT, keyformat=KEYFORMAT, similarity=DEFAULT_SIMILARITY, relative_to=None):
|
|
204
204
|
"""
|
|
205
205
|
relative_to : bibtex directory, optional
|
|
@@ -299,18 +299,19 @@ class Biblio:
|
|
|
299
299
|
newkey = self.append_abc_to_key(entry) # add abc
|
|
300
300
|
logger.info('update key: {} => {}'.format(entry['ID'], newkey))
|
|
301
301
|
entry['ID'] = newkey
|
|
302
|
+
print("Updated entry:", self.key(entry))
|
|
302
303
|
|
|
303
304
|
else:
|
|
304
305
|
raise DuplicateKeyError('this error can be avoided if update_key is True')
|
|
305
306
|
|
|
306
307
|
else:
|
|
307
308
|
logger.info('new entry: '+self.key(entry))
|
|
309
|
+
print("New entry:", self.key(entry))
|
|
308
310
|
|
|
309
311
|
self.entries.insert(i, entry)
|
|
310
312
|
|
|
311
313
|
if rename: self.rename_entry_files(entry, copy=copy)
|
|
312
314
|
|
|
313
|
-
|
|
314
315
|
def insert_entry_check(self, entry, update_key=False, mergefiles=True, on_conflict='i', rename=False, copy=False):
|
|
315
316
|
|
|
316
317
|
duplicates = [e for e in self.entries if self.eq(e, entry)]
|
|
@@ -320,7 +321,7 @@ class Biblio:
|
|
|
320
321
|
self.insert_entry(entry, update_key, rename=rename, copy=copy)
|
|
321
322
|
|
|
322
323
|
|
|
323
|
-
|
|
324
|
+
else:
|
|
324
325
|
# some duplicates...
|
|
325
326
|
logger.debug('duplicate(s) found: {}'.format(len(duplicates)))
|
|
326
327
|
|
|
@@ -334,6 +335,7 @@ class Biblio:
|
|
|
334
335
|
if entry == candidate:
|
|
335
336
|
logger.debug('exact duplicate')
|
|
336
337
|
if rename: self.rename_entry_files(candidate, copy=copy)
|
|
338
|
+
print("Existing entry:", self.key(entry))
|
|
337
339
|
return # do nothing
|
|
338
340
|
|
|
339
341
|
if update_key and entry['ID'] != candidate['ID']:
|
|
@@ -352,6 +354,7 @@ class Biblio:
|
|
|
352
354
|
logger.debug('fixed: exact duplicate')
|
|
353
355
|
entry = candidate
|
|
354
356
|
if rename: self.rename_entry_files(candidate, copy=copy)
|
|
357
|
+
print("Existing entry:", self.key(entry))
|
|
355
358
|
return # do nothing
|
|
356
359
|
|
|
357
360
|
logger.debug('conflict resolution: '+on_conflict)
|
|
@@ -602,7 +605,7 @@ class Biblio:
|
|
|
602
605
|
format_name=True, interactive=False):
|
|
603
606
|
"""
|
|
604
607
|
Given an entry in an existing Bilio object, checks the format name and encoding. Will fetch additional info if it's missing.
|
|
605
|
-
"""
|
|
608
|
+
"""
|
|
606
609
|
|
|
607
610
|
e_old = e.copy()
|
|
608
611
|
|
|
@@ -727,7 +730,7 @@ def entry_filecheck(e, delete_broken=False, fix_mendeley=False,
|
|
|
727
730
|
check_hash=False, check_metadata=False, interactive=True, image=False, relative_to=None):
|
|
728
731
|
"""
|
|
729
732
|
Checks the bib entry file actually corresponds to an existing, correct file on disk.
|
|
730
|
-
"""
|
|
733
|
+
"""
|
|
731
734
|
|
|
732
735
|
if 'file' not in e:
|
|
733
736
|
return
|
|
@@ -184,4 +184,17 @@ def set_directory(path: Path):
|
|
|
184
184
|
os.chdir(path)
|
|
185
185
|
yield
|
|
186
186
|
finally:
|
|
187
|
-
os.chdir(origin)
|
|
187
|
+
os.chdir(origin)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def view_pdf(filepath):
|
|
191
|
+
"""
|
|
192
|
+
https://stackoverflow.com/questions/434597/open-document-with-default-os-application-in-python-both-in-windows-and-mac-os
|
|
193
|
+
"""
|
|
194
|
+
import subprocess, os, platform
|
|
195
|
+
if platform.system() == 'Darwin': # macOS
|
|
196
|
+
subprocess.call(('open', filepath))
|
|
197
|
+
elif platform.system() == 'Windows': # Windows
|
|
198
|
+
os.startfile(filepath)
|
|
199
|
+
else: # linux variants
|
|
200
|
+
subprocess.call(('xdg-open', filepath))
|
|
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
|