{"id":37065098,"url":"https://github.com/shayne/ytsubs","last_synced_at":"2026-02-23T19:32:31.189Z","repository":{"id":271497660,"uuid":"912624172","full_name":"shayne/ytsubs","owner":"shayne","description":"Take the algorithm into your own hands and rank your YouTube subscriptions to surface great videos you might have missed.","archived":false,"fork":false,"pushed_at":"2025-12-21T00:08:40.000Z","size":206,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-22T21:41:43.745Z","etag":null,"topics":["playwright","preact","python","sqlite","web-scraping","youtube"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shayne.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-01-06T03:57:18.000Z","updated_at":"2025-12-21T03:43:26.000Z","dependencies_parsed_at":"2025-01-08T06:22:55.117Z","dependency_job_id":"ddabb87d-2bb4-4e85-b05f-4e9cc6b5d2cd","html_url":"https://github.com/shayne/ytsubs","commit_stats":null,"previous_names":["shayne/youtube-subscriptions","shayne/ytsubs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/shayne/ytsubs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shayne%2Fytsubs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shayne%2Fytsubs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shayne%2Fytsubs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shayne%2Fytsubs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shayne","download_url":"https://codeload.github.com/shayne/ytsubs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shayne%2Fytsubs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["playwright","preact","python","sqlite","web-scraping","youtube"],"created_at":"2026-01-14T07:37:00.309Z","updated_at":"2026-02-23T19:32:31.175Z","avatar_url":"https://github.com/shayne.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# YouTube subscriptions viewer\n\nA local web app that displays your YouTube subscription videos sorted by a nowcast ranking algorithm tuned for ad hoc runs.\n\n## Ranking Algorithm\n\nVideos are ranked by a **core score** designed for ad hoc runs and then filtered by the selected facet window (2 days, 1 week, 2 weeks, 1 month). This means each facet shows the strongest videos **within that window**, not a globally recency-biased list.\n\nCore score components:\n\n1. **Nowcast vs Expected (55% weight)**\n   - Compares current views to age-adjusted expected views from each channel's `baseline_48h`.\n\n2. **Velocity Shock (20% weight)**\n   - Compares current views/hour to expected slope at the video's current age.\n\n3. **Subscriber Reach (15% weight)**\n   - Views relative to subscriber count with diminishing returns.\n\n4. **Duration Prior (5% weight)**\n   - Lightweight bias for durations that tend to produce stable performance.\n\nScore modifiers:\n- **Confidence multiplier (0.75-1.05)** lowers rank impact for weak parse confidence/stale baselines.\n- **Early breakout boost (up to +0.12)** helps very new videos that are simultaneously strong in nowcast and velocity.\n\nNotes:\n- Facet sorting uses facet score keys (`day`, `week`, `twoweeks`, `month`) backed by the core score.\n- Freshness diagnostics are still recorded in details for transparency, but recency is not applied as a hard rank penalty across wider windows.\n\n## Overview\n\nA tool to track YouTube subscriptions and surface high-performing videos. It consists of:\n\n1. A channel stats scraper that collects subscriber counts and a channel `baseline_48h` proxy\n2. A video scraper that collects new videos from subscribed channels\n3. Observation tracking per scrape run for better point-in-time ranking\n4. A static page generator that creates a feed of videos sorted by performance\n\n## Quick start (recommended: uvx)\n\nYou can run the tool directly with `uvx` — no cloning and no manual installs:\n\n```bash\nuvx ytsubs@latest scrape-channels\nuvx ytsubs@latest scrape-videos\nuvx ytsubs@latest open\n```\n\n## Setup (local dev)\n\n1. Requirements:\n\n   - Python 3.12+\n   - Google Chrome browser\n\n2. (Optional) Install tool versions with mise:\n\n```bash\nmise install\n```\n\n3. Install dependencies with uv:\n\n```bash\nuv sync\n```\n\n### Database reset\n\nIf local schema/data gets out of sync, reset your local DB:\n\n```bash\nrm -f ~/.local/state/ytsubs/youtube.db\n```\n\n## Usage\n\n### First-time setup\n\nRun these commands in order:\n\n```bash\nuv run ytsubs scrape-channels   # When Chrome opens, log in to YouTube\nuv run ytsubs scrape-videos     # Collect recent videos and generate the feed\nuv run ytsubs open              # Open the feed in your browser\n```\n\nYour YouTube login is saved in `~/.local/state/ytsubs/chrome_profile` (or `$XDG_STATE_HOME/ytsubs/chrome_profile`), so you'll only need to log in once. Subsequent runs will reuse this profile.\n\n### Regular usage\n\n1. Collect video data:\n\n```bash\nuv run ytsubs scrape-videos  # Run daily to get new videos\n```\n\n2. Update channel statistics (subscriber counts and baseline views):\n\n```bash\nuv run ytsubs scrape-channels  # Run occasionally (e.g., monthly)\n```\n\n3. Open the feed:\n\n```bash\nuv run ytsubs open  # Opens the latest feed\n```\n\nThe feed is written to `~/.local/state/ytsubs/ytsubs_feed.html` (or `$XDG_STATE_HOME/ytsubs/ytsubs_feed.html`).\n\n### Data locations (XDG)\n\n- Chrome profile: `~/.local/state/ytsubs/chrome_profile` (or `$XDG_STATE_HOME/ytsubs/chrome_profile`)\n- SQLite DB: `~/.local/state/ytsubs/youtube.db` (or `$XDG_STATE_HOME/ytsubs/youtube.db`)\n- Feed output: `~/.local/state/ytsubs/ytsubs_feed.html` (or `$XDG_STATE_HOME/ytsubs/ytsubs_feed.html`)\n\n### Debug tooling\n\n```bash\nuv run ytsubs debug-scrape --scrolls 4 --filter \"gymkhana\"\n```\n\n## Development\n\nThe project uses:\n\n- SQLite for data storage\n- Playwright for web scraping\n- Preact for the frontend (served statically)\n\n## Makefile commands\n\nThe project includes several helpful make commands:\n\n- `make clean`: Remove Python cache files\n- `make reset-db`: Reset database to empty tables\n- `make reset-videos`: Clear only the videos table\n- `make reset-channels`: Clear only the channels table\n\n## Requirements\n\n- Python 3.12+\n- Google Chrome\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshayne%2Fytsubs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshayne%2Fytsubs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshayne%2Fytsubs/lists"}