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 [] |