Compare commits

...

3 Commits

Author SHA1 Message Date
veclav talica
17287cfcb3 pager-based markdown portable browser 2024-02-24 19:15:37 +05:00
veclav talica
6a7a5f091c article listing in plaintext 2024-02-24 11:33:57 +05:00
veclav talica
fc14d99c92 exposed original markdown article files 2024-02-24 11:16:01 +05:00
7 changed files with 208 additions and 14 deletions

22
browse.sh Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
set +e
printf "%s" "Enter URL: "
read URL
articles=$(curl -s "$URL/articles.txt")
# list=''
# while IFS= read article; do
# list+="$article "
# done < <(printf '%s' "$articles")
while :
do
article=$(./tools/widgets/list_selector.py --desc="Select an article:" --result="line" -- $articles)
if [ -z "$article" ]; then
break
fi
curl -s "$URL/markdown/$article.md" | pager
done

View File

@ -37,9 +37,11 @@ done
./tools/feed_generator.py ./articles/ $URL > ./html/feed.xml
./tools/plaintext_article_listing_generator.py ./articles/ > ./html/articles.txt
mkdir -p "./html/markdown/"
for d in ./articles/*/; do
if [ -d "$d" ]; then
cp "$d/page.mmd" "./html/markdown/$(basename $d).mdd"
cp "$d/page.mmd" "./html/markdown/$(basename $d).md"
fi
done

View File

@ -1,4 +1,6 @@
import time, subprocess
from os import walk, path
import urllib.parse
def the_line_after_metadata(lines: []) -> int:
i = 0
@ -24,3 +26,18 @@ def parse_metadata(filepath: str) -> {}:
result["Last Edit"] = time.gmtime(int(subprocess.getoutput(r"stat -c %Y " + filepath)))
return result
def parse_article_directory(directory: str) -> {}:
articles = {}
for root, dirs, _ in walk(directory):
for d in dirs:
metadata = parse_metadata(path.abspath(root + '/' + d + "/page.mmd"))
article = urllib.parse.quote(d)
articles[article] = {
"metadata": metadata
}
break
return articles
def sort_titles_by_date(articles: {}) -> []:
return sorted(articles.keys(), key=lambda a: articles[a]["metadata"].get("Date", time.gmtime(0)), reverse=True)

View File

@ -1,11 +1,10 @@
#!/usr/bin/python3
from sys import argv, exit
from os import walk, path
from random import choice, seed
import time, urllib.parse
import time
from article_utils import parse_metadata
from article_utils import parse_article_directory, sort_titles_by_date
from page_shares import wrap_page, ADJECTIVES, MONTHS
if len(argv) <= 1:
@ -28,17 +27,9 @@ Personal blog of one {choice(ADJECTIVES)} Veclav Talica.
"""
artciles = {}
for root, dirs, _ in walk(argv[1]):
for d in dirs:
metadata = parse_metadata(path.abspath(root + '/' + d + "/page.mmd"))
article = urllib.parse.quote(d)
artciles[article] = {
"metadata": metadata
}
break
artciles = parse_article_directory(argv[1])
for title in sorted(artciles.keys(), key=lambda a: artciles[a]["metadata"].get("Date", time.gmtime(0)), reverse=True):
for title in sort_titles_by_date(artciles):
article = artciles[title]
metadata = article["metadata"]
page += (

View File

@ -0,0 +1,15 @@
#!/usr/bin/env python3
from sys import argv, exit
from article_utils import parse_article_directory, sort_titles_by_date
if len(argv) <= 1:
print("No directory was supplied")
exit(-1)
articles = parse_article_directory(argv[1])
result = '\n'.join(sort_titles_by_date(articles))
print(result)

95
tools/widgets/list_selector.py Executable file
View File

@ -0,0 +1,95 @@
#!/usr/bin/env python3
from sys import argv
import curses
from wrapper import widget_wrapper
list_starting_arg = 1
for i, arg in enumerate(argv[1:]):
if arg == '--':
if i + 2 == len(argv):
print("Empty list given")
exit(-1)
list_starting_arg = i + 2
break
else:
print("List starting -- wasn't given")
exit(-1)
desc_arg = ''
result_arg = 'index'
# todo: Generalize and simplify over descriptor object.
for arg in argv[1:]:
if arg.startswith('--'):
if arg == '--':
break
elif arg.startswith('--result='):
result_arg = arg[arg.find('=') + 1:]
if result_arg not in ['index', 'line']:
print("Invalid --result=")
exit(-1)
elif arg.startswith('--desc='):
desc_arg = arg[arg.find('=') + 1:]
else:
print("Unknown parameter ", arg)
exit(-1)
else:
print("Unknown parameter ", arg)
exit(-1)
current = 0
lines = argv[list_starting_arg:]
list_box = None
def init(screen):
global list_box
curses.start_color()
curses.curs_set(0)
y = 0
if desc_arg != '':
list_box = screen.subwin(y + 1, 0)
y += 1
def draw_list_box():
y = 0
list_box.border()
y += 1
for i, line in enumerate(lines):
list_box.addstr(y, 1, line, curses.A_REVERSE if i == current else curses.A_NORMAL)
y += 1
list_box.refresh()
def driver(screen):
global current
y = 0
if desc_arg != '':
screen.addstr(y, 0, desc_arg)
y += 1
draw_list_box()
key = screen.getch()
if key == curses.KEY_DOWN:
current = (current + 1) % len(lines)
elif key == curses.KEY_UP:
current = len(lines) - 1 if current == 0 else current - 1
elif key == curses.KEY_ENTER or key == 10 or key == 13:
if result_arg == 'index':
return str(current)
elif result_arg == 'line':
return lines[current]
screen.refresh()
if __name__ == "__main__":
print(widget_wrapper(init, driver))

52
tools/widgets/wrapper.py Normal file
View File

@ -0,0 +1,52 @@
import curses
import signal
import atexit
import os, sys
from sys import argv, exit
def handler(signum, frame):
curses.endwin()
exit(1)
# def exit_handler():
# curses.endwin()
init = None
driver = None
def curses_wrapper(screen):
curses.noecho()
curses.cbreak()
screen.keypad(True)
init(screen)
while True:
result = driver(screen)
if result != None:
return result
def widget_wrapper(p_init, p_driver):
signal.signal(signal.SIGINT, handler)
# atexit.register(exit_handler)
global init, driver
init = p_init
driver = p_driver
with open('/dev/tty', 'rb') as inf, open('/dev/tty', 'wb') as outf:
saved_stdin = os.dup(0)
saved_stdout = os.dup(1)
saved_stderr = os.dup(2)
os.dup2(inf.fileno(), 0)
os.dup2(outf.fileno(), 1)
os.dup2(outf.fileno(), 2)
result = curses.wrapper(curses_wrapper)
os.dup2(saved_stdin, 0)
os.dup2(saved_stdout, 1)
os.dup2(saved_stderr, 2)
return result