Exemplo n.º 1
0
    def GET( self, entityType, localID, remoteID, testdata = None  ):
        """
        retrieve an object
        GET-request at /[entityType]/[localID][/[remoteID]]
        examples: /Node/-1/23  Node with remoteID=23
                  /Project/34/23 Project with remoteID=23 and local_id=34
                  
        retrieve multiple objects
        GET-request at /[entityType]?attribute=value
        examples: /Node?project=(Project,-1,23)
        
        parameters:
        __orderby=[attributename]   order by attribute
        __limit=1                   limit results
        __details=1                 deliver detailed entity dicts instead of ids only
        """
        if testdata == None:
            self._nocache()
        
        if localID or remoteID:
            entity = self._getEntity( entityType, localID, remoteID )

            if entity:
                return json.dumps( entity.getDict(), indent = 4 )
            else:
                return web.notfound()
        else:

            if testdata:
                userData = testdata
            else:
                userData = web.input()

            filters = []
            filterValues = []
            for attribute in userData.keys():
                if attribute.startswith("__"):
                    continue
                filters.append( "%s=%s" % ( attribute, "%s" ) )
                filterValues.append( userData[attribute] )

            orderby = None
            if userData.has_key("__orderby"):
                orderby = userData["__orderby"]

            limit = None
            if userData.has_key("__limit"):
                limit = userData["__limit"]

            entities = factories.getObjects( entityType, 
                                             " AND ".join( filters ), 
                                             filterValues, 
                                             orderby = orderby, 
                                             limit = limit )
            json_entities = []

            for entity in entities:
                if userData.has_key("__details"):
                    json_entities.append( entity.getDict() )
                else:
                    json_entities.append( entity.getShortDict() )

            return json.dumps( json_entities, indent = 4 )
def changeEntity( myObj, changes ):
    """change entity in local database and add corresponding change-events for shotgun-sync"""

#    myObj.reload()

    src = connectors.DatabaseModificator()
    src.changeInDB( myObj, changes = changes )

    for ( key, value ) in changes.iteritems():
        if type( value ) == datetime.datetime:
            changes[key] = value.strftime( "%Y-%m-%d %H:%M:%S" )
        if type( value ) == datetime.date:
            changes[key] = value.strftime( "%Y-%m-%d" )
        elif type( value ) == datetime.timedelta:
            changes[key] = float( value.days ) * 24 + float( value.seconds ) / 3600
        elif type( value ) == connectors.PostgresEntityType:
            changes[key] = value.getShortDict()
        elif isinstance( value, base_entity.ShotgunBaseEntity ):
            changes[key] = value.getShortDict()
        elif type( value ) == type( [] ):
            changes[key] = []
            for entry in value:
                if isinstance( entry, base_entity.ShotgunBaseEntity ) or type( entry ) == connectors.PostgresEntityType:
                    changes[key].append( entry.getShortDict() )
                else:
                    changes[key].append( entry )




            attributeName = key
            fieldValues = value
            entityType = myObj.getType()

            connEntityName = entityNaming.getConnectionEntityName( entityType, attributeName )

            if connEntityName != None:

                reverseAttribute = entityNaming.getReverseAttributeName( entityType, attributeName )
                linkedEntityType = myObj.shotgun_fields[attributeName]["properties"]["valid_types"]["value"][0]
                baseEntityType = entityType

                ( baseAttrName, linkedAttrName ) = entityNaming.getConnectionEntityAttrName( baseEntityType,
                                                                                         linkedEntityType,
                                                                                         connEntityName )

                basePgObj = myObj.getPgObj()

                # get connections
                filters = "%s=%s" % ( baseAttrName,
                                      "%s"
                                      )
                filterValues = [ basePgObj ]
                connections = factories.getObjects( connEntityName,
                                                    filters,
                                                    filterValues )

                # create new connection entities
                for linkedDict in changes[key]:
                    linkedPostgresObj = getPgObj( linkedDict )
                    fieldNames = [ baseAttrName, linkedAttrName ]
                    fieldValues = [ basePgObj, linkedPostgresObj ]

                    # check if existing first
                    connectionExists = False
                    for i in range( len( connections ) ):
                        connection = connections[i]
                        if connection.getRawField( linkedAttrName ) == linkedPostgresObj:
                            connections.remove( connection )
                            connectionExists = True
                            break

                    if not connectionExists:
                        debug.debug( dict( zip( fieldNames, fieldValues ) ), prefix = "OOOOOOOOO" )
                        src._addToDatabase( connEntityName, fieldValues, fieldNames )

                    # setting reverse attribute as well
                    linkedObj = factories.getObject( linkedDict["type"],
                                                     local_id = linkedDict["__local_id"],
                                                     remote_id = linkedDict["id"] )
                    retValues = linkedObj.getRawField( reverseAttribute )

                    if retValues == None:
                        retValues = []

                    if basePgObj not in retValues:
                        retValues.append( basePgObj )
                        src.changeInDB( linkedObj, reverseAttribute, retValues )


                # delete unused connection entities

                for connection in connections:
                    linkedObj = connection.getField( linkedAttrName )
                    retValues = linkedObj.getRawField( reverseAttribute )

                    retValues.remove( basePgObj )
                    src.changeInDB( linkedObj, reverseAttribute, retValues )
                    src.delete( connection )


    _createChangeEvent( src, "change",
                        corr_entity = myObj.getPgObj(),
                        changed_values = json.dumps( changes )
                        )

    return myObj
Exemplo n.º 3
0
    def testAddOutput(self):
        lastevent = self.sg.find(
            "EventLogEntry",
            filters=[],
            fields=['id', 'event_type', 'attribute_name', 'meta', 'entity'],
            order=[{
                'column': 'id',
                'direction': 'desc'
            }],
            filter_operator='all',
            limit=1)[0]

        self.lastID = lastevent["id"]

        data = {
            "project": {
                "type": "Project",
                "id": testProjectID
            },
            "code": "newoutput",
            "sg_link": {
                "type": "Task",
                "id": testTaskID
            },
        }

        newOutputDict = self.sg.create(InOut().getType(), data, [])
        self.deleteEntities.append(newOutputDict)

        newevents = self._getNewEvents()

        self.assertEqual(newevents[0]["event_type"],
                         "Shotgun_CustomEntity02_New", "event not as expected")
        self.assertEqual(newevents[1]["event_type"],
                         "Shotgun_CustomEntity02_Change",
                         "event not as expected")
        self.assertEqual(newevents[2]["event_type"],
                         "Shotgun_CustomEntity02_Change",
                         "event not as expected")
        self.assertEqual(newevents[3]["event_type"],
                         "Shotgun_CustomEntity02_Change",
                         "event not as expected")

        self._processEvents(newevents)

        newOutput = factories.getObject("CustomEntity02",
                                        remote_id=newOutputDict["id"])

        changedData = {
            'sg_sink_tasks': [
                {
                    "type": "Task",
                    "id": testTaskID
                },
                {
                    "type": "Task",
                    "id": testTaskID_2
                },
            ]
        }
        self.sg.update(newOutputDict["type"], newOutputDict["id"], changedData)

        newevents = self._getNewEvents()

        self.assertEqual(len(newevents), 5)
        self.assertEqual(
            newevents[0]["event_type"],
            "Shotgun_CustomEntity02_sg_sink_tasks_Connection_New")
        self.assertEqual(
            newevents[1]["event_type"],
            "Shotgun_CustomEntity02_sg_sink_tasks_Connection_New")
        self.assertEqual(newevents[2]["event_type"],
                         "Shotgun_CustomEntity02_Change")
        self.assertEqual(newevents[3]["event_type"], "Shotgun_Task_Change")
        self.assertEqual(newevents[4]["event_type"], "Shotgun_Task_Change")

        self._processEvents(newevents)

        # check if Connection-Entities are available

        filters = "custom_entity02=%s and task=ANY(%s)"
        taskSgObj1 = PostgresEntityType("Task", remote_id=testTaskID)
        taskSgObj2 = PostgresEntityType("Task", remote_id=testTaskID_2)
        outputSgObj = PostgresEntityType(newOutputDict["type"],
                                         remote_id=newOutputDict["id"])
        filterValues = [outputSgObj, [taskSgObj1, taskSgObj2]]

        connObjs = factories.getObjects(
            "CustomEntity02_sg_sink_tasks_Connection", filters, filterValues)
        self.assertEqual(
            len(connObjs), 2,
            "no conn-objs: %s" % pprint.pformat(connObjs, indent=2))

        # check if return attribute of Task contains this CustomEntity02
        retAttr = entityNaming.getReverseAttributeName("CustomEntity02",
                                                       "sg_sink_tasks")
        for taskID in [testTaskID, testTaskID_2]:
            taskTmpObj = factories.getObject("Task", remote_id=taskID)
            retOutputs = taskTmpObj.__getattribute__(retAttr)
            self.assertTrue(newOutput in retOutputs)

        changedData["sg_sink_tasks"] = []
        self.sg.update(newOutputDict["type"], newOutputDict["id"], changedData)

        newevents = self._getNewEvents()

        # unfortunately there are two events missing:
        # see: https://support.shotgunsoftware.com/requests/7380
        self.assertEqual(len(newevents), 3)
        self.assertEqual(newevents[0]["event_type"],
                         "Shotgun_CustomEntity02_Change")
        self.assertEqual(newevents[1]["event_type"], "Shotgun_Task_Change")
        self.assertEqual(newevents[2]["event_type"], "Shotgun_Task_Change")

        self._processEvents(newevents)

        retAttr = entityNaming.getReverseAttributeName("CustomEntity02",
                                                       "sg_sink_tasks")
        for taskID in [testTaskID, testTaskID_2]:
            taskTmpObj = factories.getObject("Task", remote_id=taskID)
            retOutputs = taskTmpObj.__getattribute__(retAttr)
            if retOutputs:
                self.assertFalse(newOutput in retOutputs)

        # check if Connection-Entities are deleted

        connObjs = factories.getObjects(
            "CustomEntity02_sg_sink_tasks_Connection", filters, filterValues)
        self.assertEqual(
            len(connObjs), 0, "conn-objs still available: %s" %
            pprint.pformat(connObjs, indent=2))
