idlib 0.0.1.dev20__py2.py3-none-any.whl → 0.0.1.dev22__py2.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.
- idlib/__init__.py +1 -1
- idlib/conventions/type.py +11 -9
- idlib/core.py +48 -4
- idlib/exceptions.py +9 -1
- idlib/streams.py +3 -2
- idlib/systems/doi.py +2 -2
- idlib/systems/orcid.py +53 -10
- idlib/systems/ror.py +1 -0
- {idlib-0.0.1.dev20.dist-info → idlib-0.0.1.dev22.dist-info}/METADATA +15 -14
- {idlib-0.0.1.dev20.dist-info → idlib-0.0.1.dev22.dist-info}/RECORD +13 -13
- {idlib-0.0.1.dev20.dist-info → idlib-0.0.1.dev22.dist-info}/WHEEL +1 -1
- {idlib-0.0.1.dev20.dist-info → idlib-0.0.1.dev22.dist-info}/LICENSE +0 -0
- {idlib-0.0.1.dev20.dist-info → idlib-0.0.1.dev22.dist-info}/top_level.txt +0 -0
idlib/__init__.py
CHANGED
idlib/conventions/type.py
CHANGED
|
@@ -13,19 +13,21 @@ class ConvTypeBytesHeader(ConventionsType):
|
|
|
13
13
|
self.stop = stop
|
|
14
14
|
self.sentinel = sentinel
|
|
15
15
|
|
|
16
|
-
def _findElement(self, element, chunk):
|
|
17
|
-
|
|
16
|
+
def _findElement(self, element, chunk, prev):
|
|
17
|
+
to_search = prev + chunk
|
|
18
|
+
m = re.search(element, to_search)
|
|
18
19
|
if m is not None:
|
|
20
|
+
lp = len(prev)
|
|
19
21
|
# FIXME icky api
|
|
20
|
-
return m.start(), m.end()
|
|
22
|
+
return m.start() - lp, m.end() -lp
|
|
21
23
|
else:
|
|
22
24
|
return None, None
|
|
23
25
|
|
|
24
|
-
def findStart(self, chunk):
|
|
25
|
-
return self._findElement(self.start, chunk)
|
|
26
|
+
def findStart(self, chunk, prev):
|
|
27
|
+
return self._findElement(self.start, chunk, prev)
|
|
26
28
|
|
|
27
|
-
def findStop(self, chunk):
|
|
28
|
-
return self._findElement(self.stop, chunk)
|
|
29
|
+
def findStop(self, chunk, prev):
|
|
30
|
+
return self._findElement(self.stop, chunk, prev)
|
|
29
31
|
|
|
30
|
-
def findSentinel(self, chunk):
|
|
31
|
-
return self._findElement(self.sentinel, chunk)
|
|
32
|
+
def findSentinel(self, chunk, prev):
|
|
33
|
+
return self._findElement(self.sentinel, chunk, prev)
|
idlib/core.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
from . import exceptions as exc
|
|
3
|
+
from .utils import log
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
def resolution_chain(iri):
|
|
@@ -7,11 +8,37 @@ def resolution_chain(iri):
|
|
|
7
8
|
yield head.url
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
def try_get(s, head):
|
|
12
|
+
# see whether the server has a bad/broken support for head requests
|
|
13
|
+
# sometimes they return e.g. 400 instead of 405, and really they should
|
|
14
|
+
# just work because they work correctly with get request ...
|
|
15
|
+
head = s.get(head.url, stream=True)
|
|
16
|
+
if head.ok:
|
|
17
|
+
log.info(f'bad HEAD implementation {head.url}')
|
|
18
|
+
else:
|
|
19
|
+
content = head.content
|
|
20
|
+
if content:
|
|
21
|
+
if head.headers['Content-Type'] == 'application/json':
|
|
22
|
+
try:
|
|
23
|
+
j = head.json()
|
|
24
|
+
log.error(f'{head.url} error json {j}')
|
|
25
|
+
except Exception as e:
|
|
26
|
+
log.error(f'{head.url} error text {head.text}')
|
|
27
|
+
|
|
28
|
+
head.close()
|
|
29
|
+
return head
|
|
30
|
+
|
|
31
|
+
|
|
10
32
|
def resolution_chain_responses(iri, raise_on_final=True):
|
|
11
33
|
#doi = doi # TODO
|
|
12
34
|
s = requests.Session()
|
|
13
|
-
head =
|
|
14
|
-
|
|
35
|
+
head = s.head(iri, allow_redirects=False)
|
|
36
|
+
if head.status_code < 400:
|
|
37
|
+
yield head
|
|
38
|
+
else:
|
|
39
|
+
head = try_get(s, head)
|
|
40
|
+
yield head
|
|
41
|
+
|
|
15
42
|
while head.is_redirect and head.status_code < 400: # FIXME redirect loop issue
|
|
16
43
|
yield head.next
|
|
17
44
|
try:
|
|
@@ -19,7 +46,12 @@ def resolution_chain_responses(iri, raise_on_final=True):
|
|
|
19
46
|
except requests.exceptions.SSLError as e:
|
|
20
47
|
raise exc.InbetweenError(msg) from e
|
|
21
48
|
|
|
22
|
-
|
|
49
|
+
if head.status_code < 400:
|
|
50
|
+
yield head
|
|
51
|
+
else:
|
|
52
|
+
head = try_get(s, head)
|
|
53
|
+
yield head
|
|
54
|
+
|
|
23
55
|
if not head.is_redirect:
|
|
24
56
|
break
|
|
25
57
|
|
|
@@ -27,7 +59,19 @@ def resolution_chain_responses(iri, raise_on_final=True):
|
|
|
27
59
|
if head.status_code == 404:
|
|
28
60
|
head.raise_for_status() # probably a permissions issue
|
|
29
61
|
elif head.status_code >= 500:
|
|
30
|
-
|
|
62
|
+
msg = f'Remote in error due to {head.status_code} at {head.url}\n'
|
|
63
|
+
raise exc.RemoteError(msg)
|
|
31
64
|
elif head.status_code >= 400:
|
|
32
65
|
msg = f'Nothing found due to {head.status_code} at {head.url}\n'
|
|
33
66
|
raise exc.ResolutionError(msg)
|
|
67
|
+
|
|
68
|
+
if head.status_code >= 400:
|
|
69
|
+
# XXX this seems like the "right" thing to do, but it will
|
|
70
|
+
# probably break a bunch of stuff, but at least this way it
|
|
71
|
+
# will be visible now, obviously yeilding None as the final
|
|
72
|
+
# element in the reference chain conflates all the possible
|
|
73
|
+
# reasons so raising is a better solution and is the default
|
|
74
|
+
# for a reason but at least this way the user knows that the
|
|
75
|
+
# final element of the chain dereference to nothing instead of
|
|
76
|
+
# assuming that the last element succeeded
|
|
77
|
+
yield None
|
idlib/exceptions.py
CHANGED
|
@@ -36,7 +36,7 @@ class CouldNotReachReferentError(CouldNotReachError):
|
|
|
36
36
|
|
|
37
37
|
Note that in a system that is not based on redirects
|
|
38
38
|
this is an error that could be returned by the index
|
|
39
|
-
but it would appear as
|
|
39
|
+
but it would appear as a referent unknown error. """
|
|
40
40
|
|
|
41
41
|
# but its supertype is ReferentUnknown or ReferentUnreachable
|
|
42
42
|
|
|
@@ -59,6 +59,14 @@ class ResolutionError(IdlibError):
|
|
|
59
59
|
# we should split into NetworkError/TimeoutError
|
|
60
60
|
# and then have RemoteError, because Resolution error is
|
|
61
61
|
# ambiguous, it is the superclass for all of them I think
|
|
62
|
+
# XXX as used, this is ClientError, and for all but 404
|
|
63
|
+
# and 410 the response means we can't actually say whether
|
|
64
|
+
# it is a true null pointer, the naming is thus very bad
|
|
65
|
+
# because as used this is not a network error, not a timeout
|
|
66
|
+
# error, it is the server saying i do not/cannot understand
|
|
67
|
+
# that is MessageReceivedButError which happens before we
|
|
68
|
+
# know if the id exists and probably actually covers most
|
|
69
|
+
# of the IdExistsButError cases
|
|
62
70
|
|
|
63
71
|
|
|
64
72
|
class MalformedIdentifierError(IdlibError):
|
idlib/streams.py
CHANGED
|
@@ -606,7 +606,7 @@ class StreamUri(Stream):
|
|
|
606
606
|
if not self.identifier_actionable in dc:
|
|
607
607
|
try:
|
|
608
608
|
dc[self.identifier_actionable] = tuple(
|
|
609
|
-
StringProgenitor(resp.url, progenitor=resp)
|
|
609
|
+
resp if resp is None else StringProgenitor(resp.url, progenitor=resp)
|
|
610
610
|
for resp in
|
|
611
611
|
self._resolution_chain_responses(self.identifier_actionable,
|
|
612
612
|
raise_on_final=False))
|
|
@@ -668,7 +668,8 @@ class StreamUri(Stream):
|
|
|
668
668
|
@cache_result
|
|
669
669
|
def headers(self):
|
|
670
670
|
uri = self.dereference()
|
|
671
|
-
|
|
671
|
+
if uri is not None:
|
|
672
|
+
return uri.progenitor().headers
|
|
672
673
|
|
|
673
674
|
def data(self, mimetype_accept=None):
|
|
674
675
|
# FIXME TODO should the data associated with the doi
|
idlib/systems/doi.py
CHANGED
|
@@ -26,8 +26,8 @@ class DoiId(oq.OntId, idlib.Identifier, idlib.Stream): # also _technically_ a s
|
|
|
26
26
|
_namespaces = _DoiPrefixes
|
|
27
27
|
_local_conventions = _namespaces
|
|
28
28
|
_id_class = str # eventually we have to drop down to something
|
|
29
|
-
local_regex = '^10
|
|
30
|
-
canonical_regex = '^https
|
|
29
|
+
local_regex = '^10\\.[0-9]{4,9}[-._;()/:a-zA-Z0-9]+$'
|
|
30
|
+
canonical_regex = '^https://doi.org/10\\.[0-9]{4,9}[-._;()/:a-zA-Z0-9]+$'
|
|
31
31
|
|
|
32
32
|
def __new__(cls, doi_in_various_states_of_mangling=None, iri=None):
|
|
33
33
|
if doi_in_various_states_of_mangling is None and iri is not None:
|
idlib/systems/orcid.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import random
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
import ontquery as oq # temporary implementation detail
|
|
3
4
|
import idlib
|
|
@@ -13,6 +14,22 @@ from idlib.config import auth
|
|
|
13
14
|
# but I need more information ...
|
|
14
15
|
|
|
15
16
|
|
|
17
|
+
def genorcid():
|
|
18
|
+
""" generate a random orcid-like id suffix """
|
|
19
|
+
_09 = '09'
|
|
20
|
+
_01 = ''.join([str(_) for _ in range(2)])
|
|
21
|
+
_0_9 = ''.join([str(_) for _ in range(10)])
|
|
22
|
+
base = (
|
|
23
|
+
'000' + random.choice(_09) + '-' +
|
|
24
|
+
'00' + random.choice(_01) + random.choice(_0_9) + '-' +
|
|
25
|
+
''.join(random.choice(_0_9) for _ in range(4))
|
|
26
|
+
+ '-' +
|
|
27
|
+
''.join(random.choice(_0_9) for _ in range(3)))
|
|
28
|
+
cs = OrcidId._digit_checksum(base.replace('-', ''))
|
|
29
|
+
fd = 'X' if cs == 10 else str(cs)
|
|
30
|
+
return base + fd
|
|
31
|
+
|
|
32
|
+
|
|
16
33
|
class OrcidPrefixes(conv.QnameAsLocalHelper, oq.OntCuries):
|
|
17
34
|
# set these manually since, sigh, factory patterns
|
|
18
35
|
_dict = {}
|
|
@@ -29,10 +46,9 @@ OrcidPrefixes({'orcid': 'https://orcid.org/',
|
|
|
29
46
|
class OrcidId(oq.OntId, idlib.Identifier):
|
|
30
47
|
_namespaces = OrcidPrefixes
|
|
31
48
|
_local_conventions = _namespaces
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
canonical_regex = ('^https://orcid.org/
|
|
35
|
-
'[0-4])[0-9][0-9][0-9]-[0-9][0-9][0-9]([0-9]|X)$')
|
|
49
|
+
_common = '000[09]-00[01][0-9]-[0-9]{4}-[0-9]{3}([0-9]|X)'
|
|
50
|
+
local_regex = (f'^{_common}$')
|
|
51
|
+
canonical_regex = (f'^https://orcid.org/{_common}$')
|
|
36
52
|
|
|
37
53
|
class OrcidMalformedError(exc.IdlibError):
|
|
38
54
|
""" WHAT HAVE YOU DONE!? """
|
|
@@ -69,6 +85,16 @@ class OrcidId(oq.OntId, idlib.Identifier):
|
|
|
69
85
|
|
|
70
86
|
return self
|
|
71
87
|
|
|
88
|
+
@staticmethod
|
|
89
|
+
def _digit_checksum(digits):
|
|
90
|
+
total = 0
|
|
91
|
+
for digit_string in digits:
|
|
92
|
+
total = (total + int(digit_string)) * 2
|
|
93
|
+
|
|
94
|
+
remainder = total % 11
|
|
95
|
+
result = (12 - remainder) % 11
|
|
96
|
+
return result
|
|
97
|
+
|
|
72
98
|
@property
|
|
73
99
|
def checksumValid(self):
|
|
74
100
|
""" see
|
|
@@ -78,12 +104,7 @@ class OrcidId(oq.OntId, idlib.Identifier):
|
|
|
78
104
|
try:
|
|
79
105
|
*digits, check_string = self.suffix.replace('-', '')
|
|
80
106
|
check = 10 if check_string == 'X' else int(check_string)
|
|
81
|
-
|
|
82
|
-
for digit_string in digits:
|
|
83
|
-
total = (total + int(digit_string)) * 2
|
|
84
|
-
|
|
85
|
-
remainder = total % 11
|
|
86
|
-
result = (12 - remainder) % 11
|
|
107
|
+
result = self._digit_checksum(digits)
|
|
87
108
|
return result == check
|
|
88
109
|
except ValueError as e:
|
|
89
110
|
raise self.OrcidChecksumError(self) from e
|
|
@@ -187,3 +208,25 @@ class Orcid(idlib.HelperNoData, idlib.Stream):
|
|
|
187
208
|
return (self.identifier.iri
|
|
188
209
|
if asType is None else
|
|
189
210
|
asType(self.identifier.iri))
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class OrcidSandboxPrefixes(conv.QnameAsLocalHelper, oq.OntCuries):
|
|
214
|
+
# set these manually since, sigh, factory patterns
|
|
215
|
+
_dict = {}
|
|
216
|
+
_n_to_p = {}
|
|
217
|
+
_strie = {}
|
|
218
|
+
_trie = {}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
OrcidSandboxPrefixes({'orcid': 'https://sandbox.orcid.org/',
|
|
222
|
+
'ORCID': 'https://sandbox.orcid.org/',
|
|
223
|
+
'orcid.pub.3': 'https://pub.sandbox.orcid.org/v3.0/',})
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class OrcidIdSandbox(OrcidId):
|
|
227
|
+
_namespaces = OrcidSandboxPrefixes
|
|
228
|
+
canonical_regex = (f'^https://sandbox.orcid.org/{OrcidId._common}$')
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class OrcidSandbox(Orcid):
|
|
232
|
+
_id_class = OrcidIdSandbox
|
idlib/systems/ror.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: idlib
|
|
3
|
-
Version: 0.0.1.
|
|
3
|
+
Version: 0.0.1.dev22
|
|
4
4
|
Summary: A library for working with identifiers of all kinds.
|
|
5
5
|
Home-page: https://github.com/tgbugs/idlib
|
|
6
6
|
Author: Tom Gillespie
|
|
@@ -9,34 +9,35 @@ License: MIT
|
|
|
9
9
|
Keywords: python persistent identifiers
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.7
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.8
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
19
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
19
20
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
20
21
|
Classifier: Operating System :: POSIX :: Linux
|
|
21
22
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
22
23
|
Classifier: Operating System :: Microsoft :: Windows
|
|
23
|
-
Requires-Python: >=3.
|
|
24
|
+
Requires-Python: >=3.7
|
|
24
25
|
Description-Content-Type: text/markdown
|
|
25
26
|
License-File: LICENSE
|
|
26
|
-
Requires-Dist: orthauth[sxpr,yaml]
|
|
27
|
+
Requires-Dist: orthauth[sxpr,yaml]>=0.0.18
|
|
27
28
|
Requires-Dist: requests
|
|
28
|
-
Provides-Extra:
|
|
29
|
-
Requires-Dist:
|
|
29
|
+
Provides-Extra: test
|
|
30
|
+
Requires-Dist: pytest; extra == "test"
|
|
31
|
+
Requires-Dist: joblib>=1.1.0; extra == "test"
|
|
32
|
+
Requires-Dist: beautifulsoup4[html5lib]; extra == "test"
|
|
33
|
+
Requires-Dist: pyontutils>=0.1.28; extra == "test"
|
|
34
|
+
Requires-Dist: google-auth-oauthlib; extra == "test"
|
|
30
35
|
Provides-Extra: org
|
|
31
|
-
Requires-Dist: beautifulsoup4[html5lib]
|
|
36
|
+
Requires-Dist: beautifulsoup4[html5lib]; extra == "org"
|
|
32
37
|
Provides-Extra: rdf
|
|
33
|
-
Requires-Dist: pyontutils
|
|
34
|
-
Provides-Extra:
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist: joblib >=1.1.0 ; extra == 'test'
|
|
37
|
-
Requires-Dist: beautifulsoup4[html5lib] ; extra == 'test'
|
|
38
|
-
Requires-Dist: pyontutils >=0.1.28 ; extra == 'test'
|
|
39
|
-
Requires-Dist: google-auth-oauthlib ; extra == 'test'
|
|
38
|
+
Requires-Dist: pyontutils>=0.1.28; extra == "rdf"
|
|
39
|
+
Provides-Extra: oauth
|
|
40
|
+
Requires-Dist: google-auth-oauthlib; extra == "oauth"
|
|
40
41
|
|
|
41
42
|
# idlib
|
|
42
43
|
[](https://pypi.org/project/idlib/)
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
idlib/__init__.py,sha256=
|
|
1
|
+
idlib/__init__.py,sha256=FdowWsUq9bwbPqZPU2sTU1iWMxm1KetrH4kknNBlMmQ,1696
|
|
2
2
|
idlib/auth-config.py,sha256=tYM2aYCYJFG5NB4Af1dSn6YxhafttOp7W7aSc-QbVV8,460
|
|
3
3
|
idlib/cache.py,sha256=lR1I3iEYvBhNeqoptS-Sj7SpIHt1K65nYlBrTK-ROVQ,3875
|
|
4
4
|
idlib/config.py,sha256=Gli2tZlbKxBos8sXDoDK1g9mngfDw1ZWpBt_7MDZH-g,76
|
|
5
|
-
idlib/core.py,sha256=
|
|
5
|
+
idlib/core.py,sha256=DfJoPe_xqJJducri1ub7e_anJYuhJ37-ZxvZCuuOpaY,2704
|
|
6
6
|
idlib/edit.py,sha256=s3yRtvNelQUA8fziu_igZeoFsW4xCK_kgfNVv3TS0iE,3635
|
|
7
|
-
idlib/exceptions.py,sha256=
|
|
7
|
+
idlib/exceptions.py,sha256=QC3Jq98iwezcqB7SmDr-UEOqdNCnvEXVkKB0eJLIwZs,4714
|
|
8
8
|
idlib/from_oq.py,sha256=HlgepGbgSUbOt5R79ALRhgiLOEvU6TSu3evB8zq7N84,94170
|
|
9
9
|
idlib/identifiers.py,sha256=s39bAS-fCQrlwAbMtaa7tjSnqKq4YPlfSbfJ6ju2o7I,3861
|
|
10
|
-
idlib/streams.py,sha256=
|
|
10
|
+
idlib/streams.py,sha256=HGcs_S7bOiUYfiSjZNGLXo5bJI7yd0bYjc8BKkdqECI,26439
|
|
11
11
|
idlib/utils.py,sha256=zItGz-lXovZytSENUZ9q7A7gLr5uK_9VMawokGSskbk,5127
|
|
12
12
|
idlib/apis/__init__.py,sha256=q2-iSMUDPlYbjqGWa1mtbe2G95N7wbjWHGj30BUdVDM,88
|
|
13
13
|
idlib/apis/protocols_io.py,sha256=3PGKBwe9P_DxhScIG-L3ZFtnEHxgHaccLhRGVPZuYHg,3956
|
|
14
14
|
idlib/conventions/__init__.py,sha256=ug6W8eNHuq9JZy5bwrZ6Rjfu8r81Rrnm0nzApmvvMzw,204
|
|
15
15
|
idlib/conventions/core.py,sha256=g0T1VoNpoC9afvUd0wp6Mu7tRxbPDFK59uwVXV-zTtA,940
|
|
16
16
|
idlib/conventions/local.py,sha256=H1WnXTY06aLq0RB_SsTLVhMZiSP9GGvWuWm_zrFUNmQ,129
|
|
17
|
-
idlib/conventions/type.py,sha256=
|
|
17
|
+
idlib/conventions/type.py,sha256=PM_BkxP5a7BTOSsb77kMmMRF2u5xMdlptIa4QYIaE6Y,1013
|
|
18
18
|
idlib/formats/__init__.py,sha256=yS6l0mbDwa2xjyxhgVzlqIf0LPqJmuhNVg8rfKSsh7M,528
|
|
19
19
|
idlib/formats/rdf.py,sha256=yIKHPaPn-SUuUMkR4VD7KffVgQD8oNaZNxcqDBilxtg,466
|
|
20
20
|
idlib/systems/__init__.py,sha256=3lWSK2DyzYX0d61DJo-gGytc-HoiOlNJl5so4s7Grrg,203
|
|
21
21
|
idlib/systems/ark.py,sha256=i9JqmuTWsJABrLHR0-_FX_PBbbpeFa7X4CO65QhyOD8,111
|
|
22
|
-
idlib/systems/doi.py,sha256=
|
|
22
|
+
idlib/systems/doi.py,sha256=PQAstSUocPpK9Ug7L-eKvJrQhn3jRU9WuKITGyZoL9g,13100
|
|
23
23
|
idlib/systems/handle.py,sha256=Gg97IuysdAdCX9j6EhuNfIddb1GDq0CmwW1SmuLkpgM,95
|
|
24
24
|
idlib/systems/isni.py,sha256=TgiSTlDcSBLRro3gg_YfQJQkfaJ3saw0Au1OMhE23wU,89
|
|
25
|
-
idlib/systems/orcid.py,sha256=
|
|
25
|
+
idlib/systems/orcid.py,sha256=aTVu_Q6fnaQvqmd6jeXdst6yKRTO-BEUMs7_4fdQK5E,7886
|
|
26
26
|
idlib/systems/pmid.py,sha256=Na-4_n7qmJ3VAbG0RUwnNTg7o4Z8OkuL_Hluq_A3IO0,181
|
|
27
|
-
idlib/systems/ror.py,sha256=
|
|
27
|
+
idlib/systems/ror.py,sha256=xIS30mxKd0IcjwalBjnyUU7GKeeU5pxM3i9hSofG6u8,8129
|
|
28
28
|
idlib/systems/rrid.py,sha256=XVHyHyiGC2OvbOSXmfU3_wswS6yUw65qZ3Pct0sjbfU,6886
|
|
29
29
|
idlib/systems/urn.py,sha256=p222KjHgfF6y9srCm7kFWuWA9NK4lI-wEQUtSeuBqYk,113
|
|
30
30
|
idlib/systems/web.py,sha256=vrSbQYWnxhe9pSgZcOqwLM3V6XQDLwv1QqWlhWWxbL0,1291
|
|
31
|
-
idlib-0.0.1.
|
|
32
|
-
idlib-0.0.1.
|
|
33
|
-
idlib-0.0.1.
|
|
34
|
-
idlib-0.0.1.
|
|
35
|
-
idlib-0.0.1.
|
|
31
|
+
idlib-0.0.1.dev22.dist-info/LICENSE,sha256=nEuJBsoHfpXGgf6ZyFGUhQJqxFWwhSYF-45pRAqTSb4,1080
|
|
32
|
+
idlib-0.0.1.dev22.dist-info/METADATA,sha256=kjQ8xltmifA_qoV2GmEQAFeO5P3HzWVMc0MjiINC38o,2052
|
|
33
|
+
idlib-0.0.1.dev22.dist-info/WHEEL,sha256=pxeNX5JdtCe58PUSYP9upmc7jdRPgvT0Gm9kb1SHlVw,109
|
|
34
|
+
idlib-0.0.1.dev22.dist-info/top_level.txt,sha256=xIk87gJPbeCKih9BVMP8PlEFdpcsGplenz0VQhx5sP8,6
|
|
35
|
+
idlib-0.0.1.dev22.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|