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

⌈⌋ branch:  streamtuner2


Diff

Differences From Artifact [29c966c64c]:

To Artifact [460ab10c07]:


40
41
42
43
44
45
46
47
48














49
50
51
52
53
54
55
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







-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+






action.extract_playlist.extr_urls["rnjs"] = dict(
    url   = r" (?x) \"streamUrl\" \s*:\s* \"(\w+:\\?/\\?/[^\"]+)\" ",
    title = r" (?x) \"(?:description|seoTitle)\" \s*:\s* \"([^\"]+)\" ",
    unesc = "json",
)


# Radio.net extraction relies on HTML grepping, finding an api key required for station details,
# and letting the action module extract the station/stream URL from that JSON format.
# Radio.net
#
# · Uses HTML block-wise regex extraction.
#   → <a href="stationname.radio.net"> <img…> <strong>…</strong> <small>…</small>
#
# · There's an API key in each page listing, contained in a script block
#   as `apiKey: '…'?`
#
# · Which is needed for generating the station info JSON urls:
#   → https://api.radio.net/info/v2/search/station?apikey=…&pageindex=1&station=STNAME
#
# · To extract these JSON info targets, a custom extraction recipie is injected
#   into the action module.
#   → "streamUrl": and "description": are scanned for.
#
class radionet (ChannelPlugin):

    # control flags
    has_search = False
    audioformat = "audio/mpeg"
    listformat = "rnjs"
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
87
88
89
90
91
92
93

94


















95
96
97
98
99

100
101
102
103
104
105
106
107







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+






        # category page, get key
        html = ahttp.get(self.genre_url.format(cat))
        for p in range(2, 4):
            if html.find('"?p={}">'.format(p)) >= 0:
                html += ahttp.get(self.genre_url.format(cat) + "?p={}".format(p))
        self.set_key(html)
        r = []
        """

        <div class="stationinfo-content">Fresh pop music, R&#039;n&#039;B, the newest chart hits and the Top 40 can all be found on this Internet radio station, ANTENNE BAYERN.</div>
        </div><div class="stationinfo   stationinfo-extended  "  expandable ng-cloak >
        <a href="http://antennefrankfurt.radio.net/" class="stationinfo-link" id="">
        <svg class="icon icon-play" id=""><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-play" id=""></use></svg>
        <img src="http://static.radio.net/images/broadcasts/60/cf/19304/c44.png" onError="this.src=window.stationLogo;" alt="ANTENNE FRANKFURT 95.1 " id="">
        <strong id="">
        <svg class="icon icon-podcast"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-podcast"></use></svg>
        <span highlight-text="Top 40" highlight-class="highlight-tags" id="">antenne frankfurt 95.1 </span>
        </strong>
        <small highlight-text="Top 40" highlight-class="highlight-tags" id="">
        Frankfurt am Main, Germany / Charts, News, Pop, Top 40, News, Weather</small>
        <em now-playing="19304" searched-term="Top 40" id=""></em>
        </a>
        <a class="stationinfo-info-toggle" href="" ng-click="toggle()">
        <svg class="icon icon-arrow-up"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-arrow-up"></use></svg>
        <svg class="icon icon-arrow-down"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-arrow-down"></use></svg>
        </a>
        """
        # split station blocks
        for row in re.split("""<div class="stationinfo""", html)[1:]:
        
            # extract text fields
            d = re.findall("""
              <a\s+href="(?:http:)?(//([\w-]+)\.radio\.net/?)" .*?
              <a\s+href="(?:https?:)?(//([\w-]+)\.radio\.net/?)" .*?
              <img\s+src="([^<">]+)" .*?
              <strong[^>]*>(.*?)</strong> .*?
              <small[^>]*>\s*(.*?)\s*</small> .*?
            """, row, re.X|re.S)
            
            # refurbish extracted strings
            if d and len(d) and len(d[0]) == 5: