Skip to content

Commit

Permalink
- Rewrite nearly the whole thing for better parsing, support, readabi…
Browse files Browse the repository at this point in the history
…lity, etc. (OOP forever!)

- Consolidate Plex API config with schedules, now in config.yaml
- Changes to schema for schedules
- No more priority of, e.g. date_range over monthly
- No more default
- `misc` reworked to `always`
- Update Docker files
- Update README
- Delete old files, linting stuff (screw mypy)
  • Loading branch information
nwithan8 committed Dec 9, 2023
1 parent 7a8f97b commit 1616d91
Show file tree
Hide file tree
Showing 25 changed files with 1,232 additions and 1,500 deletions.
5 changes: 0 additions & 5 deletions .pylintrc

This file was deleted.

15 changes: 2 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,8 @@ COPY requirements.txt requirements.txt
# Install Python requirements
RUN pip3 install --no-cache-dir -r requirements.txt

# Make Docker /config volume for optional config file
VOLUME /config

# Copy logging.conf file from build machine to Docker /config folder
COPY logging.conf /config/

# Copy example config file from build machine to Docker /config folder
# Also copies any existing config.ini file from build machine to Docker /config folder, (will cause the bot to use the existing config file if it exists)
COPY config.ini* /config/

# Copy example schedule file from build machine to Docker /config folder
# Also copies any existing schedules.yaml file from build machine to Docker /config folder, (will cause the bot to use the existing schedule file if it exists)
COPY schedules.yaml* /config/
# Copy config file from build machine to Docker /config folder
COPY config.yaml /

# Make Docker /logs volume for log file
VOLUME /logs
Expand Down
95 changes: 52 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,35 @@ Install Python requirements:
pip install -r requirements.txt
```

Copy `config.ini.sample` to `config.ini` and complete the `[auth]` section with your Plex server information.

Copy `schedules.yaml.sample` to `schedules.yaml` and [edit your schedule](#schedule-rules).
Copy `config.yaml.example` to `config.yaml`, provide your `plex` details and [edit your schedule](#schedule-rules).

Run the script:

```sh
python schedule_preroll.py
python run.py
```

#### Advanced Usage

```sh
$ python schedule_preroll.py -h
$ python run.py -h

usage: schedule_preroll.py [-h] [-v] [-l LOG_CONFIG_FILE] [-c CONFIG_FILE] [-s SCHEDULE_FILE]
usage: run.py [-h] [-c CONFIG] [-l LOG] [-d]

Automate scheduling of pre-roll intros for Plex
Plex Prerolls - A tool to manage prerolls for Plex

optional arguments:
options:
-h, --help show this help message and exit
-v, --version show the version number and exit
-lc LOG_CONFIG_FILE, --logconfig-path LOG_CONFIG_FILE
Path to logging config file. [Default: ./logging.conf]
-c CONFIG_FILE, --config-path CONFIG_FILE
Path to Config.ini to use for Plex Server info. [Default: ./config.ini]
-s SCHEDULE_FILE, --schedule-path SCHEDULE_FILE
Path to pre-roll schedule file (YAML) to be use. [Default: ./schedules.yaml]
-c CONFIG, --config CONFIG
Path to config file. Defaults to 'config.yaml'
-l LOG, --log LOG Log file directory. Defaults to 'logs/'
-d, --dry-run Dry run, no real changes made
```

##### Example

```sh
python schedule_preroll.py \
-c path/to/custom/config.ini \
-s path/to/custom/schedules.yaml \
-lc path/to/custom/logger.conf
python run.py -c path/to/custom/config.yaml -l path/to/custom/log/directory/ # Trailing slash required
```

### Run as Docker Container
Expand All @@ -94,18 +86,18 @@ docker run -d \
-e PGID=1000 \
-e TZ=Etc/UTC \
-e CRON_SCHEDULE="0 0 * * *" \
-v /path/to/config:/config \
-v /path/to/config:/ \
-v /path/to/logs:/logs \
--restart unless-stopped \
nwithan8/plex_prerolls:latest
```

#### Paths and Environment Variables

| Path | Description |
|-----------|--------------------------------------------------------------------------------------|
| `/config` | Path to config files (`config.ini` and `schedules.yaml` should be in this directory) |
| `/logs` | Path to log files (`schedule_preroll.log` will be in this directory) |
| Path | Description |
|---------|-------------------------------------------------------------------|
| `/` | Path to config files (`config.yaml` should be in this directory) |
| `/logs` | Path to log files (`Plex Prerolls.log` will be in this directory) |

| Environment Variable | Description |
|----------------------|-------------------------------------------------------------------|
Expand All @@ -118,27 +110,28 @@ docker run -d \

