Skip to content

feat: Update to v3.1.0 - Project Timestamp Preservation & macOS Folder Support#3

Merged
taruma merged 4 commits intomainfrom
development
Sep 25, 2025
Merged

feat: Update to v3.1.0 - Project Timestamp Preservation & macOS Folder Support#3
taruma merged 4 commits intomainfrom
development

Conversation

@taruma
Copy link
Copy Markdown
Owner

@taruma taruma commented Sep 25, 2025

This release updates Shotbuddy to version v3.1.0, introducing key enhancements for project management and improved macOS compatibility.

Key Changes:

  • Project Created Timestamp Preservation: Implemented functionality to preserve and backfill project creation timestamps using folder ctime (fix Created replaced with last updated #1). This ensures that the original creation date of projects is maintained, even after modifications.
  • macOS Folder Browser Support: Enhanced the folder browser to include full support for macOS environments, along with debug hooks (fix Cant open browser dialog in MAC #2). This improves usability for macOS users when selecting or creating project directories.

This minor release focuses on stability and user experience improvements, particularly for project metadata integrity and cross-platform functionality.

)

- Added macOS-specific AppleScript fallback for native folder selection
- Introduced debug/test parameters for simulating behaviors across OS
- Improved error handling, logging, and user-friendly warning messages
- Updated frontend to display warnings instead of errors for better UX
…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.
@taruma taruma merged commit 43c57ae into main Sep 25, 2025
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @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

  • Project Timestamp Preservation: Projects now preserve their creation timestamps, using the folder's creation time (ctime) as a fallback if the timestamp is missing, and persisting this value.
  • macOS Folder Browser Support: Enhanced the folder browsing functionality to include native support for macOS environments using AppleScript, alongside new debug hooks for testing.
  • Improved Installation & Updates: The README.md now provides comprehensive installation instructions for both uv and venv/pip, along with clear steps for updating Shotbuddy.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

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 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.

Comment on lines +176 to +184
# 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
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

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
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 os and subprocess modules are imported inside the browse_folder function (lines 220, 257, 275). According to PEP 8, imports should be at the top of the file. This improves readability and avoids repeated import overhead.

Please move these imports to the top of app/routes/project_routes.py.

Comment on lines +225 to 249
# 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'
}
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

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.

Comment thread app/static/js/main.js
Comment on lines +189 to +204
// 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);
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

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.

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.

Cant open browser dialog in MAC Created replaced with last updated

1 participant