From 49a2516e6b076667e163aaff2ae2e94ed52fa083 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Wed, 16 Feb 2011 19:24:13 +0100 Subject: chardb: Added image to character entries --- lib/Multi/Feed.pm | 5 ++-- lib/Multi/Image.pm | 40 ++++++++++++++++++++++++--- lib/VNDB/DB/Chars.pm | 12 ++++++--- lib/VNDB/Handler/Chars.pm | 69 ++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 108 insertions(+), 18 deletions(-) (limited to 'lib') diff --git a/lib/Multi/Feed.pm b/lib/Multi/Feed.pm index 12631497..483089bd 100644 --- a/lib/Multi/Feed.pm +++ b/lib/Multi/Feed.pm @@ -64,13 +64,14 @@ sub generate { # changes $_[KERNEL]->post(pg => query => q{ - SELECT '/'||c.type||COALESCE(vr.vid, rr.rid, pr.pid)||'.'||c.rev AS id, - COALESCE(vr.title, rr.title, pr.name) AS title, extract('epoch' from c.added) AS updated, + SELECT '/'||c.type||COALESCE(vr.vid, rr.rid, pr.pid, cr.cid)||'.'||c.rev AS id, + COALESCE(vr.title, rr.title, pr.name, cr.name) AS title, extract('epoch' from c.added) AS updated, u.username, u.id AS uid, c.comments AS summary FROM changes c LEFT JOIN vn_rev vr ON c.type = 'v' AND c.id = vr.id LEFT JOIN releases_rev rr ON c.type = 'r' AND c.id = rr.id LEFT JOIN producers_rev pr ON c.type = 'p' AND c.id = pr.id + LEFT JOIN chars_rev cr ON c.type = 'c' AND c.id = cr.id JOIN users u ON u.id = c.requester WHERE c.requester <> 1 ORDER BY c.id DESC diff --git a/lib/Multi/Image.pm b/lib/Multi/Image.pm index ad1d436c..3f8bb1a9 100644 --- a/lib/Multi/Image.pm +++ b/lib/Multi/Image.pm @@ -18,10 +18,11 @@ sub spawn { POE::Session->create( package_states => [ $p => [qw| _start - _start shutdown cv_check cv_process scr_check scr_process + _start shutdown ch_check ch_process cv_check cv_process scr_check scr_process |], ], heap => { + chpath => $VNDB::ROOT.'/static/ch', cvpath => $VNDB::ROOT.'/static/cv', sfpath => $VNDB::ROOT.'/static/sf', stpath => $VNDB::ROOT.'/static/st', @@ -35,20 +36,53 @@ sub spawn { sub _start { $_[KERNEL]->alias_set('image'); $_[KERNEL]->sig(shutdown => 'shutdown'); - $_[KERNEL]->post(pg => listen => coverimage => 'cv_check', screenshot => 'scr_check'); + $_[KERNEL]->post(pg => listen => charimage => 'ch_check', coverimage => 'cv_check', screenshot => 'scr_check'); + $_[KERNEL]->yield('ch_check'); $_[KERNEL]->yield('cv_check'); $_[KERNEL]->yield('scr_check'); } sub shutdown { - $_[KERNEL]->post(pg => unlisten => 'coverimage', 'screenshot'); + $_[KERNEL]->post(pg => unlisten => 'charimage', 'coverimage', 'screenshot'); + $_[KERNEL]->delay('ch_check'); $_[KERNEL]->delay('cv_check'); $_[KERNEL]->delay('scr_check'); $_[KERNEL]->alias_remove('image'); } +sub ch_check { + $_[KERNEL]->delay('ch_check'); + $_[KERNEL]->post(pg => query => 'SELECT image FROM chars_rev WHERE image < 0 LIMIT 1', undef, 'ch_process'); +} + + +sub ch_process { # num, res + return $_[KERNEL]->delay(ch_check => $_[HEAP]{check_delay}) if $_[ARG0] == 0; + + my $id = -1*$_[ARG1][0]{image}; + my $start = time; + my $img = sprintf '%s/%02d/%d.jpg', $_[HEAP]{chpath}, $id%100, $id; + my $os = -s $img; + + my $im = Image::Magick->new; + $im->Read($img); + $im->Set(magick => 'JPEG'); + my($ow, $oh) = ($im->Get('width'), $im->Get('height')); + my($nw, $nh) = imgsize($ow, $oh, @{$VNDB::S{ch_size}}); + $im->Thumbnail(width => $nw, height => $nh); + $im->Set(quality => 80); + $im->Write($img); + + $_[KERNEL]->post(pg => do => 'UPDATE chars_rev SET image = image*-1 WHERE image = ?', [ -1*$id ]); + $_[KERNEL]->call(core => log => 'Processed character image %d in %.2fs: %.2fkB (%dx%d) -> %.2fkB (%dx%d)', + $id, time-$start, $os/1024, $ow, $oh, (-s $img)/1024, $nw, $nh); + + $_[KERNEL]->yield('ch_check'); +} + + sub cv_check { $_[KERNEL]->delay('cv_check'); $_[KERNEL]->post(pg => query => 'SELECT image FROM vn_rev WHERE image < 0 LIMIT 1', undef, 'cv_process'); diff --git a/lib/VNDB/DB/Chars.pm b/lib/VNDB/DB/Chars.pm index b12c4425..3f744239 100644 --- a/lib/VNDB/DB/Chars.pm +++ b/lib/VNDB/DB/Chars.pm @@ -5,7 +5,7 @@ use strict; use warnings; use Exporter 'import'; -our @EXPORT = qw|dbCharGet dbCharRevisionInsert|; +our @EXPORT = qw|dbCharGet dbCharRevisionInsert dbCharImageId|; # options: id rev what results page @@ -26,7 +26,7 @@ sub dbCharGet { ); my @select = qw|c.id cr.name cr.original|; - push @select, qw|c.hidden c.locked cr.alias cr.desc| if $o{what} =~ /extended/; + push @select, qw|c.hidden c.locked cr.alias cr.desc cr.image| if $o{what} =~ /extended/; push @select, qw|h.requester h.comments c.latest u.username h.rev h.ihid h.ilock|, "extract('epoch' from h.added) as added", 'cr.id AS cid' if $o{what} =~ /changes/; my @join; @@ -51,10 +51,16 @@ sub dbCharRevisionInsert { my($self, $o) = @_; my %set = map exists($o->{$_}) ? (qq|"$_" = ?|, $o->{$_}) : (), - qw|name original alias desc|; + qw|name original alias desc image|; $self->dbExec('UPDATE edit_char !H', \%set) if keys %set; } +# fetches an ID for a new image +sub dbCharImageId { + return shift->dbRow("SELECT nextval('charimg_seq') AS ni")->{ni}; +} + + 1; diff --git a/lib/VNDB/Handler/Chars.pm b/lib/VNDB/Handler/Chars.pm index f593077f..1c0643fd 100644 --- a/lib/VNDB/Handler/Chars.pm +++ b/lib/VNDB/Handler/Chars.pm @@ -35,6 +35,10 @@ sub page { [ original => diff => 1 ], [ alias => diff => qr/[ ,\n\.]/ ], [ desc => diff => qr/[ ,\n\.]/ ], + [ image => htmlize => sub { + return $_[0] > 0 ? sprintf '', $self->{url_static}, $_[0]%100, $_[0] + : mt $_[0] < 0 ? '_chdiff_image_proc' : '_chdiff_image_none'; + }], ); } @@ -42,6 +46,7 @@ sub page { $self->htmlItemMessage('c', $r); h1 $r->{name}; h2 class => 'alttitle', $r->{original} if $r->{original}; + img src => sprintf('%s/ch/%02d/%d.jpg', $self->{url_static}, $r->{image}%100, $r->{image}), alt => $r->{name} if $r->{image}; if($r->{desc}) { p class => 'description'; lit bb2html($r->{desc}); @@ -64,7 +69,7 @@ sub edit { || $id && ($r->{locked} && !$self->authCan('lock') || $r->{hidden} && !$self->authCan('del')); my %b4 = !$id ? () : ( - (map { $_ => $r->{$_} } qw|name original alias desc ihid ilock|), + (map { $_ => $r->{$_} } qw|name original alias desc image ihid ilock|), ); my $frm; @@ -75,11 +80,16 @@ sub edit { { post => 'original', required => 0, maxlength => 200, default => '' }, { post => 'alias', required => 0, maxlength => 500, default => '' }, { post => 'desc', required => 0, maxlength => 5000, default => '' }, + { post => 'image', required => 0, default => 0, template => 'int' }, { post => 'editsum', required => 0, maxlength => 5000 }, { post => 'ihid', required => 0 }, { post => 'ilock', required => 0 }, ); push @{$frm->{_err}}, 'badeditsum' if !$frm->{editsum} || lc($frm->{editsum}) eq lc($frm->{desc}); + + # handle image upload + $frm->{image} = _uploadimage($self, $r, $frm); + if(!$frm->{_err}) { $frm->{ihid} = $frm->{ihid} ?1:0; $frm->{ilock} = $frm->{ilock}?1:0; @@ -99,18 +109,57 @@ sub edit { $self->htmlHeader(title => $title, noindex => 1); $self->htmlMainTabs('c', $r, 'edit') if $r; $self->htmlEditMessage('c', $r, $title); - $self->htmlForm({ frm => $frm, action => $r ? "/c$id/edit" : '/c/new', editsum => 1 }, - 'chare_geninfo' => [ mt('_chare_form_generalinfo'), - [ input => name => mt('_pedit_form_name'), short => 'name' ], - [ input => name => mt('_pedit_form_original'), short => 'original' ], - [ static => content => mt('_pedit_form_original_note') ], - [ text => name => mt('_pedit_form_alias'), short => 'alias', rows => 3 ], - [ static => content => mt('_pedit_form_alias_note') ], - [ text => name => mt('_pedit_form_desc').'
'.mt('_inenglish').'', short => 'desc', rows => 6 ], - ]); + $self->htmlForm({ frm => $frm, action => $r ? "/c$id/edit" : '/c/new', editsum => 1, upload => 1 }, + chare_geninfo => [ mt('_chare_form_generalinfo'), + [ input => name => mt('_chare_form_name'), short => 'name' ], + [ input => name => mt('_chare_form_original'), short => 'original' ], + [ static => content => mt('_chare_form_original_note') ], + [ text => name => mt('_chare_form_alias'), short => 'alias', rows => 3 ], + [ static => content => mt('_chare_form_alias_note') ], + [ text => name => mt('_chare_form_desc').'
'.mt('_inenglish').'', short => 'desc', rows => 6 ], + ], + + chare_img => [ mt('_chare_image'), [ static => nolabel => 1, content => sub { + div class => 'img'; + p mt '_chare_image_none' if !$frm->{image}; + p mt '_chare_image_processing' if $frm->{image} && $frm->{image} < 0; + img src => sprintf("%s/ch/%02d/%d.jpg", $self->{url_static}, $frm->{image}%100, $frm->{image}) if $frm->{image} && $frm->{image} > 0; + end; + + div; + h2 mt '_chare_image_id'; + input type => 'text', class => 'text', name => 'image', id => 'image', value => $frm->{image}; + p mt '_chare_image_id_msg'; + br; br; + + h2 mt '_chare_image_upload'; + input type => 'file', class => 'text', name => 'img', id => 'img'; + p mt('_chare_image_upload_msg'); + end; + }]]); $self->htmlFooter; } +sub _uploadimage { + my($self, $c, $frm) = @_; + return $c ? $frm->{image} : 0 if $frm->{_err} || !$self->reqPost('img'); + + # perform some elementary checks + my $imgdata = $self->reqUploadRaw('img'); + $frm->{_err} = [ 'noimage' ] if $imgdata !~ /^(\xff\xd8|\x89\x50)/; # JPG or PNG headers + $frm->{_err} = [ 'toolarge' ] if length($imgdata) > 1024*1024; + return undef if $frm->{_err}; + + # get image ID and save it, to be processed by Multi + my $imgid = $self->dbCharImageId; + my $fn = sprintf '%s/static/ch/%02d/%d.jpg', $VNDB::ROOT, $imgid%100, $imgid; + $self->reqSaveUpload('img', $fn); + chmod 0666, $fn; + + return -1*$imgid; +} + + 1; -- cgit v1.2.3