diff options
author | Johan Berntsson | 2008-03-04 05:31:54 +0000 |
---|---|---|
committer | Johan Berntsson | 2008-03-04 05:31:54 +0000 |
commit | 279e0061c515ee0a03036bef68eea9738273d785 (patch) | |
tree | 4502228eb7b87a760e0b0e67aded9d1d870d0bed /ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs | |
parent | Added copyright heaaders. Minor cleanup. (diff) | |
download | opensim-SC-279e0061c515ee0a03036bef68eea9738273d785.zip opensim-SC-279e0061c515ee0a03036bef68eea9738273d785.tar.gz opensim-SC-279e0061c515ee0a03036bef68eea9738273d785.tar.bz2 opensim-SC-279e0061c515ee0a03036bef68eea9738273d785.tar.xz |
Merged 3Di code that provides scene and avatar serialization, and plugin support for region move/split/merge. See ThirdParty/3Di/README.txt. Unless the new modules are used there should be no noticeable changes when running OpenSim.
Diffstat (limited to 'ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs')
3 files changed, 507 insertions, 0 deletions
diff --git a/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MonitorGUI/View.pm b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MonitorGUI/View.pm new file mode 100644 index 0000000..bab462f --- /dev/null +++ b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MonitorGUI/View.pm | |||
@@ -0,0 +1,214 @@ | |||
1 | package MonitorGUI::View; | ||
2 | |||
3 | use strict; | ||
4 | |||
5 | my @server_list; | ||
6 | my $max_port; | ||
7 | my $regions; | ||
8 | |||
9 | sub screen_header { | ||
10 | return << "HEADER"; | ||
11 | <HTML> | ||
12 | <HEAD> | ||
13 | <STYLE TYPE="text/css"> | ||
14 | <!-- | ||
15 | a:link {font-size: 12pt; text-decoration:none; color:#0000ff ;} | ||
16 | a:visited {font-size: 12pt; text-decoration:none; color:#ff0000 ;} | ||
17 | a:active {font-size: 12pt; text-decoration:none; color:#00ff00 ;} | ||
18 | a:hover {font-size: 12pt; text-decoration:underline; color:#ff00ff ;} | ||
19 | td {font-size: 12pt;border:0;} | ||
20 | th {background-color:#000000; font-size: 12pt;border:0; color:#FFFFFF; } | ||
21 | tr {background-color:#FFFFFF; } | ||
22 | b {font-size: 12pt;} | ||
23 | //table {background-color:#000000; } | ||
24 | --> | ||
25 | </STYLE> | ||
26 | <META http-equiv="content-type" content="text/html;charset=UTF-8" /> | ||
27 | <META name="refresh" content="300" /> | ||
28 | <TITLE>Region Monitor GUI, 3Di</TITLE> | ||
29 | </HEAD> | ||
30 | <BODY> | ||
31 | HEADER | ||
32 | } | ||
33 | |||
34 | sub screen_footer { | ||
35 | return << "FOOTER"; | ||
36 | </BODY> | ||
37 | </HTML> | ||
38 | FOOTER | ||
39 | } | ||
40 | |||
41 | sub html { | ||
42 | my $grid_info = shift; | ||
43 | my $regions_list = $grid_info->{"sim-profiles"}; | ||
44 | $regions = undef; | ||
45 | foreach(@$regions_list) { | ||
46 | my $ip = $_->{sim_ip} || "UNKNOWN"; | ||
47 | my $port = $_->{sim_port} || "UNKNOWN"; | ||
48 | $regions->{$ip}->{$port} = $_; | ||
49 | if (!$regions->{max_port} || $regions->{max_port} < $port) { | ||
50 | $regions->{max_port} = $port; | ||
51 | } | ||
52 | } | ||
53 | @server_list = keys %$regions; | ||
54 | $max_port = $regions->{max_port}; | ||
55 | my $html = ""; | ||
56 | foreach my $machine (@server_list) { | ||
57 | next if ($machine eq "max_port"); | ||
58 | $html .= &_machine_view($machine, $regions->{$machine}); | ||
59 | } | ||
60 | return $html; | ||
61 | } | ||
62 | |||
63 | sub _machine_view { | ||
64 | my ($ip, $info) = @_; | ||
65 | my $region_html = ""; | ||
66 | foreach my $region (keys %$info) { | ||
67 | $region_html .= &_region_html($info->{$region}); | ||
68 | } | ||
69 | my $html =<< "MACHINE_HTML"; | ||
70 | <h3>$ip</h3> | ||
71 | $region_html | ||
72 | <hr size=0 noshade /> | ||
73 | MACHINE_HTML | ||
74 | } | ||
75 | |||
76 | sub _region_html { | ||
77 | my $region_info = shift; | ||
78 | my $name = $region_info->{name} || "UNKNOWN"; | ||
79 | my $x = $region_info->{x} || -1; | ||
80 | my $y = $region_info->{y} || -1; | ||
81 | my $ip = $region_info->{sim_ip} || "UNKNOWN"; | ||
82 | my $port = $region_info->{sim_port} || "UNKNOWN"; | ||
83 | my $get_scene_presence_filter = $region_info->{get_scene_presence_filter}; | ||
84 | my $get_scene_presence = $region_info->{get_scene_presence}; | ||
85 | my $get_avatar_filter = $region_info->{get_avatar_filter}; | ||
86 | my $get_avatar = $region_info->{get_avatar}; | ||
87 | my $avatar_names = $region_info->{avatar_names}; | ||
88 | my $action_forms = &_action_forms($region_info); | ||
89 | my $html = <<"REGION_HTML"; | ||
90 | <strong>$name</strong><br/> | ||
91 | $ip:$port | X: $x Y: $y<br/> | ||
92 | <table border="0"> | ||
93 | <tr> | ||
94 | <td>get_avatar</td> | ||
95 | <td>$get_avatar</td> | ||
96 | <td></td> | ||
97 | </tr> | ||
98 | <tr> | ||
99 | <td>get_avatar_filter</td> | ||
100 | <td>$get_avatar_filter</td> | ||
101 | <td>$avatar_names</td> | ||
102 | </tr> | ||
103 | <tr> | ||
104 | <td>get_scene_presence</td> | ||
105 | <td>$get_scene_presence</td> | ||
106 | <td></td> | ||
107 | </tr> | ||
108 | <tr> | ||
109 | <td>get_scene_presence_filter</td> | ||
110 | <td>$get_scene_presence_filter</td> | ||
111 | <td></td> | ||
112 | </tr> | ||
113 | </table> | ||
114 | $action_forms | ||
115 | REGION_HTML | ||
116 | return $html; | ||
117 | } | ||
118 | |||
119 | sub _action_forms { | ||
120 | my $region_info = shift; | ||
121 | my $ip = $region_info->{sim_ip}; | ||
122 | my $port = $region_info->{sim_port}; | ||
123 | my $default_input_port = $max_port + 1; | ||
124 | my $move_to_options = ""; | ||
125 | my $split_to_options = ""; | ||
126 | my $merge_ip_options = ""; | ||
127 | foreach(@server_list) { | ||
128 | next if ($_ eq "max_port"); | ||
129 | $merge_ip_options .= "<option value=\"$_\">$_\n"; | ||
130 | $split_to_options .= "<option value=\"$_\">$_\n"; | ||
131 | #next if ($_ eq $ip); | ||
132 | $move_to_options .= "<option value=\"$_\">$_\n"; | ||
133 | } | ||
134 | my $merge_port_options = ""; | ||
135 | my $merge_disabled = "disabled"; | ||
136 | |||
137 | foreach(keys %{$regions->{$ip}}) { | ||
138 | next if ($_ eq $port); | ||
139 | $merge_disabled = ""; | ||
140 | } | ||
141 | # for(9000..$max_port) { # TODO : | ||
142 | # next if ($_ eq $port); | ||
143 | # $merge_port_options .= "<option value=\"$_\">$_\n"; | ||
144 | # } | ||
145 | my %port = (); | ||
146 | foreach my $ip (keys %$regions) { | ||
147 | next if ($ip eq "max_port"); | ||
148 | print STDERR "--" . $ip . "\n"; | ||
149 | foreach my $region_port (keys %{$regions->{$ip}}) { | ||
150 | print STDERR "---" . $region_port . "\n"; | ||
151 | $port{$region_port} = 1; | ||
152 | } | ||
153 | } | ||
154 | foreach (keys %port) { | ||
155 | $merge_port_options .= "<option value=\"$_\">$_\n"; | ||
156 | $merge_disabled = ""; | ||
157 | } | ||
158 | return << "ACTION_FORMS"; | ||
159 | <table> | ||
160 | <tr> | ||
161 | <form method="POST"> | ||
162 | <td> | ||
163 | <input type="hidden" name="A" value="move" /> | ||
164 | <input type="hidden" name="from_ip" value="$ip" /> | ||
165 | <input type="hidden" name="from_port" value="$port" /> | ||
166 | <input type="submit" value="Move to" /> | ||
167 | <select name="to_ip"> | ||
168 | $move_to_options | ||
169 | </select>: | ||
170 | <input type="text" name="to_port" size="5" value="$default_input_port"/> | ||
171 | </td> | ||
172 | </form> | ||
173 | |||
174 | <td> | ||
175 | | | ||
176 | </td> | ||
177 | |||
178 | <form method="POST"> | ||
179 | <td> | ||
180 | <input type="hidden" name="A" value="split" /> | ||
181 | <input type="hidden" name="from_ip" value="$ip" /> | ||
182 | <input type="hidden" name="from_port" value="$port" /> | ||
183 | <input type="submit" value="Split to" /> | ||
184 | <select name="to_ip"> | ||
185 | $split_to_options | ||
186 | </select>: | ||
187 | <input type="text" name="to_port" size="5" value="$default_input_port"/> | ||
188 | </td> | ||
189 | </form> | ||
190 | |||
191 | <td> | ||
192 | | | ||
193 | </td> | ||
194 | |||
195 | <form method="POST"> | ||
196 | <td> | ||
197 | <input type="hidden" name="A" value="merge" /> | ||
198 | <input type="hidden" name="from_ip" value="$ip" /> | ||
199 | <input type="hidden" name="master_port" value="$port" /> | ||
200 | <input type="submit" value="Merge" $merge_disabled /> | ||
201 | <select name="slave_ip" $merge_disabled> | ||
202 | $merge_ip_options | ||
203 | </select> | ||
204 | <select name="slave_port" $merge_disabled> | ||
205 | $merge_port_options | ||
206 | </select> | ||
207 | </td> | ||
208 | </form> | ||
209 | </tr> | ||
210 | </table> | ||
211 | ACTION_FORMS | ||
212 | } | ||
213 | |||
214 | 1; | ||
diff --git a/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MyCGI.pm b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MyCGI.pm new file mode 100644 index 0000000..1f232aa --- /dev/null +++ b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MyCGI.pm | |||
@@ -0,0 +1,91 @@ | |||
1 | package MyCGI; | ||
2 | |||
3 | use strict; | ||
4 | use CGI; | ||
5 | |||
6 | sub getParam { | ||
7 | my $cgi; | ||
8 | if ($ARGV[0]) { | ||
9 | $cgi = new CGI($ARGV[0]); | ||
10 | } else { | ||
11 | $cgi = new CGI; | ||
12 | } | ||
13 | my @param_names = $cgi->param(); | ||
14 | my %param = (); | ||
15 | foreach (@param_names) { | ||
16 | $param{$_} = $cgi->param($_); | ||
17 | } | ||
18 | return \%param; | ||
19 | } | ||
20 | |||
21 | sub getCookie { | ||
22 | my $name = shift; | ||
23 | my $cookie_value = &CGI::cookie($name); | ||
24 | return &_parse($cookie_value); | ||
25 | } | ||
26 | |||
27 | sub outputHtml { | ||
28 | my ($charset, $html) = @_; | ||
29 | print &CGI::header(-charset => $charset); | ||
30 | print $html; | ||
31 | } | ||
32 | |||
33 | sub outputXml { | ||
34 | my ($charset, $xml) = @_; | ||
35 | print &CGI::header( -type => 'text/xml', -charset => $charset ); | ||
36 | print $xml; | ||
37 | } | ||
38 | |||
39 | sub makeCookieValue { | ||
40 | my $param = shift; | ||
41 | my @data = (); | ||
42 | foreach(keys %$param) { | ||
43 | push(@data, $_ . "=" . $param->{$_}); | ||
44 | } | ||
45 | return join("&", @data); | ||
46 | } | ||
47 | |||
48 | sub setCookie { | ||
49 | my $param = shift; | ||
50 | my $cookie = &CGI::cookie( | ||
51 | -name => $param->{name} || return, | ||
52 | -value => $param->{value}, | ||
53 | -domain => $param->{domain}, | ||
54 | -path => $param->{path}, | ||
55 | -expires => $param->{expires}, | ||
56 | ); | ||
57 | return &CGI::header(-cookie => $cookie); | ||
58 | } | ||
59 | |||
60 | sub redirect { | ||
61 | my $dest = shift; | ||
62 | &CGI::redirect($dest); | ||
63 | } | ||
64 | |||
65 | sub urlEncode { | ||
66 | my $str = shift; | ||
67 | $str =~ s/([^\w ])/'%'.unpack('H2', $1)/eg; | ||
68 | $str =~ tr/ /+/; | ||
69 | return $str; | ||
70 | } | ||
71 | |||
72 | sub urlDecode { | ||
73 | my $str = shift; | ||
74 | $str =~ tr/+/ /; | ||
75 | $str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; | ||
76 | return $str; | ||
77 | } | ||
78 | |||
79 | sub _parse { | ||
80 | my $value = shift; | ||
81 | my @pair = split(/&/, $value); | ||
82 | my %data = (); | ||
83 | foreach(@pair) { | ||
84 | my ($name, $value) = split(/=/, $_); | ||
85 | $data{$name} = $value; | ||
86 | } | ||
87 | return \%data; | ||
88 | } | ||
89 | |||
90 | 1; | ||
91 | |||
diff --git a/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/monitor.cgi b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/monitor.cgi new file mode 100644 index 0000000..a5f6445 --- /dev/null +++ b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/monitor.cgi | |||
@@ -0,0 +1,202 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | |||
3 | use strict; | ||
4 | use Carp; | ||
5 | use MyCGI; | ||
6 | use XML::RPC; | ||
7 | use MonitorGUI::View; | ||
8 | |||
9 | use vars qw ($THIS_URL $GRID_SERVER_URL $DEFAULT_PROXY_PORT); | ||
10 | $THIS_URL = "http://10.8.1.165/monitorgui/monitor.cgi"; | ||
11 | $GRID_SERVER_URL = "http://10.8.1.165/opensim/grid.cgi"; | ||
12 | $DEFAULT_PROXY_PORT = 9000; | ||
13 | |||
14 | my %ACTIONS = ( | ||
15 | # Region commands | ||
16 | move => \&move_command, | ||
17 | split => \&split_command, | ||
18 | merge => \&merge_command, | ||
19 | # display commands | ||
20 | default => \&main_screen, | ||
21 | refresh => \&refresh, | ||
22 | ); | ||
23 | |||
24 | # ################## | ||
25 | # main | ||
26 | my $param = &MyCGI::getParam; | ||
27 | my $act = $param->{A} || "default"; | ||
28 | my $contents = ""; | ||
29 | if (!$ACTIONS{$act}) { | ||
30 | &gui_error("404 NOT FOUND"); | ||
31 | } else { | ||
32 | eval { | ||
33 | $ACTIONS{$act}->($param); | ||
34 | }; | ||
35 | if ($@) { | ||
36 | &gui_error($@); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | # ################# | ||
41 | # Region Commands | ||
42 | sub move_command { | ||
43 | my $param = shift; | ||
44 | # from | ||
45 | my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)"); | ||
46 | my $from_port = $param->{from_port} || Carp::croak("not enough params (from_port)"); | ||
47 | my $from_url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT; | ||
48 | # to | ||
49 | my $to_ip = $param->{to_ip} || Carp::croak("not enough params (to_ip)"); | ||
50 | my $to_port = $param->{to_port} || Carp::croak("not enough params (to_port)"); | ||
51 | my $to_url = "http://" . $param->{to_ip} . ":" . $DEFAULT_PROXY_PORT; | ||
52 | # commands | ||
53 | eval { | ||
54 | &OpenSim::Utility::XMLRPCCall_array($from_url, "SerializeRegion", [$from_ip, $from_port]); | ||
55 | &OpenSim::Utility::XMLRPCCall_array($to_url, "DeserializeRegion_Move", [$from_ip, $from_port, $to_ip, $to_port]); | ||
56 | &OpenSim::Utility::XMLRPCCall_array($from_url, "TerminateRegion", [$from_port]); | ||
57 | }; | ||
58 | if ($@) { | ||
59 | print STDERR "Get Status Error: $@\n"; | ||
60 | } | ||
61 | |||
62 | # client refresh | ||
63 | &redirect_refresh({wait=>5, force=>"$from_url|$to_url", msg=>"Move region $from_ip:$from_port from $from_url to $to_url"}); | ||
64 | } | ||
65 | |||
66 | sub split_command { | ||
67 | my $param = shift; | ||
68 | # from | ||
69 | my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)"); | ||
70 | my $from_port = $param->{from_port} || Carp::croak("not enough params (from_port)"); | ||
71 | my $from_url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT; | ||
72 | # to | ||
73 | my $to_ip = $param->{to_ip} || Carp::croak("not enough params (to_ip)"); | ||
74 | my $to_port = $param->{to_port} || Carp::croak("not enough params (to_port)"); | ||
75 | my $to_url = "http://" . $param->{to_ip} . ":" . $DEFAULT_PROXY_PORT; | ||
76 | # commands | ||
77 | eval { | ||
78 | &OpenSim::Utility::XMLRPCCall_array($from_url, "SerializeRegion", [$from_ip, $from_port]); | ||
79 | &OpenSim::Utility::XMLRPCCall_array($to_url, "DeserializeRegion_Clone", [$from_ip, $from_port, $to_ip, $to_port]); | ||
80 | }; | ||
81 | if ($@) { | ||
82 | print STDERR "Get Status Error: $@\n"; | ||
83 | } | ||
84 | |||
85 | &redirect_refresh({wait=>5, force=>"$from_url", msg=>"Split region $from_ip:$from_port"}); | ||
86 | } | ||
87 | |||
88 | sub merge_command { | ||
89 | my $param = shift; | ||
90 | # from | ||
91 | my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)"); | ||
92 | my $url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT; | ||
93 | # ports | ||
94 | my $master_port = $param->{master_port} || Carp::croak("not enough params (master_port)"); | ||
95 | my $slave_ip = $param->{slave_ip} || Carp::croak("not enough params (slave_ip)"); | ||
96 | my $slave_port = $param->{slave_port} || Carp::croak("not enough params (slave_port)"); | ||
97 | my $slave_url = "http://" . $param->{slave_ip} . ":" . $DEFAULT_PROXY_PORT; | ||
98 | # commands | ||
99 | eval { | ||
100 | &XMLRPCCall_array($url, "MergeRegions", [$from_ip, $master_port]); | ||
101 | &XMLRPCCall_array($slave_url, "TerminateRegion", [$slave_port]); | ||
102 | }; | ||
103 | if ($@) { | ||
104 | print STDERR "Get Status Error: $@\n"; | ||
105 | } | ||
106 | &redirect_refresh({wait=>5, force=>"$url", msg=>"Merge region $from_ip:$master_port, $slave_port"}); | ||
107 | } | ||
108 | |||
109 | # ################# | ||
110 | # Display | ||
111 | sub main_screen { | ||
112 | my %xml_rpc_param = ( | ||
113 | # TODO: should be 0 - 65535 ? | ||
114 | xmin => 999, ymin => 999, xmax => 1010, ymax => 1010, | ||
115 | ); | ||
116 | my $res_obj = undef; | ||
117 | eval { | ||
118 | $res_obj = &XMLRPCCall($GRID_SERVER_URL, "map_block", \%xml_rpc_param); | ||
119 | }; | ||
120 | if ($@) { | ||
121 | &gui_error("map_block Error: " . $@); | ||
122 | } | ||
123 | my %copy_obj = %$res_obj; | ||
124 | my $getstatus_failed = "<font color=\"red\">GetStatus Failed</font>"; | ||
125 | my $regions_list = $res_obj->{"sim-profiles"}; | ||
126 | foreach(@$regions_list) { | ||
127 | if ($_->{sim_ip} && $_->{sim_port}) { | ||
128 | my $url = "http://" . $_->{sim_ip} . ":" . $DEFAULT_PROXY_PORT; | ||
129 | my $port = $_->{sim_port}; | ||
130 | my $res = undef; | ||
131 | eval { | ||
132 | $res = &XMLRPCCall_array($url, "GetStatus", [$port]); | ||
133 | }; | ||
134 | if ($@) { | ||
135 | print STDERR "Get Status Error: $@\n"; | ||
136 | } | ||
137 | $_->{get_scene_presence_filter} = $res ? $res->{get_scene_presence_filter} : $getstatus_failed; | ||
138 | $_->{get_scene_presence} = $res ? $res->{get_scene_presence} : $getstatus_failed; | ||
139 | $_->{get_avatar_filter} = $res ? $res->{get_avatar_filter} : $getstatus_failed; | ||
140 | $_->{get_avatar} = $res ? $res->{get_avatar} : $getstatus_failed; | ||
141 | $_->{avatar_names} = $res ? $res->{avatar_names} : "NO USER"; | ||
142 | } | ||
143 | } | ||
144 | my $html = &MonitorGUI::View::html(\%copy_obj); | ||
145 | &MyCGI::outputHtml("UTF-8", &MonitorGUI::View::screen_header . $html . &MonitorGUI::View::screen_footer); | ||
146 | } | ||
147 | |||
148 | sub gui_error { | ||
149 | my $msg = shift; | ||
150 | &MyCGI::outputHtml("UTF-8", "<h1>ERROR</h1><hr />$msg"); | ||
151 | } | ||
152 | |||
153 | sub redirect_refresh { | ||
154 | my $args = shift; | ||
155 | my $wait = $args->{wait}; | ||
156 | my $force = $args->{force} || ""; | ||
157 | my $msg = $args->{msg} || ""; | ||
158 | my $param = "A=refresh&wait=$wait&ip=$force&msg=$msg"; | ||
159 | my $dist_url = $THIS_URL . "?" . $param; | ||
160 | &MyCGI::redirect($dist_url); | ||
161 | } | ||
162 | |||
163 | sub refresh { | ||
164 | my $param = shift; | ||
165 | my $msg = $param->{msg} || ""; | ||
166 | my $wait = $param->{wait} || 0; | ||
167 | my $force = $param->{ip} || ""; | ||
168 | #my $jump_url = $force ? "$THIS_URL?A=force&ip=$force" : $THIS_URL; | ||
169 | my $jump_url = $THIS_URL; | ||
170 | my $html =<< "HTML"; | ||
171 | <html> | ||
172 | <head> | ||
173 | <meta http-equiv="Refresh" content="$wait;URL=$jump_url" /> | ||
174 | <title>Region Monitor GUI REFRESH</title> | ||
175 | </head> | ||
176 | <body> | ||
177 | <h3>$msg</h3> | ||
178 | <br> | ||
179 | wait <font color="red"><b>$wait</b></font> sec for server to take effect ... <br> | ||
180 | (* The page will jump to "Monitor Screen" automatically) | ||
181 | </body> | ||
182 | </html> | ||
183 | HTML | ||
184 | &MyCGI::outputHtml("UTF-8", $html); | ||
185 | } | ||
186 | |||
187 | # ################## | ||
188 | # Utility | ||
189 | sub XMLRPCCall { | ||
190 | my ($url, $methodname, $param) = @_; | ||
191 | my $xmlrpc = new XML::RPC($url); | ||
192 | my $result = $xmlrpc->call($methodname, $param); | ||
193 | return $result; | ||
194 | } | ||
195 | |||
196 | sub XMLRPCCall_array { | ||
197 | my ($url, $methodname, $param) = @_; | ||
198 | my $xmlrpc = new XML::RPC($url); | ||
199 | my $result = $xmlrpc->call($methodname, @$param); | ||
200 | return $result; | ||
201 | } | ||
202 | |||