الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

درس: هلا برمجنا تويتر Twitter؟

بدأه Mohammad Elsheimy في 21 مايو 2010 · 22 رد · 4,220 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

قمت بكتابة هذا الدرس سابقا في موقعي، مع الدوت نت.

قم بتحميل المثال، twittoo

المحتويات

محتويات هذا الموضوع:

  • المحتويات
  • مقدمة
  • برمجة Twitter
  • دوال الـ API
    • الدوال البسيطة
    • المدخلات للدوال
    • التوثيق Authentication

  • تويتر والدوت نت
    • الوصول إلى الدوال
    • الدوال والتوثيق
    • الترميز Encoding
    • عناصر البيانات
    • تخزين البيانات
  • المثال، برنامج twittoo
    • الوصف
    • لقطات
    • التصميم
    • تقصير العناوين URL Shortening
    • التحميل

  • خاتمة

مقدمة

درسنا اليوم ليس كأي سابق له، درسنا اليوم يتكلم عن موضوع مميز للغاية وهو كيفية برمجة تويتر Twitter.

twitter-logo.png?w=155&h=36هل تستخدم Twitter؟ هل لديك حساب في Twitter؟ هل تريد أن تنشئ برنامج أو موقع إنترنت يقوم بالارتباط مع تويتر Twitter؟ إذا كانت إجابتك بنعم، فحتما سوف تعجبك هذه الصفحات القليلة والتي تتحدث عن تويتر Twitter وكيفية استغلاله برمجيا.

درسنا اليوم ليس مقصورا على Twitter فقط! بل إنه يعلمك أفكار جديدة ومتنوعة منها كيفية التعامل مع بيانات الـ XML، وكيفية التعامل مع دوال ومكاتب الويب Web APIs وغيرها. بجانب هذا سوف نتعرض لفكرة أكثر من رائعة وهي كيفية استخدام خدمات تقصير العناوين URL Shortening مثل http://is.gd وبرمجتها والاستفادة منها.

علاوة على هذا كله، يمكنك تحميل مثال رائع عبارة عن برنامج Desktop بسيط للتعامل مع تويتر Twitter.

بداية وقبل أن نبدأ أحب أن أقدم لك حساب الـ Twitter الخاص بي وهو @elsheimy.

أحب أن أنبه على أن برمجة تويتر Twitter هي موضوع كبير للغاية يحتاج إلى كتاب بأكمله! لهذا فطريقنا في هذا الدرس سوف يكون بشرح الأفكار وإعطاء أمثلة حول الدوال وغيرها، وستترك باقي الدوال للقارئ يبحث فيها باستخدام الشرح الخاص بموقع Twitter.

لن نطيل أكثر، هيا بنا إلى الموضوع.

برمجة Twitter

بداية، يجب عليك معرفة بعض الأشياء قبل الشروع في الكود من أهمها ما هو طقم البرمجة أو Twitter API؟ الـ Twitter API هي عبارة عن مجموعة كبيرة من الدوال كل واحدة فيها لها وظيفتها الخاصة بها.

مثلا، هناك دالة تقوم بإرجاع الـ Tweets الخاصة بالأصدقاء الذين تتبعهم، ودالة ثانية تقوم بإرجاع قائمة بالأصدقاء الذين تتبعهم Following، ودالة ثالثة تقوم بإرجاع الأصدقاء الذين يتبعوك Following. بالإضافة إلى ذلك فهناك دالة لإضافة Status أو كما تسمى Update أو Tweet جديدة، وأخرى لعمل Retweet، وأخرى لعمل Reply، وأخيرة لعمل Direct Message.

ولكن، كيف هي هذه الدوال؟ هل هذه الدوال هي عبارة عن مكتبة Library مثلا نقوم بإرفاقها كمرجع Reference في مشروعنا؟ هل هذه الدوال هي عبارة عن خدمة ويب Web Service أو خدمة WCF Service؟ لا هذا ولا ذاك! دوال الـ Twitter ببساطة عبارة عن عناوين إنترنت Web Addresses أو نقاط وصول Endpoints. كيف هذا؟

نأخذ مثلا مثال، هناك الدالة statuses/public timeline method مثلا والتي تقوم بإرجاع آخر تحديثات Updates (أو Tweets) بطريقة عشاوئية، فهذه الدالة لديها العنوانhttp://api.twitter.com/1/statuses/public_timeline.xml، فنلاحظ أنه يمكنك نسخ هذا العنوان ووضعه في المتصفح الخاص بك ومشاهدة النتائج والتي هي عبارة عن بيانات XML.

ولكن كيف نتعامل مع هذه الدوال من خلال الكود؟ يمكننا من خلال الأنواع Classes الموجودة في الـ Namespace المسماة System.Net بأن نقوم بعمل طلب Request على الدالة (عن طريق عنوانها) ونحصل على الإجابة Response المطلوبة والتي هي عبارة عن بيانات XML أيضا. وبعد حصولنا على هذه البيانات يمكننا معالجتها عن طريق الـ Classes الموجودة في System.Xml كي نستطيع عرضها بالشكل المناسب في موقعنا.

كما ذكرنا، سيكون عمدتنا في هذا الموضوع بإذن الله هو بوابة برمجة تويترhttp://apiwiki.twitter.com، سوف نتكلم عن بعض الدوال وستترك باقيها للقارئ يبحث عنها في الموقع.

دوال الـ API

هنا سوف نأخذ جولة سريعة في طقم البرمجة لـ Twitter وسوف نستعرض بعض من أهم الدوال لـ API.

الدوال البسيطة

الدالة الأولى معنا وهي دالة الـ Public Timeline وهي دالة بسيطة أي أنها لا تحتاج إلى توثيق للمستخدم Authentication (أي لا تحتاج إلى اسم الحساب وكلمة المرور) وأيضا لا تحتاج إلى أي مدخلات Arguments.

