Skip to content

Commit c556989

Browse files
committed
Merge remote-tracking branch 'upstream/master' into trunc_artist
2 parents 3051ccb + 8720d64 commit c556989

26 files changed

+422
-97
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
repos:
55
- repo: https://github.com/psf/black
6-
rev: 23.11.0
6+
rev: 24.2.0
77
hooks:
88
- id: black
99

1010
- repo: https://github.com/pycqa/isort
11-
rev: 5.12.0
11+
rev: 5.13.2
1212
hooks:
1313
- id: isort
1414
name: isort (python)

beets/dbcore/query.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ class NamedQuery(Query):
122122
"""
123123

124124
@abstractmethod
125-
def __init__(self, pattern):
126-
...
125+
def __init__(self, pattern): ...
127126

128127

129128
P = TypeVar("P")

beets/dbcore/types.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ class ModelType(typing.Protocol):
3535
given type.
3636
"""
3737

38-
def __init__(self, value: Any = None):
39-
...
38+
def __init__(self, value: Any = None): ...
4039

4140
else:
4241
# No structural subtyping in Python < 3.8...

beets/ui/commands.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,14 @@ def get_singleton_disambig_fields(info: hooks.TrackInfo) -> Sequence[str]:
216216
calculated_values = {
217217
"index": "Index {}".format(str(info.index)),
218218
"track_alt": "Track {}".format(info.track_alt),
219-
"album": "[{}]".format(info.album)
220-
if (
221-
config["import"]["singleton_album_disambig"].get()
222-
and info.get("album")
223-
)
224-
else "",
219+
"album": (
220+
"[{}]".format(info.album)
221+
if (
222+
config["import"]["singleton_album_disambig"].get()
223+
and info.get("album")
224+
)
225+
else ""
226+
),
225227
}
226228

227229
for field in chosen_fields:
@@ -240,9 +242,11 @@ def get_album_disambig_fields(info: hooks.AlbumInfo) -> Sequence[str]:
240242
out = []
241243
chosen_fields = config["match"]["album_disambig_fields"].as_str_seq()
242244
calculated_values = {
243-
"media": "{}x{}".format(info.mediums, info.media)
244-
if (info.mediums and info.mediums > 1)
245-
else info.media,
245+
"media": (
246+
"{}x{}".format(info.mediums, info.media)
247+
if (info.mediums and info.mediums > 1)
248+
else info.media
249+
),
246250
}
247251

248252
for field in chosen_fields:
@@ -1160,9 +1164,11 @@ def resolve_duplicate(self, task, found_duplicates):
11601164
print_(
11611165
"Old: "
11621166
+ summarize_items(
1163-
list(duplicate.items())
1164-
if task.is_album
1165-
else [duplicate],
1167+
(
1168+
list(duplicate.items())
1169+
if task.is_album
1170+
else [duplicate]
1171+
),
11661172
not task.is_album,
11671173
)
11681174
)

beets/util/functemplate.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,6 @@ def __init__(self, values, functions):
5858
# Code generation helpers.
5959

6060

61-
def ex_lvalue(name):
62-
"""A variable load expression."""
63-
return ast.Name(name, ast.Store())
64-
65-
6661
def ex_rvalue(name):
6762
"""A variable store expression."""
6863
return ast.Name(name, ast.Load())
@@ -75,15 +70,6 @@ def ex_literal(val):
7570
return ast.Constant(val)
7671

7772

78-
def ex_varassign(name, expr):
79-
"""Assign an expression into a single variable. The expression may
80-
either be an `ast.expr` object or a value to be used as a literal.
81-
"""
82-
if not isinstance(expr, ast.expr):
83-
expr = ex_literal(expr)
84-
return ast.Assign([ex_lvalue(name)], expr)
85-
86-
8773
def ex_call(func, args):
8874
"""A function-call expression with only positional parameters. The
8975
function may be an expression or the name of a function. Each

beetsplug/advancedrewrite.py

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,22 @@
2727
from beets.ui import UserError
2828

2929

30-
def simple_rewriter(field, rules):
30+
def rewriter(field, simple_rules, advanced_rules):
3131
"""Template field function factory.
3232
3333
Create a template field function that rewrites the given field
3434
with the given rewriting rules.
35-
``rules`` must be a list of (pattern, replacement) pairs.
35+
``simple_rules`` must be a list of (pattern, replacement) pairs.
36+
``advanced_rules`` must be a list of (query, replacement) pairs.
3637
"""
3738

3839
def fieldfunc(item):
3940
value = item._values_fixed[field]
40-
for pattern, replacement in rules:
41+
for pattern, replacement in simple_rules:
4142
if pattern.match(value.lower()):
4243
# Rewrite activated.
4344
return replacement
44-
# Not activated; return original value.
45-
return value
46-
47-
return fieldfunc
48-
49-
50-
def advanced_rewriter(field, rules):
51-
"""Template field function factory.
52-
53-
Create a template field function that rewrites the given field
54-
with the given rewriting rules.
55-
``rules`` must be a list of (query, replacement) pairs.
56-
"""
57-
58-
def fieldfunc(item):
59-
value = item._values_fixed[field]
60-
for query, replacement in rules:
45+
for query, replacement in advanced_rules:
6146
if query.match(item):
6247
# Rewrite activated.
6348
return replacement
@@ -97,8 +82,12 @@ def __init__(self):
9782
}
9883

9984
# Gather all the rewrite rules for each field.
100-
simple_rules = defaultdict(list)
101-
advanced_rules = defaultdict(list)
85+
class RulesContainer:
86+
def __init__(self):
87+
self.simple = []
88+
self.advanced = []
89+
90+
rules = defaultdict(RulesContainer)
10291
for rule in self.config.get(template):
10392
if "match" not in rule:
10493
# Simple syntax
@@ -124,12 +113,12 @@ def __init__(self):
124113
f"for field {fieldname}"
125114
)
126115
pattern = re.compile(pattern.lower())
127-
simple_rules[fieldname].append((pattern, value))
116+
rules[fieldname].simple.append((pattern, value))
128117

129118
# Apply the same rewrite to the corresponding album field.
130119
if fieldname in corresponding_album_fields:
131120
album_fieldname = corresponding_album_fields[fieldname]
132-
simple_rules[album_fieldname].append((pattern, value))
121+
rules[album_fieldname].simple.append((pattern, value))
133122
else:
134123
# Advanced syntax
135124
match = rule["match"]
@@ -168,24 +157,18 @@ def __init__(self):
168157
f"for field {fieldname}"
169158
)
170159

171-
advanced_rules[fieldname].append((query, replacement))
160+
rules[fieldname].advanced.append((query, replacement))
172161

173162
# Apply the same rewrite to the corresponding album field.
174163
if fieldname in corresponding_album_fields:
175164
album_fieldname = corresponding_album_fields[fieldname]
176-
advanced_rules[album_fieldname].append(
165+
rules[album_fieldname].advanced.append(
177166
(query, replacement)
178167
)
179168

180169
# Replace each template field with the new rewriter function.
181-
for fieldname, fieldrules in simple_rules.items():
182-
getter = simple_rewriter(fieldname, fieldrules)
183-
self.template_fields[fieldname] = getter
184-
if fieldname in Album._fields:
185-
self.album_template_fields[fieldname] = getter
186-
187-
for fieldname, fieldrules in advanced_rules.items():
188-
getter = advanced_rewriter(fieldname, fieldrules)
170+
for fieldname, fieldrules in rules.items():
171+
getter = rewriter(fieldname, fieldrules.simple, fieldrules.advanced)
189172
self.template_fields[fieldname] = getter
190173
if fieldname in Album._fields:
191174
self.album_template_fields[fieldname] = getter

beetsplug/export.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def __init__(self):
7474
"xml": {
7575
# XML module formatting options.
7676
"formatting": {}
77-
}
77+
},
7878
# TODO: Use something like the edit plugin
7979
# 'item_fields': []
8080
}

beetsplug/lastimport.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,20 @@ def process_tracks(lib, tracks, log):
204204

205205
for num in range(0, total):
206206
song = None
207-
trackid = tracks[num]["mbid"].strip()
208-
artist = tracks[num]["artist"].get("name", "").strip()
209-
title = tracks[num]["name"].strip()
207+
trackid = tracks[num]["mbid"].strip() if tracks[num]["mbid"] else None
208+
artist = (
209+
tracks[num]["artist"].get("name", "").strip()
210+
if tracks[num]["artist"].get("name", "")
211+
else None
212+
)
213+
title = tracks[num]["name"].strip() if tracks[num]["name"] else None
210214
album = ""
211215
if "album" in tracks[num]:
212-
album = tracks[num]["album"].get("name", "").strip()
216+
album = (
217+
tracks[num]["album"].get("name", "").strip()
218+
if tracks[num]["album"]
219+
else None
220+
)
213221

214222
log.debug("query: {0} - {1} ({2})", artist, title, album)
215223

@@ -219,6 +227,19 @@ def process_tracks(lib, tracks, log):
219227
dbcore.query.MatchQuery("mb_trackid", trackid)
220228
).get()
221229

230+
# If not, try just album/title
231+
if song is None:
232+
log.debug(
233+
"no album match, trying by album/title: {0} - {1}", album, title
234+
)
235+
query = dbcore.AndQuery(
236+
[
237+
dbcore.query.SubstringQuery("album", album),
238+
dbcore.query.SubstringQuery("title", title),
239+
]
240+
)
241+
song = lib.items(query).get()
242+
222243
# If not, try just artist/title
223244
if song is None:
224245
log.debug("no album match, trying by artist/title")
@@ -244,7 +265,7 @@ def process_tracks(lib, tracks, log):
244265

245266
if song is not None:
246267
count = int(song.get("play_count", 0))
247-
new_count = int(tracks[num]["playcount"])
268+
new_count = int(tracks[num].get("playcount", 1))
248269
log.debug(
249270
"match: {0} - {1} ({2}) " "updating: play_count {3} => {4}",
250271
song.artist,

0 commit comments

Comments
 (0)