نقل منتدى IPB 3.1 إلى Discourse

مرحبًا يا مجتمع Discourse،

أود مشاركة تجربتي في استيراد منتدى IPB 3.1 إلى Discourse 2.1، على أمل أن تكون هذه المعلومات مفيدة للآخرين.

ملخص موجز عن المجتمع:

  • الموضوع: إطار عمل Yii لـ PHP (مناقشات ودعم متعلقة بالكود)
  • الأعضاء: حوالي 26 ألف عضو
  • المواضيع: حوالي 64 ألف موضوع
  • المنشورات: حوالي 293 ألف منشور

استغرق الاستيراد 27 ساعة و46 دقيقة على جهاز يحتوي على 16 جيجابايت من ذاكرة الوصول العشوائي (RAM) و4 أنوية معالج.

متطلبات الاستيراد:

  • الاحتفاظ بالأعضاء، مع تنظيف جميع حسابات البريد العشوائي (SPAM) (حوالي 250 ألف حساب، منها حوالي 26 ألف حساب تبقى بعد التنظيف)
  • تنفيذ SSO من الموقع الإلكتروني (لا تتم إدارة حسابات المستخدمين بواسطة Discourse)
  • الاحتفاظ بالمواضيع والمنشورات والفئات مع عناوين URL الأصلية الخاصة بها لضمان استمرار عمل نتائج محركات الويب، وكذلك الروابط الأخرى من منصات مثل Stackoverflow

هذا الاستناد إلى https://meta.discourse.org/t/migrating-from-invision-power-board-to-discourse/34639/23، لذا شكرًا لـ @pfaffman على العمل الرائع الذي قام به في أداة الاستيراد.

التحضير

تصدير البيانات من IPB

mysqldump <اسم_قاعدة_البيانات> > /tmp/ipb.sql
cd /var/www/yiiframework.com/forum/ && tar czvf uploads.tgz uploads/

انسخ ملف تصدير SQL وملف الرفع (uploads) إلى الخادم الجديد وضعها في /var/discourse/shared/standalone/.
أفترض هنا إعداد Docker بسيط لـ Discourse.

أي سكريبت يجب استخدامه؟

يوجد سكريبتان للاستيراد: ipboard.rb و ipboard3.rb. يبدو أن سكريبت ipboard3.rb غير مكتمل ولا يتطابق مع مخطط الجداول الذي لدينا، لذا اخترت استخدام ipboard.rb.

الإصدار الحالي من سكريبت استيراد ipboard.rb لا يتعامل بشكل جيد مع المرفقات ولا يحول وسوم الكود، وهو أمر بالغ الأهمية بالنسبة لنا لأننا نتحدث كثيرًا عن كود PHP. لذا قمت بإجراء التعديلات التالية على السكريبت:

جعل المرفقات المرفوعة متاحة

يستبدل سكريبت الاستيراد مرفقات المنشور بروابط إلى الملف المرفوع.
إذا كنت تنوي الإبقاء على مثيل IPB الخاص بك متصلاً على نفس العنوان الذي كان عليه سابقًا، فيمكنك ببساطة تحديد العنوان (UPLOADS هو إعداد في سكريبت الاستيراد، انظر أدناه) لمجلد الرفع، وستكون قد انتهيت:

UPLOADS="https://www.yiiframework.com/forum/uploads"

ولكننا نستورد إلى Discourse لإزالة المنتدى القديم تمامًا، لذا يجب علينا وضع الملفات المرفوعة في مكان آخر. إذا كنت تستخدم وكيل nginx أمام Discourse، فيمكنك تكوينه لتقديم الملفات المرفوعة من مجلد على الخادم. ضع التالي في جزء server من إعدادات nginx:

location /ipb_uploads/ {
    alias /var/www/ipb_uploads/;
}

وقم بتكوين عنوان URL للمرفقات (انظر أدناه) على النحو التالي:

UPLOADS="https://forum.yiiframework.com/ipb_uploads"

إعداد MySQL في حاوية Discourse

ابدأ غلاف bash في حاوية تطبيق Discourse:

docker exec -it app bash

في الحاوية، قم بتثبيت MySQL واستيراد قاعدة البيانات:

apt-get install mysql-server mysql-client libmysqlclient-dev
service mysql start
echo "create database ipb" | mysql -uroot -p
mysql -uroot -p ipb < /shared/ipb.sql

