[172] add Config Secrets

pull/1369/head
meisnate12 2 years ago
parent ba2b34987c
commit dce42b265f

@ -24,6 +24,8 @@ Added `has_edition` as a [Boolean Filter](https://metamanager.wiki/en/latest/met
Added `has_stinger` and `stinger_rating` as [Filters](https://metamanager.wiki/en/latest/metadata/filters.html) based on http://www.mediastinger.com Added `has_stinger` and `stinger_rating` as [Filters](https://metamanager.wiki/en/latest/metadata/filters.html) based on http://www.mediastinger.com
When editing episode metadata the key can now be either episode number, episode title, or episodeoriginally released date. When editing episode metadata the key can now be either episode number, episode title, or episodeoriginally released date.
The Collectionless builder now can work with other builders. The Collectionless builder now can work with other builders.
Added `country` as an option for Shows when using the builders `plex_search` and `smart_filter`.
Added [Config Secrets](https://metamanager.wiki/en/latest/home/environmental.html#config-secrets) and the ability to load Environment Variables using a `.env` File inside your config folder.
# New Defaults Features # New Defaults Features
Removed Translations from the defaults directory and in to their own [repo](https://github.com/meisnate12/PMM-Translations) which is managed at [translations.metamanager.wiki](https://translations.metamanager.wiki/projects/plex-meta-manager/defaults/). Removed Translations from the defaults directory and in to their own [repo](https://github.com/meisnate12/PMM-Translations) which is managed at [translations.metamanager.wiki](https://translations.metamanager.wiki/projects/plex-meta-manager/defaults/).

@ -1 +1 @@
1.18.3-develop171 1.18.3-develop172

@ -34,8 +34,8 @@ templates:
- imdb_list - imdb_list
- trakt_list - trakt_list
- mdblist_list - mdblist_list
- summary_<<key>> - summary_format
- name_<<key>> - name_format
- key_name - key_name
- translation_key - translation_key
- limit - limit

@ -6,6 +6,8 @@ If you run into a race condition where you have set an Environment Variable with
These docs are assuming you have a basic understanding of Docker concepts. One place to get familiar with Docker would be the [official tutorial](https://www.docker.com/101-tutorial/). These docs are assuming you have a basic understanding of Docker concepts. One place to get familiar with Docker would be the [official tutorial](https://www.docker.com/101-tutorial/).
Environment Variables can also be placed inside a `.env` file inside your config folder.
| Attribute | Shell Command | Environment Variable | | Attribute | Shell Command | Environment Variable |
|:------------------------------------------------------|:----------------------------------------------|:-------------------------| |:------------------------------------------------------|:----------------------------------------------|:-------------------------|
| [Config](#config) | `-c` or `--config` | `PMM_CONFIG` | | [Config](#config) | `-c` or `--config` | `PMM_CONFIG` |
@ -38,6 +40,7 @@ These docs are assuming you have a basic understanding of Docker concepts. One
| [ENV Plex Token](#env-plex-url--token) | `-pt` or `--plex-token` | `PMM_PLEX_TOKEN` | | [ENV Plex Token](#env-plex-url--token) | `-pt` or `--plex-token` | `PMM_PLEX_TOKEN` |
| [Divider Character](#divider-character--screen-width) | `-d` or `--divider` | `PMM_DIVIDER` | | [Divider Character](#divider-character--screen-width) | `-d` or `--divider` | `PMM_DIVIDER` |
| [Screen Width](#divider-character--screen-width) | `-w` or `--width` | `PMM_WIDTH` | | [Screen Width](#divider-character--screen-width) | `-w` or `--width` | `PMM_WIDTH` |
| [Other Secrets](#config-secrets) | `--pmm-***` | `PMM_***` |
Further explanation and examples of each command can be found below. Further explanation and examples of each command can be found below.
@ -1071,3 +1074,45 @@ python plex_meta_manager.py --divider * --width 200
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --divider * --width 200 docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --divider * --width 200
``` ```
```` ````
### Config Secrets
All Run Commands that start with `--pmm-***` and Environment Variables that start with `PMM_***` will be loaded in as Config Secrets.
These Config Secrets can be loaded into the config by placing `<<***>>` in any field in the config, where `***` is whatever name you want to call the variable.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #1d1d1d;"></th>
<th>Shell</th>
<th>Environment</th>
</tr>
<tr>
<th>Flags</th>
<td><code>--pmm-***</code></td>
<td><code>PMM_***</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--pmm-mysecret 123456789</code></td>
<td><code>PMM_MYSECRET=123456789</code></td>
</tr>
</table>
````{tab} Local Environment
```
python plex_meta_manager.py --pmm-mysecret 123456789
```
````
````{tab} Docker Environment
```
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --pmm-mysecret 123456789
```
````
#### Example Config Usage
```yaml
tmdb:
apikey: <<mysecret>>
```

@ -112,7 +112,7 @@ library_operations = {
} }
class ConfigFile: class ConfigFile:
def __init__(self, default_dir, attrs): def __init__(self, default_dir, attrs, secrets):
logger.info("Locating config...") logger.info("Locating config...")
config_file = attrs["config_file"] config_file = attrs["config_file"]
if config_file and os.path.exists(config_file): self.config_path = os.path.abspath(config_file) if config_file and os.path.exists(config_file): self.config_path = os.path.abspath(config_file)
@ -124,6 +124,7 @@ class ConfigFile:
self._mediastingers = None self._mediastingers = None
self.default_dir = default_dir self.default_dir = default_dir
self.secrets = secrets
self.read_only = attrs["read_only"] if "read_only" in attrs else False self.read_only = attrs["read_only"] if "read_only" in attrs else False
self.version = attrs["version"] if "version" in attrs else None self.version = attrs["version"] if "version" in attrs else None
self.branch = attrs["branch"] if "branch" in attrs else None self.branch = attrs["branch"] if "branch" in attrs else None
@ -283,6 +284,25 @@ class ConfigFile:
if "trakt" in self.data: self.data["trakt"] = self.data.pop("trakt") if "trakt" in self.data: self.data["trakt"] = self.data.pop("trakt")
if "mal" in self.data: self.data["mal"] = self.data.pop("mal") if "mal" in self.data: self.data["mal"] = self.data.pop("mal")
def check_next(next_data):
if isinstance(next_data, dict):
for d in next_data:
out = check_next(next_data[d])
if out:
next_data[d] = out
elif isinstance(next_data, list):
for d in next_data:
check_next(d)
else:
for secret, secret_value in self.secrets.items():
if f"<<{secret}>>" in str(next_data):
return str(next_data).replace(f"<<{secret}>>", secret_value)
elif f"<<{secret.upper()}>>" in str(next_data):
return str(next_data).replace(f"<<{secret.upper()}>>", secret_value)
return next_data
if self.secrets:
check_next(self.data)
def check_for_attribute(data, attribute, parent=None, test_list=None, default=None, do_print=True, default_is_none=False, req_default=False, var_type="str", throw=False, save=True, int_min=0): def check_for_attribute(data, attribute, parent=None, test_list=None, default=None, do_print=True, default_is_none=False, req_default=False, var_type="str", throw=False, save=True, int_min=0):
endline = "" endline = ""
if parent is not None: if parent is not None:

@ -10,6 +10,7 @@ if sys.version_info[0] != 3 or sys.version_info[1] < 7:
try: try:
import plexapi, psutil, requests, schedule import plexapi, psutil, requests, schedule
from dotenv import load_dotenv
from PIL import ImageFile from PIL import ImageFile
from plexapi import server from plexapi import server
from plexapi.exceptions import NotFound from plexapi.exceptions import NotFound
@ -49,13 +50,18 @@ parser.add_argument("-pu", "--plex-url", dest="plex_url", help="Plex URL for Ple
parser.add_argument("-pt", "--plex-token", dest="plex_token", help="Plex Token for Plex ENV Tokens", default="", type=str) parser.add_argument("-pt", "--plex-token", dest="plex_token", help="Plex Token for Plex ENV Tokens", default="", type=str)
parser.add_argument("-d", "--divider", dest="divider", help="Character that divides the sections (Default: '=')", default="=", type=str) parser.add_argument("-d", "--divider", dest="divider", help="Character that divides the sections (Default: '=')", default="=", type=str)
parser.add_argument("-w", "--width", dest="width", help="Screen Width (Default: 100)", default=100, type=int) parser.add_argument("-w", "--width", dest="width", help="Screen Width (Default: 100)", default=100, type=int)
args = parser.parse_args() args, unknown = parser.parse_known_args()
default_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config")
load_dotenv(os.path.join(default_dir, ".env"))
static_envs = []
test_value = None test_value = None
def get_arg(env_str, default, arg_bool=False, arg_int=False): def get_arg(env_str, default, arg_bool=False, arg_int=False):
global test_value global test_value
env_vars = [env_str] if not isinstance(env_str, list) else env_str env_vars = [env_str] if not isinstance(env_str, list) else env_str
final_value = None final_value = None
static_envs.extend(env_vars)
for env_var in env_vars: for env_var in env_vars:
env_value = os.environ.get(env_var) env_value = os.environ.get(env_var)
if env_var == "BRANCH_NAME": if env_var == "BRANCH_NAME":
@ -83,7 +89,7 @@ def get_arg(env_str, default, arg_bool=False, arg_int=False):
try: try:
from git import Repo, InvalidGitRepositoryError from git import Repo, InvalidGitRepositoryError
try: try:
git_branch = Repo(path=".").head.ref.name git_branch = Repo(path=".").head.ref.name # noqa
except InvalidGitRepositoryError: except InvalidGitRepositoryError:
git_branch = None git_branch = None
except ImportError: except ImportError:
@ -123,6 +129,18 @@ log_requests = get_arg("PMM_LOG_REQUESTS", args.log_requests, arg_bool=True)
plex_url = get_arg("PMM_PLEX_URL", args.plex_url) plex_url = get_arg("PMM_PLEX_URL", args.plex_url)
plex_token = get_arg("PMM_PLEX_TOKEN", args.plex_token) plex_token = get_arg("PMM_PLEX_TOKEN", args.plex_token)
secret_args = {}
i = 0
while i < len(unknown):
if str(unknown[i]).lower().startswith("--pmm-"):
secret_args[str(unknown[i]).lower()[6:]] = str(unknown[i + 1])
i += 1
i += 1
for env_name, env_data in os.environ.items():
if str(env_name).upper().startswith("PMM_") and str(env_name).upper() not in static_envs:
secret_args[str(env_name).lower()[4:]] = env_data
if collections: if collections:
collection_only = True collection_only = True
@ -130,7 +148,6 @@ if screen_width < 90 or screen_width > 300:
print(f"Argument Error: width argument invalid: {screen_width} must be an integer between 90 and 300 using the default 100") print(f"Argument Error: width argument invalid: {screen_width} must be an integer between 90 and 300 using the default 100")
screen_width = 100 screen_width = 100
default_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config")
if config_file and os.path.exists(config_file): if config_file and os.path.exists(config_file):
default_dir = os.path.join(os.path.dirname(os.path.abspath(config_file))) default_dir = os.path.join(os.path.dirname(os.path.abspath(config_file)))
elif config_file and not os.path.exists(config_file): elif config_file and not os.path.exists(config_file):
@ -269,7 +286,7 @@ def start(attrs):
config = None config = None
stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0, "names": []} stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0, "names": []}
try: try:
config = ConfigFile(default_dir, attrs) config = ConfigFile(default_dir, attrs, secret_args)
except Exception as e: except Exception as e:
logger.stacktrace() logger.stacktrace()
logger.critical(e) logger.critical(e)

@ -1,13 +1,14 @@
PlexAPI==4.13.4
tmdbapis==1.1.0
arrapi==1.4.2 arrapi==1.4.2
GitPython==3.1.31
lxml==4.9.2 lxml==4.9.2
requests==2.28.2 num2words==0.5.12
ruamel.yaml==0.17.21
schedule==1.1.0
retrying==1.3.4
pathvalidate==2.5.2 pathvalidate==2.5.2
pillow==9.5.0 pillow==9.5.0
num2words==0.5.12 PlexAPI==4.13.4
psutil==5.9.4 psutil==5.9.4
GitPython==3.1.31 python-dotenv==1.0.0
requests==2.28.2
retrying==1.3.4
ruamel.yaml==0.17.21
schedule==1.1.0
tmdbapis==1.1.0
Loading…
Cancel
Save