Doc for paths

This commit is contained in:
El Mau 2022-03-01 20:05:19 -06:00
parent 9aa946e06e
commit 7114cafea3
2 changed files with 326 additions and 11 deletions

View File

@ -159,6 +159,24 @@ Verify if application exists
app.debug(app.path.exists_app(app_name))
Path is file
------------
.. code-block:: python
path = '/home/mau/myfile.ott'
app.msgbox(app.path.is_file(path))
Path is dir
-----------
.. code-block:: python
path = '/home/mau'
app.msgbox(app.path.is_dir(path))
Make temporary file
-------------------
@ -251,3 +269,47 @@ Open in other path
path_dir = app.paths.get_dir(path_tmp)
app.debug(path_dir)
Get path exists file
--------------------
Default open in user documents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_file = app.path.get_file()
app.msgbox(path_file)
Change init dir
^^^^^^^^^^^^^^^
.. code-block:: python
path = '/home/mau'
path_file = app.path.get_file(path)
app.msgbox(path_file)
Add filter or filters
^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_file = app.path.get_file(filters='ods')
# or
path_file = app.path.get_file(filters='ods,odt')
Can select multiple files
^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_files = app.path.get_file(multiple=True)

View File

@ -1083,6 +1083,28 @@ class Paths(object):
result = bool(shutil.which(name_app))
return result
@classmethod
def is_dir(cls, path: str):
"""Validate if path is directory
:param path: Path for validate
:type path: str
:return: True if path is directory, False if not.
:rtype: bool
"""
return Path(path).is_dir()
@classmethod
def is_file(cls, path: str):
"""Validate if path is a file
:param path: Path for validate
:type path: str
:return: True if path is a file, False if not.
:rtype: bool
"""
return Path(path).is_file()
@classmethod
def temp_file(self):
"""Make temporary file"""
@ -1128,8 +1150,6 @@ class Paths(object):
:param init_dir: Initial default path
:type init_dir: str
:param filters: Filter for show type files: 'xml' or 'txt,xml'
:type filters: str
:return: Selected path
:rtype: str
"""
@ -1147,12 +1167,16 @@ class Paths(object):
@classmethod
def get_file(cls, init_dir: str='', filters: str='', multiple: bool=False):
"""
Get path file
"""Get path exists file
init_folder: folder default open
filters: 'xml' or 'xml,txt'
multiple: True for multiple selected
:param init_dir: Initial default path
:type init_dir: str
:param filters: Filter for show type files: 'xml' or 'txt,xml'
:type filters: str
:param multiple: If user can selected multiple files
:type multiple: bool
:return: Selected path
:rtype: str
"""
if not init_dir:
init_dir = cls.documents
@ -1164,10 +1188,8 @@ class Paths(object):
file_picker.setMultiSelectionMode(multiple)
if filters:
filters = [(f.upper(), f'*.{f.lower()}') for f in filters.split(',')]
file_picker.setCurrentFilter(filters[0][0])
for f in filters:
file_picker.appendFilter(f[0], f[1])
for f in filters.split(','):
file_picker.appendFilter(f.upper(), f'*.{f.lower()}')
path = ''
if file_picker.execute():
@ -1177,6 +1199,125 @@ class Paths(object):
path = path[0]
return path
@classmethod
def files(cls, path: str, pattern: str='*'):
"""Get all files in path
:param path: Path with files
:type path: str
:param pattern: For filter files, default get all.
:type pattern: str
:return: Files in path
:rtype: list
"""
files = [str(p) for p in Path(path).glob(pattern) if p.is_file()]
return files
@classmethod
def dirs(cls, path):
"""Get directories in path
:param path: Path to scan
:type path: str
:return: Directories in path
:rtype: list
"""
dirs = [str(p) for p in Path(path).iterdir() if p.is_dir()]
return dirs
@classmethod
def walk(cls, path, filters=''):
"""Get all files in path recursively
:param path: Path with files
:type path: str
:param filters: For filter files, default get all.
:type filters: str
:return: Files in path
:rtype: list
"""
paths = []
for folder, _, files in os.walk(path):
if filters:
pattern = re.compile(r'\.(?:{})$'.format(filters), re.IGNORECASE)
paths += [cls.join(folder, f) for f in files if pattern.search(f)]
else:
paths += [cls.join(folder, f) for f in files]
return paths
@classmethod
def walk_dirs(cls, path, tree=False):
"""Get directories recursively
:param path: Path to scan
:type path: str
:param tree: get info in a tuple (ID_FOLDER, ID_PARENT, NAME)
:type tree: bool
:return: Directories in path
:rtype: list
"""
folders = []
if tree:
i = 0
p = 0
parents = {path: 0}
for root, dirs, _ in os.walk(path):
for name in dirs:
i += 1
rn = cls.join(root, name)
if not rn in parents:
parents[rn] = i
folders.append((i, parents[root], name))
else:
for root, dirs, _ in os.walk(path):
folders += [cls.join(root, name) for name in dirs]
return folders
@classmethod
def ext(cls, id_ext: str):
"""Get path extension install from id
:param id_ext: ID extension
:type id_ext: str
:return: Path extension
:rtype: str
"""
pip = CTX.getValueByName('/singletons/com.sun.star.deployment.PackageInformationProvider')
path = Paths.to_system(pip.getPackageLocation(id_ext))
return path
@classmethod
def replace_ext(cls, path: str, new_ext: str):
"""Replace extension in file path
:param path: Path to file
:type path: str
:param new_ext: New extension
:type new_ext: str
:return: Path with new extension
:rtype: str
"""
p = Paths(path)
name = f'{p.name}.{new_ext}'
path = cls.join(p.path, name)
return path
@classmethod
def open(cls, path: str):
"""Open any file with default program in systema
:param path: Path to file
:type path: str
:return: PID file, only Linux
:rtype: int
"""
pid = 0
if IS_WIN:
os.startfile(path)
else:
pid = subprocess.Popen(['xdg-open', path]).pid
return pid
# ~ Save/read data
@classmethod
@ -1265,6 +1406,118 @@ class Paths(object):
data = json.dumps(data, indent=4, ensure_ascii=False, sort_keys=True)
return cls.save(path, data)
@classmethod
def from_csv(cls, path: str, args: dict={}) -> tuple:
"""Read CSV
:param path: Path to file csv
:type path: str
:param args: Any argument support for Python library
:type args: dict
:return: Data csv like tuple
:rtype: tuple
`See CSV Reader <https://docs.python.org/3.8/library/csv.html#csv.reader>`_
"""
with open(path) as f:
rows = tuple(csv.reader(f, **args))
return rows
@classmethod
def to_csv(cls, path: str, data: Any, args: dict={}):
"""Write CSV
:param path: Path to file write csv
:type path: str
:param data: Data to write
:type data: Iterable
:param args: Any argument support for Python library
:type args: dict
`See CSV Writer <https://docs.python.org/3.8/library/csv.html#csv.writer>`_
"""
with open(path, 'w') as f:
writer = csv.writer(f, **args)
writer.writerows(data)
return
@classmethod
def zip(cls, source: Union[str, tuple, list], target='') -> str:
path_zip = target
if not isinstance(source, (tuple, list)):
path, _, name, _ = _P(source).info
start = len(path) + 1
if not target:
path_zip = f'{path}/{name}.zip'
if isinstance(source, (tuple, list)):
files = [(f, f[len(_P(f).path)+1:]) for f in source]
elif _P.is_file(source):
files = ((source, source[start:]),)
else:
files = [(f, f[start:]) for f in _P.walk(source)]
compression = zipfile.ZIP_DEFLATED
with zipfile.ZipFile(path_zip, 'w', compression=compression) as z:
for f in files:
z.write(f[0], f[1])
return path_zip
@classmethod
def unzip(cls, source, target='', members=None, pwd=None):
path = target
if not target:
path = _P(source).path
with zipfile.ZipFile(source) as z:
if not pwd is None:
pwd = pwd.encode()
if isinstance(members, str):
members = (members,)
z.extractall(path, members=members, pwd=pwd)
return
@classmethod
def zip_content(cls, path: str):
with zipfile.ZipFile(path) as z:
names = z.namelist()
return names
@classmethod
def merge_zip(cls, target, zips):
try:
with zipfile.ZipFile(target, 'w', compression=zipfile.ZIP_DEFLATED) as t:
for path in zips:
with zipfile.ZipFile(path, compression=zipfile.ZIP_DEFLATED) as s:
for name in s.namelist():
t.writestr(name, s.open(name).read())
except Exception as e:
error(e)
return False
return True
@classmethod
def kill(cls, path: str):
"""Delete path
:param path: Path to file or directory
:type path: str
:return: True if delete correctly
:rtype: bool
"""
p = Path(path)
try:
if p.is_file():
p.unlink()
elif p.is_dir():
shutil.rmtree(path)
result = True
except OSError as e:
log.error(e)
result = False
return result
class Config(object):
"""Class for set and get configurations