2016-05-05 2 views
2

Новый пользователь clojure здесь. , , немного запутавшись.Clojure: Чтение CSV-файла и значений столбца для завивки

Цели проекта:

  • чтения данных из CSV-файла
  • изолят значения в колонке 4
  • значения переходят к HTML параметру
  • использование динамически созданный URL в завиток вызова

Я застреваю в двух конкретных областях:

1) если я вынимаю println в файлах процессов, я начинаю получать ошибки об этом, не зная, что делать с «%» (Невозможно разрешить символ:% в этом контексте)

2) curl Я не могу представить значение переданного id в идентификатор параметра URL.

(defn call-curl [id] 
    (let [url "-d id=%s&format=pdf&cpull=1"] 
    (shell/sh "curl" "-u" "username:password" "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi" (format url id)))) 

(defn process-files 
    "Take file name and read data" 
    [file] 
    (let [data (slurp file) 
     rows (rest (c/parse-csv data))] 
    (dorun 
    (map #(println (call-curl (nth % 3 nil))) rows)))) 

(process-files "output.csv") 

ответ

2

Я подозреваю, что первая проблема возникает потому, что код без println выглядел как:

(map (call-curl (nth % 3 nil)) rows) 

Вместо:

(map #(call-curl (nth % 3 nil)) rows) 

В тех случаях, когда вы хотите travese всей последовательности только для побочные эффекты, я бы предложил doseq:

(doseq [row rows] 
    (call-curl (nth row 3 nil))) 

В качестве альтернативы вы можете использовать run!:

(run! call-curl (map #(nth % 3 nil))) 

, но я бы сказал, что doseq версия более читаемым.

Для второго вопроса, я думаю, вы должны предоставить каждый отдельный аргумент curl вызова в качестве отдельной строки: она должна быть

"-d" "..."

вместо

"-d ..."

I немного отредактировали его, чтобы сделать его более читаемым:

(defn call-curl [id] 
    (let [data (format "id=%s&format=pdf&cpull=1" id)] 
    (shell/sh "curl" "-u" "username:password" "-d" data "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi"))) 

Еще одно замечание о том, что в соответствии с вашим кодом вы не передаете параметр в URL-адресе, а скорее данные, переданные в качестве тела запроса. От man curl:

-d, --data

(HTTP) Отправляет указанные данные в запросе POST на сервер HTTP, таким же образом, что браузер делает, когда пользователь заполнил HTML-форму и нажмите кнопку отправки.Это вызовет curl , чтобы передать данные на сервер, используя приложение типа контента/x-www-form-urlencoded. Сравнить с -F, --form.

-d, --data - это то же самое, что и -data-ascii. --data-raw - почти то же самое, но не имеет специальной интерпретации символа @. Чтобы публиковать данные чисто бинарные, вы должны использовать двоичную опцию -data- . Чтобы URL-кодировать значение поля формы, вы можете использовать -data-urlencode.

Я не был уверен, почему вы хотите позвонить curl вместо вызова HTTP конечных точек непосредственно из Clojure, но теперь, когда вы отметили, что вы действительно хотели сделать это напрямую, позвольте мне рекомендовать вам использовать clj-http библиотеку для этого цель. С его помощью он становится таким же простым, как:

(require '[clj-http.client :as http]) 

(defn call-url [id] 
    (http/post "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi" 
    {:basic-auth ["username" "password"] 
    :form-params {:id id 
        :format "pdf" 
        :cpull 1}})) 
+0

Спасибо! Предложения разрешили все ошибки, которые я получаю. Странная вещь и причина, по которой я пытаюсь ломаться здесь, - это если я звоню в cgi из кода clojure или java, ничего не происходит. Если я копирую/вставляю вызов curl в команду, как, он работает. Но даже при использовании curl в этом контексте скрипт cgi все еще не запускается. –

+1

@ Kawili-wili Я включил пример, как выполнить HTTP POST с использованием библиотеки clj-http. –

+0

Да, много чистых наверняка. Спасибо за это. Я сразу же попробовал уродливую версию http.client, но, похоже, ничего не сделал, поэтому я переключаюсь на попытку скручивания. Я только что обнаружил, что моя проблема в том, что мне нужно было использовать потоки с функцией call-url - она ​​висела на одном вызове. Я завернул эту функцию в будущее, и теперь она плавает, как гангстеры. Еще раз спасибо! –

1

Помогло ли это?

Использует str, а не format, распределяя в какой-то степени, с желанием Выпускаемое блока:

(shell/sh 
    "curl" "-u" "username:password" "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi" 
    "-d" (str "id=" id "&format=pdf&cpull=1")) 

Возвращает вывод вызова скручивание с помощью :out ключевого слова:

#((call-curl (nth % 3 nil)) :out) 

Пересмотренный код :

(require '[clojure.java.shell :as shell]) 
(defn call-curl [id] 
    (shell/sh 
    "curl" "-u" "username:password" "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi" 
    "-d" (str "id=" id "&format=pdf&cpull=1"))) 

(defn process-files 
    "Take file name and read data" 
    [file] 
    (let [data (slurp file) 
     rows (rest (c/parse-csv data))] 
    (dorun 
    (map #(do (prn %) (call-curl (nth % 3 nil))) 
      rows)))) 

(process-files "output.csv") 
+0

Это все отличное предложение. Спасибо, что нашли время, чтобы обеспечить альтернативный подход! –

Смежные вопросы