Check-in [7c085d54f9]
Overview
Comment: | Add windows media guide radio lists (ASX). Fixed action module to extract with case-insensitve matches for that playlist format. (It's not really XML after all.) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7c085d54f9f21a9e0955e9cb0da6dfd3 |
User & Date: | mario on 2015-05-07 01:17:42 |
Other Links: | manifest | tags |
Context
2015-05-07
| ||
01:20 | Add description: line. check-in: 749946913c user: mario tags: trunk | |
01:17 | Add windows media guide radio lists (ASX). Fixed action module to extract with case-insensitve matches for that playlist format. (It's not really XML after all.) check-in: 7c085d54f9 user: mario tags: trunk | |
01:16 | Another radio station directory: listenlive.eu check-in: b0e9e031d9 user: mario tags: trunk | |
Changes
Modified action.py from [d816e37503] to [02cf432a5f].
︙ | ︙ | |||
95 96 97 98 99 100 101 | ) # Playlist format content probing (assert type) playlist_content_map = [ ("pls", r""" (?i)\[playlist\].*NumberOfEntries """), ("xspf", r""" <\?xml .* <playlist .* ((?i)http://xspf\.org)/ns/0/ """), ("m3u", r""" ^ \s* \#(EXT)?M3U """), | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | ) # Playlist format content probing (assert type) playlist_content_map = [ ("pls", r""" (?i)\[playlist\].*NumberOfEntries """), ("xspf", r""" <\?xml .* <playlist .* ((?i)http://xspf\.org)/ns/0/ """), ("m3u", r""" ^ \s* \#(EXT)?M3U """), ("asx" , r""" (?i) <asx\b """), ("smil", r""" <smil[^>]*> .* <seq> """), ("html", r""" (?i)<(audio|video)\b[^>]+\bsrc\s*=\s*["']?https?:// """), ("wpl", r""" <\?wpl \s+ version="1\.0" \s* \?> """), ("b4s", r""" <WinampXML> """), # http://gonze.com/playlists/playlist-format-survey.html ("jspf", r""" ^ \s* \{ \s* "playlist": \s* \{ """), ("asf", r""" ^ \[Reference\] .*? ^Ref\d+= """), ("url", r""" ^ \[InternetShortcut\] .*? ^URL= """), |
︙ | ︙ | |||
362 363 364 365 366 367 368 | # regex scheme rules = self.extr_urls[fmt] rows = [] fields = [name for name in ("url", "title", "homepage", "genre", "playing") if rules.get(name)] # Block-wise processing if rules.get("split"): | | | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | # regex scheme rules = self.extr_urls[fmt] rows = [] fields = [name for name in ("url", "title", "homepage", "genre", "playing") if rules.get(name)] # Block-wise processing if rules.get("split"): for part_src in re.split(rules["split"], self.src, 0, re.X): row = {} for name in fields: val = self.field(name, rules, part_src) if val and val[0]: row[name] = val[0] if row.get("url"): rows.append(row) |
︙ | ︙ | |||
435 436 437 438 439 440 441 | url = r"(?x) <location> (\w+://[^<>\s]+) </location> ", title = r"(?x) <title> ([^<>]+) ", homepage = r"(?x) <info> ([^<>]+) ", playing = r"(?x) <annotation> ([^<>]+) ", unesc = "xml", ), "asx": dict( | | | | | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | url = r"(?x) <location> (\w+://[^<>\s]+) </location> ", title = r"(?x) <title> ([^<>]+) ", homepage = r"(?x) <info> ([^<>]+) ", playing = r"(?x) <annotation> ([^<>]+) ", unesc = "xml", ), "asx": dict( split = r" (?ix) <entry[^>]*> ", url = r" (?ix) <ref \b[^>]+\b href \s*=\s* [\'\"] (\w+://[^\s\"\']+) [\'\"] ", title = r" (?ix) <title> ([^<>]+) ", unesc = "xml", ), "smil": dict( url = r" (?x) <(?:audio|video|media)\b [^>]+ \b src \s*=\s* [^\"\']? \s* (\w+://[^\"\'\s\>]+) ", unesc = "xml", ), "jspf": dict( |
︙ | ︙ |
Added contrib/windowsmedia.py version [eb5ea6c6b8].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | # encoding: UTF-8 # api: streamtuner2 # title: WindowsMedia # description: # url: http://windowsmedia.com/ # version: 0.3 # type: channel # category: radio # config: # { name: windowsmedia_culture, type: select, value: en-gb, select: "en-gb|de-de|da-dk|cs-cz|es-es|fr-fr|it-it|nl-nl|pl-pl|tr-tr|pt-pt|pt-br|en-us", description: "Country/language preference (for localized ads:?)" } # png: # iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAk1BMVEWwMjIAAQACAAoSAwQ2CQcAH5VqERZsESgNK489KFwA # MrMAN6UQQwAXNpEAPakAQJ8AQ44RO7S2JQ8ASr6vLwqPOgoZYgCCSgvPPgVCbAF9XwzMTRrqUAHNY0VemADjbTiShjOYhiJR # oApJqgRerwlUtgBjwgDAsQDdqQB02AnowgP+soDfywDs2RL25Qr4727/8rdsT1F2AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF # HUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffBQcANDDneHDIAAAAlUlEQVQY02VPWxKCMAzcKmIF5GGrVkVAKA+x # Ve9/OhUK0xmTj2Q3yU4WAPnmL6Y69rDQwJB/bDOLpYNDEFgc352betYh4EIcK5lVgVHnIk/3kCdp5g7PHykv742sp43LFS4y # lMMNgbvebJl3U6ptjSxFFDPop+7NF5RFcVK8X6qfPIS+n0BrNf9FQ98retXZDlfoxuYDwYsJfXHQg0AAAAAASUVORK5CYII= # png-orig: https://openclipart.org/detail/176727/windows-bug # priority: extra # status: unsupported # # Well, this one is Windows-specific, so naturally uses # horrible formats WAX ( ASX ) for playlists. Still can # be parsed by action module, but possibly falling back # onto raw extraction etc. # # Only fetches the first page for each category anyway. # And there's no specific category extraction, so stuck # on the UK entries. # # Most entries are lower bitrates, 32 to 64 kbit/s MP3. import re from config import * from channels import * import ahttp # Yay, windows playlists. class windowsmedia (ChannelPlugin): # control flags has_search = False listformat = "wax" audioformat = "audio/mpeg" titles = dict(listeners=False, bitrate=False, playing="Location") _web = "http://www.windowsmedia.com/RadioUI/Home.aspx?g={}&culture=en-gb" base = "http://www.windowsmedia.com/RadioUI/getstationsforgenre.aspx?g={}&offset=0&culture={}" _url = "http://www.windowsmedia.com/RadioTunerAPI/Service.asmx/playStation?stationID={}&dialupDetected=true&useHighBandwidth=false&locale={}" categories = ["80s", "Adult Hits", "Adult Rock", "Alternative Rock", "Americana + Roots", "Big Band", "Blues", "Christian Hits", "Classic R&B", "Classic Rock", "Classical", "Comedy", "Country", "Dance + Electronica", "Holiday", "Indie", "International", "Jazz", "Latin", "Metal", "Miscellaneous", "New Age", "News + Talk", "Oldies", "Public Radio", "Rap + Hip Hop", "Reggae", "Religious", "Rock", "Smooth Jazz", "Soft Rock", "Soundtracks + Musicals", "Sports", "Top 40", "Urban/Modern R&B"] # static def update_categories(self): pass # Fetch entries def update_streams(self, cat, search=None): ucat = re.sub("\W+", "", cat.lower()) html = ahttp.get(self.base.format(ucat, conf.windowsmedia_culture)) r = [] ls = re.findall(""" stationid="([a-f0-9-]+)" \s+ onclick="Listen\('[\w-]+',\s*'(.+?)',\s*'(.+?)', """, html, re.X|re.S) for id, title, homepage in ls: r.append(dict( id = id, title = unhtml(title), homepage = homepage, url = self._url.format(id, conf.windowsmedia_culture), bitrate = 32, )) return r |