fullon rewamp without cache files, populating into the WP database unlike before and adding wp_extraexif_exiftool_vars filter to add/remove things to be read from the file

This commit is contained in:
Peter Molnar 2017-07-14 10:56:15 +00:00
parent cc04a4c0b3
commit 475f3569df

View file

@ -3,13 +3,13 @@
Plugin Name: wp-extraexif Plugin Name: wp-extraexif
Plugin URI: https://github.com/petermolnar/wp-extraexif Plugin URI: https://github.com/petermolnar/wp-extraexif
Description: Read EXIF for images with cli `exiftool` Description: Read EXIF for images with cli `exiftool`
Version: 0.4 Version: 1.0
Author: Peter Molnar <hello@petermolnar.net> Author: Peter Molnar <hello@petermolnar.eu>
Author URI: http://petermolnar.net/ Author URI: http://petermolnar.net/
License: GPLv3 License: GPLv3
*/ */
/* Copyright 2016 Peter Molnar ( hello@petermolnar.net ) /* Copyright 2016-2017 Peter Molnar ( hello@petermolnar.eu )
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 3, as it under the terms of the GNU General Public License, version 3, as
@ -25,241 +25,65 @@ License: GPLv3
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
namespace WP_EXTRAEXIF; add_action( 'init', 'WP_EXTRAEXIF_init' );
register_activation_hook( __FILE__ , 'WP_EXTRAEXIF_plugin_activate' );
\add_action( 'init', 'WP_EXTRAEXIF\init' );
\register_activation_hook( __FILE__ , '\WP_EXTRAEXIF\plugin_activate' );
//\register_deactivation_hook( __FILE__ , '\WP_EXTRAEXIF\plugin_deactivate' );
define ( 'WP_EXTRAEXIF\CACHE', \WP_CONTENT_DIR . DIRECTORY_SEPARATOR.
'cache' . DIRECTORY_SEPARATOR . 'exif' . DIRECTORY_SEPARATOR );
/** /**
* activate hook * activate hook
*/ */
function plugin_activate() { function WP_EXTRAEXIF_plugin_activate() {
if ( version_compare( phpversion(), 5.3, '<' ) ) { if ( ! function_exists( 'shell_exec' ) )
die( 'The minimum PHP version required for this plugin is 5.3' ); die("This plugin requires `exec` function to call `exiftool` and it is not available.");
}
$test = test_exiftool();
if ( true !== $test )
die ( $test );
$dirs = [ CACHE ];
foreach ( $dirs as $dir ) {
if ( ! is_dir( $dir ) ) {
if ( ! mkdir( $dir ) )
die( "failed to create {$dir}" );
}
}
}
/**
*
*/
function init() {
add_filter( 'wp_read_image_metadata', 'WP_EXTRAEXIF\read_extra_exif', 1, 3 );
$dirs = [ CACHE ];
foreach ( $dirs as $dir ) {
if ( ! is_dir( $dir ) ) {
if ( ! mkdir( $dir ) )
debug( "failed to create {$dir}", 4 );
}
}
}
/**
* check the existence and executability of exiftool
*
*/
function test_exiftool () {
if ( ! function_exists( 'exec' ) )
return "This plugin requires `exec` function which is not available.";
$cmd = 'exiftool -ver'; $cmd = 'exiftool -ver';
exec( $cmd, $path, $retval); $r = shell_exec( $cmd );
if ( 0 != $retval || empty( $path ) ) if ( empty( $r ) )
return "exiftool cannot be executed via `exec`. This plugin requires " die("exiftool cannot be executed via `exec`. This plugin requires `exiftool` to be installed on the system and available in \$PATH variable; please talk to your system administrator.");
. "exiftool to be installed on the system and available in \$PATH";
return true;
} }
/** /**
* additional EXIF which only exiftool can read
* *
*/ */
function read_extra_exif ( $meta, $path ='', $sourceImageType = '' ) { function WP_EXTRAEXIF_init() {
add_filter( 'wp_read_image_metadata', 'WP_EXTRAEXIF_read_meta', 1, 4 );
if ( empty( $path ) || ! is_file( $path ) || ! is_readable( $path )) { }
debug ( "{$path} doesn't exist", 4 );
return $meta;
}
if ( $sourceImageType != IMAGETYPE_JPEG ) {
debug ( "{$path} is not JPG", 5 );
return $meta;
}
$test = test_exiftool();
if ( true !== $test ) {
debug ( "can't find exiftool", 4 );
return $meta;
}
exif_cache( $path );
function WP_EXTRAEXIF_read_meta( $meta, $file, $sourceImageType, $iptc ) {
$meta = WP_EXTRAEXIF_run($meta, $file);
return $meta; return $meta;
} }
/** function WP_EXTRAEXIF_run($current_meta, $file) {
* if (isset($current_meta['extraexif']) && !empty($current_meta['extraexif'])) {
*/ return $current_meta;
function exif_gps2dec ( $string ) {
//103 deg 20' 38.33" E
preg_match( "/([0-9.]+)\s?+deg\s?+([0-9.]+)'\s?+([0-9.]+)\"\s?+([NEWS])/",
trim( $string ), $matches );
$dd = $matches[1] + ( ( ( $matches[2] * 60 ) + ( $matches[3] ) ) / 3600 );
if ( $matches[4] == "S" || $matches[4] == "W" )
$dd = $dd * -1;
return round($dd,6);
}
/**
*
*/
function exif_gps2alt ( $string ) {
//2062.6 m Above Sea Level
preg_match( "/([0-9.]+)\s?+m/", trim($string), $matches );
$alt = $matches[1];
if ( stristr( $string, 'below') )
$alt = $alt * -1;
return $alt;
}
/**
*
*/
function clear_cache() {
$list = scandir( CACHE );
foreach ($list as $key => $name ) {
$path = realpath( CACHE . $name );
if ( is_file( $path ) && ! in_array ( $name, array( '.', '..' ) ) ) {
unlink( $path );
}
}
}
/**
*
*/
function exif_cache( $jpg ) {
if ( ! is_file( $jpg ) ) {
debug( "nonexistent JPG file at {$jpg}", 4 );
return;
} }
$hash = md5 ( $jpg ); $vars = array('-sort', '-json', '-MIMEType', '-FileType', '-FileName', '-ModifyDate', '-CreateDate', '-DateTimeOriginal', '-ImageHeight', '-ImageWidth', '-Aperture', '-FOV', '-ISO', '-FocalLength', '-FNumber', '-FocalLengthIn35mmFormat', '-ExposureTime', '-Copyright', '-Artist', '-Model', '-GPSLongitude#', '-GPSLatitude#', '-LensID');
$cached = CACHE . $hash; $vars = apply_filters('wp_extraexif_exiftool_vars', $vars);
$img_timestamp = @filemtime ( $jpg ); array_unshift($vars, 'exiftool');
array_push($vars, $file);
$cmd = join(' ', $vars);
WP_EXTRAEXIF_debug("executing: {$cmd}", LOG_DEBUG);
if ( is_file( $cached ) ) { $meta = $current_meta;
$cache_timestamp = @filemtime ( $cached ); $out = shell_exec($cmd);
if ( $cache_timestamp == $img_timestamp ) { $out = json_decode($out);
//debug( "EXIF cache is present for {$jpg}", 7 ); $out = array_pop($out);
return json_decode ( file_get_contents( $cached ), true ); foreach($out as $mkey => $mvalue) {
} if(isset($current_meta['image_meta'][$mkey])) {
}
$filters = [
'Make',
'Camera Model Name',
'Aperture',
'GPS Altitude',
'GPS Latitude',
'GPS Longitude',
'Lens ID',
'Shutter Speed',
'Field Of View',
'Focal Length',
'Hyperfocal Distance',
'ISO',
'Create Date',
'Copyright Notice',
];
$filters = \apply_filters( 'wp_extraexif_list', $filters );
$merges = [
'Shutter Speed' => 'Exposure Time',
'Aperture' => 'F Number',
];
$merges = \apply_filters( 'wp_extraexif_merges', $merges );
$mapping = [
'Make' => 'make',
'Camera Model Name' => 'camera',
'Aperture' => 'aperture',
'GPS Altitude' => 'geo_altitude',
'GPS Latitude' => 'geo_latitude',
'GPS Longitude' => 'geo_longitude',
'Lens ID' => 'lens',
'Shutter Speed' => 'shutter_speed',
'Field Of View' => 'field_of_view',
'Focal Length' => 'focal_length',
'Hyperfocal Distance' => 'focus_distance',
'ISO' => 'iso',
'Create Date' => 'date',
'Copyright Notice' => 'copyright',
];
$mapping = \apply_filters( 'wp_extraexif_mapping', $mapping );
$cmd = "exiftool {$jpg}";
exec( $cmd, $exif_raw, $retval);
if ($retval != 0 )
die( "exiftool failed, exited with {$retval} and {$exif}" );
foreach ( $exif_raw as $l ) {
preg_match( '/^(.*?)\s+:\s+(.*)$/', $l, $data );
if ( empty( $data[0]) || empty( $data[1] ) || empty( $data[2] ) )
continue; continue;
if ( $data[1] == 'GPS Latitude' || $data[1] == 'GPS Longitude' )
$data[2] = exif_gps2dec( $data[2] );
elseif ( $data[1] == 'GPS Altitude' )
$data[2] = exif_gps2alt( $data[2] );
$exif [ $data[1] ] = $data[2];
} }
$r = array(); $current_meta['image_meta'][$mkey] = $mvalue;
foreach ( $filters as $filter ) {
if ( isset( $exif[ $filter ] ) )
$r[ $mapping [ $filter ] ] = $exif[ $filter ];
elseif ( isset( $merges[ $filter ] )
&& isset( $exif[ $merges[ $filter ] ] ) )
$r[ $mapping [ $filter ] ] = $exif[ $merges[ $filter ] ];
} }
ksort( $r ); $current_meta['extraexif'] = True;
WP_EXTRAEXIF_debug("returning: " . var_export($current_meta, True), LOG_DEBUG);
file_put_contents( $cached , json_encode( $r, JSON_PRETTY_PRINT ) ); return $current_meta;
touch( $cached, $img_timestamp );
debug( "EXIF cache is created for {$jpg}", 6 );
return $r;
} }
/** /**
* *
* debug messages; will only work if WP_DEBUG is on * debug messages; will only work if WP_DEBUG is on
@ -271,7 +95,7 @@ function exif_cache( $jpg ) {
* @output log to syslog | wp_die on high level * @output log to syslog | wp_die on high level
* @return false on not taking action, true on log sent * @return false on not taking action, true on log sent
*/ */
function debug( $message, $level = LOG_NOTICE ) { function WP_EXTRAEXIF_debug( $message, $level = LOG_NOTICE ) {
if ( empty( $message ) ) if ( empty( $message ) )
return false; return false;
@ -293,17 +117,9 @@ function debug( $message, $level = LOG_NOTICE ) {
// should work with the defines only, this is just a make-it-sure step // should work with the defines only, this is just a make-it-sure step
$level_ = $levels [ $level ]; $level_ = $levels [ $level ];
// in case WordPress debug log has a minimum level
if ( defined ( '\WP_DEBUG_LEVEL' ) ) {
$wp_level = $levels [ \WP_DEBUG_LEVEL ];
if ( $level_ > $wp_level ) {
return false;
}
}
// ERR, CRIT, ALERT and EMERG // ERR, CRIT, ALERT and EMERG
if ( 3 >= $level_ ) { if ( 3 >= $level_ ) {
\wp_die( '<h1>Error:</h1>' . '<p>' . $message . '</p>' ); wp_die( '<h1>Error:</h1>' . '<p>' . $message . '</p>' );
exit; exit;
} }
@ -311,11 +127,5 @@ function debug( $message, $level = LOG_NOTICE ) {
$caller = $trace[1]; $caller = $trace[1];
$parent = $caller['function']; $parent = $caller['function'];
if (isset($caller['class']))
$parent = $caller['class'] . '::' . $parent;
if (isset($caller['namespace']))
$parent = $caller['namespace'] . '::' . $parent;
return error_log( "{$parent}: {$message}" ); return error_log( "{$parent}: {$message}" );
} }