Example #1
0
def download_metadata_metadata(job, org):

    org.status = 'Downloading Metadata'
    org.save()

    try:

        # instantiate the metadata WSDL
        metadata_client = Client(settings.SALESFORCE_METADATA_WSDL)

        # URL for metadata API
        metadata_url = org.instance_url

        # set the metadata url based on the login result
        metadata_client.set_options(location=metadata_url)

        # set the session id from the login result
        session_header = metadata_client.factory.create("SessionHeader")
        session_header.sessionId = org.access_token
        metadata_client.set_options(soapheaders=session_header)

        # query for the list of metadata types
        all_metadata = metadata_client.service.describeMetadata(
            settings.SALESFORCE_API_VERSION)

        # Components for listing metadata
        component_list = []
        loop_counter = 0

        # loop through metadata types
        for component_type in all_metadata[0]:

            # create the component type record and save
            component_type_record = ComponentType()
            component_type_record.org = org
            component_type_record.name = component_type.xmlName
            component_type_record.save()

            # Component is a folder component - eg Dashboard, Document, EmailTemplate, Report
            if not component_type.inFolder:

                # set up the component type to query for components
                component = metadata_client.factory.create("ListMetadataQuery")
                component.type = component_type.xmlName

                # Add metadata to list
                component_list.append(component)

            else:

                # Append "Folder" keyword onto end of component type
                component = metadata_client.factory.create("ListMetadataQuery")

                # EmailTemplate = EmailFolder (for some reason)
                if component_type.xmlName == 'EmailTemplate':
                    component.type = 'EmailFolder'
                else:
                    component.type = component_type.xmlName + 'Folder'

                # All folders for specified metadata type
                all_folders = metadata_client.service.listMetadata(
                    [component], settings.SALESFORCE_API_VERSION)
                folder_list = []
                folder_loop_counter = 0

                # Loop through folders
                for folder in all_folders:

                    # Exclude managed package folders
                    if 'namespacePrefix' not in folder or not folder.namespacePrefix:

                        # Create component for folder to query
                        folder_component = metadata_client.factory.create(
                            "ListMetadataQuery")
                        folder_component.type = component_type.xmlName
                        folder_component.folder = folder.fullName

                        folder_list.append(folder_component)

                        if len(folder_list) >= 3 or (len(all_folders) -
                                                     folder_loop_counter) <= 3:

                            # Loop through folder components
                            for folder_component in metadata_client.service.listMetadata(
                                    folder_list,
                                    settings.SALESFORCE_API_VERSION):

                                # create the component record and save
                                component_record = Component()
                                component_record.component_type = component_type_record
                                component_record.name = folder_component.fullName
                                component_record.save()

                            folder_list = []

                        folder_loop_counter = folder_loop_counter + 1

            # Run the metadata query only if the list has reached 3 (the max allowed to query)
            # at one time, or if there is less than 3 components left to query
            if len(component_list) >= 3 or (len(all_metadata[0]) -
                                            loop_counter) <= 3:

                # loop through the components returned from the component query
                for component in metadata_client.service.listMetadata(
                        component_list, settings.SALESFORCE_API_VERSION):

                    # Exclude managed package components
                    if 'namespacePrefix' not in component or not component.namespacePrefix:

                        # Query database for parent component_type
                        component_type_query = ComponentType.objects.filter(
                            name=component.type, org=org.id)

                        # Only add if found
                        if component_type_query:

                            # create the component record and save
                            component_record = Component()
                            component_record.component_type = component_type_query[
                                0]
                            component_record.name = component.fullName
                            component_record.save()

                # clear list once done. This list will re-build to 3 components and re-query the service
                component_list = []

            loop_counter = loop_counter + 1

        # If a component type has no child components, remove the component type altogether
        for component_type in ComponentType.objects.filter(org=org.id):
            if not Component.objects.filter(component_type=component_type.id):
                component_type.delete()

        # Create retrieve request
        retrieve_request = metadata_client.factory.create('RetrieveRequest')
        retrieve_request.apiVersion = settings.SALESFORCE_API_VERSION
        retrieve_request.singlePackage = True
        retrieve_request.packageNames = None
        retrieve_request.specificFiles = None

        # List of components to retrieve files for
        component_retrieve_list = []

        # Component types for the org
        component_types = ComponentType.objects.filter(org=org.id)

        # Now query through all components and download actual metadata
        for component_type in component_types:

            # Loop through child components of the component type
            for component in component_type.component_set.all():

                # Create PackageTypeMember instant to retrieve
                component_to_retrieve = metadata_client.factory.create(
                    'PackageTypeMembers')
                component_to_retrieve.members = component.name
                component_to_retrieve.name = component_type.name
                component_retrieve_list.append(component_to_retrieve)

        # If more than 5k components to retrieve, run it in batches. Otherwise just do it in
        # one big hit
        if len(component_retrieve_list) <= 5000:

            # Execute the callout for all components
            retrieve_files(org, metadata_client, retrieve_request,
                           component_retrieve_list, None)

        else:

            # Iterate over the component types and run in batches
            for component_type in component_types:

                component_retrieve_list = []

                # Loop through child components of the component type
                for component in component_type.component_set.all():

                    # Create PackageTypeMember instant to retrieve
                    component_to_retrieve = metadata_client.factory.create(
                        'PackageTypeMembers')
                    component_to_retrieve.members = component.name
                    component_to_retrieve.name = component_type.name
                    component_retrieve_list.append(component_to_retrieve)

                # Execute the retrieve for the component type
                retrieve_files(org, metadata_client, retrieve_request,
                               component_retrieve_list, component_type.name)

    except Exception as error:

        org.status = 'Error'
        org.error = error
        org.error_stacktrace = traceback.format_exc()

    org.status = 'Finished'
    org.save()

    # Check if both jobs are now finished
    check_overall_status(job)
Example #2
0
def retrieve_files(org, metadata_client, retrieve_request,
                   component_retrieve_list, component_type):
    """
		Method to phyiscally retrieve files from Salesforce via the metadata API 
	"""

    zipfile_name = 'metadata%s.zip' % (str(org.org_number))

    # The overall package to retrieve
    package_to_retrieve = metadata_client.factory.create('Package')
    package_to_retrieve.apiAccessLevel = None
    package_to_retrieve.types = component_retrieve_list
    package_to_retrieve.packageType = None  # This stupid line of code took me ages to work out!

    # Add retrieve package to the retrieve request
    retrieve_request.unpackaged = package_to_retrieve

    # Start the async retrieve job
    retrieve_job = metadata_client.service.retrieve(retrieve_request)

    # Set the retrieve result - should be unfinished initially
    retrieve_result = metadata_client.service.checkRetrieveStatus(
        retrieve_job.id, True)

    # Continue to query retrieve result until it's done
    while not retrieve_result.done:

        # sleep job for 5 seconds
        time.sleep(10)

        # check job status
        retrieve_result = metadata_client.service.checkRetrieveStatus(
            retrieve_job.id, True)

    if not retrieve_result.success:

        org.status = 'Error'

        if 'errorMessage' in retrieve_result:
            org.error = retrieve_result.errorMessage
        elif 'messages' in retrieve_result:
            org.error = retrieve_result.messages[0]

    else:

        # Save the zip file result to server
        zip_file = open(zipfile_name, 'w+')
        zip_file.write(b64decode(retrieve_result.zipFile))
        zip_file.close()

        # Delete all existing components for package - they need to be renamed
        if component_type:
            ComponentType.objects.filter(org=org.id,
                                         name=component_type).delete()
        else:
            ComponentType.objects.filter(org=org.id).delete()

        # Open zip file
        metadata = ZipFile(zipfile_name, 'r')

        # Loop through files in the zip file
        for filename in metadata.namelist():

            try:

                # Set folder and component name
                folder_name = filename.split('/')[0]
                component_name = filename.split('/')[1]

                # Check if component type exists
                if ComponentType.objects.filter(org=org.id, name=folder_name):

                    # If exists, use this as parent component type
                    component_type_record = ComponentType.objects.filter(
                        org=org.id, name=folder_name)[0]

                else:

                    # create the component type record and save
                    component_type_record = ComponentType()
                    component_type_record.org = org
                    component_type_record.name = folder_name
                    component_type_record.save()

                # create the component record and save
                component_record = Component()
                component_record.component_type = component_type_record

                # If more / exist, append
                if len(filename.split('/')) > 2:
                    component_record.name = component_name + '/' + filename.split(
                        '/')[2]
                else:
                    component_record.name = component_name
                component_record.content = metadata.read(filename)
                component_record.save()

            # not in a folder (could be package.xml). Skip record
            except:
                continue

        # Delete zip file, no need to store
        if os.path.isfile(zipfile_name):
            os.remove(zipfile_name)

        # Set the Org to finish when all of above is complete
        org.status = 'Finished'
Example #3
0
def download_metadata_tooling(job, org):

    org.status = 'Downloading Metadata'
    org.save()

    try:

        tooling_url = org.instance_url + '/services/data/v' + str(
            settings.SALESFORCE_API_VERSION) + '.0/tooling/'
        headers = {
            'Accept': 'application/json',
            'Authorization': 'Bearer ' + org.access_token
        }

        metadata_types = [
            'ApexClass',
            'ApexComponent',
            'ApexPage',
            'ApexTrigger',
        ]

        for component_type in metadata_types:

            # Build the query string
            data_query = 'select+id+from+%s+where+NamespacePrefix=null' % component_type

            # Execute the query
            metadata_records = requests.get(tooling_url + 'query/?q=' +
                                            data_query,
                                            headers=headers)

            # Convert to JSON object
            metadata_json = metadata_records.json()

            # Only continue if records exist to query
            if 'records' in metadata_json:

                # create the component type record and save
                component_type_record = ComponentType()
                component_type_record.org = org
                component_type_record.name = component_type
                component_type_record.save()

                count_children = 0

                for component in metadata_json['records']:

                    # Get the URL to query for the full body
                    metadata_url = org.instance_url + component['attributes'][
                        'url']

                    # Query for body
                    record = requests.get(metadata_url, headers=headers)

                    # create the component record and save
                    component_record = Component()
                    component_record.component_type = component_type_record

                    if component_type == 'ApexPage' or component_type == 'ApexComponent':
                        component_record.name = record.json()['Name']
                        component_record.content = record.json()['Markup']

                    #ApexClass or ApexTrigger
                    else:
                        component_record.name = record.json()['FullName']
                        component_record.content = record.json()['Body']

                    component_record.save()

                    count_children += 1

                if count_children == 0:
                    component_type_record.delete()

    except Exception as error:
        org.status = 'Error'
        org.error = error
        org.error_stacktrace = traceback.format_exc()

    org.status = 'Finished'
    org.save()

    # Check if both jobs are now finished
    check_overall_status(job)
Example #4
0
def download_metadata_metadata(job, org):

	org.status = 'Downloading Metadata'
	org.save()

	try:

		# instantiate the metadata WSDL
		metadata_client = Client('http://sforgcompare.herokuapp.com/static/metadata-32.xml')

		# URL for metadata API
		metadata_url = org.instance_url + '/services/Soap/m/' + str(settings.SALESFORCE_API_VERSION) + '.0/' + org.org_id

		# set the metadata url based on the login result
		metadata_client.set_options(location = metadata_url)

		# set the session id from the login result
		session_header = metadata_client.factory.create("SessionHeader")
		session_header.sessionId = org.access_token
		metadata_client.set_options(soapheaders = session_header)
		
		# query for the list of metadata types
		all_metadata = metadata_client.service.describeMetadata(settings.SALESFORCE_API_VERSION)

		# Components for listing metadata
		component_list = []
		loop_counter = 0;

		# loop through metadata types
		for component_type in all_metadata[0]:

			# create the component type record and save
			component_type_record = ComponentType()
			component_type_record.org = org
			component_type_record.name = component_type.xmlName
			component_type_record.save()

			# Component is a folder component - eg Dashboard, Document, EmailTemplate, Report
			if not component_type.inFolder:

				# set up the component type to query for components
				component = metadata_client.factory.create("ListMetadataQuery")
				component.type = component_type.xmlName

				# Add metadata to list
				component_list.append(component)
			
			else:

				# Append "Folder" keyword onto end of component type
				component = metadata_client.factory.create("ListMetadataQuery")

				# EmailTemplate = EmailFolder (for some reason)
				if component_type.xmlName == 'EmailTemplate':
					component.type = 'EmailFolder'
				else:
					component.type = component_type.xmlName + 'Folder'

				# All folders for specified metadata type
				all_folders = metadata_client.service.listMetadata([component], settings.SALESFORCE_API_VERSION)
				folder_list = []
				folder_loop_counter = 0

				# Loop through folders
				for folder in all_folders:

					# Create component for folder to query
					folder_component = metadata_client.factory.create("ListMetadataQuery")
					folder_component.type = component_type.xmlName
					folder_component.folder = folder.fullName

					folder_list.append(folder_component)

					if len(folder_list) >= 3 or (len(all_folders) - folder_loop_counter) <= 3:

						# Loop through folder components
						for folder_component in metadata_client.service.listMetadata(folder_list, settings.SALESFORCE_API_VERSION):

							# create the component record and save
							component_record = Component()
							component_record.component_type = component_type_record
							component_record.name = folder_component.fullName
							component_record.save()

						folder_list = []

					folder_loop_counter = folder_loop_counter + 1

			# Run the metadata query only if the list has reached 3 (the max allowed to query)
			# at one time, or if there is less than 3 components left to query 
			if len(component_list) >= 3 or (len(all_metadata[0]) - loop_counter) <= 3:

				# loop through the components returned from the component query
				for component in metadata_client.service.listMetadata(component_list, settings.SALESFORCE_API_VERSION):

					# Query database for parent component_type
					component_type_query = ComponentType.objects.filter(name = component.type, org = org.id)

					# Only add if found
					if component_type_query:

						# create the component record and save
						component_record = Component()
						component_record.component_type = component_type_query[0]
						component_record.name = component.fullName
						component_record.save()
		
				# clear list once done. This list will re-build to 3 components and re-query the service
				component_list = []

			loop_counter = loop_counter + 1;

		# If a component type has no child components, remove the component type altogether
		for component_type in ComponentType.objects.filter(org = org.id):
			if not Component.objects.filter(component_type = component_type.id):
				component_type.delete()

		# Create retrieve request
		retrieve_request = metadata_client.factory.create('RetrieveRequest')
		retrieve_request.apiVersion = settings.SALESFORCE_API_VERSION
		retrieve_request.singlePackage = True
		retrieve_request.packageNames = None
		retrieve_request.specificFiles = None

		component_retrieve_list = []

		# Now query through all components and download actual metadata
		for component_type in ComponentType.objects.filter(org = org.id):

			# Loop through child components of the component type
			for component in component_type.component_set.all():

				component_to_retrieve = metadata_client.factory.create('PackageTypeMembers')
				component_to_retrieve.members = component.name
				component_to_retrieve.name = component_type.name
				component_retrieve_list.append(component_to_retrieve)

		# The overall package to retrieve
		package_to_retrieve = metadata_client.factory.create('Package')
		package_to_retrieve.apiAccessLevel = None
		package_to_retrieve.types = component_retrieve_list

		# Add retrieve package to the retrieve request
		retrieve_request.unpackaged = package_to_retrieve

		# Start the async retrieve job
		retrieve_job = metadata_client.service.retrieve(retrieve_request)

		# Set the retrieve result - should be unfinished initially
		retrieve_result = metadata_client.service.checkRetrieveStatus(retrieve_job.id)

		# Continue to query retrieve result until it's done
		while not retrieve_result.done:

			# check job status
			retrieve_result = metadata_client.service.checkRetrieveStatus(retrieve_job.id)

			# sleep job for 5 seconds
			time.sleep(10)

		if not retrieve_result.success:

			org.status = 'Error'

			if 'errorMessage' in retrieve_result:
				org.error = retrieve_result.errorMessage
			elif 'messages' in retrieve_result:
				org.error = retrieve_result.messages[0]
			
		else:

			# Save the zip file result to server
			zip_file = open('metadata.zip', 'w+')
			zip_file.write(b64decode(retrieve_result.zipFile))
			zip_file.close()

			# Delete all existing components for package - they need to be renamed
			ComponentType.objects.filter(org = org.id).delete()

			# Open zip file
			metadata = ZipFile('metadata.zip', 'r')

			# Loop through files in the zip file
			for filename in metadata.namelist():

				try:

					# Set folder and component name
					folder_name = filename.split('/')[0]
					component_name = filename.split('/')[1]

					# Check if component type exists
					if ComponentType.objects.filter(org = org.id, name = folder_name):

						# If exists, use this as parent component type
						component_type_record = ComponentType.objects.filter(org = org.id, name = folder_name)[0]

					else:

						# create the component type record and save
						component_type_record = ComponentType()
						component_type_record.org = org
						component_type_record.name = folder_name
						component_type_record.save()

					# create the component record and save
					component_record = Component()
					component_record.component_type = component_type_record

					# If more / exist, append
					if len(filename.split('/')) > 2:
						component_record.name = component_name + '/' + filename.split('/')[2]
					else:
						component_record.name = component_name
					component_record.content = metadata.read(filename)
					component_record.save()

				# not in a folder (could be package.xml). Skip record
				except:
					continue

			# Delete zip file, no need to store
			os.remove('metadata.zip')

			org.status = 'Finished'

	except Exception as error:
		org.status = 'Error'
		org.error = error

	org.save()

	# Check if both jobs are now finished
	check_overall_status(job)
Example #5
0
def download_metadata_tooling(job, org):

	org.status = 'Downloading Metadata'
	org.save()
	
	try:
		
		tooling_url = org.instance_url + '/services/data/v' + str(settings.SALESFORCE_API_VERSION) + '.0/tooling/'
		headers = { 
			'Accept': 'application/json',
			'Authorization': 'Bearer ' + org.access_token
		}

		metadata_types = [
			'ApexClass',
			'ApexComponent',
			'ApexPage',
			'ApexTrigger',
		]

		for component_type in metadata_types:

			data_query = 'select+id+from+' + component_type
			metadata_records = requests.get(tooling_url + 'query/?q=' + data_query, headers = headers)
			
			# Only continue if records exist to query
			if 'records' in metadata_records.json():

				# create the component type record and save
				component_type_record = ComponentType()
				component_type_record.org = org
				component_type_record.name = component_type
				component_type_record.save()

				count_children = 0

				for component in metadata_records.json()['records']:

					metadata_url = org.instance_url + component['attributes']['url']

					record = requests.get(metadata_url, headers = headers)

					# Only take non package components
					if record.json()['NamespacePrefix'] == None:

						# create the component record and save
						component_record = Component()
						component_record.component_type = component_type_record
						
						if component_type == 'ApexPage' or component_type == 'ApexComponent':
							component_record.name = record.json()['Name']
							component_record.content = record.json()['Markup']

						#ApexClass or ApexTrigger
						else:
							component_record.name = record.json()['FullName']
							component_record.content = record.json()['Body']
							
						component_record.save()

						count_children += 1

				if count_children == 0:
					component_type_record.delete()

			org.status = 'Finished'

	except Exception as error:
		org.status = 'Error'
		org.error = error

	org.save()

	# Check if both jobs are now finished
	check_overall_status(job)
Example #6
0
def download_metadata_metadata(job, org):

    org.status = 'Downloading Metadata'
    org.save()

    try:

        # instantiate the metadata WSDL
        metadata_client = Client(
            'http://sforgcompare.herokuapp.com/static/metadata-32.xml')

        # URL for metadata API
        metadata_url = org.instance_url + '/services/Soap/m/' + str(
            settings.SALESFORCE_API_VERSION) + '.0/' + org.org_id

        # set the metadata url based on the login result
        metadata_client.set_options(location=metadata_url)

        # set the session id from the login result
        session_header = metadata_client.factory.create("SessionHeader")
        session_header.sessionId = org.access_token
        metadata_client.set_options(soapheaders=session_header)

        # query for the list of metadata types
        all_metadata = metadata_client.service.describeMetadata(
            settings.SALESFORCE_API_VERSION)

        # Components for listing metadata
        component_list = []
        loop_counter = 0

        # loop through metadata types
        for component_type in all_metadata[0]:

            # create the component type record and save
            component_type_record = ComponentType()
            component_type_record.org = org
            component_type_record.name = component_type.xmlName
            component_type_record.save()

            # Component is a folder component - eg Dashboard, Document, EmailTemplate, Report
            if not component_type.inFolder:

                # set up the component type to query for components
                component = metadata_client.factory.create("ListMetadataQuery")
                component.type = component_type.xmlName

                # Add metadata to list
                component_list.append(component)

            else:

                # Append "Folder" keyword onto end of component type
                component = metadata_client.factory.create("ListMetadataQuery")

                # EmailTemplate = EmailFolder (for some reason)
                if component_type.xmlName == 'EmailTemplate':
                    component.type = 'EmailFolder'
                else:
                    component.type = component_type.xmlName + 'Folder'

                # All folders for specified metadata type
                all_folders = metadata_client.service.listMetadata(
                    [component], settings.SALESFORCE_API_VERSION)
                folder_list = []
                folder_loop_counter = 0

                # Loop through folders
                for folder in all_folders:

                    # Create component for folder to query
                    folder_component = metadata_client.factory.create(
                        "ListMetadataQuery")
                    folder_component.type = component_type.xmlName
                    folder_component.folder = folder.fullName

                    folder_list.append(folder_component)

                    if len(folder_list) >= 3 or (len(all_folders) -
                                                 folder_loop_counter) <= 3:

                        # Loop through folder components
                        for folder_component in metadata_client.service.listMetadata(
                                folder_list, settings.SALESFORCE_API_VERSION):

                            # create the component record and save
                            component_record = Component()
                            component_record.component_type = component_type_record
                            component_record.name = folder_component.fullName
                            component_record.save()

                        folder_list = []

                    folder_loop_counter = folder_loop_counter + 1

            # Run the metadata query only if the list has reached 3 (the max allowed to query)
            # at one time, or if there is less than 3 components left to query
            if len(component_list) >= 3 or (len(all_metadata[0]) -
                                            loop_counter) <= 3:

                # loop through the components returned from the component query
                for component in metadata_client.service.listMetadata(
                        component_list, settings.SALESFORCE_API_VERSION):

                    # Query database for parent component_type
                    component_type_query = ComponentType.objects.filter(
                        name=component.type, org=org.id)

                    # Only add if found
                    if component_type_query:

                        # create the component record and save
                        component_record = Component()
                        component_record.component_type = component_type_query[
                            0]
                        component_record.name = component.fullName
                        component_record.save()

                # clear list once done. This list will re-build to 3 components and re-query the service
                component_list = []

            loop_counter = loop_counter + 1

        # If a component type has no child components, remove the component type altogether
        for component_type in ComponentType.objects.filter(org=org.id):
            if not Component.objects.filter(component_type=component_type.id):
                component_type.delete()

        # Create retrieve request
        retrieve_request = metadata_client.factory.create('RetrieveRequest')
        retrieve_request.apiVersion = settings.SALESFORCE_API_VERSION
        retrieve_request.singlePackage = True
        retrieve_request.packageNames = None
        retrieve_request.specificFiles = None

        component_retrieve_list = []

        # Now query through all components and download actual metadata
        for component_type in ComponentType.objects.filter(org=org.id):

            # Loop through child components of the component type
            for component in component_type.component_set.all():

                component_to_retrieve = metadata_client.factory.create(
                    'PackageTypeMembers')
                component_to_retrieve.members = component.name
                component_to_retrieve.name = component_type.name
                component_retrieve_list.append(component_to_retrieve)

        # The overall package to retrieve
        package_to_retrieve = metadata_client.factory.create('Package')
        package_to_retrieve.apiAccessLevel = None
        package_to_retrieve.types = component_retrieve_list

        # Add retrieve package to the retrieve request
        retrieve_request.unpackaged = package_to_retrieve

        # Start the async retrieve job
        retrieve_job = metadata_client.service.retrieve(retrieve_request)

        # Set the retrieve result - should be unfinished initially
        retrieve_result = metadata_client.service.checkRetrieveStatus(
            retrieve_job.id)

        # Continue to query retrieve result until it's done
        while not retrieve_result.done:

            # check job status
            retrieve_result = metadata_client.service.checkRetrieveStatus(
                retrieve_job.id)

            # sleep job for 5 seconds
            time.sleep(10)

        if not retrieve_result.success:

            org.status = 'Error'

            if 'errorMessage' in retrieve_result:
                org.error = retrieve_result.errorMessage
            elif 'messages' in retrieve_result:
                org.error = retrieve_result.messages[0]

        else:

            # Save the zip file result to server
            zip_file = open('metadata.zip', 'w+')
            zip_file.write(b64decode(retrieve_result.zipFile))
            zip_file.close()

            # Delete all existing components for package - they need to be renamed
            ComponentType.objects.filter(org=org.id).delete()

            # Open zip file
            metadata = ZipFile('metadata.zip', 'r')

            # Loop through files in the zip file
            for filename in metadata.namelist():

                try:

                    # Set folder and component name
                    folder_name = filename.split('/')[0]
                    component_name = filename.split('/')[1]

                    # Check if component type exists
                    if ComponentType.objects.filter(org=org.id,
                                                    name=folder_name):

                        # If exists, use this as parent component type
                        component_type_record = ComponentType.objects.filter(
                            org=org.id, name=folder_name)[0]

                    else:

                        # create the component type record and save
                        component_type_record = ComponentType()
                        component_type_record.org = org
                        component_type_record.name = folder_name
                        component_type_record.save()

                    # create the component record and save
                    component_record = Component()
                    component_record.component_type = component_type_record

                    # If more / exist, append
                    if len(filename.split('/')) > 2:
                        component_record.name = component_name + '/' + filename.split(
                            '/')[2]
                    else:
                        component_record.name = component_name
                    component_record.content = metadata.read(filename)
                    component_record.save()

                # not in a folder (could be package.xml). Skip record
                except:
                    continue

            # Delete zip file, no need to store
            os.remove('metadata.zip')

            org.status = 'Finished'

    except Exception as error:
        org.status = 'Error'
        org.error = error

    org.save()

    # Check if both jobs are now finished
    check_overall_status(job)
