def getMeta(self, files): et = ExifTool() et.start() a = et.get_metadata_batch(files) et.terminate() meta = self._removeErrors(a) return meta
pconn = sqlite3.connect(placesDbPath) pconn.row_factory = sqlite3.Row pdb = pconn.cursor() ldb = conn.cursor() pdb.execute("SELECT COUNT(*) FROM RKPlace") numPlaces = pdb.fetchone()[0] print("Found %d places." % numPlaces) # No images? if numImages == 0: sys.exit(0) if args.exif: et = ExifTool() et.start() index = 0 copied = 0 ignored = 0 stack = [] stack_timestamp = "" places_freq = dict() # Iterate over the photos. for row in db.execute(''' SELECT m.imagePath, m.fileName, v.imageDate AS date, v.imageTimeZoneOffsetSeconds AS offset, v.uuid, v.modelId FROM RKMaster AS m INNER JOIN RKVersion AS v ON v.masterId = m.modelId WHERE m.isInTrash = 0
class FlirExtractor: """Extracts thermal data from FLIR images using ExifTool. Attributes: exiftoolpath: The path to the ExifTool executable. Example: with FlirExtractor(exiftoolpath="/usr/bin/exiftool") as extractor: # get a single thermal data point thermal_data = extractor.get_thermal("./path/to/FLIR.jpg") # get multiple thermal data thermal_d_list = extractor.get_thermal_batch( ["./FLIR1.jpg", "./FLIR2.jpg"] ) """ exiftoolpath: Optional[Path] _exiftool: Optional[ExifTool] def __init__(self, exiftoolpath: Path = exiftool_default_exe): self.exiftoolpath = exiftoolpath self._exiftool = None @property def exiftool(self) -> ExifTool: _exiftool = self._exiftool if _exiftool is None: raise AttributeError( "ExifTool was not initialized. " "Use FlirExtractor in a context manager, e.g. \n" "with FlirExtractor() as e:\n" " e.do_magic()") return _exiftool def open(self): """Creates an Exiftool process. Not recommended, use `with:` context manager instead. """ if self._exiftool is not None: raise Exception("ExifTool was already initialized.") self._exiftool = ExifTool(executable_=str(self.exiftoolpath)) self._exiftool.start() def close(self): """Closes the Exiftool process. Not recommended, use `with:` context manager instead. """ if self._exiftool is None: return # already closed, do nothing self._exiftool.terminate() self._exiftool = None def __enter__(self): self.open() return self def __exit__(self, exception_type, exception_value, traceback): self.close() def get_thermal(self, filepath: Path) -> "np.ndarray": """Gets a thermal image from a FLIR file. Parameters: filepath: The path to the FLIR file. Returns: The thermal data in Celcius as a 2-D numpy array. """ return get_thermal(self.exiftool, filepath) def get_thermal_batch(self, filepaths: Iterable[Path]) -> Iterable["np.ndarray"]: """Gets thermal images from a list of FLIR files. Parameters: filepaths: The paths to the FLIR files. Returns: A list of the thermal data in Celcius as 2-D numpy arrays. """ return get_thermal_batch(self.exiftool, filepaths)
class ExifManager(object): xmp_re = re.compile(':') newline_re = re.compile('\n') logger = logging.getLogger(__name__) def __init__(self): self._exiftool = ExifTool() self._tempfiles = set() def __del__(self): self.stop() def serialize_xmp(self, file_list, **kwargs): args = {'keep_open': True} args.update(kwargs) counter = CountLogger(self.logger, file_list) counter.count(msg='Serialize XMP', inc=False) for path in file_list: self.serialize_xmp_one_file(path, **args) counter.count(msg="XMP for %s" % (os.path.basename(path), )) self.stop() def serialize_xmp_one_file(self, path, **kwargs): keep_open = kwargs.get('keep_open', False) kwargs.pop('keep_open', None) if not self._exiftool.running: self.start() xmp = "%s.xmp" % (path, ) tags = ['-tagsFromFile', path, xmp] self._exiftool.execute(*tags) if not keep_open: self.stop() def get_tag(self, tag, file): self.start() value = self._exiftool.get_tag(tag, file) self.stop() return value def add_metadata(self, file_list, prop_dict, overwrite_original=False): self.start() for file in file_list: self._add_md_to_file(file, prop_dict, overwrite_original) self.stop() def add_json_metadata(self, file_list, prop_dict, overwrite_original=False): self.start() for file in file_list: self._add_json_md_to_file(file, prop_dict, overwrite_original) self.stop() def add_json_one_file(self, filename, prop_dict, **kwargs): """ kwargs can be: overwrite_original : True|[False] keep_open : True|[False] (keep exiftool instance running) """ keep_open = kwargs.get('keep_open', False) kwargs.pop('keep_open', None) if not self._exiftool.running: self.start() self._add_json_md_to_file(filename, prop_dict, **kwargs) if not keep_open: self.stop() def add_md_one_file(self, filename, prop_dict, **kwargs): """ kwargs can be: overwrite_original : True|[False] keep_open : True|[False] (keep exiftool instance running) """ keep_open = kwargs.get('keep_open', False) kwargs.pop('keep_open', None) if not self._exiftool.running: self.start() self._add_md_to_file(filename, prop_dict, **kwargs) if not keep_open: self.stop() def _add_json_md_to_file(self, file, prop_dict, overwrite_original=False): dct = {'SourceFile': file} dct.update(**prop_dict) path = self._to_json_file(dct) tags = ['-json=%s' % path, file] if overwrite_original: tags.insert(0, '-overwrite_original') return self._exiftool.execute(*tags) def _add_md_to_file(self, file, prop_dict, overwrite_original=False): tags = self._build_tags(prop_dict) if overwrite_original: tags.insert(0, '-overwrite_original') tags.append(file) self._exiftool.execute(*tags) def start(self): self._exiftool.start() def stop(self): self._exiftool.terminate() self._cleanup() def _build_tags(self, prop_dict): tags = [] for key in prop_dict: value = prop_dict.get(key) if isinstance(value, list) or isinstance(value, tuple): for v in value: tags.append(self._build_tag(key, v)) else: tags.append(self._build_tag(key, value)) return tags def _build_tag(self, name, value): if ExifManager.newline_re.search(value): path = self._value_to_file(value) return "%s<=%s" % (self._tag(name), path) else: return "%s=%s" % (self._tag(name), value.encode('utf-8')) def _tag(self, name): if ExifManager.xmp_re.search(name): return "-xmp-%s" % name else: return "-%s" % name def _to_json_file(self, prop_dict): return self._value_to_file(json.dumps(prop_dict)) def _value_to_file(self, value): f = tempfile.NamedTemporaryFile(delete=False) f.write(value.encode('utf-8')) f.flush() f.seek(0) name = f.name self._tempfiles.add(name) return name def _cleanup(self): for f in self._tempfiles: try: os.remove(f) except OSError: pass self._tempfiles.clear()
for row in arows: uuid=row["uuid"] albumName=row["name"] uuIdAlbum[uuid]=albumName; print("Found %d albums" % len(uuIdAlbum)) if args.verbose: print("Albums found:", uuIdAlbum) # No images? if numImages == 0: sys.exit(0) if args.exif: et = ExifTool(); et.start(); def placeByModelId(modelId): ldb.execute(''' SELECT placeId FROM RKPlaceForVersion WHERE versionId = ?''', (modelId,)) placeIds = ', '.join([str(placeId[0]) for placeId in ldb.fetchall()]) if len(placeIds): pdb.execute(''' SELECT DISTINCT defaultName AS name FROM RKPlace WHERE modelId IN(%s) ORDER BY area ASC''' % placeIds)