रेल में Google डेटा का इस्तेमाल करना

एरिक बिडलमैन, Google Data API टीम
फ़रवरी 2009

सुविधा के बारे में जानकारी

"Ruby कहां है क्लाइंट लाइब्रेरी में.?"

हमारे डेवलपर की जुनूनी दिलचस्पी और Ruby on Rails (आरआरआर) की लंबे समय की दिलचस्पी को देखते हुए, मेरे सहकर्मी जेफ़ फ़िशर ने माउंट डूम की गहराई से Ruby यूटिलिटी लाइब्रेरी बनाई है. आपको बता दें कि यह पूरी क्लाइंट लाइब्रेरी नहीं है. हालांकि, यह पुष्टि करने और एक्सएमएल में बदलाव करने जैसी बुनियादी बातों को मैनेज करती है. यह भी ज़रूरी है कि आप REXML मॉड्यूल और XPath का इस्तेमाल करके, ऐटम फ़ीड के साथ काम करें.

दर्शक

यह लेख उन डेवलपर के लिए है जो Ruby का इस्तेमाल करके Google Data API ऐक्सेस करने में दिलचस्पी रखते हैं. खास तौर पर, Ruby on Rails. इसमें यह माना जाता है कि उपयोगकर्ता को Ruby प्रोग्रामिंग भाषा और Rails वेब-डेवलपमेंट फ़्रेमवर्क के बारे में कुछ जानकारी है. मैं ज़्यादातर सैंपल के लिए दस्तावेज़ की सूची वाले एपीआई पर फ़ोकस करता हूं, लेकिन उन सिद्धांतों को किसी भी डेटा एपीआई पर लागू किया जा सकता है.

शुरू करें

ज़रूरी शर्तें

Google Data Ruby Utility लाइब्रेरी इंस्टॉल करना

लाइब्रेरी पाने के लिए, आप सीधे प्रोजेक्ट होस्ट करने वाले लाइब्रेरी सोर्स को डाउनलोड करें या जेम इंस्टॉल करें:

sudo gem install gdata

सलाह: सही तरीके से काम करने के लिए, gem list --local चलाएं और पुष्टि करें कि जेम ठीक से इंस्टॉल किया गया था.

पुष्टि करना

क्लाइंट-लॉगिन

ClientLogin आपके ऐप्लिकेशन को उपयोगकर्ताओं के Google या G Suite खाते में प्रोग्राम के रूप में लॉग इन करने की अनुमति देता है. उपयोगकर्ता के क्रेडेंशियल की पुष्टि करने के बाद, Google पुष्टि करने वाला टोकन जारी करता है, ताकि उसे बाद के एपीआई अनुरोधों में रेफ़र किया जा सके. टोकन समय की तय अवधि के लिए मान्य रहता है. यह समय, हर उस Google सेवा के आधार पर तय किया जाता है जिसके साथ आप काम कर रहे हैं. सुरक्षा कारणों से और अपने उपयोगकर्ताओं को सबसे अच्छा अनुभव देने के लिए, आपको केवल इंस्टॉल किए गए डेस्कटॉप ऐप्लिकेशन को डेवलप करते समय ही ClientLogin का उपयोग करना चाहिए. वेब ऐप्लिकेशन के लिए, AuthSub या OAuth का इस्तेमाल करना बेहतर होगा.

Ruby लाइब्रेरी में हर एपीआई के लिए एक क्लाइंट क्लास होती है. उदाहरण के लिए, दस्तावेज़ों की सूची के डेटा एपीआई में user@gmail.com में लॉग इन करने के लिए, इस कोड स्निपेट का इस्तेमाल करें:

client = GData::Client::DocList.new
client.clientlogin('user@gmail.com', 'pa$$word')

The YouTube Data API would be:

client = GData::Client::YouTube.new
client.clientlogin('user@gmail.com', 'pa$$word')

लागू की गई सेवा क्लास की पूरी सूची देखें. अगर किसी सेवा के लिए क्लाइंट क्लास नहीं है, तो GData::Client::Base क्लास का इस्तेमाल करें. उदाहरण के तौर पर, नीचे दिया गया कोड, उपयोगकर्ताओं को G Suite खाते से लॉग इन करने के लिए मजबूर करता है.

client_login_handler = GData::Auth::ClientLogin.new('writely', :account_type => 'HOSTED')
token = client_login_handler.get_token('user@example.com', 'pa$$word', 'google-RailsArticleSample-v1')
client = GData::Client::Base.new(:auth_handler => client_login_handler)

ध्यान दें: डिफ़ॉल्ट रूप से, लाइब्रेरी accountType के लिए HOSTED_OR_GOOGLE का इस्तेमाल करती है. वैल्यू HOSTED_OR_GOOGLE, HOSTED या GOOGLE हो सकती हैं.

ClientLogin का उपयोग करने का एक नुकसान यह है कि इसमें लॉग इन न कर पाने पर, आपके आवेदन को कैप्चा से जुड़ी चुनौतियां भेजी जा सकती हैं. अगर ऐसा होता है, तो clientlogin() मैथड को इसके अन्य पैरामीटर के साथ कॉल करके गड़बड़ी को ठीक किया जा सकता है: client.clientlogin(username, password, captcha_token, captcha_answer). कैप्चा से निपटने के बारे में ज़्यादा जानकारी के लिए, इंस्टॉल किए गए ऐप्लिकेशन के लिए पुष्टि का पूरा दस्तावेज़ देखें.

पुष्टि करने का तरीका

AuthSubRequest यूआरएल जनरेट करना

scope = 'http://www.google.com/calendar/feeds/'
next_url = 'http://example.com/change/to/your/app'
secure = false  # set secure = true for signed AuthSub requests
sess = true
authsub_link = GData::Auth::AuthSub.get_url(next_url, scope, secure, sess)

कोड के पिछले ब्लॉक में, authsub_link में यह यूआरएल बनाया जाता है:

https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F&session=1&secure=0

क्लाइंट ऑब्जेक्ट के authsub_url तरीके का भी इस्तेमाल किया जा सकता है. हर सर्विस क्लास ने एक authsub_scope एट्रिब्यूट डिफ़ॉल्ट के तौर पर सेट किया है. इसलिए, आपको अलग से एट्रिब्यूट डालने की ज़रूरत नहीं है.

client = GData::Client::DocList.new
next_url = 'http://example.com/change/to/your/app'
secure = false  # set secure = true for signed AuthSub requests
sess = true
domain = 'example.com'  # force users to login to a G Suite hosted domain
authsub_link = client.authsub_url(next_url, secure, sess, domain)

कोड के पिछले ब्लॉक में यह यूआरएल बनता है:

https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fdocs.google.com%2Ffeeds%2F&session=1&secure=0&hd=example.com

सिर्फ़ एक बार इस्तेमाल होने वाले टोकन को सेशन टोकन में अपग्रेड करना

उनके डेटा का ऐक्सेस देने के बाद, AuthSub उपयोगकर्ता को http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN पर वापस रीडायरेक्ट करेगा. ध्यान दें कि सिर्फ़ next_url के इस्तेमाल के बाद, यूआरएल सिर्फ़ क्वेरी पैरामीटर के तौर पर जोड़ा जाता है.

इसके बाद, लंबे समय तक चलने वाले सेशन टोकन के लिए सिंगल-यूज़ टोकन इस्तेमाल करें:

client.authsub_token = params[:token] # extract the single-use token from the URL query params
session[:token] = client.auth_handler.upgrade()
client.authsub_token = session[:token] if session[:token]

सुरक्षित AuthSub बहुत मिलता-जुलता है. टोकन को अपग्रेड करने से पहले, आपको अपनी निजी कुंजी सेट करनी ही होगी:

PRIVATE_KEY = '/path/to/private_key.pem'

client.authsub_token = params[:token]
client.authsub_private_key = PRIVATE_KEY
session[:token] = client.auth_handler.upgrade()
client.authsub_token = session[:token] if session[:token]

ध्यान दें: सुरक्षित टोकन का इस्तेमाल करने के लिए, पक्का करें कि आपने सिर्फ़ एक बार इस्तेमाल किए जाने वाले टोकन के लिए secure=true सेट किया है. ऊपर AuthSubRequest यूआरएल जनरेट करना देखें.

टोकन मैनेजमेंट

