فبراير 2009
مقدمة
"أين يمكنني العثور على Ruby في قائمة مكتبات البرامج للعملاء؟"
بفضل الإقبال الشديد من المطوّرين على استخدام Ruby on Rails (RoR) وشعبيتها الدائمة، تمكّن زميلي "جيف فيشر" من إنشاء مكتبة أدوات Ruby من أعماق "جبل الهلاك". يُرجى العِلم أنّها ليست مكتبة عملاء كاملة، ولكنّها تتعامل مع الأساسيات، مثل المصادقة ومعالجة XML الأساسية. يتطلّب ذلك أيضًا العمل مباشرةً مع خلاصة Atom باستخدام وحدة REXML وXPath.
الجمهور
هذه المقالة مخصّصة للمطوّرين المهتمين بالوصول إلى Google Data APIs باستخدام Ruby، وتحديدًا Ruby on Rails. يفترض هذا الدليل أنّ القارئ على دراية ببعض أساسيات لغة البرمجة Ruby وإطار عمل Rails لتطوير الويب. أركّز في معظم الأمثلة على واجهة برمجة التطبيقات لقائمة المستندات، ولكن يمكن تطبيق المفاهيم نفسها على أي من واجهات برمجة التطبيقات للبيانات.
البدء
المتطلبات
تثبيت مكتبة الأدوات المساعدة للغة Ruby في Google Data
للحصول على المكتبة، يمكنك إما تنزيل مصدر المكتبة مباشرةً من خدمة استضافة المشاريع أو تثبيت Gem:
sudo gem install gdata
ملاحظة: من الأفضل تشغيل gem list --local
للتأكّد من تثبيت Gem بشكل صحيح.
المصادقة
ClientLogin
تسمح ClientLogin لتطبيقك بتسجيل دخول المستخدمين آليًا إلى حساباتهم على Google أو G Suite. بعد التحقّق من صحة بيانات اعتماد المستخدم، تصدر Google رمز مصادقة يمكن الرجوع إليه في طلبات واجهة برمجة التطبيقات اللاحقة. يظل الرمز المميّز صالحًا لمدة زمنية محددة، يحدّدها أي خدمة من خدمات Google تستخدمها. لأسباب أمنية ولتوفير أفضل تجربة للمستخدمين، يجب استخدام ClientLogin فقط عند تطوير تطبيقات مثبَّتة على أجهزة الكمبيوتر. بالنسبة إلى تطبيقات الويب، يُفضّل استخدام AuthSub أو OAuth.
تحتوي مكتبة Ruby على فئة عميل لكل واجهة من واجهات برمجة التطبيقات. على سبيل المثال، استخدِم مقتطف الرمز البرمجي التالي لتسجيل الدخول إلى [email protected]
Documents List Data API:
client = GData::Client::DocList.new client.clientlogin('[email protected]', 'pa$$word')
The YouTube Data API would be:
client = GData::Client::YouTube.new client.clientlogin('[email protected]', '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=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%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=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%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]
تتشابه Secure 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 لطلب AuthSub أعلاه.
إدارة الرموز المميزة
توفّر خدمة AuthSub معالجَين إضافيَّين، هما AuthSubTokenInfo وAuthSubRevokeToken، لإدارة الرموز المميزة. تكون السمة AuthSubTokenInfo
مفيدة للتحقّق من صلاحية الرمز المميّز. يمنح AuthSubRevokeToken
المستخدمين خيار إيقاف إمكانية الوصول إلى بياناتهم. يجب أن يستخدم تطبيقك AuthSubRevokeToken
كأفضل ممارسة. تتوافق كلتا الطريقتين مع مكتبة Ruby.
للاستعلام عن البيانات الوصفية لرمز مميّز، اتّبِع الخطوات التالية:
client.auth_handler.info
لإبطال رمز مميّز لجلسة، اتّبِع الخطوات التالية:
client.auth_handler.revoke
اطّلِع على مستندات مصادقة AuthSub لتطبيقات الويب الكاملة للحصول على التفاصيل الكاملة حول AuthSub.
OAuth
في وقت كتابة هذه المقالة، لم تتم إضافة بروتوكول OAuth إلى الوحدة GData::Auth
.
يجب أن يكون استخدام بروتوكول OAuth في مكتبة الأدوات المساعدة أمرًا بسيطًا نسبيًا عند استخدام oauth-plugin في Rails أو oauth gem في Ruby. في كلتا الحالتين، عليك إنشاء عنصر GData::HTTP::Request
وتمرير عنوان Authorization
الذي تم إنشاؤه بواسطة كل مكتبة.
الوصول إلى الخلاصات
GET (جلب البيانات)
بعد إعداد عنصر العميل، استخدِم الطريقة get()
للاستعلام عن خلاصة Google Data. يمكن استخدام 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()
الخاصة بالعميل لإنشاء بيانات جديدة على الخادم. سيضيف المثال التالي
[email protected]
كمساهم إلى المستند الذي يحمل رقم التعريف: 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='[email protected]'/> </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:entry> أو بيانات أخرى من الخادم، استخدِم طريقة 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)
إنشاء تطبيق Rails جديد
عادةً ما يتضمّن التمرين الأول في إنشاء تطبيق Rails جديد تشغيل مولّدات التعليمات البرمجية لإنشاء ملفات 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 Contacts API.
الخاتمة
إنّ الجزء الأصعب من إنشاء تطبيق Google Data Rails هو ضبط Rails. مع ذلك، فإنّ الخطوة التالية في الأهمية هي نشر تطبيقك. لهذا السبب، ننصحك بشدة باستخدام mod_rails لنظام Apache. عملية الإعداد والتثبيت والتشغيل سهلة للغاية. ستتمكّن من استخدامها في وقت قصير جدًا.
الموارد
- قائمة Google Data APIs
- صفحة مشروع Google Data Ruby Utility Library
- المقالة: استخدام Ruby مع Google Data APIs
- تنزيل Ruby
- تنزيل RubyGems وRails
الملحق
أمثلة
DocList Manager هو نموذج كامل من Ruby on Rails يوضّح المواضيع التي تمت مناقشتها في هذه المقالة. يتوفّر رمز المصدر الكامل من خدمة استضافة المشاريع.