elog -> evlog
This commit is contained in:
parent
154280cec9
commit
8e23b695bb
16
README.md
16
README.md
@ -1,31 +1,31 @@
|
||||
# daily-event-logger
|
||||
# evlog
|
||||
|
||||
This is a little utility I use for logging my daily activities and events. It is written in Python.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
python3 -m pip install daily-event-logger
|
||||
pipx install evlog
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To change the directory where elogs are stored, set a shell environment variable ELOG_DIR. To make this change permament, set the following in your shell configuration:
|
||||
To change the directory where evlogs are stored, set a shell environment variable EVLOG_DIR. To make this change permament, set the following in your shell configuration:
|
||||
|
||||
```bash
|
||||
export ELOG_DIR="/path/to/elog/dir"
|
||||
export EVLOG_DIR="/path/to/evlog/dir"
|
||||
```
|
||||
|
||||
Otherwise, the default elog directory will be `~/elogs`.
|
||||
Otherwise, the default evlog directory will be `~/evlogs`.
|
||||
|
||||
To get started, add your first elog entry! This will create a JSON file under your elog directory for the day and ensure the elog directory exists. E.g.:
|
||||
To get started, add your first evlog entry! This will create a JSON file under your evlog directory for the day and ensure the evlog directory exists. E.g.:
|
||||
|
||||
```bash
|
||||
elog add -m "Started new elog. Yay!"
|
||||
evlog add -m "Started new evlog. Yay!"
|
||||
```
|
||||
|
||||
```bash
|
||||
usage: elog [-h] [-v] {add,edit,rm,ls,lsfiles,search} ...
|
||||
usage: evlog [-h] [-v] {add,edit,rm,ls,lsfiles,search} ...
|
||||
|
||||
positional arguments:
|
||||
{add,edit,rm,ls,lsfiles,search}
|
||||
|
174
evlog.py
174
evlog.py
@ -17,50 +17,50 @@ from rich.traceback import install
|
||||
|
||||
install(show_locals=True)
|
||||
|
||||
VERSION = "0.1.5"
|
||||
VERSION = "0.1.6"
|
||||
|
||||
default_date = dt.date.today().strftime("%Y-%m-%d")
|
||||
ELOG_DIR = os.getenv("ELOG_DIR")
|
||||
if ELOG_DIR is None:
|
||||
elog_dir = Path("~/elogs").expanduser()
|
||||
EVLOG_DIR = os.getenv("EVLOG_DIR")
|
||||
if EVLOG_DIR is None:
|
||||
evlog_dir = Path("~/evlogs").expanduser()
|
||||
else:
|
||||
elog_dir = Path(ELOG_DIR)
|
||||
evlog_dir = Path(EVLOG_DIR)
|
||||
|
||||
|
||||
def elog_init(filename):
|
||||
"""Initialize elog file and directory, if necessary.
|
||||
def evlog_init(filename):
|
||||
"""Initialize evlog file and directory, if necessary.
|
||||
|
||||
elog_dir is taken from the current shell's ELOG_DIR environment variable, or else it defaults to
|
||||
~/elogs.
|
||||
evlog_dir is taken from the current shell's EVLOG_DIR environment variable, or else it defaults to
|
||||
~/evlogs.
|
||||
"""
|
||||
elog_file = elog_dir.joinpath(filename).with_suffix(".json")
|
||||
evlog_file = evlog_dir.joinpath(filename).with_suffix(".json")
|
||||
|
||||
elog_dir.mkdir(exist_ok=True)
|
||||
elog_file.touch()
|
||||
evlog_dir.mkdir(exist_ok=True)
|
||||
evlog_file.touch()
|
||||
|
||||
json_array = []
|
||||
|
||||
with open(elog_file, "w") as ef:
|
||||
with open(evlog_file, "w") as ef:
|
||||
json.dump(json_array, ef)
|
||||
|
||||
|
||||
def elog_list(args):
|
||||
"""List elog entries.
|
||||
def evlog_list(args):
|
||||
"""List evlog entries.
|
||||
|
||||
Lists elog entries for provided timestamp range and/or elog file
|
||||
Lists evlog entries for provided timestamp range and/or evlog file
|
||||
"""
|
||||
if args.file:
|
||||
selected_elog_file = elog_dir.joinpath(args.file)
|
||||
selected_evlog_file = evlog_dir.joinpath(args.file)
|
||||
else:
|
||||
selected_elog_file = elog_dir.joinpath(default_date + "_elog").with_suffix(
|
||||
selected_evlog_file = evlog_dir.joinpath(default_date + "_evlog").with_suffix(
|
||||
".json"
|
||||
)
|
||||
|
||||
if not selected_elog_file.exists():
|
||||
exit("elog file %s not found. Are you sure it exists?" % selected_elog_file)
|
||||
if not selected_evlog_file.exists():
|
||||
exit("evlog file %s not found. Are you sure it exists?" % selected_evlog_file)
|
||||
|
||||
if not args.start:
|
||||
ts_from = selected_elog_file.stem[:10] + " 00:00:00"
|
||||
ts_from = selected_evlog_file.stem[:10] + " 00:00:00"
|
||||
else:
|
||||
dt.datetime.strptime(args.start, "%Y-%m-%d %H:%M:%S")
|
||||
ts_from = args.start
|
||||
@ -71,7 +71,7 @@ def elog_list(args):
|
||||
dt.datetime.strptime(args.end, "%Y-%m-%d %H:%M:%S")
|
||||
ts_to = args.end
|
||||
|
||||
with open(selected_elog_file, "r") as ef:
|
||||
with open(selected_evlog_file, "r") as ef:
|
||||
json_data = json.load(ef)
|
||||
|
||||
table = Table(style="#5f00ff", header_style="bold", box=box.ROUNDED)
|
||||
@ -87,12 +87,12 @@ def elog_list(args):
|
||||
console.print(table)
|
||||
|
||||
|
||||
def elog_list_files(args):
|
||||
"""List all elog files.
|
||||
def evlog_list_files(args):
|
||||
"""List all evlog files.
|
||||
|
||||
Lists all elog files currently present in elog directory.
|
||||
Lists all evlog files currently present in evlog directory.
|
||||
"""
|
||||
for file in sorted(elog_dir.iterdir()):
|
||||
for file in sorted(evlog_dir.iterdir()):
|
||||
if file.is_file():
|
||||
if args.absolute:
|
||||
print(file)
|
||||
@ -100,18 +100,18 @@ def elog_list_files(args):
|
||||
print(file.name)
|
||||
|
||||
|
||||
def elog_search(args):
|
||||
def evlog_search(args):
|
||||
"""Search for a string.
|
||||
|
||||
Searches all elog files and prints found matches.
|
||||
Searches all evlog files and prints found matches.
|
||||
"""
|
||||
found_entries = list()
|
||||
elog_list = [file.name for file in elog_dir.iterdir()]
|
||||
evlog_list = [file.name for file in evlog_dir.iterdir()]
|
||||
|
||||
console = Console()
|
||||
|
||||
for file in elog_list:
|
||||
with open(elog_dir.joinpath(file), "r") as ef:
|
||||
for file in evlog_list:
|
||||
with open(evlog_dir.joinpath(file), "r") as ef:
|
||||
json_data = json.load(ef)
|
||||
for entry in json_data:
|
||||
if args.word in entry["message"]:
|
||||
@ -126,14 +126,14 @@ def elog_search(args):
|
||||
)
|
||||
else:
|
||||
console.print(
|
||||
"[bold yellow]{0}[/bold yellow] was not found in any of the elog files".format(
|
||||
"[bold yellow]{0}[/bold yellow] was not found in any of the evlog files".format(
|
||||
args.word
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def elog_sort(file):
|
||||
"""Sort elog entries.
|
||||
def evlog_sort(file):
|
||||
"""Sort evlog entries.
|
||||
|
||||
Entries are sorted by provided timestamp.
|
||||
"""
|
||||
@ -154,7 +154,7 @@ def validate_json(file):
|
||||
|
||||
Call jsonschema.validate on `file`.
|
||||
"""
|
||||
elog_schema = {
|
||||
evlog_schema = {
|
||||
"type": "array",
|
||||
"properties": {
|
||||
"timestamp": {"type": "string"},
|
||||
@ -166,17 +166,17 @@ def validate_json(file):
|
||||
json_data = json.load(ef)
|
||||
|
||||
try:
|
||||
validate(instance=json_data, schema=elog_schema)
|
||||
validate(instance=json_data, schema=evlog_schema)
|
||||
except jsonschema.ValidationError as err:
|
||||
print("Invalid JSON detected on %s" % file)
|
||||
print(err)
|
||||
|
||||
|
||||
def elog_append(args):
|
||||
def evlog_append(args):
|
||||
"""
|
||||
Append a new elog entry to the elog file.
|
||||
Append a new evlog entry to the evlog file.
|
||||
|
||||
Use elog file indicated by provided timestamp, or else use the elog file for current day.
|
||||
Use evlog file indicated by provided timestamp, or else use the evlog file for current day.
|
||||
"""
|
||||
if not args.timestamp:
|
||||
ts = dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
@ -184,64 +184,68 @@ def elog_append(args):
|
||||
dt.datetime.strptime(args.timestamp, "%Y-%m-%d %H:%M:%S")
|
||||
ts = args.timestamp
|
||||
|
||||
elog_filename = ts[:10] + "_elog"
|
||||
elog_file = elog_dir.joinpath(elog_filename).with_suffix(".json")
|
||||
evlog_filename = ts[:10] + "_evlog"
|
||||
evlog_file = evlog_dir.joinpath(evlog_filename).with_suffix(".json")
|
||||
|
||||
if not elog_file.exists():
|
||||
elog_init(elog_file)
|
||||
if not evlog_file.exists():
|
||||
evlog_init(evlog_file)
|
||||
|
||||
entry = {"timestamp": ts, "message": args.message}
|
||||
|
||||
with open(elog_file, "r+") as ef:
|
||||
with open(evlog_file, "r+") as ef:
|
||||
json_data = json.load(ef)
|
||||
json_data.append(entry)
|
||||
ef.seek(0)
|
||||
json.dump(json_data, ef, indent=4)
|
||||
|
||||
elog_sort(elog_file)
|
||||
validate_json(elog_file)
|
||||
evlog_sort(evlog_file)
|
||||
validate_json(evlog_file)
|
||||
|
||||
|
||||
def elog_edit(args):
|
||||
"""Edit elog entry at provided index argument."""
|
||||
def evlog_edit(args):
|
||||
"""Edit evlog entry at provided index argument."""
|
||||
if args.file:
|
||||
elog_file = elog_dir.joinpath(args.file)
|
||||
evlog_file = evlog_dir.joinpath(args.file)
|
||||
else:
|
||||
elog_file = elog_dir.joinpath(default_date + "_elog").with_suffix(".json")
|
||||
evlog_file = evlog_dir.joinpath(default_date + "_evlog").with_suffix(".json")
|
||||
|
||||
if not elog_file.exists():
|
||||
exit("elog file not found. Please run 'elog append' to start a new elog file.")
|
||||
if not evlog_file.exists():
|
||||
exit(
|
||||
"evlog file not found. Please run 'evlog append' to start a new evlog file."
|
||||
)
|
||||
|
||||
with open(elog_file, "r+") as ef:
|
||||
with open(evlog_file, "r+") as ef:
|
||||
json_data = json.load(ef)
|
||||
json_data[args.index]["message"] = args.message
|
||||
ef.seek(0)
|
||||
json.dump(json_data, ef, indent=4)
|
||||
|
||||
validate_json(elog_file)
|
||||
validate_json(evlog_file)
|
||||
|
||||
|
||||
def elog_remove(args):
|
||||
"""Remove an elog entry at provided index argument."""
|
||||
def evlog_remove(args):
|
||||
"""Remove an evlog entry at provided index argument."""
|
||||
if args.file:
|
||||
elog_file = elog_dir.joinpath(args.file)
|
||||
evlog_file = evlog_dir.joinpath(args.file)
|
||||
else:
|
||||
elog_file = elog_dir.joinpath(default_date + "_elog").with_suffix(".json")
|
||||
evlog_file = evlog_dir.joinpath(default_date + "_evlog").with_suffix(".json")
|
||||
|
||||
if not elog_file.exists():
|
||||
exit("elog file not found. Please run 'elog append' to start a new elog file.")
|
||||
if not evlog_file.exists():
|
||||
exit(
|
||||
"evlog file not found. Please run 'evlog append' to start a new evlog file."
|
||||
)
|
||||
|
||||
with open(elog_file, "r") as ef:
|
||||
with open(evlog_file, "r") as ef:
|
||||
json_data = json.load(ef)
|
||||
json_data.pop(args.index)
|
||||
|
||||
with open(elog_file, "w") as ef:
|
||||
with open(evlog_file, "w") as ef:
|
||||
json.dump(json_data, ef, indent=4)
|
||||
|
||||
validate_json(elog_file)
|
||||
validate_json(evlog_file)
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(prog="elog")
|
||||
parser = argparse.ArgumentParser(prog="evlog")
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--version",
|
||||
@ -251,14 +255,14 @@ parser.add_argument(
|
||||
)
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
add_parser = subparsers.add_parser("add", description="Add an elog entry")
|
||||
add_parser = subparsers.add_parser("add", description="Add an evlog entry")
|
||||
add_parser.add_argument(
|
||||
"-t",
|
||||
"--timestamp",
|
||||
required=False,
|
||||
type=str,
|
||||
action="store",
|
||||
help="Timestamp for elog entry: str",
|
||||
help="Timestamp for evlog entry: str",
|
||||
)
|
||||
add_parser.add_argument(
|
||||
"-m",
|
||||
@ -266,18 +270,18 @@ add_parser.add_argument(
|
||||
required=True,
|
||||
type=str,
|
||||
action="store",
|
||||
help="Message for elog entry: str",
|
||||
help="Message for evlog entry: str",
|
||||
)
|
||||
add_parser.set_defaults(func=elog_append)
|
||||
add_parser.set_defaults(func=evlog_append)
|
||||
|
||||
edit_parser = subparsers.add_parser("edit", description="Edit an elog entry")
|
||||
edit_parser = subparsers.add_parser("edit", description="Edit an evlog entry")
|
||||
edit_parser.add_argument(
|
||||
"-i",
|
||||
"--index",
|
||||
required=True,
|
||||
type=int,
|
||||
action="store",
|
||||
help="Index of elog entry: int",
|
||||
help="Index of evlog entry: int",
|
||||
)
|
||||
edit_parser.add_argument(
|
||||
"-m",
|
||||
@ -285,7 +289,7 @@ edit_parser.add_argument(
|
||||
required=True,
|
||||
type=str,
|
||||
action="store",
|
||||
help="New message for elog entry: str",
|
||||
help="New message for evlog entry: str",
|
||||
)
|
||||
edit_parser.add_argument(
|
||||
"-f",
|
||||
@ -293,18 +297,18 @@ edit_parser.add_argument(
|
||||
required=False,
|
||||
type=str,
|
||||
action="store",
|
||||
help="elog file to edit. Ex: 2022-10-02_elog.json",
|
||||
help="evlog file to edit. Ex: 2022-10-02_evlog.json",
|
||||
)
|
||||
edit_parser.set_defaults(func=elog_edit)
|
||||
edit_parser.set_defaults(func=evlog_edit)
|
||||
|
||||
rm_parser = subparsers.add_parser("rm", description="Remove an elog entry")
|
||||
rm_parser = subparsers.add_parser("rm", description="Remove an evlog entry")
|
||||
rm_parser.add_argument(
|
||||
"-i",
|
||||
"--index",
|
||||
required=True,
|
||||
type=int,
|
||||
action="store",
|
||||
help="Index of elog entry: int",
|
||||
help="Index of evlog entry: int",
|
||||
)
|
||||
rm_parser.add_argument(
|
||||
"-f",
|
||||
@ -312,11 +316,11 @@ rm_parser.add_argument(
|
||||
required=False,
|
||||
type=str,
|
||||
action="store",
|
||||
help="elog file to remove from. Ex: 2022-10-02_elog.json",
|
||||
help="evlog file to remove from. Ex: 2022-10-02_evlog.json",
|
||||
)
|
||||
rm_parser.set_defaults(func=elog_remove)
|
||||
rm_parser.set_defaults(func=evlog_remove)
|
||||
|
||||
ls_parser = subparsers.add_parser("ls", description="List elog entries")
|
||||
ls_parser = subparsers.add_parser("ls", description="List evlog entries")
|
||||
ls_parser.add_argument(
|
||||
"-s",
|
||||
"--start",
|
||||
@ -341,27 +345,27 @@ ls_parser.add_argument(
|
||||
required=False,
|
||||
type=str,
|
||||
action="store",
|
||||
help="elog file to view. Ex: 2022-10-02_elog.json",
|
||||
help="evlog file to view. Ex: 2022-10-02_evlog.json",
|
||||
)
|
||||
ls_parser.set_defaults(func=elog_list)
|
||||
ls_parser.set_defaults(func=evlog_list)
|
||||
|
||||
ls_files_parser = subparsers.add_parser("lsfiles", description="List all elog files")
|
||||
ls_files_parser = subparsers.add_parser("lsfiles", description="List all evlog files")
|
||||
ls_files_parser.add_argument(
|
||||
"-a",
|
||||
"--absolute",
|
||||
required=False,
|
||||
action="store_true",
|
||||
help="List the absolute paths of the elog files",
|
||||
help="List the absolute paths of the evlog files",
|
||||
)
|
||||
ls_files_parser.set_defaults(func=elog_list_files)
|
||||
ls_files_parser.set_defaults(func=evlog_list_files)
|
||||
|
||||
search_parser = subparsers.add_parser(
|
||||
"search", description="Search for keywords in elog files"
|
||||
"search", description="Search for keywords in evlog files"
|
||||
)
|
||||
search_parser.add_argument(
|
||||
"-w", "--word", required=True, type=str, action="store", help="Word to search for"
|
||||
)
|
||||
search_parser.set_defaults(func=elog_search)
|
||||
search_parser.set_defaults(func=evlog_search)
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "evlog"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
authors = [
|
||||
{ name="Jeffrey Serio", email="hyperreal@moonshadow.dev" },
|
||||
]
|
||||
@ -18,8 +18,8 @@ dependencies = ["jsonschema>=4.17.0", "rich>=12.6.0"]
|
||||
elog = "evlog:main"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://git.hyperreal.coffee/hyperreal/daily-event-logger"
|
||||
Issues = "https://git.hyperreal.coffee/hyperreal/daily-event-logger/issues"
|
||||
Homepage = "https://git.hyperreal.coffee/hyperreal/evlog"
|
||||
Issues = "https://git.hyperreal.coffee/hyperreal/evlog/issues"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user