-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Format length as M:SS by default #1749
Changes from 4 commits
67eb0ed
8d2fda7
62ee915
cca307c
0e64275
4afdbdf
a5ecc77
2f2cdd2
25cb556
3e2d247
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -195,6 +195,29 @@ def normalize(self, key): | |
return self.parse(key) | ||
|
||
|
||
class DurationType(types.Float): | ||
"""Human-friendly (M:SS) representation of a time interval.""" | ||
query = dbcore.query.DurationQuery | ||
|
||
def format(self, value): | ||
# TODO: decide if documenting format_raw_length | ||
if not beets.config['format_raw_length'].get(bool): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, |
||
return beets.ui.human_seconds_short(value or 0.0) | ||
else: | ||
return value | ||
|
||
def parse(self, string): | ||
try: | ||
# Try to format back hh:ss to seconds. | ||
return beets.ui.raw_seconds_short(string) | ||
except ValueError: | ||
# Fall back to a plain float.. | ||
try: | ||
return float(string) | ||
except ValueError: | ||
return self.null | ||
|
||
|
||
# Library-specific sort types. | ||
|
||
class SmartArtistSort(dbcore.query.Sort): | ||
|
@@ -426,7 +449,7 @@ class Item(LibModel): | |
'original_day': types.PaddedInt(2), | ||
'initial_key': MusicalKey(), | ||
|
||
'length': types.FLOAT, | ||
'length': DurationType(), | ||
'bitrate': types.ScaledInt(1000, u'kbps'), | ||
'format': types.STRING, | ||
'samplerate': types.ScaledInt(1000, u'kHz'), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -416,6 +416,19 @@ def human_seconds_short(interval): | |
return u'%i:%02i' % (interval // 60, interval % 60) | ||
|
||
|
||
def raw_seconds_short(string): | ||
"""Formats a human-readable M:SS string as a float (number of seconds). | ||
|
||
Raises ValueError if the conversion cannot take place due to `string` not | ||
being in the right format. | ||
""" | ||
match = re.match('^(\d+):([0-5]\d)$', string) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A note about using a regexp: I have decided to go through this route to make it consistent with It might be desirable to make it a bit more flexible (allow HH:MM:SS, or M:SS.zzzzz, etc), and it should not be too hard, but I've opted not to include those for keeping it as an "inverse" of sorts of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perfect. This seems good for now—and hour-long tracks are certainly an edge case. |
||
if not match: | ||
raise ValueError('String not in M:SS format') | ||
minutes, seconds = map(int, match.groups()) | ||
return float(minutes * 60 + seconds) | ||
|
||
|
||
# Colorization. | ||
|
||
# ANSI terminal colorization code heavily inspired by pygments: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point on the circular import—and we mostly try to make dbcore a separate component. Maybe the function should live in this module?