تقوم هذه الدالة statuses/public timeline method بإرجاع أحدث 20 تحديث Tweet (أو Update) من مستخدمين تويتر بطريقة عشوائية. عنوان هذه الدالة هوhttp://api.twitter.com/1/statuses/public_timeline.xml. إذا قمت بنسخ هذا العنوان ولصقه في المتصفح الخاص بك سوف تحصل على نتيجة مشابهة للنتيجة التالية:

<?xml version="1.0" encoding="UTF-8"?>

<statuses type="array">

    <status>

        <created_at>Wed Apr 14 19:32:07 +0000 2010</created_at>

        <id>12179999634</id>

        <text>35 Ingenious Examples of Footwear - http://su.pr/1JxMAr</text>

        <source><a href="http://apiwiki.twitter.com/" rel="nofollow">API</a></source>

        <truncated>false</truncated>

        <in_reply_to_status_id></in_reply_to_status_id>

        <in_reply_to_user_id></in_reply_to_user_id>

        <favorited>false</favorited>

        <in_reply_to_screen_name></in_reply_to_screen_name>

        <user>

            <id>15736190</id>

            <name>Smashing Magazine</name>

            <screen_name>smashingmag</screen_name>

            <location>Freiburg, Germany</location>

            <description>Vitaly Friedman, editor-in-chief of SmashingMagazine.com and Noupe.com, online magazines dedicated to designers and developers.</description>

            <profile_image_url>http://a3.twimg.com/profile_images/572829723/original_normal.jpg</profile_image_url>

            <url>http://www.smashingmagazine.com</url>

            <protected>false</protected>

            <followers_count>166019</followers_count>

            <profile_background_color>B2DFDA</profile_background_color>

            <profile_text_color>333333</profile_text_color>

            <profile_link_color>f51616</profile_link_color>

            <profile_sidebar_fill_color>ffffff</profile_sidebar_fill_color>

            <profile_sidebar_border_color>eeeeee</profile_sidebar_border_color>

            <friends_count>394</friends_count>

            <created_at>Tue Aug 05 14:00:40 +0000 2008</created_at>

            <favourites_count>4</favourites_count>

            <utc_offset>-10800</utc_offset>

            <time_zone>Greenland</time_zone>

            <profile_background_image_url>http://s.twimg.com/a/1271213136/images/themes/theme13/bg.gif</profile_background_image_url>

            <profile_background_tile>true</profile_background_tile>

            <notifications>false</notifications>

            <geo_enabled>true</geo_enabled>

            <verified>false</verified>

            <following>false</following>

            <statuses_count>8703</statuses_count>

            <lang>en</lang>

            <contributors_enabled>false</contributors_enabled>

        </user>

        <geo />

        <coordinates />

        <place />

        <contributors />

    </status>

    . . .

</statuses>

نلاحظ أن النتيجة هي عبارة عن بيانات XML. ونلاحظ أيضا أن هذه البيانات لها تركيب معين، والجميل في تويترTwitter هو أنه هناك نظام وتركيب معين XML Schema ينطبق على جميع البيانات من نفس النوع. فهذه البيانات هي عبارة عن قائمة من التحديثات Statuses، فبالتالي أي قائمة من التحديثات مثل تحديثات الأصدقاء لمستخدم معين أو تحديثات هذا المستخدم نفسه سوف يكون لها نفس النظام والتركيب Schema.

المدخلات للدوال

بعض الدوال تحتاج إلى مدخلات. من هذه الدوال دالة users/show method وهي تقوم بإرجاع التحديثات الخاصة بمستخدم معين. وهذه الدالة لديها العنوانhttp://api.twitter.com/1/users/show.xml وهي تطلب إما تحديد الكود المعرف ID الخاص بالمستخدم المطلوب وإما تحديد اسم الظهور للمستخدم Screen Name.

إذا فعندما تريد الحصول على تحديثات من المستخدم @elsheimy، فإنك تقوم النداء على هذه الدالة بواحدة من أربعة طرق:

فتكون النتيجة لهذه الدالة هي بيانات XML مطابقة تماما لما يظهر لك إذا ذهبت إلى صفحة المستخدم مثلا http://twitter.com/elsheimy.

<?xml version="1.0" encoding="UTF-8"?>

<user>

    <id>19645411</id>

    <name>Mohammad Elsheimy</name>

    <screen_name>Elsheimy</screen_name>

    <location>KB, Egypt</location>

    <description>Technology evangelist from Egypt born in 1991</description>

    <profile_image_url>http://a1.twimg.com/profile_images/833061500/02-19-2010__0__-_Small_normal.jpg</profile_image_url>

    <url>http://JustLikeAMagic.WordPress.com</url>

    <protected>false</protected>

    <followers_count>278</followers_count>

    <profile_background_color>DBE9ED</profile_background_color>

    <profile_text_color>333333</profile_text_color>

    <profile_link_color>CC3366</profile_link_color>

    <profile_sidebar_fill_color>E6F6F9</profile_sidebar_fill_color>

    <profile_sidebar_border_color>DBE9ED</profile_sidebar_border_color>

    <friends_count>179</friends_count>

    <created_at>Wed Jan 28 10:47:36 +0000 2009</created_at>

    <favourites_count>7</favourites_count>

    <utc_offset>7200</utc_offset>

    <time_zone>Cairo</time_zone>

    <profile_background_image_url>http://s.twimg.com/a/1271811071/images/themes/theme17/bg.gif</profile_background_image_url>

    <profile_background_tile>false</profile_background_tile>

    <notifications></notifications>

    <geo_enabled>true</geo_enabled>

    <verified>false</verified>

    <following></following>

    <statuses_count>1877</statuses_count>

    <lang>en</lang>

    <contributors_enabled>false</contributors_enabled>

    <status>

        <created_at>Wed Apr 21 16:21:46 +0000 2010</created_at>

        <id>12585240751</id>

        <text>I'm reading this, it's really hot: #RFC 2616 - Hypertext Transfer Protocol -- #HTTP /1.1 http://bit.ly/b1353K #tech #www</text>

        <source><a href="http://bit.ly" rel="nofollow">bit.ly</a></source>

        <truncated>false</truncated>

        <in_reply_to_status_id></in_reply_to_status_id>

        <in_reply_to_user_id></in_reply_to_user_id>

        <favorited>false</favorited>

        <in_reply_to_screen_name></in_reply_to_screen_name>

        <geo/>

        <coordinates/>

        <place/>

        <contributors/>

    </status>