عندما حاولت إجراء أول استيراد لاختبار السكريبت، استغرق الأمر عدة أيام لاستيراد 200 ألف مستخدم، وكنا نعلم أن عددًا كبيرًا منها كان حسابات بريد عشوائي (SPAM)، لذا قمنا بإنشاء بعض استعلامات SQL لحذف الحسابات التي لم تنشر أي شيء:

لاحظ أننا سنستخدم SSO، لذا سيتم إعادة إنشاء المستخدمين المحذوفين عند تسجيل دخولهم.
إذا لم تكن تنوي استخدام SSO، فقد تكون معاييرك لحذف المستخدمين مختلفة.
يمكنك استيراد بياناتك دون تنظيفها.

mysql -uroot -p
# ثم طبق استعلامات التنظيف

بعد ذلك نحتاج إلى تثبيت الاعتماديات اللازمة لسكريبت الاستيراد:

cd /var/www/discourse
echo "gem 'mysql2'" >>Gemfile
echo "gem 'reverse_markdown'" >>Gemfile
bundle install --no-deployment

للسماح بالوصول إلى قاعدة بيانات Discourse Postgres، استبدل peer بـ trust في /etc/postgresql/10/main/pg_hba.conf. لاحظ أن الرقم 10 يمثل إصدار postgres، وإذا لم يكن الملف موجودًا في إعدادك، فاستبدل 10 بالإصدار الذي تعمل به حاليًا.
أعد تشغيل Postgres لتحميل التغييرات: service postgresql restart

الاستيراد

جهز الرموز التعبيرية (Avatars) والملفات المرفوعة:

mkdir /shared/imports
mv /shared/uploads.tgz /shared/imports
cd /shared/imports && tar xzvf uploads.tgz

شغل سكريبت الاستيراد:

cd /var/www/discourse
DB_HOST="localhost" DB_NAME="yiisite" DB_USER="root" DB_PW="root" TABLE_PREFIX="ipb_" IMPORT_AFTER="1970-01-01" UPLOADS="https://www.forum.yiiframework.com/ipb_uploads" AVATARS_DIR="/shared/imports/uploads/" USERDIR="user" bundle exec ruby script/import_scripts/ipboard.rb | tee import.log

تأكد من تعديل عنوان URL الخاص بـ UPLOADS كما ناقشنا أعلاه، حيث سيتم تضمين الرفع في المنشورات كروابط إلى الملف الأصلي المرفوع.

التنظيف

إذا سار كل شيء على ما يرام، قم بالتنظيف باستخدام service mysql stop، apt-get purge mysql-server، rm -rf /var/lib/mysql.

إعداد إعادة توجيه عناوين URL

للحفاظ على عناوين URL الحالية للمنتدى سليمة، ينشئ سكريبت الاستيراد روابط دائمة (permalinks) لكل موضوع تعكس عنوان URL للمواضيع والفئات في IPB.
ومع ذلك، لا تغطي هذه الروابط الدائمة الروابط إلى منشورات محددة في موضوع أو صفحات مختلفة.
لكي تعمل هذه العناوين بشكل صحيح، يجب عليك تكوين بعض قواعد إعادة كتابة عناوين URL، وهناك 3 خيارات:

  • استخدام إعداد permalink normalizations في Discourse لإزالة الأجزاء غير الضرورية من عناوين URL
  • قواعد إعادة الكتابة في nginx، إذا كان لديك وكيل nginx أمام Discourse
  • إذا كان المنتدى القديم على عنوان URL/مضيف مختلف عن Discourse، فيمكنك استخدام سكريبت مخصص لإعادة كتابة عناوين URL (وهو ما قمت به)

إليك كود PHP الذي نستخدمه لإعادة توجيه عناوين URL:

موارد ذات صلة

18 إعجابًا

مرحباً،

عذراً على إحياء هذا الموضوع القديم، لكنني أيضاً أخطط للانتقال من IPB (الإصدار 3.4) إلى Discourse وأتبع هذا الدليل. لذا، قررت الرد مباشرة في هذا الموضوع بدلاً من إنشاء موضوع جديد.

لم يعد حزمة mysql متوفرة في التوزيع، لذا اتبعت هذا الدليل
باختصار:

