Coder Social home page Coder Social logo

beets-alternatives's Introduction

beets-alternatives

Check and test Coverage Status

You want to manage multiple versions of your audio files with beets? Your favorite iPlayer has limited space and does not support Ogg Vorbis? You want to keep lossless versions on a large external drive? You want to symlink your audio to other locations?

With this beets plugin every file in you music library have multiple alternate versions in separate locations.

If you’re interested in contributing to this project, check out the developer documentation.

Getting Started

Install the plugin and make sure you using at least version 1.6.0 of beets and Python 3.8.

pip install --upgrade beets>=1.6.0 beets-alternatives

Then, enable the plugin. You may use the beet config --edit command to add the alternatives plugin to the configuration.

plugins:
- ...
- alternatives

Now, you can get rolling with one of the use cases below.

External Files

Suppose your favorite portable player only supports MP3 and MP4, has limited disk space and is mounted at /player. Instead of selecting its content manually and using the convert plugin to transcode it, you want to sync it automatically. First we give this external collection the name ‘myplayer’ and start configuring beets.

alternatives:
  myplayer:
    directory: /player
    paths:
      default: $album/$title
    formats: aac mp3
    query: "onplayer:true"
    removable: true

The first two options determine the location of the external files and correspond to the global directory and paths settings. The format option specifies the formats we transcode the files to (more on that below). Finally, the query option tells the plugin which files you want to put in the external location. The value is a query string as used for the beets command line. In our case we use a flexible attribute to make the selection transparent.

Let’s add some files to our selection by setting the flexible attribute from the query option. (Since we use boolean values for the ‘onplayer’ field it might be a good idea to set the type of this field to bool using the types plugin)

beet modify onplayer=true artist:Bach

The configured query also matches all tracks that are part of an album where the onplayer attribute is ‘true’. We could also use

beet modify -a onplayer=true albumartist:Bach

We then tell beets to create the external files.

$ beet alt update myplayer
Collection at '/player' does not exists. Maybe you forgot to mount it.
Do you want to create the collection? (y/N)

The question makes sure that you don’t recreate a external collection if the device is not mounted. Since this is our first go, we answer the question with yes.

The command will copy all files with the artist ‘Bach’ and format either ‘AAC’ or ‘MP3’ to the /player directory. All other formats will be transcodec to the ‘AAC’ format unsing the convert plugin. The transcoding process can be configured through convert’s configuration.

If you update some tracks in your main collection, the alt update command will propagate the changes to your external collection. Since we don’t need to convert the files but just update the tags, this will be much faster the second time.

beet modify composer="Johann Sebastian Bach" artist:Bach
beet alt update myplayer

After going for a run you mitght realize that Bach is probably not the right thing to work out to. So you decide to put Beethoven on your player.

beet modify onplayer! artist:Bach
beet modify onplayer=true artist:Beethoven
beet alt update myplayer

This removes all Bach tracks from the player and adds Beethoven’s.

Symlink Views

Instead of copying and converting files this plugin can also create symbolic links to the files in your library. For example you want to have a directory containing all music sorted by year and album.

directory: /music
paths:
  default: $artist/$album/$title

alternatives:
  by-year:
    directory: by-year
    paths:
      default: $year/$album/$title
    formats: link

The first thing to note here is the link format. Instead of converting the files this tells the plugin to create symbolic links to the original audio file. We also note that the directory is a relative path: it will be resolved with respect to the global directory option. We could also omit the directory configuration as it defaults to the collection’s name. Finally, we omitted the query option. This means that we want to create symlinks for all files. Of course you can still add a query to select only parts of your collection.

The beet alt update by-year command will now create the symlinks. For example

/music/by-year/1982/Thriller/Beat It.mp3
-> /music/Michael Jackson/Thriller/Beat It.mp3

You can also specify if you want absolute symlinks (default) or relative ones with link_type. The option link_type must be absolute or relative

alternatives:
  by-year:
    directory: by-year
    paths:
      default: $year/$album/$title
    formats: link
    link_type: relative

With this config, the beet alt update by-year command will create relative symlinks. E.g:

/music/by-year/1982/Thriller/Beat It.mp3
-> ../../../Michael Jackson/Thriller/Beat It.mp3

Now, if you move the /music/ folder to another location, the links will continue working

CLI Reference

beet alt update [--create|--no-create] NAME

Updates the external collection configured under alternatives.NAME.

  • Add missing files. Convert them to the configured format or copy them.

  • Remove files that don’t match the query but are still in the external collection

  • Move files to the path determined from the paths configuration.

  • Update tags if the modification time of the external file is older than that of the source file from the library.

The command accepts the following option.

  • --[no-]create If the removable configuration option is set and the external base directory does not exist, then the command will ask you to confirm the creation of the external collection. These options specify the answer as a cli option.
beet alt update [--create|--no-create] --all

Update all external collections defined in alternatives configuration.

beet alt list-tracks [--format=FORMAT] NAME

Lists all tracks that are currently included in the collection.

The --format option accepts a beets path format string that is used to format each track.

Configuration

An external collection is configured as a name-settings-pair under the alternatives configuration. The name is used to reference the collection from the command line. The settings is a map of the following settings.

  • directory The root directory to store the external files under. Relative paths are resolved with respect to the global directory configuration. If omitted it defaults to the name of the collection and is therefore relative to the library directory. (optional)

  • paths Path templates for audio files under directory. Configured like the global paths option and defaults to it if not given. (optional)

  • query A query string that determine which tracks belong to the collection. A track belongs to the collection if itself or the album it is part of matches the query. To match all items, specify an empty string. (required)

  • formats A list of space separated strings that determine the audio file formats in the external collection. If the ‘format’ field of a track is included in the list, the file is copied. Otherwise, the file is transcoded to the first format in the list. The name of the first format must correpond to a key in the convert.formats configuration. This configuration controls the transcoding process.

    The special format ‘link’ is used to create symbolic links instead of transcoding the file. It can not be combined with other formats.

    By default no transcoding is done.

  • removable If this is true (the default) and directory does not exist, the update command will ask you to confirm the creation of the external collection. (optional)

  • link_type Can be absolute (default) or relative. If formats is link, it sets the type of links to create. For differences between link types and examples see Symlink Views.

Feature Requests

If you have an idea or a use case this plugin is missing, feel free to open an issue.

The following is a list of things I might add in the feature.

  • Symbolic links for each artist in a multiple artists release (see the beets issue)

License

Copyright (c) 2014-2023 Thomas Scholtes.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

beets-alternatives's People

Contributors

daviddavo avatar geigerzaehler avatar johnyerhot avatar kraymer avatar pkess avatar renovate[bot] avatar wisp3rwind avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

beets-alternatives's Issues

OSError: [Errno 38] Function not implemented

Hi!
I just discovered this plugin and tried it out.
I installed it with pip and have the 0.9 version installed, along with beets 1.50.

On my first try I got this error:

soergeld@soergeld-Latitude-7480:~$ beet -vv alt update by-work
user configuration: /home/soergeld/.config/beets/config.yaml
data directory: /home/soergeld/.config/beets
plugin paths: 
Sending event: pluginload
library database: /media/soergeld/EEC7-74A2/Musique/beets/Musicdata_sync.db
library directory: /media/soergeld/EEC7-74A2/Musique/beets
Sending event: library_opened
+/media/soergeld/EEC7-74A2/Musique/beets_by-work/ZZZ_Non-classical/Harvard University Choir, Jones, Edward Elwyn/99th Annual Christmas Carol Services/01-16 Hymn_ Hark! The Herald Angels Sing.m4a
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/beets/util/__init__.py", line 503, in link
    os.symlink(syspath(path), syspath(dest))
OSError: [Errno 38] Function not implemented

Error: Function not implemented during link of paths /media/soergeld/EEC7-74A2/Musique/beets/Harvard University Choir, Jones, Edward Elwyn/99th Annual Christmas Carol Services/01-16 Hymn_ Hark! The Herald Angels Sing.m4a, /media/soergeld/EEC7-74A2/Musique/beets_by-work/ZZZ_Non-classical/Harvard University Choir, Jones, Edward Elwyn/99th Annual Christmas Carol Services/01-16 Hymn_ Hark! The Herald Angels Sing.m4a

Configuration:

alternatives:
    by-work:
        directory: ../beets_by-work
        paths:
            albumartist_sort::'Wise Guys': %asciify{ZZZ_Non-classical/$albumartist_sort/$album %ifdef{albumdisambig,($albumdisambig),}/$disc-$track $title}
            album:'Lambarena': %asciify{ZZZ_Non-classical/$album %ifdef{albumdisambig,($albumdisambig),}/$disc-$track $title}
            album:'Gladrags': %asciify{ZZZ_Non-classical/$albumartist_sort/$album %ifdef{albumdisambig,($albumdisambig),}/$disc-$track $title}
            album:'Piano Rags': %asciify{ZZZ_Non-classical/$albumartist_sort/$album %ifdef{albumdisambig,($albumdisambig),}/$disc-$track $title}
            ...
        formats: link

Do you have an idea what's going wrong?

MTP Support

I really like this idea, but it's somewhat limited by the fact that devices need to be mounted the regular way, which is fine for dumb devices, but most newer ones like phones usually don't mount this way, and don't have a fixed mountpount you can easily refer to.

Adding MTP support would greatly improve this plugin's ubiquity and would make it a lot more helpful with never devices.

Some files are always converted

There are some albums that every time I do an "beet alt update xxx" are converted.

How can I check why is this happening?

Best regards and very good work

Query on CLI option

Would it be possible to expose the query option as part of the cli args for this plugin? I do a lot of batch processing and cross convert my entire library from flac -> compressed formats.

Having a cli option for the query would let me more easily process my batches without having to remember to update my config on each run or waiting for the plugin to go through my entire beets library.

Check for existing files / Invoke convert's convert_item

Convert.convert_item has destination file checking. Then it invokes encode. This plugin goes straight to convert.encode, skipping the dupe check, meaning existing files are overwritten by a new encode. I found this because I had to kill the convert process to shut my PC off. Resuming it today began from the beginning.

if self.should_transcode(item):

https://github.com/beetbox/beets/blob/1b187fbf5345727e0dfdaea958a714f19e917a4e/beetsplug/convert.py#L295

convert_item has different arguments, so it won't be a drop-in replacement. Or this plugin could implement dupe checking on its own.

beet alt update doesn't always remove obsolete links

Hi!
I've been using beets_alternatives to create softlinks and therefore have two parralel classification systems for my music. However, I noticed a problem: When the directory of a file changes and I apply beet alt update by-work it creates new links with updated paths and targets, but doesn't remove the old ones.
Here my configuration:

alternatives:
    by-work:
        directory: /media/soergeld/My Passport/by-work
        paths:
            comp type::'non-classical': Non-Classique/$aaa/$aa/$tr
            type::'non-classical': Non-Classique/$aaa/$aa/$tr
            comp type::'medieval': Medieval/$aaa/$aa/$tr
            type::'medieval': Medieval/$aaa/$aa/$tr
            comp pw::'No_Work': Classique/$artist_sort/Divers/$aaa/$aa/$tr
            pw::'No_Work': Classique/$artist_sort/Divers/$aaa/$aa/$tr
            comp pc::'No_Parent_Composer': Classique/$artist_sort/$pw/$aaa/$aa/$tr
            pc::'No_Parent_Composer': Classique/$artist_sort/$pw/$aaa/$aa/$tr
            comp work_prefix::'None':  Classique/$pc/$pw/$aaa/$aa/$tr
            work_prefix::'None':  Classique/$pc/$pw/$aaa/$aa/$tr
            comp: Classique/$pc/$work_prefix/$pw/$aaa/$aa/$tr
            default: Classique/$pc/$work_prefix/$pw/$aaa/$aa/$tr
            
        formats: link

