pyzotero 1.6.10__py3-none-any.whl → 1.6.13__py3-none-any.whl
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.
- pyzotero/zotero.py +14 -16
- {pyzotero-1.6.10.dist-info → pyzotero-1.6.13.dist-info}/METADATA +46 -56
- pyzotero-1.6.13.dist-info/RECORD +7 -0
- pyzotero-1.6.13.dist-info/WHEEL +4 -0
- _version.py +0 -21
- pyzotero-1.6.10.dist-info/RECORD +0 -11
- pyzotero-1.6.10.dist-info/WHEEL +0 -5
- pyzotero-1.6.10.dist-info/licenses/AUTHORS +0 -2
- pyzotero-1.6.10.dist-info/licenses/LICENSE.md +0 -35
- pyzotero-1.6.10.dist-info/top_level.txt +0 -2
pyzotero/zotero.py
CHANGED
|
@@ -7,7 +7,6 @@ __author__ = "Stephan Hügel"
|
|
|
7
7
|
__api_version__ = "3"
|
|
8
8
|
|
|
9
9
|
import copy
|
|
10
|
-
import datetime
|
|
11
10
|
import hashlib
|
|
12
11
|
import io
|
|
13
12
|
import json
|
|
@@ -33,7 +32,7 @@ from urllib.parse import (
|
|
|
33
32
|
import bibtexparser
|
|
34
33
|
import feedparser
|
|
35
34
|
import httpx
|
|
36
|
-
import
|
|
35
|
+
import whenever
|
|
37
36
|
from httpx import Request
|
|
38
37
|
|
|
39
38
|
import pyzotero as pz
|
|
@@ -361,6 +360,11 @@ class Zotero:
|
|
|
361
360
|
if c := self.client:
|
|
362
361
|
c.close()
|
|
363
362
|
|
|
363
|
+
@property
|
|
364
|
+
def __version__(self):
|
|
365
|
+
"""Return the version of the pyzotero library"""
|
|
366
|
+
return pz.__version__
|
|
367
|
+
|
|
364
368
|
def _check_for_component(self, url, component):
|
|
365
369
|
"""Check a url path query fragment for a specific query parameter"""
|
|
366
370
|
return bool(parse_qs(url).get(component))
|
|
@@ -419,13 +423,9 @@ class Zotero:
|
|
|
419
423
|
"""
|
|
420
424
|
# cache template and retrieval time for subsequent calls
|
|
421
425
|
try:
|
|
422
|
-
thetime =
|
|
423
|
-
tzinfo=pytz.timezone("GMT"),
|
|
424
|
-
)
|
|
426
|
+
thetime = whenever.ZonedDateTime.now("Europe/London").py_datetime()
|
|
425
427
|
except AttributeError:
|
|
426
|
-
thetime =
|
|
427
|
-
tzinfo=pytz.timezone("GMT"),
|
|
428
|
-
)
|
|
428
|
+
thetime = whenever.ZonedDateTime.now("Europe/London").py_datetime()
|
|
429
429
|
self.templates[key] = {"tmplt": response.json(), "updated": thetime}
|
|
430
430
|
return copy.deepcopy(response.json())
|
|
431
431
|
|
|
@@ -470,7 +470,7 @@ class Zotero:
|
|
|
470
470
|
params = {}
|
|
471
471
|
if not self.url_params:
|
|
472
472
|
self.url_params = {}
|
|
473
|
-
merged_params = params
|
|
473
|
+
merged_params = {**params, **self.url_params}
|
|
474
474
|
# our incoming url might be from the "links" dict, in which case it will contain url parameters.
|
|
475
475
|
# Unfortunately, httpx doesn't like to merge query paramaters in the url string and passed params
|
|
476
476
|
# so we strip the url params, combining them with our existing url_params
|
|
@@ -545,9 +545,7 @@ class Zotero:
|
|
|
545
545
|
# If the template is more than an hour old, try a 304
|
|
546
546
|
if (
|
|
547
547
|
abs(
|
|
548
|
-
|
|
549
|
-
tzinfo=pytz.timezone("GMT"),
|
|
550
|
-
)
|
|
548
|
+
whenever.ZonedDateTime.now("Europe/London").py_datetime()
|
|
551
549
|
- self.templates[template]["updated"],
|
|
552
550
|
).seconds
|
|
553
551
|
> ONE_HOUR
|
|
@@ -800,7 +798,7 @@ class Zotero:
|
|
|
800
798
|
if self.snapshot:
|
|
801
799
|
self.snapshot = False
|
|
802
800
|
pth += ".zip"
|
|
803
|
-
with Path.open(
|
|
801
|
+
with Path(pth).open("wb") as f:
|
|
804
802
|
f.write(file)
|
|
805
803
|
|
|
806
804
|
@retrieve
|
|
@@ -1854,7 +1852,7 @@ class Zupload:
|
|
|
1854
1852
|
if Path(str(self.basedir.joinpath(templt["filename"]))).is_file():
|
|
1855
1853
|
try:
|
|
1856
1854
|
# if it is a file, try to open it, and catch the error
|
|
1857
|
-
with Path
|
|
1855
|
+
with Path(str(self.basedir.joinpath(templt["filename"]))).open():
|
|
1858
1856
|
pass
|
|
1859
1857
|
except OSError:
|
|
1860
1858
|
msg = f"The file at {self.basedir.joinpath(templt['filename'])!s} couldn't be opened or found."
|
|
@@ -1914,7 +1912,7 @@ class Zupload:
|
|
|
1914
1912
|
"""Step 1: get upload authorisation for a file"""
|
|
1915
1913
|
mtypes = mimetypes.guess_type(attachment)
|
|
1916
1914
|
digest = hashlib.md5() # noqa: S324
|
|
1917
|
-
with Path.open(
|
|
1915
|
+
with Path(attachment).open("rb") as att:
|
|
1918
1916
|
for chunk in iter(lambda: att.read(8192), b""):
|
|
1919
1917
|
digest.update(chunk)
|
|
1920
1918
|
auth_headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
|
@@ -1961,7 +1959,7 @@ class Zupload:
|
|
|
1961
1959
|
upload_list = [("key", upload_dict.pop("key"))]
|
|
1962
1960
|
for key, value in upload_dict.items():
|
|
1963
1961
|
upload_list.append((key, value))
|
|
1964
|
-
upload_list.append(("file", Path.open(
|
|
1962
|
+
upload_list.append(("file", Path(attachment).open("rb").read()))
|
|
1965
1963
|
upload_pairs = tuple(upload_list)
|
|
1966
1964
|
try:
|
|
1967
1965
|
self.zinstance._check_backoff()
|
|
@@ -1,48 +1,45 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: pyzotero
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.13
|
|
4
4
|
Summary: Python wrapper for the Zotero API
|
|
5
|
+
Keywords: Zotero,DH
|
|
6
|
+
Author: Stephan Hügel
|
|
5
7
|
Author-email: Stephan Hügel <urschrei@gmail.com>
|
|
6
8
|
License: # Blue Oak Model License
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Project-URL: Repository, https://github.com/urschrei/pyzotero
|
|
43
|
-
Project-URL: Tracker, https://github.com/urschrei/pyzotero/issues
|
|
44
|
-
Project-URL: documentation, https://pyzotero.readthedocs.org
|
|
45
|
-
Keywords: Zotero,DH
|
|
9
|
+
|
|
10
|
+
Version 1.0.0
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
This license gives everyone as much permission to work with this software as possible, while protecting contributors from liability.
|
|
15
|
+
|
|
16
|
+
## Acceptance
|
|
17
|
+
|
|
18
|
+
In order to receive this license, you must agree to its rules. The rules of this license are both obligations under that agreement and conditions to your license. You must not do anything with this software that triggers a rule that you cannot or will not follow.
|
|
19
|
+
|
|
20
|
+
## Copyright
|
|
21
|
+
|
|
22
|
+
Each contributor licenses you to do everything with this software that would otherwise infringe that contributor's copyright in it.
|
|
23
|
+
|
|
24
|
+
## Notices
|
|
25
|
+
|
|
26
|
+
You must ensure that everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license or a link to <https://blueoakcouncil.org/license/1.0.0>.
|
|
27
|
+
|
|
28
|
+
## Excuse
|
|
29
|
+
|
|
30
|
+
If anyone notifies you in writing that you have not complied with [Notices](#notices), you can keep your license by taking all practical steps to comply within 30 days after the notice. If you do not do so, your license ends immediately.
|
|
31
|
+
|
|
32
|
+
## Patent
|
|
33
|
+
|
|
34
|
+
Each contributor licenses you to do everything with this software that would otherwise infringe any patent claims they can license or become able to license.
|
|
35
|
+
|
|
36
|
+
## Reliability
|
|
37
|
+
|
|
38
|
+
No contributor can revoke this license.
|
|
39
|
+
|
|
40
|
+
## No Liability
|
|
41
|
+
|
|
42
|
+
***As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim.***
|
|
46
43
|
Classifier: Programming Language :: Python
|
|
47
44
|
Classifier: Programming Language :: Python :: 3.9
|
|
48
45
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -56,22 +53,15 @@ Classifier: Intended Audience :: Education
|
|
|
56
53
|
Classifier: License :: OSI Approved :: Blue Oak Model License (BlueOak-1.0.0)
|
|
57
54
|
Classifier: Operating System :: OS Independent
|
|
58
55
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
56
|
+
Requires-Dist: feedparser>=6.0.12
|
|
57
|
+
Requires-Dist: bibtexparser>=1.4.3,<2.0.0
|
|
58
|
+
Requires-Dist: httpx>=0.28.1
|
|
59
|
+
Requires-Dist: whenever>=0.8.8
|
|
59
60
|
Requires-Python: >=3.9
|
|
61
|
+
Project-URL: Repository, https://github.com/urschrei/pyzotero
|
|
62
|
+
Project-URL: Tracker, https://github.com/urschrei/pyzotero/issues
|
|
63
|
+
Project-URL: documentation, https://pyzotero.readthedocs.org
|
|
60
64
|
Description-Content-Type: text/markdown
|
|
61
|
-
License-File: LICENSE.md
|
|
62
|
-
License-File: AUTHORS
|
|
63
|
-
Requires-Dist: feedparser>=6.0.11
|
|
64
|
-
Requires-Dist: pytz
|
|
65
|
-
Requires-Dist: bibtexparser
|
|
66
|
-
Requires-Dist: httpx>=0.28.1
|
|
67
|
-
Provides-Extra: test
|
|
68
|
-
Requires-Dist: pytest>=7.4.2; extra == "test"
|
|
69
|
-
Requires-Dist: httpretty; extra == "test"
|
|
70
|
-
Requires-Dist: python-dateutil; extra == "test"
|
|
71
|
-
Requires-Dist: ipython; extra == "test"
|
|
72
|
-
Requires-Dist: pytest-asyncio; extra == "test"
|
|
73
|
-
Requires-Dist: pytest-cov>=6.0.0; extra == "test"
|
|
74
|
-
Dynamic: license-file
|
|
75
65
|
|
|
76
66
|
[](https://pypi.python.org/pypi/Pyzotero/) [](http://pyzotero.readthedocs.org/en/latest/?badge=latest) [](https://pypi.python.org/pypi/Pyzotero) [](https://anaconda.org/conda-forge/pyzotero) [](https://pepy.tech/project/pyzotero)
|
|
77
67
|
|
|
@@ -79,7 +69,7 @@ Dynamic: license-file
|
|
|
79
69
|
|
|
80
70
|
# Quickstart
|
|
81
71
|
|
|
82
|
-
1. `pip install pyzotero` **or** `conda
|
|
72
|
+
1. `uv add pyzotero` **or** `pip install pyzotero` **or** `conda install conda-forge::pyzotero`
|
|
83
73
|
2. You'll need the ID of the personal or group library you want to access:
|
|
84
74
|
- Your **personal library ID** is available [here](https://www.zotero.org/settings/keys), in the section `Your userID for use in API calls`
|
|
85
75
|
- For **group libraries**, the ID can be found by opening the group's page: `https://www.zotero.org/groups/groupname`, and hovering over the `group settings` link. The ID is the integer after `/groups/`
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pyzotero/__init__.py,sha256=5QI4Jou9L-YJAf_oN9TgRXVKgt_Unc39oADo2Ch8bLI,243
|
|
2
|
+
pyzotero/filetransport.py,sha256=umLik1LLmrpgaNmyjvtBoqqcaMgIq79PYsTvN5vG-gY,5530
|
|
3
|
+
pyzotero/zotero.py,sha256=u3ELdw3aC7qXOWmzKpMILxL1ZNwFIMTnPzA5xEnqTfE,76032
|
|
4
|
+
pyzotero/zotero_errors.py,sha256=6obx9-pBO0z1bxt33vuzDluELvA5kSLCsfc-uGc3KNw,2660
|
|
5
|
+
pyzotero-1.6.13.dist-info/WHEEL,sha256=pFCy50wRV2h7SjJ35YOsQUupaV45rMdgpNIvnXbG5bE,79
|
|
6
|
+
pyzotero-1.6.13.dist-info/METADATA,sha256=M0oe4xiuBrI37mquQYareIme_zmeDGwU21J20k1qLT4,7176
|
|
7
|
+
pyzotero-1.6.13.dist-info/RECORD,,
|
_version.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# file generated by setuptools-scm
|
|
2
|
-
# don't change, don't track in version control
|
|
3
|
-
|
|
4
|
-
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
-
|
|
6
|
-
TYPE_CHECKING = False
|
|
7
|
-
if TYPE_CHECKING:
|
|
8
|
-
from typing import Tuple
|
|
9
|
-
from typing import Union
|
|
10
|
-
|
|
11
|
-
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
12
|
-
else:
|
|
13
|
-
VERSION_TUPLE = object
|
|
14
|
-
|
|
15
|
-
version: str
|
|
16
|
-
__version__: str
|
|
17
|
-
__version_tuple__: VERSION_TUPLE
|
|
18
|
-
version_tuple: VERSION_TUPLE
|
|
19
|
-
|
|
20
|
-
__version__ = version = '1.6.10'
|
|
21
|
-
__version_tuple__ = version_tuple = (1, 6, 10)
|
pyzotero-1.6.10.dist-info/RECORD
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
_version.py,sha256=OJVhA57HANUDqkAHd3ZCn5-ZlvWQIP0l_IKmHcQrfms,513
|
|
2
|
-
pyzotero/__init__.py,sha256=5QI4Jou9L-YJAf_oN9TgRXVKgt_Unc39oADo2Ch8bLI,243
|
|
3
|
-
pyzotero/filetransport.py,sha256=umLik1LLmrpgaNmyjvtBoqqcaMgIq79PYsTvN5vG-gY,5530
|
|
4
|
-
pyzotero/zotero.py,sha256=AKqVOgElcW7j3lae1yTF_EmJ6rK2tzdvMW4TOFdM_dE,76078
|
|
5
|
-
pyzotero/zotero_errors.py,sha256=6obx9-pBO0z1bxt33vuzDluELvA5kSLCsfc-uGc3KNw,2660
|
|
6
|
-
pyzotero-1.6.10.dist-info/licenses/AUTHORS,sha256=ZMicxg7lRScOYbxzMPznlzMbmrFIUIHwg-NvljEMbRQ,110
|
|
7
|
-
pyzotero-1.6.10.dist-info/licenses/LICENSE.md,sha256=bhy1CPMj1zWffD9YifFmSeBzPylsrhb1qP8OCEx5Etw,1550
|
|
8
|
-
pyzotero-1.6.10.dist-info/METADATA,sha256=wvUszhp8agewknBv2R0oczSsryunCfxhYhOaRrmD6pc,7471
|
|
9
|
-
pyzotero-1.6.10.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
|
|
10
|
-
pyzotero-1.6.10.dist-info/top_level.txt,sha256=BOPNkPk5VtNDCy_li7Xftx6k0zG8STGxh-KgckcxLEw,18
|
|
11
|
-
pyzotero-1.6.10.dist-info/RECORD,,
|
pyzotero-1.6.10.dist-info/WHEEL
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Blue Oak Model License
|
|
2
|
-
|
|
3
|
-
Version 1.0.0
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
This license gives everyone as much permission to work with this software as possible, while protecting contributors from liability.
|
|
8
|
-
|
|
9
|
-
## Acceptance
|
|
10
|
-
|
|
11
|
-
In order to receive this license, you must agree to its rules. The rules of this license are both obligations under that agreement and conditions to your license. You must not do anything with this software that triggers a rule that you cannot or will not follow.
|
|
12
|
-
|
|
13
|
-
## Copyright
|
|
14
|
-
|
|
15
|
-
Each contributor licenses you to do everything with this software that would otherwise infringe that contributor's copyright in it.
|
|
16
|
-
|
|
17
|
-
## Notices
|
|
18
|
-
|
|
19
|
-
You must ensure that everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license or a link to <https://blueoakcouncil.org/license/1.0.0>.
|
|
20
|
-
|
|
21
|
-
## Excuse
|
|
22
|
-
|
|
23
|
-
If anyone notifies you in writing that you have not complied with [Notices](#notices), you can keep your license by taking all practical steps to comply within 30 days after the notice. If you do not do so, your license ends immediately.
|
|
24
|
-
|
|
25
|
-
## Patent
|
|
26
|
-
|
|
27
|
-
Each contributor licenses you to do everything with this software that would otherwise infringe any patent claims they can license or become able to license.
|
|
28
|
-
|
|
29
|
-
## Reliability
|
|
30
|
-
|
|
31
|
-
No contributor can revoke this license.
|
|
32
|
-
|
|
33
|
-
## No Liability
|
|
34
|
-
|
|
35
|
-
***As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim.***
|