From 16c7c92ce21e430974a706fa3fcce430ddfc7dc4 Mon Sep 17 00:00:00 2001
From: tmp-hallenser <1869257+tmp-hallenser@users.noreply.github.com>
Date: Tue, 26 May 2020 11:40:53 +0200
Subject: [PATCH] Fix support of raw files (#574)
* Create medium, small and thumb also for raw files
* Use imagemagic to extract metadata in case of raw files and exiftool not available
* Update composer.lock
* fix livePhotoUrl path (#590)
* Make raw file extensions case insensitive
* Added try-catch for scaling
* Added try-catch for path of xmp file
* Added attempt to create video preview at t=0
In case video thumbnail extaction at middle of video fails, we try a second thumbnail at the beginning of the video
---
app/Http/Controllers/ImportController.php | 6 +-
app/Metadata/Extractor.php | 26 +-
app/ModelFunctions/PhotoFunctions.php | 116 +++-
app/Photo.php | 15 +-
composer.lock | 632 +---------------------
public/dist/main.js | 6 +-
setup_exiftool.sh | 8 +-
7 files changed, 163 insertions(+), 646 deletions(-)
diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php
index a4a2ff3834..0a781521cb 100644
--- a/app/Http/Controllers/ImportController.php
+++ b/app/Http/Controllers/ImportController.php
@@ -362,7 +362,9 @@ public function server_exec(string $path, $albumID, $delete_imported, $force_ski
continue;
}
$extension = Helpers::getExtension($file, true);
- if (@exif_imagetype($file) !== false || in_array(strtolower($extension), $this->photoFunctions->validExtensions, true)) {
+ $raw_formats = strtolower(Configs::get_value('raw_formats', ''));
+ $is_raw = in_array(strtolower($extension), explode('|', $raw_formats), true);
+ if (@exif_imagetype($file) !== false || in_array(strtolower($extension), $this->photoFunctions->validExtensions, true) || $is_raw) {
// Photo or Video
if ($this->photo($file, $delete_imported, $albumID, $force_skip_duplicates) === false) {
$this->status_update('Problem: ' . $file . ': Could not import file');
@@ -370,7 +372,7 @@ public function server_exec(string $path, $albumID, $delete_imported, $force_ski
continue;
}
} else {
- $this->status_update('Problem: ' . $file . ': Unsupported file type');
+ $this->status_update('Problem: Unsupported file type (' . $file . ')');
Logs::error(__METHOD__, __LINE__, 'Unsupported file type (' . $file . ')');
continue;
}
diff --git a/app/Metadata/Extractor.php b/app/Metadata/Extractor.php
index 3054e013a9..0535dc0f22 100644
--- a/app/Metadata/Extractor.php
+++ b/app/Metadata/Extractor.php
@@ -4,6 +4,7 @@
use App\Configs;
use App\Logs;
+use App\ModelFunctions\Helpers;
use PHPExif\Reader\Reader;
class Extractor
@@ -71,11 +72,24 @@ public function extract(string $filename, string $type): array
{
$reader = null;
+ // Get kind of file (photo, video, raw)
+ $extension = Helpers::getExtension($filename, false);
+
+ // check raw files
+ $is_raw = false;
+ $raw_formats = strtolower(Configs::get_value('raw_formats', ''));
+ if (in_array(strtolower($extension), explode('|', $raw_formats), true)) {
+ $is_raw = true;
+ }
+
if (strpos($type, 'video') !== 0) {
// It's a photo
if (Configs::hasExiftool()) {
// reader with Exiftool adapter
$reader = Reader::factory(Reader::TYPE_EXIFTOOL);
+ } elseif (Configs::hasImagick() && $is_raw) {
+ // Use imagick as exif reader for raw files (broader support)
+ $reader = Reader::factory(Reader::TYPE_IMAGICK);
} else {
// Use Php native tools
$reader = Reader::factory(Reader::TYPE_NATIVE);
@@ -109,7 +123,17 @@ public function extract(string $filename, string $type): array
// Attempt to get sidecar metadata if it exists, make sure to check 'real' path in case of symlinks
$sidecarData = [];
- $realFile = is_link($filename) && readlink($filename) ? readlink($filename) : $filename;
+ // readlink fails if it's not a link -> we need to separate it
+ $realFile = $filename;
+ if (is_link($filename)) {
+ try {
+ // if readlink($filename) == False then $realFile = $filename.
+ // if readlink($filename) != False then $realFile = readlink($filename)
+ $realFile = readlink($filename) ?: $filename;
+ } catch (\Exception $e) {
+ Logs::error(__METHOD__, __LINE__, $e->getMessage());
+ }
+ }
if (Configs::hasExiftool() && file_exists($realFile . '.xmp')) {
try {
// Don't use the same reader as the file in case it's a video
diff --git a/app/ModelFunctions/PhotoFunctions.php b/app/ModelFunctions/PhotoFunctions.php
index bdea116f4a..4039c3b5cf 100644
--- a/app/ModelFunctions/PhotoFunctions.php
+++ b/app/ModelFunctions/PhotoFunctions.php
@@ -100,10 +100,11 @@ public function __construct(Extractor $metadataExtractor, ImageHandlerInterface
*
* @return string
*/
- private function file_type($file, string $extension)
+ public function file_type($file, string $extension)
{
// check raw files
- if (in_array(strtolower($extension), explode('|', Configs::get_value('raw_formats', '')), true)) {
+ $raw_formats = strtolower(Configs::get_value('raw_formats', ''));
+ if (in_array(strtolower($extension), explode('|', $raw_formats), true)) {
return 'raw';
}
@@ -286,20 +287,18 @@ public function add(array $file, $albumID_in = 0, $delete_imported = false, $for
}
}
+ $info = $this->metadataExtractor->extract($path, $mimeType);
if ($kind == 'raw') {
- $info = $this->metadataExtractor->bare();
- $this->metadataExtractor->size($info, $path);
- $this->metadataExtractor->validate($info);
$info['type'] = 'raw';
- } else {
- $info = $this->metadataExtractor->extract($path, $mimeType);
}
// Use title of file if IPTC title missing
- if ($kind == 'raw') {
- $info['title'] = substr(basename($file['name']), 0, 98);
- } elseif ($info['title'] === '') {
- $info['title'] = substr(basename($file['name'], $extension), 0, 98);
+ if ($info['title'] === '') {
+ if ($kind == 'raw') {
+ $info['title'] = substr(basename($file['name']), 0, 98);
+ } else {
+ $info['title'] = substr(basename($file['name'], $extension), 0, 98);
+ }
}
$photo->title = $info['title'];
@@ -400,8 +399,16 @@ public function add(array $file, $albumID_in = 0, $delete_imported = false, $for
}
}
- // Create Thumb
if ($kind == 'raw') {
+ try {
+ $frame_tmp = $this->createJpgFromRaw($photo);
+ } catch (Exception $exception) {
+ Logs::error(__METHOD__, __LINE__, $exception->getMessage());
+ }
+ }
+
+ // Create Thumb
+ if ($kind == 'raw' && $frame_tmp == '') {
$photo->thumbUrl = '';
$photo->thumb2x = 0;
} elseif (!in_array($photo->type, $this->validVideoTypes, true) || $frame_tmp !== '') {
@@ -450,13 +457,14 @@ public function add(array $file, $albumID_in = 0, $delete_imported = false, $for
*/
public function createSmallerImages(Photo $photo, string $frame_tmp = '')
{
- if ($frame_tmp === '') {
+ if ($frame_tmp === '' || $photo->type == 'raw') {
+ // Create medium file for normal photos and for raws
$mediumMaxWidth = intval(Configs::get_value('medium_max_width'));
$mediumMaxHeight = intval(Configs::get_value('medium_max_height'));
- $this->resizePhoto($photo, 'medium', $mediumMaxWidth, $mediumMaxHeight);
+ $this->resizePhoto($photo, 'medium', $mediumMaxWidth, $mediumMaxHeight, $frame_tmp);
if (Configs::get_value('medium_2x') === '1') {
- $this->resizePhoto($photo, 'medium2x', $mediumMaxWidth * 2, $mediumMaxHeight * 2);
+ $this->resizePhoto($photo, 'medium2x', $mediumMaxWidth * 2, $mediumMaxHeight * 2, $frame_tmp);
}
}
@@ -469,6 +477,51 @@ public function createSmallerImages(Photo $photo, string $frame_tmp = '')
}
}
+ /**
+ * @param Photo $photo
+ *
+ * @return string Path of the jpg file
+ */
+ public function createJpgFromRaw(Photo $photo): string
+ {
+ // we need imagick to do the job
+ if (!Configs::hasImagick()) {
+ Logs::notice(__METHOD__, __LINE__, 'Saving JPG of raw file to failed: Imagick not installed.');
+
+ return '';
+ }
+
+ $filename = $photo->url;
+ $url = Storage::path('raw/' . $filename);
+ $ext = pathinfo($filename)['extension'];
+
+ // test if Imagaick supports the filetype
+ // Query return file extensions as all upper case
+ if (!in_array(strtoupper($ext), \Imagick::queryformats())) {
+ Logs::notice(__METHOD__, __LINE__, 'Filetype ' . $ext . ' not supported by Imagick.');
+
+ return '';
+ }
+
+ $tmp_file = tempnam(sys_get_temp_dir(), 'lychee') . '.jpeg';
+ Logs::notice(__METHOD__, __LINE__, 'Saving JPG of raw file to ' . $tmp_file);
+
+ $resWidth = $resHeight = 0;
+ $resWidth = $resHeight = 0;
+ $width = $photo->width;
+ $height = $photo->height;
+
+ try {
+ $this->imageHandler->scale($url, $tmp_file, $width, $height, $resWidth, $resHeight);
+ } catch (\Exception $e) {
+ Logs::error(__METHOD__, __LINE__, 'Failed to create JPG from raw file ' . $url . $filename);
+
+ return '';
+ }
+
+ return $tmp_file;
+ }
+
/**
* @param Photo $photo
*
@@ -482,11 +535,36 @@ public function extractVideoFrame(Photo $photo): string
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open(Storage::path('big/' . $photo->url));
- $frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($photo->aperture / 2));
-
- $tmp = tempnam(sys_get_temp_dir(), 'lychee');
+ $tmp = tempnam(sys_get_temp_dir(), 'lychee') . '.jpeg';
Logs::notice(__METHOD__, __LINE__, 'Saving frame to ' . $tmp);
- $frame->save($tmp);
+
+ try {
+ $frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($photo->aperture / 2));
+ $frame->save($tmp);
+ } catch (\Exception $e) {
+ Logs::notice(__METHOD__, __LINE__, 'Failed to extract snapshot from video ' . $tmp);
+ }
+
+ // check if the image has data
+ $success = file_exists($tmp) ? (filesize($tmp) > 0) : false;
+
+ if (!$success) {
+ Logs::notice(__METHOD__, __LINE__, 'Failed to extract snapshot from video ' . $tmp);
+ try {
+ $frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(0));
+ $frame->save($tmp);
+ $success = file_exists($tmp) ? (filesize($tmp) > 0) : false;
+ if (!$success) {
+ Logs::notice(__METHOD__, __LINE__, 'Fallback failed to extract snapshot from video ' . $tmp);
+ } else {
+ Logs::notice(__METHOD__, __LINE__, 'Fallback successful - snapshot from video ' . $tmp . ' at t=0 created.');
+ }
+ } catch (\Exception $e) {
+ Logs::notice(__METHOD__, __LINE__, 'Fallback failed to extract snapshot from video ' . $tmp);
+
+ return '';
+ }
+ }
return $tmp;
}
diff --git a/app/Photo.php b/app/Photo.php
index 5bdd2754ce..5ec9876fab 100644
--- a/app/Photo.php
+++ b/app/Photo.php
@@ -278,6 +278,9 @@ public function prepareData()
// We need to format the framerate (stored as focal) -> max 2 decimal digits
$photo['focal'] = round($photo['focal'], 2);
+ } elseif ($this->type == 'raw') {
+ // It's a raw file -> we also use jpeg as extension
+ $photoUrl = $this->thumbUrl;
} else {
$photoUrl = $this->url;
}
@@ -335,7 +338,7 @@ public function prepareData()
$photo['url'] = Storage::url($path_prefix . $this->url);
if ($this->livePhotoUrl !== '' && $this->livePhotoUrl !== null) {
- $photo['livePhotoUrl'] = Storage::url($path_prefix . $this->livePhotoUrl);
+ $photo['livePhotoUrl'] = Storage::url('big/' . $this->livePhotoUrl);
} else {
$photo['livePhotoUrl'] = null;
}
@@ -488,7 +491,7 @@ public function predelete(bool $keep_original = false)
}
}
- if (strpos($this->type, 'video') === 0) {
+ if ((strpos($this->type, 'video') === 0) || ($this->type == 'raw')) {
$photoName = $this->thumbUrl;
} else {
$photoName = $this->url;
@@ -501,11 +504,11 @@ public function predelete(bool $keep_original = false)
// TODO: USE STORAGE FOR DELETE
// check first if livePhotoUrl is available
if ($this->livePhotoUrl !== null) {
- if (!Storage::exists($path_prefix . $this->livePhotoUrl)) {
- Logs::error(__METHOD__, __LINE__, 'Could not find file in ' . Storage::path($path_prefix . $this->livePhotoUrl));
+ if (!Storage::exists('big/' . $this->livePhotoUrl)) {
+ Logs::error(__METHOD__, __LINE__, 'Could not find file in ' . Storage::path('big/' . $this->livePhotoUrl));
$error = true;
- } elseif (!Storage::delete($path_prefix . $this->livePhotoUrl)) {
- Logs::error(__METHOD__, __LINE__, 'Could not delete file in ' . Storage::path($path_prefix . $this->livePhotoUrl));
+ } elseif (!Storage::delete('big/' . $this->livePhotoUrl)) {
+ Logs::error(__METHOD__, __LINE__, 'Could not delete file in ' . Storage::path('big/' . $this->livePhotoUrl));
$error = true;
}
}
diff --git a/composer.lock b/composer.lock
index f9bdce1faa..971552c362 100644
--- a/composer.lock
+++ b/composer.lock
@@ -178,12 +178,6 @@
"brick",
"math"
],
- "funding": [
- {
- "url": "https://tidelift.com/funding/github/packagist/brick/math",
- "type": "tidelift"
- }
- ],
"time": "2020-04-15T15:59:35+00:00"
},
{
@@ -412,20 +406,6 @@
"sqlserver",
"sqlsrv"
],
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal",
- "type": "tidelift"
- }
- ],
"time": "2020-04-20T17:19:26+00:00"
},
{
@@ -579,20 +559,6 @@
"uppercase",
"words"
],
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector",
- "type": "tidelift"
- }
- ],
"time": "2020-05-11T11:25:59+00:00"
},
{
@@ -1102,20 +1068,6 @@
"laravel",
"markdown"
],
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://www.patreon.com/GrahamJCampbell",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/graham-campbell/markdown",
- "type": "tidelift"
- }
- ],
"time": "2020-04-14T14:11:12+00:00"
},
{
@@ -1532,32 +1484,6 @@
"md",
"parser"
],
- "funding": [
- {
- "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark",
- "type": "custom"
- },
- {
- "url": "https://www.colinodell.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://www.paypal.me/colinpodell/10.00",
- "type": "custom"
- },
- {
- "url": "https://github.com/colinodell",
- "type": "github"
- },
- {
- "url": "https://www.patreon.com/colinodell",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/league/commonmark",
- "type": "tidelift"
- }
- ],
"time": "2020-05-04T22:15:21+00:00"
},
{
@@ -1642,12 +1568,6 @@
"sftp",
"storage"
],
- "funding": [
- {
- "url": "https://offset.earth/frankdejonge",
- "type": "other"
- }
- ],
"time": "2020-05-18T15:13:39+00:00"
},
{
@@ -1656,12 +1576,12 @@
"source": {
"type": "git",
"url": "https://github.com/LycheeOrg/php-exif.git",
- "reference": "c44e85aed20384a249238f3736ca04792d146d90"
+ "reference": "da0831af9dd6843307e1a7b81bf5c0d07542e706"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/LycheeOrg/php-exif/zipball/c44e85aed20384a249238f3736ca04792d146d90",
- "reference": "c44e85aed20384a249238f3736ca04792d146d90",
+ "url": "https://api.github.com/repos/LycheeOrg/php-exif/zipball/da0831af9dd6843307e1a7b81bf5c0d07542e706",
+ "reference": "da0831af9dd6843307e1a7b81bf5c0d07542e706",
"shasum": ""
},
"require": {
@@ -1709,7 +1629,7 @@
"jpeg",
"tiff"
],
- "time": "2020-05-21T20:22:40+00:00"
+ "time": "2020-05-24T20:32:49+00:00"
},
{
"name": "maennchen/zipstream-php",
@@ -1851,16 +1771,6 @@
"logging",
"psr-3"
],
- "funding": [
- {
- "url": "https://github.com/Seldaek",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
- "type": "tidelift"
- }
- ],
"time": "2020-05-22T08:12:19+00:00"
},
{
@@ -2017,16 +1927,6 @@
"datetime",
"time"
],
- "funding": [
- {
- "url": "https://opencollective.com/Carbon",
- "type": "open_collective"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
- "type": "tidelift"
- }
- ],
"time": "2020-05-19T22:14:16+00:00"
},
{
@@ -2071,16 +1971,16 @@
},
{
"name": "opis/closure",
- "version": "3.5.2",
+ "version": "3.5.3",
"source": {
"type": "git",
"url": "https://github.com/opis/closure.git",
- "reference": "2e3299cea6f485ca64d19c540f46d7896c512ace"
+ "reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/opis/closure/zipball/2e3299cea6f485ca64d19c540f46d7896c512ace",
- "reference": "2e3299cea6f485ca64d19c540f46d7896c512ace",
+ "url": "https://api.github.com/repos/opis/closure/zipball/cac47092144043d5d676e2e7cf8d0d2f83fc89ca",
+ "reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca",
"shasum": ""
},
"require": {
@@ -2128,7 +2028,7 @@
"serialization",
"serialize"
],
- "time": "2020-05-21T20:09:36+00:00"
+ "time": "2020-05-25T09:32:45+00:00"
},
{
"name": "php-ffmpeg/php-ffmpeg",
@@ -3141,12 +3041,6 @@
"identifier",
"uuid"
],
- "funding": [
- {
- "url": "https://github.com/ramsey",
- "type": "github"
- }
- ],
"time": "2020-03-29T20:13:32+00:00"
},
{
@@ -3266,12 +3160,6 @@
"rss",
"spatie"
],
- "funding": [
- {
- "url": "https://spatie.be/open-source/support-us",
- "type": "custom"
- }
- ],
"time": "2020-04-23T07:40:56+00:00"
},
{
@@ -3413,20 +3301,6 @@
"caching",
"psr6"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-28T17:58:55+00:00"
},
{
@@ -3561,20 +3435,6 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-03-30T11:42:42+00:00"
},
{
@@ -3628,20 +3488,6 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-03-27T16:56:45+00:00"
},
{
@@ -3697,20 +3543,6 @@
],
"description": "Symfony ErrorHandler Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-03-30T14:14:32+00:00"
},
{
@@ -3781,20 +3613,6 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-03-27T16:56:45+00:00"
},
{
@@ -3903,20 +3721,6 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-12T14:40:17+00:00"
},
{
@@ -3966,20 +3770,6 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-03-27T16:56:45+00:00"
},
{
@@ -4035,20 +3825,6 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-18T20:50:06+00:00"
},
{
@@ -4146,20 +3922,6 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-28T18:53:25+00:00"
},
{
@@ -4222,20 +3984,6 @@
"mime",
"mime-type"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-17T03:29:44+00:00"
},
{
@@ -4294,20 +4042,6 @@
"polyfill",
"portable"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:14:59+00:00"
},
{
@@ -4367,20 +4101,6 @@
"portable",
"shim"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:47:27+00:00"
},
{
@@ -4443,20 +4163,6 @@
"portable",
"shim"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:47:27+00:00"
},
{
@@ -4516,20 +4222,6 @@
"portable",
"shim"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:47:27+00:00"
},
{
@@ -4585,20 +4277,6 @@
"portable",
"shim"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:47:27+00:00"
},
{
@@ -4657,20 +4335,6 @@
"portable",
"shim"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:47:27+00:00"
},
{
@@ -4720,20 +4384,6 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-15T15:59:10+00:00"
},
{
@@ -4810,20 +4460,6 @@
"uri",
"url"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-21T21:02:50+00:00"
},
{
@@ -4959,20 +4595,6 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-12T16:45:47+00:00"
},
{
@@ -5105,20 +4727,6 @@
"debug",
"dump"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-12T16:45:47+00:00"
},
{
@@ -5179,20 +4787,6 @@
"instantiate",
"serialize"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-15T15:59:10+00:00"
},
{
@@ -5306,30 +4900,20 @@
"env",
"environment"
],
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
- "type": "tidelift"
- }
- ],
"time": "2020-05-23T09:43:32+00:00"
},
{
"name": "voku/portable-ascii",
- "version": "1.4.10",
+ "version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/voku/portable-ascii.git",
- "reference": "240e93829a5f985fab0984a6e55ae5e26b78a334"
+ "reference": "2d302cf7dc474d5f7f18b29b03e0e77d408922a4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/portable-ascii/zipball/240e93829a5f985fab0984a6e55ae5e26b78a334",
- "reference": "240e93829a5f985fab0984a6e55ae5e26b78a334",
+ "url": "https://api.github.com/repos/voku/portable-ascii/zipball/2d302cf7dc474d5f7f18b29b03e0e77d408922a4",
+ "reference": "2d302cf7dc474d5f7f18b29b03e0e77d408922a4",
"shasum": ""
},
"require": {
@@ -5344,8 +4928,7 @@
"type": "library",
"autoload": {
"psr-4": {
- "voku\\": "src/voku/",
- "voku\\tests\\": "tests/"
+ "voku\\": "src/voku/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -5365,25 +4948,7 @@
"clean",
"php"
],
- "funding": [
- {
- "url": "https://www.paypal.me/moelleken",
- "type": "custom"
- },
- {
- "url": "https://github.com/voku",
- "type": "github"
- },
- {
- "url": "https://www.patreon.com/voku",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
- "type": "tidelift"
- }
- ],
- "time": "2020-03-13T01:23:26+00:00"
+ "time": "2020-05-23T23:15:19+00:00"
},
{
"name": "willdurand/geocoder",
@@ -5512,12 +5077,6 @@
"profiler",
"webprofiler"
],
- "funding": [
- {
- "url": "https://github.com/barryvdh",
- "type": "github"
- }
- ],
"time": "2020-05-05T10:53:32+00:00"
},
{
@@ -5589,12 +5148,6 @@
"phpstorm",
"sublime"
],
- "funding": [
- {
- "url": "https://github.com/barryvdh",
- "type": "github"
- }
- ],
"time": "2020-04-22T09:57:26+00:00"
},
{
@@ -5700,16 +5253,6 @@
"ssl",
"tls"
],
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
"time": "2020-04-08T08:27:21+00:00"
},
{
@@ -5791,16 +5334,6 @@
"dependency",
"package"
],
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
"time": "2020-05-06T08:28:10+00:00"
},
{
@@ -5966,12 +5499,6 @@
"Xdebug",
"performance"
],
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- }
- ],
"time": "2020-03-01T12:26:26+00:00"
},
{
@@ -6293,26 +5820,20 @@
}
],
"description": "A tool to automatically fix PHP code style",
- "funding": [
- {
- "url": "https://github.com/keradus",
- "type": "github"
- }
- ],
"time": "2020-04-15T18:51:10+00:00"
},
{
"name": "itsgoingd/clockwork",
- "version": "v4.1.3",
+ "version": "v4.1.4",
"source": {
"type": "git",
"url": "https://github.com/itsgoingd/clockwork.git",
- "reference": "049a7dacfa8ee749bf792fcfb85515d09b0d94a6"
+ "reference": "5da03673010a227f400e30debf622954920ecd5d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/049a7dacfa8ee749bf792fcfb85515d09b0d94a6",
- "reference": "049a7dacfa8ee749bf792fcfb85515d09b0d94a6",
+ "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/5da03673010a227f400e30debf622954920ecd5d",
+ "reference": "5da03673010a227f400e30debf622954920ecd5d",
"shasum": ""
},
"require": {
@@ -6358,13 +5879,7 @@
"profiling",
"slim"
],
- "funding": [
- {
- "url": "https://github.com/itsgoingd",
- "type": "github"
- }
- ],
- "time": "2020-05-02T21:02:52+00:00"
+ "time": "2020-05-24T23:30:22+00:00"
},
{
"name": "justinrainbow/json-schema",
@@ -6654,20 +6169,6 @@
"php",
"symfony"
],
- "funding": [
- {
- "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L",
- "type": "custom"
- },
- {
- "url": "https://github.com/nunomaduro",
- "type": "github"
- },
- {
- "url": "https://www.patreon.com/nunomaduro",
- "type": "patreon"
- }
- ],
"time": "2020-04-04T19:56:08+00:00"
},
{
@@ -7412,16 +6913,6 @@
"testing",
"xunit"
],
- "funding": [
- {
- "url": "https://phpunit.de/donate.html",
- "type": "custom"
- },
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
"time": "2020-05-22T13:51:52+00:00"
},
{
@@ -8086,16 +7577,6 @@
"parser",
"validator"
],
- "funding": [
- {
- "url": "https://github.com/Seldaek",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint",
- "type": "tidelift"
- }
- ],
"time": "2020-04-30T19:05:18+00:00"
},
{
@@ -8196,20 +7677,6 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-03-27T16:54:36+00:00"
},
{
@@ -8264,20 +7731,6 @@
"configuration",
"options"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-06T10:40:56+00:00"
},
{
@@ -8337,20 +7790,6 @@
"portable",
"shim"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:47:27+00:00"
},
{
@@ -8401,20 +7840,6 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-03-27T16:56:45+00:00"
},
{
@@ -8474,20 +7899,6 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-04-28T17:58:55+00:00"
},
{
@@ -8594,6 +8005,5 @@
},
"platform-dev": {
"ext-imagick": "*"
- },
- "plugin-api-version": "1.1.0"
+ }
}
diff --git a/public/dist/main.js b/public/dist/main.js
index 35bd5be32e..3b73a5bdfe 100644
--- a/public/dist/main.js
+++ b/public/dist/main.js
@@ -7912,9 +7912,9 @@ upload.start = {
if (typeof data === 'string' && data.search('phpdebugbar') !== -1) {
// get rid of phpdebugbar thingy
- var n = data.search(" 0) {
- data = data.slice(0, n);
+ var debug_bar_n = data.search(" 0) {
+ data = data.slice(0, debug_bar_n);
}
}
diff --git a/setup_exiftool.sh b/setup_exiftool.sh
index e6356d6686..8e23bb983d 100755
--- a/setup_exiftool.sh
+++ b/setup_exiftool.sh
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
set -e
-wget http://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-11.77.tar.gz
-tar -zxvf Image-ExifTool-11.77.tar.gz
-cd Image-ExifTool-11.77
+wget https://exiftool.org/Image-ExifTool-11.99.tar.gz
+tar -zxvf Image-ExifTool-11.99.tar.gz
+cd Image-ExifTool-11.99
perl Makefile.PL
make test
sudo make install
cd ..
-rm -rf Image-ExifTool-11.77
\ No newline at end of file
+rm -rf Image-ExifTool-11.99