tr, pw, pc, aa, aaa and type are created using the inline plugin, I can show you how if needed.

As an example, beet mbsync && beet write outputted, among other things,

Georg Philipp Telemann - Complete Overtures, Volume 1 - Overture in D TWV 55: D18, 1. Ouverture
  albumartist: Georg Philipp Telemann; Collegium Instrumentale Brugense, Patrick Peire -> Georg Philipp Telemann; Het Kamerokest, Patrick Peire
  albumartist_sort: Telemann, Georg Philipp; Collegium Instrumentale Brugense, Peire, Patrick -> Telemann, Georg Philipp; Kamerokest, Het, Peire, Patrick
.
.
.
Georg Philipp Telemann - Complete Overtures, Volume 1 - Overture in A TWV 55: A4, 4. Minuetta 1-Minuetta 2
  albumartist: Georg Philipp Telemann; Collegium Instrumentale Brugense, Patrick Peire -> Georg Philipp Telemann; Het Kamerokest, Patrick Peire
  albumartist_sort: Telemann, Georg Philipp; Collegium Instrumentale Brugense, Peire, Patrick -> Telemann, Georg Philipp; Kamerokest, Het, Peire, Patrick

The files then got moved according to their new metadata. Applying beet alt update by-work after that showed

+/media/soergeld/My Passport/by-work/Classique/Telemann, Georg Philipp/Overture-Suite in D, TWV 55_D18/Kamerokest, Het, Peire, Patrick/Complete Overtures, Volume 1/1-1 Overture in D TWV 55_ D18, 1. Ouverture.mp3
.
.
.
+/media/soergeld/My Passport/by-work/Classique/Telemann, Georg Philipp/Overture in A, TWV 55_A4/Kamerokest, Het, Peire, Patrick/Complete Overtures, Volume 1/3-73 Overture in A TWV 55_ A4, 4. Minuetta 1-Minuetta 2.mp3

but the old links remain. Do you have an idea why? I didn't notice this behaviour before and it seemed to work fine, but then I didn't check in detail as I have a collection of ~50 000 tracks. However, find /media/soergeld/My\ Passport/by-work/ -xtype l shows more broken links, and I noticed that I had to remove all links and restart from scratch (which isn't that much of a problem) from time to time.
It seems like at least sometimes, more precisely when you move a file with beets, beets-alternatives would create new links and not redirect (and eventually modify) the existing ones, that are then left broken.

So to summarize:
I have files on beets with soft links from beets-alternatives
I change the files on beets and move them
I want to update the soft links
Instead of updating the old soft links to the new location of the files, new soft links are created and the old ones are left broken.

Error in README

You propose:
beet modify onplayer=true artist:Bach
Shouldn't it be:
beet modify artist:Bach onplayer=true ?
According to the beets documentation, the QUERY should precede the modification:
beet modify [-MWay] [-f FORMAT] QUERY [FIELD=VALUE...] [FIELD!...]

Publish to PyPI

Publish this code as a package to PyPI. Setup CI to do auto-publishing.

No support for non-utf8 paths

beets-alternatives currently does not support non-utf8 paths, while beets does (I didn't really test any of this, that's only guessed from reading the code).

When the Python 3 PR is applied, the only remaining problem should be path storage in the database. The issue is that beets' flexible attributes are treated as sqlite TEXT. While sqlite appears to support arbitrary binary data in its TEXT columns as long as no SQL operations tries to interpret it as actual encoded text, Python's sqlite3.Connection.text_factory interprets the data as unicode strings (grep suggests that bees does not change text_factory from the default).
Whether the default text_factory supports surrogate escapes is not documented (and from a quick look at the cpython code, I couldn't tell either). Thus, supporting such paths can probably not be solved by using a custom beets.dbcore.types.Type subclass, but would require changes to beets itself. Maybe using the backslashreplace error handler with the utf8 codec could also work (which might bring up issues with backwards-compatibility, though).

Personally, I don't really care about non-ut8 paths, but wanted to track this here either way.

Auto update

Enable auto-updating when you import something, the collection is updated, etc

Feature request: update all

Hi, would it be possible to add an option to update all the "names" at once?
I keep a music folder on my phone synced to a folder on my server, and I use different subfolders under that main folder (each one corresponding to an alt NAME) to create playlists that I can play on my phone. I would like to create a cron job to refresh all these subfolders overnight, but I'm constantly adding/removing subfolders so it would be easier not to have to specifically update each of them (as the list keeps changing).
I was thinking that maybe a new command (e.g. beet alt update_all) could be added which would update all of the entries under the alternatives section of the config file.
Alternatively, if there was a command that listed all the current "names" in the config file a similar result could be achieved (with some additional scripting).
Thanks

File exists during link of paths using symlink mode

Not sure how much the symlink mode is used, but I'm encountering a couple problems with it. The most reproducible is this one:
Error: File exists during link of paths /home/user/music/beets/classical/William Walton; Royal Philharmonic Orchestra, André Previn/Symphony no. 1 _ Orb & Sceptre _ Crown Imperial/05 Crown Imperial.flac, /home/user/music/beets/classical-works/Walton, William/1937 - Crown Imperial/Royal Philharmonic Orchestra, André Previn/05 Crown Imperial.flac
As far as I can tell I think this happens when the source file has changed.

Here's my config section:

  works:
    directory: classical-works
    paths:
      default: "%ifdef{parent_composer_sort,$parent_composer_sort,%if{$composer_sort,$composer_sort,[No composer]}}/%ifdef{parentwork_date,$parentwork_date,[No date]} - %ifdef{parentwork,$parentwork,[No work]}/$parentwork_artist/$track $title"
    query: "genre:classical"
    formats: link

Symlink artwork in SymlinkViews?

As mentioned in #48 (comment), we could consider linking artwork in SymlinkViews, which would be interesting for users which do not employ the embedart plugin on their main library. Directly embedding the artwork ourselves (as the embed option does in the case of External collections) is not a sensible thing since it modifies the original files.

Every album re-copied on each update

I just started using this plugin, and the first time I ran beets alt update ipod after setting things up worked just fine. It took all night, as expected. However, after I added a new album to my library and then ran beets alt update ipod again, it first printed + lines with the new tracks. Then it appeared to print all of my tracks and it looks like it's also going to take hours. I'm guessing it's re-copying over some files each time, which defeats the purpose of this for me coming from using a simple rsync script.
Maybe I made a mistake at some point? Or maybe this is an interaction with the extrafiles plugin? Here's my config...

config.yaml
directory: /run/media/snead/icepack/music
library: ~/music/beets-library.db
original_date: yes
format_album: $albumartist - [$original_year/$year] $album
format_item: $artist - $album - $disc.$track. $title
sort_album: albumartist+ year+ album+
per_disc_numbering: yes
import:
  autotag: no
  copy: no
  timid: yes
  languages: en
  incremental: yes
  incremental_skip_later: yes
match:
  preferred:
    countries: ['US', 'GB|UK', 'JP']
    media: ['CD', 'DigitalMedia|File', 'Vinyl']
    original_year: yes
musicbrainz:
  extra_tags: [year]
paths:
  albumtype:soundtrack: Soundtracks/[$realyear] $album/%if{$multidisc,Disc %right{$disc,1}/}$track. $title
  comp: %first{$genre}/[$realyear] $album/%if{$multidisc,Disc %right{$disc,1}%if{$grouping,. $grouping}/}$track. $title
  albumtype:single: %the{$albumartist}/Singles/%if{$subartist,[$subartist]}[$realyear] $album/$track. $title
  default: %the{$albumartist}/[$realyear]%if{$subartist,[$subartist]} $album%ifdef{atypes, $atypes}/%if{$multidisc,Disc %right{$disc,1}%if{$grouping,. $grouping}/}$track. $title
item_fields:
  multidisc: 1 if disctotal > 1 else 0
  # MF Doom is something special, with all of his alternate names
  subartist: albumartist_credit if albumartist.lower() != albumartist_credit.lower() else ''
  realyear: original_year if original_year != 0 and original_year < year else year
plugins: the badfiles albumtypes missing rewrite fromfilename inline extrafiles fetchart alternatives convert duplicates
# Automatically resample all hi-fi FLACs down to CD quality on import
convert:
  auto: no
  embed: no
  max_bitrate: 1411
  never_convert_lossy_files: yes
  format: flac
  formats:
    flac: ffmpeg -y -i $source -acodec flac -af aresample=osf=s16:dither_method=triangular:resampler=soxr:out_sample_rate=44100 $dest
fetchart:
  auto: no
  cautious: yes
  cover_names: cover front folder album art
  minwidth: 1000
  enforce_ratio: 2%
  sources: filesystem coverart itunes
  deinterlace: yes
extrafiles:
  patterns:
    images: '*.(jpg|jpeg|png)'
albumtypes:
  types:
    - ep: 'EP'
    - single: 'Single'
    - live: 'Live'
    - compilation: 'Comp'
  ignore_va: compilation
  bracket: '()'
rewrite:
  albumartist DANGERDOOM: MF DOOM
  albumartist Viktor Vaughn: MF DOOM
  albumartist The Jimi Hendrix Experience: Jimi Hendrix
  albumartist Mychael Danna, DeVotchKa: DeVotchKa
  albumartist Adrian Orange: Thanksgiving
  albumartist The Velvet Underground & Nico: The Velvet Underground
  albumartist kidkanevil & Daisuke Tanabe: Daisuke Tanabe
  albumartist David Byrne & St. Vincent: David Byrne
  albumartist filous & Daði Freyr: Daði Freyr
  albumartist J\.U\.F: Gogol Bordello
  albumartist Gorillaz feat.*: Gorillaz
  albumartist Spacemonkeyz vs. Gorillaz: Gorillaz
  albumartist Justin Timberlake & .*: Justin Timberlake
  albumartist The Management: MGMT
  albumartist Urban Thermo Dynamics: Mos Def
  albumartist The Flaming Lips .*: The Flaming Lips
  albumartist Prince and The Revolution: Prince
alternatives:
  ipod:
    directory: /run/media/snead/SHELBY_S IP/music-beets
    query: "onplayer:true"
    removable: true
replace:
  '[\?]$': ''
  '[\\/]': "-"
  '^\.': _
  '<\|': ''
  '\|>': ''
  '[\x00-\x1f]': _
  ':': ';'
  '"': "'"
  '[<>\?\*\|]': _
  '\.$': ''
  '\s+$': ''
  '^\s+': ''
  '^-': _
  '': '-'
duplicates:
  album: yes
  keys: [albumartist, album, year]

Work-conserving behavior when multiple alternative collections overlap

A nice feature would be to avoid repeated transcoding if a version of file in proper format already exists in one of the alternative collections.

On update, the plugin could check if any of the to-be-transcoded files are supposed be present in any existing alternative locations (by intersecting the database queries). If the query yields something, try to copy these files from the guessed location. If the file is actually not there, fall back to transcoding.

Create m3u for newly imported tracks

First of all, thank you so much for this plugin. It has saved me countless hours in my music management!

One feature I think would make this even more useful would be functionality from the already existing "ImportFeeds" plugin: https://beets.readthedocs.io/en/stable/plugins/importfeeds.html

I use beets-alternatives to create a smaller version of my library to use with Rekordbox (DJ software). Rekordbox supports importing new tracks through a m3u file, XML file or drag&drop.

If beets-alternatives could create an m3u file containing absolute paths, each time you did "beet alt update myplayer", that would be amazing. There is probably other clients out there that can also utilize m3u files for importing new music. But I realize that this might be a limited use case. Thought I would propose it as a feature request anyway.

Again, thank you so much to everyone that has contributed to this plugin, (almost) literally a life saver for me.

Use relative symlinks

It would be nice to add an option to use relative symlinks instead of absolute ones (like when you have a server that won't work if you use absolute links)

`beet alt update foo`: FileNotFoundError

Hi there - I'm trying to solve this problem.

FYI, plex is my alternative collection that contains everything in my library.

I have tried running beet alt update othercollection which is a subset of my collection, and it works fine. So I suspect it's just one of the tracks in my collection that is causing the problem.

beet alt update plex
Traceback (most recent call last):
  File "/Users/patrick/Music/beets/beetsenv3/bin/beet", line 11, in <module>
    load_entry_point('beets==1.4.9', 'console_scripts', 'beet')()
  File "/Users/patrick/Music/beets/beetsenv3/lib/python3.8/site-packages/beets/ui/__init__.py", line 1266, in main
    _raw_main(args)
  File "/Users/patrick/Music/beets/beetsenv3/lib/python3.8/site-packages/beets/ui/__init__.py", line 1253, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/Users/patrick/Music/beets/beetsenv3/lib/python3.8/site-packages/beetsplug/alternatives.py", line 81, in func
    opts.func(lib, opts)
  File "/Users/patrick/Music/beets/beetsenv3/lib/python3.8/site-packages/beetsplug/alternatives.py", line 44, in update
    alt.update(create=options.create)
  File "/Users/patrick/Music/beets/beetsenv3/lib/python3.8/site-packages/beetsplug/alternatives.py", line 191, in update
    for (item, actions) in self.items_actions():
  File "/Users/patrick/Music/beets/beetsenv3/lib/python3.8/site-packages/beetsplug/alternatives.py", line 167, in items_actions
    yield self.matched_item_action(item)
  File "/Users/patrick/Music/beets/beetsenv3/lib/python3.8/site-packages/beetsplug/alternatives.py", line 145, in matched_item_action
    if (item_mtime_alt < os.path.getmtime(syspath(item.path))):
  File "/usr/local/bin/../../../Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/genericpath.py", line 55, in getmtime
    return os.stat(filename).st_mtime
FileNotFoundError: [Errno 2] No such file or directory: b'/var/folders/17/x5g8zxq558j5t6_9hvdph_xc0000gn/T/tmpj67sp7pf.flac'

Hard link untranscoded files when copied within filesystem

When copying files from the library to a new directory, within the same filesystem, the files should be hard linked rather than copied. This would take less time than copying and use less space, without any obvious downsides.

Use case:
I keep a lossy version of my library next to my regular library, for easy copying to other devices. Any songs that are lossless are transcoded but the lossy ones are copied over as is. Currently all lossy files end up taking up space in both directories.

Crashes when the destination file exists, but wasn't created by this plugin

As discussed in #48, beets-alternatives crashes with a traceback if for some reason (most likely a bug in the plugin itself, or maybe due to a crashed alt update which wasn't committed to the database) the destination file/link already exists, but wasn't created by the plugin itself. This came up in the review comment #48 (comment) with respect to SymlinkViews, but probably equally affects External and ExternalConvert collections. Possible paths forward:

  1. Keep everything as-is and crash, since this plugin always works under the assumption that the destination directory is exclusively managed by itself.
  2. Same as above, but log a warning instead and skip the affected item (or abort cleanly?). Minimum viable option IMO, any kind of crash has the potential to disrupt consistency between filesystem and beets' database.
  3. Same as above, but overwrite without asking.
  4. Query the user whether to replace the existing files. Probably not worth the effort and complexity in light of 1., see also @geigerzaehler's comments in the linked discussion in #48 (comment).

Failure on case insensitive filesystem when case changes

I see this error when using this plugin on a case-insensitive filesystem (fat32):

Error: file exists while renaming /media/NIKON D3300/Music/classical/Henri Dutilleux; Cyril Ciabaud, Kasia Tomczak-Feltrin, Mathieu Petit, Romain Robine, Orchestre National de Lille, Jean‐Claude Casadesus/Symphony no. 1 _ Métaboles _ Les Citations/01 Symphony no. 1_ I. Passacaille_ Andante.opus to /media/NIKON D3300/Music/classical/Henri Dutilleux; Cyril Ciabaud, Kasia Tomczak-Feltrin, Mathieu Petit, Romain Robine, Orchestre national de Lille, Jean‐Claude Casadesus/Symphony no. 1 _ Métaboles _ Les Citations/01 Symphony no. 1_ I. Passacaille_ Andante.opus

The N in Orchestre National de Lille changed to lowercase, and that seems to be what's causing this problem.

Enhancement: Embed artwork when converting formats.

My music library is mostly FLAC and I am using beets-alternatives to maintain a folder of songs in MP3 format for my iPhone/iPod. When beets-alternatives converts the songs to MP3, it would be nice if it embedded the album artwork at the same time. The 'embedart' plugin already exists, so maybe you can tie into that? Or this could already be possible and I am just missing it.

beet completion crashes with lastest git

When trying to run beet completion with the latest git of beets and beets-alternatives

beets-alternatives 0.10.0.r0.g5751eb7

beets version 1.5.0
Python version 3.7.4
plugins: absubmit, acousticbrainz, alternatives, artistcountry, badfiles, beatport, chroma, convert, discogs, duplicates, edit, embedart, export, fetchart, filefilter, fromfilename, ftintitle, fuzzy, hook, ihate, importfeeds, info, lastimport, lyrics, mbsubmit, mbsync, metasync, missing, playlist, random, replaygain, rewrite, smartplaylist, thumbnails, web

fails with

Traceback (most recent call last):
  File "/usr/bin/beet", line 11, in <module>
    load_entry_point('beets==1.5.0', 'console_scripts', 'beet')()
  File "/usr/lib/python3.7/site-packages/beets/ui/__init__.py", line 1267, in main
    _raw_main(args)
  File "/usr/lib/python3.7/site-packages/beets/ui/__init__.py", line 1254, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/usr/lib/python3.7/site-packages/beets/ui/commands.py", line 1707, in print_completion
    for line in completion_script(default_commands + plugins.commands()):
  File "/usr/lib/python3.7/site-packages/beets/ui/commands.py", line 1748, in completion_script
    for opts in cmd.parser._get_all_options()[1:]:
AttributeError: 'ArgumentParser' object has no attribute '_get_all_options'

full output

Archive Support

This is mentioned as being unimplemented in the readme. Firstly I thought it would be good to have a ticket to track it.

Secondly, I'm not sure when it would be useful. I'm trying to figure out if it's something that I might want to use for my collection or not. Could you describe what you're planning to do with it?

Beet alt raises AttributeError with Python 3.7

➜  beets-alternatives git:(master) beet alt                  
Traceback (most recent call last):
  File "/usr/bin/beet", line 11, in <module>
    load_entry_point('beets==1.4.9', 'console_scripts', 'beet')()
  File "/usr/lib/python3.7/site-packages/beets/ui/__init__.py", line 1266, in main
    _raw_main(args)
  File "/usr/lib/python3.7/site-packages/beets/ui/__init__.py", line 1253, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/home/davo/Documentos/beets-alternatives/beetsplug/alternatives.py", line 79, in func
    opts.func(lib, opts)
AttributeError: 'Namespace' object has no attribute 'func'

custom paths with inline plugin broken?

Hello! Some of my paths make use of the built in inline plugin (I'm guessing most people using beets use it) but beets-alternatives throws a NameError 'len' not defined which is kinda weird since it's a builtin function of python. This might of course be an inline issue but i know of no other plugins making use of it in the same way and so don't know how to test it.

Traceback (most recent call last):
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/inline.py", line 120, in _func_func
    return func()
  File "inline", line 3, in __INLINE_FUNC__
NameError: name 'len' is not defined

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/util/functemplate.py", line 574, in substitute
    res = self.compiled(values, functions)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/util/functemplate.py", line 598, in wrapper_func
    args[VARIABLE_PREFIX + varname] = values[varname]
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/library.py", line 428, in __getitem__
    value = self._get(key)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/library.py", line 416, in _get
    return self._get_formatted(self.album, key)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/dbcore/db.py", line 86, in _get_formatted
    value = model._type(key).format(model.get(key))
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/dbcore/db.py", line 371, in _get
    return getters[key](self)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/inline.py", line 122, in _func_func
    raise InlineError(python_code, exc)
beetsplug.inline.InlineError: error in inline path field code:
allowedLength = 64
if len(album)  > allowedLength:
    return album[0:allowedLength] + '...'
return album

NameError: name 'len' is not defined

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/inline.py", line 120, in _func_func
    return func()
  File "inline", line 3, in __INLINE_FUNC__
NameError: name 'len' is not defined

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/rainbowpants/.local/bin/beet", line 8, in <module>
    sys.exit(main())
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/ui/__init__.py", line 1285, in main
    _raw_main(args)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/ui/__init__.py", line 1272, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/alternatives.py", line 135, in func
    opts.func(lib, opts)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/alternatives.py", line 63, in update
    alt.update(create=options.create)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/alternatives.py", line 258, in update
    dest = self.destination(item)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/alternatives.py", line 365, in destination
    dest = super(ExternalConvert, self).destination(item)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/alternatives.py", line 290, in destination
    return item.destination(basedir=self.directory,
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/library.py", line 979, in destination
    subpath = self.evaluate_template(subpath_tmpl, True)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/dbcore/db.py", line 625, in evaluate_template
    return template.substitute(self.formatted(for_path=for_path),
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/util/functemplate.py", line 576, in substitute
    res = self.interpret(values, functions)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/util/functemplate.py", line 568, in interpret
    return self.expr.evaluate(Environment(values, functions))
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/util/functemplate.py", line 256, in evaluate
    out.append(part.evaluate(env))
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/util/functemplate.py", line 163, in evaluate
    if self.ident in env.values:
  File "/usr/lib/python3.8/_collections_abc.py", line 666, in __contains__
    self[key]
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/library.py", line 428, in __getitem__
    value = self._get(key)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/library.py", line 416, in _get
    return self._get_formatted(self.album, key)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/dbcore/db.py", line 86, in _get_formatted
    value = model._type(key).format(model.get(key))
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beets/dbcore/db.py", line 371, in _get
    return getters[key](self)
  File "/home/rainbowpants/.local/lib/python3.8/site-packages/beetsplug/inline.py", line 122, in _func_func
    raise InlineError(python_code, exc)
beetsplug.inline.InlineError: error in inline path field code:
allowedLength = 64
if len(album)  > allowedLength:
    return album[0:allowedLength] + '...'
return album

NameError: name 'len' is not defined```

ebmedart doesn't seem to work

What do I need to configure for convert and alternatives plugin to make my FLAC files in the alternative version embeded with art? As far as I understood the docs, it should be default. I've set embedart: yes in my convert config stanza but still my encoded alternative version mp3 files don't have coverart embeded.

  • My art is embeded in the original files
  • I don't have cover.ext image files lying around in my album folders. Could this be the problem?

Thanks and sorry for being brief. If you think it makes sense, I'll certainly deliver detailed logs, commands and so on.

Can't upgrade to 0.10.2 with pip

Hi!

This might be an error from my end, and I apologize if that is the case.

FreeNAS 11.3U5
Beets 1.4.9 installed in a jail running FreeBSD 11.4-RELEASE-p6
Python 3.7.9
Pip 21.0.1

I can't seem to upgrade beets-alternatives to 0.10.2 with pip. Here is the very very verbose output

root@beets2:~ # pip install -U -vvv beets-alternatives
Using pip 21.0.1 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)
Non-user install because site-packages writeable
Created temporary directory: /tmp/pip-ephem-wheel-cache-d_n86stt
Created temporary directory: /tmp/pip-req-tracker-230zzdea
Initialized build tracking at /tmp/pip-req-tracker-230zzdea
Created build tracker: /tmp/pip-req-tracker-230zzdea
Entered build tracker: /tmp/pip-req-tracker-230zzdea
Created temporary directory: /tmp/pip-install-15ghx5dk
Requirement already satisfied: beets-alternatives in /usr/local/lib/python3.7/site-packages (0.10.1)
1 location(s) to search for versions of beets-alternatives:
* https://pypi.org/simple/beets-alternatives/
Fetching project page and analyzing links: https://pypi.org/simple/beets-alternatives/
Getting page https://pypi.org/simple/beets-alternatives/
Found index url https://pypi.org/simple
Looking up "https://pypi.org/simple/beets-alternatives/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): pypi.org:443
https://pypi.org:443 "GET /simple/beets-alternatives/ HTTP/1.1" 304 0
  Found link https://files.pythonhosted.org/packages/79/42/78a5a24ea5792364412c901f973899c4a0f258113957ce0e4fbafa9ab8d7/beets-alternatives-0.9.0.tar.gz#sha256=73a0a03562a32ea274a419d707309d4410caeaf3c3e160357ca6f4101f7866a5 (from https://pypi.org/simple/beets-alternatives/), version: 0.9.0
  Found link https://files.pythonhosted.org/packages/0b/35/246e9858ff7908e4d7460b1ac5225dc46d8728c2e98b33afc1ecba3b590f/beets_alternatives-0.9.0-py3-none-any.whl#sha256=617c30b5a2416ddc21900c6a14390a8cb0cd4336abbf80e3a0be243d4c472aaa (from https://pypi.org/simple/beets-alternatives/), version: 0.9.0
  Found link https://files.pythonhosted.org/packages/db/3c/2529311291f9e04ae02a7bf1e6b93ed894ffacdf8dab4a32a2ed7b6062e1/beets-alternatives-0.10.0.tar.gz#sha256=7d74df4b3490b60ecfef76c8692123016e58d3e5b2fb158df0b174f69b000f52 (from https://pypi.org/simple/beets-alternatives/), version: 0.10.0
  Found link https://files.pythonhosted.org/packages/1a/30/89f2fab0e664fb7661e71f75fde8ced4ca53a1959897b5cd545e78799c92/beets_alternatives-0.10.0-py3-none-any.whl#sha256=ef984bccd287b900576bdaf15c62269a21dcef4cdeec2ea8609d3481db804b88 (from https://pypi.org/simple/beets-alternatives/), version: 0.10.0
  Found link https://files.pythonhosted.org/packages/89/f3/be33d66993502cdf17dc7397cb0d8c12d088bd8fd9043cad1381f4caacbe/beets-alternatives-0.10.1.tar.gz#sha256=45a5f777bfd75917162ab69a8153b9730f131c5699aaa30ce8f02190bf81dba7 (from https://pypi.org/simple/beets-alternatives/), version: 0.10.1
  Found link https://files.pythonhosted.org/packages/ac/b5/e11fc20c9798d6c43d3a081e313a4d1280f6a6accf408e1783d26ede4d30/beets_alternatives-0.10.1-py3-none-any.whl#sha256=3ce4b3ea19c49db08e842cfbbfb24143e1ef92ce8f9423d4689fc349fc354ee7 (from https://pypi.org/simple/beets-alternatives/), version: 0.10.1
  Found link https://files.pythonhosted.org/packages/de/07/59d101ce9f64095a62f98a736baeb1ab610196517a65a6530d228826d6a5/beets-alternatives-0.10.2.linux-x86_64.tar.gz#sha256=f6a5f8af380c875e30ee008ee6722cf16a3984d198d9f3ec2c4e95f161961eee (from https://pypi.org/simple/beets-alternatives/), version: 0.10.2.linux-x86_64
Given no hashes to check 6 links for project 'beets-alternatives': discarding no candidates
Requirement already satisfied: beets>=1.4.7 in /usr/local/lib/python3.7/site-packages (from beets-alternatives) (1.4.9)
Requirement already satisfied: six in /usr/local/lib/python3.7/site-packages (from beets-alternatives) (1.15.0)
Requirement already satisfied: mutagen>=1.33 in /usr/local/lib/python3.7/site-packages (from beets>=1.4.7->beets-alternatives) (1.42.0)
Requirement already satisfied: unidecode in /usr/local/lib/python3.7/site-packages (from beets>=1.4.7->beets-alternatives) (1.1.1)
Requirement already satisfied: musicbrainzngs>=0.4 in /usr/local/lib/python3.7/site-packages (from beets>=1.4.7->beets-alternatives) (0.7.1)  
Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/site-packages (from beets>=1.4.7->beets-alternatives) (5.3.1)
Requirement already satisfied: munkres>=1.0.0 in /usr/local/lib/python3.7/site-packages (from beets>=1.4.7->beets-alternatives) (1.0.12)      
Requirement already satisfied: jellyfish in /usr/local/lib/python3.7/site-packages (from beets>=1.4.7->beets-alternatives) (0.8.2)
Created temporary directory: /tmp/pip-unpack-xumn_hv7
Removed build tracker: '/tmp/pip-req-tracker-230zzdea'

Encoded files in alt are encoded again during `alt update`

When running alt update, files that have previously been encoded (by earlier alt update runs) seem to be re-encoded. For instance, I've already run an alt update that included this version of Loveless but every time I run I see this again:

convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/01 Only Shallow.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/02 Loomer.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/03 Touched.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/04 To Here Knows When.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/05 When You Sleep.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/06 I Only Said.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/07 Come in Alone.flac
convert: Finished encoding /my/beets/library/dir/My Bloody Valentine/Loveless/03 Touched.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/08 Sometimes.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/09 Blown a Wish.flac
convert: Finished encoding /my/beets/library/dir/My Bloody Valentine/Loveless/02 Loomer.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/10 What You Want.flac
convert: Finished encoding /my/beets/library/dir/My Bloody Valentine/Loveless/07 Come in Alone.flac
convert: Encoding /my/beets/library/dir/My Bloody Valentine/Loveless/11 Soon.flac
convert: Finished encoding /my/beets/library/dir/My Bloody Valentine/Loveless/01 Only Shallow.flac
convert: Finished encoding /my/beets/library/dir/My Bloody Valentine/Loveless/05 When You Sleep.flac
convert: Finished encoding /my/beets/library/dir/My Bloody Valentine/Loveless/09 Blown a Wish.flac

I have a alt setup to convert to lossy formats from my lossless ones for my phone, and it seem to slow down and run through this encode step for every lossless track which means the process gets slower and slower every time I add an album in FLAC.

My config looks like this:

directory: /my/beets/library/dir/
library: /my/beets/library/dir/beet-library.db
plugins: convert alternatives copyartifacts
convert:
  copy_album_art: yes
  never_convert_lossy_files: yes
  formats:
    cd:
      command: ffmpeg -i $source -y -vn -sample_fmt s16 -ar 44100 $dest
      extension: flac
    mobile:
      command: ffmpeg -i $source -y -vn -ab 320k -ar 44100 $dest
      extension: mp3
alternatives:
  cloudplayer:
    directory: /my/alt/library/dir
    formats: mobile AAC aac mp3
    query: ""
    removable: true
copyartifacts:
    extensions: .pdf .jpg .png
    print_ignored: yes

Respect convert's threads config

The Convert plugin has a threads setting:

https://beets.readthedocs.io/en/latest/plugins/convert.html#configuration

But I find no evidence that this config is respected, either when using beets-alternatives or in its source code.

I notice class Worker has a max_workers param in the init. But I don't see max_workers used anywhere.

class Worker(futures.ThreadPoolExecutor):

def __init__(self, fn, max_workers=None):

I love the plugin, it's almost exactly what I want.

Update performance for SymlinkViews

Check where the performance bottleneck is for updating SymlinkViews, cf. #48 (comment). Since this requires only accesses to filesystem metadata and two columns in the database (path and beets-alternatives path_key), it should be fairly fast (on SSDs at least).

Undo installation?

Beets was working fine, but since I ran pip install git+git://github.com/geigerzaehler/beets-alternatives.git@master, it now gives me the following error:

   File "/usr/local/bin/beet", line 9, in <module>
    load_entry_point('beets==1.3.19', 'console_scripts', 'beet')()
  File "/usr/lib/python3/dist-packages/pkg_resources.py", line 351, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python3/dist-packages/pkg_resources.py", line 2363, in load_entry_point
    return ep.load()
  File "/usr/lib/python3/dist-packages/pkg_resources.py", line 2088, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__'])
  File "/usr/local/lib/python3.4/dist-packages/beets/ui/__init__.py", line 36, in <module>
    from beets import library
  File "/usr/local/lib/python3.4/dist-packages/beets/library.py", line 28, in <module>
    from beets.mediafile import MediaFile, MutagenError, UnreadableFileError
  File "/usr/local/lib/python3.4/dist-packages/beets/mediafile.py", line 380, in <module>
    class StorageStyle(object):
  File "/usr/local/lib/python3.4/dist-packages/beets/mediafile.py", line 410, in StorageStyle
    def __init__(self, key, as_type=unicode, suffix=None, float_places=2):

Any idea how I might get beets working again (with or without alternatives)?

Disable album art embedding

This issue is follow-up for a question raised in #58.

I said:

I'm confused by the implementation of sync_art / embed. From reading the code it seems that album art is embedded even if convert.embed is set to false. More specifically, I think SYNC_ART is set independent of the configuration option.

@geigerzaehler answered:

Yes, you’re right. Do you expect covert.embed to control that behavior (even though it configures a different plugin)? Do we need our own configuration setting for this? Feel free to discuss this in an issue.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/workflows/main.yaml
  • actions/checkout v4
  • actions/setup-python v5
  • coverallsapp/github-action v2
  • actions/checkout v4
  • actions/setup-python v5
pep621
pyproject.toml
poetry
pyproject.toml
  • python ^3.8.1
  • beets >=1.6.0 <3
  • confuse ^2.0.1
  • coverage ^7.4.4
  • mediafile ^0.12.0
  • mock ^5.0.2
  • pyright ^1.1.340
  • pytest ^8.0.2
  • pytest-cov ^5.0.0
  • ruff ^0.5.0
  • typeguard ^4.1.5
  • typing-extensions ^4.9.0

  • Check this box to trigger a request for Renovate to run again on this repository

Copy album art to destination folder (without embedding)

Convert supports copying album art:

https://github.com/beetbox/beets/blob/1b187fbf5345727e0dfdaea958a714f19e917a4e/beetsplug/convert.py#L373

The function is called when a config is set for convert: copy_album_art. But this plugin only does embedding: it only references art.embed_item.

https://github.com/beetbox/beets/blob/d778a5236ba163844f20bf5f499a1773ddd7bb91/beets/art.py#L53

(Sorry for making more issues; I hope I'm not misinterpreting the goals of this plugin).

beet alt ballons memory, may lead to OOM

Using beets-alternavives. I Installed it within docker container. I'm deploying it using docker-compose with hard limits for usage:

    deploy:
      resources:
        limits:
          # Adjust as needed
          cpus: '0.5'
          memory: '2048M'

I've discovered that running command may lead to OOM condition.
Here's part from inside of container when ran from interactive shell:

/src # beet alt 

usage: beet alt [-h] {update,list-tracks} ...
beet alt: error: the following arguments are required: {update,list-tracks}
/src # 
/src # beet alt uptade mp3-mirror
usage: beet alt [-h] {update,list-tracks} ...
beet alt: error: argument {update,list-tracks}: invalid choice: 'uptade' (choose from 'update', 'list-tracks')
/src # beet alt update mp3-mirror
     
Killed
/src # 
/src # 

Note: "Killed" occured automatically. I didn't do that manually.

This is confirmed from my Grafana output:

obraz

Support replacements on alternates

This can be used to support making an alternate for placing on a restricted filesystem (such as FAT) while leaving the main library intact. Basically, this is a request to support the top-level replace configuration in an alternate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.