diff --git a/VERSION b/VERSION
index 28ce0e1f..8f0335f0 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.18.0-develop69
+1.18.0-develop70
diff --git a/docs/metadata/details/definition.md b/docs/metadata/details/definition.md
index 90679439..f2563091 100644
--- a/docs/metadata/details/definition.md
+++ b/docs/metadata/details/definition.md
@@ -32,4 +32,5 @@ All the following attributes serve various functions as how the definition funct
| `sync_missing_to_trakt_list` | **Description:** Used to also sync missing items to the Trakt List specified by `sync_to_trakt_list`.
**Default:** `false`
**Values:** `true` or `false` |
| `allowed_library_types` | **Description:** Used to specify the types of libraries that this definition can work with.
Multiple can be used for one definition as a list or comma separated string. One `false` will cause it to fail.
**Values:** `movie`, `show`, `artist`, `true`, `false` |
| `default_percent` | **Description:** Used to declare the default percent for `episodes`, `seasons`, `tracks`, and `albums` [special filters](../filters.md#special-filters). Default is 50.
**Values:** Integer between 1 and 100 |
-| `ignore_blank_results` | **Description:** Used to not have Errors resulting from blank results from builders
**Default:** `false`
**Values:** `true` or `false` |
+| `ignore_blank_results` | **Description:** Used to not have Errors resulting from blank results from builders.
**Default:** `false`
**Values:** `true` or `false` |
+| `only_run_on_create` | **Description:** Used to only run the collection definition if the collection doesn't already exist.
**Default:** `false`
**Values:** `true` or `false` |
\ No newline at end of file
diff --git a/modules/builder.py b/modules/builder.py
index f39e1841..2ae18953 100644
--- a/modules/builder.py
+++ b/modules/builder.py
@@ -42,7 +42,7 @@ ignored_details = [
"smart_filter", "smart_label", "smart_url", "run_again", "schedule", "sync_mode", "template", "variables", "test", "suppress_overlays",
"delete_not_scheduled", "tmdb_person", "build_collection", "collection_order", "builder_level", "overlay",
"validate_builders", "libraries", "sync_to_users", "collection_name", "playlist_name", "name", "blank_collection",
- "allowed_library_types", "delete_playlist", "ignore_blank_results"
+ "allowed_library_types", "delete_playlist", "ignore_blank_results", "only_run_on_create"
]
details = [
"ignore_ids", "ignore_imdb_ids", "server_preroll", "changes_webhooks", "collection_filtering", "collection_mode", "limit", "url_theme",
@@ -242,11 +242,25 @@ class CollectionBuilder:
else:
self.name = self.mapping_name
+ try:
+ self.obj = self.library.get_playlist(self.name) if self.playlist else self.library.get_collection(self.name, force_search=True)
+ except Failed:
+ self.obj = None
+
+ self.only_run_on_create = False
+ if "only_run_on_create" in methods and not self.playlist:
+ logger.debug("")
+ logger.debug("Validating Method: only_run_on_create")
+ logger.debug(f"Value: {data[methods['only_run_on_create']]}")
+ self.only_run_on_create = util.parse(self.Type, "only_run_on_create", self.data, datatype="bool", methods=methods, default=False)
+ if self.obj and self.only_run_on_create:
+ raise NotScheduled("Skipped because only_run_on_create is True and the collection already exists")
+
if "allowed_library_types" in methods and not self.playlist:
logger.debug("")
logger.debug("Validating Method: allowed_library_types")
if self.data[methods["allowed_library_types"]] is None:
- raise NotScheduled(f"Skipped because allowed_library_types has no library types")
+ raise NotScheduled("Skipped because allowed_library_types has no library types")
logger.debug(f"Value: {self.data[methods['allowed_library_types']]}")
found_type = False
for library_type in util.get_list(self.data[methods["allowed_library_types"]], lower=True):
@@ -430,7 +444,7 @@ class CollectionBuilder:
logger.debug("")
logger.debug("Validating Method: ignore_blank_results")
logger.debug(f"Value: {data[methods['ignore_blank_results']]}")
- self.ignore_blank_results = util.parse(self.Type, "ignore_blank_results", self.data, datatype="bool", methods=methods, default=True)
+ self.ignore_blank_results = util.parse(self.Type, "ignore_blank_results", self.data, datatype="bool", methods=methods, default=False)
self.smart_filter_details = ""
self.smart_label_url = None
@@ -812,17 +826,11 @@ class CollectionBuilder:
or (self.library.Radarr and self.radarr_details["add_missing"])
or (self.library.Sonarr and self.sonarr_details["add_missing"]))
if self.build_collection:
- try:
- self.obj = self.library.get_playlist(self.name) if self.playlist else self.library.get_collection(self.name, force_search=True)
- except Failed:
+ if self.obj and ((self.smart and not self.obj.smart) or (not self.smart and self.obj.smart)):
+ logger.info("")
+ logger.error(f"{self.Type} Error: Converting {self.obj.title} to a {'smart' if self.smart else 'normal'} collection")
+ self.library.delete(self.obj)
self.obj = None
- else:
- if (self.smart and not self.obj.smart) or (not self.smart and self.obj.smart):
- logger.info("")
- logger.error(f"{self.Type} Error: Converting {self.obj.title} to a {'smart' if self.smart else 'normal'} collection")
- self.library.delete(self.obj)
- self.obj = None
-
if self.smart:
check_url = self.smart_url if self.smart_url else self.smart_label_url
if self.obj and check_url != self.library.smart_filter(self.obj):