अप्रैल 2008
- शुरुआती जानकारी
- Ruby इंस्टॉल और इंस्टॉल करना
- पुष्टि करना | 'स्प्रेडशीट एपीआई' का इस्तेमाल करना
- वर्कशीट पाना
- सूचीफ़ीड में कॉन्टेंट पोस्ट करना
- कॉन्टेंट अपडेट करने के लिए, सेलफ़ीड का इस्तेमाल करना
- निष्कर्ष
सुविधा के बारे में जानकारी
रूबी एक डाइनैमिक स्क्रिप्टिंग भाषा है जिसे हाल ही के कुछ सालों में, रेल के वेब डेवलपमेंट के फ़्रेमवर्क की वजह से बहुत पसंद किया गया है. इस लेख में, Google Data API सेवाओं के साथ इंटरैक्ट करने के लिए, Ruby का इस्तेमाल करने का तरीका बताया गया है. इसके बजाय, हम रेल पर ध्यान नहीं देते हैं. इसके बजाय, हम मूल एचटीटीपी निर्देशों और फ़ीड के स्ट्रक्चर के बारे में ज़्यादा जानकारी देना चाहते हैं. यहां दिए गए सभी उदाहरणों को irb, Ruby के इंटरैक्टिव शेल का इस्तेमाल करके, कमांड लाइन से फ़ॉलो किया जा सकता है.
जैसा कि आपको cURL लेख से याद होगा, Google Data API वेब संसाधन दिखाने, बनाने, और उन्हें अपडेट करने के लिए, ऐटम पब्लिशिंग प्रोटोकॉल का इस्तेमाल करता है. इस प्रोटोकॉल की सुंदरता यह है कि मानक HTTP क्रियाओं का इस्तेमाल ऐसे अनुरोध तैयार करने के लिए किया जाता है जिनका जवाब मानक HTTP स्थिति कोड के साथ दिया जाता है.
इस लेख में हम कॉन्टेंट को फिर से पाने के लिए, GET का इस्तेमाल करके नया कॉन्टेंट अपलोड करने के लिए POST और मौजूदा कॉन्टेंट को अपडेट करने के लिए PUT जोड़ें. 'Google डेटा एपीआई' का इस्तेमाल करते समय आपको कुछ स्टैंडर्ड कोड मिल सकते हैं. 200, किसी फ़ीड या एंट्री को पाने में सफल होने के बारे में बताते हैं. इसके अलावा, किसी संसाधन को पूरी तरह से बनाने या अपडेट करने के लिए 201 तय किए गए हैं. अगर कोई गड़बड़ी होती है, जैसे कि गलत अनुरोध भेजा जाता है, तो 400 कोड ('गलत अनुरोध') वापस भेज दिया जाएगा. जवाब के मुख्य भाग में एक ज़्यादा जानकारी वाला मैसेज दिया जाएगा और बताया जाएगा कि क्या गड़बड़ी हुई.
Ruby, 'Net' मॉड्यूल के हिस्से के रूप में कोई अच्छा डीबग करने का विकल्प देता है. हालांकि, हमने इन सभी सैंपल को छोटा रखने के लिए, इसे यहां चालू नहीं किया है.
Ruby पाना और इंस्टॉल करना
अगर आप Linux का इस्तेमाल कर रहे हैं, तो Ruby को इंस्टॉल करने के लिए, ज़्यादातर पैकेज मैनेजमेंट सिस्टम इस्तेमाल किए जा सकते हैं. अन्य ऑपरेटिंग सिस्टम और पूरा सोर्स कोड पाने के लिए, कृपया http://www.ruby-lang.org/en/download/ देखें. Irb, हम इन उदाहरणों के लिए जिन इंटरैक्टिव शेल का इस्तेमाल करेंगे, उन्हें डिफ़ॉल्ट रूप से इंस्टॉल किया जाना चाहिए. यहां दिए गए कोड के उदाहरणों का पालन करने के लिए, आपको Ruby डेटा के स्ट्रक्चर में एक्सएमएल पार्स करने के लिए एक छोटी लाइब्रेरी, XmlSimple
भी इंस्टॉल करनी होगी. Xml Simple को पाने/इंस्टॉल करने के लिए, कृपया http://xml-Simple.rubyforge.org/ पर जाएं
जब आपकी मशीन पर Ruby की एक कॉपी चलने लगे, तब आप Google की डेटा सेवाओं के लिए बुनियादी अनुरोध करने के लिए, Net:HTTP
पैकेज का इस्तेमाल कर सकते हैं. नीचे दिया गया स्निपेट, Ruby के इंटरैक्टिव शेल से इंपोर्ट करने का ज़रूरी तरीका दिखाता है. हम 'net/http' पैकेज की आवश्यकता के लिए, YouTube से शीर्ष रेट किए गए वीडियो फ़ीड के URL को पार्स करने और फिर एक 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>
उस अनुरोध को कमांड लाइन तक एक्सएमएल का थोड़ा-सा इकोल होना चाहिए. आपने देखा होगा कि सभी आइटम <feed> एलिमेंट में होते हैं और उन्हें <enter> एलिमेंट कहा जाता है. हमें अभी एक्सएमएल फ़ॉर्मैटिंग के बारे में चिंता करने की ज़रूरत नहीं है, मैं सिर्फ़ एचटीटीपी का इस्तेमाल करके एक बुनियादी Google Data API अनुरोध करने का तरीका बताना चाहता/चाहती हूं. हम अभी एपीआई स्विच करने जा रहे हैं और स्प्रेडशीट पर फ़ोकस कर रहे हैं, क्योंकि जो जानकारी हम भेज सकते हैं और वापस पा सकते हैं, वह 'कमांड-लाइन फ़्रेंडली' है.
पुष्टि करना | Google Spreadsheets API का इस्तेमाल करना
हम एंट्री एलिमेंट के फ़ीड को फिर से फ़ेच करके शुरू करेंगे. इस बार हम अपनी स्प्रेडशीट के साथ काम करना चाहेंगे. ऐसा करने के लिए, हमें सबसे पहले Google खातों की सेवा से पुष्टि करनी होगी.
जैसा कि आपको GData प्रमाणीकरण में दिए गए दस्तावेज़ से याद आ सकता है, Google सेवाओं के साथ प्रमाणीकरण करने के दो तरीके हैं. AuthSub वेब-आधारित ऐप्लिकेशन के लिए है और कम शब्दों में, इसमें टोकन-एक्सचेंज की प्रोसेस शामिल है. AuthSub का असल फ़ायदा यह है कि आपके ऐप्लिकेशन को उपयोगकर्ता क्रेडेंशियल सेव करने की ज़रूरत नहीं होती है. ClientLogin, "इंस्टॉल किए गए" ऐप्लिकेशन के लिए है. ClientLogin प्रक्रिया में, Google की सेवाओं को https के माध्यम से उपयोगकर्ता नाम और पासवर्ड के साथ एक स्ट्रिंग भेजी जाती है जो उस सेवा की पहचान करती है जिसका आप उपयोग करना चाहते हैं. Google Spreadsheets API सेवा को स्ट्रिंग के अनुसार समझदारी से पहचाना जाता है.
वापस अपने इंटरैक्टिव शेल पर स्विच करके, Google से पुष्टि करें. ध्यान दें कि हम पुष्टि करने के अनुरोध और क्रेडेंशियल भेजने के लिए, https का इस्तेमाल कर रहे हैं:
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 ]
ठीक है। अब हमें आपकी पुष्टि हो चुकी है. इसलिए, हम यह अनुरोध करते हैं कि
http://spreadsheets.google.com/feeds/spreadsheets/private/full
यह एक पुष्टि किया गया अनुरोध है, इसलिए हम अपने हेडर भी भेजना चाहते हैं. दरअसल, हम अलग-अलग फ़ीड के लिए कई अनुरोध करेंगे, इसलिए हम इस फ़ंक्शन को एक आसान फ़ंक्शन में डाल सकते हैं. इसे हम 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> ...
मुझे फिर बहुत सारा एक्सएमएल दिख रहा है, जिसकी चर्चा मैंने ऊपर कर दी है. ऐसा इसलिए, क्योंकि आपको इसे कमांड लाइन से समझने की ज़रूरत नहीं है. चीज़ों को ज़्यादा उपयोगकर्ता के लिए आसान बनाने के लिए, हमें 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 ]
वर्कशीट पाना
इसलिए, जैसा कि आप ऊपर दिए गए आउटपुट में देख सकते हैं, मेरे फ़ीड में 6 स्प्रेडशीट हैं. इस लेख को छोटा रखने के लिए, मैंने ऊपर दिए गए बाकी एक्सएमएल आउटपुट को काट दिया है (साथ ही, ज़्यादातर दूसरी लिस्टिंग में भी). इस स्प्रेडशीट की ज़्यादा जानकारी के लिए, हमें कुछ और चरण पूरे करने होंगे:
- स्प्रेडशीट कुंजी पाएं
- हमारी वर्कशीट फ़ीड पाने के लिए स्प्रेडशीट कुंजी का उपयोग करें
- उस वर्कशीट के लिए आईडी पाएं जिसका हम उपयोग करना चाहते हैं
- वर्कशीट का असल कॉन्टेंट ऐक्सेस करने के लिए, SalesforceFeed या listFeed से संपर्क करें
ऐसा लग सकता है कि यह काम काफ़ी आसान है. हालांकि, अगर हम कुछ आसान तरीके लिखते हैं, तो हम आपको बताएंगे कि यह तरीका काफ़ी आसान है. सेलफ़ीड और listFeed, वर्कशीट की असल सेल के कॉन्टेंट को दो अलग-अलग तरह से दिखाते हैं. listFeed जानकारी की एक पूरी पंक्ति दिखाता है. साथ ही, हमारा सुझाव है कि नया डेटा पोस्ट करें. सेलफ़ीड अलग-अलग सेल के बारे में बताता है. इसका इस्तेमाल, अलग-अलग सेल अपडेट या अलग-अलग सेल के बैच अपडेट (दोनों को पीयूटी का इस्तेमाल करके) के लिए किया जाता है. ज़्यादा जानकारी के लिए, कृपया Google Spreadsheets API दस्तावेज़ देखें.
पहले हमें वर्कशीट कुंजी निकालने की ज़रूरत है (ऊपर दिए गए एक्सएमएल आउटपुट में हाइलाइट किया गया है) इसके बाद वर्कशीट फ़ीड पाना होगा:
# 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 ]
जैसा कि यहां देखा जा सकता है, अब हमें listFeed औरcellFeed को ऐक्सेस करने के लिए, लिंक (highlighted above
) मिल गए हैं. listFeed के बारे में गहराई से जानने से पहले, मुझे यह समझाएं कि हमारी नमूना स्प्रैडशीट में वर्तमान में कौन सा डेटा मौजूद है, ताकि आपको पता चल जाए कि हम क्या खोज रहे हैं:
हमारी स्प्रेडशीट बहुत आसान है और बस इस तरह दिखती है:
भाषा | वेबसाइट |
---|---|
Java | http://java.com |
php | http://php.net |
सूची-फ़ीड में यह डेटा कुछ ऐसा दिखता है:
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 ]
जैसा कि आप देख सकते हैं, listFeed हर पंक्ति के लिए एक एंट्री बनाकर, आपकी वर्कशीट का कॉन्टेंट दिखाता है. इसमें यह माना जाता है कि स्प्रेडशीट की पहली पंक्ति में आपके सेल हेडर हैं और फिर उस पंक्ति के डेटा के आधार पर डाइनैमिक रूप से एक्सएमएल हेडर जनरेट करते हैं. असल एक्सएमएल को देखकर, आपको आगे यह जानकारी मिल जाएगी:
<?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>
तेज़ी से तुलना के लिए, हम देखते हैं कि सेलफ़ीड में वही जानकारी कैसे दिखाई जाती है:
# 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 ]
जैसा कि यहां देखा जा सकता है, हर सेल के लिए एक 6 एंट्री मिलती है. मैंने सेल A1 की वैल्यू के अलावा, दूसरे सभी आउटपुट को काट दिया है. इसमें 'भाषा' शब्द मौजूद है. साथ ही, ऊपर दिखाए गए बदलाव करें लिंक पर भी ध्यान दें. इस लिंक के आखिर में एक वर्शन स्ट्रिंग (8srbs) मौजूद है. सेल डेटा को अपडेट करते समय वर्शन स्ट्रिंग ज़रूरी होती है, जैसा कि हम इस लेख के आखिर में करेंगे. इससे यह पक्का होता है कि अपडेट ओवरराइट नहीं होते हैं. सेल डेटा को अपडेट करने के लिए जब आप एक PUT अनुरोध कर रहे हों, तो आपको अपने अनुरोध में सेल की सबसे हाल की वर्शन स्ट्रिंग शामिल करनी होगी. हर अपडेट के बाद, नए वर्शन की स्ट्रिंग दिखेगी.
listFeed में सामग्री पोस्ट कर रहा है
कॉन्टेंट पोस्ट करने के लिए सबसे पहले हमें पोस्टफ़ीड लिंक पोस्ट करना ज़रूरी होता है. सूची फ़ीड का अनुरोध करने पर यह लिंक दिखेगा. इसमें rel
एट्रिब्यूट की वैल्यू के तौर पर, http://schemas.google.com/g/2005#post
यूआरएल शामिल होगा. आपको लिंक के इस एलिमेंट को पार्स करना होगा और इसके href
एट्रिब्यूट को निकालना होगा. सबसे पहले हम पोस्ट करने की प्रक्रिया को आसान बनाने के लिए एक छोटा तरीका बनाएंगे:
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>
201 स्थिति बताती है कि हमारी पोस्ट सफल रही.
कॉन्टेंट अपडेट करने के लिए सेल फ़ीड का इस्तेमाल करना
दस्तावेज़ में यह देखा जा सकता है कि सेल फ़ीड मौजूदा कॉन्टेंट पर PUT अनुरोधों को प्राथमिकता देता है. हालांकि, ऊपर दी गई सेलफ़ीड से मिली जानकारी, सिर्फ़ हमारी वास्तविक स्प्रेडशीट का पहले से मौजूद डेटा है. इसलिए, हम नई जानकारी कैसे जोड़ सकते हैं? हमें हर उस खाली सेल के लिए अनुरोध करना होगा जिसमें हम डेटा डालना चाहते हैं. नीचे दिए गए स्निपेट में खाली सेल R5C1 (पंक्ति 5, कॉलम 1) को वापस पाने का तरीका बताया गया है. इसमें हम Python प्रोग्रामिंग भाषा के बारे में कुछ जानकारी शामिल करना चाहते हैं.
हमारे मूल वैरिएबल cellfeed_uri
में सिर्फ़ सेलफ़ीड के लिए यूआरआई शामिल था. अब हम उस सेल को जोड़ना चाहते हैं जिसमें हम बदलाव करना चाहते हैं. इसके बाद, उस सेल के वर्शन की स्ट्रिंग में बदलाव करना चाहते हैं:
# 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>"
जैसा कि ऊपर दिए गए कोड लिस्ट में देखा जा सकता है, वर्शन स्ट्रिंग 47pc
है. (शायद आपको बिलकुल दाईं ओर स्क्रोल करना पड़े.) काम को आसान बनाने के लिए, हम आसानी से एक ऐसा तरीका बना सकते हैं जो हमें उस सेल के वर्शन स्ट्रिंग की जानकारी दे जिसमें हम दिलचस्पी रखते हैं:
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
इस दौरान, हम PUT अनुरोध के लिए भी एक तरीका लिख सकते हैं या बेहतर तरीके से, हमें पूरे बैच का अपडेट पूरा करने का एक तरीका लिखने दें. हमारा फ़ंक्शन नीचे दिए गए वैरिएबल वाले हैश के कलेक्शन का इस्तेमाल करेगा:
:batch_id
- बैच अनुरोध के हर हिस्से के लिए एक यूनीक आइडेंटिफ़ायर.:cell_id
- सेल का आईडी, R#C# फ़ॉर्मैट में अपडेट किया जाना है. इसमें सेल A1 को R1C1 के तौर पर दिखाया जाएगा.:data
- वह डेटा जिसे हम शामिल करना चाहते हैं.
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 ]
जैसा कि आप देख सकते हैं, हमारा बैच अनुरोध सफल रहा, क्योंकि हमें 200 OK जवाब कोड मिल गया था. रिस्पॉन्स एक्सएमएल को पार्स करते समय, हम देख सकते हैं कि हमने अपनी response_data
कैटगरी में जो भी :batch_id
सेट किया है उसके लिए एक अलग मैसेज दिखता है. बैच प्रोसेसिंग के बारे में ज़्यादा जानकारी के लिए, कृपया GData में बैच प्रोसेसिंग दस्तावेज़ देखें.
नतीजा
जैसा कि आपने देखा होगा, Google Data API के साथ खेलने के लिए Ruby के इंटरैक्टिव शेल का इस्तेमाल करना बहुत आसान है. हम listFeed औरcellFeed, दोनों का इस्तेमाल करके अपनी स्प्रेडशीट और वर्कशीट को ऐक्सेस कर पाए. इसके अलावा, हमने POST के एक अनुरोध का इस्तेमाल करके, कुछ नया डेटा डाला है. इसके बाद, कोड की सिर्फ़ 120 लाइनों वाले बैच को अपडेट करने के लिए, लिखा गया तरीका इस्तेमाल किया है. इस वजह से, इनमें से कुछ आसान तरीकों को क्लास में जोड़ना और अपने लिए फिर से इस्तेमाल होने वाला फ़्रेमवर्क तैयार करना बहुत मुश्किल नहीं है.
अगर इन टूल को इस्तेमाल करने के बारे में आपका कोई पसंदीदा सवाल है, तो कृपया चर्चा समूहों में हमसे जुड़ें.
ऊपर दी गई कोड सैंपल वाली एक क्लास फ़ाइल http://code.google.com/p/google-data-sample-ruby पर मिल सकती है