stackexchange-favs-to-pinboard

Check-in [6beb1d0a21]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Initial commit: Works for me, your mileage may vary, etc, etc
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | descendants | origin/master | trunk
Files: files | file ages | folders
SHA3-256: 6beb1d0a21a3d916001598c14e6df6bd2304ab972aaef3285ed68e68a0512df7
User & Date: atomicules@lavabit.com 2013-02-17 23:02:47
Context
2013-02-17
23:08
Typical, spot something I missed as soon as I push check-in: d45e2bb088 user: atomicules@lavabit.com tags: origin/master, trunk
23:02
Initial commit: Works for me, your mileage may vary, etc, etc check-in: 6beb1d0a21 user: atomicules@lavabit.com tags: origin/master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace

Added README.markdown.































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#StackExchange Favourites to Pinboard

Import all your StackExchange site (Stackoverflow, Super User, Cross Validated, etc) favourites to Pinboard. Because amazingly no-one else seems to have done this. And yes, this is how I write Ruby code, tabs as well - if you think this is bad style you should see my Haskell.

##To Use

Run `ruby /path/to/stackexchange-favs-to-pinboard.rb -i StackExchangeID -t PinboardAPIToken` 

You can get your Pinboard API token on your password tab of the settings page. Your StackExchange ID, is what you get when logged in to stackexchange.com itself - this is probably different from your Stackoverflow ID, etc.

Since it does not overwrite existing bookmarks you can safely run it every so often to bring in new ones. 

##Requirements

Nowt beyond Ruby. I am aware there are Gems for StackExchange, but most of them seem to assume you are targeting just one site (Stackoverflow), not any/all StackExchange sites you may use. There is also at least one really good Gem for Pinboard, but it just seemed overkill for the one API function I wanted to use, plus I don't think it rate limits.

Added stackexchange-favs-to-pinboard.rb.















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#StackExchange Favs to Pinboard
require 'open-uri'
require 'json'
require 'optparse'
require 'cgi'

optparse = OptionParser.new do |opts|
	opts.on('-i', '--id ID', "Stackexchange ID") { |i| StackID = i }
	opts.on('-t', '--token TOKEN', "Pinboard API Token") { |t| Token = t }
end
optparse.parse!

def get_sites(id)
	response = open("https://api.stackexchange.com/2.1/users/#{id}/associated")
	parsed = parse(response)
end

def parse(response) 
	#From: Garth, http://stackoverflow.com/a/1366187/208793
	gz = Zlib::GzipReader.new(StringIO.new(response.string))
	parsed = JSON.parse(gz.read)
end

def get_favs(site, id)
	response = open("https://api.stackexchange.com/2.1/users/#{id}/favorites?order=desc&sort=activity&site=#{site}")
	parsed = parse(response)
end

def pinboard_add(auth_token, url, description, replace, tags)
	attempts = 1
	posted = false
	until ($rate_limit > 60) | (attempts > 3) | posted 
		response = open(URI.encode("https://api.pinboard.in/v1/posts/add?auth_token=#{auth_token}&url=#{url}&description=#{description}&replace=#{replace}&tags=#{tags}").gsub("'", "%27"))
		#Bit of a hacky kludge. For some reason URI.encode doesn't catch apostrophes.
		if (response.status[0] == "200") & response.string.include?("done")
			puts "Added #{url}"
			posted = true
		elsif (response.status[0] == "200") & response.string.include?("exists")
			puts "Skipping #{url}, already exists"
			posted = true
		elsif response.status[0] == "429"
			# 429 Too Many Requests, increase rate limit
			$rate_limit *= 2
			puts "Rate Limit increased to #{$rate_limit} seconds"
		end
		attempts += 1
		#Rate limit as per Pinboard API requirements
		sleep $rate_limit
	end
	if $rate_limit > 60
		puts "Rate limit has exceeded 60 secs, let's try again another time"
		quit
	elsif attempts > 3
		puts "Failed 3 times to save #{url}, bombing out"
	end
end

if defined?(StackID) and defined?(Token)
	$rate_limit = 3
	parsed = get_sites(StackID)
	parsed["items"].each do |site|
		favs = get_favs(site["site_url"].sub("http://", "").sub(".stackexchange", "").sub(".com", ""), site["user_id"])
		favs["items"].each do |fav|
			title = fav["title"]
			tags = fav["tags"]
			link = fav["link"]
			pinboard_add(Token, link, CGI.unescape_html(title), "no", tags.join(", ")+", stackexchangefavs")
			#Need to unescape so can URI encode
		end
	end
end