Read files directly from gallery or dedicated yaml file
This commit is contained in:
142
convert.php
142
convert.php
@@ -9,13 +9,43 @@ use Symfony\Component\Console\Input\InputOption;
|
|||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
|
function writeMetaYaml($sDir) {
|
||||||
|
$aMeta['dir'] = rtrim($sDir, '"\'/\\');
|
||||||
|
$aMeta['files'] = array();
|
||||||
|
if (file_exists($aMeta['dir'])) {
|
||||||
|
$aFiles = glob($aMeta['dir'] . '/*.jpg');
|
||||||
|
foreach ($aFiles as $sFile) {
|
||||||
|
$aMeta['files'][basename($sFile)] = ['title' => '', 'comment' => ''];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sYaml = str_replace("''", null, Yaml::dump($aMeta, 4, 2));
|
||||||
|
file_put_contents($sDir . '/meta.yaml', $sYaml);
|
||||||
|
}
|
||||||
|
// writeMetaYaml('C:\Users\Rik\Downloads\Blog\jekyll-gallery\in');
|
||||||
|
|
||||||
|
|
||||||
|
// $sTest = <<<TEST
|
||||||
|
// dir: C:\Users\Rik\Downloads\Blog\jekyll-gallery\in\*
|
||||||
|
// files:
|
||||||
|
// IMG_20151211_152349.jpg:
|
||||||
|
// comment:
|
||||||
|
// IMG_20151211_15234329.jpg:
|
||||||
|
// name: A Classic View
|
||||||
|
// title: Anders
|
||||||
|
// comment: |
|
||||||
|
// bla
|
||||||
|
// da
|
||||||
|
// TEST;
|
||||||
|
// print_r(Yaml::parse($sTest));
|
||||||
|
// exit;
|
||||||
$oConsole = new Application();
|
$oConsole = new Application();
|
||||||
|
|
||||||
$oConsole
|
$oConsole
|
||||||
->register('run')
|
->register('run')
|
||||||
->setDefinition([
|
->setDefinition([
|
||||||
new InputOption('export', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Target image export sizes'),
|
new InputOption('export', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Target image export sizes'),
|
||||||
new InputOption('layout', null, InputOption::VALUE_REQUIRED, 'Rendering layout for individual photos', 'gallery-photo'),
|
new InputOption('layout', null, InputOption::VALUE_REQUIRED, 'Rendering layout for individual images', 'gallery-photo'),
|
||||||
|
new InputOption('importdir', null, InputOption::VALUE_REQUIRED, 'Directory to scan for images'),
|
||||||
new InputArgument('name', null, InputArgument::REQUIRED, 'Gallery name'),
|
new InputArgument('name', null, InputArgument::REQUIRED, 'Gallery name'),
|
||||||
new InputArgument('assetdir', InputArgument::OPTIONAL, 'Asset directory for exported images', 'asset/gallery'),
|
new InputArgument('assetdir', InputArgument::OPTIONAL, 'Asset directory for exported images', 'asset/gallery'),
|
||||||
new InputArgument('mdowndir', InputArgument::OPTIONAL, 'Markdown directory for dumping individual photo details', 'gallery'),
|
new InputArgument('mdowndir', InputArgument::OPTIONAL, 'Markdown directory for dumping individual photo details', 'gallery'),
|
||||||
@@ -28,57 +58,79 @@ $oConsole
|
|||||||
')
|
')
|
||||||
->setCode(
|
->setCode(
|
||||||
function (InputInterface $oInput, OutputInterface $oOutput) {
|
function (InputInterface $oInput, OutputInterface $oOutput) {
|
||||||
|
// Get input arguments and options
|
||||||
$sGallery = $oInput->getArgument('name');
|
$sGallery = $oInput->getArgument('name');
|
||||||
$sAssetPath = $oInput->getArgument('assetdir') . '/' . $sGallery;
|
$sAssetPath = $oInput->getArgument('assetdir') . '/' . $sGallery;
|
||||||
$sRenderPath = $oInput->getArgument('mdowndir') . '/' . $sGallery;
|
$sRenderPath = $oInput->getArgument('mdowndir') . '/' . $sGallery;
|
||||||
|
$sImportDir = $oInput->getOption('importdir');
|
||||||
$sLayout = $oInput->getOption('layout');
|
$sLayout = $oInput->getOption('layout');
|
||||||
$sExports = $oInput->getOption('export');
|
$sExports = $oInput->getOption('export');
|
||||||
|
|
||||||
$sStdin = stream_get_contents(STDIN);
|
|
||||||
|
|
||||||
$oImagine = new Imagine\Gd\Imagine();
|
$oImagine = new Imagine\Gd\Imagine();
|
||||||
|
|
||||||
|
// Initialize directories
|
||||||
if (!is_dir($sAssetPath)) {
|
if (!is_dir($sAssetPath)) {
|
||||||
mkdir($sAssetPath, 0700, true);
|
mkdir($sAssetPath, 0700, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_dir($sRenderPath)) {
|
if (!is_dir($sRenderPath)) {
|
||||||
mkdir($sRenderPath, 0700, true);
|
mkdir($sRenderPath, 0700, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sStdinPhotos = explode('------------', trim($sStdin));
|
if (isset($sImportDir)) {
|
||||||
$aPhotos = [];
|
// Use provided directory
|
||||||
|
$sImportDir = rtrim($oInput->getOption('importdir'), '/\\');
|
||||||
// load data
|
} else {
|
||||||
foreach ($sStdinPhotos as $i => $aPhotoRaw) {
|
// Get directory and metadata from yaml
|
||||||
$aPhotoSplit = explode('------', trim($aPhotoRaw), 2);
|
$sStdin = stream_get_contents(STDIN);
|
||||||
|
$aYaml = Yaml::parse($sStdin);
|
||||||
if (empty($aPhotoSplit[0])) {
|
$sImportDir = rtrim($aYaml['dir'], '"\'/\\');
|
||||||
continue;
|
$aMeta = $aYaml['files'];
|
||||||
|
if (!isset($aYaml['all'])) {
|
||||||
|
$aFiles = array_keys($aYaml['files']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aPhoto = array_merge([
|
// Scan import directory for images
|
||||||
|
if (!isset($aFiles)) {
|
||||||
|
$aFiles = array_map('basename', glob($sImportDir . '/*.jpg'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop over files
|
||||||
|
$aPhotos = [];
|
||||||
|
foreach ($aFiles as $i => $sFile) {
|
||||||
|
// Build photo information
|
||||||
|
$aPhoto = [
|
||||||
|
'path' => $sImportDir . '/' . $sFile,
|
||||||
'ordering' => $i,
|
'ordering' => $i,
|
||||||
'comment' => isset($aPhotoSplit[1]) ? $aPhotoSplit[1] : null,
|
'name' => isset($aMeta[$sFile]['name']) ? $aMeta[$sFile]['name'] : null,
|
||||||
], Yaml::parse($aPhotoSplit[0]));
|
'comment' => isset($aMeta[$sFile]['comment']) ? $aMeta[$sFile]['comment'] : null
|
||||||
|
];
|
||||||
|
|
||||||
$aPhoto['id'] = substr(sha1_file($aPhoto['path']), 0, 7) . '-' . preg_replace('/(-| )+/', '-', preg_replace('/[^a-z0-9 ]/i', '-', preg_replace('/\'/', '', strtolower(preg_replace('/\p{Mn}/u', '', Normalizer::normalize($aPhoto['title'], Normalizer::FORM_KD))))));
|
// Generate id from file contents
|
||||||
$aPhoto['date'] = \DateTime::createFromFormat(
|
$aPhoto['id'] = substr(sha1_file($aPhoto['path']), 0, 7);
|
||||||
'l, F j, Y \a\t g:i:s A',
|
if (isset($aPhoto['title'])) {
|
||||||
$aPhoto['date']
|
$aPhoto['id'] .= '-' . preg_replace('/(-| )+/', '-', preg_replace('/[^a-z0-9 ]/i', '-', preg_replace('/\'/', '', strtolower(preg_replace('/\p{Mn}/u', '', Normalizer::normalize($aPhoto['title'], Normalizer::FORM_KD))))));
|
||||||
);
|
}
|
||||||
|
|
||||||
|
// Parse selected EXIF data
|
||||||
$aPhoto['exif'] = exif_read_data($aPhoto['path']);
|
$aPhoto['exif'] = exif_read_data($aPhoto['path']);
|
||||||
|
if (isset($aPhoto['exif']['GPSLongitude'])) {
|
||||||
|
$aPhoto = array_merge($aPhoto, [
|
||||||
|
'longitude' => coordinateToDegrees($aPhoto['exif']['GPSLongitude'], $aPhoto['exif']['GPSLongitudeRef']),
|
||||||
|
'latitude' => coordinateToDegrees($aPhoto['exif']['GPSLatitude'], $aPhoto['exif']['GPSLatitudeRef']),
|
||||||
|
'altitude' => fractionToFloat($aPhoto['exif']['GPSAltitude']),
|
||||||
|
'direction' => fractionToFloat($aPhoto['exif']['GPSImgDirection'])]);
|
||||||
|
}
|
||||||
|
$aPhoto['date'] = new DateTime($aPhoto['exif']['DateTimeOriginal']);
|
||||||
$aPhotos[] = $aPhoto;
|
$aPhotos[] = $aPhoto;
|
||||||
}
|
}
|
||||||
|
|
||||||
// manipulate
|
// Manipulate
|
||||||
foreach ($aPhotos as $i => $aPhoto) {
|
foreach ($aPhotos as $i => $aPhoto) {
|
||||||
$oOutput->write('<info>' . $aPhoto['id'] . '</info>');
|
$oOutput->write('<info>' . $aPhoto['id'] . '</info>');
|
||||||
|
|
||||||
$aPhoto['sizes'] = [];
|
$aPhoto['sizes'] = [];
|
||||||
|
|
||||||
// image exports
|
// Image exports
|
||||||
if (0 < count($sExports)) {
|
if (0 < count($sExports)) {
|
||||||
$oSourceJpg = $oImagine->open($aPhoto['path']);
|
$oSourceJpg = $oImagine->open($aPhoto['path']);
|
||||||
if (isset($aPhoto['exif']['Orientation'])) {
|
if (isset($aPhoto['exif']['Orientation'])) {
|
||||||
@@ -108,7 +160,7 @@ $oConsole
|
|||||||
}
|
}
|
||||||
|
|
||||||
$oSourceSize = $oSourceJpg->getSize();
|
$oSourceSize = $oSourceJpg->getSize();
|
||||||
$oOutput->write('[' . $oSourceSize->getWidth() . 'x' . $oSourceSize->getHeight() . ']...');
|
$oOutput->writeln(' [' . $oSourceSize->getWidth() . 'x' . $oSourceSize->getHeight() . ']...');
|
||||||
|
|
||||||
foreach ($sExports as $sExport) {
|
foreach ($sExports as $sExport) {
|
||||||
$oOutput->write(' <comment>' . $sExport . '</comment>');
|
$oOutput->write(' <comment>' . $sExport . '</comment>');
|
||||||
@@ -146,10 +198,10 @@ $oConsole
|
|||||||
'height' => $sExportsize->getHeight(),
|
'height' => $sExportsize->getHeight(),
|
||||||
];
|
];
|
||||||
|
|
||||||
$oOutput->write('[' . $sExportsize->getWidth() . 'x' . $sExportsize->getHeight() . ']');
|
$oOutput->writeln(' [' . $sExportsize->getWidth() . 'x' . $sExportsize->getHeight() . ']');
|
||||||
|
|
||||||
$sExportPath = $sAssetPath . '/' . $aPhoto['id'] . '~' . $sExport . '.jpg';
|
$sExportPath = $sAssetPath . '/' . $aPhoto['id'] . '~' . $sExport . '.jpg';
|
||||||
|
|
||||||
|
// Write converted image
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
$sExportPath,
|
$sExportPath,
|
||||||
$sExportImage->get('jpeg', ['quality' => 90])
|
$sExportImage->get('jpeg', ['quality' => 90])
|
||||||
@@ -157,21 +209,19 @@ $oConsole
|
|||||||
|
|
||||||
touch($sExportPath, $aPhoto['date']->getTimestamp());
|
touch($sExportPath, $aPhoto['date']->getTimestamp());
|
||||||
$sExportImage = null;
|
$sExportImage = null;
|
||||||
$oOutput->write('...');
|
|
||||||
}
|
}
|
||||||
$oSourceJpg = null;
|
$oSourceJpg = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oOutput->write('<comment>markdown</comment>...');
|
$oOutput->write(' <comment>markdown</comment>');
|
||||||
|
|
||||||
$aMatter = [
|
$aMatter = [
|
||||||
'layout' => $sLayout,
|
'layout' => $sLayout,
|
||||||
'title' => $aPhoto['title'],
|
'title' => isset($aPhoto['title']) ? $aPhoto['title'] : null,
|
||||||
'date' => $aPhoto['date']->format('Y-m-d H:i:s'),
|
'date' => $aPhoto['date']->format('Y-m-d H:i:s'),
|
||||||
'ordering' => $aPhoto['ordering']
|
'ordering' => $aPhoto['ordering']
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($aPhoto['exif']) {
|
if (isset($aPhoto['exif']['Make'])) {
|
||||||
$aMatter['exif'] = [
|
$aMatter['exif'] = [
|
||||||
'make' => $aPhoto['exif']['Make'],
|
'make' => $aPhoto['exif']['Make'],
|
||||||
'model' => $aPhoto['exif']['Model'],
|
'model' => $aPhoto['exif']['Model'],
|
||||||
@@ -188,7 +238,7 @@ $oConsole
|
|||||||
$aMatter['next'] = '/gallery/' . $sGallery . '/' . $aPhotos[$i + 1]['id'];
|
$aMatter['next'] = '/gallery/' . $sGallery . '/' . $aPhotos[$i + 1]['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($aPhoto['latitude']) {
|
if (isset($aPhoto['latitude'])) {
|
||||||
$aMatter['location'] = [
|
$aMatter['location'] = [
|
||||||
'latitude' => $aPhoto['latitude'],
|
'latitude' => $aPhoto['latitude'],
|
||||||
'longitude' => $aPhoto['longitude'],
|
'longitude' => $aPhoto['longitude'],
|
||||||
@@ -200,7 +250,6 @@ $oConsole
|
|||||||
}
|
}
|
||||||
|
|
||||||
ksort_recursive($aMatter);
|
ksort_recursive($aMatter);
|
||||||
|
|
||||||
uasort(
|
uasort(
|
||||||
$aMatter['sizes'],
|
$aMatter['sizes'],
|
||||||
function ($aA, $aB) {
|
function ($aA, $aB) {
|
||||||
@@ -208,10 +257,11 @@ $oConsole
|
|||||||
$iSurfaceB = $aB['width'] * $aB['height'];
|
$iSurfaceB = $aB['width'] * $aB['height'];
|
||||||
return $iSurfaceA == $iSurfaceB
|
return $iSurfaceA == $iSurfaceB
|
||||||
? 0
|
? 0
|
||||||
: (($aa > $bb)? -1 : 1);
|
: (($iSurfaceA > $iSurfaceB)? -1 : 1);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Write Markdown file
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
$sRenderPath . '/' . $aPhoto['id'] . '.md',
|
$sRenderPath . '/' . $aPhoto['id'] . '.md',
|
||||||
'---' . "\n" . Yaml::dump($aMatter, 4, 2) . '---' . "\n" . ((!empty($aPhoto['comment'])) ? ($aPhoto['comment'] . "\n") : '')
|
'---' . "\n" . Yaml::dump($aMatter, 4, 2) . '---' . "\n" . ((!empty($aPhoto['comment'])) ? ($aPhoto['comment'] . "\n") : '')
|
||||||
@@ -219,7 +269,8 @@ $oConsole
|
|||||||
|
|
||||||
$oOutput->writeln(' done');
|
$oOutput->writeln(' done');
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$oConsole->run(new ArgvInput(array_merge([$_SERVER['argv'][0], 'run' ], array_slice($_SERVER['argv'], 1))));
|
$oConsole->run(new ArgvInput(array_merge([$_SERVER['argv'][0], 'run' ], array_slice($_SERVER['argv'], 1))));
|
||||||
|
|
||||||
@@ -233,3 +284,22 @@ function ksort_recursive(&$aArray, $mSortFlags = SORT_REGULAR) {
|
|||||||
ksort($aArray, $mSortFlags);
|
ksort($aArray, $mSortFlags);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function coordinateToDegrees($aCoordinate, $sHemisphere) {
|
||||||
|
$aCoordinate = array_map('fractionToFloat', $aCoordinate);
|
||||||
|
$aDegrees = array_map(function ($a, $b) {
|
||||||
|
return $a / $b;
|
||||||
|
}, $aCoordinate, array(1, 60, 3600));
|
||||||
|
$iFlip = ($sHemisphere == 'W' or $sHemisphere == 'S') ? -1 : 1;
|
||||||
|
return $iFlip * array_sum($aDegrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fractionToFloat($sFraction) {
|
||||||
|
$aParts = explode('/', $sFraction);
|
||||||
|
$iParts = count($aParts);
|
||||||
|
return $iParts
|
||||||
|
? ($iParts > 1
|
||||||
|
? floatval($aParts[0]) / floatval($aParts[1])
|
||||||
|
: $aParts[0])
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user