more work on utils/ with glm

quietlight
Apr 30, 2026, 9:12 PM
QVIGQOQZIEXLFMMAA7RTL7MQWI4MC3CH22R6YO6J7LGLHWLCSD4AC

Dependencies

  • [2] LQLC7S3A trying gemini: Inconsistent Standards in @utils/ refactoring
  • [3] KZKLAINJ run out of space on nest, cleaned out
  • [4] P6HBSK3W me
  • [5] LBWQJEDH minor refactor and more tests for utils/

Change contents

  • replacement in utils/filename_parser.go at line 44
    [3.123767][3.123767:123839]()
    // ParseFilenameTimestamps parses timestamps from a batch of filenames.
    [3.123767]
    [3.123839]
    // ParseFilenameTimestamps extracts timestamps from a batch of filenames using variance-based format detection.
  • edit in utils/filename_parser.go at line 47
    [3.123983][3.123983:124083]()
    // ParseFilenameTimestamps extracts timestamps from filenames using variance-based format detection
  • replacement in utils/filename_parser.go at line 75
    [3.124819][3.124819:125146]()
    // ApplyTimezoneOffset applies a fixed timezone offset to timestamps
    // Uses the EARLIEST (chronologically) timestamp to determine the offset, then applies it to all
    // This matches AudioMoth behavior (no DST adjustment during deployment)
    // ApplyTimezoneOffset converts local timestamps to location timezone with DST handling
    [3.124819]
    [3.125146]
    // ApplyTimezoneOffset converts local timestamps to a location timezone with DST handling.
    // Uses the EARLIEST (chronologically) timestamp to determine the offset, then applies it to all.
    // This matches AudioMoth behavior (no DST adjustment during deployment).
  • replacement in utils/filename_parser.go at line 258
    [3.130583][3.130583:130730]()
    // HasTimestampFilename checks if a filename matches the timestamp pattern
    // HasTimestampFilename checks if filename contains a timestamp pattern
    [3.130583]
    [3.130730]
    // HasTimestampFilename checks if a filename contains a timestamp pattern
  • edit in utils/file_import.go at line 10
    [3.135143]
    [3.135143]
    // FileImportError records errors encountered during file processing
    type FileImportError struct {
    FileName string `json:"file_name"`
    Error string `json:"error"`
    Stage string `json:"stage"` // "scan", "hash", "parse", "validate", "insert"
    }
  • replacement in utils/data_file.go at line 319
    [3.165064][3.165064:165143]()
    func ParseSpeciesCallType(s string) (species, callType string) {
    if s == "" {
    [3.165064]
    [3.165143]
    func ParseSpeciesCallType(label string) (species, callType string) {
    if label == "" {
  • replacement in utils/data_file.go at line 323
    [3.165162][3.165162:165213]()
    if before, after, ok := strings.Cut(s, "+"); ok {
    [3.165162]
    [3.165213]
    if before, after, ok := strings.Cut(label, "+"); ok {
  • replacement in utils/data_file.go at line 326
    [3.165239][3.165239:165253]()
    return s, ""
    [3.165239]
    [3.165253]
    return label, ""
  • edit in utils/cluster_import.go at line 14
    [3.171639][3.171639:171890]()
    // FileImportError records errors encountered during file processing
    type FileImportError struct {
    FileName string `json:"file_name"`
    Error string `json:"error"`
    Stage string `json:"stage"` // "scan", "hash", "parse", "validate", "insert"
    }
  • replacement in utils/cluster_import.go at line 379
    [3.184637][3.184637:184698]()
    "SELECT EXISTS(SELECT 1 FROM file WHERE xxh64_hash = ?)",
    [3.184637]
    [3.184698]
    "SELECT EXISTS(SELECT 1 FROM file WHERE xxh64_hash = ? AND active = true)",
  • replacement in utils/audiomoth_parser.go at line 36
    [3.207855][3.207855:208003]()
    // IsAudioMoth checks if the comment or artist field indicates an AudioMoth recording
    // IsAudioMoth detects if WAV file is from AudioMoth recorder
    [3.207855]
    [3.208003]
    // IsAudioMoth detects if a WAV file is from an AudioMoth recorder by checking comment and artist fields
  • replacement in utils/audiomoth_parser.go at line 41
    [3.208140][3.208140:208355]()
    // ParseAudioMothComment parses structured AudioMoth comment field
    // Returns parsed data or error if parsing fails
    // ParseAudioMothComment extracts timestamp, gain, battery, and temperature from AudioMoth comment
    [3.208140]
    [3.208355]
    // ParseAudioMothComment extracts timestamp, gain, battery, and temperature from an AudioMoth comment.
  • replacement in utils/audiomoth_parser.go at line 101
    [3.210046][3.210046:210124]()
    // parseLegacyComment parses older AudioMoth comment format (space-separated)
    [3.210046]
    [3.210124]
    // parseLegacyComment parses older AudioMoth comment format (space-separated).
  • replacement in utils/audio_player.go at line 84
    [3.216198][3.216198:216298]()
    // Close stops playback and releases the oto context.
    func (ap *AudioPlayer) Close() {
    ap.Stop()
    }
    [3.216198]
    // Close stops playback. The oto context is released by the garbage collector
    // (oto v3 does not expose a context close method).
  • edit in me.txt at line 561
    [3.772785][2.6036:6916]()
    Here is a brief report based on a comprehensive review of the utils directory.
    ### 1. Duplicated Functionality
    - Audio Processing (Float64 to 16-bit PCM): wav_writer.go and audio_player.go contain identical,
    duplicated logic for converting float64 arrays into int16 LittleEndian bytes (including the [-1.0,
    1.0] bounds clamping and * 32767 scaling).
    - Timestamp Resolution Strategy: cluster_import.go (batchProcessFiles) manually reimplements the
    entire fallback chain for timestamp resolution (AudioMoth → Filename → File Modification Time). This
    exact logic is already neatly abstracted in file_import.go as ResolveTimestamp().
    - Directory Scanning: cluster_import.go implements its own scanClusterFiles to find .wav files, while
    data_file.go implements FindDataFiles to find .data files. These could be consolidated into a
    generic, reusable directory walker.
  • edit in me.txt at line 562
    [2.6917][2.6917:6939]()
    ### 2. Untested Code
  • edit in me.txt at line 563
    [2.6940][2.6940:7741](),[2.7773][2.7773:7774]()
    Overall statement coverage for utils is at 46.5%. The following areas are completely untested (0%
    coverage):
    - Files with 0% coverage:
    - audio_player.go (Audio playback and context management)
    - config.go (JSON config file loading/parsing)
    - cluster_import.go (The core batch import logic and database transactions)
    - spectrogram.go (FFT operations, windowing, and image rendering)
    - wav_writer.go (WAV encoding logic)
    - Untested Critical Functions in otherwise tested files:
    - file_import.go: ProcessSingleFile, CheckDuplicateHash
    - mapping.go: ValidateMappingAgainstDB, Classify, ValidateCoversSpecies, Classes, Placeholders
    - validation.go: GetDatasetType, ValidateDatasetTypeForImport, ValidateDatasetTypeUnstructured,
    ValidateLocationBelongsToDataset