v1.15.1 finishing touches

pull/652/head
meisnate12 3 years ago
parent 9e02ba04e7
commit 4c4fa2e1df

@ -1,44 +0,0 @@
name: Docker Develop Release Arm7
on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]
jobs:
docker-develop:
runs-on: ubuntu-latest
steps:
- name: Check Out Repo
uses: actions/checkout@v2
with:
ref: develop
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: ./
file: ./Dockerfile
platforms: linux/arm/v7
push: true
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/plex-meta-manager:develop

2
.gitignore vendored

@ -9,7 +9,7 @@ __pycache__/
# Distribution / packaging
.idea
.Python
/test.py
/test*
logs/
config/*
!config/overlays/

@ -80,9 +80,9 @@ Before posting on GitHub about an enhancement, error, or configuration question
- [MyAnimeList Attributes](https://github.com/meisnate12/Plex-Meta-Manager/wiki/MyAnimeList-Attributes)
- [Metadata and Playlist Files](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Metadata-and-Playlist-Files)
- Metadata
- [Movies Metadata](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Movies-Metadata)
- [Shows Metadata](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Shows-Metadata)
- [Artists Metadata](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Artists-Metadata)
- [Movie Library Metadata](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Movie-Library-Metadata)
- [TV Show Library Metadata](https://github.com/meisnate12/Plex-Meta-Manager/wiki/TV-Show-Library-Metadata)
- [Music Library Metadata](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Music-Library-Metadata)
- [Templates](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Templates)
- [Filters](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Filters)
- Builders
@ -93,6 +93,7 @@ Before posting on GitHub about an enhancement, error, or configuration question
- [IMDb Builders](https://github.com/meisnate12/Plex-Meta-Manager/wiki/IMDb-Builders)
- [Trakt Builders](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Trakt-Builders)
- [Tautulli Builders](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Tautulli-Builders)
- [MdbList Builders](https://github.com/meisnate12/Plex-Meta-Manager/wiki/MdbList-Builders)
- [Letterboxd Builders](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Letterboxd-Builders)
- [ICheckMovies Builders](https://github.com/meisnate12/Plex-Meta-Manager/wiki/ICheckMovies-Builders)
- [FlixPatrol Builders](https://github.com/meisnate12/Plex-Meta-Manager/wiki/FlixPatrol-Builders)

@ -1 +1 @@
1.15.0-develop220122
1.15.1

@ -26,6 +26,8 @@ settings: # Can be individually specified
dimensional_asset_rename: false
download_url_assets: false
show_missing_season_assets: false
show_missing_episode_assets: false
show_asset_not_needed: true
sync_mode: append
minimum_items: 1
default_collection_order:
@ -43,6 +45,7 @@ settings: # Can be individually specified
tvdb_language: eng
ignore_ids:
ignore_imdb_ids:
item_refresh_delay: 0
playlist_sync_to_user: all
verify_ssl: true
webhooks: # Can be individually specified per library as well

@ -109,7 +109,7 @@ sonarr_details = [
"sonarr_add_missing", "sonarr_add_existing", "sonarr_folder", "sonarr_monitor", "sonarr_language", "sonarr_series",
"sonarr_quality", "sonarr_season", "sonarr_search", "sonarr_cutoff_search", "sonarr_tag"
]
album_details = ["item_label", "item_album_sorting"]
album_details = ["non_item_remove_label", "item_label", "item_album_sorting"]
filters_by_type = {
"movie_show_season_episode_artist_album_track": ["title", "summary", "collection", "has_collection", "added", "last_played", "user_rating", "plays"],
"movie_show_season_episode_album_track": ["year"],
@ -165,7 +165,7 @@ custom_sort_builders = [
"flixpatrol_url", "flixpatrol_demographics", "flixpatrol_popular", "flixpatrol_top",
"trakt_recommended_daily", "trakt_recommended_weekly", "trakt_recommended_monthly", "trakt_recommended_yearly", "trakt_recommended_all",
"trakt_watched_daily", "trakt_watched_weekly", "trakt_watched_monthly", "trakt_watched_yearly", "trakt_watched_all",
"tautulli_popular", "tautulli_watched", "letterboxd_list", "icheckmovies_list",
"tautulli_popular", "tautulli_watched", "mdblist_list", "letterboxd_list", "icheckmovies_list",
"anilist_top_rated", "anilist_popular", "anilist_trending", "anilist_search",
"mal_all", "mal_airing", "mal_upcoming", "mal_tv", "mal_movie", "mal_ova", "mal_special",
"mal_popular", "mal_favorite", "mal_suggested", "mal_userlist", "mal_season", "mal_genre", "mal_studio"
@ -182,7 +182,7 @@ playlist_attributes = [
"server_preroll", "changes_webhooks", "minimum_items",
] + custom_sort_builders + summary_details + poster_details + radarr_details + sonarr_details
music_attributes = [
"item_label", "item_assets", "item_lock_background", "item_lock_poster", "item_lock_title",
"non_item_remove_label", "item_label", "item_assets", "item_lock_background", "item_lock_poster", "item_lock_title",
"item_refresh", "item_refresh_delay", "plex_search", "plex_all", "filters"
] + details + summary_details + poster_details + background_details
@ -1090,7 +1090,7 @@ class CollectionBuilder:
self.builders.append((method_name, self._parse(method_name, method_data, "bool")))
def _mdblist(self, method_name, method_data):
for mdb_dict in self.config.Mdblist.validate_mdb_lists(method_data, self.language):
for mdb_dict in self.config.Mdblist.validate_mdblist_lists(method_data):
self.builders.append((method_name, mdb_dict))
def _tautulli(self, method_name, method_data):
@ -1356,7 +1356,7 @@ class CollectionBuilder:
if tvdb_id not in self.missing_shows:
self.missing_shows.append(tvdb_id)
except Failed as e:
logger.error(e)
logger.warning(e)
elif show_id not in self.missing_shows:
self.missing_shows.append(show_id)
else:
@ -1374,7 +1374,7 @@ class CollectionBuilder:
try:
input_id = self.config.Convert.tmdb_to_tvdb(input_id, fail=True)
except Failed as e:
logger.error(e)
logger.warning(e)
continue
if input_id not in self.ignore_ids:
if input_id in self.library.show_map:
@ -1396,7 +1396,7 @@ class CollectionBuilder:
if tvdb_id not in self.missing_shows:
self.missing_shows.append(tvdb_id)
except Failed as e:
logger.error(e)
logger.warning(e)
continue
if not isinstance(rating_keys, list):
rating_keys = [rating_keys]

@ -54,7 +54,7 @@ class ConfigFile:
self.run_hour = datetime.strptime(attrs["time"], "%H:%M").hour
self.requested_collections = util.get_list(attrs["collections"]) if "collections" in attrs else None
self.requested_libraries = util.get_list(attrs["libraries"]) if "libraries" in attrs else None
self.requested_metadata = util.get_list(attrs["metadata"]) if "metadata" in attrs else None
self.requested_metadata_files = util.get_list(attrs["metadata_files"]) if "metadata_files" in attrs else None
self.resume_from = attrs["resume"] if "resume" in attrs else None
yaml.YAML().allow_duplicate_keys = True
@ -667,11 +667,14 @@ class ConfigFile:
if lib["operations"]["genre_mapper"] and isinstance(lib["operations"]["genre_mapper"], dict):
params["genre_mapper"] = {}
for new_genre, old_genres in lib["operations"]["genre_mapper"].items():
for old_genre in util.get_list(old_genres):
if old_genre == new_genre:
logger.error("Config Error: genres cannot be mapped to themselves")
else:
params["genre_mapper"][old_genre] = new_genre
if old_genres is None:
params["genre_mapper"][new_genre] = old_genres
else:
for old_genre in util.get_list(old_genres):
if old_genre == new_genre:
logger.error("Config Error: genres cannot be mapped to themselves")
else:
params["genre_mapper"][old_genre] = new_genre
else:
logger.error("Config Error: genre_mapper is blank")
if "genre_collections" in lib["operations"]:

@ -75,9 +75,9 @@ class Convert:
elif anidb_id in self.anidb_to_tvdb:
ids.append((self.anidb_to_tvdb[anidb_id], "tvdb"))
elif anidb_id in self.anidb_ids:
logger.error(f"Convert Error: No TVDb ID or IMDb ID found for AniDB ID: {anidb_id}")
logger.warning(f"Convert Error: No TVDb ID or IMDb ID found for AniDB ID: {anidb_id}")
else:
logger.error(f"Convert Error: AniDB ID: {anidb_id} not found")
logger.warning(f"Convert Error: AniDB ID: {anidb_id} not found")
return ids
def anilist_to_ids(self, anilist_ids, library):
@ -86,7 +86,7 @@ class Convert:
if anilist_id in self.anilist_to_anidb:
anidb_ids.append(self.anilist_to_anidb[anilist_id])
else:
logger.error(f"Convert Error: AniDB ID not found for AniList ID: {anilist_id}")
logger.warning(f"Convert Error: AniDB ID not found for AniList ID: {anilist_id}")
return self.anidb_to_ids(anidb_ids, library)
def myanimelist_to_ids(self, mal_ids, library):
@ -97,7 +97,7 @@ class Convert:
elif int(mal_id) in self.mal_to_anidb:
ids.extend(self.anidb_to_ids(self.mal_to_anidb[int(mal_id)], library))
else:
logger.error(f"Convert Error: AniDB ID not found for MyAnimeList ID: {mal_id}")
logger.warning(f"Convert Error: AniDB ID not found for MyAnimeList ID: {mal_id}")
return ids
def tmdb_to_imdb(self, tmdb_id, is_movie=True, fail=False):

@ -1,4 +1,4 @@
import logging, os, requests, shutil, time
import logging, os, shutil, time
from abc import ABC, abstractmethod
from modules import util
from modules.meta import MetadataFile

@ -1,19 +1,20 @@
import logging
from modules import util
from modules.util import Failed
from urllib.parse import urlparse
logger = logging.getLogger("Plex Meta Manager")
builders = ["mdblist_list"]
base_url = "https://mdblist.com/lists"
headers = { 'User-Agent': 'Plex-Meta-Manager' }
headers = {"User-Agent": "Plex-Meta-Manager"}
class Mdblist:
def __init__(self, config):
self.config = config
def validate_mdb_lists(self, mdb_lists, language):
def validate_mdblist_lists(self, mdb_lists):
valid_lists = []
for mdb_dict in util.get_list(mdb_lists, split=False):
if not isinstance(mdb_dict, dict):
@ -49,7 +50,9 @@ class Mdblist:
if method == "mdblist_list":
limit_status = f" Limit at: {data['limit']} items" if data['limit'] > 0 else ''
logger.info(f"Processing Mdblist.com List: {data['url']}{limit_status}")
url = f"{data['url']}?limit={data['limit']}"
return [(i["imdb_id"], "imdb") for i in self.config.get_json(url,headers=headers)]
parsed_url = urlparse(data["url"])
url_base = parsed_url._replace(query=None).geturl()
params = {"limit": data["limit"]} if data["limit"] > 0 else None
return [(i["imdb_id"], "imdb") for i in self.config.get_json(url_base, headers=headers, params=params)]
else:
raise Failed(f"Mdblist Error: Method {method} not supported")

@ -31,18 +31,18 @@ def get_dict(attribute, attr_data, check_list=None):
new_dict = {}
for _name, _data in attr_data[attribute].items():
if _name in check_list:
logger.error(f"Config Warning: Skipping duplicate {attribute[:-1] if attribute[-1] == 's' else attribute}: {_name}")
logger.warning(f"Config Warning: Skipping duplicate {attribute[:-1] if attribute[-1] == 's' else attribute}: {_name}")
elif _data is None:
logger.error(f"Config Warning: {attribute[:-1] if attribute[-1] == 's' else attribute}: {_name} has no data")
logger.error(f"Config Error: {attribute[:-1] if attribute[-1] == 's' else attribute}: {_name} has no data")
elif not isinstance(_data, dict):
logger.error(f"Config Warning: {attribute[:-1] if attribute[-1] == 's' else attribute}: {_name} must be a dictionary")
logger.error(f"Config Error: {attribute[:-1] if attribute[-1] == 's' else attribute}: {_name} must be a dictionary")
else:
new_dict[str(_name)] = _data
return new_dict
else:
logger.warning(f"Config Warning: {attribute} must be a dictionary")
logger.error(f"Config Error: {attribute} must be a dictionary")
else:
logger.warning(f"Config Warning: {attribute} attribute is blank")
logger.error(f"Config Error: {attribute} attribute is blank")
return None
@ -238,7 +238,7 @@ class MetadataFile(DataFile):
logger.info("")
logger.info(f"Loading Metadata {file_type}: {path}")
data = self.load_file()
self.metadata = get_dict("metadata", data, library.metadatas)
self.metadata = get_dict("metadata", data, library.metadata_files)
self.templates = get_dict("templates", data)
self.collections = get_dict("collections", data, library.collections)

@ -34,7 +34,7 @@ parser.add_argument("-lo", "--library-only", "--libraries-only", dest="library_o
parser.add_argument("-lf", "--library-first", "--libraries-first", dest="library_first", help="Run library operations before collections", action="store_true", default=False)
parser.add_argument("-rc", "-cl", "--collection", "--collections", "--run-collection", "--run-collections", dest="collections", help="Process only specified collections (comma-separated list)", type=str)
parser.add_argument("-rl", "-l", "--library", "--libraries", "--run-library", "--run-libraries", dest="libraries", help="Process only specified libraries (comma-separated list)", type=str)
parser.add_argument("-rm", "-m", "--metadata", "--metadatas", "--run-metadata", "--run-metadatas", dest="metadata", help="Process only specified Metadata files (comma-separated list)", type=str)
parser.add_argument("-rm", "-m", "--metadata", "--metadata-files", "--run-metadata-files", dest="metadata", help="Process only specified Metadata files (comma-separated list)", type=str)
parser.add_argument("-dc", "--delete", "--delete-collections", dest="delete", help="Deletes all Collections in the Plex Library before running", action="store_true", default=False)
parser.add_argument("-nc", "--no-countdown", dest="no_countdown", help="Run without displaying the countdown", action="store_true", default=False)
parser.add_argument("-nm", "--no-missing", dest="no_missing", help="Run without running the missing section", action="store_true", default=False)
@ -70,7 +70,7 @@ library_only = get_arg("PMM_LIBRARIES_ONLY", args.library_only, arg_bool=True)
library_first = get_arg("PMM_LIBRARIES_FIRST", args.library_first, arg_bool=True)
collections = get_arg("PMM_COLLECTIONS", args.collections)
libraries = get_arg("PMM_LIBRARIES", args.libraries)
metadatas = get_arg("PMM_METADATA", args.metadata)
metadata_files = get_arg("PMM_METADATA_FILES", args.metadata)
delete = get_arg("PMM_DELETE_COLLECTIONS", args.delete, arg_bool=True)
resume = get_arg("PMM_RESUME", args.resume)
no_countdown = get_arg("PMM_NO_COUNTDOWN", args.no_countdown, arg_bool=True)
@ -160,7 +160,7 @@ def start(attrs):
logger.debug(f"--libraries-first (PMM_LIBRARIES_FIRST): {library_first}")
logger.debug(f"--run-collections (PMM_COLLECTIONS): {collections}")
logger.debug(f"--run-libraries (PMM_LIBRARIES): {libraries}")
logger.debug(f"--run-metadata (PMM_METADATA): {metadatas}")
logger.debug(f"--run-metadata-files (PMM_METADATA_FILES): {metadata_files}")
logger.debug(f"--ignore-schedules (PMM_IGNORE_SCHEDULES): {ignore_schedules}")
logger.debug(f"--delete-collections (PMM_DELETE_COLLECTIONS): {delete}")
logger.debug(f"--resume (PMM_RESUME): {resume}")
@ -262,7 +262,7 @@ def update_libraries(config):
library.map_guids()
for metadata in library.metadata_files:
metadata_name = metadata.get_file_name()
if config.requested_metadata and metadata_name not in config.requested_metadata:
if config.requested_metadata_files and metadata_name not in config.requested_metadata_files:
continue
logger.info("")
util.separator(f"Running {metadata_name} Metadata File\n{metadata.path}")
@ -1072,7 +1072,7 @@ def run_playlists(config):
try:
input_id = config.Convert.tmdb_to_tvdb(input_id, fail=True)
except Failed as e:
logger.error(e)
logger.warning(e)
continue
if input_id not in builder.ignore_ids:
found = False
@ -1121,7 +1121,7 @@ def run_playlists(config):
if tvdb_id not in builder.missing_shows:
builder.missing_shows.append(tvdb_id)
except Failed as e:
logger.error(e)
logger.warning(e)
continue
if not isinstance(rating_keys, list):
rating_keys = [rating_keys]
@ -1225,7 +1225,7 @@ def run_playlists(config):
return status, stats
try:
if run or test or collections or libraries or metadatas or resume:
if run or test or collections or libraries or metadata_files or resume:
start({
"config_file": config_file,
"test": test,
@ -1233,7 +1233,7 @@ try:
"ignore_schedules": ignore_schedules,
"collections": collections,
"libraries": libraries,
"metadata": metadatas,
"metadata_files": metadata_files,
"library_first": library_first,
"resume": resume,
"trace": trace

Loading…
Cancel
Save