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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [fac6bc374a]

Overview
Comment:streema: fix url regex (now alphanumeric titles) and urn_resolve patterns for new player layout
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fac6bc374af603a232416444dced8fc226733c79
User & Date: mario on 2019-06-14 18:25:28
Other Links: manifest | tags
Context
2019-07-15
14:38
vTuner: minor fix from stream_update regex check-in: 4419f22d5d user: mario tags: trunk
2019-06-14
18:25
streema: fix url regex (now alphanumeric titles) and urn_resolve patterns for new player layout check-in: fac6bc374a user: mario tags: trunk
2019-03-24
11:50
Switched radionet plugin to resolve_urn() and speedier
-grep loop.
check-in: 9688154862 user: mario tags: trunk
Changes

Modified contrib/streema.py from [46c666d039] to [147f9871b4].

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
# api: streamtuner2
# title: Streema
# description: Directory and app for over 70.000 stations
# type: channel
# category: radio
# version: 0.3
# url: http://www.streema.com/
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABF0lEQVR42oWTMWsCURCE/Y/Bxh+QLrUIloKdELCxTOOBRSSgpZVYhCAWCtcEETGQJmCTkG7k47HcereeA4vnu32zszt7jceRFMXDQGoN
#   pd40RXci9d+kpxep+VzkNaLLXBzMpe1R+vu/jq8fabxKOSEBL6YfqgVEnSwgsMoen9+JcJlL5990xv9QAYf5qbhMC/RrQf/trLgctoA8A/0yPCO38PkVApPpAdFsndyoJeDlaKFarPZ3FJj3i12qHIEh
#   sichgSfi18j8bHDmpgvlQfFMNe/O5hAoMOnMoJMVRNjHCnsFbGKFgCl7IJPloZoHLrEPlRYi+8ogh724uUiv72ny0QeEQl+5QmDDIomeLVhdzuzzLrt1AQVnVKF/yji7AAAAAElFTkSuQmCC
# config: -
# priority: optional
# extraction-method: regex, action-handler
#
# Streema lists over 70000 radio stations. Requires a double lookup
# however, as stream addresses are embedded in the web player only.
# It does only poll one page of results.
#
# Currently playing field is quite spotty. No homepages are listed.
# The category map is prepared here, because it's quite slow to
# update. Region/city categories are left unused.
#
# The server search function is implemented however.
#


import re
import ahttp
from config import *
from channels import *


# streema.com
class streema (ChannelPlugin):





|











|









|







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
# api: streamtuner2
# title: Streema
# description: Directory and app for over 70.000 stations
# type: channel
# category: radio
# version: 0.4
# url: http://www.streema.com/
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABF0lEQVR42oWTMWsCURCE/Y/Bxh+QLrUIloKdELCxTOOBRSSgpZVYhCAWCtcEETGQJmCTkG7k47HcereeA4vnu32zszt7jceRFMXDQGoN
#   pd40RXci9d+kpxep+VzkNaLLXBzMpe1R+vu/jq8fabxKOSEBL6YfqgVEnSwgsMoen9+JcJlL5990xv9QAYf5qbhMC/RrQf/trLgctoA8A/0yPCO38PkVApPpAdFsndyoJeDlaKFarPZ3FJj3i12qHIEh
#   sichgSfi18j8bHDmpgvlQfFMNe/O5hAoMOnMoJMVRNjHCnsFbGKFgCl7IJPloZoHLrEPlRYi+8ogh724uUiv72ny0QeEQl+5QmDDIomeLVhdzuzzLrt1AQVnVKF/yji7AAAAAElFTkSuQmCC
# config: -
# priority: optional
# extraction-method: regex, action-handler
#
# Streema lists over 70000 radio stations. Requires a double lookup
# however, as stream addresses are embedded in the web player only.
# Channel only polls one page of results, skips external stream pages.
#
# Currently playing field is quite spotty. No homepages are listed.
# The category map is prepared here, because it's quite slow to
# update. Region/city categories are left unused.
#
# The server search function is implemented however.
#


import re, traceback
import ahttp
from config import *
from channels import *


# streema.com
class streema (ChannelPlugin):
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
        else:
            return
        
        # split into blocks
        for html in re.split('<div[^>]+?(?:data-role="player-popup"|class="item")', html):

            # not very efficient
            url = re.findall('data-url="/radios/play/(\d+)"', html)
            homepage = re.findall('data-profile-url="/radios/(.+?)"', html)
            title = re.findall('title="Play (.+?)"', html)
            img = re.findall('<img\s*src="(.+?)"', html)
            playing = re.findall('<span class="now-playing-text">(.*?)</span>', html, re.S)
            genre = re.findall('<p class="genre">(.*?)</p>', html, re.S)
            listeners = re.findall('<p>(\d+) Listen\w*s</p>', html)

            # catch absent fields
            try:
                r.append(dict(
                   url = "urn:streema:" + url[0],
                   homepage = self.base + "/" + homepage[0],
                   title = title[0],
                   img = img[0],
                   img_resize = 24,
                   playing = playing[0],
                   genre = unhtml(genre[0]),
                   listeners = to_int(listeners[0])
                ))
            except:


                pass #some field missing
        
        # done
        return r


    # load page and get first download url (there's four, but usually identical)
    def resolve_urn(self, row):
        if row.get("url", "-").find("urn:streema:") != 0:
            return
        id = row["url"][12:]
        html = ahttp.get("http://streema.com/radios/play/%s" % id)

        url = re.findall('<ul class="stream-downloads">.+?<a href="(.+?)"', html, re.S)





        if not url:
            return
        row["url"] = url[0]










|




















>
>












>
|
>
>
>
>
>
|
<
|
>
>

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
114
115
116

117
118
119
120
        else:
            return
        
        # split into blocks
        for html in re.split('<div[^>]+?(?:data-role="player-popup"|class="item")', html):

            # not very efficient
            url = re.findall('data-url="/radios/play/([\w_.-]+)"', html)   # skips external-stream-tab http:// entries
            homepage = re.findall('data-profile-url="/radios/(.+?)"', html)
            title = re.findall('title="Play (.+?)"', html)
            img = re.findall('<img\s*src="(.+?)"', html)
            playing = re.findall('<span class="now-playing-text">(.*?)</span>', html, re.S)
            genre = re.findall('<p class="genre">(.*?)</p>', html, re.S)
            listeners = re.findall('<p>(\d+) Listen\w*s</p>', html)

            # catch absent fields
            try:
                r.append(dict(
                   url = "urn:streema:" + url[0],
                   homepage = self.base + "/" + homepage[0],
                   title = title[0],
                   img = img[0],
                   img_resize = 24,
                   playing = playing[0],
                   genre = unhtml(genre[0]),
                   listeners = to_int(listeners[0])
                ))
            except:
                #log.E(e)
                #traceback.print_exc()
                pass #some field missing
        
        # done
        return r


    # load page and get first download url (there's four, but usually identical)
    def resolve_urn(self, row):
        if row.get("url", "-").find("urn:streema:") != 0:
            return
        id = row["url"][12:]
        html = ahttp.get("http://streema.com/radios/play/%s" % id)
        patterns = [
            '<ul class="stream-downloads">.+?<a href="(.+?)"',
            "<source src='(.+?)'",
            'stream:\s+\{.+?\s+url:\s+"(.+?)"'
        ]
        for rx in patterns:
            url = re.findall(rx, html, re.S)
            if url:

                row["url"] = url[0]
                return url[0]
        return