system.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. import sys
  4. import os
  5. from Naked.settings import debug as DEBUG_FLAG
  6. #------------------------------------------------------------------------------
  7. #
  8. # FILE & DIRECTORY PATHS
  9. #
  10. #------------------------------------------------------------------------------
  11. #------------------------------------------------------------------------------
  12. # [ filename function ] (string)
  13. # returns file name from a file path (including the file extension)
  14. # Tests: test_SYSTEM.py :: test_sys_filename
  15. #------------------------------------------------------------------------------
  16. def filename(filepath):
  17. try:
  18. return os.path.basename(filepath)
  19. except Exception as e:
  20. if DEBUG_FLAG:
  21. sys.stderr.write("Naked Framework Error: unable to return base filename from filename() function (Naked.toolshed.system).")
  22. raise e
  23. #------------------------------------------------------------------------------
  24. # [ file_extension function ] (string)
  25. # returns file extension from a filepath
  26. # Tests: test_SYSTEM.py :: test_sys_file_extension
  27. #------------------------------------------------------------------------------
  28. def file_extension(filepath):
  29. try:
  30. return os.path.splitext(filepath)[1]
  31. except Exception as e:
  32. if DEBUG_FLAG:
  33. sys.stderr.write("Naked Framework Error: unable to return file extension with file_extension() function (Naked.toolshed.system).")
  34. raise e
  35. #------------------------------------------------------------------------------
  36. # [ directory function ] (string)
  37. # returns directory path to the filepath
  38. # Tests: test_SYSTEM.py :: test_sys_dir_path
  39. #------------------------------------------------------------------------------
  40. def directory(filepath):
  41. try:
  42. return os.path.dirname(filepath)
  43. except Exception as e:
  44. if DEBUG_FLAG:
  45. sys.stderr.write("Naked Framework Error: unable to return directory path to file with directory() function (Naked.toolshed.system).")
  46. raise e
  47. #------------------------------------------------------------------------------
  48. # [ make_path function ] (string)
  49. # returns OS independent file path from tuple of path components
  50. # Tests: test_SYSTEM.py :: test_sys_make_filepath
  51. #------------------------------------------------------------------------------
  52. def make_path(*path_list):
  53. try:
  54. return os.path.join(*path_list)
  55. except Exception as e:
  56. if DEBUG_FLAG:
  57. sys.stderr.write("Naked Framework Error: unable to make OS independent path with the make_path() function (Naked.toolshed.system).")
  58. raise e
  59. #------------------------------------------------------------------------------
  60. # [ currentdir_to_basefile decorator function ] (returns decorated original function)
  61. # concatenates the absolute working directory path to the basename of file in the first parameter of the undecorated function
  62. # Tests: test_SYSTEM.py :: test_sys_add_currentdir_path_to_basefile
  63. #------------------------------------------------------------------------------
  64. def currentdir_to_basefile(func):
  65. try:
  66. from functools import wraps
  67. @wraps(func)
  68. def wrapper(file_name, *args, **kwargs):
  69. current_directory = os.getcwd() #get current working directory path
  70. full_path = os.path.join(current_directory, file_name) # join cwd path to the filename for full path
  71. return func(full_path, *args, **kwargs) #return the original function with the full path to file as first argument
  72. return wrapper
  73. except Exception as e:
  74. if DEBUG_FLAG:
  75. sys.stderr.write("Naked Framework Error: error with the currentdir_to_basefile() decorator function (Naked.toolshed.system).")
  76. raise e
  77. #------------------------------------------------------------------------------
  78. # [ currentdir_firstparam decorator function ] (returns decorated original function)
  79. # adds the current working directory as the first function parameter of the decorated function
  80. # Tests: test_SYSTEM.py :: test_sys_add_currentdir_path_first_arg
  81. #------------------------------------------------------------------------------
  82. def currentdir_firstparam(func):
  83. try:
  84. from functools import wraps
  85. @wraps(func)
  86. def wrapper(dir="", *args, **kwargs):
  87. current_directory = os.getcwd()
  88. return func(current_directory, *args, **kwargs)
  89. return wrapper
  90. except Exception as e:
  91. if DEBUG_FLAG:
  92. sys.stderr.write("Naked Framework Error: error with the currentdir_firstargument() decorator function (Naked.toolshed.system).")
  93. raise e
  94. #------------------------------------------------------------------------------
  95. # [ currentdir_lastargument decorator function ] (returns decorated original function)
  96. # adds the current working directory as the last function parameter of the decorated function
  97. # Note: you cannot use other named arguments in the original function with this decorator
  98. # Note: the current directory argument in the last position must be named current_dir
  99. # Tests: test_SYSTEM.py :: test_sys_add_currentdir_last_arg
  100. #------------------------------------------------------------------------------
  101. def currentdir_lastparam(func):
  102. try:
  103. from functools import wraps
  104. @wraps(func)
  105. def wrapper(*args, **kwargs):
  106. the_cwd = os.getcwd()
  107. return func(*args, current_dir=the_cwd)
  108. return wrapper
  109. except Exception as e:
  110. if DEBUG_FLAG:
  111. sys.stderr.write("Naked Framework Error: error with the currentdir_lastargument() decorator function (Naked.toolshed.system).")
  112. raise e
  113. #------------------------------------------------------------------------------
  114. # [ fullpath function ] (string)
  115. # returns the absolute path to a file that is in the current working directory
  116. # file_name = the basename of the file in the current working directory
  117. # Example usage where test.txt is in working directory:
  118. # filepath = fullpath("test.txt")
  119. # Tests: test_SYSTEM.py :: test_sys_full_path_to_file
  120. #------------------------------------------------------------------------------
  121. @currentdir_to_basefile # current directory decorator - adds the directory path up to the filename to the basefile name argument to original function
  122. def fullpath(file_name):
  123. try:
  124. return file_name
  125. except Exception as e:
  126. if DEBUG_FLAG:
  127. sys.stderr.write("Naked Framework Error: unable to return absolute path to the file with the fullpath() function (Naked.toolshed.system).")
  128. raise e
  129. #------------------------------------------------------------------------------
  130. # [ cwd function ] (string)
  131. # returns the current working directory path
  132. # does not need to be called with an argument, the decorator assigns it
  133. # Example usage:
  134. # current_dir = cwd()
  135. # Tests: test_SYSTEM.py :: test_sys_cwd_path
  136. #------------------------------------------------------------------------------
  137. @currentdir_firstparam
  138. def cwd(dir=""):
  139. try:
  140. return dir
  141. except Exception as e:
  142. if DEBUG_FLAG:
  143. sys.stderr.write("Naked Framework Error: unable to return the current working directory with the cwd() function (Naked.toolshed.system).")
  144. raise e
  145. #------------------------------------------------------------------------------
  146. #
  147. # DIRECTORY WRITES
  148. #
  149. #------------------------------------------------------------------------------
  150. ## TODO: add tests
  151. #------------------------------------------------------------------------------
  152. # [ make_dirs function ] (--none--)
  153. # make a new directory path (recursive if multiple levels of depth) if it
  154. # DOES NOT already exist
  155. #------------------------------------------------------------------------------
  156. def make_dirs(dirpath):
  157. try:
  158. import os
  159. import errno
  160. os.makedirs(dirpath)
  161. return True
  162. except OSError as ose:
  163. if ose.errno != errno.EEXIST: # directory already exists
  164. if DEBUG_FLAG:
  165. sys.stderr.write("Naked Framework Error: Could not write the directory path passed as an argument to the make_dirs() function (Naked.toolshed.system).")
  166. raise ose
  167. else:
  168. return False
  169. except Exception as e:
  170. raise e
  171. #------------------------------------------------------------------------------
  172. #
  173. # FILE & DIRECTORY TESTING
  174. #
  175. #------------------------------------------------------------------------------
  176. #------------------------------------------------------------------------------
  177. # [ file_exists function ] (boolean)
  178. # return boolean for existence of file in specified path
  179. # Tests: test_SYSTEM.py :: test_file_exists
  180. #------------------------------------------------------------------------------
  181. def file_exists(filepath):
  182. try:
  183. if os.path.exists(filepath) and os.path.isfile(filepath): # test that exists and is a file
  184. return True
  185. else:
  186. return False
  187. except Exception as e:
  188. if DEBUG_FLAG:
  189. sys.stderr.write("Naked Framework Error: error with test for the presence of the file with the file_exists() method (Naked.toolshed.system).")
  190. raise e
  191. #------------------------------------------------------------------------------
  192. # [ is_file function ] (boolean)
  193. # returns boolean for determination of whether filepath is a file
  194. # Tests: test_SYSTEM.py :: test_sys_is_file, test_sys_is_file_missing_file,
  195. # test_sys_is_file_when_dir
  196. #------------------------------------------------------------------------------
  197. def is_file(filepath):
  198. try:
  199. return os.path.isfile(filepath)
  200. except Exception as e:
  201. if DEBUG_FLAG:
  202. sys.stderr.write("Naked Framework Error: error with test for file with the is_file() function (Naked.toolshed.system).")
  203. raise e
  204. #------------------------------------------------------------------------------
  205. # [ dir_exists function ] (boolean)
  206. # return boolean for existence of directory in specified path
  207. # Tests: test_SYSTEM.py :: test_dir_exists, test_dir_exists_missing_dir
  208. #------------------------------------------------------------------------------
  209. def dir_exists(dirpath):
  210. try:
  211. if os.path.exists(dirpath) and os.path.isdir(dirpath): # test that exists and is a directory
  212. return True
  213. else:
  214. return False
  215. except Exception as e:
  216. if DEBUG_FLAG:
  217. sys.stderr.write("Naked Framework Error: error with test for directory with the dir_exists() function (Naked.toolshed.system).")
  218. raise e
  219. #------------------------------------------------------------------------------
  220. # [ is_dir function ] (boolean)
  221. # returns boolean for determination of whether dirpath is a directory
  222. # Tests: test_SYSTEM.py :: test_sys_dir_is_dir, test_sys_dir_is_dir_when_file,
  223. # test_sys_dir_is_dir_when_missing
  224. #------------------------------------------------------------------------------
  225. def is_dir(dirpath):
  226. try:
  227. return os.path.isdir(dirpath)
  228. except Exception as e:
  229. if DEBUG_FLAG:
  230. sys.stderr.write("Naked Framework Error: error with test for directory with the is_dir() function (Naked.toolshed.system).")
  231. raise e
  232. #------------------------------------------------------------------------------
  233. #
  234. # FILE METADATA
  235. #
  236. #------------------------------------------------------------------------------
  237. #------------------------------------------------------------------------------
  238. # [ filesize function ] (int)
  239. # return file size in bytes
  240. # Tests: test_SYSTEM.py :: test_sys_meta_file_size
  241. #------------------------------------------------------------------------------
  242. def file_size(filepath):
  243. try:
  244. return os.path.getsize(filepath)
  245. except Exception as e:
  246. if DEBUG_FLAG:
  247. sys.stderr.write("Naked Framework Error: unable to return file size with the file_size() function (Naked.toolshed.system).")
  248. raise e
  249. #------------------------------------------------------------------------------
  250. # [ file_mod_time function ] (string)
  251. # return the last file modification date/time
  252. # Tests: test_SYSTEM.py :: test_sys_meta_file_mod
  253. #------------------------------------------------------------------------------
  254. def file_mod_time(filepath):
  255. try:
  256. import time
  257. return time.ctime(os.path.getmtime(filepath))
  258. except Exception as e:
  259. if DEBUG_FLAG:
  260. sys.stderr.write("Naked Framework Error: unable to return file modification data with the file_mod_time() function (Naked.toolshed.system).")
  261. raise e
  262. #------------------------------------------------------------------------------
  263. #
  264. # FILE LISTINGS
  265. #
  266. #------------------------------------------------------------------------------
  267. #------------------------------------------------------------------------------
  268. # [ list_all_files function ] (list)
  269. # returns a list of all files in developer specified directory
  270. # Tests: test_SYSTEM.py :: test_sys_list_all_files, test_sys_list_all_files_emptydir
  271. #------------------------------------------------------------------------------
  272. def list_all_files(dir):
  273. try:
  274. filenames = [name for name in os.listdir(dir) if os.path.isfile(os.path.join(dir, name))]
  275. return filenames
  276. except Exception as e:
  277. if DEBUG_FLAG:
  278. sys.stderr.write("Naked Framework Error: unable to generate directory file list with the list_all_files() function (Naked.toolshed.system).")
  279. raise e
  280. #------------------------------------------------------------------------------
  281. # [ list_filter_files function ] (list)
  282. # returns a list of files filtered by developer defined file extension in developer defined directory
  283. # Usage example:
  284. # filenames = list_filter_files("py", "tests")
  285. # Tests: test_SYSTEM.py :: test_sys_list_filter_files, test_sys_list_filter_files_nomatch
  286. #------------------------------------------------------------------------------
  287. def list_filter_files(extension_filter, dir):
  288. try:
  289. if not extension_filter.startswith("."):
  290. extension_filter = "." + extension_filter
  291. filenames = [name for name in os.listdir(dir) if name.endswith(extension_filter)]
  292. return filenames
  293. except Exception as e:
  294. if DEBUG_FLAG:
  295. sys.stderr.write("Naked Framework Error: unable to return list of filtered files with the list_filter_files() function (Naked.toolshed.system).")
  296. raise e
  297. #------------------------------------------------------------------------------
  298. # [ list_all_files_cwd function ] (list)
  299. # returns a list of all files in the current working directory
  300. # Note: does not require argument, the decorator assigns the cwd
  301. # Usage example:
  302. # file_list = list_all_files_cwd()
  303. # Tests: test_SYSTEM.py :: test_sys_list_all_files_cwd
  304. #------------------------------------------------------------------------------
  305. @currentdir_firstparam
  306. def list_all_files_cwd(dir=""):
  307. try:
  308. return list_all_files(dir)
  309. except Exception as e:
  310. if DEBUG_FLAG:
  311. 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).")
  312. raise e
  313. #------------------------------------------------------------------------------
  314. # [ list_filter_files_cwd function ] (list)
  315. # returns a list of all files in the current working directory filtered by developer specified file extension
  316. # Note: do not specify the second argument, decorator assigns it
  317. # Usage example:
  318. # file_list = list_filter_files_cwd(".py")
  319. # Tests: test_SYSTEM.py :: test_sys_filter_files_cwd, test_sys_filter_files_cwd_nomatch
  320. #------------------------------------------------------------------------------
  321. @currentdir_lastparam
  322. def list_filter_files_cwd(extension_filter, current_dir=""):
  323. try:
  324. return list_filter_files(extension_filter, current_dir)
  325. except Exception as e:
  326. if DEBUG_FLAG:
  327. 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).")
  328. raise e
  329. #------------------------------------------------------------------------------
  330. # [ list_match_files function ] (list)
  331. # returns a list of all files that match the developer specified wildcard match pattern
  332. # can optionally specify return of full path to the files (rather than relative path from cwd) by setting full_path to True
  333. # Usage examples:
  334. # file_list = list_match_files("*.py")
  335. # file_list_fullpath = list_match_files("*.py", True)
  336. # Tests: test_SYSTEM.py :: test_sys_match_files, test_sys_match_files_fullpath
  337. #------------------------------------------------------------------------------
  338. def list_match_files(match_pattern, full_path = False):
  339. try:
  340. from glob import glob
  341. filenames = glob(match_pattern)
  342. if full_path:
  343. filenames_fullpath = []
  344. cwd = os.getcwd()
  345. for name in filenames:
  346. name = os.path.join(cwd, name) #make the full path to the file
  347. filenames_fullpath.append(name) #add to the new list
  348. return filenames_fullpath #then return that list
  349. else:
  350. return filenames
  351. except Exception as e:
  352. if DEBUG_FLAG:
  353. sys.stderr.write("Naked Framework Error: unable to return list of matched files with the list_match_files() function (Naked.toolshed.system).")
  354. raise e
  355. #------------------------------------------------------------------------------
  356. #
  357. # SYMBOLIC LINK TESTING
  358. #
  359. #------------------------------------------------------------------------------
  360. #------------------------------------------------------------------------------
  361. # [ is_link function ] (boolean)
  362. # return boolean indicating whether the path is a symbolic link
  363. #------------------------------------------------------------------------------
  364. def is_link(filepath):
  365. try:
  366. return os.path.islink(filepath)
  367. except Exception as e:
  368. if DEBUG_FLAG:
  369. sys.stderr.write("Naked Framework Error: unable to determine whether path is a symbolic link with the is_link() function (Naked.toolshed.system).")
  370. raise e
  371. #------------------------------------------------------------------------------
  372. # [ real_path function ] (string)
  373. # return the real file path pointed to by a symbolic link
  374. #------------------------------------------------------------------------------
  375. def real_path(filepath):
  376. try:
  377. return os.path.realpath(filepath)
  378. except Exception as e:
  379. if DEBUG_FLAG:
  380. sys.stderr.write("Naked Framework Error: unable to return real path for symbolic link with the real_path() function (Naked.toolshed.system).")
  381. raise e
  382. #------------------------------------------------------------------------------
  383. #
  384. # DATA STREAMS
  385. #
  386. #------------------------------------------------------------------------------
  387. #------------------------------------------------------------------------------
  388. # [ stdout function ]
  389. # print to std output stream
  390. #------------------------------------------------------------------------------
  391. def stdout(text):
  392. try:
  393. print(text)
  394. except Exception as e:
  395. if DEBUG_FLAG:
  396. sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout() function (Naked.toolshed.system).")
  397. raise e
  398. #------------------------------------------------------------------------------
  399. # [ stdout_xnl function ]
  400. # print to std output stream without a newline
  401. #------------------------------------------------------------------------------
  402. def stdout_xnl(text):
  403. try:
  404. sys.stdout.write(text)
  405. except Exception as e:
  406. if DEBUG_FLAG:
  407. sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout_xnl() function (Naked.toolshed.system).")
  408. raise e
  409. #------------------------------------------------------------------------------
  410. # [ stdout_iter function ]
  411. # print items in an iterable to the standard output stream with newlines after each string
  412. #------------------------------------------------------------------------------
  413. def stdout_iter(iter):
  414. try:
  415. for x in iter:
  416. stdout(x)
  417. except Exception as e:
  418. if DEBUG_FLAG:
  419. sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout_iter() function (Naked.toolshed.system).")
  420. raise e
  421. #------------------------------------------------------------------------------
  422. # [ stdout_iter_xnl function ]
  423. # print items in an iterable to the standard output stream without newlines after each string
  424. #------------------------------------------------------------------------------
  425. def stdout_iter_xnl(iter):
  426. try:
  427. for x in iter:
  428. stdout_xnl(x)
  429. except Exception as e:
  430. if DEBUG_FLAG:
  431. sys.stderr.write("Naked Framework Error: unable to print to the standard output stream with the stdout_iter() function (Naked.toolshed.system).")
  432. raise e
  433. #------------------------------------------------------------------------------
  434. # [ stderr function ]
  435. # print to std error stream
  436. # optionally (i.e. if exit = nonzero integer) permits exit from application with developer defined exit code
  437. #------------------------------------------------------------------------------
  438. def stderr(text, exit=0):
  439. try:
  440. sys.stderr.write(text + "\n")
  441. if exit:
  442. raise SystemExit(exit)
  443. except Exception as e:
  444. if DEBUG_FLAG:
  445. sys.stderr.write("Naked Framework Error: unable to print to the standard error stream with the stderr() function (Naked.toolshed.system).")
  446. raise e
  447. #------------------------------------------------------------------------------
  448. # [ stderr_xnl function ]
  449. # print to the standard error stream without a newline character after the `text` string
  450. #------------------------------------------------------------------------------
  451. def stderr_xnl(text, exit=0):
  452. try:
  453. sys.stderr.write(text)
  454. if exit:
  455. raise SystemExit(exit)
  456. except Exception as e:
  457. if DEBUG_FLAG:
  458. sys.stderr.write("Naked Framework Error: unable to print to the standard error stream with the stderr() function (Naked.toolshed.system).")
  459. raise e
  460. #------------------------------------------------------------------------------
  461. #
  462. # APPLICATION CONTROL
  463. #
  464. #------------------------------------------------------------------------------
  465. #------------------------------------------------------------------------------
  466. # [ exit_with_status function ]
  467. # application exit with developer specified exit status code (default = 0)
  468. # use an exit status integer argument
  469. # Tests: test_SYSTEM.py :: test_sys_exit_with_code
  470. #------------------------------------------------------------------------------
  471. def exit_with_status(exit=0):
  472. raise SystemExit(exit)
  473. #------------------------------------------------------------------------------
  474. # [ exit_fail function ]
  475. # application exit with status code 1
  476. # Tests: test_SYSTEM.py :: test_sys_exit_failure
  477. #------------------------------------------------------------------------------
  478. def exit_fail():
  479. raise SystemExit(1)
  480. #------------------------------------------------------------------------------
  481. # [ exit_success function]
  482. # application exit with status code 0
  483. # Tests: test_SYSTEM.py :: test_sys_exit_success
  484. #------------------------------------------------------------------------------
  485. def exit_success():
  486. raise SystemExit(0)
  487. if __name__ == '__main__':
  488. pass
  489. # #------------------------------------------------------------------------------
  490. # # Standard Output Tests
  491. # #------------------------------------------------------------------------------
  492. # stdout("This is a test")
  493. # for x in range(10):
  494. # stdout_xnl(str(x) + " ")
  495. # list_ten = ['10% ', '20% ', '30% ', '40% ', '50% ', '60% ', '70% ', '80% ', '90% ', '100%']
  496. # stdout_iter(list_ten)
  497. # #------------------------------------------------------------------------------
  498. # # Standard Error Tests
  499. # #------------------------------------------------------------------------------
  500. # stderr("This is a test")
  501. # stderr("This is a test", 1) #exit with status code 1