## Schedule Rules

Schedules follow the following priority:
1. **misc**: Items listed in `always_use` will always be included (appended) to the preroll list
- If you have a large set of prerolls, you can provide all paths and use `random_count` to randomly select a smaller subset of the list to use on each run.
Any entry whose schedule falls within the current date/time at the time of execution will be added to the preroll.

2. **date_range**: Schedule based on a specific date/time range
You can define as many schedules as you want, in the following categories (order does not matter):

3. **weekly**: Schedule based on a specific week of the year
1. **always**: Items listed here will always be included (appended) to the preroll list
- If you have a large set of prerolls, you can provide all paths and use `random_count` to randomly select a smaller
subset of the list to use on each run.

4. **monthly**: Schedule based on a specific month of the year
2. **date_range**: Schedule based on a specific date/time range (including [wildcards](#date-range-section-scheduling))

5. **default**: Default item to use if none of the above apply
3. **weekly**: Schedule based on a specific week of the year

For any conflicting schedules, the script tries to find the closest matching range and highest priority.
4. **monthly**: Schedule based on a specific month of the year

### Advanced Scheduling

#### Date Range Section Scheduling

`date_range` entries can accept both dates (`yyyy-mm-dd`) and datetimes (`yyyy-mm-dd hh:mm:ss`, 24-hour time).

`date_range` entries can also accept wildcards for any of the date/time fields. This can be useful for scheduling recurring events, such as annual events, "first-of-the-month" events, or even hourly events.
`date_range` entries can also accept wildcards for any of the date/time fields. This can be useful for scheduling
recurring events, such as annual events, "first-of-the-month" events, or even hourly events.

```yaml
date_range:
Expand All @@ -147,31 +140,46 @@ date_range:
# Each entry requires start_date, end_date, path values
- start_date: 2020-01-01 # Jan 1st, 2020
end_date: 2020-01-02 # Jan 2nd, 2020
path: /path/to/video.mp4
paths:
- /path/to/video.mp4
- /path/to/another/video.mp4
weight: 2 # Add these paths to the list twice (make up greater percentage of prerolls - more likely to be selected)
- start_date: xxxx-07-04 # Every year on July 4th
end_date: xxxx-07-04 # Every year on July 4th
path: /path/to/video.mp4
paths:
- /path/to/video.mp4
- /path/to/another/video.mp4
weight: 1
- start_date: xxxx-xx-02 # Every year on the 2nd of every month
- name: "My Schedule" # Optional name for logging purposes
start_date: xxxx-xx-02 # Every year on the 2nd of every month
end_date: xxxx-xx-03 # Every year on the 3rd of every month
path: /path/to/video.mp4
paths:
- /path/to/video.mp4
- /path/to/another/video.mp4
weight: 1
- start_date: xxxx-xx-xx 08:00:00 # Every day at 8am
end_date: xxxx-xx-xx 09:30:00 # Every day at 9:30am
path: /path/to/holiday_video.mp4
paths:
- /path/to/video.mp4
- /path/to/another/video.mp4
weight: 1
```
You should [adjust your cron schedule](#scheduling-script) to run the script more frequently if you use this feature.
`date_range` entries also accept an optional `weight` value that can be used to adjust the emphasis of this entry over others by adding the listed paths multiple times. Since Plex selects a random preroll from the list of paths, having the same path listed multiple times increases its chances of being selected over paths that only appear once. This allows you to combine, e.g. a `date_range` entry with a `misc` entry, but place more weight/emphasis on the `date_range` entry.
`date_range` entries also accept an optional `weight` value that can be used to adjust the emphasis of this entry over
others by adding the listed paths multiple times. Since Plex selects a random preroll from the list of paths, having the
same path listed multiple times increases its chances of being selected over paths that only appear once. This allows
you to combine, e.g. a `date_range` entry with a `misc` entry, but place more weight/emphasis on the `date_range` entry.

`date_range` entries also accept an optional `name` value that can be used to identify the schedule in the logs.

---

## Scheduling Script

**NOTE:** Scheduling is handled automatically in the Docker version of this script via the `CRON_SCHEDULE` environment variable.
**NOTE:** Scheduling is handled automatically in the Docker version of this script via the `CRON_SCHEDULE` environment
variable.

### Linux

Expand All @@ -184,13 +192,14 @@ crontab -e
Place desired schedule (example below for every day at midnight)

```sh
0 0 * * * python /path/to/schedule_preroll.py >/dev/null 2>&1
0 0 * * * python /path/to/run.py >/dev/null 2>&1
```

You can also wrap the execution in a shell script (useful if running other scripts/commands, using venv encapsulation, customizing arguments, etc.)
You can also wrap the execution in a shell script (useful if running other scripts/commands, using venv encapsulation,
customizing arguments, etc.)

```sh
0 0 * * * /path/to/schedule_preroll.sh >/dev/null 2>&1
0 0 * * * /path/to/run_prerolls.sh >/dev/null 2>&1
```

Schedule as frequently as needed for your schedule (ex: hourly, daily, weekly, etc.)
Expand Down
7 changes: 0 additions & 7 deletions config.ini.sample

This file was deleted.

79 changes: 79 additions & 0 deletions config.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# All keys must be in lowercase
# All paths will be case-sensitive based on your environment (Linux, Windows)

plex:
url: http://localhost:32400 # URL to your Plex server
token: thisismyplextoken # Your Plex token

# Always include these pre-rolls
always:
enabled: true
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"
count: 10 # Optional, randomly select X many videos from the list rather than all of them
weight: 1 # Optional, how much to emphasize these pre-rolls over others (higher = more likely to play)

# Schedule prerolls by date and time frames
date_range:
enabled: true
ranges:
- name: "New Years" # Optional name for logging purposes
start_date: 2020-01-01 # Jan 1st, 2020
end_date: 2020-01-02 # Jan 2nd, 2020
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"
weight: 2 # Optional, add these paths to the list twice (make up greater percentage of prerolls - more likely to be selected)
- start_date: xxxx-07-04 # Every year on July 4th
end_date: xxxx-07-04 # Every year on July 4th
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"
- start_date: xxxx-xx-02 # Every year on the 2nd of every month
end_date: xxxx-xx-03 # Every year on the 3rd of every month
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"
- start_date: xxxx-xx-xx 08:00:00 # Every day at 8am
end_date: xxxx-xx-xx 09:30:00 # Every day at 9:30am
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"

# Schedule prerolls by week of the year
weekly:
enabled: false
weeks:
- number: 1 # First week of the year
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"
weight: 1 # Optional, how much to emphasize these pre-rolls over others (higher = more likely to play)
- number: 2 # Second week of the year
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"

# Schedule prerolls by month of the year
monthly:
enabled: false
months:
- number: 1 # January
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"
weight: 1 # Optional, how much to emphasize these pre-rolls over others (higher = more likely to play)
- number: 2 # February
paths:
- "path/to/video1.mp4"
- "path/to/video2.mp4"
- "path/to/video3.mp4"
6 changes: 6 additions & 0 deletions consts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
APP_NAME = "Plex Prerolls"
APP_DESCRIPTION = "A tool to manage prerolls for Plex"
DEFAULT_CONFIG_PATH = "config.yaml"
DEFAULT_LOG_DIR = "logs/"
CONSOLE_LOG_LEVEL = "INFO"
FILE_LOG_LEVEL = "DEBUG"
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ services:
plex_prerolls:
image: nwithan8/plex_prerolls:latest
volumes:
- /path/to/config:/config
- /path/to/config:/
- /path/to/logs:/logs
environment:
CRON_SCHEDULE: "0 0 * * *" # Run every day at midnight, see https://crontab.guru/ for help
DRY_RUN: "false" # Set to true to test without actually downloading
TZ: America/New_York
11 changes: 10 additions & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ mkdir -p /etc/cron.d
# Read cron schedule from environment variable
CRON_SCHEDULE=${CRON_SCHEDULE:-"0 0 * * *"} # Default to midnight every day if not supplied

# Add "--dry-run" flag if DRY_RUN is set to true
if [ "$DRY_RUN" = "true" ]; then
DRY_RUN_FLAG="--dry-run"
else
DRY_RUN_FLAG=""
fi

# DRY_RUN_FLAG="--dry-run"

# Schedule cron job with supplied cron schedule
echo "$CRON_SCHEDULE python3 /schedule_preroll.py -c /config/config.ini -s /config/schedules.yaml -lc /config/logging.conf > /proc/1/fd/1 2>/proc/1/fd/2" > /etc/cron.d/schedule_preroll
echo "$CRON_SCHEDULE python3 /run.py -c /config.yaml -l /logs $DRY_RUN_FLAG > /proc/1/fd/1 2>/proc/1/fd/2" > /etc/cron.d/schedule_preroll

# Give execution rights on the cron job
chmod 0644 /etc/cron.d/schedule_preroll
Expand Down
36 changes: 0 additions & 36 deletions logging.conf

This file was deleted.

Empty file added modules/__init__.py
Empty file.
Loading

0 comments on commit 1616d91

Please sign in to comment.