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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [26b942d018]

Overview
Comment:New channel module "iCast.io" as seen in VLC lua scripts. (Quite efficient, but station entries of medium quality.)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 26b942d018457d981f1927c30b1a0ab44dba1c81
User & Date: mario on 2014-05-30 23:22:47
Original Comment: New channel module "iCast.io" as seen in VLC lua scripts. (Quite efficient, but station entries of medium quality.)
Other Links: manifest | tags
Context
2014-05-31
09:01
new iTunes Radio stations channel (via RoliSoft Radio Playlist generator API.) check-in: 72fbdf4b92 user: mario tags: trunk
2014-05-30
23:22
New channel module "iCast.io" as seen in VLC lua scripts. (Quite efficient, but station entries of medium quality.) check-in: 26b942d018 user: mario tags: trunk
23:21
Better cleaup of regex-extracted entries. check-in: a2142151c0 user: mario tags: trunk
Changes

Added channels/icast.py version [0e4b7862b4].

























































































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: iCast
# description: Open collaborative stream directory
# version: 0.1
# type: channel
# category: radio
# priority: optional
# 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.
#
# OTOH it's every easy to interface with. Though the repeated API queries
# due to 10-entries-per-query results make fetching slow.
#
#
#

import re
import json
from config import conf, dbg, __print__
from channels import *
import ahttp as http


# Surfmusik sharing site
class icast (ChannelPlugin):

    # description
    title = "iCast"
    module = "icast"
    homepage = "http://www.icast.io/"
    has_search = True
    listformat = "audio/x-scpls"
    titles = dict(listeners=False, bitrate=False, playing=False)

    categories = []
    config = [
    ]    
    
    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(http.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):
            data = json.loads(http.get( self.base + method + path, params))
            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))
            #__print__(dbg.DATA, data)
        return r