diff --git a/plugins/markerTagToScene/markerTagToScene.js b/plugins/markerTagToScene/markerTagToScene.js index 77ceecca..fd103a39 100644 --- a/plugins/markerTagToScene/markerTagToScene.js +++ b/plugins/markerTagToScene/markerTagToScene.js @@ -1,3 +1,6 @@ +//config +var ALL_MARKER_TAGS = false; + function ok() { return { output: "ok" @@ -5,36 +8,76 @@ function ok() { } function main() { - var hookContext = input.Args.hookContext; - var opInput = hookContext.input; - var primaryTagID = opInput.primary_tag_id; - var sceneID = opInput.scene_id; - - // we can't currently find scene markers. If it's not in the input - // then just return - if (!primaryTagID || !sceneID) { - // just return - return ok(); - } + // Check if running task, or hook triggered + if (input.args.mode === "updateAllScenes" || input.args.mode === "dryRunUpdateAllScenes") { + var isDryRun = input.args.mode === "dryRunUpdateAllScenes"; + // running task + var totalScenes; + var checkedScenes = 0; + var pageSize = 100; + var currentPage = 1; + var modifiedScenes = 0; + do { + var result = getScenesWithTagsAndMarkers(pageSize, currentPage) + totalScenes = result.count; + checkedScenes += pageSize; + currentPage++; + var scenes = result.scenes; + + for (var i = 0; i < scenes.length; i++) { + var scene = scenes[i]; + var sceneTagIDs = scene.tags.map(function (tag) { return tag.id }); + var markerTags = []; + scene.scene_markers.forEach(function (marker) { + markerTags.push(marker.primary_tag.id); + if (ALL_MARKER_TAGS) { + markerTags = markerTags.concat(marker.tags.map(function (tag) { + return tag.id + })); + } + }); + var newSceneTags = concatAndDeduplicate(sceneTagIDs, markerTags); + if (newSceneTags.length > sceneTagIDs.length) { + // This scene is going to get new tags + modifiedScenes++; + if (!isDryRun) { + setSceneTags(scene.id, newSceneTags); + } + } + } + + } while (checkedScenes < totalScenes) + + var dryRunMessage = isDryRun ? "DRY RUN: " : ""; + var allTagsMessage = ALL_MARKER_TAGS ? "all" : "the primary"; + log.Info(dryRunMessage + "Updated tags in " + modifiedScenes + " scenes to include " + allTagsMessage + " tags from their markers."); + + } else if (input.Args.hookContext) { + // hook triggered + var hookContext = input.Args.hookContext; + var opInput = hookContext.input; + var primaryMarkerTagID = opInput.primary_tag_id; + var otherMarkerTagIDs = opInput.tag_ids; + var sceneID = opInput.scene_id; - // get the existing scene tags - var sceneTags = getSceneTags(sceneID); - var tagIDs = []; - for (var i = 0; i < sceneTags.length; ++i) { - var tagID = sceneTags[i].id; - if (tagID == primaryTagID) { - log.Debug("primary tag already exists on scene"); - return; + // check if missing any of the required fields + if (!primaryMarkerTagID || !sceneID) { + // just return + return ok(); } - tagIDs.push(tagID); - } + // get the existing scene tags + var sceneTagIDs = getSceneTags(sceneID).map(function (item) { return item.id }); + var combinedTags = concatAndDeduplicate(sceneTagIDs, [primaryMarkerTagID]); + if (ALL_MARKER_TAGS && otherMarkerTagIDs) { + combinedTags = concatAndDeduplicate(combinedTags, otherMarkerTagIDs); + } - // set the tag on the scene if not present - tagIDs.push(primaryTagID); + setSceneTags(sceneID, combinedTags); - setSceneTags(sceneID, tagIDs); - log.Info("added primary tag " + primaryTagID + " to scene " + sceneID); + var allTagsMessage = ALL_MARKER_TAGS ? "all" : "primary"; + log.Info("Added " + allTagsMessage + " marker tags to scene " + sceneID); + } } function getSceneTags(sceneID) { @@ -78,4 +121,68 @@ mutation sceneUpdate($input: SceneUpdateInput!) {\ gql.Do(mutation, variables); } +function getScenesWithTagsAndMarkers(per_page, page) { + var query = "\ + query FindScenes($filter: FindFilterType, $scene_filter: SceneFilterType, $scene_ids: [Int!]) {\ + findScenes(filter: $filter, scene_filter: $scene_filter, scene_ids: $scene_ids) {\ + count\ + scenes {\ + ...MarkersAndTagSceneData\ + __typename\ + }\ + __typename\ + }\ + } fragment MarkersAndTagSceneData on Scene {\ + id\ + scene_markers {\ + id\ + primary_tag {\ + id\ + __typename\ + }\ + tags {\ + id\ + __typename\ + }\ + __typename\ + }\ + tags {\ + id\ + __typename\ + }\ + __typename\ + }"; + + + var variables = { + "filter": { + "direction": "ASC", + "page": page, + "per_page": per_page, + "q": "", + "sort": "created_at" + }, + "scene_filter": { + "has_markers": "true" + } + + } + + var result = gql.Do(query, variables); + var findScenes = result.findScenes; + if (findScenes) { + return findScenes; + } + + return {}; +} + +function concatAndDeduplicate(a, b) { + var combined = a.concat(b); + combined = combined.filter(function (item, pos, self) { + return self.indexOf(item) == pos; + }); + return combined; +} + main(); \ No newline at end of file diff --git a/plugins/markerTagToScene/markerTagToScene.yml b/plugins/markerTagToScene/markerTagToScene.yml index 2dcb10e7..6dabddcb 100644 --- a/plugins/markerTagToScene/markerTagToScene.yml +++ b/plugins/markerTagToScene/markerTagToScene.yml @@ -1,14 +1,23 @@ # example plugin config name: Scene Marker Tags to Scene -description: Adds primary tag of Scene Marker to the Scene on marker create/update. +description: Adds primary tag or all tags of Scene Marker to the Scene on marker create/update, or when task is run. url: https://github.com/stashapp/CommunityScripts -version: 1.0 +version: 1.1 exec: - markerTagToScene.js interface: js hooks: - - name: Update scene with scene marker tag - description: Adds primary tag of Scene Marker to the Scene on marker create/update. + - name: Update scene with scene marker tag(s) + description: Adds primary tag or all tags of Scene Marker to the Scene on marker create/update. triggeredBy: - SceneMarker.Create.Post - SceneMarker.Update.Post +tasks: + - name: Update Scenes Tags + description: Adds primary tag or all tags of Scene Markers to their Scenes + defaultArgs: + mode: updateAllScenes + - name: Dry Run + description: Dry run of adding tags of Scene Markers to their Scenes + defaultArgs: + mode: dryRunUpdateAllScenes