Improve BORIS/CowLog interoperability: richer parsing, timecode/frame-rate handling, and export metadata#41
Conversation
|
Warning Rate limit exceeded
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 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 configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 0/1 reviews remaining, refill in 39 minutes and 35 seconds.Comment |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
| Duplication | -1 |
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.
There was a problem hiding this comment.
Code Review
This pull request significantly enhances compatibility with BORIS and CowLog formats, introducing support for newer schemas and robust parsing of timecodes, frame rates, and metadata. Key features include merging multiple observations during import, automatic delimiter detection, and expanded CowLog export capabilities. The changes are accompanied by a detailed implementation plan and extensive test coverage. Feedback focuses on preserving formatting in session notes, refining metadata annotation parsing to avoid redundancy, and preventing title truncation during observation merges.
| candidate = (line or '').strip() | ||
| if not candidate: | ||
| return current[:max_length] | ||
| lines = [item.strip() for item in current.splitlines() if item.strip()] |
There was a problem hiding this comment.
The current implementation of _append_note_line removes all empty lines from the existing notes because of the if item.strip() filter. This may unintentionally alter the formatting of user-provided notes. Consider preserving empty lines while still checking for duplicates of the new candidate line.
| lines = [item.strip() for item in current.splitlines() if item.strip()] | |
| lines = [item.strip() for item in current.splitlines()] |
| title = ( | ||
| metadata_parts[2] | ||
| if len(metadata_parts) > 2 | ||
| else _('Imported note') | ||
| ) | ||
| note = ( | ||
| ' '.join(metadata_parts[3:]) | ||
| if len(metadata_parts) > 3 | ||
| else ( | ||
| metadata_parts[2] | ||
| if len(metadata_parts) > 2 | ||
| else _('Imported from CowLog metadata') | ||
| ) | ||
| ) | ||
| annotations.append( |
There was a problem hiding this comment.
When parsing CowLog metadata annotations with exactly three parts (e.g., # annotation 3.0 "Text"), the current logic assigns the same string to both the title and the note. This results in redundant information in the imported annotation. It would be better to use a default title and place the text in the note field when only one text token is provided.
if not annotation_time.is_nan():
title = (
metadata_parts[2]
if len(metadata_parts) > 3
else _('Imported note')
)
note = (
' '.join(metadata_parts[3:])
if len(metadata_parts) > 3
else (
metadata_parts[2]
if len(metadata_parts) > 2
else _('Imported from CowLog metadata')
)
)| observation_events.append(event_item) | ||
| observation_annotations = [] | ||
| observation_annotation_rows = _coerce_object_rows(observation.get('annotations')) |
There was a problem hiding this comment.
When merging multiple BORIS observations, the annotation title is prefixed with the observation label and truncated to 120 characters. If the observation label is very long, it may consume most of the available character limit, potentially truncating the actual annotation title entirely. Consider truncating the observation label prefix to ensure the title remains visible.
label_prefix = f'[{observation_label}]'[:40]
annotation_item['title'] = (
f'{label_prefix} {annotation_item.get("title") or "Note"}'
)[:120]
|
💡 Codex ReviewPyBehaviorLog/tracker/views.py Line 2536 in 84085a3 This condition routes any PyBehaviorLog/tracker/compatibility.py Lines 80 to 84 in 84085a3 The annotation resolver only reads top-level ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |



Motivation
Description
_decimaland_normalize_frame_rate_token, supporting ISO8601 durations,HH:MM:SS:FFframe timecodes, SMPTE semicolons, and ratio frame-rate tokens.parse_cowlog_results_text) to extract metadata and annotations, supportshlex-style header parsing, detect FPS metadata, and addstrictmode to raise on unknown behaviors.parse_tabular_session_rows,parse_tabular_session_file) to accept semicolon-delimited CSVs with comma decimals, duration columns, per-row FPS, andstrictvalidation._coerce_object_rowsand merge multiple BORIS observations while annotating imported events/annotations and storing merged independent variables; preserve/import BORIS metadata intosession.notesand variable values.SUPPORTED_SCHEMA_MATRIX,_is_supported_*) to recognize newercowlog-results-v*,boris-observation-v*, and project/session patterns.# observerand# fpsmetadata and writes session annotations as# annotationlines._append_note_line,_schema_matches, and expand_resolve_event_kind_tokenmappings for symbolic tokens.strictflags throughload_session_import_payload,parse_tabular_session_file, and parsing functions.Testing
tracker/tests/test_compatibility.py,tracker/tests/test_helpers.py, andtracker/tests/test_roundtrip.py.Codex Task