Uppy uploader يتعطل مع إسقاط ملفات متعددة على composer

مرحباً،
منذ آخر تحديث (نحن في بيئة مُدارة)، يبدو أن وظيفة التحميل لدينا معطلة ولكننا لا نقوم بأي حيل سحرية.

نقوم ببساطة بتسجيل api.addComposerUploadHandler() جديد من داخل مكون سمة.
كان هذا يعمل بشكل رائع مع ملفات متعددة تم سحبها إلى المنشئ. الآن هناك أخطاء تُلقى في وحدة التحكم والتي يبدو أنها متعلقة بـ Uppy (وهو ما لا نريده).

رمزنا بسيط حقًا، ومع ذلك، يبدو أن Uppy يتداخل معه.

// تسجيل معالج تحميل مخصص لمقاطع الفيديو.

	api.addComposerUploadHandler(["mp4", "mov", "mkv", "avi", "m4v"], (file, editor) => {
		console.log("Handling upload for", file.name);
	})

إن إسقاط 3 ملفات (mkv، mov، mkv) على المنشئ يعرض رسالة الخطأ “ملفك أكبر من 4 ميجابايت” والتي أردنا تجاوزها في المقام الأول حيث نقوم بتحميل كل شيء إلى Gdrive.

وحدة تحكم Chrome تلقي هذه:

إن إسقاط ملف واحد بحجم 50 ميجابايت لا يسبب خطأ “الملف كبير جدًا” ويتم معالجة ملفنا بشكل صحيح، كما هو متوقع. لذلك يبدو أن الخطأ يحدث مع ملفات متعددة وملف واحد أكبر من حد الملف البالغ 4 ميجابايت (لست متأكدًا من مكان تعيين هذا).

شكرًا على أي مساعدة في هذا. أعتقد أنه مرتبط بآخر تحديث لـ Discourse نفسه.

@martin

مرحباً @Sören_Geier. لقد حدثت بعض التغييرات في هذا المجال مؤخرًا، على الرغم من أنني حاولت الحفاظ على التكافؤ مع معالج التحميل الحالي في المنشئ. أريد فقط الحصول على فكرة أفضل عن حالة الاستخدام الخاصة بك. على حد علمي، حتى الإصدار غير Uppy من المنشئ يقوم بالتحميل عبر api.addComposerUploadHandler ويتعامل مع ملف واحد فقط في كل مرة:

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/mixins/composer-upload.js#L215-L222

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

ما الذي كان يحدث سابقًا، أو ما الذي تتوقع حدوثه، عند سحب وإسقاط ملفات متعددة في وقت واحد؟ سيكون من المفيد رؤية كود مكون السمة الخاص بك، إذا لم تكن مرتاحًا لمشاركته علنًا، يمكنك إرسال رسالة خاصة لي هنا على Meta به.

لذا للتأكيد فقط، هل تستضيفنا؟

إعجابَين (2)

شكراً على الرد السريع يا @martin.

نعم، نحن نستضيف معكم. إذن، ما يحدث عادةً عندما تسحب ملفًا إلى المنشئ هو أنه يُدخل بعض النصوص في المنشئ مثل “جارٍ معالجة <اسم الملف>”… أيضًا، في حالة استخدام API.addComposerUploadHandler([“mp4”, “mov”, “mkv”, “avi”, “m4v”])، يتم ذلك بواسطة Discourse قبل تسليم الملف إلى المعالج المخصص هنا. توقف إدخال نص العنصر النائب هذا عن العمل في وقت ما، وهو الوقت الذي أدخلت فيه الكود بنفسي في المعالج الخاص بي:

composerController.model.appEvents.trigger("composer:insert-block", `[جارٍ معالجة: ${file.name}...]()`);

الشيء التالي الذي تعطل هو أن المعالج الخاص بنا لم يبدأ العمل لأن امتدادات الفيديو هذه اختفت فجأة من إعداد “الامتدادات المصرح بها للموضوع” - أو كان عليّ إعادة إضافتها هناك لكي تبدأ الأمور في العمل مرة أخرى.

ثم اكتشفت مشكلة إسقاط الملفات “المتعددة” كما هو موضح سابقًا.

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

إليك مقتطفات الكود ذات الصلة:

هنا أتوقع ببساطة أن يقوم Discourse بتسليم الملفات إليّ. واحدًا تلو الآخر.

// تسجيل معالج تحميل مخصص لمقاطع الفيديو.

api.addComposerUploadHandler(["mp4", "mov", "mkv", "avi", "m4v"], (file, editor) => {
console.log("جارٍ معالجة التحميل لـ", file.name);
sendToGDrive(file, api);
})

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

