From b48c5fb2dea67b53a94fae965d0a374d34d01378 Mon Sep 17 00:00:00 2001 From: WheheoHu Date: Tue, 12 May 2026 23:00:10 +0800 Subject: [PATCH] 1.0 RELEASE ! --- .gitignore | 1 - CHANGELOG.md | 8 ++- CLAUDE.md | 184 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- pyproject.toml | 4 +- uv.lock | 2 +- 6 files changed, 195 insertions(+), 6 deletions(-) create mode 100644 CLAUDE.md diff --git a/.gitignore b/.gitignore index fbd8f57..f63d0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ dftt_timecode.egg-info .pytest_cache .DS_Store playground.ipynb -CLAUDE.md dist build .claude/settings.local.json diff --git a/CHANGELOG.md b/CHANGELOG.md index d5a8b2d..fa0a75c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [1.0.0b4] +## [1.0.0] - 2026-05-12 + +### Summary + +First stable release. The library graduates from beta with the breaking changes accumulated during the `1.0.0b*` series finalized. Downstream code that worked against `1.0.0b4` should require no further changes. + +首个正式版本。库从测试版毕业,`1.0.0b*` 系列累积的破坏性变更在此版本定稿。已适配 `1.0.0b4` 的下游代码无需进一步修改。 ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..d0b4c59 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,184 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Development Commands + +### Package Management +- **Recommended:** Use `uv` package manager (used in CI/CD) + - Install dependencies: `uv sync` + - Run commands with dependencies: `uv run ` +- **Alternative:** Traditional pip + - Install in development mode: `pip install -e .` + - Install dev dependencies: `pip install -e .[dev]` (requires pyproject.toml dependency groups) + +### Testing +- Run all tests: `pytest` or `uv run pytest` +- Run with verbose output: `pytest -v -s` (configured in pyproject.toml) +- Run specific test file: `pytest test/test_dftt_timecode.py` +- Run specific test for TimeRange: `pytest test/test_dftt_timerange.py` + +### Documentation +- Build docs: `cd docs && make html` or `cd docs && uv run make html` +- Clean build: `cd docs && make clean` +- View docs: Open `docs/_build/html/index.html` +- **Note:** Documentation uses Sphinx with MyST-Parser for Markdown support + +### Building and Publishing +- Build package: `uv build` +- Publishing is automated via GitHub Actions on release creation + +## Code Structure + +This is a Python timecode library for the film and TV industry with high frame rate support. + +### Package Organization +``` +dftt_timecode/ +├── core/ +│ ├── dftt_timecode.py # Core DfttTimecode class +│ └── dftt_timerange.py # DfttTimeRange class for time intervals +├── pattern.py # Regex patterns for all timecode formats +├── error.py # Custom exception classes +├── logging_config.py # Logging setup with branch-aware default levels +└── __init__.py # Package exports and convenience aliases +``` + +### Main Components + +#### DfttTimecode Class (`dftt_timecode/core/dftt_timecode.py`) +- Core timecode class with all timecode operations +- Handles format conversion, arithmetic, and comparison operations +- Uses `fractions.Fraction` for high-precision internal timestamp storage + +#### DfttTimeRange Class (`dftt_timecode/core/dftt_timerange.py`) +- Handles time intervals with start and end timecodes +- Supports range operations: intersection, union, containment checks +- Calculates duration and frame counts for ranges + +#### Pattern Module (`dftt_timecode/pattern.py`) +- Contains regex patterns for all supported timecode formats +- Validates input strings before parsing +- Formats: SMPTE, SRT, FFMPEG, FCPX, DLP, frame count, timestamps + +#### Error Module (`dftt_timecode/error.py`) +- Custom exception classes for timecode-specific errors, all inheriting from `DFTTError` +- Timecode errors: `DFTTTimecodeValueError`, `DFTTTimecodeInitializationError`, `DFTTTimecodeTypeError`, `DFTTTimecodeOperatorError` +- TimeRange errors: `DFTTTimeRangeMethodError`, `DFTTTimeRangeValueError`, `DFTTTimeRangeTypeError`, `DFTTTimeRangeFPSError` + +#### Logging Module (`dftt_timecode/logging_config.py`) +- Provides `get_logger(name)` and `configure_logging(level)` (both re-exported at package level) +- Default level is branch-aware: `INFO` for installed packages and `main` branch, `DEBUG` for dev/feature branches +- Override via `DFTT_LOG_LEVEL` environment variable (`DEBUG`/`INFO`/`WARNING`/`ERROR`/`CRITICAL`) + +### Key Features +- **Multiple formats:** SMPTE (DF/NDF), SRT, FFMPEG, FCPX, DLP, frame count, timestamps +- **High frame rate:** 0.01-999.99 fps support +- **Strict mode:** 24-hour cycling for broadcast workflows +- **Rich operators:** Full arithmetic (+, -, *, /) and comparison (==, !=, <, >, <=, >=) +- **High precision:** Internal Fraction-based calculations for lossless accuracy +- **Convenience aliases:** `dtc` / `Timecode` (DfttTimecode), `dtr` / `Timerange` (DfttTimeRange) + +### Timecode Types Supported +- `smpte`: Standard SMPTE format (01:23:45:12 or 01:23:45;12 for drop-frame) +- `srt`: SubRip format (01:23:45,678) +- `ffmpeg`: FFmpeg format (01:23:45.67) +- `fcpx`: Final Cut Pro X format (1/24s) +- `dlp`: DLP Cinema format (01:23:45:102) +- `frame`: Frame count (1000f) +- `time`: Timestamp in seconds (3600.0s) +- `auto`: Automatic detection based on input format + +### Architecture Patterns +- **Single-dispatch methods:** Uses `functools.singledispatchmethod` for handling different input types +- **Input validation:** Comprehensive regex-based validation via pattern.py +- **Internal storage:** High-precision Fraction timestamps (no floating-point errors) +- **Lazy evaluation:** Format conversions computed on-demand +- **Immutability:** Operations return new instances rather than modifying in place + +### Testing +- Uses pytest framework with parametrized tests +- Test files: `test/test_dftt_timecode.py`, `test/test_dftt_timerange.py`, `test/test_logging_config.py` +- Covers multiple timecode formats, edge cases, and error conditions +- Fixture-based test data setup + +### Documentation System +- Sphinx with MyST-Parser (supports both RST and Markdown) +- Auto-generated API docs from docstrings +- Deployed to GitHub Pages via `.github/workflows/docs.yml` +- Changelog: Maintained in `CHANGELOG.md` (Keep a Changelog format), included in docs via RST +- Internationalization: Chinese translations under `docs/locale/`, built with `sphinx-intl` + +### CI/CD Workflows +- **Documentation:** Builds and deploys to GitHub Pages on push to main (`.github/workflows/docs.yml`) +- **Publishing:** Automatically publishes to PyPI on GitHub release creation (`.github/workflows/publish-to-pypi.yml`) + +## Version Information +- Current version: 1.0.0 +- Python requirement: >=3.11 +- Main dependencies: All standard library (fractions, logging, math, functools, re, subprocess) +- Dev dependencies: pytest, sphinx, pydata-sphinx-theme, myst-parser, sphinx-intl + +## Common Usage Patterns + +### Basic Timecode Creation +```python +from dftt_timecode import DfttTimecode, dtc + +# Full class name +tc = DfttTimecode('01:00:00:00', 'auto', fps=24, drop_frame=False, strict=True) + +# Using convenience alias +tc = dtc('01:00:00:00', fps=24) + +# Access properties +tc.type # timecode format type +tc.fps # frame rate +tc.framecount # total frames from zero +tc.timestamp # seconds from zero (float) +tc.precise_timestamp # high-precision Fraction timestamp +``` + +### Format Conversion +```python +# Convert output format +tc.timecode_output('srt') # SubRip format +tc.timecode_output('ffmpeg') # FFmpeg format + +# Change timecode type +tc.set_type('smpte') +tc.set_fps(30, rounding=True) +tc.set_strict(False) +``` + +### Arithmetic Operations +```python +result = tc1 + tc2 # add timecodes +result = tc - 100 # subtract 100 frames +result = tc * 2 # multiply by factor +result = tc / 2 # divide by factor +result = tc + 1.0 # add 1 second (float) + +# Comparisons +tc1 > tc2 # compare timecodes +tc1 == tc2 # equality check +``` + +### TimeRange Operations +```python +from dftt_timecode import DfttTimeRange, dtr + +# Create time range +tr = DfttTimeRange(start_tc='01:00:00:00', end_tc='02:00:00:00', fps=24) +# or using alias +tr = dtr('01:00:00:00', '02:00:00:00', fps=24) + +# Access properties +tr.duration # duration as DfttTimecode +tr.framecount # total frames in range + +# Range operations +tr1.intersection(tr2) # overlapping portion +tr1.union(tr2) # combined range +tc in tr # check if timecode is in range +``` diff --git a/README.md b/README.md index 2f6ddfb..b7b567d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DFTT Timecode -[![pypi](https://img.shields.io/badge/pypi-0.0.14-brightgreen)](https://pypi.org/project/dftt-timecode/) +[![pypi](https://img.shields.io/pypi/v/dftt-timecode.svg)](https://pypi.org/project/dftt-timecode/) [![python](https://img.shields.io/badge/python-3.11+-blue)](https://www.python.org/) [![GitHub license](https://img.shields.io/badge/license-LGPL2.1-green)](https://github.com/OwenYou/dftt_timecode/blob/main/LICENSE) [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://owenyou.github.io/dftt_timecode/) diff --git a/pyproject.toml b/pyproject.toml index 998d2fe..1ae1aba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "uv_build" [project] name = "dftt-timecode" -version = "1.0.0b4" +version = "1.0.0" description = "Timecode library for film and TV industry, supports HFR and a bunch of cool features" readme = "README.md" requires-python = ">=3.11" @@ -17,7 +17,7 @@ classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", - "Development Status :: 4 - Beta", + "Development Status :: 5 - Production/Stable", "Natural Language :: Chinese (Simplified)", "Operating System :: OS Independent", ] diff --git a/uv.lock b/uv.lock index 750a852..9bce1be 100644 --- a/uv.lock +++ b/uv.lock @@ -170,7 +170,7 @@ wheels = [ [[package]] name = "dftt-timecode" -version = "1.0.0b4" +version = "1.0.0" source = { editable = "." } [package.dev-dependencies]