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.
Files changed (44) hide show
  1. casaconfig-1.4.0/PKG-INFO +92 -0
  2. {casaconfig-1.2.0 → casaconfig-1.4.0}/README.md +3 -3
  3. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/__init__.py +7 -0
  4. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/config.py +34 -21
  5. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/config_defaults.py +4 -2
  6. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/config_defaults_static.py +22 -0
  7. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/data_available.py +17 -37
  8. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/data_update.py +22 -26
  9. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/do_auto_updates.py +4 -3
  10. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/do_pull_data.py +7 -27
  11. casaconfig-1.4.0/casaconfig/private/do_untar_url.py +94 -0
  12. casaconfig-1.4.0/casaconfig/private/get_available_files.py +94 -0
  13. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_data_info.py +35 -20
  14. casaconfig-1.4.0/casaconfig/private/measures_available.py +242 -0
  15. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/measures_update.py +179 -126
  16. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/print_log_messages.py +7 -3
  17. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/pull_data.py +11 -6
  18. casaconfig-1.4.0/casaconfig/private/read_readme.py +104 -0
  19. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/set_casacore_path.py +2 -2
  20. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/summary.py +3 -0
  21. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/update_all.py +6 -5
  22. casaconfig-1.4.0/casaconfig.egg-info/PKG-INFO +92 -0
  23. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/SOURCES.txt +2 -0
  24. {casaconfig-1.2.0 → casaconfig-1.4.0}/pyproject.toml +4 -3
  25. {casaconfig-1.2.0 → casaconfig-1.4.0}/tests/test_casaconfig.py +190 -17
  26. casaconfig-1.2.0/PKG-INFO +0 -293
  27. casaconfig-1.2.0/casaconfig/private/measures_available.py +0 -66
  28. casaconfig-1.2.0/casaconfig/private/read_readme.py +0 -60
  29. casaconfig-1.2.0/casaconfig.egg-info/PKG-INFO +0 -293
  30. {casaconfig-1.2.0 → casaconfig-1.4.0}/LICENSE +0 -0
  31. {casaconfig-1.2.0 → casaconfig-1.4.0}/MANIFEST.in +0 -0
  32. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/__main__.py +0 -0
  33. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/CasaconfigErrors.py +0 -0
  34. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/__init__.py +0 -0
  35. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/casasiteconfig_example.py +0 -0
  36. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_argparser.py +0 -0
  37. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_config.py +0 -0
  38. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/get_data_lock.py +0 -0
  39. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/have_network.py +0 -0
  40. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig/private/io_redirect.py +0 -0
  41. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/dependency_links.txt +0 -0
  42. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/requires.txt +0 -0
  43. {casaconfig-1.2.0 → casaconfig-1.4.0}/casaconfig.egg-info/top_level.txt +0 -0
  44. {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
- - [latext 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/latest/notebooks/external-data.html)
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 pkgutil as __pkgutil
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
- f = __os.environ.get('CASASITECONFIG')
50
+ __f = __os.environ.get('CASASITECONFIG')
50
51
  # if set, it must be a fully qualified file (leading '/') that exists
51
- if f.find('/')==0 and __os.path.isfile(f):
52
- return [ f ]
52
+ if __f.find('/')==0 and __os.path.isfile(__f):
53
+ return [ __f ]
53
54
  else:
54
55
  global __errors_encountered
55
- __errors_encountered[f] = f'CASASITECONFIG environment variable set to a path ({f}) which does not exist or is not fully qualified.'
56
- print( f'Warning: {__errors_encountered[f]}', file=__sys.stderr )
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 f in standard_siteconfig_paths:
60
- if __os.path.isfile(f):
61
- return [ f ]
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
- exec( open(__f).read( ), __orig )
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
- ## config file is a package name
101
- __pkg = __pkgutil.get_loader(__f)
102
- if __pkg is not None:
104
+ # config file is a package name
105
+ __spec = find_spec(__f)
106
+ if __spec is not None:
103
107
  try:
104
- __orig = { k: _config_defaults._globals( )[k] for k in __defaults }
105
- exec(open(__pkg.get_filename( )).read( ),__orig)
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[__pkg.get_filename( )] = __traceback.format_exc( )
114
+ __errors_encountered[__spec.origin] = __traceback.format_exc()
108
115
  else:
109
116
  for __v in __defaults:
110
- _config_defaults._globals( )[__v] = __orig[__v]
111
- __loaded_config_files.append( __pkg.get_filename( ) )
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
- exec( open(_os.path.join(_os.path.dirname(__file__),'config_defaults_static.py')).read( ), globals( ) )
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 ssl
49
- import certifi
50
-
51
- from casaconfig import RemoteError
52
- from casaconfig import NoNetwork
53
-
54
- from .have_network import have_network
55
-
56
- if not have_network():
57
- raise NoNetwork("No network, can not find the list of available data.")
58
-
59
- class LinkParser(html.parser.HTMLParser):
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
- context = ssl.create_default_context(cafile=certifi.where())
76
- with urllib.request.urlopen('https://go.nrao.edu/casarundata/', context=context, timeout=400) as urlstream:
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 a check for the
42
- versions available for installation at path has been done within the past
43
- 24 hours then this function does nothing even if there is a more
44
- recent version available from the CASA server unless force is True.
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'] < 1.0
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 1 day old and force is False then return without checking for any newer versions
209
- if verbose > 0:
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
- if verbose > 0:
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
- if verbose > 0:
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
- if verbose > 0:
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
- # always verbose here because the lock file is in use
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
- # always verbose here because the lock file is in use
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
- # always verbose here because the lock file is in use
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, and measures_auto_update from configDict to
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
- # need to first resolve the go.nrao.edu URL to find the actual data URL
87
- dataURLroot = urllib.request.urlopen(goURL, context=context).url
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)