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

⌈⌋ branch:  streamtuner2


Check-in [979614a6d9]

Overview
Comment:new plugin: liveradio.ie
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:979614a6d99dd5a2f339ff6dde7a0c3c8b3527d5
User & Date: mario on 2016-11-20 16:05:28
Other Links: manifest | tags
Context
2016-11-20
16:09
Support .QTL output format check-in: 08a43fb795 user: mario tags: trunk
16:05
new plugin: liveradio.ie check-in: 979614a6d9 user: mario tags: trunk
16:04
Fixed category assembly (last entries for Urban were missing) check-in: 5844bca11c user: mario tags: trunk
Changes

Added contrib/liveradio.py version [d6d8086730].



































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
# encoding: UTF-8
# api: streamtuner2
# title: Liveradio.ie
# description: Irish/worldwide radio station directory
# url: http://liveradio.ie/
# version: 0.2
# type: channel
# category: radio
# config: -
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABB0lEQVR4nLWTQUpDMRCGv0lregDBI3gAfW/hRrp8ZOMh5PUMXkFcu7EbTxHd
#    CC4EhfQkQg/QR5txYQqvMdVHwdnMZJj555uQwH+YurpaNZUOqTWl5i5qGIusDxIAZgBGuBhCsiOgrq7WUa+tkReAjepHystQgmn8zt0As40y
#    skYa4HwfSS5w2otd8svtWurqHyvnCZcXAHRRW7v8nANnq6bSPk0ucFQS+M3G2fkduMqLrJF5d3zSTnyYATsXmhO89WLfix8A1NWjvwhek5+m
#    praLGibPC8knFwnEh4U1ct9FvUvoLk0uPbjiCgCPyd+KD0/WyKX4EPcJFLG2/8EaMeLDoE91sH0B3ERWq2CKMoYAAAAASUVORK5CYII=
# priority: extra
#
# 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> .*?
           class="genre">([^<]+)<
        """, html, re.X|re.S)
        for row in ls:
            log.DATA(row)
            id, img, country, title, genre = row
            r.append(dict(
                homepage = self.base + "stations/" + id,
                url = "urn:liveradio:" + id,
                playing = unhtml(country),
                title = unhtml(title),
                genre = unhtml(genre),
                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