// جمع كل الملفات التي تم إسقاطها بالتتابع - كما تم الإبلاغ عنها بواسطة معالج Discourse.
function sendToGDrive(file, api) {
clearTimeout(uploaderStartTimeout);
filesHolder.push(file)
const composerController = api.container.lookup("controller:composer");
composerController.model.appEvents.trigger("composer:insert-block", `[جارٍ معالجة: ${file.name}...]()`);

uploaderStartTimeout = setTimeout(function () {
initFileSend(api);
}, 300);
}

ثم أقوم بتحميل كل ملف بشكل فردي إلى Gdrive.

// معالجة كل ملف بشكل فردي.
async function initFileSend(api) {
for (const file of filesHolder) {
const content = await sendFileToGdrive(file, api, uploadFolderId);
}
}

المشاكل الملاحظة:

  • إسقاط “ملفات متعددة” يسبب التحقق من حجم الملف بينما لا تفعل إسقاطات الملفات الفردية
إعجاب واحد (1)

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

ما سأفعله هو إجراء بعض الاختبارات المحلية لمعرفة ما فعله المُحمِّل القديم غير Uppy مع ملفات متعددة عبر معالج تحميل بإصدار مبسط من الدالة التي قدمتها في مكون سمة، ثم محاولة تحقيق التكافؤ بين الطريقة الجديدة والطريقة القديمة، لأنها ستكون أكثر مرونة بكثير من السماح بملف واحد في كل مرة على أي حال.

قد يستغرق إصلاح هذا بعض الوقت، سأعمل عليه اليوم.

إعجابَين (2)

أردت فقط تقديم تحديث سريع؛ لقد أكدت أنه مع معالجات تحميل الملحقات المسبقة، بينما يتحقق الكود مما إذا تم تحميل ملف واحد فقط، فإن هذا ليس دقيقًا لأن مُحمّل ملفات jQuery يرسل ملفًا واحدًا فقط عبر مسار الكود هذا في كل مرة، حتى لو أسقطت ملفات متعددة في وقت واحد. هذا على عكس uppy، الذي يعالج الملفات المضافة في مجموعات. يتم افتراض هذا الملف الواحد في كل مرة في مكونين إضافيين آخرين قمنا بإنشائهما يستخدمان api.addComposerUploadHandler لذلك يبدو أنه مشكلة شائعة.

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

إعجابَين (2)

تحديث أخير قبل عطلة نهاية الأسبوع. لدي هذا الإصلاح الذي يجب دمجه في بداية الأسبوع المقبل والذي سيعيد “الطريقة القديمة” لفعل الأشياء من ما قبل uppy، ولكن داخل uppy. لذلك سيعود تطبيقك للعمل بشكل صحيح بعد هذا:

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

لذلك ستتحول دالة المعالجة الخاصة بك بعد ذلك إلى شيء مثل هذا:

// تسجيل معالج تحميل مخصص لمقاطع الفيديو.
api.addComposerUploadHandler(
  ["mp4", "mov", "mkv", "avi", "m4v"],
  (files, editor) => {
    console.log("Handling upload for", files.map((file) => file.name).join(", "));
    sendToGDrive(files, api);
  }
);
إعجابَين (2)

ممتاز. شكراً لك على التحقق من الأمر بهذه السرعة!
أتمنى لك عطلة نهاية أسبوع رائعة ومستحقة :blush:

إعجابَين (2)

@Sören_Geier لقد قمت للتو بدمج DEV: Send multiple files in batches to composer upload handlers when using uppy by martin-brennan · Pull Request #15124 · discourse/discourse · GitHub الذي يغير uppy لإرسال ملفات متعددة دفعة واحدة إلى معالج التحميل؛ ستحتاج إلى تحديث مكون السمة الخاص بك الآن للتعامل مع هذا :slight_smile:

3 إعجابات

هذا رائع. لم يتم نشره بعد، أليس كذلك؟

هل تستخدم الاستضافة القياسية الخاصة بنا؟ إذا كان الأمر كذلك، فيجب أن تكون قد تم نشرها الآن :slight_smile:

3 إعجابات

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

للوصول فعليًا إلى كائن الملف الأصلي، كان عليّ التعامل مع files[0].data. (ربما تغيير يكسر التوافق؟)

قبل هذا التغيير، كان المعالج يمرر كائن الملف الأصلي. يمكنني توقع أن يواجه أشخاص آخرون تعطلًا في الوظائف مع هذا التغيير، لست متأكدًا.

لقد جعلت كل شيء يعمل الآن. شكرًا جزيلاً على سرعة الاستجابة والدعم!

3 إعجابات

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

تحرير: الإصلاح هنا، يجب نشره على استضافتنا القياسية في الساعات القليلة القادمة.

3 إعجابات

عظيم، لقد قمنا بتعديل الكود الخاص بنا أيضًا. أعتقد أنه يمكن إغلاق الموضوع الآن. شكرًا على المساعدة الاستثنائية @martin

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

لا مشكلة! لقد أحدثت الفوضى، فمن الصواب أن أقوم بتنظيفها :sweat_smile:

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