Check-in [026af5c9fb]
Overview
Comment: | Fix xiph search URL and by_format mapping. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
026af5c9fb5dda5d427a234f79144afe |
User & Date: | mario on 2015-05-02 23:44:06 |
Other Links: | manifest | tags |
Context
2015-05-02
| ||
23:44 | Better plugin comments for user interface. check-in: 85c2fd4f56 user: mario tags: trunk | |
23:44 | Fix xiph search URL and by_format mapping. check-in: 026af5c9fb user: mario tags: trunk | |
20:03 | Add combined unhtml() utility function for raw page extractors. check-in: 6f314952b9 user: mario tags: trunk | |
Changes
Modified channels/xiph.py from [10274b4d66] to [e7ab9f6f02].
1 2 3 | # encoding: UTF-8 # api: streamtuner2 # title: Xiph.org | | | | | | | > < | > | | > | | > > | 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 | # encoding: UTF-8 # api: streamtuner2 # title: Xiph.org # description: ICEcast radios. Scans per JSON API, slow XML, or raw directory. # type: channel # url: http://dir.xiph.org/ # version: 0.5 # category: radio # config: # { name: xiph_min_bitrate, value: 64, type: int, description: "Minimum bitrate; filter lesser quality streams.", category: filter } # { name: xiph_source, value: cache, type: select, select: "cache=JSON cache srv|xml=Clunky XML blob|web=Forbidden fruits", description: "Source for station list extraction." } # priority: standard # png: # iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAg5JREFUOI2lk1tIE2AUx3+7CG1tlmlG1rSEHrKgEUF7yO40taQiRj10I4qKkOaT4hIUItuTkC8hpJAQtJCICrFpzEKw # h61eQorGNBOTzbEt16ZrnR5Wq3mZD/3heziX//983znngyyov+eSbHEA5WKBhs4BKVy9gsqajqwiCwo0dA5IQX5u2s4moliMPPV1nCeDzxgNBFDHE2wsKMPzsGVefobjcnO7RMfeMuL341ZBrNEGRmPqqjdvsbbf # w7irO4Oj+rdywNNNucmERsLUVndR8uYRU13PCew6hpgP8W02xMpIsik++qk5oweW6y3yob8WnXacZDKJWh1Cp4OtRUHsh19TUlUGViv09RGqKAenU5QnLKm+rK88LjgcUnxmr/h8iNO5XYJBRAQZ/qiVeptGWjty # 5cClDWLwugQRIRiU5UdPCoD6S89jhV6pks9WG6fuwtBtF5v72vC1v+B86SsM+jD56hjnyiM0lRrAbofeXjQJLdE/78jbXSU5166I6f5VeeDdKdq6GtlSd0QkVU+8XsQhlt9W6izbZ5aMKWgtp2WT/yUHd0xSYU7i # dsPQ+1WMKIsJD08wEV2HGLeRyNMjawqRxhuKBfdgz1m7fI/4mVX+ZGxmgniOoJv+QZHGAMC7p60ZnHkC8HfzZmLTBCd9af9ccnqMc9HTdmFe4kLkJbH/4h0xVtcu+SP/C78AL6btab6woPcAAAAASUVORK5CYII= # # Xiph.org maintains the Ogg streaming standard and Vorbis, # Opus, FLAC audio, and Theora video compression formats. # The ICEcast server is a modern alternative to SHOUTcast. # # It also provides a directory listing of known internet # radio stations, only a handful of them using Ogg though. # The category list is hardwired in this plugin. And there # are three station fetching modes now: # # → "JSON cache" retrieves a refurbished JSON station list, # both sliceable genres and searchable. # # → "Clunky XML" fetches the olden YP.XML, which is really # slow, then slices out genres. No search. # # → "Forbidden Fruits" extracts from dir.xiph.org HTML pages, # with homepages and listener/max infos available. Search # is also possible. # from config import * from uikit import uikit import ahttp from channels import * import xml.dom.minidom |
︙ | ︙ | |||
174 175 176 177 178 179 180 181 | # Fetch directly from website. Which Xiph does not approve of; but # hey, it's a fallback option here. And the only way to actually # uncover station homepages. #@use_rx def from_raw_html(self, cat, search=None, use_rx=False): # Build request URL if search: | > < > > | | > > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | # Fetch directly from website. Which Xiph does not approve of; but # hey, it's a fallback option here. And the only way to actually # uncover station homepages. #@use_rx def from_raw_html(self, cat, search=None, use_rx=False): # Build request URL by_format = {t.lower(): t for t in self.categories[-1]} if search: url = "http://dir.xiph.org/search?search={}".format(search) cat = "search" elif by_format.get(cat): url = "http://dir.xiph.org/by_format/{}".format(by_format[cat]) elif cat: url = "http://dir.xiph.org/by_genre/{}".format(cat.title()) # Collect all result pages html = ahttp.get(url) for i in range(1,4): if html.find('page={}">{}</a></li>'.format(i, i+1)) < 0: break self.status(i/5.1) html += ahttp.get(url, {"search": cat.title(), "page": i}) try: html = html.encode("raw_unicode_escape").decode("utf-8") except: pass # Find streams r = [] |
︙ | ︙ | |||
205 206 207 208 209 210 211 | .*? "listeners">\[(\d+) .*? "stream-description">(.*?)< .*? Tags: (.*?) </div> .*? href="(/listen/\d+/listen.xspf)" .*? class="format"\s+title="([^"]+)" .*? /by_format/([^"]+) """, html, re.X|re.S) | > | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | .*? "listeners">\[(\d+) .*? "stream-description">(.*?)< .*? Tags: (.*?) </div> .*? href="(/listen/\d+/listen.xspf)" .*? class="format"\s+title="([^"]+)" .*? /by_format/([^"]+) """, html, re.X|re.S) print ls # Assemble for homepage, title, listeners, playing, tags, url, bits, fmt in ls: r.append(dict( genre = unhtml(tags), title = unhtml(title), homepage = ahttp.fix_url(homepage), playing = unhtml(playing), |
︙ | ︙ | |||
483 484 485 486 487 488 489 | ], "ska", [ "punkrock", "oi" ], "darkwave", | > | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | ], "ska", [ "punkrock", "oi" ], "darkwave", "/FORMAT", ["Ogg_Vorbis", "Ogg_Theora", "Opus", "NSV", "WebM"], ] # Helper functions for XML extraction mode # Shortcut to get text content from XML subnode by name |
︙ | ︙ |