]> git.sesse.net Git - pr0n/commitdiff
Fix an (irrelevant) confusion about addEventListener. master
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 19 Mar 2023 23:33:07 +0000 (00:33 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 19 Mar 2023 23:33:07 +0000 (00:33 +0100)
files/pr0n-fullscreen.css
files/pr0n-fullscreen.js
perl/Sesse/pr0n/Common.pm
perl/Sesse/pr0n/Image.pm
perl/Sesse/pr0n/Index.pm
perl/Sesse/pr0n/pr0n.pm
perl/update-image-cache.pl
sql/pr0n.sql

index b501128cd667a2ab7fa6a1d7cbf6fddfa65e1ab4..d4f897af0d05a1c9729001a199f628c6494b7344 100644 (file)
@@ -10,6 +10,9 @@ body {
 .container {
        text-align: center;
 }
+.container #optionmenu {
+       text-align: left;
+}
 
 img, #text {
        vertical-align: middle;
@@ -63,6 +66,17 @@ img, #text {
        display: none;
 }
 
+.fsbox {
+       position: absolute;
+       transform-origin: top left;
+       background-color: white;
+       color: black;
+       font: 12px sans-serif;
+       line-height: 24px;
+       border-top: 1px solid black;
+       z-index: 1;
+}
+
 html, body {
        overflow: hidden;
 }
index 076c626a9a81c49dc59a22189ead0eebef165f83..f08605cb1640f47490c13ec3b7ce3aa19559d6a4 100644 (file)
@@ -104,7 +104,7 @@ function rename_element(old_name, new_name)
        return elem;
 }
 
-function display_image(url, backend_width, backend_height, elem_id, offset, box)
+function display_image(url, backend_width, backend_height, elem_id, offset)
 {
        // See if this image already exists in the DOM; if not, add it.
        var img = document.getElementById(elem_id);
@@ -112,7 +112,7 @@ function display_image(url, backend_width, backend_height, elem_id, offset, box)
                img = document.createElement("img");
                img.id = elem_id;
                img.alt = "";
-               img.className = box ? "fsbox" : "fsimg";
+               img.className = "fsimg";
        }
        img.style.position = "absolute";
        img.style.transformOrigin = "top left";
@@ -120,7 +120,7 @@ function display_image(url, backend_width, backend_height, elem_id, offset, box)
 
        if (offset === 0) {
                img.src = url;
-               position_image(img, backend_width, backend_height, offset, box);
+               position_image(img, backend_width, backend_height, offset, false);
        } else {
                // This is a preload, so wait for the main image to be ready.
                // The test for .complete is an old IE hack, which I don't know if is relevant anymore.
@@ -128,15 +128,44 @@ function display_image(url, backend_width, backend_height, elem_id, offset, box)
                if (main_img === null || main_img.complete) {
                        img.src = url;
                } else {
-                       main_img.addEventListener('load', function() { img.src = url; }, false);
+                       main_img.addEventListener('load', function() { img.src = url; }, { 'once': true });
                }
 
                // Seemingly one needs to delay position_image(), or Firefox will set the initial
                // scroll offset completely off.
                img.style.display = 'none';
                setTimeout(function() {
-                       position_image(img, backend_width, backend_height, offset, box);
-                       img.style.display = null;
+                       img.style.display = null;  // Must be done before position_image(), for measurement.
+                       position_image(img, backend_width, backend_height, offset, false);
+               }, 1);
+       }
+}
+
+function display_infobox(html, backend_width, backend_height, elem_id, offset)
+{
+       // See if this image already exists in the DOM; if not, add it.
+       var box = document.getElementById(elem_id);
+       if (box === null) {
+               box = document.createElement("div");
+               box.id = elem_id;
+               box.alt = "";
+               box.className = "fsbox";
+       }
+       box.style.position = "absolute";
+       box.style.transformOrigin = "top left";
+       box.innerHTML = html;
+       document.getElementById("main").appendChild(box);
+
+       if (offset === 0) {
+               position_image(box, backend_width, backend_height, offset, true);
+       } else {
+               // This is a preload.
+               // Seemingly one needs to delay position_image(), or Firefox will set the initial
+               // scroll offset completely off.
+               box.style.display = 'none';
+               setTimeout(function() {
+                       box.style.display = null;  // Must be done before position_image(), for measurement.
+                       position_image(box, backend_width, backend_height, offset, true);
                }, 1);
        }
 }
@@ -160,19 +189,11 @@ function display_image_num(num, offset)
        var url = window.location.origin + "/" + evt + "/" + backend_width + "x" + backend_height + "/" + filename;
        var elem_id = num;
 
-       display_image(url, adjusted_size[2], adjusted_size[3], elem_id, offset, false);
+       display_image(url, adjusted_size[2], adjusted_size[3], elem_id, offset);
 
        if (global_infobox) {
-               var url;
-               var dpr = find_dpr();
                var elem_id = num + "_box";
-               if (dpr == 1) {
-                       url = window.location.origin + "/" + evt + "/" + backend_width + "x" + backend_height + "/box/" + filename;
-               } else {
-                       url = window.location.origin + "/" + evt + "/" + backend_width + "x" + backend_height + "@" + dpr.toFixed(2) + "/box/" + filename;
-               }
-               display_image(url, adjusted_size[2], adjusted_size[3], elem_id, offset, true);
-               document.getElementById(elem_id).style.transform += " scale(" + (1.0 / dpr) + ")";
+               display_infobox(global_image_list[num][4], adjusted_size[2], adjusted_size[3], elem_id, offset);
        }
 
        if (offset === 0) {
@@ -253,7 +274,13 @@ function position_image(img, backend_width, backend_height, offset, box)
        img.style.transform = "translate(" + extra_x_offset + "px,0px)";
 
        if (box) {
-               img.style.top = Math.min(top + height, screen_size[1] - 24) / dpr + "px";
+               img.style.top = Math.min(top + height, screen_size[1] - 24 * dpr) / dpr + "px";
+               img.style.height = "24px";
+               img.style.width = null;
+               img.style.whiteSpace = 'nowrap';
+               // Hide the box if there's no room for all the text.
+               img.style.opacity = (img.clientWidth < width / dpr + 10) ? null : 0.0;
+               img.style.width = (width / dpr) + "px";
        } else {
                img.style.top = (top / dpr) + "px";
                img.style.lineHeight = (height / dpr) + "px";
@@ -288,7 +315,7 @@ function update_shown_images()
                //    inum !== global_image_num + 1) {
                //      to_remove.push(child);
                //}
-               if (inum !== global_image_num) {
+               if (inum !== global_image_num || (child.className === "fsbox" && !global_infobox)) {
                        to_remove.push(child);
                }
        }
@@ -531,7 +558,7 @@ function set_swipe_pos(x, transition)
                        var inum = parseInt(child.id.replace("_box", ""));
                        var offset = inum - global_image_num;
                        child.style.transition = transition;
-                       child.style.transform = "translate(" + (x + find_width()[0] * offset / dpr) + "px,0px) scale(" + (1.0 / dpr) + ")";
+                       child.style.transform = "translate(" + (x + find_width()[0] * offset / dpr) + "px,0px)";
                }
        }
 }
index 8a426987bf2fbb90614f7f36620aaf37cbbcaae2..101cee6283603405dfcc5830dd9e277e837a0613 100644 (file)
@@ -219,17 +219,6 @@ sub get_cache_location {
        return $Sesse::pr0n::Config::image_base . "cache/$dir/$id-$width-$height-nobox.$format";
 }
 
