forked from Cross-PLN-Technical-Working-Group/adpn-cli
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathadpn-make-manifest.py
executable file
·232 lines (181 loc) · 7.74 KB
/
adpn-make-manifest.py
1
2
3
4
5
6
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#!/usr/bin/python3
#
# Produce a manifest HTML file from a standardized template to be staged along
# with a LOCKSS Archival Unit (AU).
#
# @version 2019.0719
import os
import sys
import stat
import json
import urllib.parse, urllib.request
import myLockssScripts
from getpass import getpass
from myLockssScripts import myPyCommandLine, myPyPipeline
def get_filesystemlocation (file) :
location = None
try :
fstat = os.stat(file)
if stat.S_ISDIR(fstat.st_mode) :
location = file
else :
location = os.path.dirname(file)
except FileNotFoundError as e :
pass
return location
class MakeManifestHTMLWebAPI :
def __init__ (self, url, parameters, file) :
self._parameters = parameters
self._api = url
self._errmesg = None
self._file = file
@property
def source_object (self) :
return self.api
@property
def api (self) :
return self._api
@property
def parameters (self, accept=None) :
if accept is None :
accept = lambda key, value: value is not None
parameters = {}
for (key, value) in self._parameters.items() :
if accept(key, value) :
parameters[key] = value
return parameters
@property
def file (self) :
return self._file
@property
def errmesg (self) :
return self._errmesg
@errmesg.setter
def errmesg (self, rhs) :
self._errmesg = rhs
def get_data_body (self) :
return urllib.parse.urlencode(self.parameters).encode('utf-8')
def read (self) :
response = None
self.errmesg = None
try :
req = urllib.request.Request(self.api, data=self.get_data_body(), method="POST")
response = urllib.request.urlopen(req)
except urllib.request.HTTPError as e :
self.errmesg = ( "HTTP ERROR %(code)d %(reason)s [URL=%(url)s]" % { "code": e.code, "reason": e.reason, "url": self.api } )
raise
except urllib.request.URLError as e :
if isinstance(e.reason, str) :
self.errmesg = ( "URL Error: %(reason)s" % { "reason": e.reason } )
else :
self.errmesg = "URL Error: <Unrecognized Error> %(args)s %(context)s" % { "args": str(e.args), "context": str(e.__context__) }
raise
except Exception as e :
self.errmesg = "<Unrecognized Exception> (%(classname)s) %(args)s %(context)s" % { "classname": e.__class__.__name__, "args": str(e.args), "context": str(e.__context__) }
raise
text = None
decoded_text = None
if response is not None :
text = response.read()
encoding = response.headers.get_content_charset('utf-8')
decoded_text = text.decode(encoding)
if len(decoded_text) == 0 :
print("[" + scriptname + "] error: empty result", file=sys.stderr)
return decoded_text
class MakeManifestHTMLLocalTemplate :
def __init__ (self, parameters, file) :
self._parameters = parameters
self._errmesg = None
self._scriptpath = os.path.realpath(__file__)
self._file = file
self._source_object = None
@property
def parameters (self, accept=None) :
if accept is None :
accept = lambda key, value: value is not None
parameters = {}
for (key, value) in self._parameters.items() :
if accept(key, value) :
parameters[key] = value
return parameters
@property
def file (self) :
return self._file
@property
def errmesg (self) :
return self._errmesg
@errmesg.setter
def errmesg (self, rhs) :
self._errmesg = rhs
@property
def source_object (self) :
return self._source_object
@source_object.setter
def source_object (self, rhs) :
self._source_object = rhs
def get_templatedirectory (self) :
scriptdir = os.path.dirname(self._scriptpath)
return os.path.join(scriptdir, "templates")
def read (self) :
self.source_object = ( "%(path)s/%(file)s.sprintf" % {"path": self.get_templatedirectory(), "file": self.file} )
instream = open(self.source_object, "r")
template = "\n".join([ line.rstrip() for line in instream ])
instream.close()
return ( template % parameters )
def align_switches (left, right, switches, override=True) :
if switches[left] is None :
switches[left] = switches[right]
if switches[right] is None :
switches[right] = switches[left]
if override :
if switches[right] != switches[left] :
switches[right] = switches[left]
if __name__ == '__main__' :
scriptpath = os.path.realpath(__file__)
scriptname = os.path.basename(scriptpath)
scriptdir = os.path.dirname(scriptpath)
configjson = os.path.join(scriptdir, "adpnet.json")
(argv, switches) = myPyCommandLine(sys.argv, defaults={
"parameters": "{}", "local": None, "api": None, "api/makemanifest": None, "jar": None, "stage/jar": None, "dry-run": False
}, configfile=configjson).parse()
align_switches("api", "api/makemanifest", switches)
align_switches("jar", "stage/jar", switches)
os.environ["PATH"] = ":".join([scriptdir, os.environ["PATH"]])
scriptLine = ['adpn-plugin-details.py', '--output=text/tab-separated-values']
if switches["jar"] is not None :
scriptLine.append("--jar=%(jar)s" % switches )
detailsScript = myPyPipeline([ scriptLine + sys.argv[1:] ])
(buff, errbuf, exits) = detailsScript.siphon()
settings = [ line.rstrip().split("\t") for line in filter(lambda text: len(text.rstrip())>0, buff.split("\n")) ]
settings = [ (line[1], line[2]) for line in settings if line[0] == 'setting' ]
urlpaths = [ urllib.parse.urlparse(value) for setting, value in settings if setting == 'au_manifest' ]
if len(urlpaths) == 0 :
urlpaths = [ urllib.parse.urlparse(value) for setting, value in settings if setting == 'au_start_url' ]
basenames = [ os.path.basename(url.path) for url in urlpaths ]
parameters = json.loads(switches['parameters'])
parameters = {**dict(settings), **parameters}
for file in basenames :
outdir = get_filesystemlocation(switches['local']) if switches['local'] is not None else "."
outfile = "%(path)s/%(file)s" % {"path": outdir, "file": file}
html_resource = MakeManifestHTMLWebAPI(switches['api'], parameters, file) if switches['api'] else MakeManifestHTMLLocalTemplate(parameters, file)
if not switches['dry-run'] :
try :
out_html = html_resource.read()
except :
if html_resource.errmesg is not None :
print("[%(cmd)s] Error generating HTML content: %(mesg)s" % { "cmd": scriptname, "mesg": html_resource.errmesg }, file=sys.stderr)
else :
raise
if "-" == switches['local'] :
hOut = sys.stdout
else :
hOut = open(outfile, "w")
if out_html is not None :
print(out_html, file=hOut)
if "-" != switches['local'] :
hOut.close()
file_size=os.stat(outfile).st_size
else :
file_size = 1
if "-" != switches['local'] :
print("%(filename)s\t%(size)d\t%(source)s:%(source_object)s" % {"filename": outfile, "size": file_size, "source": html_resource.__class__.__name__, "source_object": html_resource.source_object})