AuthSub, टोकन मैनेज करने के लिए दो अतिरिक्त हैंडलर, AuthSubTokenInfo और AuthSubImportToken देता है. टोकन की वैधता की जांच करने के लिए AuthSubTokenInfo उपयोगी होता है. AuthSubRevokeToken उपयोगकर्ताओं को उनके डेटा पर ऐक्सेस बंद करने का विकल्प देता है. आपके ऐप्लिकेशन को AuthSubRevokeToken सबसे सही तरीके के तौर पर इस्तेमाल करना चाहिए. दोनों तरीके, रूबी लाइब्रेरी में काम करते हैं.

टोकन के मेटाडेटा की क्वेरी करने के लिए:

client.auth_handler.info

किसी सेशन टोकन को निरस्त करने के लिए:

client.auth_handler.revoke

AuthSub की पूरी जानकारी के लिए वेब ऐप्लिकेशन के लिए पूरा AuthSub दस्तावेज़ देखें.

OAuth

इस लेख को लिखते समय, OAuth को GData::Auth मॉड्यूल में नहीं जोड़ा गया है.

रेल oauth-plugins या रूबी oauth gem का इस्तेमाल करते समय, यूटिलिटी लाइब्रेरी में OAuth का इस्तेमाल करना आसान होना चाहिए. दोनों ही मामलों में, आपको एक GData::HTTP::Request ऑब्जेक्ट बनाना होगा और उसे हर लाइब्रेरी से जनरेट किए गए Authorization हेडर को पास करना होगा.

फ़ीड ऐक्सेस करना

GET (डेटा लाना)

क्लाइंट ऑब्जेक्ट सेट अप करने के बाद, Google डेटा फ़ीड की क्वेरी के लिए, get() के तरीके का इस्तेमाल करें. XPath का इस्तेमाल खास ऐटम एलिमेंट को पाने के लिए किया जा सकता है. यहां उपयोगकर्ता के Google दस्तावेज़ पाने का एक उदाहरण दिया गया है:

feed = client.get('http://docs.google.com/feeds/documents/private/full').to_xml

feed.elements.each('entry') do |entry|
  puts 'title: ' + entry.elements['title'].text
  puts 'type: ' + entry.elements['category'].attribute('label').value
  puts 'updated: ' + entry.elements['updated'].text
  puts 'id: ' + entry.elements['id'].text
  
  # Extract the href value from each <atom:link>
  links = {}
  entry.elements.each('link') do |link|
    links[link.attribute('rel').value] = link.attribute('href').value
  end
  puts links.to_s
end

POST (नया डेटा बनाना)

सर्वर पर नया डेटा बनाने के लिए, क्लाइंट के post() तरीके का इस्तेमाल करें. यहां दिए गए उदाहरण में, दस्तावेज़ के आईडी के साथ new_writer@example.com को doc_id के तौर पर जोड़ा जाएगा.

# Return documents the authenticated user owns
feed = client.get('http://docs.google.com/feeds/documents/private/full/-/mine').to_xml
entry = feed.elements['entry']  # first <atom:entry>

acl_entry = <<-EOF
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:role value='writer'/>
  <gAcl:scope type='user' value='new_writer@example.com'/>
</entry>
EOF

# Regex the document id out from the full <atom:id>.
# http://docs.google.com/feeds/documents/private/full/document%3Adfrk14g25fdsdwf -> document%3Adfrk14g25fdsdwf
doc_id = entry.elements['id'].text[/full\/(.*%3[aA].*)$/, 1]
response = client.post("http://docs.google.com/feeds/acl/private/full/#{doc_id}", acl_entry)

PUT (डेटा अपडेट करना)

सर्वर पर डेटा अपडेट करने के लिए, क्लाइंट की put() विधि का उपयोग करें. यहां दिए गए उदाहरण से, किसी दस्तावेज़ का शीर्षक अपडेट होगा. इसमें यह मान लिया जाता है कि आपके पास किसी पिछली क्वेरी का फ़ीड है.

entry = feed.elements['entry'] # first <atom:entry>

# Update the document's title
entry.elements['title'].text = 'Updated title'
entry.add_namespace('http://www.w3.org/2005/Atom')
entry.add_namespace('gd','http://schemas.google.com/g/2005')