-sub get_infobox_cache_location {
-       my ($id, $width, $height, $dpr) = @_;
-       my $dir = POSIX::floor($id / 256);
-
-       if ($dpr == 1) {
-               return $Sesse::pr0n::Config::image_base . "cache/$dir/$id-$width-$height-box.png";
-       } else {
-               return $Sesse::pr0n::Config::image_base . "cache/$dir/$id-$width-$height-box\@$dpr.png";
-       }
-}
-
 sub ensure_disk_location_exists {
        my ($r, $id) = @_;
        my $dir = POSIX::floor($id / 256);
@@ -237,13 +226,15 @@ sub ensure_disk_location_exists {
        my $img_dir = $Sesse::pr0n::Config::image_base . "/images/$dir/";
        if (! -d $img_dir) {
                log_info($r, "Need to create new image directory $img_dir");
-               mkdir($img_dir) or die "Couldn't create new image directory $img_dir";
+               mkdir($img_dir);  # Ignore errors, there could be a race.
+               -d $img_dir or die "Couldn't create new image directory $img_dir";
        }
 
        my $cache_dir = $Sesse::pr0n::Config::image_base . "/cache/$dir/";
        if (! -d $cache_dir) {
                log_info($r, "Need to create new cache directory $cache_dir");
-               mkdir($cache_dir) or die "Couldn't create new image directory $cache_dir";
+               mkdir($cache_dir);  # Ignore errors, there could be a race.
+               -d $cache_dir or die "Couldn't create new cache directory $cache_dir";
        }
 }
 
@@ -708,69 +699,6 @@ sub make_cache {
        }
 }
 
-sub ensure_infobox_cached {
-       my ($r, $filename, $id, $dbwidth, $dbheight, $dpr, $xres, $yres) = @_;
-
-       my ($new_dbwidth, $new_dbheight);
-
-       my $fname = get_disk_location($r, $id);
-       my $cachename = get_infobox_cache_location($id, $xres, $yres, $dpr);
-       my $err;
-       if (! -r $cachename or (-M $cachename > -M $fname)) {
-               # If we are in overload mode (aka Slashdot mode), refuse to generate
-               # new thumbnails.
-               if (Sesse::pr0n::Overload::is_in_overload($r)) {
-                       log_warn($r, "In overload mode, not scaling $id to $xres x $yres");
-                       error($r, 'System is in overload mode, not doing any scaling');
-               }
-
-               # We need the exact width so we can make one in the right size.
-               my ($width, $height);
-
-               # This is slow, but should fortunately almost never happen, so don't bother
-               # special-casing it.
-               if (!defined($dbwidth) || !defined($dbheight)) {
-                       my $img = read_original_image($r, $filename, $id, $dbwidth, $dbheight, 0);
-                       $new_dbwidth = $width = $img->Get('columns');
-                       $new_dbheight = $height = $img->Get('rows');
-               } else {
-                       $width = $dbwidth;
-                       $height = $dbheight;
-               }
-               my $img = Image::Magick->new;
-
-               if (defined($xres) && defined($yres)) {
-                       ($width, $height) = scale_aspect($width, $height, $xres, $yres);
-               }
-               $height = 24 * $dpr;
-               $img->Set(size=>($width . "x" . $height));
-               $img->Read('xc:white');
-
-               my $info = Image::ExifTool::ImageInfo($fname);
-               if (make_infobox($img, $info, $r, $dpr)) {
-                       $img->Quantize(colors=>16, dither=>'False');
-
-                       # Since the image is grayscale, ImageMagick overrides us and writes this
-                       # as grayscale anyway, but at least we get rid of the alpha channel this
-                       # way.
-                       $img->Set(type=>'Palette');
-               } else {
-                       # Not enough room for the text, make a tiny dummy transparent infobox
-                       @$img = ();
-                       $img->Set(size=>"1x1");
-                       $img->Read('null:');
-
-                       $width = 1;
-                       $height = 1;
-               }
-
-               $err = $img->write(filename => $cachename, quality => 90, depth => 8);
-               log_info($r, "New infobox cache: $width x $height for $id.jpg");
-       }
-
-       return ($cachename, 'image/png');
-}
-
 sub get_mimetype_from_filename {
        my $filename = shift;
        my MIME::Type $type = $mimetypes->mimeTypeOf($filename);
@@ -778,8 +706,8 @@ sub get_mimetype_from_filename {
        return $type;
 }
 
-sub make_infobox {
-       my ($img, $info, $r, $dpr) = @_;
+sub make_infobox_parts {
+       my ($info) = @_;
 
        # The infobox is of the form
        # "Time - date - focal length, shutter time, aperture, sensitivity, exposure bias - flash",
@@ -894,57 +822,7 @@ sub make_infobox {
                }
        }
 
-       return 0 if (scalar @parts == 0);
-
-       # Find the required width
-       my $th = 0;
-       my $tw = 0;
-
-       for my $part (@parts) {
-               my $font;
-               if ($part->[1]) {
-                       $font = '/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf';
-               } else {
-                       $font = '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf';
-               }
-
-               my (undef, undef, $h, undef, $w) = ($img->QueryFontMetrics(text=>$part->[0], font=>$font, pointsize=>12*$dpr));
-
-               $tw += $w;
-               $th = $h if ($h > $th);
-       }
-
-       return 0 if ($tw > $img->Get('columns'));
-
-       my $x = 0;
-       my $y = $img->Get('rows') - 24*$dpr;
-
-       # Hit exact DCT blocks
-       $y -= ($y % 8);
-
-       my $points = sprintf "%u,%u %u,%u", $x, $y, ($img->Get('columns') - 1), ($img->Get('rows') - 1);
-       my $lpoints = sprintf "%u,%u %u,%u", $x, $y, ($img->Get('columns') - 1), $y;
-       $img->Draw(primitive=>'rectangle', stroke=>'white', fill=>'white', points=>$points);
-       $img->Draw(primitive=>'line', stroke=>'black', strokewidth=>$dpr, points=>$lpoints);
-
-       # Start writing out the text
-       $x = ($img->Get('columns') - $tw) / 2;
-
-       my $room = ($img->Get('rows') - $dpr - $y - $th);
-       $y = ($img->Get('rows') - $dpr) - $room/2;
-       
-       for my $part (@parts) {
-               my $font;
-               if ($part->[1]) {
-                       $font = '/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf';
-               } else {
-                       $font = '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf';
-               }
-               $img->Annotate(text=>$part->[0], font=>$font, pointsize=>12*$dpr, x=>int($x), y=>int($y));
-               $x += ($img->QueryFontMetrics(text=>$part->[0], font=>$font, pointsize=>12*$dpr))[4];
-       }
-
-       return 1;
+       return @parts;
 }
 
 sub gcd {
@@ -1048,10 +926,6 @@ sub get_all_cache_urls {
                        push @ret, "/$event/$1x$2/$filename";
                } elsif ($fname =~ /^$id-(\d+)-(\d+)-nobox\.jpg$/) {
                        push @ret, "/$event/$1x$2/nobox/$filename";
-               } elsif ($fname =~ /^$id--1--1-box\.png$/) {
-                       push @ret, "/$event/box/$filename";
-               } elsif ($fname =~ /^$id-(\d+)-(\d+)-box\.png$/) {
-                       push @ret, "/$event/$1x$2/box/$filename";
                } else {
                        log_warn($r, "Couldn't find a purging URL for $fname");
                }
index 8671b570693e8504fca4c0d83aca04bd03c90e30..f37e7ac8f986a09ce750a1258ad899e2be017770 100644 (file)
@@ -15,24 +15,20 @@ sub handler {
 
        # Find the event and file name (nobox/ is for compatibility with legacy URLs).
        my ($event,$filename,$xres,$yres,$dpr);
-       my $infobox = 0;
-       if ($r->path_info =~ m#^/([a-zA-Z0-9-]+)/original/((?:no)?box/)?([a-zA-Z0-9._()-]+)$#) {
+       if ($r->path_info =~ m#^/([a-zA-Z0-9-]+)/original/?([a-zA-Z0-9._()-]+)$#) {
                $event = $1;
-               $filename = $3;
-               $infobox = 1 if (defined($2) && $2 eq 'box/');
-       } elsif ($r->path_info =~ m#^/([a-zA-Z0-9-]+)/(\d+)x(\d+)(?:\@(\d+(?:\.\d+)?))?/((?:no)?box/)?([a-zA-Z0-9._()-]+)$#) {
+               $filename = $2;
+       } elsif ($r->path_info =~ m#^/([a-zA-Z0-9-]+)/(\d+)x(\d+)(?:\@(\d+(?:\.\d+)?))?/([a-zA-Z0-9._()-]+)$#) {
                $event = $1;
-               $filename = $6;
+               $filename = $5;
                $xres = $2;
                $yres = $3;
                $dpr = $4;
-               $infobox = 1 if (defined($5) && $5 eq 'box/');
-       } elsif ($r->path_info =~ m#^/([a-zA-Z0-9-]+)/((?:no)?box/)?([a-zA-Z0-9._()-]+)$#) {
+       } elsif ($r->path_info =~ m#^/([a-zA-Z0-9-]+)/([a-zA-Z0-9._()-]+)$#) {
                $event = $1;
-               $filename = $3;
+               $filename = $2;
                $xres = -1;
                $yres = -1;
-               $infobox = 1 if (defined($2) && $2 eq 'box/');
        }
        $dpr //= 1;
 
@@ -46,8 +42,8 @@ sub handler {
                undef, $event, Sesse::pr0n::Common::get_server_name($r), $filename);
        return error($r, "Could not find $event/$filename", 404, "File not found") unless (defined($ref));
 
-       if (defined($xres) && defined($yres) && defined($ref->{'render_id'}) && !$infobox) {
-               # We have a render, we're not asked for the original, and we do not have infobox.
+       if (defined($xres) && defined($yres) && defined($ref->{'render_id'})) {
+               # We have a render, and we're not asked for the original.
                $ref = $dbh->selectrow_hashref('SELECT id,filename,width,height FROM images WHERE id=?', 
                        undef, $ref->{'render_id'});
                return error($r, "Could not find render of $event/$filename", 404, "File not found") unless (defined($ref));
@@ -62,15 +58,11 @@ sub handler {
 
        # Scale if we need to do so
        my ($fname, $mime_type);
-       if ($infobox) {
-               ($fname, $mime_type) = Sesse::pr0n::Common::ensure_infobox_cached($r, $filename, $id, $dbwidth, $dbheight, $dpr, $xres, $yres);
-       } else {
-               my $accept = $r->header('Accept');
-               my $avif_ok = (defined($accept) && $accept =~ /(^|,)image\/avif($|,|;)/);
-               my $jxl_ok = (defined($accept) && $accept =~ /(^|,)image\/jxl($|,|;)/);
-               ($fname, $mime_type) = Sesse::pr0n::Common::ensure_cached($r, $avif_ok, $jxl_ok, $filename, $id, $dbwidth, $dbheight, $xres, $yres);
-               $res->header('Vary' => 'Accept');
-       }
+       my $accept = $r->header('Accept');
+       my $avif_ok = (defined($accept) && $accept =~ /(^|,)image\/avif($|,|;)/);
+       my $jxl_ok = (defined($accept) && $accept =~ /(^|,)image\/jxl($|,|;)/);
+       ($fname, $mime_type) = Sesse::pr0n::Common::ensure_cached($r, $avif_ok, $jxl_ok, $filename, $id, $dbwidth, $dbheight, $xres, $yres);
+       $res->header('Vary' => 'Accept');
 
        # Output the image to the user
 
index 1be7b9e63e2a1ccf436519561005f5281432c2eb..d72be98bc82799abc98e5f01d1d8a9171eb5fb81 100644 (file)
@@ -161,7 +161,51 @@ sub handler {
        # Find all images related to this event.
        my $limit = (defined($start) && defined($num) && !$settings{'fullscreen'}) ? (" LIMIT $num OFFSET " . ($start-1)) : "";
 
-       my $q = $dbh->prepare("SELECT *, (date - INTERVAL '6 hours')::date AS day FROM images WHERE vhost=? $where AND NOT is_render ORDER BY (date - INTERVAL '6 hours')::date $datesort,takenby,date,filename $limit")
+       my $extra_joins = "";
+       my $extra_fields = "";
+       if ($settings{'fullscreen'}) {
+               $extra_joins = <<"EOF";
+    LEFT JOIN exif_info exif_prog ON images.id=exif_prog.image AND exif_prog.key = 'ExposureProgram'
+    LEFT JOIN exif_info exif_focal ON images.id=exif_focal.image AND exif_focal.key = 'FocalLength'
+    LEFT JOIN exif_info exif_shutter ON images.id=exif_shutter.image AND exif_shutter.key = 'ExposureTime'
+    LEFT JOIN exif_info exif_fnum ON images.id=exif_fnum.image AND exif_fnum.key = 'FNumber'
+    LEFT JOIN exif_info exif_iso1 ON images.id=exif_iso1.image AND exif_iso1.key = 'ISO'
+    LEFT JOIN exif_info exif_iso2 ON images.id=exif_iso2.image AND exif_iso2.key = 'ISOSetting'
+    LEFT JOIN exif_info exif_ev1 ON images.id=exif_ev1.image AND exif_ev1.key = 'ExposureBiasValue'
+    LEFT JOIN exif_info exif_ev2 ON images.id=exif_ev2.image AND exif_ev2.key = 'ExposureCompensation'
+    LEFT JOIN exif_info exif_date ON images.id=exif_date.image AND exif_date.key = 'DateTimeOriginal'
+    LEFT JOIN exif_info exif_model ON images.id=exif_model.image AND exif_model.key = 'Model'
+    LEFT JOIN exif_info exif_flash ON images.id=exif_flash.image AND exif_flash.key = 'Flash'
+EOF
+               $extra_fields = <<"EOF";
+    exif_prog.value AS "ExposureProgram",
+    exif_focal.value AS "FocalLength",
+    exif_shutter.value AS "ExposureTime",
+    exif_fnum.value AS "FNumber",
+    exif_iso1.value AS "ISO",
+    exif_iso2.value AS "ISOSetting",
+    exif_ev1.value AS "ExposureBiasValue",
+    exif_ev2.value AS "ExposureCompensation",
+    exif_date.value AS "DateTimeOriginal",
+    exif_model.value AS "Model",
+    exif_flash.value AS "Flash",
+EOF
+       }
+
+       my $q = $dbh->prepare(<<"EOF")
+SELECT *,
+  $extra_fields
+  (date - INTERVAL '6 hours')::date AS day
+FROM
+  images
+  $extra_joins
+WHERE
+  vhost=?
+  $where
+  AND NOT is_render
+ORDER BY (date - INTERVAL '6 hours')::date $datesort,takenby,date,filename
+$limit
+EOF
                or return dberror($r, "prepare()");
        $q->execute(Sesse::pr0n::Common::get_server_name($r))
                or return dberror($r, "image enumeration");
@@ -178,11 +222,13 @@ sub handler {
                while (my $ref = $q->fetchrow_hashref()) {
                        my $width = defined($ref->{'width'}) ? $ref->{'width'} : -1;
                        my $height = defined($ref->{'height'}) ? $ref->{'height'} : -1;
-                       push @files, [ $ref->{'event'}, $ref->{'filename'}, $width, $height ];
+                       my @parts = Sesse::pr0n::Common::make_infobox_parts($ref);
+                       @parts = map { $_->[1] ? "<strong>" . HTML::Entities::encode_entities($_->[0]) . "</strong>" : HTML::Entities::encode_entities($_->[0]) } @parts;
+                       push @files, [ $ref->{'event'}, $ref->{'filename'}, $width, $height, join('', @parts) ];
                }
                
                for my $i (0..$#files) {
-                       my $line = sprintf "        [ \"%s\", \"%s\", %d, %d ]", @{$files[$i]};
+                       my $line = sprintf "        [ \"%s\", \"%s\", %d, %d, \"%s\" ]", @{$files[$i]};
                        $line .= "," unless ($i == $#files);
                        $io->print($line . "\n");
                }
index 3c9161b94b1da8b117db489c8b4b6c6c89ae7736..2517b849b7e0439df869c56c9c36e4a7605ad132 100644 (file)
@@ -71,7 +71,6 @@ sub handler {
                return Sesse::pr0n::Index::handler($r);
        } elsif ($uri =~ m#^/[a-zA-Z0-9-]+/
                           (\d+x\d+ ( \@\d+(\.\d+)? )? / | original/ )?
-                           ((?:no)?box/)?
                            [a-zA-Z0-9._()-]+$#x) {
                return Sesse::pr0n::Image::handler($r);
        }
index 0ed6931bfe63ca4a2fcf648fa3e03202d765360b..f50d3a0b046b5539d820bbe8365a52dbc398845e 100755 (executable)
@@ -103,7 +103,6 @@ while (my $ref = $q->fetchrow_hashref) {
        if (!$regen_mipmaps) {
                @files = grep { !/mipmap/ } @files;
        }
-       my @boxres = ();
        my @noboxres = ();
        my $any_old = 0;
        for my $c (@files) {
@@ -113,8 +112,6 @@ while (my $ref = $q->fetchrow_hashref) {
                }
                if ($c =~ /$id-(\d+)-(\d+)-nobox\.jpg/ || $c =~ /$id-(-1)-(-1)-nobox\.jpg/) {
                        push @noboxres, [$1, $2];
-               } elsif ($c =~ /$id-(\d+)-(\d+)-box\.png/ || $c =~ /$id-(-1)-(-1)-box\.png/) {
-                       push @boxres, [$1, $2];
                }
        }
        next unless $any_old;
@@ -122,9 +119,6 @@ while (my $ref = $q->fetchrow_hashref) {
        if (scalar @noboxres > 0) {
                Sesse::pr0n::Common::ensure_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, sort_res(@noboxres));
        }
-       if (scalar @boxres > 0) {
-               Sesse::pr0n::Common::ensure_infobox_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, 1, sort_res(@boxres));
-       }
        
        my @newfiles = glob("../cache/$dir/$id-*.jpg");
        my %a = map { $_ => 1 } @files;
index 371e05cf4fdfef765c35318276fef867dad6ac57..d3541ed27656b7d420995cae56c14b16d1cb1561 100644 (file)
@@ -71,7 +71,8 @@ CREATE TABLE users (
 );
 
 -- Mainly used for manual queries -- usually too slow to be very useful
--- for web views in the long run.
+-- for web views in the long run (except for the special case of the
+-- partial index below).
 CREATE TABLE exif_info (
     image integer NOT NULL REFERENCES images (id) ON DELETE CASCADE,
     key varchar NOT NULL,
@@ -81,6 +82,9 @@ CREATE TABLE exif_info (
 );
 
 CLUSTER exif_info_pkey ON exif_info;
+CREATE UNIQUE INDEX exif_info_fast_listing ON exif_info (image, key) INCLUDE (value)
+  WHERE key IN ('ExposureProgram', 'FocalLength', 'ExposureTime', 'FNumber', 'ISO', 'ISOSetting',
+                'ExposureBiasValue', 'ExposureCompensation', 'DateTimeOriginal', 'Model', 'Flash');
 
 GRANT INSERT ON TABLE deleted_images TO pr0n;
 GRANT INSERT,SELECT,UPDATE,DELETE ON TABLE events TO pr0n;