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
This commit is contained in:
boyska 2017-12-09 17:51:56 +01:00
parent a8f59b75a3
commit 1be085976e

36
feed
View file

@ -16,11 +16,31 @@ import urllib.request
from urllib.parse import urlparse, unquote from urllib.parse import urlparse, unquote
import posixpath import posixpath
import random import random
from bisect import bisect
from lxml import html from lxml import html
import requests 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): class Audio(object):
def __init__(self, url, durata=None): def __init__(self, url, durata=None):
self.url = url self.url = url
@ -138,6 +158,8 @@ def get_parser():
help='Exclude any audio that is longer than MAXLEN seconds') help='Exclude any audio that is longer than MAXLEN seconds')
p.add_argument('--random', default=False, p.add_argument('--random', default=False,
action='store_true', help='Pick randomly') 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, p.add_argument('--howmany', default=1, type=int,
help='If not specified, only 1 will be played') help='If not specified, only 1 will be played')
p.add_argument('--slotsize', help='Seconds between each audio', type=int) p.add_argument('--slotsize', help='Seconds between each audio', type=int)
@ -173,13 +195,23 @@ def put(audio, copy=False):
def main(): def main():
args = get_parser().parse_args() parser = get_parser()
args = parser.parse_args()
if not args.debug: if not args.debug:
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
else: else:
logging.basicConfig(level=logging.DEBUG) 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 = [] audios = []
for url in args.urls: for url in sources:
if url.startswith('http:') or url.startswith('https:') \ if url.startswith('http:') or url.startswith('https:') \
or os.path.isfile(url): or os.path.isfile(url):
# download the feed # download the feed