diff --git a/content/SUMMARY.md b/content/SUMMARY.md index e1c840a..56874aa 100644 --- a/content/SUMMARY.md +++ b/content/SUMMARY.md @@ -1,8 +1,8 @@ # Summary [Stavros' notes](welcome/stavros-notes.md) -- [Drone stuff](drone-stuff/index.md) - - [ArduPilot](ardupilot/index.md) +- [🛸 Drone stuff](drone-stuff/index.md) + - [🛩ī¸ ArduPilot](ardupilot/index.md) - [ArduPilot recommended settings](ardupilot/ardupilot-recommended-settings.md) - [ArduPilot setup checklist](ardupilot/ardupilot-setup-checklist.md) - [Bitmask calculator](ardupilot/bitmask-calculator.md) @@ -19,7 +19,7 @@ - [TECS tuning calculator](ardupilot/tecs-tuning-calculator.md) - [Transfer config between craft](ardupilot/transfer-config-between-craft.md) - [Tuning the TECS](ardupilot/tuning-the-tecs.md) - - [Model build notes](model-build-notes/index.md) + - [🏗ī¸ Model build notes](model-build-notes/index.md) - [Build notes for the FT Mighty Mini Arrow](model-build-notes/build-notes-for-the-ft-mighty-mini-arrow.md) - [Mini Drak build condensed instructions](model-build-notes/mini-drak-build-condensed-instructions.md) - [A simple guide to PID control](drone-stuff/a-simple-guide-to-pid-control.md) @@ -35,15 +35,16 @@ - [QGroundControl to Mission Planner conversion script](drone-stuff/qgroundcontrol-to-mission-planner-conversion-script.md) - [Transmitter external module pinout](drone-stuff/transmitter-external-module-pinout.md) - [Transportable C1 Chaser](drone-stuff/transportable-c1-chaser.md) -- [Maker things](maker-things/index.md) +- [📁 Maker things](maker-things/index.md) - [Battery discharge curves](maker-things/battery-discharge-curves.md) - [Electronics tips](maker-things/electronics-tips.md) - [GRBL_ESP32 tips](maker-things/grbl-esp32-tips.md) - [How to properly level your 3D printer](maker-things/how-to-properly-level-your-3d-printer.md) - [Installing BLTouch-compatible firmware onto the TwoTrees Sapphire Pro](maker-things/installing-bltouch-compatible-firmware-onto-the-twotrees-sapphire-pro.md) - - [Python](python/index.md) +- [đŸ–Ĩī¸ Programming](programming/index.md) + - [🐍 Python](python/index.md) - [Decorator that runs a function in a thread](python/decorator-that-runs-a-function-in-a-thread.md) -- [Software](software/index.md) +- [đŸ’Ŋ Software](software/index.md) - [Black pills](software/black-pills.md) - [Getting VoWiFi working on Xiaomi.eu](software/getting-vowifi-working-on-xiaomi-eu.md) - [Monero GUI syncing stuck with Ledger](software/monero-gui-syncing-stuck-with-ledger.md) diff --git a/docs.zip b/docs.zip deleted file mode 100644 index 3134232..0000000 Binary files a/docs.zip and /dev/null differ diff --git a/joplinexport b/joplinexport index 7497c95..c7ffec3 100755 --- a/joplinexport +++ b/joplinexport @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import dataclasses +import json import mimetypes import re import sqlite3 @@ -36,6 +37,7 @@ class Folder: id: str parent_id: str title: str + icon: str def is_private(self) -> bool: """Return whether this folder is private.""" @@ -47,7 +49,11 @@ class Folder: def get_summary_line(self, level: int) -> str: """Get the appropriate summary file line for this folder.""" - return (" " * (level - 1)) + f"- [{self.title}]({self.get_url()}/index.md)" + return ( + (" " * (level - 1)) + + f"- [{self.icon if self.icon else '📁'} " + + f"{self.title}]({self.get_url()}/index.md)" + ) def __lt__(self, other: Union["Folder", "Note"]) -> bool: """Support comparison, for sorting.""" @@ -200,9 +206,12 @@ class JoplinExporter: conn = sqlite3.connect(self.joplin_dir / "database.sqlite") c = conn.cursor() - c.execute("""SELECT id, title, parent_id FROM folders;""") + c.execute("""SELECT id, title, parent_id, icon FROM folders;""") self.folders = { - id: Folder(id, parent_id, title) for id, title, parent_id in c.fetchall() + id: Folder( + id, parent_id, title, json.loads(icon).get("emoji", "") if icon else "" + ) + for id, title, parent_id, icon in c.fetchall() } self.folders = { @@ -285,14 +294,22 @@ class JoplinExporter: # the only way this algorithm can generate headlines. if folders != note_item[:-1]: folders = note_item[:-1] - note_tree.append(folders) - + # Append all the parent folders of the current folder, as otherwise + # folders without a direct descendant note wouldn't show up. + # This will lead to duplicates, but we'll deduplicate later. + for x in range(1, len(folders) + 1): + note_tree.append(folders[:x]) note_tree.append(note_item) note_tree.sort() # Generate the summary file. items = [] + last_list = None for note_list in note_tree: + if last_list == note_list: + # Remove duplicates from above here. + continue + last_list = note_list level = len(note_list) if isinstance(note_list[-1], Folder): # The last item in the list is a folder, which means this is a header.