saush

Downloading documents programmatically with Google Docs API

Posted in Ruby by sausheong on January 28, 2008

An interesting and perhaps little known feature in the Google Documents List Data API (perhaps because it’s currently undocumented!) is that you can use the APIs to programmatically get the word processor documents in various formats. This means that if you have a document currently in your folder (or anyone’s folder for that matter), you can use the APIs to save it to your computer. Why is this useful, since we can already do this from the browser?

It’s the same reason why the Google Documents List Data API was created in the first place — it allows you to write an application that can interact with Google Docs. Say for example if you want to save the document into the database instead of a file. Or you want to allow your users to use their documents on Google Docs to interact with your application. It’s a cool little feature that has quite interesting possibilities.

Let me show you how this can be done easily in Ruby. For this I’ve written a small Ruby script that allows you to take a file from your Google Docs account and save it as a file on your computer.

require 'rubygems'
require 'net/https'
require 'open-uri'

GOOGLE_URL = 'www.google.com'
GOOGLE_DOCS_URL = 'docs.google.com'

# convenience module to use HTTPS (mainly used for login)
module Net
  class HTTPS < HTTP
    def initialize(address, port = nil)
      super(address, port)
      self.use_ssl = true
    end
  end
end

class GCommander

  # Login into the Google Docs APIs using a Google account
  def login(email, pwd)
    params = { 'Email' => email,
      'Passwd' => pwd,
      'source' => 'saush-docs-01',
      'accountType' => 'HOSTED_OR_GOOGLE',
      'service' => 'writely' # this is the Google Docs service ID
    }

    response = Net::HTTPS.post_form(URI.parse("https://#{GOOGLE_URL}/accounts/ClientLogin"), params)
    response.error! unless response.kind_of? Net::HTTPSuccess
    @token = response.body.split(/=/).last
  end

  # Fetches the document, only works with word processor documents for now
  def fetch_document(saveas, url)
    exfmt = saveas.split('.')[1]
    raise "Unsupported format" if !%w(doc pdf).include? exfmt
    file = File.new(saveas, 'w')
    doc_id = ''
    URI.parse(url).query.split('&').each {|p| doc_id = p.split('=')[1] if p.include? 'docid=' }
    doc_url = "http://docs.google.com/MiscCommands?command=saveasdoc&exportformat=#{exfmt}&docID=#{doc_id}"
    open(doc_url, 'Authorization' => "GoogleLogin auth=#{@token}") { |data|
      file.write data.read
    }
    file.close
  end

end

if __FILE__ == $0 then
  gcmd = GCommander.new
  gcmd.login('YOUR GOOGLE ACCOUNT ID', 'YOUR GOOGLE ACCOUNT PASSWORD')
  gcmd.fetch_document(ARGV[0], ARGV[1])
end

Just replace placeholders with the actual Google account ID and password. How do you use it?

ruby gcommander.rb some_file.pdf http://docs.google.com/Doc?docid=GOOGLE_DOC_ID&hl=en

The document URL should be replaced with the actual URL of the Google document, which you can cut and paste from the browser. I’ve only tested this with MS Word (.doc) and Adobe Acrobat (.pdf) documents though.

For more information on how to use Google Docs for mashups, buy my book when it comes out in March :)

Tagged with:

Copyright and Open Source Software Licensing

Posted in law, Open source by sausheong on January 3, 2008

I wrote this some time back for my dissertation for my Masters in Law (LLM) degree in 2005. I was planning to publish it in the Virginia Journal of Law and Technology at the University of Virginia but even though it was accepted there was some mix-up in the administration and the article was shelved. I didn’t have time to follow up with it and after a while, gave up getting it published. In the end I just placed it in the bepress Legal Repository.

Copyright and Open Source Software Licensing

Enjoy!

Ruby-PayPal

Posted in PayPal, Rails, Ruby by sausheong on January 1, 2008

I did a simple Ruby gem to allow easy access to PayPal’s NVP APIs recently. It isn’t much at this point in time, though both the Direct Payment and Express Checkout has been coded, only Direct Payment has really been tested. Here’s the writeup directly from the project site at http://ruby-paypal.rubyforge.org.

Installing Ruby-PayPal

A lightweight ruby wrapper for PayPal NVP APIs. To install type the following at the command line:

$ gem install ruby-paypal

Using Ruby-PayPal

It‘s critical that you understand how PayPal works and how the PayPal NVP API works. You should be relatively well-versed in the NVP API Developer Guide and Reference. You should also visit and register yourself with the PayPal Developer Network and get a Sandbox account with in the PayPal Development Central.

Note that this library only supports the API signature method of securing the API credentials.

Direct Payment

To use credit card payment through PayPal, you need to use the DoDirectPayment APIs:

username = <PayPal API username>
password = <PayPal API password>
signature = <PayPal API signature>

ipaddress = '192.168.1.1' # can be any IP address
amount = '100.00' # amount paid
card_type = 'VISA' # can be Visa, Mastercard, Amex etc
card_no = '4512345678901234' # credit card number
exp_date = '022010' # expiry date of the credit card
first_name = 'Sau Sheong'
last_name = 'Chang'

paypal = Paypal.new(username, password, signature) # uses the PayPal sandbox
response = paypal.do_direct_payment_sale(ipaddress, amount, card_type, card_no, exp_date, first_name, last_name)

if response.ack == 'Success' then
   # do your thing
end

The above code is for a final sale only.

Note that the credit card number is checked against a modulo-10 algorithm (Luhn check) as well as a simple credit card type check. For more information please refer to http://en.wikipedia.org/wiki/Luhn_algorithm and http://en.wikipedia.org/wiki/Credit_card_number

Follow

Get every new post delivered to your Inbox.

Join 447 other followers