| dependencies
 | (this space intentionally left almost blank) | |||||||||
| (ns gengoclj.auth (:import (java.util Calendar) (javax.crypto Mac) (javax.crypto.spec SecretKeySpec) (java.math BigInteger))) | ||||||||||
| (defn- current-timestamp []
  (let [cal (Calendar/getInstance)
        current-time-millis (long (/ (long (.getTimeInMillis cal)) 1000))]
    (String/valueOf current-time-millis))) | ||||||||||
| (defn- get-hash-str [data-bytes]
  (apply str
	  (map #(.substring
           (Integer/toString (+ (bit-and % 0xff) 0x100) 16) 1) data-bytes))) | ||||||||||
| Calculate HMAC signature for given data. | (defn- hmac
  [#^String key #^String data]
  (let [hmac-sha1 "HmacSHA1"
        signing-key (SecretKeySpec. (.getBytes key "iso-8859-1") hmac-sha1)
        mac (doto (Mac/getInstance hmac-sha1) (.init signing-key))]
    (get-hash-str (.doFinal mac (.getBytes data "iso-8859-1"))))) | |||||||||
| Creates map of required data for gengo authentication | (defn- add-auth-params
  [key secret request]
  (let [ts (current-timestamp)]
    (assoc request
      :query (merge
               (request :query)
               {:ts ts
                :api_sig (hmac secret ts)
                :api_key key})))) | |||||||||
| (defn- add-data-param [request] (assoc-in request [:query :data] (request :body))) | ||||||||||
| (defn authenticated-request [key secret request] (add-auth-params key secret (add-data-param request))) | ||||||||||
| (ns gengoclj.gengo
  (:require
   [clj-http.client :as http]
   [gengoclj.auth :as auth])
  (:use [clojure.data.json :only [json-str read-json]]
        [clojure.string :only [join]])) | ||||||||||
| (def client-version 0.1)
(def user-agent (format "Gengo Clojure library; Version %f" client-version))
(def gengo-live-base "https://api.gengo.com/v2/")
(def gengo-sandbox-base "http://api.sandbox.gengo.com/v2/")
(def ^{:dynamic true} *gengo-key* nil)
(def ^{:dynamic true} *gengo-secret* nil)
(def ^{:dynamic true} *sandbox?* true) | ||||||||||
| (defmacro with-gengo [[key secret sandbox?] & body]
  `(binding [*gengo-key* ~key *gengo-secret* ~secret *sandbox?* ~sandbox?]
     ~@body)) | ||||||||||
| (defstruct request :method :path :query :body) | ||||||||||
| (defstruct job :slug :body_src :lc_src :lc_tgt :tier) | ||||||||||
| (defn- uri [path]
  (if *sandbox?*
    (str gengo-sandbox-base path)
    (str gengo-live-base path))) | ||||||||||
| (defn- make-uri [request] (uri (request :path))) | ||||||||||
| (defn- parameter-string [params]
  (join "&"
        (map (fn [[key val]] (str (name key) "=" (str val)))
             (sort-by #(name (key %)) java.lang.String/CASE_INSENSITIVE_ORDER params)))) | ||||||||||
| (defn- make-post-request [request]
  {:body (parameter-string
           (merge
             (:query
               (auth/authenticated-request *gengo-key* *gengo-secret* request))
               (assoc {} :data (json-str (request :body)))))
    :query-params nil
    :headers {"Content-Type" "application/x-www-form-urlencoded"
              "User-Agent" user-agent
              "Accept" "application/json"}}) | ||||||||||
| (defn- make-put-request [request]
  {:body (parameter-string
           (merge
             (:query
               (auth/authenticated-request *gengo-key* *gengo-secret* request))
               (assoc {} :data (json-str (request :body)))))
    :query-params nil
    :headers {"Content-Type" "text/plain"
              "User-Agent" user-agent
              "Accept" "application/json"}}) | ||||||||||
| (defn- do-get! [request]
  (read-json (:body (http/get (make-uri request)
              {:body (request :body)
               :query-params (:query (auth/authenticated-request *gengo-key* *gengo-secret* request))
               :headers {"Content-Type" "application/json"
                         "User-Agent" user-agent
                         "Accept" "application/json"}})))) | ||||||||||
| (defn- do-post! [request]
  (let [request-body (make-post-request request)]
    (read-json (:body (http/post (make-uri request)
            request-body))))) | ||||||||||
| (defn- do-put! [request]
  (let [request-body (make-put-request request)]
    (read-json (:body (http/put (make-uri request)
              request-body))))) | ||||||||||
| (defn- do-delete! [request]
  (read-json (:body (http/delete (make-uri request)
               {:body (request :body)
                :query-params (:query (auth/authenticated-request *gengo-key* *gengo-secret* request))
                :headers {"Content-Type" 
                          "User-Agent" user-agent
                          "Accept" "application/json"}})))) | ||||||||||
| Get account statistics | (defn get-account-stats
  []
  (let [request (struct request "GET" "account/stats" nil nil)]
    (do-get! request))) | |||||||||
| Get account balance | (defn get-account-balance
  []
  (let [request (struct request "GET" "account/balance" nil nil)]
    (do-get! request))) | |||||||||
| Get preferred translators in array by langs and tier | (defn get-account-preferred-translators
  []
  (let [request (struct request "GET" "account/preferred_translators" nil nil)]
    (do-get! request))) | |||||||||
| Submit multiple jobs for translation | (defn post-translation-jobs
  [jobs as-group?]
  (let [request (struct request "POST" "translate/jobs" nil {:jobs jobs :as_group (if as-group? "1" "0")})]
    (do-post! request))) | |||||||||
| Request revisions for a job | (defn revise-translation-job
  [job-id comments]
  (let [request (struct request "PUT" (format "translate/job/%d" job-id) nil {:action "revise" :comment comments})]
    (do-put! request))) | |||||||||
| Approve a translation | (defn approve-translation-job
  [job-id rating translator-comments gengo-comments is-public?]
  (let [request (struct request "PUT" (format "translate/job/%d" job-id) nil
                        (merge {:action "approve" :public (if is-public? "1" "0")}
                          (if (nil? rating) {} {:rating rating})
                          (if (nil? translator-comments) {} {:commentsForTranslator translator-comments})
                          (if (nil? gengo-comments) {} {:commentsForGengo gengo-comments})))]
    (do-put! request))) | |||||||||
| Reject a translation | (defn reject-translation-job
  [job-id reason comments captcha requeue?]
  (let [request (struct request "PUT" (format "translate/job/%d" job-id) nil
                  {:action "reject" :reason reason :comment comments :captcha captcha :follow_up (if requeue? "requeue" "cancel")})]
    (do-put! request))) | |||||||||
| Get a translation job | (defn get-translation-job
  [job-id]
  (let [request (struct request "GET" (format "translate/job/%d" job-id) nil nil)]
    (do-get! request))) | |||||||||
| Get all or slected translation jobs | (defn get-translation-jobs
  [& [job-ids]]
  (let [request (struct request "GET" (if job-ids (str "translate/jobs/" (join "," job-ids)) "translate/jobs/") nil nil)]
    (do-get! request))) | |||||||||
| Post a comment for a translation job | (defn post-translation-job-comment
  [job-id comments]
  (let [request (struct request "POST" (format "translate/job/%d/comment" job-id) nil {:body comments})]
    (do-post! request))) | |||||||||
| Get comments for a translation job | (defn get-translation-job-comments
  [job-id]
  (let [request (struct request "GET" (format "translate/job/%d/comments" job-id) nil nil)]
    (do-get! request))) | |||||||||
| Get feedback for a translation job | (defn get-translation-job-feedback
  [job-id]
  (let [request (struct request "GET" (format "translate/job/%d/feedback" job-id) nil nil)]
    (do-get! request))) | |||||||||
| Get revisions for a translation job | (defn get-translation-job-revisions
  [job-id]
  (let [request (struct request "GET" (format "translate/job/%d/revisions" job-id) nil nil)]
    (do-get! request))) | |||||||||
| Get a specific revision for a translation job | (defn get-translation-job-revision
  [job-id revision-id]
  (let [request (struct request "GET" (format "translate/job/%d/revisions/%d/" job-id revision-id) nil nil)]
    (do-get! request))) | |||||||||
| Cancel a translation job. It can only be deleted if it has not been started by a translator | (defn delete-translation-job
  [job-id]
  (let [request (struct request "DELETE" (format "translate/job/%d" job-id) nil nil)]
    (do-delete! request))) | |||||||||
| Get a list of supported languages and their language codes | (defn get-service-languages
  []
  (let [request (struct request "GET" "translate/service/languages" nil nil)]
    (do-get! request))) | |||||||||
| Get a list of supported language pairs, tiers, and credit prices | (defn get-service-language-pairs
  [&[source-lang-code]]
  (let [request (struct request "GET" "translate/service/language_pairs" (if source-lang-code {:lc_src source-lang-code} nil) nil)]
    (do-get! request))) | |||||||||
| Get a quote for translation jobs. | (defn determine-translation-cost
  [jobs]
  (let [request (struct request "POST" "translate/service/quote" nil {:jobs jobs})]
    (do-post! request))) | |||||||||
| Get translation jobs which were previously submitted together by their order id | (defn get-order-jobs
  [order-id]
  (let [request (struct request "GET" (format "translate/order/%d" order-id) nil nil)]
    (do-get! request))) | |||||||||
| (ns gengoclj.examples.account (:require [gengoclj.gengo :as gengo])) | ||||||||||
| get account balance | (with-gengo ["key" "secret" true] (get-account-balance)) | |||||||||
| get account preferred translators | (with-gengo ["key" "secret" true] (get-account-preferred-translators)) | |||||||||
| get account stats | (with-gengo ["key" "secret" true] (get-account-stats)) | |||||||||
| (ns gengoclj.examples.jobs (:require [gengoclj.gengo :as gengo])) | ||||||||||
| delete a translation job | (with-gengo ["key" "secret" true] (delete-translation-job 12345)) | |||||||||
| get a translation job | (with-gengo ["key" "secret" true] (get-translation-job 12345)) | |||||||||
| get a translation job's comments | (with-gengo ["key" "secret" true] (get-translation-job-comments 12345)) | |||||||||
| get a translation job's feedback | (with-gengo ["key" "secret" true] (get-translation-job-feedback 12345)) | |||||||||
| get a translation job's revisions | (with-gengo ["key" "secret" true] (get-translation-job-revisions 12345)) | |||||||||
| get a specific translation job's revision | (with-gengo ["key" "secret" true] (get-translation-job-revision 12345 6)) | |||||||||
| get multiple translation jobs | (with-gengo ["key" "secret" true] (get-translation-jobs (list 1 2 3 4 5))) | |||||||||
| get all translation jobs | (with-gengo ["key" "secret" true] (get-translation-jobs)) | |||||||||
| post a comment on a translation job | (with-gengo ["key" "secret" true] (post-translation-job-comment 12345 "This is a comment.")) | |||||||||
| post new translation jobs | (with-gengo ["key" "secret" true]
  (let [job1 (struct job "slug1" "content1" "en" "es" "standard")
        job2 (struct job "slug2" "content2" "en" "es" "standard")]
    (post-translation-jobs (list job1 job2) true))) | |||||||||
| approve a translation job params - job-id rating (integer 1-5) translator-comments gengo-comments is-public? | (with-gengo ["key" "secret" true] (approve-translation-job 12345 4 "Something for the translator" "Something for gengo" true)) | |||||||||
| reject a translation job params - job-id reason (0: Quality 1: Incomplete 2: Other) comments captcha requeue? | (with-gengo ["key" "secret" true] (reject-translation-job 12345 0 "Some comment" "captcha text" true)) | |||||||||
| revise a translation job params - job-id comments | (with-gengo ["key" "secret" true] (revise-translation-job 12345 "Please fix this and that")) | |||||||||
| (ns gengoclj.examples.order (:require [gengoclj.gengo :as gengo])) | ||||||||||
| get group of jobs submitted together by their order id | (with-gengo ["key" "secret" true] (get-order-jobs 12345)) | |||||||||
| (ns gengoclj.examples.service (:require [gengoclj.gengo :as gengo])) | ||||||||||
| get all service language pairs | (with-gengo ["key" "secret" true] (get-service-language-pairs)) | |||||||||
| get specific service language pairs by source language | (with-gengo ["key" "secret" true] (get-service-language-pairs "en")) | |||||||||
| get service languages | (with-gengo ["key" "secret" true] (get-service-languages)) | |||||||||