Example #7
0
def download_metadata_tooling(job, org):

    org.status = 'Downloading Metadata'
    org.save()

    try:

        tooling_url = org.instance_url + '/services/data/v' + str(
            settings.SALESFORCE_API_VERSION) + '.0/tooling/'
        headers = {
            'Accept': 'application/json',
            'Authorization': 'Bearer ' + org.access_token
        }

        metadata_types = [
            'ApexClass',
            'ApexComponent',
            'ApexPage',
            'ApexTrigger',
        ]

        for component_type in metadata_types:

            data_query = 'select+id+from+' + component_type
            metadata_records = requests.get(tooling_url + 'query/?q=' +
                                            data_query,
                                            headers=headers)

            # Only continue if records exist to query
            if 'records' in metadata_records.json():

                # create the component type record and save
                component_type_record = ComponentType()
                component_type_record.org = org
                component_type_record.name = component_type
                component_type_record.save()

                count_children = 0

                for component in metadata_records.json()['records']:

                    metadata_url = org.instance_url + component['attributes'][
                        'url']

                    record = requests.get(metadata_url, headers=headers)

                    # Only take non package components
                    if record.json()['NamespacePrefix'] == None:

                        # create the component record and save
                        component_record = Component()
                        component_record.component_type = component_type_record

                        if component_type == 'ApexPage' or component_type == 'ApexComponent':
                            component_record.name = record.json()['Name']
                            component_record.content = record.json()['Markup']

                        #ApexClass or ApexTrigger
                        else:
                            component_record.name = record.json()['FullName']
                            component_record.content = record.json()['Body']

                        component_record.save()

                        count_children += 1

                if count_children == 0:
                    component_type_record.delete()

            org.status = 'Finished'

    except Exception as error:
        org.status = 'Error'
        org.error = error

    org.save()

    # Check if both jobs are now finished
    check_overall_status(job)