mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
Renamed all action occurrences with Action.
This commit is contained in:
parent
9147577b2b
commit
68acaa6470
16 changed files with 227 additions and 174 deletions
38
beets/importer/__init__.py
Normal file
38
beets/importer/__init__.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# This file is part of beets.
|
||||
# Copyright 2016, Adrian Sampson.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""Provides the basic, interface-agnostic workflow for importing and
|
||||
autotagging music files.
|
||||
"""
|
||||
|
||||
from .session import ImportAbortError, ImportSession
|
||||
from .tasks import (
|
||||
Action,
|
||||
ArchiveImportTask,
|
||||
ImportTask,
|
||||
SentinelImportTask,
|
||||
SingletonImportTask,
|
||||
)
|
||||
|
||||
# Note: Stages are not exposed to the public API
|
||||
|
||||
__all__ = [
|
||||
"ImportSession",
|
||||
"ImportAbortError",
|
||||
"Action",
|
||||
"ImportTask",
|
||||
"ArchiveImportTask",
|
||||
"SentinelImportTask",
|
||||
"SingletonImportTask",
|
||||
]
|
||||
|
|
@ -18,10 +18,10 @@ import time
|
|||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from beets import config, dbcore, library, logging, plugins, util
|
||||
from beets.importer.tasks import action
|
||||
from beets.importer.tasks import Action
|
||||
from beets.util import displayable_path, normpath, pipeline, syspath
|
||||
|
||||
from .stages import *
|
||||
from . import stages as stagefuncs
|
||||
from .state import ImportState
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -162,15 +162,15 @@ class ImportSession:
|
|||
# Duplicate: log all three choices (skip, keep both, and trump).
|
||||
if task.should_remove_duplicates:
|
||||
self.tag_log("duplicate-replace", paths)
|
||||
elif task.choice_flag in (action.ASIS, action.APPLY):
|
||||
elif task.choice_flag in (Action.ASIS, Action.APPLY):
|
||||
self.tag_log("duplicate-keep", paths)
|
||||
elif task.choice_flag is action.SKIP:
|
||||
elif task.choice_flag is Action.SKIP:
|
||||
self.tag_log("duplicate-skip", paths)
|
||||
else:
|
||||
# Non-duplicate: log "skip" and "asis" choices.
|
||||
if task.choice_flag is action.ASIS:
|
||||
if task.choice_flag is Action.ASIS:
|
||||
self.tag_log("asis", paths)
|
||||
elif task.choice_flag is action.SKIP:
|
||||
elif task.choice_flag is Action.SKIP:
|
||||
self.tag_log("skip", paths)
|
||||
|
||||
def should_resume(self, path: PathBytes):
|
||||
|
|
@ -192,17 +192,17 @@ class ImportSession:
|
|||
|
||||
# Set up the pipeline.
|
||||
if self.query is None:
|
||||
stages = [read_tasks(self)]
|
||||
stages = [stagefuncs.read_tasks(self)]
|
||||
else:
|
||||
stages = [query_tasks(self)]
|
||||
stages = [stagefuncs.query_tasks(self)]
|
||||
|
||||
# In pretend mode, just log what would otherwise be imported.
|
||||
if self.config["pretend"]:
|
||||
stages += [log_files(self)]
|
||||
stages += [stagefuncs.log_files(self)]
|
||||
else:
|
||||
if self.config["group_albums"] and not self.config["singletons"]:
|
||||
# Split directory tasks into one task for each album.
|
||||
stages += [group_albums(self)]
|
||||
stages += [stagefuncs.group_albums(self)]
|
||||
|
||||
# These stages either talk to the user to get a decision or,
|
||||
# in the case of a non-autotagged import, just choose to
|
||||
|
|
@ -210,17 +210,20 @@ class ImportSession:
|
|||
# also add the music to the library database, so later
|
||||
# stages need to read and write data from there.
|
||||
if self.config["autotag"]:
|
||||
stages += [lookup_candidates(self), user_query(self)]
|
||||
stages += [
|
||||
stagefuncs.lookup_candidates(self),
|
||||
stagefuncs.user_query(self),
|
||||
]
|
||||
else:
|
||||
stages += [import_asis(self)]
|
||||
stages += [stagefuncs.import_asis(self)]
|
||||
|
||||
# Plugin stages.
|
||||
for stage_func in plugins.early_import_stages():
|
||||
stages.append(plugin_stage(self, stage_func))
|
||||
stages.append(stagefuncs.plugin_stage(self, stage_func))
|
||||
for stage_func in plugins.import_stages():
|
||||
stages.append(plugin_stage(self, stage_func))
|
||||
stages.append(stagefuncs.plugin_stage(self, stage_func))
|
||||
|
||||
stages += [manipulate_files(self)]
|
||||
stages += [stagefuncs.manipulate_files(self)]
|
||||
|
||||
pl = pipeline.Pipeline(stages)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from beets import config, plugins
|
|||
from beets.util import MoveOperation, displayable_path, pipeline
|
||||
|
||||
from .tasks import (
|
||||
action,
|
||||
Action,
|
||||
ImportTask,
|
||||
ImportTaskFactory,
|
||||
SentinelImportTask,
|
||||
|
|
@ -173,7 +173,7 @@ def user_query(session: ImportSession, task: ImportTask):
|
|||
plugins.send("import_task_choice", session=session, task=task)
|
||||
|
||||
# As-tracks: transition to singleton workflow.
|
||||
if task.choice_flag is action.TRACKS:
|
||||
if task.choice_flag is Action.TRACKS:
|
||||
# Set up a little pipeline for dealing with the singletons.
|
||||
def emitter(task):
|
||||
for item in task.items:
|
||||
|
|
@ -186,7 +186,7 @@ def user_query(session: ImportSession, task: ImportTask):
|
|||
)
|
||||
|
||||
# As albums: group items by albums and create task for each album
|
||||
if task.choice_flag is action.ALBUMS:
|
||||
if task.choice_flag is Action.ALBUMS:
|
||||
return _extend_pipeline(
|
||||
[task],
|
||||
group_albums(session),
|
||||
|
|
@ -194,7 +194,7 @@ def user_query(session: ImportSession, task: ImportTask):
|
|||
user_query(session),
|
||||
)
|
||||
|
||||
resolve_duplicates(session, task)
|
||||
_resolve_duplicates(session, task)
|
||||
|
||||
if task.should_merge_duplicates:
|
||||
# Create a new task for tagging the current items
|
||||
|
|
@ -216,7 +216,7 @@ def user_query(session: ImportSession, task: ImportTask):
|
|||
[merged_task], lookup_candidates(session), user_query(session)
|
||||
)
|
||||
|
||||
apply_choice(session, task)
|
||||
_apply_choice(session, task)
|
||||
return task
|
||||
|
||||
|
||||
|
|
@ -231,8 +231,8 @@ def import_asis(session: ImportSession, task: ImportTask):
|
|||
return
|
||||
|
||||
log.info("{}", displayable_path(task.paths))
|
||||
task.set_choice(action.ASIS)
|
||||
apply_choice(session, task)
|
||||
task.set_choice(Action.ASIS)
|
||||
_apply_choice(session, task)
|
||||
|
||||
|
||||
@pipeline.mutator_stage
|
||||
|
|
@ -312,7 +312,7 @@ def manipulate_files(session: ImportSession, task: ImportTask):
|
|||
# Private functions only used in the stages above
|
||||
|
||||
|
||||
def apply_choice(session: ImportSession, task: ImportTask):
|
||||
def _apply_choice(session: ImportSession, task: ImportTask):
|
||||
"""Apply the task's choice to the Album or Item it contains and add
|
||||
it to the library.
|
||||
"""
|
||||
|
|
@ -335,11 +335,11 @@ def apply_choice(session: ImportSession, task: ImportTask):
|
|||
task.set_fields(session.lib)
|
||||
|
||||
|
||||
def resolve_duplicates(session: ImportSession, task: ImportTask):
|
||||
def _resolve_duplicates(session: ImportSession, task: ImportTask):
|
||||
"""Check if a task conflicts with items or albums already imported
|
||||
and ask the session to resolve this.
|
||||
"""
|
||||
if task.choice_flag in (action.ASIS, action.APPLY, action.RETAG):
|
||||
if task.choice_flag in (Action.ASIS, Action.APPLY, Action.RETAG):
|
||||
found_duplicates = task.find_duplicates(session.lib)
|
||||
if found_duplicates:
|
||||
log.debug(
|
||||
|
|
@ -360,7 +360,7 @@ def resolve_duplicates(session: ImportSession, task: ImportTask):
|
|||
|
||||
if duplicate_action == "s":
|
||||
# Skip new.
|
||||
task.set_choice(action.SKIP)
|
||||
task.set_choice(Action.SKIP)
|
||||
elif duplicate_action == "k":
|
||||
# Keep both. Do nothing; leave the choice intact.
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ from beets import autotag, config, dbcore, library, plugins, util
|
|||
from .state import ImportState
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .session import ImportSession
|
||||
from .session import ImportSession, PathBytes
|
||||
|
||||
# Global logger.
|
||||
log = logging.getLogger("beets")
|
||||
|
|
@ -62,18 +62,26 @@ REIMPORT_FRESH_FIELDS_ITEM = list(REIMPORT_FRESH_FIELDS_ALBUM)
|
|||
log = logging.getLogger("beets")
|
||||
|
||||
|
||||
action = Enum("action", ["SKIP", "ASIS", "TRACKS", "APPLY", "ALBUMS", "RETAG"])
|
||||
# The RETAG action represents "don't apply any match, but do record
|
||||
# new metadata". It's not reachable via the standard command prompt but
|
||||
# can be used by plugins.
|
||||
|
||||
|
||||
class ImportAbortError(Exception):
|
||||
"""Raised when the user aborts the tagging operation."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class Action(Enum):
|
||||
"""Enumeration of possible actions for an import task."""
|
||||
|
||||
SKIP = "SKIP"
|
||||
ASIS = "ASIS"
|
||||
TRACKS = "TRACKS"
|
||||
APPLY = "APPLY"
|
||||
ALBUMS = "ALBUMS"
|
||||
RETAG = "RETAG"
|
||||
# The RETAG action represents "don't apply any match, but do record
|
||||
# new metadata". It's not reachable via the standard command prompt but
|
||||
# can be used by plugins.
|
||||
|
||||
|
||||
class BaseImportTask:
|
||||
"""An abstract base class for importer tasks.
|
||||
|
||||
|
|
@ -143,7 +151,7 @@ class ImportTask(BaseImportTask):
|
|||
system.
|
||||
"""
|
||||
|
||||
choice_flag: action | None = None
|
||||
choice_flag: Action | None = None
|
||||
match: autotag.AlbumMatch | autotag.TrackMatch | None = None
|
||||
|
||||
# Keep track of the current task item
|
||||
|
|
@ -165,7 +173,7 @@ class ImportTask(BaseImportTask):
|
|||
self.search_ids = [] # user-supplied candidate IDs.
|
||||
|
||||
def set_choice(
|
||||
self, choice: action | autotag.AlbumMatch | autotag.TrackMatch
|
||||
self, choice: Action | autotag.AlbumMatch | autotag.TrackMatch
|
||||
):
|
||||
"""Given an AlbumMatch or TrackMatch object or an action constant,
|
||||
indicates that an action has been selected for this task.
|
||||
|
|
@ -174,20 +182,20 @@ class ImportTask(BaseImportTask):
|
|||
use isinstance to check for them.
|
||||
"""
|
||||
# Not part of the task structure:
|
||||
assert choice != action.APPLY # Only used internally.
|
||||
assert choice != Action.APPLY # Only used internally.
|
||||
|
||||
if choice in (
|
||||
action.SKIP,
|
||||
action.ASIS,
|
||||
action.TRACKS,
|
||||
action.ALBUMS,
|
||||
action.RETAG,
|
||||
Action.SKIP,
|
||||
Action.ASIS,
|
||||
Action.TRACKS,
|
||||
Action.ALBUMS,
|
||||
Action.RETAG,
|
||||
):
|
||||
# TODO: redesign to stricten the type
|
||||
self.choice_flag = choice # type: ignore[assignment]
|
||||
self.match = None
|
||||
else:
|
||||
self.choice_flag = action.APPLY # Implicit choice.
|
||||
self.choice_flag = Action.APPLY # Implicit choice.
|
||||
self.match = choice # type: ignore[assignment]
|
||||
|
||||
def save_progress(self):
|
||||
|
|
@ -205,11 +213,11 @@ class ImportTask(BaseImportTask):
|
|||
|
||||
@property
|
||||
def apply(self):
|
||||
return self.choice_flag == action.APPLY
|
||||
return self.choice_flag == Action.APPLY
|
||||
|
||||
@property
|
||||
def skip(self):
|
||||
return self.choice_flag == action.SKIP
|
||||
return self.choice_flag == Action.SKIP
|
||||
|
||||
# Convenient data.
|
||||
|
||||
|
|
@ -219,10 +227,10 @@ class ImportTask(BaseImportTask):
|
|||
(in which case the data comes from the files' current metadata)
|
||||
or APPLY (in which case the data comes from the choice).
|
||||
"""
|
||||
if self.choice_flag in (action.ASIS, action.RETAG):
|
||||
if self.choice_flag in (Action.ASIS, Action.RETAG):
|
||||
likelies, consensus = autotag.current_metadata(self.items)
|
||||
return likelies
|
||||
elif self.choice_flag is action.APPLY and self.match:
|
||||
elif self.choice_flag is Action.APPLY and self.match:
|
||||
return self.match.info.copy()
|
||||
assert False
|
||||
|
||||
|
|
@ -232,9 +240,9 @@ class ImportTask(BaseImportTask):
|
|||
If the tasks applies an album match the method only returns the
|
||||
matched items.
|
||||
"""
|
||||
if self.choice_flag in (action.ASIS, action.RETAG):
|
||||
if self.choice_flag in (Action.ASIS, Action.RETAG):
|
||||
return list(self.items)
|
||||
elif self.choice_flag == action.APPLY and isinstance(
|
||||
elif self.choice_flag == Action.APPLY and isinstance(
|
||||
self.match, autotag.AlbumMatch
|
||||
):
|
||||
return list(self.match.mapping.keys())
|
||||
|
|
@ -401,7 +409,7 @@ class ImportTask(BaseImportTask):
|
|||
"""
|
||||
changes = {}
|
||||
|
||||
if self.choice_flag == action.ASIS:
|
||||
if self.choice_flag == Action.ASIS:
|
||||
# Taking metadata "as-is". Guess whether this album is VA.
|
||||
plur_albumartist, freq = util.plurality(
|
||||
[i.albumartist or i.artist for i in self.items]
|
||||
|
|
@ -418,7 +426,7 @@ class ImportTask(BaseImportTask):
|
|||
changes["albumartist"] = config["va_name"].as_str()
|
||||
changes["comp"] = True
|
||||
|
||||
elif self.choice_flag in (action.APPLY, action.RETAG):
|
||||
elif self.choice_flag in (Action.APPLY, Action.RETAG):
|
||||
# Applying autotagged metadata. Just get AA from the first
|
||||
# item.
|
||||
if not self.items[0].albumartist:
|
||||
|
|
@ -473,7 +481,7 @@ class ImportTask(BaseImportTask):
|
|||
# old paths.
|
||||
item.move(operation)
|
||||
|
||||
if write and (self.apply or self.choice_flag == action.RETAG):
|
||||
if write and (self.apply or self.choice_flag == Action.RETAG):
|
||||
item.try_write()
|
||||
|
||||
with session.lib.transaction():
|
||||
|
|
@ -490,7 +498,7 @@ class ImportTask(BaseImportTask):
|
|||
self.remove_replaced(lib)
|
||||
|
||||
self.album = lib.add_album(self.imported_items())
|
||||
if self.choice_flag == action.APPLY and isinstance(
|
||||
if self.choice_flag == Action.APPLY and isinstance(
|
||||
self.match, autotag.AlbumMatch
|
||||
):
|
||||
# Copy album flexible fields to the DB
|
||||
|
|
@ -672,10 +680,10 @@ class SingletonImportTask(ImportTask):
|
|||
(in which case the data comes from the files' current metadata)
|
||||
or APPLY (in which case the data comes from the choice).
|
||||
"""
|
||||
assert self.choice_flag in (action.ASIS, action.RETAG, action.APPLY)
|
||||
if self.choice_flag in (action.ASIS, action.RETAG):
|
||||
assert self.choice_flag in (Action.ASIS, Action.RETAG, Action.APPLY)
|
||||
if self.choice_flag in (Action.ASIS, Action.RETAG):
|
||||
return dict(self.item)
|
||||
elif self.choice_flag is action.APPLY:
|
||||
elif self.choice_flag is Action.APPLY:
|
||||
return self.match.info.copy()
|
||||
|
||||
def imported_items(self):
|
||||
|
|
|
|||
|
|
@ -658,9 +658,9 @@ class ImportSessionFixture(ImportSession):
|
|||
|
||||
>>> lib = Library(':memory:')
|
||||
>>> importer = ImportSessionFixture(lib, paths=['/path/to/import'])
|
||||
>>> importer.add_choice(importer.action.SKIP)
|
||||
>>> importer.add_choice(importer.action.ASIS)
|
||||
>>> importer.default_choice = importer.action.APPLY
|
||||
>>> importer.add_choice(importer.Action.SKIP)
|
||||
>>> importer.add_choice(importer.Action.ASIS)
|
||||
>>> importer.default_choice = importer.Action.APPLY
|
||||
>>> importer.run()
|
||||
|
||||
This imports ``/path/to/import`` into `lib`. It skips the first
|
||||
|
|
@ -673,7 +673,7 @@ class ImportSessionFixture(ImportSession):
|
|||
self._choices = []
|
||||
self._resolutions = []
|
||||
|
||||
default_choice = importer.action.APPLY
|
||||
default_choice = importer.Action.APPLY
|
||||
|
||||
def add_choice(self, choice):
|
||||
self._choices.append(choice)
|
||||
|
|
@ -687,7 +687,7 @@ class ImportSessionFixture(ImportSession):
|
|||
except IndexError:
|
||||
choice = self.default_choice
|
||||
|
||||
if choice == importer.action.APPLY:
|
||||
if choice == importer.Action.APPLY:
|
||||
return task.candidates[0]
|
||||
elif isinstance(choice, int):
|
||||
return task.candidates[choice - 1]
|
||||
|
|
@ -707,7 +707,7 @@ class ImportSessionFixture(ImportSession):
|
|||
res = self.default_resolution
|
||||
|
||||
if res == self.Resolution.SKIP:
|
||||
task.set_choice(importer.action.SKIP)
|
||||
task.set_choice(importer.Action.SKIP)
|
||||
elif res == self.Resolution.REMOVE:
|
||||
task.should_remove_duplicates = True
|
||||
elif res == self.Resolution.MERGE:
|
||||
|
|
@ -720,7 +720,7 @@ class TerminalImportSessionFixture(TerminalImportSession):
|
|||
super().__init__(*args, **kwargs)
|
||||
self._choices = []
|
||||
|
||||
default_choice = importer.action.APPLY
|
||||
default_choice = importer.Action.APPLY
|
||||
|
||||
def add_choice(self, choice):
|
||||
self._choices.append(choice)
|
||||
|
|
@ -742,15 +742,15 @@ class TerminalImportSessionFixture(TerminalImportSession):
|
|||
except IndexError:
|
||||
choice = self.default_choice
|
||||
|
||||
if choice == importer.action.APPLY:
|
||||
if choice == importer.Action.APPLY:
|
||||
self.io.addinput("A")
|
||||
elif choice == importer.action.ASIS:
|
||||
elif choice == importer.Action.ASIS:
|
||||
self.io.addinput("U")
|
||||
elif choice == importer.action.ALBUMS:
|
||||
elif choice == importer.Action.ALBUMS:
|
||||
self.io.addinput("G")
|
||||
elif choice == importer.action.TRACKS:
|
||||
elif choice == importer.Action.TRACKS:
|
||||
self.io.addinput("T")
|
||||
elif choice == importer.action.SKIP:
|
||||
elif choice == importer.Action.SKIP:
|
||||
self.io.addinput("S")
|
||||
else:
|
||||
self.io.addinput("M")
|
||||
|
|
|
|||
|
|
@ -811,12 +811,12 @@ def _summary_judgment(rec):
|
|||
|
||||
if config["import"]["quiet"]:
|
||||
if rec == Recommendation.strong:
|
||||
return importer.action.APPLY
|
||||
return importer.Action.APPLY
|
||||
else:
|
||||
action = config["import"]["quiet_fallback"].as_choice(
|
||||
{
|
||||
"skip": importer.action.SKIP,
|
||||
"asis": importer.action.ASIS,
|
||||
"skip": importer.Action.SKIP,
|
||||
"asis": importer.Action.ASIS,
|
||||
}
|
||||
)
|
||||
elif config["import"]["timid"]:
|
||||
|
|
@ -824,17 +824,17 @@ def _summary_judgment(rec):
|
|||
elif rec == Recommendation.none:
|
||||
action = config["import"]["none_rec_action"].as_choice(
|
||||
{
|
||||
"skip": importer.action.SKIP,
|
||||
"asis": importer.action.ASIS,
|
||||
"skip": importer.Action.SKIP,
|
||||
"asis": importer.Action.ASIS,
|
||||
"ask": None,
|
||||
}
|
||||
)
|
||||
else:
|
||||
return None
|
||||
|
||||
if action == importer.action.SKIP:
|
||||
if action == importer.Action.SKIP:
|
||||
print_("Skipping.")
|
||||
elif action == importer.action.ASIS:
|
||||
elif action == importer.Action.ASIS:
|
||||
print_("Importing as-is.")
|
||||
return action
|
||||
|
||||
|
|
@ -1064,7 +1064,7 @@ class TerminalImportSession(importer.ImportSession):
|
|||
|
||||
# Take immediate action if appropriate.
|
||||
action = _summary_judgment(task.rec)
|
||||
if action == importer.action.APPLY:
|
||||
if action == importer.Action.APPLY:
|
||||
match = task.candidates[0]
|
||||
show_change(task.cur_artist, task.cur_album, match)
|
||||
return match
|
||||
|
|
@ -1074,7 +1074,7 @@ class TerminalImportSession(importer.ImportSession):
|
|||
# Loop until we have a choice.
|
||||
while True:
|
||||
# Ask for a choice from the user. The result of
|
||||
# `choose_candidate` may be an `importer.action`, an
|
||||
# `choose_candidate` may be an `importer.Action`, an
|
||||
# `AlbumMatch` object for a specific selection, or a
|
||||
# `PromptChoice`.
|
||||
choices = self._get_choices(task)
|
||||
|
|
@ -1089,7 +1089,7 @@ class TerminalImportSession(importer.ImportSession):
|
|||
)
|
||||
|
||||
# Basic choices that require no more action here.
|
||||
if choice in (importer.action.SKIP, importer.action.ASIS):
|
||||
if choice in (importer.Action.SKIP, importer.Action.ASIS):
|
||||
# Pass selection to main control flow.
|
||||
return choice
|
||||
|
||||
|
|
@ -1097,7 +1097,7 @@ class TerminalImportSession(importer.ImportSession):
|
|||
# function.
|
||||
elif choice in choices:
|
||||
post_choice = choice.callback(self, task)
|
||||
if isinstance(post_choice, importer.action):
|
||||
if isinstance(post_choice, importer.Action):
|
||||
return post_choice
|
||||
elif isinstance(post_choice, autotag.Proposal):
|
||||
# Use the new candidates and continue around the loop.
|
||||
|
|
@ -1121,7 +1121,7 @@ class TerminalImportSession(importer.ImportSession):
|
|||
|
||||
# Take immediate action if appropriate.
|
||||
action = _summary_judgment(task.rec)
|
||||
if action == importer.action.APPLY:
|
||||
if action == importer.Action.APPLY:
|
||||
match = candidates[0]
|
||||
show_item_change(task.item, match)
|
||||
return match
|
||||
|
|
@ -1135,12 +1135,12 @@ class TerminalImportSession(importer.ImportSession):
|
|||
candidates, True, rec, item=task.item, choices=choices
|
||||
)
|
||||
|
||||
if choice in (importer.action.SKIP, importer.action.ASIS):
|
||||
if choice in (importer.Action.SKIP, importer.Action.ASIS):
|
||||
return choice
|
||||
|
||||
elif choice in choices:
|
||||
post_choice = choice.callback(self, task)
|
||||
if isinstance(post_choice, importer.action):
|
||||
if isinstance(post_choice, importer.Action):
|
||||
return post_choice
|
||||
elif isinstance(post_choice, autotag.Proposal):
|
||||
candidates = post_choice.candidates
|
||||
|
|
@ -1203,7 +1203,7 @@ class TerminalImportSession(importer.ImportSession):
|
|||
|
||||
if sel == "s":
|
||||
# Skip new.
|
||||
task.set_choice(importer.action.SKIP)
|
||||
task.set_choice(importer.Action.SKIP)
|
||||
elif sel == "k":
|
||||
# Keep both. Do nothing; leave the choice intact.
|
||||
pass
|
||||
|
|
@ -1239,16 +1239,16 @@ class TerminalImportSession(importer.ImportSession):
|
|||
"""
|
||||
# Standard, built-in choices.
|
||||
choices = [
|
||||
PromptChoice("s", "Skip", lambda s, t: importer.action.SKIP),
|
||||
PromptChoice("u", "Use as-is", lambda s, t: importer.action.ASIS),
|
||||
PromptChoice("s", "Skip", lambda s, t: importer.Action.SKIP),
|
||||
PromptChoice("u", "Use as-is", lambda s, t: importer.Action.ASIS),
|
||||
]
|
||||
if task.is_album:
|
||||
choices += [
|
||||
PromptChoice(
|
||||
"t", "as Tracks", lambda s, t: importer.action.TRACKS
|
||||
"t", "as Tracks", lambda s, t: importer.Action.TRACKS
|
||||
),
|
||||
PromptChoice(
|
||||
"g", "Group albums", lambda s, t: importer.action.ALBUMS
|
||||
"g", "Group albums", lambda s, t: importer.Action.ALBUMS
|
||||
),
|
||||
]
|
||||
choices += [
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ BytesOrStr = Union[str, bytes]
|
|||
PathLike = Union[BytesOrStr, Path]
|
||||
Replacements: TypeAlias = "Sequence[tuple[Pattern[str], str]]"
|
||||
|
||||
# Here for now to allow for a easy replace later on
|
||||
# once we can move to a PathLike (mainly used in importer)
|
||||
PathBytes = bytes
|
||||
|
||||
|
||||
class HumanReadableError(Exception):
|
||||
"""An Exception that can include a human-readable error message to
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ class BadFiles(BeetsPlugin):
|
|||
sel = ui.input_options(["aBort", "skip", "continue"])
|
||||
|
||||
if sel == "s":
|
||||
return importer.action.SKIP
|
||||
return importer.Action.SKIP
|
||||
elif sel == "c":
|
||||
return None
|
||||
elif sel == "b":
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import yaml
|
|||
|
||||
from beets import plugins, ui, util
|
||||
from beets.dbcore import types
|
||||
from beets.importer import action
|
||||
from beets.importer import Action
|
||||
from beets.ui.commands import PromptChoice, _do_query
|
||||
|
||||
# These "safe" types can avoid the format/parse cycle that most fields go
|
||||
|
|
@ -380,9 +380,9 @@ class EditPlugin(plugins.BeetsPlugin):
|
|||
|
||||
# Save the new data.
|
||||
if success:
|
||||
# Return action.RETAG, which makes the importer write the tags
|
||||
# Return Action.RETAG, which makes the importer write the tags
|
||||
# to the files if needed without re-applying metadata.
|
||||
return action.RETAG
|
||||
return Action.RETAG
|
||||
else:
|
||||
# Edit cancelled / no edits made. Revert changes.
|
||||
for obj in task.items:
|
||||
|
|
|
|||
|
|
@ -1306,12 +1306,12 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
|
|||
):
|
||||
# Album already has art (probably a re-import); skip it.
|
||||
return
|
||||
if task.choice_flag == importer.action.ASIS:
|
||||
if task.choice_flag == importer.Action.ASIS:
|
||||
# For as-is imports, don't search Web sources for art.
|
||||
local = True
|
||||
elif task.choice_flag in (
|
||||
importer.action.APPLY,
|
||||
importer.action.RETAG,
|
||||
importer.Action.APPLY,
|
||||
importer.Action.RETAG,
|
||||
):
|
||||
# Search everywhere for art.
|
||||
local = False
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
"""Warns you about things you hate (or even blocks import)."""
|
||||
|
||||
from beets.importer import action
|
||||
from beets.importer import Action
|
||||
from beets.library import Album, Item, parse_query_string
|
||||
from beets.plugins import BeetsPlugin
|
||||
|
||||
|
|
@ -65,11 +65,11 @@ class IHatePlugin(BeetsPlugin):
|
|||
skip_queries = self.config["skip"].as_str_seq()
|
||||
warn_queries = self.config["warn"].as_str_seq()
|
||||
|
||||
if task.choice_flag == action.APPLY:
|
||||
if task.choice_flag == Action.APPLY:
|
||||
if skip_queries or warn_queries:
|
||||
self._log.debug("processing your hate")
|
||||
if self.do_i_hate_this(task, skip_queries):
|
||||
task.choice_flag = action.SKIP
|
||||
task.choice_flag = Action.SKIP
|
||||
self._log.info("skipped: {0}", summary(task))
|
||||
return
|
||||
if self.do_i_hate_this(task, warn_queries):
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import re
|
|||
import confuse
|
||||
from mediafile import MediaFile
|
||||
|
||||
from beets.importer import action
|
||||
from beets.importer import Action
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets.ui import Subcommand, decargs, input_yn
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ class ZeroPlugin(BeetsPlugin):
|
|||
self.fields_to_progs[field] = []
|
||||
|
||||
def import_task_choice_event(self, session, task):
|
||||
if task.choice_flag == action.ASIS and not self.warned:
|
||||
if task.choice_flag == Action.ASIS and not self.warned:
|
||||
self._log.warning('cannot zero in "as-is" mode')
|
||||
self.warned = True
|
||||
# TODO request write in as-is mode
|
||||
|
|
|
|||
|
|
@ -648,6 +648,6 @@ by the choices on the core importer prompt, and hence should not be used:
|
|||
``a``, ``s``, ``u``, ``t``, ``g``, ``e``, ``i``, ``b``.
|
||||
|
||||
Additionally, the callback function can optionally specify the next action to
|
||||
be performed by returning a ``importer.action`` value. It may also return a
|
||||
be performed by returning a ``importer.Action`` value. It may also return a
|
||||
``autotag.Proposal`` value to update the set of current proposals to be
|
||||
considered.
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase):
|
|||
self.matcher = AutotagStub().install()
|
||||
self.matcher.matching = AutotagStub.IDENT
|
||||
self.importer = self.setup_importer()
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ from mediafile import MediaFile
|
|||
|
||||
from beets import config, importer, logging, util
|
||||
from beets.autotag import AlbumInfo, AlbumMatch, TrackInfo
|
||||
from beets.importer import albums_in_dir
|
||||
from beets.importer.tasks import albums_in_dir
|
||||
from beets.test import _common
|
||||
from beets.test.helper import (
|
||||
NEEDS_REFLINK,
|
||||
|
|
@ -324,52 +324,52 @@ class ImportSingletonTest(ImportTestCase):
|
|||
def test_apply_asis_adds_track(self):
|
||||
assert self.lib.items().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().title == "Tag Track 1"
|
||||
|
||||
def test_apply_asis_does_not_add_album(self):
|
||||
assert self.lib.albums().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get() is None
|
||||
|
||||
def test_apply_asis_adds_singleton_path(self):
|
||||
self.assert_lib_dir_empty()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
self.assert_file_in_lib(b"singletons", b"Tag Track 1.mp3")
|
||||
|
||||
def test_apply_candidate_adds_track(self):
|
||||
assert self.lib.items().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().title == "Applied Track 1"
|
||||
|
||||
def test_apply_candidate_does_not_add_album(self):
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get() is None
|
||||
|
||||
def test_apply_candidate_adds_singleton_path(self):
|
||||
self.assert_lib_dir_empty()
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
self.assert_file_in_lib(b"singletons", b"Applied Track 1.mp3")
|
||||
|
||||
def test_skip_does_not_add_first_track(self):
|
||||
self.importer.add_choice(importer.action.SKIP)
|
||||
self.importer.add_choice(importer.Action.SKIP)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get() is None
|
||||
|
||||
def test_skip_adds_other_tracks(self):
|
||||
self.prepare_album_for_import(2)
|
||||
self.importer.add_choice(importer.action.SKIP)
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.SKIP)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert len(self.lib.items()) == 1
|
||||
|
||||
|
|
@ -385,8 +385,8 @@ class ImportSingletonTest(ImportTestCase):
|
|||
self.setup_importer()
|
||||
self.importer.paths = import_files
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
|
||||
assert len(self.lib.items()) == 2
|
||||
|
|
@ -406,7 +406,7 @@ class ImportSingletonTest(ImportTestCase):
|
|||
|
||||
# As-is item import.
|
||||
assert self.lib.albums().get() is None
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
|
||||
for item in self.lib.items():
|
||||
|
|
@ -421,7 +421,7 @@ class ImportSingletonTest(ImportTestCase):
|
|||
# Autotagged.
|
||||
assert self.lib.albums().get() is None
|
||||
self.importer.clear_choices()
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
|
||||
for item in self.lib.items():
|
||||
|
|
@ -449,41 +449,41 @@ class ImportTest(ImportTestCase):
|
|||
def test_apply_asis_adds_album(self):
|
||||
assert self.lib.albums().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().album == "Tag Album"
|
||||
|
||||
def test_apply_asis_adds_tracks(self):
|
||||
assert self.lib.items().get() is None
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().title == "Tag Track 1"
|
||||
|
||||
def test_apply_asis_adds_album_path(self):
|
||||
self.assert_lib_dir_empty()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
self.assert_file_in_lib(b"Tag Artist", b"Tag Album", b"Tag Track 1.mp3")
|
||||
|
||||
def test_apply_candidate_adds_album(self):
|
||||
assert self.lib.albums().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().album == "Applied Album"
|
||||
|
||||
def test_apply_candidate_adds_tracks(self):
|
||||
assert self.lib.items().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().title == "Applied Track 1"
|
||||
|
||||
def test_apply_candidate_adds_album_path(self):
|
||||
self.assert_lib_dir_empty()
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
self.assert_file_in_lib(
|
||||
b"Applied Artist", b"Applied Album", b"Applied Track 1.mp3"
|
||||
|
|
@ -496,14 +496,14 @@ class ImportTest(ImportTestCase):
|
|||
mediafile.genre = "Tag Genre"
|
||||
mediafile.save()
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().genre == ""
|
||||
|
||||
def test_apply_from_scratch_keeps_format(self):
|
||||
config["import"]["from_scratch"] = True
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().format == "MP3"
|
||||
|
||||
|
|
@ -511,7 +511,7 @@ class ImportTest(ImportTestCase):
|
|||
config["import"]["from_scratch"] = True
|
||||
bitrate = 80000
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().bitrate == bitrate
|
||||
|
||||
|
|
@ -521,7 +521,7 @@ class ImportTest(ImportTestCase):
|
|||
import_file = os.path.join(self.import_dir, b"album", b"track_1.mp3")
|
||||
self.assertExists(import_file)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
self.assertNotExists(import_file)
|
||||
|
||||
|
|
@ -531,26 +531,26 @@ class ImportTest(ImportTestCase):
|
|||
import_file = os.path.join(self.import_dir, b"album", b"track_1.mp3")
|
||||
self.assertExists(import_file)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
self.assertNotExists(import_file)
|
||||
|
||||
def test_skip_does_not_add_track(self):
|
||||
self.importer.add_choice(importer.action.SKIP)
|
||||
self.importer.add_choice(importer.Action.SKIP)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get() is None
|
||||
|
||||
def test_skip_non_album_dirs(self):
|
||||
self.assertIsDir(os.path.join(self.import_dir, b"album"))
|
||||
self.touch(b"cruft", dir=self.import_dir)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert len(self.lib.albums()) == 1
|
||||
|
||||
def test_unmatched_tracks_not_added(self):
|
||||
self.prepare_album_for_import(2)
|
||||
self.matcher.matching = self.matcher.MISSING
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert len(self.lib.items()) == 1
|
||||
|
||||
|
|
@ -577,7 +577,7 @@ class ImportTest(ImportTestCase):
|
|||
def test_asis_no_data_source(self):
|
||||
assert self.lib.items().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
|
||||
with pytest.raises(AttributeError):
|
||||
|
|
@ -599,7 +599,7 @@ class ImportTest(ImportTestCase):
|
|||
|
||||
# As-is album import.
|
||||
assert self.lib.albums().get() is None
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
|
||||
for album in self.lib.albums():
|
||||
|
|
@ -621,7 +621,7 @@ class ImportTest(ImportTestCase):
|
|||
# Autotagged.
|
||||
assert self.lib.albums().get() is None
|
||||
self.importer.clear_choices()
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
|
||||
for album in self.lib.albums():
|
||||
|
|
@ -656,9 +656,9 @@ class ImportTracksTest(ImportTestCase):
|
|||
assert self.lib.items().get() is None
|
||||
assert self.lib.albums().get() is None
|
||||
|
||||
self.importer.add_choice(importer.action.TRACKS)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.TRACKS)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().title == "Applied Track 1"
|
||||
assert self.lib.albums().get() is None
|
||||
|
|
@ -666,9 +666,9 @@ class ImportTracksTest(ImportTestCase):
|
|||
def test_apply_tracks_adds_singleton_path(self):
|
||||
self.assert_lib_dir_empty()
|
||||
|
||||
self.importer.add_choice(importer.action.TRACKS)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.TRACKS)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
self.assert_file_in_lib(b"singletons", b"Applied Track 1.mp3")
|
||||
|
||||
|
|
@ -687,7 +687,7 @@ class ImportCompilationTest(ImportTestCase):
|
|||
self.matcher.restore()
|
||||
|
||||
def test_asis_homogenous_sets_albumartist(self):
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().albumartist == "Tag Artist"
|
||||
for item in self.lib.items():
|
||||
|
|
@ -699,7 +699,7 @@ class ImportCompilationTest(ImportTestCase):
|
|||
self.import_media[1].artist = "Another Artist"
|
||||
self.import_media[1].save()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().albumartist == "Various Artists"
|
||||
for item in self.lib.items():
|
||||
|
|
@ -711,7 +711,7 @@ class ImportCompilationTest(ImportTestCase):
|
|||
self.import_media[1].artist = "Another Artist"
|
||||
self.import_media[1].save()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
for item in self.lib.items():
|
||||
assert item.comp
|
||||
|
|
@ -722,7 +722,7 @@ class ImportCompilationTest(ImportTestCase):
|
|||
self.import_media[1].artist = "Other Artist"
|
||||
self.import_media[1].save()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().albumartist == "Other Artist"
|
||||
for item in self.lib.items():
|
||||
|
|
@ -736,7 +736,7 @@ class ImportCompilationTest(ImportTestCase):
|
|||
mediafile.mb_albumartistid = "Album Artist ID"
|
||||
mediafile.save()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().albumartist == "Album Artist"
|
||||
assert self.lib.albums().get().mb_albumartistid == "Album Artist ID"
|
||||
|
|
@ -755,7 +755,7 @@ class ImportCompilationTest(ImportTestCase):
|
|||
mediafile.mb_albumartistid = "Album Artist ID"
|
||||
mediafile.save()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().albumartist == "Album Artist"
|
||||
assert self.lib.albums().get().albumartists == [
|
||||
|
|
@ -802,7 +802,7 @@ class ImportExistingTest(ImportTestCase):
|
|||
self.importer.run()
|
||||
assert len(self.lib.items()) == 1
|
||||
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.add_choice(importer.Action.APPLY)
|
||||
self.reimporter.run()
|
||||
assert len(self.lib.items()) == 1
|
||||
|
||||
|
|
@ -810,18 +810,18 @@ class ImportExistingTest(ImportTestCase):
|
|||
self.importer.run()
|
||||
assert len(self.lib.albums()) == 1
|
||||
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.add_choice(importer.Action.APPLY)
|
||||
self.reimporter.run()
|
||||
assert len(self.lib.albums()) == 1
|
||||
|
||||
def test_does_not_duplicate_singleton_track(self):
|
||||
self.importer.add_choice(importer.action.TRACKS)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.TRACKS)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert len(self.lib.items()) == 1
|
||||
|
||||
self.reimporter.add_choice(importer.action.TRACKS)
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.add_choice(importer.Action.TRACKS)
|
||||
self.reimporter.add_choice(importer.Action.APPLY)
|
||||
self.reimporter.run()
|
||||
assert len(self.lib.items()) == 1
|
||||
|
||||
|
|
@ -831,7 +831,7 @@ class ImportExistingTest(ImportTestCase):
|
|||
medium.title = "New Title"
|
||||
medium.save()
|
||||
|
||||
self.reimporter.add_choice(importer.action.ASIS)
|
||||
self.reimporter.add_choice(importer.Action.ASIS)
|
||||
self.reimporter.run()
|
||||
assert self.lib.items().get().title == "New Title"
|
||||
|
||||
|
|
@ -846,7 +846,7 @@ class ImportExistingTest(ImportTestCase):
|
|||
)
|
||||
self.assert_file_in_lib(old_path)
|
||||
|
||||
self.reimporter.add_choice(importer.action.ASIS)
|
||||
self.reimporter.add_choice(importer.Action.ASIS)
|
||||
self.reimporter.run()
|
||||
self.assert_file_in_lib(
|
||||
b"Applied Artist", b"Applied Album", b"New Title.mp3"
|
||||
|
|
@ -865,7 +865,7 @@ class ImportExistingTest(ImportTestCase):
|
|||
self.assert_file_in_lib(old_path)
|
||||
|
||||
config["import"]["copy"] = False
|
||||
self.reimporter.add_choice(importer.action.ASIS)
|
||||
self.reimporter.add_choice(importer.Action.ASIS)
|
||||
self.reimporter.run()
|
||||
self.assert_file_not_in_lib(
|
||||
b"Applied Artist", b"Applied Album", b"New Title.mp3"
|
||||
|
|
@ -880,7 +880,7 @@ class ImportExistingTest(ImportTestCase):
|
|||
)
|
||||
|
||||
self.reimporter = self.setup_importer()
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.add_choice(importer.Action.APPLY)
|
||||
self.reimporter.run()
|
||||
new_path = os.path.join(
|
||||
b"Applied Artist", b"Applied Album", b"Applied Track 1.mp3"
|
||||
|
|
@ -899,7 +899,7 @@ class ImportExistingTest(ImportTestCase):
|
|||
)
|
||||
|
||||
self.reimporter = self.setup_importer(move=True)
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.add_choice(importer.Action.APPLY)
|
||||
self.reimporter.run()
|
||||
self.assertNotExists(self.import_media[0].path)
|
||||
|
||||
|
|
@ -913,9 +913,9 @@ class GroupAlbumsImportTest(ImportTestCase):
|
|||
self.setup_importer()
|
||||
|
||||
# Split tracks into two albums and use both as-is
|
||||
self.importer.add_choice(importer.action.ALBUMS)
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ALBUMS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
self.importer.add_choice(importer.Action.ASIS)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
|
|
@ -972,7 +972,7 @@ class GlobalGroupAlbumsImportTest(GroupAlbumsImportTest):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.importer.clear_choices()
|
||||
self.importer.default_choice = importer.action.ASIS
|
||||
self.importer.default_choice = importer.Action.ASIS
|
||||
config["import"]["group_albums"] = True
|
||||
|
||||
|
||||
|
|
@ -1019,7 +1019,7 @@ class InferAlbumDataTest(BeetsTestCase):
|
|||
)
|
||||
|
||||
def test_asis_homogenous_single_artist(self):
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self.task.set_choice(importer.Action.ASIS)
|
||||
self.task.align_album_level_fields()
|
||||
assert not self.items[0].comp
|
||||
assert self.items[0].albumartist == self.items[2].artist
|
||||
|
|
@ -1027,7 +1027,7 @@ class InferAlbumDataTest(BeetsTestCase):
|
|||
def test_asis_heterogenous_va(self):
|
||||
self.items[0].artist = "another artist"
|
||||
self.items[1].artist = "some other artist"
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self.task.set_choice(importer.Action.ASIS)
|
||||
|
||||
self.task.align_album_level_fields()
|
||||
|
||||
|
|
@ -1037,7 +1037,7 @@ class InferAlbumDataTest(BeetsTestCase):
|
|||
def test_asis_comp_applied_to_all_items(self):
|
||||
self.items[0].artist = "another artist"
|
||||
self.items[1].artist = "some other artist"
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self.task.set_choice(importer.Action.ASIS)
|
||||
|
||||
self.task.align_album_level_fields()
|
||||
|
||||
|
|
@ -1047,7 +1047,7 @@ class InferAlbumDataTest(BeetsTestCase):
|
|||
|
||||
def test_asis_majority_artist_single_artist(self):
|
||||
self.items[0].artist = "another artist"
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self.task.set_choice(importer.Action.ASIS)
|
||||
|
||||
self.task.align_album_level_fields()
|
||||
|
||||
|
|
@ -1060,7 +1060,7 @@ class InferAlbumDataTest(BeetsTestCase):
|
|||
for item in self.items:
|
||||
item.albumartist = "some album artist"
|
||||
item.mb_albumartistid = "some album artist id"
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self.task.set_choice(importer.Action.ASIS)
|
||||
|
||||
self.task.align_album_level_fields()
|
||||
|
||||
|
|
@ -1089,7 +1089,7 @@ class InferAlbumDataTest(BeetsTestCase):
|
|||
def test_small_single_artist_album(self):
|
||||
self.items = [self.items[0]]
|
||||
self.task.items = self.items
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self.task.set_choice(importer.Action.ASIS)
|
||||
self.task.align_album_level_fields()
|
||||
assert not self.items[0].comp
|
||||
|
||||
|
|
@ -1599,7 +1599,7 @@ class ReimportTest(ImportTestCase):
|
|||
|
||||
def _setup_session(self, singletons=False):
|
||||
self.setup_importer(import_dir=self.libdir, singletons=singletons)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
|
||||
def _album(self):
|
||||
return self.lib.albums().get()
|
||||
|
|
@ -1845,7 +1845,7 @@ class ImportMusicBrainzIdTest(ImportTestCase):
|
|||
search_ids=[self.MB_RELEASE_PREFIX + self.ID_RELEASE_0]
|
||||
)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().album == "VALID_RELEASE_0"
|
||||
|
||||
|
|
@ -1858,7 +1858,7 @@ class ImportMusicBrainzIdTest(ImportTestCase):
|
|||
)
|
||||
|
||||
self.importer.add_choice(2) # Pick the 2nd best match (release 1).
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.albums().get().album == "VALID_RELEASE_1"
|
||||
|
||||
|
|
@ -1867,7 +1867,7 @@ class ImportMusicBrainzIdTest(ImportTestCase):
|
|||
search_ids=[self.MB_RECORDING_PREFIX + self.ID_RECORDING_0]
|
||||
)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().title == "VALID_RECORDING_0"
|
||||
|
||||
|
|
@ -1880,7 +1880,7 @@ class ImportMusicBrainzIdTest(ImportTestCase):
|
|||
)
|
||||
|
||||
self.importer.add_choice(2) # Pick the 2nd best match (recording 1).
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.add_choice(importer.Action.APPLY)
|
||||
self.importer.run()
|
||||
assert self.lib.items().get().title == "VALID_RECORDING_1"
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ from mediafile import MediaFile
|
|||
from beets import config, plugins, ui
|
||||
from beets.dbcore import types
|
||||
from beets.importer import (
|
||||
Action,
|
||||
ArchiveImportTask,
|
||||
SentinelImportTask,
|
||||
SingletonImportTask,
|
||||
action,
|
||||
)
|
||||
from beets.library import Item
|
||||
from beets.plugins import MetadataSourcePlugin
|
||||
|
|
@ -389,7 +389,7 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase):
|
|||
"aBort",
|
||||
) + ("Foo", "baR")
|
||||
|
||||
self.importer.add_choice(action.SKIP)
|
||||
self.importer.add_choice(Action.SKIP)
|
||||
self.importer.run()
|
||||
self.mock_input_options.assert_called_once_with(
|
||||
opts, default="a", require=ANY
|
||||
|
|
@ -424,7 +424,7 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase):
|
|||
) + ("Foo", "baR")
|
||||
|
||||
config["import"]["singletons"] = True
|
||||
self.importer.add_choice(action.SKIP)
|
||||
self.importer.add_choice(Action.SKIP)
|
||||
self.importer.run()
|
||||
self.mock_input_options.assert_called_with(
|
||||
opts, default="a", require=ANY
|
||||
|
|
@ -461,7 +461,7 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase):
|
|||
"enter Id",
|
||||
"aBort",
|
||||
) + ("baZ",)
|
||||
self.importer.add_choice(action.SKIP)
|
||||
self.importer.add_choice(Action.SKIP)
|
||||
self.importer.run()
|
||||
self.mock_input_options.assert_called_once_with(
|
||||
opts, default="a", require=ANY
|
||||
|
|
@ -523,7 +523,7 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase):
|
|||
return [ui.commands.PromptChoice("f", "Foo", self.foo)]
|
||||
|
||||
def foo(self, session, task):
|
||||
return action.SKIP
|
||||
return Action.SKIP
|
||||
|
||||
self.register_plugin(DummyPlugin)
|
||||
# Default options + extra choices by the plugin ('Foo', 'Bar')
|
||||
|
|
|
|||
Loading…
Reference in a new issue