Index: _package.epm ================================================================== --- _package.epm +++ _package.epm @@ -45,35 +45,35 @@ f 644 root root /usr/share/streamtuner2/pq.py ./pq.py #-- channels d 755 root root /usr/share/streamtuner2/channels - f 644 root root /usr/share/streamtuner2/channels/__init__.py ./channels/__init__.py f 644 root root /usr/share/streamtuner2/channels/_generic.py ./channels/_generic.py -f 644 root root /usr/share/streamtuner2/channels/shoutcast.py ./channels/shoutcast.py -f 644 root root /usr/share/streamtuner2/channels/shoutcast.png ./channels/shoutcast.png -f 644 root root /usr/share/streamtuner2/channels/xiph.py ./channels/xiph.py -f 644 root root /usr/share/streamtuner2/channels/xiph.png ./channels/xiph.png +f 644 root root /usr/share/streamtuner2/channels/internet_radio.py ./channels/internet_radio.py +f 644 root root /usr/share/streamtuner2/channels/internet_radio.png ./channels/internet_radio.png +f 644 root root /usr/share/streamtuner2/channels/jamendo.py ./channels/jamendo.py +f 644 root root /usr/share/streamtuner2/channels/jamendo.png ./channels/jamendo.png f 644 root root /usr/share/streamtuner2/channels/live365.py ./channels/live365.py f 644 root root /usr/share/streamtuner2/channels/live365.png ./channels/live365.png -f 644 root root /usr/share/streamtuner2/channels/google.py ./channels/google.py -f 644 root root /usr/share/streamtuner2/channels/google.png ./channels/google.png -f 644 root root /usr/share/streamtuner2/channels/punkcast.py ./channels/punkcast.py -f 644 root root /usr/share/streamtuner2/channels/punkcast.png ./channels/punkcast.png -#f 644 root root /usr/share/streamtuner2/channels/basicch.py ./channels/basicch.py -#f 644 root root /usr/share/streamtuner2/channels/basicch.png ./channels/basicch.png -f 644 root root /usr/share/streamtuner2/channels/jamendo.py ./channels/jamendo.py -f 644 root root /usr/share/streamtuner2/channels/jamendo.png ./channels/jamendo.png +f 644 root root /usr/share/streamtuner2/channels/modarchive.py ./channels/modarchive.py +f 644 root root /usr/share/streamtuner2/channels/modarchive.png ./channels/modarchive.png +f 644 root root /usr/share/streamtuner2/channels/musicgoal.py ./channels/musicgoal.py +f 644 root root /usr/share/streamtuner2/channels/musicgoal.png ./channels/musicgoal.png f 644 root root /usr/share/streamtuner2/channels/myoggradio.py ./channels/myoggradio.py f 644 root root /usr/share/streamtuner2/channels/myoggradio.png ./channels/myoggradio.png -f 644 root root /usr/share/streamtuner2/channels/internet_radio_org_uk.py ./channels/internet_radio_org_uk.py -f 644 root root /usr/share/streamtuner2/channels/internet_radio_org_uk.png ./channels/internet_radio_org_uk.png -f 644 root root /usr/share/streamtuner2/channels/timer.py ./channels/timer.py -f 644 root root /usr/share/streamtuner2/channels/links.py ./channels/links.py +f 644 root root /usr/share/streamtuner2/channels/punkcast.py ./channels/punkcast.py +f 644 root root /usr/share/streamtuner2/channels/punkcast.png ./channels/punkcast.png +f 644 root root /usr/share/streamtuner2/channels/shoutcast.py ./channels/shoutcast.py +f 644 root root /usr/share/streamtuner2/channels/shoutcast.png ./channels/shoutcast.png +f 644 root root /usr/share/streamtuner2/channels/surfmusik.py ./channels/surfmusik.py +f 644 root root /usr/share/streamtuner2/channels/surfmusik.png ./channels/surfmusik.png +f 644 root root /usr/share/streamtuner2/channels/xiph.py ./channels/xiph.py +f 644 root root /usr/share/streamtuner2/channels/xiph.png ./channels/xiph.png +f 644 root root /usr/share/streamtuner2/channels/youtube.py ./channels/youtube.py +f 644 root root /usr/share/streamtuner2/channels/youtube.png ./channels/youtube.png f 644 root root /usr/share/streamtuner2/channels/global_key.py ./channels/global_key.py -#f 644 root root /usr/share/streamtuner2/channels/tv.py ./channels/tv.py -#f 644 root root /usr/share/streamtuner2/channels/tv.png ./channels/tv.png -f 644 root root /usr/share/streamtuner2/channels/musicgoal.py ./channels/musicgoal.py -f 644 root root /usr/share/streamtuner2/channels/musicgoal.png ./channels/musicgoal.png +f 644 root root /usr/share/streamtuner2/channels/links.py ./channels/links.py +f 644 root root /usr/share/streamtuner2/channels/timer.py ./channels/timer.py #-- scripts #d 755 root root /usr/share/streamtuner2/scripts - #f 644 root root /usr/share/streamtuner2/scripts/radiotop40_de.py ./scripts/radiotop40_de.py #-- themes #f 644 root root /usr/share/streamtuner2/themes/MountainDew/gtk-2.0/gtkrc ./themes/MountainDew/gtk-2.0/gtkrc ADDED channels/internet_radio.png Index: channels/internet_radio.png ================================================================== --- channels/internet_radio.png +++ channels/internet_radio.png cannot compute difference between binary files ADDED channels/internet_radio.py Index: channels/internet_radio.py ================================================================== --- channels/internet_radio.py +++ channels/internet_radio.py @@ -0,0 +1,151 @@ +# +# api: streamtuner2 +# title: Internet-Radio.com +# description: Broad list of webradios from all genres. +# type: channel +# category: radio +# version: 0.2 +# priority: standard +# +# +# Might become new main plugin +# +# +# + + + +from channels import * +import re +from config import conf, __print__, dbg +import ahttp as http +from pq import pq + + + + +# streams and gui +class internet_radio (ChannelPlugin): + + + # description + title = "InternetRadio" + module = "internet_radio" + homepage = "http://www.internet-radio.org.uk/" + listformat = "audio/x-scpls" + + # settings + config = [ + {"name":"internetradio_max_pages", "type":"int", "value":5, "description":"How many pages to fetch and read."}, + ] + + + # category map + categories = [] + current = "" + default = "" + + + # load genres + def update_categories(self): + + html = http.get(self.homepage) + rx = re.compile("""]+value="/stations/[-+&.\w\s%]+/">([^<]+)""") + + self.categories = rx.findall(html) + + + + + + # fetch station lists + def update_streams(self, cat, force=0): + + entries = [] + if cat not in self.categories: + return [] + + # regex + #rx_div = re.compile('(.+?)', re.S) + rx_data = re.compile(""" + (?:M3U|PLS)',\s*'(http://[^']+)' + .*? +

([^\n]*?) + .*? + (?:href="(http://[^"]+)"[^>]+target="_blank"[^>]*)? + >\s* + \s*(\w[^<]+)[<\n] + .*? + playing\s*:\s*([^<\n]+) + .*? + (\d+)\s*Kbps + (?:
(\d+)\s*Listeners)? + """, re.S|re.X) + #rx_homepage = re.compile('href="(http://[^"]+)"[^>]+target="_blank"') + rx_pages = re.compile('href="/stations/[-+\w%\d\s]+/page(\d+)">\d+') + rx_numbers = re.compile("(\d+)") + + + # multiple pages + max = max(int(conf.internetradio_max_pages), 1) + page = 1 + while page <= max: + + # fetch + html = http.get(self.homepage + "stations/" + cat.lower().replace(" ", "%20") + "/" + ("page"+str(page) if page>1 else "")) + + + # regex parsing? + if not conf.pyquery: + # step through + for uu in rx_data.findall(html): + (url, genre, homepage, title, playing, bitrate, listeners) = uu + + # transform data + entries.append({ + "url": url, + "genre": self.strip_tags(genre), + "homepage": http.fix_url(homepage), + "title": title, + "playing": playing, + "bitrate": int(bitrate), + "listeners": int(listeners if listeners else 0), + "format": "audio/mpeg", # there is no stream info on that, but internet-radio.org.uk doesn't seem very ogg-friendly anyway, so we assume the default here + }) + + # DOM parsing + else: + # the streams are arranged in table rows + doc = pq(html) + for dir in (pq(e) for e in doc("tr.stream")): + + bl = dir.find("td[align=right]").text() + bl = rx_numbers.findall(str(bl) + " 0 0") + + entries.append({ + "title": dir.find("b").text(), + "homepage": http.fix_url(dir.find("a.url").attr("href")), + "url": dir.find("a").eq(2).attr("href"), + "genre": dir.find("td").eq(0).text(), + "bitrate": int(bl[0]), + "listeners": int(bl[1]), + "format": "audio/mpeg", + "playing": dir.find("td").eq(1).children().remove().end().text()[13:].strip(), + }) + + # next page? + if str(page+1) not in rx_pages.findall(html): + max = 0 + else: + page = page + 1 + + # keep listview updated while searching + self.update_streams_partially_done(entries) + try: self.parent.status(float(page)/float(max)) + except: """there was a div by zero bug report despite max=1 precautions""" + + # fin + self.parent.status() + return entries + + DELETED channels/internet_radio_org_uk.png Index: channels/internet_radio_org_uk.png ================================================================== --- channels/internet_radio_org_uk.png +++ channels/internet_radio_org_uk.png cannot compute difference between binary files DELETED channels/internet_radio_org_uk.py Index: channels/internet_radio_org_uk.py ================================================================== --- channels/internet_radio_org_uk.py +++ channels/internet_radio_org_uk.py @@ -1,151 +0,0 @@ -# -# api: streamtuner2 -# title: Internet-Radio.com -# description: Broad list of webradios from all genres. -# type: channel -# category: radio -# version: 0.2 -# priority: standard -# -# -# Might become new main plugin -# -# -# - - - -from channels import * -import re -from config import conf, __print__, dbg -import ahttp as http -from pq import pq - - - - -# streams and gui -class internet_radio_org_uk (ChannelPlugin): - - - # description - title = "InternetRadio" - module = "internet_radio_org_uk" - homepage = "http://www.internet-radio.org.uk/" - listformat = "audio/x-scpls" - - # settings - config = [ - {"name":"internetradio_max_pages", "type":"int", "value":5, "description":"How many pages to fetch and read."}, - ] - - - # category map - categories = [] - current = "" - default = "" - - - # load genres - def update_categories(self): - - html = http.get(self.homepage) - rx = re.compile("""]+value="/stations/[-+&.\w\s%]+/">([^<]+)""") - - self.categories = rx.findall(html) - - - - - - # fetch station lists - def update_streams(self, cat, force=0): - - entries = [] - if cat not in self.categories: - return [] - - # regex - #rx_div = re.compile('(.+?)', re.S) - rx_data = re.compile(""" - (?:M3U|PLS)',\s*'(http://[^']+)' - .*? -

([^\n]*?) - .*? - (?:href="(http://[^"]+)"[^>]+target="_blank"[^>]*)? - >\s* - \s*(\w[^<]+)[<\n] - .*? - playing\s*:\s*([^<\n]+) - .*? - (\d+)\s*Kbps - (?:
(\d+)\s*Listeners)? - """, re.S|re.X) - #rx_homepage = re.compile('href="(http://[^"]+)"[^>]+target="_blank"') - rx_pages = re.compile('href="/stations/[-+\w%\d\s]+/page(\d+)">\d+') - rx_numbers = re.compile("(\d+)") - - - # multiple pages - max = max(int(conf.internetradio_max_pages), 1) - page = 1 - while page <= max: - - # fetch - html = http.get(self.homepage + "stations/" + cat.lower().replace(" ", "%20") + "/" + ("page"+str(page) if page>1 else "")) - - - # regex parsing? - if not conf.pyquery: - # step through - for uu in rx_data.findall(html): - (url, genre, homepage, title, playing, bitrate, listeners) = uu - - # transform data - entries.append({ - "url": url, - "genre": self.strip_tags(genre), - "homepage": http.fix_url(homepage), - "title": title, - "playing": playing, - "bitrate": int(bitrate), - "listeners": int(listeners if listeners else 0), - "format": "audio/mpeg", # there is no stream info on that, but internet-radio.org.uk doesn't seem very ogg-friendly anyway, so we assume the default here - }) - - # DOM parsing - else: - # the streams are arranged in table rows - doc = pq(html) - for dir in (pq(e) for e in doc("tr.stream")): - - bl = dir.find("td[align=right]").text() - bl = rx_numbers.findall(str(bl) + " 0 0") - - entries.append({ - "title": dir.find("b").text(), - "homepage": http.fix_url(dir.find("a.url").attr("href")), - "url": dir.find("a").eq(2).attr("href"), - "genre": dir.find("td").eq(0).text(), - "bitrate": int(bl[0]), - "listeners": int(bl[1]), - "format": "audio/mpeg", - "playing": dir.find("td").eq(1).children().remove().end().text()[13:].strip(), - }) - - # next page? - if str(page+1) not in rx_pages.findall(html): - max = 0 - else: - page = page + 1 - - # keep listview updated while searching - self.update_streams_partially_done(entries) - try: self.parent.status(float(page)/float(max)) - except: """there was a div by zero bug report despite max=1 precautions""" - - # fin - self.parent.status() - return entries - - Index: cli.py ================================================================== --- cli.py +++ cli.py @@ -33,11 +33,11 @@ title = "CLI interface" version = 0.3 # channel plugins - channel_modules = ["shoutcast", "xiph", "internet_radio_org_uk", "jamendo", "myoggradio", "live365"] + channel_modules = ["shoutcast", "xiph", "internet_radio", "jamendo", "myoggradio", "live365"] current_channel = "cli" plugins = {} # only populated sparsely by .stream() # start Index: config.py ================================================================== --- config.py +++ config.py @@ -63,43 +63,44 @@ # some defaults def defaults(self): self.play = { "audio/mpeg": "audacious ", # %u for url to .pls, %g for downloaded .m3u "audio/ogg": "audacious ", - "audio/*": "totem ", + "audio/*": "audacious ", + "video/youtube": "totem $(youtube-dl -g %srv)", "video/*": "vlc --one-instance %srv", "url/http": "sensible-browser", } self.record = { "audio/*": "xterm -e streamripper %srv", # -d /home/***USERNAME***/Musik - "video/youtube": "xterm -e youtube-dl %srv", + "video/youtube": "xterm -e \"youtube-dl %srv\"", } self.plugins = { - "bookmarks": 1, # built-in plugins, cannot be disabled + "bookmarks": 1, # built-in plugin, cannot be disabled "shoutcast": 1, "xiph": 1, - "file": 0, # disable per default - "punkcast": 0, # disable per default + "file": 0, # disable per default + "punkcast": 0, # disable per default + "history": 0, "basicch": 0, # ceased - "tv": 0, # no longer working + "tv": 0, # ceased } self.tmp = os.environ.get("TEMP", "/tmp") self.max_streams = "500" self.show_bookmarks = 1 self.show_favicons = 1 self.load_favicon = 1 - self.heuristic_bookmark_update = 1 - self.retain_deleted = 1 + self.heuristic_bookmark_update = 0 + self.retain_deleted = 0 self.auto_save_appstate = 1 self.theme = "" #"MountainDew" - self.debug = False - self.channel_order = "shoutcast, xiph, internet_radio_org_uk, jamendo, myoggradio, .." + self.channel_order = "shoutcast, xiph, internet_radio, jamendo, myoggradio, .." self.reuse_m3u = 1 - self.google_homepage = 1 + self.google_homepage = 0 self.windows = platform.system()=="Windows" self.pyquery = 1 - self.debug = 1 + self.debug = 0 # each plugin has a .config dict list, we add defaults here def add_plugin_defaults(self, config, module=""):