You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
555 lines
24 KiB
555 lines
24 KiB
#!/usr/bin/env python
|
|
# encoding: utf-8
|
|
# cython: profile=False
|
|
|
|
import sys
|
|
import os
|
|
from Naked.settings import debug as DEBUG_FLAG
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# FILE & DIRECTORY PATHS
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ filename function ] (string)
|
|
# returns file name from a file path (including the file extension)
|
|
# Tests: test_SYSTEM.py :: test_sys_filename
|
|
#------------------------------------------------------------------------------
|
|
def filename(filepath):
|
|
try:
|
|
return os.path.basename(filepath)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return base filename from filename() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ file_extension function ] (string)
|
|
# returns file extension from a filepath
|
|
# Tests: test_SYSTEM.py :: test_sys_file_extension
|
|
#------------------------------------------------------------------------------
|
|
def file_extension(filepath):
|
|
try:
|
|
return os.path.splitext(filepath)[1]
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return file extension with file_extension() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ directory function ] (string)
|
|
# returns directory path to the filepath
|
|
# Tests: test_SYSTEM.py :: test_sys_dir_path
|
|
#------------------------------------------------------------------------------
|
|
def directory(filepath):
|
|
try:
|
|
return os.path.dirname(filepath)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return directory path to file with directory() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ make_path function ] (string)
|
|
# returns OS independent file path from tuple of path components
|
|
# Tests: test_SYSTEM.py :: test_sys_make_filepath
|
|
#------------------------------------------------------------------------------
|
|
def make_path(*path_list):
|
|
try:
|
|
return os.path.join(*path_list)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to make OS independent path with the make_path() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ currentdir_to_basefile decorator function ] (returns decorated original function)
|
|
# concatenates the absolute working directory path to the basename of file in the first parameter of the undecorated function
|
|
# Tests: test_SYSTEM.py :: test_sys_add_currentdir_path_to_basefile
|
|
#------------------------------------------------------------------------------
|
|
def currentdir_to_basefile(func):
|
|
try:
|
|
from functools import wraps
|
|
|
|
@wraps(func)
|
|
def wrapper(file_name, *args, **kwargs):
|
|
current_directory = os.getcwd() #get current working directory path
|
|
full_path = os.path.join(current_directory, file_name) # join cwd path to the filename for full path
|
|
return func(full_path, *args, **kwargs) #return the original function with the full path to file as first argument
|
|
return wrapper
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: error with the currentdir_to_basefile() decorator function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ currentdir_firstparam decorator function ] (returns decorated original function)
|
|
# adds the current working directory as the first function parameter of the decorated function
|
|
# Tests: test_SYSTEM.py :: test_sys_add_currentdir_path_first_arg
|
|
#------------------------------------------------------------------------------
|
|
def currentdir_firstparam(func):
|
|
try:
|
|
from functools import wraps
|
|
|
|
@wraps(func)
|
|
def wrapper(dir="", *args, **kwargs):
|
|
current_directory = os.getcwd()
|
|
return func(current_directory, *args, **kwargs)
|
|
return wrapper
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: error with the currentdir_firstargument() decorator function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ currentdir_lastargument decorator function ] (returns decorated original function)
|
|
# adds the current working directory as the last function parameter of the decorated function
|
|
# Note: you cannot use other named arguments in the original function with this decorator
|
|
# Note: the current directory argument in the last position must be named current_dir
|
|
# Tests: test_SYSTEM.py :: test_sys_add_currentdir_last_arg
|
|
#------------------------------------------------------------------------------
|
|
def currentdir_lastparam(func):
|
|
try:
|
|
from functools import wraps
|
|
|
|
@wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
the_cwd = os.getcwd()
|
|
return func(*args, current_dir=the_cwd)
|
|
return wrapper
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: error with the currentdir_lastargument() decorator function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ fullpath function ] (string)
|
|
# returns the absolute path to a file that is in the current working directory
|
|
# file_name = the basename of the file in the current working directory
|
|
# Example usage where test.txt is in working directory:
|
|
# filepath = fullpath("test.txt")
|
|
# Tests: test_SYSTEM.py :: test_sys_full_path_to_file
|
|
#------------------------------------------------------------------------------
|
|
@currentdir_to_basefile # current directory decorator - adds the directory path up to the filename to the basefile name argument to original function
|
|
def fullpath(file_name):
|
|
try:
|
|
return file_name
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return absolute path to the file with the fullpath() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ cwd function ] (string)
|
|
# returns the current working directory path
|
|
# does not need to be called with an argument, the decorator assigns it
|
|
# Example usage:
|
|
# current_dir = cwd()
|
|
# Tests: test_SYSTEM.py :: test_sys_cwd_path
|
|
#------------------------------------------------------------------------------
|
|
@currentdir_firstparam
|
|
def cwd(dir=""):
|
|
try:
|
|
return dir
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return the current working directory with the cwd() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# DIRECTORY WRITES
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
## TODO: add tests
|
|
#------------------------------------------------------------------------------
|
|
# [ make_dirs function ] (--none--)
|
|
# make a new directory path (recursive if multiple levels of depth) if it
|
|
# DOES NOT already exist
|
|
#------------------------------------------------------------------------------
|
|
def make_dirs(dirpath):
|
|
try:
|
|
import os
|
|
import errno
|
|
os.makedirs(dirpath)
|
|
return True
|
|
except OSError as ose:
|
|
if ose.errno != errno.EEXIST: # directory already exists
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: Could not write the directory path passed as an argument to the make_dirs() function (Naked.toolshed.system).")
|
|
raise ose
|
|
else:
|
|
return False
|
|
except Exception as e:
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# FILE & DIRECTORY TESTING
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ file_exists function ] (boolean)
|
|
# return boolean for existence of file in specified path
|
|
# Tests: test_SYSTEM.py :: test_file_exists
|
|
#------------------------------------------------------------------------------
|
|
def file_exists(filepath):
|
|
try:
|
|
if os.path.exists(filepath) and os.path.isfile(filepath): # test that exists and is a file
|
|
return True
|
|
else:
|
|
return False
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: error with test for the presence of the file with the file_exists() method (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ is_file function ] (boolean)
|
|
# returns boolean for determination of whether filepath is a file
|
|
# Tests: test_SYSTEM.py :: test_sys_is_file, test_sys_is_file_missing_file,
|
|
# test_sys_is_file_when_dir
|
|
#------------------------------------------------------------------------------
|
|
def is_file(filepath):
|
|
try:
|
|
return os.path.isfile(filepath)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: error with test for file with the is_file() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ dir_exists function ] (boolean)
|
|
# return boolean for existence of directory in specified path
|
|
# Tests: test_SYSTEM.py :: test_dir_exists, test_dir_exists_missing_dir
|
|
#------------------------------------------------------------------------------
|
|
def dir_exists(dirpath):
|
|
try:
|
|
if os.path.exists(dirpath) and os.path.isdir(dirpath): # test that exists and is a directory
|
|
return True
|
|
else:
|
|
return False
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: error with test for directory with the dir_exists() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ is_dir function ] (boolean)
|
|
# returns boolean for determination of whether dirpath is a directory
|
|
# Tests: test_SYSTEM.py :: test_sys_dir_is_dir, test_sys_dir_is_dir_when_file,
|
|
# test_sys_dir_is_dir_when_missing
|
|
#------------------------------------------------------------------------------
|
|
def is_dir(dirpath):
|
|
try:
|
|
return os.path.isdir(dirpath)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: error with test for directory with the is_dir() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# FILE METADATA
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ filesize function ] (int)
|
|
# return file size in bytes
|
|
# Tests: test_SYSTEM.py :: test_sys_meta_file_size
|
|
#------------------------------------------------------------------------------
|
|
def file_size(filepath):
|
|
try:
|
|
return os.path.getsize(filepath)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return file size with the file_size() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ file_mod_time function ] (string)
|
|
# return the last file modification date/time
|
|
# Tests: test_SYSTEM.py :: test_sys_meta_file_mod
|
|
#------------------------------------------------------------------------------
|
|
def file_mod_time(filepath):
|
|
try:
|
|
import time
|
|
return time.ctime(os.path.getmtime(filepath))
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return file modification data with the file_mod_time() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# FILE LISTINGS
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ list_all_files function ] (list)
|
|
# returns a list of all files in developer specified directory
|
|
# Tests: test_SYSTEM.py :: test_sys_list_all_files, test_sys_list_all_files_emptydir
|
|
#------------------------------------------------------------------------------
|
|
def list_all_files(dir):
|
|
try:
|
|
filenames = [name for name in os.listdir(dir) if os.path.isfile(os.path.join(dir, name))]
|
|
return filenames
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to generate directory file list with the list_all_files() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ list_filter_files function ] (list)
|
|
# returns a list of files filtered by developer defined file extension in developer defined directory
|
|
# Usage example:
|
|
# filenames = list_filter_files("py", "tests")
|
|
# Tests: test_SYSTEM.py :: test_sys_list_filter_files, test_sys_list_filter_files_nomatch
|
|
#------------------------------------------------------------------------------
|
|
def list_filter_files(extension_filter, dir):
|
|
try:
|
|
if not extension_filter.startswith("."):
|
|
extension_filter = "." + extension_filter
|
|
filenames = [name for name in os.listdir(dir) if name.endswith(extension_filter)]
|
|
return filenames
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return list of filtered files with the list_filter_files() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ list_all_files_cwd function ] (list)
|
|
# returns a list of all files in the current working directory
|
|
# Note: does not require argument, the decorator assigns the cwd
|
|
# Usage example:
|
|
# file_list = list_all_files_cwd()
|
|
# Tests: test_SYSTEM.py :: test_sys_list_all_files_cwd
|
|
#------------------------------------------------------------------------------
|
|
@currentdir_firstparam
|
|
def list_all_files_cwd(dir=""):
|
|
try:
|
|
return list_all_files(dir)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return list of all files in current working directory with the list_all_files_cwd() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ list_filter_files_cwd function ] (list)
|
|
# returns a list of all files in the current working directory filtered by developer specified file extension
|
|
# Note: do not specify the second argument, decorator assigns it
|
|
# Usage example:
|
|
# file_list = list_filter_files_cwd(".py")
|
|
# Tests: test_SYSTEM.py :: test_sys_filter_files_cwd, test_sys_filter_files_cwd_nomatch
|
|
#------------------------------------------------------------------------------
|
|
@currentdir_lastparam
|
|
def list_filter_files_cwd(extension_filter, current_dir=""):
|
|
try:
|
|
return list_filter_files(extension_filter, current_dir)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return list of filtered files in current working directory with the list_filter_files_cwd() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ list_match_files function ] (list)
|
|
# returns a list of all files that match the developer specified wildcard match pattern
|
|
# can optionally specify return of full path to the files (rather than relative path from cwd) by setting full_path to True
|
|
# Usage examples:
|
|
# file_list = list_match_files("*.py")
|
|
# file_list_fullpath = list_match_files("*.py", True)
|
|
# Tests: test_SYSTEM.py :: test_sys_match_files, test_sys_match_files_fullpath
|
|
#------------------------------------------------------------------------------
|
|
def list_match_files(match_pattern, full_path = False):
|
|
try:
|
|
from glob import glob
|
|
filenames = glob(match_pattern)
|
|
if full_path:
|
|
filenames_fullpath = []
|
|
cwd = os.getcwd()
|
|
for name in filenames:
|
|
name = os.path.join(cwd, name) #make the full path to the file
|
|
filenames_fullpath.append(name) #add to the new list
|
|
return filenames_fullpath #then return that list
|
|
else:
|
|
return filenames
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return list of matched files with the list_match_files() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# SYMBOLIC LINK TESTING
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ is_link function ] (boolean)
|
|
# return boolean indicating whether the path is a symbolic link
|
|
#------------------------------------------------------------------------------
|
|
def is_link(filepath):
|
|
try:
|
|
return os.path.islink(filepath)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to determine whether path is a symbolic link with the is_link() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ real_path function ] (string)
|
|
# return the real file path pointed to by a symbolic link
|
|
#------------------------------------------------------------------------------
|
|
def real_path(filepath):
|
|
try:
|
|
return os.path.realpath(filepath)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to return real path for symbolic link with the real_path() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# DATA STREAMS
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ stdout function ]
|
|
# print to std output stream
|
|
#------------------------------------------------------------------------------
|
|
def stdout(text):
|
|
try:
|
|
print(text)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ stdout_xnl function ]
|
|
# print to std output stream without a newline
|
|
#------------------------------------------------------------------------------
|
|
def stdout_xnl(text):
|
|
try:
|
|
sys.stdout.write(text)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout_xnl() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ stdout_iter function ]
|
|
# print items in an iterable to the standard output stream with newlines after each string
|
|
#------------------------------------------------------------------------------
|
|
def stdout_iter(iter):
|
|
try:
|
|
for x in iter:
|
|
stdout(x)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout_iter() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ stdout_iter_xnl function ]
|
|
# print items in an iterable to the standard output stream without newlines after each string
|
|
#------------------------------------------------------------------------------
|
|
def stdout_iter_xnl(iter):
|
|
try:
|
|
for x in iter:
|
|
stdout_xnl(x)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout_iter() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ stderr function ]
|
|
# print to std error stream
|
|
# optionally (i.e. if exit = nonzero integer) permits exit from application with developer defined exit code
|
|
#------------------------------------------------------------------------------
|
|
def stderr(text, exit=0):
|
|
try:
|
|
sys.stderr.write(text + "\n")
|
|
if exit:
|
|
raise SystemExit(exit)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to print to the standard error stream with the stderr() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ stderr_xnl function ]
|
|
# print to the standard error stream without a newline character after the `text` string
|
|
#------------------------------------------------------------------------------
|
|
def stderr_xnl(text, exit=0):
|
|
try:
|
|
sys.stderr.write(text)
|
|
if exit:
|
|
raise SystemExit(exit)
|
|
except Exception as e:
|
|
if DEBUG_FLAG:
|
|
sys.stderr.write("Naked Framework Error: unable to print to the standard error stream with the stderr() function (Naked.toolshed.system).")
|
|
raise e
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# APPLICATION CONTROL
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ exit_with_status function ]
|
|
# application exit with developer specified exit status code (default = 0)
|
|
# use an exit status integer argument
|
|
# Tests: test_SYSTEM.py :: test_sys_exit_with_code
|
|
#------------------------------------------------------------------------------
|
|
def exit_with_status(exit=0):
|
|
raise SystemExit(exit)
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ exit_fail function ]
|
|
# application exit with status code 1
|
|
# Tests: test_SYSTEM.py :: test_sys_exit_failure
|
|
#------------------------------------------------------------------------------
|
|
def exit_fail():
|
|
raise SystemExit(1)
|
|
|
|
#------------------------------------------------------------------------------
|
|
# [ exit_success function]
|
|
# application exit with status code 0
|
|
# Tests: test_SYSTEM.py :: test_sys_exit_success
|
|
#------------------------------------------------------------------------------
|
|
def exit_success():
|
|
raise SystemExit(0)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pass
|
|
# #------------------------------------------------------------------------------
|
|
# # Standard Output Tests
|
|
# #------------------------------------------------------------------------------
|
|
# stdout("This is a test")
|
|
# for x in range(10):
|
|
# stdout_xnl(str(x) + " ")
|
|
# list_ten = ['10% ', '20% ', '30% ', '40% ', '50% ', '60% ', '70% ', '80% ', '90% ', '100%']
|
|
# stdout_iter(list_ten)
|
|
# #------------------------------------------------------------------------------
|
|
# # Standard Error Tests
|
|
# #------------------------------------------------------------------------------
|
|
# stderr("This is a test")
|
|
# stderr("This is a test", 1) #exit with status code 1
|