MetaBox/Scripts/Modeling/Edit/PlugIt/PlugIt_Widgets.py
2025-01-14 02:17:16 +08:00

811 lines
25 KiB
Python

# -*- coding: latin-1 -*-
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
import maya.cmds as mc
import os, json
import maya.mel as mel
import shutil
from . import PlugIt_UI
from . import PlugIt_Global
import importlib
importlib.reload(PlugIt_Global)
# Special cases for different Maya versions
try:
from shiboken2 import wrapInstance
except ImportError:
from shiboken import wrapInstance
from maya import OpenMayaUI as omui
ASSET_FAVOURITES_PATH = PlugIt_Global.ASSET_FAVOURITES_PATH
##PATH_SET
IconPath = PlugIt_Global.IconsPathThemeClassic
PreferencePath = PlugIt_Global.PreferencePath
TOOLS_PATH = PlugIt_Global.ToolsPath
Click_pref = json.load(open(PreferencePath + 'Pref_Click.json', "r"))
PREF_CLICK = (Click_pref['CLICK'])
if PREF_CLICK == 0:
ClickIndex = 0
if PREF_CLICK == 1:
ClickIndex = 1
FOLDER_PATH = ""
quickPlug_ScriptJob = 1111
class PlugIt_ListWidget(QListWidget):
""" LE WIDGET QUI LISTE LES ASSETS """
def __init__(self, path, parent):
super(PlugIt_ListWidget, self).__init__()
self.parent=parent # just for updating favoutites
self.path = path
self.iconSize = 168
self.buffer = 4
self.buttons = []
self.isFavOrResearch = False # bool: si la QListWidget sera utilisée pour les favoris ou la recherche
self.setViewMode(QListWidget.IconMode)
self.setResizeMode(QListWidget.Adjust)
self.setMovement(QListWidget.Static)
self.setGridSize(QSize(self.iconSize + self.buffer, self.iconSize + self.buffer))
self.setSortingEnabled(0)
self.verticalScrollBar().setSingleStep(20)
self.populate()
def populate(self):
try: # tab normal si self.path est un DOSSIER
folderList = os.listdir(self.path)
self.createsButtonsFromFileList(folderList= folderList)
except: # favoris si self.path est une LISTE DE FICHIERS
folderList = self.path
folderList = json.loads(folderList)
self.isFavOrResearch = True
self.createsButtonsFromFileList(folderList=folderList)
def createsButtonsFromFileList(self, folderList):
# crée les bouttons grâce a la liste des chemins de tous les assets a afficher
icon_list = []
for folder in folderList:
if not self.isFavOrResearch:
icon_list.append(folder+"/"+folder+".png")
else:
icon_list.append(folder)
for icon in icon_list:
item = QListWidgetItem()
item.setFlags(Qt.ItemFlag.NoItemFlags)
item.setSizeHint(QSize(400, 400))
self.addItem(item)
if self.isFavOrResearch:
pixPath = icon
else:
pixPath = self.path + "/" + icon
button = PlugIt_Button(pixPath, self, item)
icon = QIcon(pixPath)
button.setFlat(True)
button.setIconSize(QSize(self.iconSize, self.iconSize))
button.setObjectName("Items")
#button.setContentsMargins(200, 200, 200, 200)
button.setIcon(icon)
self.buttons.append(button)
self.setItemWidget(item, button)
class PlugIt_Button(QPushButton):
""" ON VA AJOUTER CE BOUTTON POUR CHAQUE ASSET DANS LE PlugIt_ListWidget """
def __init__(self, itemPath, parent, itemWidget):
super(PlugIt_Button, self).__init__()
self.itemWidget = itemWidget
self.itemPath = itemPath
self.parent = parent
self.assetName = self.itemPath[:-4] # json
self.assetName = self.assetName[self.assetName.rfind("/") + 1:]
self.setContextMenuPolicy(Qt.DefaultContextMenu)
def enterEvent(self, event, action=None):
pass
# fonction appelée quand la souris hovers le boutton
#self.parent.parent.AssetName.setText(self.assetName)
def leaveEvent(self, event):
# fonction appelée quand la souris sort du boutton
#print ("leave")
pass
def mousePressEvent(self, QMouseEvent):
# fonction appelée quand on fait un clic souris (droit ou gauche)
# si c'est un clic gauche:
if QMouseEvent.button() == Qt.LeftButton:
if ClickIndex == 0:
PlacementMode_pref = json.load(open(PreferencePath + 'DRAGMODE_Widget.json', "r"))
PLACEMENTMODE = (PlacementMode_pref['VALUE'])
print("PLACEMENTMODE = " + str(PLACEMENTMODE))
if PLACEMENTMODE == 0:
self.PLUG()
elif PLACEMENTMODE == 1:
self.PLUG_1x1()
elif PLACEMENTMODE == 2:
#Back to ObjectMode
mc.SelectVertexMask()
mc.SelectToggleMode()
mc.select(d=True)
self.set_ImportDrag()
else:
pass
# si c'est un clic miliue:
if QMouseEvent.button() == Qt.MiddleButton:
pass
# si c'est un clic droit
if QMouseEvent.button() == Qt.RightButton:
##KNOW FAV TAB
FavTabpref_path = open(PreferencePath + 'KnowFavTab.json', "r")
FavTabdata_pref = json.load(FavTabpref_path)
FavTabPath = (FavTabdata_pref['TAB_ACTIVE_NAME'])
self.menu = QMenu(self)
##____________________________________________________________________// MRB MENU
# __________________________________________________________SECURE STEP
secure = QAction(" // " + str(self.assetName) + " // ")
self.menu.addAction(secure)
# __________________________________________________________-----
sep0 = QAction("------------- ")
self.menu.addAction(sep0)
# __________________________________________________________ADD FAVORITE : add to favourites, sauf si on est déjà dans le tab favourite
if FavTabPath == "\u2764":
mb_RemoveFavorite = QAction("Remove from favourite")
mb_RemoveFavorite.triggered.connect(self.RemoveFavoriteMenuAction)
self.menu.addAction(mb_RemoveFavorite)
else:
mb_Favorite = QAction("Add to favourite")
mb_Favorite.triggered.connect(self.AddFavoriteMenuAction)
self.menu.addAction(mb_Favorite)
# __________________________________________________________-----
sep = QAction("------------- ")
self.menu.addAction(sep)
# __________________________________________________________OPEN FILE
mb_OpenFile = QAction("Open File ")
mb_OpenFile.triggered.connect(self.WARNING_SaveOpen)
self.menu.addAction(mb_OpenFile)
# __________________________________________________________OPEN FOLDER
mb_OpenFolder = QAction("Open Folder ")
mb_OpenFolder.triggered.connect(self.set_OpenFolder)
self.menu.addAction(mb_OpenFolder)
# __________________________________________________________RENAME
mb_Rename = QAction("Rename ")
mb_Rename.triggered.connect(self.set_Rename)
self.menu.addAction(mb_Rename)
# __________________________________________________________DELETE
mb_Delete = QAction("Delete ")
mb_Delete.triggered.connect(self.set_Delete)
self.menu.addAction(mb_Delete)
# show the menu
self.popup = self.menu.exec_(self.mapToGlobal(QMouseEvent.pos()))
def mouseDoubleClickEvent(self, QMouseEvent):
if ClickIndex == 1:
PlacementMode_pref = json.load(open(PreferencePath + 'DRAGMODE_Widget.json', "r"))
PLACEMENTMODE = (PlacementMode_pref['VALUE'])
if PLACEMENTMODE == 0:
self.PLUG()
elif PLACEMENTMODE == 1:
self.PLUG_1x1()
elif PLACEMENTMODE == 2:
# Back to ObjectMode
mc.SelectVertexMask()
mc.SelectToggleMode()
mc.select(d=True)
self.set_ImportDrag()
else:
pass
# *****************************************************
# UNE FONCTION PAR ACTION DU MENU CLIC DROIT
# *****************************************************
def importMenuAction(self):
mc.file(self.itemPath[:-4] + ".ma", i=True)
def AddFavoriteMenuAction(self):
# add to favourite
favouriteFilePath = ASSET_FAVOURITES_PATH
with open(favouriteFilePath, 'r+') as file:
fileContent = file.read()
JSONtoPYTHON = json.loads(fileContent)
#check si l'asset est deja en favoris
if self.itemPath in JSONtoPYTHON:
mc.warning("this asset is already in your favourites")
return
JSONtoPYTHON.append(self.itemPath)
final = json.dumps(JSONtoPYTHON)
# update favourite json file for saving
with open(favouriteFilePath, 'w+') as file:
file.write(final)
#update favourite tab
self.parent.parent.favouritesWidget.createsButtonsFromFileList(folderList=[self.itemPath])
mc.warning("Asset successfully added to the favourite tab")
def RemoveFavoriteMenuAction(self):
favouriteFilePath = ASSET_FAVOURITES_PATH
with open(favouriteFilePath, 'r+') as file:
fileContent = file.read()
JSONtoPYTHON = json.loads(fileContent)
JSONtoPYTHON.remove(self.itemPath)
final = json.dumps(JSONtoPYTHON)
print ("fileContent = " + str(fileContent) )
print ("JSONtoPYTHON = " + str(JSONtoPYTHON))
print ("final = " + str(final))
# update favourite json file for saving
with open(favouriteFilePath, 'w+') as file:
file.write(final)
#update favourite tab
from . import PlugIt_UI
import importlib
importlib.reload(PlugIt_UI)
PlugIt_UI.showUI()
mc.warning("Asset successfully remove to the favourite tab")
def set_ImportDrag(self):
#VERIF THERE IS A MESH
listAllGeometrieScene = mc.ls(type="mesh")
if listAllGeometrieScene == []:
PlugIt_Global.WarningWindow("Drag Placement mode need at least one mesh in the scene.", 350)
return
#Clean Previous Bug Scene :
if mc.objExists("Plug_Mesh"):
mc.delete("Plug_Mesh")
if mc.objExists("Plug_AllFaces_set"):
mc.delete("Plug_AllFaces_set")
if mc.objExists("Plug_EdgeBorder_set"):
mc.delete("Plug_EdgeBorder_set")
if mc.objExists("Plug_Selection_set"):
mc.delete("Plug_Selection_set")
from . import PlugIt_DragTool
importlib.reload(PlugIt_DragTool)
fileMA = self.itemPath.replace(".png" , ".ma")
print("fileMA = " + str(fileMA))
PlugIt_DragTool.goPress(fileMA)
def set_OpenFile(self):
selectedObject = self.itemPath[:-4]
mc.file(selectedObject + ".ma", o=True)
def set_ImportFile(self):
SaveSize_pref = json.load(open(PreferencePath + 'MultiSize.json', "r"))
MULTISIZEVALUE = (SaveSize_pref['MULTISIZEVALUE'])
ImportShaderMode_pref = json.load(open(PreferencePath + 'ImportShader.json', "r"))
IMPORTSHADERMODE = (ImportShaderMode_pref['IMPORTSHADERMODE'])
# Clean if previous mode was Drag and still active
mc.setToolTo('moveSuperContext')
before = set(mc.ls(assemblies=True, l= True))
selectedObject = self.itemPath[:-4]
if IMPORTSHADERMODE == 0:
shadingNetworksOptVar = mc.optionVar(q='removeDuplicateShadingNetworksOnImport')
mc.optionVar(intValue=('removeDuplicateShadingNetworksOnImport', 1))
mc.file(selectedObject + ".ma", i=True, removeDuplicateNetworks=True)
mc.optionVar(intValue=('removeDuplicateShadingNetworksOnImport', shadingNetworksOptVar))
else:
mc.file(selectedObject + ".ma", i=True)
after = set(mc.ls(assemblies=True, l= True))
imported = after.difference(before)
mc.select(imported)
if MULTISIZEVALUE != 1.0:
mc.CreateEmptyGroup()
mc.rename(self.assetName + '_Ctrl')
objToPlace = mc.ls(sl=True)
mc.parent(imported, objToPlace[0])
mc.select(objToPlace[0])
mc.makeIdentity(apply=True)
mc.xform(ws=1, a=1, piv=[0, 0, 0])
mc.setAttr(objToPlace[0] + ".scaleX", MULTISIZEVALUE)
mc.setAttr(objToPlace[0] + ".scaleY", MULTISIZEVALUE)
mc.setAttr(objToPlace[0] + ".scaleZ", MULTISIZEVALUE)
def set_ImportReplace(self):
##_________________INIT
SaveSize_pref = json.load(open(PreferencePath + 'MultiSize.json', "r"))
MULTISIZEVALUE = (SaveSize_pref['MULTISIZEVALUE'])
ImportShaderMode_pref = json.load(open(PreferencePath + 'ImportShader.json', "r"))
IMPORTSHADERMODE = (ImportShaderMode_pref['IMPORTSHADERMODE'])
selection = mc.ls(selection=True, l= True)
if selection == []:
PlugIt_Global.WarningWindow("On 'Replace' mode : you should select one Object.", 350)
return
##_________________IMPORT L'ASSET
before = set(mc.ls(assemblies=True, l= True))
selectedObject = self.itemPath[:-4]
if IMPORTSHADERMODE == 0:
shadingNetworksOptVar = mc.optionVar(q='removeDuplicateShadingNetworksOnImport')
mc.optionVar(intValue=('removeDuplicateShadingNetworksOnImport', 1))
mc.file(selectedObject + ".ma", i=True, removeDuplicateNetworks=True)
mc.optionVar(intValue=('removeDuplicateShadingNetworksOnImport', shadingNetworksOptVar))
else:
mc.file(selectedObject + ".ma", i=True)
after = set(mc.ls(assemblies=True, l= True))
imported = after.difference(before)
##_______________CREATION DU GROUPE QUI CONTIENT TOUS LES MESH
mc.CreateEmptyGroup()
mc.rename(self.assetName + '_Ctrl')
objToPlace = mc.ls(sl=True)
mc.parent(imported, objToPlace[0])
if MULTISIZEVALUE != 1.0:
mc.setAttr(objToPlace[0] + ".scaleX", MULTISIZEVALUE)
mc.setAttr(objToPlace[0] + ".scaleY", MULTISIZEVALUE)
mc.setAttr(objToPlace[0] + ".scaleZ", MULTISIZEVALUE)
mc.select(objToPlace[0])
mc.makeIdentity(apply=True)
mc.select(objToPlace[0])
mc.makeIdentity(apply=True)
allNewSel = []
#OPERATION DE REPLACEMENT
if len(selection) > 1:
for each in selection:
objDup = mc.duplicate(objToPlace[0])
mc.matchTransform(objDup[0], each, pos=True, rot=True, scl =True)
mc.delete(each)
allNewSel.append(objDup[0])
else:
SELECTION = selection
mc.matchTransform(objToPlace[0], SELECTION, pos=True, rot=True, scl =True)
mc.delete(SELECTION)
if len(selection) > 1:
toAdd = allNewSel.pop(0)
theGoodSel = allNewSel.append(toAdd)
#currentSel = mc.ls(sl=True, l=True)
mc.delete(objToPlace[0])
print ("allNewSel == " + str(allNewSel))
print ("theGoodSel == " + str(theGoodSel))
mc.select(allNewSel)
else:
mc.select(objToPlace[0])
mc.setToolTo('moveSuperContext')
def set_importAtSelection(self):
SaveSize_pref = json.load(open(PreferencePath + 'MultiSize.json', "r"))
MULTISIZEVALUE = (SaveSize_pref['MULTISIZEVALUE'])
ImportShaderMode_pref = json.load(open(PreferencePath + 'ImportShader.json', "r"))
IMPORTSHADERMODE = (ImportShaderMode_pref['IMPORTSHADERMODE'])
selectionCheck = mc.ls(sl=True)
if selectionCheck == []:
PlugIt_Global.WarningWindow("On 'Place at Selection' mode : you should select component first.", 350)
return
mc.setToolTo('moveSuperContext')
pos = mc.manipMoveContext('Move', query=True, position=True)
selection = mc.ls(selection=True, l= True)
##_________________IMPORT L'ASSET
before = set(mc.ls(assemblies=True, l= True))
selectedObject = self.itemPath[:-4]
if IMPORTSHADERMODE == 0:
shadingNetworksOptVar = mc.optionVar(q='removeDuplicateShadingNetworksOnImport')
mc.optionVar(intValue=('removeDuplicateShadingNetworksOnImport', 1))
mc.file(selectedObject + ".ma", i=True, removeDuplicateNetworks=True)
mc.optionVar(intValue=('removeDuplicateShadingNetworksOnImport', shadingNetworksOptVar))
else:
mc.file(selectedObject + ".ma", i=True)
after = set(mc.ls(assemblies=True, l= True))
imported = after.difference(before)
##_______________CREATION DU GROUPE QUI CONTIENT TOUS LES MESH
mc.CreateEmptyGroup()
mc.rename(self.assetName + '_Ctrl')
objToPlace = mc.ls(sl=True)
mc.parent(imported, objToPlace[0])
if MULTISIZEVALUE != 1.0:
mc.setAttr(objToPlace[0] + ".scaleX", MULTISIZEVALUE)
mc.setAttr(objToPlace[0] + ".scaleY", MULTISIZEVALUE)
mc.setAttr(objToPlace[0] + ".scaleZ", MULTISIZEVALUE)
mc.select(objToPlace[0])
mc.makeIdentity(apply=True)
mc.select(objToPlace[0])
mc.makeIdentity(apply=True)
mc.xform(ws=1, a=1, piv=[0, 0, 0])
mc.move(pos[0], pos[1], pos[2], objToPlace)
constr = mc.normalConstraint(selection, objToPlace, aimVector=(0, 1, 0), worldUpType=0)
mc.delete(constr)
mc.select(objToPlace[0])
mc.setToolTo('moveSuperContext')
def set_OpenFolder(self):
selectedObject = self.itemPath[:-4]
removeEnd = selectedObject.replace("/" + self.assetName, "")
ItemFolderPath = removeEnd + "/" + self.assetName
os.startfile(ItemFolderPath)
def set_Rename(self):
selectedObject = self.itemPath[:-4]
removeEnd = selectedObject.replace("/" + self.assetName, "")
ItemFolderPath = removeEnd + "/" + self.assetName
from . import PlugIt_Rename
import importlib
importlib.reload(PlugIt_Rename)
PlugIt_Rename.SEND_INFO(str(removeEnd), str(ItemFolderPath))
PlugIt_Rename.showUI()
def set_Delete(self):
selectedObject = self.itemPath[:-4]
removeEnd = selectedObject.replace("/" + self.assetName, "")
ItemFolderPath = removeEnd + "/" + self.assetName
shutil.rmtree(ItemFolderPath)
# FAV CLEAN List
itemName = (ItemFolderPath.split("/")[-1]).replace(".png", "")
print ("itemName = " + itemName)
favouriteFilePath = ASSET_FAVOURITES_PATH
with open(favouriteFilePath, 'r+') as file:
fileContent = file.read()
FAVLIST = json.loads(fileContent)
FAVLISTLen = len(FAVLIST)-1
for each in FAVLIST:
nameInList = (each.split("/")[-1]).replace(".png", "")
print ("each = " + each)
print ("nameInList = " + nameInList)
if nameInList == itemName:
if FAVLIST.index(each) == 0:
print ("PLACE AT : START")
stringToReplace = "'" + str(ItemFolderPath) + "/" + str(itemName) + ".png" + "'" + ","
elif FAVLIST.index(each) == FAVLISTLen:
print ("PLACE AT : END")
stringToReplace = ", " + "'" + str(ItemFolderPath) + "/" + str(itemName) + ".png" + "'"
else:
print ("PLACE AT : MIDDLE")
stringToReplace = "'" + str(ItemFolderPath) + "/" + str(itemName) + ".png" + "'" + ","
print ("stringToReplace IN DELETE == " + stringToReplace)
newFAV = str(FAVLIST).replace(str(stringToReplace), "")
print ("NEW FAV IN DELETE == " + newFAV)
newFAVtoWritte = newFAV.replace("'", '"')
# update favourite json file for saving
with open(favouriteFilePath, 'w+') as file:
file.write(newFAVtoWritte)
from . import PlugIt_UI
import importlib
importlib.reload(PlugIt_UI)
ui = PlugIt_UI.showUI()
def none (self):
pass
def WARNING_SaveOpen(self):
BackgroundColor = 0.16
Message = "Save changes before to open?"
# ________________//
if mc.window("WarningWindow", exists=True):
mc.deleteUI("WarningWindow")
mc.window("WarningWindow", title=' Save Changes ', s=False, vis=True, rtf=False)
mc.columnLayout(adj=True, rs=3, bgc=[BackgroundColor, BackgroundColor, BackgroundColor])
mc.separator(h=8, style='none')
mc.text(l=" " + Message + " ", al="center")
mc.separator(h=8, style='none')
mc.rowColumnLayout( numberOfRows=1 )
mc.separator(w=10, style='none')
mc.button(l="Save", c=self.WarningSave, width= 85, h=20)
mc.separator(w=10, style='none')
mc.button(l="Don't save", c=self.WarningDontSave, width= 85, h=20)
mc.separator(w=10, style='none')
mc.button(l="Cancel", c=self.WarningCancel, width= 85, h=20)
mc.window("WarningWindow", e=True, wh=(300, 80))
qw = omui.MQtUtil.findWindow("WarningWindow")
widget = wrapInstance(int(qw), QWidget)
icon = QIcon(IconPath + "Windows_Ico_Warning.png")
widget.setWindowIcon(icon)
mc.showWindow()
def WarningSave(self, *args):
selectedObject = self.itemPath[:-4]
mc.file(f=True, save=True )
mc.file(selectedObject + ".ma", o=True, f=True)
mc.deleteUI("WarningWindow")
def WarningDontSave(self, *args):
selectedObject = self.itemPath[:-4]
mc.file(selectedObject + ".ma", o=True, f=True)
mc.deleteUI("WarningWindow")
def WarningCancel(self, *args):
mc.deleteUI("WarningWindow")
def autoDetectFace(self):
selection = mc.ls(sl=True)
isFace = mc.filterExpand(sm=34)
if selection == []:
print("Selection Empty")
elif len(selection) != 1:
print("More then 1 len")
elif isFace == None:
pass
else:
if mc.window("P L U G - O p t i o n s", exists=True):
return
fileMA = self.itemPath.replace(".png", ".ma")
from . import PlugIt_Plug
importlib.reload(PlugIt_Plug)
PlugIt_Plug.PERFORM_1x1_PLUG(fileMA)
def PLUG(self):
MelScript_ExtractFace = TOOLS_PATH + 'wzx_DuplicateFace.mel'
if mc.window("P L U G - O p t i o n s", exists=True):
return
selection = mc.ls(sl=True)
isFace = mc.filterExpand(sm=34)
oneFace = 0
if selection == []:
PlugIt_Global.WarningWindow("You should select faces.", 300)
return
elif isFace == None:
PlugIt_Global.WarningWindow("Not Face component. You should select faces component only.", 400)
return
mc.ConvertSelectionToEdgePerimeter()
numberOfEdges = len(mc.filterExpand(sm=32))
mc.select(selection)
if len(isFace) > 9:
PlugIt_Global.WarningWindow("You can't select more than 9 faces.", 300)
return
elif len(selection) != 1:
selectionObject = mc.ls(hl=True)
mc.delete(selectionObject, constructionHistory=True)
saveSelFace = mc.ls(sl=True)
# ______ Verif Adgacente Faces
mel.eval('source "' + MelScript_ExtractFace + '"')
try:
mc.polySeparate()
mc.PickWalkUp()
mc.delete()
PlugIt_Global.WarningWindow("Be sure to only select one area of adjacent faces.", 600)
return
except:
mc.delete()
mc.select(saveSelFace)
else:
oneFace = 1
##__________________________________________________________ V E R I F I C A T I O N
#SI no selection
#Si selection pas face
#Si face number + de 16 edges
fileMA = self.itemPath.replace(".png", ".ma")
from . import PlugIt_Plug
importlib.reload(PlugIt_Plug)
PlugIt_Plug.PERFORM_PLUG(fileMA, oneFace, numberOfEdges)
def PLUG_1x1(self):
SCRIPT_JOB_PREVIOUS = (json.load(open(PreferencePath + 'ScriptJob_1x1.json', "r"))['VALUE'])
print("quickPlug_ScriptJob =" + str(SCRIPT_JOB_PREVIOUS))
if SCRIPT_JOB_PREVIOUS == 1111:
quickPlug_ScriptJob = mc.scriptJob(event=["SelectionChanged", self.autoDetectFace])
open(PreferencePath + 'ScriptJob_1x1.json', "w").write(json.dumps({"VALUE": quickPlug_ScriptJob}))
else:
mc.scriptJob(kill=SCRIPT_JOB_PREVIOUS, force=True)
quickPlug_ScriptJob = mc.scriptJob(event=["SelectionChanged", self.autoDetectFace])
open(PreferencePath + 'ScriptJob_1x1.json', "w").write(json.dumps({"VALUE": quickPlug_ScriptJob}))