In the fetch_text method (line ~207):
if not r.encoding:
r.encoding = "utf-8" # ← Double quotes!
In the scrape method, make sure there are 2 blank lines before the next class:
return None
class Tekstowo(SearchBackend): # ← Two blank lines above
That should pass the formatting check! The repo follows PEP 8 style (double quotes, 2 blank lines between classes).
## Key Improvements (addressing reviewer feedback):
- ✅ Uses regex instead of while loop (more efficient, one pass)
- ✅ No infinite loop risk
- ✅ Handles any number of backslashes before quotes
- ✅ Clear inline comments
## Problem
The lyrics plugin has two bugs that corrupt fetched lyrics:
1. **Unicode corruption**: Characters like `ò`, `è`, `à` are corrupted to `√≤`, `√®`, etc.
2. **Escaped quotes**: Quotes appear as `\"` instead of `"` in lyrics
## Root Causes
### Issue 1: MacRoman encoding misdetection
- **Location**: `RequestHandler.fetch_text()` line 220
- **Cause**: Setting `r.encoding = None` forces requests to use `apparent_encoding`
- **Problem**: For Genius.com (and others), requests incorrectly detects MacRoman instead of UTF-8
- **Result**: UTF-8 bytes `c3 b2` (ò) decoded as MacRoman produces "√≤" (U+221A U+2264)
### Issue 2: Incomplete JSON unescape
- **Location**: `Genius.scrape()` line 576
- **Cause**: The `remove_backslash` regex doesn't handle all escape patterns in JSON
- **Problem**: Genius embeds lyrics in JSON with patterns like `\\"` and `\\\\"`
- **Result**: After BeautifulSoup processing, escaped quotes remain in final text
## Solution
### Fix 1: Trust server encoding, fallback to UTF-8
```python
# OLD: r.encoding = None
# NEW:
if not r.encoding:
r.encoding = 'utf-8'
```
- Respects server's declared encoding (UTF-8 for Genius)
- Falls back to UTF-8 if no encoding specified (safer than apparent_encoding)
- Preserves original intent of handling misconfigured servers
### Fix 2: Iteratively clean escaped quotes
```python
while '\\"' in lyrics:
lyrics = lyrics.replace('\\"', '"')
```
- Handles variable escape levels (`\"`, `\\\"`, `\\\\\"`)
- Minimal change - keeps original `remove_backslash` regex
- Applied after BeautifulSoup to avoid interfering with HTML parsing
## Testing
Tested with:
- Caparezza - "Argenti Vive" (Italian, many accented characters)
- WestsideGunn - "Heel Cena" (escaped quotes in lyrics)
Before:
```
mi si parò davanti
\\"I got big moves\\"
```
After:
```
mi si parò davanti
"I got big moves"
```
## Impact
- Fixes lyrics for all languages with non-ASCII characters
- Fixes Genius lyrics with quotes
- No breaking changes - maintains backward compatibility
- Minimal code changes (14 lines total)
See this line in https://musicbrainz.org/doc/MusicBrainz_API#Lookups
> To include more than one subquery in a single request, separate the arguments to inc= with a + (plus sign), like inc=recordings+labels.
Introduce a new RequestHandler base class to introduce a shared session,
centralize HTTP request management and error handling across plugins.
Key changes:
- Add RequestHandler base class with a shared/cached session
- Convert TimeoutSession to use SingletonMeta for proper resource
management
- Create LyricsRequestHandler subclass with lyrics-specific error
handling
- Update MusicBrainzAPI to inherit from RequestHandler
## Description
Fixes#5625
When `convert.never_convert_lossy_files` is enabled, `beet convert` was
ignoring the explicit `--format` option and just copying the lossy files
without
transcoding them. For example:
- `beet convert format:mp3 --format opus`
would still produce MP3 files instead of OPUS.
Change:
- Allows to override options `never_convert_lossy_files`, `max_bitrate`
or `no_convert` for `beet convert` as well as trying to convert to the
same format as existing already with a new option `--force`. That way,
for example lossy files selected by the query are transcoded to the
requested format anyway.
- Keeps existing behavior for automatic conversion on import (no CLI
override there).
- Adds tests to cover checking whether `--force` correctly overrides
settings or CLI options.
- Documents the behavior in the convert plugin docs
Co-authored-by: J0J0 Todos <jojo@peek-a-boo.at>