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