Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@roomrys
Copy link
Contributor

@roomrys roomrys commented Mar 21, 2024

Description

Very similar steps to SessionsTable (#1654) and CamerasTable (#1671) (to be filled in), except for these few items:

  • Add a dictionary {linked: ..., unlinked: ...} to LabelsDataCache that remembers which videos are linked/unlinked to a RecordingSession in labels.sessions (this dictionary will be used for the items in the UnlinkedVideosTable)
  • Add command class and CommandContext.link_video_to_camera method to link a Video to a RecordingSession
  • Add button to "Link Video" (connecting it to the CommandContext method created above)

Types of changes

  • Bugfix
  • New feature
  • Refactor / Code style update (no logical changes)
  • Build / CI changes
  • Documentation Update
  • Other (explain)

Does this address any currently open issues?

[list open issues here]

Outside contributors checklist

  • Review the guidelines for contributing to this repository
  • Read and sign the CLA and add yourself to the authors list
  • Make sure you are making a pull request against the develop branch (not main). Also you should start your branch off develop
  • Add tests that prove your fix is effective or that your feature works
  • Add necessary documentation (if appropriate)

Thank you for contributing to SLEAP!

❤️

Summary by CodeRabbit

  • New Features
    • Introduced a feature to link videos to recording sessions, enhancing the management of unlinked videos.
    • Added a "link video" button that becomes active under specific conditions, streamlining the video linking process.
  • Enhancements
    • Improved the GUI state update mechanism to check for selected unlinked videos.
    • Optimized internal caching for sessions and videos to boost application performance.
  • Refactor
    • Updated the method for linking videos to sessions, ensuring a smoother user experience.
  • Tests
    • Added tests to validate the functionality of the unlinked videos table within the application.
  • Style
    • Made minor whitespace adjustments for improved code readability, with no impact on functionality.

@coderabbitai
Copy link

coderabbitai bot commented Mar 21, 2024

Walkthrough

The recent updates focus on enhancing video linkage within the SLEAP application. Key improvements include adding checks and updates for unlinked videos, enabling a "link video" button, and updating models and tables for better management of video sessions. Additionally, a new command for linking videos to sessions has been introduced, along with minor adjustments and test enhancements to ensure smooth functionality.

Changes

Files Summary
.../gui/app.py Enhanced video linkage with checks, button enabling, and cache updates.
.../gui/widgets/docks.py Introduced unlinked videos model, table, and link button creation.
.../gui/commands.py Added linkVideoToSession method for video-session linkage.
.../gui/dataviews.py Minor whitespace adjustments.
.../io/dataset.py Added video linkage tracking and updated session-video linkage methods.
tests/gui/widgets/test_docks.py Added tests for unlinked videos' functionality in the SessionsDock.

Poem

In the digital meadow, under the code-blue sky,
A rabbit hopped, with a gleam in its eye.
"Link videos!" it cried, with joy so profound,
For unlinked videos, a solution was found.
🐰💻🎥
With each push and pull, in the code they weave,
A tapestry of links, in SLEAP, they achieve.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@roomrys roomrys changed the base branch from develop to liezl/add-gui-elements-for-sessions March 21, 2024 20:46
Copy link
Contributor Author

@roomrys roomrys left a comment

Choose a reason for hiding this comment

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

Looks pretty good, a few requests. I am sure we will find out if anything else is missing in tests.

Comment on lines 389 to 400
class UnlinkedVideosTableModel(GenericTableModel):
properties = ("path", "h", "w", "frames", "channels")

def item_to_data(self, obj, item):
res = {}
res["path"] = item.filename
res["h"] = item.height
res["w"] = item.width
res["frames"] = item.num_framesd
res["channels"] = item.channels
return res

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove - I think we should just be able to re-use the VideosTableModel since we display the exact same data.

VideosTableModel,
CamerasTableModel,
SessionsTableModel,
UnlinkedVideosTableModel,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove

):
self.sessions_model_type = SessionsTableModel
self.camera_model_type = CamerasTableModel
self.unlinked_videos_model_type = UnlinkedVideosTableModel
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change to VideosTableModel

self._track_occupancy = dict()
self._frame_count_cache = dict()
self._session_by_video: Dict[Video, RecordingSession] = dict()
self.linkage_of_videos = {"linked": [], "unlinked": []}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's stick with previous convention and add an underscore:

Suggested change
self.linkage_of_videos = {"linked": [], "unlinked": []}
self._linkage_of_videos = {"linked": [], "unlinked": []}

just so that others know not just to be using/updating this variable wherever (supposedly "private" to the containing class, even though that doesn't exist in python).

for video in session.videos:
self._session_by_video[video] = session

# Build linkage of videos by session
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We also want to handle just updating the cache in LabelsDataCache.update

@roomrys roomrys added the MultiView Stack This PR is part of the MultView stacked PRs. label Mar 21, 2024
Copy link
Contributor Author

@roomrys roomrys left a comment

Choose a reason for hiding this comment

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

The LinkVideoToSession command needs some work.

return len(filename) > 0

class LinkVideoToSession(EditCommand):
topics = [UpdateTopic.video]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A bit confusing, it seems like the update topic would be the video, but actually, we are making changes to the RecordingSession, not to the Video.

Suggested change
topics = [UpdateTopic.video]
topics = [UpdateTopic.sessions]

Comment on lines 2041 to 2042
video = context.state["video"]
session = context.state["session"]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Video and RecordingSession should come from the selected items in the UnlinkedVideosTable and SessionsTable respectively. We also need the selected camera as the last piece of our linking.

Suggested change
video = context.state["video"]
session = context.state["session"]
video = context.state["selected_unlinked_video"]
session = context.state["selected_session"]
camcorder = context.state["selected_camera"]

Comment on lines 2044 to 2048
if video is None:
raise ValueError("No video selected.")

if session is None:
raise ValueError("No session selected.")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is okay, but also, we should never get the ValueError because we are disabling the video_link_button when there is no selected RecordingSession or no selected Video. And, we also need a selected Camcorder.

sleap/gui/app.py Outdated
"generate_button"
].setEnabled(has_videos)
self._buttons["remove session"].setEnabled(has_selected_session)
self._buttons["link video"].setEnabled(has_selected_video)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We require three items to perform the LinkVideoToSession command:

  • a selected RecordingSession
  • a selected Video and a
  • selected Camcorder
    We should probably check that has_selected_video and has_selected_session and has_selected_camera.
Suggested change
self._buttons["link video"].setEnabled(has_selected_video)
self._buttons["link video"].setEnabled(has_selected_video and has_selected_session and has_selected_camera)

Comment on lines 2052 to 2063
@staticmethod
def ask(context: CommandContext, params: dict) -> bool:
"""Shows gui for adding video to project."""
if context.state["video"] is None:
QtWidgets.QMessageBox(text="No video selected.").exec_()
return False

if context.state["session"] is None:
QtWidgets.QMessageBox(text="No session selected.").exec_()
return False

return True
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove - the ask method is intended to be (although has not always been) used to ask the user for additional input through the GUI (i.e. the name of a file, "are you sure", etc.).

Suggested change
@staticmethod
def ask(context: CommandContext, params: dict) -> bool:
"""Shows gui for adding video to project."""
if context.state["video"] is None:
QtWidgets.QMessageBox(text="No video selected.").exec_()
return False
if context.state["session"] is None:
QtWidgets.QMessageBox(text="No session selected.").exec_()
return False
return True

if session is None:
raise ValueError("No session selected.")

video.recording_session = session
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm... that attribute doesn't exist. We intentionally tried to develop the multiview feature to leave existing datastructures untouched. Instead, try using

Suggested change
video.recording_session = session
session.add_video(video=video, camcorder=camcorder)

raise ValueError("No session selected.")

video.recording_session = session

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Lets also reset the selected video and camera here:

Suggested change
# Reset the selected camera and video
context.state["selected_camera"] = None
context.state["selected_unlinked_video"] = None

@roomrys roomrys changed the title Add UnlinkedVideosTable to SessionsDock (4a -> 4) Add UnlinkedVideosTable to SessionsDock Mar 22, 2024
@codecov
Copy link

codecov bot commented Mar 29, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 73.84%. Comparing base (79f7fba) to head (a2a4886).
Report is 142 commits behind head on liezl/add-gui-elements-for-sessions.

Additional details and impacted files
@@                           Coverage Diff                           @@
##           liezl/add-gui-elements-for-sessions    #1720      +/-   ##
=======================================================================
+ Coverage                                73.37%   73.84%   +0.46%     
=======================================================================
  Files                                      134      135       +1     
  Lines                                    23973    24689     +716     
=======================================================================
+ Hits                                     17591    18231     +640     
- Misses                                    6382     6458      +76     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@7174Andy 7174Andy marked this pull request as ready for review March 29, 2024 21:14
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 145a1d1 and a2a4886.
Files selected for processing (6)
  • sleap/gui/app.py (5 hunks)
  • sleap/gui/commands.py (2 hunks)
  • sleap/gui/dataviews.py (1 hunks)
  • sleap/gui/widgets/docks.py (5 hunks)
  • sleap/io/dataset.py (7 hunks)
  • tests/gui/widgets/test_docks.py (2 hunks)
