Internet radio browser GUI for music/video streams from various directory services.

⌈⌋ branch:  streamtuner2

Artifact [5eb14dba9a]

Artifact 5eb14dba9af312062209409b91c182cee4512b3d:

# encoding: utf-8
# api: streamtuner2
# title: Links to directory services
# description: Static list of various music directory websites.
# type: group
# category: web
# version: 0.4
# priority: standard
# config: -
# Simply adds a "links" entry in bookmarks tab, where known services
# are listed with homepage links. Registered plugins automatically
# end up on top of that list.

from config import *
from channels import *
import ahttp
import copy, json, re

# hooks into main.bookmarks
class links (FeaturePlugin):

    # list
    streams = [    ]
    default = [
        ("stream", "RadioTower", ""),
        ("stream", "8tracks", ""),
        ("stream", "Jango", ""),
        ("stream", "", ""),
        ("stream", "StreamFinder", ""),
        ("stream", "Rhapsody (US-only)", ""),
        ("stream", "Pirateradio Network", ""),
        ("stream", "radio-locator", ""),
        ("stream", "Radio Station World", ""),
        ("stream", "iHeart", ""),
        ("download", "Live Music Archive(.org)", ""),
        ("download", "FMA, free music archive", ""),
        ("download", "Audiofarm", ""),
        ("stream", "SoundCloud", ""),
        ("download", "ccMixter", ""),
        ("stream", "Hype Machine", ""),
        ("download", "Amazon Free MP3s", ""),
        ("download", "ccTrax", ""),
        ("list", "WP: Streaming music services", ""),
        ("list", "WP: Music databases", ""),
        ("commercial", "Google Play Music", ""),
        ("commercial", "Deezer", ""),

    # prepare gui
    def init2(self, parent):
        if not parent:
        self.bookmarks = parent.bookmarks

        # prepare target category
        if not self.bookmarks.streams.get(self.module):
            self.bookmarks.streams[self.module] = self.streams
        self.bookmarks.add_category(self.module, self)

    def update_streams(self, cat="links"):
        del self.streams[:]
        # Collect links from channel plugins
        for name,channel in self.parent.channels.items():
                    "favourite": 1,
                    "genre": "channel",
                    "title": channel.meta.get("title", channel.module),
                    "homepage": channel.meta.get("url", ""),
                    "format": "text/html",
            except Exception as e:
                log.ERR("links: adding entry failed:", e)
        # Add wiki or built-in link list
        for row in self.default:
            (genre, title, homepage) = row
                "genre": genre,
                "title": title,
                "homepage": homepage,
                "type": "text/html",

        # add to bookmarks
        return self.streams

    # retrieve links from repository wiki page (via JSON API /json/wiki/get/…)
    def from_wiki(self):
        src = ahttp.get("", timeout=2)
        if not src:
        wiki = json.loads(src)
        if not wiki or not wiki.get("payload"):
        wiki = wiki["payload"]["content"]
        pairs = re.findall("(?:(\w+)\s*\|\s*)?\[([\w\s(&,;!:#+\-)]+)\]\((http[^)\s]+)\)", wiki)
        if not pairs:
        self.default = [(cat if cat else "site", title, url) for cat,title,url in pairs]