file.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. '''
  2. Created on 26 janv. 2016
  3. Convenient methods for manage files and directories
  4. @author: olivier.massot
  5. '''
  6. import os
  7. import shutil
  8. import subprocess
  9. __VERSION__ = "0.1"
  10. def fdir(path):
  11. """return the parent directory of the file or directory
  12. (no existence control)"""
  13. return os.path.join(os.path.dirname(path), "")
  14. def fname(chemin, ext=True):
  15. """return the name of the file
  16. ext: return the name with its extension
  17. (no existence control)"""
  18. if not ext:
  19. chemin = os.path.splitext(chemin)[0]
  20. return os.path.basename(chemin)
  21. def fext(chemin):
  22. """return the extension of the file
  23. (no existence control)"""
  24. try:
  25. return os.path.splitext(chemin)[1]
  26. except IndexError:
  27. return ""
  28. def fexists(path):
  29. """test the existence of a file or directory"""
  30. return os.path.exists(os.path.normpath(path))
  31. def fishttp(path):
  32. """is the path a web url?"""
  33. return path[0:7] == "http://" or path[0:8] == "https://"
  34. def frun(path):
  35. """run/open the required file, directory, webpage..."""
  36. if not fishttp(path):
  37. path = os.path.normpath(path)
  38. try:
  39. os.startfile(path)
  40. except AttributeError:
  41. subprocess.call(['open', path])
  42. def flist(target_dir, recursive=False, listdirs=False, listfiles=True, complete_paths=False):
  43. """list the subdirectories and/or the files of the directory;
  44. """
  45. if not os.path.isdir(target_dir):
  46. raise ValueError("'{var}' is not an valid directory".format(var=target_dir))
  47. result = []
  48. for root, dirs, files in os.walk(target_dir):
  49. if listdirs:
  50. if complete_paths:
  51. dirs = [os.path.join(root, d) for d in dirs]
  52. result.extend(dirs)
  53. if listfiles:
  54. if complete_paths:
  55. files = [os.path.join(root, f) for f in files]
  56. result.extend(files)
  57. if not recursive:
  58. break
  59. return result
  60. def fcopy(file_path, target, erase=False):
  61. """copy the file
  62. - If target is a directory, copy the file in this directory and keep its name
  63. - If target is a file path, copy the file to match this path
  64. if erase is True but there is already a file at this path,
  65. append a suffix '_X' to the file name"""
  66. file_path = os.path.normpath(file_path)
  67. cible = os.path.normpath(target)
  68. if not os.path.isfile(file_path):
  69. raise IOError("File {file_path} does not exist".format(file_path=file_path))
  70. if not os.path.isdir(target):
  71. if len(fname(target)) > 0:
  72. target_dir = os.path.dirname(target)
  73. else:
  74. raise IOError("{target_dir} is not a valid target".format(target_dir=target_dir))
  75. else:
  76. target_dir = cible
  77. name, ext = (fname(target, False), fext(target)) if len(fname(target)) > 0 \
  78. else (fname(file_path, False), fext(file_path))
  79. target = os.path.join(target_dir, '%s%s' % (name, ext))
  80. if not erase:
  81. counter = 1
  82. while fexists(target):
  83. counter += 1
  84. target = os.path.join(target_dir, '%s_%d%s' % (name, counter, ext))
  85. shutil.copyfile(file_path, target)
  86. return target
  87. def faccess(path, mode="r"):
  88. """return True if user has an access to the directory or file in parameter
  89. Warning: a negative answer could be caused by a missing access
  90. or by an impossibility to connect to the drive"""
  91. if mode not in ("r", "w"):
  92. raise ValueError("mode should be 'r' or 'w'")
  93. not_found = False
  94. path = os.path.normpath(path)
  95. try:
  96. with open(path, mode) as _:
  97. pass
  98. return True
  99. except (PermissionError, FileNotFoundError, OSError):
  100. not_found = True
  101. if not_found:
  102. if mode == "r":
  103. try:
  104. next(os.walk(path))
  105. except StopIteration:
  106. return False
  107. return True
  108. else:
  109. try:
  110. with open(os.path.join(path, "__test__"), "w") as _:
  111. pass
  112. os.remove(os.path.join(path, "__test__"))
  113. return True
  114. except PermissionError:
  115. return False
  116. else:
  117. raise FileNotFoundError("File {path} does not exist".format(path=path))
  118. def fjoin(*args):
  119. """recursively the paths in parameter"""
  120. result = ""
  121. for path in args:
  122. result = os.path.join(result, os.path.normpath(path))
  123. return result
  124. def fmkdir(dirpath):
  125. """ create the directory recursively """
  126. sub_path = os.path.dirname(dirpath)
  127. if not os.path.exists(sub_path):
  128. fmkdir(sub_path)
  129. if not os.path.exists(dirpath):
  130. os.mkdir(dirpath)
  131. def frmdir(dirpath):
  132. """delete the directory, even it is not empty"""
  133. shutil.rmtree(dirpath)
  134. def fhumansize(size):
  135. """return a human readable size of file"""
  136. suffixes = ['bytes', 'kB', 'MB', 'GB', 'TB']
  137. suffix_index = 0
  138. while size >= 1024:
  139. suffix_index += 1 #increment the index of the suffix
  140. size = size/1024.0 #apply the division
  141. return "{0:03.2f} {1}".format(size, suffixes[suffix_index]) if suffix_index > 0 \
  142. else "{0} {1}".format(size, suffixes[suffix_index])