def create(self, files):
    for file in files:
        fileName, fileExtension = os.path.splitext(file)
        if fileExtension != '.resource':
            sublime.message_dialog("You can only create resource bundles for static resources")
            return
    printer = PanelPrinter.get(self.window.id())
    printer.show()
    printer.write('\nCreating Resource Bundle(s)\n')

    if not os.path.exists(util.mm_project_directory()+'/resource-bundles'):
        os.makedirs(util.mm_project_directory()+'/resource-bundles')

    for file in files:
        fileName, fileExtension = os.path.splitext(file)
        baseFileName = fileName.split("/")[-1]
        if os.path.exists(os.path.join(util.mm_project_directory(),'resource-bundles',baseFileName+fileExtension)):
            printer.write('[OPERATION FAILED]: The resource bundle already exists\n')
            return
        cmd = 'unzip \''+file+'\' -d \''+util.mm_project_directory()+'/resource-bundles/'+baseFileName+fileExtension+'\''
        os.system(cmd)

    printer.write('[Resource bundle creation complete]\n')
    printer.hide()
    util.send_usage_statistics('Create Resource Bundle') 
    def submit_payload(self, process):
        o = self.operation
        
        if o == 'new_metadata':
            # unique payload parameters
            payload = {
                'project_name'                  : self.project_name,
                'api_name'                      : self.params.get('metadata_name', None),
                'metadata_type'                 : self.params.get('metadata_type', None),
                'apex_trigger_object_api_name'  : self.params.get('object_api_name', None),
                'apex_class_type'               : self.params.get('apex_class_type', None),
                'github_template'               : self.params.get('github_template', None)
            }
            workspace = util.get_project_settings().get("workspace")
            if workspace != None:
                payload['workspace'] = util.get_project_settings().get("workspace")
            else:
                payload['workspace'] = os.path.dirname(util.mm_project_directory())
        else:
            payload = {}
            
            if o != 'new_project' and o != 'new_project_from_existing_directory':
                payload['project_name'] = self.project_name
                workspace = util.get_project_settings().get("workspace")
                if workspace != None:
                    payload['workspace'] = util.get_project_settings().get("workspace")
                else:
                    payload['workspace'] = os.path.dirname(util.mm_project_directory())
        
            #open type
            if o == 'open_sfdc_url':
                payload['type'] = self.params.get('type', 'edit')
            
            if o == 'run_apex_script':
                payload['script_name'] = self.params.get('script_name', None)
                payload['return_log'] = False

            ##catch all
            if self.params != None:
                for key in self.params:
                    if key not in payload:
                        payload[key] = self.params[key]
                
        #debug('>>>>>> ',payload)    

        if type(payload) is dict:
            payload = json.dumps(payload)  
        debug(payload)  
        try:
            process.stdin.write(payload)
        except:
            process.stdin.write(payload.encode('utf-8'))
        process.stdin.close()
def create(self, files, refresh=False):
    for file in files:
        fileName, fileExtension = os.path.splitext(file)
        if fileExtension != '.resource':
            sublime.message_dialog("You can only create resource bundles for static resources")
            return
    
    printer = PanelPrinter.get(self.window.id())
    printer.show()
    if refresh:
        printer.write('\nRefreshing Resource Bundle(s)\n')
    else:
        printer.write('\nCreating Resource Bundle(s)\n')

    if not os.path.exists(os.path.join(util.mm_project_directory(),'resource-bundles')):
        os.makedirs(os.path.join(util.mm_project_directory(),'resource-bundles'))

    for f in files:
        fileName, fileExtension = os.path.splitext(f)
        if sys.platform == "win32":
            baseFileName = fileName.split("\\")[-1]
        else:
            baseFileName = fileName.split("/")[-1]
        if not refresh:
            if os.path.exists(os.path.join(util.mm_project_directory(),'resource-bundles',baseFileName+fileExtension)):
                printer.write('[OPERATION FAILED]: The resource bundle already exists\n')
                return
        if sys.platform == "win32":
            fz = zipfile.ZipFile(f, 'r')
            for fileinfo in fz.infolist():
                path = os.path.join(util.mm_project_directory(),'resource-bundles',baseFileName+fileExtension)
                directories = fileinfo.filename.split('/')
                #directories = fileinfo.filename.split('\\')
                for directory in directories:
                    if directory.startswith('__MACOSX'):
                        continue
                    path = os.path.join(path, directory)
                    if directory == directories[-1]: break # the file
                    if not os.path.exists(path):
                        os.makedirs(path)
                try:
                    outputfile = open(path, "wb")
                    shutil.copyfileobj(fz.open(fileinfo.filename), outputfile)
                except:
                    pass
        else:
            cmd = 'unzip \''+f+'\' -d \''+util.mm_project_directory()+'/resource-bundles/'+baseFileName+fileExtension+'\''
            os.system(cmd)

    printer.write('[Resource bundle creation complete]\n')
    printer.hide()
    community.sync_activity('new_resource_bundle')
def handle_result(operation, process_id, printer, result, thread):
    #print(thread.process_id)
    #print(thread.params)
    process_region = printer.panel.find(process_id,0)
    status_region = printer.panel.find('Result:',process_region.begin())

    try:
        result = json.loads(result)
        if operation == 'compile' and 'actions' in result and util.to_bool(result['success']) == False:
            diff_merge_settings = config.settings.get('mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(result["body"], result["actions"][0].title()):
                    printer.panel.run_command('write_operation_status', {"text": " Diffing with server", 'region': [status_region.end(), status_region.end()+10] })
                    th = MavensMateDiffThread(thread.window, thread.view, result['tmp_file_path'])
                    th.start()
                    
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
            else:
                if sublime.ok_cancel_dialog(result["body"], "Overwrite Server Copy"):
                    printer.panel.run_command('write_operation_status', {"text": " Overwriting server copy", 'region': [status_region.end(), status_region.end()+10] })
                    thread.params['action'] = 'overwrite'
                    sublime.set_timeout(lambda: call('compile', params=thread.params), 100)   
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
   
        else:
            print_result_message(operation, process_id, status_region, result, printer, thread) 
            if operation == 'new_metadata' and 'success' in result and util.to_bool(result['success']) == True:
                if 'messages' in result:
                    if type(result['messages']) is not list:
                        result['messages'] = [result['messages']]
                    for m in result['messages']:
                        if 'package.xml' not in m['fileName']:
                            file_name = m['fileName']
                            location = util.mm_project_directory() + "/" + file_name.replace('unpackaged/', 'src/')
                            sublime.active_window().open_file(location)
                            break
            if 'success' in result and util.to_bool(result['success']) == True:
                if printer != None and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                    printer.hide()  
            elif 'State' in result and result['State'] == 'Completed' and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                #tooling api
                if printer != None:
                    printer.hide()
            if operation == 'refresh':            
                sublime.set_timeout(lambda: sublime.active_window().active_view().run_command('revert'), 200)
                util.clear_marked_line_numbers()
    except AttributeError:   
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
    except Exception:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
def refresh(self, dirs):
    files = []
    for d in dirs:
        static_resource_location = os.path.join(util.mm_project_directory(), "src", "staticresources", os.path.basename(d))
        if os.path.isfile(static_resource_location):
            files.append(static_resource_location)
    create(self, files, True)
def deploy(bundle_name):
    if '.resource' not in bundle_name:
        bundle_name = bundle_name + '.resource'
    message = 'Bundling and deploying to server: ' + bundle_name
    # delete existing sr
    if os.path.exists(os.path.join(util.mm_project_directory(),"src","staticresources",bundle_name)):
        os.remove(os.path.join(util.mm_project_directory(),"src","staticresources",bundle_name))
    # zip bundle to static resource dir 
    os.chdir(os.path.join(util.mm_project_directory(),"resource-bundles",bundle_name))
    if 'darwin' in sys.platform or 'linux' in sys.platform:
        #cmd = "zip -r -X '"+util.mm_project_directory()+"/src/staticresources/"+bundle_name+"' *"      
        #os.system(cmd)
        zip_file = util.zip_directory(os.path.join(util.mm_project_directory(),"resource-bundles",bundle_name), os.path.join(util.mm_project_directory(),"src","staticresources",bundle_name))
    elif 'win32' in sys.platform:
        zip_file = util.zip_directory(os.path.join(util.mm_project_directory(),"resource-bundles",bundle_name), os.path.join(util.mm_project_directory(),"src","staticresources",bundle_name))
    print(zip_file)
    if zip_file.endswith(".zip"):
        os.rename(zip_file, zip_file[:-4])
    #compile
    file_path = os.path.join(util.mm_project_directory(),"src","staticresources",bundle_name)
    params = {
        "files" : [file_path]
    }
    mm.call('compile', params=params, message=message)
    community.sync_activity('deploy_resource_bundle')
 def __handle_new_metadata(self):
     self.__handle_compile_response()
     if 'success' in self.result and util.to_bool(self.result['success']) == True:
         if 'messages' in self.result or 'details' in self.result:
             if 'details' in self.result and 'componentSuccesses' in self.result['details']:
                 self.result['messages'] = self.result['details'].pop('componentSuccesses')
             if type(self.result['messages']) is not list:
                 self.result['messages'] = [self.result['messages']]
             for m in self.result['messages']:
                 if 'package.xml' not in m['fileName']:
                     file_name = m['fileName']
                     location = os.path.join(util.mm_project_directory(),file_name.replace('unpackaged/', 'src/'))
                     sublime.active_window().open_file(location)
                     break
 def __handle_new_metadata(self):
     self.__handle_compile_response()
     if "success" in self.result and util.to_bool(self.result["success"]) == True:
         if "messages" in self.result or "details" in self.result:
             if "details" in self.result and "componentSuccesses" in self.result["details"]:
                 self.result["messages"] = self.result["details"].pop("componentSuccesses")
             if type(self.result["messages"]) is not list:
                 self.result["messages"] = [self.result["messages"]]
             for m in self.result["messages"]:
                 if "package.xml" not in m["fileName"]:
                     file_name = m["fileName"]
                     location = os.path.join(util.mm_project_directory(), file_name.replace("unpackaged/", "src/"))
                     sublime.active_window().open_file(location)
                     break
def handle_result(operation, process_id, printer, result, thread):
    #print(thread.process_id)
    #print(thread.params)
    process_region = printer.panel.find(process_id,0)
    status_region = printer.panel.find('Result:',process_region.begin())

    try:
        result = json.loads(result)
        if operation == 'compile' and 'actions' in result and util.to_bool(result['success']) == False:
            diff_merge_settings = config.settings.get('mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(result["body"], result["actions"][0].title()):
                    printer.panel.run_command('write_operation_status', {"text": " Diffing with server", 'region': [status_region.end(), status_region.end()+10] })
                    th = MavensMateDiffThread(thread.window, thread.view, result['tmp_file_path'])
                    th.start()
                    
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
            else:
                if sublime.ok_cancel_dialog(result["body"], "Overwrite Server Copy"):
                    printer.panel.run_command('write_operation_status', {"text": " Overwriting server copy", 'region': [status_region.end(), status_region.end()+10] })
                    thread.params['action'] = 'overwrite'
                    sublime.set_timeout(lambda: call('compile', params=thread.params), 100)   
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
   
        elif operation == 'test_async':
            responses = []
            if len(result) == 1:
                res = result[0]
                response_string = ""
                if 'detailed_results' in res:
                    all_tests_passed = True
                    for r in res['detailed_results']:
                        if r["Outcome"] != "Pass":
                            all_tests_passed = False
                            break

                    if all_tests_passed:
                        response_string += '[TEST RESULT]: PASS'
                    else:
                        response_string += '[TEST RESULT]: FAIL'
                    
                    for r in res['detailed_results']:
                        if r["Outcome"] == "Pass":
                            pass #dont need to write anything here...
                        else:
                            response_string += '\n'
                            rstring = "====METHOD RESULT===="
                            rstring += "\n"
                            rstring += "{0} : {1}".format(r["MethodName"], r["Outcome"])
                            
                            rstring += "\n\n"
                            rstring += "====STACK TRACE===="
                            rstring += "\n"
                            rstring += r["StackTrace"]

                            rstring += "\n\n"
                            rstring += "====MESSAGE===="
                            rstring += "\n"
                            rstring += r["Message"]
                            rstring += "\n"
                            #responses.append("{0} | {1} | {2} | {3}\n".format(r["MethodName"], r["Outcome"], r["StackTrace"], r["Message"]))
                            responses.append(rstring)
                    response_string += "\n"       
                    response_string += "\n\n".join(responses)
                    printer.panel.run_command('write_operation_status', {'text': response_string, 'region': [status_region.end(), status_region.end()+10] })
                    printer.scroll_to_bottom()
                else:
                    printer.panel.run_command('write_operation_status', {'text': json.dumps(result), 'region': [status_region.end(), status_region.end()+10] })
            else:
                pass #TODO
        
        elif operation == 'run_apex_script':
            if result["success"] == True and result["compiled"] == True:
                printer.panel.run_command('write_operation_status', {'text': " Success", 'region': [status_region.end(), status_region.end()+10] })
                thread.window.open_file(result["log_location"], sublime.TRANSIENT)
            elif result["success"] == False:
                message = " [OPERATION FAILED]: "
                if "compileProblem" in result and result["compileProblem"] != None:
                    message += "[Line: "+str(result["line"]) + ", Column: "+str(result["column"])+"] " + result["compileProblem"] + "\n"
                if "exceptionMessage" in result and result["exceptionMessage"] != None:
                    message += result["exceptionMessage"] + "\n"
                if "exceptionStackTrace" in result and result["exceptionStackTrace"] != None:
                    message += result["exceptionStackTrace"] + "\n"
                printer.panel.run_command('write_operation_status', {'text': message, 'region': [status_region.end(), status_region.end()+10] })
        else:
            print_result_message(operation, process_id, status_region, result, printer, thread) 
            if operation == 'new_metadata' and 'success' in result and util.to_bool(result['success']) == True:
                if 'messages' in result:
                    if type(result['messages']) is not list:
                        result['messages'] = [result['messages']]
                    for m in result['messages']:
                        if 'package.xml' not in m['fileName']:
                            file_name = m['fileName']
                            location = os.path.join(util.mm_project_directory(),file_name.replace('unpackaged/', 'src/'))
                            sublime.active_window().open_file(location)
                            break
            if 'success' in result and util.to_bool(result['success']) == True:
                if printer != None and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                    printer.hide()  
            elif 'State' in result and result['State'] == 'Completed' and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                #tooling api
                if printer != None:
                    printer.hide()
            if operation == 'refresh':            
                sublime.set_timeout(lambda: sublime.active_window().active_view().run_command('revert'), 200)
                util.clear_marked_line_numbers()
    except AttributeError as e:   
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            print(e)
            print(sys.exc_info()[0])
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
    except Exception as e:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            print(e)
            print(sys.exc_info()[0])
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
    def submit_payload(self, process):
        o = self.operation
        
        if o == 'new_metadata':
            # unique payload parameters
            payload = {
                'project_name'                  : self.project_name,
                'api_name'                      : self.params.get('metadata_name', None),
                'metadata_type'                 : self.params.get('metadata_type', None),
                'apex_trigger_object_api_name'  : self.params.get('object_api_name', None),
                'apex_class_type'               : self.params.get('apex_class_type', None),
                'github_template'               : self.params.get('github_template', None)
            }
            workspace = util.get_project_settings().get("workspace")
            if workspace != None:
                payload['workspace'] = util.get_project_settings().get("workspace")
            else:
                payload['workspace'] = os.path.dirname(util.mm_project_directory())
        elif o == 'new_project_from_existing_directory':
            # no project name
            payload = self.params
        else:

            params = {
                'selected': [
                    'unit_test',
                    'deploy'
                ],
                'files': [
                    'compile',
                    'synchronize',
                    'refresh',
                    'refresh_properties',
                    'open_sfdc_url',
                    'delete'
                ],
                'directories': [
                    'refresh',
                    'synchronize',
                    'refresh_properties'
                ],
                'type': [
                    'open_sfdc_url'
                ]
            }

            # common parameters
            if o == 'new_apex_overlay' or o == 'delete_apex_overlay':
                payload = self.params
            else:
                payload = {}

            if o != 'new_project' and o != 'new_project_from_existing_directory':
                payload['project_name'] = self.project_name
                workspace = util.get_project_settings().get("workspace")
                if workspace != None:
                    payload['workspace'] = util.get_project_settings().get("workspace")
                else:
                    payload['workspace'] = os.path.dirname(util.mm_project_directory())

            #selected files
            if o in params['files']:
                payload['files'] = self.params.get('files', [])
            #directories
            if o in params['directories']: 
                payload['directories'] = self.params.get('directories', [])
            #selected metadata
            if o in params['selected']:
                if self.params != None:
                    payload['selected'] = self.params.get('selected', [])
            #open type
            if o in params['type']:
                payload['type'] = self.params.get('type', 'edit')
            
            if self.params != None and 'action' in self.params:
                payload['action'] = self.params.get('action', None)

            if self.params != None and 'metadata_types' in self.params:
                payload['metadata_types'] = self.params.get('metadata_types', None)

            if self.params != None and 'classes' in self.params:
                payload['classes'] = self.params.get('classes', None)

            if o == 'run_apex_script':
                payload['script_name'] = self.params.get('script_name', None)
                payload['return_log'] = False

        #print('>>>>>> ',payload)    

        if type(payload) is dict:
            payload = json.dumps(payload)  
        print(payload)  
        try:
            process.stdin.write(payload)
        except:
            process.stdin.write(payload.encode('utf-8'))
        process.stdin.close()