{"id":37227233,"url":"https://github.com/aucontraire/chronovista","last_synced_at":"2026-03-14T04:24:11.184Z","repository":{"id":307300613,"uuid":"1026521479","full_name":"aucontraire/chronovista","owner":"aucontraire","description":"Personal YouTube data analytics tool for comprehensive access to your YouTube engagement history.","archived":false,"fork":false,"pushed_at":"2026-02-10T18:19:21.000Z","size":2329,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-10T22:17:02.388Z","etag":null,"topics":["cli","data-analytics","data-export","google-takeout","multi-language","privacy-first","pydantic","python","transcripts","youtube-api"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aucontraire.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-26T04:07:58.000Z","updated_at":"2026-02-10T18:16:33.000Z","dependencies_parsed_at":"2025-07-30T15:55:09.799Z","dependency_job_id":"ce2f2546-7f13-46e3-949e-2bc2bc06b9c1","html_url":"https://github.com/aucontraire/chronovista","commit_stats":null,"previous_names":["aucontraire/chronovista"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/aucontraire/chronovista","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aucontraire%2Fchronovista","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aucontraire%2Fchronovista/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aucontraire%2Fchronovista/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aucontraire%2Fchronovista/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aucontraire","download_url":"https://codeload.github.com/aucontraire/chronovista/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aucontraire%2Fchronovista/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29600855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T00:59:38.239Z","status":"online","status_checked_at":"2026-02-19T02:00:07.702Z","response_time":117,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","data-analytics","data-export","google-takeout","multi-language","privacy-first","pydantic","python","transcripts","youtube-api"],"created_at":"2026-01-15T03:19:36.206Z","updated_at":"2026-03-14T04:24:11.150Z","avatar_url":"https://github.com/aucontraire.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003echronovista\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA CLI + web dashboard for your YouTube history. Sync watch history, search transcripts by timestamp, recover deleted videos, and explore 124,000+ canonical tags — all stored privately in local PostgreSQL.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-AGPL--3.0-green.svg\" alt=\"License: AGPL-3.0\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/python-3.11+-blue.svg\" alt=\"Python 3.11+\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/tests-7,670+-brightgreen.svg\" alt=\"Tests: 7,670+\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/coverage-72%25-yellow.svg\" alt=\"Coverage: 75%\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/code%20style-black-000000.svg\" alt=\"Code style: black\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e |\n  \u003ca href=\"#features\"\u003eFeatures\u003c/a\u003e |\n  \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e |\n  \u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e |\n  \u003ca href=\"#development\"\u003eDevelopment\u003c/a\u003e |\n  \u003ca href=\"docs/README.md\"\u003eDocs\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003c!-- TODO: Add a screenshot of the React dashboard or a terminal recording (vhs/asciinema) here --\u003e\n\n## Quick Start\n\n```bash\n# Clone and install\ngit clone https://github.com/chronovista/chronovista.git\ncd chronovista \u0026\u0026 poetry install\n\n# Setup database (Docker Compose, port 5434)\nmake dev-db-up\ncp .env.example .env  # Add YouTube API credentials, set DEVELOPMENT_MODE=true\nmake dev-migrate\n\n# Authenticate and sync\npoetry run chronovista auth login\npoetry run chronovista sync all\n# Or activate the virtualenv first: poetry shell\n```\n\n## Features\n\nMost YouTube data tools require cloud sync or third-party services. chronovista runs entirely on your machine: PostgreSQL stores everything, the REST API is local, and the React dashboard is served from localhost. Deleted video metadata can be recovered automatically from the Wayback Machine, and the tag normalization system groups 141,000+ raw tag variations into 124,000+ canonical forms with fuzzy search.\n\n| Category | Capabilities |\n|----------|-------------|\n| **Local-First Privacy** | All data in local PostgreSQL — no cloud sync, complete data ownership |\n| **Multi-Language Transcripts** | 50+ languages with personal preferences (fluent, learning, curious, exclude) |\n| **Transcript Search** | Timestamp-based queries — find what was said at any moment, export as SRT |\n| **Tag Intelligence** | 124K canonical tags with variation grouping, fuzzy search, and 7 curation CLI commands |\n| **Channel Analytics** | Subscription tracking, keyword extraction, topic analysis |\n| **Google Takeout** | Import complete YouTube history including deleted/private videos |\n| **Deleted Video Recovery** | Recover metadata for unavailable videos via the Wayback Machine CDX API |\n| **REST API + Web UI** | FastAPI server (20+ endpoints) with React dashboard for browsing and filtering |\n| **Write Operations** | Create playlists, like videos, subscribe to channels via OAuth |\n| **Export** | CSV/JSON with language-aware filtering |\n\n### Tech Stack\n\n- **Backend:** Python 3.11+, FastAPI, SQLAlchemy 2.0 (async), Alembic, Typer, Pydantic V2\n- **Frontend:** React 19, TypeScript 5.7 (strict), TanStack Query v5, Tailwind CSS 4\n- **Database:** PostgreSQL 15 via asyncpg\n- **Auth:** Google OAuth 2.0 with progressive scope management\n\n## Installation\n\n### Prerequisites\n\n- Python 3.11+\n- [Poetry](https://python-poetry.org/)\n- Docker (with Compose, for the development database)\n- [YouTube Data API credentials](https://console.cloud.google.com/) (API key + OAuth client)\n\n### Install\n\n```bash\ngit clone https://github.com/chronovista/chronovista.git\ncd chronovista\npoetry install\n```\n\n### Database Setup\n\n```bash\n# Start development database (Docker Compose, port 5434)\nmake dev-db-up\n\n# Configure environment\ncp .env.example .env  # Add YouTube API credentials, set DEVELOPMENT_MODE=true\n\n# Run migrations\nmake dev-migrate\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eMySQL Setup\u003c/summary\u003e\n\n```bash\ndocker run --name chronovista-mysql -e MYSQL_ROOT_PASSWORD=dev -e MYSQL_DATABASE=chronovista -p 3306:3306 -d mysql:8\n```\n\nUpdate `DATABASE_URL` in `.env`:\n```\nDATABASE_URL=mysql+aiomysql://root:dev@localhost:3306/chronovista\n```\n\u003c/details\u003e\n\n### YouTube API Setup\n\nYou'll need a Google Cloud project with YouTube Data API v3 enabled and OAuth 2.0 credentials.\n\n**→ [Full setup guide](docs/getting-started/youtube-api-setup.md)** — covers consent screen configuration, test user setup, and common authentication errors.\n\nQuick reference for `.env`:\n```env\nYOUTUBE_API_KEY=your_api_key\nYOUTUBE_CLIENT_ID=your_client_id\nYOUTUBE_CLIENT_SECRET=your_client_secret\n```\n\n## Usage\n\n### Authentication\n\n```bash\nchronovista auth login     # OAuth login\nchronovista auth status    # Check status\nchronovista auth logout    # Logout\n```\n\n### Sync Your Data\n\n```bash\nchronovista sync history      # Watch history\nchronovista sync playlists    # Playlists\nchronovista sync transcripts  # Video transcripts\nchronovista sync topics       # Topic categories\nchronovista sync all          # Everything\n```\n\n### Transcript Queries\n\n```bash\nchronovista transcript segment VIDEO_ID 5:00      # Get segment at timestamp\nchronovista transcript context VIDEO_ID 5:00      # Get 30s context window\nchronovista transcript range VIDEO_ID 1:00 5:00   # Get segments in range\nchronovista transcript range VIDEO_ID 0:00 10:00 --format srt  # SRT export\n```\n\n### Topic Analytics\n\n```bash\nchronovista topics list              # All topics with content counts\nchronovista topics popular           # Most popular by content\nchronovista topics videos 10         # Videos in Music category\nchronovista topics trends            # Popularity over time\nchronovista topics chart             # Visual ASCII chart\nchronovista topics explore           # Interactive exploration\n```\n\n### Tag Management\n\n```bash\nchronovista tags merge mejico mexiko --into mexico   # Merge spelling variants\nchronovista tags split mexico --aliases \"Mexican\"    # Split incorrectly merged tags\nchronovista tags rename mexico --to \"Mexico\"         # Change display form\nchronovista tags classify mexico --type place        # Assign entity type\nchronovista tags collisions                          # Review diacritic collision candidates\nchronovista tags undo OPERATION_ID                   # Reverse any operation\n```\n\n### Google Takeout Import\n\nImport your complete YouTube history from [Google Takeout](https://takeout.google.com/):\n\n```bash\nchronovista takeout seed /path/to/takeout              # Full import\nchronovista takeout seed /path/to/takeout --dry-run    # Preview changes\nchronovista takeout seed /path/to/takeout --incremental # Safe re-run\nchronovista takeout analyze /path/to/takeout           # Analyze patterns\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eTakeout Details\u003c/summary\u003e\n\n**What gets imported:**\n- Channels, videos, and watch history with timestamps\n- All playlists with video relationships\n- Historical data including deleted/private videos\n\n**Analysis commands:**\n```bash\nchronovista takeout peek /path/to/takeout --summary\nchronovista takeout analyze /path/to/takeout --type viewing-patterns\nchronovista takeout analyze /path/to/takeout --type channel-relationships\nchronovista takeout inspect /path/to/takeout --focus playlists\n```\n\n**Combine with API data:**\n```bash\nchronovista takeout seed /path/to/takeout\nchronovista sync all  # Enriches with current API data\n```\n\u003c/details\u003e\n\n### Recover Deleted Videos\n\nRecover metadata for deleted or unavailable videos from the [Wayback Machine](https://web.archive.org/):\n\n```bash\nchronovista recover video --video-id VIDEO_ID                # Single video\nchronovista recover video --all --limit 50                   # Batch recover\nchronovista recover video --all --dry-run                    # Preview changes\nchronovista recover video --video-id VIDEO_ID --start-year 2018  # Anchor to era\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eRecovery Details\u003c/summary\u003e\n\n**What gets recovered:**\n- Title, description, upload date, channel info\n- Tags, category, thumbnail URL\n- View count, like count\n\n**How it works:**\n- Queries the Wayback Machine CDX API for archived YouTube video pages\n- Extracts metadata from JSON or HTML meta tags\n- Three-tier overwrite policy protects existing data\n- Results cached locally for 24 hours\n\n**Options:**\n- `--start-year` / `--end-year` — Focus search on a specific archive era\n- `--delay` — Rate limiting between videos in batch mode (default: 1s)\n- `--dry-run` — Preview without making database changes\n\u003c/details\u003e\n\n### REST API\n\nStart the REST API server for programmatic access:\n\n```bash\nchronovista api start --port 8765    # Start server\n\n# Example requests (requires prior auth login)\ncurl http://localhost:8765/api/v1/health\ncurl http://localhost:8765/api/v1/videos?limit=10\ncurl \"http://localhost:8765/api/v1/search/segments?q=keyword\"\n\n# Interactive API docs\nopen http://localhost:8765/docs\n```\n\n### Web Frontend\n\n```bash\nmake dev               # Start backend (8765) + frontend (8766)\nopen http://localhost:8766\n```\n\nThe React dashboard provides video browsing with tag/category/topic filters, transcript search, playlist navigation, and deleted video visibility controls.\n\n## Development\n\n### Workflow\n\n```bash\n# Install dev dependencies\npoetry install --with dev\n\n# Start the full local stack\nmake dev               # Backend on :8765, frontend on :8766\n\n# Before committing — run all checks\nmake quality           # format + lint + type-check\n```\n\n### Testing\n\n```bash\nmake test              # All backend tests (5,493+)\nmake test-cov          # With coverage\nmake test-fast         # Quick run\n\n# Frontend tests (2,177+)\ncd frontend \u0026\u0026 npm test\n```\n\n### Code Quality\n\n```bash\nmake format            # black + isort\nmake lint              # ruff\nmake type-check        # mypy (strict, 0 errors across 415+ source files)\n```\n\n### Database\n\n```bash\nmake db-upgrade        # Run migrations\nmake db-revision       # Create new migration\n```\n\n### Frontend Development\n\n```bash\nmake dev-backend       # Backend only (port 8765)\nmake dev-frontend      # Frontend only (port 8766)\nmake generate-api      # Regenerate TypeScript API client after backend model changes\n```\n\nSee [`frontend/README.md`](frontend/README.md) for detailed frontend documentation.\n\n\u003cdetails\u003e\n\u003csummary\u003eAll Makefile Commands\u003c/summary\u003e\n\n```bash\nmake help              # Show all commands\nmake install-dev       # Dev dependencies\nmake install-all       # All dependencies\nmake shell             # Poetry shell\nmake clean             # Clean artifacts\nmake env-info          # Environment info\nmake dev-db-admin      # Start pgAdmin (localhost:8081)\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eIntegration Testing\u003c/summary\u003e\n\n```bash\n# Full setup\nmake dev-full-setup\n\n# Authenticate (one-time)\npoetry run chronovista auth login\n\n# Run integration tests\npoetry run pytest tests/integration/api/ -v\n\n# Reset if needed\nmake dev-full-reset\n```\n\nTests validate the complete flow: YouTube API -\u003e Pydantic models -\u003e Database persistence.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eTroubleshooting\u003c/summary\u003e\n\n**\"No module named mypy\":**\n```bash\npoetry install --with dev\n```\n\n**Poetry not found:**\n```bash\ncurl -sSL https://install.python-poetry.org | python3 -\nexport PATH=\"$HOME/.local/bin:$PATH\"\n```\n\n**Virtual environment issues:**\n```bash\npoetry env info\npoetry env remove python\npoetry install\n```\n\u003c/details\u003e\n\n## Architecture\n\n```\nchronovista/\n├── api/              # FastAPI REST API: 20+ endpoints, RFC 7807 errors, rate limiting\n├── cli/              # Typer CLI: 40+ commands (auth, sync, topics, recovery, tags)\n├── services/         # Business logic: sync orchestration, tag normalization, recovery pipeline\n│   └── recovery/     # Wayback Machine recovery: CDX client, HTML parser, orchestrator\n├── repositories/     # Async SQLAlchemy DAL: all DB access, composite key support\n├── models/           # Pydantic V2 domain models (separate from ORM models in db/)\n├── db/               # SQLAlchemy ORM models + Alembic migrations\n└── auth/             # OAuth 2.0 with progressive scope management\n```\n\n**Key design decisions:**\n- Async-first with full async/await (asyncpg, httpx)\n- Strict type safety: Pydantic V2 models + mypy strict mode\n- Repository pattern isolating all database access\n- Layered architecture: CLI/API -\u003e Services -\u003e Repositories -\u003e DB\n\nSee [Architecture Overview](docs/architecture/overview.md) for details.\n\n## Roadmap\n\n- [ ] ML-powered content insights and recommendations\n- [ ] Screenshot/terminal recording for README\n- [ ] CI/CD pipeline with automated badge generation\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Run `make quality` before committing\n4. Submit a pull request\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\n[AGPL-3.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faucontraire%2Fchronovista","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faucontraire%2Fchronovista","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faucontraire%2Fchronovista/lists"}