yle-areena-dvr 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ # Yle Data API credentials (optional; by default read from areena.yle.fi at runtime)
2
+ YLE_APP_ID=
3
+ YLE_APP_KEY=
4
+
5
+ # TMDb API Key for ratings and multi-language searching
6
+ # Get a free key from https://www.themoviedb.org/documentation/api
7
+ TMDB_API_KEY=your_tmdb_key_here
8
+
9
+ # Download base directory
10
+ DOWNLOAD_BASE_DIR=~/Downloads/YleAreena
@@ -0,0 +1,21 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["main"]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ["3.12", "3.13", "3.14"]
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: astral-sh/setup-uv@v6
19
+ - run: uv sync --python ${{ matrix.python-version }}
20
+ - run: uv run yle-dvr naming
21
+ - run: uv build
@@ -0,0 +1,35 @@
1
+ name: Release
2
+
3
+ # Publishes to PyPI when a version tag (e.g. v0.1.0) is pushed, using PyPI trusted publishing (OIDC).
4
+ # One-time setup on pypi.org: add a publisher for owner junousia, repo yle-areena-dvr,
5
+ # workflow release.yml, environment pypi.
6
+ on:
7
+ push:
8
+ tags: ["v*"]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: astral-sh/setup-uv@v6
16
+ - name: Tag must match pyproject version
17
+ run: test "v$(grep -m1 '^version' pyproject.toml | cut -d'"' -f2)" = "$GITHUB_REF_NAME"
18
+ - run: uv build
19
+ - uses: actions/upload-artifact@v4
20
+ with:
21
+ name: dist
22
+ path: dist/
23
+
24
+ publish:
25
+ needs: build
26
+ runs-on: ubuntu-latest
27
+ environment: pypi
28
+ permissions:
29
+ id-token: write
30
+ steps:
31
+ - uses: actions/download-artifact@v4
32
+ with:
33
+ name: dist
34
+ path: dist/
35
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,27 @@
1
+ # Secrets
2
+ .env
3
+ *.key
4
+ *.pem
5
+
6
+ # Python
7
+ .venv/
8
+ __pycache__/
9
+ *.pyc
10
+ *.pyo
11
+ *.pyd
12
+ .pytest_cache/
13
+ .mypy_cache/
14
+
15
+ # Local runtime data
16
+ *.db
17
+ *.sqlite
18
+ *.sqlite3
19
+ .tmdb-cache.json
20
+
21
+ # OS / editor
22
+ .DS_Store
23
+ .vscode/
24
+ .idea/
25
+ node_modules/
26
+ dist/
27
+ state.json
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jukka Nousiainen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.5
2
+ Name: yle-areena-dvr
3
+ Version: 0.1.0
4
+ Summary: A tool for Yle Areena to download movies and series of interest.
5
+ Project-URL: Homepage, https://github.com/junousia/yle-areena-dvr
6
+ Project-URL: Issues, https://github.com/junousia/yle-areena-dvr/issues
7
+ Author: Jukka Nousiainen
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: agent-skill,areena,dvr,tmdb,yle,yt-dlp
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Requires-Python: <3.15,>=3.12
17
+ Requires-Dist: aiosqlite
18
+ Requires-Dist: greenlet
19
+ Requires-Dist: httpx
20
+ Requires-Dist: pydantic
21
+ Requires-Dist: pydantic-cli
22
+ Requires-Dist: pydantic-settings
23
+ Requires-Dist: pyyaml
24
+ Requires-Dist: sqlmodel
25
+ Requires-Dist: yt-dlp
26
+ Description-Content-Type: text/markdown
27
+
28
+ # Yle Areena DVR
29
+
30
+ A Python tool for searching, scraping, and downloading movies and series from Yle Areena with integrated TMDb ratings and flexible naming templates.
31
+
32
+ ## Features
33
+ - **Yle Areena Search**: Find movies by query or category.
34
+ - **Scrape Curated Lists**: Extract movies directly from Areena's curated lists (e.g., "Katsotuimmat leffat").
35
+ - **TMDb Ratings**: Automatically fetch and filter by TMDb ratings (The Movie Database). Excellent multi-language support.
36
+ - **yt-dlp Integration**: High-quality downloads with subtitle support.
37
+ - **Flexible Organization**: Customize your folder structure and file naming via `config.yaml`.
38
+ - **Modern Python**: Built with Python 3.12+, Pydantic 2, and managed entirely with `uv`.
39
+
40
+ ## Installation
41
+
42
+ This project is built using `uv`, an extremely fast Python package and project manager.
43
+
44
+ ```bash
45
+ # Clone the repository
46
+ git clone https://github.com/junousia/yle-areena-dvr.git
47
+ cd yle-areena-dvr
48
+
49
+ # Sync the environment
50
+ uv sync
51
+
52
+ # Or install it globally as a tool
53
+ uv tool install .
54
+ ```
55
+
56
+ ## Setup
57
+
58
+ 1. Copy `.env.template` to `.env`:
59
+ ```bash
60
+ cp .env.template .env
61
+ ```
62
+ 2. Fill in your `TMDB_API_KEY` (free from themoviedb.org). `YLE_APP_ID` and `YLE_APP_KEY` are **optional**: by default the tool reads the keys that Areena's own web frontend embeds in its pages at runtime; set them only to override that.
63
+ 3. Customize `assets/config.yaml` to change where your movies are saved.
64
+
65
+ ## Usage
66
+
67
+ If you installed it via `uv tool install .`, you can run `yle-dvr` directly. Otherwise, use `uv run yle-dvr` inside the project directory.
68
+
69
+ ### Search for Programs
70
+ ```bash
71
+ uv run yle-dvr search --query "Metsolat" --limit 5 --min-rating 7.0
72
+
73
+ # Search for expiring programs
74
+ uv run yle-dvr search --only-expiring
75
+
76
+ # Search for recently added programs
77
+ uv run yle-dvr search --only-new
78
+
79
+ # You can also get machine-readable output for AI agents:
80
+ uv run yle-dvr search --query "Action" --json
81
+ ```
82
+
83
+ ### Scrape Curated Lists (Movies or Series)
84
+ ```bash
85
+ # Scrape movies
86
+ uv run yle-dvr scrape --url "https://areena.yle.fi/tv/ohjelmat/57-1BbXLDz6v" --min-rating 7.5
87
+
88
+ # Scrape series
89
+ uv run yle-dvr scrape --url "https://areena.yle.fi/tv/ohjelmat/57-p8JeXvBA0"
90
+ ```
91
+
92
+ ### Download a Program (Movie or Series)
93
+ ```bash
94
+ uv run yle-dvr download --id "1-2345678"
95
+ ```
96
+
97
+ ### Look Up Full Details for Suitability (Overview, Genres, Cast)
98
+ ```bash
99
+ # From a program already in the local DB
100
+ uv run yle-dvr details --id "1-2345678" --json
101
+
102
+ # Directly by title, no DB entry required
103
+ uv run yle-dvr details --title "Fight Club" --year 1999 --json
104
+ ```
105
+
106
+ ## Configuration
107
+ See `assets/config.yaml` for customization options including folder templates and subtitle preferences.
108
+
109
+ ## Disclaimer
110
+
111
+ This is an unofficial tool and is not affiliated with Yle. Downloading is intended for personal use of content that Yle makes available to you; respect Yle's terms of service and applicable copyright law. You are responsible for how you use it.
112
+
113
+ ## Use as an agent skill
114
+
115
+ `SKILL.md` makes this repo usable as a skill in [Hermes Agent](https://hermes-agent.nousresearch.com) and OpenClaw.
116
+ Clone it into the agent's skills directory (for Hermes e.g. `~/.hermes/skills/<category>/yle-areena-dvr`,
117
+ for OpenClaw `<workspace>/skills/yle-areena-dvr`), run `uv sync` there, and copy `.env.template` to `.env`.
118
+ Python 3.12-3.14 is required (3.13 is tested).
119
+
120
+ ## License
121
+
122
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,95 @@
1
+ # Yle Areena DVR
2
+
3
+ A Python tool for searching, scraping, and downloading movies and series from Yle Areena with integrated TMDb ratings and flexible naming templates.
4
+
5
+ ## Features
6
+ - **Yle Areena Search**: Find movies by query or category.
7
+ - **Scrape Curated Lists**: Extract movies directly from Areena's curated lists (e.g., "Katsotuimmat leffat").
8
+ - **TMDb Ratings**: Automatically fetch and filter by TMDb ratings (The Movie Database). Excellent multi-language support.
9
+ - **yt-dlp Integration**: High-quality downloads with subtitle support.
10
+ - **Flexible Organization**: Customize your folder structure and file naming via `config.yaml`.
11
+ - **Modern Python**: Built with Python 3.12+, Pydantic 2, and managed entirely with `uv`.
12
+
13
+ ## Installation
14
+
15
+ This project is built using `uv`, an extremely fast Python package and project manager.
16
+
17
+ ```bash
18
+ # Clone the repository
19
+ git clone https://github.com/junousia/yle-areena-dvr.git
20
+ cd yle-areena-dvr
21
+
22
+ # Sync the environment
23
+ uv sync
24
+
25
+ # Or install it globally as a tool
26
+ uv tool install .
27
+ ```
28
+
29
+ ## Setup
30
+
31
+ 1. Copy `.env.template` to `.env`:
32
+ ```bash
33
+ cp .env.template .env
34
+ ```
35
+ 2. Fill in your `TMDB_API_KEY` (free from themoviedb.org). `YLE_APP_ID` and `YLE_APP_KEY` are **optional**: by default the tool reads the keys that Areena's own web frontend embeds in its pages at runtime; set them only to override that.
36
+ 3. Customize `assets/config.yaml` to change where your movies are saved.
37
+
38
+ ## Usage
39
+
40
+ If you installed it via `uv tool install .`, you can run `yle-dvr` directly. Otherwise, use `uv run yle-dvr` inside the project directory.
41
+
42
+ ### Search for Programs
43
+ ```bash
44
+ uv run yle-dvr search --query "Metsolat" --limit 5 --min-rating 7.0
45
+
46
+ # Search for expiring programs
47
+ uv run yle-dvr search --only-expiring
48
+
49
+ # Search for recently added programs
50
+ uv run yle-dvr search --only-new
51
+
52
+ # You can also get machine-readable output for AI agents:
53
+ uv run yle-dvr search --query "Action" --json
54
+ ```
55
+
56
+ ### Scrape Curated Lists (Movies or Series)
57
+ ```bash
58
+ # Scrape movies
59
+ uv run yle-dvr scrape --url "https://areena.yle.fi/tv/ohjelmat/57-1BbXLDz6v" --min-rating 7.5
60
+
61
+ # Scrape series
62
+ uv run yle-dvr scrape --url "https://areena.yle.fi/tv/ohjelmat/57-p8JeXvBA0"
63
+ ```
64
+
65
+ ### Download a Program (Movie or Series)
66
+ ```bash
67
+ uv run yle-dvr download --id "1-2345678"
68
+ ```
69
+
70
+ ### Look Up Full Details for Suitability (Overview, Genres, Cast)
71
+ ```bash
72
+ # From a program already in the local DB
73
+ uv run yle-dvr details --id "1-2345678" --json
74
+
75
+ # Directly by title, no DB entry required
76
+ uv run yle-dvr details --title "Fight Club" --year 1999 --json
77
+ ```
78
+
79
+ ## Configuration
80
+ See `assets/config.yaml` for customization options including folder templates and subtitle preferences.
81
+
82
+ ## Disclaimer
83
+
84
+ This is an unofficial tool and is not affiliated with Yle. Downloading is intended for personal use of content that Yle makes available to you; respect Yle's terms of service and applicable copyright law. You are responsible for how you use it.
85
+
86
+ ## Use as an agent skill
87
+
88
+ `SKILL.md` makes this repo usable as a skill in [Hermes Agent](https://hermes-agent.nousresearch.com) and OpenClaw.
89
+ Clone it into the agent's skills directory (for Hermes e.g. `~/.hermes/skills/<category>/yle-areena-dvr`,
90
+ for OpenClaw `<workspace>/skills/yle-areena-dvr`), run `uv sync` there, and copy `.env.template` to `.env`.
91
+ Python 3.12-3.14 is required (3.13 is tested).
92
+
93
+ ## License
94
+
95
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: yle-areena-dvr
3
+ description: Search, scrape, enrich (TMDb), and download Yle Areena movies/series with Plex-friendly naming and local DB workflows.
4
+ ---
5
+
6
+ # Yle Areena DVR Skill
7
+
8
+ Use `uv run yle-dvr ...`.
9
+
10
+ ## Core commands
11
+
12
+ - `search` → query local DB
13
+ - `scrape` → scrape Areena list page into DB (+ TMDb enrich)
14
+ - `details` → fetch full TMDb detail (overview, genres, cast, runtime) for one title, to judge suitability
15
+ - `download` → download by Areena ID
16
+ - `naming` → list naming presets
17
+ - `backfill-years` → fill missing DB years from TMDb
18
+
19
+ ## Judging suitability with `details`
20
+
21
+ `search`/`scrape` only carry a title, TMDb rating, and year — not enough to judge whether a movie
22
+ is actually a good fit. Before recommending or auto-downloading something, look it up:
23
+
24
+ ```bash
25
+ # By Areena ID already in the local DB
26
+ uv run yle-dvr details --id "1-70111573" --json
27
+
28
+ # By title directly (no DB entry needed)
29
+ uv run yle-dvr details --title "Fight Club" --year 1999 --json
30
+
31
+ # Series (default type is "program", i.e. movie)
32
+ uv run yle-dvr details --title "Breaking Bad" --type series --json
33
+ ```
34
+
35
+ Returns `overview` (plot summary), `genres`, `cast`, `directors`, `runtime_minutes`, `tagline`,
36
+ `vote_average`/`vote_count`, and `keywords` — enough to actually reason about whether a title
37
+ matches what the user wants, instead of guessing from the title alone.
38
+
39
+ If TMDb is unreachable (network blip), the response is `{"ok": false, "error": "TMDb unreachable, try again: ..."}` —
40
+ distinct from `{"ok": false, "error": "No TMDb match for '<title>'"}`, which means it genuinely isn't
41
+ on TMDb. Retry on the former; don't treat it as "not found".
42
+
43
+ ## Key improvements
44
+
45
+ - TMDb year support in DB + download path
46
+ - Backfill command for existing records in DB
47
+ - Naming preset support and custom output templates in CLI
48
+ - JSON output on all key commands
49
+
50
+ ## Examples
51
+
52
+ ```bash
53
+ # Scrape list and enrich with TMDb
54
+ uv run yle-dvr scrape --url "https://areena.yle.fi/tv/ohjelmat/57-1BbXLDz6v"
55
+
56
+ # Search DB
57
+ uv run yle-dvr search --query "Three Billboards" --json
58
+
59
+ # Show naming presets
60
+ uv run yle-dvr naming
61
+
62
+ # Download with preset naming
63
+ uv run yle-dvr download --id "1-70111573" --naming-preset "plex-movie"
64
+
65
+ # Download with explicit output template
66
+ uv run yle-dvr download --id "1-70111573" --output-template "{title} ({year}) [YLE].%(ext)s"
67
+
68
+ # Dry run (resolve naming/path without downloading)
69
+ uv run yle-dvr download --id "1-70111573" --naming-preset "plex-movie" --dry-run
70
+
71
+ # Backfill missing years from TMDb for existing DB rows
72
+ uv run yle-dvr backfill-years --limit 500
73
+ ```
74
+
75
+ ## Naming format
76
+
77
+ Configured in `assets/config.yaml` under `naming`:
78
+
79
+ - `movie_filename`
80
+ - `series_filename`
81
+ - `presets` (e.g. `plex-movie`, `plex-series`)
82
+
83
+ Download precedence:
84
+
85
+ 1. `--output-template`
86
+ 2. `--naming-preset`
87
+ 3. Default `movie_filename` / `series_filename`
88
+
89
+ ## TMDb requirement
90
+
91
+ Set `TMDB_API_KEY` in `.env` to enable TMDb year/rating enrichment and backfill.
92
+
93
+ Without TMDb key, backfill is skipped and year enrichment is limited.
@@ -0,0 +1,26 @@
1
+ # Yle Areena DVR Configuration
2
+
3
+ # File Naming and Directory Structure Templates
4
+ # Available tokens: {title}, {year}, {id}, {genres}, {rating}
5
+ naming:
6
+ movie_folder: "movies"
7
+ movie_filename: "{title} ({year}).%(ext)s"
8
+ series_folder: "series/{title}"
9
+ series_filename: "{title} - S{season_number}E{episode_number} - {episode_title}.%(ext)s"
10
+ presets:
11
+ plex-movie: "{title} ({year}).%(ext)s"
12
+ plex-series: "{title} - S{season_number}E{episode_number} - {episode_title}.%(ext)s"
13
+ title-only: "{title}.%(ext)s"
14
+
15
+ # Download Settings
16
+ download:
17
+ base_directory: "./downloads"
18
+ format: "bv*+ba/b"
19
+ merge_output_format: "mkv"
20
+ subtitles:
21
+ enabled: true
22
+ languages: ["fi", "sv", "en"]
23
+
24
+ # Rating Filtering (Min rating to auto-download)
25
+ filters:
26
+ min_imdb_rating: 7.0
@@ -0,0 +1 @@
1
+ Placeholder for assets.
@@ -0,0 +1,42 @@
1
+ [project]
2
+ name = "yle-areena-dvr"
3
+ version = "0.1.0"
4
+ description = "A tool for Yle Areena to download movies and series of interest."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [{ name = "Jukka Nousiainen" }]
9
+ keywords = ["yle", "areena", "dvr", "yt-dlp", "tmdb", "agent-skill"]
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "Programming Language :: Python :: 3.12",
13
+ "Programming Language :: Python :: 3.13",
14
+ "Programming Language :: Python :: 3.14",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ requires-python = ">=3.12,<3.15"
18
+ dependencies = [
19
+ "yt-dlp",
20
+ "httpx",
21
+ "aiosqlite",
22
+ "sqlmodel",
23
+ "pydantic",
24
+ "pydantic-settings",
25
+ "pydantic-cli",
26
+ "pyyaml",
27
+ "greenlet",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/junousia/yle-areena-dvr"
32
+ Issues = "https://github.com/junousia/yle-areena-dvr/issues"
33
+
34
+ [project.scripts]
35
+ yle-dvr = "yle_areena_dvr.cli:main"
36
+
37
+ [build-system]
38
+ requires = ["hatchling"]
39
+ build-backend = "hatchling.build"
40
+
41
+ [tool.hatch.build.targets.wheel.force-include]
42
+ "assets/config.yaml" = "yle_areena_dvr/default_config.yaml"
@@ -0,0 +1,17 @@
1
+ # Reference Documentation for Yle Areena Dvr
2
+
3
+ This is a placeholder for detailed reference documentation.
4
+ Replace with actual reference content or delete if not needed.
5
+
6
+ ## Structure Suggestions
7
+
8
+ ### API Reference Example
9
+ - Overview
10
+ - Authentication
11
+ - Endpoints with examples
12
+ - Error codes
13
+
14
+ ### Workflow Guide Example
15
+ - Prerequisites
16
+ - Step-by-step instructions
17
+ - Best practices
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Example helper script for yle-areena-dvr
5
+ *
6
+ * This is a placeholder script that can be executed directly.
7
+ * Replace with actual implementation or delete if not needed.
8
+ *
9
+ * Example real scripts from other skills:
10
+ * - pdf/scripts/fill_fillable_fields.cjs - Fills PDF form fields
11
+ * - pdf/scripts/convert_pdf_to_images.cjs - Converts PDF pages to images
12
+ *
13
+ * Agentic Ergonomics:
14
+ * - Suppress tracebacks.
15
+ * - Return clean success/failure strings.
16
+ * - Truncate long outputs.
17
+ */
18
+
19
+ async function main() {
20
+ try {
21
+ // TODO: Add actual script logic here.
22
+ // This could be data processing, file conversion, API calls, etc.
23
+
24
+ // Example output formatting for an LLM agent
25
+ process.stdout.write("Success: Processed the task.\n");
26
+ } catch (err) {
27
+ // Trap the error and output a clean message instead of a noisy stack trace
28
+ process.stderr.write(`Failure: ${err.message}\n`);
29
+ process.exit(1);
30
+ }
31
+ }
32
+
33
+ main();