def set_values(self, dirs, formats, rescan, tracks=None): """ Required to put parameters into this thread from the outside """ self.media_dir = dirs self.file_list = tracks self.rescan = rescan self.meta = Tagging(formats) self.a_formats = formats
class Builddb(QThread): """ Gets files from a directory and build's a media database from the filtered files """ progress = pyqtSignal(int) finished = pyqtSignal(str) def __init__(self, parent): QThread.__init__(self, parent) self.ui = parent self.db = CollectionDb("builder") print("DEBUG: Setting up Builddb thread") def __file_compat(self, dirpath, fname): """ Identifies if the file is compatible with supported codecs """ now = os.path.join(dirpath, fname) ender = os.path.splitext(now)[-1].strip(".") ender = ender.lower() # We only want to get tags for certain file formats if ender in self.a_formats: return now def stop(self): self.exiting = True def set_values(self, dirs, formats, rescan, tracks=None): """ Required to put parameters into this thread from the outside """ self.media_dir = dirs self.file_list = tracks self.rescan = rescan self.meta = Tagging(formats) self.a_formats = formats def __track_list(self, dir, excl): """ Generates a list of compatible files """ tracks = [] not_need = [now for now in excl if dir in now] sets_db = Settings() # Recursively search if sets_db.get_collection_setting("recursive") == "True": # No point trying to speed this up. os.walk is a generator function for dirpath, dirnames, filenames in os.walk(dir): # The exclusion part #FIXME: although this means you exclude the dirpath you don't # exclude it's subdirs if dirpath in not_need: pass for fname in filenames: trk = self.__file_compat(dirpath, fname) if not trk: continue try: tracks.append(unicode(trk)) except UnicodeDecodeError: continue else: # Cannot use the loop for both as one is the above is a generator # and os.listdir is a list-returning function for fname in os.listdir(dir): trk = self.__file_compat(dir, fname) if trk is not None: tracks.append(trk) return list(set(tracks) - set(self.db.all_files() )) def __process_cue(self,file_name): """ Cue sheets need to be handled differently to normal audio files """ cue_now = CueSheet(file_name) cue_name = "%s - %s" % (cue_now.title, cue_now.performer) self.db.playlist_add(cue_name,file_name) def run(self): print("DEBUG: starting Builddb thread") self.ui.build_lock = True while self.ui.delete_lock: print("DEBUG: WAITING: Creation") sleep(1) old_prog = 0 if self.rescan: self.db.drop_media() print("DEBUG: Building DB from scratch") else: print("DEBUG: Updating DB") if self.file_list is None: tracks = [] for dir in self.media_dir[0]: tracks.extend(self.__track_list(dir, self.media_dir[1])) else: tracks = [] for trk in self.file_list: tracks.append(unicode(trk)) tracks_total = len(tracks) print("DEBUG: %d tracks to scan" % tracks_total) self.exiting = False strt = time() cnt = 0 for trk in tracks: if not self.exiting: # Find cuesheets if os.path.splitext(trk)[-1].lower() == ".cue": self.__process_cue(trk) continue ratio = float(cnt ) / float(tracks_total) prog = int(round(100 * ratio)) if prog > old_prog: old_prog = prog self.progress.emit(prog) info = self.meta.extract(trk) if info: # prepends the fileName as the DB function expects # a certain order to the args passed info.insert(0, trk) info.append(int(round(time()))) # The default rating info.append(0) self.db.add_media(info) cnt += 1 else: print("DEBUG: User terminated DB update/build.") self.finished.emit("cancelled") self.ui.build_lock = False self.exit() return print("DEBUG: %u of %u tracks scanned in: %0.1f seconds" % \ (cnt, tracks_total, (time() - strt))) self.finished.emit("complete") self.ui.build_lock = False