رفع صورة محلية باستخدام واجهة برمجة التطبيقات

مرحبًا يا أصدقاء،

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

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

client.upload_file({'user_id':24,url:'http://valid.url.here/foo.jpg','synchronous':true})

لكنني أعاني عندما أحاول رفع صورة موجودة على جهاز الكمبيوتر المحلي:

client.upload_file({'user_id':24,file:'/local/path/to/image/foo.jpg','synchronous':true})

…الاستجابة السابقة ترجع الخطأ التالي:

DiscourseApi::UnprocessableEntity: {"failed"=>"FAILED", 
"message"=>"undefined method 'tempfile' for 
#<String:0x00007f409d2fa398>"} from /home/user/.rvm/gems/
ruby-2.3.7/gems/discourse_api-0.36.0/lib/discourse_api/
client.rb:154:in 'handle_error'

لقد بحثت بما يكفي لأدرك أنني ربما أحتاج إلى القيام ببعض العمليات السحرية لترميز Base64 أو ما شابه ذلك لكي تكون طلبيتي مُشكَّلة بشكل صحيح (أدرك أيضًا أن طريقة الرفع في مكتبة Ruby ربما لا تستطيع التعامل مع هذا النوع من الرفع (وإذا كان الأمر كذلك، فلا بأس).

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

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

مرحبًا توني،

أوافقك الرأي أن رفع الملفات المحلية قد يكون محيرًا قليلًا عند استخدام واجهة برمجة التطبيقات (API). الحل المناسب هو التالي:

# upload_image.rb
require 'discourse_api'
require 'fileutils'

client = DiscourseApi::Client.new("Discourse Site URL")
client.api_key = "Your api key"
client.api_username = "Username"

filename = ARGV[1] # المسار الكامل للملف /home/tony/mypic.png

args = {
  :file => Faraday::UploadIO.new(filename, 'image/png')
}

resp = client.upload_file(args)

url = resp['url']
width = resp['width']
height = resp['height']



# topic_id هو معرف الموضوع الذي تريد رفع الصورة إليه.
args = {
  :topic_id => ARGV[0],
  :raw => "<img src=\"#{url}\" width=\"#{width}\" height=\"#{height}\">"
}

# سيؤدي هذا إلى إنشاء منشور جديد في الموضوع المحدد
resp = client.create_post(args)

سيستخدم هذا السكربت مكتبة Faraday gem لتوفير متطلبات الملف الصحيحة لـ upload_file. بمجرد رفع الملف، يجب تخصيصه لموضوع أو منشور ليظهر؛ وإلا سيتم حذفه تلقائيًا.

يمكنك تشغيل هذا السكربت باستخدام الأمر التالي:

ruby upload_image.rb <topic_id> <filename>
ruby upload_image.rb 128 /home/tony/mypic.png

بليك،

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

-توني.

قضيت وقتًا طويلاً في محاولة فهم كيفية استدعاء نقطة نهاية التحميل من سكريبت بلغة بايثون. أولاً، اتبعت التوصية بعكس هندسة استدعاء واجهة برمجة تطبيقات التحميل عبر أدوات مطوري Chrome. بعد ذلك، قمت بتكرار استدعاء التحميل عبر Postman. كان الجزء المستغرق وقتًا طويلاً بالنسبة لي هو ترجمة ذلك إلى كود بايثون يعمل. لسبب ما، لم يكن كود بايثون المُولَّد من Postman يعمل أيضًا. إليك كيف نجح الأمر في النهاية بالنسبة لي:

requests.post('/uploads.json', files={'files[]': open('/path/to/image.png', 'rb')}, data={'type': 'composer'})