word edit: download images from url input
[sheet.git] / writer.plp
1 <(common.inc.plp)><:
2
3 Html({
4         title => 'words cheat sheet admin',
5         version => '1.0',
6         nocache => 1,
7         raw => <<'EOT',
8 <style>
9 dd > input {
10         width: 32em;
11         max-width: 100%;
12         padding: 1ex;
13         font-family: monospace;
14 }
15 dl > dt, dl > dd {
16         float: none;
17         display: inline-block;
18         box-sizing: border-box;
19         width: 50%;
20         margin: 0;
21         line-height: 4ex;
22         vertical-align: text-top;
23 }
24 dd > img {
25         max-width: 300px;
26         display: block;
27 }
28 </style>
29 EOT
30 });
31
32 use List::Util qw( pairs pairkeys );
33
34 my $db = eval {
35         my @dbinfo = (
36                 'DBI:Pg:dbname=sheet;host=localhost', 'sheetadmin', 'fairuse',
37         ) or die "database not configured\n";
38         require DBIx::Simple;
39         DBIx::Simple->new(@dbinfo[0..2], {
40                 RaiseError => 1,
41                 pg_enable_utf8 => 1,
42         });
43 } or Abort('Database error', 501, $@);
44
45 my @wordcols = (
46         form    => 'Translation',
47         ref     => 'Reference',
48         cat     => 'Category',
49         lang    => 'Language',
50         source  => 'Image URL',
51         thumb   => 'Convert options',
52         wptitle => 'Wikipedia',
53 );
54 my $find = $Request ? {id => $Request} : undef;
55
56 my $row;
57 if ($ENV{REQUEST_METHOD} eq 'POST') {
58         $row = {%post{ pairkeys @wordcols }};
59         $_ = length ? $_ : undef for values %{$row};
60         eval {
61                 my %res = (returning => '*');
62                 my $query = $find ? $db->update(word => $row, $find, \%res) :
63                         $db->insert(word => $row, \%res);
64                 $row = $query->hash;
65         } or Alert("Entry could not be saved", $@);
66
67         my $imgpath = "data/word/org/$row->{id}.jpg";
68         if (my $download = $row->{source} and !-e $imgpath) {
69                 require LWP::UserAgent;
70                 my $ua = LWP::UserAgent->new;
71                 $ua->agent('/');
72                 my $status = $ua->mirror($download, $imgpath);
73                 $status->is_success or Alert([
74                         "Source image not found",
75                         "Download from <q>$download</q> failed: ".$status->status_line,
76                 ]);
77         }
78
79         my $thumbpath = "data/word/eng/$row->{form}.jpg";
80         if (-e $imgpath) {
81                 my @cmds = @{ $row->{thumb} // [] };
82                 unshift @cmds, -gravity => @cmds ? 'northwest' : 'center';
83                 unshift @cmds, 'convert';
84                 push @cmds, -resize => '300x200^', -extent => '300x200';
85                 push @cmds, '-strip', -quality => '60%', -interlace => 'plane';
86                 push @cmds, $imgpath, $thumbpath;
87                 my $status = system @cmds;
88                 $status == 0 or Alert([
89                         "Thumbnail image not generated",
90                         "Failed to convert source image, error code ".($status >> 8),
91                 ], "@cmds");
92         }
93
94         $row = {map {$_ => $row->{$_}} qw(lang cat)} if not $Request;
95 }
96 elsif ($find) {
97         $row = $db->select(word => '*', $find)->hash
98                 or Abort("Word not found", 404);
99 }
100
101 my $title = $row ? "entry <small>#$row->{id}</small>" : 'new entry';
102 :>
103 <h1>Words <:= $title :></h1>
104
105 <form action="" method="post">
106 <dl>
107 <:
108
109 for my $col (pairs @wordcols) {
110         my $val = $row->{$col->key} // '';
111         $val = '{'.join(',', map {s/,/\\,/gr} @{$val}).'}' if ref $val eq 'ARRAY';
112         printf '<dt><label for="%s">%s</label></dt>'
113                 . '<dd><input id="%1$s" name="%1$s" value="%s" />',
114                 $col->key, $col->value, $val;
115         -e and printf ' <img src="/%s" alt="%s" />', $_, $row->{form} for
116                 $col->key eq 'source' ? "data/word/org/$row->{id}.jpg" :
117                 $col->key eq 'thumb'  ? "data/word/eng/$row->{form}.jpg" :
118                 ();
119         say '</dd>';
120 }
121 :>
122 </dl>
123 <p><input type="submit" value="Save" /></p>
124 </form>