Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reorganization of API modules, protection of interfaces
- Loading branch information
David Sheets
committed
Apr 21, 2010
1 parent
dbe1c86
commit 8a95315
Showing
11 changed files
with
297 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
exception Facebook_error of string * exn list | ||
exception Facebook_timeout | ||
exception Facebook_bad_sig | ||
|
||
type application = { | ||
app_cookie_prefix : string option; | ||
app_key : string; | ||
app_sec : string; | ||
app_domain : string; | ||
timeout : float option; | ||
mutable seq : int; | ||
} | ||
and user = { | ||
uid : int64; | ||
user_app : application; | ||
time : float; | ||
session : (string * float) option; | ||
added : bool; | ||
friends : user list; | ||
props : (string * string) list; | ||
} | ||
|
||
val application : | ||
?timeout:float option -> | ||
?cpref:string -> string -> string -> string -> application Lwt.t | ||
|
||
val generate_sig : application -> string Map.Make(String).t -> string | ||
val validate_params : | ||
application -> | ||
?ns:string -> (string * string) list -> string Map.Make(String).t Lwt.t | ||
|
||
val load_user : application -> int64 -> user | ||
val save_user : user -> unit | ||
val user : application -> Cohttp.Http_request.request -> user option Lwt.t | ||
val uid : user -> int64 | ||
val gen_cookies : string -> user -> (string * string) list |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
(* | ||
ocaml-facebook - Facebook Platform client API in OCaml | ||
Copyright (C) <2010> David Sheets <sheets@alum.mit.edu> | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU Library General Public License as | ||
published by the Free Software Foundation, version 2. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU Library General Public License for more details. | ||
You should have received a copy of the GNU Library General Public | ||
License along with this program; if not, write to the Free Software | ||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
USA | ||
*) | ||
|
||
open Lwt | ||
open Api | ||
module J = Json_type.Browse | ||
|
||
let call user = Namespace.call_method "dashboard" user | ||
|
||
let tuple_list kfn vfn json = List.fold_left | ||
(fun al -> function | ||
| k::v::[] -> (kfn k, vfn v)::al | ||
| _ -> al) | ||
[] | ||
(J.list J.array json) | ||
|
||
let uid_of_json json = Int64.of_string (J.string json) | ||
|
||
let get_count user = (call user "getCount" [("uid", `B user.uid)]) >|= J.int | ||
|
||
let multi_get_count = function | ||
| [] -> return [] | ||
| (ux::_) as ul -> let uids = `List (List.map (fun u -> `B u.uid) ul) in | ||
(call ux "multiGetCount" [("uids", uids)]) | ||
>|= (tuple_list uid_of_json J.int) | ||
|
||
let set_count user i = | ||
(call user "setCount" [("uid", `B user.uid); ("count", `D i)]) >|= J.bool | ||
|
||
let multi_set_count = function | ||
| [] -> return [] | ||
| (ux::_) as ul -> let uids = `List (List.map (fun u -> `B u.uid) ul) in | ||
(* yes, this method uses 'ids' instead of 'uids' *) | ||
(call ux "multiSetCount" [("ids", uids)]) | ||
>|= (tuple_list uid_of_json J.bool) | ||
|
||
let increment_count user = | ||
(call user "incrementCount" [("uid", `B user.uid)]) >|= J.bool | ||
|
||
let multi_increment_count = function | ||
| [] -> return [] | ||
| (ux::_) as ul -> let uids = `List (List.map (fun u -> `B u.uid) ul) in | ||
(call ux "multiIncrementCount" [("uids", uids)]) | ||
>|= (tuple_list uid_of_json J.bool) | ||
|
||
let decrement_count user = | ||
(call user "decrementCount" [("uid", `B user.uid)]) >|= J.bool | ||
|
||
let multi_decrement_count = function | ||
| [] -> return [] | ||
| (ux::_) as ul -> let uids = `List (List.map (fun u -> `B u.uid) ul) in | ||
(call ux "multiDecrementCount" [("uids", uids)]) | ||
>|= (tuple_list uid_of_json J.bool) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
val get_count : Api.user -> int Lwt.t | ||
val multi_get_count : Api.user list -> (int64 * int) list Lwt.t | ||
val set_count : Api.user -> int -> bool Lwt.t | ||
val multi_set_count : Api.user list -> (int64 * bool) list Lwt.t | ||
val increment_count : Api.user -> bool Lwt.t | ||
val multi_increment_count : Api.user list -> (int64 * bool) list Lwt.t | ||
val decrement_count : Api.user -> bool Lwt.t | ||
val multi_decrement_count : Api.user list -> (int64 * bool) list Lwt.t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
(* | ||
ocaml-facebook - Facebook Platform client API in OCaml | ||
Copyright (C) <2010> David Sheets <sheets@alum.mit.edu> | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU Library General Public License as | ||
published by the Free Software Foundation, version 2. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU Library General Public License for more details. | ||
You should have received a copy of the GNU Library General Public | ||
License along with this program; if not, write to the Free Software | ||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
USA | ||
*) | ||
|
||
let call user = Namespace.call_method "fql" user | ||
|
||
let query user q = call user "query" [("query", `S q)] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
val query : Api.user -> string -> Json_type.t Lwt.t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
(* | ||
ocaml-facebook - Facebook Platform client API in OCaml | ||
Copyright (C) <2010> David Sheets <sheets@alum.mit.edu> | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU Library General Public License as | ||
published by the Free Software Foundation, version 2. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU Library General Public License for more details. | ||
You should have received a copy of the GNU Library General Public | ||
License along with this program; if not, write to the Free Software | ||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
USA | ||
*) | ||
|
||
open Printf | ||
open Lwt | ||
open Cohttp | ||
open Api | ||
|
||
module StrMap = Map.Make(String) | ||
module AStrMap = Util.Assoc(StrMap) | ||
module MStrMap = Util.Map(StrMap) | ||
module J = Json_type.Browse | ||
|
||
type fb_data = [ `B of int64 | ||
| `D of int | ||
| `F of float | ||
| `S of string | ||
| `List of fb_data list | ||
] | ||
|
||
let facebook_http = "http://api.facebook.com/restserver.php" | ||
let facebook_https = "https://api.facebook.com/restserver.php" | ||
|
||
let rec coerce = function | ||
| `B l -> Int64.to_string l | ||
| `D i -> string_of_int i | ||
| `F f -> string_of_float f | ||
| `S s -> s | ||
| `List v -> Json_io.string_of_json (json_of_list v) | ||
and json_coerce = function | ||
| `B l -> json_of_string (Int64.to_string l) | ||
| `D i -> json_of_int i | ||
| `F f -> json_of_float f | ||
| `S s -> json_of_string s | ||
| `List v -> json_of_list v | ||
and json_of_int i = Json_type.Int i | ||
and json_of_float f = Json_type.Float f | ||
and json_of_string s = Json_type.String s | ||
and json_of_list l = Json_type.Array (List.map json_coerce l) | ||
|
||
let bind_value fn (k, v) = (k, fn v) | ||
|
||
let std_params user meth params = | ||
let get = [("method", meth); | ||
("api_key", user.user_app.app_key); | ||
("v", "1.0")] in | ||
let get = match user.session with None -> get | ||
| Some (k, _) -> ("session_key", k) :: get in | ||
let post = [("call_id", string_of_int user.user_app.seq); | ||
("format", "JSON")] @ params in | ||
let pmap = AStrMap.into_map StrMap.empty (get @ post) in | ||
let () = user.user_app.seq <- user.user_app.seq + 1 in | ||
(get, ("sig", generate_sig user.user_app pmap) :: post) | ||
|
||
let url_encode = Netencoding.Url.mk_url_encoded_parameters | ||
|
||
let attempt_post headers body url = | ||
let rec post exnlist = function | ||
| 0 -> fail (Facebook_error ("Cannot connect to Facebook", exnlist)) | ||
| n -> begin try_lwt Http_user_agent.post ~headers ~body url with | ||
| e -> post (e::exnlist) (n - 1) | ||
end | ||
in post [] 3 | ||
|
||
let facebook_error meth user params jo = | ||
let code = J.int (List.assoc "error_code" jo) in | ||
let msg = J.string (List.assoc "error_msg" jo) in | ||
fail (Facebook_error (sprintf "Error %d in %s : %s" code meth msg, [])) | ||
|
||
let call_method ns user name params = | ||
let params = List.map (bind_value coerce) params in | ||
let meth = "facebook." ^ ns ^ "." ^ name in | ||
let get, post = std_params user meth params in | ||
let qs = url_encode get in | ||
let headers = [("User-Agent", "ocaml-facebook/0.1")] in | ||
let body = url_encode post in | ||
let url = facebook_http ^ "?" ^ qs in | ||
lwt _, jss = attempt_post headers body url in | ||
let json = Json_io.json_of_string ~recursive:true ~big_int_mode:true jss in | ||
let fberr = try let jo = J.objekt json in if List.mem_assoc "error_response" jo | ||
then Some jo else None | ||
with Json_type.Json_error _ -> None | ||
in match fberr with Some jo -> facebook_error meth user params jo | ||
| None -> return json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
type fb_data = | ||
[ `B of int64 | ||
| `D of int | ||
| `F of float | ||
| `List of fb_data list | ||
| `S of string ] | ||
|
||
val call_method : string -> Api.user -> string -> (string * fb_data) list -> Json_type.t Lwt.t |
Oops, something went wrong.