</user>

نلاحظ أن هذه البيانات لها نفس التركيب Schema مثل سابقتها.

التوثيق Authentication

بعض الدوال تحتاج إلى عملية توثيق Authentication للمستخدم. فمثلا، الدوال التي تعرض التحديثات Statuses الخاصة بأصدقاء هذا المستخدم تحتاج إلى إدخال اسم المستخدم وكلمة المرور كي يتسنى له مشاهدة البيانات.

فالقاعدة هي كالآتي: البيانات التي لا يسمح لك بمشاهدتها في موقع http://Twitter.com قبل عملية الدخول Sign in هي التي تحتاج دوالها إلى توثيق Authentication، فعملية التوثيق هي بمثابة عملية الدخول Sign in.

هناك نوعين من التوثيق:

  • التوثيق البسيط Basic Authentication:
    وفيها نقوم بإرفاق البيانات المطلوبة (اسم المستخدم وكلمة المرور) في كل عملية نداء Request لأي دالة. هذه الطريقة هي الأسهل وللأسف أعلن Twitter أنها سوف تمنع في وقت لاحق. سوف نستخدم هذا النوع في درسنا.
  • توثيق OAuth:
    وهي عملية أكثر تعقيدا، وتتطلب موضوع بأكلمه، لذلك لن نستخدمها في درس اليوم وسوف نقوم بشرحها في درس آخر بإذن الله تعالى. وهذه العملية تعتمد على قيام المبرمج بتسجيل برنامجه في Twitter والحصول على بيانات خاصة به.

من الدوال التي تحتاج إلى توثيق دالة statuses/friends timeline method وهي التي تقوم بإرجاع التحديثات الخاصة بأصدقاء المستخدم. وهذه الدالة لها العنوانhttp://api.twitter.com/1/statuses/friends_timeline.xml. عند قيامك بالذهاب إلى هذا العنوان في متصفحك، سوف تظهر أمامك شاشة صغيرة خاصة بالمتصفح مسؤولة عن عملية التوثيق، وهذه الشاشة تكون مشابهة للشاشة التالية:

ie-authentication.jpg?w=326&h=319شكل 1 - شاشة توثيق برنامج Internet Explorer

فقط عند إدخالك لإسم مستخدم وكلمة مرور صحيحين سوف تحصل على البيانات المطلوبة.

من الدوال الأخرى الجميلة جدا دالة direct_messages/new method وهي تقوم بإرسال رسالة شخصية Direct Message من المستخدم الموثق إلى مستخدم آخر. وهذه الدالة تأخذ مدخلين، كود ID المستخدم أو اسم ظهوره Screen Name، ونص الرسالة والذي لا يزيد عن 140 حرف.

فعلى سبيل المثال يمكنك إرسال الرسالة “hi, how is it going” إلى المستخدم @elsheimy عن طريق أيا من الطريقتين:

نلاحظ أنه هناك حروف وعلامات مثل المسافة وعلامة الاستفهام (؟) لا يمكنها الظهور في عناوين الإنترنت ولهذا فإنه يستعاض عنها بالرمز الخاص بها، مثلا المسافة تساوي %20 لأ الكود الستعشري Hexadecimal الخاص بها هو 20. سوف نتعلم في هذا الدرس كيفية عمل Encoding للنصوص لتصبح قابلة للتداول في عناوين الإنترنت.

إذا نجحت هذه العملية فإنها تقوم بإرجاع بيانات XML مشابهة للتالية:

<?xml version="1.0" encoding="UTF-8"?>

<direct_message>

    <id>88619848</id>

    <sender_id>1401881</sender_id>

    <text>all your bases are belong to us.</text>

    <recipient_id>7004322</recipient_id>

    <created_at>Wed Apr 08 20:30:04 +0000 2009</created_at>

    <sender_screen_name>dougw</sender_screen_name>

    <recipient_screen_name>igudo</recipient_screen_name>

    <sender>

        <id>1401881</id>

        <name>Doug Williams</name>

        <screen_name>dougw</screen_name>

        <location>San Francisco, CA</location>

        <description>Twitter API Support. Internet, greed, users, dougw and opportunities are my passions.</description>

        <profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/59648642/avatar_normal.png</profile_image_url>

        <url>http://www.igudo.com</url>

        <protected>false</protected>

        <followers_count>1036</followers_count>

        <profile_background_color>9ae4e8</profile_background_color>

        <profile_text_color>000000</profile_text_color>

        <profile_link_color>0000ff</profile_link_color>

        <profile_sidebar_fill_color>e0ff92</profile_sidebar_fill_color>

        <profile_sidebar_border_color>87bc44</profile_sidebar_border_color>

        <friends_count>290</friends_count>

        <created_at>Sun Mar 18 06:42:26 +0000 2007</created_at>

        <favourites_count>0</favourites_count>

        <utc_offset>-18000</utc_offset>

        <time_zone>Eastern Time (US & Canada)</time_zone>

        <profile_background_image_url>http://s3.amazonaws.com/twitter_production/profile_background_images/2752608/twitter_bg_grass.jpg</profile_background_image_url>

        <profile_background_tile>false</profile_background_tile>

        <statuses_count>3394</statuses_count>

        <notifications>false</notifications>

        <following>false</following>

        <verified>true</verified>

    </sender>

    <recipient>

        <id>7004322</id>

        <name>Doug Williams</name>

        <screen_name>igudo</screen_name>

        <location>North Carolina</location>

        <description>A character.</description>

        <profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/15446222/twitter_48_48_normal.jpg</profile_image_url>

        <url>http://www.igudo.com</url>

        <protected>false</protected>

        <followers_count>19</followers_count>

        <profile_background_color>69A1AA</profile_background_color>

        <profile_text_color>000000</profile_text_color>

        <profile_link_color>F00</profile_link_color>

        <profile_sidebar_fill_color>ACBEC1</profile_sidebar_fill_color>

        <profile_sidebar_border_color>8A8F85</profile_sidebar_border_color>

        <friends_count>3</friends_count>

        <created_at>Thu Jun 21 21:16:21 +0000 2007</created_at>

        <favourites_count>0</favourites_count>

        <utc_offset>-18000</utc_offset>

        <time_zone>Eastern Time (US & Canada)</time_zone>

        <profile_background_image_url>http://static.twitter.com/images/themes/theme1/bg.gif</profile_background_image_url>

        <profile_background_tile>false</profile_background_tile>

        <statuses_count>382</statuses_count>

        <notifications>false</notifications>

        <following>true</following>

        <verified>true</verified>

    </recipient>

