# customlib
A few tools for day to day work.
---
### Installation:
```commandline
python -m pip install [--upgrade] customlib
```
---
### Available tools:
<details>
<summary>FileHandler</summary>
<p>
This is a file handler that can be used as a context-manager with thread & file locking.
How to:
```python
from customlib.filehandlers import FileHandler
fh = FileHandler("test_file.txt", "a", encoding="UTF-8")
fh.write("Just testing out this cool new filehandler.\n")
fh.close()
```
or even beter:
```python
with FileHandler("test_file.txt", "a", encoding="UTF-8") as fh:
fh.write("Just testing out this cool new filehandler.\n")
```
</p>
</details>
---
<details>
<summary>FileLocker</summary>
<p>
This is a file locker that can also be used as a context-manager.
How to:
```python
from customlib.filelockers import FileLocker, LOCK
fl1 = FileLocker()
if __name__ == '__main__':
fh1 = open("just_a_file.txt", "w", encoding="UTF-8")
fl1.acquire(fh1, flags=LOCK.EX)
fh1.write("Just testing the locking system...\n")
fl1.release(fh1)
fh1.close()
```
**Lock types:**
- `LOCK.EX`: int (0x1), exclusive lock
- `LOCK.SH`: int (0x2), shared lock
**Lock flags:**
- `LOCK.NB`: int (0x4), non-blocking
**Manually unlock (only needed internally):**
- `LOCK.UN`: int (0), unlock
</p>
</details>
---
<details>
<summary>Vault</summary>
<p>
This is a handler that makes use of keyring for password safe-keeping.
How to:
```python
from customlib.keyvault import Vault
vault = Vault()
password: str = vault.generate(exclude="\'\"\\", length=16)
vault.set_password(service="test_service", username="test_username", password=password)
if __name__ == '__main__':
password: str = vault.get_password(service="test_service", username="test_username")
print(password)
vault.del_password(service="test_service", username="test_username")
```
`generate` params:
* `include`: The character set(s) to be used when generating the password.
* `u`: ascii_uppercase
* `l`: ascii_lowercase
* `d`: digits
* `p`: punctuation
* `exclude`: The characters to be excluded from the password.
* `length`: The number of characters our password should have.
This is not so different from `keyring`, after all, it is making use of its methods.
It exists only to serve as a base class for `KeyVault`!
</p>
</details>
---
<details>
<summary>KeyVault</summary>
<p>
This is a handler that makes use of keyring for password safe-keeping using encryption.
How to:
```python
from customlib.keyvault import KeyVault
vault = KeyVault()
vault.password(
value=vault.generate(exclude="\'\"\\", length=16),
salt=vault.generate(exclude="\'\"\\", length=16)
)
if __name__ == '__main__':
vault.set_password(service="test_service", username="test_username", password="test_password")
print(vault.get_password(service="test_service", username="test_username"))
vault.del_password(service="test_service", username="test_username")
```
`generate` params:
* `include`: The character set(s) to be used when generating the password.
* `u`: ascii_uppercase
* `l`: ascii_lowercase
* `d`: digits
* `p`: punctuation
* `exclude`: The characters to be excluded from the password.
* `length`: The number of characters our password should have.
</p>
</details>
---
<details>
<summary>ClassRegistry</summary>
<p>
Immutable class registry handler.
Example:
```python
from customlib.registry import ClassRegistry
@ClassRegistry.register("some_name")
class SomeClass(object):
def __init__(self, var: str):
self.var = var
if __name__ == '__main__':
# instantiating 'SomeClass':
some_class = ClassRegistry.get("some_name", "var_value")
print(some_class.var)
```
</p>
</details>
---
<details>
<summary>MutableClassRegistry</summary>
<p>
Mutable class registry handler.
If a key already exists in `__register__` it will be updated.
Example:
```python
from customlib.registry import MutableClassRegistry
@MutableClassRegistry.register("some_name")
class SomeClass(object):
def __init__(self, var: str):
self.var = var
if __name__ == '__main__':
# instantiating 'SomeClass'
some_class = MutableClassRegistry.get("some_name", "var_value")
print(some_class.var)
```
</p>
</details>
---
<details>
<summary>OsSleepInhibitor</summary>
<p>
With this handler we can prevent the operating system from going to sleep.
Works in `Windows` and it might work as well in `Linux` and `Darwin` systems (not tested!).
How to:
```python
from customlib.systemhandlers import OsSleepInhibitor
if __name__ == '__main__':
with OsSleepInhibitor(keep_screen_awake=True) as osi:
print("I just did something that took a lot of time...")
```
</p>
</details>
---
<details>
<summary>MetaSingleton</summary>
<p>
Singleton metaclass for restricting `non-strict` classes to only one instance per runtime.
How to:
```python
from customlib.singletons import MetaSingleton
class CfgParser(object, metaclass=MetaSingleton):
"""test"""
if __name__ == '__main__':
cfg1 = CfgParser()
cfg2 = CfgParser()
print("*" * 80)
print("cfg1 == cfg2:", cfg1 == cfg2)
print("cfg1 is cfg2:", cfg1 is cfg2)
```
```
cfg1 == cfg2: True
cfg1 is cfg2: True
```
</p>
</details>
---
<details>
<summary>singleton</summary>
<p>
Singleton decorator for `metaclass`.
Restrict object to only one instance per runtime.
How to:
```python
from customlib.singletons import singleton
@singleton
class CfgParser(object):
"""test"""
if __name__ == '__main__':
cfg1 = CfgParser()
cfg2 = CfgParser()
print("*" * 80)
print("cfg1 == cfg2:", cfg1 == cfg2)
print("cfg1 is cfg2:", cfg1 is cfg2)
```
```
cfg1 == cfg2: True
cfg1 is cfg2: True
```
</p>
</details>
---
<details>
<summary>del_prefix</summary>
<p>
If `target` starts with the `prefix` string and `prefix` is not empty, return `string[len(prefix):]`.
Otherwise, return a copy of the original string.
How to:
```python
from customlib.utils import del_prefix
a = "some cool string"
if __name__ == '__main__':
b = del_prefix(target=a, prefix="some ")
print(b) # --> "cool string"
```
</p>
</details>
---
<details>
<summary>del_suffix</summary>
<p>
If `target` ends with the `suffix` string and `suffix` is not empty, return `string[:-len(suffix)]`.
Otherwise, return a copy of the original string.
How to:
```python
from customlib.utils import del_suffix
a = "some cool string"
if __name__ == '__main__':
b = del_suffix(target=a, suffix=" string")
print(b) # --> "some cool"
```
</p>
</details>
---
### WARNING:
As of version `v6.0.0` the following modules are no longer in this library:
* `logging` (now [logpie](https://github.com/ClaudiuDrug/logpie))
* `config` (now [cfgpie](https://github.com/ClaudiuDrug/cfgpie))
* `sqlite` (now [sqlitepie](https://github.com/ClaudiuDrug/sqlitepie))
---
### Note:
This is still work in progress!
---