X-Git-Url: http://git.shiar.net/sheet.git/blobdiff_plain/643b24914332240284adb01359c55406405a7e89..5299da1556ec4ccf5c93fea0d1c4dcef5f6bb180:/word/edit.plp diff --git a/word/edit.plp b/word/edit.plp index 31fca23..55fbeac 100644 --- a/word/edit.plp +++ b/word/edit.plp @@ -1,6 +1,8 @@ <(../common.inc.plp)><: +my $editorurl = '/word/edit'; s{\Aedit(/|\z)}{} for $Request // (); + Html({ title => 'words cheat sheet admin', version => '1.0', @@ -13,6 +15,7 @@ EOT use List::Util qw( pairs pairkeys ); use Shiar_Sheet::FormRow; +use SQL::Abstract '1.83'; use JSON; my $db = eval { @@ -21,7 +24,6 @@ my $db = eval { } or Abort('Database error', 501, $@); my $user = eval { - my $rootpath = '/word/edit'; if (defined $post{username}) { $cookie{login} = EncodeURI(join ':', @post{qw( username pass )}); } @@ -30,7 +32,7 @@ my $user = eval { if (AddCookie(CGI::Cookie->new( -name => 'login', -value => '', - -path => $rootpath, + -path => $editorurl, -expires => 'now', )->as_string)) { delete $cookie{login}; @@ -50,7 +52,7 @@ my $user = eval { my $httpcookie = CGI::Cookie->new( -name => 'login', -value => join(':', @{$found}{qw( username pass )}), - -path => $rootpath, + -path => $editorurl, ) or die "prepared object is empty\n"; AddCookie($httpcookie->as_string); } or Abort(["Unable to create login cookie", $@], 403); @@ -71,6 +73,7 @@ my $user = eval { }; my %lang = ( + '' => ['(reference)'], nl => ["\N{REGIONAL INDICATOR SYMBOL LETTER N}\N{REGIONAL INDICATOR SYMBOL LETTER L}", 'nederlands'], en => ["\N{REGIONAL INDICATOR SYMBOL LETTER G}\N{REGIONAL INDICATOR SYMBOL LETTER B}", 'english'], eo => [qq'\N{BLACK STAR}', 'esperanto'], @@ -88,7 +91,9 @@ my %wordcol = ( prio => [ {-label => 'Level', -select => sub { my ($row) = @_; - my @enum = qw[ essential basic common distinctive optional invisible ]; + my @enum = qw[ + essential ubiquitous basic common distinctive specialised rare invisible + ]; return { ('' => 'parent') x (defined $row->{ref}), map { $_ => $enum[$_] } 0 .. $#enum @@ -105,17 +110,19 @@ my %wordcol = ( return "data/word/org/$_[0]->{id}.jpg"; }}, convert => {-label => 'Convert options', -json => 'image', -multiple => 1, -src => sub { - return "data/word/en/$_[0]->{id}.jpg"; + return "data/word/32/$_[0]->{id}.jpg"; }}, + crop32 => {-json => 'image', type => 'hidden'}, # set by javascript interface story => {-label => 'Story', type => 'textarea', hidden => 'hidden'}, ); if (my $search = $fields{q}) { - my %filter = (form => {ilike => '%'.$search.'%'}); + my %filter = $search eq '^' ? (cat => undef, ref => undef) : + (form => {ilike => '%'.parseinput($search).'%'}); my $results = $db->select(word => '*', \%filter); say '

Search

\n"; @@ -146,17 +153,23 @@ elsif (defined $post{form}) {{ 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 + ref $_ eq 'HASH' or $_ = decode_json($_) for $replace->{$jsoncol} // (); } else { $row->{$col} = $val; } } my $imagecol = $row->{image}; # backup image subcolumns - ref $_ eq 'HASH' and $_ = encode_json($_) for values %{$row}; + while (my ($col, $val) = each %{$row}) { + # convert json subcolumns to database string + ref $val eq 'HASH' or next; + $val = { %{$_}, %{$val} } for $replace->{$col} // (); # preserve unknown + defined $val->{$_} or delete $val->{$_} for keys %{$val}; # delete emptied + $row->{$col} = encode_json($val); + } - if (!$row->{form}) { + if (!$row->{form} and $row->{lang}) { if ($row->{ref} ne 'delete') { Alert("Empty title", "Confirm removal by setting Reference to delete." @@ -203,17 +216,17 @@ elsif (defined $post{form}) {{ require Shiar_Sheet::ImagePrep; my $image = Shiar_Sheet::ImagePrep->new($wordcol{source}->{-src}->($row)); my $reimage = eval { - ($imagecol->{source} // '') ne ($replace->{source} // '') or return; + ($imagecol->{source} // '') ne ($replace->{image}->{source} // '') or return; $image->download($imagecol->{source}); }; !$@ or Alert(["Source image not found", $@]); - $reimage ||= $row->{image} ~~ $replace->{image}; # different source - $reimage ||= $row->{cover} ~~ $replace->{cover}; # resize + $reimage ||= $row->{convert} ~~ $replace->{image}->{convert}; # different + $reimage ||= $row->{cover} ~~ $replace->{image}->{cover}; # resize $reimage++ if $fields{rethumb}; # force refresh if ($reimage) { eval { - $image->convert($wordcol{convert}->{-src}->($row), $imagecol->{convert}); + $image->generate($wordcol{convert}->{-src}->($row), $imagecol); } or do { my ($warn, @details) = ref $@ ? @{$@} : $@; Alert([ "Thumbnail image not generated", $warn ], @details); @@ -221,13 +234,13 @@ elsif (defined $post{form}) {{ } }} else { - $row->{lang} //= $user->{editlang}->[0]; + $row->{lang} //= $user->{editlang}->[0] unless exists $row->{lang}; $row->{$_} = $get{$_} for keys %get; - $row->{prio} = defined $row->{ref} ? undef : 1 unless exists $row->{prio}; + $row->{prio} = defined $row->{ref} ? undef : 4 unless exists $row->{prio}; } eval { - my $imagerow = $row->{image} && decode_json(delete $row->{image}) || {}; + my $imagerow = $row->{image} && JSON->new->decode(delete $row->{image}) || {}; while (my ($col, $val) = each %{$imagerow}) { $row->{$col} = $val; } @@ -250,21 +263,24 @@ for my $col (@wordcols) { my ($attr, @span) = ref $info eq 'ARRAY' ? @{$info} : $info; next if delete $attr->{hidden} and not $row->{$col}; my $title = ref $attr ? delete $attr->{-label} : $attr; - printf '
  • ', $col, $title; + printf '

  • ', $col, $title; printf ''; print $row->input($col => $attr); if (my $imgsrc = $attr->{-src}) { - printf('%s', - $col, $_, $row->{form}, $col eq 'source' && ' hidden' + my $hide = $col eq 'source'; + printf '
    ', $col unless $hide; + printf('%s', + $_, $row->{form}, $hide && qq( id="${col}preview" hidden) ) for grep { -e } $imgsrc->($row); + printf '
    ' unless $hide; } print $row->input($_ => delete $wordcol{$_}) for @span; print '
    '; - say '

  • '; + say ''; } if (not $row->{ref}) { - printf '
  • - +

    @@ -306,20 +322,24 @@ if ($row->{id}) { say ' + + <: }