def add_file(file_path, file_data=None): split_path = file_path.split('/') split_path_is_metadata_folder = [ s in AntMigrationTool.metadata_type_folders.values() and s != '' for s in split_path ] index_for_metadata_folder = split_path_is_metadata_folder.index( True) res = re.search(regex, file_path) folder_path = res.group(1) folder_name = '/'.join(split_path[index_for_metadata_folder:-1]) file_name = split_path[-1] # folder_name = res.group(2) # file_name = res.group(3) if file_name == '*': for item in dir.get_files_list(folder_path): add_file(item) return if file_data is None: file_data = open(file_path, 'rb').read() new_folder_path = '{}/{}'.format(self.push_path, folder_name) new_file_path = '{}/{}'.format(new_folder_path, file_name) dir.make_dir(new_folder_path, delete_first=False) dir.create_file(new_file_path, file_data)
def _write_build_xml(self, path): template = AntMigrationTool.build_xml_template_path # This is a file which contains the commands for the ant program to work. It must already exist in the directory in order for this script to function if not os.path.exists(template): message = "The following file is required in order to retrieve data from Salesforce: {}".format( template) message += '\n See examples at: https://developer.salesforce.com/docs/atlas.en-us.daas.meta/daas/meta_development.htm' raise EnvironmentError(message) dir.create_file(path, open(template, 'r').read())
def _write_build_properties(self, path): file_data = 'sf.username = {}'.format(self.sf.credentials.username) file_data += '\nsf.password = {}{}'.format( self.sf.credentials.password, self.sf.credentials.security_token) file_data += '\nsf.serverurl = {}'.format( 'https://login.salesforce.com' if self.sf.credentials.sandbox == 'False' else 'https://test.salesforce.com') file_data += '\nsf.maxPoll = {}'.format(20) dir.create_file(path, file_data)
def to_xml(self, file_path=None): s = xmltodict.unparse(self.tree, encoding='UTF-8', short_empty_elements=True, pretty=True, indent=' ') + '\n' file_path = file_path or self.xml_file_path if file_path is not None: dir.create_file(file_path, s) return s
def discard_changes(file_path, diff_blob=None, match_lambda=None): changes = get_file_changes_v3(diff_blob, file_path) file_binary = dir.read_file(file_path, mode='rb') file_lines = file_binary.split(b'\n') for change in reversed(changes): result = match_lambda(change) if result is True: g2, g3, g4, g5, g6, g7 = change['info'].group(2, 3, 4, 5, 6, 7) start_index = int(g3) + change['num_preview_lines'] - 1 # start_index = int(g4) - len(change['deletions']) # start_index = int(g4) + 3 - 1 # Add 3 for the "context" lines provided by git, then subtract 1 because of 0-based index lines_to_remove = len(change['additions']) for i in range(lines_to_remove): file_lines.pop(start_index) for i, s in enumerate(change['deletions']): file_lines.insert(start_index + i, s) dir.create_file(file_path, b'\n'.join(file_lines))
def to_xml(self, file_path=None): file_path = file_path or self.xml_file_path copy = ObjDict.deepclone(self.tree) self.fix_quotes(copy, 'GlobalValueSet.description') self.fix_quotes(copy, 'GlobalValueSet.customValue.fullName') self.fix_quotes(copy, 'GlobalValueSet.customValue.label') s = xmltodict.unparse(copy, encoding='UTF-8', short_empty_elements=True, pretty=True, indent=' ') + '\n' s = s.replace('"', '"').replace(''', ''') if file_path is not None: dir.create_file(file_path, s) return s
def set_folder_settings(folder_name, settings: DeploymentSettings): dir.create_file(settings_path(folder_name), json.dumps(asdict(settings), indent=2))
def to_html(data, file_name, additional_header_html='', render_newlines=False, render_links=False, **kwargs): if type(data) is list: data = pd.DataFrame(data) assert type(data) is pd.DataFrame write_file_name = file_name if "/" in file_name else get_download_folder( ) + "/" + file_name if not write_file_name.endswith('.html'): write_file_name += '.html' styling_html = """ <style> .table { border-collapse: collapse; margin: 25px 0; font-size: 0.9em; font-family: sans-serif; min-width: 400px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); } .table thead tr { background-color: #d4d9e1; text-align: left; } .table tbody tr { border-bottom: 1px solid #dddddd; text-align: left; } .table th,td { padding-left: .5em; padding-right: .5em; } .table tbody tr:nth-of-type(even) { background-color: #f3f3f3; } .table tbody tr:last-of-type { border-bottom: 2px solid black; } .table tbody tr:hover { background-color: #ffffc8; } .n { color: #bdbdbd; } </style> """ html_str = data.fillna('#NULL#').to_html(index=False, classes='table', show_dimensions=True, render_links=True) html_str = html_str.replace('<td>#NULL#</td>', '<td class="n">NULL</td>') html_str = html_str.replace('<td></td>', '<td class="n">BLANK</td>') html_str = html_str.replace('<tr style="text-align: right;">', '<tr>') if render_newlines: html_str = html_str.replace('\\n', '<br>') # if render_links: # html_str = re.sub(r'<a\s(href=.*?>.*?)<\/a>', '<a $&</a>', html_str) final_html = f""" <html> <head> <title>{file_name}</title> {styling_html} </head> <body style='width: 100000px'> {html_str} </body> </html> """ dir.create_file(write_file_name, final_html) return
def main(): dist_path = 'output/python-salesforce/' dist_zip_path = 'output/python-salesforce.zip' inclusions = [ r'example-credentials.json', r'.vscode/launch.json', r'.vscode/settings.json', r'locations.py', r'classes/', r'functions/', r'dataloader.py', r'clone_utility.py', r'utility_sf_tasks.py', r'requirements.txt', r'resources/ant/(?:build|fullpullpackage).xml', # r'resources/chromedriver' ] exclusions = [ r'.*?__pycache__', r'.*?.DS_Store', r'classes/gui.py', r'classes/concept_parsing_sql_command', r'classes/salesforce_api_helpers.py', r'classes/csv_file.py', r'classes/formula_parser.py', r'classes/table_file.py', ] inclusions = ['^' + s for s in inclusions] exclusions = ['^' + s for s in exclusions] all_files = [ f[f.find('python-salesforce') + len('python-salesforce') + 1:] for f in dir.get_files_list('./', True) ] filtered_files = [] for f in all_files: matches_a_path = any([re.match(reg, f) != None for reg in inclusions]) matches_no_exclusion = all( [re.match(reg, f) == None for reg in exclusions]) if matches_a_path and matches_no_exclusion: filtered_files.append(f) files = [(f, os.path.join(dist_path, f)) for f in filtered_files] dir.del_dir(dist_path) for src, tar in files: s = dir.read_file(src) if src.endswith('.py'): s = s.replace('*****@*****.**', new_user_email) if src.endswith('.py'): s = s.replace('daniel.hicks_1', new_user_folder_name) if 'example-credentials' in src: tar = tar.replace('example-credentials', 'credentials') dir.create_file(tar, s) prompt( f'\nFiles have been written to {dist_path}. When ready, press Enter to zip the folder' ) # writing files to a zipfile with zipfile.ZipFile(dist_zip_path, 'w') as zip: files_to_zip = dir.listdir(dist_path, recursive=True) for f in files_to_zip: zip.write(f, f.replace('output/python-salesforce/', '')) dir.del_dir(dist_path) print(f'Zip file created:\n{os.path.abspath(dist_zip_path)}') return
def _write(self, path, file_data): return dir.create_file(path, file_data)
def to_xml(self, file_path=None): file_path = file_path or self.xml_file_path copy = ObjDict.deepclone(self.tree) # for elem in getlist(copy.CustomObject, 'fields'): # fix(elem, 'description') # fix(elem, 'defaultValue') # fix(elem, 'inlineHelpText') # fix(elem, 'label') # fix(elem, 'formula') # if 'formula' in elem: # elem.formula = elem.formula.replace('\r\n', '\n') # if 'valueSet' in elem and 'valueSettings' in elem.valueSet: # for item in getlist(elem.valueSet, 'valueSettings'): # fix(item, 'valueName') # if 'valueSet' in elem and 'valueSetDefinition' in elem.valueSet: # for item in getlist(elem.valueSet.valueSetDefinition, 'value'): # fix(item, 'fullName') # fix(item, 'label') # for elem in getlist(copy.CustomObject, 'validationRules'): # fix(elem, 'description') # fix(elem, 'errorMessage') # fix(elem, 'errorConditionFormula') self.fix_quotes( copy, 'CustomObject.fields.valueSet.valueSettings.valueName') self.fix_quotes( copy, 'CustomObject.fields.valueSet.valueSetDefinition.value.fullName') self.fix_quotes( copy, 'CustomObject.fields.valueSet.valueSetDefinition.value.label') self.fix_quotes(copy, 'CustomObject.fields.description') self.fix_quotes(copy, 'CustomObject.fields.defaultValue') self.fix_quotes(copy, 'CustomObject.fields.inlineHelpText') self.fix_quotes(copy, 'CustomObject.fields.label') self.fix_quotes(copy, 'CustomObject.fields.formula') self.fix_quotes(copy, 'CustomObject.validationRules.description') self.fix_quotes(copy, 'CustomObject.validationRules.errorMessage') self.fix_quotes(copy, 'CustomObject.validationRules.errorConditionFormula') self.fix_quotes(copy, 'CustomObject.recordTypes.description') self.fix_quotes(copy, 'CustomObject.listViews.label') self.fix_quotes(copy, 'CustomObject.webLinks.url') for elem in self.tree_path( copy, 'CustomObject.recordTypes.picklistValues.values'): elem.fullName = unparse_hexadecimal_text(elem.fullName) # for elem in getlist(copy.CustomObject, 'recordTypes'): # fix(elem, 'description') # for elem in getlist(copy.CustomObject, 'listViews'): # fix(elem, 'label') # for elem in getlist(copy.CustomObject, 'webLinks'): # fix(elem, 'url') s = xmltodict.unparse(copy, encoding='UTF-8', short_empty_elements=True, pretty=True, indent=' ') + '\n' s = s.replace('&quot;', '"').replace('&apos;', ''') s = s.replace('<allInternalUsers/>', '<allInternalUsers></allInternalUsers>') s = s.replace('<value/>', '<value></value>') if file_path is not None: dir.create_file(file_path, s) return s
def to_json(self, file_path=None): s = json.dumps(self.tree, indent=2) file_path = file_path or self.json_file_path if file_path is not None: dir.create_file(file_path, s) return s