word/edit: image metadata in combined json column
[sheet.git] / writer.plp
index c6d5898b77a93870ba9e3f1fbace448b44c13e89..cd2e2bf1d6369529ad52a1186dcb14792ea82f2f 100644 (file)
@@ -12,6 +12,7 @@ EOT
 
 use List::Util qw( pairs pairkeys );
 use Shiar_Sheet::FormRow;
+use JSON;
 
 my $db = eval {
        require Shiar_Sheet::DB;
@@ -99,10 +100,10 @@ my %wordcol = (
        form    => {-label => 'Title'},
        alt     => {-label => 'Synonyms', -multiple => 1},
        wptitle => {-label => 'Wikipedia'},
-       source  => {-label => 'Image', -src => sub {
+       source  => {-label => 'Image', -json => 'image', -src => sub {
                return "data/word/org/$_[0]->{id}.jpg";
        }},
-       thumb   => {-label => 'Convert options', -multiple => 1, -src => sub {
+       convert => {-label => 'Convert options', -json => 'image', -multiple => 1, -src => sub {
                return "data/word/en/$_[0]->{id}.jpg";
        }},
        story   => {-label => 'Story', type => 'textarea', hidden => 'hidden'},
@@ -114,7 +115,7 @@ if (my $search = $fields{q}) {
        say '<h1>Search</h1><ul>';
        printf("<li><small>%s</small> %s %s</li>\n",
                $_->{id}, showlink($_->{form}, "/writer/$_->{id}"),
-               sprintf('<img src="/%s" style="height:3ex; width:auto" />', $wordcol{thumb}->{-src}->($_)) x defined $_->{thumb}
+               sprintf('<img src="/%s" style="height:3ex; width:auto" />', $wordcol{convert}->{-src}->($_)) x defined $_->{image}
        ) for $results->hashes;
        say "</ul>\n";
        exit;
@@ -137,12 +138,22 @@ elsif (defined $post{form}) {{
                return Encode::decode_utf8($_[0]);
        }
 
-       my $replace = $row;
-       $row = {map { $_ =>
-               ref $wordcol{$_} eq 'HASH' && $wordcol{$_}->{-multiple} ?
-                       [ map { parseinput($_) } $post{'@'.$_}->@* ] :
-               scalar parseinput($post{$_})
-       } keys %wordcol};
+       my $replace = $row;  # currently stored
+       $row = {};  # proposed update
+       while (my ($col, $colinfo) = each %wordcol) {
+               ref $colinfo eq 'HASH' or $colinfo = {};
+               my @val = map { parseinput($_) } $post{'@'.$col}->@*;
+               my $val = $colinfo->{-multiple} && @val ? \@val : $val[-1];
+               if (my $jsoncol = $colinfo->{-json}) {
+                       defined $val and
+                       $row->{$jsoncol}->{$col} = $val;  # hash will be encoded
+               }
+               else {
+                       $row->{$col} = $val;
+               }
+       }
+       my $imagecol = $row->{image};  # backup image subcolumns
+       ref $_ eq 'HASH' and $_ = encode_json($_) for values %{$row};
 
        if (!$row->{form}) {
                if ($row->{ref} ne 'delete') {
@@ -191,17 +202,17 @@ elsif (defined $post{form}) {{
        require Shiar_Sheet::ImagePrep;
        my $image = Shiar_Sheet::ImagePrep->new($wordcol{source}->{-src}->($row));
        my $reimage = eval {
-               ($row->{source} // '') ne ($replace->{source} // '') or return;
-               $image->download($row->{source});
+               ($imagecol->{source} // '') ne ($replace->{source} // '') or return;
+               $image->download($imagecol->{source});
        };
        !$@ or Alert(["Source image not found", $@]);
 
-       $reimage ||= $row->{thumb} ~~ $replace->{thumb};  # different convert
+       $reimage ||= $row->{image} ~~ $replace->{image};  # different source
        $reimage ||= $row->{cover} ~~ $replace->{cover};  # resize
        $reimage++ if $fields{rethumb};  # force refresh
        if ($reimage) {
                eval {
-                       $image->convert($wordcol{thumb}->{-src}->($row), $row->{thumb});
+                       $image->convert($wordcol{convert}->{-src}->($row), $imagecol->{convert});
                } or do {
                        my ($warn, @details) = ref $@ ? @{$@} : $@;
                        Alert([ "Thumbnail image not generated", $warn ], @details);
@@ -214,6 +225,14 @@ else {
        $row->{prio} = defined $row->{ref} ? undef : 1 unless exists $row->{prio};
 }
 
+eval {
+       my $imagerow = $row->{image} && decode_json(delete $row->{image}) || {};
+       while (my ($col, $val) = each %{$imagerow}) {
+               $row->{$col} = $val;
+       }
+       1;
+} or Alert("Error decoding image metadata", $@);
+
 my $title = $row->{id} ? "entry <small>#$row->{id}</small>" : 'new entry';
 bless $row, 'Shiar_Sheet::FormRow';
 :>