Change log#

0.1.5 (unreleased)#

New features#

  • Added Dependabot config. #78

  • Added CODEOWNERS. #28

  • Added SECURITY.md. #44

  • Added field_modes support to Fernet live-proxy tokens so per-field UI choices are applied on fetch. #139

  • Added Open Web Calendar tutorial at docs/tutorials/open-web-calendar.rst. #93

  • Added docs/examples.rst with real-world workflows. #59

Minor changes#

  • Adopted sphinx_issues extension for shorter changelog issue and pull request references.

Bug fixes#

0.1.4 (2026-04-20)#

New features#

  • Persisted per-field anonymization options across page loads via localStorage. #116

Minor changes#

  • Removed “(30-day expiry)” from shareable-link checkbox labels. #113

  • Synced per-field anonymization options across Upload, Paste, and Fetch URL tabs. #115

  • Changed web UI default field modes: SUMMARY keeps original, other text/address fields are removed, UID remains randomized. #117

Bug fixes#

  • Fixed Dockerfile CMD to use JSON array form with sh -c wrapper, resolving the JSONArgsRecommended lint warning while preserving shell variable expansion for HOST, PORT, and WORKERS.

  • Preserved X-WR-TIMEZONE. #112

0.1.3 (2026-04-02)#

New features#

  • Added automatic Docker build trigger on release via gh workflow run in .github/workflows/release.yml. #77

Minor changes#

  • Migrated repository from mergecal to pycalendar GitHub organization.

  • Docker image moved from Docker Hub (sashankbhamidi/icalendar-anonymizer) to GitHub Container Registry (ghcr.io/pycalendar/icalendar-anonymizer). All historical tags are available at the new location. #71 #106

0.1.2 (2026-02-11)#

New features#

  • Added configurable per-field anonymization modes with four options: keep (preserve original), remove (strip property), randomize (hash - default), and replace (fixed placeholder). Supports 10 configurable fields: SUMMARY, DESCRIPTION, LOCATION, COMMENT, CONTACT, RESOURCES, CATEGORIES, ATTENDEE, ORGANIZER, and UID. New field_modes parameter in anonymize() function. CLI flags: --summary, --description, --location, etc. Web API: config field in request bodies and query parameters. Frontend: collapsible “Advanced Options” section in all three tabs. Backward compatible with existing preserve parameter. Constraint: UID cannot use remove mode (would break recurring events). #92

  • Added Fernet-based encrypted links for live calendar proxying. Endpoints: POST /fernet-generate (creates token) and GET /fernet/{token} (fetches and anonymizes on-the-fly). Token encrypts source URL and salt via FERNET_KEY environment variable. Frontend radio buttons toggle between Fernet (live) and R2 (snapshot) modes. Vendors pure-Python Fernet implementation for Cloudflare Workers compatibility. #95

  • Added /anonymized endpoint for curl-friendly anonymization. Supports GET with ics query parameter and POST with raw ICS body. Returns text/calendar without Content-Disposition header for easy piping. #25

  • Added shareable links with Cloudflare R2 storage. Users can generate time-limited public URLs for anonymized calendars with 30-day auto-expiry. New endpoints: POST /share (generate link) and GET /s/{id} (retrieve file). Frontend checkboxes in all three tabs (upload, paste, fetch URL). R2 client wrapper with MockR2Client for local dev and WorkersR2Client for production. Health endpoint reports R2 availability. R2 bucket binding configured in wrangler.jsonc. #7

  • Added Cloudflare Workers deployment support with Python FastAPI via Pyodide. Configured wrangler.jsonc for Workers Assets serving static files. Created worker.py entry point using asgi.fetch() integration. Added build.sh to bundle local package into python_modules/. GitHub Actions workflow deploys on main branch. Custom domain configured at https://icalendar-anonymizer.com. #19 #83

  • Added Docker setup for self-hosting. Multi-stage Dockerfile with Python 3.13-slim, non-root user (UID 1000), and gunicorn with uvicorn workers. Health check endpoint GET /health returns service status, version, and feature flags. docker-compose.yml with environment variables for host, port, workers, and file size limit. Documentation at docs/usage/self-hosting.rst. #8

  • Added frontend interface with file upload, paste, and URL fetch capabilities. Implemented drag and drop file upload with visual feedback. Added progressive enhancement for no-JavaScript environments. Provided WCAG AA compliant accessibility features (keyboard navigation, screen readers). Included mobile-responsive design for all device sizes. Zero external dependencies (vanilla HTML/CSS/JS). #5

  • Added FastAPI web service with three endpoints: POST /anonymize (JSON), POST /upload (file), GET /fetch (URL). SSRF protection blocks private IPs, localhost, and invalid schemes. 10s timeout, 10MB limit. Install: pip install icalendar-anonymizer[web]. #4

Minor changes#

  • Added REUSE.toml for fallback licensing of files without SPDX headers (auto-generated _version.py). In-file headers remain preferred. #58

  • Improved test coverage for Cloudflare Workers integration. #90

  • Moved fastapi, httpx, and python-multipart from core dependencies to [web] extras. Base installation now only requires icalendar. #23

  • Updated documentation to use python -m pip per best practices. #97

Bug fixes#

  • Fixed Fernet encryption for Cloudflare Workers by vendoring pyaes and fernet (MIT-licensed from ricmoo/pyaes and oz123/python-fernet). Pyodide requires pure-Python or wasm32 wheels; cryptography has neither on PyPI. Added FERNET_KEY env copy from Workers to os.environ. #100 #101

  • Fixed property iteration causing subcomponent corruption. Changed calendar property iteration from property_items() to items() to avoid copying subcomponent properties to calendar level, and added filtering of BEGIN/END structural markers in component property processing. This resolves malformed ICS output where event properties appeared at calendar level and were wrapped in spurious subcomponents during serialization/deserialization. #92

  • Fixed Cloudflare Workers deployment issues including module bundling, build order, static asset serving, and wrangler configuration. #84 #85 #86 #87 #88

