Skip to content

GUI terminal sometimes leaves PTY in raw mode (^M on Enter) during/after interactive beet import #199

@Tompennyau

Description

@Tompennyau

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


...

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingterminal

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions