pyPreservica 3.2.3__py3-none-any.whl → 3.2.5__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.
Potentially problematic release.
This version of pyPreservica might be problematic. Click here for more details.
- pyPreservica/__init__.py +1 -1
- pyPreservica/common.py +6 -4
- pyPreservica/entityAPI.py +4 -4
- pyPreservica/uploadAPI.py +46 -0
- {pypreservica-3.2.3.dist-info → pypreservica-3.2.5.dist-info}/METADATA +1 -1
- {pypreservica-3.2.3.dist-info → pypreservica-3.2.5.dist-info}/RECORD +9 -9
- {pypreservica-3.2.3.dist-info → pypreservica-3.2.5.dist-info}/WHEEL +0 -0
- {pypreservica-3.2.3.dist-info → pypreservica-3.2.5.dist-info}/licenses/LICENSE.txt +0 -0
- {pypreservica-3.2.3.dist-info → pypreservica-3.2.5.dist-info}/top_level.txt +0 -0
pyPreservica/__init__.py
CHANGED
pyPreservica/common.py
CHANGED
|
@@ -822,9 +822,6 @@ class AuthenticatedAPI:
|
|
|
822
822
|
self.minor_version = int(version_numbers[1])
|
|
823
823
|
self.patch_version = int(version_numbers[2])
|
|
824
824
|
|
|
825
|
-
if self.server == "preview.preservica.com":
|
|
826
|
-
self.minor_version = 1
|
|
827
|
-
|
|
828
825
|
return version
|
|
829
826
|
elif request.status_code == requests.codes.unauthorized:
|
|
830
827
|
self.token = self.__token__()
|
|
@@ -833,6 +830,9 @@ class AuthenticatedAPI:
|
|
|
833
830
|
logger.error(f"version number failed with http response {request.status_code}")
|
|
834
831
|
logger.error(str(request.content))
|
|
835
832
|
RuntimeError(request.status_code, "version number failed")
|
|
833
|
+
return None
|
|
834
|
+
|
|
835
|
+
|
|
836
836
|
|
|
837
837
|
def __str__(self):
|
|
838
838
|
return f"pyPreservica version: {pyPreservica.__version__} (Preservica 8.0 Compatible) " \
|
|
@@ -892,9 +892,11 @@ class AuthenticatedAPI:
|
|
|
892
892
|
data = {'username': self.username,
|
|
893
893
|
'continuationToken': response.json()['continuationToken'],
|
|
894
894
|
'tenant': self.tenant, 'twoFactorToken': totp.now()}
|
|
895
|
+
|
|
896
|
+
header = {'Content-Type': 'application/x-www-form-urlencoded'}
|
|
895
897
|
response_2fa = self.session.post(
|
|
896
898
|
f'{self.protocol}://{self.server}/api/accesstoken/complete-2fa',
|
|
897
|
-
data=data)
|
|
899
|
+
data=data, headers=header)
|
|
898
900
|
if response_2fa.status_code == requests.codes.ok:
|
|
899
901
|
return response_2fa.json()['token']
|
|
900
902
|
else:
|
pyPreservica/entityAPI.py
CHANGED
|
@@ -61,7 +61,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
61
61
|
Generator function to return bitstream chunks
|
|
62
62
|
|
|
63
63
|
:param bitstream: The bitstream
|
|
64
|
-
:param chunk_size: The chunk size to return
|
|
64
|
+
:param chunk_size: The chunk size to return (defaults to 4K)
|
|
65
65
|
:return: A chunk of the requested bitstream content
|
|
66
66
|
"""
|
|
67
67
|
if not isinstance(bitstream, Bitstream):
|
|
@@ -75,7 +75,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
75
75
|
for chunk in request.iter_content(chunk_size=chunk_size):
|
|
76
76
|
yield chunk
|
|
77
77
|
else:
|
|
78
|
-
exception = HTTPException(bitstream.filename, request.status_code, request.url, "
|
|
78
|
+
exception = HTTPException(bitstream.filename, request.status_code, request.url, "bitstream_chunks",
|
|
79
79
|
request.content.decode('utf-8'))
|
|
80
80
|
logger.error(exception)
|
|
81
81
|
raise exception
|
|
@@ -113,7 +113,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
113
113
|
logger.error("Downloaded file size did not match the Preservica held value")
|
|
114
114
|
return None
|
|
115
115
|
else:
|
|
116
|
-
exception = HTTPException(bitstream.filename, response.status_code, response.url, "
|
|
116
|
+
exception = HTTPException(bitstream.filename, response.status_code, response.url, "bitstream_bytes",
|
|
117
117
|
response.content.decode('utf-8'))
|
|
118
118
|
logger.error(exception)
|
|
119
119
|
raise exception
|
|
@@ -1044,7 +1044,6 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
1044
1044
|
xml_request = xml.etree.ElementTree.tostring(xml_object, encoding='utf-8')
|
|
1045
1045
|
end_point = f"/{entity.path}/{entity.reference}/metadata"
|
|
1046
1046
|
logger.debug(xml_request)
|
|
1047
|
-
print(xml_request)
|
|
1048
1047
|
request = self.session.post(f'{self.protocol}://{self.server}/api/entity{end_point}', data=xml_request,
|
|
1049
1048
|
headers=headers)
|
|
1050
1049
|
if request.status_code == requests.codes.ok:
|
|
@@ -2648,3 +2647,4 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
2648
2647
|
"_delete_entity", request.content.decode('utf-8'))
|
|
2649
2648
|
logger.error(exception)
|
|
2650
2649
|
raise exception
|
|
2650
|
+
|
pyPreservica/uploadAPI.py
CHANGED
|
@@ -1633,6 +1633,52 @@ class UploadAPI(AuthenticatedAPI):
|
|
|
1633
1633
|
logger.error(exception)
|
|
1634
1634
|
raise exception
|
|
1635
1635
|
|
|
1636
|
+
def clean_upload_bucket(self, bucket_name: str, older_than_days: int = 90):
|
|
1637
|
+
"""
|
|
1638
|
+
Clean up objects in an upload bucket which are older than older_than_days.
|
|
1639
|
+
|
|
1640
|
+
"""
|
|
1641
|
+
from azure.storage.blob import ContainerClient
|
|
1642
|
+
|
|
1643
|
+
for location in self.upload_locations():
|
|
1644
|
+
if location['containerName'] == bucket_name:
|
|
1645
|
+
|
|
1646
|
+
if location['type'] != 'AWS':
|
|
1647
|
+
credentials = self.upload_credentials(location['apiId'])
|
|
1648
|
+
account_key = credentials['key']
|
|
1649
|
+
session_token = credentials['sessionToken']
|
|
1650
|
+
sas_url = f"https://{account_key}.blob.core.windows.net/{bucket_name}"
|
|
1651
|
+
container = ContainerClient.from_container_url(container_url=sas_url, credential=session_token)
|
|
1652
|
+
now = datetime.now(timezone.utc)
|
|
1653
|
+
for blob in container.list_blobs():
|
|
1654
|
+
if abs((blob.last_modified - now).days) > older_than_days:
|
|
1655
|
+
logger.debug(f"Deleting expired object {blob.name}")
|
|
1656
|
+
container.delete_blob(blob.name)
|
|
1657
|
+
|
|
1658
|
+
if location['type'] == 'AWS':
|
|
1659
|
+
credentials = self.upload_credentials(location['apiId'])
|
|
1660
|
+
access_key = credentials['key']
|
|
1661
|
+
secret_key = credentials['secret']
|
|
1662
|
+
session_token = credentials['sessionToken']
|
|
1663
|
+
session = boto3.Session(aws_access_key_id=access_key, aws_secret_access_key=secret_key,
|
|
1664
|
+
aws_session_token=session_token)
|
|
1665
|
+
s3_client = session.client("s3")
|
|
1666
|
+
paginator = s3_client.get_paginator('list_objects_v2')
|
|
1667
|
+
now = datetime.now(timezone.utc)
|
|
1668
|
+
for page in paginator.paginate(Bucket=bucket_name):
|
|
1669
|
+
if 'Contents' in page:
|
|
1670
|
+
for key in page['Contents']:
|
|
1671
|
+
last_modified = key['LastModified']
|
|
1672
|
+
if abs((last_modified - now).days) > older_than_days:
|
|
1673
|
+
logger.debug(f"Deleting expired object {key['Key']}")
|
|
1674
|
+
s3_client.delete_object(Bucket=bucket_name, Key=key['Key'])
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
|
|
1681
|
+
|
|
1636
1682
|
def upload_locations(self):
|
|
1637
1683
|
"""
|
|
1638
1684
|
Upload locations are configured on the Sources page as 'SIP Upload'.
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
pyPreservica/__init__.py,sha256=
|
|
1
|
+
pyPreservica/__init__.py,sha256=Lqe6IieUt542PCQEfLGEN7qZmByqdxDJdzu6uRyQ6_c,1250
|
|
2
2
|
pyPreservica/adminAPI.py,sha256=Ls7uJA2Lu5t2k5vOFqrOlbZxmDrSp1-JuD_5z10w9w0,37990
|
|
3
3
|
pyPreservica/authorityAPI.py,sha256=A52sFiAK4E4mlend_dknNIOW2BEwKXcLFI02anZBt3U,9211
|
|
4
|
-
pyPreservica/common.py,sha256=
|
|
4
|
+
pyPreservica/common.py,sha256=vky_eupqQUG3zELTqqFMKP9m2kpwzXEgrxhGxxH6qDU,39231
|
|
5
5
|
pyPreservica/contentAPI.py,sha256=ZvX2aGQEaksmw-m-oEUI6daVSqFe_IcE1cGwCNbSCDQ,22286
|
|
6
|
-
pyPreservica/entityAPI.py,sha256=
|
|
6
|
+
pyPreservica/entityAPI.py,sha256=TErRGGMkvGxKBferwucde4wIH8rR3djsr6VOq2JqUqI,132409
|
|
7
7
|
pyPreservica/mdformsAPI.py,sha256=D6p7uD2qNY76P6_k5MSaXnrYMp487hDXwladYvASejI,20052
|
|
8
8
|
pyPreservica/monitorAPI.py,sha256=LJOUrynBOWKlNiYpZ1iH8qB1oIIuKX1Ms1SRBcuXohA,6274
|
|
9
9
|
pyPreservica/opex.py,sha256=ccra1S4ojUXS3PlbU8WfxajOkJrwG4OykBnNrYP_jus,4875
|
|
10
10
|
pyPreservica/parAPI.py,sha256=f0ZUxLd0U-BW6kBx5K7W2Pv7NjG3MkTNydmxQ3U1ZVE,9296
|
|
11
11
|
pyPreservica/retentionAPI.py,sha256=QUTCbN4P3IpqmrebU_wd3n5ZVcyxVLTFAli8Y_GxOW4,24843
|
|
12
12
|
pyPreservica/settingsAPI.py,sha256=jXnMOCq3mimta6E-Os3J1I1if2pYsjLpOazAx8L-ZQI,10721
|
|
13
|
-
pyPreservica/uploadAPI.py,sha256=
|
|
13
|
+
pyPreservica/uploadAPI.py,sha256=vYCfKicbpkjb78oCCkOzeB5T3Gl-zu-xZIvQPQ80Nio,102186
|
|
14
14
|
pyPreservica/webHooksAPI.py,sha256=KMObsdHp_0K0HjJUl5oaFh-vs21GCAQZo2ZTKkY38R8,6872
|
|
15
15
|
pyPreservica/workflowAPI.py,sha256=OcOiiUdrQerbPllrkj1lWpmuW0jTuyyV0urwPSYcd_U,17561
|
|
16
|
-
pypreservica-3.2.
|
|
17
|
-
pypreservica-3.2.
|
|
18
|
-
pypreservica-3.2.
|
|
19
|
-
pypreservica-3.2.
|
|
20
|
-
pypreservica-3.2.
|
|
16
|
+
pypreservica-3.2.5.dist-info/licenses/LICENSE.txt,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
17
|
+
pypreservica-3.2.5.dist-info/METADATA,sha256=1qISp87q4dr1eHJSUPi5wxX39QtQUgZYbHVynR6ynlw,3077
|
|
18
|
+
pypreservica-3.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
pypreservica-3.2.5.dist-info/top_level.txt,sha256=iIBh6NAznYQHOV8mv_y_kGKSDITek9rANyFDwJsbU-c,13
|
|
20
|
+
pypreservica-3.2.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|