71102eb1336e5c8960e3492d248065f6b4557b41
[pr0n] / perl / Sesse / pr0n / Rotate.pm
1 package Sesse::pr0n::Rotate;
2 use strict;
3 use warnings;
4
5 use Sesse::pr0n::Common qw(error dberror);
6 use Apache2::Request;
7
8 sub handler {
9         my $r = shift;
10         my $apr = Apache2::Request->new($r);
11         my $dbh = Sesse::pr0n::Common::get_dbh();
12         my ($user, $takenby) = Sesse::pr0n::Common::check_access($r);
13         if (!defined($user)) {
14                 return Apache2::Const::OK;
15         }
16
17         # FIXME: People can rotate and delete across vhosts using this interface.
18         # We should add some sanity checks.
19
20         my @to_purge = ();
21
22         Sesse::pr0n::Common::header($r, "Rotation/deletion results");
23
24         {
25                 # Enable transactions and error raising temporarily
26                 local $dbh->{RaiseError} = 1;
27
28                 my @params = $apr->param();
29                 my $key;
30                 for $key (@params) {
31                         local $dbh->{AutoCommit} = 0;
32
33                         # Rotation
34                         if ($key =~ /^rot-(\d+)-(90|180|270)$/ && $apr->param($key) eq 'on') {
35                                 my ($id, $rotval) = ($1,$2);
36                                 my $fname = Sesse::pr0n::Common::get_disk_location($r, $id);
37                                 push @to_purge, Sesse::pr0n::Common::get_all_cache_urls($r, $dbh, $id);
38                                 (my $tmpfname = $fname) =~ s/\.jpg$/-tmp.jpg/;
39
40                                 system("/usr/bin/jpegtran -rotate $rotval -copy all < '$fname' > '$tmpfname' && mv '$tmpfname' '$fname'") == 0
41                                         or error($r, "Rotation of $id [/usr/bin/jpegtran -rotate $rotval -copy all < '$fname' > '$tmpfname' && mv '$tmpfname' '$fname'] failed: $!.");
42                                 $r->print("    <p>Rotated image ID `$id' by $rotval degrees.</p>\n");
43
44                                 if ($rotval == 90 || $rotval == 270) {
45                                         my $q = $dbh->do('UPDATE images SET height=width,width=height WHERE id=?', undef, $id)
46                                                 or dberror($r, "Size clear of $id failed");
47                                         $dbh->do('UPDATE last_picture_cache SET last_update=CURRENT_TIMESTAMP WHERE (vhost,event)=( SELECT vhost,event FROM images WHERE id=? )',
48                                                 undef, $id)
49                                                 or dberror($r, "Cache invalidation at $id failed");
50                                 }
51                         } elsif ($key =~ /^del-(\d+)$/ && $apr->param($key) eq 'on') {
52                                 my $id = $1;
53                                 push @to_purge, Sesse::pr0n::Common::get_all_cache_urls($r, $dbh, $id);
54                                 {
55
56                                         eval {
57                                                 $dbh->do('UPDATE last_picture_cache SET last_update=CURRENT_TIMESTAMP WHERE (vhost,event)=( SELECT vhost,event FROM images WHERE id=? )',
58                                                         undef, $id);
59                                                 $dbh->do('INSERT INTO deleted_images SELECT * FROM images WHERE id=?',
60                                                         undef, $id);
61                                                 $dbh->do('DELETE FROM exif_info WHERE image=?',
62                                                         undef, $id);
63                                                 $dbh->do('DELETE FROM images WHERE id=?',
64                                                         undef, $id);
65                                         };
66                                         if ($@) {
67 # Some error occurred, rollback and bomb out
68                                                 $dbh->rollback;
69                                                 dberror($r, "Transaction aborted because $@");
70                                         }
71                                 }
72                                 $r->print("    <p>Deleted image `$id'.</p>\n");
73                         }
74                 }
75         }
76         
77         my $event = $apr->param('event');
78         $dbh->do('UPDATE last_picture_cache SET last_update=CURRENT_TIMESTAMP WHERE vhost=? AND event=?', undef, $r->get_server_name, $event)
79                 or dberror($r, "Cache invalidation failed");
80
81         push @to_purge, "/$event/";
82         push @to_purge, "/+all/";
83         Sesse::pr0n::Common::purge_cache($r, @to_purge);
84
85         Sesse::pr0n::Common::footer($r);
86
87         return Apache2::Const::OK;
88 }
89
90 1;
91
92