Rewrite in Bash
This commit is contained in:
parent
d3b46e19a6
commit
500919c811
5 changed files with 63 additions and 153 deletions
59
histd.sh
Executable file
59
histd.sh
Executable file
|
@ -0,0 +1,59 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Histd: how I spent this day.
|
||||||
|
# A simple but useful personal diary CLI utility.
|
||||||
|
|
||||||
|
function edit_note {
|
||||||
|
# Creates the required directories and opens a text editor
|
||||||
|
# so that the user can describe the day.
|
||||||
|
|
||||||
|
# Create dirs (base_dir/year/month)
|
||||||
|
WORKDIR="$BASE_DIR/$(date +%Y)/$(date +%m)"
|
||||||
|
mkdir -p $WORKDIR
|
||||||
|
|
||||||
|
# Generate file name
|
||||||
|
PATH_TO_FILE="$WORKDIR/$(date +%d).md"
|
||||||
|
|
||||||
|
# Check editor
|
||||||
|
if [[ $EDITOR == "" ]]; then
|
||||||
|
echo EDITOR is undefined
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Open editor
|
||||||
|
cd $BASE_DIR
|
||||||
|
$EDITOR $PATH_TO_FILE
|
||||||
|
cd -
|
||||||
|
}
|
||||||
|
|
||||||
|
function backup {
|
||||||
|
# Creates an archive with all notes
|
||||||
|
ARCHIVE_PATH=~/histd-$(date +%F).tar.xz
|
||||||
|
cd $BASE_DIR
|
||||||
|
tar cfJ $ARCHIVE_PATH ../histd
|
||||||
|
cd -
|
||||||
|
|
||||||
|
echo Saved to $ARCHIVE_PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
function merge {
|
||||||
|
# This function concatenates all files and prefixes each with the filename.
|
||||||
|
# The result will be printed to stdout.
|
||||||
|
find $BASE_DIR -type f -name "*.md" -exec echo "# {}" \; -exec cat "{}" \; -exec echo \;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Prepare the environment
|
||||||
|
BASE_DIR=~/.local/share/histd
|
||||||
|
mkdir -p $BASE_DIR
|
||||||
|
|
||||||
|
# Parse commands
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
edit_note
|
||||||
|
elif [[ $1 == "backup" ]]; then
|
||||||
|
backup
|
||||||
|
elif [[ $1 == "merge" ]]; then
|
||||||
|
merge
|
||||||
|
else
|
||||||
|
echo Command not found
|
||||||
|
fi
|
118
histd/cli.py
118
histd/cli.py
|
@ -1,118 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
"""
|
|
||||||
Histd: how I spent this day.
|
|
||||||
A simple but useful personal diary CLI utility.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from datetime import date
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
"""
|
|
||||||
Main function, run first.
|
|
||||||
Prepares environment and parses commands.
|
|
||||||
"""
|
|
||||||
base_dir = get_base_dir()
|
|
||||||
today = date.today()
|
|
||||||
|
|
||||||
if len(sys.argv) == 1:
|
|
||||||
edit_note(base_dir, today)
|
|
||||||
elif sys.argv[1] == "backup":
|
|
||||||
backup(base_dir, today)
|
|
||||||
elif sys.argv[1] == "merge":
|
|
||||||
merge(base_dir)
|
|
||||||
else:
|
|
||||||
print('Command not found')
|
|
||||||
|
|
||||||
|
|
||||||
def get_base_dir() -> str:
|
|
||||||
"""
|
|
||||||
Creates the directories necessary for the program
|
|
||||||
to work, if they are not present.
|
|
||||||
|
|
||||||
Returns the path to the directory where data can be stored.
|
|
||||||
"""
|
|
||||||
base_dir = os.path.expanduser('~/.local/share/histd')
|
|
||||||
os.makedirs(base_dir, exist_ok=True)
|
|
||||||
return base_dir
|
|
||||||
|
|
||||||
|
|
||||||
def edit_note(base_dir: str, note_date: date) -> None:
|
|
||||||
"""
|
|
||||||
Creates the required directories and opens a text editor
|
|
||||||
so that the user can describe the day.
|
|
||||||
"""
|
|
||||||
# Create dirs (base_dir/year/month)
|
|
||||||
year = str(note_date.year)
|
|
||||||
month = f'{note_date.month:02}'
|
|
||||||
workdir = os.path.join(base_dir, year, month)
|
|
||||||
os.makedirs(workdir, exist_ok=True)
|
|
||||||
|
|
||||||
# Open file (base_dir/year/month/day.md) with default editor
|
|
||||||
filename = f'{note_date.day:02}.md'
|
|
||||||
path_to_file = os.path.join(workdir, filename)
|
|
||||||
editor = os.environ.get('EDITOR', 'nano')
|
|
||||||
try:
|
|
||||||
subprocess.run([editor, path_to_file], check=True, cwd=base_dir)
|
|
||||||
except FileNotFoundError:
|
|
||||||
print("Error: I can't find your text editor")
|
|
||||||
print("Make sure the 'EDITOR' environment variable is set correctly")
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
print("Your editor returned non-zero exit code")
|
|
||||||
|
|
||||||
|
|
||||||
def backup(base_dir: str, current_date: date) -> None:
|
|
||||||
"""
|
|
||||||
Creates an archive with all notes
|
|
||||||
"""
|
|
||||||
date_str = f'{current_date.year}-{current_date.month:02}-{current_date.day:02}'
|
|
||||||
archive_path = os.path.expanduser(f"~/histd-{date_str}.tar.xz")
|
|
||||||
cmd = ["tar", "cfJ", archive_path, "."]
|
|
||||||
try:
|
|
||||||
subprocess.run(cmd, check=True, cwd=base_dir)
|
|
||||||
print(f'Saved to {archive_path}')
|
|
||||||
except FileNotFoundError:
|
|
||||||
print("Error: I can't find tar program")
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
print("Archiver returned non-zero exit code")
|
|
||||||
|
|
||||||
|
|
||||||
def merge(base_dir: str) -> None:
|
|
||||||
"""
|
|
||||||
This function concatenates all files and prefixes each with the filename.
|
|
||||||
The result will be printed to stdout.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def read_files(path: str) -> str:
|
|
||||||
"""
|
|
||||||
Recursive function to read all files in a directory
|
|
||||||
"""
|
|
||||||
strings = []
|
|
||||||
contents = os.listdir(path)
|
|
||||||
|
|
||||||
for entry in contents:
|
|
||||||
entry_path = os.path.join(path, entry)
|
|
||||||
|
|
||||||
# It's a directory
|
|
||||||
if os.path.isdir(entry_path):
|
|
||||||
# Read all files in this directory
|
|
||||||
res = read_files(entry_path)
|
|
||||||
strings.append(res)
|
|
||||||
# It's a file
|
|
||||||
else:
|
|
||||||
with open(entry_path, 'r', encoding='utf-8') as note:
|
|
||||||
strings.append(f'## {entry_path}')
|
|
||||||
strings.append(note.read())
|
|
||||||
|
|
||||||
return '\n\n'.join(strings)
|
|
||||||
|
|
||||||
res = read_files(base_dir)
|
|
||||||
print(res)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,27 +0,0 @@
|
||||||
[project]
|
|
||||||
name = "histd"
|
|
||||||
version = "0.0.4"
|
|
||||||
authors = [
|
|
||||||
{ name="Ivan Reshetnikov", email="ordinarydev@protonmail.com" },
|
|
||||||
]
|
|
||||||
description = "A simple but useful personal diary application"
|
|
||||||
readme = "readme.md"
|
|
||||||
requires-python = ">=3.7"
|
|
||||||
|
|
||||||
classifiers = [
|
|
||||||
"Programming Language :: Python :: 3",
|
|
||||||
"License :: OSI Approved :: MIT License",
|
|
||||||
"Operating System :: POSIX :: Linux",
|
|
||||||
"Topic :: Utilities",
|
|
||||||
]
|
|
||||||
|
|
||||||
[project.urls]
|
|
||||||
"Homepage" = "https://github.com/ordinary-dev/histd"
|
|
||||||
"Bug Tracker" = "https://github.com/ordinary-dev/histd/issues"
|
|
||||||
|
|
||||||
[project.scripts]
|
|
||||||
histd = "histd.cli:main"
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["setuptools"]
|
|
||||||
build-backend = "setuptools.build_meta"
|
|
12
readme.md
12
readme.md
|
@ -15,24 +15,20 @@ tree ~/.local/share/histd
|
||||||
# └── 19.md
|
# └── 19.md
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installation
|
|
||||||
```bash
|
|
||||||
pip install histd
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
```bash
|
```bash
|
||||||
histd
|
chmod +x histd.sh
|
||||||
|
./histd.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
## Backup
|
## Backup
|
||||||
To create an archive of all notes, run the following command:
|
To create an archive of all notes, run the following command:
|
||||||
```bash
|
```bash
|
||||||
histd backup
|
./histd.sh backup
|
||||||
```
|
```
|
||||||
|
|
||||||
## Merge all notes
|
## Merge all notes
|
||||||
This command concatenates all files and prefixes each with the filename.
|
This command concatenates all files and prefixes each with the filename.
|
||||||
```bash
|
```bash
|
||||||
histd merge
|
./histd.sh merge
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in a new issue