0.1.1 (2025-12-25)#

New features#

  • Added Sphinx documentation with PyData theme on Read the Docs. Includes installation guide, Python API reference with property table and autodoc, CLI usage guide, web service API documentation, and contributing guide with commit format reference. Changed bash to shell code-block lexer, converted lists to definition lists, added documentation standards section. Configured docs/conf.py with sphinx_design, sphinx_copybutton, sphinx.ext.intersphinx. Updated pyproject.toml with doc dependencies. Added badge to README.md. Documentation at https://icalendar-anonymizer.readthedocs.io/stable/. #9 #60

  • Added .readthedocs.yaml configuration file with Ubuntu 24.04 build environment and Python 3.13 to enable automatic documentation builds on Read the Docs. #56

  • Added command-line interface with icalendar-anonymize and ican commands. Supports stdin/stdout piping, file I/O, and verbose mode. Uses Click for argument parsing with built-in - convention for Unix-style streams. Binary mode handling for ICS files. Comprehensive error handling with clear messages. Install with pip install icalendar-anonymizer[cli]. #3

Minor changes#

  • Commented out CHANGES.rst formatting guidelines to hide from rendered documentation. Added note in CONTRIBUTING.md directing contributors to read the source file for formatting guidelines. Guidelines remain visible in source. #61

Bug fixes#

  • Fixed GitHub release notes to strip “v” prefix from PyPI version in install command. Added version extraction step in .github/workflows/release.yml to convert tag v0.1.0 to 0.1.0 for pip install command, ensuring correct PyPI package installation.

0.1.0 (2025-12-05)#

New features#

  • Added preserve parameter to anonymize() function. Accepts optional set of property names to preserve beyond defaults. Case-insensitive. Allows preserving properties like CATEGORIES or COMMENT for bug reproduction when user confirms no sensitive data. Added 7 tests for preserve functionality. #53

  • Added core anonymization engine with anonymize() function using SHA-256 deterministic hashing. Removes personal data (names, emails, locations, descriptions) while preserving technical properties (dates, recurrence, timezones). Configurable salt parameter enables reproducible output. Property classification system with default-deny for unknown properties. Structure-preserving hash functions maintain word count and email format. UID uniqueness preserved across calendar. Special handling for ATTENDEE/ORGANIZER with CN parameter anonymization. Test suite with 35 tests achieves 95% coverage. #1 #2

  • Added comprehensive CI/CD workflows with GitHub Actions: test matrix across Ubuntu/Windows/macOS with Python 3.11-3.13, Ruff to lint and check the format of code, Codecov integration with multi-platform coverage tracking, PyPI trusted publishing (OIDC, no tokens required), Docker multi-arch builds (AMD64/ARM64), and automatic GitHub releases with generated notes. Added .github/workflows/tests.yml, .github/workflows/publish.yml, .github/workflows/docker.yml, and .github/workflows/release.yml. Configured hatch test matrix for local multi-version testing and coverage exclusions in pyproject.toml. Added CI/CD badges to README.md (tests, coverage, PyPI version, Python versions, Docker pulls). Added test structure with placeholder files referencing related issues. Docker images originally published to Docker Hub at sashankbhamidi/icalendar-anonymizer; migrated to GitHub Container Registry at ghcr.io/pycalendar/icalendar-anonymizer in v0.1.3. #10

  • Added .gitattributes to normalize line endings across platforms (LF in repository, native line endings on checkout).

  • Added comprehensive pre-commit hooks configuration with Ruff linting/formatting, file integrity checks, and commit message validation. Updated CONTRIBUTING.md with setup instructions and usage documentation. Added Ruff badge to README.md. #20

  • Added conventional commits configuration (.cz.toml), pre-commit hooks, CI workflows, and documentation. #27

  • Applied Sphinx best practices to CHANGES.rst including proper RST roles, subheadings, and past tense verbs. #31

  • Added project configuration files (.gitignore, .editorconfig, .python-version, requirements-dev.txt). #16

  • Added LICENSE with AGPL-3.0-or-later license. #14

  • Added CONTRIBUTING.md with development workflow, commit message format, testing requirements, and project structure. #15

  • Added README.md with installation instructions and usage examples for Python API, CLI, and web service. #13

  • Added pyproject.toml with hatchling build system, hatch-vcs version management, package structure, and dependencies. Tests included in package at src/icalendar_anonymizer/tests/. #12

  • Added REUSE specification compliance with SPDX headers to all source files, configuration files, documentation, and workflows. Added .github/workflows/reuse.yml for automated CI compliance checking and reuse hook to .pre-commit-config.yaml for local validation. Downloaded LICENSES/AGPL-3.0-or-later.txt. Project is fully compliant with REUSE 3.3 specification for clear licensing. #22

Minor changes#

  • Standardized docstring format to multi-line Google-style across all modules. Removed placeholder Examples sections. #52

  • Parametrized duplicate test patterns using pytest.mark.parametrize() for datetime, recurrence, metadata, text anonymization, and word count tests. Reduced test duplication while maintaining coverage. #52

  • Added doctest validation for core modules with test_with_doctest.py. #52

  • Updated CONTRIBUTING.md with code style guidelines including docstring format, test organization patterns, and import conventions. #52