Initial commit
This commit is contained in:
commit
06da0be072
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
themes/
|
||||||
|
public/
|
40
.gitlab-ci.yml
Normal file
40
.gitlab-ci.yml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
build:
|
||||||
|
image: python
|
||||||
|
stage: build
|
||||||
|
before_script:
|
||||||
|
- wget https://github.com/getzola/zola/releases/download/v0.12.2/zola-v0.12.2-x86_64-unknown-linux-gnu.tar.gz -O zola.tgz
|
||||||
|
- unzip zola.tgz
|
||||||
|
script:
|
||||||
|
- ./zola build
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
|
||||||
|
pages:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- ls -lah public/
|
||||||
|
dependencies:
|
||||||
|
- build
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
neocities:
|
||||||
|
image: ruby:2.6.5
|
||||||
|
dependencies:
|
||||||
|
- build
|
||||||
|
stage: deploy
|
||||||
|
environment: neocities
|
||||||
|
script:
|
||||||
|
- echo -e "source 'https://rubygems.org'\n\ngem 'neocities'" > Gemfile
|
||||||
|
- gem install bundler
|
||||||
|
- bundle install
|
||||||
|
# Place user-provide token
|
||||||
|
- if [ -z "$NEOCITIES_TOKEN" ]; then echo Please see README.md for information on how to set your Neocities API token && false; else mkdir -p $HOME/.config/neocities && mv $NEOCITIES_TOKEN $HOME/.config/neocities/config; fi
|
||||||
|
- cd public
|
||||||
|
- bundle exec neocities push .
|
||||||
|
only:
|
||||||
|
- master
|
9
config.toml
Normal file
9
config.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# The URL the site will be built for
|
||||||
|
base_url = "https://notes.stavros.io"
|
||||||
|
compile_sass = false
|
||||||
|
highlight_code = true
|
||||||
|
build_search_index = true
|
||||||
|
theme = "book"
|
||||||
|
title = "Stavros' Notes"
|
||||||
|
|
||||||
|
[extra]
|
3
content/_index.md
Normal file
3
content/_index.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
+++
|
||||||
|
redirect_to = "welcome"
|
||||||
|
+++
|
7
content/drone-stuff/_index.md
Normal file
7
content/drone-stuff/_index.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
+++
|
||||||
|
title = "Drone stuff"
|
||||||
|
weight = 2
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
Select one of the sublinks on the left to see the notes in this section.
|
9
content/drone-stuff/omnibus-f4-pro-servo-diode.md
Normal file
9
content/drone-stuff/omnibus-f4-pro-servo-diode.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
+++
|
||||||
|
title = "Omnibus F4 pro servo diode"
|
||||||
|
weight = 1
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
To isolate the servo 5V rail, remove this diode:
|
||||||
|
|
||||||
|
![a435bcae86912205b6fac41731285b8d.png](6d668e05d8a54580966b94a752f3b7db)
|
9
content/drone-stuff/omnibus-f4-v3.md
Normal file
9
content/drone-stuff/omnibus-f4-v3.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
+++
|
||||||
|
title = "Omnibus F4 V3"
|
||||||
|
weight = 0
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
This is the pinout of the Omnibus F4 V3:
|
||||||
|
|
||||||
|
![53b3161d509dcc7bbfb43c89b16b0bae.png](99f5c91454204c1d9740a8d9b876833b)
|
7
content/notes/_index.md
Normal file
7
content/notes/_index.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
+++
|
||||||
|
title = "Notes"
|
||||||
|
weight = 3
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
Select one of the sublinks on the left to see the notes in this section.
|
7
content/notes/various.md
Normal file
7
content/notes/various.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
+++
|
||||||
|
title = "Various"
|
||||||
|
weight = 0
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
Hello
|
7
content/welcome/_index.md
Normal file
7
content/welcome/_index.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
+++
|
||||||
|
title = "Welcome"
|
||||||
|
weight = 1
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
Select one of the sublinks on the left to see the notes in this section.
|
9
content/welcome/welcome.md
Normal file
9
content/welcome/welcome.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
+++
|
||||||
|
title = "Welcome"
|
||||||
|
weight = 0
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
Welcome! This is my notes site.
|
||||||
|
|
||||||
|
[Omnibus F4 pro servo diode](../../drone-stuff/omnibus-f4-pro-servo-diode)
|
117
joplinexport.py
Executable file
117
joplinexport.py
Executable file
@ -0,0 +1,117 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import re
|
||||||
|
import sqlite3
|
||||||
|
from collections import defaultdict
|
||||||
|
from pathlib import Path
|
||||||
|
from shutil import rmtree
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
def slugify(text):
|
||||||
|
return re.sub(r"[\W_]+", "-", text.lower()).strip("-")
|
||||||
|
|
||||||
|
|
||||||
|
class Note:
|
||||||
|
def __init__(self, id, parent_id, parent_title, title, body):
|
||||||
|
self.id = id
|
||||||
|
self.parent_id = parent_id
|
||||||
|
self.parent_title = parent_title
|
||||||
|
self.title = title
|
||||||
|
self.body = body
|
||||||
|
|
||||||
|
def get_url(self):
|
||||||
|
return slugify(self.parent_title) + "/" + slugify(self.title)
|
||||||
|
|
||||||
|
|
||||||
|
class JoplinExporter:
|
||||||
|
content_dir = Path("content")
|
||||||
|
|
||||||
|
def clean_content_dir(self):
|
||||||
|
"""Reset the content directory to a known state to begin."""
|
||||||
|
rmtree(self.content_dir)
|
||||||
|
self.content_dir.mkdir()
|
||||||
|
with open(self.content_dir / "_index.md", mode="w") as outfile:
|
||||||
|
outfile.write('+++\nredirect_to = "welcome"\n+++')
|
||||||
|
|
||||||
|
def resolve_note_links(self, note: Note) -> str:
|
||||||
|
def replacement(match):
|
||||||
|
note_id = match.group(1)
|
||||||
|
new_url = self.get_note_url_by_id(note_id)
|
||||||
|
return "](" + ("../../" + new_url if new_url else note_id) + ")"
|
||||||
|
|
||||||
|
return re.sub(r"\]\(:/([a-f0-9]{32})\)", replacement, note.body)
|
||||||
|
|
||||||
|
def get_note_url_by_id(self, note_id: str) -> Optional[str]:
|
||||||
|
"""Return a note's relative URL by its ID."""
|
||||||
|
note = self.note_lookup_dict.get(note_id)
|
||||||
|
if not note:
|
||||||
|
return None
|
||||||
|
return note.get_url()
|
||||||
|
|
||||||
|
def read_data(self):
|
||||||
|
conn = sqlite3.connect(Path.home() / ".config/joplin-desktop/database.sqlite")
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
# Create table
|
||||||
|
c.execute("""SELECT id, title FROM folders;""")
|
||||||
|
self.folders = {id: title for id, title in c.fetchall()}
|
||||||
|
|
||||||
|
c.execute("""SELECT id, title FROM resources;""")
|
||||||
|
self.resources = {id: title for id, title in c.fetchall()}
|
||||||
|
|
||||||
|
c.execute("""SELECT id, parent_id, title, body FROM notes;""")
|
||||||
|
self.notes = defaultdict(list)
|
||||||
|
self.note_lookup_dict = {}
|
||||||
|
for id, parent_id, title, body in c.fetchall():
|
||||||
|
note = Note(id, parent_id, self.folders[parent_id], title, body)
|
||||||
|
self.notes[note.parent_id].append(note)
|
||||||
|
self.note_lookup_dict[note.id] = note
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
def export(self):
|
||||||
|
folder_list = list(self.folders.items())
|
||||||
|
# Sort "Welcome" last.
|
||||||
|
folder_list.sort(
|
||||||
|
key=lambda x: x[1].lower().strip() if x[1] != "Welcome" else "0"
|
||||||
|
)
|
||||||
|
|
||||||
|
outdir = Path.cwd() / "content"
|
||||||
|
self.clean_content_dir()
|
||||||
|
|
||||||
|
for counter, folder in enumerate(folder_list, start=1):
|
||||||
|
folder_id, folder_title = folder
|
||||||
|
dir = outdir / slugify(folder_title)
|
||||||
|
dir.mkdir(parents=True)
|
||||||
|
with (dir / "_index.md").open(mode="w") as outfile:
|
||||||
|
outfile.write(
|
||||||
|
f"""+++
|
||||||
|
title = "{folder_title}"
|
||||||
|
weight = {counter}
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
Select one of the sublinks on the left to see the notes in this section."""
|
||||||
|
)
|
||||||
|
|
||||||
|
for counter, note in enumerate(
|
||||||
|
sorted(self.notes[folder_id], key=lambda n: n.title)
|
||||||
|
):
|
||||||
|
print(f"Exporting {folder_title} - {note.title}...")
|
||||||
|
with (outdir / (note.get_url() + ".md")).open(mode="w") as outfile:
|
||||||
|
outfile.write(
|
||||||
|
f"""+++
|
||||||
|
title = "{note.title}"
|
||||||
|
weight = {counter}
|
||||||
|
sort_by = "weight"
|
||||||
|
insert_anchor_links = "right"
|
||||||
|
+++
|
||||||
|
{self.resolve_note_links(note)}"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("Exporting Joplin database...")
|
||||||
|
exporter = JoplinExporter()
|
||||||
|
exporter.read_data()
|
||||||
|
exporter.export()
|
Loading…
Reference in New Issue
Block a user