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/feed_generator.py ./articles/ $URL > ./html/feed.xml
./tools/plaintext_article_listing_generator.py ./articles/ > ./html/articles.txt
mkdir -p "./html/markdown/" mkdir -p "./html/markdown/"
for d in ./articles/*/; do for d in ./articles/*/; do
if [ -d "$d" ]; then if [ -d "$d" ]; then
cp "$d/page.mmd" "./html/markdown/$(basename $d).mdd" cp "$d/page.mmd" "./html/markdown/$(basename $d).md"
fi fi
done done

View File

@ -1,4 +1,6 @@
import time, subprocess import time, subprocess
from os import walk, path
import urllib.parse
def the_line_after_metadata(lines: []) -> int: def the_line_after_metadata(lines: []) -> int:
i = 0 i = 0
@ -24,3 +26,18 @@ def parse_metadata(filepath: str) -> {}:
result["Last Edit"] = time.gmtime(int(subprocess.getoutput(r"stat -c %Y " + filepath))) result["Last Edit"] = time.gmtime(int(subprocess.getoutput(r"stat -c %Y " + filepath)))
return result 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 #!/usr/bin/python3
from sys import argv, exit from sys import argv, exit
from os import walk, path
from random import choice, seed 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 from page_shares import wrap_page, ADJECTIVES, MONTHS
if len(argv) <= 1: if len(argv) <= 1:
@ -28,17 +27,9 @@ Personal blog of one {choice(ADJECTIVES)} Veclav Talica.
""" """
artciles = {} artciles = parse_article_directory(argv[1])
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
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] article = artciles[title]
metadata = article["metadata"] metadata = article["metadata"]
page += ( 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