Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
feederbox826 committed Jun 12, 2024
2 parents 4c94b3a + dcd9f3a commit 376906b
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 73 deletions.
21 changes: 20 additions & 1 deletion plugins/AITagger/ai_tagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import json
import subprocess
import csv
import zipfile
import shutil
from typing import Any

# ----------------- Setup -----------------
Expand Down Expand Up @@ -156,7 +158,19 @@ async def __tag_images(images):
async with semaphore:
imagePaths = [image['files'][0]['path'] for image in images]
imageIds = [image['id'] for image in images]
#TODO

temp_files = []
for i, path in enumerate(imagePaths):
if '.zip' in path:
zip_index = path.index('.zip') + 4
zip_path, img_path = path[:zip_index], path[zip_index+1:].replace('\\', '/')
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
temp_path = os.path.join(config.temp_image_dir, img_path)
os.makedirs(os.path.dirname(temp_path), exist_ok=True)
zip_ref.extract(img_path, config.temp_image_dir)
imagePaths[i] = os.path.abspath(os.path.normpath(temp_path))
temp_files.append(imagePaths[i])

try:
server_results = ImageResult(**await process_images_async(imagePaths))
process_server_image_results(server_results, imageIds)
Expand All @@ -166,6 +180,11 @@ async def __tag_images(images):
stash.update_images({"ids": imageIds, "tag_ids": {"ids": [tagme_tag_id], "mode": "REMOVE"}})
finally:
increment_progress()
for temp_file in temp_files:
if os.path.isdir(temp_file):
shutil.rmtree(temp_file)
else:
os.remove(temp_file)



Expand Down
2 changes: 1 addition & 1 deletion plugins/AITagger/ai_tagger.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: AI Tagger
description: Tag videos and Images with Locally hosted AI using Skier's Patreon AI models
version: 1.1
version: 1.2
url: https://github.com/stashapp/CommunityScripts/tree/main/plugins/AITagger
exec:
- python
Expand Down
1 change: 1 addition & 0 deletions plugins/AITagger/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
API_BASE_URL = 'http://localhost:8000'
IMAGE_REQUEST_BATCH_SIZE = 320
CONCURRENT_TASK_LIMIT = 10
temp_image_dir = "./temp_images"

