casaconfig 1.2.0__tar.gz → 1.4.0__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-1.4.0/PKG-INFO +92 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/README.md +3 -3
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/__init__.py +7 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/config.py +34 -21
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/config_defaults.py +4 -2
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/config_defaults_static.py +22 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/data_available.py +17 -37
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/data_update.py +22 -26
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/do_auto_updates.py +4 -3
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/do_pull_data.py +7 -27
- casaconfig-1.4.0/casaconfig/private/do_untar_url.py +94 -0
- casaconfig-1.4.0/casaconfig/private/get_available_files.py +94 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_data_info.py +35 -20
- casaconfig-1.4.0/casaconfig/private/measures_available.py +242 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/measures_update.py +179 -126
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/print_log_messages.py +7 -3
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/pull_data.py +11 -6
- casaconfig-1.4.0/casaconfig/private/read_readme.py +104 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/set_casacore_path.py +2 -2
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/summary.py +3 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/update_all.py +6 -5
- casaconfig-1.4.0/casaconfig.egg-info/PKG-INFO +92 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/SOURCES.txt +2 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/pyproject.toml +4 -3
- {casaconfig-1.2.0 → casaconfig-1.4.0}/tests/test_casaconfig.py +190 -17
- casaconfig-1.2.0/PKG-INFO +0 -293
- casaconfig-1.2.0/casaconfig/private/measures_available.py +0 -66
- casaconfig-1.2.0/casaconfig/private/read_readme.py +0 -60
- casaconfig-1.2.0/casaconfig.egg-info/PKG-INFO +0 -293
- {casaconfig-1.2.0 → casaconfig-1.4.0}/LICENSE +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/MANIFEST.in +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/__main__.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/CasaconfigErrors.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/__init__.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/casasiteconfig_example.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_argparser.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_config.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_data_lock.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/have_network.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/io_redirect.py +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/dependency_links.txt +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/requires.txt +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/top_level.txt +0 -0
- {casaconfig-1.2.0 → casaconfig-1.4.0}/setup.cfg +0 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: casaconfig
|
3
|
+
Version: 1.4.0
|
4
|
+
Summary: CASA Operational Configuration Package
|
5
|
+
Author-email: National Radio Astronomy Observatory <casa-feedback@nrao.edu>
|
6
|
+
License-Expression: Apache-2.0
|
7
|
+
Project-URL: Homepage, https://casa.nrao.edu/
|
8
|
+
Project-URL: Documentation, https://casadocs.readthedocs.io/
|
9
|
+
Project-URL: Repository, https://github.com/casangi/casaconfig.git
|
10
|
+
Requires-Python: >=3.10
|
11
|
+
Description-Content-Type: text/markdown
|
12
|
+
License-File: LICENSE
|
13
|
+
Requires-Dist: certifi>=2023.5.7
|
14
|
+
Dynamic: license-file
|
15
|
+
|
16
|
+
# casaconfig
|
17
|
+
Runtime data necessary for CASA operation.
|
18
|
+
|
19
|
+
- [latest casaconfig API on casadocs](https://casadocs.readthedocs.io/en/latest/api/casaconfig.html)
|
20
|
+
- [stable casaconfig API on casadocs](https://casadocs.readthedocs.io/en/stable/api/casaconfig.html)
|
21
|
+
|
22
|
+
|
23
|
+
## Release Instructions
|
24
|
+
1. Create a release branch with a version name (ie v1.6.2)
|
25
|
+
2. Ensure the version number in pyproject.toml on the branch is set correctly
|
26
|
+
3. Create a tag of the release branch (ie v1.6.2-1)
|
27
|
+
4. Github Action runs automatically to publish a pip package to pypi
|
28
|
+
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
```
|
32
|
+
$: pip install casaconfig
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
See the casaconfig API documentation on casadocs (links above).
|
38
|
+
|
39
|
+
Also see the External Data section of casadocs for additional details
|
40
|
+
|
41
|
+
- [latest External Data section on casadocs](https://casadocs.readthedocs.io/en/latest/notebooks/external-data.html)
|
42
|
+
- [stable External Data section on casadocs](https://casadocs.readthedocs.io/en/stable/notebooks/external-data.html)
|
43
|
+
|
44
|
+
## Developers Instructions
|
45
|
+
1. every push to the casaconfig repository will push a new wheel to [test pypi](https://test.pypi.org/project/casaconfig/#history)
|
46
|
+
2. the version in pyproject.toml must be updated before each push so that the wheel has a unique name (e.g. "1.2.3dev2", where "dev?" could be incremented during development; see the [specification](https://packaging.python.org/en/latest/specifications/version-specifiers/#version-specifiers) for more information about valid version signifiers)
|
47
|
+
3. When testing with a casatools build, "pip install" the development casaconfig wheel before running any tests - it may be installed before casatools is installed or after since the casatools build does not depend on casasconfig (uninstall any already installed casaconfig if necessary).
|
48
|
+
4. For release, follow the above instructions.
|
49
|
+
|
50
|
+
Wheels can be built locally following the same process used by the CI actions. To install the build-system dependencies as defined in pyproject.toml and then generate a source distribution and wheel:
|
51
|
+
```
|
52
|
+
python3 -m pip install build setuptools --user
|
53
|
+
python3 -m build
|
54
|
+
```
|
55
|
+
This will create:
|
56
|
+
```
|
57
|
+
casaconfig.egg-info
|
58
|
+
├── PKG-INFO
|
59
|
+
├── SOURCES.txt
|
60
|
+
├── dependency_links.txt
|
61
|
+
├── requires.txt
|
62
|
+
└── top_level.txt
|
63
|
+
dist
|
64
|
+
├── casaconfig-[VERSION]-py3-none-any.whl
|
65
|
+
└── casaconfig-[VERSION].tar.gz
|
66
|
+
```
|
67
|
+
|
68
|
+
### Setting up CASA branches for casaconfig development
|
69
|
+
|
70
|
+
The casaconfig build process publishes test wheels to test.pypi.org
|
71
|
+
|
72
|
+
In order to test these with Casa packages, two changes are needed in the casa6 repository branch.
|
73
|
+
|
74
|
+
1) Add a line to casa6/build.conf with the appropriate wheel version. For example:
|
75
|
+
|
76
|
+
```
|
77
|
+
casaconfig==1.0.3.dev2
|
78
|
+
```
|
79
|
+
2) Add the following line with the apppropriate branch name to casa6/casatools/setup.py
|
80
|
+
|
81
|
+
```
|
82
|
+
META_DATA["install_requires"] = "casaconfig@git+https://github.com/casangi/casaconfig@CAS-14512"
|
83
|
+
```
|
84
|
+
|
85
|
+
This adds the casaconfig branch as a casatools install time dependency. It will not use the wheel, but rather build the branch in place. This is required in order to avoid adding test.pypi.org as a pip extra-index-url, which might cause other development packages to be installed inadvertently. Note that casaconfig dependency is typically defined in setup.cfg, but the syntax above does not work with setup.cfg.
|
86
|
+
|
87
|
+
|
88
|
+
### Preparing the casa6 branch for merge
|
89
|
+
|
90
|
+
1) Merge the casaconfig branch to main and create a wheel
|
91
|
+
2) Update casa6/build.conf to use that wheel
|
92
|
+
3) Comment out the extra "install_requires" line from setup.py
|
@@ -23,8 +23,8 @@ See the casaconfig API documentation on casadocs (links above).
|
|
23
23
|
|
24
24
|
Also see the External Data section of casadocs for additional details
|
25
25
|
|
26
|
-
- [
|
27
|
-
- [stable External Data section on casadocs](https://casadocs.readthedocs.io/en/
|
26
|
+
- [latest External Data section on casadocs](https://casadocs.readthedocs.io/en/latest/notebooks/external-data.html)
|
27
|
+
- [stable External Data section on casadocs](https://casadocs.readthedocs.io/en/stable/notebooks/external-data.html)
|
28
28
|
|
29
29
|
## Developers Instructions
|
30
30
|
1. every push to the casaconfig repository will push a new wheel to [test pypi](https://test.pypi.org/project/casaconfig/#history)
|
@@ -74,4 +74,4 @@ This adds the casaconfig branch as a casatools install time dependency. It will
|
|
74
74
|
|
75
75
|
1) Merge the casaconfig branch to main and create a wheel
|
76
76
|
2) Update casa6/build.conf to use that wheel
|
77
|
-
3) Comment out the extra "install_requires" line from setup.py
|
77
|
+
3) Comment out the extra "install_requires" line from setup.py
|
@@ -13,3 +13,10 @@ from .private.set_casacore_path import set_casacore_path
|
|
13
13
|
from .private.get_config import get_config
|
14
14
|
from .private.get_data_info import get_data_info
|
15
15
|
from .private.CasaconfigErrors import *
|
16
|
+
|
17
|
+
def version():
|
18
|
+
"""
|
19
|
+
return the casaconfig version string
|
20
|
+
"""
|
21
|
+
import importlib.metadata
|
22
|
+
return importlib.metadata.version(__name__)
|
@@ -30,11 +30,12 @@ Configuration state for all CASA python packages.
|
|
30
30
|
DO NOT ADD new configuration variables here. Instead, add them in
|
31
31
|
private/config_defaults_static.py.
|
32
32
|
'''
|
33
|
-
from .private import config_defaults as _config_defaults
|
34
|
-
import traceback as __traceback
|
35
|
-
import sys as __sys
|
36
33
|
import os as __os
|
37
|
-
import
|
34
|
+
import sys as __sys
|
35
|
+
import traceback as __traceback
|
36
|
+
from importlib.util import find_spec
|
37
|
+
|
38
|
+
from .private import config_defaults as _config_defaults
|
38
39
|
from .private import io_redirect as _io
|
39
40
|
from .private.get_argparser import get_argparser as __get_argparser
|
40
41
|
|
@@ -46,19 +47,19 @@ def _standard_config_path( ):
|
|
46
47
|
'/home/casa/casasiteconfig.py' ]
|
47
48
|
|
48
49
|
if 'CASASITECONFIG' in __os.environ:
|
49
|
-
|
50
|
+
__f = __os.environ.get('CASASITECONFIG')
|
50
51
|
# if set, it must be a fully qualified file (leading '/') that exists
|
51
|
-
if
|
52
|
-
return [
|
52
|
+
if __f.find('/')==0 and __os.path.isfile(__f):
|
53
|
+
return [ __f ]
|
53
54
|
else:
|
54
55
|
global __errors_encountered
|
55
|
-
__errors_encountered[
|
56
|
-
print(
|
56
|
+
__errors_encountered[__f] = f'CASASITECONFIG environment variable set to a path ({__f}) which does not exist or is not fully qualified.'
|
57
|
+
print(f'Warning: {__errors_encountered[__f]}', file=__sys.stderr )
|
57
58
|
return [ ]
|
58
59
|
|
59
|
-
for
|
60
|
-
if __os.path.isfile(
|
61
|
-
return [
|
60
|
+
for __f in standard_siteconfig_paths:
|
61
|
+
if __os.path.isfile(__f):
|
62
|
+
return [ __f ]
|
62
63
|
return [ 'casasiteconfig' ]
|
63
64
|
|
64
65
|
## list of config variables
|
@@ -89,7 +90,10 @@ with _io.all_redirected(to=__os.devnull) if _module_execution else _io.no_redire
|
|
89
90
|
## config file is a fully qualified path
|
90
91
|
try:
|
91
92
|
__orig = { k: _config_defaults._globals( )[k] for k in __defaults }
|
92
|
-
|
93
|
+
__exec_code = None
|
94
|
+
with open(__f) as __config_def_f:
|
95
|
+
__exec_code = __config_def_f.read()
|
96
|
+
exec( __exec_code, __orig )
|
93
97
|
except Exception as e:
|
94
98
|
__errors_encountered[__f] = __traceback.format_exc( )
|
95
99
|
else:
|
@@ -97,18 +101,21 @@ with _io.all_redirected(to=__os.devnull) if _module_execution else _io.no_redire
|
|
97
101
|
_config_defaults._globals( )[__v] = __orig[__v]
|
98
102
|
__loaded_config_files.append( __f )
|
99
103
|
else:
|
100
|
-
|
101
|
-
|
102
|
-
if
|
104
|
+
# config file is a package name
|
105
|
+
__spec = find_spec(__f)
|
106
|
+
if __spec is not None:
|
103
107
|
try:
|
104
|
-
__orig = {
|
105
|
-
|
108
|
+
__orig = {k: _config_defaults._globals()[k] for k in __defaults}
|
109
|
+
__exec_code = None
|
110
|
+
with open(__spec.origin) as __config_def_f:
|
111
|
+
__exec_code = __config_def_f.read()
|
112
|
+
exec(__exec_code, __orig)
|
106
113
|
except Exception as e:
|
107
|
-
__errors_encountered[
|
114
|
+
__errors_encountered[__spec.origin] = __traceback.format_exc()
|
108
115
|
else:
|
109
116
|
for __v in __defaults:
|
110
|
-
_config_defaults._globals(
|
111
|
-
__loaded_config_files.append(
|
117
|
+
_config_defaults._globals()[__v] = __orig[__v]
|
118
|
+
__loaded_config_files.append(__spec.origin)
|
112
119
|
|
113
120
|
# if datapath is empty here, set it to [measurespath]
|
114
121
|
if len(_config_defaults.datapath) == 0:
|
@@ -148,8 +155,14 @@ for __v in __defaults:
|
|
148
155
|
pass
|
149
156
|
# debugging
|
150
157
|
# print("None value seen while expanding path-like fields for config parameter %s" % __v)
|
158
|
+
|
159
|
+
# reload _config_defaults so that it contains the original, default, values
|
160
|
+
import importlib
|
161
|
+
importlib.reload(_config_defaults)
|
151
162
|
|
152
163
|
def load_success( ):
|
164
|
+
'''return the list of loaded config files'''
|
153
165
|
return __loaded_config_files
|
154
166
|
def load_failure( ):
|
167
|
+
'''return the list of errors encountered while loading config files'''
|
155
168
|
return __errors_encountered
|
@@ -33,7 +33,6 @@ config_defaults_static.py (found in the same directory as this file).
|
|
33
33
|
import os as _os
|
34
34
|
import sys as _sys
|
35
35
|
import time as _time
|
36
|
-
import pkgutil as _pkgutil
|
37
36
|
|
38
37
|
from .get_argparser import get_argparser as __get_argparser
|
39
38
|
|
@@ -46,5 +45,8 @@ __flags,__args = __parser.parse_known_args(_sys.argv)
|
|
46
45
|
def _globals( ):
|
47
46
|
return globals()
|
48
47
|
|
49
|
-
|
48
|
+
__exec_code = None
|
49
|
+
with open(_os.path.join(_os.path.dirname(__file__),'config_defaults_static.py')) as __conf_defs_static_f:
|
50
|
+
__exec_code = __conf_defs_static_f.read( )
|
51
|
+
exec( __exec_code, globals( ) )
|
50
52
|
|
@@ -4,6 +4,14 @@ datapath = [ ]
|
|
4
4
|
# location of required measures data, takes precedence over any measures data also present in datapath.
|
5
5
|
measurespath = "~/.casa/data"
|
6
6
|
|
7
|
+
# locations to check for measures tarballs, this can be a single string value or
|
8
|
+
# a list of strings, the first element in the list is the default value to use
|
9
|
+
# Each element should be a URL giving a location containing a set of measures
|
10
|
+
# tarballs having names following the form WSRT_Measures_YYYYMMDD-HHMMSS.*
|
11
|
+
# WHere YYYYMMDD is a date and HHMMSS is a time, anything can come after the
|
12
|
+
# .* but it should indicate a form of tarball, usually compressed, e.g. "ztar"
|
13
|
+
measures_site = ["https://www.astron.nl/iers/", "https://go.nrao.edu/iers/"]
|
14
|
+
|
7
15
|
# automatically update measures data if not current (measurespath must be owned by the user)
|
8
16
|
# when data_auto_update is True then measures_auto_update MUST also be True
|
9
17
|
measures_auto_update = True
|
@@ -11,6 +19,20 @@ measures_auto_update = True
|
|
11
19
|
# automatically update casarundata and measures data if not current (measurespath must be owned by the user)
|
12
20
|
data_auto_update = True
|
13
21
|
|
22
|
+
# the interval, in days, that an installed casarundata is considered to be recent
|
23
|
+
# recent casarundata installations are not updated unless the force argument is true
|
24
|
+
data_update_interval = 1
|
25
|
+
|
26
|
+
# the interval, in days, that an installed measures data is considered to be recent
|
27
|
+
# recent measures data installations are not updated unless the force argument is tru
|
28
|
+
measures_update_interval = 1
|
29
|
+
|
30
|
+
# a measures site is considered out of date if the newest tar file found there is older
|
31
|
+
# than this many days. This may cause a warning and affect which measures_site is actually use.
|
32
|
+
# the units are days and it is used as an integer. No attempt is made to account for the time
|
33
|
+
# zone difference between the local time and the time of the measures site
|
34
|
+
measures_site_interval = 2
|
35
|
+
|
14
36
|
# location of the optional user's startup.py
|
15
37
|
startupfile = '~/.casa/startup.py'
|
16
38
|
|
@@ -42,48 +42,28 @@ def data_available():
|
|
42
42
|
|
43
43
|
"""
|
44
44
|
|
45
|
-
import html.parser
|
46
|
-
import urllib.request
|
47
45
|
import urllib.error
|
48
|
-
import
|
49
|
-
import
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def reset(self):
|
61
|
-
super().reset()
|
62
|
-
self.rundataList = []
|
63
|
-
|
64
|
-
def handle_starttag(self, tag, attrs):
|
65
|
-
if tag == 'a':
|
66
|
-
for (name, value) in attrs:
|
67
|
-
# only care if this is an href and the value starts with
|
68
|
-
# casarundata and has '.tar.' somewhere later and does not end in .md5
|
69
|
-
if name == 'href' and (value.startswith('casarundata') and (value.rfind('.tar')>11) and (value[-4:] != '.md5')):
|
70
|
-
# only add it to the list if it's not already there
|
71
|
-
if (value not in self.rundataList):
|
72
|
-
self.rundataList.append(value)
|
46
|
+
from .get_available_files import get_available_files
|
47
|
+
from .CasaconfigErrors import RemoteError, NoNetwork
|
48
|
+
|
49
|
+
# the pattern matches <anything>_Measures_YYYY.MM.DD-v.<anything>tar<anything>
|
50
|
+
# where YYYY MM DD are digits that must match that length.
|
51
|
+
# v is also a digit, but it can be 1 or more digits in length
|
52
|
+
# and "tar" can appear anywhere after the "." after the "v" digit(s)
|
53
|
+
# this allows the specific compression to change over time so
|
54
|
+
# long as the tarfile module can understand that compression
|
55
|
+
# Note that "get_available_files" always exludes files that end in
|
56
|
+
# ".md5" so it's not necessary to exclude that string from this pattern.
|
57
|
+
pattern = r"^casarundata-\d{4}\.\d{2}\.\d{2}-\d+\..*tar.*"
|
73
58
|
|
74
59
|
try:
|
75
|
-
|
76
|
-
|
77
|
-
parser = LinkParser()
|
78
|
-
encoding = urlstream.headers.get_content_charset() or 'UTF-8'
|
79
|
-
for line in urlstream:
|
80
|
-
parser.feed(line.decode(encoding))
|
81
|
-
|
82
|
-
# return the sorted list, earliest versions are first, newest is last
|
83
|
-
return sorted(parser.rundataList)
|
84
|
-
|
60
|
+
return get_available_files('https://go.nrao.edu/casarundata', pattern)
|
61
|
+
|
85
62
|
except urllib.error.URLError as urlerr:
|
86
63
|
raise RemoteError("Unable to retrieve list of available casarundata versions : " + str(urlerr)) from None
|
64
|
+
|
65
|
+
except NoNetwork as exc:
|
66
|
+
raise
|
87
67
|
|
88
68
|
except Exception as exc:
|
89
69
|
msg = "Unexpected exception while getting list of available casarundata versions : " + str(exc)
|
@@ -23,6 +23,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
23
23
|
The verbose argument controls the level of information provided when this function when the data
|
24
24
|
are unchanged for expected reasons. A level of 0 prints and logs nothing. A
|
25
25
|
value of 1 logs the information and a value of 2 logs and prints the information.
|
26
|
+
Error messages are always printed and logged (when a logger is provided).
|
26
27
|
|
27
28
|
The path must contain a previously installed version of casarundata.
|
28
29
|
Use pull_data to install casarundata into a new path (empty or does not exist).
|
@@ -38,10 +39,13 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
38
39
|
and nothing is updated. Release version information is only available in
|
39
40
|
monolithic CASA installations.
|
40
41
|
|
41
|
-
If a specific version is not requested (the default) and
|
42
|
-
|
43
|
-
|
44
|
-
recent version available from the CASA server
|
42
|
+
If a specific version is not requested (the default) and it has been less
|
43
|
+
than data_update_interval (a config value) days since the last check for a
|
44
|
+
more recent version then this function does nothing even if there is a more
|
45
|
+
recent version available from the CASA server. Using force=True forces a check
|
46
|
+
for a more recent version, ignoring the days since the last check. The
|
47
|
+
data_update_interval is always used as an int type (including
|
48
|
+
any truncation of the actual value in config if not an integer).
|
45
49
|
|
46
50
|
If force is True then the requested version (or the latest version available
|
47
51
|
now) is installed even if that version is already installed or a check for the
|
@@ -127,8 +131,9 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
127
131
|
from .get_data_lock import get_data_lock
|
128
132
|
from .do_pull_data import do_pull_data
|
129
133
|
|
134
|
+
from .. import config as _config
|
135
|
+
|
130
136
|
if path is None:
|
131
|
-
from .. import config as _config
|
132
137
|
path = _config.measurespath
|
133
138
|
|
134
139
|
if path is None:
|
@@ -136,7 +141,6 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
136
141
|
return
|
137
142
|
|
138
143
|
if verbose is None:
|
139
|
-
from .. import config as _config
|
140
144
|
verbose = _config.casaconfig_verbose
|
141
145
|
|
142
146
|
# when a specific version is requested then the measures readme.txt that is part of that version
|
@@ -190,7 +194,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
190
194
|
currentDate = dataReadmeInfo['date']
|
191
195
|
installed_files = dataReadmeInfo['manifest']
|
192
196
|
if dataReadmeInfo['age'] is not None:
|
193
|
-
ageRecent = dataReadmeInfo['age'] <
|
197
|
+
ageRecent = dataReadmeInfo['age'] < int(_config.data_update_interval)
|
194
198
|
|
195
199
|
if currentVersion == 'unknown':
|
196
200
|
msgs = []
|
@@ -205,9 +209,8 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
205
209
|
raise BadReadme('data_update: the readme.txt file at path did not contain the expected list of installed files')
|
206
210
|
|
207
211
|
if version is None and force is False and ageRecent:
|
208
|
-
# if version is None, the readme is less than
|
209
|
-
|
210
|
-
print_log_messages('data_update: version installed or checked less than 1 day ago, nothing updated or checked', logger, verbose=verbose)
|
212
|
+
# if version is None, the readme is less than data_update_interval days old and force is False then return without checking for any newer versions
|
213
|
+
print_log_messages('data_update: version installed or checked less than %s day(s) ago, nothing updated or checked' % int(_config.data_update_interval), logger, verbose=verbose)
|
211
214
|
# no lock has been set yet, safe to simply return here
|
212
215
|
return
|
213
216
|
|
@@ -231,7 +234,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
231
234
|
expectedMeasuresVersion = releaseInfo['measures']
|
232
235
|
|
233
236
|
if requestedVersion not in available_data:
|
234
|
-
print_log_messages('Requested casarundata version %s was not found. See available_data for a list of available casarundata versions.' % requestedVersion)
|
237
|
+
print_log_messages('Requested casarundata version %s was not found. See available_data for a list of available casarundata versions.' % requestedVersion, logger, True)
|
235
238
|
# no lock has been set yet, safe to simply return here
|
236
239
|
return
|
237
240
|
|
@@ -248,20 +251,17 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
248
251
|
force = False
|
249
252
|
# 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
|
250
253
|
if not force:
|
251
|
-
|
252
|
-
print_log_messages('data_update: requested "release" version of casarundata and measures are already installed.', logger, verbose=verbose)
|
254
|
+
print_log_messages('data_update: requested "release" version of casarundata and measures are already installed.', logger, verbose=verbose)
|
253
255
|
# no lock has been set yet, safe to simply return here
|
254
256
|
return
|
255
257
|
else:
|
256
258
|
# normal usage, ok to return now
|
257
259
|
if latestVersion:
|
258
|
-
|
259
|
-
print_log_messages('The latest version is already installed in %s' % path, logger, verbose=verbose)
|
260
|
+
print_log_messages('The latest version is already installed in %s' % path, logger, verbose=verbose)
|
260
261
|
# touch the dates of the readme to prevent a future check on available data for the next 24 hours
|
261
262
|
os.utime(readme_path)
|
262
263
|
else:
|
263
|
-
|
264
|
-
print_log_messages('Requested casarundata version is already installed in %s, %s' % (path, currentVersion), logger, verbose=verbose)
|
264
|
+
print_log_messages('Requested casarundata version is already installed in %s, %s' % (path, currentVersion), logger, verbose=verbose)
|
265
265
|
|
266
266
|
# no lock has been set yet, safe to simply return here
|
267
267
|
return
|
@@ -271,7 +271,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
271
271
|
lock_fd = None
|
272
272
|
clean_lock = True # set to False if the contents are actively being update and the lock file should not be cleaned on exception
|
273
273
|
try:
|
274
|
-
print_log_messages('data_update using version %s, acquiring the lock ... ' % requestedVersion, logger)
|
274
|
+
print_log_messages('data_update using version %s, acquiring the lock ... ' % requestedVersion, logger, verbose=verbose)
|
275
275
|
|
276
276
|
lock_fd = get_data_lock(path, 'data_update')
|
277
277
|
# the BadLock exception that may happen here is caught below
|
@@ -283,7 +283,6 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
283
283
|
currentVersion = dataReadmeInfo['version']
|
284
284
|
currentDate = dataReadmeInfo['date']
|
285
285
|
installedFiles = dataReadmeInfo['manifest']
|
286
|
-
ageRecent = dataReadmeInfo['age'] < 1.0
|
287
286
|
if ((currentVersion == requestedVersion) and (not force)):
|
288
287
|
if expectedMeasuresVersion is not None:
|
289
288
|
# this is a 'release' update request, need to check that the measures version is also now OK
|
@@ -294,18 +293,15 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
294
293
|
do_update = False
|
295
294
|
# if measuresReadmeInfo is None there was a problem which requires a full update so do_update remains True
|
296
295
|
if not do_update:
|
297
|
-
|
298
|
-
print_log_messages('data update requested "release" version of casarundata and measures are already installed.', logger)
|
296
|
+
print_log_messages('data update requested "release" version of casarundata and measures are already installed.', logger, verbose=verbose)
|
299
297
|
else:
|
300
298
|
# nothing to do here, already at the expected version and an update is not being forced
|
301
299
|
if latestVersion:
|
302
|
-
|
303
|
-
print_log_messages('The latest version is already installed, using version %s' % currentVersion, logger)
|
300
|
+
print_log_messages('The latest version is already installed, using version %s' % currentVersion, logger, verbose=verbose)
|
304
301
|
# touch the dates of the readme to prevent a future check on available data for the next 24 hours
|
305
302
|
os.utime(readme_path)
|
306
303
|
else:
|
307
|
-
|
308
|
-
print_log_messages('requested version is already installed.', logger)
|
304
|
+
print_log_messages('requested version is already installed.', logger, verbose=verbose)
|
309
305
|
do_update = False
|
310
306
|
|
311
307
|
if do_update:
|
@@ -320,7 +316,7 @@ def data_update(path=None, version=None, force=False, logger=None, auto_update_r
|
|
320
316
|
if do_update:
|
321
317
|
# do not clean the lock file contents at this point unless do_pull_data returns normally
|
322
318
|
clean_lock = False
|
323
|
-
do_pull_data(path, requestedVersion, installed_files, currentVersion, currentDate, logger)
|
319
|
+
do_pull_data(path, requestedVersion, installed_files, currentVersion, currentDate, logger, verbose)
|
324
320
|
clean_lock = True
|
325
321
|
if namedVersion:
|
326
322
|
# a specific version has been requested, set the times on the measures readme.txt to now to avoid
|
@@ -17,8 +17,8 @@ this module will be included in the api
|
|
17
17
|
|
18
18
|
def do_auto_updates(configDict, logger=None, verbose=None):
|
19
19
|
"""
|
20
|
-
Use measurespath, data_auto_update,
|
21
|
-
do any auto updates as necessary.
|
20
|
+
Use measurespath, data_auto_update, measures_auto_update, and measures_site
|
21
|
+
from configDict to do any auto updates as necessary.
|
22
22
|
|
23
23
|
This is intended for use during casatools init but may be useful in other cases.
|
24
24
|
|
@@ -36,6 +36,7 @@ def do_auto_updates(configDict, logger=None, verbose=None):
|
|
36
36
|
The verbose argument controls the level of information provided when this function when the data
|
37
37
|
are unchanged for expected reasons. A level of 0 prints and logs nothing. A
|
38
38
|
value of 1 logs the information and a value of 2 logs and prints the information.
|
39
|
+
Error messages are always printed and logged (when a logger is provided).
|
39
40
|
|
40
41
|
See data_update and measures_update for additional details about exceptions
|
41
42
|
|
@@ -72,6 +73,6 @@ def do_auto_updates(configDict, logger=None, verbose=None):
|
|
72
73
|
if configDict.data_auto_update:
|
73
74
|
data_update(configDict.measurespath, logger=logger, auto_update_rules=True, verbose=verbose)
|
74
75
|
if configDict.data_auto_update or configDict.measures_auto_update:
|
75
|
-
measures_update(configDict.measurespath, logger=logger, auto_update_rules=True, verbose=verbose)
|
76
|
+
measures_update(configDict.measurespath, measures_site=configDict.measures_site, logger=logger, auto_update_rules=True, verbose=verbose)
|
76
77
|
|
77
78
|
return
|
@@ -12,7 +12,7 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
def do_pull_data(path, version, installed_files, currentVersion, currentDate, logger):
|
15
|
+
def do_pull_data(path, version, installed_files, currentVersion, currentDate, logger, verbose):
|
16
16
|
"""
|
17
17
|
Pull the casarundata for the given version and install it in path, removing
|
18
18
|
the installed files and updating the readme.txt file when done.
|
@@ -30,6 +30,7 @@ def do_pull_data(path, version, installed_files, currentVersion, currentDate, lo
|
|
30
30
|
- currentVersion (str) - from the readme file if it already exists, or an empty string if there is no previously installed version.
|
31
31
|
- currentDate (str) - from the readme file if it already exists, or an empty string if there is no previously installed version.
|
32
32
|
- logger (casatools.logsink) - Instance of the casalogger to use for writing messages. Messages are always written to the terminal. Set to None to skip writing messages to a logger.
|
33
|
+
- verbose (int) - Level of output, 0 is none, 1 is to logger, 2 is to logger and terminal.
|
33
34
|
|
34
35
|
Returns
|
35
36
|
None
|
@@ -37,15 +38,11 @@ def do_pull_data(path, version, installed_files, currentVersion, currentDate, lo
|
|
37
38
|
"""
|
38
39
|
|
39
40
|
import os
|
40
|
-
import sys
|
41
41
|
from datetime import datetime
|
42
|
-
import ssl
|
43
|
-
import urllib.request
|
44
|
-
import certifi
|
45
|
-
import tarfile
|
46
42
|
import shutil
|
47
43
|
|
48
44
|
from .print_log_messages import print_log_messages
|
45
|
+
from .do_untar_url import do_untar_url
|
49
46
|
|
50
47
|
readme_path = os.path.join(path, 'readme.txt')
|
51
48
|
|
@@ -53,7 +50,7 @@ def do_pull_data(path, version, installed_files, currentVersion, currentDate, lo
|
|
53
50
|
# remove the previously installed files
|
54
51
|
# remove this readme file so it's not confusing if something goes wrong after this
|
55
52
|
os.remove(readme_path)
|
56
|
-
print_log_messages('Removing files using manifest from previous install of %s on %s' % (currentVersion, currentDate), logger)
|
53
|
+
print_log_messages('Removing files using manifest from previous install of %s on %s' % (currentVersion, currentDate), logger, verbose=verbose)
|
57
54
|
for relpath in installed_files:
|
58
55
|
filepath = os.path.join(path,relpath)
|
59
56
|
# don't say anything if filepath isn't found, remove it if it is found
|
@@ -81,27 +78,10 @@ def do_pull_data(path, version, installed_files, currentVersion, currentDate, lo
|
|
81
78
|
# okay, safe to install the requested version
|
82
79
|
|
83
80
|
goURL = 'https://go.nrao.edu/casarundata'
|
84
|
-
context = ssl.create_default_context(cafile=certifi.where())
|
85
81
|
|
86
|
-
#
|
87
|
-
|
88
|
-
dataURL = os.path.join(dataURLroot, version)
|
82
|
+
# extract version from goURL to path, no custom extraction filter, verbose output, use the logger when set
|
83
|
+
do_untar_url(goURL, version, path, None, "downloading casarundata contents to ", logger)
|
89
84
|
|
90
|
-
with urllib.request.urlopen(dataURL, context=context, timeout=400) as tstream, tarfile.open(fileobj=tstream, mode='r|*') as tar :
|
91
|
-
l = int(tstream.headers.get('content-length', 0))
|
92
|
-
sizeString = "unknown size"
|
93
|
-
if (l>0): sizeString = ("%.0fM" % (l/(1024*1024)))
|
94
|
-
# use print directly to make use of the end argument
|
95
|
-
print('downloading casarundata contents to %s (%s) ... ' % (path,sizeString), file = sys.stdout, end="" )
|
96
|
-
sys.stdout.flush()
|
97
|
-
# also log it
|
98
|
-
if logger is not None: logger.post('downloading casarundata contents to %s ...' % path, 'INFO')
|
99
|
-
# use the 'data' filter if available, revert to previous 'fully_trusted' behavior of not available
|
100
|
-
tar.extraction_filter = getattr(tarfile, 'data_filter', (lambda member, path: member))
|
101
|
-
tar.extractall(path=path)
|
102
|
-
|
103
|
-
print("done", file=sys.stdout)
|
104
|
-
|
105
85
|
# the tarball has been extracted to path/version
|
106
86
|
# get the instaled files of files to be written to the readme file
|
107
87
|
versdir = os.path.join(path,version[:version.index('.tar')])
|
@@ -133,4 +113,4 @@ def do_pull_data(path, version, installed_files, currentVersion, currentDate, lo
|
|
133
113
|
for f in installed_files:
|
134
114
|
fid.write("\n%s" % f)
|
135
115
|
|
136
|
-
print_log_messages('casarundata installed %s at %s' % (version, path), logger)
|
116
|
+
print_log_messages('casarundata installed %s at %s' % (version, path), logger, verbose=verbose)
|