Exemple #1
0
    def login(self, session_id_expired):
        if self.username not in globals() or session_id_expired:
            result = soap_login(self.toolingapi_settings)

            # If login succeed, display error and return False
            if result["status_code"] > 399:
                util.sublime_error_message(result)
                return False

            result["headers"] = {
                "Authorization": "OAuth " + result["session_id"],
                "Content-Type": "application/json; charset=UTF-8",
                "Accept": "application/json"
            }
            globals()[self.username] = result

        return True
Exemple #2
0
    def login(self, session_id_expired):
        if self.username not in globals() or session_id_expired:
            result = soap_login(self.toolingapi_settings)

            # If login succeed, display error and return False
            if result["status_code"] > 399:
                util.sublime_error_message(result)
                return False

            result["headers"] = {
                "Authorization": "OAuth " + result["session_id"],
                "Content-Type": "application/json; charset=UTF-8",
                "Accept": "application/json"
            }
            globals()[self.username] = result

        return True
Exemple #3
0
    def save_component(self, component_attribute, body):
        """
        This method contains 5 steps:
        1. Post classid to get MetadataContainerId
        2. Post Component Member
        3. Post ContainerAsyncRequest to get AsyncRequest Id
        4. Get ContainerAsyncRequest Response by Id in step 3
        5. Delete the MetadataContainerId

        Notes: Because if ContainerAsyncRequest has problem, we can't reuse the 
            MetadataContainerId, so we need to delete it and get it every time.

        @component_attribute
        @body: Code content

        """
        # Component Attribute
        component_type = component_attribute["type"]
        component_id = component_attribute["id"]
        component_body = component_attribute["body"]

        # Get MetadataContainerId
        data = {  
            "name": "Save" + component_type[4 : len(component_type)] + component_id
        }
        container_url = '/services/data/v28.0/tooling/sobjects/MetadataContainer'
        result = self.post(container_url, data)
        print ("MetadataContainer Response: ", result)

        # If status_code < 399, it means post succeed
        if result["status_code"] < 399:
            container_id = result.get("id")
        else:
            # If status_code < 399, it means post failed, 
            # If DUPLICATE Container Id, just delete it and restart this function
            if result["errorCode"] == "DUPLICATE_VALUE":
                error_message = result["message"]
                container_id = error_message[error_message.rindex("1dc"): len(error_message)]
                delete_result = self.delete(container_url + "/" + container_id)
                if delete_result["status_code"] < 399:
                    util.sublime_status_message("container_id is deleted.")
                
                # We can't reuse the container_id which caused error
                # Post Request to get MetadataContainerId
                return self.save_component(component_attribute, body)
            else:
                util.sublime_error_message(result)
                return

        # Post ApexComponentMember
        data = {
            "ContentEntityId": component_id,
            "MetadataContainerId": container_id,
            "Body": body
        }
        url = "/services/data/v28.0/tooling/sobjects/" + component_type + "Member"
        result = self.post(url, data)
        print ("Post ApexComponentMember: ", result)

        # Post ContainerAsyncRequest
        data = {
            "MetadataContainerId": container_id,
            "isCheckOnly": False
        }
        sync_request_url = '/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest'
        result = self.post(sync_request_url, data)
        request_id = result.get("id")
        print ("Post ContainerAsyncRequest: ", result)

        # Get ContainerAsyncRequest Result
        
        result = self.get(sync_request_url + "/" + request_id)
        state = result["State"]
        print ("Get ContainerAsyncRequest: ")
        pprint.pprint(result)

        return_result = {}
        if state == "Completed":
            return_result = {
                "success": True 
            }

        while state == "Queued":
            print ("Async Request is queued, please wait for 5 seconds...")
            time.sleep(5)

            result = self.get(sync_request_url + "/" + request_id)
            state = result["State"]
            if state == "Completed":
                return_result = {
                    "success": True 
                }

        if state == "Failed":
            # This error need more process, because of confused single quote
            compile_errors = unescape(result["CompilerErrors"])
            compile_errors = json.loads(compile_errors)
            if len(compile_errors) > 0:
                compile_error = compile_errors[0]
                extend = util.none_value(compile_error["extent"])
                line = util.none_value(compile_error["line"])
                problem = util.none_value(compile_error["problem"])
                name = util.none_value(compile_error["name"])
                error_message = extend + ": " + name + " has problem: " +\
                    problem + " at line " + str(line)
            else:
                error_message = result["ErrorMsg"]
            error_message = unescape(error_message, {"&apos;": "'", "&quot;": '"'})
            
            return_result = {
                "success": False,
                "message": error_message
            }

        # Whatever succeed or failed, just delete MetadataContainerId
        delete_result = self.delete(container_url + "/" + container_id)
        status_code = delete_result["status_code"]
        if status_code < 399:
            util.sublime_status_message("container_id is deleted.")

        # Result used in thread invoke
        self.result = return_result
