1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#
# Multi::Image - Image compressing and resizing
#
package Multi::Image;
use strict;
use warnings;
use POE;
use Image::Magick;
use Image::MetaData::JPEG;
sub spawn {
my $p = shift;
POE::Session->create(
package_states => [
$p => [qw| _start cmd_coverimage format compress update finish |],
],
heap => {
imgpath => '/www/vndb/static/cv'
},
);
}
sub _start {
$_[KERNEL]->alias_set('image');
$_[KERNEL]->sig(shutdown => 'shutdown');
$_[KERNEL]->call(core => register => qr/^coverimage(?: ([0-9]+)|)$/, 'cmd_coverimage');
# check for unprocessed cover images every day on 0:00 and 12:00 local time
$_[KERNEL]->post(core => addcron => '0 0,12 * * *', 'coverimage');
}
sub cmd_coverimage {
$_[HEAP]{curcmd} = $_[ARG0];
if($_[ARG1]) {
$_[HEAP]{todo} = [ $_[ARG1] ];
} else {
my $q = $Multi::SQL->prepare('SELECT image FROM vn_rev WHERE image < 0');
$q->execute();
$_[HEAP]{todo} = [ map { -1*$_->[0]} @{$q->fetchall_arrayref([])} ];
if(!@{$_[HEAP]{todo}}) {
$_[KERNEL]->call(core => log => 2, 'No images to process');
$_[KERNEL]->yield('finish');
return;
}
}
$_[KERNEL]->yield(format => $_[HEAP]{todo}[0]);
}
sub format { # imgid
$_[HEAP]{imgid} = $_[ARG0];
$_[HEAP]{img} = sprintf '%s/%02d/%d.jpg', $_[HEAP]{imgpath}, $_[ARG0]%100, $_[ARG0];
$_[KERNEL]->call(core => log => 3, 'Processing image %d', $_[HEAP]{imgid});
$_[HEAP]{im} = Image::Magick->new;
$_[HEAP]{im}->Read($_[HEAP]{img});
$_[HEAP]{im}->Set(magick => 'JPEG');
my($w, $h) = ($_[HEAP]{im}->Get('width'), $_[HEAP]{im}->Get('height'));
if($w > 256 || $h > 400) {
$_[KERNEL]->call(core => log => 3, 'Image too large (%dx%d), resizing', $w, $h);
if($w/$h > 256/400) { # width is the limiting factor
$h *= 256/$w;
$w = 256;
} else {
$w *= 400/$h;
$h = 400;
}
$_[HEAP]{im}->Thumbnail(width => $w, height => $h);
}
$_[KERNEL]->yield('compress');
}
sub compress {
$_[HEAP]{im}->Set(quality => 80);
$_[HEAP]{im}->Write($_[HEAP]{img});
undef $_[HEAP]{im};
$_[HEAP]{md} = Image::MetaData::JPEG->new($_[HEAP]{img});
$_[HEAP]{md}->drop_segments('METADATA');
$_[HEAP]{md}->save($_[HEAP]{img});
undef $_[HEAP]{md};
$_[KERNEL]->call(core => log => 3, 'Compressed image %d to %.2fkB', $_[HEAP]{imgid}, (-s $_[HEAP]{img})/1024);
$_[KERNEL]->yield('update');
}
sub update {
if($Multi::SQL->do('UPDATE vn_rev SET image = ? WHERE image = ?', undef, $_[HEAP]{imgid}, -1*$_[HEAP]{imgid})) {
$_[KERNEL]->yield('finish');
} elsif(!$_[ARG0]) {
$_[KERNEL]->delay(update => 3, 3);
} else {
$_[KERNEL]->call(core => log => 1, 'Image %d not present in the database!', $_[HEAP]{imgid});
$_[KERNEL]->yield('finish');
}
}
sub finish {
if($_[HEAP]{imgid}) {
$_[HEAP]{todo} = [ grep { $_[HEAP]{imgid} != $_ } @{$_[HEAP]{todo}} ];
if(@{$_[HEAP]{todo}}) {
$_[KERNEL]->yield(format => $_[HEAP]{todo}[0]);
return;
}
}
$_[KERNEL]->post(core => finish => $_[HEAP]{curcmd});
delete @{$_[HEAP]}{qw| curcmd imgid img im md todo |};
}
1;
|