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
|
# config: -
# png:
# iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABB0lEQVR4nLWTQUpDMRCGv0lregDBI3gAfW/hRrp8ZOMh5PUMXkFcu7EbTxHd
# CC4EhfQkQg/QR5txYQqvMdVHwdnMZJj555uQwH+YurpaNZUOqTWl5i5qGIusDxIAZgBGuBhCsiOgrq7WUa+tkReAjepHystQgmn8zt0As40y
# skYa4HwfSS5w2otd8svtWurqHyvnCZcXAHRRW7v8nANnq6bSPk0ucFQS+M3G2fkduMqLrJF5d3zSTnyYATsXmhO89WLfix8A1NWjvwhek5+m
# praLGibPC8knFwnEh4U1ct9FvUvoLk0uPbjiCgCPyd+KD0/WyKX4EPcJFLG2/8EaMeLDoE91sH0B3ERWq2CKMoYAAAAASUVORK5CYII=
# priority: extra
# extraction-method: regex, action-handler
#
# LiveRadio.ie, based in Ireland, is a radio station directory. It provides
# genre or country browsing (not in this plugin). It accepts user submissions.
#
# This channel loads their station logos as favicons, provides a live search.
#
# However, station URLs have to be fetched in a second page request. Such
# the listings are unsuitable for exporting right away. OTOH the website is
# pretty fast; so no delay there or in fetching complete categories.
import re
from config import *
from channels import *
import ahttp
import action
# Just a blog, needs per-page lookup
class liveradio (ChannelPlugin):
# control flags
has_search = True
listformat = "srv"
audioformat = "audio/mpeg"
titles = dict(listeners=False, bitrate=False, playing="Location")
fixed_size = 30
img_resize = [30,30]
# data store
categories = ["Top 20"]
catmap = {"Top 20":"top-20"}
base = "http://www.liveradio.ie/"
# static
def update_categories(self):
html = ahttp.get("http://www.liveradio.ie/genres")
self.categories = ["Top 20"]
for row in re.findall(r"""<a href="/(stations/genre-[\w-]+)">([^<]+)</a>""", html):
self.categories.append(unhtml(row[1]))
self.catmap[unhtml(row[1])] = unhtml(row[0])
# Fetch entries
def update_streams(self, cat, search=None):
# fetch
html = ""
page = 1
while page < 9:
page_sfx = "/%s"% page if page > 1 else ""
if cat:
add = ahttp.get(self.base + self.catmap[cat] + page_sfx)
elif search:
add = ahttp.get(self.base + "stations" + page_sfx, { "text": search, "country_id": "", "genre_id": ""})
html += add
if re.search('/\d+">Next</a>', add):
page += 1
else:
break
# extract
r = []
ls = re.findall("""
itemtype="http://schema.org/RadioStation"> .*?
href="/stations/([\w-]+) .*?
<img\s+src="/(files/images/[^"]+)" .*?
="country">([^<]+)< .*?
itemprop="name"><a[^>]+>([^<]+)</a> .*?
|
>
|
>
|
>
>
|
|
|
|
>
>
>
>
>
>
|
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
89
90
91
92
93
94
95
|
# config: -
# png:
# iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABB0lEQVR4nLWTQUpDMRCGv0lregDBI3gAfW/hRrp8ZOMh5PUMXkFcu7EbTxHd
# CC4EhfQkQg/QR5txYQqvMdVHwdnMZJj555uQwH+YurpaNZUOqTWl5i5qGIusDxIAZgBGuBhCsiOgrq7WUa+tkReAjepHystQgmn8zt0As40y
# skYa4HwfSS5w2otd8svtWurqHyvnCZcXAHRRW7v8nANnq6bSPk0ucFQS+M3G2fkduMqLrJF5d3zSTnyYATsXmhO89WLfix8A1NWjvwhek5+m
# praLGibPC8knFwnEh4U1ct9FvUvoLk0uPbjiCgCPyd+KD0/WyKX4EPcJFLG2/8EaMeLDoE91sH0B3ERWq2CKMoYAAAAASUVORK5CYII=
# priority: extra
# x-elevate: priority:default
# extraction-method: regex, action-handler
#
# LiveRadio.ie, based in Ireland, is a radio station directory. It provides
# genre or country browsing (not in this plugin). Already lists over 5550
# stations (more unique selections). Also accepts user submissions.
#
# This channel loads their station logos as favicons. Even allows to utilize
# the live search function.
#
# However, station URLs have to be fetched in a second page request. Such
# the listings are unsuitable for exporting right away. OTOH the website is
# pretty fast; so no delay there or in fetching complete categories.
#
import re
from config import *
from channels import *
import ahttp
import action
# Categorized directory, secondary URL lookup
class liveradio (ChannelPlugin):
# control flags
has_search = True
listformat = "srv"
audioformat = "audio/mpeg"
titles = dict(listeners=False, bitrate=False, playing="Location")
fixed_size = 30
img_resize = [30,30]
# data store
categories = ["Top 20"]
catmap = {"Top 20":"top-20"}
base = "http://www.liveradio.ie/"
# Extract genre links and URL aliases (e.g. "Top 20" maps to "/top-20")
def update_categories(self):
html = ahttp.get("http://www.liveradio.ie/genres")
self.categories = ["Top 20"]
for row in re.findall(r"""<a href="/(stations/genre-[\w-]+)">([^<]+)</a>""", html):
self.categories.append(unhtml(row[1]))
self.catmap[unhtml(row[1])] = unhtml(row[0])
# Fetch entries
def update_streams(self, cat, search=None):
# Assemble HTML (collect 1..9 into single blob prior extraction)
html = ""
page = 1
while page < 9:
page_sfx = "/%s"% page if page > 1 else ""
if cat:
add = ahttp.get(self.base + self.catmap[cat] + page_sfx)
elif search:
add = ahttp.get(self.base + "stations" + page_sfx, { "text": search, "country_id": "", "genre_id": ""})
html += add
if re.search('/\d+">Next</a>', add):
page += 1
else:
break
# Extract all the things
#
# ยท entries utilize HTML5 microdata classification
# ยท title and genre available right away
# ยท img url is embedded
# ยท keep station ID as `urn:liveradion:12345`
#
r = []
ls = re.findall("""
itemtype="http://schema.org/RadioStation"> .*?
href="/stations/([\w-]+) .*?
<img\s+src="/(files/images/[^"]+)" .*?
="country">([^<]+)< .*?
itemprop="name"><a[^>]+>([^<]+)</a> .*?
|
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
img = self.base + img,
img_resize = 32
))
return r
# Update `url` on station data access (incurs a delay for playing or recording)
def resolve_urn(self, row):
if row.get("url").startswith("urn:liveradio"):
id = row["url"].split(":")[2]
html = ahttp.get(self.base + "stations/" + id)
ls = re.findall("jPlayer\('setMedia',\s*\{\s*'?\w+'?:\s*'([^']+)'", html, re.M)
if ls:
row["url"] = unhtml(ls[0])
else:
log.ERR("No stream found on %s" % row["homepage"])
return row
|
>
>
>
>
>
|
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
img = self.base + img,
img_resize = 32
))
return r
# Update `url` on station data access (incurs a delay for playing or recording)
#
# ยท utilizes action.handler["urn:liveradio"] โ urn_resolve hook
# ยท where the .update_streams() extraction stores `urn:liveradio:12345` as urls
# ยท and this callback extracts the JS invocation URL from liveradio.de station summaries
#
def resolve_urn(self, row):
if row.get("url").startswith("urn:liveradio"):
id = row["url"].split(":")[2]
html = ahttp.get(self.base + "stations/" + id)
ls = re.findall("jPlayer\('setMedia',\s*\{\s*'?\w+'?:\s*'([^']+)'", html, re.M)
if ls:
row["url"] = unhtml(ls[0])
else:
log.ERR("No stream found on %s" % row["homepage"])
return row
|