edit_uri = entry.elements["link[@rel='edit']"].attributes['href']
response = client.put(edit_uri, entry.to_s)

मिटाएं

सर्वर से <atom:enter> या कोई दूसरा डेटा मिटाने के लिए, delete() तरीके का इस्तेमाल करें. नीचे दिया गया उदाहरण, दस्तावेज़ को मिटा देगा. कोड यह मान लेता है कि आपके पास पिछली क्वेरी से एक दस्तावेज़ प्रविष्टि है.

entry = feed.elements['entry'] # first <atom:entry>
edit_uri = entry.elements["link[@rel='edit']"].attributes['href']
client.headers['If-Match'] = entry.attribute('etag').value  # make sure we don't nuke another client's updates
client.delete(edit_uri)

एक नया रेल ऐप्लिकेशन बनाना

आम तौर पर, नया रेल ऐप्लिकेशन बनाने की पहली प्रोसेस में, आपकी एमवीसी फ़ाइलें बनाने के लिए मचान बनाना शामिल होता है. इसके बाद, आपकी डेटाबेस टेबल सेट अप करने के लिए, rake db:migrate चल रहा है. हालांकि, चूंकि हमारा ऐप्स डेटा के लिए Google दस्तावेज़ सूची API की क्वेरी करता है, इसलिए हमें जेनरिक मचान या डेटाबेस की बहुत कम ज़रूरत होती है. इसके बजाय, एक नया ऐप्लिकेशन और आसान नियंत्रक बनाएं:

rails doclist
cd doclist
ruby script/generate controller doclist

और config/environment.rb में ये बदलाव करें:

config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
config.gem 'gdata', :lib => 'gdata'

पहली लाइन, ऐप्लिकेशन से ActiveRecord को हटा देती है. दूसरी लाइन, स्टार्टअप पर gdata जेम लोड करती है.

आखिर में, मैंने डिफ़ॉल्ट रास्ते ('/') को DoclistController में documents कार्रवाई से कनेक्ट करने का विकल्प चुना. इस लाइन को config/routes.rb में जोड़ें:

map.root :controller => 'doclist', :action => 'all'

कंट्रोलर शुरू करना

हमने मचान जनरेट नहीं किया है. इसलिए, app/controllers/doclist_controller.rb में DoclistController में मैन्युअल तौर पर 'all' कार्रवाई जोड़ें.

class DoclistController < ApplicationController
  def all
    @foo = 'I pity the foo!'
  end
end

और app/views/doclist/ के तहत all.html.erb बनाएं:

<%= @foo %>

वेब सर्वर सक्रिय करें और डेवलपमेंट शुरू करें

अब आप ruby script/server को शुरू करके डिफ़ॉल्ट वेब सर्वर को चालू कर पाएंगे. अगर सब कुछ ठीक है, तो ब्राउज़र को 'I pity the foo!' पर ले जाने के लिए, http://localhost:3000/ को दिखाना चाहिए.

सलाह: public/index.html को हटाना या उसका नाम बदलना न भूलें.

सब कुछ ठीक से काम कर लेने के बाद, DocList Manager प्रोजेक्ट के बारे में जानने के लिए, मेरे फ़ाइनल DoclistController और ApplicationController पर नज़र डालें. आप ContactsController भी देखना चाहें, जो कॉल को Google Contacts API पर हैंडल करता है.

नतीजा

Google डेटा रेल ऐप्लिकेशन बनाने का सबसे मुश्किल काम रेल को कॉन्फ़िगर करना है! हालांकि, आपका आवेदन बंद करने का समय है. इसके लिए, मैं Apache के लिए mod_raIL इस्तेमाल करने का सुझाव देता हूं. इसे सेट करना, इंस्टॉल करना और चलाना बहुत आसान है. आप कुछ ही समय में इसे इस्तेमाल करने लगेंगे!

रिसॉर्स

अन्य जानकारी

उदाहरण

DocList Manager, रूबी पर एक पूरा रूबी है जो इस लेख में चर्चा किए गए विषयों को दिखाता है. पूरा सोर्स कोड प्रोजेक्ट होस्टिंग से उपलब्ध है.