From 05e7b52a1f94a40996f2619ad9db8bbdb1518497 Mon Sep 17 00:00:00 2001 From: Julien Valroff Date: Sun, 8 Jan 2012 07:54:46 +0100 Subject: Imported Upstream version 0.4.3 --- rapid/metadataxmp.py | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100755 rapid/metadataxmp.py (limited to 'rapid/metadataxmp.py') diff --git a/rapid/metadataxmp.py b/rapid/metadataxmp.py new file mode 100755 index 0000000..47321e3 --- /dev/null +++ b/rapid/metadataxmp.py @@ -0,0 +1,198 @@ +#!/usr/bin/python +# -*- coding: latin1 -*- + +### Copyright (C) 2011-12 Damon Lynch + +### This program is free software; you can redistribute it and/or modify +### it under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 2 of the License, or +### (at your option) any later version. + +### This program is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. + +### You should have received a copy of the GNU General Public License +### along with this program; if not, write to the Free Software +### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import subprocess + +import multiprocessing, logging +logger = multiprocessing.get_logger() + +class XmpMetadataSidecar: + + def __init__(self, filename): + self.filename = filename + self.keys = [] + + def _add_pair(self, key_value_pair): + self.keys.append(key_value_pair) + logger.debug(key_value_pair) + + def _generate_exiv2_command_line(self): + # -f option: overwrites any existing xmp file + return ['exiv2', '-f'] + self.keys + ['-exX', self.filename] + + def _generate_exiv2_contact_info(self, key, value): + return "-M set Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:%s %s" % (key, value) + + def _generate_exiv2_dc(self, key, value): + return "-M set Xmp.dc.%s %s" % (key, value) + + def _generate_exiv2_photoshop(self, key, value): + return "-M set Xmp.photoshop.%s %s" % (key, value) + + def _generate_exiv2_rights(self, key, value): + return "-M set Xmp.xmpRights.%s %s" % (key, value) + + def _generate_exiv2_iptc(self, key, value): + return "-M set Xmp.iptc.%s %s" % (key, value) + + def _generate_exiv2_exif(self, key, value): + return "-M set Xmp.exif.%s %s" % (key, value) + + def set_location(self, location): + self._add_pair(self._generate_exiv2_iptc('Location', location)) + + def set_city(self, city): + self._add_pair(self._generate_exiv2_photoshop('City', city)) + + def set_state_province(self, state): + self._add_pair(self._generate_exiv2_photoshop('State', state)) + + def set_country(self, country): + self._add_pair(self._generate_exiv2_photoshop('Country', country)) + + def set_country_code(self, country_code): + self._add_pair(self._generate_exiv2_iptc('CountryCode', country_code)) + + def set_headline(self, headline): + self._add_pair(self._generate_exiv2_photoshop('Headline', headline)) + + def set_description_writer(self, writer): + """ + Synonym: Caption writer + """ + self._add_pair(self._generate_exiv2_photoshop('CaptionWriter', writer)) + + def set_description(self, description): + """A synonym for this in some older programs is 'Caption'""" + self._add_pair(self._generate_exiv2_dc('description', description)) + + def set_subject(self, subject): + """ + You can call this more than once, to add multiple subjects + + A synonym is 'Keywords' + """ + self._add_pair(self._generate_exiv2_dc('subject', subject)) + + def set_creator(self, creator): + """ + Sets the author (creator) field. Photo Mechanic calls this 'Photographer'. + """ + self._add_pair(self._generate_exiv2_dc('creator', creator)) + + def set_creator_job_title(self, job_title): + self._add_pair(self._generate_exiv2_photoshop('AuthorsPosition', job_title)) + + def set_credit_line(self, credit_line): + self._add_pair(self._generate_exiv2_photoshop('Credit', credit_line)) + + def set_source(self, source): + """ + original owner or copyright holder of the photograph + """ + self._add_pair(self._generate_exiv2_photoshop('Source', source)) + + def set_copyright(self, copyright): + self._add_pair(self._generate_exiv2_dc('rights', copyright)) + + def set_copyright_url(self, copyright_url): + self._add_pair(self._generate_exiv2_rights('WebStatement', copyright_url)) + + def set_contact_city(self, city): + self._add_pair(self._generate_exiv2_contact_info('CiAdrCity', city)) + + def set_contact_country(self, country): + self._add_pair(self._generate_exiv2_contact_info('CiAdrCtry', country)) + + def set_contact_address(self, address): + """The contact information address part. + Comprises an optional company name and all required information + to locate the building or postbox to which mail should be sent.""" + self._add_pair(self._generate_exiv2_contact_info('CiAdrExtadr', address)) + + def set_contact_postal_code(self, postal_code): + self._add_pair(self._generate_exiv2_contact_info('CiAdrPcode', postal_code)) + + def set_contact_region(self, region): + """State/Province""" + self._add_pair(self._generate_exiv2_contact_info('CiAdrRegion', region)) + + def set_contact_email(self, email): + """Multiple email addresses can be given, separated by a comma.""" + self._add_pair(self._generate_exiv2_contact_info('CiEmailWork', email)) + + def set_contact_telephone(self, telephone): + """Multiple numbers can be given, separated by a comma.""" + self._add_pair(self._generate_exiv2_contact_info('CiTelWork', telephone)) + + def set_contact_url(self, url): + """Multiple URLs can be given, separated by a comma.""" + self._add_pair(self._generate_exiv2_contact_info('CiUrlWork', url)) + + def set_exif_value(self, key, value): + self._add_pair(self._generate_exiv2_exif(key, value)) + + def write_xmp_sidecar(self): + cmd = self._generate_exiv2_command_line() + if logger.getEffectiveLevel() == logging.DEBUG: + cmd_line = '' + for c in cmd: + cmd_line += c + ' ' + cmd_line = cmd_line.strip() + logger.debug("XMP write command: %s", cmd_line) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) + return proc.communicate()[0].strip() + + +if __name__ == '__main__': + import sys + + + if (len(sys.argv) != 2): + print 'Usage: ' + sys.argv[0] + ' path/to/photo/containing/metadata' + + else: + x = XmpMetadataSidecar(sys.argv[1]) + x.set_description("This is image is just a sample and is nothing serious. I used to test out writing XMP files in Rapid Photo Downloader.") + x.set_description_writer("Damon Lynch wrote caption") + x.set_headline("Sample image to test XMP") + x.set_subject("Keyword 1") + x.set_subject("Keyword 2") + x.set_city("Minneapolis") + x.set_location("University of Minnesota") + x.set_state_province("Minnesota") + x.set_country("United States of America") + x.set_country_code("USA") + x.set_creator("Damon Lynch") + x.set_creator_job_title("Photographer") + x.set_credit_line("Contact Damon for permission") + x.set_source("Damon Lynch is the original photographer") + x.set_copyright("© 2011 Damon Lynch, all rights reserved.") + x.set_copyright_url("http://www.damonlynch.net/license") + x.set_contact_address("Contact house number, street, apartment") + x.set_contact_city('Contact City') + x.set_contact_region('Contact State') + x.set_contact_postal_code('Contact Post code') + x.set_contact_telephone('+1 111 111 1111') + x.set_contact_country('Contact Country') + x.set_contact_address('Address\nApartment') + x.set_contact_url('http://www.sample.net') + x.set_contact_email('name@email1.com, name@email2.com') + + x.write_xmp_sidecar() -- cgit v1.2.3