Created
October 9, 2022 13:52
-
-
Save Sorebit/f47f011dd879d0f94ee250bfa924b544 to your computer and use it in GitHub Desktop.
Pinboard -> Obsidian migration script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Turns a json exported from pinboard.in into a folder of Obsidian-compliant .md notes | |
Usage: | |
python p2o.py <export.json path> <out folder> | |
""" | |
import contextlib | |
import dateutil | |
from enum import Enum | |
from pathlib import Path | |
import json | |
import sys | |
from pydantic import BaseModel | |
from pdb import set_trace | |
WAITING_ROOM = 'Pinboard Waiting Room' | |
class Bookmark(BaseModel): | |
class yesno(Enum): | |
yes = 'yes' | |
no = 'no' | |
def __bool__(self): | |
return self == self.__class__.yes | |
href: str | |
description: str | |
extended: str | |
time: str | |
toread: yesno | |
tags: str | |
"""tags are separated by spaces in a single string""" | |
def as_md(self): | |
tags = self.tags | |
if self.toread: | |
tags = 'toread ' + tags | |
md = "" | |
if tags: | |
# Add tags to frontmatter | |
md = ( | |
f"---\n" | |
f"tags: [" | |
f"{', '.join(tags.split(' '))}" | |
"]\n" | |
f"---\n" | |
) | |
md += ( | |
f"# {self.description}\n" | |
f"Added: {dateutil.parser.parse(self.time)}\n" | |
f"Link: {self.href}\n" | |
) | |
if self.extended: | |
md += f"Extra:\n{self.extended}\n" | |
if self.toread: | |
md += f"#toread\n" | |
# Link to a "waiting room" note | |
md += f'\n[[{WAITING_ROOM}]]' | |
return md | |
def main(in_file: Path, out_dir: Path | None): | |
""" | |
:param in_file: Path to an pinboard_export.json file | |
:param out_folder: When specified, saves all markdown inside this directory. | |
""" | |
# Create output directory, if it doesn't already exist | |
if out_dir: | |
with contextlib.suppress(FileExistsError): | |
out_dir.mkdir() | |
# Output all markdown generated from bookmarks info (json) | |
with open(in_file, 'r') as f: | |
o = json.load(f) | |
for i, b in enumerate(o): | |
bookmark = Bookmark.parse_obj(b) | |
print(bookmark.as_md()) | |
if out_dir: | |
# Path to a file containing this single bookmark | |
path = out_dir / f'{i}.md' | |
with open(path, 'w') as out_file: | |
out_file.write(bookmark.as_md()) | |
if __name__ == '__main__': | |
in_file = Path(sys.argv[1]) | |
if len(sys.argv) > 2: | |
out_folder = Path(sys.argv[2]) | |
else: | |
out_folder = None | |
main(in_file, out_folder) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment