Skip to content

Commit

Permalink
feat(core): only print colored text when attached to terminal
Browse files Browse the repository at this point in the history
  • Loading branch information
jaxvanyang committed Jun 7, 2024
1 parent 49f689f commit c29ea9a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 18 deletions.
10 changes: 8 additions & 2 deletions src/batchlink/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
"""Module providing batchlink main APIs."""

from .core import batch_link, formatted_paths, remove
from .core import batch_link, color_print, formatted_paths, remove

__version__ = "0.1.0"

__all__ = ["__version__", "formatted_paths", "remove", "batch_link"]
__all__ = [
"__version__",
"batch_link",
"color_print",
"formatted_paths",
"remove",
]
89 changes: 73 additions & 16 deletions src/batchlink/core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Module providing batchlink core APIs."""

import shutil
import sys
from os import PathLike
from pathlib import Path

Expand Down Expand Up @@ -46,28 +47,82 @@ def formatted_paths(paths: list[Path], template: str) -> list[Path]:
return new_paths


def remove(file: PathLike, *, dry_run: bool = False) -> None:
"""Remove this file, symbolic link or directory, if exists.
def color_print(*strs, sep=" ", end="\n", file=None, flush=False) -> None:
"""Print colored text of objects to the text stream file if it's interactive.
This function also print a message before removing.
If the file is not interactive, replacement fields are removed from format strings.
Args:
file: The file to be removed.
*strs: The format strings to be printed, which may contain the replacement
fields - black, red, green, yellow, blue, magenta, cyan, white and reset. For
example, '{green}hello{reset} {red}world{reset}'.
sep: String inserted between values. Default is a space.
end: String appended after the last value. Default is a newline.
file: A file-like object (stream). Default is the current sys.stdout.
flush: Whether to forcibly flush the stream.
"""

if not isinstance(file, Path):
file = Path(file)
if file is None:
file = sys.stdout

color_dict = (
{
"black": "\x1b[30m",
"red": "\x1b[31m",
"green": "\x1b[32m",
"yellow": "\x1b[33m",
"blue": "\x1b[34m",
"magenta": "\x1b[35m",
"cyan": "\x1b[36m",
"white": "\x1b[37m",
"reset": "\x1b[00m",
}
if file.isatty()
else {
"black": "",
"red": "",
"green": "",
"yellow": "",
"blue": "",
"magenta": "",
"cyan": "",
"white": "",
"reset": "",
}
)

strs = [str.format(**color_dict) for str in strs]

print(*strs, sep=sep, end=end, file=file, flush=flush)


def remove(path: PathLike, *, dry_run: bool = False, file=None) -> None:
"""Remove the file, symbolic link or directory of the path, if exists.
This function also print a message to the file before removing.
if file.is_dir() or file.is_file():
print(f"\x1b[33mRemove\x1b[00m {file}")
Args:
path: The path of file to be removed.
file: The file-like object (stream) to print message to. Default is the current
sys.stdout.
"""

if file is None:
file = sys.stdout

if not isinstance(path, Path):
path = Path(path)

if path.is_dir() or path.is_file():
color_print(f"{{yellow}}Remove{{reset}} {path}", file=file)

if dry_run:
return

if file.is_dir():
file.rmdir()
elif file.is_file():
file.unlink()
if path.is_dir():
path.rmdir()
elif path.is_file():
path.unlink()


def batch_link(
Expand Down Expand Up @@ -124,7 +179,9 @@ def rename_file(src_path: Path, dest_path: Path):
if force:
remove(dest_path, dry_run=dry_run)

print(f"\x1b[34mRename\x1b[00m {src_path} \x1b[34mto\x1b[00m {dest_path}")
color_print(
f"{{blue}}Rename{{reset}} {src_path} {{blue}}to{{reset}} {dest_path}"
)

if dry_run:
return
Expand All @@ -135,7 +192,7 @@ def copy_file(src_path: Path, dest_path: Path):
if force:
remove(dest_path, dry_run=dry_run)

print(f"\x1b[34mCopy\x1b[00m {src_path} \x1b[34mto\x1b[00m {dest_path}")
color_print(f"{{blue}}Copy{{reset}} {src_path} {{blue}}to{{reset}} {dest_path}")

if dry_run:
return
Expand All @@ -157,8 +214,8 @@ def link_file(src_path: Path, dest_path: Path):
if force:
remove(dest_path, dry_run=dry_run)

print(
f"\x1b[34mCreate {link_type} link\x1b[00m {dest_path} \x1b[34mto\x1b[00m "
color_print(
f"{{blue}}Create {link_type} link{{reset}} {dest_path} {{blue}}to{{reset}} "
f"{src_path}"
)

Expand Down

0 comments on commit c29ea9a

Please sign in to comment.