Skip to content

Improve CowLog/BORIS/pybehavior compatibility: robust parsing, schema support, and annotation export#36

Merged
Smartappli merged 1 commit intomainfrom
codex/adapter-code-pour-compatibilite-avec-boris-et-cowlog
Apr 27, 2026
Merged

Improve CowLog/BORIS/pybehavior compatibility: robust parsing, schema support, and annotation export#36
Smartappli merged 1 commit intomainfrom
codex/adapter-code-pour-compatibilite-avec-boris-et-cowlog

Conversation

@Smartappli
Copy link
Copy Markdown
Owner

Motivation

  • Make session import/export more resilient to varied CowLog/BORIS/pybehavior payload shapes and timecode formats and preserve metadata and annotations during round-trips.
  • Accept newer/alternate schema versions and mapping-style payloads produced by different tools.
  • Improve timecode parsing to support ISO 8601 durations, SMPTE/frame timecodes (with configurable FPS), and semicolon-separated rows.

Description

  • Expanded schema handling and normalization utilities by adding _schema_matches, _is_supported_* helpers and _coerce_object_rows, and updated code paths to accept mapping or list forms for events, annotations, segments, and observations across import_session_payload, import_project_payload, and related flows.
  • Enhanced time parsing with a richer _decimal implementation to parse ISO8601 (PT...S), HH:MM:SS:FF frame timecodes (honoring frame_rate), SMPTE semicolon variants, and comma/locale decimals, and threaded frame_rate through parsing where relevant.
  • Improved CowLog and tabular parsers (parse_cowlog_results_text, parse_tabular_session_rows) to detect metadata (headers), extract annotations from metadata/rows, support semicolon-delimited rows, shlex tokenization, duration columns for state intervals, per-row/custom FPS, and better warnings.
  • Merge multiple BORIS observations into single session imports with optional annotation/comment prefixes and import of merged independent variables and media labels, appending import summaries to session.notes via _append_note_line.
  • Normalize event/annotation/segment inputs (dict vs list) consistently and ensure annotations are exported to CowLog-compatible TXT via session_export_cowlog_txt.
  • Minor utilities and behavior token mappings: expanded _resolve_event_kind_token mappings and added _coerce_name_list/_normalize helpers for more robust name-list coercion.
  • Tests: added and updated unit tests to cover new parsing behaviors, schema acceptance, merged observations, frame rates, ISO durations, SMPTE formats, metadata annotations, and CowLog export of annotations.

Testing

  • Ran unit tests under tracker/tests/ including updated and new tests in test_compatibility.py, test_helpers.py, and test_roundtrip.py, which exercise CowLog parsing, BORIS/tabular imports, project/ethogram imports, merged observations, timecode formats, and CowLog export annotations.
  • New/updated tests include checks for cowlog-results-v2, CowLog timecode variants and metadata annotations, tabular frame/timecode/duration handling, mapping-style BORIS payloads and merged observations, and roundtrip normalization; all tests passed locally.

Codex Task

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Warning

Rate limit exceeded

@Smartappli has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 32 minutes and 10 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5caa19b4-cb92-4cd2-9fc6-bb033a177566

📥 Commits

Reviewing files that changed from the base of the PR and between 59663dc and c6345e1.

📒 Files selected for processing (5)
  • tracker/compatibility.py
  • tracker/tests/test_compatibility.py
  • tracker/tests/test_helpers.py
  • tracker/tests/test_roundtrip.py
  • tracker/views.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/adapter-code-pour-compatibilite-avec-boris-et-cowlog

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Smartappli Smartappli merged commit dd3435e into main Apr 27, 2026
5 of 26 checks passed
@Smartappli Smartappli deleted the codex/adapter-code-pour-compatibilite-avec-boris-et-cowlog branch April 27, 2026 11:32
@sonarqubecloud
Copy link
Copy Markdown

@codacy-production
Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 4 duplication

Metric Results
Duplication 4

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6345e12e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tracker/views.py
Comment on lines +2188 to 2191
resolved_kind = _resolve_event_kind_token(lowered)
if resolved_kind is not None:
event_kind = resolved_kind
state_marker_used = True
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve modifier/subject tokens before event-kind aliases

This branch now classifies any token matching _resolve_event_kind_token before checking modifiers or subjects, and the new alias set includes common values like 1, 2, on, and off. In CowLog rows, those tokens can legitimately be modifier names or subject IDs, so they get consumed as event markers, silently dropping modifier/subject data and potentially changing state semantics during import.

Useful? React with 👍 / 👎.

Comment thread tracker/views.py
Comment on lines +2717 to +2718
def _schema_matches(value: str | None, pattern: str) -> bool:
return bool(value and re.fullmatch(pattern, value))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject non-string schema values safely

The new schema matcher calls re.fullmatch on any truthy schema value, which raises TypeError for non-strings (for example, malformed JSON with a numeric schema). Because session/project/ethogram import validation now routes through this helper, those payloads produce server errors instead of the expected unsupported-format validation path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly enhances the system's compatibility with CowLog and BORIS data formats by improving the parsing of complex timecodes, including HH:MM:SS:FF and ISO 8601 durations. It introduces the ability to merge multiple observations during import, handles metadata more comprehensively, and ensures that annotations are included in CowLog exports. Additionally, the internal data resolution logic was updated to support both list and dictionary-based payloads. Review feedback suggests making the timecode normalization more robust and ensuring consistent decimal separator handling for frame-based timestamps.

Comment thread tracker/views.py
Comment on lines +603 to +604
if re.fullmatch(r'\d{1,3}:\d{1,2}:\d{1,2};\d{1,3}', token):
token = token.replace(';', ':')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current regex for semicolon-separated timecodes is quite restrictive as it only matches the 4-part HH:MM:SS;FF format. It would be more robust to normalize semicolons to colons for any timecode-like string (e.g., MM:SS;FF) before splitting, provided it doesn't conflict with ISO 8601 duration markers.

Suggested change
if re.fullmatch(r'\d{1,3}:\d{1,2}:\d{1,2};\d{1,3}', token):
token = token.replace(';', ':')
if ';' in token and not token.startswith(('P', 'p')):
token = token.replace(';', ':')

Comment thread tracker/views.py
hours = Decimal(parts[0])
minutes = Decimal(parts[1])
seconds = Decimal(parts[2].replace(',', '.'))
frames = Decimal(parts[3])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with the hours, minutes, and seconds parts, the frames part should also handle locale-specific decimal separators (commas) by replacing them with dots before converting to Decimal.

Suggested change
frames = Decimal(parts[3])
frames = Decimal(parts[3].replace(',', '.'))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant