Beispiel #1
0
def slice_file(path, size, offset=0, whence=0, output_dir=None, slice_name=None, slice_ext=None):
    """Write a new file from a slice of an existing file

    Args:
        path (str): Path of existing file.
        size (int): Read length in bytes.
        offset (int): (optional) Offset from the whence position. Defaults to 0.
        whence (int): (optional) Originating file seek position. 0 - Absolute, 1 - Current, 2 - End of file. Defaults to 0.
        output_dir (str): (optional) Path to the directory where new file is saved.
        slice_name (str): (optional) File name of the slice file. Defaults to the full file's name (with extension).
        slice_ext (str): (optional) File extension of the slice file. Defaults to 'slice_oYYwXX' where YY and XX are the offset and whence respectively.

    Returns:
        str: File path of slice file.

    """
    if not is_str_not_empty(path): raise ValueError("file path must be a string")
    if not is_int_pos(size): raise ValueError("size must be a positive integer")
    if not is_int_not_neg(offset): raise ValueError("offset must be a non negative integer")
    if whence not in [0,1,2]: raise ValueError("whence must be 0 - Absolute, 1 - Current, 2 - End of file")

    output_dir = os.path.abspath('.') if output_dir is None else os.path.abspath(output_dir)
    ext = slice_ext if is_str_not_empty(slice_ext) else 'slice_o' + str(offset) + 'w' + str(whence)
    name = slice_name if is_str_not_empty(slice_name) else os.path.split(path)[1]

    slice_path = os.path.abspath(os.path.join(output_dir, name + '.' + ext))

    write_file(slice_path, read_file(path, size, offset, whence))

    return slice_path
Beispiel #2
0
def read_file(path, size=None, offset=0, whence=0):
    """Read a file in binary mode

    Args:
        path (str): Path of file.
        size (int): Read length in bytes. Defaults to None.
        offset (int): (optional) Offset from the whence position. Defaults to 0.
        whence (int): (optional) Originating file seek position. 0 - Absolute, 1 - Current, 2 - End of file. Defaults to 0.

    Returns:
        str: Binary data.

    """
    if not is_str_not_empty(path): raise ValueError("file path must be a string")
    if not is_int_not_neg(offset): raise ValueError("offset must be a positive integer")
    if whence not in [0,1,2]: raise ValueError("whence must be 0 - Absolute, 1 - Current, 2 - End of file")

    f = open(path, 'rb')
    f.seek(offset, whence)
    if size is None:
        data = f.read()
    else:
        data = f.read(size)
    f.close()
    return data
Beispiel #3
0
def list_dir(dir=".", recurse=True, depth=0, get_file=True, get_dir=True):
    """Search a directory for files and directories

    Args:
        dir (str): (optional) Directory to search. Suggestion: use absolute path. Defaults to current working directory.
        recurse (bool): (optional) Recursive search flag. Defaults to True.
        depth (int): (optional) Set the recursion depth. Defaults to 0, which has a max of Python's recursion limit.
        get_dir (bool): (optional) Return entry for directory. Defaults to True.
        get_file (bool): (optional) Return entry for file. Defaults to True.

    Returns:
        list: List of strings of paths for files and directories.

    """
    if not is_str_not_empty(dir):
        raise ValueError("dir must be a non empty string")
    if not os.path.isdir(dir):
        raise ValueError("dir must be a valid directory")
    if not is_bool(recurse):
        raise TypeError("recurse must be True or False")
    if is_int_neg(depth):
        raise ValueError("depth must be >= 0")
    if not is_bool(get_file):
        raise TypeError("get_file must be True or False")
    if not is_bool(get_dir):
        raise TypeError("get_dir must be True or False")

    list = []
    i = 0
    if recurse == True:
        os_walk = os.walk(dir, topdown=True)
        for root, dirs, files in os_walk:
            if get_file == True:
                for name in files:
                    list.append(os.path.join(os.path.abspath(root), name))
            if get_dir == True:
                for name in dirs:
                    list.append(os.path.join(os.path.abspath(root), name))
            i += 1
            if depth == i:
                break
    else:
        listdir = os.listdir(dir)
        for name in listdir:
            path = os.path.join(os.path.abspath(dir), name)
            if get_dir == True and get_file == True:
                list.append(path)
            elif get_file == True and os.path.isfile(path) == True:
                list.append(path)
            elif get_dir == True and os.path.isdir(path) == True:
                list.append(path)
    return list
Beispiel #4
0
def hash_file(hash_name, path, size=None, offset=0, whence=0):
    """Return the hash of a file

    Args:
        hash_name (str): Hash algorithm name. See :py:mod:`hashlib`
        path (str): Path of file.
        size (int): (optional) Read length in bytes. Defaults to None.
        offset (int): (optional) Offset from the whence position. Defaults to 0.
        whence (int): (optional) Originating file seek position. 0 - Absolute, 1 - Current, 2 - End of file. Defaults to 0.

    Returns:
        str: Hash (hex) string.

    """
    if not is_str_not_empty(hash_name): raise ValueError("hash_name must be a string")
    if not is_str_not_empty(path): raise ValueError("file path must be a string")
    if not is_int_not_neg(offset): raise ValueError("offset must be a positive integer")
    if whence not in [0,1,2]: raise ValueError("whence must be 0 - Absolute, 1 - Current, 2 - End of file")

    data = read_file(path, size, offset, whence)
    alg = getattr(hash, hash_name.lower())
    return alg(data)
Beispiel #5
0
def find_file(re_filter=None, branch=".", recurse=True, depth=0, get_file=True, get_dir=True, case_i=True):
    """Search a branch directory for files and / or directories whose name matches one or more of the filter patterns

    Args:
        branch (str): (optional) Directory to search. Suggestion: use absolute path. Defaults to current working directory.
        re_filter (list): (optional) List of strings of wildcard patterns. Defaults to None, which skips any filtering.
        recurse (bool): (optional) Recursive search flag. Defaults to True.
        depth (int): (optional) Set the recursion depth. Defaults to 0, which has a max of Python's recursion limit.
        get_file (bool): (optional) Return entry for file. Defaults to True.
        get_dir (bool): (optional) Return entry for directory. Defaults to True.
        case_i (bool): (optional) Case insensitive search. Defaults to True.

    Returns:
        list: List of strings with paths of files.

    """
    if not is_str_not_empty(branch):
        raise ValueError("branch must be a non empty string")
    if not os.path.isdir(branch):
        raise ValueError("branch must be a valid directory")
    if not is_bool(recurse):
        raise ValueError("recurse must be True or False")
    if is_int_neg(depth):
        raise ValueError("depth must be >= 0")
    if not is_bool(get_file):
        raise ValueError("get_file must be True or False")
    if not is_bool(get_dir):
        raise ValueError("get_dir must be True or False")
    if not is_bool(case_i):
        raise ValueError("case_i must be True or False")

    search_results = list_dir(branch, recurse, depth, get_file, get_dir)

    if re_filter is None or len(re_filter) < 1:
        return search_results
    elif re_filter == "*":
        return search_results
    elif is_list(re_filter) and "*" in re_filter:
        return search_results

    if is_str(re_filter):
        re_filter = [re_filter]

    re_flag = 0
    if case_i:
        re_flag = re.IGNORECASE

    bre = partial(wildcard_re, wildcard="*", escape="\\")
    return list_filter(map(bre, re_filter), search_results, re_flag)
Beispiel #6
0
def find_file_re(re_filter=None, branch=".", recurse=True, depth=0, get_file=True, get_dir=True, re_flag=0):
    """Search a branch directory for files and / or directories whose name matches one or more of the regex filter patterns

    Args:
        branch (str): (optional) Directory to search. Suggestion: use absolute path. Defaults to current working directory.
        re_filter (list): (optional) List of strings of regular expression patterns. Defaults to None, which skips any filtering.
        recurse (bool): (optional) Recursive search flag. Defaults to True.
        depth (int): (optional) Set the recursion depth. Defaults to 0, which has a max of Python's recursion limit.
        get_file (bool): (optional) Return entry for file. Defaults to True.
        get_dir (bool): (optional) Return entry for directory. Defaults to True.
        re_flag (int): (optional) See :py:mod:`re`

    Returns:
        list: List of strings with paths of files.

    """
    if not is_str_not_empty(branch):
        raise ValueError("branch must be a non empty string")
    if not os.path.isdir(branch):
        raise ValueError("branch must be a valid directory")
    if not is_bool(recurse):
        raise TypeError("recurse must be True or False")
    if is_int_neg(depth):
        raise ValueError("depth must be >= 0")
    if not is_bool(get_file):
        raise ValueError("get_file must be True or False")
    if not is_bool(get_dir):
        raise ValueError("get_dir must be True or False")

    search_results = list_dir(branch, recurse, depth, get_file, get_dir)

    if re_filter is None or len(re_filter) < 1:
        return search_results

    if is_str(re_filter):
        re_filter = [re_filter]

    return list_filter(re_filter, search_results, re_flag)
Beispiel #7
0
def write_file(path, data, mode='new', offset=0, whence=0):
    """Write a file in binary mode

    Args:
        path (str): Path of file.
        data (str): Data to be written.
        mode (str): (optional) 'new' for a new or replacement file. 'insert' for writing more data into a file. 'overwrite' for writing new data over a file. 'append' for adding to the end of a file. Defaults to 'new'.
        offset (int): (optional) Offset from the whence position. Defaults to 0.
        whence (int): (optional) Originating file seek position. 0 - Absolute, 1 - Current, 2 - End of file. Defaults to 0.

    Returns:
        str: File path to written file.

    """
    if not is_str_not_empty(path): raise ValueError("file path must be a string")
    if not is_str_not_empty(data): raise ValueError("data must be a string")
    if mode not in ['new','insert','overwrite','append']: raise ValueError("mode must be 'new' or 'insert' or 'overwrite' or 'append'")
    if not is_int_not_neg(offset): raise ValueError("offset must be a non negative integer")
    if whence not in [0,1,2]: raise ValueError("whence must be 0 - Absolute, 1 - Current, 2 - End of file")

    path = os.path.abspath(path)
    #: create the directory path to the file if it doesn't exist
    if not os.path.exists(os.path.split(path)[0]):
        mode = 'new'
        os.makedirs(os.path.split(path)[0])
    #: stop an attempt to overwrite a directory
    elif os.path.isdir(path) == True:
        raise ValueError('may not write file over a directory: ' + path)

    if mode == 'append':
        offset = 0
        whence = 2

    if mode == 'insert' or mode == 'overwrite' or mode == 'append':
        original_file_size = os.stat(path).st_size
        original_file = open(path, 'rb')
        #: determine the offset position for the write action
        original_file.seek(offset, whence)
        start_pos = original_file.tell()
        original_file.seek(0, 0)

        #: create a temporary file
        temp_file = open(path + '.tmp', 'wb')
        #: write any offset data
        if start_pos > 0:
            temp_file.write(original_file.read(start_pos))
        #: write new data
        temp_file.write(data)
        temp_file.flush()
        os.fsync(temp_file.fileno())
        temp_file.close()
        temp_file_size = os.stat(path + '.tmp').st_size

        #: write any remaining data from the original file
        if mode == 'overwrite' and temp_file_size < original_file_size:
            temp_file = open(path + '.tmp', 'ab')
            original_file.seek(temp_file_size, 0)
            temp_file.write(original_file.read())
            temp_file.flush()
            os.fsync(temp_file.fileno())
            temp_file.close()
        elif mode == 'insert':
            temp_file = open(path + '.tmp', 'ab')
            original_file.seek(start_pos, 0)
            temp_file.write(original_file.read())
            temp_file.flush()
            os.fsync(temp_file.fileno())
            temp_file.close()

        original_file.close()
        #: replace the original file
        os.rename(path + '.tmp', path)
    elif mode == 'new':
        f = open(path, 'wb')
        f.write(data)
        f.flush()
        os.fsync(f.fileno())
        f.close()

    return path