Basket2MD is a Python script that migrates notes from KDE Basket to Obsidian while preserving the tree structure. It converts HTML notes to Markdown, copies attached files, and organizes everything into a hierarchical folder structure suitable for Obsidian.
- Python 3.14 or higher (required for
pathlib.copy)
- Clone the repository and navigate to the directory:
git clone https://github.com/vozbu/basket2md.git cd basket2md - Create a virtual environment:
python3 -m venv venv
- Activate the virtual environment:
- On bash/zsh:
source venv/bin/activate - On fish:
source venv/bin/activate.fish
- On bash/zsh:
- Install dependencies:
pip3 install -r requirements.txt
Run the script with the following command:
./basket2md.py -o /path/to/obsidian/vault-i, --input: Path to KDE Basket directory (default:~/.local/share/basket/baskets)-o, --output: Path to Obsidian vault directory (required)-v, --verbose: Increase verbosity (use-vvfor more details)
Example:
./basket2md.py -i ~/.local/share/basket/baskets -o ~/Documents/Obsidian/MyVault -vv- Copies attached files (images, documents, etc.) from Basket notes to the corresponding Obsidian folders
- Preserves file metadata during copying
- Handles missing files gracefully with warnings
- HTML notes: Converted to Markdown using the
markdownifylibrary - Text (.txt) files: Converted to separate Markdown (.md) files with frontmatter metadata, instead of being copied as attachments
- Links: Converted to Markdown link format
[title](url) - Images/Files: Referenced files are copied to the output directory
- Todo items: Converted to Markdown checkboxes (
- [x]for done,- [ ]for unchecked) - Titles: Converted to Markdown headers (
# Title)
- Processes nested note groups from Basket's XML structure
- Maintains hierarchical organization in Obsidian
- Creates separate Markdown files for each Basket folder
Each generated Markdown file includes YAML frontmatter with metadata:
source: Always set to "KDE Basket"dir_name: The original Basket directory namecreated: The earliest creation date (ISO format) from all notes in the group (if available)updated: The latest modification date (ISO format) from all notes in the group (if available)
The access time (atime) and modification time (mtime) of generated Markdown files and directories are set based on the collected dates:
- For files: Access time is set to the
createddate if available, otherwise to theupdateddate; modification time is set to theupdateddate if available - For directories: Modification time is set to the latest
updateddate from all notes and subdirectories within that directory
Basket has some formatting made weird, parsers don't handle it well.
Subnotes sometimes has titles in it not structured as titles in HTML files. It could be extracted with some kind of heuristics.