wget http://repo.mysql.com/mysql-apt-config_0.8.13-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb
sudo apt update
sudo apt install mysql-server mysql-client libmysqlclient-deb
service mysql start

لكنني بعد ذلك حصلت على الخطأ التالي:
mysql: unrecognized service

هل لديك أي فكرة عن كيفية بدء تشغيل mysql؟

شكراً لك

هل كانت هناك أخطاء عند تنفيذ الأوامر التي كان ينبغي أن تقوم بتثبيته؟ أوصي بالبحث في جوجل.

أيضًا، قد ترغب في استخدام البرنامج النصي ipb الذي يعد جزءًا من Discourse بدلاً من البرنامج النصي المشار إليه في المنشور الأصلي.

هل هناك أي تحديث لهذا البرنامج النصي لأنه لن يعمل مع IPB 4x وهو أيضًا غير متوافق مع Discourse نفسه حيث تغير هيكل الجداول وظل البرنامج النصي كما هو

إعجاب واحد (1)

أقوم الآن باستيراد ipboard. اضطررت إلى إزالة بعض الجداول والصفوف من بعض الاستعلامات. يبدو أن لديها العديد من تكوينات الجداول المختلفة.

يعد الحصول على مشاركات ipb الأولية بتنسيق markdown أمرًا صعبًا أيضًا.

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

إعجابَين (2)

to help you, IPB 4x tables is as follow:

mysql> SHOW TABLES;
+-------------------------------------------+
| Tables_in_ipboard                         |
+-------------------------------------------+
| ipb_bbcode_mediatag                       |
| ipb_ccs_folders                           |
| ipb_cms_blocks                            |
| ipb_cms_containers                        |
| ipb_cms_custom_database_1                 |
| ipb_cms_custom_database_2                 |
| ipb_cms_database_categories               |
| ipb_cms_database_comments                 |
| ipb_cms_database_fields                   |
| ipb_cms_database_fields_reciprocal_map    |
| ipb_cms_database_fields_thumbnails        |
| ipb_cms_database_reviews                  |
| ipb_cms_database_revisions                |
| ipb_cms_databases                         |
| ipb_cms_folders                           |
| ipb_cms_media                             |
| ipb_cms_media_folders                     |
| ipb_cms_page_database_map                 |
| ipb_cms_page_widget_areas                 |
| ipb_cms_pages                             |
| ipb_cms_template_conflicts                |
| ipb_cms_templates                         |
| ipb_cms_url_store                         |
| ipb_core_achievements_log                 |
| ipb_core_achievements_log_milestones      |
| ipb_core_achievements_rules               |
| ipb_core_acp_notifcations_dismissals      |
| ipb_core_acp_notifications                |
| ipb_core_acp_notifications_preferences    |
| ipb_core_acp_search_index                 |
| ipb_core_acp_tab_order                    |
| ipb_core_acronyms                         |
| ipb_core_admin_login_logs                 |
| ipb_core_admin_logs                       |
| ipb_core_admin_permission_rows            |
| ipb_core_advertisements                   |
| ipb_core_alerts                           |
| ipb_core_alerts_seen                      |
| ipb_core_announcements                    |
| ipb_core_anonymous_posts                  |
| ipb_core_api_keys                         |
| ipb_core_api_logs                         |
| ipb_core_api_webhook_fires                |
| ipb_core_api_webhooks                     |
| ipb_core_applications                     |
| ipb_core_approval_queue                   |
| ipb_core_archive_log                      |
| ipb_core_archive_restore                  |
| ipb_core_attachments                      |
| ipb_core_attachments_map                  |
| ipb_core_automatic_moderation_pending     |
| ipb_core_automatic_moderation_rules       |
| ipb_core_automatic_moderation_types       |
| ipb_core_badges                           |
| ipb_core_banfilters                       |
| ipb_core_bulk_mail                        |
| ipb_core_cache                            |
| ipb_core_club_pages                       |
| ipb_core_clubs                            |
| ipb_core_clubs_fields                     |
| ipb_core_clubs_fieldvalues                |
| ipb_core_clubs_memberships                |
| ipb_core_clubs_node_map                   |
| ipb_core_contact_verify                   |
| ipb_core_content_featured                 |
| ipb_core_content_meta                     |
| ipb_core_deletion_log                     |
| ipb_core_dev                              |
| ipb_core_edit_history                     |
| ipb_core_editor_stored_replies            |
| ipb_core_email_templates                  |
| ipb_core_emoticons                        |
| ipb_core_error_logs                       |
| ipb_core_file_logs                        |
| ipb_core_file_storage                     |
| ipb_core_files                            |
| ipb_core_files_temp                       |
| ipb_core_follow                           |
| ipb_core_follow_count_cache               |
| ipb_core_geoip_cache                      |
| ipb_core_googleauth_used_codes            |
| ipb_core_group_promotions                 |
| ipb_core_groups                           |
| ipb_core_hooks                            |
| ipb_core_hooks_files                      |
| ipb_core_ignored_users                    |
| ipb_core_incoming_emails                  |
| ipb_core_inline_messages                  |
| ipb_core_ips_bulletins                    |
| ipb_core_item_markers                     |
| ipb_core_item_member_map                  |
| ipb_core_item_redirect                    |
| ipb_core_item_statistics_cache            |
| ipb_core_javascript                       |
| ipb_core_leaders                          |
| ipb_core_leaders_groups                   |
| ipb_core_like_cache                       |
| ipb_core_log                              |
| ipb_core_login_failures                   |
| ipb_core_login_handlers                   |
| ipb_core_login_links                      |
| ipb_core_login_methods                    |
| ipb_core_mail_error_logs                  |
| ipb_core_member_badges                    |
| ipb_core_member_history                   |
| ipb_core_member_privacy_actions           |
| ipb_core_member_ranks                     |
| ipb_core_member_recognize                 |
| ipb_core_member_status_replies            |
| ipb_core_member_status_updates            |
| ipb_core_members                          |
| ipb_core_members_feature_seen             |
| ipb_core_members_known_devices            |
| ipb_core_members_known_ip_addresses       |
| ipb_core_members_logins                   |
| ipb_core_members_warn_actions             |
| ipb_core_members_warn_logs                |
| ipb_core_members_warn_reasons             |
| ipb_core_menu                             |
| ipb_core_message_posts                    |
| ipb_core_message_topic_user_map           |
| ipb_core_message_topics                   |
| ipb_core_moderator_logs                   |
| ipb_core_moderators                       |
| ipb_core_modules                          |
| ipb_core_notification_defaults            |
| ipb_core_notification_preferences         |
| ipb_core_notifications                    |
| ipb_core_notifications_pwa_keys           |
| ipb_core_notifications_pwa_queue          |
| ipb_core_oauth_authorize_prompts          |
| ipb_core_oauth_clients                    |
| ipb_core_oauth_server_access_tokens       |
| ipb_core_oauth_server_authorization_codes |
| ipb_core_output_cache                     |
| ipb_core_permission_index                 |
| ipb_core_pfields_content                  |
| ipb_core_pfields_data                     |
| ipb_core_pfields_groups                   |
| ipb_core_plugins                          |
| ipb_core_points_log                       |
| ipb_core_polls                            |
| ipb_core_post_before_registering          |
| ipb_core_profanity_filters                |
| ipb_core_profile_completion               |
| ipb_core_profile_steps                    |
| ipb_core_question_and_answer              |
| ipb_core_queue                            |
| ipb_core_ratings                          |
| ipb_core_rc_author_notification_text      |
| ipb_core_rc_comments                      |
| ipb_core_rc_index                         |
| ipb_core_rc_reports                       |
| ipb_core_reactions                        |
| ipb_core_referral_banners                 |
| ipb_core_referrals                        |
| ipb_core_reputation_index                 |
| ipb_core_reputation_leaderboard_history   |
| ipb_core_reputation_levels                |
| ipb_core_rss_export                       |
| ipb_core_rss_import                       |
| ipb_core_rss_imported                     |
| ipb_core_s3_deletions                     |
| ipb_core_saved_charts                     |
| ipb_core_search_index                     |
| ipb_core_search_index_item_map            |
| ipb_core_search_index_tags                |
| ipb_core_security_answers                 |
| ipb_core_security_questions               |
| ipb_core_seo_meta                         |
| ipb_core_sessions                         |
| ipb_core_share_links                      |
| ipb_core_sitemap                          |
| ipb_core_social_promote                   |
| ipb_core_social_promote_content           |
| ipb_core_social_promote_sharers           |
| ipb_core_soft_delete_log                  |
| ipb_core_solved_index                     |
| ipb_core_spam_service_log                 |
| ipb_core_spam_whitelist                   |
| ipb_core_statistics                       |
| ipb_core_store                            |
| ipb_core_stream_subscriptions             |
| ipb_core_streams                          |
| ipb_core_sys_conf_settings                |
| ipb_core_sys_cp_sessions                  |
| ipb_core_sys_lang                         |
| ipb_core_sys_lang_words                   |
| ipb_core_sys_login                        |
| ipb_core_sys_settings_titles              |
| ipb_core_sys_social_group_members         |
| ipb_core_sys_social_groups                |
| ipb_core_tags                             |
| ipb_core_tags_cache                       |
| ipb_core_tags_perms                       |
| ipb_core_tasks                            |
| ipb_core_tasks_log                        |
| ipb_core_theme_conflict                   |
| ipb_core_theme_content_history            |
| ipb_core_theme_css                        |
| ipb_core_theme_resources                  |
| ipb_core_theme_settings_fields            |
| ipb_core_theme_settings_values            |
| ipb_core_theme_templates                  |
| ipb_core_themes                           |
| ipb_core_upgrade_history                  |
| ipb_core_validating                       |
| ipb_core_view_updates                     |
| ipb_core_voters                           |
| ipb_core_widget_areas                     |
| ipb_core_widget_trash                     |
| ipb_core_widgets                          |
| ipb_custom_bbcode                         |
| ipb_forums_answer_ratings                 |
| ipb_forums_archive_posts                  |
| ipb_forums_archive_rules                  |
| ipb_forums_forums                         |
| ipb_forums_posts                          |
| ipb_forums_question_ratings               |
| ipb_forums_topic_mmod                     |
| ipb_forums_topics                         |
| ipb_forums_view_method                    |
| ipb_nexus_alternate_contacts              |
| ipb_nexus_billing_agreements              |
| ipb_nexus_cart_uploads                    |
| ipb_nexus_coupons                         |
| ipb_nexus_customer_addresses              |
| ipb_nexus_customer_cards                  |
| ipb_nexus_customer_fields                 |
| ipb_nexus_customer_spend                  |
| ipb_nexus_customers                       |
| ipb_nexus_donate_goals                    |
| ipb_nexus_donate_logs                     |
| ipb_nexus_eom                             |
| ipb_nexus_fraud_rules                     |
| ipb_nexus_invoice_tracker                 |
| ipb_nexus_invoices                        |
| ipb_nexus_licensekeys                     |
| ipb_nexus_member_subscription_packages    |
| ipb_nexus_member_subscriptions            |
| ipb_nexus_notes                           |
| ipb_nexus_package_base_prices             |
| ipb_nexus_package_fields                  |
| ipb_nexus_package_filters                 |
| ipb_nexus_package_filters_map             |
| ipb_nexus_package_filters_values          |
| ipb_nexus_package_groups                  |
| ipb_nexus_package_images                  |
| ipb_nexus_packages                        |
| ipb_nexus_packages_ads                    |
| ipb_nexus_packages_products               |
| ipb_nexus_paymethods                      |
| ipb_nexus_payouts                         |
| ipb_nexus_product_options                 |
| ipb_nexus_purchases                       |
| ipb_nexus_referral_rules                  |
| ipb_nexus_reviews                         |
| ipb_nexus_ship_orders                     |
| ipb_nexus_shipping                        |
| ipb_nexus_support_default_content         |
| ipb_nexus_support_departments             |
| ipb_nexus_support_fields                  |
| ipb_nexus_support_notify                  |
| ipb_nexus_support_ratings                 |
| ipb_nexus_support_replies                 |
| ipb_nexus_support_request_log             |
| ipb_nexus_support_requests                |
| ipb_nexus_support_severities              |
| ipb_nexus_support_staff_dpt_order         |
| ipb_nexus_support_staff_preferences       |
| ipb_nexus_support_statuses                |
| ipb_nexus_support_stock_actions           |
| ipb_nexus_support_streams                 |
| ipb_nexus_support_tracker                 |
| ipb_nexus_support_views                   |
| ipb_nexus_tax                             |
| ipb_nexus_transactions                    |
| ipb_rc_reports_index                      |
| x_utf_ipb_convert_session                 |
| x_utf_ipb_convert_session_tables          |
+-------------------------------------------+