commit
c7d0e5215d
0
dist/main.css
vendored
Executable file → Normal file
0
dist/main.css
vendored
Executable file → Normal file
BIN
dist/main.js
vendored
BIN
dist/main.js
vendored
Binary file not shown.
BIN
dist/view.js
vendored
BIN
dist/view.js
vendored
Binary file not shown.
@ -1,3 +1,27 @@
|
|||||||
|
## v3.1.2
|
||||||
|
|
||||||
|
Released June 12, 2016
|
||||||
|
|
||||||
|
- `Improved` Added indexes to SQL fields to improve query execution time (Thanks @qligier, #533)
|
||||||
|
- `Improved` Protocol-relative URLs for open graph metadata (#546)
|
||||||
|
- `Improved` Remove metadata from medium-sized images and thumbnails (Imagick only) (#556)
|
||||||
|
- `Improved` Reduce quality of medium-sized images (Imagick only) (#556)
|
||||||
|
- `Improved` orientation-handling with Imagick (#556)
|
||||||
|
|
||||||
|
## v3.1.1
|
||||||
|
|
||||||
|
Released April 30, 2016
|
||||||
|
|
||||||
|
- `New` share button when logged out (#473)
|
||||||
|
- `New` Import of IPTC photo tags (Thanks @qligier, #514)
|
||||||
|
- `New` Added reset username and password to FAQ (#500 #128)
|
||||||
|
- `Improved` Removed will-change from the main image to improve the image rendering in Chrome (#501)
|
||||||
|
- `Improved` scroll and rendering performance by removing will-change
|
||||||
|
- `Improved` Open Facebook and Twitter sharing sheet in new window
|
||||||
|
- `Improved` EXIF and IPTC extraction (Thanks @qligier, #518)
|
||||||
|
- `Fixed` broken URL in Update.md (#516)
|
||||||
|
- `Fixed` error 500 on database connect error (Thanks @tribut, #530)
|
||||||
|
|
||||||
## v3.1.0
|
## v3.1.0
|
||||||
|
|
||||||
Released March 29, 2016
|
Released March 29, 2016
|
||||||
|
@ -3,7 +3,7 @@ Everything you need is a web-server with PHP 5.5 or later and a MySQL-Database.
|
|||||||
|
|
||||||
The following PHP extensions must be activated:
|
The following PHP extensions must be activated:
|
||||||
|
|
||||||
exif, gd, json, mbstring, mysqli, zip
|
session, exif, mbstring, gd, mysqli, json, zip
|
||||||
|
|
||||||
To use Lychee without restrictions, we recommend to increase the values of the following properties in `php.ini`:
|
To use Lychee without restrictions, we recommend to increase the values of the following properties in `php.ini`:
|
||||||
|
|
||||||
|
@ -99,22 +99,22 @@ final class Album {
|
|||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
$return['public'] = '0';
|
$return['public'] = '0';
|
||||||
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE star = 1 " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url, medium FROM ? WHERE star = 1 " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
$return['public'] = '0';
|
$return['public'] = '0';
|
||||||
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE public = 1 " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url, medium FROM ? WHERE public = 1 " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
$return['public'] = '0';
|
$return['public'] = '0';
|
||||||
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url, medium FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '0':
|
case '0':
|
||||||
$return['public'] = '0';
|
$return['public'] = '0';
|
||||||
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = 0 " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url, medium FROM ? WHERE album = 0 " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -122,7 +122,7 @@ final class Album {
|
|||||||
$albums = Database::execute(Database::get(), $query, __METHOD__, __LINE__);
|
$albums = Database::execute(Database::get(), $query, __METHOD__, __LINE__);
|
||||||
$return = $albums->fetch_assoc();
|
$return = $albums->fetch_assoc();
|
||||||
$return = Album::prepareData($return);
|
$return = Album::prepareData($return);
|
||||||
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = '?' " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS, $this->albumIDs));
|
$query = Database::prepare(Database::get(), "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url, medium FROM ? WHERE album = '?' " . Settings::get()['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS, $this->albumIDs));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ final class Database {
|
|||||||
'030000', // 3.0.0
|
'030000', // 3.0.0
|
||||||
'030001', // 3.0.1
|
'030001', // 3.0.1
|
||||||
'030003', // 3.0.3
|
'030003', // 3.0.3
|
||||||
'030100' // 3.1.0
|
'030100', // 3.1.0
|
||||||
|
'030102' // 3.1.2
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,7 +238,6 @@ final class Photo {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save to DB
|
|
||||||
$values = array(LYCHEE_TABLE_PHOTOS, $id, $info['title'], $photo_name, $info['description'], $info['tags'], $info['type'], $info['width'], $info['height'], $info['size'], $info['iso'], $info['aperture'], $info['make'], $info['model'], $info['shutter'], $info['focal'], $info['takestamp'], $path_thumb, $albumID, $public, $star, $checksum, $medium);
|
$values = array(LYCHEE_TABLE_PHOTOS, $id, $info['title'], $photo_name, $info['description'], $info['tags'], $info['type'], $info['width'], $info['height'], $info['size'], $info['iso'], $info['aperture'], $info['make'], $info['model'], $info['shutter'], $info['focal'], $info['takestamp'], $path_thumb, $albumID, $public, $star, $checksum, $medium);
|
||||||
$query = Database::prepare(Database::get(), "INSERT INTO ? (id, title, url, description, tags, type, width, height, size, iso, aperture, make, model, shutter, focal, takestamp, thumbUrl, album, public, star, checksum, medium) VALUES ('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?')", $values);
|
$query = Database::prepare(Database::get(), "INSERT INTO ? (id, title, url, description, tags, type, width, height, size, iso, aperture, make, model, shutter, focal, takestamp, thumbUrl, album, public, star, checksum, medium) VALUES ('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?')", $values);
|
||||||
$result = Database::execute(Database::get(), $query, __METHOD__, __LINE__);
|
$result = Database::execute(Database::get(), $query, __METHOD__, __LINE__);
|
||||||
@ -296,7 +295,7 @@ final class Photo {
|
|||||||
Plugins::get()->activate(__METHOD__, 0, func_get_args());
|
Plugins::get()->activate(__METHOD__, 0, func_get_args());
|
||||||
|
|
||||||
// Quality of thumbnails
|
// Quality of thumbnails
|
||||||
$thumbQuality = 90;
|
$quality = 90;
|
||||||
|
|
||||||
// Size of the thumbnail
|
// Size of the thumbnail
|
||||||
$newWidth = 200;
|
$newWidth = 200;
|
||||||
@ -312,9 +311,12 @@ final class Photo {
|
|||||||
// Read image
|
// Read image
|
||||||
$thumb = new Imagick();
|
$thumb = new Imagick();
|
||||||
$thumb->readImage($url);
|
$thumb->readImage($url);
|
||||||
$thumb->setImageCompressionQuality($thumbQuality);
|
$thumb->setImageCompressionQuality($quality);
|
||||||
$thumb->setImageFormat('jpeg');
|
$thumb->setImageFormat('jpeg');
|
||||||
|
|
||||||
|
// Remove metadata to save some bytes
|
||||||
|
$thumb->stripImage();
|
||||||
|
|
||||||
// Copy image for 2nd thumb version
|
// Copy image for 2nd thumb version
|
||||||
$thumb2x = clone $thumb;
|
$thumb2x = clone $thumb;
|
||||||
|
|
||||||
@ -359,12 +361,12 @@ final class Photo {
|
|||||||
|
|
||||||
// Create thumb
|
// Create thumb
|
||||||
fastImageCopyResampled($thumb, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth, $newHeight, $newSize, $newSize);
|
fastImageCopyResampled($thumb, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth, $newHeight, $newSize, $newSize);
|
||||||
imagejpeg($thumb, $newUrl, $thumbQuality);
|
imagejpeg($thumb, $newUrl, $quality);
|
||||||
imagedestroy($thumb);
|
imagedestroy($thumb);
|
||||||
|
|
||||||
// Create retina thumb
|
// Create retina thumb
|
||||||
fastImageCopyResampled($thumb2x, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth*2, $newHeight*2, $newSize, $newSize);
|
fastImageCopyResampled($thumb2x, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth*2, $newHeight*2, $newSize, $newSize);
|
||||||
imagejpeg($thumb2x, $newUrl2x, $thumbQuality);
|
imagejpeg($thumb2x, $newUrl2x, $quality);
|
||||||
imagedestroy($thumb2x);
|
imagedestroy($thumb2x);
|
||||||
|
|
||||||
// Free memory
|
// Free memory
|
||||||
@ -395,6 +397,9 @@ final class Photo {
|
|||||||
// Call plugins
|
// Call plugins
|
||||||
Plugins::get()->activate(__METHOD__, 0, func_get_args());
|
Plugins::get()->activate(__METHOD__, 0, func_get_args());
|
||||||
|
|
||||||
|
// Quality of medium-photo
|
||||||
|
$quality = 90;
|
||||||
|
|
||||||
// Set to true when creation of medium-photo failed
|
// Set to true when creation of medium-photo failed
|
||||||
$error = false;
|
$error = false;
|
||||||
|
|
||||||
@ -427,6 +432,8 @@ final class Photo {
|
|||||||
|
|
||||||
// Adjust image
|
// Adjust image
|
||||||
$medium->scaleImage($newWidth, $newHeight, true);
|
$medium->scaleImage($newWidth, $newHeight, true);
|
||||||
|
$medium->stripImage();
|
||||||
|
$medium->setImageCompressionQuality($quality);
|
||||||
|
|
||||||
// Save image
|
// Save image
|
||||||
try { $medium->writeImage($newUrl); }
|
try { $medium->writeImage($newUrl); }
|
||||||
@ -472,20 +479,50 @@ final class Photo {
|
|||||||
|
|
||||||
if (extension_loaded('imagick')&&Settings::get()['imagick']==='1') {
|
if (extension_loaded('imagick')&&Settings::get()['imagick']==='1') {
|
||||||
|
|
||||||
switch ($info['orientation']) {
|
$image = new Imagick();
|
||||||
|
$image->readImage($path);
|
||||||
|
|
||||||
case 3:
|
$orientation = $image->getImageOrientation();
|
||||||
$rotateImage = 180;
|
|
||||||
|
switch ($orientation) {
|
||||||
|
|
||||||
|
case Imagick::ORIENTATION_TOPLEFT:
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case Imagick::ORIENTATION_TOPRIGHT:
|
||||||
$rotateImage = 90;
|
$image->flopImage();
|
||||||
$swapSize = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case Imagick::ORIENTATION_BOTTOMRIGHT:
|
||||||
$rotateImage = 270;
|
$image->rotateImage(new ImagickPixel(), 180);
|
||||||
$swapSize = true;
|
break;
|
||||||
|
|
||||||
|
case Imagick::ORIENTATION_BOTTOMLEFT:
|
||||||
|
$image->flopImage();
|
||||||
|
$image->rotateImage(new ImagickPixel(), 180);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Imagick::ORIENTATION_LEFTTOP:
|
||||||
|
$image->flopImage();
|
||||||
|
$image->rotateImage(new ImagickPixel(), -90);
|
||||||
|
$swapSize = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Imagick::ORIENTATION_RIGHTTOP:
|
||||||
|
$image->rotateImage(new ImagickPixel(), 90);
|
||||||
|
$swapSize = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Imagick::ORIENTATION_RIGHTBOTTOM:
|
||||||
|
$image->flopImage();
|
||||||
|
$image->rotateImage(new ImagickPixel(), 90);
|
||||||
|
$swapSize = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Imagick::ORIENTATION_LEFTBOTTOM:
|
||||||
|
$image->rotateImage(new ImagickPixel(), -90);
|
||||||
|
$swapSize = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -494,15 +531,13 @@ final class Photo {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($rotateImage!==0) {
|
// Adjust photo
|
||||||
$image = new Imagick();
|
$image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
|
||||||
$image->readImage($path);
|
$image->writeImage($path);
|
||||||
$image->rotateImage(new ImagickPixel(), $rotateImage);
|
|
||||||
$image->setImageOrientation(1);
|
// Free memory
|
||||||
$image->writeImage($path);
|
$image->clear();
|
||||||
$image->clear();
|
$image->destroy();
|
||||||
$image->destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -512,6 +547,11 @@ final class Photo {
|
|||||||
|
|
||||||
switch ($info['orientation']) {
|
switch ($info['orientation']) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// do nothing
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// mirror
|
// mirror
|
||||||
// not yet implemented
|
// not yet implemented
|
||||||
@ -561,6 +601,7 @@ final class Photo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recreate photo
|
// Recreate photo
|
||||||
|
// In this step the photos also loses its metadata :(
|
||||||
$newSourceImg = imagecreatetruecolor($newWidth, $newHeight);
|
$newSourceImg = imagecreatetruecolor($newWidth, $newHeight);
|
||||||
imagecopyresampled($newSourceImg, $sourceImg, 0, 0, 0, 0, $newWidth, $newHeight, $newWidth, $newHeight);
|
imagecopyresampled($newSourceImg, $sourceImg, 0, 0, 0, 0, $newWidth, $newHeight, $newWidth, $newHeight);
|
||||||
imagejpeg($newSourceImg, $path, 100);
|
imagejpeg($newSourceImg, $path, 100);
|
||||||
@ -593,7 +634,7 @@ final class Photo {
|
|||||||
public static function prepareData(array $data) {
|
public static function prepareData(array $data) {
|
||||||
|
|
||||||
// Excepts the following:
|
// Excepts the following:
|
||||||
// (array) $data = ['id', 'title', 'tags', 'public', 'star', 'album', 'thumbUrl', 'takestamp', 'url']
|
// (array) $data = ['id', 'title', 'tags', 'public', 'star', 'album', 'thumbUrl', 'takestamp', 'url', 'medium']
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
$photo = null;
|
$photo = null;
|
||||||
@ -606,7 +647,11 @@ final class Photo {
|
|||||||
$photo['star'] = $data['star'];
|
$photo['star'] = $data['star'];
|
||||||
$photo['album'] = $data['album'];
|
$photo['album'] = $data['album'];
|
||||||
|
|
||||||
// Parse urls
|
// Parse medium
|
||||||
|
if ($data['medium']==='1') $photo['medium'] = LYCHEE_URL_UPLOADS_MEDIUM . $data['url'];
|
||||||
|
else $photo['medium'] = '';
|
||||||
|
|
||||||
|
// Parse paths
|
||||||
$photo['thumbUrl'] = LYCHEE_URL_UPLOADS_THUMB . $data['thumbUrl'];
|
$photo['thumbUrl'] = LYCHEE_URL_UPLOADS_THUMB . $data['thumbUrl'];
|
||||||
$photo['url'] = LYCHEE_URL_UPLOADS_BIG . $data['url'];
|
$photo['url'] = LYCHEE_URL_UPLOADS_BIG . $data['url'];
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `?` (
|
CREATE TABLE IF NOT EXISTS `?` (
|
||||||
`id` bigint(14) NOT NULL,
|
`id` bigint(14) unsigned NOT NULL,
|
||||||
`title` varchar(100) NOT NULL DEFAULT '',
|
`title` varchar(100) NOT NULL DEFAULT '',
|
||||||
`description` varchar(1000) DEFAULT '',
|
`description` varchar(1000) DEFAULT '',
|
||||||
`sysstamp` int(11) NOT NULL,
|
`sysstamp` int(11) NOT NULL,
|
||||||
@ -11,4 +11,4 @@ CREATE TABLE IF NOT EXISTS `?` (
|
|||||||
`downloadable` tinyint(1) NOT NULL DEFAULT '0',
|
`downloadable` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
`password` varchar(100) DEFAULT NULL,
|
`password` varchar(100) DEFAULT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
@ -7,6 +7,6 @@ CREATE TABLE IF NOT EXISTS `?` (
|
|||||||
`type` varchar(11) NOT NULL,
|
`type` varchar(11) NOT NULL,
|
||||||
`function` varchar(100) NOT NULL,
|
`function` varchar(100) NOT NULL,
|
||||||
`line` int(11) NOT NULL,
|
`line` int(11) NOT NULL,
|
||||||
`text` TEXT,
|
`text` text,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
@ -2,8 +2,8 @@
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `?` (
|
CREATE TABLE IF NOT EXISTS `?` (
|
||||||
`id` bigint(14) NOT NULL,
|
`id` bigint(14) unsigned NOT NULL,
|
||||||
`title` varchar(100) NOT NULL,
|
`title` varchar(100) NOT NULL DEFAULT '',
|
||||||
`description` varchar(1000) DEFAULT '',
|
`description` varchar(1000) DEFAULT '',
|
||||||
`url` varchar(100) NOT NULL,
|
`url` varchar(100) NOT NULL,
|
||||||
`tags` varchar(1000) NOT NULL DEFAULT '',
|
`tags` varchar(1000) NOT NULL DEFAULT '',
|
||||||
@ -20,9 +20,11 @@ CREATE TABLE IF NOT EXISTS `?` (
|
|||||||
`focal` varchar(20) NOT NULL,
|
`focal` varchar(20) NOT NULL,
|
||||||
`takestamp` int(11) DEFAULT NULL,
|
`takestamp` int(11) DEFAULT NULL,
|
||||||
`star` tinyint(1) NOT NULL,
|
`star` tinyint(1) NOT NULL,
|
||||||
`thumbUrl` varchar(50) NOT NULL,
|
`thumbUrl` char(37) NOT NULL,
|
||||||
`album` varchar(30) NOT NULL DEFAULT '0',
|
`album` bigint(20) unsigned NOT NULL,
|
||||||
`checksum` VARCHAR(100) DEFAULT NULL,
|
`checksum` char(40) DEFAULT NULL,
|
||||||
`medium` tinyint(1) NOT NULL DEFAULT '0',
|
`medium` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`),
|
||||||
) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
KEY `Index_album` (`album`),
|
||||||
|
KEY `Index_star` (`star`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
@ -4,4 +4,4 @@
|
|||||||
CREATE TABLE IF NOT EXISTS `?` (
|
CREATE TABLE IF NOT EXISTS `?` (
|
||||||
`key` varchar(50) NOT NULL DEFAULT '',
|
`key` varchar(50) NOT NULL DEFAULT '',
|
||||||
`value` varchar(200) DEFAULT ''
|
`value` varchar(200) DEFAULT ''
|
||||||
) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
73
php/database/update_030102.php
Normal file
73
php/database/update_030102.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update to version 3.1.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Lychee\Modules\Database;
|
||||||
|
use Lychee\Modules\Response;
|
||||||
|
|
||||||
|
// Change type of the album id field
|
||||||
|
$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `album` `album` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not change type of the album id field!');
|
||||||
|
|
||||||
|
// Add index to the album id field
|
||||||
|
$query = Database::prepare($connection, "SHOW INDEX FROM `?` WHERE KEY_NAME = 'Index_album'", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not check if Index_album exists!');
|
||||||
|
|
||||||
|
if ($result->num_rows===0) {
|
||||||
|
|
||||||
|
$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_album` (`album`)", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not add index to the album id field!');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add index to the star field
|
||||||
|
$query = Database::prepare($connection, "SHOW INDEX FROM `?` WHERE KEY_NAME = 'Index_star'", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not check if Index_star exists!');
|
||||||
|
|
||||||
|
if ($result->num_rows===0) {
|
||||||
|
|
||||||
|
$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_star` (`star`)", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not add index to the star field!');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change type of the checksum field
|
||||||
|
$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `checksum` `checksum` CHAR(40) NULL DEFAULT NULL", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not change type of the checksum field!');
|
||||||
|
|
||||||
|
// Change type of the thumbUrl field
|
||||||
|
$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `thumbUrl` `thumbUrl` CHAR(37) NOT NULL", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not change type of the thumbUrl field!');
|
||||||
|
|
||||||
|
// Change type of the id field
|
||||||
|
$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not change type of the id field!');
|
||||||
|
|
||||||
|
// Change type of the id field
|
||||||
|
$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_ALBUMS));
|
||||||
|
$result = Database::execute($connection, $query, 'update_030102', __LINE__);
|
||||||
|
|
||||||
|
if ($result===false) Response::error('Could not change type of the id field!');
|
||||||
|
|
||||||
|
// Set version
|
||||||
|
if (Database::setVersion($connection, '030102')===false) Response::error('Could not update version of database!');
|
||||||
|
|
||||||
|
?>
|
@ -24,8 +24,8 @@ function getGraphHeader($photoID) {
|
|||||||
else $dir = 'big';
|
else $dir = 'big';
|
||||||
|
|
||||||
$parseUrl = parse_url('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
$parseUrl = parse_url('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||||
$url = $parseUrl['scheme'] . '://' . $parseUrl['host'] . $parseUrl['path'] . '?' . $parseUrl['query'];
|
$url = '//' . $parseUrl['host'] . $parseUrl['path'] . '?' . $parseUrl['query'];
|
||||||
$picture = $parseUrl['scheme'] . '://' . $parseUrl['host'] . $parseUrl['path'] . '/../uploads/' . $dir . '/' . $row->url;
|
$picture = '//' . $parseUrl['host'] . $parseUrl['path'] . '/../uploads/' . $dir . '/' . $row->url;
|
||||||
|
|
||||||
$url = htmlentities($url);
|
$url = htmlentities($url);
|
||||||
$picture = htmlentities($picture);
|
$picture = htmlentities($picture);
|
||||||
|
@ -53,10 +53,13 @@ if (hasPermissions(LYCHEE_UPLOADS)===false) $error .= ('Error: \'uploads/
|
|||||||
if (hasPermissions(LYCHEE_DATA)===false) $error .= ('Error: \'data/\' is missing or has insufficient read/write privileges' . PHP_EOL);
|
if (hasPermissions(LYCHEE_DATA)===false) $error .= ('Error: \'data/\' is missing or has insufficient read/write privileges' . PHP_EOL);
|
||||||
|
|
||||||
// About GD
|
// About GD
|
||||||
$gdVersion = gd_info();
|
$gdVersion = array('GD Version' => '-');
|
||||||
if (!$gdVersion['JPEG Support']) $error .= ('Error: PHP gd extension without jpeg support' . PHP_EOL);
|
if (function_exists('gd_info')) {
|
||||||
if (!$gdVersion['PNG Support']) $error .= ('Error: PHP gd extension without png support' . PHP_EOL);
|
$gdVersion = gd_info();
|
||||||
if (!$gdVersion['GIF Read Support'] || !$gdVersion['GIF Create Support']) $error .= ('Error: PHP gd extension without full gif support' . PHP_EOL);
|
if (!$gdVersion['JPEG Support']) $error .= ('Error: PHP gd extension without jpeg support' . PHP_EOL);
|
||||||
|
if (!$gdVersion['PNG Support']) $error .= ('Error: PHP gd extension without png support' . PHP_EOL);
|
||||||
|
if (!$gdVersion['GIF Read Support'] || !$gdVersion['GIF Create Support']) $error .= ('Error: PHP gd extension without full gif support' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
if (!file_exists(LYCHEE_CONFIG_FILE)) exit('Error: Configuration not found. Please install Lychee for additional tests');
|
if (!file_exists(LYCHEE_CONFIG_FILE)) exit('Error: Configuration not found. Please install Lychee for additional tests');
|
||||||
@ -96,6 +99,10 @@ if (empty(ini_get('allow_url_fopen'))) echo('Warning: You may experience problem
|
|||||||
// Check mysql version
|
// Check mysql version
|
||||||
if ($database->server_version<50500) echo('Warning: Lychee uses the GBK charset to avoid sql injections on your MySQL version. Please update to MySQL 5.5 or higher to enable UTF-8 support.' . PHP_EOL);
|
if ($database->server_version<50500) echo('Warning: Lychee uses the GBK charset to avoid sql injections on your MySQL version. Please update to MySQL 5.5 or higher to enable UTF-8 support.' . PHP_EOL);
|
||||||
|
|
||||||
|
// Check imagick
|
||||||
|
if (!extension_loaded('imagick')) echo('Warning: Pictures that are rotated lose their metadata! Please install Imagick to avoid that.' . PHP_EOL);
|
||||||
|
else if (!$settings['imagick']) echo('Warning: Pictures that are rotated lose their metadata! Please enable Imagick in settings to avoid that.' . PHP_EOL);
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
if ($error==='') echo('No critical problems found. Lychee should work without problems!' . PHP_EOL);
|
if ($error==='') echo('No critical problems found. Lychee should work without problems!' . PHP_EOL);
|
||||||
else echo $error;
|
else echo $error;
|
||||||
|
2094
src/npm-shrinkwrap.json
generated
2094
src/npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Lychee",
|
"name": "Lychee",
|
||||||
"version": "3.1.0",
|
"version": "3.1.2",
|
||||||
"description": "Self-hosted photo-management done right.",
|
"description": "Self-hosted photo-management done right.",
|
||||||
"authors": "Tobias Reich <tobias@electerious.com>",
|
"authors": "Tobias Reich <tobias@electerious.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -14,20 +14,20 @@
|
|||||||
"compile": "gulp"
|
"compile": "gulp"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-preset-es2015": "^6.6.0",
|
"babel-preset-es2015": "^6.13.2",
|
||||||
"basiccontext": "^3.5.1",
|
"basiccontext": "^3.5.1",
|
||||||
"basicmodal": "^3.3.4",
|
"basicmodal": "^3.3.7",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-autoprefixer": "3.1.0",
|
"gulp-autoprefixer": "3.1.0",
|
||||||
"gulp-babel": "^6.1.2",
|
"gulp-babel": "^6.1.2",
|
||||||
"gulp-concat": "^2.6.0",
|
"gulp-concat": "^2.6.0",
|
||||||
"gulp-inject": "^4.0.0",
|
"gulp-inject": "^4.1.0",
|
||||||
"gulp-load-plugins": "^1.2.0",
|
"gulp-load-plugins": "^1.2.4",
|
||||||
"gulp-minify-css": "^1.2.4",
|
"gulp-minify-css": "^1.2.4",
|
||||||
"gulp-rimraf": "^0.2.0",
|
"gulp-rimraf": "^0.2.0",
|
||||||
"gulp-sass": "^2.2.0",
|
"gulp-sass": "^2.3.2",
|
||||||
"gulp-uglify": "^1.5.3",
|
"gulp-uglify": "^2.0.0",
|
||||||
"jquery": "^2.2.3",
|
"jquery": "^3.1.0",
|
||||||
"mousetrap": "^1.5.3"
|
"mousetrap": "^1.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,10 +306,12 @@ contextMenu.sharePhoto = function(photoID, e) {
|
|||||||
{ title: build.iconic('envelope-closed') + 'Mail', fn: () => photo.share(photoID, 'mail') },
|
{ title: build.iconic('envelope-closed') + 'Mail', fn: () => photo.share(photoID, 'mail') },
|
||||||
{ title: build.iconic('dropbox', iconClass) + 'Dropbox', visible: lychee.publicMode===false, fn: () => photo.share(photoID, 'dropbox') },
|
{ title: build.iconic('dropbox', iconClass) + 'Dropbox', visible: lychee.publicMode===false, fn: () => photo.share(photoID, 'dropbox') },
|
||||||
{ title: build.iconic('link-intact') + 'Direct Link', fn: () => window.open(photo.getDirectLink()) },
|
{ title: build.iconic('link-intact') + 'Direct Link', fn: () => window.open(photo.getDirectLink()) },
|
||||||
{ visible: lychee.publicMode===false },
|
{ },
|
||||||
{ title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => photo.setPublic(photoID) }
|
{ title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => photo.setPublic(photoID) }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (lychee.publicMode===true) items.splice(7, 1)
|
||||||
|
|
||||||
basicContext.show(items, e.originalEvent)
|
basicContext.show(items, e.originalEvent)
|
||||||
$('.basicContext input#link').focus().select()
|
$('.basicContext input#link').focus().select()
|
||||||
|
|
||||||
@ -325,11 +327,13 @@ contextMenu.shareAlbum = function(albumID, e) {
|
|||||||
{ title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => album.share('twitter') },
|
{ title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => album.share('twitter') },
|
||||||
{ title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => album.share('facebook') },
|
{ title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => album.share('facebook') },
|
||||||
{ title: build.iconic('envelope-closed') + 'Mail', fn: () => album.share('mail') },
|
{ title: build.iconic('envelope-closed') + 'Mail', fn: () => album.share('mail') },
|
||||||
{ visible: lychee.publicMode===false },
|
{ },
|
||||||
{ title: build.iconic('pencil') + 'Edit Sharing', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, true, e) },
|
{ title: build.iconic('pencil') + 'Edit Sharing', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, true, e) },
|
||||||
{ title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, false) }
|
{ title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, false) }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (lychee.publicMode===true) items.splice(5, 1)
|
||||||
|
|
||||||
basicContext.show(items, e.originalEvent)
|
basicContext.show(items, e.originalEvent)
|
||||||
$('.basicContext input#link').focus().select()
|
$('.basicContext input#link').focus().select()
|
||||||
|
|
||||||
|
@ -67,8 +67,6 @@ header.bind = function() {
|
|||||||
|
|
||||||
header.show = function() {
|
header.show = function() {
|
||||||
|
|
||||||
clearTimeout($(window).data('timeout'))
|
|
||||||
|
|
||||||
lychee.imageview.removeClass('full')
|
lychee.imageview.removeClass('full')
|
||||||
header.dom().removeClass('header--hidden')
|
header.dom().removeClass('header--hidden')
|
||||||
|
|
||||||
@ -76,18 +74,12 @@ header.show = function() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
header.hide = function(e, delay = 500) {
|
header.hide = function(e) {
|
||||||
|
|
||||||
if (visible.photo() && !visible.sidebar() && !visible.contextMenu() && basicModal.visible()===false) {
|
if (visible.photo() && !visible.sidebar() && !visible.contextMenu() && basicModal.visible()===false) {
|
||||||
|
|
||||||
clearTimeout($(window).data('timeout'))
|
lychee.imageview.addClass('full')
|
||||||
|
header.dom().addClass('header--hidden')
|
||||||
$(window).data('timeout', setTimeout(function() {
|
|
||||||
|
|
||||||
lychee.imageview.addClass('full')
|
|
||||||
header.dom().addClass('header--hidden')
|
|
||||||
|
|
||||||
}, delay))
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ $(document).ready(function() {
|
|||||||
// Fullscreen on mobile
|
// Fullscreen on mobile
|
||||||
.on('touchend', '#imageview #image', function(e) {
|
.on('touchend', '#imageview #image', function(e) {
|
||||||
if (swipe.obj==null || (swipe.offset>=-5&&swipe.offset<=5)) {
|
if (swipe.obj==null || (swipe.offset>=-5&&swipe.offset<=5)) {
|
||||||
if (visible.header()) header.hide(e, 0)
|
if (visible.header()) header.hide(e)
|
||||||
else header.show()
|
else header.show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
lychee = {
|
lychee = {
|
||||||
|
|
||||||
title : document.title,
|
title : document.title,
|
||||||
version : '3.1.0',
|
version : '3.1.2',
|
||||||
versionCode : '030100',
|
versionCode : '030102',
|
||||||
|
|
||||||
updatePath : '//update.electerious.com/index.json',
|
updatePath : '//update.electerious.com/index.json',
|
||||||
updateURL : 'https://github.com/electerious/Lychee',
|
updateURL : 'https://github.com/electerious/Lychee',
|
||||||
|
@ -159,7 +159,7 @@ multiselect.resize = function(e) {
|
|||||||
|
|
||||||
multiselect.stopResize = function() {
|
multiselect.stopResize = function() {
|
||||||
|
|
||||||
$(document).off('mousemove mouseup')
|
if (multiselect.position.top!==null) $(document).off('mousemove mouseup')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +82,12 @@ photo.preloadNext = function(photoID) {
|
|||||||
album.json.content[photoID].nextPhoto!='') {
|
album.json.content[photoID].nextPhoto!='') {
|
||||||
|
|
||||||
let nextPhoto = album.json.content[photoID].nextPhoto
|
let nextPhoto = album.json.content[photoID].nextPhoto
|
||||||
let url = album.json.content[nextPhoto].url
|
let medium = album.json.content[nextPhoto].medium
|
||||||
|
|
||||||
$('head [data-prefetch]').remove()
|
if (medium!=null && medium!=='') {
|
||||||
$('head').append(`<link data-prefetch rel="prefetch" href="${ url }">`)
|
$('head [data-prefetch]').remove()
|
||||||
|
$('head').append(`<link data-prefetch rel="prefetch" href="${ medium }">`)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,9 +309,12 @@ view.photo = {
|
|||||||
$('body').css('overflow', 'hidden')
|
$('body').css('overflow', 'hidden')
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
$(document)
|
var timeout
|
||||||
.bind('mouseenter', header.show)
|
$(document).bind('mousemove', function() {
|
||||||
.bind('mouseleave', header.hide)
|
clearTimeout(timeout)
|
||||||
|
header.show()
|
||||||
|
timeout = setTimeout(header.hide, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
lychee.animate(lychee.imageview, 'fadeIn')
|
lychee.animate(lychee.imageview, 'fadeIn')
|
||||||
|
|
||||||
@ -329,8 +332,7 @@ view.photo = {
|
|||||||
|
|
||||||
// Disable Fullscreen
|
// Disable Fullscreen
|
||||||
$(document)
|
$(document)
|
||||||
.unbind('mouseenter')
|
.unbind('mousemove')
|
||||||
.unbind('mouseleave')
|
|
||||||
|
|
||||||
// Hide Photo
|
// Hide Photo
|
||||||
lychee.animate(lychee.imageview, 'fadeOut')
|
lychee.animate(lychee.imageview, 'fadeOut')
|
||||||
|
@ -60,6 +60,15 @@ lychee.html = function(literalSections, ...substs) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lychee.getEventName = function() {
|
||||||
|
|
||||||
|
let touchendSupport = (/Android|iPhone|iPad|iPod/i).test(navigator.userAgent || navigator.vendor || window.opera) && ('ontouchend' in document.documentElement)
|
||||||
|
let eventName = (touchendSupport===true ? 'touchend' : 'click')
|
||||||
|
|
||||||
|
return eventName
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Sub-implementation of photo -------------------------------------------------------------- //
|
// Sub-implementation of photo -------------------------------------------------------------- //
|
||||||
|
|
||||||
let photo = {}
|
let photo = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user