Check-in [a4cb6da4ac]
Overview
| Comment: | Add old Compound★ example plugin, slightly updated for current meta data scheme. |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
a4cb6da4ac10fa22844cf96488041120 |
| User & Date: | mario on 2015-04-14 16:57:36 |
| Other Links: | manifest | tags |
Context
|
2015-04-14
| ||
| 17:03 | Not implemented: `8tracks` (plugin name suffers from identifier mismatch, and it's not quite doable in ST2, because 8tracks requires feedback shortly after playback has begun; yet streamtuner can't inspect any configured audio player for actually doing so.) check-in: 327d2ed94c user: mario tags: trunk | |
| 16:57 | Add old Compound★ example plugin, slightly updated for current meta data scheme. check-in: a4cb6da4ac user: mario tags: trunk | |
| 16:43 | Old helper script to make streamripper add genre. Though there are `-D` pattern options that often work better. And KStreamripper or fIcy/fPls might be more modern. check-in: 39e61e9915 user: mario tags: trunk | |
Changes
Added contrib/bieber.py version [42bda022a3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# api: streamtuner2
# title: Bieber
# description: Bieber music
# url: http://www.justinbiebermusic.com/
# version: 5.2
# type: channel
# category: example
# config:
# { "name": "bieber_filter", "type": "text", "value": "BIEBERBLAST", "description": "So and so." }
# priority: joke
#
# This was an entertaining test plugin for development. (Compound function
# went into the search feature, and the compound channel plugin obviously.)
#
# It's however a very simple plugin, and hence a good basis for writing
# your own extensions.
from channels import *
# Bieber music filter plugin
class bieber(ChannelPlugin):
# config data
config = [
]
# category map
categories = ['the Biebs']
default = 'the Biebs'
current = 'the Biebs'
# static category list
def update_categories(self):
# nothing to do here
pass
# just runs over all channel plugins, and scans their streams{} for matching entries
def update_streams(self, cat, force=0):
# result list
entries = []
# kill our current list, so we won't find our own entries
self.streams = {}
# swamp through all plugins
for name,p in self.parent.channels.iteritems():
#print "bieberquest: channel", name
# subcategories in plugins
for cat,stations in p.streams.iteritems():
#print " bq cat", cat
# station entries
for row in stations:
# collect text fields, do some typecasting, lowercasing
text = "|".join([str(e) for e in row.values()])
text = text.lower()
# compare
if text.find("bieb") >= 0:
# add to result list
row["genre"] = name + ": " + row.get("genre", "")
entries.append(row)
# return final rows list
return entries
|
Added contrib/compound.py version [cde5ef1bb0].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# encoding: UTF-8
# api: streamtuner2
# title: Compound★
# description: combines station lists from multiple channels
# version: 0.1
# type: channel
# category: virtual
# url: http://fossil.include-once.org/streamtuner2/
# config: -
# { name: compound_channels, type: text, value: "shoutcast, internet_radio, xiph, surfmusic", description: "Merge channels, or use all (*)" }
# { name: compound_genres, type: text, value: "Top 40, x", description: "Extract categories, or just use intersection (x)" }
# priority: unsupported
#
# Use this plugin to mix categories and their station entries from two
# or more different directory channels. It merges the lists, albeit in
# a rather crude way. (If anyone is interested, I could add a proper
# regex or something now.)
#
# Per default it lists only selected categories. But can be configured to
# merge just intersectioning categories/genres. Entry order is determined
# from station occourence count in channels AND their individual listener
# count (where available) using some guesswork to eliminate duplicates.
from channels import *
import action
import http
from config import conf
# merging channel
class compound (ChannelPlugin):
# runtime options
has_search = False
listformat = "href" # row entries will contain exact `listformat` classification
audioformat = "audio/*" # same as for correct encoding mime type
# references
parent = None
# data
streams = {}
categories = []
# which categories
def update_categories(self):
# as-is category list
cats = self.split(conf.compound_genres)
self.categories = [c for c in cats if c != "x"]
# if intersection
if "x" in cats:
once = []
for chan in self.channels():
for add in self.flatten(self.parent.channels[chan].categories):
# second occourence in two channels
if add.lower() in once:
if add not in self.categories:
self.categories.append(add)
else: #if add not in self.categories:
once.append(add.lower())
pass
# flatten our two-level categories list
def flatten(self, a):
return [i for sub in a for i in (sub if type(sub)==list else [sub])]
# break up name lists
def split(self, s):
return [s.strip() for s in s.split(",")]
# get list of channels
def channels(self):
# get list
ls = self.split(conf.compound_channels)
# resolve "*"
if "*" in ls:
ls = self.parent.channel_names # includes bookmarks
if self.module in ls:
ls.remove(self.module) # but not compound
return ls
# combine stream lists
def update_streams(self, cat):
r = []
have = []
# look through channels
if cat in self.categories:
for cn in self.channels():
# get channel, refresh list
c = self.parent.channels[cn]
#
for row in self.get_streams(c, cat):
# copy
row = dict(row)
#row["listeners"] = 1000 + row.get("listeners", 0) / 10
row["extra"] = cn # or genre?
row["listformat"] = c.listformat
# duplicates
if row["title"].lower() in have or row["url"] in have:
for i,cmp in enumerate(r):
if cmp["title"].lower()==row["title"].lower() or cmp["url"].find(row["url"])>=0:
r[i]["listeners"] = row.get("listeners",0) + 5000
pass
else:
r.append(row)
have.append(row["title"].lower()) # we're comparing lowercase titles
have.append(row["url"][:row["url"].find("http://")]) # save last http:// part (internet-radio redirects to shoutcast urls)
# sort by listeners
r = sorted(r, key=lambda x: -x.get("listeners", 0))
return r
# extract station list from other channel plugin
def get_streams(self, c, cat):
# if empty?
#c.load(cat)
return c.streams.get(cat) \
or c.update_streams(cat.replace(" ","")) \
or []
|