Search your Pinboard bookmarks with Launchbar

[Tweet]

This script is based on my Pinboard mirroring script that I use to keep Spotlight-searchable, OpenMeta-tagged copies of my Pinboard bookmarks locally. It’s a good system, but I was thinking that a direct bookmark file search in Launchbar would be exponentially faster than Spotlight on the occasions that I remembered any part of the title.

I dumped my entire Pinboard bookmark collection to a simple bookmark file and indexed it as a subgroup in Launchbar. I’m sure this would work fine with some other launchers as well, but it’s a 5-minute script… any porting will have to be up to those who need it.

Any description on the bookmark gets stripped of newlines and put into the “title” attribute, but this isn’t indexed by Launchbar. I just figured, since it’s there… Tags are included in the text of the bookmark as @tags to make it possible search by tag groups in Launchbar. It works reasonably well. If you know what you’re looking for, this is the fastest way I’ve found to get there.

You can edit the config in the script below and run it once to build the bookmark file. Open up Launchbar and hit I to get to the Index window. Hit the plus sign at the bottom to add a new Bookmark group and select Custom Bookmark file. Then point it to the file that the script created and you should have a fully searchable index in a few seconds. Then you can just run the script occasionally to overwrite the file with changes and additions. It’s not advanced; no delta checking or throttling, so use with loving care.

allpinboard.rbraw
#!/usr/bin/ruby
=begin
This script is designed to generate a simple html file with _all_ of your Pinboard.in bookmarks
The HTML file can be added to Launchbar's index as a custom bookmark file and you can search
your entire Pinboard.in collection instantly from Launchbar (by title only). It includes
any applied tags as part of the title to aid in searching.

This does no checking for deltas, it just grabs the whole bunch and overwrites the html file
every time. Don't run it too frequently.

Set your username, password and the path/filename to write to below.
=end
### User configuration
PB_USERNAME = 'username'
PB_PASSWORD = 'password'
BOOKMARK_FILE = 'path/to/store/PinboardBookmarks.html'
### END config

require 'cgi'
require 'fileutils'
require 'net/https'
require 'rexml/document'

class Net::HTTP
  alias_method :old_initialize, :initialize
  def initialize(*args)
    old_initialize(*args)
    @ssl_context = OpenSSL::SSL::SSLContext.new
    @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end
end

def get_bookmarks
    xml = ''
    http = Net::HTTP.new('api.pinboard.in', 443)
    http.use_ssl = true
    http.start do |http|
    	request = Net::HTTP::Get.new('/v1/posts/all')
    	request.basic_auth PB_USERNAME,PB_PASSWORD
    	response = http.request(request)
    	response.value
    	xml = response.body
    end
    return REXML::Document.new(xml)
  end

  def bookmarks_to_array(doc)
    bookmarks = []
    doc.elements.each('posts/post') do |ele|
      post = {}
      ele.attributes.each {|key,val|
        post[key] = val;
      }
      bookmarks.push(post)
    end
    return bookmarks
  end

  bookmarks = bookmarks_to_array(get_bookmarks)
  output = ""
  bookmarks.each do |b|
    output += %Q{<a href="#{b['href']}" title="#{CGI.escapeHTML(b['extended']).gsub(/\n/,' ')}">#{b['description'].gsub(/\n+/,"\n")} @#{b['tag'].split(' ').join(' @')}</a>\n}
  end

# Append to a file:
open(File.expand_path(BOOKMARK_FILE), 'w') { |f|
    f.puts output
}