From 1be085976e772637b17188657869be4d022dac11 Mon Sep 17 00:00:00 2001 From: boyska Date: Sat, 9 Dec 2017 17:51:56 +0100 Subject: [PATCH] FIX #1: --source-weights source weights are meant to first of all pick a source, with the defined weights. This option is unrelated to --random. In fact, --random will switch from chronological order to random one. --source-weights will, instead, pick only one of the sources given in command line. A typical example is for jingles: if you have a big number of jingles that should run relatively rarely, and a small number of jingles that should run often, then putting them all in the same directory isn't a good idea. You'd better put them in two different dirs and use --source-weights 1:2 --- feed | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/feed b/feed index 0d71a39..47512e8 100755 --- a/feed +++ b/feed @@ -16,11 +16,31 @@ import urllib.request from urllib.parse import urlparse, unquote import posixpath import random +from bisect import bisect from lxml import html import requests +def weighted_choice(values, weights): + ''' + random.choice with weights + + weights must be integers greater than 0. + + Their meaning is "relative", that is [1,2,3] is the same as [2,4,6] + ''' + assert len(values) == len(weights) + total = 0 + cum_weights = [] + for w in weights: + total += w + cum_weights.append(total) + x = random.random() * total + i = bisect(cum_weights, x) + return values[i] + + class Audio(object): def __init__(self, url, durata=None): self.url = url @@ -138,6 +158,8 @@ def get_parser(): help='Exclude any audio that is longer than MAXLEN seconds') p.add_argument('--random', default=False, action='store_true', help='Pick randomly') + p.add_argument('--source-weights', + help='Select only one "source" based on this weights') p.add_argument('--howmany', default=1, type=int, help='If not specified, only 1 will be played') p.add_argument('--slotsize', help='Seconds between each audio', type=int) @@ -173,13 +195,23 @@ def put(audio, copy=False): def main(): - args = get_parser().parse_args() + parser = get_parser() + args = parser.parse_args() if not args.debug: logging.basicConfig(level=logging.WARNING) else: logging.basicConfig(level=logging.DEBUG) + sources = args.urls + + if args.source_weights: + weights = tuple(map(int, args.source_weights.split(':'))) + if len(weights) != len(sources): + parser.exit(status=2, message='Weight must be in the' + ' same number as sources\n') + sources = [weighted_choice(sources, weights)] + audios = [] - for url in args.urls: + for url in sources: if url.startswith('http:') or url.startswith('https:') \ or os.path.isfile(url): # download the feed