Commit c8311074 authored by Eva Schiffer's avatar Eva Schiffer
Browse files

revising info to make it more robust and let the io module have control of it's info display

parent 13810a45
......@@ -1753,26 +1753,84 @@ def main():
"""
def info(*args, options=None) :
"""list information about a list of files
Given a file (or list of files), print out the names of the available variables in the file(s).
"""list information about the contents of one or more files
Given a file (or several files), print out the names of the available variables in the file(s).
TODO, this is in the process of being reimplemented and may not yet provide the described functionality
The level of informational detail produced will depend on the verbosity mode you're operating in.
When using quiet or default verbosity, only a list of variables (and dimensions if applicable)
and their sizes will be output. In the verbose or debug verbosity, attributes and attribute
values will also be output. See the general help message for more details on how to change your
verbosity mode using command line arguments.
If you provide an output path that is not the current directory, information will be saved to
a glance_info.txt file in that directory.
Not all file formats provide the same information. This is related to how the file formats work,
not how Glance reads or understands them.
Examples:
glance info A.hdf
glance info B.h5 C.nc
glance info -p ./out/ D.h5
"""
# are we showing the more verbose version of the file info?
do_verbose = True if options.debug or options.verbose else False
# if we were given an output path use that to write to
toPrintTo = sys.stdout
outpath = clean_path(options.outputpath)
fileForOutput = None
if outpath != clean_path('./'):
# if needed, create the directory
setup_dir_if_needed(outpath, "output")
# open the file for writing, get rid of whatever's there
fileForOutput = open(os.path.join(outpath, "glance_info.txt"), "w")
toPrintTo = fileForOutput
# check that the files the user provided exist and are of types we can process
usable_ext_types = io.get_acceptable_file_extensions()
usable_files = set()
for file_name in args :
if os.path.exists(file_name) :
split_temp = os.path.splitext(file_name)
temp_ext = split_temp[1]
if len(temp_ext) <= 0 :
LOG.warning("Requested file has no extention declaring it's type. "
"Unable to load file without type information: " + file_name)
else : # in this case we have an extension to consider
temp_ext = temp_ext[1:] # take the starting '.' off the extention text
if temp_ext in usable_ext_types :
usable_files.add(clean_path(file_name))
else :
LOG.warning("Requested file has an extention of a type that Glance "
"can't open. Unable to load file: " + file_name)
else :
LOG.warning("Requested file does not exist and therefore cannot be loaded: " + file_name)
problems = 0
for fn in args:
for file_path in usable_files:
try :
lal = list(io.open(fn)())
lal.sort()
if options.parsable_output:
print("".join([fn + "\t" + x + "\n" for x in lal]))
file_obj = io.open(file_path)
if options.parsable_output :
var_list = list(file_obj())
var_list.sort()
print("".join([file_path + "\t" + x + "\n" for x in var_list]), file=toPrintTo, )
else:
print(fn + ': ' + ('\n ' + ' ' * len(fn)).join(lal))
display_str = file_obj.display_string()
print(display_str, file=toPrintTo, )
#print(file_path + ': ' + ('\n ' + ' ' * len(file_path)).join(var_list), file=toPrintTo, )
except KeyError :
LOG.warning('Unable to open / process file selection: ' + fn)
LOG.warning('Unable to open / process file selection: ' + file_path)
problems += 1
# if we opened a file to put our output into, close it
if fileForOutput is not None :
fileForOutput.close()
if problems > 255:
# exit code is 8-bits, limit ourselves.
problems = 255
......
......@@ -229,6 +229,7 @@ class nc (object):
_nc = None
_var_map = None
_path = None
# walk down through all groups and get variable names and objects
def _walkgroups(self, start_at, prefix=None, ):
......@@ -252,6 +253,7 @@ class nc (object):
if allowWrite :
mode = 'a' # a is for append, if I use w it creates a whole new file, deleting the old one
self._path = filename
self._nc = netCDF4.Dataset(filename, mode)
self.attributeCache = CaseInsensitiveAttributeCache(self)
self._var_map = { }
......@@ -578,6 +580,27 @@ class nc (object):
"""
return True
def display_string (self, show_attrs=False, ) :
"""
Create and return a display string that describes informational details but not
the actual data that's inside the file.
If show_attrs is true, then global and variable attributes and their values will
be included in the returned display string.
returns a string, describing the file in a user readable format.
"""
# TODO, this is a temporary implementation to be replaced with more details soon
to_return = "File path: " + self._path + "\n"
temp_vars = self()
for var_name in temp_vars :
to_return += "\t" + var_name + "\n"
return to_return
# some other aliases for different valid netcdf file extentions
nc4 = nc
cdf = nc
......@@ -590,13 +613,14 @@ class h5(object):
"""wrapper for HDF5 datasets
"""
_h5 = None
_path = None
def __init__(self, filename, allowWrite=False):
self.attributeCache = CaseInsensitiveAttributeCache(self)
mode = 'r'
if allowWrite :
mode = 'r+'
self._path = filename
mode = 'r' if not allowWrite else 'r+'
if h5py is None:
LOG.error('h5py module is not installed and is needed in order to read h5 files')
assert(h5py is not None)
......@@ -783,12 +807,33 @@ class h5(object):
# TODO, are there any bad types for these files?
return True
def display_string (self, show_attrs=False, ) :
"""
Create and return a display string that describes informational details but not
the actual data that's inside the file.
If show_attrs is true, then global and variable attributes and their values will
be included in the returned display string.
returns a string, describing the file in a user readable format.
"""
# TODO, this is a temporary implementation to be replaced with more details soon
to_return = "File path: " + self._path + "\n"
temp_vars = self()
for var_name in temp_vars :
to_return += "\t" + var_name + "\n"
return to_return
class aeri(object):
"""wrapper for AERI RNC/SUM/CXS/etc datasets
"""
_dmv = None
_vectors = { }
_scalars = { }
_path = None
@staticmethod
def _meta_mapping(fp):
......@@ -809,6 +854,7 @@ class aeri(object):
if dmvlib is None:
LOG.error('cannot open AERI files without dmv module being available')
assert (dmvlib is not None)
self._path = filename
self._dmv = dmvlib.dmv()
rc = self._dmv.openFile(filename)
if rc!=0:
......@@ -922,6 +968,26 @@ class aeri(object):
# TODO, are there any bad types for these files?
return True
def display_string (self, show_attrs=False, ) :
"""
Create and return a display string that describes informational details but not
the actual data that's inside the file.
If show_attrs is true, then global and variable attributes and their values will
be included in the returned display string.
returns a string, describing the file in a user readable format.
"""
# TODO, this is a temporary implementation to be replaced with more details soon
to_return = "File path: " + self._path + "\n"
temp_vars = self()
for var_name in temp_vars :
to_return += "\t" + var_name + "\n"
return to_return
# handle the variety of file suffixes by building aliases to aeri class
cxs = rnc = cxv = csv = spc = sum = uvs = aeri
......@@ -932,6 +998,7 @@ class tiff (object):
"""
_tiff = None
_path = None
GRAY_NAME = "grayscale value"
RED_NAME = "red"
......@@ -1006,7 +1073,9 @@ class tiff (object):
return to_return
def __init__(self, filename, allowWrite=False, useMeaningfulNames=True):
self._path = filename
if gdal is None:
LOG.error('gdal is not installed and is needed in order to read GeoTIFF files')
assert(gdal is not None)
......@@ -1137,6 +1206,26 @@ class tiff (object):
# TODO, are there any bad types for these files?
return True
def display_string (self, show_attrs=False, ) :
"""
Create and return a display string that describes informational details but not
the actual data that's inside the file.
If show_attrs is true, then global and variable attributes and their values will
be included in the returned display string.
returns a string, describing the file in a user readable format.
"""
# TODO, this is a temporary implementation to be replaced with more details soon
to_return = "File path: " + self._path + "\n"
temp_vars = self()
for var_name in temp_vars :
to_return += "\t" + var_name + "\n"
return to_return
# people also name tiff files with one f...
tif = tiff
# Nick has special tiff files with alpha...
......@@ -1276,6 +1365,21 @@ class jpss_adl(object):
# TODO, are there any bad types for these files?
return True
def display_string (self, show_attrs=False, ) :
"""
Create and return a display string that describes informational details but not
the actual data that's inside the file.
If show_attrs is true, then global and variable attributes and their values will
be included in the returned display string.
returns a string, describing the file in a user readable format.
"""
LOG.warning("Display strings have not be implemented for JPSS ADL blobs")
return "Display strings are not implemented for this DEPRECATED class."
def open(pathname, allowWrite=False):
suffix = os.path.splitext(pathname)[1][1:].lower()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment