Skip to content

Instantly share code, notes, and snippets.

@doitian
Last active February 9, 2022 19:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doitian/27606b562faf6fc36bb65b87802dd97f to your computer and use it in GitHub Desktop.
Save doitian/27606b562faf6fc36bb65b87802dd97f to your computer and use it in GitHub Desktop.
A script to export Vivaldi bookmarks into markdown files.
#!/usr/bin/env python3
from pathlib import Path
import tempfile
import json
import textwrap
import hashlib
import os
import shutil
import filecmp
BOOKMARKLET_PREFIX = 'javascript:'
BOOKMARKLET_PREFIX_LEN = len(BOOKMARKLET_PREFIX)
def export_bookmarks_folder(dir, folder, name=None):
dir.mkdir(exist_ok=True)
name = name or folder['name']
with open(dir / f'{name} - Bookmarks.md', 'w') as md_file:
print(f'# {name} - Bookmarks\n', file=md_file)
print(f'#bookmarks #from/browser\n', file=md_file)
description = folder.get('meta_info', {}).get('Description', '')
if description != '':
print(description, file=md_file)
print('', file=md_file)
for child in folder['children']:
if child['type'] == 'folder':
export_bookmarks_folder(dir / child['name'], child)
print(f'- 📁 [[{child["name"]} - Bookmarks]]', file=md_file)
else:
url = child['url']
sha = hashlib.sha256(url.encode('utf-8')).hexdigest()[:7]
if url.startswith(BOOKMARKLET_PREFIX):
print(textwrap.dedent('''\
- {} #bookmarklet ^{}
```javascript
{}
```
''').format(child['name'], sha, textwrap.indent(url[BOOKMARKLET_PREFIX_LEN:], ' ')), file=md_file)
else:
print(
f"- {child['name']} [{url.split('://')[1].split('/')[0]}]({url}) ^{sha}", file=md_file)
description = child.get('meta_info', {}).get('Description', '')
if description != '':
print('', file=md_file)
print(textwrap.indent(description, ' '), file=md_file)
print('', file=md_file)
export_dir = Path.home() / 'Dropbox' / 'Brain' / '3 Resources' / 'Bookmarks'
tmp_dir = Path(tempfile.mkdtemp())
with (Path.home() / 'Library/Application Support/Vivaldi/Default/Bookmarks').open() as fd:
root = json.load(fd)["roots"]["bookmark_bar"]
export_bookmarks_folder(tmp_dir, root, name='Roots')
for root, dirs, files in os.walk(tmp_dir):
for f in files:
src_file = Path(root) / f
relative_path = src_file.relative_to(tmp_dir)
target_file = export_dir / relative_path
target_file.parent.mkdir(exist_ok=True)
if not target_file.exists() or not filecmp.cmp(src_file, target_file, shallow=False):
print('NEW:', relative_path)
os.replace(src_file, target_file)
else:
print('SKIP:', relative_path)
shutil.rmtree(tmp_dir)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment