def get_metadata(path): """ get a gexiv2 metadata object or None for path :param path: path to an image that is supported by gexiv2 :returns :py:class:`GExiv2.Metadata` or None """ GExiv2.initialize() metadata = GExiv2.Metadata.new() try: metadata.open_path(path) except GLib.Error as e: print('{}: can not get metadata obj: {}'.format(path, e)) return None else: return metadata
def initialise(cls, config_store, verbosity): if not GExiv2.initialize(): raise RuntimeError('Failed to initialise GExiv2') GExiv2.log_set_level( max(GExiv2.LogLevel.DEBUG, min(GExiv2.LogLevel.ERROR, 4 - verbosity))) GExiv2.log_use_glib_logging() # Recent versions of Exiv2 have these namespaces defined, but # older versions may not recognise them. The xapGImg URL is # invalid, but Photini doesn't write xapGImg so it doesn't # matter. for prefix, name in (('exifEX', 'http://cipa.jp/exif/1.0/'), ('xapGImg', 'http://ns.adobe.com/xxx/'), ('xmpGImg', 'http://ns.adobe.com/xap/1.0/g/img/'), ('xmpRights', 'http://ns.adobe.com/xap/1.0/rights/')): GExiv2.Metadata.register_xmp_namespace(name, prefix) # Gexiv2 won't register the 'Iptc4xmpExt' namespace as its # abbreviated version 'iptcExt' is already defined. This kludge # registers it by reading some data with the full namespace data = XMP_WRAPPER.format( 'xmlns:Iptc4xmpExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/"') # open the data to register the namespace GExiv2.Metadata().open_buf(data.encode('utf-8')) # make list of possible character encodings cls.encodings = ['utf-8', 'iso8859-1', 'ascii'] char_set = locale.getdefaultlocale()[1] if char_set: try: name = codecs.lookup(char_set).name if name not in cls.encodings: cls.encodings.append(name) except LookupError: pass
def photos_by_exif(self, exif: str) -> bool: folders: List[str] files: List[str] folders, files = get_files_and_folders(self.base_folder) GExiv2.initialize() no_error: bool = True for f in files: try: photo: GExiv2.Metadata = GExiv2.Metadata.new() photo.open_path(f) if photo.has_exif() and photo.has_tag(exif): tag: Optional[str] = photo.get_tag_string(exif) # works only with date at the right moment # TODO filedate: str = tag[:10].replace(':', '') folder_for_photo: str = GLib.build_pathv(GLib.DIR_SEPARATOR_S, [self.base_folder, filedate]) # Gio.Files photo_file: Gio.File = Gio.File.new_for_path(f) destination_folder: Gio.File = Gio.File.new_for_path(folder_for_photo) destination_path: str = GLib.build_pathv(GLib.DIR_SEPARATOR_S, [folder_for_photo, photo_file.get_basename()]) destination_for_photo: Gio.File = Gio.File.new_for_path(destination_path) if filedate not in folders: Gio.File.make_directory(destination_folder) self.folders_made.append(destination_folder.get_path()) photo_file.move(destination_for_photo, Gio.FileCopyFlags.NONE) folders.append(filedate) self.operations[f] = destination_path else: photo_file.move(destination_for_photo, Gio.FileCopyFlags.NONE) self.operations[f] = destination_path else: print('cannot read data in:', f) except GLib.Error as err: print('%s: %s in file: %s, (code: %s)' % (err.domain, err.message, f, err.code)) self.settings.set_value('folders-made', GLib.Variant('as', self.folders_made)) self.settings.set_value('operations', GLib.Variant('a{ss}', self.operations)) return no_error
def do_activate(self): if not self.window: self.window = psp_mw.MainWindow(self) GExiv2.initialize() self.window.present()
pass # import required libraries from gi.repository import GExiv2, GLib, GObject # import optional library try: from gi.repository import Gspell except ImportError: Gspell = None logger = logging.getLogger(__name__) # initialise GObject stuff GLib.set_prgname('Photini') if not GExiv2.initialize(): raise RuntimeError('Failed to initialise GExiv2') GExiv2.log_use_glib_logging() if GLib.glib_version >= (2, 46): # the numeric values of GLib.LogLevelFlags suggest ERROR is more # severe than CRITICAL, Python's logging has them the other way # round _log_mapping = { GLib.LogLevelFlags.LEVEL_DEBUG: logging.DEBUG, GLib.LogLevelFlags.LEVEL_INFO: logging.INFO, GLib.LogLevelFlags.LEVEL_MESSAGE: logging.INFO, GLib.LogLevelFlags.LEVEL_WARNING: logging.WARNING, GLib.LogLevelFlags.LEVEL_CRITICAL: logging.ERROR, GLib.LogLevelFlags.LEVEL_ERROR: logging.CRITICAL, }
## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation, either version 3 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, see ## <http://www.gnu.org/licenses/>. from gi.repository import GObject, GExiv2 GExiv2.initialize() class MetadataHandler(object): def __init__(self, path): self._path = path self._md = GExiv2.Metadata() self._md.open_path(path) def save(self): try: return self._md.save_file(self._path) except GObject.GError as ex: print str(ex) return False def copy(self, other, exif=True, iptc=True, xmp=True, comment=True):
except ValueError: pass from gi.repository import GObject, GExiv2 import six from photini import __version__ logger = logging.getLogger(__name__) gexiv2_version = '{} {}, GExiv2 {}.{}.{}, GObject {}'.format( ('PyGI', 'pgi')[using_pgi], gi.__version__, GExiv2.MAJOR_VERSION, GExiv2.MINOR_VERSION, GExiv2.MICRO_VERSION, GObject._version) # pydoc gi.repository.GExiv2.Metadata is useful to see methods available GExiv2.initialize() # we can't reroute GExiv2 messages to Python logging, so mute them... GExiv2.log_set_level(GExiv2.LogLevel.MUTE) # ...unless in test mode def debug_metadata(): GExiv2.log_set_level(GExiv2.LogLevel.INFO) def safe_fraction(value): # Avoid ZeroDivisionError when '0/0' used for zero values in Exif if isinstance(value, six.string_types): numerator, sep, denominator = value.partition('/') if denominator and int(denominator) == 0: