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): |