-
Notifications
You must be signed in to change notification settings - Fork 5
Description
When running an interactive beet import inside the beets-flask GUI terminal, the terminal occasionally gets stuck in a raw/non-canonical state. After this happens, pressing Enter no longer submits the line—it echoes a literal ^M. This makes the GUI terminal unusable until the terminal tab is closed/reopened (or the container is restarted).
Steps to reproduce
1. Open the beets-flask GUI terminal.
2. Run an interactive import, e.g.: beet import /xyz
3. Interact with the prompt (choose candidates, press Enter repeatedly).
Sometimes an abnormal exit (e.g., Ctrl+C, pager exit, or crash) triggers it.
4. Back at the prompt, pressing Enter shows ^M and does not execute the command.
Expected behavior
The GUI terminal should remain in “cooked” TTY mode. Pressing Enter should always produce a newline (LF) and submit the command, even after interactive programs exit or are interrupted.
Actual behavior
• Enter echoes ^M (CR) instead of submitting.
• Output often shows visible ^M characters.
• In the broken session, stty -a typically shows flags like -icrnl -icanon -echo raw.
• Workarounds:
• In the same terminal, using Ctrl+J (LF) to submit and then:
stty sane
or
stty cooked -raw icanon echo icrnl -inlcr -igncr onlcr isig
• Close/reopen the GUI terminal tab.
• Restart the container.
beets-flask config
#gui:
num_preview_workers: 4
terminal:
start_path: "/deemix"
library:
readonly: no
artist_separators: [",", ";", "&"]
inbox:
ignore:
- ".*"
- "*~"
- "System Volume Information"
- "lost+found"
- "@eaDir"
- "@SynoEAStream"
folders:
deemix-local:
name: "Deemix Downloads"
path: "/deemix"
autotag: "auto"
auto_threshold: null
lidarr:
name: "Lidarr Imports"
path: "/lidarr"
autotag: "preview"
auto_threshold: null
beet-copy:
name: "Manual Imports"
path: "/copy"
autotag: "auto"
auto_threshold: null
sabnzb:
name: "SABNZB Music"
path: "/sabnzb"
autotag: "preview"
auto_threshold: null
songkong:
name: "songkong"
path: "/songkong"
autotag: "preview"
auto_threshold: null
beets config
# # Global Options ##################################################################################
include: # A list of extra configuration files to include.
# IMPORTANT: Most configurations doesn't seem to work in external files, so leave them here.
- local.yaml # Edit paths to your needs.
- secrets.yaml # Secret strings (REDUCTED) like usernames and passwords. Add this file to git.ignore.
- plugins.yaml # Activate/deactivate plugins here.
original_date: yes # Use the original date for the release.
per_disc_numbering: yes # The track numbers are incremented throughout a multi disk release.
threaded: yes # Indicating whether the autotagger should use multiple threads.
# This makes things substantially faster by overlapping work.
###################################################################################################
clutter: # When beets imports all the files in a directory, it tries to remove the directory if it’s empty.
# A directory is considered empty if it only contains files whose names match the glob patterns in clutter,
# which should be a list of strings.
# The importer only removes recursively searched subdirectories—the top-level directory you specify on the command line is never deleted.
[
.DS_Store,
Thumbs.DB,
origin.yaml
]
#bucket:
#bucket_alpha_regex:
#[A-Z] # Create folders with the first letters of the band names.
# Paths ###########################################################################################
asciify_path: yes # Convert all non-ASCII characters in paths to ASCII equivalents.
max_filename_length: 255 # 0 = unlimited.
ignore:
- "*.ogg"
- "*.m4v"
paths: # Directory and naming scheme.
# The aunique{} function ensures that identically-named albums are placed in different directories.
default: '$albumartist/$album%aunique{albumartist album,albumtype label catalognum}%if{$year, ($year)}/$track - $title'
singleton: 'Singles/$albumartist/$title'
comp: 'Compilations/$album%aunique{albumartist album,albumtype label catalognum}%if{$year, ($year)}/$track - $title'
albumtype:soundtrack: 'Soundtracks/$album%aunique{albumartist album,albumtype label catalognum}%if{$year, ($year)}/$track - $title'
multidisc: '$albumartist/$album%aunique{albumartist album,albumtype label catalognum}%if{$year, ($year)}/$media $disc/$track - $title'
##################################################################################################
# Import ##########################################################################################
import: # Beets can move or copy files but it doesn’t make sense to do both).
write: yes # Controlling whether metadata (e.g., ID3) tags are written to files when using beet import.
copy: no # Keep your current directory structure.
# The option is ignored if move is enabled (i.e., beets can move or copy files but it doesn’t make sense to do both).
move: yes # Move the files. Otherwise there will be duplicates.
resume: yes # Controls whether interrupted imports should be resumed.
# “Yes” means that imports are always resumed when possible;
# “no” means resuming is disabled entirely;
# “ask” (the default) means that the user should be prompted when resuming is possible.
resume_file: /config/resume.pickle
incremental: no # Don't record imported directories.
incremental_skip_later: no # Controlling whether imported directories are recorded and whether these recorded directories are skipped.
from_scratch: no # Controlling whether existing metadata is discarded when a match is applied.
quiet_fallback: skip # Either skip (default) or asis, specifying what should happen in quiet mode when there is no strong recommendation.
none_rec_action: ask # Either ask (default), asis or skip.
# Specifies what should happen during an interactive import session when there is no recommendation.
# Useful when you are only interested in processing medium and strong recommendations interactively.
timid: no # Controlling whether the importer runs in timid mode,
# in which it asks for confirmation on every autotagging match, even the ones that seem very close.
log: /config/logs/music/import.log
default_action: apply # One of apply, skip, asis, or none, indicating which option should be the default when selecting an action for a given match.
# This is the action that will be taken when you type return without an option letter.
languages: en de # Prefer transliterated English names.
detail: no # Whether the importer UI should show detailed information about each match it finds.
# When enabled, this mode prints out the title of every track, regardless of whether it matches the original metadata.
# The default behavior only shows changes. Default: no.
group_albums: no # By default, the beets importer groups tracks into albums based on the directories they reside in.
# This option instead uses files’ metadata to partition albums.
# Enable this option if you have directories that contain tracks from many albums mixed together.
autotag: yes # If most of your collection consists of obscure music,
# you may be interested in disabling autotagging by setting this option to no.
duplicate_action: ask # Either skip, keep, remove, merge or ask. Controls how duplicates are treated in import task.
# “skip” means that new item (album or track) will be skipped;
# “keep” means keep both old and new items;
# “remove” means remove old item;
# “merge” means merge into one album;
# “ask” means the user should be prompted for the action each time.
bell: yes # Ring the terminal bell to get your attention when the importer needs your input.
importadded:
preserve_mtimes: no # After importing files, re-set their mtimes to their original value. Default: no.
preserve_write_mtimes: no # After writing files, re-set their mtimes to their original value. Default: no.
badfiles:
check_on_import: no
# AcousticBrainz ##################################################################################
absubmit: # The absubmit plugin lets you submit acoustic analysis results to the AcousticBrainz server.
auto: yes # Analyze every file on import. Otherwise, you need to use the beet absubmit command explicitly. Default: no
force: no # Analyze items and submit of AcousticBrainz data even for tracks that already have it. Default: no.
pretend: no # Do not analyze and submit of AcousticBrainz data but print out the items which would be processed. Default: no.
acoustid:
apikey: REDACTED # Command: beet submit
acousticbrainz: # The acousticbrainz plugin gets acoustic-analysis information from the AcousticBrainz project.
auto: yes # Enable AcousticBrainz during beet import. Default: yes.
force: yes # Download AcousticBrainz data even for tracks that already have it. Default: no.
tags: # Which tags from the list above to set on your files. Default: [] (all).
# As far as I know, the following tags couldn't be read by Roon.
- average_loudness
- bpm # ToDo: Mostly zero.
- chords_changes_rate
- chords_key
- chords_number_rate
- chords_scale
- danceable
- gender
- genre_rosamerica
- initial_key # This is a built-in beets field, which can also be provided by Key Finder Plugin.
- key_strength
- mood_acoustic
- mood_aggressive
- mood_electronic
- mood_happy
- mood_party
- mood_relaxed
- mood_sad
- moods_mirex
- rhythm
- timbre
- tonal
- voice_instrumental
###################################################################################################
# MusicBrainz #####################################################################################
musicbrainz:
user: REDACTED
pass: REDACTED
searchlimit: 20 # Recommendation from: https://github.com/kernitus/beets-oldestdate
external_ids:
discogs: yes
spotify: yes
bandcamp: yes
#beatport: yes
deezer: yes
tidal: yes
extra_tags: # Enable improved MediaBrainz queries from tags.
- catalognum
- country
- label
- media
- year
# Match #####################################################################################
match:
sources:
- originquery
- discogs
- musicbrainz
- beatport4
- bandcamp
- deezer
preferred:
media:
- "Digital Media|File"
- "Digital Media"
- "Vinyl"
- '12" Vinyl'
- "LP"
- '7" Vinyl'
countries:
- US
- "GB|UK"
- JP
- DE
- XW
strong_rec_thresh: 0.05 # Reflects the distance threshold below which beets will make a “strong recommendation” that the metadata be used.
# Strong recommendations are accepted automatically (except in “timid” mode),
# so you can use this to make beets ask your opinion more or less often.
# The threshold is a distance value between 0.0 and 1.0, so you can think of it as the opposite of a similarity value.
# For example, if you want to automatically accept any matches above 90% similarity, use: "strong_rec_thresh: 0.10"
# The default strong recommendation threshold is 0.04.
# When a match is below the medium recommendation threshold
# or the distance between it and the next-best match is above the gap threshold,
# the importer will suggest that match but not automatically confirm it.
# Otherwise, you’ll see a list of options to choose from.
medium_rec_thresh: 0.125 # The medium_rec_thresh and rec_gap_thresh options work similarly.
distance_weights:
album_id: 0.01 # If tagging is enabled in Lidarr, the musicbrainz ID might already exist. Lower the weight so beets has a change to change it.
track_id: 0.01
source: 1.0 # still a factor, but lower priority
artist: 2.0
album: 2.0
track_title: 2.0
# ── New controls for recommendation behavior ─────────────────────────────────
rec_gap_thresh: 0.20
max_rec:
missing_tracks: medium
unmatched_tracks: medium
# ── Ignore noisy “tracks” and weird lengths ─────────────────────────────────
ignore_data_tracks: yes
ignore_video_tracks: yes
track_length_grace: 5 # allow up to 5 seconds variance
track_length_max: 20 # flag anything over 20 minutes
mbcollection:
auto: yes # Automatically amend your MusicBrainz collection whenever you import a new album.
collection: REDACTED # Which MusicBrainz collection to update. Use the ID from the URL instead of the name.
remove: yes # Remove albums from collections which are no longer present in the beets database.
# ToDo: remove doesn't work.
mbsubmit: # As MusicBrainz currently does not support submitting albums programmatically,
# the recommended workflow is to copy the output of the Print tracks choice and
# paste it into the parser that can be found by clicking on the “Track Parser” button on MusicBrainz “Tracklist” tab.
format: $track. $title - $artist ($length)
# The format used for printing the tracks, defined using the same template syntax as beets’ path formats.
# Default: $track. $title - $artist ($length).
threshold: medium # The minimum strength of the autotagger recommendation that will cause the Print tracks choice to be displayed on the prompt.
# Default: medium (causing the choice to be displayed for all albums that have a recommendation of medium strength or lower).
# Valid values: none, low, medium, strong.
## chroma #######################################
#chroma: # Turning on fingerprinting can increase the accuracy of the autotagger - especially on files with very poor metadata.
#auto: yes # The Acoustid plugin extends the autotagger to use acoustic fingerprinting to find information for arbitrary audio.
# Install that plugin if you’re willing to spend a little more CPU power to get tags for unidentified albums.
# (But be aware that it does slow down the process.)
## parentwork ###################################
parentwork: # This plugin adds seven tags:
# - parentwork: The title of the parent work.
# - mb_parentworkid: The musicbrainz id of the parent work.
# - parentwork_disambig: The disambiguation of the parent work title.
# - parent_composer: The composer of the parent work.
# - parent_composer_sort: The sort name of the parent work composer.
# - work_date: The composition date of the work, or the first parent work that has a composition date. Format: yyyy-mm-dd.
force: no # As a default, parentwork only fetches work info for recordings that do not already have a parentwork tag.
# If force is enabled, it fetches it for all recordings. Default: no.
auto: yes # If enabled, automatically fetches works at import.
# It takes quite some time, because beets is restricted to one musicbrainz query per second. Default: no.
# Bandcamp ########################################################################################
# beetcamp
bandcamp: # Beetcamp. Uses the bandcamp URL as id (for both albums and songs).
# If no matching release is found when importing you can select enter Id and paste the bandcamp URL.
preferred_media: Digital # A comma-separated list of media to prioritise when fetching albums.
include_digital_only_tracks: true
# For media that isn't Digital Media, include all tracks,
# even if their titles contain digital only (or alike).
search_max: 10 # Maximum number of items to fetch through search queries. Default: 10.
art: true # Add a source to the FetchArt plug-in to download album art for Bandcamp albums
# (requires FetchArt plug-in enabled).
#exclude_extra_fields: # The data that is added after the core auto tagging process is considered extra:
#- lyrics # (currently) lyrics and comments (release description) fields.
#- comments # Since there yet isn't an easy way to preview them before they get applied,
# you can ignore them if you find them irrelevant or inaccurate.
###################################################################################################
# Lyrics ##########################################################################################
lyrics:
auto: yes # Fetch lyrics automatically during import. Default: yes.
fallback: '' # By default, the file will be left unchanged when no lyrics are found.
synced: yes # Use the empty string '' to reset the lyrics in such a case.
# Default: None.
force: no # By default, beets won’t fetch lyrics if the files already have ones.
# To instead always fetch lyrics, set the force option to yes.
# Default: no.
genius_api_key: Redacted
#google_API_key:Redacted # Your Google API key (to enable the Google Custom Search backend).
#google_engine_ID: Redacted # The custom search engine to use.
# Default: The beets custom search engine, which gathers an updated list of sources known to be scrapeable.
sources: # List of sources to search for lyrics.
# An asterisk * expands to all available sources.
# Both it and the genius source will only be enabled if BeautifulSoup is installed.
#- bandcamp # ToDo: Not shure if this entry is really nescessary.
- local
- genius
- lrclib
- lyricwiki
#- google # The google source will be automatically deactivated if no google_API_key is setup.
#- musixmatch # Possibly just 30% of a whole song text
# Leave in last position or comment it out.
# @test
###################################################################################################
# Last.fm #########################################################################################
lastimport:
per_page: 500 # The number of tracks to request from the API at once. Default: 500.
retry_limit: 3 # How many times should we re-send requests to Last.fm on failure? Default: 3.
lastfm: {}
#user: REDACTED
#api_key: REDACTED
types:
play_count: int
rating: float
lastgenre: # Fetches tags from Last.fm and assigns them as genres to your albums and items.
auto: yes # Fetch genres automatically during import. Default: yes.
canonical: /config/genres/genres-tree.yaml
# Use a canonicalization tree. Setting this to yes will use a built-in tree.
whitelist: /config/genres/genres.txt
# The filename of a custom genre list, yes to use the internal whitelist, or no to consider all genres valid.
# Default: yes.
count: 5 # Number of genres to fetch. Default: 1
fallback: 'Undefined' # A string if to use a fallback genre when no genre is found.
# You can use the empty string '' to reset the genre.
# Default: None.
separator: '; '
force: no # By default, beets will always fetch new genres, even if the files already have one.
# To instead leave genres in place in when they pass the #whitelist: ~/.config/beets/genres.txt,
# set the force option to no.
min_weight: 10 # Minimum popularity factor below which genres are discarded. Default: 10.
prefer_specific: no # Sort genres by the most to least specific, rather than most to least popular. Default: no.
source: track # Which entity to look up in Last.fm. Can be either artist, album or track. Default: album.
title_case: yes # Convert the new tags to TitleCase before saving. Default: yes.
###################################################################################################
# Muspy ###########################################################################################
#follow: # Get notifications about new releases from album artists in your Beets library using muspy.
#email: Redacted
#password: Redacted
#userid: REDACTED
#auto: yes
###################################################################################################
# Pictures ########################################################################################
# In Roon, all the images embedded in the file tags, are stored next to the audio files or
# stored in a folder called artwork or scans next to the files are displayed.
# This includes all images that include cover, front or folder.
art_filename: cover # When importing album art, the name of the file (without extension) where the cover art image should be placed.
# This is a template string, so you can use any of the syntax available to Path Formats.
# filenote ########################################################################################
filetote:
print_ignored: yes
ignore_hidden: no
pairing:
enabled: true
extensions: .lrc .LRC .lyr .LYR
patterns:
# Logs, cues
logcue:
- '*.[lL][oO][gG]'
- '*.[cC][uU][eE]'
# Playlists (split out so they land in paths.playlists)
playlists:
- '*.[mM]3[uU]'
- '*.[mM]3[uU]8'
# Canonical covers in the album root
cover:
- '[cC]over.jpg'
- '[cC]over.jpeg'
- '[fF]ront.*'
- '[fF]older.*'
# Other artwork in root or scans subfolders (+ Origin-Cover sidecar)
art:
- '*.[jJ][pP][gG]'
- '*.[jJ][pP][eE][gG]'
- '*.[pP][nN][gG]'
- '*.[gG][iI][fF]'
- '*.[wW][eE][bB][pP]'
- '*.[pP][dD][fF]'
- '[Ss]cans/*'
- '[Ss]can*/*'
- '.origin/origin-cover.*'
# Origin + explicit metadata you want to keep
origin:
- 'origin.yaml'
- 'origin.yml'
# Temporary markers (move them somewhere instead of ignoring)
origin_tmp:
- '.post_origin.lock'
- '.post_origin_done'
# Checksums & integrity
sums:
- '*.sfv'
- '*.md5'
- '*.sha1'
- '*.sha256'
# Misc text/meta
docs:
- '*.nfo'
- '*.txt'
- '*.json'
- '*.xml'
- '*.url'
- '*.webloc'
- '*.lrc'
- '*.lyr'
- '*.yaml'
- '*.yml'
# Catch-all for anything else
extras:
- '*.*'
paths:
playlists: '$albumpath/playlist.m3u8'
logcue: '$albumpath/%left{$albumartist,60} - %left{$album,80}'
cover: '$albumpath/Artwork/$old_filename'
art: '$albumpath/Artwork/$old_filename'
lyrics_fallback: '$albumpath/Lyrics/$old_filename'
origin: '$albumpath/$old_filename'
#origin_tmp:'$albumpath/Extras/$old_filename'
sums: '$albumpath/Extras/$old_filename'
docs: '$albumpath/Extras/$old_filename'
extras: '$albumpath/Extras/$old_filename'
# fetchart ########################################################################################
fetchart:
auto: yes # Enable automatic album art fetching during import.
cautious: no # Pick only trusted album art by ignoring filenames that do not contain one of the keywords in "cover_names".
cover_names: [cover, folder, front] # aligns with your filetote patterns
cover_format: jpg # ensures a consistent extension
enforce_ratio: yes # Only allow images with 1:1 aspect ratio
minwidth: 1000 # Only images with a width bigger or equal to minwidth are considered as valid album art candidates.
maxwidth: 3000 # A maximum image width to downscale fetched images if they are too big.
# The height is recomputed so that the aspect ratio is preserved.
sources: # An asterisk * expands to all available sources.
- filesystem # No remote art sources are queried if local art is found in the filesystem.
- coverart
- albumart
- lastfm
- google
- itunes
- amazon
- fanarttv
- bandcamp
google_key: Redacted# <-- your API key
google_engine: Redacted
lastfm_key: Redacted # Last.fm API key for art
fanarttv_key: REDACTED # API key to use for the fanart API.
store_source: yes # Store the art source (e.g. filesystem) in the beets database as art_source.
lastfm:
user: Redacted
api_key: Redacted
secret: Redacted
embedart:
auto: yes # Enable automatic album art embedding.
compare_threshold: 50 # A threshold of 0 (the default) disables similarity checking and always embeds new images.
# Recommended between 10 and 100.
# The smaller the threshold number, the more similar the images must be.
ifempty: yes # Avoid embedding album art for files that already have art embedded.
maxwidth: 0 # A maximum width to downscale images before embedding them (the original image file is not altered).
# The resize operation reduces image width to at most maxwidth pixels.
# The height is recomputed so that the aspect ratio is preserved. See also Image Resizing for further caveats about image resizing.
quality: 95
remove_art_file: no # Automatically remove the album art file for the album after it has been embedded.
# This option is best used alongside the FetchArt plugin to download art with the purpose
# of directly embedding it into the file’s metadata without an “intermediate” album art file.
###################################################################################################
# ReplayGain ######################################################################################
replaygain:
auto: yes # Enable ReplayGain analysis during import. Default: yes.
# ReplayGain analysis is not fast, so you may want to disable it during import.
backend: ffmpeg # The analysis backend; either gstreamer, command, or audiotools. Default: command.
overwrite: no # Re-analyze files that already have ReplayGain tags. Default: no.
targetlevel: 89 # A number of decibels for the target loudness level. Default: 89.
per_disc: no # Calculate album ReplayGain on disc level instead of album level. Default: no.
###################################################################################################
# Maintanance #####################################################################################
duplicates:
album: yes # List duplicate albums instead of tracks. Default: no.
#checksum: ffmpeg -i {file} -f crc -
# Use an arbitrary command to compute a checksum of items.
# This overrides the keys option the first time it is run;
# however, because it caches the resulting checksum as flexattrs in the database,
# you can use --key=name_of_the_checksumming_program --key=any_other_keys
# (or set the keys configuration option) the second time around.
# Default: ffmpeg -i {file} -f crc -.
#copy: # A destination base directory into which to copy matched items.
# Default: none (disabled).
count: yes # Print a count of duplicate tracks or albums in the format
# $albumartist - $album - $title: $count (for tracks)
# or
# $albumartist - $album: $count (for albums).
# Default: no.
delete: no # Removes matched items from the library and from the disk. Default: no
format: format_item # A specific format with which to print every track or album.
# This uses the same template syntax as beets’ path formats.
# The usage is inspired by, and therefore similar to, the list command.
# Default: format_item
full: yes # List every track or album that has duplicates, not just the duplicates themselves. Default: no
keys:
#- mb_trackid
#- mb_albumid
- albumartist
- album
- title
- year
- length
#- catalognum
# Define in which track or album fields duplicates are to be searched.
# By default, the plugin uses the musicbrainz track and album IDs for this purpose.
# Using the keys option (as a YAML list in the configuration file,
# or as space-delimited strings in the command-line),
# you can extend this behavior to consider other attributes.
# Default: [mb_trackid, mb_albumid]
merge: yes # Merge duplicate items by consolidating tracks and/or metadata where possible.
move:Redacted # A destination base directory into which it will move matched items. Default: none (disabled).
path: no # Output the path instead of metadata when listing duplicates. Default: no.
strict: no # Do not report duplicate matches if some of the attributes are not defined (ie. null or empty). Default: no
tag: duplicate=true # A key=value pair.
# The plugin will add a new key attribute with value value as a flexattr to the database for duplicate items. Default: no.
tiebreak:
items: [bitrate, samplerate, format, filesize] # Dictionary of lists of attributes keyed by items or albums to use when choosing duplicates.
# By default, the tie-breaking procedure favors the most complete metadata attribute set.
# If you would like to consider the lower bitrates as duplicates, for example, set tiebreak: items: [bitrate].
# Default: {}.
check:
import: no # Add checksums for new files during the import process.
# This also disables integrity checks on import and will not ask you to skip the import of corrupted files.
write-check: yes # Verify checksums before writing files with beet write or beet modify.
write-update: yes # Update checksums after writing files with beet write or beet modify.
convert-update: no # Update the checksum if a file has been converted with the --keep-new flag.
threads: 1 # Threads to compute checksums.
###################################################################################################
# Export ##########################################################################################
convert: # By default, the command places converted files into the destination directory and leaves your library pristine.
auto: no # Import transcoded versions of your files automatically during imports.
command: ffmpeg -i $source -sample_fmt s16 -ar 44100 $dest
extension: flac
source: /config/convert/input
dest: /config/convert/output
# The directory where the files will be converted (or copied) to. Default: none.
# With this option enabled, the importer will transcode all (in the default configuration) non-MP3 files
# over the maximum bitrate before adding them to your library.
#tmpdir: none # The directory where temporary files will be stored during import. Default: none (system default),
copy_album_art: no # Since the covers are embedded in the files when Roon exports them, this configuration is not necessary.
embed: no # Embed album art in converted items. Default: yes.
#id3v23: inherit # Can be used to override the global id3v23 option. Default: inherit.
never_convert_lossy_files: yes
# Cross-conversions between lossy codecs—such as mp3, ogg vorbis, etc.
# Makes little sense as they will decrease quality even further.
# If set to yes, lossy files are always copied.
quiet: false # Prevent the plugin from announcing every file it processes.
# Default: false.
threads: 1 # The number of threads to use for parallel encoding.
# By default, the plugin will detect the number of processors available and use them all.
permissions: # octal modes # Maybe nescessary for smb shares like ROCK or NAS drives.
file: 777
dir: 777
# plex ##############################################################################################
plex:Redacted
host: Redacted # No https:// or plex.direct
port: Redacted
token:Redacted
library_name: Music # Or whatever your Plex music library is named
secure: true
ignore_cert_errors: true
# WEB ##############################################################################################
web:
host: 0.0.0.0
port: Redacted
#Missing-tracks plugin configuration ##############################################################################################
missing:
format: $albumartist - $album - $title
count: yes
total: yes
#Unimported-files plugin configuration ##############################################################################################
unimported:
patterns:
- "*.flac"
- "*.mp3"
ignore_extensions:
- .jpg
- .jpeg
- .png
- .gif
- .webp
- .pdf
- .nfo
- .txt
- .lrc
- .lyr
- .yaml
- .yml
- .cue
- .log
- .sfv
- .md5
- .sha1
- .sha256
- .json
- .xml
- .url
- .webloc
ignore_hidden: true
ignore_subdirectories:
- "@eaDir"
- "@SynoResource"
- "@SynoEAStream"
- tmp
- data
#originquery ##############################################################################################
### ORIGINQUERY-REPLACE-START
originquery:
origin_file: origin.yaml
origin_type: yaml
import_copy_origin: true
fallback_to_mb: true
tag_patterns:
media: "$.mydata['Release type']"
year: "$.mydata['Edition year']"
label: "$.mydata['Record label']"
catalognum: "$.mydata['Catalog number']"
#format: "$.mydata.Format"
#encoding: "$.mydata.Encoding"
#directory_path: "$.mydata.Directory"
#info_hash: "$.mydata['Info hash']"
#permalink: "$.mydata.Permalink"
#filesize: "$.mydata.Size"
#description: "$.mydata.Description"
#genre: "$.mydata.Tags"
### ORIGINQUERY-REPLACE-END
#bpmanalyser ##############################################################################################
bpmanalyser:
auto: yes # run during import
write: yes # write BPM to files
force: no
threads: AUTO
quiet: yes
#autobpm ##############################################################################################
autobpm:
auto: yes # Calculate BPM during import
overwrite: no # Don’t replace existing BPM values
beat_track_kwargs:
start_bpm: 125 # Seed tempo (set this based on your typical genre)
tightness: 25 # 100 = stricter confidence around start_bpm
#playlist##############################################################################################
playlist:
auto: yes
relative_to: /music
playlist_dir: /music/playlist
extension: m3u
#keyfinder##############################################################################################
keyfinder:
auto: yes # Automatically detect key on import
bin: /config/keyfinder-camelot.sh
overwrite: no # Don't overwrite if tag already exists
# UI ##############################################################################################
verbose: no
ui:
color: yes
colors:
text_success: green
text_warning: blue
text_error: red
text_highlight: blue
text_highlight_minor: lightgray
action_default: darkblue
action: purple
format_item: "$albumartist - $album - $title - $initial_key - $bpm"
hook:
hooks:
#############################################
- event: album_imported
command: echo "\"{album}\""
- event: import
command: echo "imported from {paths}"
#############################################
- event: art_set
command: echo "Coverart saved"
- event: import_begin
command: echo "Import started..."
- event: import_task_apply
command: echo "Metadata applied"
- event: item_copied
command: echo "\"{item}\" copied from \"{source}\" to \"{destination}\""
- event: item_moved
command: echo "Moved \"{item}\""
- event: write
command: echo "Writing to {path}"
- event: cli_exit
command: echo "All tasks finished!"
Docker-compose file / Docker command
# paste here, in particular volume mounts
Container logs
Find the output from docker logs beets-flask
below:
> docker logs beets-flask
[INFO] beets-flask.wdog: Watchdog: Enqueuing /deemix/Slikback as import_auto
--
[INFO] beets-flask.wdog: Watchdog: Starting inbox handler task /deemix/Slikback
Arguments: (FileNotFoundError('Path `/deemix/Slikback/Attrition` is not a file.'),)
Message: 'Error in inbox handler task for /deemix/Slikback/Attrition'
log.exception(f"Error in inbox handler task for {album_folder}", e)
File "/repo/backend/beets_flask/watchdog/inbox.py", line 139, in task_func
result = coro.send(None)
File "/usr/local/lib/python3.11/asyncio/tasks.py", line 277, in __step
self.__step()
File "/usr/local/lib/python3.11/asyncio/tasks.py", line 360, in __wakeup
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.11/asyncio/events.py", line 84, in _run
handle._run()
File "/usr/local/lib/python3.11/site-packages/nest_asyncio.py", line 133, in _run_once
self._run_once()
File "/usr/local/lib/python3.11/site-packages/nest_asyncio.py", line 81, in run_forever
asyncio.get_event_loop().run_forever()
File "/repo/backend/./launch_watchdog_worker.py", line 19, in <module>
Call stack:
TypeError: not all arguments converted during string formatting
~~~~^~~~~~~~~~~
msg = msg % self.args
File "/usr/local/lib/python3.11/logging/__init__.py", line 377, in getMessage
^^^^^^^^^^^^^^^^^^^
record.message = record.getMessage()
File "/usr/local/lib/python3.11/logging/__init__.py", line 687, in format
^^^^^^^^^^^^^^^^^^
return fmt.format(record)
File "/usr/local/lib/python3.11/logging/__init__.py", line 953, in format
^^^^^^^^^^^^^^^^^^^
msg = "%s\n" % self.format(record)
File "/usr/local/lib/python3.11/logging/handlers.py", line 196, in shouldRollover
^^^^^^^^^^^^^^^^^^^^^^^^^^^
if self.shouldRollover(record):
File "/usr/local/lib/python3.11/logging/handlers.py", line 73, in emit
Traceback (most recent call last):
During handling of the above exception, another exception occurred:
FileNotFoundError: Path `/deemix/Slikback/Attrition` is not a file.
raise FileNotFoundError(f"Path `{path}` is not a file.")
File "/repo/backend/beets_flask/disk.py", line 249, in from_path
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return File.from_path(path, cache=cache)
File "/repo/backend/beets_flask/disk.py", line 82, in fs_item_from_path
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
folder = fs_item_from_path(folder_path)
File "/repo/backend/beets_flask/watchdog/inbox.py", line 178, in auto_tag
await auto_tag(album_folder)
File "/repo/backend/beets_flask/watchdog/inbox.py", line 137, in task_func
Traceback (most recent call last):
--- Logging error ---
Arguments: (FileNotFoundError('Path `/deemix/Slikback/Attrition` is not a file.'),)
Message: 'Error in inbox handler task for /deemix/Slikback/Attrition'
log.exception(f"Error in inbox handler task for {album_folder}", e)
File "/repo/backend/beets_flask/watchdog/inbox.py", line 139, in task_func
result = coro.send(None)
File "/usr/local/lib/python3.11/asyncio/tasks.py", line 277, in __step
self.__step()
File "/usr/local/lib/python3.11/asyncio/tasks.py", line 360, in __wakeup
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.11/asyncio/events.py", line 84, in _run
handle._run()
File "/usr/local/lib/python3.11/site-packages/nest_asyncio.py", line 133, in _run_once
self._run_once()
File "/usr/local/lib/python3.11/site-packages/nest_asyncio.py", line 81, in run_forever
asyncio.get_event_loop().run_forever()
File "/repo/backend/./launch_watchdog_worker.py", line 19, in <module>
Call stack:
TypeError: not all arguments converted during string formatting
~~~~^~~~~~~~~~~
msg = msg % self.args
File "/usr/local/lib/python3.11/logging/__init__.py", line 377, in getMessage
^^^^^^^^^^^^^^^^^^^
record.message = record.getMessage()
File "/usr/local/lib/python3.11/logging/__init__.py", line 687, in format
^^^^^^^^^^^^^^^^^^
return fmt.format(record)
File "/usr/local/lib/python3.11/logging/__init__.py", line 953, in format
^^^^^^^^^^^^^^^^^^^
msg = self.format(record)
File "/usr/local/lib/python3.11/logging/__init__.py", line 1110, in emit
Traceback (most recent call last):
During handling of the above exception, another exception occurred:
FileNotFoundError: Path `/deemix/Slikback/Attrition` is not a file.
raise FileNotFoundError(f"Path `{path}` is not a file.")
File "/repo/backend/beets_flask/disk.py", line 249, in from_path
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return File.from_path(path, cache=cache)
File "/repo/backend/beets_flask/disk.py", line 82, in fs_item_from_path
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
folder = fs_item_from_path(folder_path)
File "/repo/backend/beets_flask/watchdog/inbox.py", line 178, in auto_tag
await auto_tag(album_folder)
File "/repo/backend/beets_flask/watchdog/inbox.py", line 137, in task_func
Traceback (most recent call last):
--- Logging error ---
[INFO] beets-flask.wdog: Watchdog: Starting inbox handler task /deemix/Slikback/Attrition
could not list directory /deemix/Slikback/Attrition: No such file or directory
could not list directory /deemix/Slikback/Attrition/playlist.m3u8: No such file or directory
could not list directory /deemix/Slikback/Attrition/folder.jpg: No such file or directory
[INFO] beets-flask.wdog: Watchdog: skipping enqueue /deemix/Slikback/Attrition
[INFO] beets-flask.wdog: Watchdog: Starting inbox handler task /deemix/Slikback/Attrition
could not list directory /deemix/Slikback/Attrition/09 - Sheltered.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/07 - Taped.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/10 - Spend.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/cover.jpg: No such file or directory
could not list directory /deemix/Slikback/Attrition/11 - Fracture.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/08 - Trars.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/02 - Knot.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/05 - Duality.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/04 - Guerrilla.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/06 - Semblance Of Composure.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/03 - Sekli.flac: No such file or directory
could not list directory /deemix/Slikback/Attrition/01 - Snow.flac: No such file or directory
[INFO] beets-flask.wdog: Watchdog: Enqueuing /deemix/Slikback/Attrition as import_auto
[INFO] beets-flask.wdog: Watchdog: Starting inbox handler task /deemix/Slikback/Attrition
[INFO] beets-flask.wdog: Watchdog: Enqueuing /deemix/Sleepy Rich/Solaris as import_auto
[INFO] beets-flask.wdog: Watchdog: Starting inbox handler task /deemix/Sleepy Rich/Solaris
...