lockss-pyclient 0.1.0.dev2__py3-none-any.whl → 0.1.0.dev3__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.
- lockss/pyclient/__init__.py +8 -29
- lockss/pyclient/__main__.py +37 -0
- lockss/pyclient/_internal_common.py +395 -0
- lockss/pyclient/_internal_config.py +207 -0
- lockss/pyclient/_internal_crawler.py +251 -0
- lockss/pyclient/_internal_md.py +111 -0
- lockss/pyclient/_internal_poller.py +174 -0
- lockss/pyclient/_internal_rs.py +232 -0
- lockss/pyclient/cli.py +839 -0
- lockss/pyclient/config/__init__.py +15 -0
- lockss/pyclient/config/api/aus_api.py +14 -6
- lockss/pyclient/config/api/config_api.py +12 -12
- lockss/pyclient/config/api/utils_api.py +2 -2
- lockss/pyclient/config/configuration.py +1 -1
- lockss/pyclient/config/models/__init__.py +15 -0
- lockss/pyclient/config/models/access_type.py +90 -0
- lockss/pyclient/config/models/au_agreements.py +136 -0
- lockss/pyclient/config/models/au_config_page_info.py +140 -0
- lockss/pyclient/config/models/au_state_bean.py +942 -0
- lockss/pyclient/config/models/au_status.py +837 -8
- lockss/pyclient/config/models/au_suspect_url_versions.py +136 -0
- lockss/pyclient/config/models/check_substance_result.py +6 -22
- lockss/pyclient/config/models/dated_peer_id_set_impl.py +162 -0
- lockss/pyclient/config/models/hash_result.py +136 -0
- lockss/pyclient/config/models/page_info.py +226 -0
- lockss/pyclient/config/models/peer_agreement.py +188 -0
- lockss/pyclient/config/models/peer_agreements.py +136 -0
- lockss/pyclient/config/models/platform_configuration_ws_result.py +421 -8
- lockss/pyclient/config/models/platform_configuration_ws_result_daemon_version.py +188 -0
- lockss/pyclient/config/models/platform_configuration_ws_result_java_version.py +188 -0
- lockss/pyclient/config/models/platform_configuration_ws_result_platform.py +162 -0
- lockss/pyclient/config/models/substance_checker_state.py +91 -0
- lockss/pyclient/config/models/suspect_url_version.py +214 -0
- lockss/pyclient/config/swagger.yaml +2031 -0
- lockss/pyclient/crawler/__init__.py +1 -0
- lockss/pyclient/crawler/api/crawls_api.py +2 -2
- lockss/pyclient/crawler/configuration.py +1 -1
- lockss/pyclient/crawler/models/__init__.py +1 -0
- lockss/pyclient/crawler/models/crawl_desc.py +4 -12
- lockss/pyclient/crawler/models/crawl_kind_enum.py +90 -0
- lockss/pyclient/crawler/models/page_info.py +22 -24
- lockss/pyclient/crawler/swagger.yaml +1197 -0
- lockss/pyclient/md/configuration.py +1 -1
- lockss/pyclient/md/models/page_info.py +22 -24
- lockss/pyclient/md/swagger.yaml +583 -0
- lockss/pyclient/output.py +131 -0
- lockss/pyclient/poller/__init__.py +11 -5
- lockss/pyclient/poller/api/export_api.py +5 -5
- lockss/pyclient/poller/api/hash_api.py +3 -3
- lockss/pyclient/poller/api/poll_detail_api.py +42 -42
- lockss/pyclient/poller/api/poller_polls_api.py +18 -18
- lockss/pyclient/poller/api/service_api.py +2 -2
- lockss/pyclient/poller/api/voter_polls_api.py +18 -18
- lockss/pyclient/poller/configuration.py +1 -1
- lockss/pyclient/poller/models/__init__.py +11 -5
- lockss/pyclient/poller/models/export_file_type_enum.py +93 -0
- lockss/pyclient/poller/models/export_filename_translation_enum.py +91 -0
- lockss/pyclient/poller/models/page_info.py +226 -0
- lockss/pyclient/poller/models/poll_desc.py +3 -11
- lockss/pyclient/poller/models/poll_variant_enum.py +92 -0
- lockss/pyclient/poller/models/poller_page_info.py +140 -0
- lockss/pyclient/poller/models/repair_page_info.py +140 -0
- lockss/pyclient/poller/models/repair_type_enum.py +91 -0
- lockss/pyclient/poller/models/tally_type_enum.py +93 -0
- lockss/pyclient/poller/models/url_page_info.py +140 -0
- lockss/pyclient/poller/models/voter_page_info.py +140 -0
- lockss/pyclient/poller/models/voter_urls_enum.py +92 -0
- lockss/pyclient/poller/swagger.yaml +1658 -0
- lockss/pyclient/rs/__init__.py +6 -0
- lockss/pyclient/rs/api/artifacts_api.py +20 -20
- lockss/pyclient/rs/api/aus_api.py +5 -5
- lockss/pyclient/rs/api/repo_api.py +4 -4
- lockss/pyclient/rs/api/status_api.py +1 -1
- lockss/pyclient/rs/api/wayback_api.py +12 -12
- lockss/pyclient/rs/configuration.py +8 -1
- lockss/pyclient/rs/models/__init__.py +6 -0
- lockss/pyclient/rs/models/artifact.py +111 -81
- lockss/pyclient/rs/models/au_size.py +6 -0
- lockss/pyclient/rs/models/auid_page_info.py +2 -2
- lockss/pyclient/rs/models/bulk_au_op_enum.py +90 -0
- lockss/pyclient/rs/models/include_content_enum.py +91 -0
- lockss/pyclient/rs/models/page_info.py +26 -29
- lockss/pyclient/rs/models/pywb_match_enum.py +93 -0
- lockss/pyclient/rs/models/pywb_output_enum.py +90 -0
- lockss/pyclient/rs/models/pywb_sort_enum.py +91 -0
- lockss/pyclient/rs/models/storage_info.py +131 -80
- lockss/pyclient/rs/models/versions_enum.py +90 -0
- lockss/pyclient/rs/swagger.yaml +1306 -0
- {lockss_pyclient-0.1.0.dev2.dist-info → lockss_pyclient-0.1.0.dev3.dist-info}/METADATA +10 -3
- {lockss_pyclient-0.1.0.dev2.dist-info → lockss_pyclient-0.1.0.dev3.dist-info}/RECORD +93 -45
- {lockss_pyclient-0.1.0.dev2.dist-info → lockss_pyclient-0.1.0.dev3.dist-info}/WHEEL +1 -1
- lockss_pyclient-0.1.0.dev3.dist-info/entry_points.txt +3 -0
- {lockss_pyclient-0.1.0.dev2.dist-info → lockss_pyclient-0.1.0.dev3.dist-info/licenses}/LICENSE +0 -0
lockss/pyclient/cli.py
ADDED
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2000-2025, Board of Trustees of Leland Stanford Jr. University
|
|
4
|
+
#
|
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
|
7
|
+
#
|
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
|
9
|
+
# this list of conditions and the following disclaimer.
|
|
10
|
+
#
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
# and/or other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# 3. Neither the name of the copyright holder nor the names of its contributors
|
|
16
|
+
# may be used to endorse or promote products derived from this software without
|
|
17
|
+
# specific prior written permission.
|
|
18
|
+
#
|
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
|
|
31
|
+
from io import TextIOWrapper
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
from typing import Literal
|
|
34
|
+
import sys
|
|
35
|
+
|
|
36
|
+
from lockss.pybasic.cliutil import BaseCli, COPYRIGHT_DESCRIPTION, LICENSE_DESCRIPTION, VERSION_DESCRIPTION
|
|
37
|
+
from lockss.pybasic.errorutil import InternalError
|
|
38
|
+
from pydantic.v1 import BaseModel as BaseModel1, Field as Field1, NonNegativeInt as NonNegativeInt1, root_validator as root_validator1
|
|
39
|
+
|
|
40
|
+
from .output import output_options
|
|
41
|
+
from . import *
|
|
42
|
+
from . import __copyright__, __license__, __version__
|
|
43
|
+
from ._internal_common import _param_default, _RS
|
|
44
|
+
from . import config, crawler, md, poller, rs
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class NodeOptions(BaseModel1):
|
|
48
|
+
host: str = Field1(aliases=["-H"], description="The IP address or FQDN of the LOCKSS node, optionally followed by a colon and port number")
|
|
49
|
+
repo: NonNegativeInt1 = Field1(RS_DEFAULT_PORT, aliases=['--repository-port', '-R'], description='Repository Service port')
|
|
50
|
+
config: NonNegativeInt1 = Field1(CONFIG_DEFAULT_PORT, aliases=['--configuration-port', '-C'], description='Configuration Service port')
|
|
51
|
+
poller: NonNegativeInt1 = Field1(POLLER_DEFAULT_PORT, aliases=['--poller-port', '-L'], description='Poller Service port')
|
|
52
|
+
crawler: NonNegativeInt1 = Field1(CRAWLER_DEFAULT_PORT, aliases=['--crawler-port', '-W'], description='Crawler Service port')
|
|
53
|
+
md: NonNegativeInt1 = Field1(MD_DEFAULT_PORT, aliases=['--metadata-port', '-M'], description='Metadata Service port')
|
|
54
|
+
|
|
55
|
+
def make_node(self, **kwargs) -> Node:
|
|
56
|
+
return Node(self.host,
|
|
57
|
+
rs_port=self.repo,
|
|
58
|
+
config_port=self.config,
|
|
59
|
+
poller_port=self.poller,
|
|
60
|
+
crawler_port=self.crawler,
|
|
61
|
+
md_port=self.md,
|
|
62
|
+
**kwargs)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class AuthOptions(NodeOptions):
|
|
66
|
+
username: str = Field1(aliases=["-U"], description="Username")
|
|
67
|
+
password: Optional[str] = Field1(aliases=["-P"], description="Password")
|
|
68
|
+
|
|
69
|
+
def make_node(self) -> Node:
|
|
70
|
+
return super().make_node(username=self.username,
|
|
71
|
+
password=self.password)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class NamespaceOptions(BaseModel1):
|
|
75
|
+
namespace: Optional[str] = Field1(aliases=["-n"], description="Namespace")
|
|
76
|
+
|
|
77
|
+
def get_namespace(self, default: str):
|
|
78
|
+
return self.namespace if self.namespace else default
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class AuidOptions(NamespaceOptions):
|
|
82
|
+
auid: str = Field1(aliases=['-a'], description='Archival Unit identifier (AUID)')
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class CrawlerIdOptions(BaseModel1):
|
|
86
|
+
crawler_id: str = Field1(alias='crawler-id', aliases=['-c'], description='crawler identifier')
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class DoiOptions(BaseModel1):
|
|
90
|
+
doi: str = Field1(aliases=['-d'], description='DOI')
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class IfMatchOptions(BaseModel1):
|
|
94
|
+
if_match: Optional[str] = Field1(description='set the If-Match HTTP header to the given value')
|
|
95
|
+
if_modified_since: Optional[str] = Field1(description='set the If-Modified-Since HTTP header to the given value')
|
|
96
|
+
if_none_match: Optional[str] = Field1(description='set the If-None-Match HTTP header to the given value')
|
|
97
|
+
if_unmodified_since: Optional[str] = Field1(description='set the If-Unmodified-Since HTTP header to the given value')
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class JobOptions(BaseModel1):
|
|
101
|
+
job: str = Field1(description='job identifier')
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class OpenUrlOptions(BaseModel1):
|
|
105
|
+
params: list[str] = Field1(aliases=['-p'], description='cumulative list of OpenURL parameters')
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class OutputOptions(BaseModel1):
|
|
109
|
+
output: Optional[Path] = Field1(aliases=['-o'], description='write output to the given file')
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class PollKeyOptions(BaseModel1):
|
|
113
|
+
poll_key: str = Field1(aliases=['-k'], description='poll key')
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class PeerIdOptions(PollKeyOptions):
|
|
117
|
+
peer_id: str = Field1(aliases=['-p'], description='peer identifier')
|
|
118
|
+
agreed: bool = Field1(False, description='return the agreed peer URLs')
|
|
119
|
+
disagreed: bool = Field1(False, description='return the disagreed peer URLs')
|
|
120
|
+
poller_only: bool = Field1(False, description='return the poller-only peer URLs')
|
|
121
|
+
voter_only: bool = Field1(False, description='return the voter-only peer URLs')
|
|
122
|
+
|
|
123
|
+
@root_validator1
|
|
124
|
+
def _validate_exactly_one(cls, values):
|
|
125
|
+
attrs = ('agreed', 'disagreed', 'poller_only', 'voter_only')
|
|
126
|
+
if len([attr for attr in attrs if values.get(attr)]) != 1:
|
|
127
|
+
raise ValueError('Expected exactly one of {", ".join(f"--{hattr}" for hattr in [attr.replace("_", "-") for attr in attrs])}')
|
|
128
|
+
return values
|
|
129
|
+
|
|
130
|
+
def get_voter_urls_enum(self) -> poller.VoterUrlsEnum:
|
|
131
|
+
if self.agreed: return poller.VoterUrlsEnum.AGREED
|
|
132
|
+
elif self.disagreed: return poller.VoterUrlsEnum.DISAGREED
|
|
133
|
+
elif self.poller_only: return poller.VoterUrlsEnum.POLLERONLY
|
|
134
|
+
elif self.voter_only: return poller.VoterUrlsEnum.VOTERONLY
|
|
135
|
+
else: raise InternalError from ValueError(self.json())
|
|
136
|
+
|
|
137
|
+
class RepairTypeOptions(BaseModel1):
|
|
138
|
+
active: bool = Field1(False, description='return the active repairs')
|
|
139
|
+
completed: bool = Field1(False, description='return the completed repairs')
|
|
140
|
+
pending: bool = Field1(False, description='return the pending repairs')
|
|
141
|
+
|
|
142
|
+
@root_validator1
|
|
143
|
+
def _validate_exactly_one(cls, values):
|
|
144
|
+
attrs = ('active', 'completed', 'pending')
|
|
145
|
+
if len([attr for attr in attrs if values.get(attr)]) != 1:
|
|
146
|
+
raise ValueError('Expected exactly one of {", ".join(f"--{hattr}" for hattr in [attr.replace("_", "-") for attr in attrs])}')
|
|
147
|
+
return values
|
|
148
|
+
|
|
149
|
+
def get_repair_type_enum(self) -> poller.RepairTypeEnum:
|
|
150
|
+
if self.active: return poller.RepairTypeEnum.ACTIVE
|
|
151
|
+
elif self.completed: return poller.RepairTypeEnum.COMPLETED
|
|
152
|
+
elif self.pending: return poller.RepairTypeEnum.PENDING
|
|
153
|
+
else: raise InternalError from ValueError(self.json())
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class TallyTypeOptions(BaseModel1):
|
|
157
|
+
agree: bool = Field1(False, description='return the tallies for URLs that agree')
|
|
158
|
+
disagree: bool = Field1(False, description='return the tallies for URLs that disagree')
|
|
159
|
+
error: bool = Field1(False, description='return the tallies for URLs that have errors')
|
|
160
|
+
no_quorum: bool = Field1(False, description='return the tallies for URLs that have no quorum')
|
|
161
|
+
too_close: bool = Field1(False, description='return the tallies for URLs that are too close')
|
|
162
|
+
|
|
163
|
+
@root_validator1
|
|
164
|
+
def _validate_exactly_one(cls, values):
|
|
165
|
+
attrs = ('active', 'completed', 'pending')
|
|
166
|
+
if len([attr for attr in attrs if values.get(attr)]) != 1:
|
|
167
|
+
raise ValueError('Expected exactly one of {", ".join(f"--{hattr}" for hattr in [attr.replace("_", "-") for attr in attrs])}')
|
|
168
|
+
return values
|
|
169
|
+
|
|
170
|
+
def get_tally_type_enum(self) -> poller.TallyTypeEnum:
|
|
171
|
+
if self.agree: return poller.TallyTypeEnum.AGREE
|
|
172
|
+
elif self.disagree: return poller.TallyTypeEnum.DISAGREE
|
|
173
|
+
elif self.error: return poller.TallyTypeEnum.ERROR
|
|
174
|
+
elif self.no_quorum: return poller.TallyTypeEnum.NOQUORUM
|
|
175
|
+
elif self.too_close: return poller.TallyTypeEnum.TOOCLOSE
|
|
176
|
+
else: raise InternalError from ValueError(self.json())
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class UrlOptions(BaseModel1):
|
|
180
|
+
url: Optional[str] = Field1(aliases=['-u'], description='URL')
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class UrlPrefixOptions(UrlOptions):
|
|
184
|
+
url_prefix: Optional[str] = Field1(aliases=['-p'], description='URL prefix')
|
|
185
|
+
|
|
186
|
+
@root_validator1
|
|
187
|
+
def _validate_exactly_one(cls, values):
|
|
188
|
+
attrs = ('url', 'url_prefix')
|
|
189
|
+
if len([attr for attr in attrs if values.get(attr)]) != 1:
|
|
190
|
+
raise ValueError('Expected exactly one of {", ".join(f"--{hattr}" for hattr in [attr.replace("_", "-") for attr in attrs])}')
|
|
191
|
+
return values
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class UuidOptions(NamespaceOptions):
|
|
195
|
+
uuid: str = Field1(aliases=['-w'], description='artifact identifier')
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class UncommittedOptions(BaseModel1):
|
|
199
|
+
uncommitted: bool = Field1(False, description='include uncommitted artifacts in results')
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class UserAccountOptions(BaseModel1):
|
|
203
|
+
user_account: str = Field1(description='user account name')
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class VersionsOptions(BaseModel1):
|
|
207
|
+
all: bool = Field1(False, description='include all versions of artifacts in results')
|
|
208
|
+
latest: bool = Field1(False, description='include only the latest version of artifacts in results')
|
|
209
|
+
|
|
210
|
+
@root_validator1
|
|
211
|
+
def _validate_at_most_one(cls, values):
|
|
212
|
+
attrs = ('all', 'latest')
|
|
213
|
+
if len([attr for attr in attrs if values.get(attr)]) > 1:
|
|
214
|
+
raise ValueError('Expected at most one of {", ".join(f"--{hattr}" for hattr in [attr.replace("_", "-") for attr in attrs])}')
|
|
215
|
+
return values
|
|
216
|
+
|
|
217
|
+
def get_versions_enum(self, default: rs.VersionsEnum) -> rs.VersionsEnum:
|
|
218
|
+
if self.all: return rs.VersionsEnum.ALL
|
|
219
|
+
elif self.latest: return rs.VersionsEnum.LATEST
|
|
220
|
+
else: return default
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
ArtifactOptions = output_options('ArtifactOptions', rs.Artifact, disambiguate=['auid', 'namespace'])
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
AuConfigurationOptions = output_options('AuConfigurationOptions', config.AuConfiguration)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
CrawlJobOptions = output_options('CrawlJobOptions', crawler.CrawlJob)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
CrawlStatusOptions = output_options('CrawlStatusOptions', crawler.CrawlStatus)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
CrawlUrlInfoOptions = output_options('CrawlUrlInfoOptions', crawler.UrlInfo)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
MdJobOptions = output_options('MdJobOptions', md.Job)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
MdUrlInfoOptions = output_options('MdUrlInfoOptions', md.UrlInfo)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class LockssApi(BaseModel1):
|
|
245
|
+
|
|
246
|
+
class Config(BaseModel1):
|
|
247
|
+
|
|
248
|
+
class Aus(BaseModel1):
|
|
249
|
+
|
|
250
|
+
class Agreements(AuidOptions, AuthOptions): pass
|
|
251
|
+
|
|
252
|
+
class Configuration(BaseModel1):
|
|
253
|
+
|
|
254
|
+
class Get(AuConfigurationOptions, AuidOptions, AuthOptions): pass
|
|
255
|
+
|
|
256
|
+
class GetAll(AuConfigurationOptions, AuthOptions): pass
|
|
257
|
+
|
|
258
|
+
get: Optional[Get] = Field1(description='Get the configuration of an AU')
|
|
259
|
+
get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the configurations of all AUs')
|
|
260
|
+
|
|
261
|
+
class NoAuPeerSet(output_options('DatedPeerIdSetImplOptions', config.DatedPeerIdSetImpl), AuidOptions, AuthOptions): pass
|
|
262
|
+
|
|
263
|
+
class State(output_options('AuStateBeanOptions', config.AuStateBean, disambiguate=['auid']), AuidOptions, AuthOptions): pass
|
|
264
|
+
|
|
265
|
+
class Status(output_options('AuStatusOptions', config.AuStatus), AuidOptions, AuthOptions): pass
|
|
266
|
+
|
|
267
|
+
class SuspectUrls(output_options('SuspectUrlVersionOptions', config.SuspectUrlVersion), AuidOptions, AuthOptions): pass
|
|
268
|
+
|
|
269
|
+
agreements: Optional[Agreements] = Field1(descriptions='Get the poll agreements of an AU')
|
|
270
|
+
configuration: Optional[Configuration] = Field1(description='AU configuration operations')
|
|
271
|
+
no_au_peer_set: Optional[NoAuPeerSet] = Field1(alias='no-au-peer-set', description='Get the NoAuPeerSet object of an AU')
|
|
272
|
+
state: Optional[State] = Field1(description='Get the state of an AU')
|
|
273
|
+
status: Optional[Status] = Field1(description='Get the status of an AU')
|
|
274
|
+
suspect_urls: Optional[SuspectUrls] = Field1(description='Get the suspect URL versions of an AU')
|
|
275
|
+
|
|
276
|
+
class LastUpdateTime(AuthOptions): pass
|
|
277
|
+
|
|
278
|
+
class LoadedUrls(AuthOptions): pass
|
|
279
|
+
|
|
280
|
+
class Platform(output_options('PlatformConfigurationWsResultOptions', config.PlatformConfigurationWsResult), AuthOptions): pass
|
|
281
|
+
|
|
282
|
+
class Section(BaseModel1):
|
|
283
|
+
|
|
284
|
+
class Get(IfMatchOptions, OutputOptions, AuthOptions):
|
|
285
|
+
section: str = Field1(description='the name of the section for which the configuration file is requested')
|
|
286
|
+
|
|
287
|
+
get: Optional[Get] = Field1(description='Get the named configuration file')
|
|
288
|
+
|
|
289
|
+
class Status(output_options('ConfigApiStatusOptions', config.ApiStatus), NodeOptions): pass
|
|
290
|
+
|
|
291
|
+
class Url(IfMatchOptions, OutputOptions, AuthOptions):
|
|
292
|
+
url: str = Field1(aliases=['-u'], description='the URL for which the configuration is requested')
|
|
293
|
+
|
|
294
|
+
class Users(BaseModel1):
|
|
295
|
+
|
|
296
|
+
class Get(UserAccountOptions, AuthOptions): pass
|
|
297
|
+
|
|
298
|
+
class Usernames(AuthOptions): pass
|
|
299
|
+
|
|
300
|
+
get: Optional[Get] = Field1(description='Get user account details')
|
|
301
|
+
usernames: Optional[Usernames] = Field1(description='Get the usernames configured in the system')
|
|
302
|
+
|
|
303
|
+
aus: Optional[Aus] = Field1(description='AU operations')
|
|
304
|
+
last_update_time: Optional[LastUpdateTime] = Field1(alias='last-update-time', description='Get the timestamp when the configuration was last updated')
|
|
305
|
+
loaded_urls: Optional[LoadedUrls] = Field1(alias='loaded-urls', description='Get the URLs from which the cofniguration was loaded')
|
|
306
|
+
platform: Optional[Platform] = Field1(description='Get the platform configuration')
|
|
307
|
+
section: Optional[Section] = Field1(description='Section operations')
|
|
308
|
+
status: Optional[Status] = Field1(description='Get the status of the service')
|
|
309
|
+
url: Optional[Url] = Field1(description='Get the configuration file for a URL')
|
|
310
|
+
users: Optional[Users] = Field1(description='User operations')
|
|
311
|
+
|
|
312
|
+
class Crawler(BaseModel1):
|
|
313
|
+
|
|
314
|
+
class Crawlers(BaseModel1):
|
|
315
|
+
|
|
316
|
+
class Get(output_options('CrawlerConfigOptions', crawler.CrawlerConfig, disambiguate=['crawler-id']), CrawlerIdOptions, AuthOptions): pass
|
|
317
|
+
|
|
318
|
+
class GetAll(output_options('CrawlerStatusesOptions', crawler.CrawlerStatuses), AuthOptions): pass
|
|
319
|
+
|
|
320
|
+
get: Optional[Get] = Field1(description='Get queued crawl job')
|
|
321
|
+
get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the list of crawl jobs')
|
|
322
|
+
|
|
323
|
+
class Crawls(BaseModel1):
|
|
324
|
+
|
|
325
|
+
class Get(CrawlStatusOptions, JobOptions, AuthOptions): pass
|
|
326
|
+
|
|
327
|
+
class GetAll(CrawlStatusOptions, AuthOptions): pass
|
|
328
|
+
|
|
329
|
+
class Urls(BaseModel1):
|
|
330
|
+
|
|
331
|
+
class Errors(CrawlUrlInfoOptions, JobOptions, AuthOptions): pass
|
|
332
|
+
|
|
333
|
+
class Excluded(CrawlUrlInfoOptions, JobOptions, AuthOptions): pass
|
|
334
|
+
|
|
335
|
+
class Fetched(CrawlUrlInfoOptions, JobOptions, AuthOptions): pass
|
|
336
|
+
|
|
337
|
+
class MediaTypes(BaseModel1):
|
|
338
|
+
|
|
339
|
+
class Get(CrawlUrlInfoOptions, JobOptions, AuthOptions):
|
|
340
|
+
media_type: str = Field1(description='the media type (e.g. application/pdf)')
|
|
341
|
+
|
|
342
|
+
#class GetAll(JobOptions, AuthOptions): pass
|
|
343
|
+
|
|
344
|
+
get: Optional[Get] = Field1(description='Get the URLs of a given media type for a crawl')
|
|
345
|
+
#get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the media types for a crawl')
|
|
346
|
+
|
|
347
|
+
class NotModified(CrawlUrlInfoOptions, JobOptions, AuthOptions): pass
|
|
348
|
+
|
|
349
|
+
class Parsed(CrawlUrlInfoOptions, JobOptions, AuthOptions): pass
|
|
350
|
+
|
|
351
|
+
class Pending(CrawlUrlInfoOptions, JobOptions, AuthOptions): pass
|
|
352
|
+
|
|
353
|
+
errors: Optional[Errors] = Field1(description='Get the error URLs for a crawl')
|
|
354
|
+
excluded: Optional[Excluded] = Field1(description='Get the excluded URLs for a crawl')
|
|
355
|
+
fetched: Optional[Fetched] = Field1(description='Get the fetched URLs for a crawl')
|
|
356
|
+
media_types: Optional[MediaTypes] = Field1(alias='media-types', description='Subcommand for media type operations')
|
|
357
|
+
not_modified: Optional[NotModified] = Field1(alias='not-modified', description='Get the not modified URLs for a crawl')
|
|
358
|
+
parsed: Optional[Parsed] = Field1(description='Get the parsed URLs for a crawl')
|
|
359
|
+
pending: Optional[Pending] = Field1(description='Get the pending URLs for a crawl')
|
|
360
|
+
|
|
361
|
+
get: Optional[Get] = Field1(description='Get the list of crawls')
|
|
362
|
+
get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the crawl status of a job')
|
|
363
|
+
urls: Optional[Urls] = Field1(description='Subcommand for crawl URL operations')
|
|
364
|
+
|
|
365
|
+
class Jobs(BaseModel1):
|
|
366
|
+
|
|
367
|
+
class Delete(AuthOptions): pass # FIXME
|
|
368
|
+
|
|
369
|
+
class DeleteAll(AuthOptions): pass # FIXME
|
|
370
|
+
|
|
371
|
+
class Get(CrawlJobOptions, JobOptions, AuthOptions): pass
|
|
372
|
+
|
|
373
|
+
class GetAll(CrawlJobOptions, AuthOptions): pass
|
|
374
|
+
|
|
375
|
+
class Request(AuthOptions): pass # FIXME
|
|
376
|
+
|
|
377
|
+
delete: Optional[Delete] = Field1(description='Remove or stop a crawl job') # FIXME
|
|
378
|
+
delete_all: Optional[DeleteAll] = Field1(alias='delete-all', description='Delete all of the currently queued and active crawl jobs') # FIXME
|
|
379
|
+
get: Optional[Get] = Field1(description='Get queued poll status')
|
|
380
|
+
get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the list of crawl jobs')
|
|
381
|
+
request: Optional[Request] = Field1(description='Request a crawl as defined by the descriptor') # FIXME
|
|
382
|
+
|
|
383
|
+
class Status(output_options('CrawlerApiStatusOptions', crawler.ApiStatus), NodeOptions): pass
|
|
384
|
+
|
|
385
|
+
crawlers: Optional[Crawlers] = Field1(description='Subcommand for crawler information operations')
|
|
386
|
+
crawls: Optional[Crawls] = Field1(description='Subcommand for crawl status operations')
|
|
387
|
+
jobs: Optional[Jobs] = Field1(description='Subcommand for crawler job operations')
|
|
388
|
+
status: Optional[Status] = Field1(description='Get the status of the service')
|
|
389
|
+
|
|
390
|
+
class Md(BaseModel1):
|
|
391
|
+
|
|
392
|
+
class Get(output_options('ItemMetadataOptions', md.ItemMetadata), AuidOptions, AuthOptions): pass
|
|
393
|
+
|
|
394
|
+
class Jobs(BaseModel1):
|
|
395
|
+
|
|
396
|
+
class Delete(AuthOptions): pass # FIXME
|
|
397
|
+
|
|
398
|
+
class DeleteAll(AuthOptions): pass # FIXME
|
|
399
|
+
|
|
400
|
+
class Get(MdJobOptions, JobOptions, AuthOptions): pass
|
|
401
|
+
|
|
402
|
+
class GetAll(MdJobOptions, AuthOptions): pass
|
|
403
|
+
|
|
404
|
+
class Request(AuthOptions): pass # FIXME
|
|
405
|
+
|
|
406
|
+
delete: Optional[Delete] = Field1(description='Delete a metadata job') # FIXME
|
|
407
|
+
delete_all: Optional[DeleteAll] = Field1(alias='delete-all', description='Delete all of the currently queued and active metadata jobs') # FIXME
|
|
408
|
+
get: Optional[Get] = Field1(description='Get queued job status')
|
|
409
|
+
get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the list of queued jobs')
|
|
410
|
+
request: Optional[Request] = Field1(description='Request a metadata update operation') # FIXME
|
|
411
|
+
|
|
412
|
+
class Query(BaseModel1):
|
|
413
|
+
|
|
414
|
+
class Doi(MdUrlInfoOptions, DoiOptions, AuthOptions): pass
|
|
415
|
+
|
|
416
|
+
class OpenUrl(MdUrlInfoOptions, OpenUrlOptions, AuthOptions): pass
|
|
417
|
+
|
|
418
|
+
doi: Optional[Doi] = Field1(description='Perform a DOI query')
|
|
419
|
+
openurl: Optional[OpenUrl] = Field1(description='Perform an OpenURL query')
|
|
420
|
+
|
|
421
|
+
class Status(output_options('MdApiStatusOptions', md.ApiStatus), NodeOptions): pass
|
|
422
|
+
|
|
423
|
+
get: Optional[Get] = Field1(description='Get the metadata stored for an AU')
|
|
424
|
+
jobs: Optional[Jobs] = Field1(description='Subcommand for metadata job operations')
|
|
425
|
+
query: Optional[Query] = Field1(description='Subcommand for query operations')
|
|
426
|
+
status: Optional[Status] = Field1(description='Get the status of the service')
|
|
427
|
+
|
|
428
|
+
class Poller(BaseModel1):
|
|
429
|
+
|
|
430
|
+
class Jobs(BaseModel1):
|
|
431
|
+
|
|
432
|
+
class Get(output_options('PollerSummaryOptions', poller.PollerSummary, disambiguate=['poll-key']), JobOptions, AuthOptions): pass
|
|
433
|
+
|
|
434
|
+
class Request(AuthOptions): pass # FIXME
|
|
435
|
+
|
|
436
|
+
get: Optional[Get] = Field1(description='Get queued poll status')
|
|
437
|
+
request: Optional[Request] = Field1(description='Request to call a poll as the poller') # FIXME
|
|
438
|
+
|
|
439
|
+
class Polls(BaseModel1):
|
|
440
|
+
|
|
441
|
+
class AsPoller(BaseModel1):
|
|
442
|
+
|
|
443
|
+
class Get(output_options('PollerDetailOptions', poller.PollerDetail, disambiguate=['poll-key']), PollKeyOptions, AuthOptions): pass
|
|
444
|
+
|
|
445
|
+
class GetAll(output_options('PollerSummaryOptions', poller.PollerSummary, disambiguate=['poll-key']), AuthOptions): pass
|
|
446
|
+
|
|
447
|
+
get: Optional[Get] = Field1(description='Get the detailed information about a poll in which a node is the poller')
|
|
448
|
+
get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the list of recent polls in which a node is the poller')
|
|
449
|
+
|
|
450
|
+
class AsVoter(BaseModel1):
|
|
451
|
+
|
|
452
|
+
class Get(output_options('VoterDetailOptions', poller.VoterDetail, disambiguate=['poll-key']), PollKeyOptions, AuthOptions): pass
|
|
453
|
+
|
|
454
|
+
class GetAll(output_options('VoterSummaryOptions', poller.VoterSummary, disambiguate=['poll-key']), AuthOptions): pass
|
|
455
|
+
|
|
456
|
+
get: Optional[Get] = Field1(description='Get the detailed information about a poll in which a node is a voter')
|
|
457
|
+
get_all: Optional[GetAll] = Field1(alias='get-all', description='Get the list of recent polls in which a node is a voter')
|
|
458
|
+
|
|
459
|
+
class PeerData(PeerIdOptions, AuthOptions): pass
|
|
460
|
+
|
|
461
|
+
class Repairs(output_options('RepairDataOptions', poller.RepairData), RepairTypeOptions, PollKeyOptions, AuthOptions): pass
|
|
462
|
+
|
|
463
|
+
class Tallies(TallyTypeOptions, PollKeyOptions, AuthOptions): pass
|
|
464
|
+
|
|
465
|
+
as_poller: Optional[AsPoller] = Field1(alias='as-poller', description='Subcommand for polls in which a node is the poller')
|
|
466
|
+
as_voter: Optional[AsVoter] = Field1(alias='as-voter', description='Subcommand for polls in which a node is the voter')
|
|
467
|
+
peer_data: Optional[PeerData] = Field1(alias='peer-data', description='Get peer data for a poll')
|
|
468
|
+
repairs: Optional[Repairs] = Field1(description='Get the repairs for a poll')
|
|
469
|
+
tallies: Optional[Tallies] = Field1(description='Get the tallies for a poll')
|
|
470
|
+
|
|
471
|
+
class Status(output_options('PollerApiStatusOptions', poller.ApiStatus), NodeOptions): pass
|
|
472
|
+
|
|
473
|
+
jobs: Optional[Jobs] = Field1(description='Subcommand for poller job operations')
|
|
474
|
+
polls: Optional[Polls] = Field1(description='Subcommand for poll status operations')
|
|
475
|
+
status: Optional[Status] = Field1(description='Get the status of the service')
|
|
476
|
+
|
|
477
|
+
class Repo(BaseModel1):
|
|
478
|
+
|
|
479
|
+
class Artifacts(BaseModel1):
|
|
480
|
+
|
|
481
|
+
class Delete(UuidOptions, NamespaceOptions, AuthOptions): pass
|
|
482
|
+
|
|
483
|
+
class Get(BaseModel1):
|
|
484
|
+
|
|
485
|
+
class ByAuid(ArtifactOptions, UncommittedOptions, VersionsOptions, UrlPrefixOptions, AuidOptions, AuthOptions): pass
|
|
486
|
+
|
|
487
|
+
class ByUrl(ArtifactOptions, VersionsOptions, UrlPrefixOptions, NamespaceOptions, AuthOptions): pass
|
|
488
|
+
|
|
489
|
+
class ByUuid(UuidOptions, AuthOptions):
|
|
490
|
+
response: Optional[Union[Path, Literal['-']]] = Field1(description='write the response headers to the given file, or "-" for standard output')
|
|
491
|
+
payload: Optional[Union[Path, Literal['-']]] = Field1(description='write the payload to the given file, or "-" for standard output')
|
|
492
|
+
|
|
493
|
+
by_auid: Optional[ByAuid] = Field1(alias='by-auid', description='Get artifacts in an Archival Unit')
|
|
494
|
+
by_url: Optional[ByUrl] = Field1(alias="by-url", description="Returns all artifacts that match a given URL or URL prefix and/or version")
|
|
495
|
+
by_uuid: Optional[ByUuid] = Field1(alias="by-uuid", description="Gets artifacts and artifact metadata")
|
|
496
|
+
|
|
497
|
+
class Update(UuidOptions, NamespaceOptions, AuthOptions):
|
|
498
|
+
commit: bool = Field1(description='Whether the artifact should be marked as committed or not committed')
|
|
499
|
+
|
|
500
|
+
delete: Optional[Delete] = Field1(description='Deletes an artifact')
|
|
501
|
+
get: Optional[Get] = Field1(description='Gets one or more artifacts')
|
|
502
|
+
update: Optional[Update] = Field1(description='Updates an artifact')
|
|
503
|
+
|
|
504
|
+
class Aus(BaseModel1):
|
|
505
|
+
|
|
506
|
+
class Auids(NamespaceOptions, AuthOptions): pass
|
|
507
|
+
|
|
508
|
+
class Size(output_options('AuSizeOptions', rs.AuSize), AuidOptions, AuthOptions): pass
|
|
509
|
+
|
|
510
|
+
auids: Optional[Auids] = Field1(description='Get Archival Unit IDs (AUIDs) in a namespace')
|
|
511
|
+
size: Optional[Size] = Field1(description='Get the size of Archival Unit artifacts in a namespace')
|
|
512
|
+
|
|
513
|
+
class ChecksumAlgorithms(AuthOptions): pass
|
|
514
|
+
|
|
515
|
+
class Info(output_options('RepositoryInfoOptions', rs.RepositoryInfo), AuthOptions): pass
|
|
516
|
+
|
|
517
|
+
class Namespaces(AuthOptions): pass
|
|
518
|
+
|
|
519
|
+
class Status(output_options('RsApiStatusOptions', rs.ApiStatus), NodeOptions): pass
|
|
520
|
+
|
|
521
|
+
class StorageInfo(AuthOptions): pass
|
|
522
|
+
|
|
523
|
+
artifacts: Optional[Artifacts] = Field1(description="LOCKSS Repository Service API artifacts commands")
|
|
524
|
+
aus: Optional[Aus] = Field1(description='LOCKSS Repository Service API archival unit (AU) commands')
|
|
525
|
+
checksum_algorithms: Optional[ChecksumAlgorithms] = Field1(alias='checksum-algorithms', description='Get the supported checksum algorithms')
|
|
526
|
+
info: Optional[Info] = Field1(description='Get repository information')
|
|
527
|
+
namespaces: Optional[Namespaces] = Field1(description='Get namespaces of the committed artifacts in the repository')
|
|
528
|
+
status: Optional[Status] = Field1(description="Get the status of the service")
|
|
529
|
+
storage_info: Optional[StorageInfo] = Field1(alias='storage-info', description="Get repository storage information")
|
|
530
|
+
|
|
531
|
+
config: Optional[Config] = Field1(description='Subcommand for Configuration Service operations')
|
|
532
|
+
copyright: Optional[BaseModel1] = Field1(description=COPYRIGHT_DESCRIPTION)
|
|
533
|
+
crawler: Optional[Crawler] = Field1(description='Subcommand for Crawler Service operations')
|
|
534
|
+
license: Optional[BaseModel1] = Field1(description=LICENSE_DESCRIPTION)
|
|
535
|
+
md: Optional[Md] = Field1(description='Subcommand for Metadata Service operations')
|
|
536
|
+
poller: Optional[Poller] = Field1(description='Subcommand for Poller Service operations')
|
|
537
|
+
repo: Optional[Repo] = Field1(description='Subcommand for Repository Service operations')
|
|
538
|
+
version: Optional[BaseModel1] = Field1(description=VERSION_DESCRIPTION)
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
class LockssApiCli(BaseCli[LockssApi]):
|
|
542
|
+
|
|
543
|
+
def __init__(self):
|
|
544
|
+
"""
|
|
545
|
+
Constructs a new ``DebugPanelCli`` instance.
|
|
546
|
+
"""
|
|
547
|
+
super().__init__(model=LockssApi,
|
|
548
|
+
prog='lockssapi',
|
|
549
|
+
description='LOCKSS Python client')
|
|
550
|
+
|
|
551
|
+
def _config_aus_agreements(self, cmd: LockssApi.Config.Aus.Agreements) -> None:
|
|
552
|
+
print(config_get_au_agreements(cmd.make_node(),
|
|
553
|
+
cmd.auid).to_dict())
|
|
554
|
+
|
|
555
|
+
def _config_aus_configuration_get(self, cmd: LockssApi.Config.Aus.Configuration.Get) -> None:
|
|
556
|
+
cmd.display(config_get_au_config(cmd.make_node(),
|
|
557
|
+
cmd.auid))
|
|
558
|
+
|
|
559
|
+
def _config_aus_configuration_get_all(self, cmd: LockssApi.Config.Aus.Configuration.GetAll) -> None:
|
|
560
|
+
cmd.display(config_get_au_configs(cmd.make_node()))
|
|
561
|
+
|
|
562
|
+
def _config_aus_no_au_peer_set(self, cmd: LockssApi.Config.Aus.NoAuPeerSet) -> None:
|
|
563
|
+
cmd.display(config_get_no_au_peer_set(cmd.make_node(),
|
|
564
|
+
cmd.auid))
|
|
565
|
+
|
|
566
|
+
def _config_aus_state(self, cmd: LockssApi.Config.Aus.State) -> None:
|
|
567
|
+
cmd.display(config_get_au_state(cmd.make_node(),
|
|
568
|
+
cmd.auid))
|
|
569
|
+
|
|
570
|
+
def _config_aus_status(self, cmd: LockssApi.Config.Aus.Status) -> None:
|
|
571
|
+
cmd.display(config_get_au_status(cmd.make_node(),
|
|
572
|
+
cmd.auid))
|
|
573
|
+
|
|
574
|
+
def _config_aus_suspect_urls(self, cmd: LockssApi.Config.Aus.SuspectUrls) -> None:
|
|
575
|
+
cmd.display(config_get_au_suspect_url_versions(cmd.make_node(),
|
|
576
|
+
cmd.auid).suspect_versions)
|
|
577
|
+
|
|
578
|
+
def _config_last_update_time(self, cmd: LockssApi.Config.LastUpdateTime) -> None:
|
|
579
|
+
print(config_last_update_time(cmd.make_node()))
|
|
580
|
+
|
|
581
|
+
def _config_loaded_urls(self, cmd: LockssApi.Config.LoadedUrls) -> None:
|
|
582
|
+
for url in config_get_loaded_urls(cmd.make_node()):
|
|
583
|
+
print(url)
|
|
584
|
+
|
|
585
|
+
def _config_platform(self, cmd: LockssApi.Config.Platform) -> None:
|
|
586
|
+
cmd.display(config_get_platform_config(cmd.make_node()))
|
|
587
|
+
|
|
588
|
+
def _config_section_get(self, cmd: LockssApi.Config.Section.Get) -> None:
|
|
589
|
+
mp = config_get_section(cmd.make_node(),
|
|
590
|
+
cmd.section,
|
|
591
|
+
if_match=cmd.if_match,
|
|
592
|
+
if_modified_since=cmd.if_modified_since,
|
|
593
|
+
if_none_match=cmd.if_none_match,
|
|
594
|
+
if_unmodified_since=cmd.if_unmodified_since)
|
|
595
|
+
part = None
|
|
596
|
+
try:
|
|
597
|
+
part = mp.get('configFile')
|
|
598
|
+
if cmd.output:
|
|
599
|
+
part.save_as(cmd.output)
|
|
600
|
+
else:
|
|
601
|
+
for line in TextIOWrapper(part.file):
|
|
602
|
+
print(line, end='')
|
|
603
|
+
finally:
|
|
604
|
+
if part:
|
|
605
|
+
part.close()
|
|
606
|
+
|
|
607
|
+
def _config_status(self, cmd: LockssApi.Config.Status) -> None:
|
|
608
|
+
cmd.display(config_get_status(cmd.make_node()))
|
|
609
|
+
|
|
610
|
+
def _config_url(self, cmd: LockssApi.Config.Url) -> None:
|
|
611
|
+
mp = config_get_url(cmd.make_node(),
|
|
612
|
+
cmd.url,
|
|
613
|
+
if_match=cmd.if_match,
|
|
614
|
+
if_modified_since=cmd.if_modified_since,
|
|
615
|
+
if_none_match=cmd.if_none_match,
|
|
616
|
+
if_unmodified_since=cmd.if_unmodified_since)
|
|
617
|
+
part = None
|
|
618
|
+
try:
|
|
619
|
+
part = mp.get('configFile')
|
|
620
|
+
if cmd.output:
|
|
621
|
+
part.save_as(cmd.output)
|
|
622
|
+
else:
|
|
623
|
+
for line in TextIOWrapper(part.file):
|
|
624
|
+
print(line, end='')
|
|
625
|
+
finally:
|
|
626
|
+
if part:
|
|
627
|
+
part.close()
|
|
628
|
+
|
|
629
|
+
def _config_users_get(self, cmd: LockssApi.Config.Users.Get) -> None:
|
|
630
|
+
print(config_get_user_account(cmd.make_node(),
|
|
631
|
+
cmd.user_account))
|
|
632
|
+
|
|
633
|
+
def _config_users_usernames(self, cmd: LockssApi.Config.Users.Usernames) -> None:
|
|
634
|
+
for username in sorted(config_get_usernames(cmd.make_node())):
|
|
635
|
+
print(username)
|
|
636
|
+
|
|
637
|
+
def _copyright(self, cmd: BaseModel1) -> None:
|
|
638
|
+
self._parser.exit(0, __copyright__)
|
|
639
|
+
|
|
640
|
+
def _crawler_crawlers_get(self, cmd: LockssApi.Crawler.Crawlers.Get) -> None:
|
|
641
|
+
cmd.display(crawler_get_crawler(cmd.make_node(),
|
|
642
|
+
cmd.crawler_id))
|
|
643
|
+
|
|
644
|
+
def _crawler_crawlers_get_all(self, cmd: LockssApi.Crawler.Crawlers.GetAll) -> None:
|
|
645
|
+
cmd.display(crawler_get_crawlers(cmd.make_node()))
|
|
646
|
+
|
|
647
|
+
def _crawler_crawls_urls_errors(self, cmd: LockssApi.Crawler.Crawls.Urls.Errors) -> None:
|
|
648
|
+
cmd.display(crawler_get_crawl_errors(cmd.make_node(),
|
|
649
|
+
cmd.job))
|
|
650
|
+
|
|
651
|
+
def _crawler_crawls_urls_excluded(self, cmd: LockssApi.Crawler.Crawls.Urls.Excluded) -> None:
|
|
652
|
+
cmd.display(crawler_get_crawl_excluded(cmd.make_node(),
|
|
653
|
+
cmd.job))
|
|
654
|
+
|
|
655
|
+
def _crawler_crawls_urls_fetched(self, cmd: LockssApi.Crawler.Crawls.Urls.Fetched) -> None:
|
|
656
|
+
cmd.display(crawler_get_crawl_fetched(cmd.make_node(),
|
|
657
|
+
cmd.job))
|
|
658
|
+
|
|
659
|
+
def _crawler_crawls_get(self, cmd: LockssApi.Crawler.Crawls.Get) -> None:
|
|
660
|
+
cmd.display(crawler_get_crawl(cmd.make_node(),
|
|
661
|
+
cmd.job))
|
|
662
|
+
|
|
663
|
+
def _crawler_crawls_get_all(self, cmd: LockssApi.Crawler.Crawls.GetAll) -> None:
|
|
664
|
+
cmd.display(crawler_get_crawls(cmd.make_node()))
|
|
665
|
+
|
|
666
|
+
def _crawler_crawls_urls_media_types_get(self, cmd: LockssApi.Crawler.Crawls.Urls.MediaTypes.Get) -> None:
|
|
667
|
+
cmd.display(crawler_get_crawl_by_media_type(cmd.make_node(),
|
|
668
|
+
cmd.job,
|
|
669
|
+
cmd.media_type))
|
|
670
|
+
|
|
671
|
+
def _crawler_crawls_urls_not_modified(self, cmd: LockssApi.Crawler.Crawls.Urls.NotModified) -> None:
|
|
672
|
+
cmd.display(crawler_get_crawl_not_modified(cmd.make_node(),
|
|
673
|
+
cmd.job))
|
|
674
|
+
|
|
675
|
+
def _crawler_crawls_urls_parsed(self, cmd: LockssApi.Crawler.Crawls.Urls.Parsed) -> None:
|
|
676
|
+
cmd.display(crawler_get_crawl_parsed(cmd.make_node(),
|
|
677
|
+
cmd.job))
|
|
678
|
+
|
|
679
|
+
def _crawler_crawls_urls_pending(self, cmd: LockssApi.Crawler.Crawls.Urls.Pending) -> None:
|
|
680
|
+
cmd.display(crawler_get_crawl_pending(cmd.make_node(),
|
|
681
|
+
cmd.job))
|
|
682
|
+
|
|
683
|
+
def _crawler_jobs_get(self, cmd: LockssApi.Crawler.Jobs.Get) -> None:
|
|
684
|
+
cmd.display(crawler_get_job(cmd.make_node(),
|
|
685
|
+
cmd.job))
|
|
686
|
+
|
|
687
|
+
def _crawler_jobs_get_all(self, cmd: LockssApi.Crawler.Jobs.GetAll) -> None:
|
|
688
|
+
cmd.display(crawler_get_jobs(cmd.make_node()))
|
|
689
|
+
|
|
690
|
+
def _crawler_status(self, cmd: LockssApi.Crawler.Status) -> None:
|
|
691
|
+
cmd.display(crawler_get_status(cmd.make_node()))
|
|
692
|
+
|
|
693
|
+
def _license(self, cmd: BaseModel1) -> None:
|
|
694
|
+
self._parser.exit(0, __license__)
|
|
695
|
+
|
|
696
|
+
def _md_get(self, cmd: LockssApi.Md.Get) -> None:
|
|
697
|
+
cmd.display(md_get_metadata(cmd.make_node(),
|
|
698
|
+
cmd.auid))
|
|
699
|
+
|
|
700
|
+
def _md_jobs_get(self, cmd: LockssApi.Md.Jobs.Get) -> None:
|
|
701
|
+
cmd.display(md_get_job(cmd.make_node(),
|
|
702
|
+
cmd.job))
|
|
703
|
+
|
|
704
|
+
def _md_jobs_get_all(self, cmd: LockssApi.Md.Jobs.GetAll) -> None:
|
|
705
|
+
cmd.display(md_get_jobs(cmd.make_node()))
|
|
706
|
+
|
|
707
|
+
def _md_query_doi(self, cmd: LockssApi.Md.Query.Doi) -> None:
|
|
708
|
+
cmd.display(md_doi_query(cmd.make_node(),
|
|
709
|
+
cmd.doi))
|
|
710
|
+
|
|
711
|
+
def _md_query_openurl(self, cmd: LockssApi.Md.Query.OpenUrl) -> None:
|
|
712
|
+
cmd.display(md_openurl_query(cmd.make_node(),
|
|
713
|
+
cmd.params))
|
|
714
|
+
|
|
715
|
+
def _md_status(self, cmd: LockssApi.Md.Status) -> None:
|
|
716
|
+
cmd.display(md_get_status(cmd.make_node()))
|
|
717
|
+
|
|
718
|
+
def _poller_jobs_get(self, cmd: LockssApi.Poller.Jobs.Get) -> None:
|
|
719
|
+
cmd.display(poller_get_poll_status(cmd.make_node(),
|
|
720
|
+
cmd.job))
|
|
721
|
+
|
|
722
|
+
def _poller_polls_as_poller_get(self, cmd: LockssApi.Poller.Polls.AsPoller.Get) -> None:
|
|
723
|
+
cmd.display(poller_get_poller_poll(cmd.make_node(),
|
|
724
|
+
cmd.poll_key))
|
|
725
|
+
|
|
726
|
+
def _poller_polls_as_poller_get_all(self, cmd: LockssApi.Poller.Polls.AsPoller.GetAll) -> None:
|
|
727
|
+
cmd.display(poller_get_poller_polls(cmd.make_node()))
|
|
728
|
+
|
|
729
|
+
def _poller_polls_as_voter_get(self, cmd: LockssApi.Poller.Polls.AsVoter.Get) -> None:
|
|
730
|
+
cmd.display(poller_get_voter_poll(cmd.make_node(),
|
|
731
|
+
cmd.poll_key))
|
|
732
|
+
|
|
733
|
+
def _poller_polls_as_voter_get_all(self, cmd: LockssApi.Poller.Polls.AsVoter.GetAll) -> None:
|
|
734
|
+
cmd.display(poller_get_voter_polls(cmd.make_node()))
|
|
735
|
+
|
|
736
|
+
def _poller_polls_peer_data(self, cmd: LockssApi.Poller.Polls.PeerData) -> None:
|
|
737
|
+
for url in poller_get_peer_data(cmd.make_node(),
|
|
738
|
+
cmd.poll_key,
|
|
739
|
+
cmd.peer_id,
|
|
740
|
+
cmd.get_voter_urls_enum()):
|
|
741
|
+
print(url)
|
|
742
|
+
|
|
743
|
+
def _poller_polls_repairs(self, cmd: LockssApi.Poller.Polls.Repairs) -> None:
|
|
744
|
+
cmd.display(poller_get_repair_data(cmd.make_node(),
|
|
745
|
+
cmd.poll_key,
|
|
746
|
+
cmd.get_repair_type_enum()))
|
|
747
|
+
|
|
748
|
+
def _poller_polls_tallies(self, cmd: LockssApi.Poller.Polls.Tallies) -> None:
|
|
749
|
+
for url in poller_get_tally_urls(cmd.make_node(),
|
|
750
|
+
cmd.poll_key,
|
|
751
|
+
cmd.get_tally_type_enum()):
|
|
752
|
+
print(url)
|
|
753
|
+
|
|
754
|
+
def _poller_status(self, cmd: LockssApi.Poller.Status) -> None:
|
|
755
|
+
cmd.display(poller_get_status(cmd.make_node()))
|
|
756
|
+
|
|
757
|
+
def _repo_artifacts_delete(self, cmd: LockssApi.Repo.Artifacts.Delete) -> None:
|
|
758
|
+
repo_delete_artifact(cmd.make_node(),
|
|
759
|
+
cmd.uuid,
|
|
760
|
+
namespace=cmd.get_namespace(_param_default(_RS, '/artifacts/{uuid}', 'delete', 'namespace')))
|
|
761
|
+
print(cmd.uuid)
|
|
762
|
+
|
|
763
|
+
def _repo_artifacts_get_by_auid(self, cmd: LockssApi.Repo.Artifacts.Get.ByAuid) -> None:
|
|
764
|
+
cmd.display(repo_get_artifacts_by_auid(cmd.make_node(),
|
|
765
|
+
cmd.auid,
|
|
766
|
+
url=cmd.url,
|
|
767
|
+
url_prefix=cmd.url_prefix,
|
|
768
|
+
namespace=cmd.get_namespace(_param_default(_RS, '/aus/{auid}/artifacts', 'get', 'namespace')),
|
|
769
|
+
versions=cmd.get_versions_enum(rs.VersionsEnum.LATEST),
|
|
770
|
+
include_uncommitted=cmd.uncommitted))
|
|
771
|
+
|
|
772
|
+
def _repo_artifacts_by_url(self, cmd: LockssApi.Repo.Artifacts.Get.ByUrl) -> None:
|
|
773
|
+
cmd.display(repo_get_artifacts_by_url(cmd.make_node(),
|
|
774
|
+
url=cmd.url,
|
|
775
|
+
url_prefix=cmd.url_prefix,
|
|
776
|
+
namespace=cmd.get_namespace(_param_default(_RS, '/artifacts', 'get', 'namespace')),
|
|
777
|
+
versions=cmd.get_versions_enum(rs.VersionsEnum.LATEST)))
|
|
778
|
+
|
|
779
|
+
def _repo_artifacts_get_by_uuid(self, cmd: LockssApi.Repo.Artifacts.Get.ByUuid) -> None:
|
|
780
|
+
mp = repo_get_artifact_by_uuid(cmd.make_node(),
|
|
781
|
+
cmd.uuid,
|
|
782
|
+
namespace=_param_default(_RS, '/artifacts/{uuid}', 'get', 'namespace'),
|
|
783
|
+
include_content=rs.IncludeContentEnum.ALWAYS if cmd.payload else rs.IncludeContentEnum.NEVER)
|
|
784
|
+
print(mp.get('artifactProps').value)
|
|
785
|
+
for path, part_name in ((cmd.response, 'httpResponseHeader'), (cmd.payload, 'payload')):
|
|
786
|
+
if path is None:
|
|
787
|
+
continue
|
|
788
|
+
part = None
|
|
789
|
+
try:
|
|
790
|
+
part = mp.get(part_name)
|
|
791
|
+
if path == '-':
|
|
792
|
+
print()
|
|
793
|
+
while len((bytez := part.file.read(1024))) > 0:
|
|
794
|
+
sys.stdout.write(bytez)
|
|
795
|
+
else:
|
|
796
|
+
part.save_as(path)
|
|
797
|
+
finally:
|
|
798
|
+
if part:
|
|
799
|
+
part.close()
|
|
800
|
+
|
|
801
|
+
def _repo_aus_auids(self, cmd: LockssApi.Repo.Aus.Auids) -> None:
|
|
802
|
+
for auid in sorted(repo_get_auids(cmd.make_node())):
|
|
803
|
+
print(auid)
|
|
804
|
+
|
|
805
|
+
def _repo_aus_size(self, cmd: LockssApi.Repo.Aus.Size) -> None:
|
|
806
|
+
cmd.display(repo_get_au_size(cmd.make_node(),
|
|
807
|
+
cmd.auid,
|
|
808
|
+
namespace=cmd.get_namespace(_param_default(_RS, '/aus/{auid}/size', 'get', 'namespace'))))
|
|
809
|
+
|
|
810
|
+
def _repo_checksum_algorithms(self, cmd: LockssApi.Repo.ChecksumAlgorithms) -> None:
|
|
811
|
+
for checksum_algorithm in sorted(repo_get_checksum_algorithms(cmd.make_node())):
|
|
812
|
+
print(checksum_algorithm)
|
|
813
|
+
|
|
814
|
+
def _repo_info(self, cmd: LockssApi.Repo.Info) -> None:
|
|
815
|
+
cmd.display(repo_get_info(cmd.make_node()))
|
|
816
|
+
|
|
817
|
+
def _repo_namespaces(self, cmd: LockssApi.Repo.Namespaces) -> None:
|
|
818
|
+
for namespace in sorted(repo_get_namespaces(cmd.make_node())):
|
|
819
|
+
print(namespace)
|
|
820
|
+
|
|
821
|
+
def _repo_status(self, cmd: LockssApi.Repo.Status) -> None:
|
|
822
|
+
cmd.display(repo_get_status(cmd.make_node()))
|
|
823
|
+
|
|
824
|
+
def _repo_storage_info(self, cmd: LockssApi.Repo.StorageInfo) -> None:
|
|
825
|
+
print(repo_get_storage_info(cmd.make_node()).to_dict())
|
|
826
|
+
|
|
827
|
+
def _version(self, cmd: BaseModel1) -> None:
|
|
828
|
+
self._parser.exit(0, __version__)
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
def main() -> None:
|
|
832
|
+
"""
|
|
833
|
+
Entry point for the lockssapi command line tool.
|
|
834
|
+
"""
|
|
835
|
+
LockssApiCli().run()
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
if __name__ == '__main__':
|
|
839
|
+
main()
|