def createProject(): site = 'https://chimneypot.shotgunstudio.com' scriptName = 'createProject' scriptKey = '90699580e396b61d3acfb71e0595adde7458dfd4' repo = '/mnt/karramba/' rootList = ['film', 'out', 'ref', 'src', 'temp'] filmList = ['assets', 'sequences'] assetList = ['light', 'material', 'mattepaint', 'model', 'rig', 'shader', 'textures'] shotList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'src', 'tmp'] sqList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'shots'] dataList = ['cache', 'geo', 'render', 'shadowmap', 'sim', 'track', 'photonmap'] outList = ['dailies', 'hires'] prName = raw_input('Print project name:') prPath = repo + prName if not os.path.exists(prPath): os.mkdir(prPath) for i in rootList: os.makedirs(prPath + os.sep + i) for i in filmList: os.makedirs(prPath + os.sep + 'film' + os.sep + i) for i in assetList: os.makedirs(prPath + os.sep + 'film' + os.sep + 'assets' + os.sep + i) for i in outList: os.makedirs(prPath + os.sep + 'out' + os.sep + i) sg = Shotgun(site, scriptName, scriptKey) sg.create('Project', {'name':prName})
def __init__(self): sgSite = 'https://chimneypot.shotgunstudio.com' scriptName = 'dBase' scriptKey = '729a76955455909c79f6d90262bb9fbe9186b92b' self.db = Shotgun(sgSite, scriptName, scriptKey)
def _create_instance(self): instance = Shotgun(self.base_url, 'dummy_script_name', 'dummy_api_key', connect=False) instance.config = self.config return instance
def main(notebookName): #Get your developer token here: https://www.evernote.com/api/DeveloperToken.action and put it here dev_token = 'yourEvernoteDevKey' #Put your Shotgun script details here sg = Shotgun('https://yourSite.shotgunstudio.com','evernote-shotgun','yourScriptKey') #Put the Shotgun HumanUser ID here for the person you want to appear as the Note's author in Shotgun sgUserId = 45 sgUser = sg.find_one("HumanUser",[['id', 'is', sgUserId]]) #Establish a connection to Evernote and store note and user data client = EvernoteClient(token=dev_token, sandbox=False) userStore = client.get_user_store() user = userStore.getUser() noteStore = client.get_note_store() #Check if the supplied notebook exists, and if it does, send to processNotebook() print('\nFinding notebook') notebooks = noteStore.listNotebooks() notebookNames = [notebook.name for notebook in notebooks] if notebookName not in notebookNames: print('\nSorry, there are no notebooks in your account named {0}'.format(notebookName)) else: for notebook in notebooks: if notebook.name == notebookName: print('\nProcessing notebook - BEGIN') processNotebook(noteStore, notebook, sg, sgUser) print('\nProcessing notebook - DONE\n') else: continue
def addSrc(): repo = '/mnt/karramba' shotFoldList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'src', 'tmp'] seqFoldList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'shots'] dataFoldList = ['cache', 'geo', 'render', 'shadowmap', 'sim', 'track', 'photonmap'] outFoldList = ['dailies', 'hires'] site = 'https://chimneypot.shotgunstudio.com' scriptName = 'addSrc' scriptKey = 'd7dac4e2c55faf486875dfb944ffc9d8e49a0c44' sg = Shotgun(site, scriptName, scriptKey) projList = sg.find('Project', [], ['name']) for i in projList: print 'id:' + str(i['id']) + ' ' + i['name'] prId = int(raw_input('Print project id:')) proj = sg.find_one('Project', [['id','is',prId]], ['name']) if not [x for x in os.listdir(repo) if x==proj['name']]: print "Project doesn't exist in repository" return s = os.sep prPath = repo + s + proj['name'] seqPath = prPath + s + 'film' + s + 'sequences' seqList = os.listdir(prPath + s + 'src') for i in seqList: sequenceFold = prPath + s + 'film' + s + 'sequences' os.makedirs(sequenceFold + s + i) for j in seqFoldList: os.makedirs(sequenceFold + s + i + s + j) for d in dataFoldList: os.makedirs(sequenceFold + s + i + s + 'data' + s + d) for o in outFoldList: os.makedirs(sequenceFold + s + i + s + 'out' + s + o) shList = os.listdir(prPath + s + 'src' + s + i) for sh in shList: shFold = sequenceFold + s + i + s + 'shots' os.makedirs(shFold + s + sh) for f in shotFoldList: os.makedirs(shFold + s + sh + s + f) for ds in dataFoldList: os.makedirs(shFold + s + sh + s + 'data' + s + ds) for ot in outFoldList: os.makedirs(shFold + s + sh + s + 'out' + s + ot) shutil.move(prPath + s + 'src' + s + i + s + sh, shFold + s + sh + s + 'src') os.system('ln -sf ' + shFold + s + sh + s + 'src ' + prPath + s + 'src' + s + i + s + sh)
def __init__(self): ''' creates the connection to the server and connects to database. creates list of Ids form the database collections that needs to convert to shotgun collections ''' SERVER_PATH = "https://hcpstudio.shotgunstudio.com" SCRIPT_NAME = 'sgApi' SCRIPT_KEY = '3899a8466f2cea694c2ba5341d871da845509d18d96a4feb7fb8d147de0fa819' self.sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) self.dbObjectID = ObjectId() master = DaoMaster() session = DaoMaster.getSession() self.itemInstance = session.getItemsDao() self.ItemStatusList = ['rdy', 'ip', 'app', 'crnt', 'outd','dep', 'vari', 'rej'] self.ItemType = ['Source', 'Prop', 'Environment', 'Character', 'Rig', 'Fx', 'Template', 'Geometry', 'Art', 'Shader', 'Texture', 'Cache', 'ImageSequence', 'DCC', 'None'] self.ItemClass = ['Item', 'Asset', 'superAsset']
def submitShotgunTicket(output, jobList): currentuser = str(User.currentUser().name()) title = "AtS - %s"%currentuser desc = [] desc.append(output+"\n") desc.append("JOBLIST:") for job in jobList: desc.append(str(job.key())+" - "+str(job.name())) sg = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) id = sg.find("HumanUser",[['login','is',currentuser]],['id']) userid = id[0] ticket_data = { 'created_by': {'type':'HumanUser','id':userid['id']}, 'title': title, 'description': "\n".join(desc), 'addressings_to':[{'type':'Group', 'id':19}, {'type':'HumanUser','id':userid['id']}], 'project': {'type':'Project', 'id':178}, 'sg_service': {'type':'CustomNonProjectEntity01', 'id':27}, } sg_ticket = sg.create('Ticket', ticket_data, ['id']) new_ticket_url = SERVER_PATH + "/detail/Ticket/" + str(sg_ticket['id']) QDesktopServices.openUrl( QUrl(new_ticket_url) )
def __init__(self, base_url, script_name, api_key, convert_datetimes_to_utc=True, http_proxy=None, ensure_ascii=True, connect=True, host=None, port=None): ''' We will initialize the Shotgun object, but will not connect right away. Instead it will will attempt to create a socket connection using the Shotgun object and the host and port data provided or generated. If we do not have a host and port specified, or do not find a connection, we will fall back and connect to the actual Shotgun server instead. ''' Shotgun.__init__(self, base_url, script_name, api_key, convert_datetimes_to_utc=convert_datetimes_to_utc, http_proxy=http_proxy, ensure_ascii=ensure_ascii, connect=False) # If a host is not specified, attempt using the local machine. if not host: host = socket.gethostname() # If a port is not specified, generate a port from the app key. if not port: port = common.appKeyToPort(self.config.api_key) self._sgclient = None self._host = host self._port = port if connect: self.connect()
def getProjects(): site = 'https://chimneypot.shotgunstudio.com' scriptName = 'AssetBrowser' scriptKey = 'c35ab5f5322d4b1e8b6488bb315c03e5f38881ea' repo = '/mnt/karramba/' rootList = ['film', 'out', 'ref', 'src', 'temp'] filmList = ['assets', 'sequences'] assetList = ['light', 'material', 'mattepaint', 'model', 'rig', 'shader', 'textures'] shotList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'src', 'tmp'] sqList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'shots'] dataList = ['cache', 'geo', 'render', 'shadowmap', 'sim', 'track', 'photonmap'] outList = ['dailies', 'hires'] prName = raw_input('Print project name:') prPath = repo + prName if not os.path.exists(prPath): os.mkdir(prPath) for i in rootList: os.makedirs(prPath + os.sep + i) for i in filmList: os.makedirs(prPath + os.sep + 'film' + os.sep + i) for i in assetList: os.makedirs(prPath + os.sep + 'film' + os.sep + 'assets' + os.sep + i) for i in outList: os.makedirs(prPath + os.sep + 'out' + os.sep + i) sg = Shotgun(site, scriptName, scriptKey) sg.create('Project', {'name':prName})
def addSrc(): repo = '/mnt/karramba' shotFoldList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'src', 'tmp'] seqFoldList = ['anim', 'comp', 'data', 'fx', 'light', 'out', 'shots'] dataFoldList = [ 'cache', 'geo', 'render', 'shadowmap', 'sim', 'track', 'photonmap' ] outFoldList = ['dailies', 'hires'] site = 'https://chimneypot.shotgunstudio.com' scriptName = 'addSrc' scriptKey = 'd7dac4e2c55faf486875dfb944ffc9d8e49a0c44' sg = Shotgun(site, scriptName, scriptKey) projList = sg.find('Project', [], ['name']) for i in projList: print 'id:' + str(i['id']) + ' ' + i['name'] prId = int(raw_input('Print project id:')) proj = sg.find_one('Project', [['id', 'is', prId]], ['name']) if not [x for x in os.listdir(repo) if x == proj['name']]: print "Project doesn't exist in repository" return s = os.sep prPath = repo + s + proj['name'] seqPath = prPath + s + 'film' + s + 'sequences' seqList = os.listdir(prPath + s + 'src') for i in seqList: sequenceFold = prPath + s + 'film' + s + 'sequences' os.makedirs(sequenceFold + s + i) for j in seqFoldList: os.makedirs(sequenceFold + s + i + s + j) for d in dataFoldList: os.makedirs(sequenceFold + s + i + s + 'data' + s + d) for o in outFoldList: os.makedirs(sequenceFold + s + i + s + 'out' + s + o) shList = os.listdir(prPath + s + 'src' + s + i) for sh in shList: shFold = sequenceFold + s + i + s + 'shots' os.makedirs(shFold + s + sh) for f in shotFoldList: os.makedirs(shFold + s + sh + s + f) for ds in dataFoldList: os.makedirs(shFold + s + sh + s + 'data' + s + ds) for ot in outFoldList: os.makedirs(shFold + s + sh + s + 'out' + s + ot) shutil.move(prPath + s + 'src' + s + i + s + sh, shFold + s + sh + s + 'src') os.system('ln -sf ' + shFold + s + sh + s + 'src ' + prPath + s + 'src' + s + i + s + sh)
def SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '')) self.sg = Shotgun('https://xxxxxxxxxxxxxxxx.shotgunstudio.com', 'timelogservice', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') self.main()
def _moveFilesToPublish(self): base_url = "http://bubblebathbay.shotgunstudio.com" script_name = 'playBlastPublisher' api_key = '718daf67bfd2c7e974f24e7cbd55b86bb101c4e5618e6d5468bc4145840e4558' sgsrv = Shotgun(base_url = base_url , script_name = script_name, api_key = api_key, ensure_ascii=True, connect=True) selectedShots = [item.text(0) for item in self.treeWidgetItems if item.checkState(0)] if selectedShots: for each in selectedShots: episode = each.split('sh')[0] shotName = '%s_sh%s' % (each.split('sh')[0], each.split('sh')[1].split('Lay')[0]) self.publishPath = self.publishingPath(episode, shotName) for root, dirs, files in os.walk(self.shFldPath): for fl in sorted(files): if fl.endswith('.mov') and fl == '%s.mov' % each: srcPath = os.path.join(root,fl) self.playblastName = fl while os.path.exists(os.path.join(self.publishPath, fl)): allFiles= os.listdir(self.publishPath) publishFiles = [] if allFiles: for allFile in allFiles: if allFile.endswith('.mov'): publishFiles.append(allFile) versionNumber = int(sorted(publishFiles)[-1].split('.v')[1].split('.mov')[0]) versionNumber += 1 if versionNumber < 10: publishFileName = '%sLayout.v%03d.mov' % (shotName.replace('_', ''), versionNumber) self.publishPath = os.path.join(self.publishPath, publishFileName) self.playblastName = os.path.basename(self.publishPath) else: publishFileName = '%sLayout.v%02d.mov' % (shotName.replace('_', ''), versionNumber) self.publishPath = os.path.join(self.publishPath, publishFileName) self.playblastName = os.path.basename(self.publishPath) shutil.copy2(srcPath, self.publishPath) publishMovPath = os.path.join(self.publishingPath(episode, shotName), self.playblastName) getShotTasks = sgsrv.find_one('Shot', filters = [["code", "is", shotName]], fields=['id', 'tasks']) for key, values in getShotTasks.iteritems(): if key == 'tasks': for value in values: if value['name'] == 'Layout': self.taskId = value['id'] if self.publishPath.endswith('review'): self.publishPath = os.path.join(self.publishPath,fl) self.playblastName = fl data = { 'project': {'type':'Project','id': 66}, 'code': self.playblastName, 'description': 'Layout playblast published', 'sg_path_to_movie': publishMovPath, 'sg_status_list': 'rev', 'entity': {'type':'Shot', 'id':getShotTasks['id']}, 'sg_task': {'type':'Task', 'id':self.taskId}, 'user': {'type':'HumanUser', 'id':92} } result = sgsrv.create('Version', data) result2 = sgsrv.upload("Version", result['id'], publishMovPath, "sg_uploaded_movie") print "Done"
class AppServerSvc(win32serviceutil.ServiceFramework): _svc_name_ = "timelog" _svc_display_name_ = "shotgun time log" def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) SetConsoleCtrlHandler(lambda x: True, True) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) self.count = 0 self.estinmins = 0 self.isAlive = True self.envv = '' self.prlist = [] def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) self.run = False def SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '')) self.sg = Shotgun('https://xxxxxxxxxxxxxxxx.shotgunstudio.com', 'timelogservice', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') self.main() def updateProject(self, projectid): servicemanager.LogWarningMsg(unicode(projectid)) filters = [["project.Project.id", "is", projectid]] fields = ["time_logs_sum", "est_in_mins"] for eventTimeLog in self.sg.find('Task', filters, fields): self.count = self.count + eventTimeLog['time_logs_sum'] if eventTimeLog['est_in_mins'] is not None: self.estinmins = self.estinmins + eventTimeLog['est_in_mins'] data = {'sg_artisttimelog': self.count / 600} asset = self.sg.update("Project", projectid, data) data = {'sg_total_bid': self.estinmins / 600} asset = self.sg.update("Project", projectid, data) def main(self): while self.isAlive: filters = [["sg_status", "is", "active"]] fields = ['id'] for f in self.sg.find('Project', filters, fields): self.prlist.append(f['id']) for prid in self.prlist: self.updateProject(prid) self.count = 0 self.estinmins = 0 if win32event.WaitForSingleObject( self.hWaitStop, 3000) == win32event.WAIT_OBJECT_0: break
def _pubBttn(self): base_url = "http://bubblebathbay.shotgunstudio.com" script_name = 'playBlastPublisher' api_key = '718daf67bfd2c7e974f24e7cbd55b86bb101c4e5618e6d5468bc4145840e4558' sgsrv = Shotgun(base_url = base_url , script_name = script_name, api_key = api_key, ensure_ascii=True, connect=True) selectedShots = sorted([item.text(0) for item in self.shotTreeWidgetItems if item.checkState(0)]) for shot in selectedShots: if shot in self.srcPath.keys(): destPath = self._getPublishPath(shot) srcPath = self.srcPath[str(shot)] ext = os.path.splitext(srcPath)[-1] # print os.path.basename(srcPath) # while os.path.exists(os.path.join(str(destPath), os.path.basename(srcPath))): # print "In Loop" # print os.path.basename(srcPath) # allFiles= os.listdir(destPath) # publishFiles = [] # if allFiles: # for allFile in allFiles: # if allFile.endswith(ext): # print allFile # publishFiles.append(allFile) # versionNumber = int(sorted(publishFiles)[-1].split('.v')[1].split(ext)[0]) # versionNumber += 1 # if versionNumber < 10: # publishFileName = '%sLayout.v%03d%s' % (shotName.replace('_', ''), versionNumber, ext) # self.publishPath = os.path.join(self.publishPath, publishFileName) # self.playblastName = os.path.basename(self.publishPath) # else: # publishFileName = '%sLayout.v%02d%s' % (shotName.replace('_', ''), versionNumber, ext) # self.publishPath = os.path.join(self.publishPath, publishFileName) # self.playblastName = os.path.basename(self.publishPath) # shutil.copy2(srcPath, destPath) shotName = '%s_%s' % (self._getEpisodeName(shot), self._getShotName(shot)) getShotTasks = self.tk.shotgun.find_one('Shot', filters = [["code", "is", shotName]], fields=['id', 'tasks']) taskName = self.comboBox.currentText() self.playblastName = os.path.basename(srcPath) publishMovPath = os.path.join(destPath, self.playblastName).replace('\\', '/') shutil.copy2(srcPath, destPath) for task in getShotTasks['tasks']: if task['name'] == taskName: taskId = task['id'] data = { 'project': {'type':'Project','id': 66}, 'code': self.playblastName, 'description': 'Playblast published', 'sg_path_to_movie': publishMovPath, 'sg_status_list': 'rev', 'entity': {'type':'Shot', 'id':getShotTasks['id']}, 'sg_task': {'type':'Task', 'id':taskId}, 'user': {'type':'HumanUser', 'id':92} } result = sgsrv.create('Version', data) result2 = sgsrv.upload("Version", result['id'], publishMovPath, "sg_uploaded_movie") print "Published %s" % self.playblastName
class AppServerSvc(win32serviceutil.ServiceFramework): _svc_name_ = "timelog" _svc_display_name_ = "shotgun time log" def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) SetConsoleCtrlHandler(lambda x: True, True) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) self.count = 0 self.estinmins = 0 self.isAlive = True self.envv = "" self.prlist = [] def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) self.run = False def SvcDoRun(self): servicemanager.LogMsg( servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, "") ) self.sg = Shotgun( "https://xxxxxxxxxxxxxxxx.shotgunstudio.com", "timelogservice", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ) self.main() def updateProject(self, projectid): servicemanager.LogWarningMsg(unicode(projectid)) filters = [["project.Project.id", "is", projectid]] fields = ["time_logs_sum", "est_in_mins"] for eventTimeLog in self.sg.find("Task", filters, fields): self.count = self.count + eventTimeLog["time_logs_sum"] if eventTimeLog["est_in_mins"] is not None: self.estinmins = self.estinmins + eventTimeLog["est_in_mins"] data = {"sg_artisttimelog": self.count / 600} asset = self.sg.update("Project", projectid, data) data = {"sg_total_bid": self.estinmins / 600} asset = self.sg.update("Project", projectid, data) def main(self): while self.isAlive: filters = [["sg_status", "is", "active"]] fields = ["id"] for f in self.sg.find("Project", filters, fields): self.prlist.append(f["id"]) for prid in self.prlist: self.updateProject(prid) self.count = 0 self.estinmins = 0 if win32event.WaitForSingleObject(self.hWaitStop, 3000) == win32event.WAIT_OBJECT_0: break
def getentitydatafromshotgun(): sg = Shotgun(const.SHOTGUN_URL, const.API_NAME, const.API_KEY) entityData = sg.schema_entity_read({'type': 'Project', 'id': 70}) visibleEntities = [] for entityName in entityData: fields = sg.schema_field_read(entityName) if 'project' in fields: if entityData[entityName]['visible']['value']: visibleEntities.append(entityData[entityName]['name']['value']) print("\"" + entityData[entityName]['name']['value'] + "\": \"" + entityName + "\",") return visibleEntities
def connect(self): ''' Attempts to connect to a Double Barrel Server first, then connects directly to Shotgun if failed. ''' # Attempt to open a socket at the host and port. sgclient = DoubleBarrelClient(self, self.host(), self.port()) if sgclient.connect(): self._sgclient = sgclient if not self._sgclient: Shotgun.connect(self)
def _get_projects_list(): sg = Shotgun('http://yoursite.com', 'your_api', '123456') filters = [['sg_status', 'is', 'Active'], ['tank_name', 'is_not', '']] fields = ['name'] order = [{'field_name': 'name', 'direction': 'asc'}] projectsDic = sg.find('Project', filters, fields, order) newProjectsDic = [] for project in projectsDic: newProjectsDic.append(project['name'].replace(' ', '')) return newProjectsDic
def home(language): ''' Show introduction ''' ui = i18n[language] if request.method == 'POST': print("request form: ", request.form, flush=True) print("request form: ", list(request.form), flush=True) data = {} data['entity_type'] = request.form.get('entity_type', None) data['entity_id'] = request.form.get('selected_ids', None) data['project_name'] = request.form.get('project_name', None) data['project_id'] = request.form.get('project_id', None) hostname = request.host.split(":") config['vod_url'] = "{}{}:{}".format(configure['vod']['site']['ssl'], hostname[0], configure['vod']['site']['url']) print("config: ", config, flush=True) try: sg = Shotgun("{}{}".format(configure['shotgun']['site']['ssl'],\ request.form.get("server_hostname", None)), \ configure['shotgun']['site']['script_name'] , \ configure['shotgun']['site']['script_key'], \ sudo_as_login=request.form.get("user_login", None)) config["sg"] = sg print("prefs: ", sg.preferences_read(), flush=True) except Exception as e: return render_template('%s.html' % 'message', message=ui['message']['auth_error']) if len(data['entity_id'].split(",")) == 1: entityhandler = entity_handler(config, data) if data["entity_type"] != "Task": data['tasks'] = entityhandler.get_tasks() print("Tasks: ", data['tasks'], flush=True) data['entity_name'] = entityhandler.get_entity_name() return render_template('%s.html' % 'index', data=data, i18n=ui["index"], language=language) else: message = ui['message']['select_error'].format( len(data['entity_id'].split(","))) return render_template('%s.html' % 'message', message=message) else: return render_template('%s.html' % 'message', message=ui['message']['server_up'])
def __init__(self): ''' creates the connection to the shotgun site by api ''' ''' shotgun conection ''' SERVER_PATH = "https://hcpstudio.shotgunstudio.com" SCRIPT_NAME = 'Tracker' SCRIPT_KEY = '99b5c166044037cc2d04646b1dfd58b2f44e8a146b710b425b8f561f2a21e49d' self.sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) self.userId = None self.userDic = {} self.tasks = None self.projectPath = None
def main(): parser = argparse.ArgumentParser(description=DESCRIPTION) parser.add_argument( "--path", help="Output directory path for schema files.", required=True, ) parser.add_argument( "--shotgun", help="A SG site url, a script name and its key", required=True, ) args = parser.parse_args() sg_url = args.shotgun sg = Shotgun(sg_url, login=raw_input("Login: "******"schema.pickle"), os.path.join(schema_dir, "schema_entity.pickle"), )
def main(): """ Map Shotgun users to JIRA users using their respective emails. """ logger_settings, shotgun_settings, jira_settings, project = _get_settings() # Apply settings if logger_settings: logging.config.dictConfig(logger_settings) # Set the logger settings first since JIRA session is chatty. jira = JiraSession( jira_settings["site"], basic_auth=(jira_settings["user"], jira_settings["secret"]), ) if not jira.is_jira_cloud: logger.error("This script can be run for JIRA Cloud only.") return 1 sg = Shotgun( shotgun_settings["site"], script_name=shotgun_settings["script_name"], api_key=shotgun_settings["script_key"], ) sync_jira_users_into_shotgun(sg, jira, project) return 0
def SvcDoRun(self): servicemanager.LogMsg( servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, "") ) self.sg = Shotgun( "https://xxxxxxxxxxxxxxxx.shotgunstudio.com", "timelogservice", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ) self.main()
def _create_new_connection(is_headless, data): """ Creates a new Shotgun connection based on user input. :param bool is_headless: Indicates if the script was invoked without a shell. :param dict data: Data found in the credentials file. :returns: A Shotgun connection and a user entity for the loged in user. """ if is_headless: raise UserInteractionRequiredError() # If the credentials didn't work or the file didn't exist, # ask for the credentials. site = _get_credential("Site", data.get("site", "")) login = _get_credential("Login", data.get("login", "")) sg = None # While we don't have a valid connection, keep asking for a password. while not sg: password = getpass("Password: "******"Authentication failure. Bad password?" print sg = None else: _set_password(site, login, password) # Update the data dictionary. Note that the dictionary can also # contain information about Toggl, so we need to update it # instead of creating a new one. data["site"] = site data["login"] = login data["session_token"] = session_token with open(_get_credential_file_path(), "w") as f: json.dump(data, f) return sg, _get_self(sg, login)
def submitShotgunTicket(output, jobList): currentuser = str(User.currentUser().name()) title = "AtS - %s" % currentuser desc = [] desc.append(output + "\n") desc.append("JOBLIST:") for job in jobList: desc.append(str(job.key()) + " - " + str(job.name())) sg = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) id = sg.find("HumanUser", [['login', 'is', currentuser]], ['id']) userid = id[0] ticket_data = { 'created_by': { 'type': 'HumanUser', 'id': userid['id'] }, 'title': title, 'description': "\n".join(desc), 'addressings_to': [{ 'type': 'Group', 'id': 19 }, { 'type': 'HumanUser', 'id': userid['id'] }], 'project': { 'type': 'Project', 'id': 178 }, 'sg_service': { 'type': 'CustomNonProjectEntity01', 'id': 27 }, } sg_ticket = sg.create('Ticket', ticket_data, ['id']) new_ticket_url = SERVER_PATH + "/detail/Ticket/" + str(sg_ticket['id']) QDesktopServices.openUrl(QUrl(new_ticket_url))
def getentitiesfromshotgun(name): sg = Shotgun(const.SHOTGUN_URL, const.API_NAME, const.API_KEY) sgname = name if name in const.ENTITY_MAP: sgname = const.ENTITY_MAP[name] fields = sg.schema_field_read(sgname) rawents = sg.find(sgname, [['project', 'is', { 'type': 'Project', 'id': 70 }]], list(fields.keys())) pp(rawents) clean = [] for ent in rawents: if 'image' in ent and ent['image']: directory = "data/filestorage/%s/%s/%s" % (name, ent['id'], "image") if not os.path.exists(os.path.dirname(directory)): os.makedirs(os.path.dirname(directory)) sg.download_attachment({'url': ent['image']}, directory) ent['image'] = directory for field in fields: if fields[field]['data_type']['value'] == 'url' and ent[field]: pp(ent) directory = "data/filestorage/%s/%s/%s" % (name, ent['id'], ent[field]['name']) if not isinstance(ent['id'], int): directory = "data/filestorage/%s/%s/%s" % ( name, ent['id']['value'], ent[field]['name']) if not os.path.exists(os.path.dirname(directory)): os.makedirs(os.path.dirname(directory)) sg.download_attachment(ent[field], directory) ent[field] = directory ent[field] = { "value": ent[field], "type": fields[field]['data_type']['value'] } ent.pop("created_at", None) ent.pop("created_by", None) ent.pop("updated_at", None) ent.pop("updated_by", None) ent.pop("filmstrip_image", None) ent.pop("cached_display_name", None) dic = {} dic['type'] = {'type': 'text', 'value': ent.pop('type')} for f in ent: dic[fields[f]['name']['value']] = ent[f] clean.append(dic) return clean
def __init__(self, parent = None): QtGui.QWidget.__init__(self, parent) notificationList = [] # sender, receiver, date, message, noteDict ) notificationList.append( notification("Cyrilc", "john", datetime.datetime.now(), "Wait for approval ! rhooooooo lr lr bon y va oui ou non il est l'heure d'ylller j'ai faim. et de toute facon il est l'heure", "pas") ) notificationList.append( notification("Donat", "john", datetime.datetime.now(), "Peu continuer !", "pas") ) notificationList.append( notification("MikeB", "john", datetime.datetime.now(), "Oui c'est sympas", "pas") ) notificationList.append( notification("Aurelien", "john", datetime.datetime.now(), "Launch Time", "pas") ) notificationList.append( notification("Thomas", "john", datetime.datetime.now(), "Wait for appoval", "pas") ) notificationList.append( notification("James", "john", datetime.datetime.now(), "Approved", "pas") ) notificationList.append( notification("Mike", "john", datetime.datetime.now(), "Aurevoir John !", "pas") ) notificationList.append( notification("Tristan", "john", datetime.datetime.now(), "Bonjour John !", "pas") ) notificationList.append( notification("Eric", "john", datetime.datetime.now(), "Bonjour John !", "pas") ) notificationList.append( notification("Francois", "john", datetime.datetime.now(), "Bonjour John !", "pas") ) path_to_shotgunApi = getPathToShotgunApi() sys.path.append(path_to_shotgunApi) from shotgun_api3 import Shotgun self.SERVER_PATH = "https://nozon.shotgunstudio.com" self.SCRIPT_NAME = 'noteManager' self.SCRIPT_KEY = '30b93ec002ce2e22ecd6fb31fdda6063797deed1d612b4f6ca39e8030104707c' self.sg = Shotgun(self.SERVER_PATH, self.SCRIPT_NAME, self.SCRIPT_KEY) sg_spawnedNotes = self.sg.find("CustomEntity04", [ ['sg_note','is_not', None] ] , ["project"] ) for a in sg_spawnedNotes : print a self.setMinimumWidth(1000) self.setMinimumHeight(50) self.noteBarW = NotificationBar(notificationList, ["jack","popeye","james","conan le barbare"]) button = QtGui.QPushButton("pafpaf") #button.clicked.connect(self.noteBarW.addNotification) lay = QtGui.QVBoxLayout() lay.addWidget(button) lay.addWidget(self.noteBarW) lay.addWidget(QtGui.QPushButton("pafpaf")) self.setLayout(lay) lay.setSpacing(0) lay.setContentsMargins(0,0,0,0) self.show()
def _connectToSG(self, kmode): SERVER_PATH = kmode[KparamSGserver] SCRIPT_USER = kmode[KparamSGscript] SCRIPT_KEY = kmode[KparamSGkey] try: SG = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) return SG except lib.httplib2.ServerNotFoundError, err: raise ShotgunExceptions(msg=err.message, error=err)
def connect_to_shotgun(self): ''' URL - your studio Shotgun url USER can be a human login or a script name KEY - a password in a human case ''' from shotgun_api3 import Shotgun sg = Shotgun(URL, USER, KEY, ca_certs=CACERTS) return sg
def get_standalone_sg(): conf_data = ShotgunConfParser.sg_conf_data() sg_api_path = conf_data.get("sg_api_path") if sg_api_path not in sys.path: sys.path.insert(0, sg_api_path) from shotgun_api3 import Shotgun SERVER_PATH = conf_data.get("sg_site") SCRIPT_NAME = conf_data.get("script_name") SCRIPT_KEY = conf_data.get("api_key") return Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY)
def __init__(self, parent=None): # set up the UI and variable here - don't forget to call updateUI at end super(dMFXsubmitterDialog, self).__init__(parent) self.acceptDrops() self.setupUi(self) # generic call to setup the Ui provided by Qt self.password = '' self.version_file_path = '' self.user = '' self.user_id = '' self.user_name = '' self.user_initials = '' self.submit_movie = False self.movie_file_path = '' self.description = '' self.login_status = False self.allOK = True self.submit_call_track = True self.version_type = 'Shot' self.created_version_id = None self.sg = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) self.sgu = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) self.users_with_initals = INITIALS_LIST self.user_list = [] self.lineEdit_versionFile.dragEnterEvent = types.MethodType( dragEnterEvent, self.lineEdit_versionFile) self.lineEdit_versionFile.dropEvent = types.MethodType( dropEvent, self.lineEdit_versionFile) self.lineEdit_versionFile.setAcceptDrops(True) self.lineEdit_versionFile.setDragEnabled(True) self.lineEdit_forReview.dragEnterEvent = types.MethodType( dragEnterEvent, self.lineEdit_forReview) self.lineEdit_forReview.dropEvent = types.MethodType( dropEvent, self.lineEdit_forReview) self.lineEdit_forReview.setAcceptDrops(True) self.lineEdit_forReview.setDragEnabled(True) # start things happening... get the users from sg and populate them into the drop-down self.update_user_list() self.connect(self, SIGNAL('update'), self.updateUI) self.new_value = 'this is not a new value' #self.emit(SIGNAL("update")) self.updateUI()
def Button_Callback(): print ""+SCRIPT_NAME+" "+VERSION+"\n" print "Connecting to %s..." % (SERVER_PATH), sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) print "\n\nConnected\n\n" # --------------------------------------------------------------------------------------------- # Testing Block BEGIN # --------------------------------------------------------------------------------------------- result = sg.schema_entity_read() pprint(result) print ""+SERVER_PATH+"\n ... completed\n" pass
def getShotsBySeqId(seq_id): site = 'https://chimneypot.shotgunstudio.com' scriptName = 'AssetBrowser' scriptKey = 'c35ab5f5322d4b1e8b6488bb315c03e5f38881ea' sg = Shotgun(site, scriptName, scriptKey) fields = ['id','type','code'] filters = [['sg_sequence','is',{'type':'Sequence','id':seq_id}]] shots= sg.find("Shot",filters,fields) if len(shots) < 1: print "couldn't find any shots" #exit(0) else: None return shots
def getShotsBySeqId(seq_id): site = 'https://chimneypot.shotgunstudio.com' scriptName = 'AssetBrowser' scriptKey = 'c35ab5f5322d4b1e8b6488bb315c03e5f38881ea' sg = Shotgun(site, scriptName, scriptKey) fields = ['id', 'type', 'code'] filters = [['sg_sequence', 'is', {'type': 'Sequence', 'id': seq_id}]] shots = sg.find("Shot", filters, fields) if len(shots) < 1: print "couldn't find any shots" #exit(0) else: None return shots
def getAllProjects(): site = 'https://chimneypot.shotgunstudio.com' scriptName = 'AssetBrowser' scriptKey = 'c35ab5f5322d4b1e8b6488bb315c03e5f38881ea' sg = Shotgun(site, scriptName, scriptKey) fields = ['id','name','type'] projects= sg.find("Project",[],fields) if len(projects) < 1: print "couldn't find any projects" #exit(0) else: print "Found "+str(len(projects))+" projects" # pprint (projects) return projects
def main(script, project): ## get shotgun script information && create the shotgun instance SERVER_PATH = "" SCRIPT_NAME = '' SCRIPT_KEY = '' sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) projectList = getProjectList(sg, logging, project) ## get list of episodes to update episodeList = getEpisodeList(sg, logging, projectList['projectID']) ## for each episode in episode list ## set its path to XML && get shotList and sequenceList for i in range(0, len(episodeList)): ## get the full episode name, episodeID, && duration episodeName = episodeList[i]['code'] episodeID = episodeList[i]['id'] episodeDuration = episodeList[i]['sg_duration'] ## get the episode, xmlName, xmlFolder and path for the episode episode = episodeName.split('_') episode = episode[1] xmlName = episode.lower() + "_shotdata.xml" xmlFolder = projectList[ 'pathToProject'] + '\\05_PROD\\EPISODES\\' + episodeName + "\\99_PIPELINE\\" xmlPath = xmlFolder + xmlName ## get the sequences and shot info sequenceList = getSequenceList(sg, logging, episodeID) shotList = getShotList(sg, logging, episodeID) ## update the XML updateXML(xmlPath, episodeName, episodeDuration, sequenceList, shotList) ## update the episode to active episodeData = {'sg_status_list': 'act'} episodeUpdate = sg.update('Scene', episodeID, episodeData)
def connect(self): settings = copy.deepcopy(self.settings_dict) db_url = getattr(settings, 'SHOTGUN_URL', None) script_name = getattr(settings, 'SHOTGUN_SCRIPT_NAME', None) api_key = getattr(settings, 'SHOTGUN_KEY', None) self.connected = True self.connection = Shotgun(base_url=db_url, script_name=script_name, api_key=api_key)
def get_app_store_credentials(connection): """ Return the validated script for this site to connect to the app store """ (script, key) = __get_app_store_key(connection) # get the proxy string from the connection proxy = get_proxy_from_connection(connection) # connect to the app store try: sg_app_store = Shotgun(constants.SGTK_APP_STORE, script, key, http_proxy=proxy) # pull down the full script information app_store_script = sg_app_store.find_one( "ApiUser", [["firstname", "is", script]], fields=["type", "firstname", "id", "salted_password"]) except Exception: return None return app_store_script
def __init__(self, **kwargs): self.contents_folder = kwargs['contents_folder'] self.linux_username = kwargs['linux_username'] self.job_num = kwargs['job_num'] self.job_name = kwargs['job_name'] self.locate_user_shotgun_id = kwargs['locate_user_shotgun_id'] self.in_or_out = kwargs['in_or_out'] if self.in_or_out == 'in': self.ingested_files = kwargs['ingested_files'] proxy = '###' server_path = '###' convert_datetimes_to_utc = False self.sg = Shotgun(server_path, kwargs['script_name'], kwargs['script_key'], convert_datetimes_to_utc, proxy) self.contents = '' self.title = ''
def get_app_store_credentials(connection, proxy): """ Return the validated script for this site to connect to the app store """ (script, key) = __get_app_store_key(connection) # connect to the app store try: sg_app_store = Shotgun(constants.SGTK_APP_STORE, script, key, http_proxy=proxy, connect=False) # pull down the full script information app_store_script = sg_app_store.find_one( "ApiUser", [["firstname", "is", script]], fields=["type", "firstname", "id", "salted_password"]) except AuthenticationFault: raise InvalidAppStoreCredentialsError( "The Toolkit App Store credentials found in Shotgun are invalid.") return app_store_script
def getAllProjects(): site = 'https://chimneypot.shotgunstudio.com' scriptName = 'AssetBrowser' scriptKey = 'c35ab5f5322d4b1e8b6488bb315c03e5f38881ea' sg = Shotgun(site, scriptName, scriptKey) fields = ['id', 'name', 'type'] projects = sg.find("Project", [], fields) if len(projects) < 1: print "couldn't find any projects" #exit(0) else: print "Found " + str(len(projects)) + " projects" # pprint (projects) return projects
def _log_into_sg(is_headless): """ Ensures that the user is logged into Shotgun. If not logged, the credentials are queried. If out of date, useful defaults are provided. :param bool is_headless: If True, logging won't attempt to ask for credentials. :returns: Shotgun connection and associated HumanUser entity. """ # Assume the file is empty originally. data = _get_credentials_from_file() # No session token, create a new connection. if not data.get("session_token"): return _create_new_connection(is_headless, data) # Try to create a session with the session token that is stored. sg = Shotgun(data["site"], session_token=data["session_token"]) try: return sg, _get_self(sg, data["login"]) except AuthenticationFault: pass print "Session token expired. Retrieving password from keyring." password = _get_password(data["site"], data["login"]) # If there is no password, ask for the credentials from scratch. if not password: print "Password not found in keyring or empty." return _create_new_connection(is_headless, data) try: sg = Shotgun(data["site"], login=data["login"], password=password) data["session_token"] = sg.get_session_token() with open(_get_credential_file_path(), "w") as f: json.dump(data, f) return sg, _get_self(sg, data["login"]) except AuthenticationFault: print "Password in keychain doesnt't seem to work. Did you change it?" return _create_new_connection(is_headless, data)
def are_credentials_expired(self): """ Checks if the credentials for the user are expired. This check is done solely on the Shotgun side. If SSO is being used, we do not attempt to contact the IdP to validate the session. :returns: True if the credentials are expired, False otherwise. """ print('creation expired') logger.debug( "Connecting to shotgun to determine if credentials have expired..." ) sg = Shotgun(self.get_host(), session_token=self.get_session_token(), http_proxy=self.get_http_proxy()) try: sg.find_one("HumanUser", []) return False except ProtocolError as e: # One potential source of the error is that our SAML claims have # expired. We check if we were given a 302 and the # saml_login_request URL. # But if we get there, it means our session_token is still valid # as far as Shotgun is concerned. if (e.errcode == httplib.FOUND and "location" in e.headers and e.headers["location"].endswith( "/saml/saml_login_request")): # If we get here, the session_token is still valid. logger.debug( "The SAML claims have expired. But the session_token is still valid" ) return False else: logger.error( "Unexpected exception while validating credentials: %s" % e) return True except AuthenticationFault: return True
def __init__(self, parent = None): # set up the UI and variable here - don't forget to call updateUI at end super(dMFXsubmitterDialog,self).__init__(parent) self.acceptDrops() self.setupUi(self) # generic call to setup the Ui provided by Qt self.password = '' self.version_file_path = '' self.user = '' self.user_id = '' self.user_name = '' self.user_initials = '' self.submit_movie = False self.movie_file_path = '' self.description = '' self.login_status = False self.allOK = True self.submit_call_track = True self.version_type = 'Shot' self.created_version_id = None self.sg = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) self.sgu = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) self.users_with_initals = INITIALS_LIST self.user_list = [] self.lineEdit_versionFile.dragEnterEvent = types.MethodType(dragEnterEvent,self.lineEdit_versionFile) self.lineEdit_versionFile.dropEvent = types.MethodType(dropEvent,self.lineEdit_versionFile) self.lineEdit_versionFile.setAcceptDrops(True) self.lineEdit_versionFile.setDragEnabled(True) self.lineEdit_forReview.dragEnterEvent = types.MethodType(dragEnterEvent,self.lineEdit_forReview) self.lineEdit_forReview.dropEvent = types.MethodType(dropEvent,self.lineEdit_forReview) self.lineEdit_forReview.setAcceptDrops(True) self.lineEdit_forReview.setDragEnabled(True) # start things happening... get the users from sg and populate them into the drop-down self.update_user_list() self.connect(self,SIGNAL('update'),self.updateUI) self.new_value = 'this is not a new value' #self.emit(SIGNAL("update")) self.updateUI()
def setupLightFiles(cb010 = True, cb020 = True, cb030 = True, cb040 = True, cb050 = True, cb060 = True, optimizeEnv = True, rippleLyr = True, bgHillLyr = True, directory = 'I:/bubblebathbay/episodes', episode = 152, shots = 1): ## Initialize Shotgun API base_url = "http://bubblebathbay.shotgunstudio.com" script_name = 'audioUploader' api_key = 'bbfc5a7f42364edd915656d7a48d436dc864ae7b48caeb69423a912b930bc76a' sgsrv = Shotgun(base_url = base_url , script_name = script_name, api_key = api_key, ensure_ascii = True, connect = True) ## Query data from Shotgun data = sgsrv.find('Shot', filters = [["code", "contains", 'ep%s_sh' % episode]], fields = ['code', 'sg_cut_in', 'sg_cut_out', 'sg_tod', 'sg_ocean_type']) if data: if episode: if shots: for each in data: if each['code'].split('_')[-1].strip('sh') in shots: try: cmds.refresh(suspend = True) get_data_from_shotgun(cb010 = cb010, cb020 = cb020, cb030 = cb030, cb040 = cb040, cb050 = cb050, cb060 = cb060, optimizeEnv = optimizeEnv, rippleLyr = rippleLyr, bgHillLyr = bgHillLyr, directory = directory, **each) except: pass finally: cmds.refresh(suspend = False)
from tests import connect from shotgun_api3 import Shotgun if True: sg = connect() else: sg = Shotgun('http://127.0.0.1:8020', 'name', 'key') print sg.server_info proj = sg.create('Project', {'name': 'Mock Project Test'}) seq = sg.create('Sequence', {'code': 'AA', 'project': proj}) shot = sg.create('Shot', {'code': 'AA_001', 'sg_sequence': seq}) print proj print seq print shot # # print sg.find('Project', [('id', 'is_not', 0)], ['name'], order=[ # {'field_name': 'id', 'direction': 'asc'}, # ]) print sg._call_rpc('count', None) exit() print sg.create('Project', {'name': 'Test Project'}) print sg.count() print sg.find_one('Project', [], order=[ {'field_name': 'id', 'direction': 'asc'},
def launch(progressBar, logLabel, filterDataList , app, projectContext = None, sg= None ) : SERVER_PATH = "https://nozon.shotgunstudio.com" SCRIPT_NAME = 'noteManager' SCRIPT_KEY = '3fbb2a5f180457af709fcad231c96ac8a916711427af5a06c47eb1758690f6e4' if not sg : try : from shotgun_api3 import Shotgun sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) except : sg = app.engine.tank.shotgun projectId = None if projectContext : projectId = projectContext else : projectId = app.context.project today = datetime.datetime.utcnow().strftime("%Y%m%d") import os try : os.makedirs("c:/temp/EVENTLOG") except : pass if not progressBar : import glob test = outputLogFileName = "c:/temp/EVENTLOG/eventManager_"+projectId["name"]+"_"+ "*" +".html" outputLogFileName = "c:/temp/EVENTLOG/eventManager_"+projectId["name"]+"_"+ today +".html" if len(glob.glob(test)) : print "skiped" return f = open(outputLogFileName, 'w') f.write("<!DOCTYPE html><html><head><title>Page Title</title></head><body><dir>") def cout(text) : text = text.replace(" "," ") text = text.replace("\n","<br>") text = text.replace("<font color=","<font color=") f.write(str(text)+"<br>\n") eventFilter_List=[] if not filterDataList : filterEvent = event_filter() filterEvent.massTest = 60.0 eventFilter_List.append( filterEvent ) for filterData in filterDataList : eventFilter_List.append( event_filter(*filterData)) if progressBar : progressBar.setFormat("Querying database") textLineList=["<font color='#000000'>Results : </font>"] cout("Retrieving project workstation list : " + str(projectId) ) eventFilterList = ['version_up','save_file_as', 'open_file', 'file_publish', 'new_file','open_file','open_file_snapshot' ] filters = [ ["project", "is", projectId], ["event_type", "in", eventFilterList ] ] wsDictList=[] firstEventLog = None lastEventLog = None eventLogList = sg.find("EventLogEntry", filters, [ "meta" , "created_at"] ) cout("got It ! ") for eventLog in eventLogList : if eventLog["meta"].has_key("ws") : if not eventLog["meta"]["ws"] in wsDictList : wsDictList.append(eventLog["meta"]["ws"]) if not firstEventLog : firstEventLog = eventLog elif firstEventLog["id"] > eventLog["id"] : firstId = eventLog if not lastEventLog : lastEventLog = eventLog elif lastEventLog["id"] < eventLog["id"] : lastEventLog = eventLog if not firstEventLog : print "there's no event for this project " f.close() return textLineList.append(" -> " + " + ".join(wsDictList)) cout("First event " + str(firstEventLog["created_at"]) ) cout("Retrieving every event list since " + str(firstEventLog["created_at"]) ) { "filter_operator": "all", "filters": [ ["created_at", "greater_than", firstEventLog["created_at"]] , ["created_at", "smaller_than", lastEventLog["created_at"]] ] } filters = [ ["created_at", "between", [ firstEventLog["created_at"], lastEventLog["created_at"] ] ] , ["entity", 'is_not', None], ["event_type", "in", eventFilterList ] ] wsDict = {} eventLogList = sg.find("EventLogEntry", filters, [ "meta", "entity", "project", "event_type", "created_at" ] ) cout("got It ! ") for eventLog in eventLogList : thisProject = False if eventLog['project']['id'] == projectId['id'] : thisProject = True dataEvent = sg_Event( eventLog["created_at"], eventLog["entity"], eventLog["event_type"], thisProject, eventLog["id"]) # event_datetime, event_context, event_type, thisProject = True if not wsDict.has_key(eventLog["meta"]["ws"]) : wsDict[eventLog["meta"]["ws"]] = [dataEvent] else : wsDict[eventLog["meta"]["ws"]].append(dataEvent) stepProgressBar = 0 if progressBar : progressBar.setFormat("Computing events") progressBar.setValue(stepProgressBar) ev = 0 workstationDict = {} for workstation,dailyEventQueue in wsDict.iteritems(): contextList = get_contextList(dailyEventQueue) array_2D = makeArray( dailyEventQueue, contextList ) cout(" -> " + str(workstation) ) dayContext_timeTree = calculateArray(array_2D, contextList, eventFilter_List, cout) drawArray(array_2D, eventFilter_List, cout) workstationDict[workstation]=dayContext_timeTree ev+= len(array_2D) stepProgressBar+= 100/len(wsDict.keys()) if progressBar : progressBar.setValue(stepProgressBar) outputText = displayDataContext(workstationDict, cout ) outputText +="<br><br> See full log file :<br>" outputText += str(outputLogFileName) if progressBar : progressBar.setValue(100) progressBar.setFormat("Computing done") logLabel.setText(outputText.replace(" "," ")) cout("done : " + str (ev) ) f.write("</dir></body></html>") f.close() datafileName = "c:/temp/EVENTLOG/eventManager_"+projectId["name"]+"_"+ today +".pkl" displayDataContext_perDay( workstationDict, projectId["name"], datafileName )
''' Call this script from the command line as python delete_actionmenu.py ***you MUST know the ID of the action menu you want to delete and enter it below This is a very stupid script and is provided as a utility only Documentation to come - note that you will have to write a find routine to find the correct ID to delete! Author Tom Stratton / tom at tomstratton dot net ''' from shotgun_api3 import Shotgun from pprint import pprint SERVER_PATH = 'https://*****.shotgunstudio.com' #your server path here SCRIPT_USER = '******' #your script name SCRIPT_KEY = '********' #your key here sg = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) ID_TO_DELELE = 1 sg.delete('ActionMenuItem', ID_TO_DELELE) # note that the id numbers will have to be either found or remembered!
if path.isfile(CONFIG_FILE): #test for existence of config file config = ConfigParser.RawConfigParser() config.read(CONFIG_FILE) SERVER_PATH = config.get( THIS_SCRIPT_CONFIG, 'SERVER_PATH') SCRIPT_USER = config.get( THIS_SCRIPT_CONFIG,'SCRIPT_USER') SCRIPT_KEY = config.get( THIS_SCRIPT_CONFIG,'SCRIPT_KEY') CURRENT_VERSION_FIELD = config.get( THIS_SCRIPT_CONFIG, 'CURRENT_VERSION_FIELD') else: raise ConfigError('Your server side configuration file is missing!') #set up fields variable to contain the Version fields that we want to retreive - 'entity' is the Link field which should link to a Shot # NOTE - if any version is NOT linked to something via the entity field bad things will happen! fields = ['id', 'entity', 'sg_asset_type', ] # version id, shot info, "version" #initialize shotgun sg = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) # Create instance of FieldStorage to process the POST data sent to this script form = cgi.FieldStorage() # Get data from fields selected_ids_str = form.getvalue('selected_ids') form_project_id = form.getvalue('project_id') # and convert to values that can be used by Shotgun API (list and ints) version_ids=[int(x) for x in selected_ids_str.split(',')] # list of ints from a string project_id =int(form_project_id) # integer from string success = True # keep track of errors so that true success for all requests can be reported to the user filters = [ ['project','is',{'type':'Project','id':project_id}],
''' from shotgun_api3 import Shotgun from pprint import pprint SERVER_PATH = 'http://****.shotgunstudio.com' #your server path here SCRIPT_USER = '******' #your script name SCRIPT_KEY = '*********' #your key here URL_OF_CGI = "http://www.YOURURL.***/cgi-bin/set_current_version_posthandler_cgi.py" title = "Set As Current Version" entity_type = "Version" selection_required = True # initiate a shotgun API instance sg = Shotgun(SERVER_PATH, SCRIPT_USER, SCRIPT_KEY) #define the action menu item data = { "title": title, "url": URL_OF_CGI, "list_order": 1, "entity_type": entity_type, "selection_required": selection_required, } #Create the menu item menu_item = sg.create("ActionMenuItem", data) pprint(menu_item) # keep the output in case you need to delete the menu later!
__author__ = 'andrew.willis' from shotgun_api3 import Shotgun sg = Shotgun("http://andrewwillish.shotgunstudio.com", "scriptTest", "8b7db88321b7c296541580d1659872d2e63527c040b37b4a2ca0eb47f9da04cb") proj = sg.find_one("Project",[['name','is','KIKO']]) print sg.create("shot",{'code':'SEQ01','project':proj}) #sg.update('Shot',shot['id'],{"sg_status_list":"ip"}) #sg.delete("Shot", 1160)
class DownloadPlaylist(QWidget): def __init__(self, parent = None): QWidget.__init__(self, parent) self.setWindowTitle('Check Playlist local files...') ## Set base vars self.missingLocalFiles = [] self.missingLocalFilesDict = {} self.onlineFilesDict = {} self.tempSGFiles = [] self.badfiles = [] self.badfileBoxes = [] self.tempFileCheckBoxes = [] self.localFileCheckBoxes = [] self.playlist = [] ## Start the UI Build self.mainLayout = QVBoxLayout(self) self.allPlayLists = '' ## Instance the api for talking directly to shotgun. base_url = "http://bubblebathbay.shotgunstudio.com" script_name = 'audioUploader' api_key = 'bbfc5a7f42364edd915656d7a48d436dc864ae7b48caeb69423a912b930bc76a' self.sgsrv = Shotgun(base_url = base_url , script_name = script_name, api_key = api_key, ensure_ascii=True, connect=True) self.allPlayLists = [] ### Now find the playlists from shotgun to use. self._populatePlaylists() self.playListLayout = QHBoxLayout(self) self.playListDropDown = QComboBox(self) self.playListDropDown.setMinimumWidth(200) self.playListDropDown.setMaximumHeight(25) self.playListSearchLabel = QLabel('Search') self.playListSearchInput = QLineEdit(self) self.playListSearchInput.textChanged.connect(self._searchDropDown) self.playListLayout.addWidget(self.playListDropDown) self.playListLayout.addWidget(self.playListSearchLabel) self.playListLayout.addWidget(self.playListSearchInput) self.checkForLocal = QPushButton('Check Local Files Exist...') self.checkForLocal.clicked.connect(self._checkFiles) self.checkForLocal.setStyleSheet("QPushButton {background-color: green}") self.downloadFilesButton = QPushButton('Click to download missing files...') self.downloadFilesButton.clicked.connect(self._processDownload) self.downloadFilesButton.setStyleSheet("QPushButton {background-color: green}") self.updateList() self.mainLayout.addLayout(self.playListLayout) self.mainLayout.addWidget(self.checkForLocal) self.mainLayout.addWidget(self.downloadFilesButton) self.downloadFilesButton.hide() ### Now do the check boxes for files.... ### FILES TO LOCAL PROJECT FOLDER self.scrollLayout = QScrollArea(self) self.scrollLayout.setMinimumHeight(50) self.filesGroupBox = QGroupBox(self.scrollLayout) self.filesGroupBox.setTitle('Files to download to local drive') self.filesGroupBox.setFlat(True) self.scrollLayout.setWidget(self.filesGroupBox) self.scrollLayout.setWidgetResizable(True) self.fileLayout = QGridLayout(self.filesGroupBox) ### FILES TO LOCAL PROJECT FOLDER self.scrollLayout2 = QScrollArea(self) self.scrollLayout2.setMinimumHeight(50) self.filesGroupBox2 = QGroupBox(self.scrollLayout2) self.filesGroupBox2.setTitle('Files to download to temp folder') self.filesGroupBox2.setFlat(True) self.scrollLayout2.setWidget(self.filesGroupBox2) self.scrollLayout2.setWidgetResizable(True) self.tempFilesLayout = QGridLayout(self.filesGroupBox2) ### FILES TO LOCAL PROJECT FOLDER self.scrollLayout3 = QScrollArea(self) self.scrollLayout3.setMinimumHeight(50) self.filesGroupBox3 = QGroupBox(self.scrollLayout3) self.filesGroupBox3.setTitle('BAD FILES! Contact Co-Ord to fix.') self.filesGroupBox3.setFlat(True) self.scrollLayout3.setWidget(self.filesGroupBox3) self.scrollLayout3.setWidgetResizable(True) self.badFileCheckBoxLayout = QGridLayout(self.filesGroupBox3) self.mainLayout.addWidget(self.scrollLayout) self.mainLayout.addWidget(self.scrollLayout2) self.mainLayout.addWidget(self.scrollLayout3) def _populatePlaylists(self): self.pendingReview = self.sgsrv.find('Playlist', filters = [["sg_status", "is", 'rev']], fields=['code', 'created_at', 'versions']) self.delivered = self.sgsrv.find('Playlist', filters = [["sg_status", "is", 'dlvr']], fields=['code', 'created_at', 'versions']) if self.pendingReview: for eachPL in self.pendingReview: self.allPlayLists.append(eachPL) if self.delivered: for eachPL in self.delivered: self.allPlayLists.append(eachPL) def _clearLists(self): #os.system('echo clearing lists now...') if self.localFileCheckBoxes != []: for each in self.localFileCheckBoxes: try: each.setParent(None) sip.delete(each) each = None except RuntimeError: pass if self.tempFileCheckBoxes != []: for each in self.tempFileCheckBoxes: try: each.setParent(None) sip.delete(each) each = None except RuntimeError: pass if self.badfileBoxes != []: for each in self.badfileBoxes: try: each.setParent(None) sip.delete(each) each = None except RuntimeError: pass def _doFileCheckboxes(self): """ Process all the files found into check boxes for processing """ self._clearLists() self.badfileBoxes = [] self.tempFileCheckBoxes = [] self.localFileCheckBoxes = [] ## LOCAL DOWNLOAD ## First add the ALL checkbox self.ALL_Local = QCheckBox(self) self.ALL_Local.setChecked(False) self.ALL_Local.setText('Toggle All') self.ALL_Local.toggled.connect(self._toggleAllLocal) self.fileLayout.addWidget(self.ALL_Local, 0, 0) self.colCount = 5 r = 1 c = 1 for eachType in sorted(self.missingLocalFiles): self.fileCheckBox = QCheckBox(self) self.fileCheckBox.setChecked(True) self.fileCheckBox.setText(eachType) self.localFileCheckBoxes.append(self.fileCheckBox) if c == self.colCount: r = r + 1 c = 1 self.fileLayout.addWidget(self.fileCheckBox, r, c) c = c + 1 ## TEMP FILES ## First add the ALL checkbox self.ALL_Temp = QCheckBox(self) self.ALL_Temp.setChecked(False) self.ALL_Temp.setText('Toggle All') self.ALL_Temp.toggled.connect(self._toggleAllTemp) self.tempFilesLayout.addWidget(self.ALL_Temp, 0, 0) self.colCount = 5 r = 1 c = 1 for eachType in sorted(self.tempSGFiles): self.fileCheckBox = QCheckBox(self) self.fileCheckBox.setChecked(True) self.fileCheckBox.setText(eachType) self.tempFileCheckBoxes.append(self.fileCheckBox) if c == self.colCount: r = r + 1 c = 1 self.tempFilesLayout.addWidget(self.fileCheckBox, r, c) c = c + 1 ## BAD FILES self.colCount = 5 r = 1 c = 1 for eachType in sorted(self.badfiles): self.fileCheckBox = QLabel(self) self.fileCheckBox.setText(eachType) self.fileCheckBox.setStyleSheet("QLabel {background-color:red; text-align:center;}") self.badfileBoxes.append(self.fileCheckBox) if c == self.colCount: r = r + 1 c = 1 self.badFileCheckBoxLayout.addWidget(self.fileCheckBox, r, c) c = c + 1 self.repaint() def _toggleAllTemp(self): for eachBox in self.tempFileCheckBoxes: if self.ALL_Temp.isChecked(): eachBox.setChecked(True) else: eachBox.setChecked(False) def _toggleAllLocal(self): for eachBox in self.localFileCheckBoxes: if self.ALL_Local.isChecked(): eachBox.setChecked(True) else: eachBox.setChecked(False) def _searchDropDown(self): self.playListDropDown.clear() for eachPlayList in sorted(self.allPlayLists): if str(self.playListSearchInput.text()) in eachPlayList['code']: self.playListDropDown.addItem(eachPlayList['code']) def updateList(self): self.playListDropDown.clear() for eachPlayList in sorted(self.allPlayLists): self.playListDropDown.addItem(eachPlayList['code']) def _setPlaylist(self): """ Set the playlist from the current pulldown """ for eachPlayList in self.allPlayLists: if eachPlayList['code'] == self.playListDropDown.currentText(): print 'Fetching versions for %s now..' % eachPlayList['code'] self.playlist = eachPlayList else: pass def _getVersionInfo(self, versionData): """ Function to process the version data from shotgun If we are under darwin osx change the path to local to match our project drives so the path to local is correct for osx """ getVersInfo = self.sgsrv.find_one('Version', filters = [["id", "is", versionData['id']]], fields = ['code', 'sg_path_to_movie', 'sg_uploaded_movie']) pathToLocal = getVersInfo['sg_path_to_movie'] ## Process the osx pathToLocal if sys.platform == 'darwin': if pathToLocal: pathToLocal = pathToLocal.replace('I:', '/_projects').replace("\\", "/") getVersInfo['sg_path_to_movie'] = pathToLocal ## Now process the URL try: url = getVersInfo['sg_uploaded_movie']['url'] except TypeError: url = None return getVersInfo['code'], pathToLocal, url, getVersInfo def _checkFiles(self): self._clearLists() os.system('cls') #os.system('echo Checking Playlist: %s \n' % self.playListDropDown.currentText()) os.system('echo Looking for files on local drive....\n') self.tempSGFiles = [] self.missingLocalFiles = [] self.missingLocalFilesDict = {} self.onlineFilesDict = {} self.badfiles = [] self.getVersions = [] self.playList = [] self.missingUploadedMoveMsg = 'MISSING UPLOADED MOVIE. THIS NEEDS TO BE FIXED. PLEASE CONTACT CO-ORD ABOUT THIS!' ###################################################### ## Set the state for the UI into checking for files... self.checkForLocal.setText('Checking files...') self.checkForLocal.setStyleSheet("QPushButton {background-color: yellow}") self.downloadFilesButton.hide() self.repaint() ###################################################### ###################################################### ## Scan each path to local and then check for existing files. self._setPlaylist() self.getVersions = self.playlist['versions'] if self.getVersions: for eachVer in self.playlist['versions']: ###################################################### ## Fetch the version information from shotgun versionName, pathToLocal, url, getVersInfo = self._getVersionInfo(eachVer) print 'Checking \t%s now...' % versionName ###################################################### ## If we have a valid path to local in shotgun.... if pathToLocal and 'B:' not in pathToLocal and 'Shotgun' not in pathToLocal: print 'Path: \t\t%s' % pathToLocal ## Now check to see if the path to the file is true or not. pathExists = os.path.isfile(pathToLocal) os.system('echo EXISTS?: \t%s' % pathExists) ## If it doesn't exist mark this file for download to local path if not pathExists: ## Check if we can download this file from an uploaded movie!?! if url: os.system('echo DL: \t\t%s\n' % versionName) os.system('echo .') ## Add the file to the list for the check-boxes, and the dictionary used for download info if eachVer['name'] not in self.missingLocalFiles: self.missingLocalFiles.append(versionName)## For the check-boxes self.missingLocalFilesDict[versionName] = getVersInfo ## For the down loader else: os.system('echo %s %s' % (versionName, self.missingUploadedMoveMsg)) os.system('echo .') ## Add the file to the bad list of files as we are missing an online uploaded file to download. if eachVer['name'] not in self.badfiles: self.badfiles.append(eachVer['name']) ## If the file does exist on the local HD, check to see if we have to resume it or not. ## Check the file sizes match if they don't add to missing files.. else: if url: ## Find the online file size and compare it against the local file size on disk u = urllib2.urlopen(url) meta = u.info() onlinefileSize = int(meta.getheaders("Content-Length")[0]) localmeta = os.stat('%s' % pathToLocal) if not localmeta.st_size == onlinefileSize: os.system('echo Filesize mismatch for %s marking for download again..\n' % pathToLocal.split(os.sep)[-1]) os.system('echo Size On Disk: %.8f \tSize On SGun: %.8f' % (float(localmeta.st_size)/1000000, float(onlinefileSize)/1000000)) #print localmeta.st_size #17,892,757 bytes os.system('echo .') ## Add the file to the list for the check-boxes, and the dictionary used for download info if eachVer['name'] not in self.missingLocalFiles: self.missingLocalFiles.append(versionName)## For the check-boxes self.missingLocalFilesDict[versionName] = getVersInfo ## For the down loader else: os.system('echo %s %s' % (versionName, self.missingUploadedMoveMsg)) os.system('echo .') if eachVer['name'] not in self.badfiles: self.badfiles.append(eachVer['name']) else: ## We don't have a valid path in shotgun to a local file! if url: ## But we do have a url to an uploaded movie... os.system('echo No local path found in shotgun field for %s. File will be saved to Temp folder...' % versionName) os.system('echo .') ## Add the file to the list for the check-boxes, and the dictionary used for download info if eachVer['name'] not in self.tempSGFiles: self.tempSGFiles.append(getVersInfo['code']) ## for the check-boxes self.onlineFilesDict[getVersInfo['code']] = getVersInfo ## For the down loader else: ## OOPS this is missing both a local path and uploaded movie in shotgun :( :( :( os.system('echo %s MISSING UPLOADED MOVIE AND LOCAL PATH!!!! THIS NEEDS TO BE FIXED. PLEASE CONTACT CO-ORD ABOUT THIS!' % versionName) os.system('echo .') ## Add the file to the list of bad files. self.badfiles.append(eachVer['name']) else: print '%s has NO versions! This playlist is empty! PLEASE CONTACT CO-ORD ABOUT THIS!' % self.playlist['code'] ######################################## ## NOW CHECK THE FINAL LISTS AND SET THE UI INTO THE CORRECT STATE ## EITHER READY FOR DOWNLOAD OR START A NEW CHECK if self.missingLocalFiles or self.tempSGFiles or self.badfiles: self.downloadFilesButton.show() self.checkForLocal.setText('Check Complete...click to check again...') self.checkForLocal.setStyleSheet("QPushButton {background-color: orange}") ## Now process the check box lists... self._doFileCheckboxes() else: os.system('echo CHECKS OUT OKAY!! ALL FILES EXIST FOR THIS PLAYLIST.....\n') self.checkForLocal.setText('Check Local File Exist...') self.checkForLocal.setStyleSheet("QPushButton {background-color: green}") ## Now clear out all the checkboxes. self._clearLists() def _downloadFile(self, pathToLocal, url): """ Main download function """ fileName = pathToLocal.split(os.sep)[-1] u = urllib2.urlopen(url) meta = u.info() file_size = int(meta.getheaders("Content-Length")[0]) #os.system('cls') os.system('echo Downloading: %s \tSize: %.2f MB\n' % (fileName, float(file_size)/1000000)) f = open(pathToLocal, 'wb') file_size_dl = 0 block_sz = 8192 while True: buffer = u.read(block_sz) if not buffer: break file_size_dl += len(buffer) f.write(buffer) status = r".........%20s: %34.2f MB [%3.2f%%]" % (fileName, float(file_size_dl)/1000000, file_size_dl * 100. / file_size) status = status + chr(8)*(len(status)+1) print status, f.close() os.system('echo \n') os.system('echo Download Complete....') def _resumeDownload(self, pathToLocal, url, localSize, totalSGFileSize): """ Resume download function """ fileName = pathToLocal.split(os.sep)[-1] req = urllib2.Request(url) remainingB = totalSGFileSize - localSize ## Now set the header for the range req.headers["Range"] = "bytes=%s-%s" % (localSize, totalSGFileSize) u = urllib2.urlopen(req) #create the connection meta = u.info() file_size = int(meta.getheaders("Content-Length")[0]) #os.system('cls') os.system('echo Resuming: %s \tSize: %.2f MB \tRemaining: %.2f MB\n' % (fileName, float(totalSGFileSize)/1000000, float(remainingB)/1000000)) f = open(pathToLocal, 'ab') file_size_dl = 0 block_sz = 8192 while True: buffer = u.read(block_sz) if not buffer: break file_size_dl += len(buffer) ## Now write to the file.. f.write(buffer) ## Now print the satus status = r".........%20s: %34.2f Mb [%3.2f%%]" % (fileName, float(file_size_dl)/1000000, file_size_dl * 100. / totalSGFileSize) status = status + chr(8)*(len(status)+1) print status, f.close() os.system('echo \n') os.system('echo Download Complete....') def _preDownload(self, pathToLocal, url): """ Function to check if the file exists on the local hd if it doesn't match that of the online file """ ## First check to see if the file exists! if not os.path.isfile(pathToLocal): ## Do a full download of the file now. self._makeDirectories(pathToLocal) self._downloadFile(pathToLocal, url) else: ## The file exists, lets check to resume or skip it. u = urllib2.urlopen(url) meta = u.info() onlinefileSize = int(meta.getheaders("Content-Length")[0]) localmeta = os.stat(pathToLocal) if localmeta.st_size == onlinefileSize: os.system('echo %s already down-loaded skipping...\n' % pathToLocal) return elif localmeta.st_size > onlinefileSize: ## Delete it, it's a bad download.... print 'Removing %s ...' % pathToLocal.split(os.sep)[-1] os.remove(pathToLocal) try: self._downloadFile(pathToLocal, url) except IOError, e: os.system('echo OH NO!: %s' % e) os.system('echo Try a restart of the application and check the files again to solve this problem...') else:
def __init__(self, parent = None): QWidget.__init__(self, parent) self.setWindowTitle('Check Playlist local files...') ## Set base vars self.missingLocalFiles = [] self.missingLocalFilesDict = {} self.onlineFilesDict = {} self.tempSGFiles = [] self.badfiles = [] self.badfileBoxes = [] self.tempFileCheckBoxes = [] self.localFileCheckBoxes = [] self.playlist = [] ## Start the UI Build self.mainLayout = QVBoxLayout(self) self.allPlayLists = '' ## Instance the api for talking directly to shotgun. base_url = "http://bubblebathbay.shotgunstudio.com" script_name = 'audioUploader' api_key = 'bbfc5a7f42364edd915656d7a48d436dc864ae7b48caeb69423a912b930bc76a' self.sgsrv = Shotgun(base_url = base_url , script_name = script_name, api_key = api_key, ensure_ascii=True, connect=True) self.allPlayLists = [] ### Now find the playlists from shotgun to use. self._populatePlaylists() self.playListLayout = QHBoxLayout(self) self.playListDropDown = QComboBox(self) self.playListDropDown.setMinimumWidth(200) self.playListDropDown.setMaximumHeight(25) self.playListSearchLabel = QLabel('Search') self.playListSearchInput = QLineEdit(self) self.playListSearchInput.textChanged.connect(self._searchDropDown) self.playListLayout.addWidget(self.playListDropDown) self.playListLayout.addWidget(self.playListSearchLabel) self.playListLayout.addWidget(self.playListSearchInput) self.checkForLocal = QPushButton('Check Local Files Exist...') self.checkForLocal.clicked.connect(self._checkFiles) self.checkForLocal.setStyleSheet("QPushButton {background-color: green}") self.downloadFilesButton = QPushButton('Click to download missing files...') self.downloadFilesButton.clicked.connect(self._processDownload) self.downloadFilesButton.setStyleSheet("QPushButton {background-color: green}") self.updateList() self.mainLayout.addLayout(self.playListLayout) self.mainLayout.addWidget(self.checkForLocal) self.mainLayout.addWidget(self.downloadFilesButton) self.downloadFilesButton.hide() ### Now do the check boxes for files.... ### FILES TO LOCAL PROJECT FOLDER self.scrollLayout = QScrollArea(self) self.scrollLayout.setMinimumHeight(50) self.filesGroupBox = QGroupBox(self.scrollLayout) self.filesGroupBox.setTitle('Files to download to local drive') self.filesGroupBox.setFlat(True) self.scrollLayout.setWidget(self.filesGroupBox) self.scrollLayout.setWidgetResizable(True) self.fileLayout = QGridLayout(self.filesGroupBox) ### FILES TO LOCAL PROJECT FOLDER self.scrollLayout2 = QScrollArea(self) self.scrollLayout2.setMinimumHeight(50) self.filesGroupBox2 = QGroupBox(self.scrollLayout2) self.filesGroupBox2.setTitle('Files to download to temp folder') self.filesGroupBox2.setFlat(True) self.scrollLayout2.setWidget(self.filesGroupBox2) self.scrollLayout2.setWidgetResizable(True) self.tempFilesLayout = QGridLayout(self.filesGroupBox2) ### FILES TO LOCAL PROJECT FOLDER self.scrollLayout3 = QScrollArea(self) self.scrollLayout3.setMinimumHeight(50) self.filesGroupBox3 = QGroupBox(self.scrollLayout3) self.filesGroupBox3.setTitle('BAD FILES! Contact Co-Ord to fix.') self.filesGroupBox3.setFlat(True) self.scrollLayout3.setWidget(self.filesGroupBox3) self.scrollLayout3.setWidgetResizable(True) self.badFileCheckBoxLayout = QGridLayout(self.filesGroupBox3) self.mainLayout.addWidget(self.scrollLayout) self.mainLayout.addWidget(self.scrollLayout2) self.mainLayout.addWidget(self.scrollLayout3)
def __init__(self, path, name, key, project): self.SERVER_PATH = path self.SCRIPT_NAME = name self.SCRIPT_KEY = key self.project_id = project self.sg = Shotgun(self.SERVER_PATH, self.SCRIPT_NAME, self.SCRIPT_KEY)
class studioShotgun(object): def __init__(self, path, name, key, project): self.SERVER_PATH = path self.SCRIPT_NAME = name self.SCRIPT_KEY = key self.project_id = project self.sg = Shotgun(self.SERVER_PATH, self.SCRIPT_NAME, self.SCRIPT_KEY) #---------------------------------------------------------------------- ## set Project id by ID def setProjectId(self, newId): self.project_id = newId #---------------------------------------------------------------------- ## set Project id by ID def setProjectName(self, name): newId = 0 projects = self.sg.find('Project', [], ['name']) for project in projects: if project['name'] == name: newId = project['id'] self.project_id = newId #---------------------------------------------------------------------- ## find asset by name def findAssetByName(self, name): fields = ['id', 'code', 'sg_asset_type', 'tasks'] filters = [['project', 'is', {'type': 'Project', 'id': self.project_id}], ['code', 'is', name]] result = self.sg.find('Asset', filters, fields) return result #---------------------------------------------------------------------- ## find shot by name def findShotByName(self, episode, shot): fields = ['id', 'code', 'sg_asset_type', 'tasks', 'sg_sequence'] filters = [['project', 'is', {'type': 'Project', 'id': self.project_id}], ['code', 'is', shot]] result = self.sg.find('Shot', filters, fields) for x in result: name = x['sg_sequence']['name'].split('_')[0] if name == episode: return x return [] #---------------------------------------------------------------------- ## upload thumbnail to asset def uploadThumbnail(self, asset, thumbnail): upload = 0 asset = self.findAssetByName(asset) if asset: upload = self.sg.upload_thumbnail("Asset", asset[0]['id'], thumbnail) return upload #---------------------------------------------------------------------- ## create new asset def createAsset(self, asset, assetType, template, assetFile='', description=''): ## find asset asset = self.findAssetByName(asset) if not asset: ## create asset + task template filters = [['code', 'is', template]] template = self.sg.find_one('TaskTemplate', filters) data = {'project': {'type': 'Project', 'id': self.project_id}, 'code': asset, 'description': description, 'sg_asset_type': assetType, 'sg_url_perforce': assetFile, 'task_template': template} asset = self.sg.create('Asset', data) return asset #---------------------------------------------------------------------- ## update file path in asset def updateAssetFilePath(self, asset, filename): asset = self.findAssetByName(asset) data = {'sg_url_perforce': filename} asset = self.sg.update("Asset", asset[0]['id'], data) return asset #---------------------------------------------------------------------- ## create new version def createVersion(self, shotId, taskId, userId, filename, comment=''): curTime = datetime.now().strftime('%Y.%m.%d_%H.%M') fname = str(filename.split('/')[-1].split('.')[0]) + '_' + curTime data = {'project': {'type': 'Project', 'id': self.project_id}, 'code': fname, 'description': comment, 'sg_status_list': 'rev', 'entity': {'type': 'Shot', 'id': shotId}, 'sg_task': {'type': 'Task', 'id': taskId}, 'user': {'type': 'HumanUser', 'id': userId}} result = self.sg.create('Version', data) upload = self.sg.upload('Version', result['id'], filename, 'sg_uploaded_movie') return [result, upload] #---------------------------------------------------------------------- ## get user data from shotgum def getUserData(self, user): filters = [['login', 'is', user]] user = self.sg.find('HumanUser', filters) if user: return user[0] else: return [] #---------------------------------------------------------------------- ## get all user from project def getAllUsers(self): fields = ['id', 'login', 'name', 'projects', 'department'] filters = [['projects', 'is', {'type': 'Project', 'id': self.project_id}]] users = self.sg.find('HumanUser', filters, fields) return users