casaconfig 0.0.79__tar.gz → 0.0.81__tar.gz
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.
- {casaconfig-0.0.79/casaconfig.egg-info → casaconfig-0.0.81}/PKG-INFO +1 -1
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/__main__.py +10 -5
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/config.py +3 -8
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/data_available.py +2 -2
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/data_update.py +91 -37
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/do_auto_updates.py +10 -7
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/do_pull_data.py +1 -1
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/get_data_info.py +58 -46
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/measures_update.py +118 -49
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/print_log_messages.py +11 -2
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/pull_data.py +62 -29
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/update_all.py +9 -4
- {casaconfig-0.0.79 → casaconfig-0.0.81/casaconfig.egg-info}/PKG-INFO +1 -1
- {casaconfig-0.0.79 → casaconfig-0.0.81}/setup.py +1 -1
- {casaconfig-0.0.79 → casaconfig-0.0.81}/LICENSE +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/MANIFEST.in +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/README.md +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/__init__.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/__init__.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/casasiteconfig.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/config_defaults.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/config_defaults_static.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/get_argparser.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/get_config.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/get_data_lock.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/io_redirect.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/measures_available.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/read_readme.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig/private/set_casacore_path.py +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig.egg-info/SOURCES.txt +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig.egg-info/dependency_links.txt +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig.egg-info/requires.txt +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/casaconfig.egg-info/top_level.txt +0 -0
- {casaconfig-0.0.79 → casaconfig-0.0.81}/setup.cfg +0 -0
@@ -7,6 +7,8 @@ parser = get_argparser(add_help=True)
|
|
7
7
|
# get_argparser supplies configfile, noconfig, nositeconfig
|
8
8
|
# add measurespath, pull-data, data-update, measures-update, update-all, reference-testing, current-data
|
9
9
|
|
10
|
+
parser.prog = "casaconfig"
|
11
|
+
|
10
12
|
# measurespath will default to the value in config if not set here
|
11
13
|
parser.add_argument( "--measurespath", dest='measurespath', default=None,
|
12
14
|
help="location of casarundata")
|
@@ -23,6 +25,8 @@ parser.add_argument( "--reference-testing", action='store_const', const=True, de
|
|
23
25
|
help="set measurespath to the casarundata when this version was produced, used for testing purposes")
|
24
26
|
parser.add_argument( "--current-data", dest='currentdata', action='store_const', const=True, default=False,
|
25
27
|
help="print out a summary of the current casarundata and measures data installed in measurespath and then exit")
|
28
|
+
parser.add_argument("--force", dest='force', action='store_const', const=True, default=False,
|
29
|
+
help="force an update using the force=True option to update_all, data_update, and measures_update")
|
26
30
|
|
27
31
|
# initialize the configuration to be used
|
28
32
|
flags,args = parser.parse_known_args(sys.argv)
|
@@ -65,8 +69,8 @@ if flags.currentdata:
|
|
65
69
|
|
66
70
|
# measures
|
67
71
|
measuresInfo = dataInfo['measures']
|
68
|
-
if measuresInfo is None or
|
69
|
-
print("No measures data found (missing or unexpected readme.txt, not obviously
|
72
|
+
if measuresInfo is None or measuresInfo['version'] == "invalid":
|
73
|
+
print("No measures data found (missing or unexpected readme.txt, not obviously legacy measures data).")
|
70
74
|
elif measuresInfo['version'] == "unknown":
|
71
75
|
print("measures version is unknown (probably legacy measures data not maintained by casaconfig).")
|
72
76
|
else:
|
@@ -83,17 +87,18 @@ else:
|
|
83
87
|
# ignore all other options
|
84
88
|
else:
|
85
89
|
# the update options, update all does everything, no need to invoke anything else
|
90
|
+
print("Checking for updates into %s" % measurespath)
|
86
91
|
if flags.updateall:
|
87
|
-
casaconfig.update_all(measurespath)
|
92
|
+
casaconfig.update_all(measurespath,force=flags.force)
|
88
93
|
else:
|
89
94
|
# do any pull_update first
|
90
95
|
if flags.pulldata:
|
91
96
|
casaconfig.pull_data(measurespath)
|
92
97
|
# then data_update, not necessary if pull_data just happened
|
93
98
|
if flags.dataupdate and not flags.pulldata:
|
94
|
-
casaconfig.data_update(measurespath)
|
99
|
+
casaconfig.data_update(measurespath, force=flags.force)
|
95
100
|
# then measures_update
|
96
101
|
if flags.measuresupdate:
|
97
|
-
casaconfig.measures_update(measurespath)
|
102
|
+
casaconfig.measures_update(measurespath, force=flags.force)
|
98
103
|
|
99
104
|
sys.exit(0)
|
@@ -124,14 +124,9 @@ for __v in __defaults:
|
|
124
124
|
if globals()[__v] is not None:
|
125
125
|
globals()[__v] = __os.path.abspath(__os.path.expanduser(globals()[__v]))
|
126
126
|
else:
|
127
|
-
|
128
|
-
|
129
|
-
print("
|
130
|
-
for __f in __loaded_config_files:
|
131
|
-
print(" %s" % __f)
|
132
|
-
print("__config_files : ")
|
133
|
-
for __f in __config_files:
|
134
|
-
print(" %s" % __f)
|
127
|
+
pass
|
128
|
+
# debugging
|
129
|
+
# print("None value seen while expanding path-like fields for config parameter %s" % __v)
|
135
130
|
|
136
131
|
def load_success( ):
|
137
132
|
return __loaded_config_files
|
@@ -51,8 +51,8 @@ def data_available():
|
|
51
51
|
if tag == 'a':
|
52
52
|
for (name, value) in attrs:
|
53
53
|
# only care if this is an href and the value starts with
|
54
|
-
# casarundata and has '.tar.' somewhere later
|
55
|
-
if name == 'href' and (value.startswith('casarundata') and (value.rfind('.tar')>11)):
|
54
|
+
# casarundata and has '.tar.' somewhere later and does not end in .md5
|
55
|
+
if name == 'href' and (value.startswith('casarundata') and (value.rfind('.tar')>11) and (value[-4:] != '.md5')):
|
56
56
|
# only add it to the list if it's not already there
|
57
57
|
if (value not in self.rundataList):
|
58
58
|
self.rundataList.append(value)
|
@@ -20,6 +20,8 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
20
20
|
Check for updates to the installed casarundata and install the update or change to
|
21
21
|
the requested version when appropriate.
|
22
22
|
|
23
|
+
If no update is necessary then this function will silently return.
|
24
|
+
|
23
25
|
The path must contain a previously installed version of casarundata.
|
24
26
|
Use pull_data to install casarundata into a new path (empty or does not exist).
|
25
27
|
|
@@ -34,13 +36,14 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
34
36
|
and nothing is updated. Release version information is only available in
|
35
37
|
monolithic CASA installations.
|
36
38
|
|
37
|
-
If a specific version is not requested (the default)
|
38
|
-
|
39
|
-
|
39
|
+
If a specific version is not requested (the default) and a check for the
|
40
|
+
versions available for installation at path has been done within the past
|
41
|
+
24 hours then this function does nothing even if there is a more
|
42
|
+
recent version available from the CASA server unless force is True.
|
40
43
|
|
41
|
-
If force is True then the requested version
|
42
|
-
is
|
43
|
-
|
44
|
+
If force is True then the requested version (or the latest version available
|
45
|
+
now) is installed even if that version is already installed or a check for the
|
46
|
+
latest version has been done within the past 24 hours.
|
44
47
|
|
45
48
|
A text file (readme.txt at path) records the version string, the date
|
46
49
|
when that version was installed in path, and the files installed into path. That file
|
@@ -92,7 +95,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
92
95
|
Parameters
|
93
96
|
- path (str=None) - Folder path to update. Must contain a valid readme.txt. If not set then config.measurespath is used.
|
94
97
|
- version (str=None) - Version of casarundata to retrieve (usually in the form of casarundata-x.y.z.tar.gz, see data_available()). Default None retrieves the latest.
|
95
|
-
- force (bool=False) - If True, always re-download the casarundata. Default False will not download casarundata if
|
98
|
+
- force (bool=False) - If True, always re-download the casarundata. Default False will not download casarundata if updated within the past day unless the version parameter is specified and different from what was last downloaded.
|
96
99
|
- logger (casatools.logsink=None) - Instance of the casalogger to use for writing messages. Default None writes messages to the terminal.
|
97
100
|
- auto_update_rules (bool=False) - If True then the user must be the owner of path, version must be None, and force must be False.
|
98
101
|
|
@@ -107,6 +110,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
107
110
|
from .data_available import data_available
|
108
111
|
from .print_log_messages import print_log_messages
|
109
112
|
from .get_data_lock import get_data_lock
|
113
|
+
from .pull_data import pull_data
|
110
114
|
from .do_pull_data import do_pull_data
|
111
115
|
from .get_data_info import get_data_info
|
112
116
|
|
@@ -119,6 +123,11 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
119
123
|
print_log_messages('path is None and has not been set in config.measurespath (probably casasiteconfig.py). Provide a valid path and retry.', logger, True)
|
120
124
|
return
|
121
125
|
|
126
|
+
# when a specific version is requested then the measures readme.txt that is part of that version
|
127
|
+
# will get a timestamp of now so that default measures updates won't happen for a day unless the
|
128
|
+
# force argument is used for measures_update
|
129
|
+
namedVersion = version is not None
|
130
|
+
|
122
131
|
path = os.path.expanduser(path)
|
123
132
|
readme_path = os.path.join(path, 'readme.txt')
|
124
133
|
|
@@ -130,12 +139,19 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
130
139
|
print_log_messages('force must be False when auto_update_rules is True', logger, True)
|
131
140
|
return
|
132
141
|
if (not os.path.isdir(path)) or (os.stat(path).st_uid != os.getuid()):
|
133
|
-
|
142
|
+
msgs = []
|
143
|
+
msgs.append("Warning: path must exist as a directory and it must be owned by the user, path = %s" % path)
|
144
|
+
msgs.append("Warning: no data updates are possible on this path by this user.")
|
145
|
+
print_log_messages(msgs, logger, False)
|
134
146
|
return
|
135
147
|
|
136
148
|
if not os.path.exists(readme_path):
|
137
|
-
|
138
|
-
|
149
|
+
# path must exist and it must be empty in order to continue
|
150
|
+
if not os.path.exists(path) or (len(os.listdir(path)) > 0):
|
151
|
+
print_log_messages('No readme.txt file found at path. Nothing updated or checked.', logger, True);
|
152
|
+
return
|
153
|
+
# ok to install a fresh copy, use pull_data directly
|
154
|
+
return pull_data(path,version,force,logger)
|
139
155
|
|
140
156
|
# path must be writable with execute bit set
|
141
157
|
if (not os.access(path, os.W_OK | os.X_OK)) :
|
@@ -147,42 +163,53 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
147
163
|
installed_files = []
|
148
164
|
currentVersion = []
|
149
165
|
currentDate = []
|
166
|
+
ageRecent = False
|
150
167
|
|
151
168
|
dataReadmeInfo = get_data_info(path, logger, type='casarundata')
|
152
169
|
|
153
170
|
if dataReadmeInfo is None or dataReadmeInfo['version'] == 'invalid':
|
154
|
-
|
155
|
-
|
171
|
+
msgs = []
|
172
|
+
msgs.append('The readme.txt file at path could not be read as expected')
|
173
|
+
msgs.append('choose a different path or empty this path and try again using pull_data')
|
174
|
+
print_log_messages(msgs, logger, True)
|
156
175
|
# no lock has been set yet, safe to simply return here
|
157
176
|
return
|
158
177
|
|
159
178
|
currentVersion = dataReadmeInfo['version']
|
160
179
|
currentDate = dataReadmeInfo['date']
|
161
180
|
installed_files = dataReadmeInfo['manifest']
|
181
|
+
if dataReadmeInfo['age'] is not None:
|
182
|
+
ageRecent = dataReadmeInfo['age'] < 1.0
|
162
183
|
|
163
184
|
if currentVersion is 'unknown':
|
164
|
-
|
165
|
-
|
166
|
-
|
185
|
+
msgs = []
|
186
|
+
msgs.append('The data update path appears to be casarundata but no readme.txt file was found')
|
187
|
+
msgs.append('A data update is not possible but CASA use of this data may be OK.')
|
188
|
+
msgs.append('casaconfig must first install the casarundata in path for data_update to run as expected on that path')
|
189
|
+
print_log_messages(msgs, logger, True)
|
167
190
|
|
168
191
|
if (len(installed_files) == 0):
|
169
192
|
# this shouldn't happen
|
170
|
-
|
171
|
-
|
193
|
+
msgs = []
|
194
|
+
msgs.append('The readme.txt file at path did not contain the expected list of installed files')
|
195
|
+
msgs.append('choose a different path or empty this path and try again using pull_data')
|
196
|
+
print_log_messages(msgs, logger, True)
|
172
197
|
# no lock has been set yet, safe to simply return here
|
173
198
|
return
|
174
199
|
|
175
|
-
|
176
|
-
|
177
|
-
#
|
178
|
-
print_log_messages('data_update
|
200
|
+
if version is None and force is False and ageRecent:
|
201
|
+
# if version is None, the readme is less than 1 day old and force is False then return without checking for any newer versions
|
202
|
+
# normal use is silent, this line is useful during debugging
|
203
|
+
# print_log_messages('data_update latest version checked recently in %s, using version %s' % (path, currentVersion), logger)
|
179
204
|
# no lock has been set yet, safe to simply return here
|
180
205
|
return
|
181
206
|
|
182
207
|
available_data = data_available()
|
183
208
|
requestedVersion = version
|
209
|
+
latestVersion = False
|
184
210
|
|
185
211
|
if requestedVersion is None:
|
212
|
+
latestVersion = True
|
186
213
|
requestedVersion = available_data[-1]
|
187
214
|
|
188
215
|
expectedMeasuresVersion = None
|
@@ -190,7 +217,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
190
217
|
# use the release version from get_data_info
|
191
218
|
releaseInfo = get_data_info()['release']
|
192
219
|
if releaseInfo is None:
|
193
|
-
print_log_messages('No release info found,
|
220
|
+
print_log_messages('No release info found, data_update can not continue', logger, True)
|
194
221
|
return
|
195
222
|
requestedVersion = releaseInfo['casarundata']
|
196
223
|
expectedMeasuresVersion = releaseInfo['measures']
|
@@ -213,12 +240,20 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
213
240
|
force = False
|
214
241
|
# if measuresReadmeInfo is None then that's a problem and force remains True, this also catches 'invalid' and 'unknown' measures versions, which should not happen here
|
215
242
|
if not force:
|
216
|
-
|
243
|
+
# normal use is silent, this line is useful during debugging
|
244
|
+
# print_log_messages('data_update requested "release" version of casarundata and measures are already installed.', logger)
|
217
245
|
# no lock has been set yet, safe to simply return here
|
218
246
|
return
|
219
247
|
else:
|
220
248
|
# normal usage, ok to return now
|
221
|
-
|
249
|
+
# normal use is silent, commented out lines are useful during debugging
|
250
|
+
if latestVersion:
|
251
|
+
# print_log_messages('The latest version is already installed in %s, using version %s' % (path, currentVersion), logger)
|
252
|
+
# touch the dates of the readme to prevent a future check on available data for the next 24 hours
|
253
|
+
os.utime(readme_path)
|
254
|
+
#else:
|
255
|
+
# print_log_messages('Requested casarundata is installed in %s, using version %s' % (path, currentVersion), logger)
|
256
|
+
|
222
257
|
# no lock has been set yet, safe to simply return here
|
223
258
|
return
|
224
259
|
|
@@ -231,10 +266,12 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
231
266
|
lock_fd = get_data_lock(path, 'data_update')
|
232
267
|
# if lock_fd is None it means the lock file was not empty - because we know that path exists at this point
|
233
268
|
if lock_fd is None:
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
269
|
+
msgs = []
|
270
|
+
msgs.append('The lock file at %s is not empty.' % path)
|
271
|
+
msgs.append('A previous attempt to update path may have failed or exited prematurely.')
|
272
|
+
msgs.append('Remove the lock file and set force to True with the desired version (default to most recent).')
|
273
|
+
msgs.append('It may be best to completely repopulate path using pull_data and measures_update.')
|
274
|
+
print_log_messages(msgs, logger, True)
|
238
275
|
return
|
239
276
|
|
240
277
|
do_update = True
|
@@ -244,6 +281,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
244
281
|
currentVersion = dataReadmeInfo['version']
|
245
282
|
currentDate = dataReadmeInfo['date']
|
246
283
|
installedFiles = dataReadmeInfo['manifest']
|
284
|
+
ageRecent = dataReadmeInfo['age'] < 1.0
|
247
285
|
if ((currentVersion == requestedVersion) and (not force)):
|
248
286
|
if expectedMeasuresVersion is not None:
|
249
287
|
# this is a 'release' update request, need to check that the measures version is also now OK
|
@@ -257,33 +295,49 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
257
295
|
print_log_messages('data update requested "release" version of casarundata and measures are already installed.', logger)
|
258
296
|
else:
|
259
297
|
# nothing to do here, already at the expected version and an update is not being forced
|
298
|
+
if latestVersion:
|
299
|
+
print_log_messages('The latest version is already installed, using version %s' % currentVersion, logger)
|
300
|
+
# touch the dates of the readme to prevent a future check on available data for the next 24 hours
|
301
|
+
os.utime(readme_path)
|
302
|
+
else:
|
303
|
+
print_log_messages('requested version is already installed.', logger)
|
260
304
|
do_update = False
|
261
|
-
print_log_messages('data_update requested version is already installed.', logger)
|
262
305
|
|
263
306
|
if do_update:
|
264
307
|
# update is still on, check the manifest
|
265
308
|
if len(installed_files) == 0:
|
266
309
|
# this shouldn't happen, do not do an update
|
267
310
|
do_update = False
|
268
|
-
|
269
|
-
|
270
|
-
|
311
|
+
msgs = []
|
312
|
+
msgs.append('The readme.txt file read at path did not contain the expected list of installed files')
|
313
|
+
msgs.append('This should not happen unless multiple sessions are trying to update data at the same time and one experienced problems or was done out of sequence')
|
314
|
+
msgs.append('Check for other updates in process or choose a different path or clear out this path and try again using pull_data or update_all')
|
315
|
+
print_log_messages(msgs, logger, True)
|
271
316
|
else:
|
272
317
|
# this shouldn't happen, do not do an update
|
273
318
|
do_update = False
|
274
|
-
|
275
|
-
|
276
|
-
|
319
|
+
msgs = []
|
320
|
+
msgs.append('Unexpected problem reading readme.txt file during data_update, can not safely update to the requested version')
|
321
|
+
msgs.append('This should not happen unless multiple sessions are trying to update at the same time and one experienced problems or was done out of sequence')
|
322
|
+
msgs.append('Check for other updates in process or choose a different path or clear out this path and try again using pull_data or update_all')
|
323
|
+
print_log_messages(msgs, logger, True)
|
277
324
|
|
278
325
|
if do_update:
|
279
326
|
do_pull_data(path, requestedVersion, installed_files, currentVersion, currentDate, logger)
|
327
|
+
if namedVersion is not None:
|
328
|
+
# a specific version has been requested, set the times on the measures readme.txt to now to avoid
|
329
|
+
# a default update of the measures data without using the force argument
|
330
|
+
measuresReadmePath = os.path.join(path,'geodetic/readme.txt')
|
331
|
+
os.utime(measuresReadmePath)
|
280
332
|
|
281
333
|
# truncate the lock file
|
282
334
|
lock_fd.truncate(0)
|
283
335
|
|
284
336
|
except Exception as exc:
|
285
|
-
|
286
|
-
|
337
|
+
msgs = []
|
338
|
+
msgs.append('ERROR! : Unexpected exception while populating casarundata version %s to %s' % (requestedVersion, path))
|
339
|
+
msgs.append('ERROR! : %s' % exc)
|
340
|
+
print_log_messages(msgs, logger, True)
|
287
341
|
# leave the contents of the lock file as is to aid in debugging
|
288
342
|
# import traceback
|
289
343
|
# traceback.print_exc()
|
@@ -45,20 +45,23 @@ def do_auto_updates(configDict, logger=None):
|
|
45
45
|
from .print_log_messages import print_log_messages
|
46
46
|
from .data_update import data_update
|
47
47
|
from .measures_update import measures_update
|
48
|
-
|
48
|
+
|
49
49
|
if configDict.measurespath is None:
|
50
50
|
# likely still unset in casasiteconfig.py, suggest setting it in ~/.casa/config.py
|
51
51
|
# or ask the site administrator (which may be the user) to edit casasiteconfig.py
|
52
52
|
# point at the documentation
|
53
53
|
# continue, because things still might work if there are measures in datapath
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
msgs = []
|
55
|
+
msgs.append('measurespath is None in config')
|
56
|
+
msgs.append('this likely means a casasiteconfig.py was used and measurespath remains unset there.')
|
57
|
+
msgs.append('Either set measurespath in your config file at ~/.casa/config.py')
|
58
|
+
msgs.append('or ask the site manager to set that in casasiteconfig.py')
|
59
|
+
msgs.append('visit https://casadocs.readthedocs.io/en/stable/notebooks/external-data.html for more information')
|
59
60
|
|
60
61
|
if (configDict.measures_auto_update or configDict.data_auto_update):
|
61
|
-
|
62
|
+
msgs.append('Auto updates of measures path are not possible because measurespath is not set, skipping auto updates')
|
63
|
+
|
64
|
+
print_log_messages(msgs, logger, True)
|
62
65
|
|
63
66
|
return
|
64
67
|
|
@@ -49,7 +49,7 @@ def do_pull_data(path, version, installed_files, currentVersion, currentDate, lo
|
|
49
49
|
|
50
50
|
readme_path = os.path.join(path, 'readme.txt')
|
51
51
|
|
52
|
-
if (len(installed_files) > 0):
|
52
|
+
if (installed_files is not None and len(installed_files) > 0):
|
53
53
|
# remove the previously installed files
|
54
54
|
# remove this readme file so it's not confusing if something goes wrong after this
|
55
55
|
os.remove(readme_path)
|
@@ -51,9 +51,9 @@ def get_data_info(path=None, logger=None, type=None):
|
|
51
51
|
expected for casarundata then the version returned for 'casarundata' is 'unknown' and
|
52
52
|
the date is an empty string. In that case the path may contain casarundata from a legacy
|
53
53
|
installation of CASA data. CASA will be able to use the files at this location but they
|
54
|
-
can not be maintained by casaconfig. If the path is not empty
|
55
|
-
contain legacy casarundata or the readme.txt
|
56
|
-
then the version is 'invalid'.
|
54
|
+
can not be maintained by casaconfig. If the path is not empty (except for a possible lock
|
55
|
+
file while it's in use but does not appear to contain legacy casarundata or the readme.txt
|
56
|
+
file found there can not be read as expected then the version is 'invalid'.
|
57
57
|
|
58
58
|
If no readme.txt file can be found for the measures at path/geodetic but both the geodetic
|
59
59
|
and ephemeris directories are present in path then the version returned for 'measures' is
|
@@ -83,10 +83,14 @@ def get_data_info(path=None, logger=None, type=None):
|
|
83
83
|
result = None
|
84
84
|
|
85
85
|
import os
|
86
|
+
import time
|
86
87
|
import importlib.resources
|
87
88
|
from .print_log_messages import print_log_messages
|
88
89
|
from .read_readme import read_readme
|
89
90
|
|
91
|
+
currentTime = time.time()
|
92
|
+
secondsPerDay = 24. * 60. * 60.
|
93
|
+
|
90
94
|
if path is None:
|
91
95
|
from .. import config as _config
|
92
96
|
path = _config.measurespath
|
@@ -106,51 +110,59 @@ def get_data_info(path=None, logger=None, type=None):
|
|
106
110
|
# casarundata and measures
|
107
111
|
|
108
112
|
if os.path.isdir(path) and (len(os.listdir(path))>0):
|
109
|
-
#
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
if ok:
|
129
|
-
# probably casarundata
|
130
|
-
result['casarundata'] = {'version':'unknown', 'date':''}
|
113
|
+
# if the only thing at path is the lock file then proceed as if path is empty - skip this section
|
114
|
+
pathfiles = os.listdir(path)
|
115
|
+
if len(pathfiles) == 1 and pathfiles[0] == "data_update.lock":
|
116
|
+
pass
|
117
|
+
else:
|
118
|
+
# there's something at path, look for the casarundata readme
|
119
|
+
if type is None or type=='casarundata':
|
120
|
+
datareadme_path = os.path.join(path,'readme.txt')
|
121
|
+
if os.path.exists(datareadme_path):
|
122
|
+
# the readme exists, get the info
|
123
|
+
result['casarundata'] = {'version':'error', 'date':'', 'manifest':[], 'age':None}
|
124
|
+
readmeContents = read_readme(datareadme_path)
|
125
|
+
if readmeContents is not None:
|
126
|
+
currentAge = (currentTime - os.path.getmtime(datareadme_path)) / secondsPerDay
|
127
|
+
currentVersion = readmeContents['version']
|
128
|
+
currentDate = readmeContents['date']
|
129
|
+
# the manifest ('extra') must exist with at least 1 entry, otherwise this is no a valid readme file and the version should be 'error'
|
130
|
+
if len(readmeContents['extra']) > 0:
|
131
|
+
result['casarundata'] = {'version':currentVersion, 'date':currentDate, 'manifest':readmeContents['extra'], 'age':currentAge}
|
131
132
|
else:
|
132
|
-
# probably
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
result['measures'] = {'version':'
|
133
|
+
# does it look like it's probably casarundata?
|
134
|
+
expected_dirs = ['alma','catalogs','demo','ephemerides','geodetic','gui','nrao']
|
135
|
+
ok = True
|
136
|
+
for d in expected_dirs:
|
137
|
+
if not os.path.isdir(os.path.join(path,d)): ok = False
|
138
|
+
if ok:
|
139
|
+
# probably casarundata
|
140
|
+
result['casarundata'] = {'version':'unknown', 'date':'', 'manifest': None,'age':None}
|
141
|
+
else:
|
142
|
+
# probably not casarundata
|
143
|
+
# this is invalid, unexpected things are happening there
|
144
|
+
result['casarundata'] = {'version':'invalid', 'date':'', 'manifest': None, 'age':None}
|
145
|
+
|
146
|
+
if type is None or type=='measures':
|
147
|
+
# look for the measures readme
|
148
|
+
measuresreadme_path = os.path.join(path,'geodetic/readme.txt')
|
149
|
+
if os.path.exists(measuresreadme_path):
|
150
|
+
# the readme exists, get the info
|
151
|
+
result['measures'] = {'version':'error', 'date':'', 'age':None}
|
152
|
+
readmeContents = read_readme(measuresreadme_path)
|
153
|
+
if readmeContents is not None:
|
154
|
+
currentVersion = readmeContents['version']
|
155
|
+
currentDate = readmeContents['date']
|
156
|
+
currentAge = (currentTime - os.path.getmtime(measuresreadme_path)) / secondsPerDay
|
157
|
+
result['measures'] = {'version':currentVersion,'date':currentDate,'age':currentAge}
|
151
158
|
else:
|
152
|
-
# probably
|
153
|
-
|
159
|
+
# does it look like it's probably measuresdata?
|
160
|
+
# path should have ephemerides and geodetic directories
|
161
|
+
if os.path.isdir(os.path.join(path,'ephemerides')) and os.path.isdir(os.path.join(path,'geodetic')):
|
162
|
+
result['measures'] = {'version':'unknown', 'date':'', 'age':None}
|
163
|
+
else:
|
164
|
+
# probably not measuresdata
|
165
|
+
result['measures'] = {'version':'invalid', 'date':'', 'age':None}
|
154
166
|
|
155
167
|
if type is None or type=='release':
|
156
168
|
# release data versions
|
@@ -15,12 +15,14 @@
|
|
15
15
|
this module will be included in the api
|
16
16
|
"""
|
17
17
|
|
18
|
-
def measures_update(path=None, version=None, force=False, logger=None, auto_update_rules=False):
|
18
|
+
def measures_update(path=None, version=None, force=False, logger=None, auto_update_rules=False, use_astron_obs_table=False):
|
19
19
|
"""
|
20
|
-
|
20
|
+
Update or install the IERS data used for measures calculations from the ASTRON server at path.
|
21
21
|
|
22
22
|
Original data source used by ASTRON is here: https://www.iers.org/IERS/EN/DataProducts/data.html
|
23
23
|
|
24
|
+
If no update is necessary then this function will silently return.
|
25
|
+
|
24
26
|
CASA maintains a separate Observatories table which is available in the casarundata
|
25
27
|
collection through pull_data and data_update. The Observatories table found at ASTRON
|
26
28
|
is not installed by measures_update and any Observatories file at path will not be changed
|
@@ -34,9 +36,13 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
34
36
|
If the version requested matches the one in that text file then this function does
|
35
37
|
nothing unless force is True.
|
36
38
|
|
37
|
-
If a specific version is not requested (the default) and the
|
38
|
-
is
|
39
|
-
recent version
|
39
|
+
If a specific version is not requested (the default) and the modification time of that text
|
40
|
+
file is less than 24 hrs before now then this function does nothing unless force is True. When this
|
41
|
+
function checks for a more recent version and finds that the installed version is the most recent
|
42
|
+
then modification time of that text file is checked to the current time even though nothing has
|
43
|
+
changed in path. This limits the number of attempts to update the measures data (including checking f\
|
44
|
+
or more recent data) to once per day. When the force argument is True and a specific version is
|
45
|
+
not requested then this function always checks for the latest version.
|
40
46
|
|
41
47
|
When auto_update_rules is True then path must exist and contain the expected readme.txt file.
|
42
48
|
Path must be owned by the user, force must be False, and the version must be None. This
|
@@ -96,7 +102,7 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
96
102
|
Parameters
|
97
103
|
- path (str=None) - Folder path to place updated measures data. Must contain a valid geodetic/readme.txt. If not set then config.measurespath is used.
|
98
104
|
- version (str=None) - Version of measures data to retrieve (usually in the form of yyyymmdd-160001.ztar, see measures_available()). Default None retrieves the latest.
|
99
|
-
- force (bool=False) - If True, always re-download the measures data. Default False will not download measures data if
|
105
|
+
- force (bool=False) - If True, always re-download the measures data. Default False will not download measures data if updated within the past day unless the version parameter is specified and different from what was last downloaded.
|
100
106
|
- logger (casatools.logsink=None) - Instance of the casalogger to use for writing messages. Default None writes messages to the terminal
|
101
107
|
- auto_update_rules (bool=False) - If True then the user must be the owner of path, version must be None, and force must be False.
|
102
108
|
|
@@ -120,6 +126,7 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
120
126
|
from .print_log_messages import print_log_messages
|
121
127
|
from .get_data_lock import get_data_lock
|
122
128
|
from .get_data_info import get_data_info
|
129
|
+
from .measures_available import measures_available
|
123
130
|
|
124
131
|
if path is None:
|
125
132
|
from .. import config as _config
|
@@ -140,7 +147,10 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
140
147
|
print_log_messages('force must be False when auto_update_rules is True', logger, True)
|
141
148
|
return
|
142
149
|
if (not os.path.isdir(path)) or (os.stat(path).st_uid != os.getuid()):
|
143
|
-
|
150
|
+
msgs = []
|
151
|
+
msgs.append("Warning: path must exist as a directory and it must be owned by the user, path = %s" % path)
|
152
|
+
msgs.append("Warning: no measures auto update is possible on this path by this user.")
|
153
|
+
print_log_messages(msgs, logger, False)
|
144
154
|
return
|
145
155
|
|
146
156
|
if not os.path.exists(path):
|
@@ -148,8 +158,7 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
148
158
|
os.makedirs(path)
|
149
159
|
|
150
160
|
current = None
|
151
|
-
|
152
|
-
today_string = datetime.today().strftime('%Y-%m-%d')
|
161
|
+
ageRecent = False
|
153
162
|
|
154
163
|
# first, does this look like it needs to be updated
|
155
164
|
|
@@ -157,17 +166,19 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
157
166
|
readmeInfo = get_data_info(path, logger, type='measures')
|
158
167
|
if readmeInfo is not None:
|
159
168
|
current = readmeInfo['version']
|
160
|
-
|
169
|
+
if readmeInfo['age'] is not None:
|
170
|
+
ageRecent = readmeInfo['age'] < 1.0
|
161
171
|
|
162
172
|
if not force:
|
163
|
-
# don't
|
164
|
-
if
|
165
|
-
|
173
|
+
# don't check for new version if the age is less than 1 day
|
174
|
+
if version is None and ageRecent:
|
175
|
+
# normal use is silent, this line is useful during debugging
|
176
|
+
# print_log_messages('measures_update latest version checked recently in %s, using version %s' % (path, current), logger)
|
166
177
|
return
|
167
178
|
|
168
179
|
# don't overwrite something that looks bad unless forced to do so
|
169
180
|
if current == 'invalid':
|
170
|
-
print_log_messages('
|
181
|
+
print_log_messages('The measures readme.txt file could not be read as expected, an update can not proceed unless force is True', logger, True)
|
171
182
|
return
|
172
183
|
|
173
184
|
# don't overwrite something that looks like valid measures data unless forced to do so
|
@@ -175,6 +186,38 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
175
186
|
print_log_messages('The measures data at %s is not maintained by casaconfig and so it can not be updated unless force is True' % path, logger, True)
|
176
187
|
return
|
177
188
|
|
189
|
+
checkVersion = version
|
190
|
+
if checkVersion is None:
|
191
|
+
# get the current most recent version
|
192
|
+
try:
|
193
|
+
checkVersion = measures_available()[-1]
|
194
|
+
except:
|
195
|
+
# unsure what happened, leave it at none, which will trigger an update attempt, which might work
|
196
|
+
pass
|
197
|
+
|
198
|
+
# don't re-download the same data
|
199
|
+
if (checkVersion is not None) and (checkVersion == current):
|
200
|
+
# normal use is silent, this line is useful during debugging
|
201
|
+
# print_log_messages('measures_update requested version already installed in %s' % path, logger)
|
202
|
+
# update the age of the readme to now
|
203
|
+
try:
|
204
|
+
readme_path = os.path.join(path,'geodetic/readme.txt')
|
205
|
+
# readme_path should already exist if it's here
|
206
|
+
os.utime(readme_path)
|
207
|
+
except:
|
208
|
+
# unsure what happened, everything otherwise is fine if we got here, ignore this error
|
209
|
+
pass
|
210
|
+
|
211
|
+
return
|
212
|
+
|
213
|
+
# don't do anything unless the Observatories table is already installed as expected
|
214
|
+
obsTabPath = os.path.join(path,'geodetic/Observatories')
|
215
|
+
if not os.path.isdir(obsTabPath):
|
216
|
+
print("Error: the Observatories table was not found as expected in %s" % path, logger, True)
|
217
|
+
print("Either install casarundata first or set use_astron_obs_table and force to be True when using measures_update.", logger, True)
|
218
|
+
print("Note that the Observatories table provided in the Astron measures tarfile is not the same as that maintained by CASA", logger, True)
|
219
|
+
return
|
220
|
+
|
178
221
|
# path must be writable with execute bit set
|
179
222
|
if (not os.access(path, os.W_OK | os.X_OK)) :
|
180
223
|
print_log_messages('No permission to write to the measures path, cannot update : %s' % path, logger, True)
|
@@ -185,15 +228,18 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
185
228
|
# lock the measures_update.lock file
|
186
229
|
lock_fd = None
|
187
230
|
try:
|
188
|
-
print_log_messages('measures_update
|
231
|
+
print_log_messages('measures_update ... acquiring the lock ... ', logger)
|
189
232
|
|
190
233
|
lock_fd = get_data_lock(path, 'measures_update')
|
191
234
|
# if lock_fd is None it means the lock file was not empty - because we know that path exists at this point
|
192
235
|
if lock_fd is None:
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
236
|
+
# using a list of messages results in a better printing if the logger is redirected to the terminal
|
237
|
+
msgs = []
|
238
|
+
msgs.append('The lock file at %s is not empty.' % path)
|
239
|
+
msgs.append('A previous attempt to update path may have failed or exited prematurely.')
|
240
|
+
msgs.append('Remove the lock file and set force to True with the desired version (default to most recent).')
|
241
|
+
msgs.append('It may be best to completely repopulate path using pull_data and measures_update.')
|
242
|
+
print_log_messages(msgs, logger, True)
|
197
243
|
return
|
198
244
|
|
199
245
|
do_update = force
|
@@ -201,31 +247,40 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
201
247
|
if not do_update:
|
202
248
|
# recheck the readme file, another update may have already happened before the lock was obtained
|
203
249
|
current = None
|
204
|
-
|
250
|
+
ageRecent = False
|
251
|
+
|
205
252
|
readmeInfo = get_data_info(path, logger, type='measures')
|
206
253
|
if readmeInfo is not None:
|
207
254
|
current = readmeInfo['version']
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
255
|
+
if readmeInfo['age'] is not None:
|
256
|
+
ageRecent = readmeInfo['age'] < 1.0
|
257
|
+
|
258
|
+
if (version is not None) and (version == current):
|
259
|
+
# no update will be done, version is as requested - not silent here because the lock is in use
|
260
|
+
print_log_messages('The requested measures version is already installed in %s, using version %s' % (path, current), logger)
|
261
|
+
elif (version is None) and ageRecent:
|
262
|
+
# no update will be done, it's already been checked or updated recently - not silent here because the lock is in use
|
263
|
+
print_log_messages('The latest measures version was checked recently in %s, using version %s' % (path, current), logger)
|
213
264
|
else:
|
265
|
+
# final check for problems before updating
|
214
266
|
if not force and readmeInfo is not None and (version=='invalid' or version=='unknown'):
|
215
267
|
# at this point, this indicates something is unexpectedly wrong, do not continue
|
216
|
-
|
217
|
-
|
218
|
-
|
268
|
+
# using a list of messages results in a better printing if the logger is redirected to the terminal
|
269
|
+
msgs = []
|
270
|
+
msgs.append('Something unexpected has changed in the measures path location, and measures_update can not continue')
|
271
|
+
msgs.append('A previous measures_update may have exited unexpectedly')
|
272
|
+
msgs.append('It may be necessary to reinstall the casarundata as well as the measures data if %s is the correct path' % path)
|
273
|
+
print_log_messages(msgs, logger, True)
|
219
274
|
# update is already turned off, the lock file will be cleaned up on exit
|
220
|
-
|
221
|
-
|
222
|
-
|
275
|
+
else:
|
276
|
+
# an update is needed
|
277
|
+
do_update = True
|
223
278
|
|
224
279
|
if do_update:
|
225
280
|
if force:
|
226
|
-
print_log_messages('
|
281
|
+
print_log_messages('A measures update has been requested by the force argument', logger)
|
227
282
|
|
228
|
-
print_log_messages('
|
283
|
+
print_log_messages(' ... connecting to ftp.astron.nl ...', logger)
|
229
284
|
|
230
285
|
ftp = FTP('ftp.astron.nl')
|
231
286
|
rc = ftp.login()
|
@@ -233,43 +288,55 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
233
288
|
files = sorted([ff for ff in ftp.nlst() if (len(ff) > 0) and (not ff.endswith('.dat')) and (ftp.size(ff) > 0)])
|
234
289
|
|
235
290
|
# target filename to download
|
291
|
+
# for the non-force unspecified version case this can only get here if the age is > 1 day so there should be a newer version
|
292
|
+
# but that isn't checked - this could install a version that's already installed
|
236
293
|
target = files[-1] if version is None else version
|
237
294
|
if target not in files:
|
238
295
|
print_log_messages('measures_update cant find specified version %s' % target, logger, True)
|
239
296
|
|
240
297
|
else:
|
241
|
-
# there are files to extract,
|
242
|
-
|
243
|
-
if os.path.exists(
|
244
|
-
os.remove(
|
298
|
+
# there are files to extract, make sure there's no past measures.ztar from a failed previous install
|
299
|
+
ztarPath = os.path.join(path,'measures.ztar')
|
300
|
+
if os.path.exists(ztarPath):
|
301
|
+
os.remove(ztarPath)
|
245
302
|
|
246
|
-
with open(
|
247
|
-
print_log_messages('
|
303
|
+
with open(ztarPath, 'wb') as fid:
|
304
|
+
print_log_messages(' ... downloading %s from ASTRON server to %s ...' % (target, path), logger)
|
248
305
|
ftp.retrbinary('RETR ' + target, fid.write)
|
249
306
|
|
250
307
|
ftp.close()
|
251
|
-
|
308
|
+
|
309
|
+
# remove any existing measures readme.txt now in case something goes wrong during extraction
|
310
|
+
readme_path = os.path.join(path,'geodetic/readme.txt')
|
311
|
+
if os.path.exists(readme_path):
|
312
|
+
os.remove(readme_path)
|
313
|
+
|
252
314
|
# extract from the fetched tarfile
|
253
|
-
with tarfile.open(
|
315
|
+
with tarfile.open(ztarPath, mode='r:gz') as ztar:
|
254
316
|
# the list of members to extract
|
255
317
|
x_list = []
|
256
318
|
for m in ztar.getmembers() :
|
257
|
-
|
258
|
-
|
259
|
-
|
319
|
+
if force and use_astron_obs_table:
|
320
|
+
# exclude the *.old names in geodetic
|
321
|
+
if not(re.search('geodetic',m.name) and re.search('.old',m.name)):
|
322
|
+
x_list.append(m)
|
323
|
+
else:
|
324
|
+
# exclude the Observatories table and *.old names in geodetic
|
325
|
+
if not((re.search('geodetic',m.name) and re.search('.old',m.name)) or re.search('Observatories',m.name)):
|
326
|
+
x_list.append(m)
|
260
327
|
|
261
328
|
# use the 'data' filter if available, revert to previous 'fully_trusted' behavior of not available
|
262
329
|
ztar.extraction_filter = getattr(tarfile, 'data_filter', (lambda member, path: member))
|
263
330
|
ztar.extractall(path=path,members=x_list)
|
264
331
|
ztar.close()
|
265
332
|
|
266
|
-
os.
|
333
|
+
os.remove(ztarPath)
|
267
334
|
|
268
|
-
#
|
335
|
+
# create a new readme.txt file
|
269
336
|
with open(readme_path,'w') as fid:
|
270
337
|
fid.write("# measures data populated by casaconfig\nversion : %s\ndate : %s" % (target, datetime.today().strftime('%Y-%m-%d')))
|
271
338
|
|
272
|
-
print_log_messages('
|
339
|
+
print_log_messages(' ... measures data update at %s' % path, logger)
|
273
340
|
|
274
341
|
# closing out the do_update
|
275
342
|
|
@@ -278,8 +345,10 @@ def measures_update(path=None, version=None, force=False, logger=None, auto_upda
|
|
278
345
|
lock_fd.truncate(0)
|
279
346
|
|
280
347
|
except Exception as exc:
|
281
|
-
|
282
|
-
|
348
|
+
msgs = []
|
349
|
+
msgs.append("ERROR! : Unexpected exception while updating measures at %s" % path)
|
350
|
+
msgs.append("ERROR! : %s" % exc)
|
351
|
+
print_log_messages(msgs, logger, True)
|
283
352
|
# leave the contents of the lock file as is to aid in debugging
|
284
353
|
|
285
354
|
# if the lock file is not closed, do that now to release the lock
|
@@ -16,6 +16,8 @@ def print_log_messages(msg, logger, is_err=False):
|
|
16
16
|
"""
|
17
17
|
Print msg and optionally write it to an instance of the casalogger.
|
18
18
|
|
19
|
+
If msg is a list then the elements are each printed first followed by logging each element.
|
20
|
+
|
19
21
|
Messages are normally printed to sys.stdout and logged as INFO to the casalogger.
|
20
22
|
|
21
23
|
When is_err is True the message is printed sys.stderr and logged as SEVERE
|
@@ -39,5 +41,12 @@ def print_log_messages(msg, logger, is_err=False):
|
|
39
41
|
fileout = sys.stderr
|
40
42
|
loglevel = 'SEVERE'
|
41
43
|
|
42
|
-
|
43
|
-
if
|
44
|
+
# this is rarely called and this should be a fast operation, it makes the code simpler
|
45
|
+
if type(msg) is not list:
|
46
|
+
msg = [msg]
|
47
|
+
|
48
|
+
for m_msg in msg:
|
49
|
+
print(m_msg,file=fileout)
|
50
|
+
|
51
|
+
for m_msg in msg:
|
52
|
+
if logger is not None: logger.post(m_msg, loglevel)
|
@@ -75,6 +75,10 @@ def pull_data(path=None, version=None, force=False, logger=None):
|
|
75
75
|
pull_data should typically be followed by a restart of CASA so that
|
76
76
|
any changes are seen by the tools and tasks that use this data.
|
77
77
|
|
78
|
+
**Note:** When version is None (the default), data_available is always used to find out
|
79
|
+
what versions are available. There is no check on when the data were last updated before
|
80
|
+
calling data_available (as there is in the two update functions).
|
81
|
+
|
78
82
|
Parameters
|
79
83
|
- path (str) - Folder path to place casarundata contents. It must be empty or not exist or contain a valid, previously installed version. If not set then config.measurespath is used.
|
80
84
|
- version (str=None) - casadata version to retrieve. Default None gets the most recent version.
|
@@ -103,6 +107,11 @@ def pull_data(path=None, version=None, force=False, logger=None):
|
|
103
107
|
print_log_messages('path is None and has not been set in config.measurespath (probably casasiteconfig.py). Provide a valid path and retry.', logger, True)
|
104
108
|
return
|
105
109
|
|
110
|
+
# when a specific version is requested then the measures readme.txt that is part of that version
|
111
|
+
# will get a timestamp of now so that default measures updates won't happen for a day unless the
|
112
|
+
# force argument is used for measures_update
|
113
|
+
namedVersion = version is not None
|
114
|
+
|
106
115
|
path = os.path.expanduser(path)
|
107
116
|
readme_path = os.path.join(path, 'readme.txt')
|
108
117
|
|
@@ -111,35 +120,40 @@ def pull_data(path=None, version=None, force=False, logger=None):
|
|
111
120
|
currentVersion = None
|
112
121
|
currentDate = None
|
113
122
|
|
114
|
-
# attempt a pull if path does not exist or is empty
|
115
|
-
|
123
|
+
# attempt a pull if path does not exist or is empty (except for any lock file, handled later)
|
124
|
+
readmeInfo = get_data_info(path, logger, type='casarundata')
|
125
|
+
do_pull = readmeInfo is None
|
116
126
|
if not do_pull:
|
117
127
|
# find the current version, install date, and installed files
|
118
|
-
readmeInfo = get_data_info(path, logger, type='casarundata')
|
119
|
-
# the only way readmeInfo is None is if path does not exist or is empty, which we already know is not the case
|
120
128
|
currentVersion = readmeInfo['version']
|
121
129
|
currentDate = readmeInfo['date']
|
122
130
|
installed_files = readmeInfo['manifest']
|
123
131
|
|
124
132
|
if currentVersion == 'invalid':
|
125
|
-
|
126
|
-
|
133
|
+
msgs = []
|
134
|
+
msgs.append('destination path is not empty and this does not appear to be casarundata OR the readme.txt file found there could not be read as expected')
|
135
|
+
msgs.append('choose a different path or empty this path and try again')
|
136
|
+
print_log_messages(msgs, logger, True)
|
127
137
|
# no lock has been set yet, safe to simply return here
|
128
138
|
return
|
129
139
|
|
130
140
|
if currentVersion == 'unknown':
|
131
|
-
|
132
|
-
|
141
|
+
msgs = []
|
142
|
+
msgs.append('destination path appears to be casarundata but no readme.txt file was found')
|
143
|
+
msgs.append('no data will be installed but CASA use of this data may be OK. Choose a different path or delete this path to install new casarundata.')
|
133
144
|
if force:
|
134
|
-
|
135
|
-
|
145
|
+
msgs.append('force is True but there is no readme.txt found and the location is not empty, no data will be installed')
|
146
|
+
msgs.append('Choose a different path or empty this path to install new casarundata')
|
147
|
+
print_log_messages(msgs, logger, True)
|
136
148
|
# no lock as been set yet, safe to simply return here
|
137
149
|
return
|
138
150
|
|
139
|
-
if (len(installed_files) == 0):
|
151
|
+
if (installed_files is None or len(installed_files) == 0):
|
140
152
|
# this shouldn't happen
|
141
|
-
|
142
|
-
|
153
|
+
msgs = []
|
154
|
+
msgs.append('destination path is not empty and the readme.txt file found there did not contain the expected list of installed files')
|
155
|
+
msgs.append('choose a different path or empty this path and try again')
|
156
|
+
print_log_messages(msgs, logger, True)
|
143
157
|
# no lock as been set yet, safe to simply return here
|
144
158
|
return
|
145
159
|
|
@@ -191,10 +205,12 @@ def pull_data(path=None, version=None, force=False, logger=None):
|
|
191
205
|
lock_fd = get_data_lock(path, 'pull_data')
|
192
206
|
# if lock_fd is None it means the lock file was not empty - because we know that path exists at this point
|
193
207
|
if lock_fd is None:
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
208
|
+
msgs = []
|
209
|
+
msgs.append('The lock file at %s is not empty.' % path)
|
210
|
+
msgs.append('A previous attempt to update path may have failed or exited prematurely.')
|
211
|
+
msgs.append('Remove the lock file and set force to True with the desired version (default to the most recent).')
|
212
|
+
msgs.append('It may be best to clean out that location and do a fresh pull_data.')
|
213
|
+
print_log_messages(msgs, logger, True)
|
198
214
|
return
|
199
215
|
|
200
216
|
do_pull = True
|
@@ -205,6 +221,9 @@ def pull_data(path=None, version=None, force=False, logger=None):
|
|
205
221
|
if readmeInfo is not None:
|
206
222
|
currentVersion = readmeInfo['version']
|
207
223
|
currentDate = readmeInfo['date']
|
224
|
+
print('readmeInfo is not None')
|
225
|
+
print('currentVersion : %s' % currentVersion)
|
226
|
+
print('currentDate : %s' % currentDate)
|
208
227
|
if ((currentVersion == version) and (not force)):
|
209
228
|
if expectedMeasuresVersion is not None:
|
210
229
|
# this is a release pull and the measures version must also match
|
@@ -224,30 +243,44 @@ def pull_data(path=None, version=None, force=False, logger=None):
|
|
224
243
|
do_pull = False
|
225
244
|
print_log_messages('pull_data requested version is already installed.', logger)
|
226
245
|
|
246
|
+
# a version of 'invalid', 'error', or 'unknown' is a surprise here, likely caused by something else doing something
|
247
|
+
# incompatible with this attempt
|
248
|
+
if version in ['invalid','error','unknown']:
|
249
|
+
do_pull = False
|
250
|
+
msgs = []
|
251
|
+
msgs.append('Unexpected version or problem found in readme.txt file during pull_data, can not safely pull the requested version')
|
252
|
+
msgs.append('This should not happen unless multiple sessions are trying to pull_data at the same time and one experienced problems or was done out of sequence')
|
253
|
+
print_log_messages(msgs, logger, True)
|
254
|
+
|
255
|
+
|
227
256
|
if do_pull:
|
228
257
|
# make sure the copy of installed_files is the correct one
|
229
258
|
installed_files = readmeInfo['manifest']
|
230
259
|
if len(installed_files) == 0:
|
231
260
|
# this shoudn't happen, do not do a pull
|
232
261
|
do_pull = False
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
print_log_messages('Unexpected error reading readme.txt file during pull_data, can not safely pull the requested version', logger, True)
|
240
|
-
print_log_messages('This should not happen unless multiple sessions are trying to pull_data at the same time and one experienced problems or was done out of sequence', logger, True)
|
241
|
-
|
262
|
+
msgs = []
|
263
|
+
msgs.append('destination path is not empty and the readme.txt file found there did not contain the expected list of installed files')
|
264
|
+
msgs.append('This should not happen unless multiple sessions are trying to pull_data at the same time and one experienced problems or was done out of sequence')
|
265
|
+
msgs.append('Check for other updates in process or choose a different path or clear out this path and try again')
|
266
|
+
print_log_messages(msgs, logger, True)
|
267
|
+
|
242
268
|
if do_pull:
|
243
269
|
do_pull_data(path, version, installed_files, currentVersion, currentDate, logger)
|
270
|
+
if namedVersion:
|
271
|
+
# a specific version has been requested, set the times on the measures readme.txt to now to avoid
|
272
|
+
# a default update of the measures data without using the force argument
|
273
|
+
measuresReadmePath = os.path.join(path,'geodetic/readme.txt')
|
274
|
+
os.utime(measuresReadmePath)
|
244
275
|
|
245
|
-
# truncate the lock
|
276
|
+
# truncate the lock filed
|
246
277
|
lock_fd.truncate(0)
|
247
278
|
|
248
279
|
except Exception as exc:
|
249
|
-
|
250
|
-
|
280
|
+
msgs = []
|
281
|
+
msgs.append('ERROR! : Unexpected exception while populating casarundata version %s to %s' % (version, path))
|
282
|
+
msgs.append('ERROR! : %s' % exc)
|
283
|
+
print_log_messages(msgs, logger, True)
|
251
284
|
# leave the contents of the lock file as is to aid in debugging
|
252
285
|
# import traceback
|
253
286
|
# traceback.print_exc()
|
@@ -15,7 +15,7 @@
|
|
15
15
|
this module will be included in the api
|
16
16
|
"""
|
17
17
|
|
18
|
-
def update_all(path=None, logger=None):
|
18
|
+
def update_all(path=None, logger=None, force=False):
|
19
19
|
"""
|
20
20
|
Update the data contants at path to the most recently released versions
|
21
21
|
of casarundata and measures data.
|
@@ -33,6 +33,8 @@ def update_all(path=None, logger=None):
|
|
33
33
|
If path already contains the most recent versions of casarundata and
|
34
34
|
measurespath then nothing will change at path.
|
35
35
|
|
36
|
+
The force argument is passed to data_update and measures_update
|
37
|
+
|
36
38
|
This uses pull_data, data_update and measures_update. See the
|
37
39
|
documentation for those functions for additional details.
|
38
40
|
|
@@ -76,7 +78,10 @@ def update_all(path=None, logger=None):
|
|
76
78
|
# path must be a directory and it must be owned by the user
|
77
79
|
|
78
80
|
if (not os.path.isdir(path)) or (os.stat(path).st_uid != os.getuid()):
|
79
|
-
|
81
|
+
msgs = []
|
82
|
+
msgs.append("Warning: path must exist as a directory and it must be owned by the user, path = %s" % path)
|
83
|
+
msgs.append("Warning: no updates are possible on this path by this user.")
|
84
|
+
print_log_messages(msgs, logger, False)
|
80
85
|
return
|
81
86
|
|
82
87
|
# if path is empty, first use pull_data
|
@@ -106,7 +111,7 @@ def update_all(path=None, logger=None):
|
|
106
111
|
return
|
107
112
|
|
108
113
|
# the updates should work now
|
109
|
-
data_update(path, logger)
|
110
|
-
measures_update(path, logger)
|
114
|
+
data_update(path, logger, force=force)
|
115
|
+
measures_update(path, logger, force=force)
|
111
116
|
|
112
117
|
return
|
@@ -6,7 +6,7 @@ with open('README.md', "r") as fid: #encoding='utf-8'
|
|
6
6
|
|
7
7
|
setup(
|
8
8
|
name='casaconfig',
|
9
|
-
version='0.0.
|
9
|
+
version='0.0.81',
|
10
10
|
description='CASA Operational Configuration Package',
|
11
11
|
long_description=long_description,
|
12
12
|
long_description_content_type="text/markdown",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|