def add_exifs(self, entries): """Add metadata to multiple files. Args: entries: Iterable of (path, sha256, exif) tuples. Where exif is any dictionary-like object with exif attributes. """ # Split the work into chunks for chunk in chunks(entries, size=1000): with self.database.session_scope() as session: index = {(path, sha256): exif for path, sha256, exif in chunk} query = session.query(Files).options(joinedload(Files.exif)) files = query.filter(self._by_path_and_hash(list( index.keys()))).all() # Update existing files for file in files: exif = index.pop((file.file_path, file.sha256)) exif_entity = file.exif or Exif(file=file) self._update_exif(exif_entity, exif) file.exif = exif_entity # Create missing files new_files = [] for (path, sha256), exif in index.items(): new_file = Files(file_path=path, sha256=sha256) exif_entity = Exif(file=new_file) self._update_exif(exif_entity, exif) new_file.exif = exif_entity new_files.append(new_file) session.add_all(new_files)
def test_transform_nan(): exif = Exif(General_FileSize=math.inf, General_Duration=-math.inf, Video_FrameRate=math.nan) data = Transform.exif_dict(exif) assert data["General_FileSize"] is None assert data["General_Duration"] is None assert data["Video_FrameRate"] is None
def make_file(prefix="", length=42, ext="flv", audio=True, date=datetime.date(2000, 1, 1), scenes=((0, 1), (1, 2))): """Create unique file.""" path = f"{prefix}some/path/{uuid()}.{ext}" sha256 = f"hash-of-{path}" return Files(file_path=path, sha256=sha256, exif=Exif(General_FileExtension=ext, Audio_Duration=float(audio), General_Encoded_Date=date, General_Duration=length), meta=VideoMetadata(), scenes=[Scene(start_time=start, duration=duration) for start, duration in scenes])
def test_transform_file(): file = Files(file_path="foo", exif=Exif(General_FileSize=42.0)) # Exclude exif data = Transform.file_dict(file) assert data["file_path"] == file.file_path assert "exif" not in data # Include exif data = Transform.file_dict(file, exif=True) assert data["file_path"] == file.file_path assert data["exif"]["General_FileSize"] == file.exif.General_FileSize
def make_file(prefix="", length=42, ext="flv", scenes=((0, 1), (1, 2))): """Create unique file.""" path = f"{prefix}some/path/{uuid()}.{ext}" sha256 = f"hash-of-{path}" return Files(file_path=path, sha256=sha256, exif=Exif(General_FileExtension=ext, General_Duration=length * 1000), meta=VideoMetadata(), scenes=[ Scene(start_time=start, duration=duration) for start, duration in scenes ])
def test_transform_exif(): exif = Exif( General_FileExtension="mp4", General_FileSize=0.5, General_Duration=0.5, ) data = Transform.exif_dict(exif) assert data["General_FileExtension"] == exif.General_FileExtension assert data["General_FileSize"] == exif.General_FileSize assert data["General_Duration"] == exif.General_Duration assert data["General_OverallBitRate_Mode"] is None exclude = {"id", "file_id", "file", "Json_full_exif"} assert set(data.keys()) == entity_fields(Exif) - exclude
def add_file_exif(self, path, sha256, exif): """Add a single file EXIF attributes. Args: path (String): Source video file path. sha256 (String): Source video file hash. exif: Dictionary object containing EXIF attributes. """ with self.database.session_scope() as session: query = session.query(Files).options(joinedload(Files.exif)) file = query.filter(Files.file_path == path, Files.sha256 == sha256).one_or_none() file = file or Files(file_path=path, sha256=sha256) exif_entity = file.exif or Exif(file=file) self._update_exif(exif_entity, exif) file.exif = exif_entity session.add(exif_entity)