Skip to content
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

random: add --time option, update docs #2322

Merged
merged 2 commits into from
Dec 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 61 additions & 18 deletions beetsplug/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,46 +32,89 @@ def random_item(lib, opts, args):
else:
objs = list(lib.items(query))

if opts.time:
total_time = 0.0
time_sec = (opts.time * 60)
objs_shuffled = objs
random.shuffle(objs_shuffled)

if not opts.equal_chance:
objs = []

for item in objs_shuffled:
if opts.album:
item.length = sum(a.length for a in item.items())
if (total_time + item.length) <= time_sec:
objs.append(item)
total_time += item.length

else:
pass

if opts.equal_chance:
# Group the objects by artist so we can sample from them.
key = attrgetter('albumartist')
objs.sort(key=key)
objs_by_artists = {}
for artist, v in groupby(objs, key):
objs_by_artists[artist] = list(v)

objs = []
for _ in range(opts.number):
# Terminate early if we're out of objects to select.
if not objs_by_artists:
break

# Choose an artist and an object for that artist, removing
# this choice from the pool.
artist = random.choice(list(objs_by_artists.keys()))
objs_from_artist = objs_by_artists[artist]
i = random.randint(0, len(objs_from_artist) - 1)
objs.append(objs_from_artist.pop(i))

# Remove the artist if we've used up all of its objects.
if not objs_from_artist:
del objs_by_artists[artist]

else:
if opts.time:
for item in objs_shuffled:
if not objs_by_artists:
break

if opts.album:
item.length = sum(a.length for a in item.items())
if (total_time + item.length) <= time_sec:
artist = random.choice(list(objs_by_artists.keys()))
objs_from_artist = objs_by_artists[artist]
i = random.randint(0, len(objs_from_artist) - 1)
objs.append(objs_from_artist.pop(i))
total_time += item.length

if not objs_from_artist:
del objs_by_artists[artist]

else:
pass

else:
for _ in range(opts.number):
# Terminate early if we're out of objects to select.
if not objs_by_artists:
break

# Choose an artist and an object for that artist, removing
# this choice from the pool.
artist = random.choice(list(objs_by_artists.keys()))
objs_from_artist = objs_by_artists[artist]
i = random.randint(0, len(objs_from_artist) - 1)
objs.append(objs_from_artist.pop(i))

# Remove the artist if we've used up all of its objects.
if not objs_from_artist:
del objs_by_artists[artist]

elif not opts.time:
number = min(len(objs), opts.number)
objs = random.sample(objs, number)

for item in objs:
print_(format(item))

random_cmd = Subcommand('random',
help=u'chose a random track or album')
help=u'choose a random track or album')
random_cmd.parser.add_option(
u'-n', u'--number', action='store', type="int",
help=u'number of objects to choose', default=1)
random_cmd.parser.add_option(
u'-e', u'--equal-chance', action='store_true',
help=u'each artist has the same chance')
random_cmd.parser.add_option(
u'-t', u'--time', action='store', type="float",
help=u'total length in minutes of objects to choose')
random_cmd.parser.add_all_common_options()
random_cmd.func = random_item

Expand Down
4 changes: 4 additions & 0 deletions docs/plugins/random.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ of Bob Dylan won't make you listen to Bob Dylan 50% of the time.
The ``-n NUMBER`` option controls the number of objects that are selected and
printed (default 1). To select 5 tracks from your library, type ``beet random
-n5``.

The ``-t MINUTES`` option controls the combined length of the objects that are
selected and printed. To select tracks that total one hour, tyoe ``beet random
-t60``