Core Hooks

These are hooks specific to Moe’s core interface.

Config

class Hooks

Config hook specifications.

static add_config_validator(settings: LazySettings)

Add a settings validator for the configuration file.

Parameters:

settings – Moe’s settings.

Example

settings.validators.register(
    dynaconf.Validator("MOVE.ASCIIFY_PATHS", must_exist=True)
)
static add_hooks(pm: PluginManager)

Add hookspecs to be registered to Moe.

Parameters:

pm – PluginManager that registers the hookspec.

Example

from moe.add import Hooks
pm.add_hookspecs(Hooks)
static plugin_registration()

Allows actions after the initial plugin registration.

In order for a module to implement and register plugin hooks, it must be registered as a separate plugin with the pm. A plugin can be either just a module, or a full package.

If a plugin is a package, only it’s __init__.py will be initially registered, meaning only __init__.py will be able to run hook implementations at start-up. This hook is provided so each plugin can register it’s individual sub-modules as appropriate.

Important

Ensure any sub-modules you register as plugins are registered with the original plugin name as the prefix. This helps prevent naming conflicts.

For example, see how the edit plugin conditionally enables its cli sub-module:

@moe.hookimpl
def plugin_registration():
    if config.CONFIG.pm.has_plugin("cli"):
        config.CONFIG.pm.register(edit_cli, "edit_cli")

This hook can also be used as a way of checking for plugin dependencies by inspecting the enabled plugins in the configuration.

For example, because the list plugin only exists as a cli plugin, it will un-register itself and log a warning if the cli plugin is not enabled:

@moe.hookimpl
def plugin_registration():
    if not config.CONFIG.pm.has_plugin("cli"):
        config.CONFIG.pm.set_blocked("list")
        log.warning("You can't list stuff without a cli!")
static register_sa_event_listeners()

Registers new sqlalchemy event listeners.

These listeners will automatically apply to all sessions globally if the Session class is passed as the listener target as shown in the example.

Important

This hook is for Moe internal use only and should not be used by plugins.

Example

sqlalchemy.event.listen(
    Session,
    "before_flush",
    _my_func,
)

Then you can define _my_func as such:

def _my_func(
    session: sqlalchemy.orm.Session,
    flush_context: sqlalchemy.orm.UOWTransaction,
    instances: Optional[Any],
):
    print("we made it")

Library

General

class Hooks

General usage library item hooks.

static edit_changed_items(session: Session, items: list[LibItem])

Edit items in the library that were changed in some way.

Parameters:
  • session – Library db session.

  • items – Any changed items that existed in the library prior to the current session.

See also

The process_changed_items() hook for processing items with finalized values.

static edit_new_items(session: Session, items: list[LibItem])

Edit new items in the library.

Parameters:
  • session – Library db session.

  • items – Any items being added to the library for the first time.

See also

The process_new_items() hook for processing items with finalized values.

static process_changed_items(session: Session, items: list[LibItem])

Process items in the library that were changed in some way.

Parameters:
  • session – Library db session.

  • items – Any changed items that existed in the library prior to the current session.

Important

Any changes made to the items will be lost.

See also

The edit_changed_items() hook for editing items before their values are finalized.

static process_new_items(session: Session, items: list[LibItem])

Process new items in the library.

Parameters:
  • session – Library db session.

  • items – Any items being added to the library for the first time.

Important

Any changes made to the items will be lost.

See also

The edit_new_items() hook for editing items before their values are finalized.

static process_removed_items(session: Session, items: list[LibItem])

Process items that have been removed from the library.

Parameters:
  • session – Library db session.

  • items – Any items that existed in the library prior to the current session, but have now been removed from the library.

Albums

class Hooks

Album hook specifications.

static is_unique_album(album: Album, other: Album) bool

Add new conditions to determine whether two albums are unique.

“Uniqueness” is meant in terms of whether the two albums should be considered duplicates in the library. These additional conditions will be applied inside a album’s is_unique() method.

Tracks

class Hooks

Track hook specifications.

static is_unique_track(track: Track, other: Track) bool

Add new conditions to determine whether two tracks are unique.

“Uniqueness” is meant in terms of whether the two tracks should be considered duplicates in the library. These additional conditions will be applied inside a track’s is_unique() method.

static read_custom_tags(track_path: Path, album_fields: dict[str, Any], track_fields: dict[str, Any]) None

Read and set any fields from a track_path.

