Permalink
Browse files

Further cleanup.

clj-oauth2 restored temporarily until friend migration complete....
  • Loading branch information...
1 parent 67abee2 commit 2dd53db2c448f61ff4fc989ffca39366ad04cb7d Donald Clark Jackson committed Mar 31, 2013
View
@@ -4,3 +4,4 @@ lib
classes
target
.lein-deps-sum
+.lein-repl-history
View
@@ -1,6 +1,9 @@
(defproject net.likestream/clj-facebook-graph "0.5.0-SNAPSHOT"
+
:description "A Clojure client for the Facebook Graph API"
- :url "http://github.com/FreeAgent/clj-facebook-graph/"
+
+ :url "http://github.com/LikeStream/clj-facebook-graph/"
+
:license {:name "Eclipse Public License - v 1.0"
:url "http://www.eclipse.org/legal/epl-v10.html"
:distribution :repo
@@ -11,6 +14,7 @@
[ring/ring-core "1.1.8"]
[clj-http "0.7.0"]
[slingshot "0.10.3"]
+ [bwhmather/clj-oauth2 "0.5.1"]
]
:profiles {:dev {:dependencies [[ring/ring-devel "1.1.8"]
@@ -1,9 +1,7 @@
(ns clj-facebook-graph.auth
- (:use [clj-facebook-graph.helper :only [facebook-base-url facebook-fql-base-url]]
- ;; [clojure.data.json :only [read-json]]
- )
- (:require ;; [clj-oauth2.client :as oauth2]
+ (:require [clj-facebook-graph.helper :refer [facebook-base-url facebook-fql-base-url]]
[clojure.string :as str]
+ [clj-oauth2.client :as oauth2]
[cheshire.core :as json])
(:import [org.apache.commons.codec.binary Base64]
[javax.crypto Mac]
@@ -14,13 +12,13 @@
:authorization-uri "https://graph.facebook.com/oauth/authorize"
:access-token-uri "https://graph.facebook.com/oauth/access_token"})
-;; (defn get-access-token
-;; "Fetches the access token using clj-oauth2/client."
-;; [facebook-app-info params & [auth-req]]
-;; (:access-token (oauth2/get-access-token
-;; (merge facebook-oauth2-endpoint facebook-app-info)
-;; params
-;; auth-req)))
+(defn get-access-token
+ "Fetches the access token using clj-oauth2/client."
+ [facebook-app-info params & [auth-req]]
+ (:access-token (oauth2/get-access-token
+ (merge facebook-oauth2-endpoint facebook-app-info)
+ params
+ auth-req)))
;; (defn make-auth-request [facebook-app-info]
@@ -37,11 +35,13 @@
`(binding [*facebook-auth* ~facebook-auth]
~@body))
-(defn- oauth2-access-token []
+(defn- oauth2-access-token
+ []
(assoc *facebook-auth*
:query-param (:access-query-param facebook-oauth2-endpoint) :token-type "draft-10"))
-(defn has-facebook-auth[]
+(defn has-facebook-auth
+ []
"Returns whether there is an existing binding for facebook-auth"
((complement nil?) *facebook-auth*))
@@ -77,7 +77,12 @@
(defn strtr
"My take on PHP's strtr function."
[value from to]
- ((apply comp (map (fn [a b] #(.replace % a b)) from to))
+ ((apply comp
+ (map (fn
+ [a b]
+ #(.replace % a b))
+ from
+ to))
value))
(defn decode-signed-request
@@ -86,29 +91,29 @@
[signed-request key]
(when (and signed-request key
(re-matches #"^[^\.]+\.[^\.]+$" signed-request))
- (let [[signiture payload] (str/split signed-request #"\.")
- signiture (str (strtr signiture "-_" "+/") "=")]
- (when (= signiture (hmac-sha-256 key payload))
+ (let [[signature payload] (str/split signed-request #"\.")
+ signature (str (strtr signature "-_" "+/") "=")]
+ (when (= signature (hmac-sha-256 key payload))
(json/parse-string (base64-decode payload)
true)))))
-;; (read-json (base64-decode payload))))))
-
-(defn extract-facebook-auth [session]
+(defn extract-facebook-auth
+ [session]
(:facebook-auth (val session)))
(defn facebook-auth-user
"Get the basic facebook user data for the given facebook-auth (access_token)."
[client-get facebook-auth]
- (with-facebook-auth facebook-auth (client-get [:me] {:extract :body})))
+ (with-facebook-auth facebook-auth
+ (client-get [:me] {:extract :body})))
(defn facebook-auth-by-name
"Take all sessions from the session-store and extracts the facebook-auth
information. Finally a map is created where the user's Facebook name is
associated with his current facebook-auth (access-token)."
[client-get session-store]
(first (map #(let [facebook-auth (extract-facebook-auth %)
- user-name (:name (facebook-auth-user client-get facebook-auth))]
+ user-name (:name (facebook-auth-user client-get facebook-auth))]
(identity {user-name
facebook-auth}))
session-store)))
@@ -7,49 +7,40 @@
; You must not remove this notice, or any other, from this software.
(ns clj-facebook-graph.client
- "A client for the Facebook Graph API based on clj-http and clj-oauth2."
- (:use [clj-facebook-graph.helper :only [wrap-exceptions facebook-base-url facebook-fql-base-url]]
- [clj-facebook-graph.auth :only [wrap-facebook-access-token]]
- [clj-facebook-graph.error-handling :only [wrap-facebook-exceptions]])
- (:require [clj-http.client :as client]
- [clj-facebook-graph.auth :as auth])
+ "A client for the Facebook Graph API using clj-http"
+ (:require [clj-http.client :as http]
+ [clj-http.core :as http-core :only [request]]
+ [clj-facebook-graph.helper :refer [wrap-exceptions facebook-base-url facebook-fql-base-url]]
+ [clj-facebook-graph.error-handling :refer [wrap-facebook-exceptions]])
(:refer-clojure :exclude [get]))
-
-(defn wrap-facebook-url-builder [client]
+(defn wrap-facebook-url-builder
"Offers some convenience by assemble a Facebook Graph API URL from a vector of keywords or strings.
- Instead of defining the whole Facebook Graph API URL like this (client/get \"https://graph.facebook.com/me/friends\") you can
- simple write (client/get [:me :friends]) (you can also write [\"me\" \"friends\"]). It's flexible thanks to the homogeneity
+ Instead of defining the whole Facebook Graph API URL like this (http/get \"https://graph.facebook.com/me/friends\") you can
+ simple write (http/get [:me :friends]) (you can also write [\"me\" \"friends\"]). It's flexible thanks to the homogeneity
of the Facebook Graph API. When you have more than an id (here \"me\") and a connection type
(here \"friends\"), you can also provide three or more
keywords (or strings) like in the case of 'https://graph.facebook.com/me/videos/uploaded' for example."
+ [client]
(fn [req]
(let [{:keys [url]} req]
(if (vector? url)
- (let [url-parts-as-str (map #(if (keyword? %) (name %) (str %)) url)
- url (apply str (interpose "/" (conj url-parts-as-str facebook-base-url)))]
+ (let [url-parts-as-str (map #(if (keyword? %)
+ (name %)
+ (str %))
+ url)
+ url (apply str
+ (interpose "/" (conj url-parts-as-str
+ facebook-base-url)))]
(client (assoc req :url url)))
(client req)))))
-;; Use Cheshire support within clj-http...
-;; (defn wrap-json-response-conversion [client]
-;; "Automatically transforms the body of a response of a Facebook Graph API request from JSON to a Clojure
-;; data structure through the use of clojure.data.json. It checks if the header Content-Type
-;; is 'text/javascript' which the Facebook Graph API returns in the case of a JSON response."
-;; (fn [req]
-;; (let [{:keys [headers] :as resp} (client req)
-;; content-type (headers "content-type")]
-;; (if (and content-type
-;; (or
-;; (.startsWith content-type "text/javascript")
-;; (.startsWith content-type "application/json")))
-;; (assoc resp :body (read-json (:body resp)))
-;; resp))))
-(defn has-facebook-auth[]
- "Returns whether there is an existing binding for facebook-auth"
- (auth/has-facebook-auth))
+;; (defn has-facebook-auth
+;; "Returns whether there is an existing binding for facebook-auth"
+;; []
+;; (auth/has-facebook-auth))
-(defn wrap-facebook-data-extractor [client]
+(defn wrap-facebook-data-extractor
"The Facebook Graph API mostly returns a JSON document in the form like this one:
{
\"data\": [...]
@@ -63,10 +54,11 @@
automatically triggers the pagination as you walk through the seq.
This Ring-style middleware also supports to simply extract the body part of the request
(':extract :body'). "
+ [client]
(fn [req]
(let [{:keys [extract paging]} req
- response (client req)
- body (:body response)]
+ response (client req)
+ body (:body response)]
(if extract
(if (= :body extract)
body
@@ -80,7 +72,8 @@
extraction)))
response))))
-(defn wrap-fql [client]
+(defn wrap-fql
+ [client]
(fn [req]
(let [{:keys [url fql]} req]
(if (and (= url :fql))
@@ -101,18 +94,17 @@
wrap-facebook-exceptions
wrap-exceptions
wrap-request-fn
- ;; wrap-oauth2
- ;; wrap-facebook-access-token
- ;; wrap-json-response-conversion
wrap-facebook-url-builder
wrap-facebook-data-extractor
wrap-fql
))
- ([request] (wrap-request request client/wrap-request)))
+ ([request]
+ (wrap-request request
+ http/wrap-request)))
(def
request
- (wrap-request #'clj-http.core/request))
+ (wrap-request #'http-core/request))
(defn get
"Like #'request, but sets the :method and :url as appropriate."
@@ -122,4 +114,5 @@
(defn post
"Like #'request, but sets the :method and :url as appropriate."
[url & [req]]
- (request (merge req {:as :json :method :post :url url})))
+ (request (merge req
+ {:as :json :method :post :url url})))
@@ -17,13 +17,13 @@
^{:doc "A map with some interesting Facebook errors that are
assigned to a keyword to identify the error easier. At the moment the
map only include two errors which are relevant for authentication and authorisation."}
- facebook-errors {
- :OAuthException {"Error validating access token"
- :invalid-access-token
- "An access token is required to request this resource."
- :access-token-required
- }
- })
+ facebook-errors
+ {:OAuthException {"Error validating access token"
+ :invalid-access-token
+ "An access token is required to request this resource."
+ :access-token-required
+ }
+ })
(defn identify-facebook-error
"Tries to identify the Facebook error in the response with the help
@@ -33,12 +33,14 @@
error is returned in a form like this one:
{:error [:OAuthException :invalid-access-token] :message \"Error validation access token\"}"
- [response] (let [{:keys [type message]} (get-in response [:body :error])
- error-type (keyword type)]
- {:error
- [error-type (if-let [error (get-in facebook-errors [error-type message])]
- error :unknown)]
- :message message}))
+ [response]
+ (let [{:keys [type message]} (get-in response [:body :error])
+ error-type (keyword type)
+ error-categorized (if-let [error (get-in facebook-errors [error-type message])]
+ error
+ :unknown)]
+ {:error [error-type error-categorized]
+ :message message}))
(defn wrap-facebook-exceptions
"The ring-style middleware to detect Facebook errors in the response of
@@ -9,14 +9,14 @@
(ns clj-facebook-graph.helper
"Some helper functions."
(:use ;; [clojure.data.json :only [read-json read-json-from Read-JSON-From]]
- [clojure.java.io :only [reader]]
+ ;; [clojure.java.io :only [reader]]
[clj-http.client :only [unexceptional-status?]]
[clj-facebook-graph.uri :only [make-uri]]
[clojure.string :only [blank?]]
ring.middleware.params
- [slingshot.slingshot :only [throw+ try+]])
- (:import
- (java.io PushbackReader ByteArrayInputStream InputStreamReader)))
+ [slingshot.slingshot :only [throw+ try+]]))
+ ;; (:import
+ ;; (java.io PushbackReader ByteArrayInputStream InputStreamReader)))
(def facebook-base-url "https://graph.facebook.com")
@@ -29,28 +29,32 @@
;; (ByteArrayInputStream. input)))
;; keywordize? eof-error? eof-value)))
-(defn build-url [request]
+(defn build-url
"Builds a URL string which corresponds to the information of the request."
+ [request]
(let [{:keys [server-port server-name uri query-params scheme]} request]
(str (make-uri {:scheme (name scheme)
:host server-name
:port server-port
:path uri
:query query-params}))))
-(defn wrap-exceptions [client]
+(defn wrap-exceptions
"An alternative Ring-style middleware to the #'clj-http.core/wrap-exceptions. This
one also extracts the body from the http response, which is very helpful to see
the error description Facebook has returned as JSON document."
+ [client]
(fn [req]
(let [{:keys [status body] :as resp} (client req)]
- (if (or (not (clojure.core/get req :throw-exceptions true))
+ (if (or (not (clojure.core/get req
+ :throw-exceptions
+ true))
(unexceptional-status? status))
resp
(throw+ (str "Status: " status " body: " (slurp body)))))))
-(defn wrap-print-request-map [client]
- "Simply prints the request map to *out*."
- (fn [req]
- (println req)
- (client req)))
+;; (defn wrap-print-request-map [client]
+;; "Simply prints the request map to *out*."
+;; (fn [req]
+;; (println req)
+;; (client req)))
Oops, something went wrong.

0 comments on commit 2dd53db

Please sign in to comment.