Source code for jii_multispeq.measurement.file

"""
Support on working with local measurement files.
"""

import json
import os
import datetime
import warnings

from tabulate import tabulate
import pandas as pd

from jii_multispeq.measurement import analyze as _analyze 

[docs] def list_files ( directory='./local/' ): """ List all local files in the provided directory :param directory: Directory :type directory: str :return: None :rtype: None """ if not os.path.exists ( directory ): raise ValueError("Selected directory does not exist.") tbl_content = [] for root, _, files in os.walk( directory ): tbl_content = [] for file in files: if file.lower().endswith('.json'): file_path = os.path.join(root, file) try: with open( file_path, 'r', encoding='utf-8') as fp: data = json.load( fp ) except json.JSONDecodeError: warnings.warn('Error: Invalid JSON (%s)' % file_path ) continue ctime = os.path.getctime(file_path) date_str = datetime.datetime.fromtimestamp(ctime).strftime('%Y-%m-%d %H:%M') name_str = 'n/a' notes_str = 'n/a' type_str = 'single' if isinstance(data, list) and len(data) > 1: type_str = "multi (%s)" % len(data) if isinstance(data, dict): if 'created_at' in data: date_str = datetime.datetime.fromisoformat(data['created_at']).strftime('%Y-%m-%d %H:%M') if 'name' in data: name_str = data['name'] if 'notes' in data: notes_str = "n/a" if data['notes'] == "" else data['notes'] tbl_content.append([ file, date_str, type_str, name_str, notes_str ]) if len(tbl_content) > 0: print( "\n├─ %s (%s)\n" % (root, len(tbl_content) ) ) table = tabulate( tbl_content, headers=['File', 'Date', 'Type', 'Name', 'Notes'] ) print( table )
[docs] def load_files ( directory=None, recursive=False, fn=None ): """ Load files from selected directories into a dictionary. :param directory: Measurements in one or multiple directories :type directory: str or list[str] :param recursive: Recursive listing of files and subdirectories :type recursive: bool :param fn: Function to analyze the provided data :type fn: function :return: Dictionary with Measurements :rtype: list[dict] :raise ValueError: if directory is not provided with a sting or list :raise ValueError: if recursive is not True or False :raise ValueError: if no valid function is provided """ if directory is None: warnings.warn("No directroy selected") return [] if not isinstance(directory, (str, list)): raise ValueError("Directory needs to be provided as a string or list") if (not fn is None) & (not hasattr( fn, '__call__')): raise Exception("No function is provided") if isinstance(directory, str): directory = [directory] files_all = [] for dir in directory: if not os.path.exists(dir): warnings.warn("Directory %s does not exist" % dir) continue # If recursive directory selection is used if recursive: for root, _, files in os.walk( dir ): for file in files: if file.lower().endswith('.json'): files_all.append( os.path.join(root, file) ) else: for file in os.listdir( dir ): filepath = os.path.join(dir, file) if os.path.isfile(filepath) and filepath.lower().endswith('.json'): files_all.append( filepath ) # Remove duplicates that may occure when recursive is used with multiple directories files_all = list(set(files_all)) # Now gather data from all files to return one list[dict] data = [] for file_path in files_all: try: with open( file_path, 'r', encoding='utf-8') as fp: data.append( json.load( fp ) ) except json.JSONDecodeError: warnings.warn('Error: Invalid JSON (%s)' % file_path ) continue ## Run function on every element if (not fn is None) & (hasattr( fn, '__call__')): data[:] = [_analyze(itm, fn) for itm in data] return data
[docs] def load_files_df ( directory=None, recursive=False, fn=None ): """ Load files from selected directories into a dataframe. :param directory: Measurements in one or multiple directories :type directory: str or list[str] :param recursive: Recursive listing of files and subdirectories :type recursive: bool :param fn: Function to analyze the provided data :type fn: function :return: Dataframe with Measurements :rtype: pandas.DataFrame """ ## Load all files and apply function if selected data = load_files ( directory, recursive, fn ) ## Now the data can be added to the dataframe df = pd.DataFrame(data) return df