مزامنة/إعادة نشر المواضيع عبر مواقع Discourse المختلفة

لدي حاليًا موضوع واحد على موقع واحد، والذي أود أن يكون موجودًا أيضًا على موقع آخر. بينما يمكنني ربطه تشعبيًا، ما أود حقًا هو القدرة على تعديله على أي من الموقعين، وانعكاس التغييرات على كليهما. هذا يوفر عليّ امتلاك نسخة واحدة من الموضوع قديمة جدًا، وبدلاً من ذلك يحافظ على تحديث كلا الموضوعين باستمرار. كما أنه يوفر لي طريقة للامركزية للمعلومات من موقعي.

بعض الأفكار حول الوظائف

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

أتفهم أن تنفيذ مثل هذه الميزة بعيد كل البعد عن كونه أمرًا سهلاً، ولكني أتساءل عما إذا كان قد تم النظر في هذا الأمر على الإطلاق، وما هي النتائج/التجارب الموجودة بالفعل؟

إعجابَين (2)

وجود محتوى مكرر على مواقع متعددة هو أمر سيء للغاية بالنسبة لتحسين محركات البحث (SEO). من غير المرجح أن يتم دعم ذلك.

ما هي حالة الاستخدام أو الغرض؟ هل تريد بشكل أساسي أن تكون المواقع الأخرى نسخة احتياطية من الموقع الأساسي؟

إعجابَين (2)

هل يمكنك تقديم المزيد من المعلومات حول هذا؟ من وجهة نظري، هذا من شأنه أن يقلل من المحتوى المكرر.

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

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

أعتقد أن هذا قد يكون ممكنًا حتى باستخدام مفتاح API للموقع الآخر؟ ربما شيء مثل زر/قسم في المحرر حيث يمكن إنشاء قائمة بمفاتيح API وعناوين URL للموضوع المستهدف. عندما تجري تغييرات على موضوع المصدر، يمكنك النقر على شيء مثل “دفع التغييرات إلى استنساخات هذا الموضوع”. كل ما سيفعله هذا هو دفع التحديث إلى المواضيع الموجودة على المثيلات الأخرى.

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

ضع المعلومات في مكان واحد بالضبط حيث يمكن للجميع رؤيتها. الرابط هو الطريقة للقيام بذلك.

ولكن لديك معلومات سرية تريد جعلها متاحة في مكان آخر. هذا شيء آخر. من الممكن جدًا مع إضافة. إنه نوع المشكلة حيث يتطلب الحل المبتكر 10 أضعاف العمل الذي تتطلبه المشكلة الفعلية. (غالبًا ما أقضي ساعات في أتمتة مهمة تحتاج إلى القيام بها مرة واحدة فقط، على سبيل المثال.)

ولكن ستحتاج إلى وضعه في مكان يكون متاحًا فقط للمستخدم الذي نشره. أو جعله متاحًا على مستوى الموقع؟

مرة أخرى، يجب أن تكون لكل مستخدم وفي المُسلسل للمستخدم الحالي فقط (أو ربما تخزينها في ملف تعريف المستخدم؟). وستحتاج إلى هيكل بيانات لربط مفاتيح API بالمواقع المختلفة. يبدو وكأنه شيء أعتقد أنه يمكنني القيام به في 2-5 ساعات.

لذا فأنت بحاجة في مكان ما إلى تخزين عنوان URL للمواقع الأخرى التي يُفترض أن يكون لديها هذا الموضوع. قد يكون إنشاء هذا المنشور معقدًا أيضًا؛ أسهل طريقة هي إنشاؤه يدويًا وتضمين عنوان URL لهذا الموضوع في موقع المصدر. يمكنك ربما تخزين ذلك في المنشور الخام في نوع من BBcode أو شيء من هذا القبيل. سيتيح لك ذلك إنشاء مكون ينشئ الزر والرابط لكل منها، ثم سيكون لديك كود Rails سيقوم بجدولة مهمة ستحاول نشرها إلى الموقع (المواقع) الأخرى. لكن المواقع المستلمة لن تحتاج إلى أي كود - يمكنك استخدام واجهة برمجة التطبيقات لدفع تعديل إلى المنشور.

يبدو وكأنه نوع الشيء الذي أعتقد أنه يمكنني القيام به في 5-10 ساعات ولكنه سيستغرق ضعف ذلك على الأرجح. إذا كان هذا ممتعًا لك، فيمكن أن يكون مشروعًا رائعًا.

