+# Depending on your front-end cache, you might want to get creative somehow here.
+# This example assumes you have a front-end cache and it can translate an X-Pr0n-Purge
+# regex tacked onto a request into something useful. The elements given in
+# should not be regexes, though, as e.g. Squid will not be able to handle that.
+sub purge_cache {
+ my ($r, $res, @elements) = @_;
+ return if (scalar @elements == 0);
+
+ my @pe = ();
+ for my $elem (@elements) {
+ log_info($r, "Purging $elem");
+ (my $e = $elem) =~ s/[.+*|()]/\\$&/g;
+ push @pe, $e;
+ }
+
+ my $regex = "^";
+ if (scalar @pe == 1) {
+ $regex .= $pe[0];
+ } else {
+ $regex .= "(" . join('|', @pe) . ")";
+ }
+ $regex .= "(\\?.*)?\$";
+ $res->header('X-Pr0n-Purge' => $regex);
+}
+
+# Find a list of all cache URLs for a given image, given what we have on disk.
+sub get_all_cache_urls {
+ my ($r, $dbh, $id) = @_;
+ my $dir = POSIX::floor($id / 256);
+ my @ret = ();
+
+ my $q = $dbh->prepare('SELECT event, filename FROM images WHERE id=?')
+ or die "Couldn't prepare: " . $dbh->errstr;
+ $q->execute($id)
+ or die "Couldn't find event and filename: " . $dbh->errstr;
+ my $ref = $q->fetchrow_hashref;
+ my $event = $ref->{'event'};
+ my $filename = $ref->{'filename'};
+ $q->finish;
+
+ my $base = $Sesse::pr0n::Config::image_base . "cache/$dir";
+ for my $file (<$base/$id-*>) {
+ my $fname = File::Basename::basename($file);
+ if ($fname =~ /^$id-mipmap-.*\.jpg$/) {
+ # Mipmaps don't have an URL, ignore
+ } elsif ($fname =~ /^$id--1--1\.jpg$/) {
+ push @ret, "/$event/$filename";
+ } elsif ($fname =~ /^$id-(\d+)-(\d+)\.jpg$/) {
+ 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");
+ }
+ }
+
+ return @ret;
+}
+
+sub set_last_modified {
+ my ($res, $mtime) = @_;
+
+ my $str = POSIX::strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime($mtime));
+ $res->header('Last-Modified' => $str);
+}
+
+sub get_server_name {
+ my $r = shift;
+ my $host = $r->env->{'HTTP_HOST'};
+ $host =~ s/:.*//;
+ return $host;
+}
+
+sub log_info {
+ my ($r, $msg) = @_;
+ if (defined($r->logger)) {
+ $r->logger->({ level => 'info', message => $msg });
+ } else {
+ print STDERR "[INFO] $msg\n";
+ }
+}
+
+sub log_warn {
+ my ($r, $msg) = @_;
+ if (defined($r->logger)) {
+ $r->logger->({ level => 'warn', message => $msg });
+ } else {
+ print STDERR "[WARN] $msg\n";
+ }
+}
+
+sub log_error {
+ my ($r, $msg) = @_;
+ if (defined($r->logger)) {
+ $r->logger->({ level => 'error', message => $msg });
+ } else {
+ print STDERR "[ERROR] $msg\n";
+ }
+}
+