diff --git a/src/synth_mapping_helper/__init__.py b/src/synth_mapping_helper/__init__.py index 6ff2e8a..5a326f8 100644 --- a/src/synth_mapping_helper/__init__.py +++ b/src/synth_mapping_helper/__init__.py @@ -1,4 +1,4 @@ -__version__ = "1.5.4" +__version__ = "1.5.5" from . import movement from . import pattern_generation diff --git a/src/synth_mapping_helper/analysis.py b/src/synth_mapping_helper/analysis.py index e233683..367fc74 100644 --- a/src/synth_mapping_helper/analysis.py +++ b/src/synth_mapping_helper/analysis.py @@ -150,7 +150,7 @@ def all_wall_densities(diffs: dict[str, DataContainer]) -> dict[str, dict[str, P def hand_curve(notes: SINGLE_COLOR_NOTES, window_b: float) -> HAND_CURVE_TYPE: if not notes: - return np.full((1,3), np.nan) + return np.full((1,3), np.nan), np.full((1,3), np.nan), np.full((1,3), np.nan) # step 1: find average positions for each time "bin", by weighted average of notes and (interpolated) rails data_points: dict[int, "numpy array (3,)"] = {} # t//i: weight,x,y for _, nodes in sorted(notes.items()): @@ -209,7 +209,11 @@ def _append_section(): if current_curve: _append_section() # put it all together - return np.concatenate(out_curve), np.concatenate(out_vel), np.concatenate(out_acc) + return ( + np.concatenate(out_curve), + np.concatenate(out_vel) if out_vel else np.full((1,3), np.nan), + np.concatenate(out_acc) if out_acc else np.full((1,3), np.nan) + ) def hand_curves(data: DataContainer) -> dict[str, HAND_CURVE_TYPE]: return { diff --git a/src/synth_mapping_helper/gui_tabs/utils.py b/src/synth_mapping_helper/gui_tabs/utils.py index cd90409..e5dd4f1 100644 --- a/src/synth_mapping_helper/gui_tabs/utils.py +++ b/src/synth_mapping_helper/gui_tabs/utils.py @@ -30,6 +30,7 @@ logger = logging.getLogger("SMH-GUI") wiki_base = "https://github.com/adosikas/synth_mapping_helper/wiki" +start_time = datetime.datetime.now(datetime.timezone.utc) last_errors: list[tuple[str, Exception|None, Any, Any, datetime.datetime]] = [] @dataclass @@ -131,9 +132,11 @@ def render(self, content: Any) -> bytes: @app.get("/error_report", response_class=PrettyJSONResponse) def error_report(): + now = datetime.datetime.now(datetime.timezone.utc) out = { "version": __version__, - "report_time": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H-%M-%SZ"), + "report_time": now.strftime("%Y-%m-%dT%H-%M-%SZ"), + "runtime": str(datetime.timedelta(seconds=round((now-start_time).total_seconds()))), # rounded to full seconds "errors": [], } for msg, exc, context, data, time in last_errors: diff --git a/src/synth_mapping_helper/synth_format.py b/src/synth_mapping_helper/synth_format.py index 1ec411a..76fdafa 100644 --- a/src/synth_mapping_helper/synth_format.py +++ b/src/synth_mapping_helper/synth_format.py @@ -498,9 +498,9 @@ class SynthFileMeta: def get_safe_name(self, audio_data: bytes) -> str: # editor tracks spectrum data by filename, so just append sha256 of content to filename - sha256_hash = sha256(audio_data).hexdigest() - # _. or . - m = re.match(r"(.*?)(?:_[0-9a-fA-F]{64})*\.([^.]*)$", self.audio_name) + sha256_hash = sha256(audio_data).hexdigest()[:8] + # _. or . + m = re.match(r"(.*?)(?:_[0-9a-fA-F]{8,64})*\.([^.]*)$", self.audio_name) if m: name, ext = m[1], m[2] else: # should only happen if there is no dot in the filename