Exemple #4
0
    def save_component(self, component_attribute, body):
        """
        This method contains 5 steps:
        1. Post classid to get MetadataContainerId
        2. Post Component Member
        3. Post ContainerAsyncRequest to get AsyncRequest Id
        4. Get ContainerAsyncRequest Response by Id in step 3
        5. Delete the MetadataContainerId

        Notes: Because if ContainerAsyncRequest has problem, we can't reuse the 
            MetadataContainerId, so we need to delete it and get it every time.

        @component_attribute
        @body: Code content

        """
        # Component Attribute
        component_type = component_attribute["type"]
        component_id = component_attribute["id"]
        component_body = component_attribute["body"]

        # Get MetadataContainerId
        data = {
            "name":
            "Save" + component_type[4:len(component_type)] + component_id
        }
        container_url = '/services/data/v28.0/tooling/sobjects/MetadataContainer'
        result = self.post(container_url, data)
        print("MetadataContainer Response: ", result)

        # If status_code < 399, it means post succeed
        if result["status_code"] < 399:
            container_id = result.get("id")
        else:
            # If status_code < 399, it means post failed,
            # If DUPLICATE Container Id, just delete it and restart this function
            if result["errorCode"] == "DUPLICATE_VALUE":
                error_message = result["message"]
                container_id = error_message[error_message.
                                             rindex("1dc"):len(error_message)]
                delete_result = self.delete(container_url + "/" + container_id)
                if delete_result["status_code"] < 399:
                    util.sublime_status_message("container_id is deleted.")

                # We can't reuse the container_id which caused error
                # Post Request to get MetadataContainerId
                return self.save_component(component_attribute, body)
            else:
                util.sublime_error_message(result)
                return

        # Post ApexComponentMember
        data = {
            "ContentEntityId": component_id,
            "MetadataContainerId": container_id,
            "Body": body
        }
        url = "/services/data/v28.0/tooling/sobjects/" + component_type + "Member"
        result = self.post(url, data)
        print("Post ApexComponentMember: ", result)

        # Post ContainerAsyncRequest
        data = {"MetadataContainerId": container_id, "isCheckOnly": False}
        sync_request_url = '/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest'
        result = self.post(sync_request_url, data)
        request_id = result.get("id")
        print("Post ContainerAsyncRequest: ", result)

        # Get ContainerAsyncRequest Result

        result = self.get(sync_request_url + "/" + request_id)
        state = result["State"]
        print("Get ContainerAsyncRequest: ", result)

        return_result = {}
        if state == "Completed":
            return_result = {"success": True}

        while state == "Queued":
            print("Async Request is queued, please wait for 5 seconds...")
            time.sleep(5)

            result = self.get(sync_request_url + "/" + request_id)
            state = result["State"]
            if state == "Completed":
                return_result = {"success": True}

        if state == "Failed":
            # This error need more process, because of confused single quote
            compile_errors = unescape(result["CompilerErrors"])
            compile_errors = json.loads(compile_errors)
            if len(compile_errors) > 0:
                compile_error = compile_errors[0]
                extend = util.none_value(compile_error["extent"])
                line = util.none_value(compile_error["line"])
                problem = util.none_value(compile_error["problem"])
                name = util.none_value(compile_error["name"])
                error_message = extend + ": " + name + " has problem: " +\
                    problem + " at line " + str(line)
            else:
                error_message = result["ErrorMsg"]
            error_message = unescape(error_message, {
                "&apos;": "'",
                "&quot;": '"'
            })

            return_result = {"success": False, "message": error_message}

        # Whatever succeed or failed, just delete MetadataContainerId
        delete_result = self.delete(container_url + "/" + container_id)
        status_code = delete_result["status_code"]
        if status_code < 399:
            util.sublime_status_message("container_id is deleted.")

        # Result used in thread invoke
        self.result = return_result