From: garvinhicking Date: Fri, 10 Feb 2006 13:43:43 +0000 (+0000) Subject: Commit on-the-fly image synchronization by Marty. X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=9293c95352de6df6ef1378b45e720ce238a2eabb;p=s9y.git Commit on-the-fly image synchronization by Marty. Currently in debugging state. --- diff --git a/docs/NEWS b/docs/NEWS index 2fb8895..b9a3db0 100644 --- a/docs/NEWS +++ b/docs/NEWS @@ -3,7 +3,10 @@ Version 1.1-alpha1() ------------------------------------------------------------------------ - * Added first patches for image directory permissions. (garvinhicking) + * Added on-the-fly synchronizing of the Serendipity media database + with the file system (Marty, garvinhicking) + + * Introduce permission setup for media directories (garvinhicking) * Added config option for specifying number of entries in the RSS feed (garvinhicking) diff --git a/include/functions.inc.php b/include/functions.inc.php index 7d58a37..80c4366 100644 --- a/include/functions.inc.php +++ b/include/functions.inc.php @@ -967,5 +967,18 @@ function serendipity_updateCategory($cid, $name, $desc, $authorid, $icon, $paren } +if (!function_exists('microtime_float')) { + /** + * Get current timestamp as microseconds + * + * @access public + * @return float the time + */ + function microtime_float() { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } +} + define("serendipity_FUNCTIONS_LOADED", true); /* vim: set sts=4 ts=4 expandtab : */ diff --git a/include/functions_images.inc.php b/include/functions_images.inc.php index a5e6b51..18565b9 100644 --- a/include/functions_images.inc.php +++ b/include/functions_images.inc.php @@ -231,7 +231,13 @@ function serendipity_fetchImages($group = false, $start = 0, $end = 20, $images $basedir = $serendipity['serendipityPath'] . $serendipity['uploadPath']; $images = array(); if ($dir = @opendir($basedir . $odir)) { - while(false !== ($f = readdir($dir))) { + $aTempArray = array(); + while (($file = @readdir($dir)) !== false) { + array_push($aTempArray, $file); + } + @closedir($dir); + sort($aTempArray); + foreach($aTempArray as $f) { if ($f != '.' && $f != '..' && strpos($f, $serendipity['thumbSuffix']) === false) { $cdir = ($odir != '' ? $odir . '/' : ''); if (is_dir($basedir . $odir . '/' . $f)) { @@ -345,7 +351,7 @@ function serendipity_insertHotlinkedImageInDatabase($filename, $url, $authorid = function serendipity_insertImageInDatabase($filename, $directory, $authorid = 0, $time = NULL) { global $serendipity; - if ( is_null($time) ) { + if (is_null($time)) { $time = time(); } @@ -1139,6 +1145,128 @@ function serendipity_displayImageList($page = 0, $lineBreak = NULL, $manage = fa $perPage = (!empty($serendipity['GET']['sortorder']['perpage']) ? $serendipity['GET']['sortorder']['perpage'] : $sort_row_interval[0]); $start = ($page-1) * $perPage; + ## SYNCH START ## + $aExclude = array("CVS" => true, ".svn" => true); + serendipity_plugin_api::hook_event('backend_media_path_exclude_directories', $aExclude); + $paths = array(); + $aFilesOnDisk = array(); + + $aResultSet = serendipity_traversePath( + $serendipity['serendipityPath'] . $serendipity['uploadPath']. $limit_path, + '', + false, + NULL, + 1, + NULL, + FALSE, + $aExclude + ); + + foreach ($aResultSet AS $sKey => $sFile) { + if ($sFile['directory']) { + echo "{$sFile['relpath']} is a directory.
"; #DEBUG + array_push($paths, $sFile); + } else { + echo "{$sFile['relpath']} is a file.
"; #DEBUG + // Store the file in our array, remove any ending slashes + $aFilesOnDisk[$sFile['relpath']] = 1; + } + unset($aResultSet[$sKey]); + } + sort($paths); + echo "

Got files:

" . print_r($aFilesOnDisk, true) . "

"; #DEBUG + $serendipity['current_image_hash'] = md5(serialize($aFilesOnDisk)); + $serendipity['current_image_hash'] = md5(time()); #DEBUGGING + + $nTimeStart = microtime_float(); + // MTG 21/01/06: request all images from the database, delete any which don't exist + // on the filesystem, and mark off files from the file list which are already + // in the database + + $nCount = 0; + if (serendipity_checkPermission('adminImagesSync') && $serendipity['current_image_hash'] != $serendipity['last_image_hash']) { + $aResultSet = serendipity_db_query("SELECT path, name, extension, thumbnail_name, id + FROM {$serendipity['dbPrefix']}images", false, 'assoc'); + echo "

Got images:

" . print_r($aResultSet, true) . "

"; #DEBUG + if (is_array($aResultSet)) { + foreach ($aResultSet AS $sKey => $sFile) { + serendipity_plugin_api::hook_event('backend_thumbnail_filename_select', $sFile); + $sThumbNailFile = ''; + if (isset($sFile['thumbnail_filename'])) { + $sThumbNailFile = $sFile['thumbnail_filename']; + } else { + $sThumbNailFile = $sFile['path'] . $sFile['name'] . '.' . $sFile['thumbnail_name'] . '.' . $sFile['extension']; + } + + $sFileName = $sFile['path'] . $sFile['name'] . '.' . $sFile['extension']; + echo "

File name is $sFileName,
thumbnail is $sThumbNailFile

"; #DEBUG + unset($aResultSet[$sKey]); + + if (isset($aFilesOnDisk[$sFileName])){ + unset($aFilesOnDisk[$sFileName]); + } else { + echo "Deleting Image {$sFile['id']}
\n"; #DEBUG + #serendipity_deleteImage($sFile['id']); #DEBUGGING + ++$nCount; + } + + unset($aFilesOnDisk[$sThumbNailFile]); + } + } + + if ($nCount > 0){ + echo "

Cleaned up ".$nCount." database entries

"; #DEBUG + } + + serendipity_set_config_var('last_image_hash', $serendipity['current_image_hash'], 0); + $aUnmatchedOnDisk = array_keys($aFilesOnDisk); + echo "

Got unmatched files:

" . print_r($aUnmatchedOnDisk, true) . "

"; #DEBUG + $nCount = 0; + foreach ($aUnmatchedOnDisk AS $sFile) { + if (preg_match('@\.' . $serendipity['thumbSuffix'] . '\.@', $sFile)) { + echo "

Skipping thumbnailed file $sFile

"; #DEBUG + continue; + } else { + echo "

Checking $sFile

"; #DEBUG + } + + // MTG: 21/01/06: put files which have just 'turned up' into the database + $aImageData = serendipity_getImageData($sFile); + if (serendipity_isImage($aImageData)) { + $nPos = strrpos($sFile, "/"); + if (is_bool($nPos) && !$nPos) { + $sFileName = $sFile; + $sDirectory = ""; + } else { + ++$nPos; + $sFileName = substr($sFile, $nPos); + $sDirectory = substr($sFile, 0, $nPos); + } + echo "

Inserting image $sFileName from $sDirectory

" . print_r($aImageData, true) . "
into database

"; #DEBUG + # TODO: Check if the thumbnail generation goes fine with Marty's code + serendipity_makeThumbnail($sFileName, $sDirectory); + serendipity_insertImageInDatabase($sFileName, $sDirectory); + ++$nCount; + } + } + + if ($nCount > 0) { + echo "

Inserted ".$nCount." images into the database

"; #DEBUG + } + } else { + echo "

Media Gallery database is up to date

"; #DEBUG + } + + /* + $nTimeEnd = microtime_float ( ); + $nDifference = $nTimeEnd - $nTimeStart; + echo "

total time taken was " . $nDifference . "

"; + */ + ## SYNCH FINISHED ## + + ## Aply ACL afterwards: + serendipity_directoryACL($paths, 'read'); + $serendipity['imageList'] = serendipity_fetchImagesFromDatabase( $start, $perPage, @@ -1153,16 +1281,6 @@ function serendipity_displayImageList($page = 0, $lineBreak = NULL, $manage = fa $linkPrevious = '?' . $extraParems . 'serendipity[page]=' . ($page-1); $linkNext = '?' . $extraParems . 'serendipity[page]=' . ($page+1); $sort_order = serendipity_getImageFields(); - $paths = serendipity_traversePath( - $serendipity['serendipityPath'] . $serendipity['uploadPath']. $limit_path, - '', - true, - NULL, - 1, - NULL, - 'read' - ); - if (is_null($lineBreak)) { $lineBreak = floor(750 / ($serendipity['thumbSize'] + 20)); } @@ -1233,7 +1351,7 @@ function serendipity_displayImageList($page = 0, $lineBreak = NULL, $manage = fa - +
- -
@@ -1242,11 +1360,11 @@ function serendipity_displayImageList($page = 0, $lineBreak = NULL, $manage = fa
@@ -1258,9 +1376,12 @@ function serendipity_displayImageList($page = 0, $lineBreak = NULL, $manage = fa $x = 0; foreach ($serendipity['imageList'] as $k => $file) { ++$x; $preview = ''; - $img = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . '.' . $file['extension']; - $i = @getimagesize($img); - $file['imgsrc'] = $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . '.' . $file['extension']; + $sThumbSource = serendipity_getThumbNailPath($file['path'], $file['name'], $file['extension'], $file['thumbnail_name']); + $img = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $sThumbSource; + if (!isset($file['imgsrc'])) { + $file['imgsrc'] = $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . '.' . $file['extension']; + } + $i = @getimagesize($img); $is_image = serendipity_isImage($file); if (!($serendipity['authorid'] == $file['authorid'] || $file['authorid'] == '0' || serendipity_checkPermission('adminImagesViewOthers'))) { @@ -1270,7 +1391,7 @@ function serendipity_displayImageList($page = 0, $lineBreak = NULL, $manage = fa /* If it is an image, and the thumbnail exists */ if ($is_image && file_exists($img)) { - $preview .= ''. $file['name'] . ''; + $preview .= ''. $file['name'] . ''; if ($url) { $preview = ''. $preview .''; } @@ -1470,9 +1591,10 @@ function serendipity_killPath($basedir, $directory = '', $forceDelete = false) { * @param int Level of nesting (recursive use) * @param int The maximum level of nesting (recursive use) * @param mixed Toggle whether to apply serendipity_directoryACL (false / 'read' / 'write') + * @param array An array of directories to skip [passed by plugins, for example] * @return array Array of files/directories */ -function serendipity_traversePath($basedir, $dir='', $onlyDirs = true, $pattern = NULL, $depth = 1, $max_depth = null, $apply_ACL = false) { +function serendipity_traversePath($basedir, $dir='', $onlyDirs = true, $pattern = NULL, $depth = 1, $max_depth = NULL, $apply_ACL = false, $aExcludeDirs = NULL) { $odir = serendipity_dirSlash('end', $basedir) . serendipity_dirSlash('end', $dir); $dh = @opendir($odir); @@ -1482,20 +1604,27 @@ function serendipity_traversePath($basedir, $dir='', $onlyDirs = true, $pattern $files = array(); while (($file = @readdir($dh)) !== false) { - if ( $file != '.' && $file != '..' ) { - if ( $onlyDirs === false || ($onlyDirs === true && is_dir($odir . $file)) ) { - if ( is_null($pattern) || preg_match($pattern, $file) ) { + if ($file != '.' && $file != '..') { + $bPatternMatch = (is_null($pattern) || preg_match($pattern, $file)); + $sFullPath = $odir . $file; + $bIsDir = is_dir($sFullPath); + if ($onlyDirs === false || $bIsDir) { + if ($bPatternMatch && + (!$bIsDir || $aExcludeDirs == null || !isset($aExcludeDirs[$file]))) { $files[] = array( - 'name' => $file, - 'depth' => $depth, - 'relpath' => ltrim(str_replace('\\', '/', serendipity_dirSlash('end', $dir)) . basename($file) . '/', '/') + 'name' => $file, + 'depth' => $depth, + 'relpath' => ltrim(str_replace('\\', '/', serendipity_dirSlash('end', $dir)) . basename($file) . ($bIsDir ? '/' : ''), '/'), + 'directory' => $bIsDir ); } } - if (is_dir($odir . $file) && ($max_depth === null || $depth < $max_depth)) { + if ($bIsDir && + ($max_depth === null || $depth < $max_depth) && + ($aExcludeDirs == null || !isset($aExcludeDirs[$file]))) { $next_dir = serendipity_dirSlash('end', $dir) . basename($file); - $files = array_merge($files, serendipity_traversePath($basedir, $next_dir, $onlyDirs, $pattern, ($depth+1), $max_depth)); + $files = array_merge($files, serendipity_traversePath($basedir, $next_dir, $onlyDirs, $pattern, ($depth+1), $max_depth, $apply_ACL, $aExcludeDirs)); } } } @@ -1762,4 +1891,80 @@ function serendipity_directoryACL(&$paths, $type = 'read') { } return true; -} \ No newline at end of file +} + + /** + * Build the name of a thumbnail image file. + * + * @author MTG + * @param string Relative Path + * @param string File name + * @param string File extension + * @param string Thumbnail suffix + * @return array Thumbnail path + * + */ +function serendipity_getThumbNailPath($sRelativePath, $sName, $sExtension, $sThumbName) { + $aTempArray = array('path' => $sRelativePath, + 'name' => $sName, + 'extension' => $sExtension); + serendipity_plugin_api::hook_event('backend_thumbnail_filename_select', $aTempArray); + + if (isset($aTempArray['thumbnail_filename'])) { + $sThumbNailPath = $aTempArray['thumbnail_filename']; + } else { + $sThumbNailPath = $sRelativePath . $sName . (!empty($sThumbName) ? '.' . $sThumbName : '') . '.' . $sExtension; + } + + return $sThumbNailPath; +} + + /** + * Given a relative path to an image, construct an array containing all + * relevant information about that image in the file structure. + * + * @author MTG + * @param string Relative Path + * @return array Data about image + * + */ +function serendipity_getImageData($sRelativePath) { + global $serendipity; + + // First, peel off the file name from the path + $nPos = strrpos($sRelativePath, '/'); + if (is_bool($nPos) && !$nPos) { + $sFileName = $sRelativePath; + $sDirectory = ''; + } else { + $nLastSlashPos = 1 + $nPos; + $sFileName = substr($sRelativePath, $nLastSlashPos); + $sDirectory = substr($sRelativePath, 0, $nLastSlashPos); + } + + list($sName, $sExtension) = serendipity_parseFileName($sFileName); + + $sImagePath = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $sRelativePath; + + $aSizeData = @serendipity_getimagesize($sImagePath , '', $sExtension); + $nWidth = $aSizeData[0]; + $nHeight = $aSizeData[1]; + $sMime = $aSizeData['mime']; + $nFileSize = @filesize($sImagePath); + + $array = array( + 'name' => $sName, + 'extension' => $sExtension, + 'mime' => $sMime, + 'size' => $nFileSize, + 'dimensions_width' => $nWidth, + 'dimensions_height' => $nHeight, + 'path' => $sDirectory, + 'authorid' => 0, + 'hotlink' => 0, + 'id' => $sRelativePath + ); + + return $array; +} + diff --git a/serendipity_admin_image_selector.php b/serendipity_admin_image_selector.php index 9708d74..095a134 100644 --- a/serendipity_admin_image_selector.php +++ b/serendipity_admin_image_selector.php @@ -115,14 +115,16 @@ switch ($serendipity['GET']['step']) { echo PERM_DENIED; break; } - $file['imgsrc'] = $serendipity['serendipityHTTPPath'] . $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . '.' . $file['extension']; + $sThumbNail = serendipity_getThumbNailPath($file['path'], $file['name'], $file['extension'], $file['thumbnail_name']); + $file['imgsrc'] = $serendipity['serendipityHTTPPath'] . $serendipity['uploadHTTPPath'] . $sThumbNail; + if ($file['hotlink']) { $imgName = $file['path']; } else { $imgName = $serendipity['serendipityHTTPPath'] . $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] .'.'. $file['extension']; } - $thumbbasename = $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . '.' . $file['extension']; + $thumbbasename = $sThumbNail; if ($file['hotlink']) { $thumbName = $file['path']; @@ -198,8 +200,11 @@ switch ($serendipity['GET']['step']) { />
- -
+ $serendipity['serendipityHTTPPath'] . $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] .'.'. $file['extension']); + serendipity_plugin_api::hook_event('frontend_image_selector_link_url', $aArray); + ?> +

- + - +