SpinStabilized/clock

Simple, configurable, multi-timezone clock.

★ 0Forks 0PythonGitHub ↗Compare

README

Multi-Timezone Clock

An application to show the time in multiple timezones. It is built in Python using the PyQt5 GUI framework and packaged as a macOS application with py2app.

Development Environment

The project uses uv to manage Python, the virtual environment, and dependencies. Dependencies are declared in pyproject.toml and pinned in uv.lock, which should both be committed. The Python version is set in .python-version.

Install uv (for example with Homebrew):

brew install uv

Then, from the project directory, create the virtual environment and install all dependencies:

make setup-dev

This runs uv sync, which creates a .venv directory in the project and installs everything from uv.lock, including the development dependencies needed to build the app.

Run the application from source with:

make run

or, equivalently:

uv run python Clock.py

uv run always uses the project's .venv, so there is no need to activate it first. If you prefer working inside the environment, activate it with source .venv/bin/activate and leave it with deactivate.

Managing Dependencies

Add or remove dependencies with uv rather than editing pyproject.toml by hand, so the lock file stays in sync:

uv add <package>          # runtime dependency
uv add --dev <package>    # development/build dependency
uv remove <package>

To upgrade packages within the constraints in pyproject.toml, run uv lock --upgrade (or uv lock --upgrade-package <package> for just one), followed by uv sync.

Troubleshooting

If the app fails to start with an error that Qt could not find the cocoa platform plugin, the cached copy of the Qt packages may be damaged. Clear them from the uv cache and reinstall:

uv cache clean pyqt5 pyqt5-qt5 pyqt5-sip
uv sync --reinstall-package pyqt5 --reinstall-package pyqt5-qt5 --reinstall-package pyqt5-sip

Configuration

The timezones shown are read from a JSON configuration file at ~/.clock.json. If the file does not exist, it is created on first launch with these defaults:

{
    "ui_settings": {},
    "timezones": [
        ["JST", "Asia/Tokyo"],
        ["UTC", "UTC"],
        ["ET", "US/Eastern"]
    ]
}

Each timezone entry is a pair of the label displayed in the window and an IANA timezone name. Edit this file to change which timezones appear. The defaults in clockui/AppConfig.py are only used when the file is first created.

Application Build Environment

The application is built with py2app, which is installed as a development dependency by make setup-dev. For local testing, build an alias bundle with:

make dist-test

This builds a macOS application package in ./dist that references the source modules in the development environment instead of copying them in. It builds very quickly and can be built and launched in one step with:

make run-dist-test

When ready to test and distribute the final app, build the full application with:

make dist

This creates a self-contained macOS application in ./dist that can be run as a normal app, installed in the Applications directory, or run from the Desktop. Use make run-dist to build and open it in one step.

Build Notes

  • setuptools is pinned below version 81 in the development dependencies because py2app, on Python 3.9, still relies on the pkg_resources module that newer setuptools releases have removed.
  • setup.py includes a small subclass of the py2app command that clears install_requires. setuptools fills that field from the dependencies in pyproject.toml, and py2app refuses to build when it is set. Dependencies are handled by uv, and py2app finds what to bundle by tracing the imports in Clock.py.

Makefile Targets

Run make or make help to list the available targets.

Target Description
setup-dev Create the .venv and install dependencies with uv
run Run the clock app from the Python source
dist-test Build a test application bundle in dist/ that links to source
run-dist-test Build and run the test application bundle
dist Build a full application package in dist/
run-dist Build and open the full application
clean Remove the build/ and dist/ directories
uninstall Remove build/, dist/, and the .venv

Open Issues

  • TBD

Coding Conventions

The source code is built for Python 3 and includes type annotations and type hinting. Documentation mostly follows the numpy style conventions.

Authors

Created By: Brian McLaughlin ([email protected])

Contributors

SpinStabilized

Issues