Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 22.10.0
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
38 changes: 29 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
<div align="center">
<h2>Logit</h2>
<img src="assets/title_logo.png" width=500>
</div>

## 📝 Usage
```py
from logit import log, Level

log.clutter("Test message!")

log.config(level=Level.ERROR)

log.clutter("Wont appear no more")
log.error("Error error!")
```

output:
```
CLUTTER | test.py:3 | Test message!
ERROR | test.py:6 | Error error!
```

## 🛠️ Setup and Install
- Clone the repository
- Install from `pip`
```
git clone https://github.com/blankRiot96/logit
pip install logit-axis
```
- Install from current directory
OR

- Clone the repository, and install from directory
```
git clone https://github.com/blankRiot96/logit
cd logit
pip install .
```

- Or simply use the `git+` syntax,
OR

- Or simply use the `git+` syntax,
```
pip install git+https://github.com/blankRiot96/logit
```

## 🍉 Credits
- @blankRiot96 - Lead maintainer




Binary file added assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/title_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions commit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""To be ran to commit changes."""

import subprocess

subprocess.run("git add .", shell=True)
subprocess.run("pre-commit")
subprocess.run("aicommits.cmd", shell=True)
22 changes: 22 additions & 0 deletions logit/_common.py
Original file line number Diff line number Diff line change
@@ -1 +1,23 @@
import json
import os
from pathlib import Path


def get_path(path: str | Path, file=True) -> Path:
path = Path(path)
if not path.exists():
if file:
path.touch()
else:
path.mkdir()

return path


LEVEL: str = "CLUTTER"
APP_DATA_FOLDER = get_path(Path(os.getenv("APPDATA")) / "logit", file=False)
CONFIG_FILE = get_path(APP_DATA_FOLDER / "config.json")

if not CONFIG_FILE.exists():
with open(CONFIG_FILE, "w") as f:
json.dump({"files": {}}, f, indent=2)
72 changes: 72 additions & 0 deletions logit/_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Handles all App Data for logit."""

import datetime
import json
import shutil
import time
from functools import lru_cache
from pathlib import Path

from ._common import APP_DATA_FOLDER, CONFIG_FILE


@lru_cache
def get_logit_config() -> dict:
"""Gets the logit configuration.

Example:
get_logit_config() -> {
files: {
"path/to/app.log": {
"last_rotation": 1677050919.7114477,
},
...
}
}
"""
with open(CONFIG_FILE) as f:
data = json.load(f)

return data


def set_logit_config(config: dict) -> None:
"""Sets the logit configuration."""

with open(CONFIG_FILE, "w") as f:
json.dump(config, f, indent=2)


def save_last_rotation_time(log_file_path: Path) -> None:
"""Saves the last rotation time for log file to AppData."""

config = get_logit_config()
abs_path = str(log_file_path.absolute())
config["files"][abs_path]["last_rotation"] = time.time()
set_logit_config(config)


def get_last_rotation_time(log_file_path: Path) -> int:
"""Gets the last rotation time for log file in AppData."""

config = get_logit_config()
abs_path = str(log_file_path.absolute())

if config["files"].get(abs_path) is None:
print("why is this happening")
config["files"][abs_path] = {"last_rotation": time.time()}
set_logit_config(config)
return config["files"][abs_path]["last_rotation"]


def _create_archive_logfile_name(log_file_path: Path) -> str:
"""Creates an archive logfile name."""
now = datetime.datetime.now()
archive_file_name = f"{now.date()}-archive-{log_file_path.name}"
return (APP_DATA_FOLDER / Path(archive_file_name)).absolute()


def move_log_file(log_file_path: Path) -> None:
"""Moves the log file path and creates an archive."""
shutil.move(log_file_path, _create_archive_logfile_name(log_file_path))
log_file_path.touch()
2 changes: 1 addition & 1 deletion logit/_enums.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enum import StrEnum, auto, Enum
import typing as _t
from enum import Enum, StrEnum, auto


class Level(StrEnum):
Expand Down
49 changes: 37 additions & 12 deletions logit/_logger.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import os
import pathlib as _p
import shutil
import time
import typing as _t

from . import _common
from ._data import get_last_rotation_time, move_log_file, save_last_rotation_time
from ._enums import Level
from ._time import parse_time_data
from .output import _output_builder, level, line_number
from .types_ import LogConfigDict
from . import _common

import typing as _t
import pathlib as _p
from .output import _output_builder, line_number, level


