1 package Sesse::pr0n::Upload;
5 use Sesse::pr0n::Common qw(error dberror);
11 my $dbh = Sesse::pr0n::Common::get_dbh();
13 my $res = Plack::Response->new(200);
14 my $io = IO::String->new;
16 my ($user,$takenby) = Sesse::pr0n::Common::check_access($r);
17 return Sesse::pr0n::Common::generate_401($r) if (!defined($user));
19 # Just "ping, are you alive"
20 if ($r->method eq "OPTIONS") {
21 $res->content_type('text/plain; charset="utf-8"');
25 if ($r->method eq "PUT") {
26 if ($r->path_info !~ m#^/upload/([a-zA-Z0-9-]+)/(autorename/)?(.{1,250})$#) {
28 $res->content_type('text/plain; charset=utf-8');
29 $res->body("No access");
33 my ($event, $autorename, $filename) = ($1, $2, $3);
34 my $size = $r->header('content-length');
35 my $orig_filename = $filename;
37 # Remove evil characters
38 if ($filename =~ /[^a-zA-Z0-9._()-]/) {
39 if (defined($autorename) && $autorename eq "autorename/") {
40 $filename =~ tr/a-zA-Z0-9.()-/_/c;
43 $res->content_type('text/plain; charset=utf-8');
44 $res->body("Illegal characters in filename");
50 my $ref = $dbh->selectrow_hashref("SELECT NEXTVAL('imageid_seq') AS id;");
51 my $newid = $ref->{'id'};
52 if (!defined($newid)) {
53 return dberror($r, "Couldn't get new ID");
56 # Autorename if we need to
57 $ref = $dbh->selectrow_hashref("SELECT COUNT(*) AS numfiles FROM images WHERE vhost=? AND event=? AND filename=?",
58 undef, Sesse::pr0n::Common::get_server_name($r), $event, $filename)
59 or return dberror($r, "Couldn't check for existing files");
60 if ($ref->{'numfiles'} > 0) {
61 if (defined($autorename) && $autorename eq "autorename/") {
62 Sesse::pr0n::Common::log_info($r, "Renaming $filename to $newid.jpeg");
63 $filename = "$newid.jpeg";
66 $res->content_type('text/plain; charset=utf-8');
67 $res->body("File $filename already exists in event $event, cannot overwrite");
73 # Enable transactions and error raising temporarily
74 local $dbh->{AutoCommit} = 0;
75 local $dbh->{RaiseError} = 1;
78 # Try to insert this new file
80 $dbh->do('INSERT INTO images (id,vhost,event,uploadedby,takenby,filename) VALUES (?,?,?,?,?,?)',
81 undef, $newid, Sesse::pr0n::Common::get_server_name($r), $event, $user, $takenby, $filename);
82 Sesse::pr0n::Common::purge_cache($r, $res, "/$event/");
84 # Now save the file to disk
85 Sesse::pr0n::Common::ensure_disk_location_exists($r, $newid);
86 $fname = Sesse::pr0n::Common::get_disk_location($r, $newid);
88 open NEWFILE, ">", $fname
90 print NEWFILE $r->content;
91 close NEWFILE or die "close($fname): $!";
93 # Orient stuff correctly
94 system("/usr/bin/exifautotran", $fname) == 0
95 or die "/usr/bin/exifautotran: $!";
97 # Make cache while we're at it.
98 # FIXME: Ideally we'd want to ensure cache of -1x-1 here as well (for NEFs), but that would
99 # preclude mipmapping in its current form.
100 Sesse::pr0n::Common::ensure_cached($r, $filename, $newid, undef, undef, 320, 256);
102 # OK, we got this far, commit
105 Sesse::pr0n::Common::log_info($r, "Successfully wrote $event/$filename to $fname");
108 # Some error occurred, rollback and bomb out
111 return error($r, "Transaction aborted because $@");
115 $res->content_type('text/plain; charset="utf-8"');
121 $res->content_type('text/plain; charset=utf-8');
122 Sesse::pr0n::Common::log_error($r, "unknown method " . $r->method);
124 $res->body("Unknown method");