diff options
author | Olivier Tilloy <olivier@tilloy.net> | 2010-11-29 20:36:41 +0100 |
---|---|---|
committer | Olivier Tilloy <olivier@tilloy.net> | 2010-11-29 20:36:41 +0100 |
commit | 6ec0844a732a8d8b1aebbee3bf3dec1441af5bbd (patch) | |
tree | ace48eac0440d4fd9bd9b7081f4294409981ec3e | |
parent | 17c9ce29dd1b25537b9570191276e13cc3baa690 (diff) | |
download | pyexiv2-6ec0844a732a8d8b1aebbee3bf3dec1441af5bbd.tar.gz |
Functions in the xmp module to register and unregister custom namespaces.
-rw-r--r-- | src/exiv2wrapper.cpp | 59 | ||||
-rw-r--r-- | src/exiv2wrapper.hpp | 6 | ||||
-rw-r--r-- | src/exiv2wrapper_python.cpp | 4 | ||||
-rw-r--r-- | src/pyexiv2/__init__.py | 3 | ||||
-rw-r--r-- | src/pyexiv2/xmp.py | 66 |
5 files changed, 137 insertions, 1 deletions
diff --git a/src/exiv2wrapper.cpp b/src/exiv2wrapper.cpp index 0d80e05..4512222 100644 --- a/src/exiv2wrapper.cpp +++ b/src/exiv2wrapper.cpp @@ -34,6 +34,9 @@ #define NON_REPEATABLE 102 #define KEY_NOT_FOUND 103 #define INVALID_VALUE 104 +#define EXISTING_PREFIX 105 +#define BUILTIN_NS 106 +#define NOT_REGISTERED 107 // Custom macros #define CHECK_METADATA_READ \ @@ -1279,6 +1282,15 @@ void translateExiv2Error(Exiv2::Error const& error) case INVALID_VALUE: PyErr_SetString(PyExc_ValueError, "Invalid value"); break; + case EXISTING_PREFIX: + PyErr_SetString(PyExc_KeyError, "A namespace with this prefix already exists"); + break; + case BUILTIN_NS: + PyErr_SetString(PyExc_KeyError, "Cannot unregister a builtin namespace"); + break; + case NOT_REGISTERED: + PyErr_SetString(PyExc_KeyError, "No namespace registered under this name"); + break; // Default handler default: @@ -1286,5 +1298,52 @@ void translateExiv2Error(Exiv2::Error const& error) } } + +void registerXmpNs(const std::string& name, const std::string& prefix) +{ + try + { + const std::string& ns = Exiv2::XmpProperties::ns(prefix); + } + catch (Exiv2::Error& error) + { + // No namespace exists with the requested prefix, it is safe to + // register a new one. + Exiv2::XmpProperties::registerNs(name, prefix); + return; + } + throw Exiv2::Error(EXISTING_PREFIX, prefix); +} + +void unregisterXmpNs(const std::string& name) +{ + const std::string& prefix = Exiv2::XmpProperties::prefix(name); + if (prefix != "") + { + Exiv2::XmpProperties::unregisterNs(name); + try + { + const Exiv2::XmpNsInfo* info = Exiv2::XmpProperties::nsInfo(prefix); + } + catch (Exiv2::Error& error) + { + // The namespace has been successfully unregistered. + return; + } + // The namespace hasn’t been unregistered because it’s builtin. + throw Exiv2::Error(BUILTIN_NS, name); + } + else + { + throw Exiv2::Error(NOT_REGISTERED, name); + } +} + +void unregisterAllXmpNs() +{ + // Unregister all custom namespaces. + Exiv2::XmpProperties::unregisterNs(); +} + } // End of namespace exiv2wrapper diff --git a/src/exiv2wrapper.hpp b/src/exiv2wrapper.hpp index 5058d56..3c87628 100644 --- a/src/exiv2wrapper.hpp +++ b/src/exiv2wrapper.hpp @@ -272,6 +272,12 @@ private: // Translate an Exiv2 generic exception into a Python exception void translateExiv2Error(Exiv2::Error const& error); + +// Functions to manipulate custom XMP namespaces +void registerXmpNs(const std::string& name, const std::string& prefix); +void unregisterXmpNs(const std::string& name); +void unregisterAllXmpNs(); + } // End of namespace exiv2wrapper #endif diff --git a/src/exiv2wrapper_python.cpp b/src/exiv2wrapper_python.cpp index 5b793f7..bd20774 100644 --- a/src/exiv2wrapper_python.cpp +++ b/src/exiv2wrapper_python.cpp @@ -153,5 +153,9 @@ BOOST_PYTHON_MODULE(libexiv2python) .def("_setExifThumbnailFromFile", &Image::setExifThumbnailFromFile) .def("_setExifThumbnailFromData", &Image::setExifThumbnailFromData) ; + + def("_registerXmpNs", registerXmpNs, args("name", "prefix")); + def("_unregisterXmpNs", unregisterXmpNs, args("name")); + def("_unregisterAllXmpNs", unregisterAllXmpNs); } diff --git a/src/pyexiv2/__init__.py b/src/pyexiv2/__init__.py index 54d7ebe..9aa3185 100644 --- a/src/pyexiv2/__init__.py +++ b/src/pyexiv2/__init__.py @@ -62,7 +62,8 @@ import libexiv2python from pyexiv2.metadata import ImageMetadata from pyexiv2.exif import ExifValueError, ExifTag, ExifThumbnail from pyexiv2.iptc import IptcValueError, IptcTag -from pyexiv2.xmp import XmpValueError, XmpTag +from pyexiv2.xmp import XmpValueError, XmpTag, register_namespace, \ + unregister_namespace, unregister_namespaces from pyexiv2.preview import Preview from pyexiv2.utils import FixedOffset, Rational, NotifyingList, \ undefined_to_string, string_to_undefined, \ diff --git a/src/pyexiv2/xmp.py b/src/pyexiv2/xmp.py index 2142c41..c6488a1 100644 --- a/src/pyexiv2/xmp.py +++ b/src/pyexiv2/xmp.py @@ -440,6 +440,18 @@ class XmpTag(object): else: raise XmpValueError(value, type) + elif type == '': + # Unknown type, assume string + if isinstance(value, unicode): + try: + return value.encode('utf-8') + except UnicodeEncodeError: + raise XmpValueError(value, type) + elif isinstance(value, str): + return value + else: + raise XmpValueError(value, type) + raise NotImplementedError('XMP conversion for type [%s]' % type) def __str__(self): @@ -454,3 +466,57 @@ class XmpTag(object): right = self._raw_value return '<%s = %s>' % (left, right) + +def register_namespace(name, prefix): + """ + Register a custom XMP namespace. + + Overriding the prefix of a known or previously registered namespace is not + allowed. + + :param name: the name of the custom namespace (ending with a ``/``), + typically a URL (e.g. http://purl.org/dc/elements/1.1/) + :type name: string + :param prefix: the prefix for the custom namespace (keys in this namespace + will be in the form ``Xmp.{prefix}.{something}``) + :type prefix: string + + :raise ValueError: if the name doesn’t end with a ``/`` + :raise KeyError: if a namespace already exist with this prefix + """ + if not name.endswith('/'): + raise ValueError('Name should end with a /') + libexiv2python._registerXmpNs(name, prefix) + + +def unregister_namespace(name): + """ + Unregister a custom XMP namespace. + + A custom namespace is identified by its name, **not** by its prefix. + + Attempting to unregister an unknown namespace raises an error, as does + attempting to unregister a builtin namespace. + + :param name: the name of the custom namespace (ending with a ``/``), + typically a URL (e.g. http://purl.org/dc/elements/1.1/) + :type name: string + + :raise ValueError: if the name doesn’t end with a ``/`` + :raise KeyError: if the namespace is unknown or a builtin namespace + """ + if not name.endswith('/'): + raise ValueError('Name should end with a /') + libexiv2python._unregisterXmpNs(name) + + +def unregister_namespaces(): + """ + Unregister all custom XMP namespaces. + + Builtin namespaces are not unregistered. + + This function always succeeds. + """ + libexiv2python._unregisterAllXmpNs() + |