Source code for majis.misc.csv

"""CSV miscellaneous module."""

from planetary_coverage.events import Event, EventsDict, EventsList, EventWindow

from .time import fmt_datetime

CSV_TIME_REL_KEYS = {
    't_start': ['OBS_START', 'OBS_START_REL'],
    't_end': ['OBS_END', 'OBS_END_REL'],
}


[docs] def get_header( blocks: list[list | dict] | EventsList | EventsDict, ref: str | dict | None = None, ) -> list: """Get CSV header. The keys are unique and ordered with the following rules: - If `OBS_NAME` is present, it will be placed first. - `t_start` and `t_end` are required and replaced by `OBS_START` and `OBS_END` and placed after `OBS_NAME` (if present). - if `ref` time is provided `OBS_START_REL` and `OBS_END_REL` are appended after `OBS_START` and `OBS_END`. - `COMMENTS` is present, it will always put last. """ keys = dict.fromkeys(key for block in blocks for key in block) first, last = [], [] if 'OBS_NAME' in keys: keys.pop('OBS_NAME') first.append('OBS_NAME') if 't_start' in keys: keys.pop('t_start') first.append('OBS_START') else: raise KeyError('Missing `t_start` keyword.') if 't_end' in keys: keys.pop('t_end') first.append('OBS_END') else: raise KeyError('Missing `t_end` keyword.') if ref: first.append('OBS_START_REL') first.append('OBS_END_REL') if 'COMMENTS' in keys: keys.pop('COMMENTS') last.append('COMMENTS') return first + list(keys) + last
[docs] def get_value( block: dict | Event | EventWindow, key: str, ref: str | None = None, ) -> str: """Format block value. This method extract the block value for a given property and re-format the datetime if necessary. Comments values are escaped with double quotes (`"..."`). """ if key == 'OBS_START': return fmt_datetime(block['t_start']) if key in ['OBS_START', 'OBS_END']: return fmt_datetime(block['t_end']) if key == 'OBS_START_REL' and ref: return fmt_datetime(block['t_start'], ref=ref) if key == 'OBS_END_REL' and ref: return fmt_datetime(block['t_end'], ref=ref) value = str(block.get(key, '')) if key == 'COMMENTS': return f'"{value}"' return value
[docs] def fmt_csv( blocks: dict | EventsList | EventsDict, ref: str | None = None, sep: str = ';', ) -> str: """Format CSV format.""" # Get unique header keys (ordered) header = get_header(blocks, ref=ref) # Create rows values with separator rows = [ sep.join(get_value(block, key, ref=ref) for key in header) for block in blocks ] # Merge header and rows return ['#' + sep.join(header)] + rows