lyrics: Crash when BeautifulSoup is not installed
See original GitHub issueProblem
The Lyrics plugin throws an error/crashes when ran without BeautifulSoup installed.
Terminal output
I currently can’t run a verbose command because Beets is dragging itself through finding lyrics for many many albums.
The following error is displayed in Terminal when running:
$ beets lyrics artist song
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/util/confit.py:21: UserWarning: beets.util.confit is deprecated; use confuse instead
warnings.warn("beets.util.confit is deprecated; use confuse instead")
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/bin/beet", line 11, in <module>
load_entry_point('beets==1.5.0', 'console_scripts', 'beet')()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1291, in main
_raw_main(args)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1274, in _raw_main
subcommands, plugins, lib = _setup(options, lib)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1153, in _setup
plugins = _load_plugins(options, config)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1139, in _load_plugins
plugins.send("pluginload")
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/plugins.py", line 497, in send
for handler in event_handlers()[event]:
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/plugins.py", line 480, in event_handlers
for plugin in find_plugins():
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/plugins.py", line 315, in find_plugins
_instances[cls] = cls()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beetsplug/lyrics.py", line 736, in __init__
sources = self.sanitize_bs_sources(sources)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beetsplug/lyrics.py", line 763, in sanitize_bs_sources
if source.REQUIRES_BS:
AttributeError: 'str' object has no attribute 'REQUIRES_BS'
After installing BeautifulSoup the output is
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/util/confit.py:21: UserWarning: beets.util.confit is deprecated; use confuse instead
warnings.warn("beets.util.confit is deprecated; use confuse instead")
Andrew writes:
We’re supposed to silently fix up the configuration when BeautifulSoup is not installed; not crash with a traceback. Glancing at the code, I do see the mistake.
Setup
- OS: macOS 10.13.6
- Python version: 3.7
- beets version: 1.5
- Turning off plugins made problem go away (yes/no):
My configuration (output of beet config
) is:
library: ~/Music/Beets/musiclibrary.db
directory: /Volumes/Tunez
import:
write: yes
copy: yes
move: no
link: no
hardlink: no
delete: no
resume: ask
incremental: no
incremental_skip_later: no
from_scratch: no
quiet_fallback: skip
none_rec_action: ask
timid: no
log:
autotag: yes
quiet: no
singletons: no
default_action: apply
languages: []
detail: no
flat: no
group_albums: no
pretend: false
search_ids: []
duplicate_action: remove
bell: no
set_fields: {}
clutter: ["Thumbs.DB", ".DS_Store"]
ignore: [".*", "*~", "System Volume Information", "lost+found"]
ignore_hidden: yes
replace:
'[\\/]': _
'^\.': _
'[\x00-\x1f]': _
'[<>:"\?\*\|]': ''
'\.$': _
'\s+$': ''
'^\s+': ''
'^-': _
path_sep_replace: _
asciify_paths: false
art_filename: cover
max_filename_length: 0
aunique:
keys: albumartist album
disambiguators: albumtype year samplerate label catalognum albumdisambig releasegroupdisambig
bracket: '()'
plugins:
- inline
- the
- lastgenre
- discogs
- chroma
- acousticbrainz
- fromfilename
- fetchart
- embedart
- ftintitle
- edit
- info
- missing
- types
- convert
- plexupdate
- web
- unimported
- keyfinder
- fuzzy
- spotify
- describe
- bpmanalyser
- lyrics
# - smartplaylist
# - goingrunning
pluginpath:
- /Users/xxxxxxxx/Documents/BeetsPluginDescribe/beetsplug
threaded: yes
timeout: 5.0
per_disc_numbering: no
verbose: 0
terminal_encoding:
original_date: no
artist_credit: no
id3v23: no
va_name: "Various Artists"
zero:
fields: comments
update_database: true
# Inline plugin template
item_fields:
multidisc: 1 if disctotal > 1 else 0
my_samplerate: round(samplerate / 1000)
is_flac: 1 if format == "FLAC" else 0
album_fields:
format: |
formatList = []
for item in items:
formatList.append(item.format)
return formatList
av_bitrate: |
total = 0
for item in items:
total += item.bitrate
return round(total / len(items) / 1000)
album_bitdepth: |
total = 0
for item in items:
total += item.bitdepth
return round(total / len(items))
album_samplerate: |
total = 0
for item in items:
total += item.samplerate
return round(total / len(items) / 1000)
is_1644: |
bd = 0
sr = 0
br = 0
for item in items:
bd += item.bitdepth
sr += item.samplerate
br += item.bitrate
bd = round(bd / len(items))
sr = round(sr / len(items) / 1000)
br = round(br / len(items) / 1000)
return 1 if bd == 16 and sr == 44 and br > 320 else 0
ui:
terminal_width: 80
length_diff_thresh: 10.0
color: yes
colors:
text_success: green
text_warning: yellow
text_error: red
text_highlight: red
text_highlight_minor: lightgray
action_default: turquoise
action: blue
format_item: $artist - $album - $title
format_album: $albumartist - $album
time_format: '%Y-%m-%d %H:%M:%S'
format_raw_length: no
sort_album: albumartist+ album+
sort_item: artist+ album+ disc+ track+
sort_case_insensitive: yes
paths:
# default: 'Albums/%the{$albumartist}/$album (%if{$original_year,$original_year}) %aunique{albumartist album year, albumdisambig}%if{$albumdisambig,($albumdisambig $year) }%if{$is_1644,,%if{$is_flac,($format $bitdepth-$album_samplerate),($format $av_bitrate)}}/%if{$multidisc,$disc-}$track - $title'
default: 'Albums/%the{$albumartist}/%if{$original_year,$original_year} - $album %aunique{albumartist album year, albumdisambig}%if{$albumdisambig,($albumdisambig $year) }%if{$is_1644,,%if{$is_flac,($format $album_bitdepth-$album_samplerate),($format $av_bitrate)}}/%if{$multidisc,$disc-}$track - $title'
dancetrack:1: 'Singles Dance/$artist - $title (%if{$original_year,$original_year}) %aunique{albumartist album year, albumtype label catalognum albumdisambig}%if{$albumdisambig,($albumdisambig$ $year)}($bpm bpm)'
artistsingles:1: 'Albums/%the{$albumartist}/$album/$title'
custcomp:1: 'Compilations/$album/$track - $artist - $title'
custcompmin:1: 'Compilations/$album/$artist - $title'
singleton: 'Singles/$artist - $title %aunique{albumartist album year, albumtype label catalognum albumdisambig}%if{$albumdisambig,($albumdisambig$ $year)}'
comp: 'Albums/%the{$albumartist}/$album (%if{$original_year,$original_year}) %aunique{albumartist album year, albumtype label catalognum albumdisambig}%if{$albumdisambig,($albumdisambig $year) }%if{$is_1644,,%if{$is_flac,($format $bitdepth-$album_samplerate),($format $av_bitrate)}}/%if{$multidisc,$disc-}$track - $artist - $title'
statefile: state.pickle
musicbrainz:
host: musicbrainz.org
ratelimit: 1
ratelimit_interval: 1.0
searchlimit: 5
match:
strong_rec_thresh: 0.04
medium_rec_thresh: 0.25
rec_gap_thresh: 0.25
max_rec:
missing_tracks: medium
unmatched_tracks: medium
distance_weights:
source: 2.0
artist: 3.0
album: 3.0
media: 1.0
mediums: 1.0
year: 1.0
country: 0.5
label: 0.5
catalognum: 0.5
albumdisambig: 0.5
album_id: 5.0
tracks: 2.0
missing_tracks: 0.9
unmatched_tracks: 0.6
track_title: 3.0
track_artist: 2.0
track_index: 1.0
track_length: 2.0
track_id: 5.0
preferred:
countries: []
media: ['Digital Media|File' , 'CD']
original_year: no
ignored: []
required: []
ignored_media: []
ignore_data_tracks: yes
ignore_video_tracks: yes
track_length_grace: 10
track_length_max: 30
chroma:
auto: no
fetchart:
auto: yes
cautious: no
cover_names: cover front art album folder
minwidth: 290
maxwidth: 1050
sources: itunes amazon albumart lastfm fanart filesystem coverart
fanarttv_key: xxxxxxxxxxxxx
lastfm_key: xxxxxxxxxxxx
acoustid:
apikey: xxxxxxxxx
embedart:
auto: yes
ifempty: no
lastgenre:
auto: yes
canonical: no
count: 1
force: yes
source: album
whitelist: yes
min_weight: 10
fallback:
separator: ', '
prefer_specific: no
types:
av_bitrate: int
my_samplerate: int
bitdepth: int
album_bitdepth: int
album_samplerate: int
rating: int
convert:
dest: ~/Music/BeetExports
command: ffmpeg -i $source -y -vn -aq 0 $dest
extension: mp3
format: mp3
never_convert_lossy_files: yes
plex:
host: localhost
port: 32400
token: xxxxxxxxxxxxxx
lastfm:
user: xxxxxxxxxx
smartplaylist:
playlist_dir: /Users/Shared/Music/Playlists
auto: no
playlists:
- name: 'favorites.m3u'
query: rating:4..5
- name: 'danceable.m3u'
query:
- danceable:0.8..
- name: 'acoustic.m3u'
query:
- mood_acoustic:0.8..
- name: 'aggresive.m3u'
query:
- mood_aggresive:0.8..
- name: 'electronic.m3u'
query:
- mood_electronic:0.8..
- name: 'danceable.m3u'
query:
- danceable:0.8..
- name: 'happy.m3u'
query:
- mood_happy:0.8..
- name: 'party.m3u'
query:
- mood_party:0.8..
- name: 'relaxed.m3u'
query:
- mood_relaxed:0.8..
- name: 'sad.m3u'
query:
- mood_sad:0.8..
spotify:
mode: list
show_failures: on
tiebreak: first
bpmanalyser:
auto: no
dry-run: no
write: yes
force: no
quiet: no
goingrunning:
targets:
subsonic_m3u:
device_root: /Users/Shared/Music/Playlists
device_path:
clean_target: yes
generate_playlist: yes
copy_files: no
trainings:
10K:
use_flavours: [intensity_low, intensity_high, running]
duration: 180
target: subsonic_m3u
flavours:
intensity_low:
bpm: 87..88
intensity_high:
bpm: 175..177
running:
genre: [electronic, hip hop, funk, trip hop, house]
web:
host: 0.0.0.0
cors: 'http://localhost:3000'
lyrics:
auto: yes
google_API_key: xxxxxxxxxxxxxxxxx
google_engine_ID: 009217259823014548361:lndtuqkycfu
unimported:
ignore_extensions: mid wav
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:5 (4 by maintainers)
Top Results From Across the Web
Beautiful Soup crashes Python process - Stack Overflow
My Python process that processes multiple pages on one website crashes on the line: soup = BeautifulSoup(cleaned_html, "lxml").
Read more >Beautiful Soup Tutorial - Web Scraping in Python - YouTube
The Beautiful Soup module is used for web scraping in Python. Learn how to use the Beautiful Soup and Requests modules in this...
Read more >How to Build a Web Scraping Pipeline Using BeautifulSoup
Create a web scraping pipeline in Python; Navigate and parse HTML code; Use Beautiful Soup and Requests to fetch and extract data from...
Read more >Changelog — beets 1.6.0 documentation - Read the Docs
Lyrics Plugin: The plugin no longer crashes in the Genius source when BeautifulSoup is not found. Instead, it just logs a message and...
Read more >Web-scraping with Beautiful Soup - DAsH - O'Malley Library
Some sites block you from web-scraping, but most do not. ... Beautiful Soup: Installation and Basics; Identifying Target Data with Developer ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The FAQ has instructions: https://beets.readthedocs.io/en/stable/faq.html#run-the-latest-source-version-of-beets
@sampsyo Side question about that: I notice the docs don’t mention the pattern:
to install beets from source in editable mode. Should we add it? The advantage is that you can then hack on your beets working copy, and the changes are immediately reflected in your environment without needing to run
python setup.py install
every time. This is how I’ve been developing my beets plugins, and I find it very convenient. Or is there some downside topip install -e
that I don’t know (I’m not super expert at python)?Edit: Reading more carefully, I see that
pip install -e
is the third option listed… but using the “automatic source checkout” approach. So I guess the distinction here is merely whether you clone it manually yourself, and therefore get to decide where the sources go? *shrug*Edit 2: I filed #4084 suggesting an addition to the FAQ about
pip install -e .
. Please feel free to close if it’s not to your liking.