1 # This is part of the YARRG website. YARRG is a tool and website
2 # for assisting players of Yohoho Puzzle Pirates.
4 # Copyright (C) 2009 Ian Jackson <ijackson@chiark.greenend.org.uk>
5 # Copyright (C) 2009 Clare Boothby
7 # YARRG's client code etc. is covered by the ordinary GNU GPL (v3 or later).
8 # The YARRG website is covered by the GNU Affero GPL v3 or later, which
9 # basically means that every installation of the website will let you
10 # download the source.
12 # This program is free software: you can redistribute it and/or modify
13 # it under the terms of the GNU Affero General Public License as
14 # published by the Free Software Foundation, either version 3 of the
15 # License, or (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU Affero General Public License for more details.
22 # You should have received a copy of the GNU Affero General Public License
23 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # Yohoho and Puzzle Pirates are probably trademarks of Three Rings and
26 # are used without permission. This program is not endorsed or
27 # sponsored by Three Rings.
30 # This Perl module is used by the Mason scripts in yarrg/web/.
31 # We look for a symlink DATA to the actual data to use, so that
32 # the data uploader and website displayer can use different code.
48 our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
51 @EXPORT = qw(&dbw_connect &dbw_filename &ocean_list &sourcebasedir
52 &to_json_shim &to_json_protecttags
53 &set_ctype_utf8 &webdatadir
54 &expected_error &dbw_lookup_string
55 &printable &tr_datarow &tr_datarow_s &escerrq
56 &prettyprint_age &meta_prettyprint_age);
62 sub dotperllibdir () {
66 if ($dir =~ m/\.perl-lib$/) {
70 die "no appropriate dotperllib dir in @INC";
73 sub sourcebasedir () {
74 return dotperllibdir().'/..';
77 sub some_datadir ($) {
79 my $edir= $ENV{"YARRG_${what}_DIR"};
80 return $edir if defined $edir;
81 my $dir= dotperllibdir();
82 my $dirwhat= "$dir/$what";
85 } elsif ($!==&ENOENT) {
88 die "stat $dirwhat $!";
93 sub webdatadir () { return some_datadir('WEBDATA'); }
94 sub datadir () { return some_datadir('DATA'); }
99 my $datadir= datadir();
101 my $fn= "$datadir/source-info.txt";
102 my $f= new IO::File $fn or die "$fn $!";
105 next unless m/^ocean\s+(\S.*\S)\s*$/;
108 $f->error and die $!;
115 sub dbw_filename ($) {
117 die "unknown ocean $ocean ?"
118 unless grep { $_ eq $ocean } ocean_list();
119 return dbr_filename(datadir(), $ocean);
122 sub dbw_connect ($) {
124 my $fn= dbw_filename($ocean);
125 return db_connect_core($fn);
128 sub to_json_shim ($) {
130 # In JSON.pm 2.x, jsonToObj prints a warning to stderr which
131 # our callers don't like at all.
132 if ($JSON::VERSION >= 2.0) {
133 return to_json($obj);
135 return objToJson($obj);
139 sub to_json_protecttags ($) {
141 my $j= to_json_shim($v);
146 sub meta_prettyprint_age ($$$) {
147 my ($age,$floor,$plus) = @_;
149 $age < 60 ? 'less than a minute' :
150 $age < 60*2 ? '1 minute' :
151 $age < 3600*2 ? $floor ($age/60) $plus' minutes' :
152 $age < 86400*2 ? $floor ($age/3600) $plus ' hours' :
153 $floor ($age/86400) $plus ' days';
158 sub prettyprint_age ($) {
160 '.meta_prettyprint_age('$age','floor','.').'
167 sub dbw_lookup_string ($$$$$$$$) { # => ( $emsg, @dbresults )
169 $sth, $stmt_nqs, $abbrev_initials, $maxambig,
170 $em_nomatch, $em_manyambig, $emf_ambiguous) = @_;
172 $each =~ s/^\s*//; $each =~ s/\s*$//; $each =~ s/\s+/ /g;
175 my @pats= ("$each", "$each \%", "$each\%", "\%$each\%");
176 if ($abbrev_initials) {
177 push @pats, join ' ', map { "$_%" } split //, $each;
179 foreach my $pat (@pats) {
180 $sth->execute(($pat) x $stmt_nqs);
181 $results= $sth->fetchall_arrayref();
182 last if @$results==1;
183 $m{ $_->[0] }=1 for @$results;
189 } elsif (keys(%m) > $maxambig) {
190 return $em_manyambig;
192 return $emf_ambiguous->($each, join(', ', sort keys %m));
195 return (undef, @{ $results->[0] });
198 sub expected_error ($) {
199 my $r= { Emsg => $_[0] };
200 bless $r, 'CommodsWeb::ExpectedError';
204 sub printable ($) { # printable($m) where $m is the Mason request object
206 my $a= scalar $m->caller_args(-1);
207 foreach my $t (qw(pdf ps html pdf2 ps2)) {
208 return $t if $a->{"printable_$t"};
213 sub tr_datarow_s ($$) {
214 my ($m, $lineno) = @_;
216 if (!printable($m)) {
217 return "<tr class=\"datarow$lineno\">";
219 return "<tr bgcolor=\"".
220 ($lineno ? "#ffffff" : "#e3e3e3" ).
225 sub tr_datarow ($$) {
226 my ($m, $lineno) = @_;
227 $m->print(tr_datarow_s($m, $lineno));
231 return '"'.CGI::escapeHTML($_[0]).'"';
232 # Prettier qotes as below are not in HTML 3.2:
233 # return '“'.CGI::escapeHTML($_[0]).'”';
234 # return '‘'.CGI::escapeHTML($_[0]).'’';
237 package CommodsWeb::ExpectedError;
241 return $self->{Emsg};