def closeEvent(self, event): LOGGER.debug('Shutting down gracefully....') self._meta_files_mgr.disconnect() settings.persist_to_disk() self._dir_watcher_thread.quit() self._dir_watcher_thread.wait() self._img_loader_thread.quit() self._img_loader_thread.wait()
def get_img_exif(self, abspath): exif = {} try: with PIL.Image.open(abspath) as image: exif = { PIL.ExifTags.TAGS[k]: v for k, v in image._getexif().items() if k in PIL.ExifTags.TAGS } except Exception as ex: LOGGER.debug("EXIF data for %s could not be loaded." % abspath) return exif
def scan_folders(self): watched_folders = self._meta_files_mgr.get_watched_dirs() # Scan the watched directories. for idx, folder in enumerate(watched_folders): self.scan_folder(folder['id'], folder['abspath'], folder['name']) # TODO: Emit list of unclean entries for notification # self._meta_files_mgr.get_unclean_entries # Finally, remove the non-existent files # self._meta_files_mgr.clean_db(self._img_integrity_ts) LOGGER.debug("Folder scan completed.")
def load_scandir(self, sd_id, serial, load_count, scrollDirection): """ <TODO> """ self._img_integrity_ts = start_time = time.time() self._meta_files_mgr.connect() LOGGER.debug('Load Scan Dir started.') dir_info = self._meta_files_mgr.get_scan_dir(sd_id) self.load_scan_dir_info_success.emit(dir_info) reverse = True if scrollDirection == ScrollDirection.Up else False images = self._meta_files_mgr.get_scan_dir_images_by_serial( sd_id, serial, load_count, reverse) self.load_images_success.emit(images, scrollDirection)
def run_insert_query(self, query, params, commit=True): """ Description: Executes an insert sql query using Pythons DB-API (Parameter substitution) Arguments: 'query': The sql query string 'params' : tuple containing parameters """ cursor = self.conn.cursor() try: cursor.execute(query, params) if commit: self.conn.commit() except sqlite3.OperationalError as msg: LOGGER.error('[DB]: %s' % msg) except sqlite3.IntegrityError as msg: LOGGER.debug('[DB]: %s : %s : %s' % (msg, query, params)) LOGGER.error('[DB]: %s : %s' % (msg, params)) return cursor.lastrowid
def _handle_load_images_sucess(self, images, scrollDirection): img_count = len(images) print('Recevied %s images' % img_count) LOGGER.debug('Recevied %s images' % img_count) for img in images: img['thumb'] = QImage.fromData(img['thumb']) item = QStandardItem() thumb_caption_type = settings.get( SettingType.UI_THUMBS_CAPTION_DISPLAY_MODE, Thumb_Caption_Type.NoCaption.name) if thumb_caption_type == Thumb_Caption_Type.FileName.name: item.setText(img['name']) item.setData(img['id'], QtCore.Qt.UserRole + 1) item.setData(img['serial'], QtCore.Qt.UserRole + 2) item.setIcon(QIcon(QPixmap.fromImage(img['thumb']))) item.setText(str(img['serial'])) if scrollDirection == ScrollDirection.Up: self._thumbs_view_model.insertRow(0, item) if scrollDirection == ScrollDirection.Down: self._thumbs_view_model.appendRow(item)
def get_img_properties(self, si_id, sd_id): if not self._meta_db.is_open: self.connect() dr_img = self.get_image_from_id(si_id, sd_id) exif = self.get_img_exif(dr_img['abspath']) # print(exif) properties = {} properties['abspath'] = dr_img['abspath'] properties['filename'] = dr_img['name'] properties['filesize'] = self.format_size( QtCore.QFileInfo(dr_img['abspath']).size()) properties['dimensions'] = '' if exif: if 'DateTime' in exif: properties['DateTime'] = exif['DateTime'] if 'DateTimeDigitized' in exif: properties['DateTimeDigitized'] = exif['DateTimeDigitized'] if 'ImageWidth' in exif: properties['ImageWidth'] = exif['ImageWidth'] if 'ImageLength' in exif: properties['ImageLength'] = exif['ImageLength'] if 'ExifImageWidth' in exif: properties['ExifImageWidth'] = exif['ExifImageWidth'] if 'ExifImageHeight' in exif: properties['ExifImageHeight'] = exif['ExifImageHeight'] if 'Orientation' in exif: properties['Orientation'] = exif['Orientation'] if 'XPKeywords' in exif: properties['XPKeywords'] = exif['XPKeywords'].decode("utf-16") if 'ImageUniqueID' in exif: properties['ImageUniqueID'] = exif['ImageUniqueID'] if 'ColorSpace' in exif: properties['ColorSpace'] = exif['ColorSpace'] if 'BitsPerSample' in exif: properties['BitsPerSample'] = exif['BitsPerSample'] if 'PhotometricInterpretation' in exif: properties['PhotometricInterpretation'] = exif[ 'PhotometricInterpretation'] if 'ResolutionUnit' in exif: properties['ResolutionUnit'] = exif['ResolutionUnit'] if 'Software' in exif: properties['Software'] = exif['Software'] if 'SamplesPerPixel' in exif: properties['SamplesPerPixel'] = exif['SamplesPerPixel'] if 'XResolution' in exif: properties['XResolution'] = exif['XResolution'] if 'YResolution' in exif: properties['YResolution'] = exif['YResolution'] if 'ImageWidth' in exif: properties['dimensions'] = "%sx%s" % ( properties['ImageWidth'], properties['ImageLength']) elif 'ExifImageWidth' in exif: properties['dimensions'] = "%sx%s" % ( properties['ExifImageWidth'], properties['ExifImageHeight']) else: LOGGER.debug("EXIF data for %s not found." % dr_img['abspath']) # TODO: IPTC support # iptc_info = IPTCInfo(dr_img['abspath']) # if len(iptc_info.data) < 4: # LOGGER.debug("IPTC dat for %s not found." % dr_img['abspath']) # else: # print(iptc_info) return properties
def init_loader_thread(self): self._img_loader.moveToThread(self._img_loader_thread) self._img_loader_thread.start() LOGGER.debug('Loader thread started.')
def init_watch_thread(self): self._watch.moveToThread(self._dir_watcher_thread) self._dir_watcher_thread.start() self._run_watcher() LOGGER.debug('Watcher thread started.')
def scan_folder(self, parent_id, abs_path, dir_name): """ <TODO> """ is_new_or_modified = False if not os.path.isdir(abs_path): return modified_time = os.path.getmtime(abs_path) sd_id = 0 sd_info = self._meta_files_mgr.get_scan_dir_id(abs_path) if not sd_info or sd_info['id'] <= 0: sd_id = self._meta_files_mgr.add_scan_dir(parent_id, abs_path, dir_name, self._img_integrity_ts) sd_info = self._meta_files_mgr.get_scan_dir_id(abs_path) is_new_or_modified = True else: sd_id = sd_info['id'] self._meta_files_mgr.update_scan_dir_integrity_check( sd_id, self._img_integrity_ts) if not sd_info['mtime'] or (modified_time > sd_info['mtime']): LOGGER.debug("Folder(%s):(%s) has changed since last scan." % (sd_id, sd_info['abspath'])) is_new_or_modified = True if is_new_or_modified is True: dir_iter = QDirIterator( abs_path, self._img_ext_filter, QDir.AllEntries | QDir.AllDirs | QDir.NoDotAndDotDot, QDirIterator.FollowSymlinks) else: dir_iter = QDirIterator(abs_path, QDir.AllDirs | QDir.NoDotAndDotDot, QDirIterator.FollowSymlinks) has_new_images = False img_serial = self._meta_files_mgr.get_scan_dir_img_next_serial(sd_id) while dir_iter.hasNext(): dir_iter.next() file_info = dir_iter.fileInfo() if file_info.isDir(): LOGGER.debug("Found Directory: %s" % file_info.absoluteFilePath()) self.scan_folder(parent_id, file_info.absoluteFilePath(), file_info.fileName()) else: si_info = self._meta_files_mgr.get_image_id( file_info.absoluteFilePath()) # file exists if si_info and si_info['id'] > 0: LOGGER.debug("Found Image: %s" % file_info.absoluteFilePath()) latest_mtime = os.path.getmtime( file_info.absoluteFilePath()) if latest_mtime > si_info['mtime']: self._meta_files_mgr.update_image_thumb( si_info['id'], file_info.absoluteFilePath(), latest_mtime, self._img_integrity_ts) else: self._meta_files_mgr.update_image( si_info['id'], self._img_integrity_ts) # new file to add elif not si_info: LOGGER.debug("Found New image: %s" % file_info.absoluteFilePath()) self.new_img_found.emit({ 'dir': dir_name, 'filename': file_info.fileName() }) self._meta_files_mgr.add_image( sd_id, file_info.absoluteFilePath(), file_info.fileName(), self._img_integrity_ts, img_serial) has_new_images = True img_serial = img_serial + 1 self._meta_files_mgr.commit() if is_new_or_modified is True: img_del_count = self._meta_files_mgr.prune_scan_img( sd_id, self._img_integrity_ts) img_count = self._meta_files_mgr.get_scan_dir_img_count(sd_id) self._meta_files_mgr.update_scan_dir_img_count(sd_id, img_count) if has_new_images or img_del_count > 0: self.dir_added_or_updated.emit({ 'id': sd_id, 'name': dir_name, 'img_count': img_count }) # Only update `mtime` if the scan_dir is new or modified if img_count > 0: self._meta_files_mgr.update_scan_dir_mtime( sd_id, modified_time) else: self._meta_files_mgr.remove_scan_dir(sd_id) self.dir_empty_or_deleted.emit({'id': sd_id})