</direct_message>

تويتر والدوت نت

الوصول إلى الدوال

كي يمكنك النداء على أي دالة ستحتاج إلى عمل طلب Request إلى هذه الدالة وانتظار الجواب Response أو النتيجة من هذه الدالة. ويمكنك عمل هذا عن طريق العناصر Classes الموجود في الـ Namespace المسمى System.Net وبالتحديد العنصرين WebRequest و WebResponse.

الكود التالي يوضح كيفية الوصول إلى دالة بسيطة والنداء عليها:

// C# Code




public static Main()

{

    GetResponse("http://api.twitter.com/1/statuses/public_timeline.xml");

}




public static XmlDocument GetResponse(string uri)

{

    WebRequest req = WebRequest.Create(new Uri(uri));




    XmlDocument doc = new XmlDocument();

    doc.Load(req.GetResponse().GetResponseStream());

    return doc;

}

' VB.NET Code




Sub Main()

    GetResponse("http://api.twitter.com/1/statuses/public_timeline.xml")

End Sub




Public Function GetResponse(ByVal uri As String) As XmlDocument




    Dim req As WebRequest = WebRequest.Create(New Uri(uri))




    Dim doc As New XmlDocument()

    doc.Load(req.GetResponse().GetResponseStream())




    Return doc

End Function

نلاحظ أن الكود قام باستخدام العنصر System.Xml.XmlDocument والذي يمكننا من معالجة بيانات الـ XML بسهولة.

الدوال والتوثيق

الكود التالي يوضح كيفية النداء على الدالة statuses/update method والتي تقوم بإرسال تحديث أو Tweet جديد عن طريق المستخدم المحدد. نلاحظ أن الكود استخدم التوثيق البسيط Basic Authentication.

// C# Code




public static void Main()

{

    GetResponse("http://api.twitter.com/1/statuses/update.xml?status=hello%20from%20the%20API", "elsheimy", "b@zzword", true);

}




public static XmlDocument GetResponse(string uri, string username, string password, bool post)

{

    WebRequest req = WebRequest.Create(new Uri(uri));

    if (post)

        req.Method = "POST";

    if ((username != null) && (username.Trim() != String.Empty) && (!String.IsNullOrEmpty(password)))

        req.Credentials = new NetworkCredential(username.Trim(), password);




    XmlDocument doc = new XmlDocument();

    doc.Load(req.GetResponse().GetResponseStream());

    return doc;

}

' VB.NET Code




Sub Main()

    GetResponse("http://api.twitter.com/1/statuses/update.xml?status=hello%20from%20the%20API", "elsheimy", "b@zzword", True)

End Sub




Public Function GetResponse(ByVal uri As String, ByVal username As String, ByVal password As String, ByVal post As Boolean) As XmlDocument

    Dim req As WebRequest = WebRequest.Create(New Uri(uri))

    If (post) Then

        req.Method = "POST"

    End If

    If ((username <> Nothing) And (username.Trim() <> String.Empty) And (Not String.IsNullOrEmpty(password))) Then

        req.Credentials = New NetworkCredential(username.Trim(), password)

    End If




    Dim doc As XmlDocument = New XmlDocument()

    doc.Load(req.GetResponse().GetResponseStream())




    Return doc

End Function

الترميز Encoding

كما ذكرنا سابقا، فإن هناك حروف يجب أن لا تظهر في المدخلات للدوال مثل المسافات وعلامات الاستفهامات وغيرها. وهذه الحروف يجب استبدالها بالتمثيل الستعشري Hexadecimal لأكوادها مسبوقة بعلامة النسبة المئوية %.

الكلاس التالي تقوم بتوضيح عملية الترميز Encoding. الكود لعلمية التوضيح فقط، فنحن لا نحتاج إلى تسجيل كل حرف بمقابله.

// C# Code




public static class UrlEncoder

{

private static string[,] _chars = new string[,]

        {

        { "%", "%25" },     // this is the first one

        { "$" , "%24" },

        { "&", "%26" },

        { "+", "%2B" },

        { ",", "%2C" },

        { "/", "%2F" },

        { ":", "%3A" },

        { ";", "%3B" },

        { "=", "%3D" },

        { "?", "%3F" },

        { "@", "%40" },

        { " ", "%20" },

        { "\"" , "%22" },

        { "<", "%3C" },

        { ">", "%3E" },

        { "#", "%23" },

        { "{", "%7B" },

        { "}", "%7D" },

        { "|", "%7C" },

        { "\\", "%5C" },

        { "^", "%5E" },

        { "~", "%7E" },

        { "[", "%5B" },

        { "]", "%5D" },

        { "`", "%60" } };




public static string EncodeUrl(string url)

{

    for (int i = 0; i < _chars.GetUpperBound(0); i++)

        url = url.Replace(_chars[i, 0], _chars[i, 1]);




    return url;

}




public static string DecodeUrl(string url)

{

    for (int i = 0; i < _chars.GetUpperBound(0); i++)

        url = url.Replace(_chars[i, 1], _chars[i, 0]);




    return url;

}

' VB.NET Code

Public Module UrlEncoder




    Private _chars(,) As String = _

