pathlibutil.Path
inherits from pathlib.Path
with some useful built-in python functions from shutil
and hashlib
Path.hexdigest()
to calculate andPath.verify()
for verification of hexdigest from a filePath.default_hash
to configurate default hash algorithm forPath
class (default: 'md5')Path.size()
to get size in bytes of a file or directorybyteint
function decorator converts the return value ofint
to aByteInt
object
Path.read_lines()
to yield over all lines from a file until EOFcontextmanager
to change current working directory withwith
statementPath.copy()
copy a file or directory to a new path destinationPath.delete()
delete a file or directory-treePath.move()
move a file or directory to a new path destinationPath.make_archive()
creates andPath.unpack_archive()
uncompresses an archive from a file or directoryPath.archive_formats
to get all available archive formatsPath.stat()
returns aStatResult
object to get file or directory information containingTimeInt
objects foratime
,ctime
,mtime
andbirthtime
ByteInt
object forsize
Path.relative_to()
to get relative path from a file or directory,walk_up
to walk up the directory tree.Path.with_suffix()
to change the multiple suffixes of a filePath.cwd()
to get the current working directory or executable path when script is bundled, e.g. withpyinstaller
Path.resolve()
to resolve a unc path to a mapped windows drive.Path.walk()
to walk over a directory tree likeos.walk()
Path.iterdir()
withrecursive
all files from the directory tree will be yielded andexclude_dirs
via callable.Path.is_expired()
to check if a file is expired by a givendatetime.timedelta
Path.expand()
yields file paths for multiple file patterns if they exsits.
JSON serialization of Path
objects is supported in pathlibutil.json
.
pathlibutil.json.dumps()
andpathlibutil.json.dump()
to serializePath
objects as posix paths.
Parse and modify URLs with pathlibutil.urlpath
.
pathlibutil.urlpath.UrlPath()
modify URL and easy access thepath
of the url like apathlib.PurePosixPath
object.pathlibutil.urlpath.UrlNetloc()
to parse and modify thenetloc
part of a URL.pathlibutil.urlpath.normalize()
to normalize a URL string.pathlibutil.urlpath.url_from()
to create a URL from an UNC path object.
pip install pathlibutil
to handle 7zip archives, an extra package py7zr>=0.20.2
is required!
# install as extra dependency
pip install pathlibutil[7z]
from pathlibutil import Path
readme = Path('README.md')
print(f'File size: {readme.size()} Bytes')
Read a file and print its content and some file information to stdout.
Path.read_lines()
from pathlibutil import Path
readme = Path("README.md")
print(f"File size: {readme.size()} Bytes")
print(f'File sha1: {readme.hexdigest("sha1")}')
print("File content".center(80, "="))
for line in readme.read_lines(encoding="utf-8"):
print(line, end="")
print("EOF".center(80, "="))
Write a file with md5 checksums of all python files in the pathlibutil-directory.
Path.hexdigest()
from pathlibutil import Path
file = Path("pathlibutil.md5")
with file.open("w") as f:
f.write(
"# MD5 checksums generated with pathlibutil "
"(https://pypi.org/project/pathlibutil/)\n\n"
)
i = 0
for i, filename in enumerate(Path("./pathlibutil").glob("*.py"), start=1):
f.write(f"{filename.hexdigest()} *{filename}\n")
print(f"\nwritten: {i:>5} {file.default_hash}-hashes to: {file}")
Read a file with md5 checksums and verify them.
Path.verify()
,Path.default_hash
andcontextmanager
from pathlibutil import Path
file = Path("pathlibutil.md5")
def no_comment(line: str) -> bool:
return not line.startswith("#")
with file.parent as cwd:
miss = 0
ok = 0
fail = 0
for line in filter(no_comment, file.read_lines()):
try:
digest, filename = line.strip().split(" *")
verification = Path(filename).verify(digest, "md5")
except ValueError as split_failed:
continue
except FileNotFoundError as verify_failed:
tag = "missing"
miss += 1
else:
if verification:
tag = "ok"
ok += 1
else:
tag = "fail"
fail += 1
print(f'{tag.ljust(len(digest), ".")} *{filename}')
print(f"\nok: {ok:<5} fail: {fail:<5} missing: {miss}")
Search all pycache directories and free the memory and display the number of deleted directories and the amount of memory freed in MB.
Path.delete()
,Path.size()
andByteInt
from pathlibutil import ByteInt, Path
mem = ByteInt(0)
i = 0
for i, cache in enumerate(Path(".").rglob("*/__pycache__/"), start=1):
cache_size = cache.size()
try:
cache.delete(recursive=True)
except OSError:
print(f"Failed to delete {cache}")
else:
mem += cache_size
print(f"{i} cache directories deleted, {mem:.1mb} MB freed.")
Inherit from pathlibutil.Path
to register new a archive format. Specify a
archive
as keyword argument in the new subclass, which has to be the suffix
without .
of the archives. Implement a classmethod _register_archive_format()
to register new archive formats.
Path.make_archive(), Path.archive_formats and Path.move()
import shutil
import pathlibutil
class RegisterFooBarFormat(pathlibutil.Path, archive="foobar"):
@classmethod
def _register_archive_format(cls):
"""
implement new register functions for given `archive`
"""
try:
import required_package_name
except ModuleNotFoundError:
raise ModuleNotFoundError("pip install <required_package_name>")
def pack_foobar(
base_name, base_dir, owner=None, group=None, dry_run=None, logger=None
) -> str:
"""callable that will be used to unpack archives.
Args:
base_name (`str`): name of the file to create
base_dir (`str`): directory to start archiving from, defaults to `os.curdir`
owner (`Any`, optional): as passed in `make_archive(*args, owner=None, **kwargs)`. Defaults to None.
group (`Any`, optional): as passed in `make_archive(*args, group=None, **kwargs)`. Defaults to None.
dry_run (`Any`, optional): as passed in `make_archive(*args, dry_run=None, **kwargs)`. Defaults to None.
logger (`logging.Logger`, optional): as passed in `make_archive(*args, logger=None, **kwargs)`. Defaults to None.
Returns:
str: path of the new created archive
"""
raise NotImplementedError("implement your own pack function")
def unpack_foobar(archive, path, filter=None, extra_args=None) -> None:
"""callable that will be used to unpack archives.
Args:
archive (`str`): path of the archive
path (`str`): directory the archive must be extracted to
filter (`Any`, optional): as passed in `unpack_archive(*args, filter=None, **kwargs)`. Defaults to None.
extra_args (`Sequence[Tuple[name, value]]`, optional): additional keyword arguments, specified by `register_unpack_format(*args, extra_args=None, **kwargs)`. Defaults to None.
"""
raise NotImplementedError("implement your own unpack function")
shutil.register_archive_format(
"foobar", pack_foobar, description="foobar archives"
)
shutil.register_unpack_format("foobar", [".foo.bar"], unpack_foobar)
file = pathlibutil.Path("README.md")
print(f"available archive formats: {file.archive_formats}")
archive = file.make_archive("README.foo.bar")
backup = archive.move("./backup/")
print(f"archive created: {archive.name} and moved to: {backup.parent}")
Access the current working directory with optional parameter frozen
to determine
different directories when script is bundled to an executable,
e.g. with pyinstaller
.
Path.cwd()
>>> poetry run examples/example6.py -b
Building frozen: K:/pathlibutil/examples/example6.exe
Build succeeded: 0
>>> poetry run examples/example6.py
we are not frozen
bundle dir is K:/pathlibutil/examples
sys.argv[0] is K:/pathlibutil/examples/example6.py
sys.executable is K:/pathlibutil/.venv/Scripts/python.exe
os.getcwd is K:/pathlibutil
Path.cwd(frozen=True) is K:/pathlibutil
Path.cwd(frozen=False) is K:/pathlibutil
Path.cwd(frozen=_MEIPASS) is K:/pathlibutil
>>> examples/example6.exe
we are ever so frozen
bundle dir is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042
sys.argv[0] is examples/example6.exe
sys.executable is K:/pathlibutil/examples/example6.exe
os.getcwd is K:/pathlibutil
Path.cwd(frozen=True) is K:/pathlibutil/examples
Path.cwd(frozen=False) is K:/pathlibutil
Path.cwd(frozen=_MEIPASS) is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042
Console application to convert UNC paths to intranet URLs.
By default, it checks if the filename and URL are available and copies the normalized URL to the clipboard.
pathlibutil.urlpath.url_from()
import argparse
import sys
try:
import pyperclip
import pathlibutil.urlpath as up
except ModuleNotFoundError as e:
raise ModuleNotFoundError(f"pip install {e.name.split('.')[0]}") from e
def intranet_from(uncpath: str, check: bool = True) -> str:
"""
Return the intranet URL for the given UNC path.
"""
url = up.url_from(
uncpath,
hostname="http://intranet.example.de",
strict=check,
)
return url.normalize()
def cli():
parser = argparse.ArgumentParser(
description=intranet_from.__doc__,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"filename",
nargs="*",
help="The UNC path to the file.",
)
parser.add_argument(
"-c",
"--no-check",
action="store_false",
dest="check",
help="Don't check if filename and url is available.",
)
parser.add_argument(
"-s",
"--silent",
action="store_true",
help="Do not print the url to stdout.",
)
parser.add_argument(
"-n",
"--no-clip",
action="store_false",
dest="clip",
help="Don't copy the url to the clipboard.",
)
args = parser.parse_args()
filename = " ".join(args.filename)
url = intranet_from(filename, check=args.check)
if not args.silent:
print(url)
if args.clip:
pyperclip.copy(url)
if __name__ == "__main__":
try:
cli()
except Exception as e:
print(e, file=sys.stderr)
sys.exit(1)