def merge_key(file_output, buffer_size=4096, overwrite=False): """ Merge multiple key file parts to a single key file. """ if not overwrite: pv.path(file_output, "output key", True, False) else: pv.path(file_output, "key", True, True) part_id = 0 fh_output = open(file_output, "wb") while True: part_id += 1 file_key = file_output + "." + str(part_id).rjust(3, "0") if not os.path.exists(file_key): break fh_key = open(file_key, "rb") file_size = common.get_file_size(file_key) byte_blocks = int(file_size / buffer_size) byte_remainder = file_size % buffer_size for block in range(byte_blocks): fh_output.write(fh_key.read(buffer_size)) if byte_remainder > 0: fh_output.write(fh_key.read(byte_remainder)) fh_key.close() fh_output.close()
def read_option(file_path, section, option, fallback=None): """ Parse config file and read out the value of a certain option. """ try: # For details see the notice in the header import paval as pv pv.path(file_path, "config", True, True) pv.string(section, "section string") pv.string(option, "option string") except NameError: pass c = ConfigParser.RawConfigParser() c.read(file_path) value = "" try: value = c.get(section, option) except ConfigParser.NoSectionError: if fallback: return str(fallback) else: raise Exception("This section does not exist in the given " \ "config file.") except ConfigParser.NoOptionError: if fallback: return str(fallback) else: raise Exception("This option does not exist in the given " \ "section.") return str(value)
def __export(self, overwrite): """ Core method to export encryption parameters into a config file. """ if overwrite: if os.path.exists(self.__file_export): os.remove(self.__file_export) else: pv.path(self.__file_export, "export", True, False) relative_paths = bool( int(common.global_config(["Export"], ["relative_paths"], "0"))) if relative_paths: file_input = self.__file_input.split(os.sep)[-1] file_key = self.__file_key.split(os.sep)[-1] file_output = self.__file_output.split(os.sep)[-1] else: file_input = self.__file_input file_key = self.__file_key file_output = self.__file_output f = self.__file_export s = "Erfr" parameter.write_option(f, s, "version", get_version(), True) s = "Task" if self.__task_id == None: parameter.write_option(f, s, "task_id", 0) else: parameter.write_option(f, s, "task_id", int(self.__task_id)) s = "Files" parameter.write_option(f, s, "input_file", file_input) parameter.write_option(f, s, "key_file", file_key) parameter.write_option(f, s, "output_file", file_output) s = "Options" parameter.write_option(f, s, "buffer_size", int(self.__buffer_size)) parameter.write_option( \ f, s, "use_existing_key", int(self.__existing_key)) parameter.write_option(f, s, "overwrite", int(self.__overwrite)) s = "Obfuscation" parameter.write_option( \ f, s, "obfuscate_enc",int(self.__obfuscate_enc)) parameter.write_option( \ f, s, "obfuscate_key", int(self.__obfuscate_key)) s = "PRNG" parameter.write_option(f, s, "fortuna", int(self.__fortuna)) parameter.write_option(f, s, "dev_random", int(self.__dev_random)) s = "Rotation" if self.__rotate: parameter.write_option(f, s, "rotate_min", int(self.__rotate_min)) parameter.write_option(f, s, "rotate_max", int(self.__rotate_max)) parameter.write_option( \ f, s, "rotate_step", int(self.__rotate_step)) parameter.write_option(f, s, "rotate_mod", int(self.__rotate_mod)) s = "Reversion" if self.__reverse: parameter.write_option( \ f, s, "reverse_bytes", int(self.__reverse_bytes)) s = "S-box" parameter.write_option(f, s, "sbox", int(self.__sbox))
def foobar(input_file, file_list, option, buffer_size, count): """ Sample method showing some usage examples. """ # First of all, check if the paramters have the correct type pv.param_type_list([[input_file, "input file", str], [file_list, "file list", list], [option, "option", str], [buffer_size, "buffer size", int], [count, "count", int]]) # Ensure that 'input_file' exists pv.path(input_file, "input file", True, True) # Ensure that 'input_file' is not identical with any from 'file_list' pv.compfile(input_file, "input file", file_list) # Ensure that the file name of 'input_file' does not contain any wildcards # and also that it does not contain brackets or exlamation marks pv.string(input_file, "input file", False, ['(', ')', '!']) # Ensure 'option' is one of the options from the list pv.compstr(option, "option", ["print", "read", "write"]) # Ensure that 'buffer_size' is a postive integer between 1 and 4096 pv.intrange(buffer_size, "buffer size", 1, 4096, False) # Finally, ensure that 'count' is either zero or a positive integer pv.intvalue(count, "count", True, True, False) print("Parameter validation successful.")
def __get_content(directory, ignore_read_errors, list_content, lines_ignored): """ Gather the content for building the content file. """ pv.path(directory, "source directory", False, True) directory = os.path.abspath(directory) ignored = 0 list_dirs = [] for item in os.listdir(directory): path = os.path.join(directory, item) if os.path.isfile(path): list_content.append(path) else: list_content.append(path) list_dirs.append(path) for directory in list_dirs: try: content, ignored = \ __get_content(directory, ignore_read_errors, list_content, lines_ignored) except: if ignore_read_errors: lines_ignored += (ignored + 1) else: raise Exception("Unable to read the contents of the " \ "directory \"%s\" (maybe a permission " \ "problem)." % directory) return list_content, lines_ignored
def extract_bytes(file_input, file_output, offset=0, length=0, buffer_size=4096, overwrite=False, remove=False): """ Extract a user-defined byte range into a separate file. """ pv.path(file_input, "input", True, True) if not overwrite: pv.path(file_output, "output", True, False) pv.compfile(file_input, "input", [[file_output, "output"]]) pv.intvalue(offset, "offset", True, True, False) pv.intvalue(length, "length", True, False, False) pv.intvalue(buffer_size, "buffer size", True, False, False) file_input = os.path.abspath(file_input) file_output = os.path.abspath(file_output) offset = int(offset) length = int(length) buffer_size = int(buffer_size) file_size = get_file_size(file_input) if (offset + length) > file_size: exception("With this offset the maximal length is %s bytes." % \ str(file_size - offset)) __extract_bytes(file_input, file_output, offset, length, buffer_size, remove)
def get_file_size(file_path): """ Get the size of a file in bytes. """ pv.path(file_path, "", True, True) f = open(file_path, "rb") f.seek(0, 2) file_size = f.tell() f.close() return int(file_size)
def remove_section(file_path, section): """ Remove a certain section from the parameter file. """ pv.path(file_path, "parameter", True, True) pv.string(section, "section string") c = ConfigParser.RawConfigParser() c.read(file_path) c.remove_section(section) with open(file_path, 'w') as fh_parameter: c.write(fh_parameter)
def replace_chars(config_file, string="", remove_spaces=False, remove_chars=False, number=1, sort_length=False): """ Replace characters in a string based on the given config file. """ pv.string(string, "string to modify") pv.intrange(number, "number of strings", 1, None) try: pv.path(config_file, "config", True, True) except: config_dir = os.path.abspath(os.path.dirname(sys.argv[0])) config_file = \ os.path.join(config_dir, "cfg", os.path.basename(config_file)) pv.path(config_file, "config", True, True) config_file = os.path.abspath(config_file) number = int(number) if remove_spaces: string = string.replace(" ", "") if remove_chars: chars = __read_option(config_file, "Remove", "Characters") chars = chars.replace(" ", "") for char in chars: string = string.replace(char, "") dict_chars = {} for char in string: if char in ("[", "]", "=", ";", ","): continue value = __read_option(config_file, "Replace", char.upper()) if char not in dict_chars: replace_chars = value.strip(", ").replace(" ", "").split(",") dict_chars.update({char: replace_chars}) output = [] for n in range(number): string_new = __transform(string, output, dict_chars) output.append(string_new) if sort_length: output = sorted(output, key=len, reverse=True) return output
def compare_files(file_input, directory, ignore_read_errors=True, obfuscate_enc=0, obfuscate_key=0): """ Compare files to find out which key fits to an encrypted file and vice versa. """ pv.path(file_input, "input", True, True) pv.path(directory, "compare", False, True) pv.intvalue(obfuscate_enc, "encrypted file obfuscation", True, True, \ False) pv.intvalue(obfuscate_key, "key file obfuscation", True, True, False) obfuscate_enc = int(obfuscate_enc) obfuscate_key = int(obfuscate_key) file_input = os.path.abspath(file_input) file_input_size = int(common.get_file_size(file_input)) directory = os.path.abspath(directory) list_files = [] for item in os.listdir(directory): path = os.path.join(directory, item) if os.path.isfile(path): if path == file_input: continue file_enc_size1 = int(common.get_file_size(path) + obfuscate_enc) file_enc_size2 = int(common.get_file_size(path) - obfuscate_enc) file_key_size1 = int(common.get_file_size(path) + obfuscate_key) file_key_size2 = int(common.get_file_size(path) - obfuscate_key) try: if file_input_size == file_enc_size1 or \ file_input_size == file_enc_size2 or \ file_input_size == file_key_size1 or \ file_input_size == file_key_size2: list_files.append(path) except Exception as e: if not ignore_read_errors: raise Exception(e) else: pass list_files.sort() return list_files
def __config_abspath(config, description): """ Get the absolute path of a config file. """ description += " config" try: pv.path(config, description, True, True) except: config_dir = os.path.abspath(os.path.dirname(sys.argv[0])) config = os.path.join(config_dir, "cfg", os.path.basename(config)) pv.path(config, description, True, True) config = os.path.abspath(config) return config
def indent(directory, file_ext, spaces=4, padding=12, left_justify=False, recursive=False, overwrite=False, verbose=False): """ Method to perform the indentation process. """ pv.path(directory, "input", False, True) pv.string(file_ext, "file extension", False, None) pv.intvalue(spaces, "spaces", True, False, False) pv.intvalue(padding, "padding", True, False, False) directory = os.path.abspath(directory) spaces = int(spaces) padding = int(padding) num = 1 if verbose: print "\nGathering files to process. Please wait.\n" list_files = common.get_files(directory, file_ext, recursive) if len(list_files) == 0: if verbose: print "No files to process.\n" return just = len(str(len(list_files))) for file_input in list_files: if verbose: print "Processing file %s of %s: '%s'" % \ (str(num).rjust(just, " "), str(len(list_files)), file_input) num += 1 if overwrite: __indent_file(file_input, spaces, padding, left_justify) else: __indent_copy(file_input, spaces, padding, left_justify) if verbose: print "\nFinished.\n"
def write_option(file_path, section, option, value="", new_file=False): """ Write an option into a parameter file. """ if not new_file: pv.path(file_path, "parameter", True, True) pv.string(section, "section string") pv.string(option, "option string") c = ConfigParser.RawConfigParser() c.read(file_path) if not section in c.sections(): c.add_section(section) c.set(section, option, value) with open(file_path, 'w') as fh_parameter: c.write(fh_parameter)
def remove_section(file_path, section): """ Remove a certain section from the config file. """ try: # For details see the notice in the header import paval as pv pv.path(file_path, "config", True, True) pv.string(section, "section string") except NameError: pass c = ConfigParser.RawConfigParser() c.read(file_path) c.remove_section(section) with open(file_path, 'w') as fh_config: c.write(fh_config)
def write_option(file_path, section, option, value="", new_section=False, new_file=False, force=False): """ Write an option into a config file. """ try: # For details see the notice in the header import paval as pv if not force: if new_file: pv.path(file_path, "config", True, False) new_section = True else: pv.path(file_path, "config", True, True) pv.string(section, "section string") pv.string(option, "option string") except NameError: if new_file: new_section = True c = ConfigParser.RawConfigParser() c.read(file_path) if force: # This makes the parameters "new_section" and "new_file" obsolete, so # they will be ignored if not section in c.sections(): c.add_section(section) else: if new_section: if section in c.sections(): raise Exception("This section cannot be created, because " \ "it already exists.") c.add_section(section) else: if not section in c.sections(): raise Exception("This section does not exist.") c.set(section, option, value) with open(file_path, 'w') as fh_config: c.write(fh_config)
def get_content_zip(archive, ignore_read_errors): """ Get the contents of a ZIP archive file. """ pv.path(archive, "archive", True, True) read_error = False try: archive_content = __get_content_zip(os.path.abspath(archive)) except: if ignore_read_errors: archive_content = None read_error = True else: raise Exception("Unable to read the contents of the ZIP " \ "archive \"%s\" (maybe a permission problem)." \ % archive) return archive_content, read_error
def obfuscate_file(task_id, file_path, buffer_size=4096, bytes_random=0, dev_random=False, fortuna=False): """ Create a task file first, then add given amount of random bytes to the given file. """ pv.path(file_path, "target", True, True) pv.intvalue(buffer_size, "buffer size", True, False, False) pv.intvalue(bytes_random, "random bytes", True, False, False) buffer_size = int(buffer_size) bytes_random = int(bytes_random) file_path = os.path.abspath(file_path) file_size = common.get_file_size(file_path) + int(bytes_random) common.build_task_file(task_id, file_path, file_size, None, 0, None, 0, "file obfuscation") add_random_bytes(file_path, buffer_size, bytes_random, dev_random, fortuna)
def get_files(directory): """ Get all content files which are stored in the given directory. """ pv.path(directory, "content file", False, True) directory = os.path.abspath(directory) list_files = [] for item in os.listdir(directory): path = os.path.join(directory, item) if os.path.exists(path) and os.path.isfile(path): if path.endswith(".dcl"): list_files.append(path) list_files.sort() if len(list_files) > 0: return list_files else: raise Exception("No content files found inside the given " + \ "directory.")
def generate_key_file(task_id, file_path, file_size, buffer_size=4096, bytes_random=0, use_existing_key=False, dev_random=False, fortuna=False, overwrite=False, parts=1): """ Create a task file first, then build the key file. """ if use_existing_key: pv.path(file_path, "key", True, True) else: if not overwrite: pv.path(file_path, "key", True, False) pv.intvalue(file_size, "key file size", True, False, False) pv.intvalue(buffer_size, "buffer size", True, False, False) pv.intvalue(bytes_random, "random bytes", True, True, False) pv.intvalue(parts, "key file parts", True, False, False) file_path = os.path.abspath(file_path) file_size = int(file_size) buffer_size = int(buffer_size) bytes_random = int(bytes_random) if parts == 1: generation_type = "key generation" else: generation_type = "multi-part key generation" file_size = file_size + bytes_random common.build_task_file(task_id, file_path, file_size, None, 0, None, 0, generation_type) build_file_key(file_path, file_size, buffer_size, bytes_random, False, dev_random, fortuna, overwrite, parts)
def read_option(file_path, section, option, fallback=None, empty=True): """ Parse parameter file and read out the value of a certain option. """ pv.path(file_path, "parameter", True, True) pv.string(section, "section string") pv.string(option, "option string") c = ConfigParser.RawConfigParser() c.read(file_path) value = "" try: value = c.get(section, option) except ConfigParser.NoSectionError: if fallback: return str(fallback) else: pass except ConfigParser.NoOptionError: if fallback: return str(fallback) else: pass try: int(value) return int(value) except: value = str(value) if len(value) > 0: return value else: if empty: return value else: if fallback == None: return None else: return str(fallback)
def add_random_bytes(file_path, buffer_size=4096, bytes_random=0, dev_random=False, fortuna=False): """ Add given amount of random bytes to a file. """ delay = common.get_delay() pv.path(file_path, "target", True, True) pv.intvalue(buffer_size, "buffer size", True, False, False) pv.intvalue(bytes_random, "random bytes", True, False, False) buffer_size = int(buffer_size) bytes_random = int(bytes_random) file_path = os.path.abspath(file_path) byte_blocks = int(bytes_random / buffer_size) byte_remainder = bytes_random % buffer_size data_random = bytearray(b"") always_use_urandom = \ bool(int(common.global_config(["Obfuscator"], ["always_use_urandom"], dev_random))) if always_use_urandom: dev_random = False prng = randgen.get_prng(dev_random, fortuna) fh_target = open(file_path, "ab") for block in range(byte_blocks): data_random = prng.get_bytes(buffer_size) fh_target.write(data_random) time.sleep(delay) if byte_remainder > 0: data_random = prng.get_bytes(byte_remainder) fh_target.write(data_random) time.sleep(delay) fh_target.close()
def replace(directory, file_ext, mode, spaces=8, recursive=False, overwrite=False, verbose=True): """ Method to perform the replacement process. """ pv.path(directory, "input", False, True) pv.string(file_ext, "file extension", False, None) mode = mode.lower() pv.compstr(mode, "mode", ["spaces", "tabs"]) pv.intvalue(spaces, "spaces", True, False, False) directory = os.path.abspath(directory) spaces = int(spaces) num = 1 if verbose: print "\nGathering files to process. Please wait.\n" list_files = common.get_files(directory, file_ext, recursive) just = len(str(len(list_files))) for file_input in list_files: if verbose: print "Processing file %s of %s: '%s'" % \ (str(num).rjust(just, " "), str(len(list_files)), file_input) num += 1 if overwrite: __replace_file(file_input, mode, spaces) else: __replace_copy(file_input, mode, spaces) if verbose: print "\nFinished.\n"
def get_content_rar(archive, bin_unrar, ignore_read_errors): """ Get the contents of a RAR archive file (requires "unrar" tool). """ pv.path(archive, "archive", True, True) pv.path(bin_unrar, "UnRAR binary", True, True) archive = os.path.abspath(archive) bin_unrar = os.path.abspath(bin_unrar) read_error = False try: archive_content = __get_content_rar(archive, bin_unrar) except: if ignore_read_errors: archive_content = None read_error = True else: raise Exception("Unable to read the contents of the RAR " \ "archive \"%s\" (maybe a permission problem)." \ % archive) return archive_content, read_error
def find_term(content_file, search_term, ignore_case=True, regex_syntax=False): """ Search a content file for the given search term. """ pv.path(content_file, "content file", True, True) pv.string(search_term, "search term", True, None) content_file = os.path.abspath(content_file) list_matches = [] regex = common.compile_regex(search_term, ignore_case, regex_syntax) fh_content = open(content_file, "r") for line in fh_content: if ignore_case: if regex.match(line.lower()): list_matches.append(line.replace("\n", "")) else: if regex.match(line): list_matches.append(line.replace("\n", "")) fh_content.close() list_matches.sort() return list_matches
def build_content_file(dir_destination, content_file, dir_source, ignore_read_errors=False, pattern_exclude=None, ignore_exclude_case=True, regex_syntax=False, bin_unace=None, bin_unrar=None, read_tar=False, read_zip=False, replace_string=None): """ Create a content file from the given directory. """ pv.path(dir_destination, "destination", False, True) pv.path(dir_source, "source", False, True) pv.path(content_file, "content", True, False) dir_destination = os.path.abspath(dir_destination) dir_source = os.path.abspath(dir_source) if not dir_destination.endswith(os.sep): dir_destination += os.sep if not dir_source.endswith(os.sep): dir_source += os.sep regex = None if not pattern_exclude == None: regex = common.compile_regex(pattern_exclude, ignore_exclude_case, regex_syntax) content_file_path = os.path.join(dir_destination, content_file) if not content_file_path.endswith(".dcl"): content_file_path += ".dcl" if os.path.exists(content_file_path): if os.path.isfile(content_file_path): raise Exception("The given content file already exists.") elif os.path.isdir(content_file_path): raise Exception("The given content file path does not seem " + \ "to be a file.") stats = __build_content_file(content_file_path, dir_source, ignore_read_errors, regex, ignore_exclude_case, bin_unace, bin_unrar, read_tar, read_zip, replace_string) return stats
def split_key(file_input, parts, buffer_size=4096, overwrite=False): """ Split a key file in a user-defined number of parts. """ if not overwrite: pv.path(file_input, "key", True, True) pv.path(file_input + ".001", "key part", True, False) else: pv.path(file_input, "key", True, True) buffer_size = int(buffer_size) parts = int(parts) if parts < 2: common.exception("The number of key parts must be greater than 1.") elif parts > 999: common.exception("The number of key parts must be less than 1000.") file_size = common.get_file_size(file_input) part_id = 0 part_size = int(file_size / parts) part_last = file_size - (part_size * (parts - 1)) fh_input = open(file_input, "rb") for part in range(parts): part_id += 1 file_key = file_input + "." + str(part_id).rjust(3, "0") if part_id < parts: file_size = int(part_size) else: file_size = int(part_last) fh_output = open(file_key, "wb") byte_blocks = int(file_size / buffer_size) byte_remainder = file_size % buffer_size for block in range(byte_blocks): fh_output.write(fh_input.read(buffer_size)) if byte_remainder > 0: fh_output.write(fh_input.read(byte_remainder)) fh_output.close() fh_input.close()
def __prepare_process(self, task_id, file_input, file_key, file_output, buffer_size, existing_key, overwrite, obfuscate_enc, obfuscate_key, fortuna, dev_random, rotate_min, rotate_max, rotate_step, rotate_mod, reverse_bytes, sbox, skip_checks): """ Prepare the requested process by checking the given parameters and execute the appropriate method. """ if not skip_checks: pv.path(file_input, "input", True, True) if not overwrite: if self.__encrypt: pv.path(file_key, "key", True, existing_key) pv.path(file_output, "output", True, False) pv.compfile(file_input, "input", [[file_key, "key"], [file_output, "output"]]) pv.intvalue(buffer_size, "buffer size", True, False, False) pv.intvalue(obfuscate_enc, "encrypted file obfuscation byte", True, True, False) pv.intvalue(obfuscate_key, "key file obfuscation byte", True, True, False) if rotate_min == None and rotate_max == None and rotate_step == None: self.__rotate = False else: pv.intvalue(rotate_min, "minimum rotation", True, True, False) pv.intvalue(rotate_max, "maximum rotation", True, True, False) pv.intvalue(rotate_min, "rotation step", True, False, True) range_value_min, range_value_max, range_value_step = \ common.validate_range(rotate_min, rotate_max, rotate_step) self.__rotate = True if reverse_bytes == None: self.__reverse = False else: pv.intrange(reverse_bytes, "reverse byte", 2, None, False) self.__reverse = True self.__task_id = task_id self.__fortuna = fortuna self.__dev_random = dev_random self.__file_input = os.path.abspath(file_input) self.__file_key = os.path.abspath(file_key) self.__file_output = os.path.abspath(file_output) self.__buffer_size = int(buffer_size) self.__existing_key = existing_key self.__overwrite = overwrite self.__obfuscate_enc = int(obfuscate_enc) self.__obfuscate_key = int(obfuscate_key) self.__sbox = sbox if self.__rotate: self.__rotate_min = int(rotate_min) self.__rotate_max = int(rotate_max) self.__rotate_step = int(rotate_step) self.__rotate_mod = rotate_mod self.__rotate_obj = rt.Rotate(self.__rotate_min, self.__rotate_max, self.__rotate_step, self.__rotate_mod) if self.__reverse: self.__reverse_bytes = int(reverse_bytes)
def modify_names(directory, action, position, input_string, replace_string=None, recursive=False, exclude=None, pattern=None, ignore_case=True, regex_syntax=False, report_file=None, ignore_symlinks=False, strip_chars=None): """ Modify the base name of files by adding, removing or replacing a user-defined string. """ pv.path(directory, "given", False, True) pv.compstr(action, "action", ["add", "remove", "replace"]) pv.compstr(position, "position", ["any", "prefix", "suffix"]) pv.string(input_string, "input string", False, common.get_invalid_chars()) action = action.lower() position = position.lower() directory = os.path.abspath(directory) if not directory.endswith(os.path.sep): directory += os.path.sep if report_file == None: simulate = False else: pv.path(report_file, "report", True, False) report_file = os.path.abspath(report_file) simulate = True if not replace_string == None: if not action == "replace": raise Exception("The replace string argument can only be used " \ "together with the action 'replace'.") else: pv.string(replace_string, "string False", False, common.get_invalid_chars()) if action == "add" and position == "any": raise Exception("The position 'any' cannot be used together with " \ "the action 'add'.") if len(input_string) == 0: raise Exception("The input string must not be empty.") else: pv.string(input_string, "input string", False, common.get_invalid_chars()) if not strip_chars == None: pv.string(strip_chars, "strip chars string", False, common.get_invalid_chars()) time_start = dt.now() list_content = [] list_excluded = [] list_renamed = [] list_skipped = [] regex = None if not pattern == None: regex = common.compile_regex(pattern, ignore_case, regex_syntax) list_content, list_excluded = \ common.get_files(directory, recursive, ignore_case, regex, exclude, ignore_symlinks) for item in list_content: list_files = item[1] __modify_names(list_files, list_renamed, list_skipped, action, position, input_string, replace_string, strip_chars) if simulate: explicit = None if exclude == None: exclude = False explicit = False elif exclude: explicit = False else: explicit = True list_header = [] list_header.append("Nomen File Name Modifier simulation report") list_header.append(["Report file name:", report_file]) list_header.append(["Directory:", directory]) list_header.append(["Recursive:", recursive]) list_header.append(["Ignore symlinks:", ignore_symlinks]) list_header.append(["Action to perform:", action.capitalize()]) list_header.append(["Position:", position.capitalize()]) list_header.append(["Input string:", "\"" + input_string + "\" " \ "(without double quotes)"]) if not replace_string == None: list_header.append(["Replace string:", "\"" + replace_string + \ "\" (without double quotes)"]) if strip_chars == None: list_header.append(["Strip chars:", "None"]) else: list_header.append(["Strip chars:", "\"" + strip_chars + "\" " \ "(without double quotes)"]) list_header.append(["Exclude files:", exclude]) list_header.append(["Explicit files:", explicit]) list_header.append(["Pattern:", pattern]) list_header.append(["Ignore case:", ignore_case]) list_header.append(["Regex syntax:", regex_syntax]) common.report(report_file, list_header, list_renamed, list_excluded, list_skipped, time_start) else: common.rename(list_renamed)
def rename_files(directory, rename_mode, separator=" ", recursive=False, padding=0, exclude=None, pattern=None, ignore_case=True, regex_syntax=False, report_file=None, ignore_symlinks=False, ignore_file_ext=False, custom_name=None, step=1, order_by=None): """ Rename the base name of files based on the name of the directory where they are stored in and add a numeric ID. """ pv.path(directory, "given", False, True) pv.compstr(rename_mode, "rename mode", ["fill-gaps", "increase", "keep-order", "rename-new"]) pv.intrange(padding, "padding", 0, 12, True) pv.string(separator, "seperator", False, common.get_invalid_chars()) pv.intvalue(step, "step", True, False, False) if not order_by == None: pv.compstr(order_by, "order by", ["accessed", "created", "modified"]) if not rename_mode == "keep-order": raise Exception("The order-by argument can only be used in " \ "combination with keep-order mode.") step = int(step) rename_mode = rename_mode.lower() directory = os.path.abspath(directory) if not directory.endswith(os.path.sep): directory += os.path.sep if report_file == None: simulate = False else: pv.path(report_file, "report", True, False) report_file = os.path.abspath(report_file) simulate = True if not custom_name == None: pv.string(custom_name, "custom file name", False, common.get_invalid_chars()) time_start = dt.now() list_content = [] list_excluded = [] list_renamed = [] list_skipped = [] regex = None if not pattern == None: regex = common.compile_regex(pattern, ignore_case, regex_syntax) list_content, list_excluded = \ common.get_files(directory, recursive, ignore_case, regex, exclude, ignore_symlinks, order_by) for item in list_content: list_files = item[1] if rename_mode == "fill-gaps": list_renamed, list_skipped = \ __rename_files_fill(list_files, list_renamed, list_skipped, separator, padding, True, ignore_file_ext, custom_name, step) elif rename_mode == "rename-new": list_renamed, list_skipped = \ __rename_files_fill(list_files, list_renamed, list_skipped, separator, padding, False, ignore_file_ext, custom_name, step) elif rename_mode == "keep-order": list_renamed, list_skipped = \ __rename_files_keep_order(list_files, list_renamed, list_skipped, separator, padding, ignore_file_ext, custom_name, step, order_by) else: raise Exception("An invalid rename mode was given.") if simulate: if padding == 0: padding = "Set automatically" else: padding = str(padding) explicit = None if exclude == None: exclude = False explicit = False elif exclude: explicit = False else: explicit = True if order_by == "accessed": order_by = "Access time" elif order_by == "created": order_by = "Creation time" elif order_by == "modified": order_by = "Modification time" else: order_by = "False" list_header = [] list_header.append("Nomen File Renamer simulation report") list_header.append(["Report file name:", report_file]) list_header.append(["Directory:", directory]) list_header.append(["Recursive:", recursive]) list_header.append(["Ignore symlinks:", ignore_symlinks]) list_header.append(["Rename mode:", rename_mode.capitalize()]) list_header.append(["Order by time:", order_by]) list_header.append(["Separator:", "\"" + separator + "\" " \ "(without double quotes)"]) list_header.append(["Numeric padding:", padding]) list_header.append(["Step size:", step]) list_header.append(["Exclude files:", exclude]) list_header.append(["Explicit files:", explicit]) list_header.append(["Pattern:", pattern]) list_header.append(["Ignore case:", ignore_case]) list_header.append(["Regex syntax:", regex_syntax]) common.report(report_file, list_header, list_renamed, list_excluded, list_skipped, time_start) else: common.rename(list_renamed)
import common import os import paval as pv import re import statcase from datetime import datetime as dt def convert_case(directory, case, conflict_mode, recursive=False, cfg_lower=None, cfg_mixed=None, cfg_title=None, cfg_upper=None, report_file=None, ignore_symlinks=False): """ Convert the case of the base name of files. """ pv.path(directory, "given", False, True) pv.compstr(case, "case", ["lower", "title", "upper", "config"]) pv.compstr(conflict_mode, "conflict mode", ["rename", "skip"]) case = case.lower() conflict_mode = conflict_mode.lower() directory = os.path.abspath(directory) if not directory.endswith(os.path.sep): directory += os.path.sep if report_file == None: simulate = False else: pv.path(report_file, "report", True, False) report_file = os.path.abspath(report_file) simulate = True