April 2008
- Pengantar
- Mendapatkan dan menginstal Ruby
- Autentikasi | Menggunakan Spreadsheets API
- Mendapatkan lembar kerja
- Memposting konten ke listFeed
- Menggunakan cellsFeed untuk memperbarui konten
- Kesimpulan
Pengantar
Ruby adalah bahasa skrip dinamis yang telah menerima banyak perhatian dalam beberapa tahun terakhir karena framework pengembangan web Rails yang populer. Artikel ini akan menjelaskan cara menggunakan Ruby untuk berinteraksi dengan layanan Google Data API. Kita tidak akan berfokus pada Rails, tetapi lebih tertarik untuk menjelaskan perintah HTTP dan struktur feed yang mendasarinya. Semua contoh yang ditampilkan di sini dapat diikuti dari command line menggunakan irb, shell interaktif Ruby.
Seperti yang mungkin Anda ingat dari artikel cURL, Google Data API menggunakan Atom Publishing Protocol untuk merepresentasikan, membuat, dan mengupdate resource web. Keunggulan protokol ini adalah kata kerja HTTP standar digunakan untuk merumuskan permintaan yang dijawab dengan kode status HTTP standar.
Verba yang akan kita gunakan dalam artikel ini adalah GET untuk mengambil konten, POST untuk mengupload konten baru, dan PUT untuk memperbarui konten yang ada. Beberapa kode standar yang mungkin Anda temui saat menggunakan Google Data API adalah 200 untuk menunjukkan keberhasilan dalam mengambil feed atau entri, atau 201 untuk menunjukkan keberhasilan pembuatan atau pembaruan resource. Jika terjadi masalah, seperti saat permintaan yang salah format dikirim, kode 400 (yang berarti 'Permintaan Tidak Valid') akan dikirim kembali. Pesan yang lebih mendetail akan diberikan di isi respons, yang menjelaskan apa yang sebenarnya salah.
Ruby menyediakan opsi pen-debug-an yang bagus sebagai bagian dari modul 'Net'. Agar contoh kode ini tetap cukup singkat, saya tidak mengaktifkannya di sini.
Mendapatkan dan menginstal Ruby
Ruby dapat diinstal menggunakan sebagian besar sistem pengelolaan paket jika Anda menggunakan Linux. Untuk sistem operasi lain dan untuk mendapatkan kode sumber lengkap, buka http://www.ruby-lang.org/en/downloads/. Irb, shell interaktif yang akan kita gunakan untuk contoh ini, harus diinstal secara default. Untuk mengikuti contoh kode yang tercantum di sini, Anda juga perlu menginstal XmlSimple
, sebuah library kecil untuk mengurai XML menjadi struktur data Ruby. Untuk mendapatkan/menginstal XmlSimple, buka http://xml-simple.rubyforge.org/
Setelah memiliki salinan Ruby yang berjalan di mesin Anda, Anda dapat menggunakan paket Net:HTTP
untuk membuat permintaan dasar ke layanan Data Google. Cuplikan di bawah menunjukkan cara melakukan impor yang diperlukan dari shell interaktif Ruby. Yang kita lakukan adalah mewajibkan paket 'net/http', mengurai URL untuk feed video dengan rating teratas dari YouTube, lalu melakukan permintaan HTTP GET.
irb(main):001:0> require 'net/http' => true irb(main):002:0> youtube_top_rated_videos_feed_uri = \ 'http://gdata.youtube.com/feeds/api/standardfeeds/top_rated' => "http://gdata.youtube.com/feeds/api/standardfeeds/top_rated" irb(main):003:0> uri = \ URI.parse(youtube_top_rated_videos_feed_uri) => #<URI::HTTP:0xfbf826e4 URL:http://gdata.youtube.com/feeds/api/standardfeeds/top_rated> irb(main):004:0> uri.host => "gdata.youtube.com" irb(main):005:0> Net::HTTP.start(uri.host, uri.port) do |http| irb(main):006:1* puts http.get(uri.path) irb(main):007:1> end #<Net::HTTPOK:0xf7ef22cc>
Permintaan tersebut akan menampilkan cukup banyak XML ke command line. Anda mungkin telah memperhatikan bahwa semua item dimuat dalam elemen <feed> dan disebut sebagai elemen <entry>. Kita tidak perlu mengkhawatirkan pemformatan XML terlebih dahulu, saya hanya ingin menjelaskan cara membuat permintaan Google Data API dasar menggunakan HTTP. Sekarang kita akan beralih ke API lain dan berfokus pada Spreadsheet, karena informasi yang dapat kita kirim dan ambil lebih 'kompatibel dengan command line'.
Autentikasi | Menggunakan Google Spreadsheet API
Kita akan mulai lagi dengan mengambil feed elemen entri. Namun, kali ini kita akan bekerja dengan spreadsheet kita sendiri. Untuk melakukannya, kita harus melakukan autentikasi dengan layanan Akun Google terlebih dahulu.
Seperti yang mungkin Anda ingat dari dokumentasi tentang Autentikasi GData, ada dua cara untuk melakukan autentikasi dengan layanan Google. AuthSub ditujukan untuk aplikasi berbasis web dan secara singkat melibatkan proses pertukaran token. Manfaat sebenarnya dari AuthSub adalah aplikasi Anda tidak perlu menyimpan kredensial pengguna. ClientLogin adalah untuk aplikasi "terinstal". Dalam proses ClientLogin, nama pengguna dan sandi dikirim ke layanan Google melalui https bersama dengan string yang mengidentifikasi layanan yang ingin Anda gunakan. Layanan Google Spreadsheet API diidentifikasi oleh string wise.
Beralih kembali ke shell interaktif, mari kita lakukan autentikasi dengan Google. Perhatikan bahwa kita menggunakan https untuk mengirim permintaan dan kredensial autentikasi:
irb(main):008:0> require 'net/https' => true irb(main):009:0> http = Net::HTTP.new('www.google.com', 443) => #<Net::HTTP www.google.com:443 open=false> irb(main):010:0> http.use_ssl = true => true irb(main):011:0> path = '/accounts/ClientLogin' => "/accounts/ClientLogin" # Now we are passing in our actual authentication data. # Please visit OAuth For Installed Apps for more information # about the accountType parameter irb(main):014:0> data = \ irb(main):015:0* 'accountType=HOSTED_OR_GOOGLE&Email=your email' \ irb(main):016:0* '&Passwd=your password' \ irb(main):017:0* '&service=wise' => accountType=HOSTED_OR_GOOGLE&Email=your email&Passwd=your password&service=wise" # Set up a hash for the headers irb(main):018:0> headers = \ irb(main):019:0* { 'Content-Type' => 'application/x-www-form-urlencoded'} => {"Content-Type"=>"application/x-www-form-urlencoded"} # Post the request and print out the response to retrieve our authentication token irb(main):020:0> resp, data = http.post(path, data, headers) warning: peer certificate won't be verified in this SSL session => [#<Net::HTTPOK 200 OK readbody=true>, "SID=DQAAAIIAAADgV7j4F-QVQjnxdDRjpslHKC3M ... [ snipping out the rest of the authentication strings ] # Strip out our actual token (Auth) and store it irb(main):021:0> cl_string = data[/Auth=(.*)/, 1] => "DQAAAIUAAADzL... [ snip ] # Build our headers hash and add the authorization token irb(main):022:0> headers["Authorization"] = "GoogleLogin auth=#{cl_string}" => "GoogleLogin auth=DQAAAIUAAADzL... [ snip ]
Oke. Jadi, setelah kita diautentikasi, mari kita coba mengambil spreadsheet kita sendiri menggunakan permintaan ke
http://spreadsheets.google.com/feeds/spreadsheets/private/full
Karena ini adalah permintaan yang diautentikasi, kita juga ingin meneruskan header. Sebenarnya, karena kita akan membuat beberapa permintaan untuk berbagai feed, kita sebaiknya menggabungkan fungsi ini ke dalam fungsi sederhana yang akan kita panggil get_feed
.
# Store the URI to the feed since we may want to use it again
irb(main):023:0> spreadsheets_uri = \
irb(main):024:0* 'http://spreadsheets.google.com/feeds/spreadsheets/private/full'
# Create a simple method to obtain a feed
irb(main):025:0> def get_feed(uri, headers=nil)
irb(main):026:1> uri = URI.parse(uri)
irb(main):027:1> Net::HTTP.start(uri.host, uri.port) do |http|
irb(main):028:2* return http.get(uri.path, headers)
irb(main):029:2> end
irb(main):030:1> end
=> nil
# Lets make a request and store the response in 'my_spreadsheets'
irb(main):031:0> my_spreadsheets = get_feed(spreadsheets_uri, headers)
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):032:0> my_spreadsheets
=> #<Net::HTTPOK 200 OK readbody=true>
# Examine our XML (showing only an excerpt here...)
irb(main):033:0> my_spreadsheets.body
=> "<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'>
<id>http://spreadsheets.google.com/feeds/spreadsheets/private/full</id><updated>2008-03-20T20:49:39.211Z</updated>
<category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'/>
<title type='text'>Available Spreadsheets - test.api.jhartmann@gmail.com</title><link rel='alternate' type='text/html' href='http://docs.google.com'/>
<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/spreadsheets/private/full'/><link rel='self' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/spreadsheets/private/full?tfe='/>
<openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><entry>
<id>http://spreadsheets.google.com/feeds/spreadsheets/private/full/o04927555739056712307.4365563854844943790</id><updated>2008-03-19T20:44:41.055Z</updated><category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'/><title type='text'>test02</title><content type='text'>test02</content><link rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/worksheets/o04927555739056712307.4365563854844943790/private/full'/><link rel='alternate' type='text/html' href='http://spreadsheets.google.com/ccc?key=o04927555739056712307.4365563854844943790'/><link rel='self' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/spreadsheets/private/full/o04927555739056712307.4365563854844943790'/><author><name>test.api.jhartmann</name><email>test.api.jhartmann@gmail.com</email></author></entry><entry> ...
Sekali lagi, kita melihat banyak XML yang telah saya kurangi penekanannya di atas karena Anda tidak perlu khawatir untuk memahaminya dari command line. Untuk membuatnya lebih mudah digunakan, mari kita parsing menjadi struktur data menggunakan XmlSimple
:
# Perform imports irb(main):034:0> require 'rubygems' => true irb(main):035:0> require 'xmlsimple' => true irb(main):036:0> doc = \ irb(main):037:0* XmlSimple.xml_in(my_spreadsheets.body, 'KeyAttr' => 'name') # Import the 'pp' module for 'pretty printing' irb(main):038:0> require 'pp' => true # 'Pretty-print' our XML document irb(main):039:0> pp doc {"totalResults"=>["6"], "category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#spreadsheet", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "title"=> [{"type"=>"text", "content"=>"Available Spreadsheets - Test-account"}], "startIndex"=>["1"], "id"=>["http://spreadsheets.google.com/feeds/spreadsheets/private/full"], "entry"=> [{"category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#spreadsheet", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "title"=>[{"type"=>"text", "content"=>"blank"}], "author"=> [{"name"=>["Test-account"], "email"=>["my email"]}], "id"=> ["http://spreadsheets.google.com/feeds/spreadsheets/private/full/o04927555739056712307.3387874275736238738"], "content"=>{"type"=>"text", "content"=>"blank"}, "link"=> [ snipping out the rest of the XML ]
Mendapatkan lembar kerja
Jadi, seperti yang dapat Anda lihat pada output di atas, feed saya berisi 6 spreadsheet. Agar artikel ini singkat, saya telah memotong output XML lainnya di atas (serta di sebagian besar listingan lainnya). Untuk mempelajari spreadsheet ini lebih dalam, kita perlu melakukan beberapa langkah lagi:
- Mendapatkan kunci spreadsheet
- Gunakan kunci spreadsheet untuk mendapatkan feed lembar kerja kami
- Dapatkan ID untuk lembar kerja yang ingin kita gunakan
- Minta cellsFeed atau listFeed untuk mengakses konten sebenarnya dari worksheet
Mungkin terdengar seperti banyak pekerjaan, tetapi saya akan menunjukkan bahwa semuanya cukup mudah jika kita menulis beberapa metode sederhana. cellsFeed dan listFeed adalah dua representasi berbeda untuk konten sel sebenarnya dari worksheet. listFeed mewakili seluruh baris informasi dan direkomendasikan untuk mengirimkan data baru dengan metode POST. cellFeed merepresentasikan setiap sel dan digunakan untuk update sel satu per satu atau update batch ke banyak sel satu per satu (keduanya menggunakan PUT). Lihat dokumentasi Google Spreadsheet API untuk mengetahui detail selengkapnya.
Pertama, kita perlu mengekstrak kunci spreadsheet (ditandai dalam output XML di atas) untuk mendapatkan feed lembar kerja:
# Extract the spreadsheet key from our datastructure irb(main):040:0> spreadsheet_key = \ irb(main):041:0* doc["entry"][0]["id"][0][/full\/(.*)/, 1] => "o04927555739056712307.3387874275736238738" # Using our get_feed method, let's obtain the worksheet feed irb(main):042:0> worksheet_feed_uri = \ irb(main):043:0* "http://spreadsheets.google.com/feeds/worksheets/#{spreadsheet_key}/private/full" => "http://spreadsheets.google.com/feeds/worksheets/o04927555739056712307.3387874275736238738/private/full" irb(main):044:0> worksheet_response = get_feed(worksheet_feed_uri, headers) => #<Net::HTTPOK 200 OK readbody=true> # Parse the XML into a datastructure irb(main):045:0> worksheet_data = \ irb(main):046:0* XmlSimple.xml_in(worksheet_response.body, 'KeyAttr' => 'name') => {"totalResults"=>["1"], "category"=>[{"term ... [ snip ] # And pretty-print it irb(main):047:0> pp worksheet_data {"totalResults"=>["1"], "category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#worksheet", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "title"=>[{"type"=>"text", "content"=>"blank"}], "author"=> [{"name"=>["test.api.jhartmann"], "email"=>["test.api.jhartmann@gmail.com"]}], "startIndex"=>["1"], "id"=> ["http://spreadsheets.google.com/feeds/worksheets/o04927555739056712307.3387874275736238738/private/full"], "entry"=> [{"category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#worksheet", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "title"=>[{"type"=>"text", "content"=>"Sheet 1"}], "rowCount"=>["100"], "colCount"=>["20"], "id"=> ["http://spreadsheets.google.com/feeds/worksheets/o04927555739056712307.3387874275736238738/private/full/od6"], "content"=>{"type"=>"text", "content"=>"Sheet 1"}, "link"=> [{"href"=> "http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full", "rel"=>"http://schemas.google.com/spreadsheets/2006#listfeed", "type"=>"application/atom+xml"}, {"href"=> "http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full", "rel"=>"http://schemas.google.com/spreadsheets/2006#cellsfeed", "type"=>"application/atom+xml"}, [ snip: cutting off the rest of the XML ]
Seperti yang dapat Anda lihat di sini, kita sekarang dapat menemukan link (highlighted above
) untuk mengakses listFeed dan cellsFeed. Sebelum kita membahas listFeed, izinkan saya menjelaskan secara singkat data yang saat ini ada di spreadsheet contoh kita agar Anda tahu apa yang kita cari:
Spreadsheet kita sangat sederhana dan hanya terlihat seperti ini:
language | situs |
---|---|
java | http://java.com |
php | http://php.net |
Berikut tampilan data ini di listFeed:
irb(main):048:0> listfeed_uri = \ irb(main):049:0* worksheet_data["entry"][0]["link"][0]["href"] => "http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full" irb(main):050:0> response = get_feed(listfeed_uri, headers) => #<Net::HTTPOK 200 OK readbody=true> irb(main):051:0> listfeed_doc = \ irb(main):052:0* XmlSimple.xml_in(response.body, 'KeyAttr' => 'name') => {"totalResults"=>["2"], "category"=>[{"term" ... [ snip ] # Again we parse the XML and then pretty print it irb(main):053:0> pp listfeed_doc {"totalResults"=>["2"], "category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#list", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "title"=>[{"type"=>"text", "content"=>"Programming language links"}], "author"=> [{"name"=>["test.api.jhartmann"], "email"=>["test.api.jhartmann@gmail.com"]}], "startIndex"=>["1"], "id"=> ["http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full"], "entry"=> [{"category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#list", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "language"=>["java"], "title"=>[{"type"=>"text", "content"=>"ruby"}], "website"=>["http://java.com"], "id"=> ["http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cn6ca"], "content"=> {"type"=>"text", "content"=>"website: http://java.com"}, "link"=> [{"href"=> "http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cn6ca", "rel"=>"self", "type"=>"application/atom+xml"}, {"href"=> "http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cn6ca/1j81anl6096", "rel"=>"edit", "type"=>"application/atom+xml"}], "updated"=>["2008-03-20T22:19:51.739Z"]}, {"category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#list", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "language"=>["php"], "title"=>[{"type"=>"text", "content"=>"php"}], "website"=>["http://php.net"], "id"=> ["http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cokwr"], "content"=>{"type"=>"text", "content"=>"website: http://php.net"}, [ snip ]
Seperti yang dapat Anda lihat, listFeed menampilkan konten spreadsheet Anda dengan membuat entri untuk setiap baris. Mengasumsikan bahwa baris pertama spreadsheet berisi header sel Anda, lalu membuat header XML secara dinamis berdasarkan data di baris tersebut. Melihat XML sebenarnya akan membantu menjelaskan hal ini lebih lanjut:
<?xml version='1.0' encoding='UTF-8'?><feed [ snip namespaces ]> <id>http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full</id> <updated>2008-03-20T22:19:51.739Z</updated> <category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#list'/> <title type='text'>Programming language links</title> [ snip: cutting out links and author information ] <entry> <id>http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cn6ca</id> [ snip: updated and category ] <title type='text'>java</title> <content type='text'>website: http://java.com</content> <link rel='self' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cn6ca'/> <link rel='edit' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cn6ca/1j81anl6096'/> <gsx:language>java</gsx:language> <gsx:website>http://java.com</gsx:website> </entry> <entry> <id>http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cokwr</id> [ snip: updated and category ] <title type='text'>php</title> <content type='text'>website: http://php.net</content> <link rel='self' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cokwr'/> <link rel='edit' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full/cokwr/41677fi0nc'/> <gsx:language>php</gsx:language> <gsx:website>http://php.net</gsx:website> </entry> </feed>
Untuk perbandingan cepat, mari kita lihat cara informasi yang sama ditampilkan di cellsFeed:
# Extract the cellfeed link irb(main):054:0> cellfeed_uri = \ irb(main):055:0* worksheet_data["entry"][0]["link"][1]["href"] => "http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full" irb(main):056:0> response = \ irb(main):057:0* get_feed(cellfeed_uri, headers) => #<Net::HTTPOK 200 OK readbody=true> # Parse into datastructure and print irb(main):058:0> cellfeed_doc = \ irb(main):059:0* XmlSimple.xml_in(response.body, 'KeyAttr' => 'name') => {"totalResults"=>["6"], [ snip ] irb(main):060:0> pp cellfeed_doc {"totalResults"=>["6"], "category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#cell", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "title"=>[{"type"=>"text", "content"=>"Programming language links"}], "rowCount"=>["101"], "colCount"=>["20"], "author"=> [{"name"=>["test.api.jhartmann"], "email"=>["test.api.jhartmann@gmail.com"]}], "startIndex"=>["1"], "id"=> ["http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full"], "entry"=> [{"category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#cell", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "cell"=> [{"col"=>"1", "row"=>"1", "content"=>"language", "inputValue"=>"language"}], "title"=>[{"type"=>"text", "content"=>"A1"}], "id"=> ["http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R1C1"], "content"=>{"type"=>"text", "content"=>"language"}, "link"=> [{"href"=> "http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R1C1", "rel"=>"self", "type"=>"application/atom+xml"}, {"href"=> "http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R1C1/8srvbs", "rel"=>"edit", "type"=>"application/atom+xml"}], "updated"=>["2008-03-20T22:19:51.739Z"]}, [ snip ]
Seperti yang dapat Anda lihat di sini, 6 entri ditampilkan, satu untuk setiap sel. Saya telah memotong semua output lainnya selain nilai untuk sel A1, yang berisi kata 'language'. Perhatikan juga link edit yang ditampilkan di atas. Link ini berisi string versi (8srvbs) di bagian akhir. String versi penting saat memperbarui data sel, seperti yang akan kita lakukan di akhir artikel ini. Hal ini memastikan bahwa update tidak ditimpa. Setiap kali membuat permintaan PUT untuk memperbarui data sel, Anda harus menyertakan string versi terbaru sel dalam permintaan. String versi baru akan ditampilkan setelah setiap update.
Memposting konten ke listFeed
Hal pertama yang kita butuhkan untuk memposting konten adalah link POST untuk listFeed. Link ini akan ditampilkan saat feed daftar diminta. Elemen ini akan berisi URL http://schemas.google.com/g/2005#post
sebagai nilai untuk atribut rel
. Anda harus mengurai elemen link ini dan mengekstrak atribut href
-nya. Pertama, kita akan membuat metode kecil untuk mempermudah postingan:
irb(main):061:0> def post(uri, data, headers) irb(main):062:1> uri = URI.parse(uri) irb(main):063:1> http = Net::HTTP.new(uri.host, uri.port) irb(main):064:1> return http.post(uri.path, data, headers) irb(main):065:1> end => nil # Set up our POST url irb(main):066:0> post_url = \ irb(main):067:0* "http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full" => "http://spreadsheets.google.com/feeds/list/o04927555739056712307.3387874275736238738/od6/private/full" # We must use 'application/atom+xml' as MIME type so let's change our headers # which were still set to 'application/x-www-form-urlencoded' when we sent our # ClientLogin information over https irb(main):068:0> headers["Content-Type"] = "application/atom+xml" => "application/atom+xml" # Setting up our data to post, using proper namespaces irb(main):069:0> new_row = \ irb(main):070:0* '<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">' << irb(main):071:0* '<gsx:language xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">' << irb(main):072:0* 'ruby</gsx:language>' << irb(main):073:0* '<gsx:website xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">' << irb(main):074:0* 'http://ruby-lang.org</gsx:website>' << irb(main):075:0* '</atom:entry>' => "<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\"><gsx:language ... [ snip ] # Performing the post irb(main):076:0> post_response = post(post_url, new_row, headers) => #<Net::HTTPCreated 201 Created readbody=true>
Status 201 menunjukkan bahwa postingan kita berhasil.
Menggunakan cellsFeed untuk memperbarui konten
Dari dokumentasi, kita dapat melihat bahwa feed sel lebih memilih permintaan PUT pada konten yang ada. Namun, karena informasi yang kita ambil dari cellsFeed di atas sebelumnya hanyalah data yang sudah ada di spreadsheet kita, bagaimana cara menambahkan informasi baru? Kita hanya perlu membuat permintaan untuk setiap sel kosong yang ingin kita masukkan datanya. Cuplikan di bawah menunjukkan cara mengambil sel kosong R5C1 (Baris 5, Kolom 1) tempat kita ingin menyisipkan beberapa informasi tentang bahasa pemrograman Python.
Variabel cellfeed_uri
asli kami hanya berisi URI untuk cellfeed itu sendiri. Sekarang kita ingin menambahkan sel yang akan diedit dan mendapatkan string versi sel tersebut untuk melakukan pengeditan:
# Set our query URI irb(main):077:0> cellfeed_query = cellfeed_uri + '/R5C1' => "http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R5C1" # Request the information to extract the edit link irb(main):078:0> cellfeed_data = get_feed(cellfeed_query, headers) => #<Net::HTTPOK 200 OK readbody=true> irb(main):079:0> cellfeed_data.body => "<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006' xmlns:batch='http://schemas.google.com/gdata/batch'>
<id>http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R5C1</id>
<updated>2008-03-24T21:55:36.462Z</updated>
<category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#cell'/>
<title type='text'>A5</title>
<content type='text'>
</content>
<link rel='self' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R5C1'/>
<link rel='edit' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R5C1/47pc'/>
<gs:cell row='5' col='1' inputValue=''>
</gs:cell>
</entry>"
Seperti yang dapat Anda lihat dalam daftar kode di atas, string versi adalah 47pc
. (Anda mungkin perlu men-scroll ke sisi kanan.) Untuk mempermudah, mari kita buat metode praktis yang memberi kita string versi untuk sel yang kita minati:
irb(main):080:0> def get_version_string(uri, headers=nil) irb(main):081:1> response = get_feed(uri, headers) irb(main):082:1> require 'rexml/document' irb(main):083:1> xml = REXML::Document.new response.body irb(main):084:1> edit_link = REXML::XPath.first(xml, '//[@rel="edit"]') irb(main):085:1> edit_link_href = edit_link.attribute('href').to_s irb(main):086:1> return edit_link_href.split(/\//)[10] irb(main):087:1> end => nil # A quick test irb(main):088:0> puts get_version_string(cellfeed_query, headers) 47pc => nil
Sekalian saja, kita juga dapat menulis metode untuk melakukan permintaan PUT, atau lebih baik lagi, kita dapat menulis metode untuk melakukan seluruh update batch. Fungsi kita akan mengambil array hash yang berisi variabel berikut:
:batch_id
- ID unik untuk setiap bagian permintaan batch.:cell_id
- ID sel yang akan diupdate dalam format R#C#, dengan sel A1 akan ditampilkan sebagai R1C1.:data
- Data yang ingin kita sisipkan.
irb(main):088:0> def batch_update(batch_data, cellfeed_uri, headers) irb(main):089:1> batch_uri = cellfeed_uri + '/batch' irb(main):090:1> batch_request = <<FEED irb(main):091:1" <?xml version="1.0" encoding="utf-8"?> \ irb(main):092:1" <feed xmlns="http://www.w3.org/2005/Atom" \ irb(main):093:1" xmlns:batch="http://schemas.google.com/gdata/batch" \ irb(main):094:1" xmlns:gs="http://schemas.google.com/spreadsheets/2006" \ irb(main):095:1" xmlns:gd="http://schemas.google.com/g/2005"> irb(main):096:1" <id>#{cellfeed_uri}</id> irb(main):097:1" FEED irb(main):098:1> batch_data.each do |batch_request_data| irb(main):099:2* version_string = get_version_string(cellfeed_uri + '/' + batch_request_data[:cell_id], headers) irb(main):100:2> data = batch_request_data[:data] irb(main):101:2> batch_id = batch_request_data[:batch_id] irb(main):102:2> cell_id = batch_request_data[:cell_id] irb(main):103:2> row = batch_request_data[:cell_id][1,1] irb(main):104:2> column = batch_request_data[:cell_id][3,1] irb(main):105:2> edit_link = cellfeed_uri + '/' + cell_id + '/' + version_string irb(main):106:2> batch_request<< <<ENTRY irb(main):107:2" <entry> irb(main):108:2" <gs:cell col="#{column}" inputValue="#{data}" row="#{row}"/> irb(main):109:2" <batch:id>#{batch_id}</batch:id> irb(main):110:2" <batch:operation type="update" /> irb(main):111:2" <id>#{cellfeed_uri}/#{cell_id}</id> irb(main):112:2" <link href="#{edit_link}" rel="edit" type="application/atom+xml" /> irb(main):113:2" </entry> irb(main):114:2" ENTRY irb(main):115:2> end irb(main):116:1> batch_request << '</feed>' irb(main):117:1> return post(batch_uri, batch_request, headers) irb(main):118:1> end => nil # Our sample batch data to insert information about the Python programming language into our worksheet irb(main):119:0> batch_data = [ \ irb(main):120:0* {:batch_id => 'A', :cell_id => 'R5C1', :data => 'Python'}, \ irb(main):121:0* {:batch_id => 'B', :cell_id => 'R5C2', :data => 'http://python.org' } ] => [{:cell_id=>"R5C1", :data=>"Python", :batch_id=>"A"}=>{:cell_id=>"R5C2", :data=>"http://python.org", :batch_id=>"B"}] # Perform the update irb(main):122:0> response = batch_update(batch_data, cellfeed_uri, headers) => #<Net::HTTPOK 200 OK readbody=true> # Parse the response.body XML and print it irb(main):123:0> response_xml = XmlSimple.xml_in(response.body, 'KeyAttr' => 'name') => [ snip ] irb(main):124:0> pp response_xml {"title"=>[{"type"=>"text", "content"=>"Batch Feed"}], "xmlns:atom"=>"http://www.w3.org/2005/Atom", "id"=> ["http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full"], "entry"=> [{"status"=>[{"code"=>"200", "reason"=>"Success"}], "category"=> [{"term"=>"http://schemas.google.com/spreadsheets/2006#cell", "scheme"=>"http://schemas.google.com/spreadsheets/2006"}], "cell"=> [{"col"=>"1", "row"=>"5", "content"=>"Python", "inputValue"=>"Python"}], "title"=>[{"type"=>"text", "content"=>"A5"}], "id"=> ["http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R5C1", "A"], "operation"=>[{"type"=>"update"}], "content"=>{"type"=>"text", "content"=>"Python"}, "link"=> [{"href"=> "http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R5C1", "rel"=>"self", "type"=>"application/atom+xml"}, {"href"=> "http://spreadsheets.google.com/feeds/cells/o04927555739056712307.3387874275736238738/od6/private/full/R5C1/49kwzg", "rel"=>"edit", "type"=>"application/atom+xml"}], "updated"=>["2008-03-27T15:48:48.470Z"]}, [ snip ]
Seperti yang dapat Anda lihat, permintaan batch kita berhasil karena kita telah menerima kode respons 200 OK. Dengan mengurai XML respons, kita dapat melihat bahwa pesan terpisah ditampilkan untuk setiap :batch_id
yang kita tetapkan dalam array response_data
. Untuk mengetahui informasi selengkapnya tentang pemrosesan batch, lihat dokumentasi Pemrosesan Batch di GData.
Kesimpulan
Seperti yang telah Anda lihat, sangat mudah menggunakan shell interaktif Ruby untuk bereksperimen dengan Google Data API. Kita dapat mengakses spreadsheet dan lembar kerja menggunakan listFeed dan cellsFeed. Selain itu, kami telah menyisipkan beberapa data baru menggunakan permintaan POST, lalu menulis metode untuk melakukan update batch hanya dengan sekitar 120 baris kode. Mulai dari sini, tidak akan terlalu sulit untuk menggabungkan beberapa metode sederhana ini ke dalam class dan membuat framework yang dapat digunakan kembali.
Bergabunglah dengan grup diskusi kami jika ada pertanyaan tentang penggunaan alat ini dengan Google Data API favorit Anda.
File class dengan contoh kode yang dijelaskan di atas dapat ditemukan di http://code.google.com/p/google-data-samples-ruby