def run(self): total = float(len(self.import_collection)) # to import, all essential fields should be identical! fields = [ '__length', 'artist', 'album', 'title', 'genre', 'tracknumber' ] logger.info("Finding matches for %s imported tracks" % len(self.import_collection)) exact_dups = 0 no_change = 0 # determine which tracks in this collection match existing # tracks in the exaile collection. grab the groups from them for i, track in enumerate(self.import_collection): # search for a matching track # -> currently exaile doesn't index tracks, and linear searches # for the track instead. Oh well. matchers = map(lambda t: TracksMatcher(track.get_tag_search(t)), fields) matched_tracks = [ r.track for r in search_tracks(self.user_collection, matchers) ] # if there are matches, add the data to the track data for matched_track in matched_tracks: # ignore exact duplicates if track is matched_track: exact_dups += 1 continue old_group_str = ' '.join(get_track_groups(matched_track)) newgroups = get_track_groups(track) new_group_str = ' '.join(newgroups) if old_group_str == new_group_str: no_change += 1 continue self.track_data.append( (old_group_str, new_group_str, matched_track, newgroups)) glib.idle_add(self.emit, 'progress-update', int(((i + 1) / total) * 100)) if self.do_stop: return logger.info( "Match information: %s exact dups, %s no change, %s differing tracks" % (exact_dups, no_change, len(self.track_data))) glib.idle_add(self.emit, 'done')
def track_import_thread(import_collection, user_collection, track_data): ''' Reads grouping information from tracks in a collection, and matches them with tracks contained in a separate collection. ''' total = float(len(import_collection)) # to import, all essential fields should be identical! fields = ['__length', 'artist', 'album', 'title', 'genre', 'tracknumber'] logger.info("Finding matches for %s imported tracks", len(import_collection)) exact_dups = 0 no_change = 0 # determine which tracks in this collection match existing # tracks in the exaile collection. grab the groups from them for i, track in enumerate(import_collection): # search for a matching track # -> currently exaile doesn't index tracks, and linear searches # for the track instead. Oh well. matchers = map(lambda t: TracksMatcher(track.get_tag_search(t)), fields) matched_tracks = [ r.track for r in search_tracks(user_collection, matchers) ] # if there are matches, add the data to the track data for matched_track in matched_tracks: # ignore exact duplicates if track is matched_track: exact_dups += 1 continue old_group_str = ' '.join(get_track_groups(matched_track)) newgroups = get_track_groups(track) new_group_str = ' '.join(newgroups) if old_group_str == new_group_str: no_change += 1 continue track_data.append( (old_group_str, new_group_str, matched_track, newgroups)) yield (i, total) logger.info( "Match information: %s exact dups, %s no change, %s differing tracks", exact_dups, no_change, len(track_data), )
def _find_tracks(self, iter): """ finds tracks matching a given iter. """ self.load_subtree(iter) search = self.get_node_search_terms(iter) matcher = trax.TracksMatcher(search) srtrs = trax.search_tracks(self.tracks, [matcher]) return [ x.track for x in srtrs ]
def _find_tracks(self, iter): """ finds tracks matching a given iter. """ self.load_subtree(iter) search = self.get_node_search_terms(iter) matcher = trax.TracksMatcher(search) srtrs = trax.search_tracks(self.tracks, [matcher]) return [x.track for x in srtrs]
def get_tracks_for_path(self, path): """ Get tracks for a path from model (expand item) :param path: Gtk.TreePath :return: list of tracks [xl.trax.Track] """ it = self.get_model().get_iter(path) search = self.container.get_node_search_terms(it) matcher = trax.TracksMatcher(search) for i in trax.search_tracks(self.container.tracks, [matcher]): yield i.track
def track_import_thread(import_collection, user_collection, track_data): ''' Reads grouping information from tracks in a collection, and matches them with tracks contained in a separate collection. ''' total = float(len(import_collection)) # to import, all essential fields should be identical! fields = ['__length', 'artist', 'album', 'title', 'genre', 'tracknumber'] logger.info("Finding matches for %s imported tracks", len(import_collection)) exact_dups = 0 no_change = 0 # determine which tracks in this collection match existing # tracks in the exaile collection. grab the groups from them for i, track in enumerate(import_collection): # search for a matching track # -> currently exaile doesn't index tracks, and linear searches # for the track instead. Oh well. matchers = map(lambda t: TracksMatcher(track.get_tag_search(t)), fields) matched_tracks = [r.track for r in search_tracks(user_collection, matchers)] # if there are matches, add the data to the track data for matched_track in matched_tracks: # ignore exact duplicates if track is matched_track: exact_dups += 1 continue old_group_str = ' '.join(get_track_groups(matched_track)) newgroups = get_track_groups(track) new_group_str = ' '.join(newgroups) if old_group_str == new_group_str: no_change += 1 continue track_data.append((old_group_str, new_group_str, matched_track, newgroups)) yield (i, total) logger.info( "Match information: %s exact dups, %s no change, %s differing tracks", exact_dups, no_change, len(track_data), )
def run(self): total = float(len(self.import_collection)) # to import, all essential fields should be identical! fields = ['__length', 'artist', 'album', 'title', 'genre', 'tracknumber'] logger.info("Finding matches for %s imported tracks" % len(self.import_collection)) exact_dups = 0 no_change = 0 # determine which tracks in this collection match existing # tracks in the exaile collection. grab the groups from them for i, track in enumerate(self.import_collection): # search for a matching track # -> currently exaile doesn't index tracks, and linear searches # for the track instead. Oh well. matchers = map(lambda t: TracksMatcher(track.get_tag_search(t)), fields) matched_tracks = [r.track for r in search_tracks(self.user_collection, matchers)] # if there are matches, add the data to the track data for matched_track in matched_tracks: # ignore exact duplicates if track is matched_track: exact_dups += 1 continue old_group_str = ' '.join(get_track_groups(matched_track)) newgroups = get_track_groups(track) new_group_str = ' '.join(newgroups) if old_group_str == new_group_str: no_change += 1 continue self.track_data.append((old_group_str, new_group_str, matched_track, newgroups)) glib.idle_add(self.emit, 'progress-update', int(((i+1)/total)*100)) if self.do_stop: return logger.info("Match information: %s exact dups, %s no change, %s differing tracks" % (exact_dups, no_change, len(self.track_data))) glib.idle_add(self.emit, 'done')
def load_subtree(self, parent): """ Loads all the sub nodes for a specified node @param node: the node """ previously_loaded = False # was the subtree already loaded iter_sep = None if parent == None: depth = 0 else: if self.model.iter_n_children(parent) != 1 or \ self.model.get_value( self.model.iter_children(parent), 1) != None: previously_loaded = True iter_sep = self.model.iter_children(parent) depth = self.model.iter_depth(parent) + 1 if previously_loaded: return search = self.get_node_search_terms(parent) try: tags = self.order.get_sort_tags(depth) matchers = [trax.TracksMatcher(search)] srtrs = trax.search_tracks(self.tracks, matchers) # sort only if we are not on top level, because tracks are # already sorted by fist order if depth > 0: srtrs = trax.sort_result_tracks(tags, srtrs) except IndexError: return # at the bottom of the tree try: image = getattr(self, "%s_image"%tags[-1]) except: image = None bottom = False if depth == len(self.order)-1: bottom = True display_counts = settings.get_option('gui/display_track_counts', True) draw_seps = settings.get_option('gui/draw_separators', True) last_char = '' last_val = '' last_dval = '' last_matchq = '' count = 0 first = True path = None expanded = False to_expand = [] for srtr in srtrs: stagvals = [unicode(srtr.track.get_tag_sort(x, artist_compilations=True)) for x in tags] stagval = " ".join(stagvals) if (last_val != stagval or bottom): tagval = self.order.format_track(depth, srtr.track) match_query = " ".join([ srtr.track.get_tag_search(t, format=True, artist_compilations=True) for t in tags]) if bottom: match_query += " " + \ srtr.track.get_tag_search("__loc", format=True, artist_compilations=True) # Different *sort tags can cause stagval to not match # but the below code will produce identical entries in # the displayed tree. This condition checks to ensure # that new entries are added if and only if they will # display different results, avoiding that problem. if match_query != last_matchq or tagval != last_dval or bottom: if display_counts and path and not bottom: iter = self.model.get_iter(path) val = self.model.get_value(iter, 1) val = "%s (%s)"%(val, count) self.model.set_value(iter, 1, val) count = 0 last_val = stagval last_dval = tagval if depth == 0 and draw_seps: val = srtr.track.get_tag_sort(tags[0], artist_compilations=True) char = first_meaningful_char(val) if first: last_char = char else: if char != last_char and last_char != '': self.model.append(parent, [None, None, None]) last_char = char first = False last_matchq = match_query iter = self.model.append(parent, [image, tagval, match_query]) path = self.model.get_path(iter) expanded = False if not bottom: self.model.append(iter, [None, None, None]) count += 1 if not expanded: alltags = [] for i in range(depth+1, len(self.order)): alltags.extend(self.order.get_sort_tags(i)) for t in alltags: if t in srtr.on_tags: # keep original path intact for following block newpath = path if depth > 0: # for some reason, nested iters are always # off by one in the terminal entry. newpath = Gtk.TreePath.new_from_indices(newpath[:-1] + [newpath[-1]-1]) to_expand.append(newpath) expanded = True if display_counts and path and not bottom: iter = self.model.get_iter(path) val = self.model.get_value(iter, 1) val = "%s (%s)"%(val, count) self.model.set_value(iter, 1, val) count = 0 if settings.get_option("gui/expand_enabled", True) and \ len(to_expand) < \ settings.get_option("gui/expand_maximum_results", 100) and \ len(self.keyword.strip()) >= \ settings.get_option("gui/expand_minimum_term_length", 2): for row in to_expand: GLib.idle_add(self.tree.expand_row, row, False) if iter_sep is not None: self.model.remove(iter_sep)
def load_subtree(self, parent): """ Loads all the sub nodes for a specified node @param node: the node """ previously_loaded = False # was the subtree already loaded iter_sep = None if parent is None: depth = 0 else: if self.model.iter_n_children(parent) != 1 or \ self.model.get_value( self.model.iter_children(parent), 1) is not None: previously_loaded = True iter_sep = self.model.iter_children(parent) depth = self.model.iter_depth(parent) + 1 if previously_loaded: return search = self.get_node_search_terms(parent) try: tags = self.order.get_sort_tags(depth) matchers = [trax.TracksMatcher(search)] srtrs = trax.search_tracks(self.tracks, matchers) # sort only if we are not on top level, because tracks are # already sorted by fist order if depth > 0: srtrs = trax.sort_result_tracks(tags, srtrs) except IndexError: return # at the bottom of the tree try: image = getattr(self, "%s_image" % tags[-1]) except Exception: image = None bottom = False if depth == len(self.order) - 1: bottom = True display_counts = settings.get_option('gui/display_track_counts', True) draw_seps = settings.get_option('gui/draw_separators', True) last_char = '' last_val = '' last_dval = '' last_matchq = '' count = 0 first = True path = None expanded = False to_expand = [] for srtr in srtrs: stagvals = [unicode(srtr.track.get_tag_sort(x)) for x in tags] stagval = " ".join(stagvals) if (last_val != stagval or bottom): tagval = self.order.format_track(depth, srtr.track) match_query = " ".join([ srtr.track.get_tag_search(t, format=True) for t in tags]) if bottom: match_query += " " + \ srtr.track.get_tag_search("__loc", format=True) # Different *sort tags can cause stagval to not match # but the below code will produce identical entries in # the displayed tree. This condition checks to ensure # that new entries are added if and only if they will # display different results, avoiding that problem. if match_query != last_matchq or tagval != last_dval or bottom: if display_counts and path and not bottom: iter = self.model.get_iter(path) val = self.model.get_value(iter, 1) val = "%s (%s)" % (val, count) self.model.set_value(iter, 1, val) count = 0 last_val = stagval last_dval = tagval if depth == 0 and draw_seps: val = srtr.track.get_tag_sort(tags[0]) char = first_meaningful_char(val) if first: last_char = char else: if char != last_char and last_char != '': self.model.append(parent, [None, None, None]) last_char = char first = False last_matchq = match_query iter = self.model.append(parent, [image, tagval, match_query]) path = self.model.get_path(iter) expanded = False if not bottom: self.model.append(iter, [None, None, None]) count += 1 if not expanded: alltags = [] for i in range(depth + 1, len(self.order)): alltags.extend(self.order.get_sort_tags(i)) for t in alltags: if t in srtr.on_tags: # keep original path intact for following block newpath = path if depth > 0: # for some reason, nested iters are always # off by one in the terminal entry. newpath = Gtk.TreePath.new_from_indices(newpath[:-1] + [newpath[-1] - 1]) to_expand.append(newpath) expanded = True if display_counts and path and not bottom: iter = self.model.get_iter(path) val = self.model.get_value(iter, 1) val = "%s (%s)" % (val, count) self.model.set_value(iter, 1, val) count = 0 if settings.get_option("gui/expand_enabled", True) and \ len(to_expand) < \ settings.get_option("gui/expand_maximum_results", 100) and \ len(self.keyword.strip()) >= \ settings.get_option("gui/expand_minimum_term_length", 2): for row in to_expand: GLib.idle_add(self.tree.expand_row, row, False) if iter_sep is not None: self.model.remove(iter_sep)