Skip to content

feat(import): read Italian WHOOP exports - #2712

Open
paradix86 wants to merge 1 commit into
ryanbr:mainfrom
paradix86:feat/import-italian-whoop-export
Open

paradix86 wants to merge 1 commit into
ryanbr:mainfrom
paradix86:feat/import-italian-whoop-export

Conversation

@paradix86

@paradix86 paradix86 commented Oct 6, 2026 •

Copy link
Copy Markdown

Adds Italian to the localized WHOOP export importers. The German (#3), Spanish (#76), French (#79) and pt-BR (#692) aliases were each added from a real export, and this one follows the same pattern using my own Italian export.

Problem

An Italian export localizes all four filenames (cicli_fisiologici.csv, sonno.csv, allenamenti.csv, voci_diario.csv) and every header, but neither importer recognized any of them, so an Italian export imported nothing.

Change

  • HeaderNorm.foreignAliases / CsvParser.foreignAliases: 36 Italian header aliases on both platforms.
    • FC max. and FC media already fold to the French/pt-BR keys, so they are not repeated (a duplicate key in the Swift literal would trap).
    • Durata (min) and GPS abilitato are left out because no importer reads them in any language.
  • localizedAlias: the four Italian filenames, on both platforms.
  • Journal Note: read through a "note" fallback in parseJournal on both platforms, not an alias. A global "note" alias would also rename the lift-program template's own Note column and break LiftProgramSheetImporterTests.testTheShippedTemplateHasTheHeadersTheImporterExpects.
  • Tools/linux-capture: correlate_ground_truth.py and validate_spo2_candidate.py get the Italian filenames and the subset of aliases they correlate on, so an Italian export works as ground truth there too.

Verification

  • Kotlin: all 311 com.noop.ingest tests pass, including WhoopCsvImporterTest at 14/14 with the three new Italian tests (header aliases, cycles values, journal with notes).
    • On Windows, the full testFullDebugUnitTest run fails 9 tests, all in WhoopDatabaseUpgradeTest, GlowRingFlatArcTest and StrapLogArchiveTest.
    • The same 9 fail on main (9f98f81) without this change, so they look like local Windows environment issues, not this PR.
  • Swift: not run locally because there is no Swift toolchain on my machine. swift-packages CI will cover the new WhoopExportImporterTests.
    • The Swift and Kotlin alias maps were compared by script: 180 entries each, identical, no duplicate keys.
  • Python: the Tools/linux-capture suite passes (238 tests), including under a cp1252 console. The 4 new tests fail without the tool changes and pass with them.
  • Lint: doc_comment_lint.py passes.
  • Fixtures: test headers are copied verbatim from the real export. Data rows are synthetic, and no personal data is included.

An Italian export localizes all four filenames and every header, and neither
importer recognized them, so it imported nothing. Add the Italian header
aliases and filenames on both platforms, following the de/es/fr/pt-BR
precedent, from a real Italian export.

The journal "Note" column is read through a "note" fallback in parseJournal
rather than a global alias, which would also rename the lift-program
template's own "Note" column. The linux-capture ground-truth tools get the
Italian filenames and the aliases they correlate on.
@paradix86
paradix86 force-pushed the feat/import-italian-whoop-export branch from ec0d6b9 to 199f37b Compare October 6, 2026 07:09
@paradix86

Copy link
Copy Markdown
Author

Tested end to end on an Android 16 emulator: debug build of this branch (same tree as 199f37b), my real Italian export, Data Sources → Import WHOOP export (.zip).

  • Days: 0 → 386, of which 378 have recovery, HRV, RHR, SpO₂ and skin temp (the 378 cycles with a wake onset).
  • Sleeps: 451 sessions, matching sonno.csv.
  • Workouts: 298, matching allenamenti.csv, all with strain.
  • Journal: 1904 entries with both yes and no answers. The CSV has 1909 rows, but entries are upserted on (day, question).

DX23876 added a commit to DX23876/noop that referenced this pull request Oct 7, 2026
An Italian export localizes the four file names and every header, so
nothing imported. Adds the Italian header aliases and file names next to
the German, Spanish, French and pt-BR ones; the journal reads its "Note"
column through a fallback rather than a global alias that would rename the
lift-program template's own column. The linux-capture ground-truth tools
accept an Italian export too.

From upstream PR ryanbr#2712 by @paradix86 (Apple and shared side; the
fork has no Android target).

Analysis migration required: no
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant