I'm getting time="2023-01-08 20:51:59" level=error msg="[Plugin / Upscale Performer image] Traceback (most recent call last):"
time="2023-01-08 20:51:59" level=error msg="[Plugin / Upscale Performer image]   File \"B:\\Stash\\plugins\\Performer_Image_Gigapixel\\upscale.py\", line 379, in <module>"
time="2023-01-08 20:51:59" level=error msg="[Plugin / Upscale Performer image]     client.upscale_PerformerImage()"
time="2023-01-08 20:51:59" level=error msg="[Plugin / Upscale Performer image] TypeError: upscale_with.upscale_PerformerImage() missing 1 required positional argument: 'performer_id'"
 here is my code import config_manager
import configparser
import requests
import sys
import json
import pathlib
import os
import shutil
import psutil
from gigapixel import Gigapixel, Scale, Mode
from pathlib import Path, WindowsPath
from PIL import Image


# Gigapixel needs to save the images to the filesystem, for the GraphQL image update mutation the image needs to be served from a URL, for this to work you need to setup custom mapped folders in Stash (https://github.com/stashapp/stash/pull/620). Below you need to specify both the location to save the images and also the custom Stash mapping for that folder.

# Path to Stash custom Served Folder from root Stash folder, eg. if C:\Stash\static, just enter static
mapped_path = "B:\Stash\custom\static"

# Url to mapped path
mapped_url = "http://localhost:9999/custom"

# Topaz Gigapixel Settings
exe_path = Path('B:\Program Files\Topaz Labs LLC\Topaz Gigapixel AI\Topaz Gigapixel AI.exe')

# Output file suffix. (e.g. pic.jpg -> pic-gigapixel.jpg)
# You should set same value inside Gigapixel (File -> Preferences -> Default filename suffix).
output_suffix = '-gigapixel'

# Global Gigapixel variables
scale_setting = []
mode_setting = []

# Gigapixel tag names
tag_names = ['Upscale Standard:0.5x','Upscale Standard:2x','Upscale Standard:4x','Upscale Standard:6x','Upscale Lines:0.5x','Upscale Lines:2x','Upscale Lines:4x','Upscale Lines:6x','Upscale Art & CG:0.5x','Upscale Art & CG:2x','Upscale Art & CG:4x','Upscale Art & CG:6x','Upscale Low Resolution:0.5x','Upscale Low Resolution:2x','Upscale Low Resolution:4x','Upscale Low Resolution:6x','Upscale Very Compressed:0.5x','Upscale Very Compressed:2x','Upscale Very Compressed:4x','Upscale Very Compressed:6x']
    
configpath = os.path.join(pathlib.Path(__file__).parent.resolve(), 'config.ini')

def get_config_value(config_file, section, option):
    config = configparser.ConfigParser()
    config.read(config_file)
    return config.get(section, option)

    
class upscale_with:

    def __init__(self, url):
        self.url = url
        self.api_key = get_config_value(configpath, 'STASH', 'api_key')
        stash_url = get_config_value(configpath, 'STASH', 'url')
        if not stash_url:
            self.error("You need to set the URL in 'config.ini'")
            return None
        self.stash_url = stash_url + "/graphql"
        self.headers = {
            "Accept-Encoding": "gzip, deflate, br",
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Connection": "keep-alive",
            "DNT": "1",
            "ApiKey": self.api_key
        }
    
    def log(self, level, message):
        print(f"[{level.upper()}] {message}")
        
    def __prefix(self,levelChar):
        startLevelChar = b'\x01'
        endLevelChar = b'\x02'

        ret = startLevelChar + levelChar + endLevelChar
        return ret.decode()

    def __log(self,levelChar, s):
        if levelChar == "":
            return

        print(self.__prefix(levelChar) + s + "\n", file=sys.stderr, flush=True)

    def trace(self,s):
        self.__log(b't', s)

    def debug(self,s):
        self.__log(b'd', s)

    def info(self,s):
        self.__log(b'i', s)

    def warning(self,s):
        self.__log(b'w', s)

    def error(self,s):
        self.__log(b'e', s)

    def progress(self,p):
        progress = min(max(0, p), 1)
        self.__log(b'p', str(progress))

    def __callGraphQL(self, query, variables=None):
        json = {}
        json['query'] = query
        if variables != None:
            json['variables'] = variables

        # handle cookies
        response = requests.post(self.url, json=json, headers=self.headers)

        if response.status_code == 200:
            result = response.json()
            if result.get("error", None):
                for error in result["error"]["errors"]:
                    raise Exception("GraphQL error: {}".format(error))
            if result.get("data", None):
                return result.get("data")
        else:
            raise Exception(
                "GraphQL query failed:{} - {}. Query: {}. Variables: {}".format(response.status_code, response.content, query, variables))
    
    
    def listTags(self):
            query = """
    query {
      allTags {
        id
        name
      }
    }"""

            result = self.__callGraphQL(query)
            return result["allTags"]
    

    def findTagIdWithName(self, tag_names):
        query = """
            query {
                allTags {
                    id
                    name
                }
            }
        """
        result = self.__callGraphQL(query)
        for tag in result["allTags"]:
            if tag["name"] in tag_names:
                return tag["id"]
        return None
        

    def createTagWithName(self, name):
        query = """
mutation tagCreate($input:TagCreateInput!) {
  tagCreate(input: $input){
    id       
  }
}
"""
        variables = {'input': {
            'name': name
        }}

        result = self.__callGraphQL(query, variables)
        return result["tagCreate"]["id"]


    def removeTagWithID(self, id):
        query = """
mutation tagDestroy($input: TagDestroyInput!) {
  tagDestroy(input: $input)
}
"""
        variables = {'input': {
            'id': id
        }}
        self.__callGraphQL(query, variables)

       
    def findPerformersByTag(self, id):
        query = """query performer_images($performer_filter: PerformerFilterType!) {
  findPerformers(performer_filter: $performer_filter filter: {per_page: -1}){

  performers{
    id
    name
    image_path
    tags{
      name
    }
  }
}
}"""
        variables = {'performer_filter': {
            'tags': {
            'value': id, 'modifier': 'INCLUDES', 'depth':1
            
            }
        }}
        result = self.__callGraphQL(query, variables)
        performers = result["findPerformers"]["performers"]
        image_paths_tags = [(performer["image_path"], performer["id"]) for performer in performers]
        return image_paths_tags  
        
        
    def processPerformerImage(self, image_path, performer_id, scale, mode):
        # code to process image using the gigapixel library
        # using the scale and mode values passed as arguments
        scale = Scale.__getattr__(scale_setting)
        mode = Mode.__getattr__(mode_setting)

        # Check if Gigapixel is open, if yes close items
        for process in psutil.process_iter():
            try:
                if process.exe() == exe_path:
                    # The process was found
                    process_id = process.pid
                    break
            except psutil.AccessDenied:
                # The process cannot be accessed, so skip it
                pass
        
        # Create Gigapixel instance.
        app = Gigapixel(exe_path, output_suffix)

        # Set current directory
        current_dir = Path().resolve()

        # Variable for saved image
        image_name = "image_to_process.jpg"
        image_saved = current_dir / image_name

        # Download image data from the image URL
        r = requests.get(image_path, stream = True)
        r.raw.decode_content = True
        with open(image_saved, 'wb') as f:
                shutil.copyfileobj(r.raw, f)
                    
        # Process the image
        output_path = app.process(image_saved, scale=scale, mode=mode)

        # Delete the original image
        os.remove(image_saved)
        
        # move the processed image to custom mapped folder
        image_moved = shutil.move(output_path, mapped_path)

        image_upload_url = mapped_url + image_name

        # Update performer with new image
        query = """
     mutation performerUpdate($performer_update_input: PerformerUpdateInput!){
       performerUpdate(input: $performer_update_input){
            id
          }
        }
        """
        variables = {"performer_update_input": {"image": image_upload_url, "id": performer_id}}
        result = self.__callGraphQL(query, variables)
        
        # Print the result of the GraphQL mutation
        self.error("result: "+str(result))
        
        # Delete the processed image
        os.remove(image_moved)
        
        
    def setup_tags(self):
        for tag_name in tag_names:
            tag_id = self.findTagIdWithName(tag_name)
            if tag_id == None:
                tag_id = self.createTagWithName(tag_name)
                self.debug("Adding tag: "+tag_name)
            else:
                self.error("Tag already exists: "+tag_name)

    def remove_tags(self):
        for tag_name in tag_names:
            tag_id = self.findTagIdWithName(tag_name)
            if tag_id == None:
                self.error("Error: "+tag_name + "doesn't exist")
            else:
                self.debug("Removing tag: , "+tag_name)
                tag_id = self.removeTagWithID(tag_id)


        
    def upscale_PerformerImage(self, performer_id):
        global scale_setting
        global mode_setting
        # Find performers by tag
        performers = self.findPerformersByTag(performer_id)

        for performer in performers:
            tags = performer['tags']
            # Check if performer is only tagged with one value
            if len(tags) == 1:
                tag = tags[0]
                # Check if tag is in tag_names
                if tag in tag_names:
                    # Put tag value into a variable
                    tag_value = tag
                    # Set variables for scale
                    if '0.5x' in tag_value:
                        scale_setting = 'Scale.X05'
                    elif "2x" in tag_value:
                        scale_setting = 'Scale.X2'  
                    elif "4x" in tag_value:
                        scale_setting = 'Scale.X4'  
                    elif "6x" in tag_value:
                        scale_setting = 'Scale.X6'
                    else:
                        print('No scale in tag name')
                    # Set variables for mode
                    if 'Standard' in tag_value:
                        mode_setting = 'Mode.STANDARD'
                    elif "Lines" in tag_value:
                        mode_setting = 'Mode.Lines'  
                    elif "Art & CG" in tag_value:
                        mode_setting = 'Mode.ART_AND_CG'  
                    elif "Low Resolution" in tag_value:
                        mode_setting = 'Mode.LOW_RESOLUTION'
                    elif "Very Compressed" in tag_value:
                        mode_setting = 'Mode.VERY_COMPRESSED'
                    else:
                        print('No mode in tag name')
                else:
                    self.error(f"Tag '{tag}' is not a valid tag name")
                    continue
            else:
                self.error(f"Performer with ID '{performer_id}' is tagged with more than one value")
                continue

            tag_id = self.findTagIdWithName(tag_name)
            if tag_id is None:
                self.error("Tag missing:"+tag_name) 
            else:
                self.info("Tag exists: "+tag_name)

            image_paths_tags = self.findPerformersByTag(tag_id)
            for image_path, performer_id in image_paths_tags:
                scale = Scale.__getattr__(scale_setting)
                mode = Mode.__getattr__(mode_setting)
                self.processPerformerImage(image_path, performer_id, scale_setting, mode_setting)  




# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    if len(sys.argv) > 1:
        url = "http://localhost:9999/graphql"
        if len(sys.argv) > 2:
            url = sys.argv[2]

        if sys.argv[1] == "setup":
            client = upscale_all(url)
            client.setup_tags()
        elif sys.argv[1] =="upscale_all":
            client = upscale_all(url)
            client.upscale_PerformerImage()
        elif sys.argv[1] =="remove_tags":
            client = upscale_all(url)
            client.remove_tags()
        elif sys.argv[1]== "api":
            fragment = json.loads(sys.stdin.read())
            scheme=fragment["server_connection"]["Scheme"]
            port=fragment["server_connection"]["Port"]
            domain="localhost"
            if "Domain" in fragment["server_connection"]:
                domain = fragment["server_connection"]["Domain"]
            if not domain:
                domain='localhost'
            url = scheme + "://" + domain + ":" +str(port) + "/graphql"

            client=upscale_with(url)
            mode=fragment["args"]["mode"]
            client.debug("Mode: "+mode)
            if mode == "setup":
                client.setup_tags()
            elif mode == "upscale_all":
                client.upscale_PerformerImage()
            elif mode == "remove_tags":
                client.remove_tags()
    else:
        print("")
