root/misc/unitconverter.cgi

Revision 2136 (checked in by miyagawa, 13 years ago)

update pound label

  • Property svn:executable set to *
Line 
1 #!/usr/bin/perl
2 use strict;
3 use warnings;
4 use CGI;
5 use HTML::Prototype;
6 use MIME::Base64;
7 use Template;
8
9 my $query = CGI->new;
10    $query->charset("utf-8");
11
12 dispatch($query);
13
14 sub dispatch {
15     my $query = shift;
16
17     if ($query->param('from')) {
18         do_convert($query);
19     } elsif ($query->param('spinner')) {
20         show_spinner($query);
21     } else {
22         show_form($query);
23     }
24 }
25
26 sub do_convert {
27     my $query = shift;
28
29     my $from = validate_unit($query->param('from'));
30     my $to   = validate_unit($query->param('to'));
31
32     my $func = "convert_${from}_${to}";
33     no strict 'refs';
34     my $value = eval { $func->(validate_number($query->param('value'))) };
35     if ($@) {
36         print $query->header, "ERR: Can't do $from to $to conversion: $@";
37         return;
38     }
39
40     my $format = $value > 0 ? '%.4f' : '%.8f';
41     $value = sprintf $format, $value;
42
43     print $query->header, $value;
44 }
45
46 sub validate_unit {
47     my $input = shift;
48     return ($input =~ /^(\w+)$/)[0];
49 }
50
51 sub validate_number {
52     my $input = shift;
53     return ($input =~ /^([\-\+\d\.]+)/)[0];
54 }
55
56 sub convert_usd_jpy {
57     require Finance::Currency::Convert::Yahoo;
58     Finance::Currency::Convert::Yahoo::convert($_[0], 'USD', 'JPY');
59 }
60
61 sub convert_jpy_usd {
62     require Finance::Currency::Convert::Yahoo;
63     Finance::Currency::Convert::Yahoo::convert($_[0], 'JPY', 'USD');
64 }
65
66 sub convert_inch_meter {
67     return 0.0254 * $_[0];
68 }
69
70 sub convert_meter_inch {
71     return $_[0] / 0.0254;
72 }
73
74 sub convert_inch_feet {
75     return $_[0] / 12;
76 }
77
78 sub convert_feet_inch {
79     return $_[0] * 12;
80 }
81
82 sub convert_feet_meter { convert_inch_meter(convert_feet_inch($_[0])) }
83 sub convert_meter_feet { convert_inch_feet(convert_meter_inch($_[0])) }
84
85 sub convert_oz_pound {
86     return $_[0] / 16;
87 }
88
89 sub convert_pound_oz {
90     return $_[0] * 16;
91 }
92
93 sub convert_g_pound {
94     return $_[0] / 453.59237;
95 }
96
97 sub convert_pound_g {
98     return $_[0] * 453.59237;
99 }
100
101 sub convert_oz_g { convert_pound_g(convert_oz_pound($_[0])) }
102 sub convert_g_oz { convert_pound_oz(convert_g_pound($_[0])) }
103
104 sub convert_sqf_sqm {
105     return $_[0] * 0.09290304;
106 }
107
108 sub convert_sqm_sqf {
109     return $_[0] / 0.09290304;
110 }
111
112 sub show_form {
113     my $query = shift;
114
115     my $tt = Template->new;
116     my $template = show_form_template();
117
118     my $stash;
119     $stash->{prototype} = HTML::Prototype->new;
120     $stash->{cgi}       = $query;
121
122     print $query->header('text/html');
123     $tt->process(\$template, $stash);
124 }
125
126 sub show_form_template {
127     return <<'TEMPLATE';
128 [% SET title = "Unit Converter (Japan and United States)" -%]
129 <html>
130 <head>
131 <title>[% title %]</title>
132 <style>
133 body,input,td { font-size: 11px; font-family: trebuchet MS }
134 input { background: #fff }
135 h1 { font-size: 2em }
136 h2 { font-size: 1.6em }
137 </style>
138 [% prototype.define_javascript_functions %]
139 <script>
140 var url = "[% cgi.url %]";
141 function doConvert(from, to, unit) {
142   var spinner = unit + "-spinner";
143   $(to).value = ''; // clear
144   $(spinner).innerHTML = "<img src=\"[% cgi.url %]?spinner=1\" style=\"vertical-align:middle\" />";
145   var query = "value=" + encodeURIComponent($(from).value) + "&from=" + from + "&to=" + to;
146   new Ajax.Request(
147     url,
148     { method: 'get',
149       parameters: query,
150       onComplete: function(req) { $(to).value = req.responseText; $(spinner).innerHTML = ""; } }
151   );
152 }
153 </script>
154 </head>
155 <body>
156 <h1>[% title %]</h1>
157
158 <h2>Currency</h2>
159 <p>
160 <input type="text" size="12" id="usd" onchange="doConvert('usd', 'jpy', 'currency')" /> USD =
161 <input type="text" size="12" id="jpy" onchange="doConvert('jpy', 'usd', 'currency')" /> JPY
162 <span id="currency-spinner"></span>
163 </p>
164
165 <h2>Length</h2>
166 <p>
167 <input type="text" size="12" id="feet" onchange="doConvert('feet', 'inch', 'length');doConvert('feet', 'meter', 'length')" /> feet =
168 <input type="text" size="12" id="inch" onchange="doConvert('inch', 'meter', 'length');doConvert('inch', 'feet', 'length')" /> inches =
169 <input type="text" size="12" id="meter" onchange="doConvert('meter', 'inch', 'length');doConvert('meter', 'feet', 'length')" /> meters
170 <span id="length-spinner"></span>
171 </p>
172
173 <h2>Weight</h2>
174 <p>
175 <input type="text" size="12" id="pound" onchange="doConvert('pound', 'oz', 'weight');doConvert('pound', 'g', 'weight')" /> lb =
176 <input type="text" size="12" id="oz" onchange="doConvert('oz', 'pound', 'weight');doConvert('oz', 'g', 'weight')" /> oz =
177 <input type="text" size="12" id="g" onchange="doConvert('g', 'pound', 'weight');doConvert('g', 'oz', 'weight')" /> g
178 <span id="weight-spinner"></span>
179 </p>
180
181 <h2>Dimensions</h2>
182 <p>
183 <input type="text" size="12" id="sqf" onchange="doConvert('sqf', 'sqm', 'dimensions')" /> square feet =
184 <input type="text" size="12" id="sqm" onchange="doConvert('sqm', 'sqf', 'dimensions')" /> m<sup>2</sup>
185 <span id="dimensions-spinner"></span>
186 </p>
187
188
189 TEMPLATE
190 }
191
192 sub show_spinner {
193     my $query = shift;
194     print $query->header('image/gif'), decode_base64(<<IMAGE);
195 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
239 ISADghsLBDEhIwRfGyMWGA8NXBEAOw==
240 IMAGE
241 }
Note: See TracBrowser for help on using the browser.