Skip to content

Instantly share code, notes, and snippets.

@valpackett
Last active September 7, 2023 21:01
Show Gist options
  • Save valpackett/5189568 to your computer and use it in GitHub Desktop.
Save valpackett/5189568 to your computer and use it in GitHub Desktop.
INSTANT Pinboard search from Alfred 2

INSTANT Pinboard search from Alfred 2

I've had a Python script that makes an HTML Bookmarks file for LaunchBar.
Now that I use Alfred 2, I modified it to make XML for Alfred.
This allows me to search my bookmarks with GREP SPEED!

Installation

First, add your token (from pinboard.in/settings/password) to ~/.netrc

machine pinboard.in
  password username:T0K3N11111111111

Then:

  1. Get pinboard-xml (I've also attached it to the gist in case I change something in my dotfiles repo)
  2. Put in the folder where you keep your scripts (eg. ~/bin)
  3. chmod +x it
  4. Add to crontab (eg. */30 * * * * ~/bin/pinboard-xml)
  5. Make a workflow in Alfred 2 with the following Script Filter (using /bin/bash) to Open URL:
echo "<?xml version=\"1.0\"?>"
echo "<items>"
cat $HOME/.bookmarks.xml | grep "{query}"
echo "</items>"

Enjoy!

#!/usr/bin/env python
# Made by Val Packett, ages ago in a past life
# https://gist.github.com/valpackett/5189568 <- also on gist
# Feel free to steal it, but attribution is nice
import os
import sys
import json
import netrc
import errno
import urllib2
def die(msg, err):
sys.stderr.write(msg)
sys.exit(err)
login = netrc.netrc().authenticators('pinboard.in')
if not login:
die('pinboard.in not found in netrc; add token as password', errno.ENODATA)
try:
getreq = urllib2.urlopen('https://api.pinboard.in/v1/posts/all?format=json&auth_token='+login[2])
if getreq.code == 429:
die('too often', errno.EPERM)
if getreq.code != 200:
die('http error %s on getting, maybe wrong password?' %
getreq.code, errno.EACCES)
items = json.loads(getreq.read())
res = '''<?xml version="1.0"?>
<items>'''
for item in items:
href = item['href'].encode('utf-8').replace('\n', '').replace('&', '&amp;')
desc = item['description'].encode('utf-8').replace('\n', '').replace('&', '&amp;')
res += '<item uid="%s" arg="%s"><title>%s</title><subtitle>%s</subtitle></item>\n' % \
(href, href, desc, href)
res += '</items>'
open(os.environ['HOME']+'/.bookmarks.xml', 'w').write(res)
except urllib2.HTTPError:
die('connection error', errno.ECONNREFUSED)
@wxn0000
Copy link

wxn0000 commented Feb 7, 2014

To solve the "&" issue, try changing:

href = item['href'].encode('utf-8').replace('\n', '')
desc = item['description'].encode('utf-8').replace('\n', '')

to

href = item['href'].encode('utf-8').replace('\n', '').replace('&', '&amp;)
desc = item['description'].encode('utf-8').replace('\n', '').replace('&', 'and')

In case there are "&" present in your pinboard bookmark description or url.

@jmjeong
Copy link

jmjeong commented Feb 20, 2014

@valpackett
Copy link
Author

Updated to use urllib2 (no deps!) and API token auth instead of password auth.

@floer32
Copy link

floer32 commented Mar 24, 2019

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment