summaryrefslogtreecommitdiff
path: root/app/Http/RequestHandlers/ImportThumbnailsData.php
diff options
context:
space:
mode:
authorGreg Roach <greg@subaqua.co.uk>2024-04-09 10:13:22 +0100
committerGreg Roach <greg@subaqua.co.uk>2024-04-09 10:13:22 +0100
commit7d87487f074b1444941aa12f5f9e7376e64ac81a (patch)
tree711947a770c5c0f5007ec24198ae04c8903121c9 /app/Http/RequestHandlers/ImportThumbnailsData.php
parent97898e6694b2624617fa6a29dafeaa5a03c3fb8c (diff)
downloadwebtrees-7d87487f074b1444941aa12f5f9e7376e64ac81a.tar.gz
webtrees-7d87487f074b1444941aa12f5f9e7376e64ac81a.tar.bz2
webtrees-7d87487f074b1444941aa12f5f9e7376e64ac81a.zip
Drop the webtrees 1.x custom-thumbnail importer
Diffstat (limited to 'app/Http/RequestHandlers/ImportThumbnailsData.php')
-rw-r--r--app/Http/RequestHandlers/ImportThumbnailsData.php259
1 files changed, 0 insertions, 259 deletions
diff --git a/app/Http/RequestHandlers/ImportThumbnailsData.php b/app/Http/RequestHandlers/ImportThumbnailsData.php
deleted file mode 100644
index f0925cfaf3..0000000000
--- a/app/Http/RequestHandlers/ImportThumbnailsData.php
+++ /dev/null
@@ -1,259 +0,0 @@
-<?php
-
-/**
- * webtrees: online genealogy
- * Copyright (C) 2023 webtrees development team
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-declare(strict_types=1);
-
-namespace Fisharebest\Webtrees\Http\RequestHandlers;
-
-use Fisharebest\Webtrees\I18N;
-use Fisharebest\Webtrees\Media;
-use Fisharebest\Webtrees\Mime;
-use Fisharebest\Webtrees\Registry;
-use Fisharebest\Webtrees\Services\SearchService;
-use Fisharebest\Webtrees\Validator;
-use Illuminate\Support\Collection;
-use Intervention\Image\ImageManager;
-use League\Flysystem\FilesystemException;
-use League\Flysystem\FilesystemOperator;
-use League\Flysystem\FilesystemReader;
-use League\Flysystem\StorageAttributes;
-use League\Flysystem\UnableToRetrieveMetadata;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Server\RequestHandlerInterface;
-
-use function abs;
-use function array_map;
-use function e;
-use function explode;
-use function glob;
-use function implode;
-use function intdiv;
-use function is_file;
-use function max;
-use function response;
-use function route;
-use function str_contains;
-use function str_replace;
-use function stripos;
-use function substr;
-use function substr_compare;
-use function view;
-
-use const GLOB_NOSORT;
-
-/**
- * Import custom thumbnails from webtrees 1.x.
- */
-class ImportThumbnailsData implements RequestHandlerInterface
-{
- private const FINGERPRINT_PIXELS = 10;
-
- private SearchService $search_service;
-
- /**
- * @param SearchService $search_service
- */
- public function __construct(SearchService $search_service)
- {
- $this->search_service = $search_service;
- }
-
- /**
- * Import custom thumbnails from webtrees 1.x.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function handle(ServerRequestInterface $request): ResponseInterface
- {
- $data_filesystem = Registry::filesystem()->data();
-
- $start = Validator::queryParams($request)->integer('start');
- $length = Validator::queryParams($request)->integer('length');
- $draw = Validator::queryParams($request)->integer('draw');
- $search = Validator::queryParams($request)->array('search')['value'];
-
- // Fetch all thumbnails
- try {
- $thumbnails = Collection::make($data_filesystem->listContents('', FilesystemReader::LIST_DEEP))
- ->filter(static fn (StorageAttributes $attributes): bool => $attributes->isFile() && str_contains($attributes->path(), '/thumbs/'))
- ->map(static fn (StorageAttributes $attributes): string => $attributes->path());
- } catch (FilesystemException) {
- $thumbnails = new Collection();
- }
-
- $recordsTotal = $thumbnails->count();
-
- if ($search !== '') {
- $thumbnails = $thumbnails->filter(static fn (string $thumbnail): bool => stripos($thumbnail, $search) !== false);
- }
-
- $recordsFiltered = $thumbnails->count();
-
- $data = $thumbnails
- ->slice($start, $length)
- ->map(function (string $thumbnail) use ($data_filesystem): array {
- // Turn each filename into a row for the table
- $original = $this->findOriginalFileFromThumbnail($thumbnail);
-
- $original_url = route(AdminMediaFileThumbnail::class, ['path' => $original]);
- $thumbnail_url = route(AdminMediaFileThumbnail::class, ['path' => $thumbnail]);
-
- $difference = $this->imageDiff($data_filesystem, $thumbnail, $original);
-
- $media = $this->search_service->findMediaObjectsForMediaFile($original);
-
- $media_links = array_map(static fn (Media $media): string => '<a href="' . e($media->url()) . '">' . $media->fullName() . '</a>', $media);
-
- $media_links = implode('<br>', $media_links);
-
- $action = view('admin/webtrees1-thumbnails-form', [
- 'difference' => $difference,
- 'media' => $media,
- 'thumbnail' => $thumbnail,
- ]);
-
- return [
- '<img src="' . e($thumbnail_url) . '" title="' . e($thumbnail) . '">',
- '<img src="' . e($original_url) . '" title="' . e($original) . '">',
- $media_links,
- I18N::percentage($difference / 100.0),
- $action,
- ];
- });
-
- return response([
- 'draw' => $draw,
- 'recordsTotal' => $recordsTotal,
- 'recordsFiltered' => $recordsFiltered,
- 'data' => $data->values()->all(),
- ]);
- }
-
- /**
- * Find the original image that corresponds to a (webtrees 1.x) thumbnail file.
- *
- * @param string $thumbnail
- *
- * @return string
- */
- private function findOriginalFileFromThumbnail(string $thumbnail): string
- {
- // First option - a file with the same name
- $original = str_replace('/thumbs/', '/', $thumbnail);
-
- // Second option - a .PNG thumbnail for some other image type
- if (substr_compare($original, '.png', -4, 4) === 0) {
- $pattern = substr($original, 0, -3) . '*';
- $matches = glob($pattern, GLOB_NOSORT);
- if ($matches !== [] && is_file($matches[0])) {
- $original = $matches[0];
- }
- }
-
- return $original;
- }
-
- /**
- * Compare two images, and return a quantified difference.
- * 0 (different) ... 100 (same)
- *
- * @param FilesystemOperator $data_filesystem
- * @param string $thumbnail
- * @param string $original
- *
- * @return int
- */
- private function imageDiff(FilesystemOperator $data_filesystem, string $thumbnail, string $original): int
- {
- // The original filename was generated from the thumbnail filename.
- // It may not actually exist.
- try {
- $file_exists = $data_filesystem->fileExists($original);
- } catch (FilesystemException | UnableToRetrieveMetadata) {
- $file_exists = false;
- }
-
- if (!$file_exists) {
- return 100;
- }
-
- try {
- $thumbnail_type = $data_filesystem->mimeType($thumbnail) ?: Mime::DEFAULT_TYPE;
- } catch (FilesystemException | UnableToRetrieveMetadata) {
- $thumbnail_type = Mime::DEFAULT_TYPE;
- }
-
- try {
- $original_type = $data_filesystem->mimeType($original) ?: Mime::DEFAULT_TYPE;
- } catch (FilesystemException | UnableToRetrieveMetadata) {
- $original_type = Mime::DEFAULT_TYPE;
- }
-
- if (explode('/', $thumbnail_type)[0] !== 'image' || explode('/', $original_type)[0] !== 'image') {
- // If either file is not an image then similarity is unimportant .
- // Response with an exact mismatch, so the GUI will recommend importing it.
- return 0;
- }
-
- $pixels1 = $this->scaledImagePixels($data_filesystem, $thumbnail);
- $pixels2 = $this->scaledImagePixels($data_filesystem, $original);
-
- $max_difference = 0;
-
- foreach ($pixels1 as $x => $row) {
- foreach ($row as $y => $pixel) {
- $max_difference = max($max_difference, abs($pixel - $pixels2[$x][$y]));
- }
- }
-
- // The maximum difference is 255 (black versus white).
- return 100 - intdiv($max_difference * 100, 255);
- }
-
- /**
- * Scale an image to 10x10 and read the individual pixels.
- * This is a slow operation, add we will do it many times on
- * the "import webtrees 1 thumbnails" page so cache the results.
- *
- * @param FilesystemOperator $filesystem
- * @param string $path
- *
- * @return array<array<int>>
- */
- private function scaledImagePixels(FilesystemOperator $filesystem, string $path): array
- {
- return Registry::cache()->file()->remember('pixels-' . $path, static function () use ($filesystem, $path): array {
- $blob = $filesystem->read($path);
- $manager = new ImageManager();
- $image = $manager->make($blob)->resize(self::FINGERPRINT_PIXELS, self::FINGERPRINT_PIXELS);
-
- $pixels = [];
- for ($x = 0; $x < self::FINGERPRINT_PIXELS; ++$x) {
- $pixels[$x] = [];
- for ($y = 0; $y < self::FINGERPRINT_PIXELS; ++$y) {
- $pixel = $image->pickColor($x, $y);
- $pixels[$x][$y] = (int) (($pixel[0] + $pixel[1] + $pixel[2]) / 3);
- }
- }
-
- return $pixels;
- });
- }
-}