Fixes for JSON data and markdown (#95)

Co-authored-by: aljohn92 <16975578+aljohn92@users.noreply.github.com>
Co-authored-by: Junkbite <clobts@protonmail.com>
develop
Carl Jamilkowski 1 year ago committed by GitHub
parent 2c38787852
commit cfc3ff790a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,7 +9,7 @@ Syncs two Radarr/Sonarr/Lidarr servers through the web API. Useful for syncing a
* Can set interval for syncing
* Support two way sync (one way by default)
* Skip content with missing files
* Set language profiles (Sonarr)
* Set language profiles
* Filter syncing by content file quality (Radarr only)
* Filter syncing by tags (Sonarr/Radarr)
* Allow for a test run using `test_run` flag (does everything but actually sync)
@ -17,9 +17,10 @@ Syncs two Radarr/Sonarr/Lidarr servers through the web API. Useful for syncing a
## Configuration
1. Edit the config.conf file and enter your servers URLs and API keys for each server.
2. Add the profile name (case insensitive) and movie path for the Radarr instance the movies will be synced to:
```ini
```ini
[radarrA]
url = https://4k.example.com:443
key = XXXXX
@ -29,11 +30,11 @@ Syncs two Radarr/Sonarr/Lidarr servers through the web API. Useful for syncing a
key = XXXXX
profile = 1080p
path = /data/Movies # if not given will use RadarrA path for each movie - may not be what you want!
```
```
3. Or if you want to sync two Sonarr instances:
```ini
```ini
[sonarrA]
url = https://4k.example.com:443
key = XXXXX
@ -43,10 +44,11 @@ Syncs two Radarr/Sonarr/Lidarr servers through the web API. Useful for syncing a
key = XXXXX
profile = 1080p
path = /data/Shows
```
4. Or if you want to sync two Lidarr instances:
5.
```ini
```ini
[lidarrA]
url = https://lossless.example.com:443
key = XXXXX
@ -56,13 +58,13 @@ Syncs two Radarr/Sonarr/Lidarr servers through the web API. Useful for syncing a
key = XXXXX
profile = Standard
path = /data/Music
```
```
**Note** you cannot have a mix of Radarr, Lidarr, or Sonarr config setups at the same time.
**Note** you cannot have a mix of Radarr, Lidarr, or Sonarr config setups at the same time.
6. Optional Configuration
5. Optional Configuration
```ini
```ini
[*arrA]
url = http://127.0.0.1:8080
key = XXXXX
@ -81,36 +83,43 @@ Syncs two Radarr/Sonarr/Lidarr servers through the web API. Useful for syncing a
path = /data/Movies
[general]
sync_bidirectionally = 1 # sync from instance A to B **AND** instance B to A (default 0)
bidirectional = 1 # sync from instance A to B **AND** instance B to A (default 0)
auto_search = 0 # search is automatically started on new content - disable by setting to 0 (default 1)
skip_missing = 1 # content with missing files are skipped on sync - disable by setting to 0 (default 1)
skip_missing = 1 # content with missing files are skipped on sync - disable by setting to 0 (default 1) (Radarr only)
monitor_new_content = 0 # set to 0 to never monitor new content synced or to 1 to always monitor new content synced (default 1)
test_run = 1 # enable test mode - will run through sync program but will not actually sync content (default 0)
sync_monitor = 1 # if set to 1 will sync if the content is monitored or not to instance B (default 0)
```
```
**Note** If `sync_bidirectionally` is set to `1`, then instance A will require either `profile_id` or `profile` AND `path` as well
**Note** If `bidirectional` is set to `1`, then instance A will require either `profile_id` or `profile` AND `path` as well
---
## Requirements
* Python 3.6 or greater
* 2 Radarr, Sonarr, or Lidarr servers
* Python 3.6 or greater
* 2 Radarr, Sonarr, or Lidarr servers
---
## How to Run
1. install the needed python modules (you'll need pip or you can install the modules manually inside the `requirements.txt` file):
```bash
```bash
pip install -r requirements.txt
```
```
2. run this script directly or through a Cron:
```bash
```bash
python index.py
```
```
---
## Docker Compose
This script can run through a docker container with a set interval (default every 5 minutes)
```bash

@ -1,12 +1,21 @@
# [radarrA]
# url = https://example.com:443
# key = FCKGW-RHQQ2-YXRKT-8TG6W-2B7Q8
# profile = HD-1080p
# profile_id = 4
# path = /data/Movies
# [radarrB]
# url = http://127.0.0.1:8080
# key = FCKGW-RHQQ2-YXRKT-8TG6W-2B7Q8
# profile_id = 1
# profile = Ultra-HD
# path = /data/4k_Movies
# [general]
# sync_bidirectionally = 0
# bidirectional = 0
# log_level = 20
# skip_missing = 0
# auto_search = 1
# monitor_new_content = 1
# test_run = 0

@ -79,6 +79,8 @@ radarrA_profile = get_config_value('RADARR_A_PROFILE', 'profile', 'radarrA')
radarrA_profile_id = get_config_value('RADARR_A_PROFILE_ID', 'profile_id', 'radarrA')
radarrA_profile_filter = get_config_value('RADARR_A_PROFILE_FILTER', 'profile_filter', 'radarrA')
radarrA_profile_filter_id = get_config_value('RADARR_A_PROFILE_FILTER_ID', 'profile_filter_id', 'radarrA')
radarrA_tag_filter = get_config_value('RADARR_A_TAG_FILTER', 'tag_filter', 'radarrA')
radarrA_tag_filter_id = get_config_value('RADARR_A_TAG_FILTER_ID', 'tag_filter_id', 'radarrA')
radarrA_language = get_config_value('RADARR_A_LANGUAGE', 'language', 'radarrA')
radarrA_language_id = get_config_value('RADARR_A_LANGUAGE_ID', 'language_id', 'radarrA')
radarrA_quality_match = get_config_value('RADARR_A_QUALITY_MATCH', 'quality_match', 'radarrA')
@ -91,6 +93,9 @@ radarrB_profile = get_config_value('RADARR_B_PROFILE', 'profile', 'radarrB')
radarrB_profile_id = get_config_value('RADARR_B_PROFILE_ID', 'profile_id', 'radarrB')
radarrB_profile_filter = get_config_value('RADARR_B_PROFILE_FILTER', 'profile_filter', 'radarrB')
radarrB_profile_filter_id = get_config_value('RADARR_B_PROFILE_FILTER_ID', 'profile_filter_id', 'radarrB')
radarrB_tag_filter = get_config_value('RADARR_B_TAG_FILTER', 'tag_filter', 'radarrB')
radarrB_tag_filter_id = get_config_value('RADARR_B_TAG_FILTER_ID', 'tag_filter_id', 'radarrB')
radarrB_language = get_config_value('RADARR_B_LANGUAGE', 'language', 'radarrB')
radarrB_language_id = get_config_value('RADARR_B_LANGUAGE_ID', 'language_id', 'radarrB')
radarrB_quality_match = get_config_value('RADARR_B_QUALITY_MATCH', 'quality_match', 'radarrB')
@ -273,6 +278,8 @@ if radarrA_url and radarrB_url:
instanceA_profile_filter_id = radarrA_profile_filter_id
instanceA_language = radarrA_language
instanceA_language_id = radarrA_language_id
instanceA_tag_filter = radarrA_tag_filter and radarrA_tag_filter.split(',')
instanceA_tag_filter_id = radarrA_tag_filter_id and radarrA_tag_filter_id.split(',')
instanceA_quality_match = radarrA_quality_match
instanceA_blacklist = radarrA_blacklist
@ -285,6 +292,8 @@ if radarrA_url and radarrB_url:
instanceB_profile_filter_id = radarrB_profile_filter_id
instanceB_language = radarrB_language
instanceB_language_id = radarrB_language_id
instanceB_tag_filter = radarrB_tag_filter and radarrB_tag_filter.split(',')
instanceB_tag_filter_id = radarrB_tag_filter_id and radarrB_tag_filter_id.split(',')
instanceB_quality_match = radarrB_quality_match
instanceB_blacklist = radarrB_blacklist

@ -211,7 +211,7 @@ def sync_servers(instanceA_contents, instanceB_language_id, instanceB_contentIds
instance_path = instanceB_path or dirname(content.get('path'))
# if skipping missing files, we want to skip any that don't have files
if skip_missing:
if is_radarr and skip_missing:
content_has_file = content.get('hasFile')
if not content_has_file:
logging.debug(f'Skipping content {title} - file missing')
@ -253,7 +253,7 @@ def sync_servers(instanceA_contents, instanceB_language_id, instanceB_contentIds
# generate content from instance A to sync into instance B
formatted_content = get_content_details(
content=dict(content),
content,
instance_path=instance_path,
instance_profile_id=instanceB_profile_id,
instance_url=instanceB_url,
@ -266,7 +266,7 @@ def sync_servers(instanceA_contents, instanceB_language_id, instanceB_contentIds
elif content_not_synced:
# sync content if not synced
logging.info(f'syncing content title "{title}"')
sync_response = instanceB_session.post(instanceB_content_url, data=json.dumps(formatted_content))
sync_response = instanceB_session.post(instanceB_content_url, json=formatted_content)
# check response and save content id for searching later on if success
if sync_response.status_code != 201 and sync_response.status_code != 200:
logger.error(f'server sync error for {title} - response: {sync_response.text}')
@ -288,7 +288,7 @@ def sync_servers(instanceA_contents, instanceB_language_id, instanceB_contentIds
if matching_content_instanceB['monitored'] != content['monitored']:
matching_content_instanceB['monitored'] = content['monitored']
instanceB_content_url = get_content_put_path(instanceB_url, instanceB_key, matching_content_instanceB.get('id'))
sync_response = instanceB_session.put(instanceB_content_url, data=json.dumps(matching_content_instanceB))
sync_response = instanceB_session.put(instanceB_content_url, json=matching_content_instanceB)
# check response and save content id for searching later on if success
if sync_response.status_code != 202:
logger.error(f'server monitoring sync error for {title} - response: {sync_response.text}')

Loading…
Cancel
Save