I hope this is the right place to ask. I’m working on importing a set of data from another forum into our new Discourse instance (internal knowledge posts that we want to transition).
I’ve got our old data nicely packed up in a bunch of JSON structures, but I’m getting hung up on uploading the various images that are related to the old posts.
I’m using the discourse_api gem and have had terrific success so far, though I realize that it’s incomplete. I can upload an image successfully if that image is hosted somewhere, like so:
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'
I’ve poked around enough to realize that I probably need to do some base64 magic or something so that my request is properly formed (I’m also realizing that maybe the upload method for the ruby gem just can’t accommodate this type of upload (and if so, that’s fine).
Mostly I’m just looking for guidance, to see if anyone else has come up against this and to see if I’m barking up the wrong tree entirely. Thanks in advance, and all that
Unless there is some reason you cannot, I recommend looking at the import script directory to see importers that use json files. It’ll be easier than the API.
I agree uploading local files can be a bit tricky to figure out using the API. This should do the trick:
# 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] #full path to file /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 is the the id for the topic you want to upload the image to.
args = {
:topic_id => ARGV[0],
:raw => "<img src=\"#{url}\" width=\"#{width}\" height=\"#{height}\">"
}
# This will create a new post in the specified topic
resp = client.create_post(args)
This will use the Faraday gem to provide the correct file requirements for upload_file. Once the file is uploaded, it then needs to be assigned to a topic/post to show up or it will be auto deleted.
Thanks a million. I’m going to go read up on the Faraday gem so that I know what it’s doing for me, and test out your script. I really appreciate you taking the time!
Pasé bastante tiempo tratando de averiguar cómo invocar el endpoint de carga desde un script de Python. Primero seguí la recomendación de realizar ingeniería inversa a la llamada de la API de carga mediante las herramientas de desarrollo de Chrome. Luego repliqué la llamada de carga a través de Postman. La parte que más me llevó tiempo fue traducir eso a un código de Python funcional. Por alguna razón, el código de Python generado por Postman tampoco funcionaba. Así es como finalmente funcionó para mí: