ocaml-bitbucket / api.ml

camlspotter 4e97499 
camlspotter ab68943 
camlspotter 710bd90 
camlspotter 4fafae1 
camlspotter 710bd90 


camlspotter d0b5325 
camlspotter e7a867f 
camlspotter 587ac17 

camlspotter 710bd90 
camlspotter 587ac17 

camlspotter 4e97499 


camlspotter 710bd90 



camlspotter fdf4f75 
camlspotter 710bd90 



camlspotter 4e97499 
camlspotter d5035b3 
camlspotter 9aad09d 

camlspotter ab68943 
camlspotter 710bd90 
camlspotter 9aad09d 

camlspotter 710bd90 
camlspotter ab68943 

camlspotter a676a3c 
camlspotter 710bd90 
camlspotter fdf4f75 
camlspotter a676a3c 


camlspotter 710bd90 
camlspotter fdf4f75 
camlspotter a676a3c 

camlspotter e7a867f 

camlspotter 4fafae1 
camlspotter 710bd90 
camlspotter e7a867f 




camlspotter 710bd90 

camlspotter 808369c 
camlspotter 710bd90 
camlspotter 808369c 


camlspotter e7a867f 

camlspotter 710bd90 

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 9aad09d 

camlspotter e7a867f 

camlspotter b760f49 
camlspotter 4e97499 


camlspotter 587ac17 
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 Meta_conv.Types.Result.Open (* I use >>= only for Result here *)
open Json_conv  (* for conv(json) *)
open Ocaml_conv (* for conv(ocaml) *)


(* field of type Json.t mc_leftovers is automatically handled for Json, but not for ocaml *)
type 'target mc_leftovers = (string * 'target) list with conv(ocaml)

(* CR jfuruse: mc_fields should be supported in Ocaml_conv *)
type 'target mc_fields = (string * 'target) list with conv(ocaml)

module Json = struct
  include Json

  let ocaml_of_t : Json.t Ocaml_conv.encoder = fun j -> Ocaml.String (Json.show j)
  let t_of_ocaml : Json.t Ocaml_conv.decoder = fun o ->
    try match o with
    | Ocaml.String s -> `Ok (Json.parse s)
    | _ -> failwith "Ocaml.String expected"
    with e -> `Error (Meta_conv.Types.Error.Deconstruction_error e, o)

  let parse s = try `Ok (parse s) with e -> `Error (`Json_parse e)
end

(** { 6 Types } *)

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

module LocalTime = struct
  (* CRv2 jfuruse: this should be lazily parsed date *)
  type t = string with conv(json), conv(ocaml)
end

module UTCTime = struct
  (* CRv2 jfuruse: this should be lazily parsed date *)
  type t = string with conv(json), conv(ocaml)
end

module Error = struct
  open Format

  let wrap_json_conv convf s = match convf s with
    | `Ok v -> `Ok v
    | `Error e -> `Error (`Json_conv e)

  let format ppf = function
    | `Http (n, _err) -> fprintf ppf "HTTP Error %d@." n
    | `Json_parse exn -> fprintf ppf "Error at Json parse: %s@." (Printexc.to_string exn)
    | `Other exn      -> fprintf ppf "Error: %s@." (Printexc.to_string exn)
    | `Json_conv ((_,v) as e) -> 
        (* CR jfuruse: This is bit strange. Meta_conv.Types.Error.format should print [v] too? *)
        Format.eprintf "%a@.Error input: %s@." 
          (Meta_conv.Types.Error.format (fun _ _ -> ())) e
          (Json.show v)
end

let curl_get_and_parse (convf : 'a Json_conv.decoder) curlf = 
  Curl.get_string curlf >>= Json.parse >>= Error.wrap_json_conv convf

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

(** { 6 End points } *)

(** 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_fields 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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.