Source code for util
"""
DEPG Utility Library
Various helper functions:
* `addr()` : Convert a coord like B37 to formulas module style
* `dict_to_list()`: Flatten a dict to a list
* `get_cache()` : Read JSON cache for quick loading
* `get_config()` : Read JSON config
"""
import json
import os
[docs]def addr(coord, sheet_name=None):
"""
Given a coordinate, convert to formulas style.
Parameters
----------
coord: str
Coordinate like ``B37``
sheet_name: str, optional
Like `PROFILE_GENERATOR`, only needed if cache was not generated yet
Returns
-------
str
A value like ``[PROFILE_GENERATOR.XLSX]PROFILE_GENERATOR!B37``
"""
spreadsheet_file = get_config()["spreadsheet_file"]
if not sheet_name:
sheet_name = get_cache()["properties"]["sheet_name"]
return "'[{}]{}'!{}".\
format(spreadsheet_file.upper(), sheet_name.upper(), coord.upper())
[docs]def dict_to_list(d):
"""
Flatten a dictionary to a one-dimensional list.
Parameters
----------
d: dict
Any one-dimensional dict, e.g. ``{k1: v1, k2: v2}``
Returns
-------
list
A flattened list, e.g. ``[k1, v1, k2, v2]``
"""
for k,v in d.items():
yield k
yield v
[docs]def get_cache(xl=None, wb=None):
"""
Cache parts of the spreadsheet, including dropdown widgets.
The formulas spreadsheet takes a long time to load, so cache enough details to render the initial page.
If xl and wb are supplied, create or refresh cache.
Parameters
----------
xl: formulas.ExcelModel, optional
The object created with the profile generator spreadsheet
wb: openpyxl.workbook.workbook.Workbook, optional
The internal workbook object, pulled from the xl object
Returns
-------
cache_data: dict
Data used to render index template
"""
cache_data = {}
cache_data_file = get_config()["cache_json"]
if xl and wb:
ws = wb.active
sol = xl.calculate()
sheet_name = wb.sheetnames[0]
cache_data["properties"] = {
"sheet_name": sheet_name,
"created": str(wb.properties.created),
"creator": wb.properties.creator,
"last_modified_by": wb.properties.last_modified_by,
"modified": str(wb.properties.modified),
}
# Pull out drop-down values using openpyxl
cache_data["dropdown_data"] = {}
for validation in ws.data_validations.dataValidation:
ranges = validation.sqref.ranges
list_cells = ws[validation.formula1]
data_cell_coord = str(ranges[0])
label_cell_coord = ws[data_cell_coord].offset(row=0, column=-1).coordinate
category = sol[addr(label_cell_coord, sheet_name)].value[0,0]
cache_data["dropdown_data"][data_cell_coord] = {
"category": category,
"values": [cell.value for cell_row in list_cells for cell in cell_row]
}
with open(cache_data_file, 'w', encoding='utf-8') as f:
json.dump(cache_data, f, ensure_ascii=False, indent=4)
else:
with open(cache_data_file) as f:
cache_data = json.load(f)
# Selected item will default to index 0
for cat_data in cache_data["dropdown_data"].values():
cat_data["selected_idx"] = 0
return cache_data
[docs]def get_config():
"""
Load config dict from config.json
Returns
-------
config_d: dict
Data used to config this app and render profiles
"""
config_file = "config.json"
if os.path.isfile(config_file):
with open(config_file) as f:
config_d = json.load(f)
if not config_d:
raise RuntimeError("Could not load config!")
return config_d