        { _

        {"%", "%25"}, _

        {"$", "%24"}, _

        {"&", "%26"}, _

        {"+", "%2B"}, _

        {",", "%2C"}, _

        {"/", "%2F"}, _

        {":", "%3A"}, _

        {";", "%3B"}, _

        {"=", "%3D"}, _

        {"?", "%3F"}, _

        {"@", "%40"}, _

        {" ", "%20"}, _

        {"\", "%22"}, _

        {"<", "%3C"}, _

        {">", "%3E"}, _

        {"#", "%23"}, _

        {"{", "%7B"}, _

        {"}", "%7D"}, _

        {"|", "%7C"}, _

        {"\", "%5C"}, _

        {"^", "%5E"}, _

        {"~", "%7E"}, _

        {"[", "%5B"}, _

        {"]", "%5D"}, _

        {"'", "%60"}}




    Public Function EncodeUrl(ByVal url As String) As String

        For i As Integer = 0 To _chars.GetUpperBound(0) - 1

            url = url.Replace(_chars(i, 0), _chars(i, 1))

        Next




        Return url

    End Function




    Public Function DecodeUrl(ByVal url As String) As String

        For i As Integer = 0 To _chars.GetUpperBound(0) - 1

            url = url.Replace(_chars(i, 1), _chars(i, 0))

        Next




        Return url

    End Function




End Module

الآن يمكننا استخدام هذا الكود لتغيير الحالة المستخدم Status:

// C# Code




public static void Main()

{

    string uri;

    string text = UrlEncoder.EncodeUrl("hello from the API");

    uri = "http://api.twitter.com/1/statuses/update.xml?status=" + text;

    GetResponse(uri, "elsheimy", "b@zzwrd", true);

}

' VB.NET Code




Public Sub Main()




    Dim uri As String

    Dim text As String = UrlEncoder.EncodeUrl("hello from the API")

    uri = "http://api.twitter.com/1/statuses/update.xml?status=" & text

    GetResponse(uri, "elsheimy", "b@zzwrd", True)

End Sub

عناصر البيانات

ماذا بعد حصولنا على بيانات XML كيف سنقوم بتخزينها؟ يمكننا ذلك عن طريق استخدام عناصر Classes تحوي البيانات المطلوبة وهذه العناصر، نظريا، تسمى عناصر البيانات أو Business Objects.

الكود التالي هو عبارة عن ثلاثة أنواع Classes تمثل الثلاثة عناصر التي نريدها وهي المستخدم والحالة والرسالة:

// C# Code




public structure TwitterUser

{

    public long ID;

    public string Name;

    public string ScreenName;

    public string Location;

    public string Description;

    public string ProfileImage;

    public string Url;

    public bool IsProtected;

    public long FollowersCount;

    public long FriendsCount;

    public string CreatedAt;

    public long FavoritesCount;

    public bool Verified;

    public bool Following;

    public long StatusCount;

}




public structure TwitterStatus

{

    public string CreatedAt;

    public long ID;

    public string Text;

    public string Source;

    public bool Truncated;

    public long InReplyToStatusID;

    public long InReplyToUserID;

    public bool Favorited;

    public string InReplyToScreenName;

    public TwitterUser User;

}




public structure TwitterMessage

{

    public long ID;

    public long SenderID;

    public long SenderScreenName;

    public long RecipientID;

    public long RecipientScreenName;

    public string Text;

    public string CreatedAt;

    public TwitterUser Sender;

    public TwitterUser Recipient;

}

' VB.NET Code




Public Structure TwitterUser

    Public ID As Long

    Public Name As String

    Public ScreenName As String

    Public Location As String

    Public Description As String

    Public ProfileImage As String

    Public Url As String

    Public IsProtected As Boolean

    Public FollowersCount As Long

    Public FriendsCount As Long

    Public CreatedAt As String

    Public FavoritesCount As Long

    Public Verified As Boolean

    Public Following As Boolean

    Public StatusCount As Long

End Structure




Public Structure TwitterStatus

    Public CreatedAt As String

    Public ID As Long

    Public Text As String

    Public Source As String

    Public Truncated As Boolean

    Public InReplyToStatusID As Long

    Public InReplyToUserID As Long

    Public Favorited As Boolean

    Public InReplyToScreenName As String

    Public User As TwitterUser

End Structure




Public Structure TwitterMessage




    Public ID As Long

    Public SenderID As Long

    Public SenderScreenName As Long

    Public RecipientID As Long

    Public RecipientScreenName As Long

    Public Text As String

    Public CreatedAt As String

    Public Sender As TwitterUser

    Public Recipient As TwitterUser

End Structure

تخزين البيانات

بعد أن قمنا باسترجاع البيانات الـ XML وبعد أن قمنا بتجهيز العناصر Classes التي ستحويها، يأتي الدور الآن على تحويل هذه البيانات إلى قائمة من هذه العناصر كي يتنسى لنا استخدامها في برنامجنا بسهولة.

الكود التالي يقوم باسترجاع التحديثات Statuses الخاصة بأصدقاء المستخدم ويحولها إلى قائمة من العنصر TwitterStatus. لاحظ الكود (الكود مختصر للإفادة):

// C# Code




public static void Main()

{

    GetStatuses("elsheimy", "b@zzword");

}




public static List<TwitterStatus> GetStatuses(string username, string password)

{

    XmlNode node = GetResponse("http://api.twitter.com/1/statuses/friends_timeline.xml",

        username, password, true);




    List<TwitterStatus> lst = new List<TwitterStatus>(node.ChildNodes.Count);




    foreach (XmlNode nd in node.ChildNodes)   // for each status

        lst.Add(HandleStatus(nd));




    return lst;

}




public static TwitterStatus HandleStatus(XmlNode nd)

{

    // HandleNumber, FormatText, HandleBool

    // are just functions that converts strings

    // to numbers, decoded strings, and bool

    TwitterStatus status = new TwitterStatus(

        nd["created_at"].InnerText,

        HandleNumber(nd["id"]),

        FormatText(nd["text"]),

        FormatText(nd["source"]),

        HandleBool(nd["truncated"]),

        HandleNumber(nd["in_reply_to_status_id"]),

        HandleNumber(nd["in_reply_to_user_id"]),

        HandleBool(nd["favorited"]),

        FormatText(nd["in_reply_to_screen_name"]),

        HandleUser(nd["user"]));

    return status;

}




public static TwitterUser HandleUser(XmlNode nd)

{

    // HandleNumber, FormatText, HandleBool

    // are just functions that converts strings

    // to numbers, decoded strings, and bool

    long id = HandleNumber(nd["id"]);

    TwitterUser user;




    user = new TwitterUser(

        id,

        FormatText(nd["name"]),

        FormatText(nd["screen_name"]),

        FormatText(nd["location"]),

        FormatText(nd["description"]),

        nd["profile_image_url"].InnerText,

        nd["url"].InnerText,

        HandleBool(nd["protected"]),

        HandleNumber(nd["followers_count"]),

        HandleNumber(nd["friends_count"]),

        nd["created_at"].InnerText,

        HandleNumber(nd["favourites_count"]),

        HandleBool(nd["verified"]),

        HandleBool(nd["following"]),

        HandleNumber(nd["statuses_count"]));




    return user;

}

' VB.NET Code




Sub Main()

    GetStatuses("elsheimy", "b@zzword")

End Sub




Public Function GetStatuses(ByVal username As String, ByVal password As String) As List(Of TwitterStatus)

    Dim node As XmlNode = GetResponse("http://api.twitter.com/1/statuses/friends_timeline.xml", username, password, True)




    Dim lst As New List(Of TwitterStatus)(node.ChildNodes.Count)




    For Each nd As XmlNode In node.ChildNodes

        lst.Add(HandleStatus(nd))

    Next




    Return lst

End Function




Public Function HandleStatus(ByVal nd As XmlNode) As TwitterStatus

    ' HandleNumber, FormatText, HandleBool

    ' are just functions that converts strings

    ' to numbers, decoded strings, and bool




    Dim status As New TwitterStatus( _

            nd("created_at").InnerText, _

            HandleNumber(nd("id")), _

            FormatText(nd("text")), _

            FormatText(nd("source")), _

            HandleBool(nd("truncated")), _

            HandleNumber(nd("in_reply_to_status_id")), _

            HandleNumber(nd("in_reply_to_user_id")), _

            HandleBool(nd("favorited")), _

            FormatText(nd("in_reply_to_screen_name")), _

            HandleUser(nd("user")))




    Return status

End Function




Public Function HandleUser(ByVal nd As XmlNode) As TwitterUser

    ' HandleNumber, FormatText, HandleBool

    ' are just functions that converts strings

    ' to numbers, decoded strings, and bool

    Dim id As Long = HandleNumber(nd("id"))




    Dim user As New TwitterUser( _

        id, _

        FormatText(nd("name")), _

        FormatText(nd("screen_name")), _

        FormatText(nd("location")), _

        FormatText(nd("description")), _

        nd("profile_image_url").InnerText, _

        nd("url").InnerText, _

        HandleBool(nd("protected")), _

        HandleNumber(nd("followers_count")), _

        HandleNumber(nd("friends_count")), _

        nd("created_at").InnerText, _

        HandleNumber(nd("favourites_count")), _

        HandleBool(nd("verified")), _

        HandleBool(nd("following")), _

        HandleNumber(nd("statuses_count")))

    Return user

End Function

المثال، برنامج twittoo

الوصف

وإلى النقطة الأكثر إثارة في موضوعنا، وهي المثال. مثالنا عبارة عن برنامج بسيط اسمه twittoo تستطيع من خلاله تصفح التحديثات Tweets وكذلك إضافة تحديثات أخرى، وتصفح الرسائل، والأصدقاء وغيرها.

لقطات

وهذه لقطات من البرنامج:

twittoo-00.jpg?w=243&h=114شكل 2 - twittoo 1

twittoo-01.jpg?w=300&h=509شكل 3 - twitto 2

twittoo-02.jpg?w=300&h=509شكل 4 - twitto 3

twittoo-03.jpg?w=300&h=509شكل 5 - twitto 4

twittoo-04.jpg?w=300&h=509شكل 6 - twitto 5

twittoo-05.jpg?w=501&h=296شكل 7 - twitto 6

تم تطوير المثال باستخدام تقنية C# و WinForms.

التصميم

واجهة البرنامج بسيطة جدا لا تعتمد على أي أدوات Controls خارجية، جميع الأدوات هي أدوات الويندوز المعروفة. قمنا باستخدام الأداة System.Windows.Forms.TableLayoutPanel لعرض الحالات Statuses وكذلك الرسائل Direct Messages، لاحظ الشكل التالي.

status-template.jpg?w=300&h=190شكل 8 - تصميم الحالة Status

تقصير العناوين URL Shortening

يتيح لك البرنامج تقصير أي عنوان إنترنت URL Shortening عن طريق خدمة http://is.gd وهذه الخدمة لها نظام API مشابه إلى حد كبير نظام التويتر. الكود التالي عبارة عن دالة تقوم بعمل تفصير لأي عنوان URL Shortening:

// C# Code




public static string Shorten(string url)

{

    if (!System.Text.RegularExpressions.Regex.IsMatch

        (url, @"(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&;:/~\+#]*[\w\-\@?^=%&;/~\+#])?"))

        throw new FormatException("The URL you specificed is not in the current format.");




    url = Uri.EscapeUriString(url);

    string reqUri = String.Format(@"http://is.gd/api.php?longurl={0}", url);




    WebRequest req = WebRequest.Create(reqUri);

    req.Timeout = 5000;

    using (System.IO.StreamReader reader =

        new System.IO.StreamReader(req.GetResponse().GetResponseStream()))

    {

        return reader.ReadLine();

    }

}

' VB.NET




Public Function Shorten(ByVal url As String) As String

    If (Not System.Text.RegularExpressions.Regex.IsMatch _

        (url, "(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&;:/~\+#]*[\w\-\@?^=%&;/~\+#])?")) Then

        Throw New FormatException("The URL you specificed is not in the current format.")

    End If




    url = Uri.EscapeUriString(url)

    Dim reqUri As String = String.Format("http://is.gd/api.php?longurl={0}", url)




    Dim req As WebRequest = WebRequest.Create(reqUri)

    req.Timeout = 5000




    Dim reader As New System.IO.StreamReader(req.GetResponse().GetResponseStream())

    url = reader.ReadLine()

    reader.Close()




    Return url

End Function

التحميل

حمل البرنامج من هنا

خاتمة

وأخيرا، أرجو أن أكون وفقت في عرض الموضوع، وعذرا على الإطالة، وأتمنى أن تشاركنوا بآرائكم واقتراحاتكم.

7
#2

جميل جدا

الله يجزيك الخير

بصراحة معك حق :)

لدي سؤال ماهي خدمات تقصير العناوين وما الفائدة منها

In bad state

#3

الله يخليك شكرا كتير على مرورك

معي حق على ايه؟ إن العرب مش بيشجعوا على الكتابة؟؟

إن كان كده ففعلا. أقسم بالله أقسم بالله أقسم بالله مافيه حد يعرف المجهود اللي انا قمت بيه علشان أجمع الأكواد وأكتب الموضوع ده، وكفاية المثال اللي معاه برنامج ممتاز ممتاز ممتاز

وبعد ده كله كم هي عدد الزيارات؟؟؟؟؟؟ هل فيه حد قال شكرا؟؟؟؟؟!!!!!!!! فقط واحد بس صوت قال "ممتاز" واثنان قالوا "جيد"!!!!!!!! شيئ محبط مش كده؟

بالنسبة لخدمة تقصير العناوين فيه مواقع كتير بتقدم الخدمة دي منها مثلا (واللي انا أفضله) http://bit.ly

ايه فائدة تقصير العناوين؟؟؟؟

الموضوع ده مثلا عناونه:

/index.php?showtopic=221667

لما أنا أقصره يصبح:

http://bit.ly/981jlh

لما انت بتذهب للعنوان http://bit.ly/981jlh بتتنتقل إلى صفحة الموضوع

وبالتالي يسهل تداوله على الفيسبوك، على التويتر، على النت عامة وسهل حفظه حتى

1
#4

أخي الحبيب محمد حقيقة لا املك لك الى الدعاء بان يجازيك الله خيرا على هذا ويزيدك علما ويجعله في ميزان حسناتك

أقدر جهدك ولكن دعني أقول لك إجعل نفسك مثل البحر الذي يستفيد الجميع من خيراته ولا تنتظر شيئا من أحد لانك سوف تصاب بالإحباط وهذا غير مقبول مطلقا لاننا نحتاج الى أمثالك الذين يكتبون بالعربية لإثراء العربية لغة القران الكريم

وفقك الله وجعله في ميزان حسانتك

#5

بالطبع والله العظيم أنا مش طالب غير الثواب ووالله لولا كده ما كنت كملت أنا عندي السايت الإنجليش بتاعي وليه زوار كتير الحمد لله ومع ذلك أنا نفسي أعمل حاجة للعرب وللمسلمين حاجة مش منتدى، لا. حاجة تكون موقع تعليمي 100% ننافس بيه Code Project والمواقع التانية.

أنا الحمد لله اتناقشت في المشروع ده مع إدارة http://C-SharpCorner.com موقع طبعا من أشهر المواقع عالميا في السي شارب وهما أبدوا موافقتهم على الفكرة إننا نعمل جزء من الموقع يكون عربي ويكون تحت عنوان http://C-SharpCorner.com/Arabic بس احنا محتاجين دعواتكم بس وجهودكم بإذن الله لما يوافقوا وينفذوا المشروع.

1
#6

موضوع جميل, بارك الله فيك

#7

شكرا لكم اخواني، شكرا على مروركم

#8

لا تنتظر الشكر من أحد

بل احتسب الأجر عند الله

بارك الله بك، جهد رائع في الطريق الصحيح

أتمنى منك المتابعة بذلك ...

#9

هل تسمح لى بنقل هذا الموضوع إلى موقعى؟

إن قلت قال الله قال رسولـه همزوك همز المنكر المتعالي
أو قلت قد قال الصحابة والألـى تبعاً لهم بالقول والأعمال
أو قلت قـال الشافعي وأحمد و أبو حنيفة والإمام الغالي
صدوا عن وحي الإله ودينـه واحتالوا على حرام الله بالإحلال
يا أمةً لعبت بدين نبيها كتلاعب الصبيان في الأوحال
حاشا رسول الله يحكم بالهوى تلك إذاً حكومة الضلال

feed.1.gif

#10

بسم الله ما شاء الله، شكرا لكم إخواني جميعا :D

أخي GHOST2010 الشرف ليا طبعا. ممكن تنقله براحتك بس بشرط الإشارة إلى الكاتب للموضوع ("محمد الشيمي") وإلى المصدر الأصلي للموضوع:

http://withdotnet.wordpress.com/2010/05/20/creating-a-simple-twitter-client-application

تحياتي

1
#11

الله يعطيك العافة وربنا يجزيك الخير

السؤال في خدمة تقصير العناوين هل من الممكن تشابه عنوانين ام لا

In bad state

#12

لا، ما ينفعش يكون فيه تشابه.

فكرة تقصير العناوين بسيطة وممكن تطبيقها في ASP.NET بسهولة.

اسمحلي أشرحلك الفكرة

الفكرة هي كالتالي:

أنا الدومين بتاعي مثلا http://sh.my

بعتمد على قاعدة بيانات فيها يمكن جدول واحد ويكون فيه مثلا عمودين:

url

orig_url

لما ييجي العميل عاوز يعمل تقصير للعنوان

ممكن أعمل Hash للعنوان الأصلي وآخد مثلا أول 6 بايت أو أول 6 حروف من الهاش ده

أو طريقة تانية

هستخدم

rand

علشان تجيبلي 6 حروف وأرقام مختلفين

واتأكد إنهم مش موجودين في القاعدة

لو موجودين هجرب مرة تانية علشان أطلع واحد جديد

لو مش موجودين أقوم ضايف ال 6 حروف دول وقصداهم العنوان الأصلي في الجدول

لما ييجي اليوزر يعمل GET أو يحاول يخش الموقع هقرأ الهاش بتاعه

يعني مثلا

http://sh.my/aAbBcC

هشوف لو الهاش ده موجود في القاعدة هقوم أحوله أو أعملله navigation على الموقع الأصلي اللي متسجل

لو مش موجود هقولله الصفحة غير موجودة

ايه رأيكم في مشروع زي ده؟ هيكون برضه أول مشروع عربي

أنا مالياش خبرة أبدا بال ASP.NET شغلي كله desktop بس ممكن أساعد في القاعدة و WCF أو Web Service

#13

تمام وربنا يخليك ويجزيك الخير طيب في موقع اخذو كمرجع لدراسة خدمة تقصير العناوين

In bad state

#15

إذا فهمت نقاشكم كما يجب فأظن أنكم تتحدثون عن url mapping تمت إضافتها في 3.5 SP1 رابطي

#16

تمام هي فكرة url mapping بجد .NET 4.0 حل مشاكل كتير جدا جدا جدا وخلاها أسهل كتير، فاحنا ممكن نعملها بالطريقة دي وممكن نعملها بالطريقة اللي انا ذكرتها أو أي طريقة غيرها بالنسبة للإصدارات التانية من الدوت نت

انا مش عارف احنا ليه دايما بنعتمد على العنصر الغير عربي؟ ليه ما نعتمدش على عناصر عربية ونعمل حاجة بتاعتنا احنا؟

#17
اقتباس
معي حق على ايه؟ إن العرب مش بيشجعوا على الكتابة؟؟

إن كان كده ففعلا. أقسم بالله أقسم بالله أقسم بالله مافيه حد يعرف المجهود اللي انا قمت بيه علشان أجمع الأكواد وأكتب الموضوع ده، وكفاية المثال اللي معاه برنامج ممتاز ممتاز ممتاز

وبعد ده كله كم هي عدد الزيارات؟؟؟؟؟؟ هل فيه حد قال شكرا؟؟؟؟؟!!!!!!!! فقط واحد بس صوت قال "ممتاز" واثنان قالوا "جيد"!!!!!!!! شيئ محبط مش كده؟

ماذا تقول فى من يؤلف كتااً كاملاً ويقوم بتوزيعه على الإنترنت ولا ينتظر أجراً ولا شكورا

ولا يثبطه عدم الرد أو يزيد من عزمة كثرة الردود

عزيزي لا أقصد اى هجوم او شيئاً من هذا

فقط تذكر انك تريد ان تنفع الناس

فلتنفع الناس ولا تنتظر المقابل

لو انتظرت المقابل من الناس فلن تأخذه من الله

مقالك هذا قد ينفع المئات من الناس ولكنك لن تعلم ولا حاجة لك فى ان تعلم

وفقك الله فى مقصدك

1

Formerly PYTHON

الراجل الحر .. حر و لو زمانه جار

يمشى ف طريقه .. لا يخشى الشوك ولا لحجار

#18

+1

السلام عليكم

أخي، أنا ما قلتش إني منتظر المقابل. لكن أنا أحطبت لما لقيت حتى مافيش زيارات. أنا قبل ما أكتب الموضوع ده بالعربي كتبته بالإنجليش:

http://justlikeamagic.wordpress.com/2010/04/22/creating-a-simple-twitter-client-application/

والموضوع ده الحمد لله خد عدد زيارات كويس في وقت قصير جدا.

ولما كتبته مرة تانية، أنا مش منتظر "شكرا" أنا منتظر تقييم، توجيه، نقد، بحيث نقدر نطور المحتوى بتاعنا كلنا كعرب وكمسلمين.

بالنسبة لموضوع الجزاء، الرسول -ص- لما تأخر عليه الوحي نزل جبريل بقوله تعالى: "ما ودعك ربك وما قلى" لإن الرسول -ص- اتعرض لإيذاء كثير وغير كده ربما يكون عرض عليه بعض الأمور البشرية فنزل قول الله تعالى: (ما ودعك ربك وما قلى) ليطمئنه.

طبعا لا مقارنة أبدا مع أكرم الأكرمين محمد -ص-، ولكن المقصود إننا بشر. ننتظر الثواب نعم، ولكن دائما لازم هناك على الأقل حوار يكون فيه نقد أو تشجيع يعرفني أنا ماشي صح واللا غلط، هل أنا مقبول أو لا، هل طريقتي مقبولة أو لا، كيف أستطيع التطوير، كيف نستطيع تقديم عون أكبر وأفضل.

تحياتي،

وشكرا على مروركم

#19
اقتباس

انا مش عارف احنا ليه دايما بنعتمد على العنصر الغير عربي؟ ليه ما نعتمدش على عناصر عربية ونعمل حاجة بتاعتنا احنا؟

هل ما زلنا نتحدث عن Url Mapping أو عن شيء آخر :cool: ؟

آقترحوا أي مشروع عملي مفيد و ستجدوني أول المشاركين ، إبتعدوا عن مجرد إنشاء مواقع ، و آغنوا المواقع العربية الموجودة حالياً ، ما الضير إن كتبنا دروسنا هنا ؟ أو قمنا بإنشاء مشاريع مفتوحة المصدر هنا ؟ لما الحاجة لإنشاء موقع آخر و الكتابة فييه ؟ كل الإمكانيات و الدعم متاح سواء من المشرفين أو الإدارة ..

تحياتي

تم تعديل هذه المشاركة بواسطة م. حسام فيصل في 27 مايو 2010 في 19:26

#20

نحن نتحدثنا في أكثر من موضوع.

بالطبع هناك العديد من المشاريع والأفكار التي سنطبقها هنا بإذن الله تعالى.

#21

إلى الأمام اخي .. دائماً تفاجانا بمواضيعك .. :)

1
118650.jpg
#22

شكرا لك smile.gif

#23

كل الشكرللمعلومات القيمة والى الامام

مواضيع مشابهة