Я создаю прототип приложения Rails для загрузки документов в FSCrawler (работает интерфейс REST) для включения в индекс Elasticsearch. На их примере это работает:
response = `curl -F "file=@#{params[:document][:upload].tempfile.path}" "http://127.0.0.1:8080/fscrawler/_upload?debug=true"`
Файл загружается, а содержимое индексируется. Это пример того, что я получаю:
"{\n \"ok\" : true,\n \"filename\" : \"RackMultipart20200130-91061-16swulg.pdf\",\n \"url\" : \"http://127.0.0.1:9200/local/_doc/d661edecf3e28572676e97a6f0d1d\",\n \"doc\" : {\n \"content\" : \"\\n \\n \\n\\nBasically, what you need to know is that Dante is all IP-based, and makes use of common IT standards. Each Dante device behaves \\n\\nmuch like any other network device you would already find on your network. \\n\\nIn order to make integration into an existing network easy, here are some of the things that Dante does: \\n\\n▪ Dante...
Когда я запускаю curl
в командной строке, я получаю ВСЕ, как правильно заданное «имя файла». Если я использую его, как указано выше, в контроллере Rails, как вы можете видеть, в качестве имени файла указано имя файла Tempfile. Это нереализуемое решение. Пытаясь использовать params[:document][:upload].tempfile
(без .path
) или просто params[:document][:upload]
оба не удаются полностью.
Я пытаюсь сделать это "правильным способом", но при каждом воплощении использования надлежащего HTTP-клиента для сделать это не удастся. Я не могу понять, как вызвать HTTP POST, который отправит файл в FSCrawler, как это делает curl
(в командной строке).
В этом примере я просто пытаюсь отправить файл с помощью объекта Tempfile
. По какой-то причине FSCrawler выдает мне ошибку в комментарии и получает немного метаданных, но содержимое не индексируется:
## Failed to extract [100000] characters of text for ...
## org.apache.tika.exception.ZeroByteFileException: InputStream must have > 0 bytes
uri = URI("http://127.0.0.1:8080/fscrawler/_upload?debug=true")
request = Net::HTTP::Post.new(uri)
form_data = [['file', params[:document][:upload].tempfile,
{ filename: params[:document][:upload].original_filename,
content_type: params[:document][:upload].content_type }]]
request.set_form form_data, 'multipart/form-data'
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(request)
end
Если я изменю выше на использование params[:document][:upload].tempfile.path
, тогда я не получаю сообщение об ошибке InputStream, но я также (все еще) не получаю индексированное содержимое. Вот пример того, что я получаю:
{"_index":"local","_type":"_doc","_id":"72c9ecf2a83440994eb87d28786e6","_version":3,"_seq_no":26,"_primary_term":1,"found":true,"_source":{"content":"/var/folders/bn/pcc1h8p16tl534pw__fdz2sw0000gn/T/RackMultipart20200130-91061-134tcxn.pdf\n","meta":{},"file":{"extension":"pdf","content_type":"text/plain; charset=ISO-8859-1","indexing_date":"2020-01-30T15:33:45.481+0000","filename":"Similarity in Postgres and Rails using Trigrams · pganalyze.pdf"},"path":{"virtual":"Similarity in Postgres and Rails using Trigrams · pganalyze.pdf","real":"Similarity in Postgres and Rails using Trigrams · pganalyze.pdf"}}}
Если я пытаюсь использовать RestClient и пытаюсь отправить файл, ссылаясь на фактический путь к Tempfile, то я получаю это сообщение об ошибке, и я получаю Ничего:
## Unsupported media type
response = RestClient.post 'http://127.0.0.1:8080/fscrawler/_upload?debug=true',
file: params[:document][:upload].tempfile.path,
content_type: params[:document][:upload].content_type
Если я попытаюсь .read()
файл и отправить его, то я нарушу форму FSCrawler:
## Internal server error
request = RestClient::Request.new(
:method => :post,
:url => 'http://127.0.0.1:8080/fscrawler/_upload?debug=true',
:payload => {
:multipart => true,
:file => File.read(params[:document][:upload].tempfile),
:content_type => params[:document][:upload].content_type
})
response = request.execute
Очевидно, я пытался это каждый раз как я могу, но я не могу реплицировать то, что curl
делает с любыми известными Ruby клиентами HTTP. Я совершенно не понимаю, как заставить Ruby отправлять данные в FSCrawler таким образом, чтобы содержимое документа индексировалось правильно. Я был в этом гораздо дольше, чем я хочу признать. Что мне здесь не хватает?