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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [846623040b]

Overview
Comment:Enhance configurability of language, remove default categories.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 846623040b2bf39d1f1a5024f96b1f9c200e1b09
User & Date: mario on 2014-05-30 23:21:12
Other Links: manifest | tags
Context
2014-05-30
23:21
Better cleaup of regex-extracted entries. check-in: a2142151c0 user: mario tags: trunk
23:21
Enhance configurability of language, remove default categories. check-in: 846623040b user: mario tags: trunk
2014-05-28
19:53
English-localized version of SurfMusic.de now supported check-in: 4db7cbeed2 user: mario tags: trunk
Changes

Modified channels/surfmusik.py from [d30a39ab13] to [38f14e35ce].

1
2
3
4
5
6
7
8
9
10
11
12
# encoding: UTF-8
# api: streamtuner2
# title: SurfMusik
# description: User collection of streams categorized by region and genre.
# version: 0.4
# type: channel
# category: radio
# author: gorgonz123
# source: http://forum.ubuntuusers.de/topic/streamtuner2-zwei-internet-radios-anhoeren-au/3/
# recognizes: max_streams
#
# This plugin comes in German (SurfMusik) and English (SurfMusic) variations.




|







1
2
3
4
5
6
7
8
9
10
11
12
# encoding: UTF-8
# api: streamtuner2
# title: SurfMusik
# description: User collection of streams categorized by region and genre.
# version: 0.5
# type: channel
# category: radio
# author: gorgonz123
# source: http://forum.ubuntuusers.de/topic/streamtuner2-zwei-internet-radios-anhoeren-au/3/
# recognizes: max_streams
#
# This plugin comes in German (SurfMusik) and English (SurfMusic) variations.
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# Surfmusik sharing site
class surfmusik (ChannelPlugin):

    # description
    title = "SurfMusik"
    module = "surfmusik"
    homepage = "http://www.surfmusik.de/"


    lang = "DE"   # last configured categories
    base = {
       "DE": "http://www.surfmusik.de/",
       "EN": "http://www.surfmusic.de/",
    }
    listformat = "audio/x-scpls"

    categories = [
        "Genres", ["50ger 50s", "Dubstep", "Latin Jazz", "Schlager", "60ger 60s", "Electronic", "Latino", "Sega", "70ger 70s", "Eurodance ", "Lounge", "Soft", "80ger 80s", "Filmmusik", "Metal", "Sport", "90ger 90s", "Flamenco", "Merengue", "Swing", "Acid", "Gay", "Mix", "Tamil", "Ambient", "Gospel", "New Age", "Tango", "Arabische Musik", "Gothic", "News", "Techno", "Afrikanische Musik", "Groove", "Nostalgie", "Gabber", "Artist Radio ", "Halloween", "Hardstyle", "Bachata", "Hip Hop", "Oldies", "Jumpstyle", "Bhangra", "Hoerspiel Radio", "Minimal", "Balladen", "House", "Pop", "Schranz", "Big Band", "Indian", "Punk", "Top 40", "Blues", "Indisch", "Radioversprecher", "Trance", "Bollywood", "Instrumentalmusik", "Reggae", "Trip Hop", "Campusradio", "Information", "RnB", "Tropical", "Celtic", "Italo Disco ", "Rochester", "Urban", "Chillout", "Jazz", "Rock", "Variety", "Country", "Karnevalsmusik", "Rock n Roll", "Volksmusik", "Dance", "Kinderradio", "Rumba/Salsa", "Zumba", "Discofox", "Kirchlich", "Russische Chansons", "Drum n Bass", "Klassik", "Salsa"],
        "Deutschland", ["Baden Wuerttemberg", "Niedersachsen", "Bayern", "Nordrhein-Westfalen", "Berlin", "Rheinland-Pfalz", "Brandenburg", "Saarland", "Bremen", "Sachsen", "Hamburg", "Sachsen-Anhalt", "Hessen", "Schleswig-Holstein", "Mecklenburg-Vorpommern", "Thueringen"],
        "Europa", ["Albanien", "Griechenland", "Mallorca", "Slowakei", "Andorra", "Irland", "Malta", "Slovenien", "Armenien", "Island", "Niederlande", "Spanien", "Aserbaidschan", "Italien", "Norwegen", "Tschech. Republ", "Belgien", "Kasachstan", "Oesterreich", "Tuerkei", "Bosnien", "Kanarische Inseln", "Polen", "Ungarn", "Bulgarien", "Kirgistan", "Portugal", "Ukraine", "Daenemark", "Kroatien", "Rumaenien", "Wales", "Deutschland", "Lettland", "Russland", "Weissrussland", "England", "Liechtenstein", "Schottland", "Zypern", "Estland", "Litauen", "Schweden", "Finnland", "Luxemburg", "Schweiz", "Frankreich", "Mazedonien", "Serbien"],
        "Afrika", ["Angola", "Malawi", "Aethiopien", "Mauritius", "Aegypten", "Marokko", "Algerien", "Namibia", "Benin", "Nigeria", "Burundi", "Reunion", "Elfenbeinkueste", "Senegal", "Gabun", "Simbabwe", "Ghana", "Somalia", "Kamerun", "Sudan", "Kap Verde", "Suedafrika", "Kenia", "Tansania", "Kongo", "Togo", "Libyen", "Tunesien", "Madagaskar", "Uganda", "Mali"],
        "USA", ["Alabama", "Illinois", "Montana", "Rhode Island", "Alaska", "Indiana", "Nebraska", "South Carolina", "Arizona", "Iowa", "Nevada", "South Dakota", "Arkansas", "Kansas", "New Hampshire", "Tennessee", "Californien", "Kentucky", "New Jersey", "Texas", "Colorado", "Louisiana", "New Mexico", "Utah", "Connecticut", "Maine", "New York", "Vermont", "Delaware", "Maryland", "North Carolina", "Virginia", "Distr.Columbia", "Massachusetts", "North Dakota", "Washington", "Florida", "Michigan", "Ohio", "West Virginia", "Georgia", "Minnesota", "Oklahoma", "Wisconsin", "Hawaii", "Mississippi", "Oregon", "Wyoming", "Idaho", "Missouri", "Pennsylvania", "NOAA Wetter Radio"],
        "Kanada", ["Alberta", "Ontario", "British Columbia", "Prince Edward Island", "Manitoba", "Québec", "Neufundland", "Saskatchewan", "New Brunswick", "Nordwest-Territorien", "Nova Scotia", "Yukon", "Nunavut",],
        "Amerika", ["Mexiko", "Costa Rica", "Argentinien", "Aruba", "El Salvador", "Bolivien", "Antigua", "Guatemala", "Brasilien", "Barbados", "Honduras", "Chile", "Bahamas", "Nicaragua", "Ecuador", "Bermuda", "Panama", "Guyana", "Curaçao", "Guyana", "Domenik. Republ", "Kolumbien", "Grenada", "Paraguay", "Guadeloupe", "Uruguay", "Haiti", "Suriname", "Jamaika", "Peru", "Kaimaninseln", "Venezuela", "Kuba", "Martinique", "Puerto Rico", "St.Lucia", "Saint Martin", "Trinidad und Tobago"],
        "Asien", ["Afghanistan", "Kirgistan", "Vereinigte Arabische Emirate", "Sued-Korea", "Bahrain", "Kuwait", "Bangladesch", "Libanon", "Brunei", "Malaysia", "China", "Nepal", "Guam", "Oman", "Hong Kong", "Pakistan", "Iran", "Palaestina", "Indien", "Philippinen", "Indonesien", "Saudi Arabien", "Israel", "Singapur", "Jordanien", "Sri Lanka", "Japan", "Syrien", "Kambodscha", "Taiwan", "Kasachstan", "Thailand",],
        "Ozeanien", ["Australien", "Neuseeland", "Suedpol", "Fidschi", "Papanew", "Tahiti",],
        #"SurfTV",
        "MusikTV", "NewsTV",
        "Poli", "Flug",
    ] 
    titles = dict( genre="Genre", title="Station", playing="Location", bitrate=False, listeners=False )
 
    config = [
        {
            "name": "surfmusik_lang",
            "value": "EN",
            "type": "select",
            "select":"DE=SurfMusik (GERMAN)|EN=SurfMusic (ENGLISH)",
            "description": "You can alternatively use the German or English localized category titles. Reload the category tree before fetching any stations.",
            "category": "language",
        }
    ]    








    # just a static list for now
    def update_categories(self):

        lang = conf.surfmusik_lang


        cats = {
            "DE": ["Genres", "Deutschland", "Europa", "USA", "Kanada", "Amerika", "Afrika", "Asien", "Ozeanien", "MusicTV", "NewsTV", "Poli", "Flug"],
            "EN": ["Genres", "Europe", "Germany", "USA", "Canada", "America", "Africa", "Asia", "Oceania", "MusicTV", "NewsTV", "Poli", "Flug"],
        }
        map = {
            "Genres": "genres.htm",
            "Europe": "euro.htm",           "Europa": "euro.htm",
            "Germany": "bundesland.htm",    "Deutschland": "bundesland.htm",
            "Africa": "africa.htm",         "Afrika": "africa.htm",
            "America": "amerika.htm",       "Amerika": "amerika.htm",
            "Asia": "asien.htm",            "Asien": "asien.htm",
            "Oceania": "ozean.htm",         "Ozeanien": "ozean.htm",
            "Canada": "canadian-radio-stations.htm", "Kanada": "kanada-online-radio.htm",
            "USA": "staaten.htm",
        }
        rx_links = re.compile(r"""
            <a\b  [^>]+ \b  href="
            (?:(?:http:)?//www.surfmusi[kc].de)? /?
            (?:land|country|genre|format)/
            ([\-+\w\d\s%]+)  \.html"
        """, re.X)

        r = []

        for cat in cats[lang]:
            r.append(cat)
            if map.get(cat):
                subcats = rx_links.findall( http.get(self.base[lang] + map[cat]) )
                subcats = [x.replace("+", " ") for x in subcats]
                subcats = [x.title() for x in subcats]
                r.append(sorted(subcats))

        self.categories = r


    # summarize links from surfmusik
    def update_streams(self, cat, force=0):

        lang = conf.surfmusik_lang
        entries = []
        i = 0
        max = int(conf.max_streams)
        is_tv = 0
        
        # placeholder category
        if cat in ["Genres"]:
            path = None
        # separate
        elif cat in ["Poli", "Flug"]:
            path = ""
        # tv
        elif cat in ["SurfTV", "MusikTV", "NewsTV"]:
            path = ""
            is_tv = 1
        # genre 
        elif cat in self.categories[1]:
            path = ("genre/" if lang == "DE" else "format/")
        # country
        else:
            path = ("land/" if lang == "DE" else "country/")
        
        if path is not None:

            html = http.get(self.base[lang] + path + cat.lower() + ".html")
            html = re.sub("&#x?\d+;", "", html)
        
            rx_radio = re.compile(r"""
                <td\s+class="home1"><a[^>]*\s+href="(.+?)"[^>]*> .*?
                <a\s+class="navil"\s+href="([^"]+)"[^>]*>([^<>]+)</a></td>
                <td\s+class="ort">(.*?)</td>.*?
                <td\s+class="ort">(.*?)</td>.*?
            """, re.X|re.I)
            rx_video = re.compile(r"""
                <a[^>]+href="([^"]+)"[^>]*>(?:<[^>]+>)*Externer
            """, re.X|re.I)

            # per-country list
            for uu in rx_radio.findall(html):
                (url, homepage, name, genre, stadt) = uu
                
                # find mms:// for webtv stations
                if is_tv:
                    m = rx_video.search(http.get(url))
                    if m:
                        url = m.group(1)
                # just convert /radio/ into /m3u/ link
                else:
                    url = "http://www.surfmusik.de/m3u/" + url[30:-5] + ".m3u"

                entries.append({
                    "title": name,
                    "homepage": homepage,
                    "url": url, 
                    "playing": stadt,
                    "genre": genre,
                    "format": ("video/html" if is_tv else "audio/mpeg"),
                })

                # limit result list
                if i > max:
                   break







