Offline
Gnagh.. sorry, I was totally off the other direction, reading/writing metadata to database..
Offline
erAck wrote:
Gnagh.. sorry, I was totally off the other direction, reading/writing metadata to database..
No worries :-) Thank you!
Offline
1. Write info from database to original jpg file (IPTC) with the write metadata plugin (including date_available and date_creation). ✔
2. Copy jpg ALL IPTC data to new version of file with Exiftool. ✔
3. Sync the new version jpg file with database. ✔
4. Write html code from database in plain text to the IPTC description field with Write metadata plugin. FAILED!
5. Check logfile for errors when trying to write html (Exiftool doesn't write logfiles according to author) FAILED
6. What to do next??
Last edited by BigIsland270972 (2023-03-02 17:44:10)
Offline
UPDATE!!
/plugins/write_metadata/main.inc.php
Added support for writing GPS location from database. You can then import GPS location from image file when syncronizing.
<?php /* Plugin Name: Write Metadata Description: Write Piwigo photo properties (title, description, author, tags) into IPTC fields Author: plg Plugin URI: http://piwigo.org/ext/extension_view.php?eid=769 Version: 12.a */ // +-----------------------------------------------------------------------+ // | Define plugin constants | // +-----------------------------------------------------------------------+ defined('WRITE_METADATA_ID') or define('WRITE_METADATA_ID', basename(dirname(__FILE__))); define('WRITE_METADATA_PATH' , PHPWG_PLUGINS_PATH.basename(dirname(__FILE__)).'/'); // +-----------------------------------------------------------------------+ // | Edit Photo | // +-----------------------------------------------------------------------+ add_event_handler('loc_begin_admin_page', 'wm_add_link', 60); function wm_add_link() { global $template, $page; $template->set_prefilter('picture_modify', 'wm_add_link_prefilter'); if (isset($page['page']) and 'photo' == $page['page']) { $template->assign( 'U_WRITEMETADATA', get_root_url().'admin.php?page=photo-'.$_GET['image_id'].'-properties&write_metadata=1' ); } } function wm_add_link_prefilter($content) { $search = '{if !url_is_remote($PATH)}'; $replacement = '{if !url_is_remote($PATH)} <a class="icon-docs" href="{$U_WRITEMETADATA}" title="{\'Write metadata\'|translate}"></a>'; return str_replace($search, $replacement, $content); } add_event_handler('loc_begin_admin_page', 'wm_picture_write_metadata'); function wm_picture_write_metadata() { global $page, $conf; load_language('plugin.lang', dirname(__FILE__).'/'); if (isset($page['page']) and 'photo' == $page['page'] and isset($_GET['write_metadata'])) { check_input_parameter('image_id', $_GET, false, PATTERN_ID); list($rc, $output) = wm_write_metadata($_GET['image_id']); if (count($output) == 0) { $_SESSION['page_infos'][] = l10n('Metadata written into file'); redirect(get_root_url().'admin.php?page=photo-'.$_GET['image_id'].'-properties'); } else { $page['errors'] = array_merge($page['errors'], $output); } } } // +-----------------------------------------------------------------------+ // | Batch Manager | // +-----------------------------------------------------------------------+ add_event_handler('loc_begin_element_set_global', 'wm_element_set_global_add_action'); function wm_element_set_global_add_action() { global $template, $page; $template->set_filename('writeMetadata', realpath(WRITE_METADATA_PATH.'element_set_global_action.tpl')); if (isset($_POST['submit']) and $_POST['selectAction'] == 'writeMetadata') { $page['infos'][] = l10n('Metadata written into file'); } $template->assign( array( 'WM_PWG_TOKEN' => get_pwg_token(), ) ); $template->append( 'element_set_global_plugins_actions', array( 'ID' => 'writeMetadata', 'NAME' => l10n('Write metadata'), 'CONTENT' => $template->parse('writeMetadata', true), ) ); } add_event_handler('ws_add_methods', 'wm_add_methods'); function wm_add_methods($arr) { include_once(WRITE_METADATA_PATH.'ws_functions.inc.php'); } // +-----------------------------------------------------------------------+ // | Common functions | // +-----------------------------------------------------------------------+ /** * inspired by convert_row_to_file_exiftool method in ExportImageMetadata * class from plugin Tags2File. In plugin write_medata we just skip the * batch command file, and execute directly on server (much more user * friendly...). */ function wm_write_metadata($image_id) { global $conf, $logger; $query = ' SELECT img.name, img.comment, img.author, img.date_creation, img.date_available, img.latitude, img.longitude, GROUP_CONCAT(tags.name) AS tags, img.path, img.representative_ext FROM '.IMAGES_TABLE.' AS img LEFT OUTER JOIN '.IMAGE_TAG_TABLE.' AS img_tag ON img_tag.image_id = img.id LEFT OUTER JOIN '.TAGS_TABLE.' AS tags ON tags.id = img_tag.tag_id WHERE img.id = '.$image_id.' GROUP BY img.id, img.name, img.comment, img.author, img.path, img.representative_ext ;'; $result = pwg_query($query); $row = pwg_db_fetch_assoc($result); $name = wm_prepare_string($row['name'], 500); $description = wm_prepare_string($row['comment'], 10000); $author = wm_prepare_string($row['author'], 500); $date_creation = wm_prepare_string($row['date_creation'], 50); $date_available = wm_prepare_string($row['date_available'], 50); $latitude = wm_prepare_string($row['latitude'], 50); $longitude = wm_prepare_string($row['longitude'], 50); $command = isset($conf['exiftool_path']) ? $conf['exiftool_path'] : 'exiftool -m -codedcharacterset=utf8 -overwrite_original'; $command.= ' -q'; if (strlen($name) > 0) { # 2#105 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:Headline="'.$name.'"'; # 2#005 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:ObjectName="'.wm_cutString($name, 64).'"'; } if (strlen($description) > 0) { # 2#120 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:Caption-Abstract="'.$description.'"'; } if (strlen($date_creation) > 0) { # 2#055 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:DateCreated="'.$date_creation.'"'; } if (strlen($date_available) > 0) { # 2#030 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:ReleaseDate="'.$date_available.'"'; } if (strlen($latitude) > 0) { $command.= ' -GPSLatitudeRef=North -GPSLatitude="'.$latitude.'"'; } if (strlen($longitude) > 0) { $command.= ' -GPSLongitudeRef=East -GPSLongitude="'.$longitude.'"'; } if (strlen($author) > 0) { # 2#080 in iptcparse($imginfo['APP13']) $iptc_field = 'By-line'; if ( $conf['use_iptc'] and isset($conf['use_iptc_mapping']['author']) and '2#122' == $conf['use_iptc_mapping']['author'] ) { # 2#122 in iptcparse($imginfo['APP13']) $iptc_field = 'Writer-Editor'; } $command.= ' -m -codedcharacterset=utf8 -IPTC:'.$iptc_field.'="'.$author.'"'; } if (strlen($row['tags']) > 0) { $tags = explode(',', $row['tags']); foreach ($tags as $tag) { $tag = wm_prepare_string($tag, 64); # 2#025 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:Keywords="'.$tag.'"'; } } $command.= ' "'.$row['path'].'"'; $command.= ' 2>&1'; // echo $command; $logger->info(__FUNCTION__.' command = '.$command); $exec_return = exec($command, $output, $rc); // echo '$exec_return = '.$exec_return.'<br>'; // echo '<pre>'; print_r($output); echo '</pre>'; // as derivatives may contain metadata, they must be reset delete_element_derivatives($row); return array($rc, $output); } function wm_prepare_string($string, $maxLen) { return wm_cutString( wm_explode_description( wm_decode_html_string_to_unicode($string) ), $maxLen ); } function wm_cutString($description, $maxLen) { if (strlen($description) > $maxLen) { $description = substr($description, 0, $maxLen); } return $description; } function wm_explode_description($description) { return str_replace( array('<br>', '<br />', "\n", "\r"), array('', '', '', ''), $description ); } function wm_decode_html_string_to_unicode($string) { if (isset($string) and strlen($string) > 0) { $string = html_entity_decode(trim($string), ENT_QUOTES, 'UTF8'); $string = stripslashes($string); } else { $string = ''; } return($string); } ?>
Offline
BigIsland270972 wrote:
1. Write info from database to original jpg file (IPTC) with the write metadata plugin (including date_available and date_creation). ✔
2. Copy jpg ALL IPTC data to new version of file with Exiftool. ✔
3. Sync the new version jpg file with database. ✔
4. Write html code from database in plain text to the IPTC description field with Write metadata plugin. FAILED!
5. Check logfile for errors when trying to write html (Exiftool doesn't write logfiles according to author) FAILED
6. What to do next??
I've come a little closer to finding a solution to write html code problem.
See error:
sh: line 1: $'p\303\245': command not found
Last edited by BigIsland270972 (2023-03-27 18:29:28)
Offline
WELL theres ONE more problem.
} if (strlen($latitude) > 0) { $command.= ' -GPSLatitudeRef=North -GPSLatitude="'.$latitude.'"'; } if (strlen($longitude) > 0) { $command.= ' -GPSLongitudeRef=East -GPSLongitude="'.$longitude.'"'; }
Latitude (-90=S to 90=N)
Longitude (-180=W to 180=E)
This code work for +pluss North and East but not for - minus South and West.
How to solve this??
Last edited by BigIsland270972 (2023-03-27 21:19:54)
Offline
@plg???
Offline
YES! Figured it out:
if ($latitude > 0) { $command.= ' -GPSLatitudeRef=North -GPSLatitude="'.$latitude.'"'; } if ($longitude > 0) { $command.= ' -GPSLongitudeRef=East -GPSLongitude="'.$longitude.'"'; } if ($latitude < 0) { $command.= ' -GPSLatitudeRef=South -GPSLatitude="'.$latitude.'"'; } if ($longitude < 0) { $command.= ' -GPSLongitudeRef=West -GPSLongitude="'.$longitude.'"'; }
Offline
The latest working version here:
<?php /* Plugin Name: Write Metadata Description: Write Piwigo photo properties (title, description, author, tags) into IPTC fields Author: plg Plugin URI: http://piwigo.org/ext/extension_view.php?eid=769 Version: 12.a */ // +-----------------------------------------------------------------------+ // | Define plugin constants | // +-----------------------------------------------------------------------+ defined('WRITE_METADATA_ID') or define('WRITE_METADATA_ID', basename(dirname(__FILE__))); define('WRITE_METADATA_PATH' , PHPWG_PLUGINS_PATH.basename(dirname(__FILE__)).'/'); // +-----------------------------------------------------------------------+ // | Edit Photo | // +-----------------------------------------------------------------------+ add_event_handler('loc_begin_admin_page', 'wm_add_link', 60); function wm_add_link() { global $template, $page; $template->set_prefilter('picture_modify', 'wm_add_link_prefilter'); if (isset($page['page']) and 'photo' == $page['page']) { $template->assign( 'U_WRITEMETADATA', get_root_url().'admin.php?page=photo-'.$_GET['image_id'].'-properties&write_metadata=1' ); } } function wm_add_link_prefilter($content) { $search = '{if !url_is_remote($PATH)}'; $replacement = '{if !url_is_remote($PATH)} <a class="icon-docs" href="{$U_WRITEMETADATA}" title="{\'Write metadata\'|translate}"></a>'; return str_replace($search, $replacement, $content); } add_event_handler('loc_begin_admin_page', 'wm_picture_write_metadata'); function wm_picture_write_metadata() { global $page, $conf; load_language('plugin.lang', dirname(__FILE__).'/'); if (isset($page['page']) and 'photo' == $page['page'] and isset($_GET['write_metadata'])) { check_input_parameter('image_id', $_GET, false, PATTERN_ID); list($rc, $output) = wm_write_metadata($_GET['image_id']); if (count($output) == 0) { $_SESSION['page_infos'][] = l10n('Metadata written into file'); redirect(get_root_url().'admin.php?page=photo-'.$_GET['image_id'].'-properties'); } else { $page['errors'] = array_merge($page['errors'], $output); } } } // +-----------------------------------------------------------------------+ // | Batch Manager | // +-----------------------------------------------------------------------+ add_event_handler('loc_begin_element_set_global', 'wm_element_set_global_add_action'); function wm_element_set_global_add_action() { global $template, $page; $template->set_filename('writeMetadata', realpath(WRITE_METADATA_PATH.'element_set_global_action.tpl')); if (isset($_POST['submit']) and $_POST['selectAction'] == 'writeMetadata') { $page['infos'][] = l10n('Metadata written into file'); } $template->assign( array( 'WM_PWG_TOKEN' => get_pwg_token(), ) ); $template->append( 'element_set_global_plugins_actions', array( 'ID' => 'writeMetadata', 'NAME' => l10n('Write metadata'), 'CONTENT' => $template->parse('writeMetadata', true), ) ); } add_event_handler('ws_add_methods', 'wm_add_methods'); function wm_add_methods($arr) { include_once(WRITE_METADATA_PATH.'ws_functions.inc.php'); } // +-----------------------------------------------------------------------+ // | Common functions | // +-----------------------------------------------------------------------+ /** * inspired by convert_row_to_file_exiftool method in ExportImageMetadata * class from plugin Tags2File. In plugin write_medata we just skip the * batch command file, and execute directly on server (much more user * friendly...). */ function wm_write_metadata($image_id) { global $conf, $logger; $query = ' SELECT img.name, img.comment, img.author, img.date_creation, img.date_available, img.latitude, img.longitude, GROUP_CONCAT(tags.name) AS tags, img.path, img.representative_ext FROM '.IMAGES_TABLE.' AS img LEFT OUTER JOIN '.IMAGE_TAG_TABLE.' AS img_tag ON img_tag.image_id = img.id LEFT OUTER JOIN '.TAGS_TABLE.' AS tags ON tags.id = img_tag.tag_id WHERE img.id = '.$image_id.' GROUP BY img.id, img.name, img.comment, img.author, img.path, img.representative_ext ;'; $result = pwg_query($query); $row = pwg_db_fetch_assoc($result); $name = wm_prepare_string($row['name'], 500); $description = wm_prepare_string($row['comment'], 10000); $author = wm_prepare_string($row['author'], 500); $date_creation = wm_prepare_string($row['date_creation'], 50); $date_available = wm_prepare_string($row['date_available'], 50); $latitude = wm_prepare_string($row['latitude'], 50); $longitude = wm_prepare_string($row['longitude'], 50); $command = isset($conf['exiftool_path']) ? $conf['exiftool_path'] : 'exiftool -m -codedcharacterset=utf8 -overwrite_original'; $command.= ' -q'; if (strlen($name) > 0) { # 2#105 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:Headline="'.$name.'"'; # 2#005 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:ObjectName="'.wm_cutString($name, 64).'"'; } if (strlen($description) > 0) { # 2#120 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:Caption-Abstract="'.$description.'"'; } if (strlen($date_creation) > 0) { # 2#055 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:DateCreated="'.$date_creation.'"'; } if (strlen($date_available) > 0) { # 2#030 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:ReleaseDate="'.$date_available.'"'; } if ($latitude > 0) { $command.= ' -GPSLatitudeRef=North -GPSLatitude="'.$latitude.'"'; } if ($longitude > 0) { $command.= ' -GPSLongitudeRef=East -GPSLongitude="'.$longitude.'"'; } if ($latitude < 0) { $command.= ' -GPSLatitudeRef=South -GPSLatitude="'.$latitude.'"'; } if ($longitude < 0) { $command.= ' -GPSLongitudeRef=West -GPSLongitude="'.$longitude.'"'; } if (strlen($author) > 0) { # 2#080 in iptcparse($imginfo['APP13']) $iptc_field = 'By-line'; if ( $conf['use_iptc'] and isset($conf['use_iptc_mapping']['author']) and '2#122' == $conf['use_iptc_mapping']['author'] ) { # 2#122 in iptcparse($imginfo['APP13']) $iptc_field = 'Writer-Editor'; } $command.= ' -m -codedcharacterset=utf8 -IPTC:'.$iptc_field.'="'.$author.'"'; } if (strlen($row['tags']) > 0) { $tags = explode(',', $row['tags']); foreach ($tags as $tag) { $tag = wm_prepare_string($tag, 64); # 2#025 in iptcparse($imginfo['APP13']) $command.= ' -IPTC:Keywords="'.$tag.'"'; } } $command.= ' "'.$row['path'].'"'; $command.= ' 2>&1'; // echo $command; $logger->info(__FUNCTION__.' command = '.$command); $exec_return = exec($command, $output, $rc); // echo '$exec_return = '.$exec_return.'<br>'; // echo '<pre>'; print_r($output); echo '</pre>'; // as derivatives may contain metadata, they must be reset delete_element_derivatives($row); return array($rc, $output); } function wm_prepare_string($string, $maxLen) { return wm_cutString( wm_explode_description( wm_decode_html_string_to_unicode($string) ), $maxLen ); } function wm_cutString($description, $maxLen) { if (strlen($description) > $maxLen) { $description = substr($description, 0, $maxLen); } return $description; } function wm_explode_description($description) { return str_replace( array('<br>', '<br />', "\n", "\r"), array('', '', '', ''), $description ); } function wm_decode_html_string_to_unicode($string) { if (isset($string) and strlen($string) > 0) { $string = html_entity_decode(trim($string), ENT_QUOTES, 'UTF8'); $string = stripslashes($string); } else { $string = ''; } return($string); } ?>
Offline
BigIsland270972 wrote:
BigIsland270972 wrote:
1. Write info from database to original jpg file (IPTC) with the write metadata plugin (including date_available and date_creation). ✔
2. Copy jpg ALL IPTC data to new version of file with Exiftool. ✔
3. Sync the new version jpg file with database. ✔
4. Write html code from database in plain text to the IPTC description field with Write metadata plugin. FAILED!
5. Check logfile for errors when trying to write html (Exiftool doesn't write logfiles according to author) FAILED
6. What to do next??I've come a little closer to finding a solution to write html code problem.
See error:
sh: line 1: $'p\303\245': command not found
The problem is RESOLVED. It was the use of double quotes " in the html code. Changed to single quote ' and all is working just FINE. :-)))
Offline
Thanks for this effort! I have been considering starting to use the Write Metadata plugin on my older images to "save" all of my Piwigo work (tags, dates, etc.) back into the original image files and the addition of the date is very valuable.
Since it's been a few months since you completed this, have you run into any issues? Do you have a fork of the plugin with these changes or should I just manually update the plugin on my site with your latest code post from 3/28?
Thanks.
Offline
And one quick note ... it looks like you're using 2#030 and 2#055 for the dates, but not 2#035 and 2#060 for the times, so you'll lose the time portion of the date/time when writing the metadata to the file.
Last edited by windracer (2023-09-29 21:31:11)
Offline
windracer wrote:
Thanks for this effort! I have been considering starting to use the Write Metadata plugin on my older images to "save" all of my Piwigo work (tags, dates, etc.) back into the original image files and the addition of the date is very valuable.
Since it's been a few months since you completed this, have you run into any issues? Do you have a fork of the plugin with these changes or should I just manually update the plugin on my site with your latest code post from 3/28?
Thanks.
Hello. I've abandoned Piwigo alltogether due to LACK of support and IGNORANCE!.
Robert
Offline
Sorry to hear that.
I made a fork of the plugin and then taken some of your changes and then added additional options (via the local config) to toggle the -overwrite_original and -preserve features in exiftool. To avoid the issue with date/time creation being separated in IPTC, I'm just writing the creation date/time to EXIF instead.
Thanks for your reply, and good luck with whatever you're using now!
https://github.com/jradwan/Piwigo-write_metadata
Last edited by windracer (2023-09-30 19:20:04)
Offline