def importEntities(conn, cur, sg): debug.debug("starting import Entities", debug.INFO) entities = sg.schema_entity_read() classes = entities.keys() classes.sort() for entityType in classes: if entityType in ["EventLogEntry"]: continue if len(UPDATE_ONLY) > 0 and entityType not in UPDATE_ONLY: continue entityName = cleanSysName(entities[entityType]["name"]["value"]) if entityType.endswith("Connection"): entityName = entityType debug.debug("import entities of type " + entityType) fieldList = connectors.getClassOfType(entityName).shotgun_fields debug.debug("deleting entities of type " + entityType) query = "DELETE FROM \"%s\"" % (entityType) cur.execute(query) debug.debug("loading entities of type " + entityType) objects = sg.find(entityType, [["id", "greater_than", 0]], fieldList.keys()) for obj in objects: values = [] names = [] reprs = [] for fieldName in fieldList.keys(): sgType = fieldList[fieldName]['data_type']['value'] convFunc = connectors.getConversionSg2Pg(sgType) if convFunc != None: names.append("\"%s\"" % fieldName) if sgType == "image" and obj[fieldName] != None: thumbnails.saveShotgunImageLocally(obj[fieldName]) if sgType == "multi_entity": reprs.append("%s::entity_sync[]") else: reprs.append("%s") values.append(convFunc(obj[fieldName])) query = "INSERT INTO \"%s\" (%s) VALUES (%s)" % ( entityType, ", ".join(names), ", ".join(reprs)) debug.debug(cur.mogrify(str(query), values), debug.DEBUG) cur.execute(query, values) conn.commit() debug.debug("finnished import Entities", debug.INFO)
def _getEntity( self, entityType, localID, remoteID ): entityClass = connectors.getClassOfType( entityType ) if not entityClass: raise web.notfound() entity = factories.getObject( entityType, remote_id = intOrNone( remoteID ), local_id = intOrNone( localID ) ) return entity
def importEntities(conn, cur, sg): debug.debug("starting import Entities", debug.INFO) entities = sg.schema_entity_read() classes = entities.keys() classes.sort() for entityType in classes: if entityType in ["EventLogEntry"]: continue if len(UPDATE_ONLY) > 0 and entityType not in UPDATE_ONLY: continue entityName = cleanSysName(entities[entityType]["name"]["value"]) if entityType.endswith("Connection"): entityName = entityType debug.debug("import entities of type " + entityType) fieldList = connectors.getClassOfType(entityName).shotgun_fields debug.debug("deleting entities of type " + entityType) query = 'DELETE FROM "%s"' % (entityType) cur.execute(query) debug.debug("loading entities of type " + entityType) objects = sg.find(entityType, [["id", "greater_than", 0]], fieldList.keys()) for obj in objects: values = [] names = [] reprs = [] for fieldName in fieldList.keys(): sgType = fieldList[fieldName]["data_type"]["value"] convFunc = connectors.getConversionSg2Pg(sgType) if convFunc != None: names.append('"%s"' % fieldName) if sgType == "image" and obj[fieldName] != None: thumbnails.saveShotgunImageLocally(obj[fieldName]) if sgType == "multi_entity": reprs.append("%s::entity_sync[]") else: reprs.append("%s") values.append(convFunc(obj[fieldName])) query = 'INSERT INTO "%s" (%s) VALUES (%s)' % (entityType, ", ".join(names), ", ".join(reprs)) debug.debug(cur.mogrify(str(query), values), debug.DEBUG) cur.execute(query, values) conn.commit() debug.debug("finnished import Entities", debug.INFO)
def POST( self, entityType, localID, remoteID, testdata = None ): """ create an object """ entityClass = connectors.getClassOfType( entityType ) if not entityClass: raise web.notfound() if testdata != None: data = testdata else: self._nocache() data = self._parseInput() entity = createEntity( entityClass, data ) return json.dumps( entity.getDict() )
def getObject( entityType, local_id = None, remote_id = None, includeRetireds = False ): """ return entity of a specific type with given IDs :py:class:`shotgun_replica.entities.Task` :param entityType: either a entities-class or a string (ex. "CustomEntity22") :type entityType: class or str :param local_id: the local id of the object :param remote_id: the remote id (shotgun) of the object :param includeRetireds: include retired (deleted) objects :rtype: object or None if object not available """ classObj = entityType if type( entityType ) == str or type( entityType ) == unicode: classObj = connectors.getClassOfType( entityType ) if not classObj: return None tableName = classObj._type dbc = connectors.DatabaseModificator() filters = [] if remote_id != None and remote_id != UNKNOWN_SHOTGUN_ID: filters.append( "id=%d" % remote_id ) if local_id != None and local_id != UNKNOWN_SHOTGUN_ID: filters.append( "__local_id=%d" % local_id ) if len( filters ) == 0: return None if includeRetireds: sqlFilter = " OR ".join( filters ) else: sqlFilter = "NOT __retired AND " + " OR ".join( filters ) resultList = dbc.getListOfEntities( tableName, sqlFilter, limit = "1" ) if len( resultList ) == 1: return resultList[0] else: return None
def getConnectionEntityAttrName( baseEntityType, linkedEntityType, connEntityName ): """return the attribute-names of the connection-entity""" baseAttrName = replaceCapitalsWithUnderscores( baseEntityType ) linkedAttrName = replaceCapitalsWithUnderscores( linkedEntityType ) debug.debug( ( baseAttrName, linkedAttrName ) ) if baseAttrName != linkedAttrName: if linkedAttrName == "human_user": linkedAttrName = "user" return ( baseAttrName, linkedAttrName ) else: theclass = connectors.getClassOfType( connEntityName ) baseAttrNamePrefixed = "source_" + baseAttrName linkedAttrNamePrefixed = "dest_" + linkedAttrName if theclass.shotgun_fields.has_key( baseAttrNamePrefixed ) and theclass.shotgun_fields.has_key( linkedAttrNamePrefixed ): debug.debug( ( baseAttrNamePrefixed, linkedAttrNamePrefixed ) ) return ( baseAttrNamePrefixed, linkedAttrNamePrefixed ) elif theclass.shotgun_fields.has_key( baseAttrName ) and theclass.shotgun_fields.has_key( "parent" ): return ( baseAttrName, "parent" )
def _changeEntity(self, event): """ process a change entity event """ entity = event["corr_entity"] entityObj = getObject(entity.type, remote_id=entity.remote_id, local_id=entity.local_id, includeRetireds=True) if entityObj == None: exception = "Object not available %s local:%s remote:%s\n\n" % ( str(entity.type), str(entity.local_id), str(entity.remote_id)) self._setProcessed(event, exception=exception) return False data = event["changed_values"] fieldDefs = connectors.getClassOfType(entity.type).shotgun_fields hasFields = True for attribute in data.keys(): if not fieldDefs.has_key(attribute): hasFields = False if not hasFields: exception = "some fields not available %s local:%s remote:%s" % ( str(entity.type), str(entity.local_id), str(entity.remote_id)) self._setProcessed(event, exception=exception) return False else: for attribute in data.keys(): dataType = fieldDefs[attribute]["data_type"]["value"] value = data[attribute] if value == None: continue if dataType == "float": data[attribute] = float(value) elif dataType == "entity": data[attribute] = getSgObj(value) elif dataType == "multi_entity": newvalue = [] for sgObj in value: newvalue.append(getSgObj(sgObj)) data[attribute] = newvalue elif dataType == "date_time": if type(value) == unicode or type(value) == str: data[attribute] = datetime.datetime.strptime( value, "%Y-%m-%d %H:%M:%S") if value.tzinfo == None: from pytz import timezone zurich = timezone("Europe/Zurich") value = zurich.localize(value) elif dataType == "date": if type(value) == unicode or type(value) == str: data[attribute] = datetime.datetime.strptime( value, "%Y-%m-%d").date() elif dataType == "duration": if type(value) == float: data[attribute] = int(value * 60) if fieldDefs.has_key( "sg_remotely_updated_by") and event["updated_by"] != None: data["sg_remotely_updated_by"] = event["updated_by"].getSgObj() try: debug.debug(data) if entityObj.getType().endswith( "Connection") and entityObj.getRemoteID( ) == UNKNOWN_SHOTGUN_ID: remoteID = connectors.getRemoteID(entityObj.getType(), entityObj.getLocalID()) if remoteID == None or remoteID == UNKNOWN_SHOTGUN_ID: # Connection-Entities need first the corresponding remote-id # they get that by the shotgun-event triggered by the event that causes this connection-entity to be created # so we simply have to wait and do nothing (hopefully ;) debug.info( "waiting for a connection-entitiy to appear %s" % (str(entityObj), )) return True self.sg.update(entityObj.getType(), entityObj.getRemoteID(), data) self._setProcessed(event) return True except shotgun_api3.Fault, fault: #event["type"] = "CouchdbChangeEvents" exception = "Error %s" % (str(fault)) self._setProcessed(event, exception=exception) return False
def main(): """ to be called """ sg_url = "https://devilfant.shotgunstudio.com" sg_test1 = {"name": "test1", "key": "e398654c5ec1c6f7c8f71ead33349c58bbf4a058"} sg1 = Shotgun( sg_url, sg_test1["name"], sg_test1["key"] ) entities = sg1.schema_entity_read() pprint( entities ) moduleString = """# -*- coding: utf-8 -*- \"""@package shotgun_replica.entities Shotgun Entities THIS FILE IS AUTO GENERATED DO NOT EDIT IT DIRECTLY change create_shotgun_classes.py instead \""" from shotgun_replica._entity_mgmt import _ShotgunEntity from shotgun_replica import %s """ % FIELDDEFINITIONSMODULE fieldDefModuleString = """# -*- coding: utf-8 -*- \""" THIS FILE IS AUTO GENERATED DO NOT EDIT IT DIRECTLY change create_shotgun_classes.py instead \""" """ classes = entities.keys() classes.sort() for entitycode in classes: print "processing %s\n" % entitycode fieldDefs = sg1.schema_field_read( entitycode ) try: theclass = connectors.getClassOfType( entitycode ) localFieldDefs = theclass.shotgun_fields except ImportError: localFieldDefs = None except AttributeError: localFieldDefs = None if fieldDefs != localFieldDefs: debug.error( "%s fielddefs differ from shotgun to local" % entitycode ) entityname = cleanSysName( entities[entitycode]["name"]["value"] ) if entitycode.endswith( "Connection" ): entityname = entitycode ( classCode, fieldDefCode ) = _createClassCode( entities, entitycode, fieldDefs, entityname ) moduleString += classCode fieldDefModuleString += fieldDefCode _createDBFields( entitycode, fieldDefs, entityname ) packageDir = os.path.dirname( __file__ ) entityFilename = os.path.join( packageDir, 'entities.py' ) entity_file = open( entityFilename, 'w' ) entity_file.write( moduleString ) entity_file.close() fieldDefFilename = os.path.join( packageDir, '%s.py' % FIELDDEFINITIONSMODULE ) fieldDef_file = open( fieldDefFilename, 'w' ) fieldDef_file.write( fieldDefModuleString ) fieldDef_file.close()
def _changeEntity( self, event ): """ process a change entity event """ entity = event["corr_entity"] entityObj = getObject( entity.type, remote_id = entity.remote_id, local_id = entity.local_id, includeRetireds = True ) if entityObj == None: exception = "Object not available %s local:%s remote:%s\n\n" % ( str( entity.type ), str( entity.local_id ), str( entity.remote_id ) ) self._setProcessed( event, exception = exception ) return False data = event["changed_values"] fieldDefs = connectors.getClassOfType( entity.type ).shotgun_fields hasFields = True for attribute in data.keys(): if not fieldDefs.has_key( attribute ): hasFields = False if not hasFields: exception = "some fields not available %s local:%s remote:%s" % ( str( entity.type ), str( entity.local_id ), str( entity.remote_id ) ) self._setProcessed( event, exception = exception ) return False else: for attribute in data.keys(): dataType = fieldDefs[attribute]["data_type"]["value"] value = data[attribute] if dataType == "float": data[attribute] = float( value ) elif dataType == "entity": data[attribute] = getSgObj( value ) elif dataType == "multi_entity": newvalue = [] for sgObj in value: newvalue.append( getSgObj( sgObj ) ) data[attribute] = newvalue elif dataType == "date_time": if type( value ) == type( u"" ): data[attribute] = datetime.datetime.strptime( value, "%Y-%m-%d %H:%M:%S" ) elif dataType == "date": if type( value ) == type( u"" ): data[attribute] = datetime.datetime.strptime( value, "%Y-%m-%d" ).date() elif dataType == "duration": if type( value ) == float: data[attribute] = int( value * 60 ) if fieldDefs.has_key( "sg_remotely_updated_by" ): data["sg_remotely_updated_by"] = event["updated_by"].getSgObj() try: debug.debug( data ) if entityObj.getType().endswith( "Connection" ) and entityObj.getRemoteID() == UNKNOWN_SHOTGUN_ID: remoteID = connectors.getRemoteID( entityObj.getType(), entityObj.getLocalID() ) if remoteID == None or remoteID == UNKNOWN_SHOTGUN_ID: # Connection-Entities need first the corresponding remote-id # they get that by the shotgun-event triggered by the event that causes this connection-entity to be created # so we simply have to wait and do nothing (hopefully ;) debug.info( "waiting for a connection-entitiy to appear %s" % ( str( entityObj ), ) ) return True self.sg.update( entityObj.getType(), entityObj.getRemoteID(), data ) self._setProcessed( event ) return True except shotgun_api3.Fault, fault: #event["type"] = "CouchdbChangeEvents" exception = "Error %s" % ( str( fault ) ) self._setProcessed( event, exception = exception ) return False
def main(): """ to be called """ sg_url = "https://devilfant.shotgunstudio.com" sg_test1 = { "name": "test1", "key": "e398654c5ec1c6f7c8f71ead33349c58bbf4a058" } sg1 = Shotgun(sg_url, sg_test1["name"], sg_test1["key"]) entities = sg1.schema_entity_read() pprint(entities) moduleString = """# -*- coding: utf-8 -*- \"""@package shotgun_replica.entities Shotgun Entities THIS FILE IS AUTO GENERATED DO NOT EDIT IT DIRECTLY change create_shotgun_classes.py instead \""" from shotgun_replica._entity_mgmt import _ShotgunEntity from shotgun_replica import %s """ % FIELDDEFINITIONSMODULE fieldDefModuleString = """# -*- coding: utf-8 -*- \""" THIS FILE IS AUTO GENERATED DO NOT EDIT IT DIRECTLY change create_shotgun_classes.py instead \""" """ classes = entities.keys() classes.sort() for entitycode in classes: print "processing %s\n" % entitycode fieldDefs = sg1.schema_field_read(entitycode) try: theclass = connectors.getClassOfType(entitycode) localFieldDefs = theclass.shotgun_fields except ImportError: localFieldDefs = None except AttributeError: localFieldDefs = None if fieldDefs != localFieldDefs: debug.error("%s fielddefs differ from shotgun to local" % entitycode) entityname = cleanSysName(entities[entitycode]["name"]["value"]) if entitycode.endswith("Connection"): entityname = entitycode (classCode, fieldDefCode) = _createClassCode(entities, entitycode, fieldDefs, entityname) moduleString += classCode fieldDefModuleString += fieldDefCode _createDBFields(entitycode, fieldDefs, entityname) packageDir = os.path.dirname(__file__) entityFilename = os.path.join(packageDir, 'entities.py') entity_file = open(entityFilename, 'w') entity_file.write(moduleString) entity_file.close() fieldDefFilename = os.path.join(packageDir, '%s.py' % FIELDDEFINITIONSMODULE) fieldDef_file = open(fieldDefFilename, 'w') fieldDef_file.write(fieldDefModuleString) fieldDef_file.close()