4 إعجابات

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

4 إعجابات

لقد فكرت في هذا مرة أخرى.

يمكن للإضافة أن تضيف حقل موضوع مخصص لرابط المصدر للمستند الأساسي. (أعتقد أنها ستحتاج أيضًا إلى حقول لاسم مستخدم عن بعد ومفتاح API إذا كان المستند الرئيسي سيتم إخفاؤه، كما أعتقد أن هذه هي حالتك، ولكن يمكن أن تنتظر هذه القطعة. أو ربما يمكن أن تعيش في حقل مخصص للمستخدم. سيعتمد الأمر على من قام بإنشاء المفتاح للتأكد من أن مفتاح API لديه امتيازات للقراءة فقط).

عند إنشاء موضوع، ستدخل شيئًا مثل " remote: https://meta.discourse.org/t/synchronising-crossposting-topics-across-different-discourse-sites/263269 " وعند إنشاء الموضوع، سيقوم Discourse بسحب النص الخام للموضوع البعيد، وإدراجه في raw كتعديل وإنشاء topic_custom_field مع عنوان URL البعيد، وربما إضافة “تم النسخ من url” في الأعلى.

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

بعد ذلك، يمكن أن يكون هناك زر “التحقق من المصدر” الذي سيقوم بسحب الموضوع البعيد وحفظ updated_at للموضوع البعيد وربما حتى raw في حقول مخصصة أخرى (يمكن لوظيفة أيضًا القيام بذلك بشكل دوري، مما يوفر بعض تجربة المستخدم). يمكنك بعد ذلك الحصول على زر تحديث سيستبدل raw الحالي بالبعيد كتعديل.

إذا كان الموقع الأساسي عامًا، فإن هذا الجزء سهل حقًا. إضافة مفتاح API للسحب من موقع خاص يعقد الأمور، وإدارة مجموعة من مفاتيح API عبر مواقع متعددة، يعقدها أكثر. إذا كان المصدر الأصلي بحاجة إلى الاستبدال، فيمكنك ربما القيام بذلك باستخدام مهمة rake لإعادة التعيين، أو إضافة القدرة على تعديل الحقل المخصص بعنوان URL البعيد عندما تحتاج إلى ذلك.

هذا الجزء يأتي مجانًا، نظرًا لأن هذا الحل يتضمن المواقع الثانوية سحب البيانات من الموقع الأساسي.

صحيح. ويمكن أن يكون هناك رابط مرة أخرى إلى موقع المصدر، حتى يتمكن الأشخاص من الذهاب إلى المصدر لرؤية تلك التعليقات، أو ربما حتى تضمينها عبر Embed comments from Discourse in your single page app.

إذا كان لديك أي ميزانية على الإطلاق لهذا، فلا تتردد في الاتصال بي.

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

مرحباً جاي،

لقد كان هذا في ذهني لفترة، على الرغم من أنه لم يتقدم كثيرًا حتى وقت قريب. للأسف، انخفضت قيمة مزامنة Discourse إلى Discourse بالنسبة لي (كانت مجرد حفنة من المواضيع)، ولكن ما زادت قيمته هو الرغبة في مزامنة ملفات markdown من منصات أخرى بشكل عام.

كانت حالة الاستخدام السائدة لدينا في الشركة هي توفير ملفات readmes و wikis من مشاريع Gitlab داخل Discourse (للحصول على ملاحظات والبحث)، ولكن مع بقاء ملف gitlab كمصدر وحيد للحقيقة. أدى افتقاري إلى معرفة لغة Ruby إلى إنشاء برنامج نصي بلغة Python، وهو بالتأكيد مبالغ فيه في تطبيقه، ولكنه مُرضٍ في وظيفته. الإصدار الأول الجيد يقوم ببعض مما أشرت إليه أيضًا. بعض الوظائف:

  • يحتوي على رابط للمصدر الأصلي (ملف في gitlab)
  • يحتوي على رابط للمراجعة المحددة (gitlab commit #)
  • يتعامل مع الصور وعناوين URL للصور
    • يقوم بتنزيل الصور من مستودع gitlab
    • يقوم بتحميلها إلى discourse
    • يستبدل عنوان URL الأصلي للصورة بعنوان URL المختصر للتحميل
  • يضيف علامة “synced_with_gitlab” لتسهيل العثور عليها جميعًا

لقد عمل بشكل جيد مع github أيضًا. كلاهما لهما نفس النكهة تقريبًا من markdown مما يجعله سلسًا للغاية.

أود أن أجعل هذا مفتوح المصدر، لكنني سأحتاج إلى معرفة ما يقوله القسم القانوني. بالإضافة إلى ذلك، لا يزال الأمر أشبه بفوضى Python غير مكتملة. الهدف هو تحويل هذا إلى إضافة Ruby في وقت ما، لكنني سأحتاج إلى معرفة ما إذا كان بإمكاني إيجاد الوقت اللازم.

3 إعجابات

صحيح. أنا أحاول مرة أخرى في هذا المشروع، وأبحث حاليًا عن إنشاء قاعدة بيانات تحتوي على:

  1. جدول واحد لكل منصة (جدول Discourse، جدول Gitlab، إلخ) لاستيعاب الفروق الدقيقة المحتملة
  2. كل جدول منصة يدعم خطافات الويب (webhooks) والاستقصاء (polling) عبر مفتاح API
  3. تشفير قاعدة البيانات أو مفتاح API - حاليًا أفكر أنه من الأفضل تشفير قاعدة البيانات بأكملها، والتفاعل معها عبر البرنامج النصي وعبارة مرور

سيبدو جدول Discourse كالتالي:

النوع الفاصل الزمني (دقيقة) آخر تشغيل (دقيقة) نطاق المصدر معرف منشور المصدر المستخدم المصدر المفتاح المصدر نطاق الوجهة معرف منشور الوجهة المستخدم الوجهة المفتاح الوجهة
خطاف ويب - 120 meta.discourse.com 1280952 - - discourse.mysite.com 120 Tris xyz12345
استقصاء 60 40 meta.discourse.com 1280953 Tris20 12345xyz discourse.mysite.com 121 Tris xyz12345
استقصاء 60 35 meta.discourse.com 1750968 Tris20 12345xyz discourse.mysite.com 221 Tris xyz12345
استقصاء 60 40 meta.discourse.com 1123292 Tris20 12345xyz discourse.mysite.com 131 Tris xyz12345
خطاف ويب - 4800 meta.discourse.com 1283678 - - discourse.mysite.com 129 Tris xyz12345

هل يبدو هذا جنونيًا ومفرطًا في الهندسة؟ جزء مني يريد بناء حل مناسب لهذا، مما يعني حساب كلا الاحتمالين - خطاف الويب والاستقصاء.

أيضًا، سأكون ممتنًا جدًا للاقتراحات فيما يتعلق بالحفاظ على أمان محتويات قاعدة البيانات. التفكير الحالي هو تشفير قاعدة البيانات بعبارة مرور يجب تقديمها كوسيط عند بدء البرنامج النصي، على سبيل المثال:

discourse-sync run password123

كمصدر إلهام، يمكن أن يكون خطاف الويب سريعًا جدًا:


كان هذا موضوعين على مثيلين مختلفين. الموضوع على اليسار هو الموضوع المصدر، والموضوع على اليمين هو الوجهة.

هناك طريقة في Rails لتشفير حقل واحد. هذا ما فعلته في لوحة التحكم الخاصة بي.

راجع Active Record Encryption — Ruby on Rails Guides

وجود كل من الاستقصاء وخطافات الويب يبدو زائدًا عن الحاجة. أعتقد أنني سأختار نهجًا واحدًا.

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

أعتقد أن إضافة ActivityPub ستحصل على بعض الاتحاد من Discourse إلى Discourse في المستقبل القريب إذا كان ذلك ممكنًا أيضًا؟

3 إعجابات

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

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

أتفق نظريًا، لكن للأسف فإن عالم الشركات يعقد الأمور:

  1. لا يمكن استخدام خطافات الويب في الشركة بسبب سياسات تكنولوجيا المعلومات (نحن نستضيف خارج الشركة بواسطة CDCK + لا يمكننا السماح بإعادة توجيه المنافذ إلى العالم الخارجي دون عملية ثقيلة) - لذلك يجب أن يكون إصدار واجهة برمجة التطبيقات موجودًا
  2. خطافات الويب سريعة ورائعة ومعقولة تمامًا للجميع، لذا من المنطقي استيعابها أيضًا :slight_smile:

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

جزء من حالة استخدام “discourse to discourse” التي أراها هو: نقطة حقيقة واحدة للوثائق (Meta) تتزامن مع المشاركات المعنية في المثيلات الأخرى. هذا يعني أنه إذا قام الفريق بتغيير Core، وقام بتحديث وثائق المستخدم Meta، فلدي نسخة محدثة من تلك الوثائق في مثيلي أصلاً ليجدها جميع المستخدمين.

بالنسبة للإصدار 2، أخطط لاستخدام قاعدة بيانات SQLlite كمدخل كما هو موضح أعلاه، وربما الكتابة بلغة Rust هذه المرة بدلاً من Python.

أدناه رسم تخطيطي تقريبي.

graph TB
    A[terminal] -- ~\u003ediscourse-sync run $PASSWORD --|> B[Rust Script]
    B -- SQLCipher:Decrypt DB using Password --> C[( sqlite: sources-and-targets')]
    C -- 'Discourse' Table Data --> B
    B -.-> D{Decision on Type}
    D -- Webhook --> E[Listen for Webhook Info]
    D -- Polling --> F[Polling API]
    E --> G[Receive New Information]
    F --> G
    G --> H[Parse and Process Data]
    H --> I[POST\n tgt_domain, tgt_usr, tgt_key, post_id]
    I --'raw' and images--> J[ Target Post ]

    subgraph Rust Script Operations
    B
    D
E
F
G
H
I
    end

سأكون سعيدًا جدًا بتلقي التعليقات والاقتراحات حول هذا :slightly_smiling_face:

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

@angus ربما يثير اهتمامك، أعتقد أننا قمنا بالفعل بحل الكثير من هذا باستخدام إضافة activity pub

6 إعجابات

نعم، أصبح هذا مدعومًا الآن بالفعل بواسطة المكون الإضافي ActivityPub. نحن قريبون جدًا من استخدامه داخليًا لمزامنة الوثائق بين meta ونسخة داخلية، وهو مدرج في قائمة مهامي للأسبوع المقبل في الواقع.

7 إعجابات

هل ينطبق هذا على كلا الحالتين؟ على سبيل المثال، المصدر عام، ولكن الهدف خاص، هل سيظل هذا يعمل؟

بقدر ما يبدو مكون ActivityPub الإضافي جيدًا، أخشى أنه قد لا يلبي احتياجات الحالات الخاصة.

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

3 إعجابات

لذا يبدو أن ActivityPub يمكن أن يعمل بالطريقة التالية:

عام --:white_check_mark: عام
عام --:white_check_mark: خاص

خاص --:x: عام
خاص --:x: خاص

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

إعجابَين (2)

@Tris20 مثير للاهتمام! شكراً لمشاركة أفكارك، وبعض التفاصيل، حول هذا الموضوع.

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

لا يوجد قيد جوهري يمكنني رؤيته على دعم النشر من الخاص إلى العام ومن الخاص إلى الخاص عبر ActivityPub. السؤال هو مسألة ضمان تلبية مخاوف الوصول والأمان عند العمل مع المثيلات الخاصة.

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

ربما يمكنك التفكير في كيفية عمل المزامنة من خاص إلى خاص في الإضافة، أي كيف يمكن معالجة أسئلة الوصول والأمان؟ ثم ربما يمكننا أنا وأنت العمل على طلب سحب (PR) معًا لإضافته كميزة. ربما ستصل إلى نقطة تشعر فيها أنه من المستحيل حقًا تحقيق ما تريد تحقيقه في سياق الإضافة (أو ActivityPub كمعيار)، ولكن العمل الذي ستقوم به للوصول إلى تلك النقطة سيكون هو نفسه العمل الذي ستحتاج إلى القيام به لحل مستقل، لذلك لن يكون عبثًا.

هناك الكثير من الأشخاص الأذكياء في عالم ActivityPub، ولن أتفاجأ إذا تم النظر في هذا النوع من المشكلات (أي النشر الخاص) بعمق في وقت ما. أحد الأماكن التي قد تجد فيها بعض الأعمال السابقة حول هذا الموضوع هو SocialHub، وهو منتدى مجتمع ActivityPub الرئيسي (Discourse بالطبع) الذي يستخدم الآن إضافة Discourse ActivityPub :slight_smile:

7 إعجابات