Example #1
0
    def singletons(self, lib, query, move, pretend, write):
        """Retrieve and apply info from the autotagger for items matched by
        query.
        """
        for item in lib.items(query + [u'singleton:true']):
            item_formatted = format(item)
            if not item.mb_trackid:
                self._log.info(u'Skipping singleton with no mb_trackid: {0}',
                               item_formatted)
                continue

            # Do we have a valid MusicBrainz track ID?
            if not re.match(MBID_REGEX, item.mb_trackid):
                self._log.info(u'Skipping singleton with invalid mb_trackid:' +
                               ' {0}', item_formatted)
                continue

            # Get the MusicBrainz recording info.
            track_info = hooks.track_for_mbid(item.mb_trackid)
            if not track_info:
                self._log.info(u'Recording ID not found: {0} for track {0}',
                               item.mb_trackid,
                               item_formatted)
                continue

            # Apply.
            with lib.transaction():
                autotag.apply_item_metadata(item, track_info)
                apply_item_changes(lib, item, move, pretend, write)
Example #2
0
    def singletons(self, lib, query, move, pretend, write):
        """Retrieve and apply info from the autotagger for items matched by
        query.
        """
        for item in lib.items(query + ['singleton:true']):
            item_formatted = format(item)
            if not item.mb_trackid:
                self._log.info('Skipping singleton with no mb_trackid: {0}',
                               item_formatted)
                continue

            # Do we have a valid MusicBrainz track ID?
            if not re.match(MBID_REGEX, item.mb_trackid):
                self._log.info(
                    'Skipping singleton with invalid mb_trackid:' + ' {0}',
                    item_formatted)
                continue

            # Get the MusicBrainz recording info.
            track_info = hooks.track_for_mbid(item.mb_trackid)
            if not track_info:
                self._log.info('Recording ID not found: {0} for track {0}',
                               item.mb_trackid, item_formatted)
                continue

            # Apply.
            with lib.transaction():
                autotag.apply_item_metadata(item, track_info)
                apply_item_changes(lib, item, move, pretend, write)
Example #3
0
def mbsync_singletons(lib, query, move, pretend, write):
    """Synchronize matching singleton items.
    """
    singletons_query = library.get_query(query, library.Item)
    singletons_query.subqueries.append(
        dbcore.query.BooleanQuery('singleton', True)
    )
    for s in lib.items(singletons_query):
        if not s.mb_trackid:
            log.info(u'Skipping singleton {0}: has no mb_trackid'
                     .format(s.title))
            continue

        old_data = dict(s)

        # Get the MusicBrainz recording info.
        track_info = hooks.track_for_mbid(s.mb_trackid)
        if not track_info:
            log.info(u'Recording ID not found: {0}'.format(s.mb_trackid))
            continue

        # Apply.
        with lib.transaction():
            autotag.apply_item_metadata(s, track_info)
            _print_and_apply_changes(lib, s, old_data, move, pretend, write)
Example #4
0
def mbsync_singletons(lib, query, move, pretend, write):
    """Retrieve and apply info from the autotagger for items matched by
    query.
    """
    for item in lib.items(query + ['singleton:true']):
        if not item.mb_trackid:
            log.info(u'Skipping singleton {0}: has no mb_trackid', item.title)
            continue

        # Get the MusicBrainz recording info.
        track_info = hooks.track_for_mbid(item.mb_trackid)
        if not track_info:
            log.info(u'Recording ID not found: {0}', item.mb_trackid)
            continue

        # Apply.
        with lib.transaction():
            autotag.apply_item_metadata(item, track_info)
            apply_item_changes(lib, item, move, pretend, write)
Example #5
0
def mbsync_singletons(lib, query, move, pretend, write):
    """Retrieve and apply info from the autotagger for items matched by
    query.
    """
    for item in lib.items(query + ['singleton:true']):
        if not item.mb_trackid:
            log.info(u'Skipping singleton {0}: has no mb_trackid', item.title)
            continue

        # Get the MusicBrainz recording info.
        track_info = hooks.track_for_mbid(item.mb_trackid)
        if not track_info:
            log.info(u'Recording ID not found: {0}', item.mb_trackid)
            continue

        # Apply.
        with lib.transaction():
            autotag.apply_item_metadata(item, track_info)
            apply_item_changes(lib, item, move, pretend, write)
Example #6
0
def mbsync_singletons(lib, query, move, pretend, write):
    """Synchronize matching singleton items.
    """
    singletons_query = library.get_query(query, library.Item)
    singletons_query.subqueries.append(library.SingletonQuery(True))
    for s in lib.items(singletons_query):
        if not s.mb_trackid:
            log.info(u'Skipping singleton {0}: has no mb_trackid'.format(
                s.title))
            continue

        old_data = dict(s)

        # Get the MusicBrainz recording info.
        track_info = hooks.track_for_mbid(s.mb_trackid)
        if not track_info:
            log.info(u'Recording ID not found: {0}'.format(s.mb_trackid))
            continue

        # Apply.
        with lib.transaction():
            autotag.apply_item_metadata(s, track_info)
            _print_and_apply_changes(lib, s, old_data, move, pretend, write)
Example #7
0
    def singletons(self, lib, query, move, pretend, write):
        """Retrieve and apply info from the autotagger for items matched by
        query.
        """
        for item in lib.items(query + ['singleton:true']):
            if not item.mb_trackid:
                self._log.info('Skipping singleton with no mb_trackid: {}',
                               item)
                continue

            if not self.is_beatport_track(item):
                self._log.info(
                    'Skipping non-{} singleton: {}',
                    self.beatport_plugin.data_source,
                    item,
                )
                continue

            # Apply.
            trackinfo = self.beatport_plugin.track_for_id(item.mb_trackid)
            with lib.transaction():
                autotag.apply_item_metadata(item, trackinfo)
                apply_item_changes(lib, item, move, pretend, write)
Example #8
0
    def show_changes(self, lib, task, match=None):
        if match is None:
            match = task.match

        changes = False
        if task.is_album:
            newmapping = {new_item(item): track_info for item, track_info in match.mapping.items()}
            autotag.apply_metadata(match.info, newmapping)

            # olditems[0].get_album() isn't working, create our own to compare
            olditems = list(match.mapping.keys())
            oldvalues = dict((key, olditems[0][key]) for key in self.album_fields)
            oldalbum = library.Album(lib, **oldvalues)

            newitems = list(newmapping.keys())
            values = dict((key, newitems[0][key]) for key in self.album_fields)
            album = library.Album(lib, **values)
            compare_fields = self.get_fields(self.album_fields, oldvalues)

            album_changes = show_model_changes(album, oldalbum, compare_fields)
            if album_changes:
                changes = True

            new_by_info = {track_info: item for item, track_info in newmapping.items()}
            for item, track_info in match.mapping.items():
                newitem = new_by_info[track_info]
                compare_fields = self.get_fields(self.nonalbum_fields, item)
                item_changes = show_model_changes(newitem, item, compare_fields)
                if item_changes:
                    changes = True
        else:
            fakeitem = new_item(task.item)
            autotag.apply_item_metadata(fakeitem, match.info)
            compare_fields = self.get_fields(self.all_fields, task.item)
            changes = show_model_changes(fakeitem, task.item, compare_fields)

        return changes
Example #9
0
    def singletons(self, lib, query, move, pretend, write, fmt):
        """Retrieve and apply info from the autotagger for items matched by
        query.
        """
        template = Template(ui._pick_format(False, fmt))

        for item in lib.items(query + ['singleton:true']):
            item_formatted = item.evaluate_template(template)
            if not item.mb_trackid:
                self._log.info(u'Skipping singleton with no mb_trackid: {0}',
                               item_formatted)
                continue

            # Get the MusicBrainz recording info.
            track_info = hooks.track_for_mbid(item.mb_trackid)
            if not track_info:
                self._log.info(u'Recording ID not found: {0} for track {0}',
                               item.mb_trackid, item_formatted)
                continue

            # Apply.
            with lib.transaction():
                autotag.apply_item_metadata(item, track_info)
                apply_item_changes(lib, item, move, pretend, write)
Example #10
0
def apply_choices(session):
    """A coroutine for applying changes to albums and singletons during
    the autotag process.
    """
    task = None
    while True:
        task = yield task
        if task.should_skip():
            continue

        items = task.imported_items()
        # Clear IDs in case the items are being re-tagged.
        for item in items:
            item.id = None
            item.album_id = None

        # Change metadata.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(task.match.info, task.match.mapping)
            else:
                autotag.apply_item_metadata(task.item, task.match.info)
            plugins.send('import_task_apply', session=session, task=task)

        # Infer album-level fields.
        if task.is_album:
            _infer_album_fields(task)

        # Find existing item entries that these are replacing (for
        # re-imports). Old album structures are automatically cleaned up
        # when the last item is removed.
        task.replaced_items = defaultdict(list)
        for item in items:
            dup_items = session.lib.items(library.MatchQuery(
                'path', item.path))
            for dup_item in dup_items:
                task.replaced_items[item].append(dup_item)
                log.debug('replacing item %i: %s' %
                          (dup_item.id, displayable_path(item.path)))
        log.debug('%i of %i items replaced' %
                  (len(task.replaced_items), len(items)))

        # Find old items that should be replaced as part of a duplicate
        # resolution.
        duplicate_items = []
        if task.remove_duplicates:
            if task.is_album:
                for album in _duplicate_check(session.lib, task):
                    duplicate_items += album.items()
            else:
                duplicate_items = _item_duplicate_check(session.lib, task)
            log.debug('removing %i old duplicated items' %
                      len(duplicate_items))

            # Delete duplicate files that are located inside the library
            # directory.
            for duplicate_path in [i.path for i in duplicate_items]:
                if session.lib.directory in util.ancestry(duplicate_path):
                    log.debug(u'deleting replaced duplicate %s' %
                              util.displayable_path(duplicate_path))
                    util.remove(duplicate_path)
                    util.prune_dirs(os.path.dirname(duplicate_path),
                                    session.lib.directory)

        # Add items -- before path changes -- to the library. We add the
        # items now (rather than at the end) so that album structures
        # are in place before calls to destination().
        with session.lib.transaction():
            # Remove old items.
            for replaced in task.replaced_items.itervalues():
                for item in replaced:
                    session.lib.remove(item)
            for item in duplicate_items:
                session.lib.remove(item)

            # Add new ones.
            if task.is_album:
                # Add an album.
                album = session.lib.add_album(items)
                task.album_id = album.id
            else:
                # Add tracks.
                for item in items:
                    session.lib.add(item)
Example #11
0
def apply_choices(config):
    """A coroutine for applying changes to albums during the autotag
    process. The parameters to the generator control the behavior of
    the import. The coroutine accepts ImportTask objects and yields
    nothing.
    """
    lib = _reopen_lib(config.lib)
    while True:    
        task = yield
        # Don't do anything if we're skipping the album or we're done.
        if task.sentinel or task.choice_flag == action.SKIP:
            if config.resume is not False:
                task.save_progress()
            continue

        # Change metadata, move, and copy.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(task.items, task.info)
            else:
                autotag.apply_item_metadata(task.item, task.info)
        items = task.items if task.is_album else [task.item]
        if config.copy and config.delete:
            old_paths = [os.path.realpath(syspath(item.path)) for item in items]
        for item in items:
            if config.copy:
                item.move(lib, True, task.should_create_album())
            if config.write and task.should_write_tags():
                item.write()

        # Add items to library. We consolidate this at the end to avoid
        # locking while we do the copying and tag updates.
        if task.should_create_album():
            # Add an album.
            albuminfo = lib.add_album(task.items,
                                      infer_aa = task.should_infer_aa())
        else:
            # Add tracks.
            for item in items:
                lib.add(item)
        lib.save()

        # Get album art if requested.
        if config.art and task.should_fetch_art():
            artpath = beets.autotag.art.art_for_album(task.info)
            if artpath:
                albuminfo.set_art(artpath)
        lib.save()

        # Announce that we've added an album.
        if task.should_create_album():
            plugins.send('album_imported', lib=lib, album=albuminfo)
        else:
            plugins.send('item_imported', lib=lib, item=task.item)

        # Finally, delete old files.
        if config.copy and config.delete:
            new_paths = [os.path.realpath(item.path) for item in items]
            for old_path in old_paths:
                # Only delete files that were actually moved.
                if old_path not in new_paths:
                    os.remove(syspath(old_path))

        # Update progress.
        if config.resume is not False:
            task.save_progress()
Example #12
0
def apply_choices(config):
    """A coroutine for applying changes to albums during the autotag
    process.
    """
    lib = _reopen_lib(config.lib)
    task = None
    while True:    
        task = yield task
        if task.should_skip():
            continue

        items = [i for i in task.items if i] if task.is_album else [task.item]
        # Clear IDs in case the items are being re-tagged.
        for item in items:
            item.id = None
            item.album_id = None

        # Change metadata.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(task.items, task.info)
            else:
                autotag.apply_item_metadata(task.item, task.info)

        # Infer album-level fields.
        if task.is_album:
            _infer_album_fields(task)

        # Find existing item entries that these are replacing. Old
        # album structures are automatically cleaned up when the
        # last item is removed.
        replaced_items = defaultdict(list)
        for item in items:
            dup_items = lib.items(library.MatchQuery('path', item.path))
            for dup_item in dup_items:
                replaced_items[item].append(dup_item)
                log.debug('replacing item %i: %s' %
                          (dup_item.id, displayable_path(item.path)))
        log.debug('%i of %i items replaced' % (len(replaced_items),
                                               len(items)))

        # Move/copy files.
        task.old_paths = [item.path for item in items]
        for item in items:
            if config.copy:
                # If we're replacing an item, then move rather than
                # copying.
                do_copy = not bool(replaced_items[item])
                lib.move(item, do_copy, task.is_album)
            if config.write and task.should_write_tags():
                item.write()

        # Add items to library. We consolidate this at the end to avoid
        # locking while we do the copying and tag updates.
        try:
            # Remove old items.
            for replaced in replaced_items.itervalues():
                for item in replaced:
                    lib.remove(item)

            # Add new ones.
            if task.is_album:
                # Add an album.
                album = lib.add_album(items)
                task.album_id = album.id
            else:
                # Add tracks.
                for item in items:
                    lib.add(item)
        finally:
            lib.save()
Example #13
0
 def apply_metadata(self):
     autotag.apply_item_metadata(self.item, self.match.info)
Example #14
0
def apply_choices(config):
    """A coroutine for applying changes to albums during the autotag
    process.
    """
    lib = _reopen_lib(config.lib)
    task = None
    while True:    
        task = yield task
        if task.should_skip():
            continue

        items = [i for i in task.items if i] if task.is_album else [task.item]
        # Clear IDs in case the items are being re-tagged.
        for item in items:
            item.id = None
            item.album_id = None

        # Change metadata.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(task.items, task.info)
            else:
                autotag.apply_item_metadata(task.item, task.info)

        # Infer album-level fields.
        if task.is_album:
            _infer_album_fields(task)

        # Find existing item entries that these are replacing. Old
        # album structures are automatically cleaned up when the
        # last item is removed.
        replaced_items = defaultdict(list)
        for item in items:
            dup_items = lib.items(library.MatchQuery('path', item.path))
            for dup_item in dup_items:
                replaced_items[item].append(dup_item)
                log.debug('replacing item %i: %s' %
                          (dup_item.id, displayable_path(item.path)))
        log.debug('%i of %i items replaced' % (len(replaced_items),
                                               len(items)))

        # Move/copy files.
        task.old_paths = [item.path for item in items]
        for item in items:
            if config.copy:
                # If we're replacing an item, then move rather than
                # copying.
                old_path = item.path
                do_copy = not bool(replaced_items[item])
                lib.move(item, do_copy, task.is_album)
                if not do_copy:
                    # If we moved the item, remove the now-nonexistent
                    # file from old_paths.
                    task.old_paths.remove(old_path)
            if config.write and task.should_write_tags():
                item.write()

        # Add items to library. We consolidate this at the end to avoid
        # locking while we do the copying and tag updates.
        try:
            # Remove old items.
            for replaced in replaced_items.itervalues():
                for item in replaced:
                    lib.remove(item)

            # Add new ones.
            if task.is_album:
                # Add an album.
                album = lib.add_album(items)
                task.album_id = album.id
            else:
                # Add tracks.
                for item in items:
                    lib.add(item)
        finally:
            lib.save()
Example #15
0
 def apply_metadata(self):
     autotag.apply_item_metadata(self.item, self.match.info)
Example #16
0
def apply_choices(session):
    """A coroutine for applying changes to albums and singletons during
    the autotag process.
    """
    task = None
    while True:
        task = yield task
        if task.should_skip():
            continue

        items = task.imported_items()
        # Clear IDs in case the items are being re-tagged.
        for item in items:
            item.id = None
            item.album_id = None

        # Change metadata.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(
                    task.match.info, task.match.mapping
                )
            else:
                autotag.apply_item_metadata(task.item, task.match.info)
            plugins.send('import_task_apply', session=session, task=task)

        # Infer album-level fields.
        if task.is_album:
            _infer_album_fields(task)

        # Find existing item entries that these are replacing (for
        # re-imports). Old album structures are automatically cleaned up
        # when the last item is removed.
        task.replaced_items = defaultdict(list)
        for item in items:
            dup_items = session.lib.items(library.MatchQuery('path', item.path))
            for dup_item in dup_items:
                task.replaced_items[item].append(dup_item)
                log.debug('replacing item %i: %s' %
                          (dup_item.id, displayable_path(item.path)))
        log.debug('%i of %i items replaced' % (len(task.replaced_items),
                                               len(items)))

        # Find old items that should be replaced as part of a duplicate
        # resolution.
        duplicate_items = []
        if task.remove_duplicates:
            if task.is_album:
                for album in _duplicate_check(session.lib, task):
                    duplicate_items += album.items()
            else:
                duplicate_items = _item_duplicate_check(session.lib, task)
            log.debug('removing %i old duplicated items' %
                      len(duplicate_items))

            # Delete duplicate files that are located inside the library
            # directory.
            for duplicate_path in [i.path for i in duplicate_items]:
                if session.lib.directory in util.ancestry(duplicate_path):
                    log.debug(u'deleting replaced duplicate %s' %
                              util.displayable_path(duplicate_path))
                    util.remove(duplicate_path)
                    util.prune_dirs(os.path.dirname(duplicate_path),
                                    session.lib.directory)

        # Add items -- before path changes -- to the library. We add the
        # items now (rather than at the end) so that album structures
        # are in place before calls to destination().
        with session.lib.transaction():
            # Remove old items.
            for replaced in task.replaced_items.itervalues():
                for item in replaced:
                    session.lib.remove(item)
            for item in duplicate_items:
                session.lib.remove(item)

            # Add new ones.
            if task.is_album:
                # Add an album.
                album = session.lib.add_album(items)
                task.album_id = album.id
            else:
                # Add tracks.
                for item in items:
                    session.lib.add(item)
Example #17
0
def apply_choices(config):
    """A coroutine for applying changes to albums during the autotag
    process.
    """
    lib = _reopen_lib(config.lib)
    task = None
    while True:    
        task = yield task
        if task.should_skip():
            continue

        items = task.all_items()
        # Clear IDs in case the items are being re-tagged.
        for item in items:
            item.id = None
            item.album_id = None

        # Change metadata.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(task.items, task.info)
            else:
                autotag.apply_item_metadata(task.item, task.info)
            plugins.send('import_task_apply', config=config, task=task)

        # Infer album-level fields.
        if task.is_album:
            _infer_album_fields(task)

        # Find existing item entries that these are replacing (for
        # re-imports). Old album structures are automatically cleaned up
        # when the last item is removed.
        replaced_items = defaultdict(list)
        for item in items:
            dup_items = lib.items(library.MatchQuery('path', item.path))
            for dup_item in dup_items:
                replaced_items[item].append(dup_item)
                log.debug('replacing item %i: %s' %
                          (dup_item.id, displayable_path(item.path)))
        log.debug('%i of %i items replaced' % (len(replaced_items),
                                               len(items)))

        # Find old items that should be replaced as part of a duplicate
        # resolution.
        duplicate_items = []
        if task.remove_duplicates:
            if task.is_album:
                for album in _duplicate_check(lib, task):
                    duplicate_items += album.items()
            else:
                duplicate_items = _item_duplicate_check(lib, task)
            log.debug('removing %i old duplicated items' %
                      len(duplicate_items))

            # Delete duplicate files that are located inside the library
            # directory.
            for duplicate_path in [i.path for i in duplicate_items]:
                if lib.directory in util.ancestry(duplicate_path):
                    log.debug(u'deleting replaced duplicate %s' %
                              util.displayable_path(duplicate_path))
                    util.soft_remove(duplicate_path)
                    util.prune_dirs(os.path.dirname(duplicate_path),
                                    lib.directory)

        # Add items -- before path changes -- to the library. We add the
        # items now (rather than at the end) so that album structures
        # are in place before calls to destination().
        try:
            # Remove old items.
            for replaced in replaced_items.itervalues():
                for item in replaced:
                    lib.remove(item)
            for item in duplicate_items:
                lib.remove(item)

            # Add new ones.
            if task.is_album:
                # Add an album.
                album = lib.add_album(items)
                task.album_id = album.id
            else:
                # Add tracks.
                for item in items:
                    lib.add(item)
        finally:
            lib.save()

        # Move/copy files.
        task.old_paths = [item.path for item in items]  # For deletion.
        for item in items:
            if config.copy or config.move:
                if config.move:
                    # Just move the file.
                    lib.move(item, False)
                else:
                    # If it's a reimport, move the file. Otherwise, copy
                    # and keep track of the old path.
                    old_path = item.path
                    do_copy = not bool(replaced_items[item])
                    lib.move(item, do_copy)
                    if not do_copy:
                        # If we moved the item, remove the now-nonexistent
                        # file from old_paths.
                        task.old_paths.remove(old_path)

            if config.write and task.should_write_tags():
                item.write()

        # Save new paths.
        try:
            for item in items:
                lib.store(item)
        finally:
            lib.save()