class Logger:
Expand All @@ -18,8 +23,10 @@ class Logger:
def __init__(self) -> None:
self.__level = Level.CLUTTER
self.rank = self.level.get_level_value()
self.log_file_path: _p.Path | str = "app.log"
self.log_file_path: _p.Path | str = _p.Path("app.log")
self.log_rotation_time: int | None = 10
self.format = {"msg-prefix": [level, line_number], "msg-suffix": []}
self._rotate_time()

@property
def level(self) -> Level:
Expand All @@ -30,8 +37,26 @@ def level(self, val: Level) -> None:
self.__level = val
self.rank = self.__level.get_level_value()

def _rotate_time(self) -> None:
"""Rotates log files based on time duration."""
if self.log_rotation_time is None:
return

last_rotation_time = get_last_rotation_time(self.log_file_path)

if time.time() - last_rotation_time > self.log_rotation_time:
move_log_file(self.log_file_path)
save_last_rotation_time(self.log_file_path)

def _output(self, msg: object) -> None:
"""Prints out log outputs to console."""
"""Prints out log outputs to console and log file."""
output = _output_builder(self.format, msg)

if not os.path.exists(self.log_file_path):
_p.Path(self.log_file_path).touch()

with open(self.log_file_path, "a") as f:
f.write(output + "\n")
print(_output_builder(self.format, msg))

def config_from_dict(self, log_config_dict: LogConfigDict) -> None:
Expand Down Expand Up @@ -65,7 +90,7 @@ def config(
log_file_path: The Location of the log file.

Returns:
A dictionary containing the releveant log config
A dictionary containing the relevant log config
"""
self.level = level
self.log_file_path = log_file_path
Expand All @@ -85,7 +110,7 @@ def clutter(self, msg: object = "") -> None:
self._output(msg)

def info(self, msg: object = "") -> None:
"""Clutter the terminal with temporary logs.
"""Log some information.

Arguments:
msg: A message to clutter the terminal with.
Expand All @@ -97,7 +122,7 @@ def info(self, msg: object = "") -> None:
self._output(msg)

def debug(self, msg: object = "") -> None:
"""Clutter the terminal with temporary logs.
"""Log some debug messages.

Arguments:
msg: A message to clutter the terminal with.
Expand All @@ -109,7 +134,7 @@ def debug(self, msg: object = "") -> None:
self._output(msg)

def warning(self, msg: object = "") -> None:
"""Clutter the terminal with temporary logs.
"""Warn user in logs.

Arguments:
msg: A message to clutter the terminal with.
Expand All @@ -122,7 +147,7 @@ def warning(self, msg: object = "") -> None:
self._output(msg)

def error(self, msg: object = "") -> None:
"""Clutter the terminal with temporary logs.
"""Mention presence of error in logs.

Arguments:
msg: A message to clutter the terminal with.
Expand Down
62 changes: 62 additions & 0 deletions logit/_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
_UNIT_MULTIPLIERS = {
"d": 24 * 60 * 60,
"w": 7 * 24 * 60 * 60,
"m": 30 * 24 * 60 * 60,
"y": 365 * 24 * 60 * 60,
}


def _premature_split_time_data(text: str) -> tuple[str, str]:
"""Prematurely splits the time data into
its constituent time period and unit (may not
be correct)."""

digit_index = 0
for char in text:
if char.isdigit():
digit_index += 1
else:
break

return text[:digit_index], text[digit_index:]


def _check_valid_time_syntax(text: str) -> bool:
"""Checks if the given text is valid."""

n_alpha = len(c for c in text if c.isalpha())
is_alnum = text.isalnum()
is_safe_split = not any(char.isdigit() for char in _premature_split_time_data()[1])

return (n_alpha == 1) and is_alnum and is_safe_split


def _split_time_data(text: str) -> tuple[int, str]:
"""Splits the given text into its constituent
time period and unit."""

quantity, unit = _premature_split_time_data()
return int(quantity), unit


def parse_time_data(text: str) -> int:
"""Parses time data from given text.

Arguments:
text: Text to parse data from.
Supports days, weeks, months and years.
day -> "d"
week -> "w"
month -> "m"
year -> "y"

Example:
parse_time_data("5d") -> 24 * 5 * 60 * 60
parse_time_data("3y") -> 24 * 365 * 60 * 60
"""

if not _check_valid_time_syntax(text):
raise ValueError(f"'{text}' is not a valid string literal for the time data.")

quantity, unit = _split_time_data(text)
return quantity * _UNIT_MULTIPLIERS[unit]
3 changes: 2 additions & 1 deletion logit/output.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import datetime
import inspect
import os
from .types_ import LogFormatDict

from . import _common
from .types_ import LogFormatDict


def local_time() -> str:
Expand Down