How you read the file and assign tags is up to each individual plugin. Internally, Moe uses the mediafile library to read tags.

Parameters:
  • track_path – Path of the track file to read.

  • album_fields – Dictionary of album fields to read from the given track file’s tags. The dictionary may contain existing fields and values, and you can choose to either override the existing fields, or to provide new fields.

  • track_fields – Dictionary of track fields to read from the given track file’s tags. The dictionary may contain existing fields and values, and you can choose to either override the existing fields, or to provide new fields.

Example

audio_file = mediafile.MediaFile(track_path)
album_fields["title"] = audio_file.album
track_fields["title"] = audio_file.title

See also

Extras

class Hooks

Extra hook specifications.

static is_unique_extra(extra: Extra, other: Extra) bool

Add new conditions to determine whether two extras are unique.

“Uniqueness” is meant in terms of whether the two extras should be considered duplicates in the library. These additional conditions will be applied inside a extra’s is_unique() method.

Plugins

Add

class Hooks

Add plugin hook specifications.

static pre_add(item: LibItem)

Provides an item prior to it being added to the library.

Use this hook if you wish to change an item’s metadata prior to it being added to the library.

Parameters:

item – Library item being added.

Note

Any UI application should have a way of detecting and resolving duplicate items prior to them being added to the database. You may consider implementing a hookwrapper to run conflict resolution code after the pre_add hook is complete, but before the item has been added to the db.

See also

Import

class Hooks

Import core plugin hook specifications.

static get_candidates(album: Album) list[CandidateAlbum]

Return candidate albums from implemented sources based on the given album.

This hook should be used to import metadata from an external source and return any candidate albums to import from. The candidate albums will then be processed in the process_candidates() hook.

Note

This hook runs within the pre_add() hook.

Parameters:

album – Album being added to the library.

Returns:

New candidate album.

static process_candidates(new_album: Album, candidates: list[CandidateAlbum])

Process the imported candidate albums.

If you wish to save and apply any candidate album metadata, it should be applied onto the original album, new_album.

Ensure any potential conflicts with existing albums in the database are resolved.

Parameters:
  • new_album – Album being added to the library.

  • candidates – New candidate albums with imported metadata sorted by how well they match new_album.

Move

class Hooks

Move plugin hook specifications.

static create_path_template_func() list[Callable]

Create a custom path template function.

Any functions returned by this hook will be available to be called from within the path templates defined by the move plugin.

Returns:

A list of all custom path functions your plugin creates. The list should contain the callable functions themselves.

static override_album_path_config(album: Album) str | None

Allows plugins to override the user’s album path configuration.

This hook allows plugins to replace the entire album path template based on album properties, rather than just adding custom functions to existing templates.

Parameters:

album – The Album object for which the path is being generated.

Returns:

An optional string representing the new album path configuration template. If None is returned, the user’s configured album path template will be used.

Example

@moe.hookimpl
def override_album_path_config(album: Album) -> Optional[str]:
    if "Classical" in album.title:
        return "Classical/{album.artist}/{album.title} ({album.year})"
    elif "Soundtrack" in album.title:
        return "Soundtracks/{album.title} ({album.year})"
static override_extra_path_config(extra: Extra) str | None

Allows plugins to override the user’s extra path configuration.

This hook allows plugins to replace the entire extra path template based on extra properties, rather than just adding custom functions to existing templates.

Parameters:

extra – The Extra object for which the path is being generated.

Returns:

An optional string representing the new extra path configuration template. If None is returned, the user’s configured extra path template will be used.

Example

@moe.hookimpl
def override_extra_path_config(extra: Extra) -> Optional[str]:
    if extra.path.name.lower().endswith(('.jpg', '.png')):
        if 'cover' in extra.path.name.lower():
            return f"{extra.album.title}.jpg"
        elif 'scan' in str(extra.path).lower():
            return f"scans/{extra.path.name}"
    elif extra.path.name.lower().endswith('.cue'):
        return f"{extra.album.title}.cue"

Write

class Hooks

Write plugin hook specifications.

static write_custom_tags(track: Track)

Allow plugins to write tags to a Track.

How you write tags to the track is up to each individual plugin. Internally, Moe uses the mediafile library to write tags.

Parameters:

track – Track to write tags to.

Example

audio_file = mediafile.MediaFile(track.path)
audio_file.album = track.album
audio_file.save()

See also