شباط (فبراير) 2009
المقدمة
"Where's Ruby is on the list of client مكتبات? "
بدافع من حماسة مطوّري البرامج وشعبية Ruby on السكك الحديدية (ROR) المتواصلة، أنشأ زميلي جيف فيشر مكتبة لمستلزمات لعبة Ruby من أعماق جبل Doom. ضع في اعتبارك أنها ليست مكتبة عميلة كاملة، ولكنها ستتعامل مع الأساسيات مثل المصادقة ومعالجة XML الأساسية. ويتطلّب ذلك أيضًا العمل مباشرةً مع خلاصة Atom باستخدام وحدة REXML وXPath.
الجمهور
هذه المقالة مُعدّة لمطوّري البرامج المهتمين بالوصول إلى واجهات برمجة تطبيقات بيانات Google باستخدام Ruby، خاصة Ruby على السكك الحديدية. وتفترض أنّ القارئ على دراية بلغة برمجة Ruby وإطار عمل تطوير خدمات "السكة الحديدية" على الويب. أركز على واجهة برمجة التطبيقات لقائمة المستندات لمعظم النماذج، ولكن يمكن تطبيق المفاهيم نفسها على أي من واجهات برمجة التطبيقات للبيانات.
البدء
المتطلّبات
- إصدار 1.8.6 لروبي من المستوى 114 أو أكثر تنزيل
- RubyGems 1.3.1 أو الأحدث تنزيل
- السكة الحديدية 2.2.2+ تنزيل
تثبيت مكتبة أداة Google Ruby في Google Data
للحصول على المكتبة، يمكنك إما تنزيل مصدر المكتبة مباشرة من استضافة المشروع أو تثبيت الأداة:
sudo gem install gdata
نصيحة: للحصول على قياس جيد، شغّل gem list --local
للتحقق من تثبيت الجوهرة بشكل صحيح.
المصادقة
ClientLogin
يتيح 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)
ملاحظة: تستخدِم المكتبة HOSTED_OR_GOOGLE
تلقائيًا في accountType
. القيم المحتملة هي HOSTED_OR_GOOGLE
أو HOSTED
أو GOOGLE
.
تتمثل إحدى سلبيات استخدام ClientLogin في إمكانية إرسال تطبيقك لاختبارات CAPTCHA في محاولات تسجيل الدخول الفاشلة. وفي حال حدوث ذلك،
يمكنك التعامل مع الخطأ عن طريق استدعاء الطريقة clientlogin()
مع معلماتها الإضافية:
client.clientlogin(username, password, captcha_token, captcha_answer)
. ارجع إلى وثائق مصادقة التطبيقات المثبتة الكاملة للحصول على مزيد من المعلومات حول التعامل مع اختبارات CAPTCHA.
AuthSub
جارٍ إنشاء عنوان URL لـ 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)
تؤدي كتلة الرمز السابقة إلى إنشاء عنوان URL التالي في 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)
تؤدي الكتلة السابقة من الشفرة إلى إنشاء عنوان URL التالي:
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
بعد
منحه إمكانية الوصول إلى بياناته. لاحظ أن عنوان URL هو 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
عند طلب رمز مميّز يُستخدم لمرة واحدة. راجع إنشاء عنوان URL لـ AuthSubRequest أعلاه.
إدارة الرموز المميزة
توفّر AuthSub معالجَين إضافيَين، وهما AuthSubTokenInfo و
AuthSubإبطالToken لإدارة الرموز المميّزة. AuthSubTokenInfo
مفيد للتحقق من صلاحية الرمز المميز. تمنح خدمة AuthSubRevokeToken
المستخدمين خيار إيقاف الوصول إلى بياناتهم. ويجب أن يستخدم تطبيقك AuthSubRevokeToken
كأفضل ممارسة. تتوفّر كلتا الطريقتين في مكتبة Ruby.
للاستعلام عن البيانات الوصفية للرمز المميز:
client.auth_handler.info
لإبطال رمز مميز للجلسة:
client.auth_handler.revoke
اطلع على وثائق مصادقة AuthSub لتطبيقات الويب الكاملة لمعرفة التفاصيل الدقيقة حول AuthSub.
OAuth
أثناء كتابة هذه المقالة، لم تتم إضافة OAuth إلى الوحدة GData::Auth
.
يجب أن يكون استخدام OAuth في مكتبة المرافق واضحًا نسبيًا عند استخدام القضبان oauth-plugin أو
Ruby oauth gem. وفي كلتا الحالتين، ستحتاج إلى إنشاء كائن GData::HTTP::Request
وتمريره العنوان Authorization
الذي تنشئه كل مكتبة.
الوصول إلى الخلاصات
GET (جلب البيانات)
بعد إعداد كائن عميل، استخدِم طريقة get()
لطلب بحث عن خلاصة بيانات في Google. يمكن استخدام XPath
لاسترداد عناصر Atom محددة. في ما يلي مثال لاسترداد مستندات 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:أو إدخال آخر من البيانات من الخادم، استخدم طريقة 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)
إنشاء تطبيق جديد لخطوط السكك الحديدية
عادةً ما يتطلب الأمر الأول عند إنشاء تطبيق السكك الحديدية الجديد تشغيل مولدات السقالات لإنشاء ملفات MVC.
بعد ذلك، يتم تشغيل rake db:migrate
لإعداد جداول قاعدة البيانات. ومع ذلك، ونظرًا لأن تطبيقنا سيبحث في واجهة برمجة التطبيقات لقائمة مستندات Google عن البيانات، فلم نعد بحاجة إلى أي سقالات أو قواعد بيانات عامة. بدلاً من ذلك، أنشئ تطبيقًا جديدًا ووحدة تحكم بسيطة:
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
عند بدء التشغيل.
أخيرًا، اخترت ربط المسار التلقائي ('/
') بالإجراء documents
في DoclistController
.
إضافة هذا السطر إلى config/routes.rb
:
map.root :controller => 'doclist', :action => 'all'
بدء وحدة تحكم
نظرًا لأننا لم ننشئ أي سقالات، فأضف إجراء باسم "all
" يدويًا إلى DoclistController
في app/controllers/doclist_controller.rb
.
class DoclistController < ApplicationController def all @foo = 'I pity the foo!' end end
وأنشئ all.html.erb
ضمن app/views/doclist/
:
<%= @foo %>
ابدأ تشغيل خادم الويب وابدأ التطوير
من المفترض أن يصبح بإمكانك الآن بدء خادم الويب التلقائي من خلال استدعاء ruby script/server
.
إذا كان كل شيء على ما يرام، يجب أن يؤدي توجيه المتصفح إلى http://localhost:3000/
إلى عرض "I pity the foo!
".
نصيحة: لا تنس إزالة public/index.html
أو إعادة تسميتها.
بعد الانتهاء من الإجراءات، ألقِ نظرة على
DoclistController
النهائي
وApplicationController
للاطلاع على
مشروع مشروع DocList Manager. ستحتاج أيضًا إلى الاطّلاع على
ContactsController
، الذي يتعامل
مع المكالمات الواردة إلى واجهة برمجة تطبيقات "جهات اتصال Google".
الخاتمة
أصعب شيء في إنشاء تطبيق Google Datarails هو تهيئة Trains! ومع ذلك، تتمثّل الخطوة الثانية في نشر تطبيقك. ولذلك، أوصي بشدة باستخدام mod_rails لنظام Apache. من السهل جدًا إعداده وتثبيته وتشغيله. ستتمكن من البدء في وقت قصير!
الموارد
- قائمة بواجهات برمجة التطبيقات لبيانات Google
- صفحة مشروع مكتبة بيانات Google Ruby
- مقالة: استخدام Ruby مع Google Data APIs
- تنزيل Ruby
- تنزيل RubyGems وRrails
الملحق
أمثلة
يعتبر DocList Manager نموذجًا كاملاً لـ Ruby on السكك الحديدية يوضح الموضوعات التي تمت مناقشتها في هذه المقالة. تتوفر شفرة المصدر الكاملة من خلال استضافة المشروع.