ADDED contrib/disabled/icast.py Index: contrib/disabled/icast.py ================================================================== --- contrib/disabled/icast.py +++ contrib/disabled/icast.py @@ -0,0 +1,101 @@ +# encoding: UTF-8 +# api: streamtuner2 +# title: iCast.io +# description: Open collaborative stream directory +# version: 0.2 +# type: channel +# url: http://www.icast.io/ +# category: radio +# priority: obsolete +# config: - +# png: +# iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAcVQTFRF +# ////8PDw5OTk9/f3z9fYW3qnKFmLC0N9K1qVYYay2N7hl6zAHU6BYIqaqdDN4vvt9fzstuPeV42+JVmWn7TKi6XBFE+Og62t+/6f7/2MoMmMs+OPpdPDns/7ir/YGlehjqjE0tnfGFGTQXWuncmX6/tt +# 4vlvvfBv6vtsreGNbaXhdrTyXJXCY4m2JWStM2aZ4PhjtOhjy/FpeKioZaDoRYTAOXSpLGGgMXK/GlONlcxG1fZZfqyEX5XRY6TqPobZI2zCWJKqGVWbMHTHH12hT4BMt+0tgrFTfKt3XpG4WZfYR4vY +# NHrTK3TMRYTCIlmdM3bNKmy8KGGWgrs3UYRXSHp0TISKS4WaPXq4OXrENHrNO3zRPnitXpZ/aqJrRnd5Y5VPWYVXNGeTNnO1M2OiLmy+PYPdSo3eUZHaU5DLg7cxtOwNntIaYpVrMGittLvEKV+lQofd +# UZXoXp7rY6HfVoutsOUMQnOHdIurM2q2Y6TvbarqZJvFYpBlp9sSs+gMboag3t/dfZCqPWysSoLNYJvgYZSxfq5NNmF6MlmCcoab19nXqKyyZoSwTnawN2OfRGqXXXqanKKjzMzMt7e3o6SjsLKvtVfy +# AwAAAAFiS0dEBxZhiOsAAAAJcEhZcwAAAEgAAABIAEbJaz4AAADxSURBVBjTY2AAAUYmIGBkZoACRhZWNnZ2Dk4uqAgjNw8vH7+AoJCwCCOIzywqJi4hKSUtIysnrwBSo6ikrKKqpq6hqaWto6QIVKCr +# p69uYGBoZGxiYmrGyczAaG5haWVtbW1ja2fv4GjOyMDo5Ozi6ubu4enl7ePr5w8U8A8IDAoOCQ0Lj4iMigYJmDtHRcbExsUnJCYlR6YwMjCzpqalZ2SGZ2Vn5+TmsTIzMOcXFBYVl5TmZGeXlXPkgxxa +# UZleVV1TW1efyNYAdmpjU3NLq1Zbe0dnVzfEM0w9vX3N/RMmTmqEeZd58pSpU6dNBnsWAEP5Nco3FJZfAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE0LTA2LTAxVDAxOjI4OjA3KzAyOjAw7O+A+AAAACV0 +# RVh0ZGF0ZTptb2RpZnkAMjAxNC0wNi0wMVQwMToyODowNyswMjowMJ2yOEQAAAAASUVORK5CYII= +# documentation: http://api.icast.io/ +# +# +# A modern alternative to ShoutCast/ICEcast. +# Streams are user-contributed, but often lack +# meta data (homepage) and there's no ordering +# by listeneres/popularity. +# +# However it's every easy and stable to interface +# with over JSON. However it's also somewhat slow, +# because each query result has only 10 entries. +# Which is why reloading takes a few seconds to +# collect 200 station entries (see main options). + + +import re +import json +from config import * +from channels import * +import ahttp + + +# iCast.io API +class icast (ChannelPlugin): + + # control attributes + has_search = True + listformat = "pls" + titles = dict(listeners=False, bitrate=False, playing=False) + categories = [] + base = "http://api.icast.io/1/" + + + # Categories require little post-processing, just dict into list conversion + def update_categories(self): + self.categories = [] + for genre,cats in json.loads(ahttp.get(self.base + "genres"))["genres"].items(): + self.categories.append(genre.title()) + self.categories.append([c.title() for c in cats]) + + # Just copy over stream URLs and station titles + def update_streams(self, cat, search=None): + + if cat: + data = self.api("stations/genre/", cat.lower(), {}) + elif search: + data = self.api("stations/search", "", {"q": search}) + else: + pass + + r = [] + for e in data: + r.append(dict( + genre = " ".join(e["genre_list"]), + url = e["streams"][0]["uri"], + format = e["streams"][0]["mime"], + title = e["name"], + #playing = " ".join(e["current"].items()), + )) + + return r + + # fetch multiple pages + def api(self, method, path, params): + r = [] + while len(r) < int(conf.max_streams): + try: + data = ahttp.get(self.base + method + path, params) + data = json.loads(data) + except Exception as e: + log.ERR("No data/json received.", e) + return r + r += data["stations"] + if len(r) >= data["meta"]["total_count"] or len(data["stations"]) < 10: + break + else: + params["page"] = int(data["meta"]["current_page"]) + 1 + self.parent.status(params["page"] * 9.5 / float(conf.max_streams)) + #log.DATA(data) + return r + ADDED contrib/disabled/itunes.py Index: contrib/disabled/itunes.py ================================================================== --- contrib/disabled/itunes.py +++ contrib/disabled/itunes.py @@ -0,0 +1,108 @@ +# encoding: UTF-8 +# api: streamtuner2 +# title: iTunes Radio +# description: iTunes unsorted station list via RoliSoft Radio Playlist caching webservice. +# version: 0.1 +# type: channel +# category: radio +# url: http://www.itunes.com? +# status: broken +# priority: optional +# config: - +# png: +# iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAA3lJREFUOI1Fk01MHGUAht9vZnZml53dhcJSYIEVt8Tu1qbQRNI0wKGxiUk1HBpjbzUmatWUCzHe1Kjx0KQH5WA08aAXYzTRpKnSFG2kpB4ILEstP1skwC50f1nmf3Zmvvk8aOtzf05PHoL/YIyhWtpD +# JBKRlpZzp3YK+6OqpqcAIBaN/N2f6L57evhUTtM0p7O797EGAgC6puCNtyYx+c6b6YXsX1M75cMXHSLFebGFI4TAdy1fZM1qf2fsxnNDJ65/9fW369OfXUNLOAoy88tNFEpVDPQnRn+bX/qiZErPdiTTCMltgBAAYwClLpqGAmV/A52idf/c2aErxf3yvc72VpC5ubuQRC714425H+4/wnBfZgQk +# FAYlHIIBICoBMREQGMXmIw2F/AoyHe7SxQvjLzddusWNjY2Sheza23eWy8N+LIWKG0DNojjTS/DqmVa8Pt6N184lMTHSA9MBHHkAf+Sqpxdza1fGx8aIcG/+91R2tfjSniaD90PQPQFhniHdJaFNYlA1DaUDBgEEikugUAlFLYzsanHiz/k7Xwr7pdrwdsno1WkbKiaD6HHwgxx2azq+yevYhQxd +# dXG5x4HhARWTQfNC2C41+vbKtSFB0Yxe3WYSJSI0h0FiHMKcgEOPYjGcgCVHQKHCovuwXAbV8uFBgG4zSdPMhOBT6gUCHCM8AQQOPs/BA2BaJrggQ9ixkOEP0cq7oNR/0j7AE0apRwUCfyveKplczYkQz0Ofp2IkREENDdS1McbtYCJuw3QA13VBqAvOtxFvkwwCusVpykE2lZDzEcEErx5gIl7F +# +aMNUEsDMxwUKwaWHpbwa66GAwuAqSMqmHi6R95QGvVlfubWrLaSXZAdp/n8bs3jRGbDdmwsqjLUcBcaXBS5egBrShC2aoBWCxhJUu9EMnJ9aurdWf5QUdGol/KDT3U/Yzet9FIliDW7A0rLUXAEYE0HjumiWT+EVy7gZLuGs+noT3s7+U9v3Z61CAB8Pj2NzfzGwJGu5LX1Mp1YrQcCOhcDxBAY +# Y4BtQPYayMSpk+4Rf25UCu+ljg1uT169+u9MAPDhB+9jdfXBkeOZk6+4JHSpbrK03oQMALIIvT2MNYHZ360/WPk+nc40Pvr4k/9vfExQEmE3HXLhhfMdqWODx4Mt4QQAWKZR3Np8uH5z5nZdEgOs6bhPnH8APR+/sJEZQ8oAAAAASUVORK5CYII= +# documentation: http://lab.rolisoft.net/playlists.html +# +# API provides pre-parsed radio station playlists for various services +# +# → Shoutcast +# → Xiph/ICEcast +# → Tunein +# → iTunes +# → FilterMusic +# → SomaFM +# → AccuRadio +# → BBC +# +# In this module only iTunes will be queried for now. +# + +import re +from config import * +from channels import * +import ahttp + + +# Surfmusik sharing site +class itunes (ChannelPlugin): + + # control attribues + has_search = False + listformat = "pls" + titles = dict(listeners=False, bitrate=False, playing=False) + #base = "http://lab.rolisoft.net/playlists/itunes.php" + base = "http://aws-eu.rolisoft.net/playlists/itunes.php" + #base = "http://aws-us.rolisoft.net/playlists/itunes.php" + + categories = [ + "Adult Contemporary", + "Alternative Rock", + "Ambient", + "Blues", + "Classic Rock", + "Classical", + "College", + "Comedy", + "Country", + "Eclectic", + "Electronica", + "Golden Oldies", + "Hard Rock", + "Hip Hop", + "International", + "Jazz", + "News", + "Raggae", + "Religious", + "RnB", + "Sports Radio", + "Top 40", + "'70s Retro", + "'80s Flashback", + "'90s Hits", + ] + + + # static list for iTunes + def update_categories(self): + pass + + # Just copy over stream URLs and station titles + def update_streams(self, cat): + + m3u = ahttp.get(self.base, {"category": cat.lower()}) + if len(m3u) < 256: + log.ERR(m3u) + + rx_m3u = re.compile(r""" + ^File(\d+)\s*=\s*(http://[^\s]+)\s*$\s* + ^Title\1\s*=\s*([^\r\n]+)\s*$\s* + """, re.M|re.I|re.X) + + r = [] + for e in rx_m3u.findall(m3u): + r.append(dict( + genre = cat, + url = e[1], + title = e[2], + format = "audio/mpeg", + playing = "", + )) + + return r + DELETED contrib/icast.py Index: contrib/icast.py ================================================================== --- contrib/icast.py +++ contrib/icast.py @@ -1,101 +0,0 @@ -# encoding: UTF-8 -# api: streamtuner2 -# title: iCast.io -# description: Open collaborative stream directory -# version: 0.2 -# type: channel -# url: http://www.icast.io/ -# category: radio -# priority: obsolete -# config: - -# png: -# iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAcVQTFRF -# ////8PDw5OTk9/f3z9fYW3qnKFmLC0N9K1qVYYay2N7hl6zAHU6BYIqaqdDN4vvt9fzstuPeV42+JVmWn7TKi6XBFE+Og62t+/6f7/2MoMmMs+OPpdPDns/7ir/YGlehjqjE0tnfGFGTQXWuncmX6/tt -# 4vlvvfBv6vtsreGNbaXhdrTyXJXCY4m2JWStM2aZ4PhjtOhjy/FpeKioZaDoRYTAOXSpLGGgMXK/GlONlcxG1fZZfqyEX5XRY6TqPobZI2zCWJKqGVWbMHTHH12hT4BMt+0tgrFTfKt3XpG4WZfYR4vY -# NHrTK3TMRYTCIlmdM3bNKmy8KGGWgrs3UYRXSHp0TISKS4WaPXq4OXrENHrNO3zRPnitXpZ/aqJrRnd5Y5VPWYVXNGeTNnO1M2OiLmy+PYPdSo3eUZHaU5DLg7cxtOwNntIaYpVrMGittLvEKV+lQofd -# UZXoXp7rY6HfVoutsOUMQnOHdIurM2q2Y6TvbarqZJvFYpBlp9sSs+gMboag3t/dfZCqPWysSoLNYJvgYZSxfq5NNmF6MlmCcoab19nXqKyyZoSwTnawN2OfRGqXXXqanKKjzMzMt7e3o6SjsLKvtVfy -# AwAAAAFiS0dEBxZhiOsAAAAJcEhZcwAAAEgAAABIAEbJaz4AAADxSURBVBjTY2AAAUYmIGBkZoACRhZWNnZ2Dk4uqAgjNw8vH7+AoJCwCCOIzywqJi4hKSUtIysnrwBSo6ikrKKqpq6hqaWto6QIVKCr -# p69uYGBoZGxiYmrGyczAaG5haWVtbW1ja2fv4GjOyMDo5Ozi6ubu4enl7ePr5w8U8A8IDAoOCQ0Lj4iMigYJmDtHRcbExsUnJCYlR6YwMjCzpqalZ2SGZ2Vn5+TmsTIzMOcXFBYVl5TmZGeXlXPkgxxa -# UZleVV1TW1efyNYAdmpjU3NLq1Zbe0dnVzfEM0w9vX3N/RMmTmqEeZd58pSpU6dNBnsWAEP5Nco3FJZfAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE0LTA2LTAxVDAxOjI4OjA3KzAyOjAw7O+A+AAAACV0 -# RVh0ZGF0ZTptb2RpZnkAMjAxNC0wNi0wMVQwMToyODowNyswMjowMJ2yOEQAAAAASUVORK5CYII= -# documentation: http://api.icast.io/ -# -# -# A modern alternative to ShoutCast/ICEcast. -# Streams are user-contributed, but often lack -# meta data (homepage) and there's no ordering -# by listeneres/popularity. -# -# However it's every easy and stable to interface -# with over JSON. However it's also somewhat slow, -# because each query result has only 10 entries. -# Which is why reloading takes a few seconds to -# collect 200 station entries (see main options). - - -import re -import json -from config import * -from channels import * -import ahttp - - -# iCast.io API -class icast (ChannelPlugin): - - # control attributes - has_search = True - listformat = "pls" - titles = dict(listeners=False, bitrate=False, playing=False) - categories = [] - base = "http://api.icast.io/1/" - - - # Categories require little post-processing, just dict into list conversion - def update_categories(self): - self.categories = [] - for genre,cats in json.loads(ahttp.get(self.base + "genres"))["genres"].items(): - self.categories.append(genre.title()) - self.categories.append([c.title() for c in cats]) - - # Just copy over stream URLs and station titles - def update_streams(self, cat, search=None): - - if cat: - data = self.api("stations/genre/", cat.lower(), {}) - elif search: - data = self.api("stations/search", "", {"q": search}) - else: - pass - - r = [] - for e in data: - r.append(dict( - genre = " ".join(e["genre_list"]), - url = e["streams"][0]["uri"], - format = e["streams"][0]["mime"], - title = e["name"], - #playing = " ".join(e["current"].items()), - )) - - return r - - # fetch multiple pages - def api(self, method, path, params): - r = [] - while len(r) < int(conf.max_streams): - try: - data = ahttp.get(self.base + method + path, params) - data = json.loads(data) - except Exception as e: - log.ERR("No data/json received.", e) - return r - r += data["stations"] - if len(r) >= data["meta"]["total_count"] or len(data["stations"]) < 10: - break - else: - params["page"] = int(data["meta"]["current_page"]) + 1 - self.parent.status(params["page"] * 9.5 / float(conf.max_streams)) - #log.DATA(data) - return r - DELETED contrib/itunes.py Index: contrib/itunes.py ================================================================== --- contrib/itunes.py +++ contrib/itunes.py @@ -1,108 +0,0 @@ -# encoding: UTF-8 -# api: streamtuner2 -# title: iTunes Radio -# description: iTunes unsorted station list via RoliSoft Radio Playlist caching webservice. -# version: 0.1 -# type: channel -# category: radio -# url: http://www.itunes.com? -# status: broken -# priority: optional -# config: - -# png: -# iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAA3lJREFUOI1Fk01MHGUAht9vZnZml53dhcJSYIEVt8Tu1qbQRNI0wKGxiUk1HBpjbzUmatWUCzHe1Kjx0KQH5WA08aAXYzTRpKnSFG2kpB4ILEstP1skwC50f1nmf3Zmvvk8aOtzf05PHoL/YIyhWtpD -# JBKRlpZzp3YK+6OqpqcAIBaN/N2f6L57evhUTtM0p7O797EGAgC6puCNtyYx+c6b6YXsX1M75cMXHSLFebGFI4TAdy1fZM1qf2fsxnNDJ65/9fW369OfXUNLOAoy88tNFEpVDPQnRn+bX/qiZErPdiTTCMltgBAAYwClLpqGAmV/A52idf/c2aErxf3yvc72VpC5ubuQRC714425H+4/wnBfZgQk -# FAYlHIIBICoBMREQGMXmIw2F/AoyHe7SxQvjLzddusWNjY2Sheza23eWy8N+LIWKG0DNojjTS/DqmVa8Pt6N184lMTHSA9MBHHkAf+Sqpxdza1fGx8aIcG/+91R2tfjSniaD90PQPQFhniHdJaFNYlA1DaUDBgEEikugUAlFLYzsanHiz/k7Xwr7pdrwdsno1WkbKiaD6HHwgxx2azq+yevYhQxd -# dXG5x4HhARWTQfNC2C41+vbKtSFB0Yxe3WYSJSI0h0FiHMKcgEOPYjGcgCVHQKHCovuwXAbV8uFBgG4zSdPMhOBT6gUCHCM8AQQOPs/BA2BaJrggQ9ixkOEP0cq7oNR/0j7AE0apRwUCfyveKplczYkQz0Ofp2IkREENDdS1McbtYCJuw3QA13VBqAvOtxFvkwwCusVpykE2lZDzEcEErx5gIl7F -# +aMNUEsDMxwUKwaWHpbwa66GAwuAqSMqmHi6R95QGvVlfubWrLaSXZAdp/n8bs3jRGbDdmwsqjLUcBcaXBS5egBrShC2aoBWCxhJUu9EMnJ9aurdWf5QUdGol/KDT3U/Yzet9FIliDW7A0rLUXAEYE0HjumiWT+EVy7gZLuGs+noT3s7+U9v3Z61CAB8Pj2NzfzGwJGu5LX1Mp1YrQcCOhcDxBAY -# Y4BtQPYayMSpk+4Rf25UCu+ljg1uT169+u9MAPDhB+9jdfXBkeOZk6+4JHSpbrK03oQMALIIvT2MNYHZ360/WPk+nc40Pvr4k/9vfExQEmE3HXLhhfMdqWODx4Mt4QQAWKZR3Np8uH5z5nZdEgOs6bhPnH8APR+/sJEZQ8oAAAAASUVORK5CYII= -# documentation: http://lab.rolisoft.net/playlists.html -# -# API provides pre-parsed radio station playlists for various services -# -# → Shoutcast -# → Xiph/ICEcast -# → Tunein -# → iTunes -# → FilterMusic -# → SomaFM -# → AccuRadio -# → BBC -# -# In this module only iTunes will be queried for now. -# - -import re -from config import * -from channels import * -import ahttp - - -# Surfmusik sharing site -class itunes (ChannelPlugin): - - # control attribues - has_search = False - listformat = "pls" - titles = dict(listeners=False, bitrate=False, playing=False) - #base = "http://lab.rolisoft.net/playlists/itunes.php" - base = "http://aws-eu.rolisoft.net/playlists/itunes.php" - #base = "http://aws-us.rolisoft.net/playlists/itunes.php" - - categories = [ - "Adult Contemporary", - "Alternative Rock", - "Ambient", - "Blues", - "Classic Rock", - "Classical", - "College", - "Comedy", - "Country", - "Eclectic", - "Electronica", - "Golden Oldies", - "Hard Rock", - "Hip Hop", - "International", - "Jazz", - "News", - "Raggae", - "Religious", - "RnB", - "Sports Radio", - "Top 40", - "'70s Retro", - "'80s Flashback", - "'90s Hits", - ] - - - # static list for iTunes - def update_categories(self): - pass - - # Just copy over stream URLs and station titles - def update_streams(self, cat): - - m3u = ahttp.get(self.base, {"category": cat.lower()}) - if len(m3u) < 256: - log.ERR(m3u) - - rx_m3u = re.compile(r""" - ^File(\d+)\s*=\s*(http://[^\s]+)\s*$\s* - ^Title\1\s*=\s*([^\r\n]+)\s*$\s* - """, re.M|re.I|re.X) - - r = [] - for e in rx_m3u.findall(m3u): - r.append(dict( - genre = cat, - url = e[1], - title = e[2], - format = "audio/mpeg", - playing = "", - )) - - return r -