Example #1
0
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})    
Example #2
0
    def __init__(self):

        sgSite = 'https://chimneypot.shotgunstudio.com'
        scriptName = 'dBase'
        scriptKey = '729a76955455909c79f6d90262bb9fbe9186b92b'

        self.db = Shotgun(sgSite, scriptName, scriptKey)
Example #3
0
 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
Example #5
0
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)
Example #6
0
    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']
Example #7
0
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) )
Example #8
0
    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})
Example #10
0
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)
Example #11
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()
Example #12
0
    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"
Example #13
0
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
    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
Example #16
0
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
Example #17
0
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
Example #18
0
    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
Example #20
0
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'])
Example #21
0
    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 _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 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
Example #25
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()
Example #26
0
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)
Example #27
0
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))
Example #28
0
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()
Example #30
0
 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
Example #32
0
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 
Example #38
0
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)
Example #39
0
    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
Example #41
0
    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 = ''
Example #42
0
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
Example #44
0
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)
Example #45
0
    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()
Example #47
0
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)
Example #48
0
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(" ","&nbsp;")
        text = text.replace("\n","<br>")
        text = text.replace("<font&nbsp;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("&nbsp; &nbsp; &nbsp;->&nbsp;" +   " + ".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("&nbsp; &nbsp; &nbsp;->&nbsp;" + 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(" ","&nbsp;"))

    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!
Example #53
0
 def _create_instance(self):
     instance = Shotgun(self.base_url, 'dummy_script_name', 'dummy_api_key', connect=False)
     instance.config = self.config
     return instance
__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)
Example #57
0
 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)
Example #58
0
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