Skip to content

Instantly share code, notes, and snippets.

@pratu16x7
Last active April 1, 2022 17:33
Show Gist options
  • Save pratu16x7/98ff6b94e827c3a9e63f093df7a6113c to your computer and use it in GitHub Desktop.
Save pratu16x7/98ff6b94e827c3a9e63f093df7a6113c to your computer and use it in GitHub Desktop.
"""
***TINY JOURNALLING APP***
be simple, easy to run, and migratable to any system
needs a daylife.md file somewhere, that is the source of all knowledge,
which has something a template to fill the day's journal entry with,
followed by some fun titles, one of which will be randomly chosen each day.
A sample daylife.md could look like this:
@template
Todays tasks:
- [ ] Wake up at 6
- [ ] _
- [ ] _
- [ ] Go to bed at 10
@titles
Keep Looking Up
Hakuna Matata
A New Day Has Come
Back from Cryostasis
Forth Eorlingas
Add the following fou lines to your bash profile to use as a command (run this: `vi ~/.bash_profile`):
export JOURNAL_ENTRIES_PATH="/home/pratu16x7/[index] daylifes"
export JOURNAL_TEMPLATE_PATH="/home/pratu16x7/daylife.md"
export JOURNAL_OPEN_COMMAND="open"
alias "journal"="python3 /<path>/<to>/<file>/journal.py"
And the reload bash_profile with this on the command line:
. ~/.bash_profile
The python `fire` module will have to be installed globally
Here's a gist of what it does:
- makes an entry inside a folder
- gives it a random title from the @titles list in daylife.md
- fills it with what you tell it to after the '@template' line in daylife.md (can be a list of tasks, sections ... anything)
Can be set inside a hugo folder, so that you can style the md pages as you wish with css and make a site
- [ ] Handle KeyError: 'JOURNAL_DAYLIFE_PATH' in case not set in env
"""
import os
import random
import subprocess
import random
from datetime import datetime
from pathlib import Path
from typing import TextIO
from lxml import etree
import fire
ENTRIES_PATH = os.environ['JOURNAL_ENTRIES_PATH'] # "/Users/pratu/Dropbox/sheets/[index] daylifes"
MONTH_DIRNAME_FORMAT = "%b_%Y"
ENTRY_DIRNAME_FORMAT = "%-d_%a_%b_%Y" # Not adding any more info to filename as of yet
ENTRY_BASENAME = "index" # Hugo's file format
ENTRY_FILE_EXT = ".md"
DAYLIFE_PATH = os.environ['JOURNAL_DAYLIFE_PATH'] # "/Users/prateekshasingh/Dropbox/I Mindful Consciousness.svg"
DEFAULT_ENCODING = "utf-8" # utf-8-sig for devnagri script and things?
OPEN_COMMAND = os.environ['JOURNAL_OPEN_COMMAND']
# Humanisers
HUMAN_DATE_FORMAT = '%-d %B, %Y'
TITLES_LIST_ID = "Titles"
DAY_TASKS_LIST_ID = "Day tasks"
def write(title: str=""):
"""
make a new entry for today if not present
open today's entry
"""
filepath = get_or_make_entry(datetime.today(), title)
cat_random_entry()
subprocess.call((OPEN_COMMAND, filepath))
def get_or_make_entry(date: datetime, title: str):
"""
Makes new journal entry for given date: A folder, and a file, with bootstrapped content
If folder exists, do nothing. Return path either ways.
:param date: date for which entry is to be made
:param title: optional, title that will set in H1 on entry markdown top of file
:return: (str) file path of the journal entry
"""
entry_dir_path = get_entry_dir_path(date)
if not entry_dir_path.exists():
entry_dir_path.mkdir(parents=True)
entry_file_path = (entry_dir_path / (date.strftime(ENTRY_DIRNAME_FORMAT) + ENTRY_FILE_EXT))
if not entry_file_path.exists():
print("making the entry file", str(entry_file_path))
with entry_file_path.open('w', encoding=DEFAULT_ENCODING) as f:
write_base_entry_as_per_daylife(f, title)
return str(entry_file_path)
def cat_random_entry():
root = ENTRIES_PATH
all_entries = []
for cur_path, directories, files in os.walk(root):
for file_name in files:
if ".md" in file_name:
all_entries.append(cur_path + "/" + file_name)
if all_entries:
chosen_entry = random.choice(all_entries)
path_split = os.path.split(chosen_entry)
print(os.path.split(path_split[0])[1], path_split[1])
with Path(chosen_entry).open('r', encoding=DEFAULT_ENCODING) as f:
print(f.read())
else:
print("No entries yet here, make your first one!")
def write_base_entry_as_per_daylife(entry_file: TextIO, title: str):
root = etree.parse(DAYLIFE_PATH)
# root.findall('.//*[@id = "Titles"]')
title = title or random.choice(get_list_items(root, TITLES_LIST_ID))
tasks = ['- [ ] ' + task for task in get_list_items(root, DAY_TASKS_LIST_ID)]
todays_entry = f"# Today, {title}" + '\n'*7 + "\n".join(tasks)
entry_file.write(todays_entry)
def get_title():
pass
def get_entry_content():
pass
def get_list_items(root, list_id: str):
ns = {'d': 'http://www.w3.org/2000/svg'} # https://stackoverflow.com/questions/37434549/python-elementtree-findall-not-working
well_behaved_tspans = root.findall(f'.//*[@id = "{list_id}"]/d:g/d:text', ns)
return [''.join(tspan.itertext()) for tspan in well_behaved_tspans]
def get_entry_dir_path(date: datetime):
return Path(ENTRIES_PATH + "/" + date.strftime(MONTH_DIRNAME_FORMAT))
def del_expired_docs():
"""
TODO: Will have to show the git diff of the paths of docs, so that
helps if I lock the vvimp docs and keep.
Some folders and files should be off limits.
"""
pass
# from numbers_parser import Document # Haha, I globally installed it
# doc = Document("Things.numbers")
# sheets = doc.sheets()
#
# tables = sheets["my stuff"].tables()
# # tables[0].rows()[0]
# stuff_table = tables[0]
# print("Cell A1 contains", stuff_table.cell(0, 1).value)
# TEMPLATE_PATH = os.environ['JOURNAL_TEMPLATE_PATH'] # "/Users/prateekshasingh/Dropbox/daylife.md"
# TEMPLATE_SEPARATOR = "@template\n"
# FUN_TITLES_SEPARATOR = "@titles\n"
#
#
# def write_base_entry_as_per_template(entry_file: TextIO, title: str):
# with get_template_path().open('r', encoding=DEFAULT_ENCODING) as template_file:
# template_content, titles = parse_template_file(template_file)
# title = title or random.choice(titles)
# entry_file.write(template_content.format(title=title))
#
#
# def parse_template_file(template_file: TextIO):
# content = template_file.read()
# template_gen = content.split(TEMPLATE_SEPARATOR)[-1]
# template, titles_gen = template_gen.split(FUN_TITLES_SEPARATOR)
# return template, titles_gen.strip().split('\n')
if __name__ == "__main__":
fire.Fire({
"write": write
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment