Compare commits
10
Commits
47b19f9945
..
btc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3d0d71ac8 | ||
|
|
9d16b1efd1 | ||
|
|
3cd6580dd9 | ||
|
|
76029b6102 | ||
|
|
a9bf973dc5 | ||
|
|
d9b568058b | ||
|
|
58e5dd177e | ||
|
|
9ef90db07b | ||
|
|
458506e798 | ||
|
|
874c759f85 |
No files matched your search
@@ -23,13 +23,12 @@ Having Plex and Jellyfin separate from the rest of my docker infrastructure allo
|
|||||||
**Storage:**
|
**Storage:**
|
||||||
* `/`: 1 TB NVME SSD
|
* `/`: 1 TB NVME SSD
|
||||||
* `/vm_storage`: 2x 240 GB SSD in ZFS mirror for config and data files
|
* `/vm_storage`: 2x 240 GB SSD in ZFS mirror for config and data files
|
||||||
* `/mnt/storage`: mergerfs + SnapRAID pool totaling 150 TiB usable storage with single disk parity (YOLO). Drives run btrfs allowing me to utilize [snapraid-btrfs](https://wiki.selfhosted.show/tools/snapraid-btrfs/) for instant snapshotting
|
* `/mnt/storage`: mergerfs + SnapRAID pool totaling ~90 TiB usable storage. Currently single parity disk but hoping to add a second one soon. Drives run btrfs allowing me to utilize [snapraid-btrfs](https://wiki.selfhosted.show/tools/snapraid-btrfs/) for instant snapshotting
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
* Flesh out backup strategy with btrfs snapshots and restic (separately)
|
* Flesh out backup strategy with btrfs snapshots and restic (separately)
|
||||||
* Potentially migrate media pool to ZFS. I've been lucky so far with no drive failures but realistically if I did have one fail, it would take ages to rebuild with single disk parity and I'd be wishing I had a more robust setup.
|
* Move everything to Arch VMs on Proxmox
|
||||||
* Move everything to Arch LXCs on Proxmox
|
|
||||||
* Possibly set up second Proxmox node for backups
|
* Possibly set up second Proxmox node for backups
|
||||||
* Immich for photo management
|
* Immich for photo management
|
||||||
* Look into [Wazuh](https://github.com/wazuh/wazuh) for threat prevention/detection
|
* Look into [Wazuh](https://github.com/wazuh/wazuh) for threat prevention/detection
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- name: restart searxng
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
restarted: true
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy settings file to destionation
|
||||||
|
template:
|
||||||
|
src: settings.yml
|
||||||
|
dest: "{{ data_dir }}/{{ role_name }}/settings.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
become: true
|
||||||
|
notify: restart searxng
|
||||||
|
|
||||||
|
- name: Start docker container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
searxng:
|
||||||
|
container_name: searxng
|
||||||
|
image: searxng/searxng
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/{{ role_name }}:/etc/searxng"
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- CHOWN
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.searxng.rule: "Host(`search.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.searxng.middlewares: lan-whitelist@file
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
command: redis-server --save "" --appendonly "no"
|
||||||
|
tmpfs:
|
||||||
|
- /var/lib/redis
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
- DAC_OVERRIDE
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,10 @@
|
|||||||
|
searxng_secret_key: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
33656138666464373665663339363665346566613637626131363335336535313131333265646539
|
||||||
|
3037373439643964343139383764386364623961383737610a313063613736316437366239663238
|
||||||
|
65333735633661316463336665353138623264396534383865363134613165636164303765356265
|
||||||
|
3865626366613966660a313738353339313133393765643136306361373061366132373130656531
|
||||||
|
61396230346333346636356562353733623332333662653164373630626339376433353663313862
|
||||||
|
61303230613135336662313531313836363466623162666233646231616333643536303233616231
|
||||||
|
62353866333465646162633738383866363338383932623335353038393130323932343363653233
|
||||||
|
62663465386661663262
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
server {
|
||||||
|
listen 3000 default_server;
|
||||||
|
listen [::]:3000 default_server;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location = /favicon.ico { access_log off; log_not_found off; }
|
||||||
|
location = /robots.txt { access_log off; log_not_found off; }
|
||||||
|
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
location /bar/ {
|
||||||
|
proxy_pass http://bar-assistant:3000/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /search/ {
|
||||||
|
proxy_pass http://meilisearch:7700/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://salt-rim:8080/;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
- name: Create service user
|
||||||
|
user:
|
||||||
|
name: "{{ role_name }}"
|
||||||
|
system: true
|
||||||
|
register: service_user
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create data directory
|
||||||
|
file:
|
||||||
|
path: "{{ data_dir }}/barassistant/barassistant"
|
||||||
|
state: directory
|
||||||
|
owner: 33
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy nginx.conf to destination
|
||||||
|
copy:
|
||||||
|
src: nginx.conf
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/nginx.conf"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Start docker container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
meilisearch:
|
||||||
|
image: getmeili/meilisearch:v1.12
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
environment:
|
||||||
|
MEILI_MASTER_KEY: "{{ meili_master_key }}"
|
||||||
|
MEILI_ENV: production
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/barassistant/meilisearch:/meili_data"
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
environment:
|
||||||
|
ALLOW_EMPTY_PASSWORD: "True"
|
||||||
|
|
||||||
|
bar-assistant:
|
||||||
|
container_name: bar-assistant
|
||||||
|
image: barassistant/server:v5
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
depends_on:
|
||||||
|
- meilisearch
|
||||||
|
- redis
|
||||||
|
environment:
|
||||||
|
APP_URL: "{{ base_url }}/bar"
|
||||||
|
LOG_CHANNEL: stderr
|
||||||
|
MEILISEARCH_KEY: "{{ meili_master_key }}"
|
||||||
|
MEILISEARCH_HOST: http://meilisearch:7700
|
||||||
|
REDIS_HOST: redis
|
||||||
|
ALLOW_REGISTRATION: "True"
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/barassistant/barassistant:/var/www/cocktails/storage/bar-assistant"
|
||||||
|
|
||||||
|
salt-rim:
|
||||||
|
image: barassistant/salt-rim:v4
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
depends_on:
|
||||||
|
- bar-assistant
|
||||||
|
environment:
|
||||||
|
API_URL: "{{ base_url }}/bar"
|
||||||
|
MEILISEARCH_URL: "{{ base_url }}/search"
|
||||||
|
BAR_NAME: "Cocktails"
|
||||||
|
DESCRIPTION: Why is the rum always gone?
|
||||||
|
DEFAULT_LOCALE: "en-US"
|
||||||
|
|
||||||
|
webserver:
|
||||||
|
image: nginx:alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
- default
|
||||||
|
volumes:
|
||||||
|
- "./nginx.conf:/etc/nginx/conf.d/default.conf"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.barassistant.rule: "Host(`cocktails.{{ personal_domain }}`)"
|
||||||
|
traefik.http.services.barassistant.loadbalancer.server.port: 3000
|
||||||
|
traefik.http.routers.bariassistant.middlewares: lan-whitelist@file
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
meili_master_key: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
61306335316339383330323264646132363837376264646235353562666239386463613431366361
|
||||||
|
3333666463623564393061616339393164353465633866320a303530613862386466383161623532
|
||||||
|
61653861653032303232666530623739303231363536316530386566313466333236613331303833
|
||||||
|
3734656334333366650a366261323139363635316264383966626237396338663030393931313532
|
||||||
|
33343737316535336539363135333834333462393330663038376132393661323866656132356566
|
||||||
|
39653732366333306134393965383339336330326566303230613362393366383561303939363937
|
||||||
|
64396230323664393236303939643337393034646637643766323938663961636639326466653332
|
||||||
|
30343132636534613835646163643832373835663030326635323236386361346133633964303137
|
||||||
|
36623631353931343861383232373231613837393936316635393838323466656330653835343932
|
||||||
|
64333432386133313363626630623837643237616132336664303963323062386365623266623333
|
||||||
|
343233663635306361333065313334313361
|
||||||
|
|
||||||
|
base_url: "https://cocktails.{{ personal_domain }}"
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
directory: /music
|
directory: /music
|
||||||
per_disc_numbering: yes
|
per_disc_numbering: yes
|
||||||
|
|
||||||
plugins: fetchart embedart web inline lyrics musicbrainz scrub lastgenre replaygain
|
plugins: fetchart web inline lyrics
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
default: $albumartist/$album%aunique{}/%if{$multidisc,$disc}$track - $title
|
default: $albumartist/$album%aunique{}/%if{$multidisc,$disc}$track - $title
|
||||||
@@ -12,11 +12,13 @@ item_fields:
|
|||||||
|
|
||||||
import:
|
import:
|
||||||
write: yes
|
write: yes
|
||||||
move: no
|
hardlink: yes
|
||||||
quiet: yes
|
resume: ask
|
||||||
|
incremental: yes
|
||||||
|
quiet_fallback: skip
|
||||||
timid: no
|
timid: no
|
||||||
|
log: /config/beet.log
|
||||||
languages: "en jp es"
|
languages: "en jp es"
|
||||||
autotag: yes
|
|
||||||
|
|
||||||
asciify_paths: yes
|
asciify_paths: yes
|
||||||
|
|
||||||
@@ -26,33 +28,13 @@ embedart:
|
|||||||
fetchart:
|
fetchart:
|
||||||
auto: yes
|
auto: yes
|
||||||
high_resolution: yes
|
high_resolution: yes
|
||||||
source:
|
|
||||||
- filesystem
|
|
||||||
- itunes
|
|
||||||
- coverart
|
|
||||||
- amazon
|
|
||||||
|
|
||||||
match:
|
|
||||||
strong_rec_thresh: 0.10
|
|
||||||
ignored_media: ['12" Vinyl']
|
|
||||||
|
|
||||||
lyrics:
|
lyrics:
|
||||||
auto: yes
|
sources: [lrclib, genius]
|
||||||
sources: [lrcmux]
|
|
||||||
|
|
||||||
scrub:
|
scrub:
|
||||||
auto: yes
|
auto: yes
|
||||||
|
|
||||||
replaygain:
|
|
||||||
auto: yes
|
|
||||||
backend: ffmpeg
|
|
||||||
|
|
||||||
# Consider directory empty even if files matching the below patterns are present
|
|
||||||
clutter:
|
|
||||||
- "*.jpg"
|
|
||||||
- "*.png"
|
|
||||||
- "*.nfo"
|
|
||||||
|
|
||||||
replace:
|
replace:
|
||||||
'^\.': _
|
'^\.': _
|
||||||
'[\x00-\x1f]': _
|
'[\x00-\x1f]': _
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
- name: Install bitcoin daemon
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: bitcoin-daemon
|
||||||
|
state: present
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Enable bitcoind
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: bitcoind
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- name: Install tor
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: tor
|
||||||
|
state: present
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
- name: Install Uncomplicated Firewall
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: ufw
|
||||||
|
state: present
|
||||||
|
|
||||||
|
# UFW logging can full up the kernel (dmesg) and message logs
|
||||||
|
- name: Disable logging
|
||||||
|
community.general.ufw:
|
||||||
|
logging: 'off'
|
||||||
|
|
||||||
|
- name: Allow OpenSSH inbound
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
name: OpenSSH # Uses standard profile located in /etc/ufw/applications.d
|
||||||
|
|
||||||
|
- name: Apply rate limiting to ssh inbound
|
||||||
|
community.general.ufw:
|
||||||
|
rule: limit
|
||||||
|
port: ssh
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
|
- name: Enable ufw system service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: ufw
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
|
||||||
|
# This is necessary in addition to enabling the system service
|
||||||
|
- name: Enable ufw rules
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
policy: deny
|
||||||
@@ -15,15 +15,6 @@
|
|||||||
mode: "{{ docker_compose_directory_mask }}"
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Create config directory
|
|
||||||
file:
|
|
||||||
path: "{{ data_dir }}/{{ role_name }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ docker_user }}"
|
|
||||||
group: "{{ docker_user }}"
|
|
||||||
mode: "{{ docker_compose_directory_mask }}"
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Copy docker-compose file to destination
|
- name: Copy docker-compose file to destination
|
||||||
template:
|
template:
|
||||||
src: docker-compose.yml
|
src: docker-compose.yml
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
{{ role_name }}:
|
||||||
|
container_name: "{{ role_name }}"
|
||||||
|
image: registry.gitlab.com/bockiii/deemix-docker
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
environment:
|
||||||
|
- "PUID={{ service_user.uid }}"
|
||||||
|
- "PGID={{ media_gid }}"
|
||||||
|
- "TZ={{ timezone }}"
|
||||||
|
- "UMASK_SET=002"
|
||||||
|
- "DEEMIX_SINGLE_USER=true"
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/{{ role_name }}:/config"
|
||||||
|
- "{{ media_storage_mnt }}/data/import/music/deemix:/downloads"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.{{ role_name }}.rule: "Host(`{{ role_name }}.local.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.{{ role_name }}.middlewares: lan-whitelist@file
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
networks:
|
|
||||||
traefik:
|
|
||||||
external: true
|
|
||||||
|
|
||||||
services:
|
|
||||||
dispatcharr:
|
|
||||||
container_name: "{{ role_name }}"
|
|
||||||
image: ghcr.io/dispatcharr/dispatcharr:latest
|
|
||||||
restart: unless-stopped
|
|
||||||
network_mode: "container:gluetun"
|
|
||||||
environment:
|
|
||||||
- DISPATCHARR_ENV=aio
|
|
||||||
- REDIS_HOST=localhost
|
|
||||||
- CELERY_BROKER_URL=redis://localhost:6379/0
|
|
||||||
- DISPATCHARR_LOG_LEVEL=info
|
|
||||||
volumes:
|
|
||||||
- "{{ data_dir }}/{{ role_name }}:/data"
|
|
||||||
devices:
|
|
||||||
- /dev/dri/renderD128:/dev/dri/renderD128
|
|
||||||
labels:
|
|
||||||
traefik.enable: true
|
|
||||||
traefik.http.routers.dispatcharr.rule: "Host(`dispatcharr.local.{{ personal_domain }}`)"
|
|
||||||
traefik.http.routers.dispatcharr.middlewares: lan-whitelist@file
|
|
||||||
traefik.http.services.dispatcharr.loadbalancer.server.port: 9191
|
|
||||||
File renamed without changes.
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
firefly_iii:
|
||||||
|
driver: bridge
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: fireflyiii/core:latest
|
||||||
|
container_name: firefly_iii_core
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/firefly3/upload:/var/www/html/storage/upload"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
- default
|
||||||
|
environment:
|
||||||
|
APP_ENV: local
|
||||||
|
APP_DEBUG: "false"
|
||||||
|
APP_KEY: "{{ app_key }}"
|
||||||
|
SITE_OWNER: {{ owner_email_address }}
|
||||||
|
DEFAULT_LANGUAGE: "en_US"
|
||||||
|
DEFAULT_LOCALE: equal
|
||||||
|
TZ: {{ timezone }}
|
||||||
|
TRUSTED_PROXIES: "*"
|
||||||
|
APP_LOG_LEVEL: notice
|
||||||
|
AUDIT_LOG_LEVEL: info
|
||||||
|
DB_CONNECTION: mysql
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_DATABASE: firefly
|
||||||
|
DB_USERNAME: firefly
|
||||||
|
DB_PASSWORD: firefly
|
||||||
|
APP_URL: "https://firefly.local.{{ personal_domain }}"
|
||||||
|
STATIC_CRON_TOKEN: "Y5uNSbJoK4FKUC9gVE5hq8YFEbFmc6BK"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.firefly.rule: "Host(`firefly.local.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.firefly.middlewares: lan-whitelist@file
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mariadb
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/mariadb/firefly3:/var/lib/mysql"
|
||||||
|
environment:
|
||||||
|
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
||||||
|
MYSQL_USER: firefly
|
||||||
|
MYSQL_PASSWORD: firefly
|
||||||
|
MYSQL_DATABASE: firefly
|
||||||
|
cron:
|
||||||
|
#
|
||||||
|
# To make this work, set STATIC_CRON_TOKEN in your .env file or as an environment variable and replace REPLACEME below
|
||||||
|
# The STATIC_CRON_TOKEN must be *exactly* 32 characters long
|
||||||
|
#
|
||||||
|
image: alpine
|
||||||
|
restart: always
|
||||||
|
container_name: firefly_iii_cron
|
||||||
|
command: sh -c "echo \"0 3 * * * wget -qO- https://firefly.local.{{ personal_domain }}/api/v1/cron/Y5uNSbJoK4FKUC9gVE5hq8YFEbFmc6BK\" | crontab - && crond -f -L /dev/stdout"
|
||||||
|
networks:
|
||||||
|
- firefly_iii
|
||||||
|
- default
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
owner_email_address: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
61373861363433363938396137653461363830323539316438323861326437663364383032363064
|
||||||
|
6438303462336466373233663366303263313139333830330a623465633166653530633961643162
|
||||||
|
65303032386661393063393134643436653737666163373833383036316234393563313536353036
|
||||||
|
3839663034393730340a626361646463636137636535653632343064353461656532656236633865
|
||||||
|
66636634323434356436313737336635363832333262383331333034313530663463
|
||||||
|
|
||||||
|
app_key: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
31333563616230396135363562313038346138633631613832646463343666643733333366303561
|
||||||
|
3461316337303862616662333031306231613532383534340a643236306232383466333531626466
|
||||||
|
33313830646365333935313237663134343033396166623730303030636438656435313462633762
|
||||||
|
3134643738616365330a636366343736306539666565663866626537303431366633646638663563
|
||||||
|
32616439336338393663373466323630323733393031633564383737383465313434313230323038
|
||||||
|
6534636266653166633539326632623165663436323936643031
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
services:
|
|
||||||
game-thumbs:
|
|
||||||
image: ghcr.io/sethwv/game-thumbs:latest
|
|
||||||
container_name: game-thumbs
|
|
||||||
restart: unless-stopped
|
|
||||||
labels:
|
|
||||||
- "autoheal=true"
|
|
||||||
ports:
|
|
||||||
- 3050:3050
|
|
||||||
environment:
|
|
||||||
PORT: 3050
|
|
||||||
NODE_ENV: ${NODE_ENV:-production}
|
|
||||||
SHOW_TIMESTAMP: ${SHOW_TIMESTAMP:-true}
|
|
||||||
LOG_TO_FILE: ${LOG_TO_FILE:-false}
|
|
||||||
MAX_LOG_FILES: ${MAX_LOG_FILES:-10}
|
|
||||||
volumes:
|
|
||||||
- "{{ data_dir }}/game-thumbs/cache:/app/.cache
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3050/health', (r) => {let d='';r.on('data', (c) => d+=c);r.on('end', () => {if (r.statusCode !== 200) process.exit(1);const j=JSON.parse(d);process.exit(j.status==='ok'?0:1)})}).on('error', () => process.exit(1))"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
start_period: 10s
|
|
||||||
retries: 3
|
|
||||||
autoheal:
|
|
||||||
image: willfarrell/autoheal:latest
|
|
||||||
container_name: autoheal
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
environment:
|
|
||||||
AUTOHEAL_CONTAINER_LABEL: "autoheal"
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
traefik:
|
traefik:
|
||||||
external: true
|
external: true
|
||||||
@@ -19,14 +21,13 @@ services:
|
|||||||
VPN_TYPE: wireguard
|
VPN_TYPE: wireguard
|
||||||
VPN_SERVICE_PROVIDER: custom
|
VPN_SERVICE_PROVIDER: custom
|
||||||
WIREGUARD_PRIVATE_KEY: "{{ torguard_private_key }}"
|
WIREGUARD_PRIVATE_KEY: "{{ torguard_private_key }}"
|
||||||
WIREGUARD_PUBLIC_KEY: "fLDSO1YJxryyquen+XupegFQWhsWkGva+g3BtuIRyWs="
|
WIREGUARD_PUBLIC_KEY: "sC96pq087HvVpRNA5oKjiotwGuRRZbdLiTgmqP+Du2s="
|
||||||
WIREGUARD_ADDRESSES: "{{ torguard_address }}"
|
WIREGUARD_ADDRESSES: "{{ torguard_address }}"
|
||||||
VPN_ENDPOINT_IP: "38.96.254.100"
|
VPN_ENDPOINT_IP: "146.70.137.122"
|
||||||
VPN_ENDPOINT_PORT: "1443"
|
VPN_ENDPOINT_PORT: "1443"
|
||||||
FIREWALL_VPN_INPUT_PORTS: "45333"
|
FIREWALL_VPN_INPUT_PORTS: "55230"
|
||||||
FIREWALL_OUTBOUND_SUBNETS: "10.0.0.0/24"
|
|
||||||
DOT: "off"
|
DOT: "off"
|
||||||
DNS_ADDRESS: "10.8.0.1"
|
DNS_ADDRESS: "9.9.9.9"
|
||||||
TZ: "{{ timezone }}"
|
TZ: "{{ timezone }}"
|
||||||
HTTPPROXY: "on"
|
HTTPPROXY: "on"
|
||||||
HTTPPROXY_USER: httpproxy
|
HTTPPROXY_USER: httpproxy
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
torguard_private_key: !vault |
|
torguard_private_key: !vault |
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
30666664646463323238386164393462633236643531656564343835383661623335363562396631
|
38386463313536353366303733396232663136393431656432346332353131333630343730336262
|
||||||
3439303437393364353064653338376563383362316237300a616338303763653034656564316630
|
3436633832613935323134393662666233643032613463310a656364653639363739306265306361
|
||||||
30626437396531323763633133363565383530393737383064366661313430623936646264373933
|
61616261663139323238636634306330393733393065373138323463653935366335363639626265
|
||||||
3734313736356534390a633837333264383233313962326636323534346163353064306539323230
|
3862396562393536320a366335363435636436333139356239306262303838333162613530643732
|
||||||
32373237396534366638356631333266386265353862666436323665376339363236336361653937
|
64336161306633343866383538303536316163396566326336633961333136373736373364343430
|
||||||
6236396266336637383032643434656234653232303236373931
|
3361613566346563346664353834613361616666383065303162
|
||||||
|
|
||||||
torguard_address: !vault |
|
torguard_address: !vault |
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
38313562363039623039623164373435653833333763653562626434666431666435653037393034
|
61626363346663646462626434316566353464623161396362356330333338616466633266383733
|
||||||
6130396230363362633761343636313066333433363135370a333732353335336231366433393631
|
3363393464616534316339393935646438333764383765370a383236613539613866373838353061
|
||||||
38393131326565633433363138346363343863393730613936643034353435656438613331343763
|
39393661393035373132663439653361363761613264656462623237336637356162623439336238
|
||||||
3138616466623530350a383164616533303461396365316331633061333431366639356637396337
|
6635383734303539640a336366373164336262363630636562636136316166343362306265326163
|
||||||
34343533366261343837653763636333326634373935316465613233316564623266
|
39306365613539383666303130633937643238653635393738323665323938646335
|
||||||
|
|
||||||
File renamed without changes.
+1
-1
@@ -5,7 +5,7 @@ networks:
|
|||||||
services:
|
services:
|
||||||
{{ role_name }}:
|
{{ role_name }}:
|
||||||
container_name: "{{ role_name }}"
|
container_name: "{{ role_name }}"
|
||||||
image: ghcr.io/seerr-team/seerr:latest
|
image: fallenbagel/jellyseerr:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- traefik
|
- traefik
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
curl -sfL https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/lidarr/setup.bash | bash
|
||||||
|
exit
|
||||||
@@ -26,12 +26,29 @@
|
|||||||
|
|
||||||
- name: Create data directory
|
- name: Create data directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ data_dir }}/{{ role_name }}/config"
|
path: "{{ data_dir }}/{{ item }}"
|
||||||
state: directory
|
state: directory
|
||||||
owner: "{{ service_user.uid }}"
|
owner: "{{ service_user.uid }}"
|
||||||
group: "{{ primary_gid }}"
|
group: "{{ primary_gid }}"
|
||||||
mode: "{{ docker_compose_directory_mask }}"
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
become: true
|
become: true
|
||||||
|
loop:
|
||||||
|
- "{{ role_name }}/config"
|
||||||
|
- "{{ role_name }}/custom-services"
|
||||||
|
- "{{ role_name }}/custom-cont"
|
||||||
|
|
||||||
|
- name: Copy arr-scripts init script
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "scripts_init.bash"
|
||||||
|
dest: "{{ data_dir }}/{{ role_name }}/custom-cont"
|
||||||
|
owner: "{{ service_user.uid }}"
|
||||||
|
mode: 0564
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy extended.conf
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "extended.conf"
|
||||||
|
dest: "{{ data_dir }}/{{ role_name }}/config"
|
||||||
|
|
||||||
- name: Start docker container
|
- name: Start docker container
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- "{{ data_dir }}/{{ role_name }}/config:/config"
|
- "{{ data_dir }}/{{ role_name }}/config:/config"
|
||||||
- "{{ media_storage_mnt }}/data:/data"
|
- "{{ media_storage_mnt }}/data:/data"
|
||||||
|
# arr-scripts - https://github.com/RandomNinjaAtk/arr-scripts/blob/main/lidarr/readme.md
|
||||||
|
- "{{ data_dir }}/{{ role_name }}/custom-services:/custom-services.d"
|
||||||
|
- "{{ data_dir }}/{{ role_name }}/custom-cont:/custom-cont-init.d"
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: true
|
traefik.enable: true
|
||||||
traefik.http.routers.{{ role_name }}.rule: "Host(`{{ role_name }}.local.{{ personal_domain }}`)"
|
traefik.http.routers.{{ role_name }}.rule: "Host(`{{ role_name }}.local.{{ personal_domain }}`)"
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
##### LIDARR EXTENDED SCRIPTS SETTINGS #####
|
||||||
|
|
||||||
|
##### PATHS
|
||||||
|
downloadPath="/config/extended/downloads" # OPTIONAL, only change if needed.... Temporary Download Location for incoming Audio files from included clients
|
||||||
|
importPath="/config/extended/import" # OPTIONAL, only change if needed.... Completed downloads are stored here for the Usenet Blackhole client to import from. When Using queue cleaner, failed imports will be automatically cleaned up.
|
||||||
|
videoPath="" # Final destination/location of completed Videos
|
||||||
|
|
||||||
|
##### SCRIPT ENABLEMENT
|
||||||
|
enableAutoConfig="true" # true = enabled :: Automatically configures Lidarr with optimal settings
|
||||||
|
enableAudio="true" # true = enabled :: Enables the Audio script to run automatically
|
||||||
|
enableVideo="false" # true = enabled :: Enables the Video script to run automatically
|
||||||
|
enableUnmappedFilesCleaner="false" # true = enabled :: Enables the UnmappedFilesCleaner script to run automatically
|
||||||
|
enableQueueCleaner="true" # true = enabled :: Enables the QueueCleaner script to run automatically
|
||||||
|
|
||||||
|
##### SCRIPT INTERVALS
|
||||||
|
audioScriptInterval=15m #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
|
||||||
|
videoScriptInterval=15m #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
|
||||||
|
autoArtistAdderInterval=12h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
|
||||||
|
unmappedFolderCleanerScriptInterval=15m #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
|
||||||
|
queueCleanerScriptInterval=15m #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
|
||||||
|
|
||||||
|
##### AUTOCONFIG SCRIPT SETTINGS
|
||||||
|
configureMediaManagement="true" # Configures Lidarr Media Management Settings
|
||||||
|
configureMetadataConsumerSettings="false" # Configures Lidarr Metadata Consumer Settings
|
||||||
|
configureMetadataProviderSettings="false" # Configures Lidarr Metadata Provider Settings
|
||||||
|
configureCustomScripts="true" # Adds custom scripts to Lidarr
|
||||||
|
configureLidarrUiSettings="true" # Configures Lidarr UI Settings
|
||||||
|
configureMetadataProfileSettings="false" # Configures Lidarr Metadata Profile Settings
|
||||||
|
configureTrackNamingSettings="true" # Configures Lidarr Track Naming Settings
|
||||||
|
|
||||||
|
##### AUDIO SCRIPT
|
||||||
|
# SEARCH
|
||||||
|
searchSort="date" # date or album :: Sorts the missing/cutoff list by release date (newest -> oldest) or album type (album -> single) for processing the list
|
||||||
|
matchDistance="3" # The number of changes required to transform the searched album title into a possible found album title match... (0, requires a perfect match)
|
||||||
|
lidarrSearchForMissing="false" # true = enabled :: When artists are added, search for them using Lidarr's built in functionality
|
||||||
|
retryNotFound="90" ## :: Number of days between re-attempting the download of previously notfound albums
|
||||||
|
ignoreInstrumentalRelease="false" # true = enabled :: Skips albums releases that have the word "instrumental" in either the title or disambiguation
|
||||||
|
preferSpecialEditions="true" # true = enabled :: This changes the release title sort order, when true, it will search for releases with longest release names first, which are more likely to be deluxe/special versions...
|
||||||
|
|
||||||
|
# CLIENT
|
||||||
|
dlClientSource="deezer" # deezer, tidal or both :: set to both, to use both clients, tidal requires extra steps, view logging output
|
||||||
|
arlToken="{{ deezer_arl }}" # OPTIONAL (fallback using Freyr) - User ARL token for deemix client
|
||||||
|
tidalCountryCode="US" # Country Code required for tidal
|
||||||
|
failedDownloadAttemptThreshold="6" # Maximum number of attempts to download a particular album ID from the service before considering it a failed download...
|
||||||
|
deezerClientTestDownloadId="197472472" # A known good deezer track id that is used to test/verify the client is functioning in the event all download attempts have failed. Prevents the script from exiting...
|
||||||
|
tidalClientTestDownloadId="166356219" # A known good tidal track id that is used to test/verify the client is functioning in the event all download attempts have failed. Prevents the script from exiting...
|
||||||
|
downloadClientTimeOut="10m" # 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days :: Kills freyr download client after the set timeout period, prevents lock ups...
|
||||||
|
|
||||||
|
# QUALITY
|
||||||
|
audioLyricType="both" # both or explicit or clean :: both, is explicit preferred matching, explicit is explicit releases only matching and clean is clean releases only matching
|
||||||
|
audioFormat="native" # native or alac or mp3 or aac or opus :: native is the native download client file type, selected by the matching audio bit-rate
|
||||||
|
audioBitrate="lossless" # master or lossless or high or low or ### :: master = MQA/lossless flac files, lossless = flac files, high = 320K, low = 128k/96k, ### = the output bit-rate of converted lossless files to selected audioFormat that is not native, example: 192...
|
||||||
|
requireQuality="true" # true = enabled :: Downloads will be checked for quality and require to have the requested file format & quality
|
||||||
|
|
||||||
|
# POST PROCESSING
|
||||||
|
enableBeetsTagging="true" # true = enabled :: Downloads will be processed and tagged by Beets
|
||||||
|
beetsMatchPercentage="90" # 1-100 :: Set this to the minimum percentage required for Beets to match the downloaded album to a musicbrainz release :: Lower percentage is less restrictive
|
||||||
|
enableReplaygainTags="true" # true = enabled :: Downloads will be tagged with ReplayGain Metadata
|
||||||
|
|
||||||
|
# ADD ARTIST AUTOMATION
|
||||||
|
addDeezerTopArtists="false" # true = enabled :: Enabling this will enable the extended script to automatically add artists that are on the Deezer Top Artist Chart to your existing Lidarr instance
|
||||||
|
addDeezerTopAlbumArtists="false" # true = enabled :: Enabling this will enable the extended script to automatically add artists that are on the Deezer Top Album Chart to your existing Lidarr instance
|
||||||
|
addDeezerTopTrackArtists="false" # true = enabled :: Enabling this will enable the extended script to automatically add artists that are on the Deezer Top Track Chart to your existing Lidarr instance
|
||||||
|
topLimit="3" # This setting controls the amount of Top Artist (Albums/Tracks/Artists) to add to Lidarr from Deezer
|
||||||
|
addRelatedArtists="false" # true = enabled :: WARNING !!! WARNING !!! Enabling this can cause an endless loop of additional artists.... Enabling this will enable the extended script to automatically add artists that are related to your existing Lidarr artists from Tidal & Deezer
|
||||||
|
numberOfRelatedArtistsToAddPerArtist="1" # 1-20 :: This will limit the number of related artists to add per artist in your library :: Minimum is 1, Maximum is 20
|
||||||
|
autoArtistAdderMonitored="true" # true or false :: If true, artists that are added automatically are monitored, when false they are added in an unmonitored state
|
||||||
|
preventRelatedArtistsLoop="true" # true = enabled :: This will prevent added related artists from adding additional related artists, thus killing an endless loop. This works by using the Lidarr's tag system (arr-extended), Remove tag from artist to allow it to be proessed for related artists...
|
||||||
|
|
||||||
|
##### VIDEO SCRIPT
|
||||||
|
addFeaturedVideoArtists="false" # true = enabled :: WARNING !!! WARNING !!! Enabling this can cause an endless loop of additional artists.... Enabling this will enable the extended Video script to automatically add Music Video Featured Artists to your existing Lidarr artists from IMVDB
|
||||||
|
videoFormat="bv[width>=1920]+ba" # ONLY CHANGE if you know what your doing, for guidence, please see yt-dlp documentation.
|
||||||
|
videoInfoJson="false" # true = enabled :: Stores yt-dlp info-json files alongside video files.
|
||||||
|
youtubeSubtitleLanguage="en" # Desired Language Code :: For guidence, please see yt-dlp documentation.
|
||||||
|
disableImvd="false" # true = enabled :: Use this to disable IMVDB as a source, will result in only tidal videos
|
||||||
|
|
||||||
|
##### DEEZER ARLCHECKER
|
||||||
|
arlUpdateInterval="24h" # Interval to check ARL Validity (default 24 hours). Reboot container after changing. s = seconds, m = minutes, h = hours, d = days
|
||||||
|
telegramBotEnable="false" # Enable/Disable Telegram Bot to notify if ARL expires. Otherwise check text file in custom-services.d/python for status.
|
||||||
|
telegramBotToken="" # Get token from BotFather during bot creation. If you use a notify channel for Lidarr, you can probably use the same bot, as this script only takes temporary control.
|
||||||
|
telegramUserChatID="" # Get your userid by chatting: t.me/userinfobot
|
||||||
|
pushoverEnable="false" # Pushover Notification Support
|
||||||
|
pushoverUserKey=""
|
||||||
|
pushoverAppAPIKey=""
|
||||||
|
ntfyEnable="false" # ntfy Notification Support
|
||||||
|
ntfyServerTopic="" # Put your server + topic address ex: https://ntfy.mydomain.com/lidarr
|
||||||
|
ntfyUserToken="" # create a new user token using the ntfy cli commands. See ntfy documentation on how to do that.
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
- name: Create install directory
|
- name: Create install directory
|
||||||
ansible.builtin.file:
|
file:
|
||||||
path: "{{ install_directory }}/{{ role_name }}"
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
state: directory
|
state: directory
|
||||||
owner: "{{ docker_user }}"
|
owner: "{{ docker_user }}"
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Copy docker-compose file to destination
|
- name: Copy docker-compose file to destination
|
||||||
ansible.builtin.template:
|
template:
|
||||||
src: docker-compose.yml
|
src: docker-compose.yml
|
||||||
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
owner: "{{ docker_user }}"
|
owner: "{{ docker_user }}"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
lubelogger:
|
||||||
|
container_name: lubelogger
|
||||||
|
image: ghcr.io/hargata/lubelogger:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
environment:
|
||||||
|
- LC_ALL=en_US.UTF-8
|
||||||
|
- LANG=en_US.UTF-8
|
||||||
|
- MailConfig__EmailServer=""
|
||||||
|
- MailConfig__EmailFrom=""
|
||||||
|
- MailConfig__Port=587
|
||||||
|
- MailConfig__Username=""
|
||||||
|
- MailConfig__Password=""
|
||||||
|
- LOGGING__LOGLEVEL__DEFAULT=Error
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/{{ role_name }}:/App"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.lubelogger.rule: "Host(`lubelogger.local.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.lubelogger.middlewares: lan-whitelist@file
|
||||||
@@ -1,5 +1,12 @@
|
|||||||
|
- name: Create service user
|
||||||
|
user:
|
||||||
|
name: "{{ role_name }}"
|
||||||
|
system: true
|
||||||
|
register: service_user
|
||||||
|
become: true
|
||||||
|
|
||||||
- name: Create install directory
|
- name: Create install directory
|
||||||
ansible.builtin.file:
|
file:
|
||||||
path: "{{ install_directory }}/{{ role_name }}"
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
state: directory
|
state: directory
|
||||||
owner: "{{ docker_user }}"
|
owner: "{{ docker_user }}"
|
||||||
@@ -7,7 +14,7 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Copy docker-compose file to destination
|
- name: Copy docker-compose file to destination
|
||||||
ansible.builtin.template:
|
template:
|
||||||
src: docker-compose.yml
|
src: docker-compose.yml
|
||||||
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
owner: "{{ docker_user }}"
|
owner: "{{ docker_user }}"
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
default:
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
mealie-frontend:
|
||||||
|
image: hkotel/mealie:frontend-v1.0.0beta-5
|
||||||
|
container_name: mealie-frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- mealie-api
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- traefik
|
||||||
|
environment:
|
||||||
|
- API_URL=http://mealie-api:9000 #
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/mealie:/app/data"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.mealie.rule: "Host(`mealie.{{ personal_domain }}`)"
|
||||||
|
traefik.http.services.mealie.loadbalancer.server.port: 3000
|
||||||
|
|
||||||
|
mealie-api:
|
||||||
|
image: hkotel/mealie:api-v1.0.0beta-5
|
||||||
|
container_name: mealie-api
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/mealie:/app/data"
|
||||||
|
environment:
|
||||||
|
- ALLOW_SIGNUP=false
|
||||||
|
- "PUID={{ service_user.uid }}"
|
||||||
|
- "PGID={{ service_user.uid }}"
|
||||||
|
- "TZ={{ timezone }}"
|
||||||
|
- MAX_WORKERS=1
|
||||||
|
- WEB_CONCURRENCY=1
|
||||||
|
- "BASE_URL=https://mealie.{{ personal_domain }}"
|
||||||
|
- DB_ENGINE=postgres
|
||||||
|
- POSTGRES_USER=mealie
|
||||||
|
- POSTGRES_PASSWORD=mealie
|
||||||
|
- POSTGRES_SERVER=postgres
|
||||||
|
- POSTGRES_PORT=5432
|
||||||
|
- POSTGRES_DB=mealie
|
||||||
|
- "DEFAULT_EMAIL={{ email }}"
|
||||||
|
- TOKEN_TIME=168
|
||||||
|
dns:
|
||||||
|
- 10.0.0.1
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
container_name: postgres
|
||||||
|
image: postgres
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/postgres/mealie:/var/lib/postgresql/data"
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: mealie
|
||||||
|
POSTGRES_USER: mealie
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
email: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
30343965383433393930313337303637353362616563313863396433323939393864393436376534
|
||||||
|
6438663537386464623830316136643461356631316436360a636664323436303464376630616639
|
||||||
|
62653263633531343733313137303863623562616632313236376466313132636234633438616164
|
||||||
|
3030303934343761390a663734333566323234613434633636353665623530643262353162383237
|
||||||
|
66633863376332663064346132356238333561663438643232646463646632656361
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
- name: restart ntfy
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/ntfy"
|
||||||
|
restarted: true
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Install configuration file
|
||||||
|
template:
|
||||||
|
src: server.yml
|
||||||
|
dest: "{{ data_dir }}/ntfy/server.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
notify: restart ntfy
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Start docker container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
ntfy:
|
||||||
|
container_name: ntfy
|
||||||
|
image: binwiederhier/ntfy:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
user: "{{ primary_uid }}:{{ primary_gid }}"
|
||||||
|
environment:
|
||||||
|
- TZ={{ timezone }}
|
||||||
|
command:
|
||||||
|
- serve
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/ntfy:/etc/ntfy"
|
||||||
|
- /var/cache/ntfy:/var/cache/ntfy
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.ntfy.rule: "Host(`push.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.ntfy.middlewares: lan-whitelist@file
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
# ntfy server config file
|
||||||
|
#
|
||||||
|
# Please refer to the documentation at https://ntfy.sh/docs/config/ for details.
|
||||||
|
# All options also support underscores (_) instead of dashes (-) to comply with the YAML spec.
|
||||||
|
|
||||||
|
# Public facing base URL of the service (e.g. https://ntfy.sh or https://ntfy.example.com)
|
||||||
|
#
|
||||||
|
# This setting is required for any of the following features:
|
||||||
|
# - attachments (to return a download URL)
|
||||||
|
# - e-mail sending (for the topic URL in the email footer)
|
||||||
|
# - iOS push notifications for self-hosted servers (to calculate the Firebase poll_request topic)
|
||||||
|
# - Matrix Push Gateway (to validate that the pushkey is correct)
|
||||||
|
#
|
||||||
|
base-url: "https://push.{{ personal_domain }}"
|
||||||
|
|
||||||
|
# Listen address for the HTTP & HTTPS web server. If "listen-https" is set, you must also
|
||||||
|
# set "key-file" and "cert-file". Format: [<ip>]:<port>, e.g. "1.2.3.4:8080".
|
||||||
|
#
|
||||||
|
# To listen on all interfaces, you may omit the IP address, e.g. ":443".
|
||||||
|
# To disable HTTP, set "listen-http" to "-".
|
||||||
|
#
|
||||||
|
# listen-http: ":80"
|
||||||
|
# listen-https:
|
||||||
|
|
||||||
|
# Listen on a Unix socket, e.g. /var/lib/ntfy/ntfy.sock
|
||||||
|
# This can be useful to avoid port issues on local systems, and to simplify permissions.
|
||||||
|
#
|
||||||
|
# listen-unix: <socket-path>
|
||||||
|
# listen-unix-mode: <linux permissions, e.g. 0700>
|
||||||
|
|
||||||
|
# Path to the private key & cert file for the HTTPS web server. Not used if "listen-https" is not set.
|
||||||
|
#
|
||||||
|
# key-file: <filename>
|
||||||
|
# cert-file: <filename>
|
||||||
|
|
||||||
|
# If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app.
|
||||||
|
# This is optional and only required to save battery when using the Android app.
|
||||||
|
#
|
||||||
|
# firebase-key-file: <filename>
|
||||||
|
|
||||||
|
# If "cache-file" is set, messages are cached in a local SQLite database instead of only in-memory.
|
||||||
|
# This allows for service restarts without losing messages in support of the since= parameter.
|
||||||
|
#
|
||||||
|
# The "cache-duration" parameter defines the duration for which messages will be buffered
|
||||||
|
# before they are deleted. This is required to support the "since=..." and "poll=1" parameter.
|
||||||
|
# To disable the cache entirely (on-disk/in-memory), set "cache-duration" to 0.
|
||||||
|
# The cache file is created automatically, provided that the correct permissions are set.
|
||||||
|
#
|
||||||
|
# The "cache-startup-queries" parameter allows you to run commands when the database is initialized,
|
||||||
|
# e.g. to enable WAL mode (see https://phiresky.github.io/blog/2020/sqlite-performance-tuning/)).
|
||||||
|
# Example:
|
||||||
|
# cache-startup-queries: |
|
||||||
|
# pragma journal_mode = WAL;
|
||||||
|
# pragma synchronous = normal;
|
||||||
|
# pragma temp_store = memory;
|
||||||
|
# pragma busy_timeout = 15000;
|
||||||
|
# vacuum;
|
||||||
|
#
|
||||||
|
# The "cache-batch-size" and "cache-batch-timeout" parameter allow enabling async batch writing
|
||||||
|
# of messages. If set, messages will be queued and written to the database in batches of the given
|
||||||
|
# size, or after the given timeout. This is only required for high volume servers.
|
||||||
|
#
|
||||||
|
# Debian/RPM package users:
|
||||||
|
# Use /var/cache/ntfy/cache.db as cache file to avoid permission issues. The package
|
||||||
|
# creates this folder for you.
|
||||||
|
#
|
||||||
|
# Check your permissions:
|
||||||
|
# If you are running ntfy with systemd, make sure this cache file is owned by the
|
||||||
|
# ntfy user and group by running: chown ntfy.ntfy <filename>.
|
||||||
|
#
|
||||||
|
# cache-file: <filename>
|
||||||
|
# cache-duration: "12h"
|
||||||
|
# cache-startup-queries:
|
||||||
|
# cache-batch-size: 0
|
||||||
|
# cache-batch-timeout: "0ms"
|
||||||
|
|
||||||
|
# If set, access to the ntfy server and API can be controlled on a granular level using
|
||||||
|
# the 'ntfy user' and 'ntfy access' commands. See the --help pages for details, or check the docs.
|
||||||
|
#
|
||||||
|
# - auth-file is the SQLite user/access database; it is created automatically if it doesn't already exist
|
||||||
|
# - auth-default-access defines the default/fallback access if no access control entry is found; it can be
|
||||||
|
# set to "read-write" (default), "read-only", "write-only" or "deny-all".
|
||||||
|
# - auth-startup-queries allows you to run commands when the database is initialized, e.g. to enable
|
||||||
|
# WAL mode. This is similar to cache-startup-queries. See above for details.
|
||||||
|
#
|
||||||
|
# Debian/RPM package users:
|
||||||
|
# Use /var/lib/ntfy/user.db as user database to avoid permission issues. The package
|
||||||
|
# creates this folder for you.
|
||||||
|
#
|
||||||
|
# Check your permissions:
|
||||||
|
# If you are running ntfy with systemd, make sure this user database file is owned by the
|
||||||
|
# ntfy user and group by running: chown ntfy.ntfy <filename>.
|
||||||
|
#
|
||||||
|
# auth-file: <filename>
|
||||||
|
# auth-default-access: "read-write"
|
||||||
|
# auth-startup-queries:
|
||||||
|
|
||||||
|
# If set, the X-Forwarded-For header is used to determine the visitor IP address
|
||||||
|
# instead of the remote address of the connection.
|
||||||
|
#
|
||||||
|
# WARNING: If you are behind a proxy, you must set this, otherwise all visitors are rate limited
|
||||||
|
# as if they are one.
|
||||||
|
#
|
||||||
|
behind-proxy: true
|
||||||
|
|
||||||
|
# If enabled, clients can attach files to notifications as attachments. Minimum settings to enable attachments
|
||||||
|
# are "attachment-cache-dir" and "base-url".
|
||||||
|
#
|
||||||
|
# - attachment-cache-dir is the cache directory for attached files
|
||||||
|
# - attachment-total-size-limit is the limit of the on-disk attachment cache directory (total size)
|
||||||
|
# - attachment-file-size-limit is the per-file attachment size limit (e.g. 300k, 2M, 100M)
|
||||||
|
# - attachment-expiry-duration is the duration after which uploaded attachments will be deleted (e.g. 3h, 20h)
|
||||||
|
#
|
||||||
|
attachment-cache-dir: "/var/cache/ntfy/attachments"
|
||||||
|
# attachment-total-size-limit: "5G"
|
||||||
|
# attachment-file-size-limit: "15M"
|
||||||
|
# attachment-expiry-duration: "3h"
|
||||||
|
|
||||||
|
# If enabled, allow outgoing e-mail notifications via the 'X-Email' header. If this header is set,
|
||||||
|
# messages will additionally be sent out as e-mail using an external SMTP server. As of today, only
|
||||||
|
# SMTP servers with plain text auth and STARTLS are supported. Please also refer to the rate limiting settings
|
||||||
|
# below (visitor-email-limit-burst & visitor-email-limit-burst).
|
||||||
|
#
|
||||||
|
# - smtp-sender-addr is the hostname:port of the SMTP server
|
||||||
|
# - smtp-sender-user/smtp-sender-pass are the username and password of the SMTP user
|
||||||
|
# - smtp-sender-from is the e-mail address of the sender
|
||||||
|
#
|
||||||
|
# smtp-sender-addr:
|
||||||
|
# smtp-sender-user:
|
||||||
|
# smtp-sender-pass:
|
||||||
|
# smtp-sender-from:
|
||||||
|
|
||||||
|
# If enabled, ntfy will launch a lightweight SMTP server for incoming messages. Once configured, users can send
|
||||||
|
# emails to a topic e-mail address to publish messages to a topic.
|
||||||
|
#
|
||||||
|
# - smtp-server-listen defines the IP address and port the SMTP server will listen on, e.g. :25 or 1.2.3.4:25
|
||||||
|
# - smtp-server-domain is the e-mail domain, e.g. ntfy.sh
|
||||||
|
# - smtp-server-addr-prefix is an optional prefix for the e-mail addresses to prevent spam. If set to "ntfy-",
|
||||||
|
# for instance, only e-mails to ntfy-$topic@ntfy.sh will be accepted. If this is not set, all emails to
|
||||||
|
# $topic@ntfy.sh will be accepted (which may obviously be a spam problem).
|
||||||
|
#
|
||||||
|
# smtp-server-listen:
|
||||||
|
# smtp-server-domain:
|
||||||
|
# smtp-server-addr-prefix:
|
||||||
|
|
||||||
|
# Interval in which keepalive messages are sent to the client. This is to prevent
|
||||||
|
# intermediaries closing the connection for inactivity.
|
||||||
|
#
|
||||||
|
# Note that the Android app has a hardcoded timeout at 77s, so it should be less than that.
|
||||||
|
#
|
||||||
|
# keepalive-interval: "45s"
|
||||||
|
|
||||||
|
# Interval in which the manager prunes old messages, deletes topics
|
||||||
|
# and prints the stats.
|
||||||
|
#
|
||||||
|
# manager-interval: "1m"
|
||||||
|
|
||||||
|
# Defines topic names that are not allowed, because they are otherwise used. There are a few default topics
|
||||||
|
# that cannot be used (e.g. app, account, settings, ...). To extend the default list, define them here.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# disallowed-topics:
|
||||||
|
# - about
|
||||||
|
# - pricing
|
||||||
|
# - contact
|
||||||
|
#
|
||||||
|
# disallowed-topics:
|
||||||
|
|
||||||
|
# Defines if the root route (/) is pointing to the landing page (as on ntfy.sh) or the
|
||||||
|
# web app. If you self-host, you don't want to change this.
|
||||||
|
# Can be "app" (default), "home" or "disable" to disable the web app entirely.
|
||||||
|
#
|
||||||
|
# web-root: app
|
||||||
|
|
||||||
|
# Various feature flags used to control the web app, and API access, mainly around user and
|
||||||
|
# account management.
|
||||||
|
#
|
||||||
|
# - enable-signup allows users to sign up via the web app, or API
|
||||||
|
# - enable-login allows users to log in via the web app, or API
|
||||||
|
# - enable-reservations allows users to reserve topics (if their tier allows it)
|
||||||
|
#
|
||||||
|
# enable-signup: false
|
||||||
|
# enable-login: false
|
||||||
|
# enable-reservations: false
|
||||||
|
|
||||||
|
# Server URL of a Firebase/APNS-connected ntfy server (likely "https://ntfy.sh").
|
||||||
|
#
|
||||||
|
# iOS users:
|
||||||
|
# If you use the iOS ntfy app, you MUST configure this to receive timely notifications. You'll like want this:
|
||||||
|
# upstream-base-url: "https://ntfy.sh"
|
||||||
|
#
|
||||||
|
# If set, all incoming messages will publish a "poll_request" message to the configured upstream server, containing
|
||||||
|
# the message ID of the original message, instructing the iOS app to poll this server for the actual message contents.
|
||||||
|
# This is to prevent the upstream server and Firebase/APNS from being able to read the message.
|
||||||
|
#
|
||||||
|
# upstream-base-url:
|
||||||
|
|
||||||
|
# Rate limiting: Total number of topics before the server rejects new topics.
|
||||||
|
#
|
||||||
|
# global-topic-limit: 15000
|
||||||
|
|
||||||
|
# Rate limiting: Number of subscriptions per visitor (IP address)
|
||||||
|
#
|
||||||
|
# visitor-subscription-limit: 30
|
||||||
|
|
||||||
|
# Rate limiting: Allowed GET/PUT/POST requests per second, per visitor:
|
||||||
|
# - visitor-request-limit-burst is the initial bucket of requests each visitor has
|
||||||
|
# - visitor-request-limit-replenish is the rate at which the bucket is refilled
|
||||||
|
# - visitor-request-limit-exempt-hosts is a comma-separated list of hostnames, IPs or CIDRs to be
|
||||||
|
# exempt from request rate limiting. Hostnames are resolved at the time the server is started.
|
||||||
|
# Example: "1.2.3.4,ntfy.example.com,8.7.6.0/24"
|
||||||
|
#
|
||||||
|
# visitor-request-limit-burst: 60
|
||||||
|
# visitor-request-limit-replenish: "5s"
|
||||||
|
# visitor-request-limit-exempt-hosts: ""
|
||||||
|
|
||||||
|
# Rate limiting: Hard daily limit of messages per visitor and day. The limit is reset
|
||||||
|
# every day at midnight UTC. If the limit is not set (or set to zero), the request
|
||||||
|
# limit (see above) governs the upper limit.
|
||||||
|
#
|
||||||
|
# visitor-message-daily-limit: 0
|
||||||
|
|
||||||
|
# Rate limiting: Allowed emails per visitor:
|
||||||
|
# - visitor-email-limit-burst is the initial bucket of emails each visitor has
|
||||||
|
# - visitor-email-limit-replenish is the rate at which the bucket is refilled
|
||||||
|
#
|
||||||
|
# visitor-email-limit-burst: 16
|
||||||
|
# visitor-email-limit-replenish: "1h"
|
||||||
|
|
||||||
|
# Rate limiting: Attachment size and bandwidth limits per visitor:
|
||||||
|
# - visitor-attachment-total-size-limit is the total storage limit used for attachments per visitor
|
||||||
|
# - visitor-attachment-daily-bandwidth-limit is the total daily attachment download/upload traffic limit per visitor
|
||||||
|
#
|
||||||
|
# visitor-attachment-total-size-limit: "100M"
|
||||||
|
# visitor-attachment-daily-bandwidth-limit: "500M"
|
||||||
|
|
||||||
|
# Payments integration via Stripe
|
||||||
|
#
|
||||||
|
# - stripe-secret-key is the key used for the Stripe API communication. Setting this values
|
||||||
|
# enables payments in the ntfy web app (e.g. Upgrade dialog). See https://dashboard.stripe.com/apikeys.
|
||||||
|
# - stripe-webhook-key is the key required to validate the authenticity of incoming webhooks from Stripe.
|
||||||
|
# Webhooks are essential up keep the local database in sync with the payment provider. See https://dashboard.stripe.com/webhooks.
|
||||||
|
#
|
||||||
|
# stripe-secret-key:
|
||||||
|
# stripe-webhook-key:
|
||||||
|
|
||||||
|
# Logging options
|
||||||
|
#
|
||||||
|
# By default, ntfy logs to the console (stderr), with an "info" log level, and in a human-readable text format.
|
||||||
|
# ntfy supports five different log levels, can also write to a file, log as JSON, and even supports granular
|
||||||
|
# log level overrides for easier debugging. Some options (log-level and log-level-overrides) can be hot reloaded
|
||||||
|
# by calling "kill -HUP $pid" or "systemctl reload ntfy".
|
||||||
|
#
|
||||||
|
# - log-format defines the output format, can be "text" (default) or "json"
|
||||||
|
# - log-file is a filename to write logs to. If this is not set, ntfy logs to stderr.
|
||||||
|
# - log-level defines the default log level, can be one of "trace", "debug", "info" (default), "warn" or "error".
|
||||||
|
# Be aware that "debug" (and particularly "trace") can be VERY CHATTY. Only turn them on briefly for debugging purposes.
|
||||||
|
# - log-level-overrides lets you override the log level if certain fields match. This is incredibly powerful
|
||||||
|
# for debugging certain parts of the system (e.g. only the account management, or only a certain visitor).
|
||||||
|
# This is an array of strings in the format:
|
||||||
|
# - "field=value -> level" to match a value exactly, e.g. "tag=manager -> trace"
|
||||||
|
# - "field -> level" to match any value, e.g. "time_taken_ms -> debug"
|
||||||
|
# Warning: Using log-level-overrides has a performance penalty. Only use it for temporary debugging.
|
||||||
|
#
|
||||||
|
# Example (good for production):
|
||||||
|
# log-level: info
|
||||||
|
# log-format: json
|
||||||
|
# log-file: /var/log/ntfy.log
|
||||||
|
#
|
||||||
|
# Example level overrides (for debugging, only use temporarily):
|
||||||
|
# log-level-overrides:
|
||||||
|
# - "tag=manager -> trace"
|
||||||
|
# - "visitor_ip=1.2.3.4 -> debug"
|
||||||
|
# - "time_taken_ms -> debug"
|
||||||
|
#
|
||||||
|
# log-level: info
|
||||||
|
# log-level-overrides:
|
||||||
|
# log-format: text
|
||||||
|
# log-file:
|
||||||
@@ -4,6 +4,7 @@ module.exports = {
|
|||||||
delay: 30,
|
delay: 30,
|
||||||
|
|
||||||
torznab: [
|
torznab: [
|
||||||
|
"http://prowlarr.local.{{ personal_domain }}/3/api?apikey={{ prowlarr_api_key }}", // ImmortalSeed
|
||||||
"http://prowlarr.local.{{ personal_domain }}/6/api?apikey={{ prowlarr_api_key }}", // Aither
|
"http://prowlarr.local.{{ personal_domain }}/6/api?apikey={{ prowlarr_api_key }}", // Aither
|
||||||
"http://prowlarr.local.{{ personal_domain }}/7/api?apikey={{ prowlarr_api_key }}", // Reelflix
|
"http://prowlarr.local.{{ personal_domain }}/7/api?apikey={{ prowlarr_api_key }}", // Reelflix
|
||||||
"http://prowlarr.local.{{ personal_domain }}/9/api?apikey={{ prowlarr_api_key }}", // LST
|
"http://prowlarr.local.{{ personal_domain }}/9/api?apikey={{ prowlarr_api_key }}", // LST
|
||||||
@@ -15,12 +16,7 @@ module.exports = {
|
|||||||
"http://prowlarr.local.{{ personal_domain }}/19/api?apikey={{ prowlarr_api_key }}", // Cathode-Ray.Tube
|
"http://prowlarr.local.{{ personal_domain }}/19/api?apikey={{ prowlarr_api_key }}", // Cathode-Ray.Tube
|
||||||
"http://prowlarr.local.{{ personal_domain }}/25/api?apikey={{ prowlarr_api_key }}", // seedpool
|
"http://prowlarr.local.{{ personal_domain }}/25/api?apikey={{ prowlarr_api_key }}", // seedpool
|
||||||
"http://prowlarr.local.{{ personal_domain }}/27/api?apikey={{ prowlarr_api_key }}", // Upload.cx
|
"http://prowlarr.local.{{ personal_domain }}/27/api?apikey={{ prowlarr_api_key }}", // Upload.cx
|
||||||
"http://prowlarr.local.{{ personal_domain }}/28/api?apikey={{ prowlarr_api_key }}", // AnimeBytes
|
|
||||||
"http://prowlarr.local.{{ personal_domain }}/30/api?apikey={{ prowlarr_api_key }}", // DocsPedia
|
"http://prowlarr.local.{{ personal_domain }}/30/api?apikey={{ prowlarr_api_key }}", // DocsPedia
|
||||||
"http://prowlarr.local.{{ personal_domain }}/31/api?apikey={{ prowlarr_api_key }}", // OnlyEncodes+
|
|
||||||
"http://prowlarr.local.{{ personal_domain }}/32/api?apikey={{ prowlarr_api_key }}", // Anthelion
|
|
||||||
"http://prowlarr.local.{{ personal_domain }}/33/api?apikey={{ prowlarr_api_key }}", // OldToonsWorld
|
|
||||||
"http://prowlarr.local.{{ personal_domain }}/34/api?apikey={{ prowlarr_api_key }}", // Zenith
|
|
||||||
],
|
],
|
||||||
|
|
||||||
outputDir: null,
|
outputDir: null,
|
||||||
@@ -30,7 +26,7 @@ module.exports = {
|
|||||||
excludeOlder: "12w",
|
excludeOlder: "12w",
|
||||||
excludeRecentSearch: "3w",
|
excludeRecentSearch: "3w",
|
||||||
action: "inject",
|
action: "inject",
|
||||||
torrentClients: ["qbittorrent:https://qui.local.{{ personal_domain }}/proxy/{{ qui_crossseed_api_key }}"],
|
torrentClients: ["qbittorrent:https://admin:password@qbittorrent.local.{{ personal_domain }}"],
|
||||||
sonarr: ["https://sonarr.local.{{ personal_domain }}/?apikey={{ sonarr_api_key }}"],
|
sonarr: ["https://sonarr.local.{{ personal_domain }}/?apikey={{ sonarr_api_key }}"],
|
||||||
radarr: ["https://radarr.local.{{ personal_domain }}/?apikey={{ radarr_api_key }}"],
|
radarr: ["https://radarr.local.{{ personal_domain }}/?apikey={{ radarr_api_key }}"],
|
||||||
seasonsFromEpisodes: 0.8,
|
seasonsFromEpisodes: 0.8,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ networks:
|
|||||||
services:
|
services:
|
||||||
qbittorrent:
|
qbittorrent:
|
||||||
container_name: qbittorrent
|
container_name: qbittorrent
|
||||||
image: lscr.io/linuxserver/qbittorrent:5.2.3
|
image: lscr.io/linuxserver/qbittorrent:5.1.2
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
network_mode: "container:gluetun"
|
network_mode: "container:gluetun"
|
||||||
environment:
|
environment:
|
||||||
@@ -13,7 +13,7 @@ services:
|
|||||||
- "PGID={{ media_gid }}"
|
- "PGID={{ media_gid }}"
|
||||||
- "TZ={{ timezone }}"
|
- "TZ={{ timezone }}"
|
||||||
- "UMASK=002"
|
- "UMASK=002"
|
||||||
#- DOCKER_MODS=arafatamim/linuxserver-io-mod-vuetorrent
|
- DOCKER_MODS=arafatamim/linuxserver-io-mod-vuetorrent
|
||||||
volumes:
|
volumes:
|
||||||
- "{{ data_dir }}/{{ role_name }}:/config"
|
- "{{ data_dir }}/{{ role_name }}:/config"
|
||||||
- "{{ media_storage_mnt }}/data/torrents:/data/torrents"
|
- "{{ media_storage_mnt }}/data/torrents:/data/torrents"
|
||||||
@@ -52,3 +52,26 @@ services:
|
|||||||
- "{{ media_storage_mnt }}/data/torrents:/data/torrents" # Necessary for partial matching
|
- "{{ media_storage_mnt }}/data/torrents:/data/torrents" # Necessary for partial matching
|
||||||
command: daemon
|
command: daemon
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
|
unpackerr:
|
||||||
|
container_name: unpackerr
|
||||||
|
image: ghcr.io/hotio/unpackerr
|
||||||
|
networks:
|
||||||
|
- starr
|
||||||
|
environment:
|
||||||
|
- "PUID={{ service_user.uid }}"
|
||||||
|
- "PGID={{ media_gid }}"
|
||||||
|
- UMASK=002
|
||||||
|
- TZ={{ timezone }}
|
||||||
|
- UN_INTERVAL=5m
|
||||||
|
- UN_FILE_MODE=0664
|
||||||
|
- UN_DIR_MODE=0775
|
||||||
|
- UN_SONARR_0_URL=http://sonarr:8989
|
||||||
|
- "UN_SONARR_0_API_KEY={{ sonarr_api_key }}"
|
||||||
|
- UN_SONARR_0_PATHS_0=/data/torrents/tv
|
||||||
|
- UN_RADARR_0_URL=http://radarr:7878
|
||||||
|
- "UN_RADARR_0_API_KEY={{ radarr_api_key }}"
|
||||||
|
- UN_RADARR_0_PATHS_0=/data/torrents/movies
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/unpackerr:/config"
|
||||||
|
- "{{ media_storage_mnt }}/data/torrents:/data/torrents"
|
||||||
@@ -5,11 +5,11 @@ commands:
|
|||||||
recheck: True
|
recheck: True
|
||||||
tag_update: True
|
tag_update: True
|
||||||
rem_unregistered: True
|
rem_unregistered: True
|
||||||
rem_orphaned: True
|
remove_orphaned: True
|
||||||
tag_nohardlinks: True
|
tag_nohardlinks: True
|
||||||
|
|
||||||
qbt:
|
qbt:
|
||||||
host: "https://qui.local.{{ personal_domain }}/proxy/{{ qui_qbitmanage_api_key }}"
|
host: "https://qbittorrent.local.{{ personal_domain }}"
|
||||||
user:
|
user:
|
||||||
pass:
|
pass:
|
||||||
|
|
||||||
@@ -41,32 +41,36 @@ cat:
|
|||||||
tracker:
|
tracker:
|
||||||
hawke:
|
hawke:
|
||||||
tag: HUNO
|
tag: HUNO
|
||||||
|
digitalcore:
|
||||||
|
tag: DigitalCore
|
||||||
myanonamouse:
|
myanonamouse:
|
||||||
tag: MaM
|
tag: MaM
|
||||||
torrentleech|tleechreload:
|
torrentleech|tleechreload:
|
||||||
tag: TL
|
tag: TorrentLeech
|
||||||
aither:
|
aither:
|
||||||
tag: ATH
|
tag: Aither
|
||||||
nyaa:
|
nyaa:
|
||||||
tag: Nyaa
|
tag: Nyaa
|
||||||
animetosho:
|
animetosho:
|
||||||
tag: AnimeTosho
|
tag: AnimeTosho
|
||||||
immortalseed:
|
immortalseed:
|
||||||
tag: ImmortalSeed
|
tag: ImmortalSeed
|
||||||
|
torrentseeds:
|
||||||
|
tag: TorrentSeeds
|
||||||
ops:
|
ops:
|
||||||
tag: OPS
|
tag: Orpheus
|
||||||
reelflix:
|
reelflix:
|
||||||
tag: RFX
|
tag: ReelFlix
|
||||||
blutopia:
|
blutopia:
|
||||||
tag: BLU
|
tag: Blu
|
||||||
lst:
|
lst:
|
||||||
tag: LST
|
tag: LST
|
||||||
speed:
|
speed:
|
||||||
tag: Speed.CD
|
tag: Speed.CD
|
||||||
alpharatio:
|
alpharatio:
|
||||||
tag: AR
|
tag: AlphaRatio
|
||||||
filelist:
|
filelist:
|
||||||
tag: FL
|
tag: FileList
|
||||||
skipthecommericals.xyz:
|
skipthecommericals.xyz:
|
||||||
tag: STC
|
tag: STC
|
||||||
cathode:
|
cathode:
|
||||||
@@ -74,19 +78,11 @@ tracker:
|
|||||||
t-ru.org:
|
t-ru.org:
|
||||||
tag: rutracker
|
tag: rutracker
|
||||||
seedpool|seedpool.org:
|
seedpool|seedpool.org:
|
||||||
tag: SP
|
tag: seedpool
|
||||||
upload.cx:
|
upload:
|
||||||
tag: ULCX
|
tag: ULCX
|
||||||
archlinux:
|
archlinux:
|
||||||
tag: archlinux
|
tag: archlinux
|
||||||
animebytes:
|
|
||||||
tag: AB
|
|
||||||
anthelion:
|
|
||||||
tag: ANT
|
|
||||||
onlyencodes:
|
|
||||||
tag: OE+
|
|
||||||
oldtoons:
|
|
||||||
tag: OTW
|
|
||||||
other:
|
other:
|
||||||
tag: other
|
tag: other
|
||||||
|
|
||||||
@@ -103,7 +99,7 @@ share_limits:
|
|||||||
priority: 1
|
priority: 1
|
||||||
include_all_tags:
|
include_all_tags:
|
||||||
- noHL
|
- noHL
|
||||||
max_seeding_time: 40320 # 4 weeks
|
max_seeding_time: 28800 # 20 days
|
||||||
cleanup: true
|
cleanup: true
|
||||||
add_group_to_tag: false
|
add_group_to_tag: false
|
||||||
isos:
|
isos:
|
||||||
|
|||||||
@@ -33,25 +33,3 @@ crossseed_webhook_endpoint: !vault |
|
|||||||
37633631313965396233613333373832353463653337393861393335373661393163343037306130
|
37633631313965396233613333373832353463653337393861393335373661393163343037306130
|
||||||
6337376662653463316530313863613532633338623731356536
|
6337376662653463316530313863613532633338623731356536
|
||||||
|
|
||||||
qui_crossseed_api_key: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
31663334373665646433616663326336306631653833373765366463373166316661333463316235
|
|
||||||
3861633161623034356431383030326233353836656466390a386534356665633561376263363030
|
|
||||||
63383766383535366530306238393836613337366136363037313364336164383366636166623265
|
|
||||||
3964366637613866300a653231333566356566616537356330613938353464303530616232306238
|
|
||||||
32666665653534653765653034396232663161323261623237373739333634383038346562613063
|
|
||||||
65653332666336613861363965393562366465666261666536396231303461656162373436633830
|
|
||||||
63326536613230626563626232363835373635323533333332373136356430393439316666386439
|
|
||||||
65356230376630376630
|
|
||||||
|
|
||||||
qui_qbitmanage_api_key: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
39616437313930376137323434396438333562316565306233316166383465333134623836633365
|
|
||||||
6136333039373366396461356665333236326539323731380a653664656637313933346533396433
|
|
||||||
33643430343437623132666233383434613066346338646232666539633066333662343565336466
|
|
||||||
3031323265343936660a366265313430663330643132373233383765633066396566343963663662
|
|
||||||
61386365653233366237363062336539653361373930383530653031656638356533313061626635
|
|
||||||
33663932666536396431626363623437326133646661653834376335373562353065323633326234
|
|
||||||
33316338653865326534336530656231643830616434396637306561376436633632343731623065
|
|
||||||
37343434326461346465
|
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
- name: Create service user
|
||||||
|
user:
|
||||||
|
name: "{{ role_name }}"
|
||||||
|
groups: "{{ media_group }}"
|
||||||
|
append: yes
|
||||||
|
system: true
|
||||||
|
register: service_user
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Start docker container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
+2
-4
@@ -1,17 +1,15 @@
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
traefik:
|
traefik:
|
||||||
external: true
|
external: true
|
||||||
starr:
|
|
||||||
external: true
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
{{ role_name }}:
|
{{ role_name }}:
|
||||||
container_name: "{{ role_name }}"
|
container_name: "{{ role_name }}"
|
||||||
image: chaptarr/chaptarr:latest
|
image: cr.hotio.dev/hotio/readarr
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- traefik
|
- traefik
|
||||||
- starr
|
|
||||||
environment:
|
environment:
|
||||||
- "PUID={{ service_user.uid }}"
|
- "PUID={{ service_user.uid }}"
|
||||||
- "PGID={{ media_gid }}"
|
- "PGID={{ media_gid }}"
|
||||||
@@ -48,9 +48,3 @@ custom_formats:
|
|||||||
assign_scores_to:
|
assign_scores_to:
|
||||||
- name: Anime
|
- name: Anime
|
||||||
score: 10 # Prefer dual audio within the same tier but not over higher quality releases
|
score: 10 # Prefer dual audio within the same tier but not over higher quality releases
|
||||||
|
|
||||||
- trash_ids:
|
|
||||||
- 923b6abef9b17f937fab56cfcf89e1f1 # DV (w/o HDR fallback)
|
|
||||||
assign_scores_to:
|
|
||||||
- name: Anime
|
|
||||||
score: -10000
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
custom_formats:
|
|
||||||
- trash_ids:
|
|
||||||
# HDR Formats
|
|
||||||
- c53085ddbd027d9624b320627748612f # DV HDR10+
|
|
||||||
- e23edd2482476e595fb990b12e7c609c # DV HDR10
|
|
||||||
- 58d6a88f13e2db7f5059c41047876f00 # DV
|
|
||||||
- 55d53828b9d81cbe20b02efd00aa0efd # DV HLG
|
|
||||||
- a3e19f8f627608af0211acd02bf89735 # DV SDR
|
|
||||||
- b974a6cd08c1066250f1f177d7aa1225 # HDR10+
|
|
||||||
- dfb86d5941bc9075d6af23b09c2aeecd # HDR10
|
|
||||||
- e61e28db95d22bedcadf030b8f156d96 # HDR
|
|
||||||
- 2a4d9069cc1fe3242ff9bdaebed239bb # HDR (undefined)
|
|
||||||
- 08d6d8834ad9ec87b1dc7ec8148e7a1f # PQ
|
|
||||||
- 9364dd386c9b4a1100dde8264690add7 # HLG
|
|
||||||
|
|
||||||
# HQ Release Groups
|
|
||||||
- 4d74ac4c4db0b64bff6ce0cffef99bf0 # UHD Bluray Tier 01
|
|
||||||
- a58f517a70193f8e578056642178419d # UHD Bluray Tier 02
|
|
||||||
- e71939fae578037e7aed3ee219bbe7c1 # UHD Bluray Tier 03
|
|
||||||
- ed27ebfef2f323e964fb1f61391bcb35 # HD Bluray Tier 01
|
|
||||||
- c20c8647f2746a1f4c4262b0fbbeeeae # HD Bluray Tier 02
|
|
||||||
- 5608c71bcebba0a5e666223bae8c9227 # HD Bluray Tier 03
|
|
||||||
- c20f169ef63c5f40c2def54abaf4438e # WEB Tier 01
|
|
||||||
- 403816d65392c79236dcb6dd591aeda4 # WEB Tier 02
|
|
||||||
- af94e0fe497124d1f9ce732069ec8c3b # WEB Tier 03
|
|
||||||
|
|
||||||
# General Streaming Services
|
|
||||||
- b3b3a6ac74ecbd56bcdbefa4799fb9df # AMZN
|
|
||||||
- 40e9380490e748672c2522eaaeb692f7 # ATVP
|
|
||||||
- cc5e51a9e85a6296ceefe097a77f12f4 # BCORE
|
|
||||||
- 16622a6911d1ab5d5b8b713d5b0036d4 # CRiT
|
|
||||||
- 84272245b2988854bfb76a16e60baea5 # DSNP
|
|
||||||
- 509e5f41146e278f9eab1ddaceb34515 # HBO
|
|
||||||
- 5763d1b0ce84aff3b21038eea8e9b8ad # HMAX
|
|
||||||
- 526d445d4c16214309f0fd2b3be18a89 # Hulu
|
|
||||||
- e0ec9672be6cac914ffad34a6b077209 # iT
|
|
||||||
- 6a061313d22e51e0f25b7cd4dc065233 # MAX
|
|
||||||
- 2a6039655313bf5dab1e43523b62c374 # MA
|
|
||||||
- 170b1d363bd8516fbf3a3eb05d4faff6 # NF
|
|
||||||
- e36a0ba1bc902b26ee40818a1d59b8bd # PMTP
|
|
||||||
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
|
||||||
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
|
||||||
|
|
||||||
# Movie Versions
|
|
||||||
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
|
||||||
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
|
||||||
- e0c07d59beb37348e975a930d5e50319 # Criterion Collection
|
|
||||||
- 9d27d9d2181838f76dee150882bdc58c # Masters of Cinema
|
|
||||||
- db9b4c4b53d312a3ca5f1378f6440fc9 # Vinegar Syndrome
|
|
||||||
- 957d0f44b592285f26449575e8b1167e # Special Edition
|
|
||||||
- eecf3a857724171f968a66cb5719e152 # IMAX
|
|
||||||
- 9f6cbff8cfe4ebbc1bde14c7b7bec0de # IMAX Enhanced
|
|
||||||
- 09d9dd29a0fc958f9796e65c2a8864b4 # Open Matte
|
|
||||||
|
|
||||||
# Miscellaneous
|
|
||||||
- e7718d7a3ce595f289bfee26adc178f5 # Repack/Proper
|
|
||||||
- ae43b294509409a6a13919dedd4764c4 # Repack2
|
|
||||||
- 5caaaa1c08c1742aa4342d8c4cc463f2 # Repack3
|
|
||||||
|
|
||||||
# Unwanted
|
|
||||||
- 923b6abef9b17f937fab56cfcf89e1f1 # DV (WEBDL)
|
|
||||||
- ed38b889b31be83fda192888e2286d83 # BR-DISK
|
|
||||||
- e6886871085226c3da1830830146846c # Gererated Dynamic HDR
|
|
||||||
- 90a6f9a284dff5103f6346090e6280c8 # LQ
|
|
||||||
- e204b80c87be9497a8a6eaff48f72905 # LQ (Release Title)
|
|
||||||
- 839bea857ed2c0a8e084f3cbdbd65ecb # x265 (no HDR/DV)
|
|
||||||
- 25c12f78430a3a23413652cbd1d48d77 # SDR (no WEBDL)
|
|
||||||
- b8cd450cbfa689c0259a01d9e29ba3d6 # 3D
|
|
||||||
- bfd8eb01832d646a0a89c4deb46f8564 # Upscaled
|
|
||||||
- 0a3f082873eb454bde444150b70253cc # Extras
|
|
||||||
- 712d74cd88bceb883ee32f773656b1f5 # Sing-Along Versions
|
|
||||||
- cae4ca30163749b891686f95532519bd # AV1
|
|
||||||
- b6832f586342ef70d9c128d40c07b872 # Bad Dual Groups
|
|
||||||
- cc444569854e9de0b084ab2b8b1532b2 # Black and White Editions
|
|
||||||
- ae9b7c9ebde1f3bd336a8cbd1ec4c5e5 # No-RlsGroup
|
|
||||||
- 7357cf5161efbf8c4d5d0c30b4815ee2 # Obfuscated
|
|
||||||
- 5c44f52a8714fdd79bb4d98e2673be1f # Retags
|
|
||||||
- f537cf427b64c38c8e36298f657e4828 # Scene
|
|
||||||
assign_scores_to:
|
|
||||||
- name: Encode
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
quality_profiles:
|
|
||||||
- name: Encode
|
|
||||||
upgrade:
|
|
||||||
allowed: true
|
|
||||||
until_quality: Bluray-2160p
|
|
||||||
until_score: 10000
|
|
||||||
min_format_score: 0
|
|
||||||
score_set: default
|
|
||||||
quality_sort: top
|
|
||||||
qualities:
|
|
||||||
- name: Bluray-2160p
|
|
||||||
- name: WEB 2160p
|
|
||||||
qualities:
|
|
||||||
- WEBDL-2160p
|
|
||||||
- WEBRip-2160p
|
|
||||||
- name: Bluray-1080p
|
|
||||||
- name: WEB 1080p
|
|
||||||
qualities:
|
|
||||||
- WEBDL-1080p
|
|
||||||
- WEBRip-1080p
|
|
||||||
- name: Remux-2160p
|
|
||||||
- name: Remux-1080p
|
|
||||||
@@ -41,6 +41,24 @@ custom_formats:
|
|||||||
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
||||||
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
||||||
|
|
||||||
|
# Audio
|
||||||
|
- 496f355514737f7d83bf7aa4d24f8169 # TrueHD Atmos
|
||||||
|
- 2f22d89048b01681dde8afe203bf2e95 # DTS:X
|
||||||
|
- 417804f7f2c4308c1f4c5d380d4c4475 # Atmos (undefined)
|
||||||
|
- 1af239278386be2919e1bcee0bde047e # DD+ Atmos
|
||||||
|
- 3cafb66171b47f226146a0770576870f # TrueHD
|
||||||
|
- dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
|
||||||
|
- a570d4a0e56a2874b64e5bfa55202a1b # FLAC
|
||||||
|
- e7c2fcae07cbada050a0af3357491d7b # PCM
|
||||||
|
- 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD HRA
|
||||||
|
- 185f1dd7264c4562b9022d963ac37424 # DD+
|
||||||
|
- f9f847ac70a0af62ea4a08280b859636 # DTS-ES
|
||||||
|
- 1c1a4c5e823891c75bc50380a6866f73 # DTS
|
||||||
|
- 240770601cc226190c367ef59aba7463 # AAC
|
||||||
|
- c2998bd0d90ed5621d8df281e839436e # DD
|
||||||
|
- 6ba9033150e7896bdc9ec4b44f2b230f # MP3
|
||||||
|
- a061e2e700f81932daf888599f8a8273 # Opus
|
||||||
|
|
||||||
# Movie Versions
|
# Movie Versions
|
||||||
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
||||||
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
||||||
|
|||||||
@@ -44,6 +44,24 @@ custom_formats:
|
|||||||
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
||||||
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
||||||
|
|
||||||
|
# Audio
|
||||||
|
- 496f355514737f7d83bf7aa4d24f8169 # TrueHD Atmos
|
||||||
|
- 2f22d89048b01681dde8afe203bf2e95 # DTS:X
|
||||||
|
- 417804f7f2c4308c1f4c5d380d4c4475 # Atmos (undefined)
|
||||||
|
- 1af239278386be2919e1bcee0bde047e # DD+ Atmos
|
||||||
|
- 3cafb66171b47f226146a0770576870f # TrueHD
|
||||||
|
- dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
|
||||||
|
- a570d4a0e56a2874b64e5bfa55202a1b # FLAC
|
||||||
|
- e7c2fcae07cbada050a0af3357491d7b # PCM
|
||||||
|
- 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD HRA
|
||||||
|
- 185f1dd7264c4562b9022d963ac37424 # DD+
|
||||||
|
- f9f847ac70a0af62ea4a08280b859636 # DTS-ES
|
||||||
|
- 1c1a4c5e823891c75bc50380a6866f73 # DTS
|
||||||
|
- 240770601cc226190c367ef59aba7463 # AAC
|
||||||
|
- c2998bd0d90ed5621d8df281e839436e # DD
|
||||||
|
- 6ba9033150e7896bdc9ec4b44f2b230f # MP3
|
||||||
|
- a061e2e700f81932daf888599f8a8273 # Opus
|
||||||
|
|
||||||
# Movie Versions
|
# Movie Versions
|
||||||
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
||||||
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
||||||
|
|||||||
@@ -44,6 +44,24 @@ custom_formats:
|
|||||||
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
||||||
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
||||||
|
|
||||||
|
# Audio
|
||||||
|
- 496f355514737f7d83bf7aa4d24f8169 # TrueHD Atmos
|
||||||
|
- 2f22d89048b01681dde8afe203bf2e95 # DTS:X
|
||||||
|
- 417804f7f2c4308c1f4c5d380d4c4475 # Atmos (undefined)
|
||||||
|
- 1af239278386be2919e1bcee0bde047e # DD+ Atmos
|
||||||
|
- 3cafb66171b47f226146a0770576870f # TrueHD
|
||||||
|
- dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
|
||||||
|
- a570d4a0e56a2874b64e5bfa55202a1b # FLAC
|
||||||
|
- e7c2fcae07cbada050a0af3357491d7b # PCM
|
||||||
|
- 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD HRA
|
||||||
|
- 185f1dd7264c4562b9022d963ac37424 # DD+
|
||||||
|
- f9f847ac70a0af62ea4a08280b859636 # DTS-ES
|
||||||
|
- 1c1a4c5e823891c75bc50380a6866f73 # DTS
|
||||||
|
- 240770601cc226190c367ef59aba7463 # AAC
|
||||||
|
- c2998bd0d90ed5621d8df281e839436e # DD
|
||||||
|
- 6ba9033150e7896bdc9ec4b44f2b230f # MP3
|
||||||
|
- a061e2e700f81932daf888599f8a8273 # Opus
|
||||||
|
|
||||||
# Movie Versions
|
# Movie Versions
|
||||||
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
||||||
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
||||||
|
|||||||
@@ -44,6 +44,24 @@ custom_formats:
|
|||||||
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
|
||||||
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
- c2863d2a50c9acad1fb50e53ece60817 # STAN
|
||||||
|
|
||||||
|
# Audio
|
||||||
|
- 496f355514737f7d83bf7aa4d24f8169 # TrueHD Atmos
|
||||||
|
- 2f22d89048b01681dde8afe203bf2e95 # DTS:X
|
||||||
|
- 417804f7f2c4308c1f4c5d380d4c4475 # Atmos (undefined)
|
||||||
|
- 1af239278386be2919e1bcee0bde047e # DD+ Atmos
|
||||||
|
- 3cafb66171b47f226146a0770576870f # TrueHD
|
||||||
|
- dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
|
||||||
|
- a570d4a0e56a2874b64e5bfa55202a1b # FLAC
|
||||||
|
- e7c2fcae07cbada050a0af3357491d7b # PCM
|
||||||
|
- 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD HRA
|
||||||
|
- 185f1dd7264c4562b9022d963ac37424 # DD+
|
||||||
|
- f9f847ac70a0af62ea4a08280b859636 # DTS-ES
|
||||||
|
- 1c1a4c5e823891c75bc50380a6866f73 # DTS
|
||||||
|
- 240770601cc226190c367ef59aba7463 # AAC
|
||||||
|
- c2998bd0d90ed5621d8df281e839436e # DD
|
||||||
|
- 6ba9033150e7896bdc9ec4b44f2b230f # MP3
|
||||||
|
- a061e2e700f81932daf888599f8a8273 # Opus
|
||||||
|
|
||||||
# Movie Versions
|
# Movie Versions
|
||||||
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
- 570bc9ebecd92723d2d21500f4be314c # Remaster
|
||||||
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
|
||||||
|
|||||||
@@ -68,6 +68,31 @@ custom_formats:
|
|||||||
- c2216b7b8aa545dc1ce8388c618f8d57 # HD Bluray Tier 02
|
- c2216b7b8aa545dc1ce8388c618f8d57 # HD Bluray Tier 02
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
||||||
|
|
||||||
|
# Audio Advanced
|
||||||
|
- 0d7824bb924701997f874e7ff7d4844a # TrueHD Atmos
|
||||||
|
- 9d00418ba386a083fbf4d58235fc37ef # DTS:X
|
||||||
|
- b6fbafa7942952a13e17e2b1152b539a # Atmos (undefined)
|
||||||
|
- 4232a509ce60c4e208d13825b7c06264 # DDPlus Atmos
|
||||||
|
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
|
||||||
|
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
|
||||||
|
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
|
||||||
|
- 30f70576671ca933adbdcfc736a69718 # PCM
|
||||||
|
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
|
||||||
|
- 63487786a8b01b7f20dd2bc90dd4a477 # DDPlus
|
||||||
|
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
|
||||||
|
- 5964f2a8b3be407d083498e4459d05d0 # DTS
|
||||||
|
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
|
||||||
|
- dbe00161b08a25ac6154c55f95e6318d # DD
|
||||||
|
- 3e8b714263b26f486972ee1e0fe7606c # MP3
|
||||||
|
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
|
||||||
|
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
|
||||||
|
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
|
||||||
|
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
|
||||||
|
- 1895195e84767de180653914ce207245 # 4.0 Sound
|
||||||
|
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
|
||||||
|
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
|
||||||
|
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
|
||||||
|
|
||||||
# Unwanted
|
# Unwanted
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
||||||
- b4a1b3d705159cdca36d71e57ca86871 # Anime Raws
|
- b4a1b3d705159cdca36d71e57ca86871 # Anime Raws
|
||||||
@@ -83,3 +108,9 @@ custom_formats:
|
|||||||
assign_scores_to:
|
assign_scores_to:
|
||||||
- name: Anime
|
- name: Anime
|
||||||
score: 10 # Prefer dual audio within the same tier but don't prefer over higher quality releases
|
score: 10 # Prefer dual audio within the same tier but don't prefer over higher quality releases
|
||||||
|
|
||||||
|
- trash_ids:
|
||||||
|
- 3bc5f395426614e155e585a2f056cdf1 # Season Pack
|
||||||
|
assign_scores_to:
|
||||||
|
- name: Anime
|
||||||
|
score: 10 # Prefer season packs over single episode releases
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
custom_formats:
|
|
||||||
- trash_ids:
|
|
||||||
# HDR Formats
|
|
||||||
- 2b239ed870daba8126a53bd5dc8dc1c8 # DV HDR10+
|
|
||||||
- 7878c33f1963fefb3d6c8657d46c2f0a # DV HDR10
|
|
||||||
- 6d0d8de7b57e35518ac0308b0ddf404e # DV
|
|
||||||
- 1f733af03141f068a540eec352589a89 # DV HLG
|
|
||||||
- 27954b0a80aab882522a88a4d9eae1cd # DV SDR
|
|
||||||
- a3d82cbef5039f8d295478d28a887159 # HDR10+
|
|
||||||
- 3497799d29a085e2ac2df9d468413c94 # HDR10
|
|
||||||
- 3e2c4e748b64a1a1118e0ea3f4cf6875 # HDR
|
|
||||||
- bb019e1cd00f304f80971c965de064dc # HDR (undefined)
|
|
||||||
- 2a7e3be05d3861d6df7171ec74cad727 # PQ
|
|
||||||
- 17e889ce13117940092308f48b48b45b # HLG
|
|
||||||
- 9b27ab6498ec0f31a3353992e19434ca # DV (WEBDL)
|
|
||||||
|
|
||||||
# Miscellaneous
|
|
||||||
- ec8fa7296b64e8cd390a1600981f3923 # Repack/Proper
|
|
||||||
- eb3d5cc0a2be0db205fb823640db6a3c # Repack v2
|
|
||||||
- 44e7c4de10ae50265753082e5dc76047 # Repack v3
|
|
||||||
- b735f09d3c025cbb7d75a5d38325b73b # Remaster
|
|
||||||
- 3bc5f395426614e155e585a2f056cdf1 # Season Pack
|
|
||||||
|
|
||||||
# Streaming Services
|
|
||||||
- d660701077794679fd59e8bdf4ce3a29 # AMZN
|
|
||||||
- f67c9ca88f463a48346062e8ad07713f # ATVP
|
|
||||||
- 77a7b25585c18af08f60b1547bb9b4fb # CC
|
|
||||||
- 36b72f59f4ea20aad9316f475f2d9fbb # DCU
|
|
||||||
- 89358767a60cc28783cdc3d0be9388a4 # DSNP
|
|
||||||
- a880d6abc21e7c16884f3ae393f84179 # HMAX
|
|
||||||
- 7a235133c87f7da4c8cccceca7e3c7a6 # HBO
|
|
||||||
- f6cce30f1733d5c8194222a7507909bb # HULU
|
|
||||||
- 0ac24a2a68a9700bcb7eeca8e5cd644c # iT
|
|
||||||
- 81d1fbf600e2540cee87f3a23f9d3c1c # MAX
|
|
||||||
- d34870697c9db575f17700212167be23 # NF
|
|
||||||
- c67a75ae4a1715f2bb4d492755ba4195 # PMTP
|
|
||||||
- 1656adc6d7bb2c8cca6acfb6592db421 # PCOK
|
|
||||||
- ae58039e1319178e6be73caab5c42166 # SHO
|
|
||||||
- 1efe8da11bfd74fbbcd4d8117ddb9213 # STAN
|
|
||||||
- 9623c5c9cac8e939c1b9aedd32f640bf # SYFY
|
|
||||||
- 9623c5c9cac8e939c1b9aedd32f640bf # UHD Streaming Boost
|
|
||||||
- d2d299244a92b8a52d4921ce3897a256 # UHD Streaming Cut
|
|
||||||
|
|
||||||
# Release Group Tiers
|
|
||||||
- 9965a052eb87b0d10313b1cea89eb451 # Remux Tier 01
|
|
||||||
- 8a1d0c3d7497e741736761a1da866a2e # Remux Tier 02
|
|
||||||
- d6819cba26b1a6508138d25fb5e32293 # HD Bluray Tier 01
|
|
||||||
- c2216b7b8aa545dc1ce8388c618f8d57 # HD Bluray Tier 02
|
|
||||||
- e6258996055b9fbab7e9cb2f75819294 # WEB Tier 01
|
|
||||||
- 58790d4e2fdcd9733aa7ae68ba2bb503 # WEB Tier 02
|
|
||||||
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
|
||||||
|
|
||||||
# Unwanted
|
|
||||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
|
||||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
|
||||||
- e2315f990da2e2cbfc9fa5b7a6fcfe48 # LQ (Release Title)
|
|
||||||
- 9b64dff695c2115facf1b6ea59c9bd07 # x265 (no HDR/DV)
|
|
||||||
- 83304f261cf516bb208c18c54c0adf97 # SDR (no WEBDL)
|
|
||||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
|
||||||
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
|
||||||
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
|
||||||
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
|
||||||
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
|
||||||
- b735f09d3c025cbb7d75a5d38325b73b # Upscaled
|
|
||||||
assign_scores_to:
|
|
||||||
- name: Remux
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
quality_profiles:
|
|
||||||
- name: Remux
|
|
||||||
upgrade:
|
|
||||||
allowed: true
|
|
||||||
until_quality: 'Bluray-2160p Remux'
|
|
||||||
until_score: 10000
|
|
||||||
min_format_score: 0
|
|
||||||
score_set: default
|
|
||||||
quality_sort: top
|
|
||||||
qualities:
|
|
||||||
- name: 'Bluray-2160p Remux'
|
|
||||||
- name: 'Bluray-1080p Remux'
|
|
||||||
- name: Bluray-2160p
|
|
||||||
- name: WEB 2160p
|
|
||||||
qualities:
|
|
||||||
- WEBDL-2160p
|
|
||||||
- WEBRip-2160p
|
|
||||||
- name: Bluray-1080p
|
|
||||||
- name: WEB 1080p
|
|
||||||
qualities:
|
|
||||||
- WEBDL-1080p
|
|
||||||
- WEBRip-1080p
|
|
||||||
@@ -51,6 +51,31 @@ custom_formats:
|
|||||||
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
||||||
|
|
||||||
|
# Audio Advanced
|
||||||
|
- 0d7824bb924701997f874e7ff7d4844a # TrueHD Atmos
|
||||||
|
- 9d00418ba386a083fbf4d58235fc37ef # DTS:X
|
||||||
|
- b6fbafa7942952a13e17e2b1152b539a # Atmos (undefined)
|
||||||
|
- 4232a509ce60c4e208d13825b7c06264 # DDPlus Atmos
|
||||||
|
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
|
||||||
|
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
|
||||||
|
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
|
||||||
|
- 30f70576671ca933adbdcfc736a69718 # PCM
|
||||||
|
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
|
||||||
|
- 63487786a8b01b7f20dd2bc90dd4a477 # DDPlus
|
||||||
|
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
|
||||||
|
- 5964f2a8b3be407d083498e4459d05d0 # DTS
|
||||||
|
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
|
||||||
|
- dbe00161b08a25ac6154c55f95e6318d # DD
|
||||||
|
- 3e8b714263b26f486972ee1e0fe7606c # MP3
|
||||||
|
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
|
||||||
|
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
|
||||||
|
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
|
||||||
|
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
|
||||||
|
- 1895195e84767de180653914ce207245 # 4.0 Sound
|
||||||
|
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
|
||||||
|
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
|
||||||
|
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
|
||||||
|
|
||||||
# Unwanted
|
# Unwanted
|
||||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
||||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
||||||
@@ -60,6 +85,8 @@ custom_formats:
|
|||||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
||||||
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
||||||
|
- ae575f95ab639ba5d15f663bf019e3e8 # Not Original Language
|
||||||
|
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
||||||
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
||||||
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
||||||
- b735f09d3c025cbb7d75a5d38325b73b # Upscaled
|
- b735f09d3c025cbb7d75a5d38325b73b # Upscaled
|
||||||
|
|||||||
@@ -51,6 +51,31 @@ custom_formats:
|
|||||||
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
||||||
|
|
||||||
|
# Audio Advanced
|
||||||
|
- 0d7824bb924701997f874e7ff7d4844a # TrueHD Atmos
|
||||||
|
- 9d00418ba386a083fbf4d58235fc37ef # DTS:X
|
||||||
|
- b6fbafa7942952a13e17e2b1152b539a # Atmos (undefined)
|
||||||
|
- 4232a509ce60c4e208d13825b7c06264 # DDPlus Atmos
|
||||||
|
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
|
||||||
|
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
|
||||||
|
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
|
||||||
|
- 30f70576671ca933adbdcfc736a69718 # PCM
|
||||||
|
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
|
||||||
|
- 63487786a8b01b7f20dd2bc90dd4a477 # DDPlus
|
||||||
|
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
|
||||||
|
- 5964f2a8b3be407d083498e4459d05d0 # DTS
|
||||||
|
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
|
||||||
|
- dbe00161b08a25ac6154c55f95e6318d # DD
|
||||||
|
- 3e8b714263b26f486972ee1e0fe7606c # MP3
|
||||||
|
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
|
||||||
|
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
|
||||||
|
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
|
||||||
|
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
|
||||||
|
- 1895195e84767de180653914ce207245 # 4.0 Sound
|
||||||
|
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
|
||||||
|
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
|
||||||
|
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
|
||||||
|
|
||||||
# Unwanted
|
# Unwanted
|
||||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
||||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
||||||
@@ -60,6 +85,8 @@ custom_formats:
|
|||||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
||||||
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
||||||
|
- ae575f95ab639ba5d15f663bf019e3e8 # Not Original Language
|
||||||
|
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
||||||
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
||||||
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
||||||
- b735f09d3c025cbb7d75a5d38325b73b # Upscaled
|
- b735f09d3c025cbb7d75a5d38325b73b # Upscaled
|
||||||
|
|||||||
@@ -51,6 +51,31 @@ custom_formats:
|
|||||||
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
||||||
|
|
||||||
|
# Audio Advanced
|
||||||
|
- 0d7824bb924701997f874e7ff7d4844a # TrueHD Atmos
|
||||||
|
- 9d00418ba386a083fbf4d58235fc37ef # DTS:X
|
||||||
|
- b6fbafa7942952a13e17e2b1152b539a # Atmos (undefined)
|
||||||
|
- 4232a509ce60c4e208d13825b7c06264 # DDPlus Atmos
|
||||||
|
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
|
||||||
|
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
|
||||||
|
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
|
||||||
|
- 30f70576671ca933adbdcfc736a69718 # PCM
|
||||||
|
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
|
||||||
|
- 63487786a8b01b7f20dd2bc90dd4a477 # DDPlus
|
||||||
|
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
|
||||||
|
- 5964f2a8b3be407d083498e4459d05d0 # DTS
|
||||||
|
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
|
||||||
|
- dbe00161b08a25ac6154c55f95e6318d # DD
|
||||||
|
- 3e8b714263b26f486972ee1e0fe7606c # MP3
|
||||||
|
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
|
||||||
|
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
|
||||||
|
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
|
||||||
|
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
|
||||||
|
- 1895195e84767de180653914ce207245 # 4.0 Sound
|
||||||
|
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
|
||||||
|
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
|
||||||
|
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
|
||||||
|
|
||||||
# Unwanted
|
# Unwanted
|
||||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
||||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
||||||
@@ -60,6 +85,7 @@ custom_formats:
|
|||||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
||||||
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
||||||
|
- ae575f95ab639ba5d15f663bf019e3e8 # Not Original Language
|
||||||
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
||||||
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
||||||
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
||||||
|
|||||||
@@ -51,6 +51,31 @@ custom_formats:
|
|||||||
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
||||||
|
|
||||||
|
# Audio Advanced
|
||||||
|
- 0d7824bb924701997f874e7ff7d4844a # TrueHD Atmos
|
||||||
|
- 9d00418ba386a083fbf4d58235fc37ef # DTS:X
|
||||||
|
- b6fbafa7942952a13e17e2b1152b539a # Atmos (undefined)
|
||||||
|
- 4232a509ce60c4e208d13825b7c06264 # DDPlus Atmos
|
||||||
|
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
|
||||||
|
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
|
||||||
|
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
|
||||||
|
- 30f70576671ca933adbdcfc736a69718 # PCM
|
||||||
|
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
|
||||||
|
- 63487786a8b01b7f20dd2bc90dd4a477 # DDPlus
|
||||||
|
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
|
||||||
|
- 5964f2a8b3be407d083498e4459d05d0 # DTS
|
||||||
|
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
|
||||||
|
- dbe00161b08a25ac6154c55f95e6318d # DD
|
||||||
|
- 3e8b714263b26f486972ee1e0fe7606c # MP3
|
||||||
|
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
|
||||||
|
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
|
||||||
|
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
|
||||||
|
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
|
||||||
|
- 1895195e84767de180653914ce207245 # 4.0 Sound
|
||||||
|
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
|
||||||
|
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
|
||||||
|
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
|
||||||
|
|
||||||
# Unwanted
|
# Unwanted
|
||||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
||||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
||||||
@@ -60,6 +85,7 @@ custom_formats:
|
|||||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
||||||
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
||||||
|
- ae575f95ab639ba5d15f663bf019e3e8 # Not Original Language
|
||||||
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
||||||
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
||||||
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
||||||
|
|||||||
@@ -51,6 +51,31 @@ custom_formats:
|
|||||||
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
||||||
|
|
||||||
|
# Audio Advanced
|
||||||
|
- 0d7824bb924701997f874e7ff7d4844a # TrueHD Atmos
|
||||||
|
- 9d00418ba386a083fbf4d58235fc37ef # DTS:X
|
||||||
|
- b6fbafa7942952a13e17e2b1152b539a # Atmos (undefined)
|
||||||
|
- 4232a509ce60c4e208d13825b7c06264 # DDPlus Atmos
|
||||||
|
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
|
||||||
|
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
|
||||||
|
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
|
||||||
|
- 30f70576671ca933adbdcfc736a69718 # PCM
|
||||||
|
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
|
||||||
|
- 63487786a8b01b7f20dd2bc90dd4a477 # DDPlus
|
||||||
|
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
|
||||||
|
- 5964f2a8b3be407d083498e4459d05d0 # DTS
|
||||||
|
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
|
||||||
|
- dbe00161b08a25ac6154c55f95e6318d # DD
|
||||||
|
- 3e8b714263b26f486972ee1e0fe7606c # MP3
|
||||||
|
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
|
||||||
|
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
|
||||||
|
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
|
||||||
|
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
|
||||||
|
- 1895195e84767de180653914ce207245 # 4.0 Sound
|
||||||
|
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
|
||||||
|
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
|
||||||
|
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
|
||||||
|
|
||||||
# Unwanted
|
# Unwanted
|
||||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
||||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
||||||
@@ -60,6 +85,7 @@ custom_formats:
|
|||||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
||||||
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
||||||
|
- ae575f95ab639ba5d15f663bf019e3e8 # Not Original Language
|
||||||
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
||||||
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
||||||
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
||||||
|
|||||||
@@ -8,24 +8,12 @@ quality_profiles:
|
|||||||
score_set: default
|
score_set: default
|
||||||
quality_sort: top
|
quality_sort: top
|
||||||
qualities:
|
qualities:
|
||||||
- name: 'WEB 2160p'
|
- name: WEB 2160p
|
||||||
qualities:
|
qualities:
|
||||||
- WEBDL-2160p
|
- WEBDL-2160p
|
||||||
- WEBRip-2160p
|
- WEBRip-2160p
|
||||||
- name: 'WEB 1080p'
|
- name: Bluray-1080p
|
||||||
|
- name: WEB 1080p
|
||||||
qualities:
|
qualities:
|
||||||
- WEBDL-1080p
|
- WEBDL-1080p
|
||||||
- WEBRip-1080p
|
- WEBRip-1080p
|
||||||
- name: HDTV-2160p
|
|
||||||
- name: Bluray-720p
|
|
||||||
- name: 'WEB 720p'
|
|
||||||
qualities:
|
|
||||||
- WEBDL-720p
|
|
||||||
- WEBRip-720p
|
|
||||||
- name: HDTV-1080p
|
|
||||||
- name: HDTV-720p
|
|
||||||
- name: 'WEB 480p'
|
|
||||||
qualities:
|
|
||||||
- WEBDL-480p
|
|
||||||
- WEBRip-480p
|
|
||||||
- name: SDTV
|
|
||||||
@@ -51,6 +51,31 @@ custom_formats:
|
|||||||
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
|
||||||
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
|
||||||
|
|
||||||
|
# Audio Advanced
|
||||||
|
- 0d7824bb924701997f874e7ff7d4844a # TrueHD Atmos
|
||||||
|
- 9d00418ba386a083fbf4d58235fc37ef # DTS:X
|
||||||
|
- b6fbafa7942952a13e17e2b1152b539a # Atmos (undefined)
|
||||||
|
- 4232a509ce60c4e208d13825b7c06264 # DDPlus Atmos
|
||||||
|
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
|
||||||
|
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
|
||||||
|
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
|
||||||
|
- 30f70576671ca933adbdcfc736a69718 # PCM
|
||||||
|
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
|
||||||
|
- 63487786a8b01b7f20dd2bc90dd4a477 # DDPlus
|
||||||
|
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
|
||||||
|
- 5964f2a8b3be407d083498e4459d05d0 # DTS
|
||||||
|
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
|
||||||
|
- dbe00161b08a25ac6154c55f95e6318d # DD
|
||||||
|
- 3e8b714263b26f486972ee1e0fe7606c # MP3
|
||||||
|
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
|
||||||
|
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
|
||||||
|
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
|
||||||
|
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
|
||||||
|
- 1895195e84767de180653914ce207245 # 4.0 Sound
|
||||||
|
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
|
||||||
|
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
|
||||||
|
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
|
||||||
|
|
||||||
# Unwanted
|
# Unwanted
|
||||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
||||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
||||||
@@ -60,6 +85,7 @@ custom_formats:
|
|||||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
||||||
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
|
||||||
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
|
||||||
|
- ae575f95ab639ba5d15f663bf019e3e8 # Not Original Language
|
||||||
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
||||||
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
|
||||||
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
- 06d66ab109d4d2eddb2794d21526d140 # Retags
|
||||||
|
|||||||
@@ -8,24 +8,12 @@ quality_profiles:
|
|||||||
score_set: default
|
score_set: default
|
||||||
quality_sort: top
|
quality_sort: top
|
||||||
qualities:
|
qualities:
|
||||||
- name: 'WEB 2160p'
|
- name: WEB 2160p
|
||||||
qualities:
|
qualities:
|
||||||
- WEBDL-2160p
|
- WEBDL-2160p
|
||||||
- WEBRip-2160p
|
- WEBRip-2160p
|
||||||
- name: 'WEB 1080p'
|
- name: Bluray-1080p
|
||||||
|
- name: WEB 1080p
|
||||||
qualities:
|
qualities:
|
||||||
- WEBDL-1080p
|
- WEBDL-1080p
|
||||||
- WEBRip-1080p
|
- WEBRip-1080p
|
||||||
- name: HDTV-2160p
|
|
||||||
- name: Bluray-720p
|
|
||||||
- name: 'WEB 720p'
|
|
||||||
qualities:
|
|
||||||
- WEBDL-720p
|
|
||||||
- WEBRip-720p
|
|
||||||
- name: HDTV-1080p
|
|
||||||
- name: HDTV-720p
|
|
||||||
- name: 'WEB 480p'
|
|
||||||
qualities:
|
|
||||||
- WEBDL-480p
|
|
||||||
- WEBRip-480p
|
|
||||||
- name: SDTV
|
|
||||||
@@ -6,7 +6,7 @@ networks:
|
|||||||
services:
|
services:
|
||||||
recyclarr:
|
recyclarr:
|
||||||
container_name: recyclarr
|
container_name: recyclarr
|
||||||
image: ghcr.io/recyclarr/recyclarr:8
|
image: ghcr.io/recyclarr/recyclarr:7
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
security_opt: ['no-new-privileges:true'] # Prevents privilege escalation - https://recyclarr.dev/wiki/installation/docker/#prevent-in-container-privilege-escalation
|
security_opt: ['no-new-privileges:true'] # Prevents privilege escalation - https://recyclarr.dev/wiki/installation/docker/#prevent-in-container-privilege-escalation
|
||||||
user: "{{ service_user.uid }}:{{ service_user.uid }}"
|
user: "{{ service_user.uid }}:{{ service_user.uid }}"
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ radarr:
|
|||||||
# Remux
|
# Remux
|
||||||
- config: radarr-remux-qualities.yml
|
- config: radarr-remux-qualities.yml
|
||||||
- config: radarr-remux-custom_formats.yml
|
- config: radarr-remux-custom_formats.yml
|
||||||
|
|
||||||
# Encode
|
|
||||||
- config: radarr-encode-qualities.yml
|
|
||||||
- config: radarr-encode-custom_formats.yml
|
|
||||||
|
|
||||||
# Web
|
# Web
|
||||||
- config: radarr-web-qualities.yml
|
- config: radarr-web-qualities.yml
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy config.js to destination
|
||||||
|
template:
|
||||||
|
src: config.js
|
||||||
|
dest: "{{ install_directory }}/renovate/config.js"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Start docker container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
module.exports = {
|
||||||
|
endpoint: "git.{{ personal_domain }}/api/v2",
|
||||||
|
token: '{{ renovate_gitea_token }}',
|
||||||
|
platform: 'gitea',
|
||||||
|
dryRun: true,
|
||||||
|
autodiscover: true,
|
||||||
|
onboarding: false,
|
||||||
|
redisUrl: 'redis://redis',
|
||||||
|
repositoryCache: 'enabled',
|
||||||
|
persistRepoData: true,
|
||||||
|
binarySource: "docker",
|
||||||
|
dockerUser: "{{ primary_uid }}",
|
||||||
|
baseDir: "{{ data_dir }}/renovate",
|
||||||
|
};
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
docker-socket-proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
renovate:
|
||||||
|
container_name: renovate
|
||||||
|
image: renovate/renovate:slim
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- docker-socket-proxy
|
||||||
|
user: "{{ service_user.uid }}:{{ service_user.group }}"
|
||||||
|
environment:
|
||||||
|
- TZ={{ timezone }}
|
||||||
|
- DOCKER_HOST=tcp://docker_socket_proxy:2375
|
||||||
|
- "RENOVATE_TOKEN={{ renovate_gitea_token }}"
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/renovate:/{{ data_dir }}/renovate" # These must be the same
|
||||||
|
- ./config.js:/usr/src/app/config.js:ro
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
renovate_gitea_token: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
61383064643566343633633962376238346137633933643634353564316266656338333665613235
|
||||||
|
3230613339633561313064393163393537623763393336300a383332626538376335613763313439
|
||||||
|
64326566393761666266303438313435346535626231376661653863663664623839663431363632
|
||||||
|
6434306532613065650a636562663030363162396435346262353839653736343530393365633331
|
||||||
|
65366534333234353239376566326234666566303038396661343137316265306433313235366530
|
||||||
|
6164656437346131376165613136363161646437343038393266
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
- name: Create service user
|
||||||
|
user:
|
||||||
|
name: "{{ role_name }}"
|
||||||
|
groups: "{{ media_group }}"
|
||||||
|
append: yes
|
||||||
|
system: true
|
||||||
|
register: service_user
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Start docker containers
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
sabnzbd:
|
||||||
|
container_name: sabnzbd
|
||||||
|
image: lscr.io/linuxserver/sabnzbd:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
environment:
|
||||||
|
- "PUID={{ service_user.uid }}"
|
||||||
|
- "PGID={{ media_gid }}"
|
||||||
|
- "TZ={{ timezone }}"
|
||||||
|
- "UMASK=002"
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/{{ role_name }}:/config"
|
||||||
|
- "{{ media_storage_mnt }}/data/usenet:/data/usenet"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.{{ role_name }}.rule: "Host(`{{ role_name }}.local.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.{{ role_name }}.middlewares: lan-whitelist@file
|
||||||
|
traefik.http.services.sabnzbd.loadbalancer.server.port: 8080
|
||||||
@@ -1 +0,0 @@
|
|||||||
'(.*\.)?pinterest.com$'
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
- name: restart searxng
|
- name: restart searxng
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: "{{ install_directory }}/{{ role_name }}"
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
state: restarted
|
restarted: true
|
||||||
|
|
||||||
@@ -23,14 +23,6 @@
|
|||||||
become: true
|
become: true
|
||||||
notify: restart searxng
|
notify: restart searxng
|
||||||
|
|
||||||
- name: Copy hostname lists to destination
|
|
||||||
copy:
|
|
||||||
src: hostnames/
|
|
||||||
dest: "{{ data_dir }}/{{ role_name }}/"
|
|
||||||
owner: "{{ docker_user }}"
|
|
||||||
become: true
|
|
||||||
notify: restart searxng
|
|
||||||
|
|
||||||
- name: Start docker container
|
- name: Start docker container
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: "{{ install_directory }}/{{ role_name }}"
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ networks:
|
|||||||
services:
|
services:
|
||||||
searxng:
|
searxng:
|
||||||
container_name: searxng
|
container_name: searxng
|
||||||
image: ghcr.io/searxng/searxng
|
image: searxng/searxng
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- traefik
|
- traefik
|
||||||
- default
|
|
||||||
volumes:
|
volumes:
|
||||||
- "{{ data_dir }}/{{ role_name }}:/etc/searxng"
|
- "{{ data_dir }}/{{ role_name }}:/etc/searxng"
|
||||||
cap_drop:
|
cap_drop:
|
||||||
@@ -22,7 +21,7 @@ services:
|
|||||||
labels:
|
labels:
|
||||||
traefik.enable: true
|
traefik.enable: true
|
||||||
traefik.http.routers.searxng.rule: "Host(`search.{{ personal_domain }}`)"
|
traefik.http.routers.searxng.rule: "Host(`search.{{ personal_domain }}`)"
|
||||||
traefik.http.routers.searxng.middlewares: lan-whitelist@file
|
#traefik.http.routers.searxng.middlewares: lan-whitelist@file
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:alpine
|
image: redis:alpine
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,4 @@
|
|||||||
|
- name: restart synapse
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
restarted: true
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
- name: Create service user
|
||||||
|
user:
|
||||||
|
name: "{{ role_name }}"
|
||||||
|
system: true
|
||||||
|
register: service_user
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy homeserver.yaml to destination
|
||||||
|
template:
|
||||||
|
src: homeserver.yaml
|
||||||
|
dest: "{{ install_directory }}/synapse/homeserver.yaml"
|
||||||
|
owner: "{{ service_user.uid }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
notify: restart synapse
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create config directory and set synapse user to owner
|
||||||
|
file:
|
||||||
|
path: "{{ data_dir }}/synapse"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ service_user.uid }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create nginx config directory
|
||||||
|
file:
|
||||||
|
path: "{{ data_dir }}/nginx/synapse/www/.well-known/matrix/"
|
||||||
|
state: directory
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Install nginx config file
|
||||||
|
template:
|
||||||
|
src: nginx/matrix.conf
|
||||||
|
dest: "{{ data_dir }}/nginx/synapse/matrix.conf"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Install well known client file
|
||||||
|
template:
|
||||||
|
src: nginx/client.json
|
||||||
|
dest: "{{ data_dir }}/nginx/synapse/www/.well-known/matrix/client"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Install well known server file
|
||||||
|
template:
|
||||||
|
src: nginx/server.json
|
||||||
|
dest: "{{ data_dir }}/nginx/synapse/www/.well-known/matrix/server"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Start docker container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
synapse:
|
||||||
|
container_name: "synapse"
|
||||||
|
image: matrixdotorg/synapse
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
- default
|
||||||
|
environment:
|
||||||
|
- "UID={{ service_user.uid }}"
|
||||||
|
- "GID={{ service_user.uid }}"
|
||||||
|
- "TZ={{ timezone }}"
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/{{ role_name }}:/data"
|
||||||
|
- ./homeserver.yaml:/data/homeserver.yaml
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.synapse.rule: "Host(`matrix.{{ personal_domain }}`) || (Host(`{{ personal_domain }}`) && PathPrefix(`/_matrix/`))"
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:14-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=synapse
|
||||||
|
- POSTGRES_PASSWORD=synapse
|
||||||
|
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/postgres/synapse:/var/lib/postgresql/data"
|
||||||
|
|
||||||
|
redis:
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
image: redis:7-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/redis/synapse:/data"
|
||||||
|
|
||||||
|
admin:
|
||||||
|
image: awesometechnologies/synapse-admin:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.synapse-admin.rule: "Host(`synapse-admin.local.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.synapse-admin.middlewares: lan-whitelist@file
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/nginx/synapse/matrix.conf:/etc/nginx/conf.d/matrix.conf"
|
||||||
|
- "{{ data_dir }}/nginx/synapse/www:/var/www"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.matrix.rule: "Host(`{{ personal_domain }}`)"
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
server_name: "{{ personal_domain }}"
|
||||||
|
pid_file: /data/homeserver.pid
|
||||||
|
public_baseurl: "https://matrix.{{ personal_domain }}"
|
||||||
|
|
||||||
|
ip_range_whitelist:
|
||||||
|
- 10.0.0.0/24
|
||||||
|
|
||||||
|
acme:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
database:
|
||||||
|
name: psycopg2
|
||||||
|
args:
|
||||||
|
user: synapse
|
||||||
|
password: synapse
|
||||||
|
database: synapse
|
||||||
|
host: db
|
||||||
|
|
||||||
|
redis:
|
||||||
|
enabled: true
|
||||||
|
host: redis
|
||||||
|
port: 6379
|
||||||
|
|
||||||
|
listeners:
|
||||||
|
- port: 8008
|
||||||
|
tls: false
|
||||||
|
type: http
|
||||||
|
x_forwarded: true
|
||||||
|
resources:
|
||||||
|
- names: [client, federation]
|
||||||
|
compress: false
|
||||||
|
|
||||||
|
registration_shared_secret: "{{ synapse_registration_shared_secret }}"
|
||||||
|
|
||||||
|
report_stats: true
|
||||||
|
|
||||||
|
media_store_path: /data/media_store
|
||||||
|
uploads_path: /data/uploads
|
||||||
|
|
||||||
|
trusted_key_servers:
|
||||||
|
- server_name: matrix.org
|
||||||
|
suppress_key_server_warning: true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"m.homeserver": {
|
||||||
|
"base_url": "https://matrix.{{ personal_domain }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name {{ personal_domain }};
|
||||||
|
|
||||||
|
# Traefik -> nginx -> synapse
|
||||||
|
location /_matrix {
|
||||||
|
proxy_pass http://synapse:8008;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
client_max_body_size 128m;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /.well-known/matrix/ {
|
||||||
|
root /var/www/;
|
||||||
|
default_type application/json;
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"m.server": "matrix.{{ personal_domain }}:443"
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
synapse_registration_shared_secret: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
33393864663831636636616361333635343366613633353234363761303235333361376230333863
|
||||||
|
6432326363656232323531636139356663623734313161350a653262636439363334353266393563
|
||||||
|
61646265303161396630653839346266336335613030623237363537663839306331333064626436
|
||||||
|
6262623236353061380a306335356365633164313639633031353663373633306539343464376639
|
||||||
|
37396535386631363866343030653835636437303230333430303033616364383734626563336265
|
||||||
|
37643164393334316534386266613930383136663934613233313939316533643164623163626334
|
||||||
|
31396163383132333365383364323866626264323234353939653236386231636536666261616534
|
||||||
|
37353930663863343533636536356363373432383437643965663636323234303730623434386264
|
||||||
|
31653131653964376164623039616166376162323235363164303163353363643733643761353264
|
||||||
|
63393632366139313538656566393239393465653536356131333430323165356263323839666636
|
||||||
|
353466373866616536383761343036666561
|
||||||
@@ -0,0 +1,639 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Description: Use conditions to kill a stream
|
||||||
|
Author: Blacktwin, Arcanemagus, Samwiseg0, JonnyWong16, DirtyCajunRice
|
||||||
|
|
||||||
|
Adding the script to Tautulli:
|
||||||
|
Tautulli > Settings > Notification Agents > Add a new notification agent >
|
||||||
|
Script
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
Tautulli > Settings > Notification Agents > New Script > Configuration:
|
||||||
|
|
||||||
|
Script Folder: /path/to/your/scripts
|
||||||
|
Script File: ./kill_stream.py (Should be selectable in a dropdown list)
|
||||||
|
Script Timeout: {timeout}
|
||||||
|
Description: Kill stream(s)
|
||||||
|
Save
|
||||||
|
|
||||||
|
Triggers:
|
||||||
|
Tautulli > Settings > Notification Agents > New Script > Triggers:
|
||||||
|
|
||||||
|
Check: Playback Start and/or Playback Pause
|
||||||
|
Save
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
Tautulli > Settings > Notification Agents > New Script > Conditions:
|
||||||
|
|
||||||
|
Set Conditions: [{condition} | {operator} | {value} ]
|
||||||
|
Save
|
||||||
|
|
||||||
|
Script Arguments:
|
||||||
|
Tautulli > Settings > Notification Agents > New Script > Script Arguments:
|
||||||
|
|
||||||
|
Select: Playback Start, Playback Pause
|
||||||
|
Arguments: --jbop SELECTOR --userId {user_id} --username {username}
|
||||||
|
--sessionId {session_id} --notify notifierID
|
||||||
|
--interval 30 --limit 1200
|
||||||
|
--richMessage RICH_TYPE --serverName {server_name}
|
||||||
|
--plexUrl {plex_url} --posterUrl {poster_url}
|
||||||
|
--richColor '#E5A00D'
|
||||||
|
--killMessage 'Your message here.'
|
||||||
|
|
||||||
|
Save
|
||||||
|
Close
|
||||||
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
||||||
|
from builtins import object
|
||||||
|
from builtins import str
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
from datetime import datetime
|
||||||
|
from requests import Session
|
||||||
|
from requests.adapters import HTTPAdapter
|
||||||
|
from requests.exceptions import RequestException
|
||||||
|
|
||||||
|
|
||||||
|
TAUTULLI_URL = ''
|
||||||
|
TAUTULLI_APIKEY = ''
|
||||||
|
TAUTULLI_PUBLIC_URL = ''
|
||||||
|
TAUTULLI_URL = os.getenv('TAUTULLI_URL', TAUTULLI_URL)
|
||||||
|
TAUTULLI_PUBLIC_URL = os.getenv('TAUTULLI_PUBLIC_URL', TAUTULLI_PUBLIC_URL)
|
||||||
|
TAUTULLI_APIKEY = os.getenv('TAUTULLI_APIKEY', TAUTULLI_APIKEY)
|
||||||
|
TAUTULLI_ENCODING = os.getenv('TAUTULLI_ENCODING', 'UTF-8')
|
||||||
|
VERIFY_SSL = False
|
||||||
|
|
||||||
|
if TAUTULLI_PUBLIC_URL != '/':
|
||||||
|
# Check to see if there is a public URL set in Tautulli
|
||||||
|
TAUTULLI_LINK = TAUTULLI_PUBLIC_URL
|
||||||
|
else:
|
||||||
|
TAUTULLI_LINK = TAUTULLI_URL
|
||||||
|
|
||||||
|
SUBJECT_TEXT = "Tautulli has killed a stream."
|
||||||
|
BODY_TEXT = "Killed session ID '{id}'. Reason: {message}"
|
||||||
|
BODY_TEXT_USER = "Killed {user}'s stream. Reason: {message}."
|
||||||
|
|
||||||
|
|
||||||
|
SELECTOR = ['stream', 'allStreams', 'paused']
|
||||||
|
|
||||||
|
RICH_TYPE = ['discord', 'slack']
|
||||||
|
|
||||||
|
TAUTULLI_ICON = 'https://github.com/Tautulli/Tautulli/raw/master/data/interfaces/default/images/logo-circle.png'
|
||||||
|
|
||||||
|
|
||||||
|
def utc_now_iso():
|
||||||
|
"""Get current time in ISO format"""
|
||||||
|
utcnow = datetime.utcnow()
|
||||||
|
|
||||||
|
return utcnow.isoformat()
|
||||||
|
|
||||||
|
|
||||||
|
def hex_to_int(value):
|
||||||
|
"""Convert hex value to integer"""
|
||||||
|
try:
|
||||||
|
return int(value, 16)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def arg_decoding(arg):
|
||||||
|
"""Decode args, encode UTF-8"""
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
return arg.decode(TAUTULLI_ENCODING).encode('UTF-8')
|
||||||
|
else:
|
||||||
|
return arg
|
||||||
|
|
||||||
|
|
||||||
|
def debug_dump_vars():
|
||||||
|
"""Dump parameters for debug"""
|
||||||
|
print('Tautulli URL - ' + TAUTULLI_URL)
|
||||||
|
print('Tautulli Public URL - ' + TAUTULLI_PUBLIC_URL)
|
||||||
|
print('Verify SSL - ' + str(VERIFY_SSL))
|
||||||
|
print('Tautulli API key - ' + TAUTULLI_APIKEY[-4:]
|
||||||
|
.rjust(len(TAUTULLI_APIKEY), "x"))
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_streams(tautulli, user_id=None):
|
||||||
|
"""Get a list of all current streams.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
user_id : int
|
||||||
|
The ID of the user to grab sessions for.
|
||||||
|
tautulli : obj
|
||||||
|
Tautulli object.
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
objects
|
||||||
|
The of stream objects.
|
||||||
|
"""
|
||||||
|
sessions = tautulli.get_activity()['sessions']
|
||||||
|
|
||||||
|
if user_id:
|
||||||
|
streams = [Stream(session=s) for s in sessions if s['user_id'] == user_id]
|
||||||
|
else:
|
||||||
|
streams = [Stream(session=s) for s in sessions]
|
||||||
|
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
def notify(all_opts, message, kill_type=None, stream=None, tautulli=None):
|
||||||
|
"""Decides which notifier type to use"""
|
||||||
|
if all_opts.notify and all_opts.richMessage:
|
||||||
|
rich_notify(all_opts.notify, all_opts.richMessage, all_opts.richColor, kill_type,
|
||||||
|
all_opts.serverName, all_opts.plexUrl, all_opts.posterUrl, message, stream, tautulli)
|
||||||
|
elif all_opts.notify:
|
||||||
|
basic_notify(all_opts.notify, all_opts.sessionId, all_opts.username, message, stream, tautulli)
|
||||||
|
|
||||||
|
|
||||||
|
def rich_notify(notifier_id, rich_type, color=None, kill_type=None, server_name=None,
|
||||||
|
plex_url=None, poster_url=None, message=None, stream=None, tautulli=None):
|
||||||
|
"""Decides which rich notifier type to use. Set default values for empty variables
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
notifier_id : int
|
||||||
|
The ID of the user to grab sessions for.
|
||||||
|
rich_type : str
|
||||||
|
Contains 'discord' or 'slack'.
|
||||||
|
color : Union[int, str]
|
||||||
|
Hex string or integer representation of color.
|
||||||
|
kill_type : str
|
||||||
|
The kill type used.
|
||||||
|
server_name : str
|
||||||
|
The name of the plex server.
|
||||||
|
plex_url : str
|
||||||
|
Plex media URL.
|
||||||
|
poster_url : str
|
||||||
|
The media poster URL.
|
||||||
|
message : str
|
||||||
|
Message sent to the client.
|
||||||
|
stream : obj
|
||||||
|
Stream object.
|
||||||
|
tautulli : obj
|
||||||
|
Tautulli object.
|
||||||
|
"""
|
||||||
|
notification = Notification(notifier_id, None, None, tautulli, stream)
|
||||||
|
# Initialize Variables
|
||||||
|
title = ''
|
||||||
|
footer = ''
|
||||||
|
# Set a default server_name if none is provided
|
||||||
|
if server_name is None:
|
||||||
|
server_name = 'Plex Server'
|
||||||
|
|
||||||
|
# Set a default color if none is provided
|
||||||
|
if color is None:
|
||||||
|
color = '#E5A00D'
|
||||||
|
|
||||||
|
# Set a default plexUrl if none is provided
|
||||||
|
if plex_url is None:
|
||||||
|
plex_url = 'https://app.plex.tv'
|
||||||
|
|
||||||
|
# Set a default posterUrl if none is provided
|
||||||
|
if poster_url is None:
|
||||||
|
poster_url = TAUTULLI_ICON
|
||||||
|
|
||||||
|
# Set a default message if none is provided
|
||||||
|
if message is None:
|
||||||
|
message = 'The server owner has ended the stream.'
|
||||||
|
|
||||||
|
if kill_type == 'Stream':
|
||||||
|
title = "Killed {}'s stream.".format(stream.friendly_name)
|
||||||
|
footer = '{} | Kill {}'.format(server_name, kill_type)
|
||||||
|
|
||||||
|
elif kill_type == 'Paused':
|
||||||
|
title = "Killed {}'s paused stream.".format(stream.friendly_name)
|
||||||
|
footer = '{} | Kill {}'.format(server_name, kill_type)
|
||||||
|
|
||||||
|
elif kill_type == 'All Streams':
|
||||||
|
title = "Killed {}'s stream.".format(stream.friendly_name)
|
||||||
|
footer = '{} | Kill {}'.format(server_name, kill_type)
|
||||||
|
poster_url = TAUTULLI_ICON
|
||||||
|
plex_url = 'https://app.plex.tv'
|
||||||
|
|
||||||
|
if rich_type == 'discord':
|
||||||
|
color = hex_to_int(color.lstrip('#'))
|
||||||
|
notification.send_discord(title, color, poster_url, plex_url, message, footer)
|
||||||
|
|
||||||
|
elif rich_type == 'slack':
|
||||||
|
notification.send_slack(title, color, poster_url, plex_url, message, footer)
|
||||||
|
|
||||||
|
|
||||||
|
def basic_notify(notifier_id, session_id, username=None, message=None, stream=None, tautulli=None):
|
||||||
|
"""Basic notifier"""
|
||||||
|
notification = Notification(notifier_id, SUBJECT_TEXT, BODY_TEXT, tautulli, stream)
|
||||||
|
|
||||||
|
if username:
|
||||||
|
body = BODY_TEXT_USER.format(user=username,
|
||||||
|
message=message)
|
||||||
|
else:
|
||||||
|
body = BODY_TEXT.format(id=session_id, message=message)
|
||||||
|
notification.send(SUBJECT_TEXT, body)
|
||||||
|
|
||||||
|
|
||||||
|
class Tautulli(object):
|
||||||
|
def __init__(self, url, apikey, verify_ssl=False, debug=None):
|
||||||
|
self.url = url
|
||||||
|
self.apikey = apikey
|
||||||
|
self.debug = debug
|
||||||
|
|
||||||
|
self.session = Session()
|
||||||
|
self.adapters = HTTPAdapter(max_retries=3,
|
||||||
|
pool_connections=1,
|
||||||
|
pool_maxsize=1,
|
||||||
|
pool_block=True)
|
||||||
|
self.session.mount('http://', self.adapters)
|
||||||
|
self.session.mount('https://', self.adapters)
|
||||||
|
|
||||||
|
# Ignore verifying the SSL certificate
|
||||||
|
if verify_ssl is False:
|
||||||
|
self.session.verify = False
|
||||||
|
# Disable the warning that the request is insecure, we know that...
|
||||||
|
import urllib3
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
def _call_api(self, cmd, payload, method='GET'):
|
||||||
|
payload['cmd'] = cmd
|
||||||
|
payload['apikey'] = self.apikey
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = self.session.request(method, self.url + '/api/v2', params=payload)
|
||||||
|
except RequestException as e:
|
||||||
|
print("Tautulli request failed for cmd '{}'. Invalid Tautulli URL? Error: {}".format(cmd, e))
|
||||||
|
if self.debug:
|
||||||
|
traceback.print_exc()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
response_json = response.json()
|
||||||
|
except ValueError:
|
||||||
|
print(
|
||||||
|
"Failed to parse json response for Tautulli API cmd '{}': {}"
|
||||||
|
.format(cmd, response.content))
|
||||||
|
return
|
||||||
|
|
||||||
|
if response_json['response']['result'] == 'success':
|
||||||
|
if self.debug:
|
||||||
|
print("Successfully called Tautulli API cmd '{}'".format(cmd))
|
||||||
|
return response_json['response']['data']
|
||||||
|
else:
|
||||||
|
error_msg = response_json['response']['message']
|
||||||
|
print("Tautulli API cmd '{}' failed: {}".format(cmd, error_msg))
|
||||||
|
return
|
||||||
|
|
||||||
|
def get_activity(self, session_key=None, session_id=None):
|
||||||
|
"""Call Tautulli's get_activity api endpoint"""
|
||||||
|
payload = {}
|
||||||
|
|
||||||
|
if session_key:
|
||||||
|
payload['session_key'] = session_key
|
||||||
|
elif session_id:
|
||||||
|
payload['session_id'] = session_id
|
||||||
|
|
||||||
|
return self._call_api('get_activity', payload)
|
||||||
|
|
||||||
|
def notify(self, notifier_id, subject, body):
|
||||||
|
"""Call Tautulli's notify api endpoint"""
|
||||||
|
payload = {'notifier_id': notifier_id,
|
||||||
|
'subject': subject,
|
||||||
|
'body': body}
|
||||||
|
|
||||||
|
return self._call_api('notify', payload)
|
||||||
|
|
||||||
|
def terminate_session(self, session_key=None, session_id=None, message=''):
|
||||||
|
"""Call Tautulli's terminate_session api endpoint"""
|
||||||
|
payload = {}
|
||||||
|
|
||||||
|
if session_key:
|
||||||
|
payload['session_key'] = session_key
|
||||||
|
elif session_id:
|
||||||
|
payload['session_id'] = session_id
|
||||||
|
|
||||||
|
if message:
|
||||||
|
payload['message'] = message
|
||||||
|
|
||||||
|
return self._call_api('terminate_session', payload)
|
||||||
|
|
||||||
|
|
||||||
|
class Stream(object):
|
||||||
|
def __init__(self, session_id=None, user_id=None, username=None, tautulli=None, session=None):
|
||||||
|
self.state = None
|
||||||
|
self.ip_address = None
|
||||||
|
self.session_id = session_id
|
||||||
|
self.user_id = user_id
|
||||||
|
self.username = username
|
||||||
|
self.session_exists = False
|
||||||
|
self.tautulli = tautulli
|
||||||
|
|
||||||
|
if session is not None:
|
||||||
|
self._set_stream_attributes(session)
|
||||||
|
|
||||||
|
def _set_stream_attributes(self, session):
|
||||||
|
for k, v in session.items():
|
||||||
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
def get_all_stream_info(self):
|
||||||
|
"""Get all stream info from Tautulli."""
|
||||||
|
session = self.tautulli.get_activity(session_id=self.session_id)
|
||||||
|
if session:
|
||||||
|
self._set_stream_attributes(session)
|
||||||
|
self.session_exists = True
|
||||||
|
else:
|
||||||
|
self.session_exists = False
|
||||||
|
|
||||||
|
def terminate(self, message=''):
|
||||||
|
"""Calls Tautulli to terminate the session.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
message : str
|
||||||
|
The message to use if the stream is terminated.
|
||||||
|
"""
|
||||||
|
self.tautulli.terminate_session(session_id=self.session_id, message=message)
|
||||||
|
|
||||||
|
def terminate_long_pause(self, message, limit, interval):
|
||||||
|
"""Kills the session if it is paused for longer than <limit> seconds.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
message : str
|
||||||
|
The message to use if the stream is terminated.
|
||||||
|
limit : int
|
||||||
|
The number of seconds the session is allowed to remain paused before it
|
||||||
|
is terminated.
|
||||||
|
interval : int
|
||||||
|
The amount of time to wait between checks of the session state.
|
||||||
|
"""
|
||||||
|
start = datetime.now()
|
||||||
|
checked_time = 0
|
||||||
|
# Continue checking 2 intervals past the allowed limit in order to
|
||||||
|
# account for system variances.
|
||||||
|
check_limit = limit + (interval * 2)
|
||||||
|
|
||||||
|
while checked_time < check_limit:
|
||||||
|
self.get_all_stream_info()
|
||||||
|
|
||||||
|
if self.session_exists is False:
|
||||||
|
sys.stdout.write(
|
||||||
|
"Session '{}' from user '{}' is no longer active "
|
||||||
|
.format(self.session_id, self.username) +
|
||||||
|
"on the server, stopping monitoring.\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
now = datetime.now()
|
||||||
|
checked_time = (now - start).total_seconds()
|
||||||
|
|
||||||
|
if self.state == 'paused':
|
||||||
|
if checked_time >= limit:
|
||||||
|
self.terminate(message)
|
||||||
|
sys.stdout.write(
|
||||||
|
"Session '{}' from user '{}' has been killed.\n"
|
||||||
|
.format(self.session_id, self.username))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
time.sleep(interval)
|
||||||
|
|
||||||
|
elif self.state == 'playing' or self.state == 'buffering':
|
||||||
|
sys.stdout.write(
|
||||||
|
"Session '{}' from user '{}' has been resumed, "
|
||||||
|
.format(self.session_id, self.username) +
|
||||||
|
"stopping monitoring.\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class Notification(object):
|
||||||
|
def __init__(self, notifier_id, subject, body, tautulli, stream):
|
||||||
|
self.notifier_id = notifier_id
|
||||||
|
self.subject = subject
|
||||||
|
self.body = body
|
||||||
|
|
||||||
|
self.tautulli = tautulli
|
||||||
|
self.stream = stream
|
||||||
|
|
||||||
|
def send(self, subject='', body=''):
|
||||||
|
"""Send to Tautulli notifier.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
subject : str
|
||||||
|
Subject of the message.
|
||||||
|
body : str
|
||||||
|
Body of the message.
|
||||||
|
"""
|
||||||
|
subject = subject or self.subject
|
||||||
|
body = body or self.body
|
||||||
|
self.tautulli.notify(notifier_id=self.notifier_id, subject=subject, body=body)
|
||||||
|
|
||||||
|
def send_discord(self, title, color, poster_url, plex_url, message, footer):
|
||||||
|
"""Build the Discord message.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
title : str
|
||||||
|
The title of the message.
|
||||||
|
color : int
|
||||||
|
The color of the message
|
||||||
|
poster_url : str
|
||||||
|
The media poster URL.
|
||||||
|
plex_url : str
|
||||||
|
Plex media URL.
|
||||||
|
message : str
|
||||||
|
Message sent to the player.
|
||||||
|
footer : str
|
||||||
|
Footer of the message.
|
||||||
|
"""
|
||||||
|
discord_message = {
|
||||||
|
"embeds": [
|
||||||
|
{
|
||||||
|
"author": {
|
||||||
|
"icon_url": TAUTULLI_ICON,
|
||||||
|
"name": "Tautulli",
|
||||||
|
"url": TAUTULLI_LINK.rstrip('/')
|
||||||
|
},
|
||||||
|
"color": color,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"inline": True,
|
||||||
|
"name": "User",
|
||||||
|
"value": self.stream.friendly_name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inline": True,
|
||||||
|
"name": "Session Key",
|
||||||
|
"value": self.stream.session_key
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inline": True,
|
||||||
|
"name": "Watching",
|
||||||
|
"value": self.stream.full_title
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inline": False,
|
||||||
|
"name": "Message Sent",
|
||||||
|
"value": message
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thumbnail": {
|
||||||
|
"url": poster_url
|
||||||
|
},
|
||||||
|
"title": title,
|
||||||
|
"timestamp": utc_now_iso(),
|
||||||
|
"url": plex_url,
|
||||||
|
"footer": {
|
||||||
|
"text": footer
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
discord_message = json.dumps(discord_message, sort_keys=True,
|
||||||
|
separators=(',', ': '))
|
||||||
|
self.send(body=discord_message)
|
||||||
|
|
||||||
|
def send_slack(self, title, color, poster_url, plex_url, message, footer):
|
||||||
|
"""Build the Slack message.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
title : str
|
||||||
|
The title of the message.
|
||||||
|
color : int
|
||||||
|
The color of the message
|
||||||
|
poster_url : str
|
||||||
|
The media poster URL.
|
||||||
|
plex_url : str
|
||||||
|
Plex media URL.
|
||||||
|
message : str
|
||||||
|
Message sent to the player.
|
||||||
|
footer : str
|
||||||
|
Footer of the message.
|
||||||
|
"""
|
||||||
|
slack_message = {
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"title": title,
|
||||||
|
"title_link": plex_url,
|
||||||
|
"author_icon": TAUTULLI_ICON,
|
||||||
|
"author_name": "Tautulli",
|
||||||
|
"author_link": TAUTULLI_LINK.rstrip('/'),
|
||||||
|
"color": color,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"title": "User",
|
||||||
|
"value": self.stream.friendly_name,
|
||||||
|
"short": True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Session Key",
|
||||||
|
"value": self.stream.session_key,
|
||||||
|
"short": True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Watching",
|
||||||
|
"value": self.stream.full_title,
|
||||||
|
"short": True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Message Sent",
|
||||||
|
"value": message,
|
||||||
|
"short": False
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thumb_url": poster_url,
|
||||||
|
"footer": footer,
|
||||||
|
"ts": time.time()
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
slack_message = json.dumps(slack_message, sort_keys=True,
|
||||||
|
separators=(',', ': '))
|
||||||
|
self.send(body=slack_message)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Killing Plex streams from Tautulli.")
|
||||||
|
parser.add_argument('--jbop', required=True, choices=SELECTOR,
|
||||||
|
help='Kill selector.\nChoices: (%(choices)s)')
|
||||||
|
parser.add_argument('--userId', type=int,
|
||||||
|
help='The unique identifier for the user.')
|
||||||
|
parser.add_argument('--username', type=arg_decoding,
|
||||||
|
help='The username of the person streaming.')
|
||||||
|
parser.add_argument('--sessionId',
|
||||||
|
help='The unique identifier for the stream.')
|
||||||
|
parser.add_argument('--notify', type=int,
|
||||||
|
help='Notification Agent ID number to Agent to ' +
|
||||||
|
'send notification.')
|
||||||
|
parser.add_argument('--limit', type=int, default=(20 * 60), # 20 minutes
|
||||||
|
help='The time session is allowed to remain paused.')
|
||||||
|
parser.add_argument('--interval', type=int, default=30,
|
||||||
|
help='The seconds between paused session checks.')
|
||||||
|
parser.add_argument('--killMessage', nargs='+', type=arg_decoding,
|
||||||
|
help='Message to send to user whose stream is killed.')
|
||||||
|
parser.add_argument('--richMessage', type=arg_decoding, choices=RICH_TYPE,
|
||||||
|
help='Rich message type selector.\nChoices: (%(choices)s)')
|
||||||
|
parser.add_argument('--serverName', type=arg_decoding,
|
||||||
|
help='Plex Server Name')
|
||||||
|
parser.add_argument('--plexUrl', type=arg_decoding,
|
||||||
|
help='URL to plex media')
|
||||||
|
parser.add_argument('--posterUrl', type=arg_decoding,
|
||||||
|
help='Poster URL of the media')
|
||||||
|
parser.add_argument('--richColor', type=arg_decoding,
|
||||||
|
help='Color of the rich message')
|
||||||
|
parser.add_argument("--debug", action='store_true',
|
||||||
|
help='Enable debug messages.')
|
||||||
|
|
||||||
|
opts = parser.parse_args()
|
||||||
|
|
||||||
|
if not opts.sessionId and opts.jbop != 'allStreams':
|
||||||
|
sys.stderr.write("No sessionId provided! Is this synced content?\n")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if opts.debug:
|
||||||
|
# Import traceback to get more detailed information
|
||||||
|
import traceback
|
||||||
|
# Dump the ENVs passed from tautulli
|
||||||
|
debug_dump_vars()
|
||||||
|
|
||||||
|
# Create a Tautulli instance
|
||||||
|
tautulli_server = Tautulli(TAUTULLI_URL.rstrip('/'), TAUTULLI_APIKEY, VERIFY_SSL, opts.debug)
|
||||||
|
|
||||||
|
# Create initial Stream object with basic info
|
||||||
|
tautulli_stream = Stream(opts.sessionId, opts.userId, opts.username, tautulli_server)
|
||||||
|
|
||||||
|
# Only pull all stream info if using richMessage
|
||||||
|
if opts.notify and opts.richMessage:
|
||||||
|
tautulli_stream.get_all_stream_info()
|
||||||
|
|
||||||
|
# Set a default message if none is provided
|
||||||
|
if opts.killMessage:
|
||||||
|
kill_message = ' '.join(opts.killMessage)
|
||||||
|
else:
|
||||||
|
kill_message = 'The server owner has ended the stream.'
|
||||||
|
|
||||||
|
if opts.jbop == 'stream':
|
||||||
|
tautulli_stream.terminate(kill_message)
|
||||||
|
notify(opts, kill_message, 'Stream', tautulli_stream, tautulli_server)
|
||||||
|
|
||||||
|
elif opts.jbop == 'allStreams':
|
||||||
|
all_streams = get_all_streams(tautulli_server, opts.userId)
|
||||||
|
for a_stream in all_streams:
|
||||||
|
tautulli_server.terminate_session(session_id=a_stream.session_id, message=kill_message)
|
||||||
|
notify(opts, kill_message, 'All Streams', a_stream, tautulli_server)
|
||||||
|
|
||||||
|
elif opts.jbop == 'paused':
|
||||||
|
killed_stream = tautulli_stream.terminate_long_pause(kill_message, opts.limit, opts.interval)
|
||||||
|
if killed_stream:
|
||||||
|
notify(opts, kill_message, 'Paused', tautulli_stream, tautulli_server)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- name: Create service user
|
||||||
|
user:
|
||||||
|
name: "{{ role_name }}"
|
||||||
|
system: true
|
||||||
|
register: service_user
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create install directory
|
||||||
|
file:
|
||||||
|
path: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_directory_mask }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Copy docker-compose file to destination
|
||||||
|
template:
|
||||||
|
src: docker-compose.yml
|
||||||
|
dest: "{{ install_directory }}/{{ role_name }}/docker-compose.yml"
|
||||||
|
owner: "{{ docker_user }}"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
validate: docker compose -f %s config
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Install script files
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: "{{ data_dir }}/tautulli/scripts"
|
||||||
|
mode: "{{ docker_compose_file_mask }}"
|
||||||
|
owner: "{{ primary_user }}"
|
||||||
|
with_fileglob:
|
||||||
|
- "files/*"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Start docker container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ install_directory }}/{{ role_name }}"
|
||||||
|
pull: always
|
||||||
|
remove_orphans: yes
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
tautulli:
|
||||||
|
container_name: "tautulli"
|
||||||
|
image: lscr.io/linuxserver/tautulli:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
environment:
|
||||||
|
- "PUID={{ service_user.uid }}"
|
||||||
|
- "PGID={{ service_user.uid }}"
|
||||||
|
- "TZ={{ timezone }}"
|
||||||
|
volumes:
|
||||||
|
- "{{ data_dir }}/{{ role_name }}:/config"
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.tautulli.rule: "Host(`tautulli.local.{{ personal_domain }}`)"
|
||||||
|
traefik.http.routers.tautulli.middlewares: lan-whitelist@file
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
networks:
|
|
||||||
traefik:
|
|
||||||
external: true
|
|
||||||
|
|
||||||
services:
|
|
||||||
teamarr:
|
|
||||||
container_name: teamarr
|
|
||||||
image: ghcr.io/egyptiangio/teamarr:latest
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- traefik
|
|
||||||
environment:
|
|
||||||
- "TZ={{ timezone }}"
|
|
||||||
volumes:
|
|
||||||
- "{{ data_dir }}/teamarr:/app/data"
|
|
||||||
labels:
|
|
||||||
traefik.enable: true
|
|
||||||
traefik.http.routers.teamarr.rule: "Host(`teamarr.local.{{ personal_domain }}`)"
|
|
||||||
traefik.http.routers.teamarr.middlewares: lan-whitelist@file
|
|
||||||
traefik.http.services.teamarr.loadbalancer.server.port: 9195
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
networks:
|
|
||||||
traefik:
|
|
||||||
external: true
|
|
||||||
|
|
||||||
services:
|
|
||||||
tracearr:
|
|
||||||
container_name: "tracearr"
|
|
||||||
image: ghcr.io/connorgallopo/tracearr:supervised
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- traefik
|
|
||||||
environment:
|
|
||||||
- "TZ={{ timezone }}"
|
|
||||||
volumes:
|
|
||||||
- "{{ data_dir }}/{{ role_name }}:/data"
|
|
||||||
labels:
|
|
||||||
traefik.enable: true
|
|
||||||
traefik.http.routers.tracearr.rule: "Host(`{{ role_name }}.local.{{ personal_domain }}`)"
|
|
||||||
traefik.http.routers.tracearr.middlewares: lan-whitelist@file
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
- name: restart traefik
|
- name: restart traefik
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: "{{ install_directory }}/traefik"
|
project_src: "{{ install_directory }}/traefik"
|
||||||
state: restarted
|
restarted: true
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
http:
|
||||||
|
routers:
|
||||||
|
router-adguard:
|
||||||
|
rule: "Host(`adguard.local.{{ personal_domain }}`)"
|
||||||
|
service: service-adguard
|
||||||
|
middlewares:
|
||||||
|
- lan-whitelist@file
|
||||||
|
|
||||||
|
services:
|
||||||
|
service-adguard:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://10.0.0.1:81
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
http:
|
||||||
|
routers:
|
||||||
|
router-ezbeq:
|
||||||
|
rule: "Host(`ezbeq.local.{{ personal_domain }}`)"
|
||||||
|
service: service-ezbeq
|
||||||
|
middlewares:
|
||||||
|
- lan-whitelist@file
|
||||||
|
|
||||||
|
services:
|
||||||
|
service-ezbeq:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://10.0.0.84:8080
|
||||||
@@ -8,4 +8,4 @@ http:
|
|||||||
service-homeassistant:
|
service-homeassistant:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: http://haos:8123
|
- url: http://10.0.0.27:8123
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
http:
|
|
||||||
routers:
|
|
||||||
router-immich:
|
|
||||||
rule: "Host(`photos.{{ personal_domain }}`)"
|
|
||||||
service: service-immich
|
|
||||||
|
|
||||||
services:
|
|
||||||
service-immich:
|
|
||||||
loadBalancer:
|
|
||||||
servers:
|
|
||||||
- url: http://immich:8080
|
|
||||||
@@ -8,4 +8,4 @@ http:
|
|||||||
service-jellyfin:
|
service-jellyfin:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: http://jellyfin:8096
|
- url: http://10.0.0.30:8096
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
http:
|
|
||||||
routers:
|
|
||||||
router-lubelogger:
|
|
||||||
rule: "Host(`lubelogger.local.{{ personal_domain }}`)"
|
|
||||||
service: service-lubelogger
|
|
||||||
|
|
||||||
services:
|
|
||||||
service-lubelogger:
|
|
||||||
loadBalancer:
|
|
||||||
servers:
|
|
||||||
- url: http://arch-web:5000
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
http:
|
|
||||||
routers:
|
|
||||||
router-pbs:
|
|
||||||
rule: "Host(`pbs.local.{{ personal_domain }}`)"
|
|
||||||
service: service-pbs
|
|
||||||
middlewares:
|
|
||||||
- lan-whitelist@file
|
|
||||||
|
|
||||||
services:
|
|
||||||
service-pbs:
|
|
||||||
loadBalancer:
|
|
||||||
servers:
|
|
||||||
- url: https://10.0.0.28:8007
|
|
||||||
@@ -8,4 +8,4 @@ http:
|
|||||||
service-plex:
|
service-plex:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: https://plex:32400
|
- url: https://10.0.0.31:32400
|
||||||
@@ -10,4 +10,4 @@ http:
|
|||||||
service-proxmox:
|
service-proxmox:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: https://pve:8006
|
- url: https://10.0.0.2:8006
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
http:
|
|
||||||
routers:
|
|
||||||
router-qui:
|
|
||||||
rule: "Host(`qui.local.{{ personal_domain }}`)"
|
|
||||||
service: service-qui
|
|
||||||
|
|
||||||
services:
|
|
||||||
service-qui:
|
|
||||||
loadBalancer:
|
|
||||||
servers:
|
|
||||||
- url: http://arch-web:7476
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
http:
|
|
||||||
routers:
|
|
||||||
router-redlib:
|
|
||||||
rule: "Host(`redlib.local.{{ personal_domain }}`)"
|
|
||||||
service: service-redlib
|
|
||||||
|
|
||||||
services:
|
|
||||||
service-redlib:
|
|
||||||
loadBalancer:
|
|
||||||
servers:
|
|
||||||
- url: http://arch-web:13225
|
|
||||||
Loaded 100 of 111 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user