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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [4836962bd4]

Overview
Comment:Ah, Shoutcast, switching again. → HTML extraction is now JS lexing → {genreid:} is now {genrename:}
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4836962bd47132eb0b783450192476ef77b66ca0
User & Date: mario on 2014-08-05 02:39:46
Other Links: manifest | tags
Context
2014-08-05
02:42
Optional homepage querying, stripping musicgoal stream_urls. check-in: 2b60750fdf user: mario tags: trunk
02:39
Ah, Shoutcast, switching again. → HTML extraction is now JS lexing → {genreid:} is now {genrename:} check-in: 4836962bd4 user: mario tags: trunk
2014-08-01
01:35
Initial support for Dirble.com, provides grouped categories and search feature. check-in: 7965619312 user: mario tags: trunk
Changes

Modified channels/shoutcast.py from [f86f5c5147] to [ffcf202481].

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
#
# api: streamtuner2
# title: Shoutcast.com
# description: Primary list of shoutcast servers (now managed by radionomy).
# type: channel
# category: radio
# priority: default
# version: 1.4
# depends: pq, re, http
# author: Mario
# original: Jean-Yves Lefort
#
# Shoutcast is a server software for audio streaming. It automatically spools
# station information on shoutcast.com
# It has been aquired by Radionomy in 2014, since then significant changes
# took place. The former YP got deprecated, now seemingly undeprecated.
#
#   http://wiki.winamp.com/wiki/SHOUTcast_Radio_Directory_API 
#
# But neither their Wiki nor Bulletin Board provide concrete information on
# the eligibility of open source desktop apps for an authhash.
#
# Therefore we'll be retrieving stuff from the homepage still. The new
# interface conveniently uses JSON already, so let's use that:
#
#   POST http://www.shoutcast.com/Home/BrowseByGenre {genreid: 9}
#
# We do need a catmap now too, but that's easy to aquire and will be kept
# within the cache dirs.
#
#
#








|

















|







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
#
# api: streamtuner2
# title: Shoutcast.com
# description: Primary list of shoutcast servers (now managed by radionomy).
# type: channel
# category: radio
# priority: default
# version: 1.5
# depends: pq, re, http
# author: Mario
# original: Jean-Yves Lefort
#
# Shoutcast is a server software for audio streaming. It automatically spools
# station information on shoutcast.com
# It has been aquired by Radionomy in 2014, since then significant changes
# took place. The former YP got deprecated, now seemingly undeprecated.
#
#   http://wiki.winamp.com/wiki/SHOUTcast_Radio_Directory_API 
#
# But neither their Wiki nor Bulletin Board provide concrete information on
# the eligibility of open source desktop apps for an authhash.
#
# Therefore we'll be retrieving stuff from the homepage still. The new
# interface conveniently uses JSON already, so let's use that:
#
#   POST http://www.shoutcast.com/Home/BrowseByGenre {genrename: Pop}
#
# We do need a catmap now too, but that's easy to aquire and will be kept
# within the cache dirs.
#
#
#

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
        
    # Extracts the category list from www.shoutcast.com,
    # stores a catmap (title => id)
    def update_categories(self):
        html = http.get(self.base_url)
        #__print__( dbg.DATA, html )
        self.categories = []

        # Main genres from mobile dropdown
        """ <option value="1">Alternative</option> """
        rx = re.compile(r'<option value="(\d+)">(\w+\h*\w+)<')
        main = rx.findall(html)
        # Genre list in sidebar
        """ <li><a href="#c-genre-2" onclick="loadStationsByGenre(2, true)">Adult Alternative</a></li> """
        rx = re.compile(r'c-genre-(\d+).+?>(\w[\w\h]*\w)<')
        subs = rx.findall(html)
        print main
        print subs

        # group

        for (id, title) in subs:

            if (id,title) in main:
                self.categories.append(title)
                current = []
                self.categories.append(current)
            else:
                current.append(title)
            self.catmap[title] = int(id)
        self.save()


    # downloads stream list from shoutcast for given category
    def update_streams(self, cat):

        if (cat not in self.catmap):
            __print__( dbg.ERR, "nocat" )
            return []
        id = self.catmap[cat]

        # page
        url = "http://www.shoutcast.com/Home/BrowseByGenre"
        params = { "genreid": int(id) }
        referer = None
        json = http.get(url, params=params, referer=referer, post=1, ajax=1)
        self.parent.status(0.75)

        # remap JSON
        entries = []
        for e in json_decode(json):







|
<
<
<
<

|
|

<
<


>
|
>
|





<













|







70
71
72
73
74
75
76
77




78
79
80
81


82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
        
    # Extracts the category list from www.shoutcast.com,
    # stores a catmap (title => id)
    def update_categories(self):
        html = http.get(self.base_url)
        #__print__( dbg.DATA, html )
        self.categories = []
        




        # Genre list in sidebar
        """  <li><a id="genre-90" href="/Genre?name=Adult" onclick="loadStationsByGenre('Adult', 90, 89); return false;">Adult</a></li> """
        rx = re.compile(r"loadStationsByGenre\(  '([^']+)' [,\s]* (\d+) [,\s]* (\d+)  \)", re.X)
        subs = rx.findall(html)



        # group
        current = []
        for (title, id, main) in subs:
            self.catmap[title] = int(id)
            if not int(main):
                self.categories.append(title)
                current = []
                self.categories.append(current)
            else:
                current.append(title)

        self.save()


    # downloads stream list from shoutcast for given category
    def update_streams(self, cat):

        if (cat not in self.catmap):
            __print__( dbg.ERR, "nocat" )
            return []
        id = self.catmap[cat]

        # page
        url = "http://www.shoutcast.com/Home/BrowseByGenre"
        params = { "genrename": cat }
        referer = None
        json = http.get(url, params=params, referer=referer, post=1, ajax=1)
        self.parent.status(0.75)

        # remap JSON
        entries = []
        for e in json_decode(json):