Compare commits

..

30 Commits

Author SHA1 Message Date
0dd69c3fe3
fix requirements rebase errror 2024-01-02 18:29:02 +00:00
95003803eb
run as non priveleged user in docker 2024-01-02 18:28:35 +00:00
fddbbf4c50
use readme.md instead of index.md 2024-01-02 18:24:33 +00:00
8b4765e9fb
remove commit gronk commit information for now 2024-01-02 18:24:33 +00:00
d83611f12a
dockerize 2024-01-02 18:24:27 +00:00
1eca81cd1d
correct env variable names, jinja template loader 2024-01-02 18:23:26 +00:00
91a57aa8c9
check if pandoc-server fails to start 2024-01-02 18:23:26 +00:00
3a9cc4c0f8
measure and print how long notes generation takes 2024-01-02 18:23:26 +00:00
44bea9c982
check for pandoc start instead of wait 2024-01-02 18:23:26 +00:00
5c8e1e5253
don't include .git directories in index listings 2024-01-02 18:23:26 +00:00
451bc567e2
update readme 2024-01-02 18:23:26 +00:00
80dce5d4ed
start pandoc web server inside python process 2024-01-02 18:23:26 +00:00
48f64bf3d4
render index pages properly 2024-01-02 18:23:26 +00:00
4e5bd41953
generate permalink page 2024-01-02 18:23:26 +00:00
de3d758005
render articles with jinja 2024-01-02 18:23:25 +00:00
444c777135
clean up code 2024-01-02 18:23:25 +00:00
9c6b2247a7
update environment variable names 2024-01-02 18:23:25 +00:00
09334831f7
formatting 2024-01-02 18:23:25 +00:00
af5bef0125
update requirements 2024-01-02 18:23:18 +00:00
b4aa431f4d
update templates 2024-01-02 18:22:57 +00:00
49a215a587
make gronk.py single file 2024-01-02 18:22:57 +00:00
0a0bd542fc
mark script as executable once copied 2024-01-02 18:22:56 +00:00
36f40f3269
update gronk_add_uuid.py 2024-01-02 18:22:56 +00:00
b61f1ba3b2
minor readme updates 2024-01-02 18:22:56 +00:00
bef8aeda52
rename to gronk 2024-01-02 18:22:56 +00:00
5bb40a57d1
add tag browser generation 2024-01-02 18:22:56 +00:00
29529cfd6a
begin rewrite 2024-01-02 18:22:15 +00:00
8bd9173847
update makefile to install python packages, apply executable perms to script after install 2023-10-15 16:07:10 +01:00
dc4560c232
update readme to include other dependecies 2023-10-15 16:03:33 +01:00
da0d9db113
downgrade pyyaml 5.4.1 -> 5.3.1 (workaround)
https://github.com/yaml/pyyaml/issues/601
2023-10-15 16:01:23 +01:00
8 changed files with 143 additions and 34 deletions

4
.dockerignore Normal file
View File

@ -0,0 +1,4 @@
.git
.env
env
**/__pycache__

3
.gitignore vendored
View File

@ -1,6 +1,7 @@
*.swp
.env
env
n
web
planning.txt
__pycache__
**/__pycache__

31
Dockerfile Normal file
View File

@ -0,0 +1,31 @@
FROM python:3.12-bookworm
ARG ARCH=
ENV BUILDARCH=${ARCH}
ENV GRONK_CSS_DIR=./css
ENV GRONK_JS_DIR=./js
ENV GRONK_TEMPLATES_DIR=./templates
WORKDIR /usr/src/app
RUN mkdir /notes
RUN mkdir /web
VOLUME /usr/src/app/notes
VOLUME /usr/src/app/web
RUN apt-get update \
&& wget -O ./pandoc.deb https://github.com/jgm/pandoc/releases/download/3.1.11/pandoc-3.1.11-1-${BUILDARCH}.deb \
&& apt install -y -f ./pandoc.deb \
&& rm ./pandoc.deb
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
RUN useradd -Ms /bin/nologin user
USER user
COPY . .
CMD [ "python3", "-u", "gronk.py", "--output-dir", "./web", "./notes" ]

11
docker-compose.yml Normal file
View File

@ -0,0 +1,11 @@
version: '3'
services:
gronk:
build:
context: '.'
args:
ARCH: ${ARCH}
volumes:
- '${SOURCE}:/usr/src/app/notes'
- '${OUTPUT}:/usr/src/app/web'

View File

@ -23,14 +23,15 @@ GRONK_COMMIT = "dev"
PANDOC_SERVER_URL = os.getenv("PANDOC_SERVER_URL", r"http://localhost:3030/")
PANDOC_TIMEOUT = int(os.getenv("PANDOC_TIMEOUT", "120"))
GRONK_CSS_DIR = Path(os.getenv("CSS_DIR", "/opt/gronk/css"))
GRONK_JS_DIR = Path(os.getenv("JS_DIR", "/opt/gronk/js"))
GRONK_TEMPLATES_DIR = Path(os.getenv("TEMPLATES_DIR", "/opt/gronk/templates"))
GRONK_CSS_DIR = Path(os.getenv("GRONK_CSS_DIR", "/opt/gronk/css"))
GRONK_JS_DIR = Path(os.getenv("GRONK_JS_DIR", "/opt/gronk/js"))
GRONK_TEMPLATES_DIR = Path(
os.getenv("GRONK_TEMPLATES_DIR", "/opt/gronk/templates/"))
JINJA_ENV = jinja2.Environment(loader=jinja2.PackageLoader("gronk"),
JINJA_ENV = jinja2.Environment(
loader=jinja2.FileSystemLoader(searchpath=GRONK_TEMPLATES_DIR),
autoescape=jinja2.select_autoescape)
JINJA_TEMPLATES = {}
JINJA_TEMPLATE_TEXTARTICLE = JINJA_ENV.get_template("article-text.html")
JINJA_TEMPLATE_HOME_INDEX = JINJA_ENV.get_template("home.html")
JINJA_TEMPLATE_INDEX = JINJA_ENV.get_template("index.html")
@ -117,8 +118,8 @@ class FileMap:
'tags': [],
}
if 'index.md' in [f.name for f in filepath.iterdir()]:
with open(filepath.joinpath('index.md'),
if 'readme.md' in [f.name for f in filepath.iterdir()]:
with open(filepath.joinpath('readme.md'),
encoding='utf-8') as file_pointer:
for key, val in frontmatter.load(
file_pointer).to_dict().items():
@ -138,6 +139,9 @@ class FileMap:
entries = []
for path in filepath.iterdir():
if '.git' in path.parts:
continue
if path.is_dir():
entry = self._get_directory_properties(
path, include_index_entries=False)
@ -354,7 +358,7 @@ def process_home_index(args, notes_git_head_sha1=None):
"""
post = {'title': 'gronk', 'content': ''}
custom_content_file = args.notes.joinpath('index.md')
custom_content_file = args.notes.joinpath('readme.md')
if custom_content_file.is_file():
fmpost = frontmatter.loads(custom_content_file.read_text()).to_dict()
for key, val in fmpost.items():
@ -434,6 +438,8 @@ def generate_tag_browser(output_dir):
def main(args):
""" Entry point for script """
start_time = time.time()
global LICENSE
global FILEMAP
@ -462,7 +468,7 @@ def main(args):
root_properties = FILEMAP.get(root)
root_properties['dst_path']['raw'].mkdir(parents=True, exist_ok=True)
pprint.pprint(root_properties)
#pprint.pprint(root_properties)
html = JINJA_TEMPLATE_INDEX.render(
gronk_commit=GRONK_COMMIT,
title=root_properties.get('title', ''),
@ -481,8 +487,8 @@ def main(args):
# render each file
for file in files:
# don't render index.md as index as it is used for directory
if file == "index.md":
# don't render readme.md as index as it is used for directory
if file == "readme.md":
continue
render_file(root.joinpath(file))
@ -499,16 +505,44 @@ def main(args):
generate_tag_browser(args.output_dir.joinpath('tags'))
generate_permalink_page(args.output_dir)
elapsed_time = time.time() - start_time
print(f"generated notes {elapsed_time=}")
return 0
def start_pandoc_server():
"""
attempt to get the version of pandoc server in a loop until it is
successful and return version as string
"""
start_time = time.time()
process = subprocess.Popen(["/usr/bin/pandoc-server"],
stdout=subprocess.PIPE)
version = None
while True:
try:
resp = requests.get(f"{PANDOC_SERVER_URL}/version")
version = resp.content.decode('utf-8')
break
except requests.ConnectionError:
time.sleep(0.1)
rc = process.poll()
if rc is not None:
print(f"PANDOC SERVER FAILED TO START: {rc=}")
print(process.stdout.read().decode("utf-8"))
raise Exception("Pandoc server failed to start")
elapsed_time = time.time() - start_time
print(f"pandoc-server started {version=} {elapsed_time=}")
return process
# TODO implement useful logging and debug printing
if __name__ == '__main__':
pandoc_process = subprocess.Popen(["/usr/bin/pandoc-server"],
stdout=subprocess.PIPE)
time.sleep(1)
print(pandoc_process.stdout)
pandoc_process = start_pandoc_server()
try:
sys.exit(main(get_args()))

View File

@ -10,22 +10,39 @@ Tested with [pandoc v2.19.2](https://github.com/jgm/pandoc/releases/tag/2.19.2).
## Why?
- View notes as a website, on any device
- Write notes with Pandoc markdown
- Easily share notes
- Powered by Pandoc, and therefore supports [Pandoc's markdown](https://pandoc.org/MANUAL.html#pandocs-markdown) (I mainly care about equations)
- [flatnotes](https://github.com/Dullage/flatnotes) is cool but I really would rather type my notes in Vim
- Lightweight HTML generated
- Minimal JavaScript
## Install
0. Install [Pandoc](https://pandoc.org/index.html) and [Pip](https://github.com/pypa/pip)
### Docker
Run the following, modifing the `-v` arguments as needed to mount the correct folders and
setting the value of `ARCH` to either `amd64` or `arm64` as appropriate.
On arch:
```
# pacman -S pandoc python-pip
docker build . -t gronk --build-arg ARCH=amd64
docker run -v ./n:/usr/src/app/notes -v ./web:/usr/src/app/web gronk
```
1. Run `make install` as root
#### Compose
A [docker compose file](./docker-compose.yml) file has been provided.
Set the following environment variables (or create a .env file) and run `docker compose up`:
- `ARCH`
- `SOURCE`
- `OUTPUT`
### Locally
0. Install [Pandoc](https://pandoc.org/index.html) and [Pip](https://github.com/pypa/pip), python3-dev, and a C compiler
1. `sudo make install`
## Other Things to Know
@ -34,9 +51,9 @@ Tested with [pandoc v2.19.2](https://github.com/jgm/pandoc/releases/tag/2.19.2).
- gronk looks for the plaintext file `LICENSE` in the root directory of your notes
## Custom Directory Index
## Custom Directory Index and Metadata
To add custom content to a directory index, put it in a file called `index.md` under the directory.
To add custom content to a directory index, put it in a file called `readme.md` under the directory.
You can set the following frontmatter variables to customise the directory index of a directory:
@ -44,7 +61,7 @@ You can set the following frontmatter variables to customise the directory index
|------------------------|-------------------|--------------------------------------------------------------------------------------------|
| `tags` | `[]` | list of tags, used by search and inherited by any notes and subdirectories |
| `uuid` | none | unique id to reference directory, used for permalinking |
| `content_after_search` | `false` | show custom content in `index.md` after search bar and directory index |
| `content_after_search` | `false` | show custom content in `readme.md` after search bar and directory index |
| `automatic_index` | `true` | show the automatically generated directory index. required for search bar to function. |
| `search_bar` | `true` | show search bar to search directory items. requires `automatic_index` (enabled by default) |
@ -82,8 +99,8 @@ a file called `styles.css`.
To add additional styling, the default styling will attempt to import `styles.css` from the root of the notes
directory.
To add additional content to the homepage, create a file called `index.md` at the top level of your notes directory.
To set the HTML `title` tag, set `title` in the frontmatter of `index.md`:
To add additional content to the homepage, create a file called `readme.md` at the top level of your notes directory.
To set the HTML `title` tag, set `title` in the frontmatter of `readme.md`:
```markdown
---
@ -103,7 +120,18 @@ $ gronk.py notes_directory
Output of `gronk.py --help`:
TODO add cli output
```
usage: gronk.py [-h] [-o OUTPUT_DIR] [-F] notes
positional arguments:
notes
options:
-h, --help show this help message and exit
-o OUTPUT_DIR, --output-dir OUTPUT_DIR
-F, --force Generate new output html even if source file was modified before output
html
```
The command will generate a website in the `output-dir` directory (`./web` by default).
It will then generate a list of all note files and put it in `index.html`.
@ -121,5 +149,3 @@ Then you just have to point a webserver at `output-dir`.
Default synatx highlighting is based off [Pygments](https://pygments.org/)' default theme and
made using Pandoc v2.7.2.
I found the theme [here](https://github.com/tajmone/pandoc-goodies/blob/master/skylighting/css/built-in-styles/pygments.css).
Pretty sure the link colours are taken from [thebestmotherfucking.website](https://thebestmotherfucking.website/).

View File

@ -11,7 +11,9 @@ oyaml==1.0
pypandoc==1.5
python-frontmatter==1.0.0
python-magic==0.4.24
PyYAML==6.0.1
PyYAML==5.3.1
regex==2021.11.10
soupsieve==2.2.1
regex==2021.11.10
requests==2.31.0
smmap==5.0.1

View File

@ -13,6 +13,6 @@
<div id="content">
{% block content %}
{% endblock %}
<p class="smallText"> page generated by <a href="https://github.com/alvierahman90/gronk">gronk</a> (commit {{ gronk_commit }}) {% if notes_git_head_sha1 %}notes commit {{ notes_git_head_sha1 }}{% endif %}</p>
<p class="smallText"> page generated by <a href="https://github.com/alvierahman90/gronk">gronk</a> <!--(commit {{ gronk_commit }}) {% if notes_git_head_sha1 %}notes commit {{ notes_git_head_sha1 }}{% endif %}--></p>
</div>
</body>