hexif-pyutils 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: hexif-pyutils
3
+ Version: 1.0.0
4
+ Summary: Super simple python utility library
5
+ Author: HeXif
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/xHeXifx/hexif-pyutils
8
+ Project-URL: Repository, https://github.com/xHeXifx/hexif-pyutils
9
+ Project-URL: Issues, https://github.com/xHeXifx/hexif-pyutils/issues
10
+ Keywords: utilties,utils,python,helpers
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+
14
+ # hexif-pyutils
15
+
16
+ Super simple Python utilities.
17
+
18
+ This was mainly put on PyPi so i can install it without cloning it off gitea and then pip installing it off the local path.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ pip install hexif-pyutils
24
+ ```
25
+
26
+ ## Install (TouchID Helper MacOS)
27
+
28
+ (If not cloned clone)
29
+ ```zsh
30
+ git clone https://github.com/xHeXifx/hexif-pyutils
31
+ ```
32
+
33
+ ```zsh
34
+ cd {repo}/macOS/touchid-executable/touchid-helper
35
+ swift build -c release
36
+ ```
37
+
38
+ Find the executable, will be somewhere in ./build and named 'touchid'
39
+ ```zsh
40
+ cp {executable location} /usr/local/bin/touchid
41
+ sudo chmod +x /usr/local/bin/touchid
42
+ ```
43
+
44
+ Optional test
45
+ ```zsh
46
+ /usr/local/bin/touchid "perform a test"
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ### Logger
52
+
53
+ ```python
54
+ from utils.logger import Logger
55
+
56
+ log = Logger("app", log_file="app.log")
57
+ log.info("Hello")
58
+ ```
59
+
60
+ What it does: simple logging wrapper with console and file output.
61
+
62
+ ### File helpers
63
+
64
+ ```python
65
+ from utils.file import read, write, get, touch
66
+
67
+ write("hello", "test.txt")
68
+ print(read("test.txt"))
69
+ print(get("test.txt").name)
70
+ touch("new.txt")
71
+ ```
72
+
73
+ What it does: basic file reading/writing, file metadata lookup, and creating empty files.
74
+
75
+ ### JSON
76
+
77
+ ```python
78
+ from utils.file.json import read, write
79
+
80
+ write({"name": "hexif"}, "data.json")
81
+ data = read("data.json")
82
+ print(data)
83
+ ```
84
+
85
+ What it does: reads and writes JSON files quickly.
86
+
87
+ ### Shell
88
+
89
+ ```python
90
+ from utils.system.shell import run
91
+
92
+ result = run("echo hello", capture_output=True, text=True)
93
+ print(result.stdout)
94
+ ```
95
+
96
+ What it does: runs shell commands using Python subprocess.
97
+
98
+ ### Touch ID
99
+
100
+ ```python
101
+ from utils.system.security import askForTouchID
102
+
103
+ allowed = askForTouchID("confirm action")
104
+ print(allowed)
105
+ ```
106
+
107
+ What it does: checks for the macOS Touch ID helper and asks for confirmation.
108
+
109
+ ## Credits
110
+
111
+ - https://hexif.vercel.app
112
+ - https://github.com/xHeXifx
@@ -0,0 +1,99 @@
1
+ # hexif-pyutils
2
+
3
+ Super simple Python utilities.
4
+
5
+ This was mainly put on PyPi so i can install it without cloning it off gitea and then pip installing it off the local path.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install hexif-pyutils
11
+ ```
12
+
13
+ ## Install (TouchID Helper MacOS)
14
+
15
+ (If not cloned clone)
16
+ ```zsh
17
+ git clone https://github.com/xHeXifx/hexif-pyutils
18
+ ```
19
+
20
+ ```zsh
21
+ cd {repo}/macOS/touchid-executable/touchid-helper
22
+ swift build -c release
23
+ ```
24
+
25
+ Find the executable, will be somewhere in ./build and named 'touchid'
26
+ ```zsh
27
+ cp {executable location} /usr/local/bin/touchid
28
+ sudo chmod +x /usr/local/bin/touchid
29
+ ```
30
+
31
+ Optional test
32
+ ```zsh
33
+ /usr/local/bin/touchid "perform a test"
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ### Logger
39
+
40
+ ```python
41
+ from utils.logger import Logger
42
+
43
+ log = Logger("app", log_file="app.log")
44
+ log.info("Hello")
45
+ ```
46
+
47
+ What it does: simple logging wrapper with console and file output.
48
+
49
+ ### File helpers
50
+
51
+ ```python
52
+ from utils.file import read, write, get, touch
53
+
54
+ write("hello", "test.txt")
55
+ print(read("test.txt"))
56
+ print(get("test.txt").name)
57
+ touch("new.txt")
58
+ ```
59
+
60
+ What it does: basic file reading/writing, file metadata lookup, and creating empty files.
61
+
62
+ ### JSON
63
+
64
+ ```python
65
+ from utils.file.json import read, write
66
+
67
+ write({"name": "hexif"}, "data.json")
68
+ data = read("data.json")
69
+ print(data)
70
+ ```
71
+
72
+ What it does: reads and writes JSON files quickly.
73
+
74
+ ### Shell
75
+
76
+ ```python
77
+ from utils.system.shell import run
78
+
79
+ result = run("echo hello", capture_output=True, text=True)
80
+ print(result.stdout)
81
+ ```
82
+
83
+ What it does: runs shell commands using Python subprocess.
84
+
85
+ ### Touch ID
86
+
87
+ ```python
88
+ from utils.system.security import askForTouchID
89
+
90
+ allowed = askForTouchID("confirm action")
91
+ print(allowed)
92
+ ```
93
+
94
+ What it does: checks for the macOS Touch ID helper and asks for confirmation.
95
+
96
+ ## Credits
97
+
98
+ - https://hexif.vercel.app
99
+ - https://github.com/xHeXifx
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: hexif-pyutils
3
+ Version: 1.0.0
4
+ Summary: Super simple python utility library
5
+ Author: HeXif
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/xHeXifx/hexif-pyutils
8
+ Project-URL: Repository, https://github.com/xHeXifx/hexif-pyutils
9
+ Project-URL: Issues, https://github.com/xHeXifx/hexif-pyutils/issues
10
+ Keywords: utilties,utils,python,helpers
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+
14
+ # hexif-pyutils
15
+
16
+ Super simple Python utilities.
17
+
18
+ This was mainly put on PyPi so i can install it without cloning it off gitea and then pip installing it off the local path.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ pip install hexif-pyutils
24
+ ```
25
+
26
+ ## Install (TouchID Helper MacOS)
27
+
28
+ (If not cloned clone)
29
+ ```zsh
30
+ git clone https://github.com/xHeXifx/hexif-pyutils
31
+ ```
32
+
33
+ ```zsh
34
+ cd {repo}/macOS/touchid-executable/touchid-helper
35
+ swift build -c release
36
+ ```
37
+
38
+ Find the executable, will be somewhere in ./build and named 'touchid'
39
+ ```zsh
40
+ cp {executable location} /usr/local/bin/touchid
41
+ sudo chmod +x /usr/local/bin/touchid
42
+ ```
43
+
44
+ Optional test
45
+ ```zsh
46
+ /usr/local/bin/touchid "perform a test"
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ### Logger
52
+
53
+ ```python
54
+ from utils.logger import Logger
55
+
56
+ log = Logger("app", log_file="app.log")
57
+ log.info("Hello")
58
+ ```
59
+
60
+ What it does: simple logging wrapper with console and file output.
61
+
62
+ ### File helpers
63
+
64
+ ```python
65
+ from utils.file import read, write, get, touch
66
+
67
+ write("hello", "test.txt")
68
+ print(read("test.txt"))
69
+ print(get("test.txt").name)
70
+ touch("new.txt")
71
+ ```
72
+
73
+ What it does: basic file reading/writing, file metadata lookup, and creating empty files.
74
+
75
+ ### JSON
76
+
77
+ ```python
78
+ from utils.file.json import read, write
79
+
80
+ write({"name": "hexif"}, "data.json")
81
+ data = read("data.json")
82
+ print(data)
83
+ ```
84
+
85
+ What it does: reads and writes JSON files quickly.
86
+
87
+ ### Shell
88
+
89
+ ```python
90
+ from utils.system.shell import run
91
+
92
+ result = run("echo hello", capture_output=True, text=True)
93
+ print(result.stdout)
94
+ ```
95
+
96
+ What it does: runs shell commands using Python subprocess.
97
+
98
+ ### Touch ID
99
+
100
+ ```python
101
+ from utils.system.security import askForTouchID
102
+
103
+ allowed = askForTouchID("confirm action")
104
+ print(allowed)
105
+ ```
106
+
107
+ What it does: checks for the macOS Touch ID helper and asks for confirmation.
108
+
109
+ ## Credits
110
+
111
+ - https://hexif.vercel.app
112
+ - https://github.com/xHeXifx
@@ -0,0 +1,13 @@
1
+ README.md
2
+ pyproject.toml
3
+ hexif_pyutils.egg-info/PKG-INFO
4
+ hexif_pyutils.egg-info/SOURCES.txt
5
+ hexif_pyutils.egg-info/dependency_links.txt
6
+ hexif_pyutils.egg-info/top_level.txt
7
+ utils/__init__.py
8
+ utils/logger.py
9
+ utils/file/__init__.py
10
+ utils/file/json.py
11
+ utils/system/__init__.py
12
+ utils/system/security.py
13
+ utils/system/shell.py
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "hexif-pyutils"
7
+ version = "1.0.0"
8
+ description = "Super simple python utility library"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+
12
+ authors = [{name = "HeXif"}]
13
+
14
+ license = "MIT"
15
+
16
+ keywords = [
17
+ "utilties",
18
+ "utils",
19
+ "python",
20
+ "helpers"
21
+ ]
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/xHeXifx/hexif-pyutils"
25
+ Repository = "https://github.com/xHeXifx/hexif-pyutils"
26
+ Issues = "https://github.com/xHeXifx/hexif-pyutils/issues"
27
+
28
+ [tool.setuptools.packages.find]
29
+ include = ["utils*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from . import file
2
+ from . import system
3
+ from . import logger
@@ -0,0 +1,77 @@
1
+ from ..file import json
2
+
3
+ from pathlib import Path as _Path
4
+ from os.path import isfile as _isfile
5
+ from os.path import exists as _exists
6
+ from typing import Any as _Any
7
+
8
+ class File:
9
+ def __init__(self, filename: str|_Path):
10
+ if not isinstance(filename, _Path):
11
+ filename = _Path(filename)
12
+ self.path = filename
13
+ self.exists = self.path.exists()
14
+
15
+ self.is_file = self.path.is_file()
16
+ self.is_dir = self.path.is_dir()
17
+ self.is_symlink = self.path.is_symlink()
18
+
19
+ self.name = self.path.name
20
+ self.stem = self.path.stem
21
+ self.extension = self.path.suffix
22
+ self.parent = self.path.parent
23
+ self.absolute = self.path.absolute()
24
+ self.resolved = self.path.resolve()
25
+
26
+ self.size_bytes = self.path.stat().st_size
27
+ self.size_kb = self.size_bytes / 1024
28
+ self.size_mb = self.size_bytes / 1024**2
29
+ self.size_gb = self.size_bytes / 1024**3
30
+
31
+
32
+ def read(filename: str|_Path) -> str|None:
33
+ """Read contents of a file"""
34
+ try:
35
+ if _isfile(filename):
36
+ with open(filename, 'r') as f:
37
+ return f.read()
38
+ else:
39
+ raise FileNotFoundError(f"File '{filename}' does not exist.")
40
+ except Exception as e:
41
+ raise Exception(f"Failed to read file {filename}") from e
42
+
43
+ def write(data: _Any, filename: str|_Path) -> bool|None:
44
+ """Opens file as 'w' and writes data
45
+
46
+ Args:
47
+ data: Information to write
48
+ filename: File to write to
49
+
50
+ Returns:
51
+ bool (True): If completed successfully
52
+ None: If fails and raises Exception
53
+ """
54
+ try:
55
+ with open(filename, 'w') as f:
56
+ f.write(data)
57
+ return True
58
+ except Exception as e:
59
+ raise Exception(f"Failed to write to file {filename}") from e
60
+
61
+ def get(file: str|_Path) -> File|None:
62
+ """Get information on a file
63
+
64
+ Returns:
65
+ File: If file is found
66
+ None: If file is not found
67
+ """
68
+ if _exists(file):
69
+ return File(file)
70
+ else:
71
+ raise FileNotFoundError()
72
+
73
+ def touch(file: str|_Path) -> None:
74
+ """Touch (create) a empty file"""
75
+ if _exists(file):
76
+ return None
77
+
@@ -0,0 +1,57 @@
1
+ import json
2
+ from pathlib import Path
3
+ import os
4
+
5
+ def read(filename: str|Path) -> dict|list|None:
6
+ """Read file with open 'r' and returns json.load()"""
7
+ try:
8
+ if os.path.isfile(filename):
9
+ with open(filename, 'r') as f:
10
+ return json.load(f)
11
+ else:
12
+ raise FileNotFoundError(f"File '{filename}' does not exist.")
13
+ except Exception as e:
14
+ raise Exception(f"Failed to read file {filename}") from e
15
+
16
+ def write(data: dict|list, filename: str|Path, indent=4) -> bool|None:
17
+ """Write dict/list data with 'f' to json file
18
+
19
+ Args:
20
+ data: JSON data to write
21
+ filename: File to write to
22
+ indent: Indentation to use in the file
23
+
24
+ Returns:
25
+ bool (True): If operation completes successfully
26
+ None: If operation fails and raises Exception
27
+ """
28
+ try:
29
+ with open(filename, 'w') as f:
30
+ json.dump(data, f, indent=indent)
31
+ return True
32
+ except Exception as e:
33
+ raise Exception(f"Failed to write to file {filename}") from e
34
+
35
+ def extract_dict_obj(text: str) -> dict | None:
36
+ """Finds and returns a dict from a string
37
+ Args:
38
+ text (str): The text you wish to extract object from
39
+
40
+ Returns:
41
+ dict: If object was extracted
42
+ None: If no object found
43
+ """
44
+ text = text.strip()
45
+ try:
46
+ obj = json.loads(text)
47
+ return obj if isinstance(obj, dict) else None
48
+ except Exception:
49
+ pass
50
+ start, end = text.find("{"), text.rfind("}")
51
+ if start == -1 or end == -1 or end <= start:
52
+ return None
53
+ try:
54
+ obj = json.loads(text[start:end + 1])
55
+ return obj if isinstance(obj, dict) else None
56
+ except Exception:
57
+ return None
@@ -0,0 +1,78 @@
1
+ import logging as _logging
2
+ from pathlib import Path as _Path
3
+
4
+
5
+ import logging as _logging
6
+ from pathlib import Path as _Path
7
+
8
+
9
+ class Logger:
10
+ """Wrapper around Python's logging.Logger."""
11
+
12
+ def __init__(
13
+ self,
14
+ name: str | None = None,
15
+ log_file: str | _Path | None = None,
16
+ level: int = _logging.INFO,
17
+ console: bool = True,
18
+ ):
19
+ self.logger = _logging.getLogger(name)
20
+ self.logger.setLevel(level)
21
+
22
+ if not self.logger.handlers:
23
+ formatter = _logging.Formatter(
24
+ "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
25
+ )
26
+
27
+ if console:
28
+ console_handler = _logging.StreamHandler()
29
+ console_handler.setFormatter(formatter)
30
+ self.logger.addHandler(console_handler)
31
+
32
+ if log_file is not None:
33
+ file_handler = _logging.FileHandler(
34
+ log_file,
35
+ encoding="utf-8"
36
+ )
37
+ file_handler.setFormatter(formatter)
38
+ self.logger.addHandler(file_handler)
39
+
40
+ def debug(self, msg, *args, **kwargs):
41
+ self.logger.debug(msg, *args, **kwargs)
42
+
43
+ def info(self, msg, *args, **kwargs):
44
+ self.logger.info(msg, *args, **kwargs)
45
+
46
+ def warning(self, msg, *args, **kwargs):
47
+ self.logger.warning(msg, *args, **kwargs)
48
+
49
+ def error(self, msg, *args, **kwargs):
50
+ self.logger.error(msg, *args, **kwargs)
51
+
52
+ def critical(self, msg, *args, **kwargs):
53
+ self.logger.critical(msg, *args, **kwargs)
54
+
55
+ def exception(self, msg, *args, **kwargs):
56
+ self.logger.exception(msg, *args, **kwargs)
57
+
58
+ def log(self, level, msg, *args, **kwargs):
59
+ self.logger.log(level, msg, *args, **kwargs)
60
+
61
+ def setLevel(self, level):
62
+ self.logger.setLevel(level)
63
+
64
+ def addHandler(self, handler):
65
+ self.logger.addHandler(handler)
66
+
67
+ def removeHandler(self, handler):
68
+ self.logger.removeHandler(handler)
69
+
70
+ def hasHandlers(self):
71
+ return self.logger.hasHandlers()
72
+
73
+ def isEnabledFor(self, level):
74
+ return self.logger.isEnabledFor(level)
75
+
76
+ def _appendToLog(content: str, log: Logger):
77
+ with open(log.logFile, 'a') as f:
78
+ f.write(content + "\n")
@@ -0,0 +1,2 @@
1
+ from ..system import shell
2
+ from ..system import security
@@ -0,0 +1,31 @@
1
+ import subprocess
2
+ from pathlib import Path
3
+
4
+ class TouchIDError(Exception):
5
+ pass
6
+
7
+ def ensureTouchID() -> bool:
8
+ """Checks if macos touchid executable exists"""
9
+ exePath = Path('/usr/local/bin/touchid')
10
+ return exePath.exists()
11
+
12
+
13
+ def askForTouchID(reason: str = "confirm a action") -> bool:
14
+ if not ensureTouchID():
15
+ raise TouchIDError("touchid executable is not installed")
16
+ result = subprocess.run(
17
+ ["touchid", reason],
18
+ stdout=subprocess.PIPE,
19
+ stderr=subprocess.PIPE,
20
+ text=True,
21
+ )
22
+
23
+ if result.returncode == 0:
24
+ return True
25
+ if result.returncode == 1:
26
+ return False
27
+
28
+ if result.returncode == 2:
29
+ raise TouchIDError(
30
+ result.stderr.strip() or "Touch ID is unavailable"
31
+ )
@@ -0,0 +1,20 @@
1
+ import subprocess as _sbp
2
+
3
+ def run(command: str, **kwargs) -> _sbp.CompletedProcess | None:
4
+ """Run a command with subprocess.
5
+
6
+ Args:
7
+ command: Command to execute as a string.
8
+ **kwargs: Additional arguments passed to subprocess.run().
9
+
10
+ Returns:
11
+ The command's stdout if capture_output=True, otherwise None.
12
+
13
+ Raises:
14
+ RuntimeError: If the command returns a non-zero exit code.
15
+ subprocess.CalledProcessError: If check=True and the command fails.
16
+ """
17
+ return _sbp.run(
18
+ command.split(),
19
+ **kwargs
20
+ )