fetchtv
Version:
A Node.js CLI tool to manage Fetch TV recordings.
353 lines (256 loc) • 11.6 kB
Markdown
# fetchtv
[](https://www.npmjs.com/package/fetchtv)
[](https://www.gnu.org/licenses/gpl-3.0)
A Node.js CLI tool to download Fetch TV recordings.
Based on [`lingfish/fetchtv-cli`](https://github.com/lingfish/fetchtv-cli) (Python) which is based on [`jinxo13/FetchTV-Helpers`](https://github.com/jinxo13/FetchTV-Helpers) (also Python).
## Contents
- [Demo](#demo)
- [Quick Start](#quick-start)
- [Installation](#installation)
- [Usage](#usage)
- [Template Variables](#template-variables)
- [Examples](#examples)
- [Disclaimer](#disclaimer)
- [Support](#support)
## Demo
https://gist.github.com/user-attachments/assets/61dfab62-a715-4cc3-a4d1-93ee0db43827
## Quick Start
- [Install](#installation) `fetchtv`
- [Run](#usage) `fetchtv`
## Installation
- [NPX](#installation-npx) (Easiest)
- [Node.js from Source](#installation-nodejs-from-source)
- [Docker from Source](#installation-docker-from-source)
### Installation: NPX
> [!NOTE]<br>
> NPX requires [Node.js](https://nodejs.org/en/download) installed and running on your system (suggestion: use [Volta](https://volta.sh)).
The easiest way to install `fetchtv` is via NPX.
First, ensure Node.js is running:
```console
node --version # Ideally >= v22.x but fetchtv is >= v18.x compatible
```
Then, run `fetchtv` via NPX:
```console
npx fetchtv # Run the tool
npx fetchtv@latest # (optional) "@latest" ensures package is up-to-date
npx -y fetchtv@latest # (optional) "-y" flag skips any prompts
npx fetchtv info
npx fetchtv shows
npx fetchtv recordings
# etc…
```
> If you encounter permissions errors with `npx` try running `npx clear-npx-cache` prior to running `npx -y fetchtv` (this clears the cache and re-downloads the package).
### Installation: Node.js from Source
> [!NOTE]<br>
> Node.js from source requires [Node.js](https://nodejs.org/en/download) installed and running on your system (suggestion: use [Volta](https://volta.sh)).
1. Clone the `fetchtv` repository:<br>
```console
git clone https://github.com/furey/fetchtv.git
```
1. Navigate to the cloned repository directory:<br>
```console
cd /path/to/fetchtv
```
1. Ensure Node.js is running:<br>
```console
node --version # Ideally >= v22.x but fetchtv is >= v18.x compatible
```
1. Install Node.js dependencies:<br>
```console
npm ci
```
1. Run `fetchtv`:<br>
```console
node fetchtv.js
node fetchtv.js info
node fetchtv.js recordings
node fetchtv.js shows
# etc…
```
#### Optional: Link `fetchtv` Tool
You may optionally link the `fetchtv` tool to your system path for easier access:
```console
npm link
```
This will create a symlink to the `fetchtv` command in your global `node_modules` directory, allowing you to run it from anywhere in your terminal:
```console
fetchtv
fetchtv info
fetchtv shows
fetchtv recordings
# etc…
```
To uninstall the linked tool, run:
```console
npm unlink
```
### Installation: Docker from Source
> [!NOTE]<br>
> Docker from source requires [Docker](https://docs.docker.com/get-started/get-docker) installed and running on your system.
1. Clone the `fetchtv` repository:<br>
```console
git clone https://github.com/furey/fetchtv.git
```
1. Navigate to the cloned repository directory:<br>
```console
cd /path/to/fetchtv
```
1. Ensure Docker is running:<br>
```console
docker --version # Ideally >= v27.x
```
1. Build the Docker image:<br>
```console
docker build -t fetchtv .
```
1. Run the container:<br>
```console
docker run -t --rm fetchtv
docker run -t --rm fetchtv info
docker run -t --rm fetchtv shows
docker run -t --rm fetchtv recordings
# etc…
```
#### UPnP/SSDP Discovery Issues
UPnP/SSDP discovery can be unreliable in Docker containers.
To work around this, it's recommended to specify your Fetch TV server's IP address directly with the `--ip` (and optionally `--port`) option when running the container. For example:
```console
docker run -t --rm fetchtv
docker run -t --rm fetchtv info --ip=192.168.86.71
docker run -t --rm fetchtv shows --ip=192.168.86.71
docker run -t --rm fetchtv recordings --ip=192.168.86.71
# etc…
```
## Usage
If you [installed via NPX](#installation-npx), you can run it from anywhere:
```console
npx fetchtv <COMMAND> [OPTIONS]
```
If you [installed from Node.js source](#installation-nodejs-from-source), you can run it from the cloned repo directory:
```console
cd /path/to/fetchtv
node fetchtv.js <COMMAND> [OPTIONS]
```
If you [linked the tool](#optional-link-fetchtv-tool) after installing from source, you can run it from anywhere:
```console
fetchtv <COMMAND> [OPTIONS]
```
| Command/Option | Alias | Type | Description |
| ---------------- | ----- | --------- | ------------------------------------------------------------------------------- |
| `info` | | `command` | Returns Fetch TV server details |
| `recordings` | | `command` | List episode recordings |
| `shows` | | `command` | List show titles and not the episodes within |
| `--ip` | | `string` | Specify the IP Address of the Fetch TV server |
| `--port` | | `number` | Specify the port of the Fetch TV server (default: `49152`) |
| `--show` | `-s` | `array` | Filter recordings to show titles containing the specified text (repeatable) |
| `--exclude` | `-e` | `array` | Filter recordings to show titles NOT containing the specified text (repeatable) |
| `--title` | `-t` | `array` | Filter recordings to episode titles containing the specified text (repeatable) |
| `--is-recording` | | `boolean` | Filter recordings to only those that are currently recording |
| `--save` | | `string` | Save recordings to the specified path |
| `--template` | | `string` | Template for save path/filename structure (uses --save as base path) |
| `--for-plex` | | `boolean` | Uses Plex-compatible template for saving recordings (overrides --template) |
| `--overwrite` | `-o` | `boolean` | Overwrite existing files when saving |
| `--json` | `-j` | `boolean` | Output show/recording/save results in JSON |
| `--debug` | `-d` | `boolean` | Enable verbose logging for debugging |
| `--help` | `-h` | `boolean` | Show help message |
### Template Variables
> []<br>
> When using `--template`, the template string must be enclosed in single quotes (`'`) to prevent shell expansion. For example:<br>
> ```console
>fetchtv recordings --save=./downloads --template='${show_title}/${recording_title}.${ext}'
> ```
When using `--template`, the following variables are available:
| Variable | Description | Example |
| -------------------------- | -------------------------------- | ---------------------------------------------- |
| `${show_title}` | Title of the show | `Australian Survivor` |
| `${recording_title}` | Title of the recording/episode | `S10 E2 - Episode 2 of Season 10 - Tue 18 Feb` |
| `${season_number}` | Season number (if available) | `10` |
| `${season_number_padded}` | Season number with leading zero | `10` |
| `${episode_number}` | Episode number (if available) | `2` |
| `${episode_number_padded}` | Episode number with leading zero | `02` |
| `${ext}` | File extension (ts, mp4, etc) | `ts` |
#### Plex-Compatible Template
The `--for-plex` option uses a predefined template optimized for Plex media server:
```js
`${show_title}/Season ${season_number}/${show_title} - S${season_number}E${episode_number_padded}.${ext}`
```
#### Example Templates
Save recordings with show folder:
```
${show_title}/${recording_title}.${ext}
```
Save recordings with show folder and `SXXEXX` episode naming:
```
${show_title}/S${season_number_padded}E${episode_number_padded}.${ext}
```
Save recordings with show and season folders:
```
${show_title}/Season ${season_number}/${recording_title}.${ext}
```
## Examples
> [!NOTE]<br>
> The following examples assume you have a Fetch TV server on your local network and you've [linked the tool](#optional-link-fetchtv-tool) to your system path.
Search for Fetch TV servers:
```console
fetchtv
```
Display Fetch box details (uses auto-discovery):
```console
fetchtv info
```
List recorded show titles:
```console
fetchtv shows --ip=192.168.86.71
```
List recordings:
```console
fetchtv recordings --ip=192.168.86.71
```
List recordings and output as JSON:
```console
fetchtv recordings --ip=192.168.86.71 --json
```
Save new recordings to `./downloads` (creates directory if needed):
```console
fetchtv recordings --ip=192.168.86.71 --save=./downloads
```
Save new recordings but exclude show titles containing `News`:
```console
fetchtv recordings --ip=192.168.86.71 --exclude=News --save=./downloads
```
Save new episodes for the show `MasterChef`:
```console
fetchtv recordings --ip=192.168.86.71 --show=MasterChef --save=./downloads
```
Save & overwrite specific `MasterChef` episodes containing `S04E12` or `S04E13`:
```console
fetchtv recordings --ip=192.168.86.71 --show=MasterChef --title=S04E12 --title=S04E13 --save=./downloads --overwrite
```
List only items currently being recorded:
```console
fetchtv recordings --ip=192.168.86.71 --is-recording
```
Save only items currently being recorded:
```console
fetchtv recordings --ip=192.168.86.71 --is-recording --save=./in-progress
```
Save recordings using a custom path template:
```console
fetchtv recordings --ip=192.168.86.71 --save=./downloads --template='${show_title}/${recording_title}.${ext}'
```
Save recordings in Plex-compatible path format:
```console
fetchtv recordings --ip=192.168.86.71 --save=./media --for-plex
```
## Disclaimer
This project:
- Is licensed under the [GNU GPLv3 License](./LICENSE.txt).
- Is not affiliated with or endorsed by Fetch TV.
- Is a derivative work based on [`lingfish/fetchtv-cli`](https://github.com/lingfish/fetchtv-cli).
- Is written with the assistance of AI and may contain errors.
- Is intended for educational and experimental purposes only.
- Is provided as-is with no warranty—please use at your own risk.
## Support
If you've found this project helpful consider supporting my work through:
[Buy Me a Coffee](https://www.buymeacoffee.com/furey) | [GitHub Sponsorship](https://github.com/sponsors/furey)
Contributions help me continue developing and improving this tool, allowing me to dedicate more time to add new features and ensuring it remains a valuable resource for the community.