def recognize_files(self, filenames, debug_out_folder, skip_face_gen=False): self.__make_debug_out_folder(debug_out_folder) self.__start_stage(len(filenames)) for f in filenames: if self.__step_stage(): break try: ext = tools.get_low_ext(f) if ext in tools.IMAGE_EXTS: encoded_faces, media = self.recognize_image(f) elif ext in tools.VIDEO_EXTS: encoded_faces, media = self.recognize_video(f) else: log.warning(f'Unknown ext: {ext}') continue if media is None: continue self.__db.insert(f, encoded_faces, commit=False) if debug_out_folder: debug_out_file_name = self.__extract_filename(f) self.__save_debug_images( encoded_faces, media, debug_out_folder, debug_out_file_name, is_video=ext in tools.VIDEO_EXTS, skip_face_gen=skip_face_gen) except Exception as ex: log.exception(f'Image {f} recognition failed') self.__end_stage()
def __get_face_src(self, params): path = params['path'][0] descr = self.__get_face_file_description(path) if descr is None: self.__not_found_response() src_filename = descr.get('src', None) if src_filename is None: self.__not_found_response() if 'type' in params and params['type'][0] == 'info': ext = tools.get_low_ext(src_filename) tp = '' if ext in tools.IMAGE_EXTS: tp = 'image' elif ext in tools.VIDEO_EXTS: tp = 'video' self.__ok_response({ 'filename': src_filename, 'type': tp, 'names': self.server.db().get_names(src_filename) }) else: self.__send_file(src_filename)
def do_GET(self): log.debug('do_GET: ' + self.path) try: path, params = self.__path_params() if path == '/list_cache': self.__list_cache(params) return if path == '/get_names': self.__get_names() return if path == '/get_name_image': self.__get_name_image(params) return if path == '/get_folders': self.__get_folders() return if path == '/get_status': self.__get_status() return if path == '/get_face_src': self.__get_face_src(params) return if path == '/get_face_pattern': self.__get_face_pattern(params) return if path == '/': path = 'index.html' if '..' in path: log.warning('".." in path: ' + path) self.__not_found_response() return ext = tools.get_low_ext(path) if ext in ('.html', '.js', '.css', '.png', '.jpg'): self.__file_request(path, params) return log.warning('Wrong path: ' + path) self.__not_found_response() except Exception as ex: self.__server_error_response(str(ex)) log.exception(ex)
def __save_faces(self, files_faces, debug_out_folder): for ff in files_faces: if self.__step_stage(): break filename = ff['filename'] log.info(f"save faces from image: {filename}") media = tools.load_media(filename, self.__max_size, self.__max_video_frames, self.__video_frames_step) debug_out_file_name = self.__extract_filename(filename) is_video = tools.get_low_ext(filename) in tools.VIDEO_EXTS self.__save_debug_images( ff['faces'], media, debug_out_folder, debug_out_file_name, is_video=is_video) self.__step_stage_face(len(ff['faces'])) self.__end_stage()
def reencode_files(self, files_faces): self.__start_stage(len(files_faces)) for ff in files_faces: try: encoded_faces = ff['faces'] filename = ff['filename'] ext = tools.get_low_ext(filename) if ext in tools.IMAGE_EXTS: self.reencode_image(filename, encoded_faces) encoded_faces = self.__filter_encoded_faces(encoded_faces) elif ext in tools.VIDEO_EXTS: encoded_faces, media = self.recognize_video(filename) else: log.warning(f'Unknown ext: {ext}') continue self.__db.insert(filename, encoded_faces, commit=False) except Exception as ex: log.exception(f'{filename} reencoding failed') self.__end_stage()
def set_tags(self, resync=False): log.info(f'Set tags started ({resync})') self.__create_tags() if resync: count, files_faces = self.__recdb.get_all() else: count, files_faces = self.__recdb.get_unsynced() images_count = 0 faces_count = 0 for ff in tools.reduce_faces_from_videos(files_faces, self.__min_video_face_count): filename = ff['filename'] self.__plexdb.clean_tags(filename, tag_prefix=TAG_PREFIX, commit=False) tags = [] for face in ff['faces']: name = face['name'] if name in self.__names: tags.append(TAG_PREFIX + name) log.debug(f"sync tags for image: {filename}: " + str(tags)) if len(tags) != 0: ext = tools.get_low_ext(filename) if ext in tools.IMAGE_EXTS: self.__plexdb.set_tags(filename, tags, plexdb.TAG_TYPE_PHOTO, commit=False) elif ext in tools.VIDEO_EXTS: self.__plexdb.set_tags(filename, tags, plexdb.TAG_TYPE_VIDEO, commit=False) self.__recdb.mark_as_synced(filename, commit=False) images_count += 1 faces_count += len(tags) self.__plexdb.commit() self.__recdb.commit() log.info(f'Set tags done: images={images_count} faces={faces_count}')
def __send_file(self, fname, params={}): try: ext = tools.get_low_ext(fname) cont = '' if ext == '.html': cont = 'text/html' elif ext == '.js': cont = 'text/javascript' elif ext == '.css': cont = 'text/css' elif ext == '.png': cont = 'image/png' elif ext == '.jpg': cont = 'image/jpeg' else: cont = 'text/none' with open(fname, 'rb') as f: self.__send_blob(f.read(), cont, params) except IOError as ex: self.__not_found_response() log.exception(ex)
def __match_files_faces( self, files_faces, debug_out_folder, save_all_faces=False, skip_face_gen=False): cnt_all = 0 cnt_changed = 0 for ff in files_faces: if self.__step_stage(): break filename = ff['filename'] log.info(f"match image: {filename}") is_video = tools.get_low_ext(filename) in tools.VIDEO_EXTS if not self.__match_faces(ff['faces']): continue for face in ff['faces']: if self.__step_stage_face(): break cnt_all += 1 changed = False if 'oldname' in face and face['oldname'] != face['name']: self.__db.set_name(face['face_id'], face['name'], face['dist'], face['pattern'], commit=False) cnt_changed += 1 changed = True log.info( f"face {face['face_id']} in file '{ff['filename']}' " + f"changed '{face['oldname']}' -> '{face['name']}'") if debug_out_folder and (changed or save_all_faces): media = tools.load_media(filename, self.__max_size, self.__max_video_frames, self.__video_frames_step) debug_out_file_name = self.__extract_filename(filename) self.__save_debug_images( (face,), media, debug_out_folder, debug_out_file_name, is_video=is_video, skip_face_gen=skip_face_gen) self.__end_stage() log.info(f'match done: count: {cnt_all}, changed: {cnt_changed}')
def sync_new(self, cfg, patt, folders, exts): log.info(f'Sync new started') cachedb_file = cfg.get_path('files', 'cachedb') cache_path = cfg.get_path('server', 'face_cache_path') if cachedb_file: cdb = cachedb.CacheDB(cachedb_file) else: cdb = None rec = recognizer.createRecognizer(patt, cfg, cdb, self.__recdb) for folder in folders: plex_files = self.__plexdb.get_files(folder) plex_files = set( filter(lambda f: tools.get_low_ext(f) in exts, plex_files)) rec_files = set(self.__recdb.get_files(folder)) filenames = sorted(plex_files - rec_files) count = len(filenames) if count != 0: log.info(f'Adding {count} files from {folder}') rec.recognize_files(filenames, cache_path) else: log.info(f'No files to add from {folder}') self.set_tags()