(** Wrapper around Perl [WWW::Mechanize] class. *) (* Copyright (C) 2003 Merjis Ltd. This library 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; either version 2 of the License, or (at your option) any later version. This library 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 General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_WWW_Mechanize.ml,v 1.8 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_LWP_UserAgent let _ = eval "use WWW::Mechanize" class www_mechanize sv = object (self) inherit lwp_useragent sv method agent_alias alias = call_method_void sv "agent_alias" [sv_of_string alias] method known_agent_aliases = let svlist = call_method_array sv "known_agent_aliases" [] in List.map string_of_sv svlist method get url = call_method_void sv "get" [sv_of_string url] method reload () = call_method_void sv "reload" [] method back () = call_method_void sv "back" [] method follow_link ?text ?text_regex ?url ?url_regex ?url_abs ?url_abs_regex ?name ?name_regex ?tag ?tag_regex ?n () = let args = ref [] in let add name f = function | None -> () | Some p -> args := sv_of_string name :: f p :: !args in add "text" sv_of_string text; add "text_regex" sv_of_string text_regex; add "url" sv_of_string url; add "url_regex" sv_of_string url_regex; add "url_abs" sv_of_string url_abs; add "url_abs_regex" sv_of_string url_abs_regex; add "name" sv_of_string name; add "name_regex" sv_of_string name_regex; add "tag" sv_of_string tag; add "tag_regex" sv_of_string tag_regex; add "n" sv_of_int n; call_method_void sv "follow_link" !args method forms = let svlist = call_method_array sv "forms" [] in List.map (new Pl_HTML_Form.html_form) svlist method form_number n = let sv = call_method sv "form_number" [sv_of_int n] in new Pl_HTML_Form.html_form sv method form_name name = let sv = call_method sv "form_name" [sv_of_string name] in new Pl_HTML_Form.html_form sv (* XXX There is an arrayref variant of this method, but what * it does is apparently undocumented. *) method field ?n name value = let args = match n with None -> [sv_of_string name; sv_of_string value] | Some n -> [sv_of_string name; sv_of_string value; sv_of_int n] in call_method_void sv "field" args method set_fields fields = let args = ref [] in List.iter (fun (k, v) -> (* Note: reversed k, v because we'll reverse the whole list.*) args := sv_of_string v :: sv_of_string k :: !args) fields; let args = List.rev !args in call_method_void sv "set_fields" args method value ?n name = let args = match n with None -> [sv_of_string name] | Some n -> [sv_of_string name; sv_of_int n] in let sv = call_method sv "value" args in string_of_sv sv (* XXX Doesn't support setting criteria. *) method set_visible names = let names = List.map sv_of_string names in call_method_void sv "set_visible" names method tick ?set name value = let args = match set with None -> [ sv_of_string name; sv_of_string value ] | Some b -> [ sv_of_string name; sv_of_string value; sv_of_bool b ] in call_method_void sv "tick" args method untick name value = call_method_void sv "untick" [ sv_of_string name; sv_of_string value ] method click ?xy button = let args = match xy with None -> [ sv_of_string button ] | Some (x, y) -> [ sv_of_string button; sv_of_int x; sv_of_int y ] in call_method_void sv "click" args method click1 () = call_method_void sv "click" [] method click_button ?name ?number ?value ?xy () = let args = ref [] in let add name f = function | None -> () | Some p -> args := sv_of_string name :: f p :: !args in add "name" sv_of_string name; add "number" sv_of_int number; add "value" sv_of_string value; (match xy with None -> () | Some (x, y) -> args := sv_of_string "x" :: sv_of_int x :: sv_of_string "y" :: sv_of_int y :: !args); call_method_void sv "click" !args method select name value = call_method_void sv "select" [ sv_of_string name; sv_of_string value ] method select_multiple name values = let av = av_empty () in List.iter (av_push av) (List.map sv_of_string values); call_method_void sv "select" [ sv_of_string name; arrayref av ] method submit () = call_method_void sv "submit" [] method submit_form ?form_number ?form_name ?fields ?button ?xy () = let args = ref [] in let add name f = function | None -> () | Some p -> args := sv_of_string name :: f p :: !args in add "form_number" sv_of_int form_number; add "form_name" sv_of_string form_name; (match fields with | None -> () | Some fields -> let hv = hv_empty () in List.iter ( fun (name, value) -> hv_set hv name (sv_of_string value) ) fields; let sv = hashref hv in args := sv_of_string "fields" :: sv :: !args ); add "button" sv_of_string button; (match xy with | None -> () | Some (x, y) -> args := sv_of_string "x" :: sv_of_int x :: sv_of_string "y" :: sv_of_int y :: !args); let sv = call_method sv "submit_form" !args in new Pl_HTTP_Response.http_response sv method success = let sv = call_method sv "success" [] in bool_of_sv sv method uri = let sv = call_method sv "uri" [] in string_of_sv sv method response = let sv = call_method sv "response" [] in new Pl_HTTP_Response.http_response sv method res = let sv = call_method sv "res" [] in new Pl_HTTP_Response.http_response sv method status = let sv = call_method sv "status" [] in int_of_sv sv method ct = let sv = call_method sv "ct" [] in string_of_sv sv method base = let sv = call_method sv "base" [] in string_of_sv sv method content = let sv = call_method sv "content" [] in string_of_sv sv (* method current_forms = *) method links = let svs = call_method_array sv "links" [] in List.map (new www_mechanize_link) svs method is_html = let sv = call_method sv "is_html" [] in bool_of_sv sv method title = let sv = call_method sv "title" [] in string_of_sv sv (* method find_link .... = *) (* method find_all_links .... = *) (* method add_header .... = *) (* method delete_header .... = *) method quiet = let sv = call_method sv "quiet" [] in bool_of_sv sv method set_quiet b = call_method_void sv "quiet" [sv_of_bool b] (* method stack_depth ... = *) method redirect_ok = let sv = call_method sv "redirect_ok" [] in bool_of_sv sv (* method request ... = *) (* method update_html ... = *) end and www_mechanize_link sv = object (self) method sv = sv method url = let sv = call_method sv "url" [] in string_of_sv sv method text = let sv = call_method sv "text" [] in string_of_sv sv method name = let sv = call_method sv "name" [] in string_of_sv sv method tag = let sv = call_method sv "tag" [] in string_of_sv sv method base = let sv = call_method sv "base" [] in string_of_sv sv method url_abs = let sv = call_method sv "url_abs" [] in string_of_sv sv end (* XXX Should be able to pass args to constructor of LWP::UserAgent. *) (* XXX WWW::Mechanize has additional parameters. *) let new_ ?autocheck () = let args = ref [] in let may f = function None -> () | Some v -> f v in may (fun v -> args := sv_of_string "autocheck" :: sv_of_bool v :: !args) autocheck; let sv = call_class_method "WWW::Mechanize" "new" !args in new www_mechanize sv