[82] #710 changed save_missing to save_report

pull/865/head
meisnate12 3 years ago
parent 3202274f4c
commit 8f3794c529

@ -1 +1 @@
1.16.5-develop81
1.16.5-develop82

@ -77,19 +77,19 @@ radarr:
The available attributes for each library are as follows:
| Attribute | Values | Default | Required |
|:-------------------------------------------|:---------------------------------------------------------------------------------------------|:--------------------------------------:|:-------------------------------:|
| [`library_name`](#library-name) | Library name (required only when trying to use multiple libraries with the same name) | Base Attribute Name | ❌ |
| [`metadata_path`](#metadata-path) | Location of Metadata YAML files | `/config/<<MAPPING_NAME>>.yml` | &#10060; |
| [`overlay_path`](#overlay-path) | Location of Overlay YAML files | None | &#10060; |
| [`missing_path`](#missing-path) | Location to create the YAML file listing missing items for this library | `/config/<<MAPPING_NAME>>_missing.yml` | &#10060; |
| [`schedule`](../metadata/details/schedule) | Use any [schedule option](../metadata/details/schedule) to control when this library is run. | daily | &#10060; |
| [`operations`](operations) | Library Operations to run | N/A | &#10060; |
| [`settings`](settings) | Any `setting` attribute that overrides a global value | global | &#10060; |
| [`plex`](plex) | Any `plex` attribute that overrides a global value | global | &#9989; Either here or globally |
| [`radarr`](radarr) | Any `radarr` attribute that overrides a global value | global | &#10060; |
| [`sonarr`](sonarr) | Any `sonarr` attribute that overrides a global value | global | &#10060; |
| [`tautulli`](tautulli) | Any `tautulli` attribute that overrides a global value | global | &#10060; |
| Attribute | Values | Default | Required |
|:-------------------------------------------|:------------------------------------------------------------------------------------------------------|:-------------------------------------:|:-------------------------------:|
| [`library_name`](#library-name) | Library name (required only when trying to use multiple libraries with the same name) | Base Attribute Name | &#10060; |
| [`metadata_path`](#metadata-path) | Location of Metadata YAML files | `/config/<<MAPPING_NAME>>.yml` | &#10060; |
| [`overlay_path`](#overlay-path) | Location of Overlay YAML files | None | &#10060; |
| [`report_path`](#report-path) | Location to create the YAML file listing added, removed, filtered, and missing items for this library | `/config/<<MAPPING_NAME>>_report.yml` | &#10060; |
| [`schedule`](../metadata/details/schedule) | Use any [schedule option](../metadata/details/schedule) to control when this library is run. | daily | &#10060; |
| [`operations`](operations) | Library Operations to run | N/A | &#10060; |
| [`settings`](settings) | Any `setting` attribute that overrides a global value | global | &#10060; |
| [`plex`](plex) | Any `plex` attribute that overrides a global value | global | &#9989; Either here or globally |
| [`radarr`](radarr) | Any `radarr` attribute that overrides a global value | global | &#10060; |
| [`sonarr`](sonarr) | Any `sonarr` attribute that overrides a global value | global | &#10060; |
| [`tautulli`](tautulli) | Any `tautulli` attribute that overrides a global value | global | &#10060; |
### Library Name
@ -157,26 +157,26 @@ libraries:
* This will remove all overlays when run and not generate new ones.
### Missing Path
### Report Path
The `missing_path` attribute is used to define where to save the "missing items" YAML file. This file is used to store information about media which is missing from the Plex library compared to what is expected from the Metadata file.
The `report_path` attribute is used to define where to save the YAML Report file. This file is used to store information about what media is added, removed, filtered, and missing from the Plex library compared to what is expected from the Metadata file.
If your Metadata file creates a collection with `Movie 1`, `Movie 2` and `Movie 3` but your Plex library only has `Movie 1` and `Movie 3`, then the missing YAML file will be updated to inform the user that `Movie 2` was missing from the library.
The default and recommended path is `/config/<<MAPPING_NAME>>_missing.yml` where `<<MAPPING_NAME>>` is the name of the library attribute, as showcased below:
The default and recommended path is `/config/<<MAPPING_NAME>>report.yml` where `<<MAPPING_NAME>>` is the name of the library attribute, as showcased below:
```yaml
libraries:
Movies:
missing_path: /config/Movies_missing.yml
report_path: /config/Movies_report.yml
```
Alternatively, "missing items" YAML files can be placed in their own directory, as below:
Alternatively, Report YAML files can be placed in their own directory, as below:
```yaml
libraries:
Movies:
missing_path: /config/missing/Movies.yml
report_path: /config/reports/Movies.yml
```
## Playlist Files Attribute

@ -46,7 +46,7 @@ The available setting attributes which can be set at each level are outlined bel
| [`show_missing`](#show-missing) | &#9989; | &#9989; | &#9989; |
| [`only_filter_missing`](#only-filter-missing) | &#9989; | &#9989; | &#9989; |
| [`show_missing_assets`](#show-missing-assets) | &#9989; | &#9989; | &#9989; |
| [`save_missing`](#save-missing) | &#9989; | &#9989; | &#9989; |
| [`save_report`](#save-report) | &#9989; | &#9989; | &#9989; |
| [`tvdb_language`](#tvdb-language) | &#9989; | &#10060; | &#10060; |
| [`ignore_ids`](#ignore-ids) | &#9989; | &#9989; | &#9989; |
| [`ignore_imdb_ids`](#ignore-imdb-ids) | &#9989; | &#9989; | &#9989; |
@ -440,8 +440,8 @@ Display missing asset warnings
</tr>
</table>
## Save Missing
Save missing items from collections to a YAML file in the same directory as your Metadata file.
## Save Report
Save a report of the items added, removed, filtered, or missing from collections to a YAML file in the same directory as your Metadata file.
<table class="dualTable colwidths-auto align-default table">
<tr>

@ -22,7 +22,7 @@ All the following attributes serve various functions as how the collection/playl
| `only_filter_missing` | **Description:** Collection/Playlist Level `only_filter_missing` toggle.<br>**Default:** `only_filter_missing` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `show_filtered` | **Description:** Collection/Playlist level `show_filtered` toggle.<br>**Default:** `show_filtered` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `show_missing` | **Description:** Collection/Playlist level `show_missing` toggle.<br>**Default:** `show_missing` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `save_missing` | **Description:** Collection/Playlist level `save_missing` toggle.<br>**Default:** `save_missing` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `save_report` | **Description:** Collection/Playlist level `save_report` toggle.<br>**Default:** `save_report` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `ignore_ids` | **Description:** Collection/Playlist level `ignore_ids` which is combined with the library and global `ignore_ids`.<br>**Default:** `ignore_ids` [settings value](../../config/settings) in the Configuration File<br>**Values:** List or comma-separated String of TMDb/TVDb IDs |
| `ignore_imdb_ids` | **Description:** Collection/Playlist level `ignore_imdb_ids` which is combined with the library and global `ignore_imdb_ids`.<br>**Default:** `ignore_imdb_ids` [settings value](../../config/settings) in the Configuration File<br>**Values:** List or comma-separated String of IMDb IDs |
| `name_mapping` | **Description:** Used to specify the folder name in the [Image Assets Directory](../../home/guides/assets) i.e. if your collection/playlist name contains characters that are not allowed in file paths (i.e. for windows `<`, `>`, `:`, `"`, `/`, `\`, `?`, `*` cannot be in the file path), but you want them in your name you can this to specify the name in the file system.<br>**Values:** Any String |

@ -31,7 +31,7 @@ summary_details = [
poster_details = ["url_poster", "tmdb_poster", "tmdb_profile", "tvdb_poster", "file_poster"]
background_details = ["url_background", "tmdb_background", "tvdb_background", "file_background"]
boolean_details = [
"show_filtered", "show_missing", "save_missing", "missing_only_released", "only_filter_missing",
"show_filtered", "show_missing", "save_report", "missing_only_released", "only_filter_missing",
"delete_below_minimum", "asset_folders", "create_asset_folders"
]
scheduled_boolean = ["visible_library", "visible_home", "visible_shared"]
@ -126,7 +126,7 @@ year_attributes = plex.year_attributes + ["tmdb_year"]
number_attributes = plex.number_attributes + ["tmdb_vote_count"]
smart_invalid = ["collection_order", "collection_level"]
smart_only = ["collection_filtering"]
smart_url_invalid = ["filters", "run_again", "sync_mode", "show_filtered", "show_missing", "save_missing", "smart_label"] + radarr_details + sonarr_details
smart_url_invalid = ["filters", "run_again", "sync_mode", "show_filtered", "show_missing", "save_report", "smart_label"] + radarr_details + sonarr_details
custom_sort_builders = [
"plex_search", "plex_pilots", "tmdb_list", "tmdb_popular", "tmdb_now_playing", "tmdb_top_rated",
"tmdb_trending_daily", "tmdb_trending_weekly", "tmdb_discover", "reciperr_list", "trakt_chart", "trakt_userlist",
@ -144,16 +144,16 @@ custom_sort_builders = [
episode_parts_only = ["plex_pilots"]
overlay_only = ["overlay", "suppress_overlays"]
overlay_attributes = [
"filters", "limit", "show_missing", "save_missing", "missing_only_released", "minimum_items", "cache_builders", "tmdb_region"
"filters", "limit", "show_missing", "save_report", "missing_only_released", "minimum_items", "cache_builders", "tmdb_region"
] + all_builders + overlay_only
parts_collection_valid = [
"filters", "plex_all", "plex_search", "trakt_list", "trakt_list_details", "collection_filtering", "collection_mode", "label", "visible_library", "limit",
"visible_home", "visible_shared", "show_missing", "save_missing", "missing_only_released", "server_preroll", "changes_webhooks",
"visible_home", "visible_shared", "show_missing", "save_report", "missing_only_released", "server_preroll", "changes_webhooks",
"item_lock_background", "item_lock_poster", "item_lock_title", "item_refresh", "item_refresh_delay", "imdb_list", "cache_builders",
"url_theme", "file_theme", "item_label"
] + episode_parts_only + summary_details + poster_details + background_details + string_details
playlist_attributes = [
"filters", "name_mapping", "show_filtered", "show_missing", "save_missing",
"filters", "name_mapping", "show_filtered", "show_missing", "save_report",
"missing_only_released", "only_filter_missing", "delete_below_minimum", "ignore_ids", "ignore_imdb_ids",
"server_preroll", "changes_webhooks", "minimum_items", "cache_builders"
] + custom_sort_builders + summary_details + poster_details + radarr_details + sonarr_details
@ -372,7 +372,7 @@ class CollectionBuilder:
"show_filtered": self.library.show_filtered,
"show_options": self.library.show_options,
"show_missing": self.library.show_missing,
"save_missing": self.library.save_missing,
"save_report": self.library.save_report,
"missing_only_released": self.library.missing_only_released,
"only_filter_missing": self.library.only_filter_missing,
"asset_folders": self.library.asset_folders,
@ -396,6 +396,7 @@ class CollectionBuilder:
self.filters = []
self.tmdb_filters = []
self.added_items = []
self.filtered_items = []
self.filtered_keys = {}
self.run_again_movies = []
self.run_again_shows = []
@ -803,7 +804,7 @@ class CollectionBuilder:
self.details["collection_mode"] = "hide"
self.sync = True
self.do_missing = not self.config.no_missing and (self.details["show_missing"] or self.details["save_missing"]
self.do_missing = not self.config.no_missing and (self.details["show_missing"] or self.details["save_report"]
or (self.library.Radarr and self.radarr_details["add_missing"])
or (self.library.Sonarr and self.sonarr_details["add_missing"]))
if self.build_collection:
@ -1735,6 +1736,7 @@ class CollectionBuilder:
if (self.filters or self.tmdb_filters) and self.details["show_filtered"] is True:
logger.info("")
logger.info("Filtering Builders:")
filtered_items = []
for i, item in enumerate(items, 1):
if not isinstance(item, (Movie, Show, Season, Episode, Artist, Album, Track)):
logger.error(f"{self.Type} Error: Item: {item} is an invalid type")
@ -1748,9 +1750,12 @@ class CollectionBuilder:
if self.check_filters(item, f"{(' ' * (max_length - len(str(i))))}{i}/{total}"):
self.added_items.append(item)
else:
filtered_items.append(item)
self.filtered_keys[item.ratingKey] = current_title
if self.details["show_filtered"] is True:
logger.info(f"{name} {self.Type} | X | {current_title}")
if self.details["save_report"] is True and filtered_items:
self.library.add_filtered(self.name, [(i.title, self.library.get_id_from_maps(i.ratingKey)) for i in filtered_items], self.library.is_movie)
def build_filter(self, method, plex_filter, display=False, default_sort=None, type_override=None):
if display:
@ -2096,7 +2101,7 @@ class CollectionBuilder:
spacing = len(str(total)) * 2 + 1
amount_added = 0
amount_unchanged = 0
playlist_adds = []
items_added = []
for i, item in enumerate(self.added_items, 1):
if self.limit and amount_added + self.beginning_count - len([r for _, r in self.remove_item_map.items() if r is not None]) >= self.limit:
logger.info(f"{self.Type} Limit reached")
@ -2109,25 +2114,20 @@ class CollectionBuilder:
self.remove_item_map[item.ratingKey] = None
amount_unchanged += 1
else:
if self.playlist:
playlist_adds.append(item)
else:
items_added.append(item)
if not self.playlist:
self.library.alter_collection(item, name, smart_label_collection=self.smart_label_collection)
amount_added += 1
if self.details["changes_webhooks"]:
if item.ratingKey in self.library.movie_rating_key_map:
add_id = self.library.movie_rating_key_map[item.ratingKey]
elif item.ratingKey in self.library.show_rating_key_map:
add_id = self.library.show_rating_key_map[item.ratingKey]
else:
add_id = None
self.notification_additions.append(util.item_set(item, add_id))
if self.playlist and playlist_adds and not self.obj:
self.obj = self.library.create_playlist(self.name, playlist_adds)
self.notification_additions.append(util.item_set(item, self.library.get_id_from_maps(item.ratingKey)))
if self.playlist and items_added and not self.obj:
self.obj = self.library.create_playlist(self.name, items_added)
logger.info("")
logger.info(f"Playlist: {self.name} created")
elif self.playlist and playlist_adds:
self.obj.addItems(playlist_adds)
elif self.playlist and items_added:
self.obj.addItems(items_added)
if self.details["save_report"] is True and items_added:
self.library.add_additions(self.name, [(i.title, self.library.get_id_from_maps(i.ratingKey)) for i in items_added], self.library.is_movie)
logger.exorcise()
logger.info("")
logger.info(f"{total} {self.collection_level.capitalize()}{'s' if total > 1 else ''} Processed")
@ -2135,7 +2135,7 @@ class CollectionBuilder:
def sync_collection(self):
amount_removed = 0
playlist_removes = []
items_removed = []
items = [item for _, item in self.remove_item_map.items() if item is not None]
if items:
logger.info("")
@ -2146,22 +2146,17 @@ class CollectionBuilder:
for i, item in enumerate(items, 1):
number_text = f"{i}/{total}"
logger.info(f"{number_text:>{spacing}} | {self.name} {self.Type} | - | {util.item_title(item)}")
if self.playlist:
playlist_removes.append(item)
else:
items_removed.append(item)
if not self.playlist:
self.library.alter_collection(item, self.name, smart_label_collection=self.smart_label_collection, add=False)
amount_removed += 1
if self.details["changes_webhooks"]:
if item.ratingKey in self.library.movie_rating_key_map:
remove_id = self.library.movie_rating_key_map[item.ratingKey]
elif item.ratingKey in self.library.show_rating_key_map:
remove_id = self.library.show_rating_key_map[item.ratingKey]
else:
remove_id = None
self.notification_removals.append(util.item_set(item, remove_id))
if self.playlist and playlist_removes:
self.notification_removals.append(util.item_set(item, self.library.get_id_from_maps(item.ratingKey)))
if self.playlist and items_removed:
self.obj.reload()
self.obj.removeItems(playlist_removes)
self.obj.removeItems(items_removed)
if self.details["save_report"] is True and items_removed:
self.library.add_removed(self.name, [(i.title, self.library.get_id_from_maps(i.ratingKey)) for i in items_removed], self.library.is_movie)
logger.info("")
logger.info(f"{amount_removed} {self.collection_level.capitalize()}{'s' if amount_removed == 1 else ''} Removed")
return amount_removed
@ -2265,6 +2260,7 @@ class CollectionBuilder:
logger.separator(f"Missing Movies from Library: {self.library.name}", space=False, border=False)
logger.info("")
missing_movies_with_names = []
filtered_movies_with_names = []
for missing_id in self.missing_movies:
try:
movie = self.config.TMDb.get_movie(missing_id)
@ -2277,12 +2273,13 @@ class CollectionBuilder:
if self.details["show_missing"] is True:
logger.info(f"{self.name} {self.Type} | ? | {current_title} (TMDb: {missing_id})")
else:
filtered_movies_with_names.append((current_title, missing_id))
if self.details["show_filtered"] is True and self.details["show_missing"] is True:
logger.info(f"{self.name} {self.Type} | X | {current_title} (TMDb: {missing_id})")
logger.info("")
logger.info(f"{len(missing_movies_with_names)} Movie{'s' if len(missing_movies_with_names) > 1 else ''} Missing")
if len(missing_movies_with_names) > 0:
if self.details["save_missing"] is True:
if self.details["save_report"] is True:
self.library.add_missing(self.name, missing_movies_with_names, True)
if self.run_again or (self.library.Radarr and (self.radarr_details["add_missing"] or "item_radarr_tag" in self.item_details)):
missing_tmdb_ids = [missing_id for title, missing_id in missing_movies_with_names]
@ -2301,12 +2298,15 @@ class CollectionBuilder:
logger.error(e)
if self.run_again:
self.run_again_movies.extend(missing_tmdb_ids)
if len(filtered_movies_with_names) > 0 and self.details["save_report"] is True:
self.library.add_filtered(self.name, filtered_movies_with_names, True)
if len(self.missing_shows) > 0 and self.library.is_show:
if self.details["show_missing"] is True:
logger.info("")
logger.separator(f"Missing Shows from Library: {self.name}", space=False, border=False)
logger.info("")
missing_shows_with_names = []
filtered_shows_with_names = []
for missing_id in self.missing_shows:
try:
title = self.config.TVDb.get_tvdb_obj(missing_id).title
@ -2318,12 +2318,13 @@ class CollectionBuilder:
if self.details["show_missing"] is True:
logger.info(f"{self.name} {self.Type} | ? | {title} (TVDb: {missing_id})")
else:
filtered_shows_with_names.append((title, missing_id))
if self.details["show_filtered"] is True and self.details["show_missing"] is True:
logger.info(f"{self.name} {self.Type} | X | {title} (TVDb: {missing_id})")
logger.info("")
logger.info(f"{len(missing_shows_with_names)} Show{'s' if len(missing_shows_with_names) > 1 else ''} Missing")
if len(missing_shows_with_names) > 0:
if self.details["save_missing"] is True:
if self.details["save_report"] is True:
self.library.add_missing(self.name, missing_shows_with_names, False)
if self.run_again or (self.library.Sonarr and (self.sonarr_details["add_missing"] or "item_sonarr_tag" in self.item_details)):
missing_tvdb_ids = [missing_id for title, missing_id in missing_shows_with_names]
@ -2342,9 +2343,14 @@ class CollectionBuilder:
logger.error(e)
if self.run_again:
self.run_again_shows.extend(missing_tvdb_ids)
if len(self.missing_parts) > 0 and self.library.is_show and self.details["show_missing"] is True:
for missing in self.missing_parts:
logger.info(f"{self.name} {self.Type} | X | {missing}")
if len(filtered_shows_with_names) > 0 and self.details["save_report"] is True:
self.library.add_filtered(self.name, filtered_shows_with_names, False)
if len(self.missing_parts) > 0 and self.library.is_show:
if self.details["show_missing"] is True:
for missing in self.missing_parts:
logger.info(f"{self.name} {self.Type} | ? | {missing}")
if self.details["save_report"] is True:
self.library.add_missing(self.name, self.missing_parts, False)
return added_to_radarr, added_to_sonarr
def load_collection_items(self):

@ -314,7 +314,7 @@ class ConfigFile:
"show_options": check_for_attribute(self.data, "show_options", parent="settings", var_type="bool", default=False),
"show_missing": check_for_attribute(self.data, "show_missing", parent="settings", var_type="bool", default=True),
"show_missing_assets": check_for_attribute(self.data, "show_missing_assets", parent="settings", var_type="bool", default=True),
"save_missing": check_for_attribute(self.data, "save_missing", parent="settings", var_type="bool", default=True),
"save_report": check_for_attribute(self.data, "save_report", parent="settings", var_type="bool", default=True),
"tvdb_language": check_for_attribute(self.data, "tvdb_language", parent="settings", default="default"),
"ignore_ids": check_for_attribute(self.data, "ignore_ids", parent="settings", var_type="int_list", default_is_none=True),
"ignore_imdb_ids": check_for_attribute(self.data, "ignore_imdb_ids", parent="settings", var_type="list", default_is_none=True),
@ -601,7 +601,7 @@ class ConfigFile:
params["show_options"] = check_for_attribute(lib, "show_options", parent="settings", var_type="bool", default=self.general["show_options"], do_print=False, save=False)
params["show_missing"] = check_for_attribute(lib, "show_missing", parent="settings", var_type="bool", default=self.general["show_missing"], do_print=False, save=False)
params["show_missing_assets"] = check_for_attribute(lib, "show_missing_assets", parent="settings", var_type="bool", default=self.general["show_missing_assets"], do_print=False, save=False)
params["save_missing"] = check_for_attribute(lib, "save_missing", parent="settings", var_type="bool", default=self.general["save_missing"], do_print=False, save=False)
params["save_report"] = check_for_attribute(lib, "save_report", parent="settings", var_type="bool", default=self.general["save_report"], do_print=False, save=False)
params["missing_only_released"] = check_for_attribute(lib, "missing_only_released", parent="settings", var_type="bool", default=self.general["missing_only_released"], do_print=False, save=False)
params["only_filter_missing"] = check_for_attribute(lib, "only_filter_missing", parent="settings", var_type="bool", default=self.general["only_filter_missing"], do_print=False, save=False)
params["create_asset_folders"] = check_for_attribute(lib, "create_asset_folders", parent="settings", var_type="bool", default=self.general["create_asset_folders"], do_print=False, save=False)
@ -631,12 +631,12 @@ class ConfigFile:
params["split_duplicates"] = check_for_attribute(lib, "split_duplicates", var_type="bool", default=False, save=False, do_print=False)
params["radarr_add_all_existing"] = check_for_attribute(lib, "radarr_add_all_existing", var_type="bool", default=False, save=False, do_print=False)
params["sonarr_add_all_existing"] = check_for_attribute(lib, "sonarr_add_all_existing", var_type="bool", default=False, save=False, do_print=False)
params["missing_path"] = None
if lib and "missing_path" in lib and lib["missing_path"]:
if os.path.exists(os.path.dirname(os.path.abspath(lib["missing_path"]))):
params["missing_path"] = lib["missing_path"]
params["report_path"] = None
if lib and "report_path" in lib and lib["report_path"]:
if os.path.exists(os.path.dirname(os.path.abspath(lib["report_path"]))):
params["report_path"] = lib["report_path"]
else:
logger.error(f"Config Error: Folder {os.path.dirname(os.path.abspath(lib['missing_path']))} does not exist")
logger.error(f"Config Error: Folder {os.path.dirname(os.path.abspath(lib['report_path']))} does not exist")
if lib and "operations" in lib and lib["operations"]:
if isinstance(lib["operations"], dict):

@ -3,7 +3,7 @@ from abc import ABC, abstractmethod
from modules import util
from modules.meta import MetadataFile, OverlayFile
from modules.operations import Operations
from modules.util import Failed, ImageData
from modules.util import Failed
from ruamel import yaml
logger = util.logger
@ -22,7 +22,6 @@ class Library(ABC):
self.overlays = []
self.metadata_files = []
self.overlay_files = []
self.missing = {}
self.movie_map = {}
self.show_map = {}
self.imdb_map = {}
@ -47,7 +46,8 @@ class Library(ABC):
self.image_table_name = self.config.Cache.get_image_table_name(self.original_mapping_name) if self.config.Cache else None
self.overlay_folder = os.path.join(self.config.default_dir, "overlays")
self.overlay_backup = os.path.join(self.overlay_folder, f"{self.mapping_name} Original Posters")
self.missing_path = params["missing_path"] if params["missing_path"] else os.path.join(self.default_dir, f"{self.mapping_name}_missing.yml")
self.report_path = params["report_path"] if params["report_path"] else os.path.join(self.default_dir, f"{self.mapping_name}_report.yml")
self.report_data = {}
self.asset_folders = params["asset_folders"]
self.create_asset_folders = params["create_asset_folders"]
self.dimensional_asset_rename = params["dimensional_asset_rename"]
@ -68,7 +68,7 @@ class Library(ABC):
self.show_options = params["show_options"]
self.show_missing = params["show_missing"]
self.show_missing_assets = params["show_missing_assets"]
self.save_missing = params["save_missing"]
self.save_report = params["save_report"]
self.only_filter_missing = params["only_filter_missing"]
self.ignore_ids = params["ignore_ids"]
self.ignore_imdb_ids = params["ignore_imdb_ids"]
@ -187,6 +187,13 @@ class Library(ABC):
return poster_uploaded, background_uploaded
def get_id_from_maps(self, key):
key = str(key)
if key in self.movie_rating_key_map:
return self.movie_rating_key_map[key]
elif key in self.show_rating_key_map:
return self.show_rating_key_map[key]
@abstractmethod
def notify(self, text, collection=None, critical=True):
pass
@ -211,17 +218,48 @@ class Library(ABC):
def get_all(self, collection_level=None, load=False):
pass
def add_additions(self, collection, items, is_movie):
self._add_to_file("Added", collection, items, is_movie)
def add_missing(self, collection, items, is_movie):
if collection not in self.missing:
self.missing[collection] = {}
section = "Movies Missing (TMDb IDs)" if is_movie else "Shows Missing (TVDb IDs)"
if section not in self.missing[collection]:
self.missing[collection][section] = {}
for title, item_id in items:
self.missing[collection][section][int(item_id)] = title
with open(self.missing_path, "w"): pass
self._add_to_file("Missing", collection, items, is_movie)
def add_removed(self, collection, items, is_movie):
self._add_to_file("Removed", collection, items, is_movie)
def add_filtered(self, collection, items, is_movie):
self._add_to_file("Filtered", collection, items, is_movie)
def _add_to_file(self, file_type, collection, items, is_movie):
logger.info(items)
if collection not in self.report_data:
self.report_data[collection] = {}
parts = isinstance(items[0], str)
if parts:
other = f"Parts {file_type}"
section = other
elif is_movie:
other = f"Movies {file_type}"
section = f"{other} (TMDb IDs)"
else:
other = f"Shows {file_type}"
section = f"{other} (TVDb IDs)"
if section not in self.report_data[collection]:
self.report_data[collection][section] = [] if parts else {}
if parts:
self.report_data[collection][section].extend(items)
else:
for title, item_id in items:
if item_id:
self.report_data[collection][section][int(item_id)] = title
else:
if other not in self.report_data[collection]:
self.report_data[collection][other] = []
self.report_data[collection][other].append(title)
with open(self.report_path, "w"): pass
try:
yaml.round_trip_dump(self.missing, open(self.missing_path, "w", encoding="utf-8"))
yaml.round_trip_dump(self.report_data, open(self.report_path, "w", encoding="utf-8"))
except yaml.scanner.ScannerError as e:
logger.error(f"YAML Error: {util.tab_new_lines(e)}")

@ -187,6 +187,7 @@ def start(attrs):
logger.debug(f"--run-metadata-files (PMM_METADATA_FILES): {metadata_files}")
logger.debug(f"--ignore-schedules (PMM_IGNORE_SCHEDULES): {ignore_schedules}")
logger.debug(f"--ignore-ghost (PMM_IGNORE_GHOST): {ignore_ghost}")
logger.debug(f"--cache-libraries (PMM_CACHE_LIBRARIES): {cache_libraries}")
logger.debug(f"--delete-collections (PMM_DELETE_COLLECTIONS): {delete}")
logger.debug(f"--resume (PMM_RESUME): {resume}")
logger.debug(f"--no-countdown (PMM_NO_COUNTDOWN): {no_countdown}")
@ -244,7 +245,6 @@ def update_libraries(config):
logger.debug("")
logger.debug(f"Mapping Name: {library.original_mapping_name}")
logger.debug(f"Folder Name: {library.mapping_name}")
logger.debug(f"Missing Path: {library.missing_path}")
for ad in library.asset_directory:
logger.debug(f"Asset Directory: {ad}")
logger.debug(f"Asset Folders: {library.asset_folders}")
@ -261,7 +261,8 @@ def update_libraries(config):
logger.debug(f"Show Filtered: {library.show_filtered}")
logger.debug(f"Show Missing: {library.show_missing}")
logger.debug(f"Show Missing Assets: {library.show_missing_assets}")
logger.debug(f"Save Missing: {library.save_missing}")
logger.debug(f"Save Report: {library.save_report}")
logger.debug(f"Report Path: {library.report_path}")
logger.debug(f"Clean Bundles: {library.clean_bundles}")
logger.debug(f"Empty Trash: {library.empty_trash}")
logger.debug(f"Optimize: {library.optimize}")
@ -289,7 +290,7 @@ def update_libraries(config):
if not temp_items:
temp_items = library.cache_items()
if config.Cache and cache_libraries:
if config.Cache:
if list_key:
config.Cache.delete_list_ids(list_key)
list_key = config.Cache.update_list_cache("library", library.mapping_name, expired, 1)

Loading…
Cancel
Save