├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md ├── import_to_devonthink.rb ├── instapaper_to_pdf.rb └── sanitize_filename.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle* -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem "mechanize" 4 | gem "htmldoc" -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | htmldoc (0.2.3) 5 | mechanize (1.0.0) 6 | nokogiri (>= 1.2.1) 7 | mini_portile2 (2.8.0) 8 | nokogiri (1.13.3) 9 | mini_portile2 (~> 2.8.0) 10 | racc (~> 1.4) 11 | racc (1.6.0) 12 | 13 | PLATFORMS 14 | ruby 15 | 16 | DEPENDENCIES 17 | htmldoc 18 | mechanize 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Instapaper-to-PDF is a simple script that prints PDFs of your Instapaper items. 2 | 3 | ### Requirements 4 | You will need [HTMLDOC](http://www.htmldoc.org) installed in order to utilize this script. 5 | 6 | To install on OS X via [Homebrew](http://mxcl.github.com/homebrew/): `brew install htmldoc`. 7 | 8 | Please review the official documentation for installation on other platforms. 9 | 10 | 11 | ### Usage 12 | Set your username, password, and desired path for saved PDFs in "instapaper\_to\_pdf.rb". Then run: 13 | 14 | ruby instapaper-to-pdf.rb 15 | 16 | 17 | Importing to DEVONthink and deleting articles from Instapaper after print are disabled by default. Uncomment the respective lines to enable them. 18 | 19 | 20 | Suggestions and pull requests are more than welcome. -------------------------------------------------------------------------------- /import_to_devonthink.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011 David Aaron Fendley 2 | # 3 | # Import-to-DEVONthink is freely distributable under the terms of MIT license. 4 | # See LICENSE file or http://www.opensource.org/licenses/mit-license.php 5 | #------------------------------------------------------------------------------ 6 | 7 | # Import to DEVONthnk 8 | def import_to_devonthink(filename, database, folder) 9 | puts "Importing to DEVONthink..." 10 | %x[ osascript <<-HDOC 11 | tell application id "com.devon-technologies.thinkpro2" to launch 12 | tell application id "com.devon-technologies.thinkpro2" 13 | set lstFound to databases where name = "#{database}" 14 | if length of lstFound > 0 then 15 | set oDb to item 1 of lstFound 16 | set theFolder to create location "#{folder}" in oDb 17 | set oWin to open window for record theFolder 18 | set theRecord to import #{filename} to theFolder 19 | close oWin 20 | end if 21 | end tell 22 | ] 23 | end -------------------------------------------------------------------------------- /instapaper_to_pdf.rb: -------------------------------------------------------------------------------- 1 | #!ruby 2 | # coding: utf-8 3 | 4 | # Copyright (c) 2011 David Aaron Fendley 5 | # 6 | # Instapaper-to-PDF is freely distributable under the terms of MIT license. 7 | # See LICENSE file or http://www.opensource.org/licenses/mit-license.php 8 | #------------------------------------------------------------------------------ 9 | 10 | # This requires the htmldoc to be installed on your system. Mac users with MacPorts can install this with: 11 | # sudo port install htmldoc 12 | # Windows and Linux users, check here: http://www.htmldoc.org/ 13 | 14 | require 'rubygems' 15 | require "mechanize" 16 | require 'htmldoc' 17 | require "./sanitize_filename" 18 | require "./import_to_devonthink" 19 | 20 | # Delete articles from Instapaper.. 21 | def delete_articles(page) 22 | page.links_with(:text => "Delete").each do |link| 23 | page = link.click 24 | end 25 | end 26 | 27 | # Instapaper credentials 28 | instapaper_username = "USERNAME" 29 | instapaper_password = "PASSWORD" 30 | pdf_destination = "/Users/username/Downloads" 31 | 32 | # Go to the login page. 33 | agent = Mechanize.new 34 | agent.user_agent_alias = 'Mac Safari' 35 | agent.redirect_ok = true 36 | page = agent.get "http://www.instapaper.com/user/login" 37 | 38 | # Login. 39 | puts "Logging in..." 40 | form = page.forms.first 41 | form.username = instapaper_username 42 | form.password = instapaper_password 43 | page = agent.submit form 44 | 45 | # Follow the redirect. 46 | page = page.link_with(:text => "Click here if you aren't redirected").click 47 | 48 | # Print a PDF of each article. 49 | page.links_with(:text => "Text").each do |link| 50 | article_page = link.click 51 | file_path = "\"" + pdf_destination + "/#{sanitize_filename(article_page.title)}.pdf\"" 52 | 53 | pdf = PDF::HTMLDoc.new 54 | 55 | pdf.set_option :outfile, file_path 56 | pdf.set_option :bodycolor, :white 57 | pdf.set_option :links, true 58 | 59 | pdf << article_page.body 60 | 61 | puts "Printing a PDF for \"#{article_page.title}\"" 62 | pdf.generate 63 | 64 | # Enable importing to DEVONthink here. Syntax: path_to_file, database, folder. 65 | # import_to_devonthink(file_path, "Personal", "Articles") 66 | end 67 | 68 | # Delete from Instapaper. 69 | # puts "Deleting articles from Instapaper" 70 | # delete_articles(page) 71 | 72 | puts "Mission accomplished." -------------------------------------------------------------------------------- /sanitize_filename.rb: -------------------------------------------------------------------------------- 1 | # From: http://stackoverflow.com/questions/1939333/how-to-make-a-ruby-string-safe-for-a-filesystem 2 | 3 | def sanitize_filename(filename) 4 | return filename.strip do |name| 5 | # NOTE: File.basename doesn't work right with Windows paths on Unix 6 | # get only the filename, not the whole path 7 | name.gsub! /^.*(\\|\/)/, '' 8 | 9 | # Finally, replace all non alphanumeric, underscore 10 | # or periods with underscore 11 | # name.gsub! /[^\w\.\-]/, '_' 12 | # Basically strip out the non-ascii alphabets too 13 | # and replace with x. 14 | # You don't want all _ :) 15 | name.gsub!(/[^0-9A-Za-z.\-]/, 'x') 16 | end 17 | end --------------------------------------------------------------------------------