Source

ocaml-bitbucket / api.ml

Full commit
camlspotter 4e97499 
camlspotter ab68943 
camlspotter 4fafae1 

camlspotter d0b5325 
camlspotter fdf4f75 
camlspotter d0b5325 
camlspotter e7a867f 

camlspotter 808369c 
camlspotter 4e97499 


camlspotter fdf4f75 


camlspotter 4e97499 

camlspotter d5035b3 
camlspotter ab68943 
camlspotter fdf4f75 
camlspotter ab68943 

camlspotter a676a3c 
camlspotter fdf4f75 
camlspotter a676a3c 


camlspotter fdf4f75 
camlspotter a676a3c 

camlspotter e7a867f 

camlspotter 4fafae1 
camlspotter e7a867f 





camlspotter 808369c 



camlspotter e7a867f 













camlspotter 32095fd 
camlspotter fdf4f75 
camlspotter 4e97499 
camlspotter 32095fd 

camlspotter a676a3c 



camlspotter 32095fd 


















camlspotter b760f49 

camlspotter fdf4f75 
camlspotter 32095fd 

camlspotter e7a867f 

camlspotter 808369c 
camlspotter e7a867f 

camlspotter 808369c 
camlspotter e7a867f 




camlspotter 808369c 
camlspotter e7a867f 












camlspotter 808369c 
camlspotter e7a867f 




camlspotter 808369c 
camlspotter e7a867f 







camlspotter 808369c 
camlspotter e7a867f 


camlspotter 808369c 
camlspotter e7a867f 

camlspotter fdf4f75 
camlspotter 808369c 
camlspotter e7a867f 




camlspotter 808369c 
camlspotter e7a867f 




camlspotter 808369c 
camlspotter e7a867f 







camlspotter b760f49 
camlspotter 4e97499 


camlspotter 808369c 
camlspotter 4e97499 

camlspotter 670db8d 
camlspotter e7a867f 






camlspotter 4e97499 
camlspotter b760f49 


camlspotter 2c28ebd 
camlspotter ab68943 
camlspotter 4fafae1 
camlspotter e7a867f 




camlspotter 4fafae1 
camlspotter d0b5325 

camlspotter 2c28ebd 
camlspotter e7a867f 




camlspotter 2c28ebd 

camlspotter ab68943 
open Printf
open Common
open Tiny_json
open Json_conv
open Sexplib.Conv
open Ocaml_conv

open Meta_conv.Types.Result.Open

type 'target mc_leftovers = (string * 'target) list with conv(json), conv(ocaml)

module Json = struct
  include Json
  let ocaml_of_t j = Ocaml.String (Json.show j)
  let t_of_ocaml = function
    | Ocaml.String s -> `Ok (Json.parse s)
    | _ -> assert false
end

module Scheme = struct
  type t = Hg(:"hg":) | Git(:"git":) with conv(json), conv(ocaml)
end

module LocalTime = struct
  type t = string with conv(json), conv(ocaml)
end

module UTCTime = struct
  type t = string with conv(json), conv(ocaml)
end

module Error = struct
  open Format

  let wrap_json_conv = function
    | `Ok v -> `Ok v
    | `Error e -> `Error (`Json_conv e)

  let format ppf = function
    | `Http (n, _err) -> fprintf ppf "HTTP Error %d@." n
    | `Json_conv ((_,v) as e) -> 
        Format.eprintf "%a@.Error input: %s@." 
          (Meta_conv.Types.Error.format (fun _ _ -> ())) e
          (Json.show v)
    | `Json_parse exn -> fprintf ppf "Error at Json parse: %s@." (Printexc.to_string exn)
    | `Other exn -> fprintf ppf "Error: %s@." (Printexc.to_string exn)
end

let curl_get_and_parse convf curlf = 
  Curl.get_string curlf |> Curl.ok200 >>= fun s ->
  (try `Ok (Json.parse s) with e -> `Error (`Json_parse e)) >>= fun j ->
  convf j |> Error.wrap_json_conv

module Data = struct

  (* CR jfuruse: It seems we should use classes since there are so many name overloads *)
    
  (** Full repository information *)
  module Repository = struct
    type t = <
      name              : string;
      scm               : Scheme.t;
      has_wiki          : bool;
      last_updated      : LocalTime.t;
      utc_last_updated  : UTCTime.t;
      created_on        : LocalTime.t;
      utc_created_on    : UTCTime.t;
      owner             : string;
      logo              : string;
      email_mailinglist : string option;
      is_mq             : bool;
      size              : int;
      read_only         : bool;
      followers_count   : int;
      state             : string; (* "str(available)" *)
      website           : string option;
      description       : string option;
      has_issues        : bool;
      is_fork           : bool;
      slug              : string;
      is_private        : bool;
      language          : string;
      email_writers     : bool;
      no_public_forks   : bool;
      resource_uri      : string;
      fork_of           : t option;
      mq_of             : t option;
      creator           : string option;
    > with conv(json), conv(ocaml)
  end

  (** Commited file *)  
  module File = struct
    type t = <
      type_ as "type" : string;
      file : string;
    > with conv(json), conv(ocaml)
  end

  (** Branch info *)    
  module Branch = struct

    type t = <
      node         : string;
      raw_node     : string;
      author       : string;
      raw_author   : string;
      utctimestamp : UTCTime.t;
      timestamp    : LocalTime.t;
      message      : string;
      files        : File.t list;
      size         : int64;
      revision     : int64;
      parents      : string list;
      branch       : string;
      unknown      : Json.t mc_leftovers;
    > with conv(json), conv(ocaml)

  end

  (** User identity info *)
  module UserID = struct
    type t = <
      username     : string;
      display_name : string;
      first_name   : string;
      last_name    : string;
      is_team      : bool;
      avatar       : string;
      resource_uri : string;
      user_rest    : Json.t mc_leftovers;
    > with conv(json), conv(ocaml)
  end

  module User = struct
    type t = <
      user : UserID.t;
      repositories : Repository.t list;
      rest : Json.t mc_leftovers;
    > with conv(json), conv(ocaml)
  end

  module UserRepo = struct

    (** Small version of Repository.t *)  
    type t = <
      owner      : string;
      scm        : Scheme.t;
      slug       : string;
      is_private : bool;
      name       : string
    >

    and ts = t list with conv(json)
  end

end

(** repositories Endpoint *)
module Repositories = struct

  (* https://api.bitbucket.org/1.0/repositories/{accountname}/{repo_slug}/branches *)
  module Branches = struct

    type t = Data.Branch.t mc_leftovers with conv(json), conv(ocaml)

    let get ~accountname ~repo_slug = 
      Format.eprintf "%s : %s...@." accountname repo_slug;
      curl_get_and_parse 
        t_of_json
        (fun h ->
          (* ~user ~password  *)
          (* h#set_userpwd (Printf.sprintf "%s:%s" user password)) *)
          h#set_url (sprintf "https://api.bitbucket.org/1.0/repositories/%s/%s/branches" accountname repo_slug)
          (* h#set_userpwd (Printf.sprintf "%s:%s" user password) *) )
  end
end

(** user Endpoint *)
module User = struct

  let get ~user ~password = 
    curl_get_and_parse
      Data.User.t_of_json
      (fun h ->
        h#set_url "https://api.bitbucket.org/1.0/user";
        h#set_userpwd (Printf.sprintf "%s:%s" user password))

  module Repositories = struct

    let get ~user ~password = 
      curl_get_and_parse
        Data.UserRepo.ts_of_json
        (fun h ->
          h#set_url "https://api.bitbucket.org/1.0/user/repositories/";
          h#set_userpwd (Printf.sprintf "%s:%s" user password))
  end

end