feat: Update to v3.1.0 - Project Timestamp Preservation & macOS Folder Support#3
feat: Update to v3.1.0 - Project Timestamp Preservation & macOS Folder Support#3
Conversation
…ime (fix #1) - In load_project_info, set 'created' from folder ctime if missing and persist it - In save_project_info, load existing info to preserve 'created', merge data without overwriting it, and use ctime as default - Ensures accurate creation dates based on filesystem metadata, preventing loss of original timestamps during updates or failures
…port This minor release, `v3.1.0`, focuses on improving project management and macOS compatibility. - **Project Created Timestamp Preservation**: Implemented functionality to preserve and backfill project creation timestamps using folder ctime (fixes #1). This ensures accurate historical data for projects. - **macOS Folder Browser Support**: Enhanced the folder browser with native macOS support and debug hooks (fixes #2), providing a better user experience on Apple systems. The `pyproject.toml` version has been updated, and the `CHANGELOG.md` and `README.md` reflect these new features and the version bump.
Refactor the installation guide to provide clearer and more comprehensive steps for users. This update introduces: - Detailed instructions for two installation methods: `uv` (recommended) and `venv` with `pip`. - Explicit guidance on using shallow clones (`--depth 1`) for smaller repository downloads. - Steps for activating and deactivating virtual environments for `venv` users. - A new "Updating Shotbuddy" section, outlining how to pull latest changes and update dependencies for both `uv` and `venv`/`pip` setups. These changes aim to enhance user experience by simplifying the setup and maintenance process.
Summary of ChangesHello @taruma, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces Shotbuddy v3.1.0, focusing on critical enhancements for project metadata integrity and cross-platform usability. It ensures that project creation timestamps are consistently preserved and backfilled using file system metadata, and significantly improves the user experience for macOS users by integrating native folder browsing capabilities. Additionally, the installation and update processes have been clarified in the documentation. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces project creation timestamp preservation and enhances macOS folder browser support. My review focuses on improving code quality and fixing a critical bug. I've identified a potential memory leak in the JavaScript event handling, a critical bug in the Python logic for preserving timestamps that could lead to data loss, and opportunities to refactor duplicated code and adhere to Python's import conventions for better maintainability. The changes to the documentation and UI are well-aligned with the feature goals.
| # Merge incoming data into existing, but preserve created | ||
| merged_info = existing_info.copy() | ||
| for key, value in info_data.items(): | ||
| merged_info[key] = value | ||
|
|
||
| # Ensure created is never overwritten | ||
| if 'created' not in merged_info: | ||
| created_default = datetime.fromtimestamp(project_path.stat().st_ctime).isoformat() | ||
| merged_info['created'] = created_default |
There was a problem hiding this comment.
The current logic for preserving the created timestamp is flawed. If the incoming info_data contains a created key, it will overwrite the original timestamp from existing_info, which defeats the purpose of this change. This could lead to data loss of the original project creation date.
The logic should be adjusted to always prioritize the created timestamp from existing_info if it's available.
# Merge incoming data into existing, preserving 'created' timestamp
merged_info = existing_info.copy()
merged_info.update(info_data)
# Always preserve the original 'created' timestamp if it exists.
if 'created' in existing_info:
merged_info['created'] = existing_info['created']
# If no 'created' timestamp exists anywhere, create one.
elif 'created' not in merged_info:
created_default = datetime.fromtimestamp(project_path.stat().st_ctime).isoformat()
merged_info['created'] = created_default| if force_path: | ||
| return jsonify({"success": True, "data": {"path": force_path}}) | ||
| if request.args.get("force_warning") == "1": | ||
| import os |
There was a problem hiding this comment.
| # Create default structure with created from folder ctime | ||
| created_default = datetime.fromtimestamp(project_path.stat().st_ctime).isoformat() | ||
| project_info = { | ||
| 'title': project_path.name, | ||
| 'description': '', | ||
| 'short_description': '', | ||
| 'notes': '', | ||
| 'tags': [], | ||
| 'created': datetime.now().isoformat(), | ||
| 'created': created_default, | ||
| 'updated': datetime.now().isoformat(), | ||
| 'version': '1.0.0' | ||
| } | ||
| else: | ||
| # Create default structure | ||
| # Create default structure with created from folder ctime | ||
| created_default = datetime.fromtimestamp(project_path.stat().st_ctime).isoformat() | ||
| project_info = { | ||
| 'title': project_path.name, | ||
| 'description': '', | ||
| 'short_description': '', | ||
| 'notes': '', | ||
| 'tags': [], | ||
| 'created': datetime.now().isoformat(), | ||
| 'created': created_default, | ||
| 'updated': datetime.now().isoformat(), | ||
| 'version': '1.0.0' | ||
| } |
There was a problem hiding this comment.
There's significant code duplication in this file for creating a default project info dictionary. This block of code is repeated here and also in load_project_info (lines 133-144) and save_project_info (lines 163-174).
To improve maintainability and reduce redundancy, consider refactoring this logic into a private helper method, like _get_default_project_info(self, project_path). This method would create and return the default dictionary, and you could call it from all the places where it's needed.
| // Add Enter key listeners for better UX | ||
| const nameInput = document.getElementById('new-project-name'); | ||
| const locationInput = document.getElementById('new-project-location'); | ||
|
|
||
| const handleEnter = (e) => { | ||
| if (e.key === 'Enter') { | ||
| e.preventDefault(); | ||
| confirmCreateProject(); | ||
| // Remove listeners after use | ||
| nameInput.removeEventListener('keydown', handleEnter); | ||
| locationInput.removeEventListener('keydown', handleEnter); | ||
| } | ||
| }; | ||
|
|
||
| nameInput.addEventListener('keydown', handleEnter); | ||
| locationInput.addEventListener('keydown', handleEnter); |
There was a problem hiding this comment.
This is a nice UX improvement to allow submitting the modal with the Enter key. However, there's a potential memory leak. The keydown event listeners are added every time openCreateProjectModal is called, but they are only removed if the user presses Enter. If the modal is closed via the 'Cancel' button or by clicking the overlay, the listeners remain active. This will cause multiple listeners to be attached if the modal is opened several times.
To fix this, you should ensure the listeners are removed when the modal is closed, for example, by adding the removal logic to closeCreateProjectModal.
This release updates Shotbuddy to version v3.1.0, introducing key enhancements for project management and improved macOS compatibility.
Key Changes:
This minor release focuses on stability and user experience improvements, particularly for project metadata integrity and cross-platform functionality.