mirror of
https://github.com/meisnate12/Plex-Meta-Manager
synced 2024-11-10 06:54:21 +00:00
[3] Added the mass_added_at_update
operation
This commit is contained in:
parent
2aac1cd1ae
commit
188063cb19
7 changed files with 138 additions and 71 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
# New Features
|
||||
Checks requirement versions to print a message if one needs to be updated
|
||||
Added the `mass_added_at_update` operation to mass set the Added At field of Movies and Shows.
|
||||
|
||||
# Updates
|
||||
Changed the `overlay_artwork_filetype` Setting to accept `webp_lossy` and `webp_lossless` while the old attribute `webp` will be treated as `webp_lossy`.
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.0.1-develop2
|
||||
2.0.1-develop3
|
||||
|
|
|
@ -302,6 +302,45 @@ You can create individual blocks of operations by using a list under `operations
|
|||
- 1900-01-01
|
||||
```
|
||||
|
||||
###### Mass Added At Update
|
||||
|
||||
??? blank "`mass_added_at_update` - Updates the added at date of every item in the library.<a class="headerlink" href="#mass-added-at-update" title="Permanent link">¶</a>"
|
||||
|
||||
<div id="mass-added-at-update" />Updates every item's added at date in the library to the chosen site's date.
|
||||
|
||||
<hr style="margin: 0px;">
|
||||
|
||||
**Attribute:** `mass_added_at_update`
|
||||
|
||||
**Accepted Values:** Source or List of sources to use in that order
|
||||
|
||||
<table class="clearTable">
|
||||
<tr><td>`tmdb`</td><td>Use TMDb Release Date</td></tr>
|
||||
<tr><td>`tvdb`</td><td>Use TVDb Release Date</td></tr>
|
||||
<tr><td>`omdb`</td><td>Use IMDb Release Date through OMDb</td></tr>
|
||||
<tr><td>`mdb`</td><td>Use MDBList Release Date</td></tr>
|
||||
<tr><td>`mdb_digital`</td><td>Use MDBList Digital Release Date</td></tr>
|
||||
<tr><td>`anidb`</td><td>Use AniDB Release Date</td></tr>
|
||||
<tr><td>`mal`</td><td>Use MyAnimeList Release Date</td></tr>
|
||||
<tr><td>`lock`</td><td>Lock Added At Field</td></tr>
|
||||
<tr><td>`unlock`</td><td>Unlock Added At Field</td></tr>
|
||||
<tr><td>`remove`</td><td>Remove Added At and Lock Field</td></tr>
|
||||
<tr><td>`reset`</td><td>Remove Added At and Unlock Field</td></tr>
|
||||
<tr><td colspan="2">Any String in the Format: YYYY-MM-DD for Added At (<code>2022-05-28</code>)</td></tr>
|
||||
</table>
|
||||
|
||||
???+ example "Example"
|
||||
|
||||
```yaml
|
||||
libraries:
|
||||
TV Shows:
|
||||
operations:
|
||||
mass_added_at_update:
|
||||
- mdb_digital
|
||||
- mdb
|
||||
- 1900-01-01
|
||||
```
|
||||
|
||||
###### Mass Rating Update
|
||||
|
||||
??? blank "`mass_***_rating_update` - Updates the audience/critic/user rating of every item in the library.<a class="headerlink" href="#mass-star-rating-update" title="Permanent link">¶</a>"
|
||||
|
|
|
@ -1429,6 +1429,10 @@
|
|||
"type": "string",
|
||||
"enum": ["tmdb","tvdb","omdb","mdb","anidb","mal","lock","unlock","remove","reset"]
|
||||
},
|
||||
"mass_added_at_update": {
|
||||
"type": "string",
|
||||
"enum": ["tmdb","tvdb","omdb","mdb","anidb","mal","lock","unlock","remove","reset"]
|
||||
},
|
||||
"mass_audience_rating_update": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
|
|
@ -135,8 +135,8 @@ library_operations = {
|
|||
"mass_audience_rating_update": mass_rating_options, "mass_episode_audience_rating_update": mass_episode_rating_options,
|
||||
"mass_critic_rating_update": mass_rating_options, "mass_episode_critic_rating_update": mass_episode_rating_options,
|
||||
"mass_user_rating_update": mass_rating_options, "mass_episode_user_rating_update": mass_episode_rating_options,
|
||||
"mass_original_title_update": mass_original_title_options, "mass_originally_available_update": mass_available_options,
|
||||
"mass_imdb_parental_labels": imdb_label_options,
|
||||
"mass_original_title_update": mass_original_title_options, "mass_imdb_parental_labels": imdb_label_options,
|
||||
"mass_originally_available_update": mass_available_options, "mass_added_at_update": mass_available_options,
|
||||
"mass_collection_mode": "mass_collection_mode", "mass_poster_update": "dict", "mass_background_update": "dict",
|
||||
"metadata_backup": "dict", "delete_collections": "dict", "genre_mapper": "dict", "content_rating_mapper": "dict",
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ class ConfigFile:
|
|||
final_list.append(str(list_attr))
|
||||
elif op == "mass_genre_update":
|
||||
final_list.append(list_attr if isinstance(list_attr, list) else [list_attr])
|
||||
elif op == "mass_originally_available_update":
|
||||
elif op in ["mass_originally_available_update", "mass_added_at_update"]:
|
||||
final_list.append(util.validate_date(list_attr))
|
||||
elif op.endswith("rating_update"):
|
||||
final_list.append(util.check_int(list_attr, datatype="float", minimum=0, maximum=10, throw=True))
|
||||
|
|
|
@ -97,6 +97,7 @@ class Library(ABC):
|
|||
self.mass_content_rating_update = params["mass_content_rating_update"]
|
||||
self.mass_original_title_update = params["mass_original_title_update"]
|
||||
self.mass_originally_available_update = params["mass_originally_available_update"]
|
||||
self.mass_added_at_update = params["mass_added_at_update"]
|
||||
self.mass_imdb_parental_labels = params["mass_imdb_parental_labels"]
|
||||
self.mass_poster_update = params["mass_poster_update"]
|
||||
self.mass_background_update = params["mass_background_update"]
|
||||
|
@ -124,7 +125,7 @@ class Library(ABC):
|
|||
self.items_library_operation = True if self.assets_for_all or self.mass_genre_update or self.remove_title_parentheses \
|
||||
or self.mass_audience_rating_update or self.mass_critic_rating_update or self.mass_user_rating_update \
|
||||
or self.mass_episode_audience_rating_update or self.mass_episode_critic_rating_update or self.mass_episode_user_rating_update \
|
||||
or self.mass_content_rating_update or self.mass_originally_available_update or self.mass_original_title_update\
|
||||
or self.mass_content_rating_update or self.mass_originally_available_update or self.mass_added_at_update or self.mass_original_title_update\
|
||||
or self.mass_imdb_parental_labels or self.genre_mapper or self.content_rating_mapper or self.mass_studio_update\
|
||||
or self.radarr_add_all_existing or self.sonarr_add_all_existing or self.mass_poster_update or self.mass_background_update else False
|
||||
self.library_operation = True if self.items_library_operation or self.delete_collections or self.mass_collection_mode \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import os, re
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from modules import plex, util, anidb
|
||||
from modules.util import Failed, LimitReached, YAML
|
||||
from plexapi.exceptions import NotFound
|
||||
|
@ -10,14 +10,15 @@ logger = util.logger
|
|||
meta_operations = [
|
||||
"mass_audience_rating_update", "mass_user_rating_update", "mass_critic_rating_update",
|
||||
"mass_episode_audience_rating_update", "mass_episode_user_rating_update", "mass_episode_critic_rating_update",
|
||||
"mass_genre_update", "mass_content_rating_update", "mass_originally_available_update", "mass_original_title_update",
|
||||
"mass_poster_update", "mass_background_update", "mass_studio_update"
|
||||
"mass_genre_update", "mass_content_rating_update", "mass_originally_available_update", "mass_added_at_update",
|
||||
"mass_original_title_update", "mass_poster_update", "mass_background_update", "mass_studio_update"
|
||||
]
|
||||
name_display = {
|
||||
"audienceRating": "Audience Rating",
|
||||
"rating": "Critic Rating",
|
||||
"userRating": "User Rating",
|
||||
"originallyAvailableAt": "Originally Available Date",
|
||||
"addedAt": "Added At Date",
|
||||
"contentRating": "Content Rating"
|
||||
}
|
||||
|
||||
|
@ -45,6 +46,7 @@ class Operations:
|
|||
logger.debug(f"Mass Content Rating Update: {self.library.mass_content_rating_update}")
|
||||
logger.debug(f"Mass Original Title Update: {self.library.mass_original_title_update}")
|
||||
logger.debug(f"Mass Originally Available Update: {self.library.mass_originally_available_update}")
|
||||
logger.debug(f"Mass Added At Update: {self.library.mass_added_at_update}")
|
||||
logger.debug(f"Mass IMDb Parental Labels: {self.library.mass_imdb_parental_labels}")
|
||||
logger.debug(f"Mass Poster Update: {self.library.mass_poster_update}")
|
||||
logger.debug(f"Mass Background Update: {self.library.mass_background_update}")
|
||||
|
@ -88,7 +90,7 @@ class Operations:
|
|||
genre_edits = {"add": {}, "remove": {}}
|
||||
content_edits = {}
|
||||
studio_edits = {}
|
||||
available_edits = {}
|
||||
date_edits = {"originallyAvailableAt": {}, "addedAt": {}}
|
||||
remove_edits = {}
|
||||
reset_edits = {}
|
||||
lock_edits = {}
|
||||
|
@ -664,65 +666,69 @@ class Operations:
|
|||
except Failed:
|
||||
continue
|
||||
|
||||
if self.library.mass_originally_available_update:
|
||||
current_available = item.originallyAvailableAt
|
||||
if current_available:
|
||||
current_available = current_available.strftime("%Y-%m-%d")
|
||||
for option in self.library.mass_originally_available_update:
|
||||
if option in ["lock", "remove"]:
|
||||
if option == "remove" and current_available:
|
||||
if "originallyAvailableAt" not in remove_edits:
|
||||
remove_edits["originallyAvailableAt"] = []
|
||||
remove_edits["originallyAvailableAt"].append(item.ratingKey)
|
||||
item_edits += "\nRemove Originally Available Date (Batched)"
|
||||
elif "originallyAvailableAt" not in locked_fields:
|
||||
if "originallyAvailableAt" not in lock_edits:
|
||||
lock_edits["originallyAvailableAt"] = []
|
||||
lock_edits["originallyAvailableAt"].append(item.ratingKey)
|
||||
item_edits += "\nLock Originally Available Date (Batched)"
|
||||
break
|
||||
elif option in ["unlock", "reset"]:
|
||||
if option == "reset" and current_available:
|
||||
if "originallyAvailableAt" not in reset_edits:
|
||||
reset_edits["originallyAvailableAt"] = []
|
||||
reset_edits["originallyAvailableAt"].append(item.ratingKey)
|
||||
item_edits += "\nReset Originally Available Date (Batched)"
|
||||
elif "originallyAvailableAt" in locked_fields:
|
||||
if "originallyAvailableAt" not in unlock_edits:
|
||||
unlock_edits["originallyAvailableAt"] = []
|
||||
unlock_edits["originallyAvailableAt"].append(item.ratingKey)
|
||||
item_edits += "\nUnlock Originally Available Date (Batched)"
|
||||
break
|
||||
else:
|
||||
try:
|
||||
if option == "tmdb":
|
||||
new_available = tmdb_obj().release_date if self.library.is_movie else tmdb_obj().first_air_date # noqa
|
||||
elif option == "omdb":
|
||||
new_available = omdb_obj().released # noqa
|
||||
elif option == "tvdb":
|
||||
new_available = tvdb_obj().release_date # noqa
|
||||
elif option == "mdb":
|
||||
new_available = mdb_obj().released # noqa
|
||||
elif option == "mdb_digital":
|
||||
new_available = mdb_obj().released_digital # noqa
|
||||
elif option == "anidb":
|
||||
new_available = anidb_obj().released # noqa
|
||||
elif option == "mal":
|
||||
new_available = mal_obj().aired # noqa
|
||||
else:
|
||||
new_available = option
|
||||
if not new_available:
|
||||
logger.info(f"No {option} Originally Available Date Found")
|
||||
raise Failed
|
||||
new_available = new_available.strftime("%Y-%m-%d")
|
||||
if current_available != new_available:
|
||||
if new_available not in available_edits:
|
||||
available_edits[new_available] = []
|
||||
available_edits[new_available].append(item.ratingKey)
|
||||
item_edits += f"\nUpdate Originally Available Date (Batched) | {new_available}"
|
||||
for attribute, item_attr in [
|
||||
(self.library.mass_originally_available_update, "originallyAvailableAt"),
|
||||
(self.library.mass_added_at_update, "addedAt")
|
||||
]:
|
||||
if attribute:
|
||||
current = getattr(item, item_attr)
|
||||
if current:
|
||||
current = current.strftime("%Y-%m-%d")
|
||||
for option in attribute:
|
||||
if option in ["lock", "remove"]:
|
||||
if option == "remove" and current:
|
||||
if item_attr not in remove_edits:
|
||||
remove_edits[item_attr] = []
|
||||
remove_edits[item_attr].append(item.ratingKey)
|
||||
item_edits += f"\nRemove {name_display[item_attr]} (Batched)"
|
||||
elif item_attr not in locked_fields:
|
||||
if item_attr not in lock_edits:
|
||||
lock_edits[item_attr] = []
|
||||
lock_edits[item_attr].append(item.ratingKey)
|
||||
item_edits += f"\nLock {name_display[item_attr]} (Batched)"
|
||||
break
|
||||
except Failed:
|
||||
continue
|
||||
elif option in ["unlock", "reset"]:
|
||||
if option == "reset" and current:
|
||||
if item_attr not in reset_edits:
|
||||
reset_edits[item_attr] = []
|
||||
reset_edits[item_attr].append(item.ratingKey)
|
||||
item_edits += f"\nReset {name_display[item_attr]} (Batched)"
|
||||
elif item_attr in locked_fields:
|
||||
if item_attr not in unlock_edits:
|
||||
unlock_edits[item_attr] = []
|
||||
unlock_edits[item_attr].append(item.ratingKey)
|
||||
item_edits += f"\nUnlock {name_display[item_attr]} (Batched)"
|
||||
break
|
||||
else:
|
||||
try:
|
||||
if option == "tmdb":
|
||||
new_date = tmdb_obj().release_date if self.library.is_movie else tmdb_obj().first_air_date # noqa
|
||||
elif option == "omdb":
|
||||
new_date = omdb_obj().released # noqa
|
||||
elif option == "tvdb":
|
||||
new_date = tvdb_obj().release_date # noqa
|
||||
elif option == "mdb":
|
||||
new_date = mdb_obj().released # noqa
|
||||
elif option == "mdb_digital":
|
||||
new_date = mdb_obj().released_digital # noqa
|
||||
elif option == "anidb":
|
||||
new_date = anidb_obj().released # noqa
|
||||
elif option == "mal":
|
||||
new_date = mal_obj().aired # noqa
|
||||
else:
|
||||
new_date = option
|
||||
if not new_date:
|
||||
logger.info(f"No {option} {name_display[item_attr]} Found")
|
||||
raise Failed
|
||||
new_date = new_date.strftime("%Y-%m-%d")
|
||||
if current != new_date:
|
||||
if new_date not in date_edits[item_attr]:
|
||||
date_edits[item_attr][new_date] = []
|
||||
date_edits[item_attr][new_date].append(item.ratingKey)
|
||||
item_edits += f"\nUpdate {name_display[item_attr]} (Batched) | {new_date}"
|
||||
break
|
||||
except Failed:
|
||||
continue
|
||||
|
||||
if len(item_edits) > 0:
|
||||
logger.info(f"Item Edits{item_edits}")
|
||||
|
@ -920,11 +926,27 @@ class Operations:
|
|||
self.library.Plex.editStudio(new_studio)
|
||||
self.library.Plex.saveMultiEdits()
|
||||
|
||||
_size = len(available_edits.items())
|
||||
for i, (new_available, rating_keys) in enumerate(sorted(available_edits.items()), 1):
|
||||
logger.info(get_batch_info(i, _size, "originallyAvailableAt", len(rating_keys), display_value=new_available))
|
||||
_size = len(date_edits["originallyAvailableAt"].items())
|
||||
for i, (new_date, rating_keys) in enumerate(sorted(date_edits["originallyAvailableAt"].items()), 1):
|
||||
logger.info(get_batch_info(i, _size, "originallyAvailableAt", len(rating_keys), display_value=new_date))
|
||||
self.library.Plex.batchMultiEdits(self.library.load_list_from_cache(rating_keys))
|
||||
self.library.Plex.editOriginallyAvailable(new_available)
|
||||
self.library.Plex.editOriginallyAvailable(new_date)
|
||||
self.library.Plex.saveMultiEdits()
|
||||
|
||||
epoch = datetime(1970, 1, 1)
|
||||
_size = len(date_edits["addedAt"].items())
|
||||
for i, (new_date, rating_keys) in enumerate(sorted(date_edits["addedAt"].items()), 1):
|
||||
logger.info(get_batch_info(i, _size, "addedAt", len(rating_keys), display_value=new_date))
|
||||
self.library.Plex.batchMultiEdits(self.library.load_list_from_cache(rating_keys))
|
||||
new_date = datetime.strptime(new_date, "%Y-%m-%d")
|
||||
logger.trace(new_date)
|
||||
try:
|
||||
ts = int(round(new_date.timestamp()))
|
||||
except (TypeError, OSError):
|
||||
offset = int(datetime(2000, 1, 1, tzinfo=timezone.utc).timestamp() - datetime(2000, 1, 1).timestamp())
|
||||
ts = int((new_date - epoch).total_seconds()) - offset
|
||||
logger.trace(epoch + timedelta(seconds=ts))
|
||||
self.library.Plex.editAddedAt(ts)
|
||||
self.library.Plex.saveMultiEdits()
|
||||
|
||||
_size = len(remove_edits.items())
|
||||
|
|
Loading…
Reference in a new issue