>



|
|

<

|
<
<
<
<
<
<
<
<
<
<
<
<
<







|
|



>
>
>
>
>
>






>


















|





>



|
|
<








|
















|
|


|


>
|














|














|







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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Surfmusik sharing site
class surfmusik (ChannelPlugin):

    # description
    title = "SurfMusik"
    module = "surfmusik"
    homepage = "http://www.surfmusik.de/"
    listformat = "audio/x-scpls"

    lang = "DE"   # last configured categories
    base = {
       "DE": ("http://www.surfmusik.de/", "genre/", "land/"),
       "EN": ("http://www.surfmusic.de/", "format/", "country/"),
    }


    categories = []













    titles = dict( genre="Genre", title="Station", playing="Location", bitrate=False, listeners=False )
 
    config = [
        {
            "name": "surfmusik_lang",
            "value": "EN",
            "type": "select",
            "select":"DE=German|EN=English",
            "description": "Switching to a new category title language requires reloading the category tree.",
            "category": "language",
        }
    ]    
    
    
    # Set channel title
    def __init__(self, parent=None):
        self.title = ("SurfMusik", "SurfMusic")[conf.get("surfmusik_lang", "EN") == "EN"]
        ChannelPlugin.__init__(self, parent)


    # just a static list for now
    def update_categories(self):

        lang = conf.surfmusik_lang
        (base_url, path_genre, path_country) = self.base[lang]

        cats = {
            "DE": ["Genres", "Deutschland", "Europa", "USA", "Kanada", "Amerika", "Afrika", "Asien", "Ozeanien", "MusicTV", "NewsTV", "Poli", "Flug"],
            "EN": ["Genres", "Europe", "Germany", "USA", "Canada", "America", "Africa", "Asia", "Oceania", "MusicTV", "NewsTV", "Poli", "Flug"],
        }
        map = {
            "Genres": "genres.htm",
            "Europe": "euro.htm",           "Europa": "euro.htm",
            "Germany": "bundesland.htm",    "Deutschland": "bundesland.htm",
            "Africa": "africa.htm",         "Afrika": "africa.htm",
            "America": "amerika.htm",       "Amerika": "amerika.htm",
            "Asia": "asien.htm",            "Asien": "asien.htm",
            "Oceania": "ozean.htm",         "Ozeanien": "ozean.htm",
            "Canada": "canadian-radio-stations.htm", "Kanada": "kanada-online-radio.htm",
            "USA": "staaten.htm",
        }
        rx_links = re.compile(r"""
            <a\b  [^>]+ \b  href="
            (?:(?:https?:)?//www.surfmusi[kc].de)? /?
            (?:land|country|genre|format)/
            ([\-+\w\d\s%]+)  \.html"
        """, re.X)

        r = []
        # Add main categories, and fetch subentries (genres or country names)
        for cat in cats[lang]:
            r.append(cat)
            if map.get(cat):
                subcats = rx_links.findall( http.get(base_url + map[cat]) )
                subcats = [x.replace("+", " ").title() for x in subcats]

                r.append(sorted(subcats))

        self.categories = r


    # summarize links from surfmusik
    def update_streams(self, cat, force=0):

        (base_url, path_genre, path_country) = self.base[conf.surfmusik_lang]
        entries = []
        i = 0
        max = int(conf.max_streams)
        is_tv = 0
        
        # placeholder category
        if cat in ["Genres"]:
            path = None
        # separate
        elif cat in ["Poli", "Flug"]:
            path = ""
        # tv
        elif cat in ["SurfTV", "MusikTV", "NewsTV"]:
            path = ""
            is_tv = 1
        # genre 
        elif cat in self.categories[self.categories.index("Genres") + 1]:
            path = path_genre
        # country
        else:
            path = path_country
        
        if path is not None:
            ucat = cat.replace(" ", "+").lower()
            html = http.get(base_url + path + ucat + ".html")
            html = re.sub("&#x?\d+;", "", html)
        
            rx_radio = re.compile(r"""
                <td\s+class="home1"><a[^>]*\s+href="(.+?)"[^>]*> .*?
                <a\s+class="navil"\s+href="([^"]+)"[^>]*>([^<>]+)</a></td>
                <td\s+class="ort">(.*?)</td>.*?
                <td\s+class="ort">(.*?)</td>.*?
            """, re.X|re.I)
            rx_video = re.compile(r"""
                <a[^>]+href="([^"]+)"[^>]*>(?:<[^>]+>)*Externer
            """, re.X|re.I)

            # per-country list
            for uu in rx_radio.findall(html):
                (url, homepage, name, genre, city) = uu
                
                # find mms:// for webtv stations
                if is_tv:
                    m = rx_video.search(http.get(url))
                    if m:
                        url = m.group(1)
                # just convert /radio/ into /m3u/ link
                else:
                    url = "http://www.surfmusik.de/m3u/" + url[30:-5] + ".m3u"

                entries.append({
                    "title": name,
                    "homepage": homepage,
                    "url": url, 
                    "playing": city,
                    "genre": genre,
                    "format": ("video/html" if is_tv else "audio/mpeg"),
                })

                # limit result list
                if i > max:
                   break