View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
369 | RackTables | default | public | 2010-09-18 23:40 | 2019-01-08 11:55 |
Reporter | f0urtyfive | Assigned To | infrastation | ||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | closed | Resolution | fixed | ||
Product Version | 0.18.4 | ||||
Target Version | 0.19.0 | Fixed in Version | 0.19.0 | ||
Summary | 369: Caching of thumbnails to reduce load time of large pictures | ||||
Description | I've implemented caching of thumbnails to decrease the load time for large pictures. I've also switched the thumbnail output format to img/jpeg as it was 1/5th the space with no noticable loss in quality for a thumbnail. Diff and SQL required to make it work will be attached. | ||||
Tags | No tags attached. | ||||
2010-09-18 23:40
|
FileCache.diff (5,238 bytes)
diff -rupN RackTables-0.18.4/inc/database.php RackTables-0.18.4-orig/inc/database.php --- RackTables-0.18.4/inc/database.php 2010-09-18 19:35:58.000000000 -0400 +++ RackTables-0.18.4-orig/inc/database.php 2010-07-09 11:01:54.000000000 -0400 @@ -3071,49 +3071,6 @@ function getFile ($file_id = 0) return $ret; } -function getFileCache($file_id = 0) -{ - $query = usePreparedSelectBlade - ( - 'SELECT FileCache.contents FROM FileCache ' . - 'JOIN File on (FileCache.id = File.id) ' . - 'WHERE FileCache.mtime = File.mtime and FileCache.id = ?', - array ($file_id) - ); - if (($row = $query->fetch (PDO::FETCH_ASSOC)) == NULL) - { - $ret = false; - } - else - { - $ret = $row['contents']; - $query->CloseCursor(); - - usePreparedExecuteBlade ('UPDATE File SET atime = ? WHERE id = ?', array (date ('YmdHis'), $file_id)); - } - return $ret; -} - -function commitAddFileCache ($file_id, $file_mtime, $contents) -{ - usePreparedExecuteBlade ('DELETE from FileCache where id = ?', array($file_id)); - - global $dbxlink; - $query = $dbxlink->prepare('INSERT INTO FileCache (id, mtime, contents) VALUES (?, ?, ?)'); - $query->bindParam(1, $file_id); - $query->bindParam(2, $file_mtime); - $query->bindParam(3, $contents, PDO::PARAM_LOB); - try - { - return $query->execute(); - } - catch (PDOException $e) - { - throw convertPDOException ($e); - } -} - - function getFileLinks ($file_id = 0) { $query = usePreparedSelectBlade @@ -3286,13 +3243,6 @@ function commitDeleteFile ($file_id) return ''; } -function commitDeleteFileCache ($file_id) -{ - if (usePreparedDeleteBlade ('FileCache', array ('id' => $file_id)) === FALSE) - return __FUNCTION__ . '(): query failed'; - return ''; -} - function getChapterList () { $ret = array(); diff -rupN RackTables-0.18.4/inc/ophandlers.php RackTables-0.18.4-orig/inc/ophandlers.php --- RackTables-0.18.4/inc/ophandlers.php 2010-09-18 19:35:26.000000000 -0400 +++ RackTables-0.18.4-orig/inc/ophandlers.php 2010-07-05 13:07:09.000000000 -0400 @@ -1926,11 +1926,6 @@ function deleteFile () if ($error != '') return buildRedirectURL (__FUNCTION__, 'ERR', array ($error)); - $error = commitDeleteFileCache ($_REQUEST['file_id']); - - if ($error != '') - return buildRedirectURL (__FUNCTION__, 'ERR', array ($error)); - return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name']))); } diff -rupN RackTables-0.18.4/render_image.php RackTables-0.18.4-orig/render_image.php --- RackTables-0.18.4/render_image.php 2010-09-18 19:22:42.000000000 -0400 +++ RackTables-0.18.4-orig/render_image.php 2010-06-24 09:42:17.000000000 -0400 @@ -1,5 +1,6 @@ <?php + ob_start(); try { require 'inc/init.php'; @@ -197,37 +198,26 @@ function renderFilePreview ($file_id = 0 echo $file['contents']; break; case 'preview': - if(!($image = getFileCache($file_id))){ - $file = getFile ($file_id); - $image = imagecreatefromstring ($file['contents']); - unset ($file['contents']); - $width = imagesx ($image); - $height = imagesy ($image); - if ($width > getConfigVar ('PREVIEW_IMAGE_MAXPXS') or $height > getConfigVar ('PREVIEW_IMAGE_MAXPXS')) - { - // TODO: cache thumbs for faster page generation - $ratio = getConfigVar ('PREVIEW_IMAGE_MAXPXS') / max ($width, $height); - $newwidth = $width * $ratio; - $newheight = $height * $ratio; - $resampled = imagecreatetruecolor ($newwidth, $newheight); - imagecopyresampled ($resampled, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); - imagedestroy ($image); - $image = $resampled; - - //TODO: Find a better way to save the stream of the image... Output buffer seems silly. - ob_start(); - imagejpeg($image); - commitAddFileCache($file_id, $file['mtime'], ob_get_contents()); - ob_flush(); - - imagedestroy ($image); - unset ($file); - unset ($resampled); - } - + $file = getFile ($file_id); + $image = imagecreatefromstring ($file['contents']); + unset ($file); + $width = imagesx ($image); + $height = imagesy ($image); + if ($width > getConfigVar ('PREVIEW_IMAGE_MAXPXS') or $height > getConfigVar ('PREVIEW_IMAGE_MAXPXS')) + { + // TODO: cache thumbs for faster page generation + $ratio = getConfigVar ('PREVIEW_IMAGE_MAXPXS') / max ($width, $height); + $newwidth = $width * $ratio; + $newheight = $height * $ratio; + $resampled = imagecreatetruecolor ($newwidth, $newheight); + imagecopyresampled ($resampled, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); + imagedestroy ($image); + $image = $resampled; + unset ($resampled); } - header("Content-type: image/jpeg"); // don't announce content-length, it may have changed after resampling - if($image !== false) echo $image; + header("Content-type: image/png"); // don't announce content-length, it may have changed after resampling + imagepng ($image); + imagedestroy ($image); break; default: showError ('Invalid argument', __FUNCTION__); |
2010-09-18 23:40
|
|
2010-09-22 01:06
|
FileCache-v2.diff (4,949 bytes)
diff -ru RackTables-0.18.4-orig/inc/database.php rt-filecache-branch/inc/database.php --- RackTables-0.18.4-orig/inc/database.php 2010-07-09 11:01:54.000000000 -0400 +++ rt-filecache-branch/inc/database.php 2010-09-21 20:42:38.000000000 -0400 @@ -3071,6 +3071,45 @@ return $ret; } +function getFileCache($file_id = 0) +{ + $query = usePreparedSelectBlade + ( + 'SELECT File.thumbnail FROM File ' . + 'WHERE File.id = ? and File.thumbnail IS NOT NULL', + array ($file_id) + ); + if (($row = $query->fetch (PDO::FETCH_ASSOC)) == NULL) + { + $ret = false; + } + else + { + $ret = $row['contents']; + $query->CloseCursor(); + + usePreparedExecuteBlade ('UPDATE File SET atime = ? WHERE id = ?', array (date ('YmdHis'), $file_id)); + } + return $ret; +} + +function commitAddFileCache ($file_id, $file_mtime, $contents) +{ + global $dbxlink; + $query = $dbxlink->prepare('UPDATE File SET thumbnail = ? WHERE id = ?'); + $query->bindParam(1, $contents, PDO::PARAM_LOB); + $query->bindParam(2, $file_id); + try + { + return $query->execute(); + } + catch (PDOException $e) + { + throw convertPDOException ($e); + } +} + + function getFileLinks ($file_id = 0) { $query = usePreparedSelectBlade @@ -3243,6 +3282,21 @@ return ''; } +function commitDeleteFileCache ($file_id) +{ + global $dbxlink; + $query = $dbxlink->prepare('UPDATE File SET thumbnail = NULL WHERE id = ?'); + $query->bindParam(1, $file_id); + try + { + return $query->execute(); + } + catch (PDOException $e) + { + throw convertPDOException ($e); + } +} + function getChapterList () { $ret = array(); diff -ru RackTables-0.18.4-orig/inc/ophandlers.php rt-filecache-branch/inc/ophandlers.php --- RackTables-0.18.4-orig/inc/ophandlers.php 2010-07-05 13:07:09.000000000 -0400 +++ rt-filecache-branch/inc/ophandlers.php 2010-09-21 20:43:14.000000000 -0400 @@ -1885,6 +1885,8 @@ if (FALSE === commitReplaceFile ($sic['file_id'], $fp)) return buildRedirectURL (__FUNCTION__, 'ERR3'); + commitDeleteFileCache ($sic['file_id']); + return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name']))); } diff -ru RackTables-0.18.4-orig/render_image.php rt-filecache-branch/render_image.php --- RackTables-0.18.4-orig/render_image.php 2010-06-24 09:42:17.000000000 -0400 +++ rt-filecache-branch/render_image.php 2010-09-18 19:22:42.000000000 -0400 @@ -1,6 +1,5 @@ <?php - ob_start(); try { require 'inc/init.php'; @@ -198,26 +197,37 @@ echo $file['contents']; break; case 'preview': - $file = getFile ($file_id); - $image = imagecreatefromstring ($file['contents']); - unset ($file); - $width = imagesx ($image); - $height = imagesy ($image); - if ($width > getConfigVar ('PREVIEW_IMAGE_MAXPXS') or $height > getConfigVar ('PREVIEW_IMAGE_MAXPXS')) - { - // TODO: cache thumbs for faster page generation - $ratio = getConfigVar ('PREVIEW_IMAGE_MAXPXS') / max ($width, $height); - $newwidth = $width * $ratio; - $newheight = $height * $ratio; - $resampled = imagecreatetruecolor ($newwidth, $newheight); - imagecopyresampled ($resampled, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); - imagedestroy ($image); - $image = $resampled; - unset ($resampled); + if(!($image = getFileCache($file_id))){ + $file = getFile ($file_id); + $image = imagecreatefromstring ($file['contents']); + unset ($file['contents']); + $width = imagesx ($image); + $height = imagesy ($image); + if ($width > getConfigVar ('PREVIEW_IMAGE_MAXPXS') or $height > getConfigVar ('PREVIEW_IMAGE_MAXPXS')) + { + // TODO: cache thumbs for faster page generation + $ratio = getConfigVar ('PREVIEW_IMAGE_MAXPXS') / max ($width, $height); + $newwidth = $width * $ratio; + $newheight = $height * $ratio; + $resampled = imagecreatetruecolor ($newwidth, $newheight); + imagecopyresampled ($resampled, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); + imagedestroy ($image); + $image = $resampled; + + //TODO: Find a better way to save the stream of the image... Output buffer seems silly. + ob_start(); + imagejpeg($image); + commitAddFileCache($file_id, $file['mtime'], ob_get_contents()); + ob_flush(); + + imagedestroy ($image); + unset ($file); + unset ($resampled); + } + } - header("Content-type: image/png"); // don't announce content-length, it may have changed after resampling - imagepng ($image); - imagedestroy ($image); + header("Content-type: image/jpeg"); // don't announce content-length, it may have changed after resampling + if($image !== false) echo $image; break; default: showError ('Invalid argument', __FUNCTION__); |
2010-09-22 01:06
|
|
Per Denis Ovsienko's suggestion I've added an alternate version (marked v2) that inserts the thumbnails into a column of the file table. | |
Committed to trunk with some minor justifications. Having reviewed this, I see, that the old (rack) thumbnail management also needs a cleanup. This code will be seen in 0.19 series (because it involves a schema change). Thank you. | |
Could you review this? [Sun Nov 21 15:14:05 2010] [error] [client 127.0.0.1] PHP Warning: strtotime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Europe/Moscow' for 'MSK/3.0/no DST' instead in /var/www/html/racktables/render_image.php on line 9, referer: http://localhost/racktables/index.php?page=rack&tab=default&rack_id=48 [Sun Nov 21 15:14:14 2010] [error] [client 127.0.0.1] PHP Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Europe/Moscow' for 'MSK/3.0/no DST' instead in /var/www/html/racktables/render_image.php on line 43, referer: http://localhost/racktables/index.php?page=object&object_id=906 |
|
According to php.net it looks like this is a new feature in PHP 5.1.0 to deal with invalid local timezones (or invalid in PHP's eyes at least), try adding this code somewhere in the init of the script: if(date_default_timezone_set(ini_get('date.timezone') === FALSE) date_default_timezone_set('UTC'); |
|
I was able to reproduce in a test environment and it looks like the issue is caused by PHP's use of non-standard timezone naming (see http://nl3.php.net/manual/en/timezones.php) Setting this line in php.ini on the host got rid of the errors. date.timezone = Europe/Moscow I'd say there are three options; tell the user to set the timezone in php.ini if they see these errors, stick the silence operator (@) in front of all the functions that are generating it as it still seems to get the right TZ (however I imagine there are cases where this could cause problems, like if the user has a totally nonsensical timezone configured), or prompt for a timezone at Install and store it as a config variable (would not be very difficult, just a select box with DateTimeZone::listIdentifiers which is built into PHP). |
|
A fix is committed. | |
Date Modified | Username | Field | Change |
---|---|---|---|
2010-09-18 23:40 | f0urtyfive | New Issue | |
2010-09-18 23:40 | f0urtyfive | File Added: FileCache.diff | |
2010-09-18 23:40 | f0urtyfive | File Added: FileCache.sql | |
2010-09-22 01:06 | f0urtyfive | File Added: FileCache-v2.diff | |
2010-09-22 01:06 | f0urtyfive | File Added: FileCache-v2.sql | |
2010-09-22 01:07 | f0urtyfive | Note Added: 0000134 | |
2010-10-09 11:09 | infrastation | Status | new => assigned |
2010-10-09 11:09 | infrastation | Assigned To | => infrastation |
2010-10-28 20:55 | infrastation | Note Added: 0000167 | |
2010-10-28 20:55 | infrastation | Status | assigned => resolved |
2010-10-28 20:55 | infrastation | Resolution | open => fixed |
2010-10-28 20:55 | infrastation | Fixed in Version | => 0.19.0 |
2010-10-28 20:55 | infrastation | Target Version | => 0.19.0 |
2010-11-21 13:39 | infrastation | Note Added: 0000189 | |
2010-11-21 13:39 | infrastation | Status | resolved => feedback |
2010-11-21 13:39 | infrastation | Resolution | fixed => reopened |
2011-01-07 19:40 | f0urtyfive | Note Added: 0000214 | |
2011-01-08 17:30 | f0urtyfive | Note Added: 0000217 | |
2011-01-11 11:21 | infrastation | Note Added: 0000219 | |
2011-01-11 11:21 | infrastation | Status | feedback => closed |
2011-01-11 11:21 | infrastation | Resolution | reopened => fixed |
2019-01-08 11:55 | infrastation | Source_changeset_attached | => RackTables master b6993903 |