Exemplo n.º 4
0
def changeEntity( myObj, changes ):
    """change entity in local database and add corresponding change-events for shotgun-sync"""

#    myObj.reload()

    src = connectors.DatabaseModificator()
    src.changeInDB( myObj, changes = changes )

    for ( key, value ) in changes.iteritems():
        if type( value ) == datetime.datetime:
            changes[key] = value.strftime( "%Y-%m-%d %H:%M:%S" )
        if type( value ) == datetime.date:
            changes[key] = value.strftime( "%Y-%m-%d" )
        elif type( value ) == datetime.timedelta:
            changes[key] = float( value.days ) * 24 + float( value.seconds ) / 3600
        elif type( value ) == connectors.PostgresEntityType:
            changes[key] = value.getShortDict()
        elif isinstance( value, base_entity.ShotgunBaseEntity ):
            changes[key] = value.getShortDict()
        elif type( value ) == type( [] ):
            changes[key] = []
            for entry in value:
                if isinstance( entry, base_entity.ShotgunBaseEntity ) or type( entry ) == connectors.PostgresEntityType:
                    changes[key].append( entry.getShortDict() )
                else:
                    changes[key].append( entry )




            attributeName = key
            fieldValues = value
            entityType = myObj.getType()

            connEntityName = entityNaming.getConnectionEntityName( entityType, attributeName )

            if connEntityName != None:

                reverseAttribute = entityNaming.getReverseAttributeName( entityType, attributeName )
                linkedEntityType = myObj.shotgun_fields[attributeName]["properties"]["valid_types"]["value"][0]
                baseEntityType = entityType

                ( baseAttrName, linkedAttrName ) = entityNaming.getConnectionEntityAttrName( baseEntityType,
                                                                                         linkedEntityType,
                                                                                         connEntityName )

                basePgObj = myObj.getPgObj()

                # get connections
                filters = "%s=%s" % ( baseAttrName,
                                      "%s"
                                      )
                filterValues = [ basePgObj ]
                connections = factories.getObjects( connEntityName,
                                                    filters,
                                                    filterValues )

                # create new connection entities
                for linkedDict in changes[key]:
                    linkedPostgresObj = getPgObj( linkedDict )
                    fieldNames = [ baseAttrName, linkedAttrName ]
                    fieldValues = [ basePgObj, linkedPostgresObj ]

                    # check if existing first
                    connectionExists = False
                    for i in range( len( connections ) ):
                        connection = connections[i]
                        if connection.getRawField( linkedAttrName ) == linkedPostgresObj:
                            connections.remove( connection )
                            connectionExists = True
                            break

                    if not connectionExists:
                        debug.debug( dict( zip( fieldNames, fieldValues ) ), prefix = "OOOOOOOOO" )
                        src._addToDatabase( connEntityName, fieldValues, fieldNames )

                    # setting reverse attribute as well
                    linkedObj = factories.getObject( linkedDict["type"],
                                                     local_id = linkedDict["__local_id"],
                                                     remote_id = linkedDict["id"] )
                    retValues = linkedObj.getRawField( reverseAttribute )

                    if retValues == None:
                        retValues = []

                    if basePgObj not in retValues:
                        retValues.append( basePgObj )
                        src.changeInDB( linkedObj, reverseAttribute, retValues )


                # delete unused connection entities

                for connection in connections:
                    linkedObj = connection.getField( linkedAttrName )
                    retValues = linkedObj.getRawField( reverseAttribute )

                    retValues.remove( basePgObj )
                    src.changeInDB( linkedObj, reverseAttribute, retValues )
                    src.delete( connection )


    _createChangeEvent( src, "change",
                        corr_entity = myObj.getPgObj(),
                        changed_values = json.dumps( changes )
                        )

    return myObj