ai_base_tag_name = "AI"
tagme_tag_name = "AI_TagMe"
Expand Down
16 changes: 10 additions & 6 deletions plugins/defaultDataForPath/defaultDataForPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function ok() {
function main() {
var hookContext = input.Args.hookContext;
var type = hookContext.type;
var ID = hookContext.ID;
var ID = hookContext.id;

if (!type || !ID) {
// just return
Expand Down Expand Up @@ -183,7 +183,11 @@ function getImagePath(ID) {
"\
query findImage($id: ID) {\
findImage(id: $id) {\
path\
visual_files {\
... on ImageFile {\
path\
}\
}\
}\
}";

Expand All @@ -197,7 +201,7 @@ query findImage($id: ID) {\
return null;
}

var path = findImage.path;
var path = findImage["visual_files"][0].path;
return path;
}

Expand Down Expand Up @@ -241,7 +245,7 @@ function getTagId(tagName) {
},
};

result = gql.Do(query, variables);
var result = gql.Do(query, variables);
if (result.findTags.tags[0]) {
return result.findTags.tags[0].id;
} else {
Expand All @@ -267,7 +271,7 @@ function getPerformerId(performerName) {
},
};

result = gql.Do(query, variables);
var result = gql.Do(query, variables);
if (result.findPerformers.performers[0]) {
return result.findPerformers.performers[0].id;
} else {
Expand All @@ -293,7 +297,7 @@ function getStudioId(studioName) {
},
};

result = gql.Do(query, variables);
var result = gql.Do(query, variables);
if (result.findStudios.studios[0]) {
return result.findStudios.studios[0].id;
} else {
Expand Down
137 changes: 124 additions & 13 deletions plugins/markerTagToScene/markerTagToScene.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,139 @@ function ok() {
};
}

function main() {
var hookContext = input.Args.hookContext;
var opInput = hookContext.Input;
var primaryTagID = opInput.PrimaryTagID;
var sceneID = opInput.SceneID;
function includes(haystack, needle) {
for (var i = 0; i < haystack.length; ++i) {
if (haystack[i] == needle) return true;
}
return false;
}

function mapSceneTagsToIds(sceneTags) {
var ret = [];
for (var i = 0; i < sceneTags.length; ++i) {
ret.push(sceneTags[i].id);
}
return ret;
}

function shouldHandleAllTags() {
var query =
"query Query {\
configuration {\
plugins\
}\
}";

var result = gql.Do(query);
//log.Info("Config is " + JSON.stringify(result.configuration));
if (!result.configuration) {
throw "Unable to get library paths";
}
if (result.configuration.plugins.hasOwnProperty("markerTagToScene")) {
//log.Info("allTags is " + result.configuration.plugins.markerTagToScene.allTags);
return !!result.configuration.plugins.markerTagToScene.allTags;
} else {
//log.Info("all tags wasn't found. defaulting to false");
return false;
}
}

function processMarker(marker, shouldHandleAllTags) {
log.Debug("processMarker (allTags = " + shouldHandleAllTags + ") " + marker);
var primaryTagID = marker.primary_tag_id;
var sceneID = marker.scene_id;

var tagIDsToCheck = [];
if (primaryTagID != null) tagIDsToCheck.push(primaryTagID);

if (shouldHandleAllTags && marker.tag_ids != null)
tagIDsToCheck = tagIDsToCheck.concat(marker.tag_ids);

// we can't currently find scene markers. If it's not in the input
// then just return
if (!primaryTagID || !sceneID) {
if (tagIDsToCheck.length == 0) {
// just return
return ok();
}

// get the existing scene tags
var sceneTags = getSceneTags(sceneID);
var sceneTags = mapSceneTagsToIds(getSceneTags(sceneID));
var newTags = [];
for (var i = 0; i < tagIDsToCheck.length; ++i) {
var tag = tagIDsToCheck[i];
if (!includes(sceneTags, tag)) newTags.push(tag);
}

if (newTags.length == 0) {
// All tags were present; don't do anything
log.Debug("All tags were already present on scene " + sceneID);
return ok();
}
var tagIDs = sceneTags.concat(newTags);
setSceneTags(sceneID, tagIDs);
log.Info("adding tags " + newTags + " to scene " + sceneID);
}

// Combine all tags from scene and the new marker
var allTags = [...new Set([...sceneTags, primaryTagID, ...opInput.TagIds])];
var newTags = allTags.filter((t) => sceneTags.includes(t));
function main() {
log.Info(JSON.stringify(input));
if (input.Args.mode == "processMarkers") {
var allTags = shouldHandleAllTags();
log.Trace("Mode is processMarkers, allTags is " + allTags);
var allMarkers = getAllMarkers();
//The markers come back as {primary_tag: { id: 600 } }
//but processMarker (because of the hook) expects 'primary_tag_id', so transform it here
log.Info(
"markerTagToScene has " + allMarkers.length + " markers to process"
);
for (var i = 0; i < allMarkers.length; ++i) {
var marker = allMarkers[i];
var sceneMarker = {};
sceneMarker.id = marker.id;
sceneMarker.scene_id = marker.scene.id;
sceneMarker.primary_tag_id = marker.primary_tag.id;
var tag_ids = [];
for (var j = 0; j < marker.tags.length; ++j) {
tag_ids.push(marker.tags[j].id);
}
sceneMarker.tag_ids = tag_ids;
//log.Info(sceneMarker);
processMarker(sceneMarker, allTags);
log.Progress(i / allMarkers.length);
}
log.Progress("Finished processing markers");
} else if (input.Args.mode == "hook") {
log.Info("Mode is hook");
processMarker(input.Args.hookContext.input, shouldHandleAllTags());
} else {
log.Error("Unknown mode");
}
}

setSceneTags(sceneID, allTags);
log.Debug("added new tags " + newTags.join(", ") + " to scene " + sceneID);
function getAllMarkers() {
var query =
"\
query Query($filter: FindFilterType) {\
findSceneMarkers (filter: $filter) {\
scene_markers {\
id,\
primary_tag {\
id\
}\
tags {\
id\
}\
scene {\
id\
}\
}\
}\
}";
var variables = { filter: { per_page: -1 } };
var result = gql.Do(query, variables);
var findSceneMarkers = result.findSceneMarkers;
if (findSceneMarkers) {
return findSceneMarkers.scene_markers;
}
}

function getSceneTags(sceneID) {
Expand All @@ -46,7 +157,7 @@ query findScene($id: ID) {\
var result = gql.Do(query, variables);
var findScene = result.findScene;
if (findScene) {
return findScene.tags.map((t) => t.id);
return findScene.tags;
}

return [];
Expand Down
12 changes: 12 additions & 0 deletions plugins/markerTagToScene/markerTagToScene.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,21 @@ version: 1.0
exec:
- markerTagToScene.js
interface: js
settings:
allTags:
displayName: All Tags
description: Add all scene tags instead of just the primary scene tag.
type: BOOLEAN
hooks:
- name: Update scene with scene marker tag
description: Adds primary tag of Scene Marker to the Scene on marker create/update.
triggeredBy:
- SceneMarker.Create.Post
- SceneMarker.Update.Post
defaultArgs:
mode: hook
tasks:
- name: Process all markers
description: Add tags from all markers to scenes
defaultArgs:
mode: processMarkers
Loading

0 comments on commit 376906b

Please sign in to comment.