|
| 1 | +import stashapi.log as log |
| 2 | +import re |
| 3 | +from stashapi.stashapp import StashInterface |
| 4 | +import sys |
| 5 | +import json |
| 6 | +import unidecode |
| 7 | +import requests |
| 8 | + |
| 9 | + |
| 10 | +def processScene(scene): |
| 11 | + tags = [] |
| 12 | + |
| 13 | + if settings["skipUnorganized"] and not scene['organized']: # don't process scenes that aren't marked organized. |
| 14 | + log.info("Not organized, bye!") |
| 15 | + sys.exit() |
| 16 | + |
| 17 | + |
| 18 | + if settings["tagStashIDs"]: |
| 19 | + if not scene["stash_ids"]: # Tagging empty Stash ID |
| 20 | + tags.append(int(settings["tagID_emptystashid"])) |
| 21 | + |
| 22 | + for stashbox in scene["stash_ids"]: # Add all the stashbox ID tags |
| 23 | + url = stashbox['endpoint'] |
| 24 | + if (url == "https://stashdb.org/graphql"): |
| 25 | + tags.append(int(settings["tagID_stashdb"])) |
| 26 | + |
| 27 | + if (url == "https://pmvstash.org/graphql"): |
| 28 | + tags.append(int(settings["tagID_pmvstash"])) |
| 29 | + |
| 30 | + if (url == "https://theporndb.net/graphql"): |
| 31 | + tags.append(int(settings["tagID_porndb"])) |
| 32 | + |
| 33 | + if (url == "https://fansdb.cc/graphql"): |
| 34 | + tags.append(int(settings["tagID_fansdb"])) |
| 35 | + |
| 36 | + if (url == "https://javstash.org/graphql"): |
| 37 | + tags.append(int(settings["tagID_javstash"])) |
| 38 | + |
| 39 | + if (len(tags) != 0): |
| 40 | + for x in scene['tags']: |
| 41 | + if (int(x['id']) in tags): |
| 42 | + log.debug(f"We already have the tag {x['id']} from {tags}") |
| 43 | + tags.remove(int(x['id'])) |
| 44 | + |
| 45 | + if tags: # Just a double check that we still have pending tags to add |
| 46 | + log.info(f"Adding the stashbox tags {tags} to scene {scene['title']}") |
| 47 | + stash.update_scenes({"ids": scene["id"], "tag_ids": {"mode": "ADD", "ids": tags}}) |
| 48 | + |
| 49 | + |
| 50 | + if settings["cleanTitles"]: |
| 51 | + if scene['title']: # Lots of title fixing. It's messy, but works good to remove weird characters and other improvements. |
| 52 | + new_title = unidecode.unidecode(scene['title'], errors='ignore') # NB!!: Cyrillic and such gets changed to "normal" characters. |
| 53 | + new_title = re.sub('^( | |@|\')+', "", new_title) |
| 54 | + new_title = re.sub(' +$', "", new_title) |
| 55 | + new_title = re.sub('^!+', "", new_title) |
| 56 | + new_title = re.sub("^\\?+", "", new_title) |
| 57 | + new_title = re.sub("^\\*+", "", new_title) |
| 58 | + new_title = re.sub('^The ("|\')', 'The ', new_title) |
| 59 | + new_title = re.sub('^A ("|\')', 'A ', new_title) |
| 60 | + new_title = re.sub(' (Wmv|Mp4|Mov|Qt|HD)$', '', new_title) |
| 61 | + new_title = re.sub('^[^A-Za-z0-9]', '', new_title) |
| 62 | + new_title = re.sub('^( )', '', new_title) |
| 63 | + if not (new_title == scene['title']): |
| 64 | + log.info(f"New title: {new_title} from {scene['title']}") |
| 65 | + if (new_title == ""): |
| 66 | + new_title = "ZZZ Invalid Title" |
| 67 | + stash.update_scenes({"ids": scene["id"], "title": new_title}) |
| 68 | + |
| 69 | + |
| 70 | + if scene["urls"]: # If scene contains Plex URL, refresh Plex metadata |
| 71 | + for urls in reversed(scene["urls"]): # todo: remove reversed(); this was a quickfix for when a scene somehow got two plex urls - the most recent url is most likely the most "valid" |
| 72 | + if ("/library/metadata/" in urls): |
| 73 | + plexurl = urls.replace("plex", "https://" + settings["plexHost"] + ":" + settings["plexPort"]) |
| 74 | + plexurl += "/refresh?X-Plex-Token=" + settings["plexToken"] |
| 75 | + log.info(f"Refreshing scene on Plex via {plexurl}") |
| 76 | + try: |
| 77 | + requests.packages.urllib3.disable_warnings() # TLS errors are irrelevant when I'm on localhost... |
| 78 | + r = requests.put(plexurl, verify=False) |
| 79 | + r.raise_for_status() |
| 80 | + except requests.exceptions.HTTPError as e: |
| 81 | + log.error(f"Plex API failed: {e.response.text}") |
| 82 | + |
| 83 | + return |
| 84 | + |
| 85 | + |
| 86 | +json_input = json.loads(sys.stdin.read()) |
| 87 | +FRAGMENT_SERVER = json_input["server_connection"] |
| 88 | +stash = StashInterface(FRAGMENT_SERVER) |
| 89 | + |
| 90 | +config = stash.get_configuration() |
| 91 | +settings = { |
| 92 | + "plexToken": "YOUR_PLEX_TOKEN_HERE", |
| 93 | + "plexHost": "localhost", |
| 94 | + "plexPort": "32400", |
| 95 | + "tagStashIDs": False, |
| 96 | + "skipUnorganized": True, |
| 97 | + "cleanTitles": True, |
| 98 | + "tagID_emptystashid": "1", |
| 99 | + "tagID_stashdb": "2", |
| 100 | + "tagID_pmvstash": "3", |
| 101 | + "tagID_porndb": "4", |
| 102 | + "tagID_fansdb": "5", |
| 103 | + "tagID_javstash": "6" |
| 104 | +} |
| 105 | +if "PlexSync" in config["plugins"]: |
| 106 | + settings.update(config["plugins"]["PlexSync"]) |
| 107 | + |
| 108 | +if "hookContext" in json_input["args"]: |
| 109 | + id = json_input["args"]["hookContext"]["id"] |
| 110 | + if ( |
| 111 | + json_input["args"]["hookContext"]["type"] == "Scene.Update.Post" |
| 112 | + or "Scene.Create.Post" |
| 113 | + ): |
| 114 | + #log.info(f"We run with {json_input}") # Uncomment for debugging what's sent to Stash |
| 115 | + exit = False |
| 116 | + request_tags = [] |
| 117 | + stashbox_tags = [] |
| 118 | + stashbox_tags.append(frozenset( |
| 119 | + { |
| 120 | + int(settings["tagID_emptystashid"]), |
| 121 | + int(settings["tagID_stashdb"]), |
| 122 | + int(settings["tagID_pmvstash"]), |
| 123 | + int(settings["tagID_porndb"]), |
| 124 | + int(settings["tagID_fansdb"]), |
| 125 | + int(settings["tagID_javstash"]) |
| 126 | + })) |
| 127 | + |
| 128 | + if "inputFields" in json_input["args"]["hookContext"]: |
| 129 | + if "tag_ids" in json_input["args"]["hookContext"]["inputFields"]: |
| 130 | + request_tags = json_input["args"]["hookContext"]["input"]["tag_ids"] |
| 131 | + if set(request_tags) & set(stashbox_tags): # prevent rerunning tag addition, when the update is simply adding the tags |
| 132 | + log.info("Already have correct tags.") |
| 133 | + exit = True |
| 134 | + else: |
| 135 | + exit = False |
| 136 | + |
| 137 | + if "urls" in json_input["args"]["hookContext"]["inputFields"]: |
| 138 | + if len(json_input["args"]["hookContext"]["inputFields"]) == 2: # Hacky fix; Plex agent sends only two fields, so in this case we won't update metadata there again. Stash UI etc usually sends all fields in update, so no worries. |
| 139 | + log.info("Got new Plex URL, will not refresh.") |
| 140 | + exit = True |
| 141 | + else: |
| 142 | + exit = False |
| 143 | + |
| 144 | + if exit == True: |
| 145 | + log.info("Nothing to do, exiting.") |
| 146 | + sys.exit() |
| 147 | + |
| 148 | + scene = stash.find_scene(id) |
| 149 | + processScene(scene) |
0 commit comments