Exemplo n.º 5
0
    def testAddOutput( self ):
        lastevent = self.sg.find( 
                                 "EventLogEntry",
                                 filters = [],
                                 fields = ['id', 'event_type', 'attribute_name', 'meta', 'entity'],
                                 order = [{'column':'id', 'direction':'desc'}],
                                 filter_operator = 'all',
                                 limit = 1
                                 )[0]

        self.lastID = lastevent["id"]

        data = {
                "project": {"type": "Project",
                            "id": testProjectID
                            },
                "code": "newoutput",
                "sg_link": {"type": "Task",
                            "id": testTaskID
                            },
                }

        newOutputDict = self.sg.create( InOut().getType(), data, [] )
        self.deleteEntities.append( newOutputDict )

        newevents = self._getNewEvents()

        self.assertEqual( newevents[0]["event_type"], "Shotgun_CustomEntity02_New", "event not as expected" )
        self.assertEqual( newevents[1]["event_type"], "Shotgun_CustomEntity02_Change", "event not as expected" )
        self.assertEqual( newevents[2]["event_type"], "Shotgun_CustomEntity02_Change", "event not as expected" )
        self.assertEqual( newevents[3]["event_type"], "Shotgun_CustomEntity02_Change", "event not as expected" )

        self._processEvents( newevents )

        newOutput = factories.getObject( "CustomEntity02", remote_id = newOutputDict["id"] )

        changedData = {
                       'sg_sink_tasks': [
                                         {
                                          "type": "Task",
                                          "id": testTaskID
                                          },
                                         {
                                          "type": "Task",
                                          "id": testTaskID_2
                                          },
                                         ]
                       }
        self.sg.update( newOutputDict["type"], newOutputDict["id"], changedData )

        newevents = self._getNewEvents()

        self.assertEqual( len( newevents ), 5 )
        self.assertEqual( newevents[0]["event_type"], "Shotgun_CustomEntity02_sg_sink_tasks_Connection_New" )
        self.assertEqual( newevents[1]["event_type"], "Shotgun_CustomEntity02_sg_sink_tasks_Connection_New" )
        self.assertEqual( newevents[2]["event_type"], "Shotgun_CustomEntity02_Change" )
        self.assertEqual( newevents[3]["event_type"], "Shotgun_Task_Change" )
        self.assertEqual( newevents[4]["event_type"], "Shotgun_Task_Change" )

        self._processEvents( newevents )

        # check if Connection-Entities are available

        filters = "custom_entity02=%s and task=ANY(%s)"
        taskSgObj1 = PostgresEntityType( "Task", remote_id = testTaskID )
        taskSgObj2 = PostgresEntityType( "Task", remote_id = testTaskID_2 )
        outputSgObj = PostgresEntityType( newOutputDict["type"], remote_id = newOutputDict["id"] )
        filterValues = [ outputSgObj, [ taskSgObj1, taskSgObj2 ] ]

        connObjs = factories.getObjects( "CustomEntity02_sg_sink_tasks_Connection", filters, filterValues )
        self.assertEqual( len( connObjs ), 2, "no conn-objs: %s" % pprint.pformat( connObjs, indent = 2 ) )

        # check if return attribute of Task contains this CustomEntity02
        retAttr = entityNaming.getReverseAttributeName( "CustomEntity02", "sg_sink_tasks" )
        for taskID in [ testTaskID, testTaskID_2 ]:
            taskTmpObj = factories.getObject( "Task", remote_id = taskID )
            retOutputs = taskTmpObj.__getattribute__( retAttr )
            self.assertTrue( newOutput in retOutputs )

        changedData["sg_sink_tasks"] = []
        self.sg.update( newOutputDict["type"], newOutputDict["id"], changedData )

        newevents = self._getNewEvents()

        # unfortunately there are two events missing:
        # see: https://support.shotgunsoftware.com/requests/7380
        self.assertEqual( len( newevents ), 3 )
        self.assertEqual( newevents[0]["event_type"], "Shotgun_CustomEntity02_Change" )
        self.assertEqual( newevents[1]["event_type"], "Shotgun_Task_Change" )
        self.assertEqual( newevents[2]["event_type"], "Shotgun_Task_Change" )

        self._processEvents( newevents )

        retAttr = entityNaming.getReverseAttributeName( "CustomEntity02", "sg_sink_tasks" )
        for taskID in [ testTaskID, testTaskID_2 ]:
            taskTmpObj = factories.getObject( "Task", remote_id = taskID )
            retOutputs = taskTmpObj.__getattribute__( retAttr )
            if retOutputs:
                self.assertFalse( newOutput in retOutputs )

        # check if Connection-Entities are deleted

        connObjs = factories.getObjects( "CustomEntity02_sg_sink_tasks_Connection", filters, filterValues )
        self.assertEqual( len( connObjs ), 0, "conn-objs still available: %s" % pprint.pformat( connObjs, indent = 2 ) )