[172] add Config Secrets

This commit is contained in:
meisnate12 2023-04-07 16:03:59 -04:00
parent ba2b34987c
commit dce42b265f
7 changed files with 102 additions and 17 deletions

View file

@ -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
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.
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
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/).

View file

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

View file

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

View file

@ -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/).
Environment Variables can also be placed inside a `.env` file inside your config folder.
| Attribute | Shell Command | Environment Variable |
|:------------------------------------------------------|:----------------------------------------------|:-------------------------|
| [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` |
| [Divider Character](#divider-character--screen-width) | `-d` or `--divider` | `PMM_DIVIDER` |
| [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.
@ -1070,4 +1073,46 @@ 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
```
````
````
### 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>>
```

View file

@ -112,7 +112,7 @@ library_operations = {
}
class ConfigFile:
def __init__(self, default_dir, attrs):
def __init__(self, default_dir, attrs, secrets):
logger.info("Locating config...")
config_file = attrs["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.default_dir = default_dir
self.secrets = secrets
self.read_only = attrs["read_only"] if "read_only" in attrs else False
self.version = attrs["version"] if "version" 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 "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):
endline = ""
if parent is not None:

View file

@ -10,6 +10,7 @@ if sys.version_info[0] != 3 or sys.version_info[1] < 7:
try:
import plexapi, psutil, requests, schedule
from dotenv import load_dotenv
from PIL import ImageFile
from plexapi import server
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("-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)
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
def get_arg(env_str, default, arg_bool=False, arg_int=False):
global test_value
env_vars = [env_str] if not isinstance(env_str, list) else env_str
final_value = None
static_envs.extend(env_vars)
for env_var in env_vars:
env_value = os.environ.get(env_var)
if env_var == "BRANCH_NAME":
@ -83,7 +89,7 @@ def get_arg(env_str, default, arg_bool=False, arg_int=False):
try:
from git import Repo, InvalidGitRepositoryError
try:
git_branch = Repo(path=".").head.ref.name
git_branch = Repo(path=".").head.ref.name # noqa
except InvalidGitRepositoryError:
git_branch = None
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_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:
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")
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):
default_dir = os.path.join(os.path.dirname(os.path.abspath(config_file)))
elif config_file and not os.path.exists(config_file):
@ -269,7 +286,7 @@ def start(attrs):
config = None
stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0, "names": []}
try:
config = ConfigFile(default_dir, attrs)
config = ConfigFile(default_dir, attrs, secret_args)
except Exception as e:
logger.stacktrace()
logger.critical(e)

View file

@ -1,13 +1,14 @@
PlexAPI==4.13.4
tmdbapis==1.1.0
arrapi==1.4.2
GitPython==3.1.31
lxml==4.9.2
requests==2.28.2
ruamel.yaml==0.17.21
schedule==1.1.0
retrying==1.3.4
num2words==0.5.12
pathvalidate==2.5.2
pillow==9.5.0
num2words==0.5.12
PlexAPI==4.13.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