Files not reviewed due to errors (2)
  • (no review received)
  • (no review received)
Files skipped from review due to trivial changes (1)
  • sleap/gui/dataviews.py
Additional Context Used
Additional comments not posted (11)
tests/gui/widgets/test_docks.py (1)

194-251: The test case test_sessions_dock_unlinked_videos_table effectively covers the functionality of the unlinked videos table within the SessionsDock. It checks the initial state, the update mechanism after unlinking videos, and the functionality of the "Link" button. However, consider adding assertions to verify the state of the linked videos in the cache after linking and unlinking operations to ensure both linked and unlinked lists are correctly updated.

sleap/gui/widgets/docks.py (5)

626-634: The creation of the "Link Video" button within create_video_link_button method is well-implemented. It's clear and follows the established pattern for adding buttons to docks. Just ensure that the linkVideoToSession command is correctly implemented and handles all necessary logic for linking videos.


644-646: The creation of unlinked_videos_model within create_models method is correctly implemented. However, it's important to ensure that the items passed to the model are indeed the unlinked videos. This might require filtering or additional logic to separate linked from unlinked videos based on the current session's state.


668-672: The creation of unlinked_videos_table is correctly implemented, following the established pattern for adding tables to docks. Ensure that the table is properly configured to display the relevant information about unlinked videos and that interactions with the table (e.g., selecting a video to link) are handled appropriately.


678-680: The connection of update_unlinked_videos_model to the selected_session state change is crucial for ensuring that the unlinked videos table is updated when the selected session changes. Verify that update_unlinked_videos_model correctly updates the model with the new set of unlinked videos corresponding to the newly selected session.


724-727: Adding the unlinked videos table and the "Link Video" button to the dock's layout is correctly done. This ensures that users have the necessary UI components to manage unlinked videos within the SessionsDock. It's important to test the UI to ensure that the table and button are displayed correctly and that the button's functionality integrates seamlessly with the rest of the application.

sleap/io/dataset.py (5)

114-114: The addition of _linkage_of_videos to track linked and unlinked videos and the corresponding logic to update this tracking seem well-integrated and align with the PR objectives. Ensure that the update_linkage_of_videos method is robust and correctly maintains the linkage status of videos across various operations in the LabelsDataCache.

Also applies to: 131-137, 172-172, 174-184, 205-206


1737-1737: The update to remove_session_video to call self._cache.update() after removing a video from a session is a good practice for maintaining cache consistency. Verify that this cache update operation is efficient and does not introduce performance issues.


1737-1737: The addition of the load_nwb class method to support loading labels from NWB files is a valuable enhancement. Ensure that the implementation of the read function for the NWB format is robust and that the load_nwb method has been thoroughly tested to confirm its correct functionality.


1737-1737: The merge_nodes method is a useful addition for managing skeletons within the Labels class. Ensure thorough testing to verify that it correctly updates instances and the skeleton, handles edge cases, and maintains data integrity.


1737-1737: The addition of make_gui_video_callback and make_video_callback methods enhances the Labels class by providing mechanisms to handle missing videos. Verify the effectiveness of the generated callback functions and their correct integration into the video loading process.

Comment on lines +584 to +588
self.unlinked_videos_model_type = VideosTableModel
super().__init__(
name="Sessions",
main_window=main_window,
model_type=[self.sessions_model_type, self.camera_model_type],
model_type=[self.sessions_model_type, self.camera_model_type, self.unlinked_videos_model_type],
Copy link

Choose a reason for hiding this comment

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

Tip

Codebase Verification

The verification process reveals that SessionsDock is instantiated in two places within the codebase, and neither instantiation includes the unlinked_videos_model_type as a parameter. This oversight could lead to runtime errors, confirming the initial review comment's concern. It is recommended to ensure that unlinked_videos_model_type is correctly passed and utilized wherever SessionsDock is instantiated.

Analysis chain

Adding unlinked_videos_model_type as an initialization parameter for SessionsDock is a good approach to maintain consistency with other docks. However, ensure that the unlinked_videos_model_type is correctly passed and utilized wherever SessionsDock is instantiated to avoid runtime errors.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that SessionsDock is correctly instantiated with unlinked_videos_model_type
rg "SessionsDock\(" --type py

Length of output: 251

@7174Andy 7174Andy marked this pull request as draft April 3, 2024 15:30
@7174Andy 7174Andy marked this pull request as ready for review April 3, 2024 15:34
@talmo talmo merged commit 936663e into liezl/add-gui-elements-for-sessions Apr 5, 2024
@talmo talmo deleted the andrew/add-unlinked-videos-table-to-sessions-dock branch April 5, 2024 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

MultiView Stack This PR is part of the MultView stacked PRs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants