···5151The resulting binaries are in `_build/test` :
52525353- `test.native` tests the library, nothing should fail.
5454-- `ocamltweets.native` gives you the latest tweets about OCaml.
5554- `jsontrip.native` among other things, reads JSON on `stdin` and rewrites it
5655 on `stdout`. Invoke with `-help` for more information.
-6
vendor/opam/jsonm/_oasis
···3434 CompiledObject: Best
3535 BuildDepends: jsonm, unix
36363737-Executable ocamltweets
3838- Path: test
3939- MainIs: ocamltweets.ml
4040- CompiledObject: Best
4141- BuildDepends: jsonm, unix
4242-4337Executable test
4438 Path: test
4539 MainIs: test.ml
···11-(* This code is in the public domain. *)
22-33-let str = Format.sprintf
44-let pp = Format.fprintf
55-let pp_text ppf s = (* hints whitespace, this should really be in Format. *)
66- let left = ref 0 and right = ref 0 and len = String.length s in
77- let flush () =
88- Format.pp_print_string ppf (String.sub s !left (!right - !left));
99- incr right; left := !right;
1010- in
1111- while (!right <> len) do
1212- if s.[!right] = '\n' then (flush (); Format.pp_force_newline ppf ()) else
1313- if s.[!right] = ' ' then (flush (); Format.pp_print_space ppf ()) else
1414- incr right;
1515- done;
1616- if !left <> len then flush ()
1717-1818-let http_get uri = Unix.open_process_in (str "curl -L -f -s \"%s\"" uri)
1919-2020-(* Tweets *)
2121-2222-type tweet =
2323- { id : string;
2424- date : string;
2525- userid : string;
2626- username : string;
2727- text : string; }
2828-2929-let tweet_link t = str "http://twitter.com/%s/status/%s" t.userid t.id
3030-let tweet_search q max = (* [q] should be URI encoded... *)
3131- str "http://search.twitter.com/search.json?q=%s&rpp=%d" q max
3232-3333-let pp_tweet ppf t = pp ppf "@\n* @[%s - %s@]@\n @[%s@]@\n@\n @[%a@]@\n@."
3434- t.username (tweet_link t) t.date pp_text t.text
3535-3636-(* N.B. The parsing code assumes members are given in order. Theoretically
3737- there's no order in JSON members. *)
3838-3939-let fold_tweets f acc src =
4040- let ret a = `Ok a in
4141- let bind v f = match v with `Error -> `Error | `End -> `End | `Ok v -> f v in
4242- let rec mem n d = match Jsonm.decode d with
4343- | `Lexeme (`Name n') when n = n' ->
4444- begin match Jsonm.decode d with
4545- | `Lexeme (`String s) -> ret s | _ -> `Error
4646- end
4747- | `End -> `End
4848- | _ -> mem n d
4949- in
5050- let parse_tweet d =
5151- bind (mem "created_at" d) (fun date ->
5252- bind (mem "from_user_id_str" d) (fun userid ->
5353- bind (mem "from_user_name" d) (fun username ->
5454- bind (mem "id_str" d) (fun id ->
5555- bind (mem "text" d) (fun text ->
5656- ret { id; date; userid; username; text })))))
5757- in
5858- let rec loop f acc d = match parse_tweet d with
5959- | `Ok t -> loop f (f acc t) d
6060- | `End -> acc
6161- | `Error -> loop f acc d
6262- in
6363- loop f acc (Jsonm.decoder src)
6464-6565-let ocaml_tweets max =
6666- let pp_tweet () t = pp_tweet Format.std_formatter t in
6767- let ic = http_get (tweet_search "OCaml" max) in
6868- fold_tweets pp_tweet () (`Channel ic);
6969- close_in ic
7070-7171-let main () =
7272- let exec = Filename.basename Sys.executable_name in
7373- let usage = str
7474- "Usage: %s [OPTION]...\n\
7575- \ Print the latest tweets about OCaml on stdout.\n\
7676- Options:" exec
7777- in
7878- let max = ref 50 in
7979- let pmode = ref false in
8080- let options = [
8181- "-max", Arg.Set_int max, "<int> Maximal number of tweets";
8282- "-p", Arg.Set pmode, " Procrastination mode"; ]
8383- in
8484- let anon _ = raise (Arg.Bad "illegal argument") in
8585- Arg.parse (Arg.align options) anon usage;
8686- if !pmode then pp Format.std_formatter "Work harder !@." else
8787- ocaml_tweets !max
8888-8989-let () = main ()