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

โŒˆโŒ‹ โŽ‡ branch:  streamtuner2


Check-in [09dec64f41]

Overview
Comment:Reverted all `module = __name__` assignments, because that was carrying the module over, not the base classname. Added #extraction-method: meta information to channel plugins.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 09dec64f41c9876fd2a4bb10d9da686dfc97ebaa
User & Date: mario on 2016-12-16 16:26:55
Other Links: manifest | tags
Context
2016-12-16
18:34
Fix popen(`locate`) exception. check-in: 8154611e3a user: mario tags: trunk
16:26
Reverted all `module = __name__` assignments, because that was carrying the module over, not the base classname. Added #extraction-method: meta information to channel plugins. check-in: 09dec64f41 user: mario tags: trunk
2016-12-15
20:30
new plugin: streema check-in: a465b6d3b5 user: mario tags: trunk
Changes

Modified channels/dirble.py from [cb216f01ee] to [0aa81f09de].

19
20
21
22
23
24
25

26
27
28
29
30
31
32
#    1F9pRbSjlytheTnY3t6iHCcMo9BYxtai1AymjSlRbII4YUcRAQQiMKWO0Vbahk2An3H9jJvU
#    IhEQCKD/TiJiZsXEzMxMYSy78rnOVvf34lISJ8R1pwGqpyCJkvUgCiyziFjJ5Fv7Tx5r07WJ
#    udJajRVDAI30TUQilG1qPry3I/Y9BThubmigb+R4x8L0m1fz5Ti3h0QE0ClcQCA+dflCz0VD
#    RKwUE5mgOvtu8u7z9wsVsyPPrBxfayqMjVtrMrmmI4f27swqkVS+GGMqy39nvy+W1uGxKL+h
#    u+uAt1KkwvVxAGJsEEWxEWzGm4iV8l1HM9K0BmEkrP8BlhoAUfmOxecAAAAASUVORK5CYII=
# priority: optional
# documentation: http://dirble.com/developer/api

#
#
# Dirble is a user-contributed list of radio stations,
# auot-updating song titles and station information.
# Homepages are there now, and thus favicons readily
# available. Extra station banners aren't fetched.
#







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#    1F9pRbSjlytheTnY3t6iHCcMo9BYxtai1AymjSlRbII4YUcRAQQiMKWO0Vbahk2An3H9jJvU
#    IhEQCKD/TiJiZsXEzMxMYSy78rnOVvf34lISJ8R1pwGqpyCJkvUgCiyziFjJ5Fv7Tx5r07WJ
#    udJajRVDAI30TUQilG1qPry3I/Y9BThubmigb+R4x8L0m1fz5Ti3h0QE0ClcQCA+dflCz0VD
#    RKwUE5mgOvtu8u7z9wsVsyPPrBxfayqMjVtrMrmmI4f27swqkVS+GGMqy39nvy+W1uGxKL+h
#    u+uAt1KkwvVxAGJsEEWxEWzGm4iV8l1HM9K0BmEkrP8BlhoAUfmOxecAAAAASUVORK5CYII=
# priority: optional
# documentation: http://dirble.com/developer/api
# extraction-method: json
#
#
# Dirble is a user-contributed list of radio stations,
# auot-updating song titles and station information.
# Homepages are there now, and thus favicons readily
# available. Extra station banners aren't fetched.
#

Modified channels/dnd.py from [afb629cd4b] to [8308af1af3].

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# never exposed to other apps as x-special/x-custom whatever. (It's also
# not using the MIME 1.0 application/* trash bin for that very reason.)


# Drag and Drop support
class dnd(object):

    module = __name__
    meta = plugin_meta()

    # Keeps selected row on starting DND event
    row = None
    # Buffer converted types
    buf = {}








|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# never exposed to other apps as x-special/x-custom whatever. (It's also
# not using the MIME 1.0 application/* trash bin for that very reason.)


# Drag and Drop support
class dnd(object):

    module = 'dnd'
    meta = plugin_meta()

    # Keeps selected row on starting DND event
    row = None
    # Buffer converted types
    buf = {}

Modified channels/exportcat.py from [de54b609ff] to [45ab7f1478].

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import re


# provides another export window, and custom file generation - does not use action.save()
class exportcat():

    meta = plugin_meta()
    module = __name__

    # Register callback
    def __init__(self, parent):
        conf.add_plugin_defaults(self.meta, self.module)
        if parent:
            self.parent = parent
            uikit.add_menu([parent.extensions, parent.extensions_context], "Export all stations", self.savewindow)







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import re


# provides another export window, and custom file generation - does not use action.save()
class exportcat():

    meta = plugin_meta()
    module = 'exportcat'

    # Register callback
    def __init__(self, parent):
        conf.add_plugin_defaults(self.meta, self.module)
        if parent:
            self.parent = parent
            uikit.add_menu([parent.extensions, parent.extensions_context], "Export all stations", self.savewindow)

Modified channels/favicon.py from [ef3ab53102] to [edc53741f5].

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84


# Hook up as feature plugin
#
class favicon(object):

    # plugin attributes
    module = __name__
    meta = plugin_meta()
    
    
    # Register with main
    def __init__(self, parent):

        # Prepare favicon cache directory







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84


# Hook up as feature plugin
#
class favicon(object):

    # plugin attributes
    module = 'favicon'
    meta = plugin_meta()
    
    
    # Register with main
    def __init__(self, parent):

        # Prepare favicon cache directory

Modified channels/filter_bitrate.py from [33e0dcdc20] to [7813c49854].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from channels import GenericChannel


# Filter streams by bitrate
class filter_bitrate(object):

    meta = plugin_meta()
    module = __name__

    # Hijack postprocessing filters in stream_update handler 
    def __init__(self, parent):
        GenericChannel.postprocess_filters.append(self.filter_rows)

    # Filter row on bitrate
    def filter_rows(self, row, channel):







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from channels import GenericChannel


# Filter streams by bitrate
class filter_bitrate(object):

    meta = plugin_meta()
    module = 'filter_bitrate'

    # Hijack postprocessing filters in stream_update handler 
    def __init__(self, parent):
        GenericChannel.postprocess_filters.append(self.filter_rows)

    # Filter row on bitrate
    def filter_rows(self, row, channel):

Modified channels/filtermusic.py from [35c1830b55] to [6f77373870].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQeBA4mIX2CmQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAGISURBVCjPnVI9SyNRFD333slMMhrNjBJU0FSLIlovy6IWbmelhRJ/gI2lkMXfIOwv2K38qizstFCs3B+wLFhoIfiR1cggkXzMvHnPIiG6
#   GkE8zYXLPfe8c94F2oAkk7CHHLIIb4AAEIlkcuJmARr8OTxW+pKe9l6PSqN0jOe9hd3014J09tdP96SHSLh8GKirsM1+TvnZ5RN/buO5ItvcUH4BCwC7vex0Vf5stroGMKFu+3omKymdfUTMrs9uDyczAHzfz+VyIpwgu1u8NGccSjbFUyOz/vyOUVVoDZbq3+1gd6lQWMnn85PTEzPR4mdnKjLhrS6uBasArNrZ3t36N29u6/7ge/1038QRECul
#   arWaNrqLvV/lHx2U/pQYbXowUTUuXwJGV0rxQ/H/sKkU/yuqC4dSfdZA0wMAELd+4wUhNFUABro52Spvg54l9y7Cq1g/RiBwAvTkQURs2waBwQARiGE93RKJzW5v/fxIl68bXdd1gyA4Pv6tlLqLbyJEoamX4iI+gEdAknsz9gP1pgAAAABJRU5ErkJggg==
# x-doc:
#   http://code.google.com/p/filtermusic-dot-net/source/browse/
# priority: extra

#
#
# Filtermusic.net is a radio collection with primarily electronic
# and dance music stations.
#
#  ยท All entries come with direct server stream URLs.
#  ยท No homepage listings, or further genre details etc.







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQeBA4mIX2CmQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAGISURBVCjPnVI9SyNRFD333slMMhrNjBJU0FSLIlovy6IWbmelhRJ/gI2lkMXfIOwv2K38qizstFCs3B+wLFhoIfiR1cggkXzMvHnPIiG6
#   GkE8zYXLPfe8c94F2oAkk7CHHLIIb4AAEIlkcuJmARr8OTxW+pKe9l6PSqN0jOe9hd3014J09tdP96SHSLh8GKirsM1+TvnZ5RN/buO5ItvcUH4BCwC7vex0Vf5stroGMKFu+3omKymdfUTMrs9uDyczAHzfz+VyIpwgu1u8NGccSjbFUyOz/vyOUVVoDZbq3+1gd6lQWMnn85PTEzPR4mdnKjLhrS6uBasArNrZ3t36N29u6/7ge/1038QRECul
#   arWaNrqLvV/lHx2U/pQYbXowUTUuXwJGV0rxQ/H/sKkU/yuqC4dSfdZA0wMAELd+4wUhNFUABro52Spvg54l9y7Cq1g/RiBwAvTkQURs2waBwQARiGE93RKJzW5v/fxIl68bXdd1gyA4Pv6tlLqLbyJEoamX4iI+gEdAknsz9gP1pgAAAABJRU5ErkJggg==
# x-doc:
#   http://code.google.com/p/filtermusic-dot-net/source/browse/
# priority: extra
# extraction-method: regex, xml
#
#
# Filtermusic.net is a radio collection with primarily electronic
# and dance music stations.
#
#  ยท All entries come with direct server stream URLs.
#  ยท No homepage listings, or further genre details etc.

Modified channels/global_key.py from [3924071f72] to [effffb2209].

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40



# register a key
class global_key(object):

    # control attributes
    module = __name__
    meta = plugin_meta()
    last = 0


    # register
    def __init__(self, parent):
        self.parent = parent







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40



# register a key
class global_key(object):

    # control attributes
    module = 'global_key'
    meta = plugin_meta()
    last = 0


    # register
    def __init__(self, parent):
        self.parent = parent

Modified channels/history.py from [171f2c6583] to [5e95ab01e2].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# bookmarks channel.


from config import *
from channels import *


class history:

    # plugin attributes
    module = __name__
    meta = plugin_meta()
    
    # store
    bm = None


    # hook up to main tab







|


|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# bookmarks channel.


from config import *
from channels import *


class history (object):

    # plugin attributes
    module = 'history'
    meta = plugin_meta()
    
    # store
    bm = None


    # hook up to main tab

Modified channels/internet_radio.py from [f1f9b6b827] to [e2da369cc7].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAaZJREFUOI2N0j1PlEEUBeBnlsVoRJcCPwINxIJGAoWVFbVK4g8w
#   oUUTFRNbG3+FhVErK36BhcYCrTR8FS4mRGUXFEKCUizRwLXgnfV1Awk3mUzmnHPvPXNnUkSE40RKFYxhHKMYxFb1GIlnMLVN/etBUjuGWDm6wEHHyQbLW/Qd
#   JTu8QEq9mJlnogz3sHOJV3iHz2iKzuDiH+bm+J3XD74EU5Gc7pSn/4aYUi14s8BIhkZ5puKhvdgpNFVccaA5oaP7TO66SCuYKnG9weMmjaz5yadqqfvkPE/z
#   8TLTIp4U3I01ljY5f/gQu1LPGvWS7Rel5NtLzOzRlfk+Ngd4i48Ke9PZVpNGUCvwawvsZm6db8GtoLt9s4iIFotZFEwXybU1VjO+z4egv/MVKlIaqTMMJ2nh
#   eeH0wQYX4BwbiQkRTSmdktJ1KY3lGYznuw3zWsS2lLo2WMl4P49ycjCbn3k0pfuVg5m1432e4zr9UGMbLwv8avmP/OJOBQOlAsvF3hYNMititzg2Kuxn7iyr
#   VbSG/tltFHt3CVvATRBRH0lpEvfwXXL3L9zE/NEe0EfHAAAAAElFTkSuQmCC

#
# Internet-Radio.co.uk/.com is one of the largest stream directories.
# Available music genre classifications are mirrored verbatim and flatly.
#
# The new version of this plugin alternates between PyQuery and Regex
# station extraction. Both overlook some paid or incomplete entries.
# HTTP retrieval happens in one batch, determined by the number of pages







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAaZJREFUOI2N0j1PlEEUBeBnlsVoRJcCPwINxIJGAoWVFbVK4g8w
#   oUUTFRNbG3+FhVErK36BhcYCrTR8FS4mRGUXFEKCUizRwLXgnfV1Awk3mUzmnHPvPXNnUkSE40RKFYxhHKMYxFb1GIlnMLVN/etBUjuGWDm6wEHHyQbLW/Qd
#   JTu8QEq9mJlnogz3sHOJV3iHz2iKzuDiH+bm+J3XD74EU5Gc7pSn/4aYUi14s8BIhkZ5puKhvdgpNFVccaA5oaP7TO66SCuYKnG9weMmjaz5yadqqfvkPE/z
#   8TLTIp4U3I01ljY5f/gQu1LPGvWS7Rel5NtLzOzRlfk+Ngd4i48Ke9PZVpNGUCvwawvsZm6db8GtoLt9s4iIFotZFEwXybU1VjO+z4egv/MVKlIaqTMMJ2nh
#   eeH0wQYX4BwbiQkRTSmdktJ1KY3lGYznuw3zWsS2lLo2WMl4P49ycjCbn3k0pfuVg5m1432e4zr9UGMbLwv8avmP/OJOBQOlAsvF3hYNMititzg2Kuxn7iyr
#   VbSG/tltFHt3CVvATRBRH0lpEvfwXXL3L9zE/NEe0EfHAAAAAElFTkSuQmCC
# extraction-method: regex, dom
#
# Internet-Radio.co.uk/.com is one of the largest stream directories.
# Available music genre classifications are mirrored verbatim and flatly.
#
# The new version of this plugin alternates between PyQuery and Regex
# station extraction. Both overlook some paid or incomplete entries.
# HTTP retrieval happens in one batch, determined by the number of pages

Modified channels/jamendo.py from [20207c9ed8] to [0db1a39017].

15
16
17
18
19
20
21


22
23
24
25
26
27
28
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAwNJREFUOI1lk0toXGUYhp/v/8+ZzDQzmdZMZ8YSkxIQCWTTYsALLsQsUsWFQgJeEJQqIigUvBK0FBQULIJKMEKrFjdOW9xoW1AbRdRCEYtd2GCxxUQbk8bMrTNnzpn//1xMLYLv6l2877N7oBcB0GMY
#   IAUY/p9w/glCrVzby3+LVqaxM4dx+inQV7KIHcKYAbzG4FYgqcmudYBAF+jKnT2QAExPYysVHCdKRQgewwRT0B1FfQboYsLLeE7hk4Oo/iD3rFit4GQGRCsYwJMt7yQVfrS6Go3HUQtvskiwCWM82qlijGdbaUsbTV5G/X65+y+rCzgBRI+VbsSmvvltqVkuX78t6rvpKWtvuMsgOfHtJia66OPz
#   86564UtDkA2Lm/VJYF6mLgXo50X0xNAHy4cK2jk+diVe+1FVVX/57oIuL66qqmriVF23rZ1TjyTLH2YT/WJ4TY+XRgAMKqNgJ41vebbvTgeFneo6Tb567zPmHn+LxdPnCIxHTFrt2CtB/8BWqtVOAewDWgGDmHG0u1VtztjC7SLqRSUkM5Clsd5ibs/7nDzyLd51xfQPq82PKS5SsHfQAEMsIZG3
#   khgvJqUqBhFBnSeTS1O/XOPou0eoVxuIsfgkRDsqxBIQgaEVXyIyTVdvGFdbQlD1LibpJDTWG9w8NcHsgRfIb8ni4qbIxhISGU87+Z00BMTuDPhfg47b4X4+oHZ4VxiksxRHi9x3y71M7p5EjAWE6OxBkj/OaSqTgyvJUUIQncuDDx6qRsHHLqpHuR0PW3vbbCj5EYyAAq7dgMVPfHRytt2Kkv7i
#   5vAw0n1wZuFvFcDq/kGP5/X1tnm+2aiTLQy59MiE00wZ49okK2fNxsWfgnRfmvJA8D3E98tztTWdBtG9IPuw+tqgI+RRTLin1miNJ3EkRhQFxIRcl8+tgj9EN35VXqrV9G2MPIPvWfgv5I1Bh/pNBOGtYCeALEKM6nlc52uUP+XFDfRpRN7psa/ZeBWSAmJ99qrQGaANeJA3AUjpXhLZ1zsD+g+5
#   Cnd9pANrngAAAABJRU5ErkJggg==


#
# Utilizes the Jamendo /v3.0/ API now completely. That means all tracks will
# be available as Ogg Vorbis per default.
#
# Radio stations are a fixed internal list. There's not much point in querying
# the API for them. (They're really just automated playlists, and MP3-only.)
#







>
>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAwNJREFUOI1lk0toXGUYhp/v/8+ZzDQzmdZMZ8YSkxIQCWTTYsALLsQsUsWFQgJeEJQqIigUvBK0FBQULIJKMEKrFjdOW9xoW1AbRdRCEYtd2GCxxUQbk8bMrTNnzpn//1xMLYLv6l2877N7oBcB0GMY
#   IAUY/p9w/glCrVzby3+LVqaxM4dx+inQV7KIHcKYAbzG4FYgqcmudYBAF+jKnT2QAExPYysVHCdKRQgewwRT0B1FfQboYsLLeE7hk4Oo/iD3rFit4GQGRCsYwJMt7yQVfrS6Go3HUQtvskiwCWM82qlijGdbaUsbTV5G/X65+y+rCzgBRI+VbsSmvvltqVkuX78t6rvpKWtvuMsgOfHtJia66OPz
#   86564UtDkA2Lm/VJYF6mLgXo50X0xNAHy4cK2jk+diVe+1FVVX/57oIuL66qqmriVF23rZ1TjyTLH2YT/WJ4TY+XRgAMKqNgJ41vebbvTgeFneo6Tb567zPmHn+LxdPnCIxHTFrt2CtB/8BWqtVOAewDWgGDmHG0u1VtztjC7SLqRSUkM5Clsd5ibs/7nDzyLd51xfQPq82PKS5SsHfQAEMsIZG3
#   khgvJqUqBhFBnSeTS1O/XOPou0eoVxuIsfgkRDsqxBIQgaEVXyIyTVdvGFdbQlD1LibpJDTWG9w8NcHsgRfIb8ni4qbIxhISGU87+Z00BMTuDPhfg47b4X4+oHZ4VxiksxRHi9x3y71M7p5EjAWE6OxBkj/OaSqTgyvJUUIQncuDDx6qRsHHLqpHuR0PW3vbbCj5EYyAAq7dgMVPfHRytt2Kkv7i
#   5vAw0n1wZuFvFcDq/kGP5/X1tnm+2aiTLQy59MiE00wZ49okK2fNxsWfgnRfmvJA8D3E98tztTWdBtG9IPuw+tqgI+RRTLin1miNJ3EkRhQFxIRcl8+tgj9EN35VXqrV9G2MPIPvWfgv5I1Bh/pNBOGtYCeALEKM6nlc52uUP+XFDfRpRN7psa/ZeBWSAmJ99qrQGaANeJA3AUjpXhLZ1zsD+g+5
#   Cnd9pANrngAAAABJRU5ErkJggg==
# extraction-method: json, custom-mime
#
#
# Utilizes the Jamendo /v3.0/ API now completely. That means all tracks will
# be available as Ogg Vorbis per default.
#
# Radio stations are a fixed internal list. There's not much point in querying
# the API for them. (They're really just automated playlists, and MP3-only.)
#

Modified channels/links.py from [f73313d581] to [2ae7536a04].

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33



# hooks into main.bookmarks
class links (object):

    # plugin info
    module = "links"
    meta = plugin_meta()
    
    # list
    streams = [    ]
    default = [
        ("stream", "rad.io", "http://www.rad.io/"),
        ("stream", "RadioTower", "http://www.radiotower.com/"),







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33



# hooks into main.bookmarks
class links (object):

    # plugin info
    module = 'links'
    meta = plugin_meta()
    
    # list
    streams = [    ]
    default = [
        ("stream", "rad.io", "http://www.rad.io/"),
        ("stream", "RadioTower", "http://www.radiotower.com/"),

Modified channels/modarchive.py from [2703341090] to [505241c688].

11
12
13
14
15
16
17


18
19
20
21
22
23
24
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAy1JREFUOI01k0trXGUAQM/33W/unblz55VJk0wekzSdaTtJ2oh0YRBEUCtUWoug4MKl4EoEQf+FoAvxDxhwo4uIoiBSH8GABElL0zQPnbyaRzMzSSadua/vc1FdnOXZHDii
#   dvsjg5BISzJWsJgaLYKwWLi/ye6pAAyFbJpnL5cRAta3D9nYOUIKAFChBuKAmUqWl65dolar0d9X5NXNXd7/5BuCKGbi/AApJ0EYxUxdGEJZFiv1PRKWhcrLJ8xMlrj1yvNMTF5BSEng+7R9gx+G9BUL9OQy+EGAlJIgihkf6qX+6IggjFCvz1R4+603yOYLRIFPfWuX
#   2W/voGUCN5UiiU8UdBDSJo5jHDvB0XGbMIqRUqL+WD/m6mod295jZWOTi6P9JIIWXu8QKUcxPWwzPuCxtNUmn3Fpnpxxd20HrQ1Sghh/7UNjy5gghvI5j/duXsNzHUQyzxezc3zwzg2Gh8t8Nvs9ey2f5Y0d/DBCWRZCgFSWhZ1MU8jn6fgRzdYxynG5dGGMmy88Q6k0
#   SMZzaZ52WFrdxk3a5DwXKQRxbFBXKkP09WRQlsRozc5Bk3J5hHTK4cb1F1HKJmkrJqujWMqmmM8QRTFBGLG+fYgaLRWJtUbrmISTZL/RwnOTfPXdr0xXB8nlciSUxI1aVIqSZvcMIxw816E2XkKFUYQRAokgDCO8dArfD/npz4fUd/c564acz2qmJqqkvDySmLnflwli
#   SRxrpDGgpAQhSNoWh6chc3cWKWRcrFSWMPCpjJX4+d4+n389D1JxtTqC0ZqTsw7ywT+PCMIIP4h4WN9j4f4Wvy0fkM+l6XZ9elKSSvUiipjmwQ7NZoNSfy+NVpvVzQNUfa/B49YZWms6fog2mr7eAo5t0zo5pVz06Osf4N03X+b6czVGR4aZv7vB/NI6aTeJVFLypBvQ
#   8UMSCQsQZFwHEAijGRk8h207fPrlj2wdthkq9dNotQkjjZISpY1BSoExoLXBmKcoSxBr8ENYvLfKDwsPWPt7k8nxAX5ZXMFOWERaIy7f/tj8L0n5tGzWSzJdHcZNOihpOGic8tfaI4TRZNM2j4+7yP9+/hd7YWLXivTEWgAAAABJRU5ErkJggg==


#
# A genre browser for tracker music files from the MOD Archive.
#
# MOD files dodn't work with all audio players. And with the default
# download method, it'll receive a .zip archive with embeded .mod file.
#
# Configuring VLC for `audio/mod+zip` or just a generic `*/*` works







>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAy1JREFUOI01k0trXGUAQM/33W/unblz55VJk0wekzSdaTtJ2oh0YRBEUCtUWoug4MKl4EoEQf+FoAvxDxhwo4uIoiBSH8GABElL0zQPnbyaRzMzSSadua/vc1FdnOXZHDii
#   dvsjg5BISzJWsJgaLYKwWLi/ye6pAAyFbJpnL5cRAta3D9nYOUIKAFChBuKAmUqWl65dolar0d9X5NXNXd7/5BuCKGbi/AApJ0EYxUxdGEJZFiv1PRKWhcrLJ8xMlrj1yvNMTF5BSEng+7R9gx+G9BUL9OQy+EGAlJIgihkf6qX+6IggjFCvz1R4+603yOYLRIFPfWuX
#   2W/voGUCN5UiiU8UdBDSJo5jHDvB0XGbMIqRUqL+WD/m6mod295jZWOTi6P9JIIWXu8QKUcxPWwzPuCxtNUmn3Fpnpxxd20HrQ1Sghh/7UNjy5gghvI5j/duXsNzHUQyzxezc3zwzg2Gh8t8Nvs9ey2f5Y0d/DBCWRZCgFSWhZ1MU8jn6fgRzdYxynG5dGGMmy88Q6k0
#   SMZzaZ52WFrdxk3a5DwXKQRxbFBXKkP09WRQlsRozc5Bk3J5hHTK4cb1F1HKJmkrJqujWMqmmM8QRTFBGLG+fYgaLRWJtUbrmISTZL/RwnOTfPXdr0xXB8nlciSUxI1aVIqSZvcMIxw816E2XkKFUYQRAokgDCO8dArfD/npz4fUd/c564acz2qmJqqkvDySmLnflwli
#   SRxrpDGgpAQhSNoWh6chc3cWKWRcrFSWMPCpjJX4+d4+n389D1JxtTqC0ZqTsw7ywT+PCMIIP4h4WN9j4f4Wvy0fkM+l6XZ9elKSSvUiipjmwQ7NZoNSfy+NVpvVzQNUfa/B49YZWms6fog2mr7eAo5t0zo5pVz06Osf4N03X+b6czVGR4aZv7vB/NI6aTeJVFLypBvQ
#   8UMSCQsQZFwHEAijGRk8h207fPrlj2wdthkq9dNotQkjjZISpY1BSoExoLXBmKcoSxBr8ENYvLfKDwsPWPt7k8nxAX5ZXMFOWERaIy7f/tj8L0n5tGzWSzJdHcZNOihpOGic8tfaI4TRZNM2j4+7yP9+/hd7YWLXivTEWgAAAABJRU5ErkJggg==
# extraction-method: regex
#
#
# A genre browser for tracker music files from the MOD Archive.
#
# MOD files dodn't work with all audio players. And with the default
# download method, it'll receive a .zip archive with embeded .mod file.
#
# Configuring VLC for `audio/mod+zip` or just a generic `*/*` works

Modified channels/myoggradio.py from [459b01f587] to [48b975db1d].

12
13
14
15
16
17
18


19
20
21
22
23
24
25
#    { name: myoggradio_morph,  type: boolean, value: 0,  description: "Convert pls/m3u into direct shoutcast url." }
# priority: standard
# png:
#   iVBORw0KGgoAAAANSUhEUgAAAAsAAAAQCAYAAADAvYV+AAAABHNCSVQICAgIfAhkiAAAARdJREFUKJGt0U8rhFEUx/HP3AfjT9QQJo80CyzGG1A2UspL8k4s
#   7G2lvAlLC0skEWliMJTHM2Nx72iSjfJb3Xv6/n7ndA5/UIWz/jtDGZ9rqXQGAT30+vAE6njA80DYCObQxe1QTFdPhlFc4D0lzmMGn3gJGEtQhipFg80a53Uq
#   syksoBYiIMRiNeMw5+GA3S0m+50rqIY0T1LZY6kga5N34v9b3ZDmK6Op7JI/Eu6ZvqMsEthDJ+ADTxEeLth/o5jheIjJdgr6QCsk531cWeOWo0W06KwycYcX
#   3KAI6QAlzSvWX/ncwDWaTNVoXiaDyo+LbmMHp2jEDvb6S8gGwBVs4SRBN1jAOC5/hMrF0w5qHMu/TPDP+gI3M01h2io9UwAAAABJRU5ErkJggg==


#
# MyOggRadio is an open source radio station directory. Because this matches
# well with streamtuner2, there's now a project partnership. Shared streams can easily
# be downloaded in this channel plugin. And streamtuner2 users can easily share their
# favourite stations into the MyOggRadio directory.
#
# Beforehand an account needs to be configured in the settings. (Registration







>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#    { name: myoggradio_morph,  type: boolean, value: 0,  description: "Convert pls/m3u into direct shoutcast url." }
# priority: standard
# png:
#   iVBORw0KGgoAAAANSUhEUgAAAAsAAAAQCAYAAADAvYV+AAAABHNCSVQICAgIfAhkiAAAARdJREFUKJGt0U8rhFEUx/HP3AfjT9QQJo80CyzGG1A2UspL8k4s
#   7G2lvAlLC0skEWliMJTHM2Nx72iSjfJb3Xv6/n7ndA5/UIWz/jtDGZ9rqXQGAT30+vAE6njA80DYCObQxe1QTFdPhlFc4D0lzmMGn3gJGEtQhipFg80a53Uq
#   syksoBYiIMRiNeMw5+GA3S0m+50rqIY0T1LZY6kga5N34v9b3ZDmK6Op7JI/Eu6ZvqMsEthDJ+ADTxEeLth/o5jheIjJdgr6QCsk531cWeOWo0W06KwycYcX
#   3KAI6QAlzSvWX/ncwDWaTNVoXiaDyo+LbmMHp2jEDvb6S8gGwBVs4SRBN1jAOC5/hMrF0w5qHMu/TPDP+gI3M01h2io9UwAAAABJRU5ErkJggg==
# extraction-method: json
#
#
# MyOggRadio is an open source radio station directory. Because this matches
# well with streamtuner2, there's now a project partnership. Shared streams can easily
# be downloaded in this channel plugin. And streamtuner2 users can easily share their
# favourite stations into the MyOggRadio directory.
#
# Beforehand an account needs to be configured in the settings. (Registration

Modified channels/pluginmanager2.py from [6958917597] to [7d11864bfe].

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#   { name: plugin_auto, type: boolean, value: 1, description: Apply plugin activation/disabling without restart. }
# priority: extra
# png:
#   iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAJ1BMVEUAAABNYQVcdAx1iTB6mQ6KsQGUsTCUuxGmyDKvzEK51FnB13LP3pnSUwRYAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsT
#   AQCanBgAAAAHdElNRQffBQ4EMidI8LXfAAABGUlEQVQoz32NPU7DQBCFx4aOxosIIOzGlkWRiogGkBssRfQoK/cxRBwAaw6AhJcLoAwtlTdlKtiSMj4U++PIBiReM/O+mXkD0ImdMxhqp23bsyHINkp9/Qu8TLXBj5BMrfsp
#   08rk2hT7KtIf2o1cmWJzIqU+pVVD9i6SW9Ev0BC9D0FDSzEExouyB0QkLGAQunMSL7IuwVNB+EZu/Bw/lLAnJ1fa6nOBT3CZQ0irDzsWiHo/gLFwqhFxbl6Me+/AiXhdmnUHfIBDMb+onccZnE7AXwTHncfH5CYHSGALeHGH
#   tybGAr7gFS8KC464Vs7Se84dGGlvmvQPqAZgFoM/7QYwQqx0fIoFuo0DE3oNuzbbgP1EKwDPlPgb5NefnUHe3aAAAAAASUVORK5CYII=
# support: experimental
#
# Scans for new plugins from the repository server, using
# a common-repo.json list. Compares new against installed
# plugins, and permits to update or download new ones.
#
# User plugins go into ~/.config/streamtuner2/channels/
# and will be picked up in favour of system-installed ones.







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#   { name: plugin_auto, type: boolean, value: 1, description: Apply plugin activation/disabling without restart. }
# priority: extra
# png:
#   iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAJ1BMVEUAAABNYQVcdAx1iTB6mQ6KsQGUsTCUuxGmyDKvzEK51FnB13LP3pnSUwRYAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsT
#   AQCanBgAAAAHdElNRQffBQ4EMidI8LXfAAABGUlEQVQoz32NPU7DQBCFx4aOxosIIOzGlkWRiogGkBssRfQoK/cxRBwAaw6AhJcLoAwtlTdlKtiSMj4U++PIBiReM/O+mXkD0ImdMxhqp23bsyHINkp9/Qu8TLXBj5BMrfsp
#   08rk2hT7KtIf2o1cmWJzIqU+pVVD9i6SW9Ev0BC9D0FDSzEExouyB0QkLGAQunMSL7IuwVNB+EZu/Bw/lLAnJ1fa6nOBT3CZQ0irDzsWiHo/gLFwqhFxbl6Me+/AiXhdmnUHfIBDMb+onccZnE7AXwTHncfH5CYHSGALeHGH
#   tybGAr7gFS8KC464Vs7Se84dGGlvmvQPqAZgFoM/7QYwQqx0fIoFuo0DE3oNuzbbgP1EKwDPlPgb5NefnUHe3aAAAAAASUVORK5CYII=
# support: stable
#
# Scans for new plugins from the repository server, using
# a common-repo.json list. Compares new against installed
# plugins, and permits to update or download new ones.
#
# User plugins go into ~/.config/streamtuner2/channels/
# and will be picked up in favour of system-installed ones.
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import compat2and3
from xml.sax.saxutils import escape as html_escape


# Plugin manager
class pluginmanager2(object):

    module = __name__
    meta = plugin_meta()
    parent = None
    vbox = None


    # Hook up
    def __init__(self, parent):







|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import compat2and3
from xml.sax.saxutils import escape as html_escape


# Plugin manager
class pluginmanager2(object):

    module = 'pluginmanager2'
    meta = plugin_meta()
    parent = None
    vbox = None


    # Hook up
    def __init__(self, parent):

Modified channels/radiobrowser.py from [f73f375ada] to [b21d774715].

20
21
22
23
24
25
26

27
28
29
30
31
32
33
#   AAAAYHRSTlPJ4/Hz8/Lx7+3s6ufi08N9/fve8/bo//T8/vb6/fr67eL02vbc9/Tt//3v/N34/5aO/MWeoM7Rbene+f7E0PykaWqx3K333/v//Pv7/eD34Z/m7O3v8fL09vf5+vv8/9Pw7ECfAAAAAWJL
#   R0TAE2Hf+AAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB98EARcyBebz0PQAAADXSURBVAjXAcwAM/8AAAECAwQFBgcICQoLDA0ODwAQYBESE2FiY2RlZhQVFmcXABhoGRobaWprbG1uHB1vcB4A
#   H3Fyc3R1dnd4eXp7fH1+IAAhf4CBgoOEhYaHiImKi4wiACONjo+QkZKTlJWWl5iZmiQAJZucJiconZ6foCkqK6GiLAAtoy4vMDEyMzQ1Njc4pKU5ADqmOzw9Pj9AQUJDREWnqEYAR6mqq6xISUpLTK2u
#   r7CxTQBOsrO0tba3uLm6u7y9vr9PAFBRUlNUVVZXWFlaW1xdXl9emUehk/NThwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNS0wNC0wMlQwMTo0OTozOSswMjowMH98i/gAAAAldEVYdGRhdGU6bW9kaWZ5
#   ADIwMTUtMDQtMDJUMDE6NDk6MTcrMDI6MDAcO09kAAAAAElFTkSuQmCC
# x-icon-src: openclipart:tape.png
# x-service-by: segler_alex

#
#
# Radio-Browser is a community-collected list of internet radios.
# Currently lists โ‰ฅ4000 streaming stations, and tracks favourited
# entries. Furthermore includes station homepage links!
#
# If you change the categories between tags/countries/languages,







>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#   AAAAYHRSTlPJ4/Hz8/Lx7+3s6ufi08N9/fve8/bo//T8/vb6/fr67eL02vbc9/Tt//3v/N34/5aO/MWeoM7Rbene+f7E0PykaWqx3K333/v//Pv7/eD34Z/m7O3v8fL09vf5+vv8/9Pw7ECfAAAAAWJL
#   R0TAE2Hf+AAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB98EARcyBebz0PQAAADXSURBVAjXAcwAM/8AAAECAwQFBgcICQoLDA0ODwAQYBESE2FiY2RlZhQVFmcXABhoGRobaWprbG1uHB1vcB4A
#   H3Fyc3R1dnd4eXp7fH1+IAAhf4CBgoOEhYaHiImKi4wiACONjo+QkZKTlJWWl5iZmiQAJZucJiconZ6foCkqK6GiLAAtoy4vMDEyMzQ1Njc4pKU5ADqmOzw9Pj9AQUJDREWnqEYAR6mqq6xISUpLTK2u
#   r7CxTQBOsrO0tba3uLm6u7y9vr9PAFBRUlNUVVZXWFlaW1xdXl9emUehk/NThwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNS0wNC0wMlQwMTo0OTozOSswMjowMH98i/gAAAAldEVYdGRhdGU6bW9kaWZ5
#   ADIwMTUtMDQtMDJUMDE6NDk6MTcrMDI6MDAcO09kAAAAAElFTkSuQmCC
# x-icon-src: openclipart:tape.png
# x-service-by: segler_alex
# extraction-method: json
#
#
# Radio-Browser is a community-collected list of internet radios.
# Currently lists โ‰ฅ4000 streaming stations, and tracks favourited
# entries. Furthermore includes station homepage links!
#
# If you change the categories between tags/countries/languages,

Modified channels/radionomy.py from [a15a6d5e39] to [05a66c0287].

10
11
12
13
14
15
16

17
18
19
20
21
22
23
#    { name: radionomy_pages,  type: int,  value: 3,  category: limit,  description: Number of pages per category to scan. }
#    { name: radionomy_update,  type: boolean,  value: 1,  description: Also fetch OnAir updates about currently playing songs. }
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAACXBIWXMAAAsTAAALEwEAmpwYAAABIElEQVQ4y62Uv0rEQBCHv/yRQziJ1bYWV/gCaxrhGrtrg1f5GMc+xOKLeIetVjZXHRrwAewstxMWFDViM5EQcrk9yTRJZn+/j51h
#   JhESypZnwAKYAWP6wwN3wLUz+gkgEsglsOR/MXdGryK5yaMk34ECWAPVFmMCTIFb4FByeSrl1JDMGf0VcIt7ZcsMeBPYIpaeABSBEABEW8jnLG00dt0WK1ueSikvwDnw4YzeNCS1Z5w2klULkgAb4Bh4AC7kKOrypDsq+JHnBDgBRtuE
#   aWBLrpzRr32COBD0vEsQCvocCsQ+oKTj/Ehm5rtnyv9AXt6nrYGrgKyxBl1Re3ykbHkDzPdcEZQtDxorshxsaQf7jcTSjxWQC8wHmL1oc/HyC1/TWBfFRR9xAAAAAElFTkSuQmCC
# priority: extra

#
# Over 6500 radio stations of mixed genres and from different
# countries.
#
# Radionomy is a commercial radio hosting service. All listed
# stations are actually hosted by itself. Public and free access.
# And stream hosting is free as well, by adding advertisements,







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#    { name: radionomy_pages,  type: int,  value: 3,  category: limit,  description: Number of pages per category to scan. }
#    { name: radionomy_update,  type: boolean,  value: 1,  description: Also fetch OnAir updates about currently playing songs. }
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAACXBIWXMAAAsTAAALEwEAmpwYAAABIElEQVQ4y62Uv0rEQBCHv/yRQziJ1bYWV/gCaxrhGrtrg1f5GMc+xOKLeIetVjZXHRrwAewstxMWFDViM5EQcrk9yTRJZn+/j51h
#   JhESypZnwAKYAWP6wwN3wLUz+gkgEsglsOR/MXdGryK5yaMk34ECWAPVFmMCTIFb4FByeSrl1JDMGf0VcIt7ZcsMeBPYIpaeABSBEABEW8jnLG00dt0WK1ueSikvwDnw4YzeNCS1Z5w2klULkgAb4Bh4AC7kKOrypDsq+JHnBDgBRtuE
#   aWBLrpzRr32COBD0vEsQCvocCsQ+oKTj/Ehm5rtnyv9AXt6nrYGrgKyxBl1Re3ykbHkDzPdcEZQtDxorshxsaQf7jcTSjxWQC8wHmL1oc/HyC1/TWBfFRR9xAAAAAElFTkSuQmCC
# priority: extra
# extraction-method: regex, dom, json
#
# Over 6500 radio stations of mixed genres and from different
# countries.
#
# Radionomy is a commercial radio hosting service. All listed
# stations are actually hosted by itself. Public and free access.
# And stream hosting is free as well, by adding advertisements,

Modified channels/radiotray.py from [95666bc7a7] to [4465adc486].

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
# api: dbus
# title: RadioTray hook
# description: Allows to bookmark stations to RadioTray
# version: 0.3
# type: feature
# category: bookmarks
# depends: deb:python-dbus, deb:streamtuner2, deb:python-xdg
# config:
#   { name: radiotray_map, type: select, value: "group", select: 'root|group|asis|play', description: 'Map genres to default RadioTray groups, or just "root".' }
# url: http://radiotray.sourceforge.net/
# priority: extra
# id: streamtuner2-radiotray

# pack: radiotray.py
# fpm-prefix: /usr/share/streamtuner2/channels/
#
# Adds a context menu "Keep in RadioTray.." for bookmarking.
# Until a newer version exposes addRadio(), this plugin
# will fall back to just playUrl().
#



|








>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# api: dbus
# title: RadioTray hook
# description: Allows to bookmark stations to RadioTray
# version: 0.4
# type: feature
# category: bookmarks
# depends: deb:python-dbus, deb:streamtuner2, deb:python-xdg
# config:
#   { name: radiotray_map, type: select, value: "group", select: 'root|group|asis|play', description: 'Map genres to default RadioTray groups, or just "root".' }
# url: http://radiotray.sourceforge.net/
# priority: extra
# id: streamtuner2-radiotray
# extraction-method: xml
# pack: radiotray.py
# fpm-prefix: /usr/share/streamtuner2/channels/
#
# Adds a context menu "Keep in RadioTray.." for bookmarking.
# Until a newer version exposes addRadio(), this plugin
# will fall back to just playUrl().
#
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import re
import dbus
from xdg.BaseDirectory import xdg_data_home
from xml.etree import ElementTree


# not a channel plugin, just a category in bookmarks, and a context menu
class radiotray:

    # plugin info
    module = __name__
    meta = plugin_meta()
    # bookmarks cat
    parent = None
    bm = None
    # radiotray config file / bookmarks
    rt_xml = "%s/%s/%s" % (xdg_data_home, "radiotray", "bookmarks.xml")








|


|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import re
import dbus
from xdg.BaseDirectory import xdg_data_home
from xml.etree import ElementTree


# not a channel plugin, just a category in bookmarks, and a context menu
class radiotray (object):

    # plugin info
    module = 'radiotray'
    meta = plugin_meta()
    # bookmarks cat
    parent = None
    bm = None
    # radiotray config file / bookmarks
    rt_xml = "%s/%s/%s" % (xdg_data_home, "radiotray", "bookmarks.xml")

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
        # keep reference to main window    
        self.parent = parent
        self.bm = parent.channels["bookmarks"]
        conf.add_plugin_defaults(self.meta, self.module)

        # create category
        self.bm.add_category("radiotray", plugin=self);
        self.bm.streams["radiotray"] = self.update_streams(cat="radiotray")
        self.bm.reload_if_current(self.module)

        # add context menu
        uikit.add_menu([parent.streammenu, parent.streamactions], "Keep in RadioTray", self.share, insert=4)
        

    # load RadioTray bookmarks







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
        # keep reference to main window    
        self.parent = parent
        self.bm = parent.channels["bookmarks"]
        conf.add_plugin_defaults(self.meta, self.module)

        # create category
        self.bm.add_category("radiotray", plugin=self);
        self.bm.category_plugins["radiotray"] = self #.update_streams(cat="radiotray")
        self.bm.reload_if_current(self.module)

        # add context menu
        uikit.add_menu([parent.streammenu, parent.streamactions], "Keep in RadioTray", self.share, insert=4)
        

    # load RadioTray bookmarks

Modified channels/reddit.py from [02442ae6d3] to [cfb66a69eb].

10
11
12
13
14
15
16

17
18
19
20
21
22
23
#   { name: reddit_pages, type: int, value: 2, description: Number of pages to fetch. }
#   { name: filter_walledgardens, type: boolean, value: 1, description: Filter walled gardens (soundcloud/spotify/โ€ฆ) if there's no player. }
#   { name: reddit_keep_all, type: boolean, value: 0, description: Keep all web links (starts a browser for websites/news). }
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJ1BMVEUAAAAcICX/AABHSk1jZ299hYz/bmajq6//lY/d0M3C1+3T7P38+/iaLhuGAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF
#   HUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffBRUXIyQbWArCAAAAh0lEQVQI12Pg3g0BDLtXrVq1eveq3Qy7gIxCU9dqEGO11/ZKbzBDenUIUM3u7cGi1UDFW0TE55wsdpZikAw/
#   eebMnMmHGVxqDuUc0zzpynD4zIk5J3vOSDNsOQMG1gy7bI5HTq85Ws2wu/jM9PIzrkArdhmXlzuuXg00eVd5+epVqxmgrtgNAOWeS1KYtcY4AAAAAElFTkSuQmCC

# priority: extra
#
# Scans music-related subreddits for MP3/Youtube/Soundcloud
# links.
# Those are usually new bands or fresh releases, or favorite
# user selections. The category/subreddit list is filtered
# for a minimum quote of usable links (namely Youtube URLs).







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#   { name: reddit_pages, type: int, value: 2, description: Number of pages to fetch. }
#   { name: filter_walledgardens, type: boolean, value: 1, description: Filter walled gardens (soundcloud/spotify/โ€ฆ) if there's no player. }
#   { name: reddit_keep_all, type: boolean, value: 0, description: Keep all web links (starts a browser for websites/news). }
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJ1BMVEUAAAAcICX/AABHSk1jZ299hYz/bmajq6//lY/d0M3C1+3T7P38+/iaLhuGAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF
#   HUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffBRUXIyQbWArCAAAAh0lEQVQI12Pg3g0BDLtXrVq1eveq3Qy7gIxCU9dqEGO11/ZKbzBDenUIUM3u7cGi1UDFW0TE55wsdpZikAw/
#   eebMnMmHGVxqDuUc0zzpynD4zIk5J3vOSDNsOQMG1gy7bI5HTq85Ws2wu/jM9PIzrkArdhmXlzuuXg00eVd5+epVqxmgrtgNAOWeS1KYtcY4AAAAAElFTkSuQmCC
# extraction-method: json
# priority: extra
#
# Scans music-related subreddits for MP3/Youtube/Soundcloud
# links.
# Those are usually new bands or fresh releases, or favorite
# user selections. The category/subreddit list is filtered
# for a minimum quote of usable links (namely Youtube URLs).

Modified channels/shoutcast.py from [f2e0c497b6] to [68512fd7c7].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
# priority: default
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAelJREFUOI2NU0toE2EYnM12t2wLkhSXSIgEJMHFQ2naQ+kpoPYQoaXH3gRFsegloUhRQTyU2oOgggQUzzlEQomIBzU+EHooBIol0cOGLqFFFiJ5SB5skvFU6ebRduA7/DAz
#   /PM9BJLoh3Q6zVQqBZfLhXq9jlAohHA4LHTzhvqJ2+02c7kcgsEgfD4fRFFEPp+HZVmUJEk41kAURcHv99Pj8cAwDGiaBkVR0C0GAJDsW7VajYVCgYlEguVymZZlsVKpcG1tlYd5fX8AAIqiCF6vF6VSibIsI5lMYvvDE1xymwDu/ec5BhkcIJPJIHJzFqf372P1cgMf
#   f46cLIKu61yJXufr5VO0voyzEZ/k8sI4s9ns0RFarRZjL56inIshekWGenYS6IzhR9PCntRBIBCw8XsiFItFNLMxPJgfwVjDi4Y8g2b9DILaMKZGd2Ca5tEGiqJg2xjF200H6J+AvKtjeG8T3998xW5nAk6n08bviSBJEqhewLlpN4bMHfwxfuH5J8J98SGerS/B4XDY
#   d+FwQ6rVKm8vXeP++6vku2lu3FEZubFIXdc5qNm2x93ILZobszRfaYwuaIzH4wOFfafwt7CFb59/Y0uYx8rLR1BVtXd1u2AzCMwsQg6cx+O5uWOFBxAGnfNJ8Q/z/DNTtgbnsgAAAABJRU5ErkJggg==
# depends: re, ahttp

#
# Shoutcast is a server software for audio streaming. It automatically spools
# station information on shoutcast.com, which today lists over 60000 radios.
#
# It has been aquired by Radionomy in 2014. Since then significant changes
# took place. The former yellow pages API got deprecated. Streamtuner2 now
# utilizes the AJAX interface for speedy playlist discovery







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# priority: default
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAelJREFUOI2NU0toE2EYnM12t2wLkhSXSIgEJMHFQ2naQ+kpoPYQoaXH3gRFsegloUhRQTyU2oOgggQUzzlEQomIBzU+EHooBIol0cOGLqFFFiJ5SB5skvFU6ebRduA7/DAz
#   /PM9BJLoh3Q6zVQqBZfLhXq9jlAohHA4LHTzhvqJ2+02c7kcgsEgfD4fRFFEPp+HZVmUJEk41kAURcHv99Pj8cAwDGiaBkVR0C0GAJDsW7VajYVCgYlEguVymZZlsVKpcG1tlYd5fX8AAIqiCF6vF6VSibIsI5lMYvvDE1xymwDu/ec5BhkcIJPJIHJzFqf372P1cgMf
#   f46cLIKu61yJXufr5VO0voyzEZ/k8sI4s9ns0RFarRZjL56inIshekWGenYS6IzhR9PCntRBIBCw8XsiFItFNLMxPJgfwVjDi4Y8g2b9DILaMKZGd2Ca5tEGiqJg2xjF200H6J+AvKtjeG8T3998xW5nAk6n08bviSBJEqhewLlpN4bMHfwxfuH5J8J98SGerS/B4XDY
#   d+FwQ6rVKm8vXeP++6vku2lu3FEZubFIXdc5qNm2x93ILZobszRfaYwuaIzH4wOFfafwt7CFb59/Y0uYx8rLR1BVtXd1u2AzCMwsQg6cx+O5uWOFBxAGnfNJ8Q/z/DNTtgbnsgAAAABJRU5ErkJggg==
# depends: re, ahttp
# extraction-method: json, regex
#
# Shoutcast is a server software for audio streaming. It automatically spools
# station information on shoutcast.com, which today lists over 60000 radios.
#
# It has been aquired by Radionomy in 2014. Since then significant changes
# took place. The former yellow pages API got deprecated. Streamtuner2 now
# utilizes the AJAX interface for speedy playlist discovery

Modified channels/somafm.py from [e683a6b30b] to [9c3d6cd3c5].

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
# encoding: UTF-8
# api: streamtuner2
# title: SomaFM
# description: Alternative radio, entirely community sponsored and non-advertisey.
# version: 0.9
# type: channel
# category: radio
# url: http://somafm.com/
# config:
#   { name: somafm_bitrate, value: 64, type: select, select: "130=AAC โ†’ 128 kbit/s|64=AAC โ†’ 64 kbit/s|32=AAC โ†’ 32 kbit/s|0=MP3 โ†’ 128 kbit/s|56=MP3 โ†’ 56 kbit/s|24=MP3 โ†’ 24 kbit/s", description: "Most streams are accessible in different bitrates." }
# priority: extra

# png:
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACpUlEQVQokQXBS28bVRQA4HvOfcwd2xNP7caFtgiqkoglKyhCiFZiUSGxQcACdkis2SGx5lcgumFXhNoNGwpISGUZMKJSGtooStM4teOJXeOZufO4j8P3wZeff7r3z32tRaL7g/7Ikq/qXKEI4BZ5HnzYiJQn
#    50IAxuIkFe9/+NXDP+9JVr++tX3jk2/I29lkV0fd0DY741+z7PC9dz7Ki9XZ8kSrDudKSIBExx3ulVJJL5UcvVkoob0zm8Nzoc0uXnq1Mcuko9NewnkkgvNaMQVCQWirugz4w88/nUyPPrh+M9a9SGAIbVXWPlSmEkIxUeanArnkrLbNepX9vffw2x+/Z2Rni7PP3n0rjuLkxf7R8b+tMVYwaKzIJvuc
#    WkRE1j7dvX/77u0QcKOz8eDxnjk+2L6QDtLfpARXGssKEcVYtQwYcsCuiP74a7zzaB8Yy03DibXWjg+nv/9yz9fsP+NO182ybIRrV5aIA5ONOTw65oJrJQhCX8sYsSH+ZDopns8coyZU3Em8NNrUinMZT56vD+azWAkF1AUAS8vWrwKtnTuYZ97Zui7XdYkXh30GUqDczcPl0ebLg0HlnQZERkikOGFX
#    GuCmbvOynq8KzMoakaNKFMY3r11LtbKOeQYKMCZ4+3xyNWbzower9Vyx0JOI+4/GRWvLgq4Mo1Haq6pcCXBAAtl5bj9+I7313ddfvHkuNpkpKxaskI1Z1rp4NqWtV2ZPT04sAeeFBy4Di8W4rLaeHe+sxJ395aqcXhiN4LXtq6fZGSAQV0gEzMed/mJxmiYi1mIyMz1WV6itZ8G1/TTlqHRZFGVpgrcI
#    GIL3ntq2aRpXGAdEXkgOgMgiKTqdSLz0wqDo8UAEwIjIGF/VNun2iBEAU0pcHkYdBdaT9bA5TP8H6318x/9OSuUAAAAASUVORK5CYII=
#











>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# encoding: UTF-8
# api: streamtuner2
# title: SomaFM
# description: Alternative radio, entirely community sponsored and non-advertisey.
# version: 0.9
# type: channel
# category: radio
# url: http://somafm.com/
# config:
#   { name: somafm_bitrate, value: 64, type: select, select: "130=AAC โ†’ 128 kbit/s|64=AAC โ†’ 64 kbit/s|32=AAC โ†’ 32 kbit/s|0=MP3 โ†’ 128 kbit/s|56=MP3 โ†’ 56 kbit/s|24=MP3 โ†’ 24 kbit/s", description: "Most streams are accessible in different bitrates." }
# priority: extra
# extraction-method: static
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACpUlEQVQokQXBS28bVRQA4HvOfcwd2xNP7caFtgiqkoglKyhCiFZiUSGxQcACdkis2SGx5lcgumFXhNoNGwpISGUZMKJSGtooStM4teOJXeOZufO4j8P3wZeff7r3z32tRaL7g/7Ikq/qXKEI4BZ5HnzYiJQn
#    50IAxuIkFe9/+NXDP+9JVr++tX3jk2/I29lkV0fd0DY741+z7PC9dz7Ki9XZ8kSrDudKSIBExx3ulVJJL5UcvVkoob0zm8Nzoc0uXnq1Mcuko9NewnkkgvNaMQVCQWirugz4w88/nUyPPrh+M9a9SGAIbVXWPlSmEkIxUeanArnkrLbNepX9vffw2x+/Z2Rni7PP3n0rjuLkxf7R8b+tMVYwaKzIJvuc
#    WkRE1j7dvX/77u0QcKOz8eDxnjk+2L6QDtLfpARXGssKEcVYtQwYcsCuiP74a7zzaB8Yy03DibXWjg+nv/9yz9fsP+NO182ybIRrV5aIA5ONOTw65oJrJQhCX8sYsSH+ZDopns8coyZU3Em8NNrUinMZT56vD+azWAkF1AUAS8vWrwKtnTuYZ97Zui7XdYkXh30GUqDczcPl0ebLg0HlnQZERkikOGFX
#    GuCmbvOynq8KzMoakaNKFMY3r11LtbKOeQYKMCZ4+3xyNWbzower9Vyx0JOI+4/GRWvLgq4Mo1Haq6pcCXBAAtl5bj9+I7313ddfvHkuNpkpKxaskI1Z1rp4NqWtV2ZPT04sAeeFBy4Di8W4rLaeHe+sxJ395aqcXhiN4LXtq6fZGSAQV0gEzMed/mJxmiYi1mIyMz1WV6itZ8G1/TTlqHRZFGVpgrcI
#    GIL3ntq2aRpXGAdEXkgOgMgiKTqdSLz0wqDo8UAEwIjIGF/VNun2iBEAU0pcHkYdBdaT9bA5TP8H6318x/9OSuUAAAAASUVORK5CYII=
#

Modified channels/specbuttons.py from [8a8982cf89] to [89ccc02506].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import action
from uikit import gtk


# Extra/mini buttons in toolbar
class specbuttons(object):
    meta = plugin_meta()
    module = __name__

    # Hook toolbar label
    def __init__(self, parent):
        if not parent:
            return
        self.parent = parent
        conf.add_plugin_defaults(self.meta, self.module)







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import action
from uikit import gtk


# Extra/mini buttons in toolbar
class specbuttons(object):
    meta = plugin_meta()
    module = 'specbuttons'

    # Hook toolbar label
    def __init__(self, parent):
        if not parent:
            return
        self.parent = parent
        conf.add_plugin_defaults(self.meta, self.module)

Modified channels/surfmusik.py from [422b59ca2d] to [ef6ef15c63].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACmklEQVQokWXSy0tUYRgG8Pe7zBnzWk06RFGhoNAmBJuBbFDcNEoK4k5cxUQbYQYZBtok2L7NuGrpIlSkQNI004g8Ss1GuqAILjSkmNKD45k53+XM97aQpOj3FzzPwwNKKfkv
#   ISVKiYjT6+uJx48Lvl/WWgihlFJKgfyPL+UPKWefPPlaXz/JefbRI4kohZBSKqUoAJA/DKL0PMX52vh41ciIF48Xurtrx8ZezM5almWMAURKCDlJpbUGxGAg8FNKnJ7Ww8NkYqKyWLxLSGB5uQRAjQFCKAAwxjjnjDFKKTAW0nrm4sVgJvMplepdWfkFUBePVwAgIb7v
#   c0SklBrEsu8HOWfB4BfHqXGcbwMD8Vwux5gaHb0djxutgTGKCEopz/PcQsFTal+ImZmZifb2XYBdgFex2OziYgHxdEetNUilpOdJxDXbnr5z5wPARij0oKXl1cuXRURELCvlFosnPYUQRHueDAZzT59eSyYLUr7u6fkYDr+37ZvXr19uaGhqbu7q6mptbdVaI6Lv+5Ra
#   1tuFhWAqdcWYz/fuPa+qCjFWWy7Xnzv3bnU1nU53dnZms1lKqTEmEAjAMeJkOu0AfGxre7O/v72xoYTo6e7e2tpCxEwmAwA1NTV7e3vlclkIQSt9/0Yymevvt7a3ry4tVV66dCylYezw4GBnZ2dzc5NznslkwuGw1poQQoque6ai4oixQ9tumJr6VSjU1tU9XFo6ikaL
#   +fzZ8+cTiURHR4fW2hhDKeUIIJRC191wnHwkEmtqutDY6H7/fn9oKBqNVldXA4AQglJKCAEAcBxHKTU3NwcAAHArFns2NdXb15fP540xpVKpVCqd/lIpRbTWAICI8/PzrutalmXb9uDgYCQS8TyPcw5/IYT8BpJoukMEtogaAAAAAElFTkSuQmCC
# recognizes: max_streams

# url: http://surfmusic.de/
#
# This plugin comes in German (SurfMusik) and English (SurfMusic) variations.
# It provides a vast collection of international stations and genres.
# While it's not an open source project, most entries are user contributed.
#
# They do have a Windows client, hencewhy it's even more important for







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACmklEQVQokWXSy0tUYRgG8Pe7zBnzWk06RFGhoNAmBJuBbFDcNEoK4k5cxUQbYQYZBtok2L7NuGrpIlSkQNI004g8Ss1GuqAILjSkmNKD45k53+XM97aQpOj3FzzPwwNKKfkv
#   ISVKiYjT6+uJx48Lvl/WWgihlFJKgfyPL+UPKWefPPlaXz/JefbRI4kohZBSKqUoAJA/DKL0PMX52vh41ciIF48Xurtrx8ZezM5almWMAURKCDlJpbUGxGAg8FNKnJ7Ww8NkYqKyWLxLSGB5uQRAjQFCKAAwxjjnjDFKKTAW0nrm4sVgJvMplepdWfkFUBePVwAgIb7v
#   c0SklBrEsu8HOWfB4BfHqXGcbwMD8Vwux5gaHb0djxutgTGKCEopz/PcQsFTal+ImZmZifb2XYBdgFex2OziYgHxdEetNUilpOdJxDXbnr5z5wPARij0oKXl1cuXRURELCvlFosnPYUQRHueDAZzT59eSyYLUr7u6fkYDr+37ZvXr19uaGhqbu7q6mptbdVaI6Lv+5Ra
#   1tuFhWAqdcWYz/fuPa+qCjFWWy7Xnzv3bnU1nU53dnZms1lKqTEmEAjAMeJkOu0AfGxre7O/v72xoYTo6e7e2tpCxEwmAwA1NTV7e3vlclkIQSt9/0Yymevvt7a3ry4tVV66dCylYezw4GBnZ2dzc5NznslkwuGw1poQQoque6ai4oixQ9tumJr6VSjU1tU9XFo6ikaL
#   +fzZ8+cTiURHR4fW2hhDKeUIIJRC191wnHwkEmtqutDY6H7/fn9oKBqNVldXA4AQglJKCAEAcBxHKTU3NwcAAHArFns2NdXb15fP540xpVKpVCqd/lIpRbTWAICI8/PzrutalmXb9uDgYCQS8TyPcw5/IYT8BpJoukMEtogaAAAAAElFTkSuQmCC
# recognizes: max_streams
# extraction-method: regex
# url: http://surfmusic.de/
#
# This plugin comes in German (SurfMusik) and English (SurfMusic) variations.
# It provides a vast collection of international stations and genres.
# While it's not an open source project, most entries are user contributed.
#
# They do have a Windows client, hencewhy it's even more important for
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53



# Surfmusik sharing site
class surfmusik (ChannelPlugin):

    # module attributes
    module = __name__
    listformat = "m3u"
    has_search = False
    lang = "DE"   # last configured categories
    base = {
       "DE": ("http://www.surfmusik.de/", "genre/", "land/"),
       "EN": ("http://www.surfmusic.de/", "format/", "country/"),
    }







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54



# Surfmusik sharing site
class surfmusik (ChannelPlugin):

    # module attributes
    module = 'surfmusik'
    listformat = "m3u"
    has_search = False
    lang = "DE"   # last configured categories
    base = {
       "DE": ("http://www.surfmusik.de/", "genre/", "land/"),
       "EN": ("http://www.surfmusic.de/", "format/", "country/"),
    }

Modified channels/timer.py from [a0ecd3dcce] to [3136ca6563].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import action
import copy
import re



# timed events (play/record) within bookmarks tab
class timer:

    # plugin info
    module = __name__
    meta = plugin_meta()
    
    # configuration settings
    timefield = "playing"
    
    # kronos scheduler list
    sched = None







|


|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import action
import copy
import re



# timed events (play/record) within bookmarks tab
class timer (object):

    # plugin info
    module = 'timer'
    meta = plugin_meta()
    
    # configuration settings
    timefield = "playing"
    
    # kronos scheduler list
    sched = None

Modified channels/tunein.py from [19252f8edf] to [d31231b5cf].

12
13
14
15
16
17
18

19
20
21
22
23
24
25
# priority: default
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAbpJREFUOI2Nkk9PE1EUxc+ZuTMIaP+KqClxx4dA0jRVgwFM/JPIRv0CunDnxsQ1G4NGvgD7LkiExG5IDHFhDDEmblwRQJG2AVuwMNOZd91QAuUR
#   e1bvnnfeLzf3PsKioq6Dtf25xsq3Kdf3gkxh9OUis29tWcdm9iPxuvHl62MNQz/a+3uhVl56M647d7sGHOxU8hpFR7Uag9+l+UddAySdWuv0soWR710DXOj93mtDWxQBRTBwq7AcZfte2bK0mQCQ11X0I5lzEW2858BZMXBkZWkGqk8Atk7c
#   mBhqVCWV2E0MDz9dYLo8ptWbwdrP2aC6nSYhIOck2PiVdDwvfXxox9WqVAcPVtc/jOkm68uf56M/9T4AoAhMq5V06NCc2d+hNAzhwBttPz5q36FxchOT0xT5HwMEvRO1CHITk9MEgHHdfED4z4La9nmQqiY2dNywHY6b++d6h65OhVvVElw3
#   7rmY2VOE7xZ5pWTdwh2t52NEzwEeQtgTIXhR5uUfnVlr783m7vXGx0/32oOlCC7dLs4COAWwfiTH9+PTrrFnbWan6LkA/HLXAFckaJ+9bKYyeKP4cIEpK/wffVOh5FvT8j8AAAAASUVORK5CYII=
# documentation: http://opml.radiotime.com/

#
# RadioTime API uses OPML for station/podcast entries.
#
# Only radio listings are queried for now. But there are
# heaps more talk and local show entries, etc. (Would require
# more deeply nested category tree.)
#







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# priority: default
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAbpJREFUOI2Nkk9PE1EUxc+ZuTMIaP+KqClxx4dA0jRVgwFM/JPIRv0CunDnxsQ1G4NGvgD7LkiExG5IDHFhDDEmblwRQJG2AVuwMNOZd91QAuUR
#   e1bvnnfeLzf3PsKioq6Dtf25xsq3Kdf3gkxh9OUis29tWcdm9iPxuvHl62MNQz/a+3uhVl56M647d7sGHOxU8hpFR7Uag9+l+UddAySdWuv0soWR710DXOj93mtDWxQBRTBwq7AcZfte2bK0mQCQ11X0I5lzEW2858BZMXBkZWkGqk8Atk7c
#   mBhqVCWV2E0MDz9dYLo8ptWbwdrP2aC6nSYhIOck2PiVdDwvfXxox9WqVAcPVtc/jOkm68uf56M/9T4AoAhMq5V06NCc2d+hNAzhwBttPz5q36FxchOT0xT5HwMEvRO1CHITk9MEgHHdfED4z4La9nmQqiY2dNywHY6b++d6h65OhVvVElw3
#   7rmY2VOE7xZ5pWTdwh2t52NEzwEeQtgTIXhR5uUfnVlr783m7vXGx0/32oOlCC7dLs4COAWwfiTH9+PTrrFnbWan6LkA/HLXAFckaJ+9bKYyeKP4cIEpK/wffVOh5FvT8j8AAAAASUVORK5CYII=
# documentation: http://opml.radiotime.com/
# extraction-method: dom
#
# RadioTime API uses OPML for station/podcast entries.
#
# Only radio listings are queried for now. But there are
# heaps more talk and local show entries, etc. (Would require
# more deeply nested category tree.)
#

Modified channels/ubuntuusers.py from [e3bc6f87a2] to [5e7bfb243b].

10
11
12
13
14
15
16

17
18
19
20
21
22
23
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACJVBMVEUAAACjeUWif2/CeiGhWTvUewuhQRjPeRCfRyK1hEeWYkynQkOJREW0Dw+TICC3DAyXRES3DAzXzMewhlOsahqtaxu3DAytaxu4DAytaxqtIiKqeTyaR0eokHKk
#    h2SjayikZhmdbC+SdVaXVz2fQhufQxyhaVGjjYKsdjS2jmXBUSS2UimUXUaybBXCRA+MPx+vbR2+RhWLSCuhe0vBiEGrZUiDX0+TREWzP0CgQ0R1RUWcHByqFBSDKCifFxesMDGKUVGfFxfIsqng3tvBhz+khmDLdxCYYiDLdxGaYyKfFxfLdxGaYyKfFhbMdxCZYiCfNTW6gHzEjki+fCqdeEifZ2eWKSmVGhqTMTGXaWexkWWrbR+rbB2og1Oo
#    mYbWfhDefwjQexHXRgnXRgrziAP/jQDvhAC7jV/YTBT3SAD3SADthAT5iADngAG8kmfRTBfxRADwRADEhjm4h0nGuay0fGW/YTnAZD21ODq6PT7BQ0S9QEG2OTq2PD3KBATSAADSAADRAADSAADSAADSAADNAwPUAADUAADPAwPPDA3QDg/QDxDNAwPVAADRAAC2SUmzjIWsf3CugXLVAADJAADBgH3Hm1/eiBveiBzVAADIAADAf3rMizb+iwD9
#    iwDIAADAf3rMjDb8iwD7iwDNAwPVAADIAADAf3rMjDb7iwDOAwPXAADJAADBf3vMizb9iwD9jAC6EBC/CQm0ERLggArggAr///+cj9kUAAAAX3RSTlMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAZGJiK1ZiYlkJps315xim5xim5xh0+rQNdPq0DabnGKbnGKbnGOcY5xjnGKbnGKbnGKbN9ecYQGRiYitWYmJZCevlG38AAAABYktH
#    RLaqBwvxAAAAB3RJTUUH3wQMETciyGk1tQAAAHlJREFUGFd1jTESQUEQBbtnd+cXJxBwDiQSN3EwV5F+ZxC6hUAJlvIVJuya7ie48nWXOxVivtbRjaPRQWu6U4sBFaIMXSgGBEQ5Z2Zm1vr8qKaq9aXU/UT5avwCQG+E/gW0KWizheot39FUHT5Xjh5sBgjLbV9VT1ceE5sL4EiAe2YAAAAASUVORK5CYII=
# config: -
# priority: extra

#
# Short user-collected list of internet radio stations
# on UbuntuUsers.de wiki. Only provides a single category,
# but stations are grouped by country already.
#









>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACJVBMVEUAAACjeUWif2/CeiGhWTvUewuhQRjPeRCfRyK1hEeWYkynQkOJREW0Dw+TICC3DAyXRES3DAzXzMewhlOsahqtaxu3DAytaxu4DAytaxqtIiKqeTyaR0eokHKk
#    h2SjayikZhmdbC+SdVaXVz2fQhufQxyhaVGjjYKsdjS2jmXBUSS2UimUXUaybBXCRA+MPx+vbR2+RhWLSCuhe0vBiEGrZUiDX0+TREWzP0CgQ0R1RUWcHByqFBSDKCifFxesMDGKUVGfFxfIsqng3tvBhz+khmDLdxCYYiDLdxGaYyKfFxfLdxGaYyKfFhbMdxCZYiCfNTW6gHzEjki+fCqdeEifZ2eWKSmVGhqTMTGXaWexkWWrbR+rbB2og1Oo
#    mYbWfhDefwjQexHXRgnXRgrziAP/jQDvhAC7jV/YTBT3SAD3SADthAT5iADngAG8kmfRTBfxRADwRADEhjm4h0nGuay0fGW/YTnAZD21ODq6PT7BQ0S9QEG2OTq2PD3KBATSAADSAADRAADSAADSAADSAADNAwPUAADUAADPAwPPDA3QDg/QDxDNAwPVAADRAAC2SUmzjIWsf3CugXLVAADJAADBgH3Hm1/eiBveiBzVAADIAADAf3rMizb+iwD9
#    iwDIAADAf3rMjDb8iwD7iwDNAwPVAADIAADAf3rMjDb7iwDOAwPXAADJAADBf3vMizb9iwD9jAC6EBC/CQm0ERLggArggAr///+cj9kUAAAAX3RSTlMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAZGJiK1ZiYlkJps315xim5xim5xh0+rQNdPq0DabnGKbnGKbnGOcY5xjnGKbnGKbnGKbN9ecYQGRiYitWYmJZCevlG38AAAABYktH
#    RLaqBwvxAAAAB3RJTUUH3wQMETciyGk1tQAAAHlJREFUGFd1jTESQUEQBbtnd+cXJxBwDiQSN3EwV5F+ZxC6hUAJlvIVJuya7ie48nWXOxVivtbRjaPRQWu6U4sBFaIMXSgGBEQ5Z2Zm1vr8qKaq9aXU/UT5avwCQG+E/gW0KWizheot39FUHT5Xjh5sBgjLbV9VT1ceE5sL4EiAe2YAAAAASUVORK5CYII=
# config: -
# priority: extra
# extraction-method: regex
#
# Short user-collected list of internet radio stations
# on UbuntuUsers.de wiki. Only provides a single category,
# but stations are grouped by country already.
#


Modified channels/ui_cht.py from [b9bdcb6542] to [d3d33c0fb0].

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


import re


# Channel Homepage in Toolbar
class ui_cht(object):
    module = __name__

    # Hook toolbar label
    def __init__(self, parent):
        self.label = parent.toolbar_link
        parent.hooks["switch"].append(self.switchy)

    # Update link label
    def switchy(self, meta, *x, **y):
        title = meta.get("title")
        url = meta.get("url")
        domain = re.sub("^.+?//|/.+$", "", url)
        self.label.set_markup("<big><b>{}</b></big>\n<a href='{}'>{}</a>".format(title, url, domain))








|













11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


import re


# Channel Homepage in Toolbar
class ui_cht(object):
    module = 'ui_cht'

    # Hook toolbar label
    def __init__(self, parent):
        self.label = parent.toolbar_link
        parent.hooks["switch"].append(self.switchy)

    # Update link label
    def switchy(self, meta, *x, **y):
        title = meta.get("title")
        url = meta.get("url")
        domain = re.sub("^.+?//|/.+$", "", url)
        self.label.set_markup("<big><b>{}</b></big>\n<a href='{}'>{}</a>".format(title, url, domain))

Modified channels/useragentswitcher.py from [bebd1e46c5] to [8661193ea8].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from channels import *
import ahttp


# override ahttp.session headers, hooks into config dialog
class useragentswitcher():

    module = __name__
    meta = plugin_meta()
    map = {
       "default": "streamtuner2/2.1 (X11; Linux amd64; rv:33.0) like WinAmp/2.1",
       "vlc": "vlc 1.1.0-git-20100330-0003",
       "firefox": "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
       "chrome": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
       "android": "Mozilla/5.0 (Linux; U; Android 4.2; en-us; Nexus 10 Build/JVP15I) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from channels import *
import ahttp


# override ahttp.session headers, hooks into config dialog
class useragentswitcher():

    module = 'useragentswitcher'
    meta = plugin_meta()
    map = {
       "default": "streamtuner2/2.1 (X11; Linux amd64; rv:33.0) like WinAmp/2.1",
       "vlc": "vlc 1.1.0-git-20100330-0003",
       "firefox": "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
       "chrome": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
       "android": "Mozilla/5.0 (Linux; U; Android 4.2; en-us; Nexus 10 Build/JVP15I) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",

Modified channels/xiph.py from [8274e75920] to [6b1f12f6e5].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
# priority: standard
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAg5JREFUOI2lk1tIE2AUx3+7CG1tlmlG1rSEHrKgEUF7yO40taQiRj10I4qKkOaT4hIUItuTkC8hpJAQtJCICrFpzEKw
#   h61eQorGNBOTzbEt16ZrnR5Wq3mZD/3heziX//983znngyyov+eSbHEA5WKBhs4BKVy9gsqajqwiCwo0dA5IQX5u2s4moliMPPV1nCeDzxgNBFDHE2wsKMPzsGVefobjcnO7RMfeMuL341ZBrNEGRmPqqjdvsbbf
#   w7irO4Oj+rdywNNNucmERsLUVndR8uYRU13PCew6hpgP8W02xMpIsik++qk5oweW6y3yob8WnXacZDKJWh1Cp4OtRUHsh19TUlUGViv09RGqKAenU5QnLKm+rK88LjgcUnxmr/h8iNO5XYJBRAQZ/qiVeptGWjty
#   5cClDWLwugQRIRiU5UdPCoD6S89jhV6pks9WG6fuwtBtF5v72vC1v+B86SsM+jD56hjnyiM0lRrAbofeXjQJLdE/78jbXSU5166I6f5VeeDdKdq6GtlSd0QkVU+8XsQhlt9W6izbZ5aMKWgtp2WT/yUHd0xSYU7i
#   dsPQ+1WMKIsJD08wEV2HGLeRyNMjawqRxhuKBfdgz1m7fI/4mVX+ZGxmgniOoJv+QZHGAMC7p60ZnHkC8HfzZmLTBCd9af9ccnqMc9HTdmFe4kLkJbH/4h0xVtcu+SP/C78AL6btab6woPcAAAAASUVORK5CYII=

#
# Xiph.org maintains the Ogg streaming standard and Vorbis,
# Opus, FLAC audio, and Theora video compression formats.
# The ICEcast server is an open alternative to SHOUTcast.
#
# It also provides a directory listing of known internet
# radio stations; only a handful of them using Ogg though.







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# priority: standard
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAg5JREFUOI2lk1tIE2AUx3+7CG1tlmlG1rSEHrKgEUF7yO40taQiRj10I4qKkOaT4hIUItuTkC8hpJAQtJCICrFpzEKw
#   h61eQorGNBOTzbEt16ZrnR5Wq3mZD/3heziX//983znngyyov+eSbHEA5WKBhs4BKVy9gsqajqwiCwo0dA5IQX5u2s4moliMPPV1nCeDzxgNBFDHE2wsKMPzsGVefobjcnO7RMfeMuL341ZBrNEGRmPqqjdvsbbf
#   w7irO4Oj+rdywNNNucmERsLUVndR8uYRU13PCew6hpgP8W02xMpIsik++qk5oweW6y3yob8WnXacZDKJWh1Cp4OtRUHsh19TUlUGViv09RGqKAenU5QnLKm+rK88LjgcUnxmr/h8iNO5XYJBRAQZ/qiVeptGWjty
#   5cClDWLwugQRIRiU5UdPCoD6S89jhV6pks9WG6fuwtBtF5v72vC1v+B86SsM+jD56hjnyiM0lRrAbofeXjQJLdE/78jbXSU5166I6f5VeeDdKdq6GtlSd0QkVU+8XsQhlt9W6izbZ5aMKWgtp2WT/yUHd0xSYU7i
#   dsPQ+1WMKIsJD08wEV2HGLeRyNMjawqRxhuKBfdgz1m7fI/4mVX+ZGxmgniOoJv+QZHGAMC7p60ZnHkC8HfzZmLTBCd9af9ccnqMc9HTdmFe4kLkJbH/4h0xVtcu+SP/C78AL6btab6woPcAAAAASUVORK5CYII=
# extraction-method: xml, regex, json
#
# Xiph.org maintains the Ogg streaming standard and Vorbis,
# Opus, FLAC audio, and Theora video compression formats.
# The ICEcast server is an open alternative to SHOUTcast.
#
# It also provides a directory listing of known internet
# radio stations; only a handful of them using Ogg though.

Modified channels/youtube.py from [5f9e55387f] to [f32eca050a].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
# priority: default
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAYNJREFUOI3Fks9LVFEUxz/nzrPx+WN0xhAUgoT6A6y/wFb+C4IbIQhcBm36H1obVNtoGYS0TFoIQstazBgNBaELQdTx
#   vea9uffbwufw3mTRzi8cLnzv955z7vccuG7YXmtyBlgBbgFTQB3Q3/RAHzgD9oHdyMNTg01gshD8DwScCJ7bx+bEN7Cl0Xt5D2aYc//Iq67LYDFHXEamgGZmmd94SHzvPoMoIguerKQZamExykS9kjQIN3eThcdP
#   WAiBo/fbHLx5Te/LZzQYgFW6qbsMKEcf+CWRpCm+2aK5ts6drZfMP9okH4/pSxV91NeI4RLmA0mS4ns9JHGaJvzMc1Lpwo3Smyi7wl6FwHmScNzt8mPnA4fv3lLrtJkIHqt+AXvViFPB+JCQ0HQDrTyg127jvu4T
#   D3Jqzg0LDLWQ2lYj7oDulmlJZCEwZuD+GGMlRae2eiNqeVgOUA9AAAuAmSEzCq4cKs5TwYvIwzPBJ+A2F2s8XZQcXedL7qwY1neDHa4dvwFfDLdx6YbozgAAAABJRU5ErkJggg==
# depends: bin:youtube-dl

#
# 
# Lists recently popular youtube videos by category or channels.
#
# Introduces the faux MIME type "video/youtube" for player and recording
# configuration; both utilizing `youtube-dl`. But VLC can consume Youtube
# URLs directly anyhow.







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# priority: default
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAYNJREFUOI3Fks9LVFEUxz/nzrPx+WN0xhAUgoT6A6y/wFb+C4IbIQhcBm36H1obVNtoGYS0TFoIQstazBgNBaELQdTx
#   vea9uffbwufw3mTRzi8cLnzv955z7vccuG7YXmtyBlgBbgFTQB3Q3/RAHzgD9oHdyMNTg01gshD8DwScCJ7bx+bEN7Cl0Xt5D2aYc//Iq67LYDFHXEamgGZmmd94SHzvPoMoIguerKQZamExykS9kjQIN3eThcdP
#   WAiBo/fbHLx5Te/LZzQYgFW6qbsMKEcf+CWRpCm+2aK5ts6drZfMP9okH4/pSxV91NeI4RLmA0mS4ns9JHGaJvzMc1Lpwo3Smyi7wl6FwHmScNzt8mPnA4fv3lLrtJkIHqt+AXvViFPB+JCQ0HQDrTyg127jvu4T
#   D3Jqzg0LDLWQ2lYj7oDulmlJZCEwZuD+GGMlRae2eiNqeVgOUA9AAAuAmSEzCq4cKs5TwYvIwzPBJ+A2F2s8XZQcXedL7qwY1neDHa4dvwFfDLdx6YbozgAAAABJRU5ErkJggg==
# depends: bin:youtube-dl
# extraction-method: json
#
# 
# Lists recently popular youtube videos by category or channels.
#
# Introduces the faux MIME type "video/youtube" for player and recording
# configuration; both utilizing `youtube-dl`. But VLC can consume Youtube
# URLs directly anyhow.

Modified contrib/cachereset.py from [4ffd1ffb9c] to [8b61178eba].

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import os


# provides another export window, and custom file generation - does not use action.save()
class cachereset():

    meta = plugin_meta()
    module = __name__

    # Register in configwin
    def __init__(self, parent):
        # hook
        if not parent:
            return
        parent.hooks["config_load"].append(self.dialog_update)







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import os


# provides another export window, and custom file generation - does not use action.save()
class cachereset():

    meta = plugin_meta()
    module = 'cachereset'

    # Register in configwin
    def __init__(self, parent):
        # hook
        if not parent:
            return
        parent.hooks["config_load"].append(self.dialog_update)

Modified contrib/continuous_record.py from [8b1442273b] to [db37b9587d].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import action
from config import *
from uikit import *
import os, os.path

# Stop button
class continuous_record(object):
    module = __name__
    meta = plugin_meta()
    parent = None
    rec = None

    # exchange button and hook
    def __init__(self, parent):
        self.parent = parent







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import action
from config import *
from uikit import *
import os, os.path

# Stop button
class continuous_record(object):
    module = 'continuous_record'
    meta = plugin_meta()
    parent = None
    rec = None

    # exchange button and hook
    def __init__(self, parent):
        self.parent = parent

Modified contrib/delicast.py from [3740c184eb] to [1da3b76466].

9
10
11
12
13
14
15

16
17
18
19
20
21
22
# config: -
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
#    AmJLR0QA/4ePzL8AAAAHdElNRQffBB4UJAsX77G0AAAANUlEQVQY02OwQwMMdv/BAEUASCFEoAIIEZIEIGYjBCAUwpb/6O5ACEABGQJ2cFsQIlB3oAEA6iVo+vl+BbQA
#    AAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDQtMzBUMjI6MzY6MDMrMDI6MDAFLUvfAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTA0LTMwVDIyOjM2OjAzKzAyOjAwdHDz
#    YwAAAABJRU5ErkJggg==
# priority: rare

#
# Just a standard genre/country radio directory. Not very
# suitable for extraction actually, because it requires a
# second page request for uncovering the streaming URLs.
#
# This is done in row(), so only happens on playback. Which
# of course won't allow for exporting/bookmarking etc.







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# config: -
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
#    AmJLR0QA/4ePzL8AAAAHdElNRQffBB4UJAsX77G0AAAANUlEQVQY02OwQwMMdv/BAEUASCFEoAIIEZIEIGYjBCAUwpb/6O5ACEABGQJ2cFsQIlB3oAEA6iVo+vl+BbQA
#    AAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDQtMzBUMjI6MzY6MDMrMDI6MDAFLUvfAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTA0LTMwVDIyOjM2OjAzKzAyOjAwdHDz
#    YwAAAABJRU5ErkJggg==
# priority: rare
# extraction-method: regex, action-handler
#
# Just a standard genre/country radio directory. Not very
# suitable for extraction actually, because it requires a
# second page request for uncovering the streaming URLs.
#
# This is done in row(), so only happens on playback. Which
# of course won't allow for exporting/bookmarking etc.

Modified contrib/file.py from [c5a4a98a96] to [63bdb9da05].

14
15
16
17
18
19
20

21
22
23
24
25
26
27
#   iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wUFDQsK23vYngAAA6lJREFUOMtFz8tu1FYAxvH/sc+xxx7bM8lkElAgISoV4qIgpEaomwg2bMqiQmo3lfowPElVVbQr3gBVqGJRGi6VEERFDROS0Ewmc/N47Bkf+7gLevke4Kfv
#   L374/vufxm/ffjnudJQoisoVonLDcN+sr39z7uXLXzfOn6cRhmSTCf3TUwa9HoN+H601ynXxwhA7ivhdCH48PkZOut0vdh48cKtej9C2iSyLsF7/xLpx4/5eu/1LZzSiaQx1z8O5cIHapUvVmpRkaUqcJMRpSjydmnEcP/2zKH6WOs/7mdZBVVXIqsKuKk4nE4qdnTueUncCpZh5HoHj4AqBVRQIrUFrLGPwlaLhOLiWtX93OPxKIuX+0HHWJ5ZF03VxpaRfFLRmM1rTKUGrRX1piUYQEIUhfhRRC0OqOMZxHIIwJIgiHFj77OnT+7KEd0Wt
#   tl0Kgev7NHyf5apCTSaoLEMlCZdu3uT85ib1hQWi1VWcMCTb3cXxPJxmExlF2LWaMFpvS4TYcx2nmpalsKoKJQSNMCQ6cwZPCMxgwKTbpfPoETWlWDx3jtblyyghEFpjSYmwbYQx6DyPJUJ0bKUKU5Yqn83QSqGVolQKGQSEGxssrK3RffyY6Zs3zK9epb6wgBWGCCFQjkOlFFVRoIfDkTRwYIRIDTR0nqPnc7RSFP/AhW2jfJ/WlSvQ7zPe3SU9OECdPYuwbUrXxSiFsW2KOB7IaZYdp3keV9DQ8znacSj+RaWkqtVACExR0NrcZPriBflw
#   SJqmWO32R9BxMEAxnfatJE37cZb1jWVRaP3x4XxOkecIy0J6HibPmY1GqHqdpa0tbNdlvLNDfnJCOR5jJhPMYECZpj2JlPEwSbqBEFTG/Jd85fZtNm/dIjk6Itnbw19e5tN79yiHQ5JnzxgfHDBrNvGjCOM4lElCkWWn1ufb2/M4TQ9LIQAoiwJTlrQ3NrCVQjoOw04Hf2UF5ftI3wchsOt1Zu/eoTsd9KtX5E+eYCaTnux2u1VRVe8N/y/PMn57+JBka4v04IDs8JDD+RxGI8RoxPz1a6yyJJ/PGT9/rivXzZRSp3m9/kYAtFdWvm3PZt+1
#   kkQEtk1g2wRSEihV+badR7Va2vS8ceR5A9uYrimKv/LZ7MhU1VF7efnD2sWL3cb6+slzrT9IgKXFxT8W07S33GpZywsLHxzLep/Gcac3Gu0H9fp7Z3X1KLp27WT9+vXh8epq8vXdu7N+FPG61UIXBXZZAmCVJX8DADze5LjPkMQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDUtMDVUMTU6MTA6NTkrMDI6MDBD/PY6AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTA1LTA1VDE1OjEwOjU5KzAyOjAwMqFOhgAAAABJRU5ErkJggg==
# png-orig:
#   https://openclipart.org/detail/168001/folder-icon-red-music

#
# Local file browser. Presents files from configured directories.
# This is not what streamtuner2 is meant for. Therefore this is
# an optional plugin, and not overly well integrated.
#
# Bugs:
# Only loads directories on startup. Doesn't work when post-activated







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#   iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wUFDQsK23vYngAAA6lJREFUOMtFz8tu1FYAxvH/sc+xxx7bM8lkElAgISoV4qIgpEaomwg2bMqiQmo3lfowPElVVbQr3gBVqGJRGi6VEERFDROS0Ewmc/N47Bkf+7gLevke4Kfv
#   L374/vufxm/ffjnudJQoisoVonLDcN+sr39z7uXLXzfOn6cRhmSTCf3TUwa9HoN+H601ynXxwhA7ivhdCH48PkZOut0vdh48cKtej9C2iSyLsF7/xLpx4/5eu/1LZzSiaQx1z8O5cIHapUvVmpRkaUqcJMRpSjydmnEcP/2zKH6WOs/7mdZBVVXIqsKuKk4nE4qdnTueUncCpZh5HoHj4AqBVRQIrUFrLGPwlaLhOLiWtX93OPxKIuX+0HHWJ5ZF03VxpaRfFLRmM1rTKUGrRX1piUYQEIUhfhRRC0OqOMZxHIIwJIgiHFj77OnT+7KEd0Wt
#   tl0Kgev7NHyf5apCTSaoLEMlCZdu3uT85ib1hQWi1VWcMCTb3cXxPJxmExlF2LWaMFpvS4TYcx2nmpalsKoKJQSNMCQ6cwZPCMxgwKTbpfPoETWlWDx3jtblyyghEFpjSYmwbYQx6DyPJUJ0bKUKU5Yqn83QSqGVolQKGQSEGxssrK3RffyY6Zs3zK9epb6wgBWGCCFQjkOlFFVRoIfDkTRwYIRIDTR0nqPnc7RSFP/AhW2jfJ/WlSvQ7zPe3SU9OECdPYuwbUrXxSiFsW2KOB7IaZYdp3keV9DQ8znacSj+RaWkqtVACExR0NrcZPriBflw
#   SJqmWO32R9BxMEAxnfatJE37cZb1jWVRaP3x4XxOkecIy0J6HibPmY1GqHqdpa0tbNdlvLNDfnJCOR5jJhPMYECZpj2JlPEwSbqBEFTG/Jd85fZtNm/dIjk6Itnbw19e5tN79yiHQ5JnzxgfHDBrNvGjCOM4lElCkWWn1ufb2/M4TQ9LIQAoiwJTlrQ3NrCVQjoOw04Hf2UF5ftI3wchsOt1Zu/eoTsd9KtX5E+eYCaTnux2u1VRVe8N/y/PMn57+JBka4v04IDs8JDD+RxGI8RoxPz1a6yyJJ/PGT9/rivXzZRSp3m9/kYAtFdWvm3PZt+1
#   kkQEtk1g2wRSEihV+badR7Va2vS8ceR5A9uYrimKv/LZ7MhU1VF7efnD2sWL3cb6+slzrT9IgKXFxT8W07S33GpZywsLHxzLep/Gcac3Gu0H9fp7Z3X1KLp27WT9+vXh8epq8vXdu7N+FPG61UIXBXZZAmCVJX8DADze5LjPkMQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDUtMDVUMTU6MTA6NTkrMDI6MDBD/PY6AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTA1LTA1VDE1OjEwOjU5KzAyOjAwMqFOhgAAAABJRU5ErkJggg==
# png-orig:
#   https://openclipart.org/detail/168001/folder-icon-red-music
# extraction-method: os
#
# Local file browser. Presents files from configured directories.
# This is not what streamtuner2 is meant for. Therefore this is
# an optional plugin, and not overly well integrated.
#
# Bugs:
# Only loads directories on startup. Doesn't work when post-activated

Modified contrib/glrp.py from [698577c08b] to [9e8e02156c].

12
13
14
15
16
17
18

19
20
21
22
23
24
25
#   REFUOMuFk7trVFEQxn9zz9nc3Tw0CstGkCBoUHfhRgyIoF3wkRAUxEUrK7ESSWehFgpqI8TCTtQ/QCsLSSFisFFUSClBQzCJaPBBYkx2c+89Y3GyeW2iA6c4Z4Zvvvm+
#   OUJZ4bHwYUrtpae0B0JGQVk/RB3p6U4mLhyQSuGGIgCqmokGeA3sEsHwr1Bc7Ph2rIMjd0/KmKiqRAO8SpVDqmANtIQwPQ+xAyPr0ABU+Nh/mEh6H2j7+DTDiWMLgA1g
#   ayOUCtBg4MUnmK1CaFeDGKG6Ocd+GztCgUwtEQikDt5NgAmgby9kLQx/gckZ+DXvWTkIZxfIWGSRExCn8KgMzaG/5yyoQCWGc10wtwDXn3swI75ZsKSNQqkNOvKLGlTg
#   9ku4OgijP0AEchk4UYR0hUe2ThyFhRTOP/GFArwdhzt90LXd51dGsFbhQODNZ5iPl2k2WBgc8ZrU1dfb7EepJMtvczFEbeD0PwA1evkmuNYNrVnYlIXju6EcQeLqASzq
#   24rAyHffOTRwphN69oBz0Jrz3fONMDS6vFyqYEWIFZKaiEfvQ7Gw5Owqhb/O+F1oMBBAksuQyu+q2oP3eK9KpGtGWW+Ha2vjYPJUiWLQEkrSvZNehDEjpCIQBBsc74pT
#   mNrXxtlbPTIjTVeUPzeFy8+0eWiUHdUEg2z8GY3gom1MPizLTy4qfwFNC7cqp8RdxgAAAABJRU5ErkJggg==
# priority: extra

#
# Imports the playlist CSV from Great Little Radio Player.


import csv
from config import *
from channels import *







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#   REFUOMuFk7trVFEQxn9zz9nc3Tw0CstGkCBoUHfhRgyIoF3wkRAUxEUrK7ESSWehFgpqI8TCTtQ/QCsLSSFisFFUSClBQzCJaPBBYkx2c+89Y3GyeW2iA6c4Z4Zvvvm+
#   OUJZ4bHwYUrtpae0B0JGQVk/RB3p6U4mLhyQSuGGIgCqmokGeA3sEsHwr1Bc7Ph2rIMjd0/KmKiqRAO8SpVDqmANtIQwPQ+xAyPr0ABU+Nh/mEh6H2j7+DTDiWMLgA1g
#   ayOUCtBg4MUnmK1CaFeDGKG6Ocd+GztCgUwtEQikDt5NgAmgby9kLQx/gckZ+DXvWTkIZxfIWGSRExCn8KgMzaG/5yyoQCWGc10wtwDXn3swI75ZsKSNQqkNOvKLGlTg
#   9ku4OgijP0AEchk4UYR0hUe2ThyFhRTOP/GFArwdhzt90LXd51dGsFbhQODNZ5iPl2k2WBgc8ZrU1dfb7EepJMtvczFEbeD0PwA1evkmuNYNrVnYlIXju6EcQeLqASzq
#   24rAyHffOTRwphN69oBz0Jrz3fONMDS6vFyqYEWIFZKaiEfvQ7Gw5Owqhb/O+F1oMBBAksuQyu+q2oP3eK9KpGtGWW+Ha2vjYPJUiWLQEkrSvZNehDEjpCIQBBsc74pT
#   mNrXxtlbPTIjTVeUPzeFy8+0eWiUHdUEg2z8GY3gom1MPizLTy4qfwFNC7cqp8RdxgAAAABJRU5ErkJggg==
# priority: extra
# extraction-method: csv
#
# Imports the playlist CSV from Great Little Radio Player.


import csv
from config import *
from channels import *

Modified contrib/gtk_theme.py from [b5df3c1053] to [c94ca7aa89].

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40



# register a key
class gtk_theme(object):

    # plugin info
    module = __name__
    meta = plugin_meta()
    theme_dirs = [uikit.gtk.rc_get_theme_dir(), conf.dir + "/themes", conf.share + "/themes"]

    # register
    def __init__(self, parent):
        self.parent = parent
        parent.hooks["config_load"].append(self.list_themes)







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40



# register a key
class gtk_theme(object):

    # plugin info
    module = 'gtk_theme'
    meta = plugin_meta()
    theme_dirs = [uikit.gtk.rc_get_theme_dir(), conf.dir + "/themes", conf.share + "/themes"]

    # register
    def __init__(self, parent):
        self.parent = parent
        parent.hooks["config_load"].append(self.list_themes)

Modified contrib/housemixes.py from [34d9935a73] to [1b91e8da1a].

10
11
12
13
14
15
16

17
18
19
20
21
22
23
#    ( -x-off-name: housemixes_pages, type: int, value: 5, description: maximum number of pages to scan )
# priority: contrib
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABQAAAASBAMAAACp/uMjAAAAGFBMVEUIBQE7KCGSPABUWFrwcACIkJayuLr3+vjaVnR4AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMB
#    AJqcGAAAAAd0SU1FB+AKCQwWONCoEiQAAACPSURBVAjXLY29DsIgFIUPxehaExJXW+EB7MJaCE/gAKvRaNdWYu/rewve6bsn5wcARN+3KNeE7hgq60t8X30Rx4mIhjOj2tMr
#    UnaMPmXAUsPiSBwRdHMcWtEKpIdHMFk7FQ6fAG0WPe46OXgos9QhrpC5jm576wayvBO0x7Pgaebee0HJDlv9sN80/xGxOH8QkRfKLi9RvwAAAABJRU5ErkJggg==
# depends: pq, ahttp

#
# House-mixes.com is an UK platform for DJs to showcase their
# house/dance/techno mixes.
#


import ahttp







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#    ( -x-off-name: housemixes_pages, type: int, value: 5, description: maximum number of pages to scan )
# priority: contrib
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABQAAAASBAMAAACp/uMjAAAAGFBMVEUIBQE7KCGSPABUWFrwcACIkJayuLr3+vjaVnR4AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMB
#    AJqcGAAAAAd0SU1FB+AKCQwWONCoEiQAAACPSURBVAjXLY29DsIgFIUPxehaExJXW+EB7MJaCE/gAKvRaNdWYu/rewve6bsn5wcARN+3KNeE7hgq60t8X30Rx4mIhjOj2tMr
#    UnaMPmXAUsPiSBwRdHMcWtEKpIdHMFk7FQ6fAG0WPe46OXgos9QhrpC5jm576wayvBO0x7Pgaebee0HJDlv9sN80/xGxOH8QkRfKLi9RvwAAAABJRU5ErkJggg==
# depends: pq, ahttp
# extraction-method: dom, action-handler
#
# House-mixes.com is an UK platform for DJs to showcase their
# house/dance/techno mixes.
#


import ahttp

Modified contrib/listenlive.py from [c1d1551be3] to [42518d754d].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAARVBMVEWdHBWSg1Cbj1mnmF6jn5GuomajpaCrqYu3qmy0roi6
#   r3rAsW25tae2t7HCvKfPv3rOw4zKxrfJyMDTzaXUz7LW1s7g4t727CdZAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJ
#   cEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffBQcAMynMUk7PAAAAkElEQVQY01VP2xbDIAizUq0WGS1e/v9TB9qdbXlLICE4
#   Z9g8gN/cB1tAVmB4JI98tdbqlZJ/eBWS3u8jTCVx7RRNKEdKzgFffVBUfpdyItjCGJG6iCqZk0Nuo6tDiIp6cAqiDokx7hZi
#   Fo3QBSp7xmChOhSxjNfJsM5OaKadncWWkL9V/6rrc7Ceg59/vWLRN2yqCjHMvARcAAAAAElFTkSuQmCC
# png-orig: https://openclipart.org/detail/148465/1-euro
# priority: extra

#
# And another radio directory, primarily collecting euro
# stations, mixed genres, and grouping by country.
#
# Also available:
#  http://www.australianliveradio.com/
#  http://www.nzradioguide.co.nz/







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAARVBMVEWdHBWSg1Cbj1mnmF6jn5GuomajpaCrqYu3qmy0roi6
#   r3rAsW25tae2t7HCvKfPv3rOw4zKxrfJyMDTzaXUz7LW1s7g4t727CdZAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJ
#   cEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffBQcAMynMUk7PAAAAkElEQVQY01VP2xbDIAizUq0WGS1e/v9TB9qdbXlLICE4
#   Z9g8gN/cB1tAVmB4JI98tdbqlZJ/eBWS3u8jTCVx7RRNKEdKzgFffVBUfpdyItjCGJG6iCqZk0Nuo6tDiIp6cAqiDokx7hZi
#   Fo3QBSp7xmChOhSxjNfJsM5OaKadncWWkL9V/6rrc7Ceg59/vWLRN2yqCjHMvARcAAAAAElFTkSuQmCC
# png-orig: https://openclipart.org/detail/148465/1-euro
# priority: extra
# extraction-method: regex
#
# And another radio directory, primarily collecting euro
# stations, mixed genres, and grouping by country.
#
# Also available:
#  http://www.australianliveradio.com/
#  http://www.nzradioguide.co.nz/

Modified contrib/liveradio.py from [d6d8086730] to [60d876bcc4].

9
10
11
12
13
14
15

16
17
18
19
20
21
22
# 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







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 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

Modified contrib/magnatune.py from [0577bfd522] to [b928142549].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAMFBMVEUAW5kAY6ACa6MVd6sWgLE2irdHmcBdpslvrsuEudWY
#   xdmiy9+21+fO4u7z+fz9//wtPja+AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB98FBhQ2G9ph
#   h8MAAACySURBVAjXY/j//22rccS9//8Z/v9NVAl1ErsPZB0W2/vudqLPf4a/Ruv+lf9/qXyf4ZnU+79O//9Pime4mPf/j9H/
#   /1+tGYr2//tj9O/dH3EGl/vHzhr9yf1nyqD6vqjW6AfXu2AgKwnIkvoXDJSFsMyAOkCyUkAdF/MTaw1/cAFNeSZ1/d6sv3VN
#   cQx/neb///f/BdC2/0dEz717E2QLclWycKihGchV/99Mc8k89/8/AD9dZbS2m1Y9AAAAAElFTkSuQmCC
# priority: extra

# 
# Magnatune is a label for independent music. It provides
# free access to a partial section of its reportoire as MP3.
# Using paid subscriptions, all albums are available in
# higher quality Ogg Vorbis or FLAC encodings however.
#
# You can listen to all albums and tracks freely. They're







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAMFBMVEUAW5kAY6ACa6MVd6sWgLE2irdHmcBdpslvrsuEudWY
#   xdmiy9+21+fO4u7z+fz9//wtPja+AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB98FBhQ2G9ph
#   h8MAAACySURBVAjXY/j//22rccS9//8Z/v9NVAl1ErsPZB0W2/vudqLPf4a/Ruv+lf9/qXyf4ZnU+79O//9Pime4mPf/j9H/
#   /1+tGYr2//tj9O/dH3EGl/vHzhr9yf1nyqD6vqjW6AfXu2AgKwnIkvoXDJSFsMyAOkCyUkAdF/MTaw1/cAFNeSZ1/d6sv3VN
#   cQx/neb///f/BdC2/0dEz717E2QLclWycKihGchV/99Mc8k89/8/AD9dZbS2m1Y9AAAAAElFTkSuQmCC
# priority: extra
# extraction-method: regex
# 
# Magnatune is a label for independent music. It provides
# free access to a partial section of its reportoire as MP3.
# Using paid subscriptions, all albums are available in
# higher quality Ogg Vorbis or FLAC encodings however.
#
# You can listen to all albums and tracks freely. They're

Modified contrib/podspider.py from [d384743d3e] to [6724c28afd].

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
# encoding: UTF-8
# api: streamtuner2
# title: PODspider
# description: lists Podcasts RSS from proprietary podspider xml database
# version: 0.0
# type: channel
# category: talk
# depends: lxml.etree, pyquery
# url: http://www.radiograbber.de/
# status: unsupported
# priority: never

#
# Podspider is one part of the commercial Windows "Radiograbber" software.
# A demo version is available from http://www.surfmusik.net/downloads/download.php?pid=13
# and runs under Wine.
# It downloads a "Podspiderpdb.xml.tmp_", which this plugin can display as
# streamtuner2 channel. The contents are a pre-classified list of PODcasts
# via RSS feeds. It needs some rework to strip out excessive duplicates, but











>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# encoding: UTF-8
# api: streamtuner2
# title: PODspider
# description: lists Podcasts RSS from proprietary podspider xml database
# version: 0.0
# type: channel
# category: talk
# depends: lxml.etree, pyquery
# url: http://www.radiograbber.de/
# status: unsupported
# priority: never
# extraction-method: dom
#
# Podspider is one part of the commercial Windows "Radiograbber" software.
# A demo version is available from http://www.surfmusik.net/downloads/download.php?pid=13
# and runs under Wine.
# It downloads a "Podspiderpdb.xml.tmp_", which this plugin can display as
# streamtuner2 channel. The contents are a pre-classified list of PODcasts
# via RSS feeds. It needs some rework to strip out excessive duplicates, but
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    return ""  # empty string if nothing found


# PODlist from Radiograbber
class podspider (ChannelPlugin):

    # pi info
    module = __name__
    homepage = "http://www.radiograbber.de/"
    listformat = "rss"

    # data
    config = [
    ]
    xml = None







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    return ""  # empty string if nothing found


# PODlist from Radiograbber
class podspider (ChannelPlugin):

    # pi info
    module = 'podspider'
    homepage = "http://www.radiograbber.de/"
    listformat = "rss"

    # data
    config = [
    ]
    xml = None

Modified contrib/prefstore.py from [e5b03874ae] to [32a9e10322].

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import re
import json


# hooks three functions to the main extension menu
class prefstore():

    module = __name__
    meta = plugin_meta()

    # Register callback
    def __init__(self, parent):
        if not parent:
            return
        self.parent = parent







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import re
import json


# hooks three functions to the main extension menu
class prefstore():

    module = 'prefstore'
    meta = plugin_meta()

    # Register callback
    def __init__(self, parent):
        if not parent:
            return
        self.parent = parent

Modified contrib/publicradiofan.py from [27f032530a] to [912394ee7c].

12
13
14
15
16
17
18

19
20
21
22
23
24
25
#   iVBORw0KGgoAAAANSUhEUgAAAA8AAAAQCAMAAAD+iNU2AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACbVBMVEUAAAD//wDR0QDd3QD//wAfHwAhKQALDgAICAYAAADo6ADd3QD8/ADb2wDm5gD//wD//wD//wCxsQClpQDt7QCjowCurgD//wD//wD//wD//wD//wD//wD//wCdnQClowCioACYmAD//wD//wD//wD//wD//wD//wD//wD//w
#   CurgCbmwCEgQCWlgCiogD//wD//wD//wD//wD//wDt7QDHxwDV1QD5+QDq6gCysgBYWQCkpADQ0AD//wD//wD//wD//wDm5gDDwwCOjgCoqADLywD+/gDJyQAgIAB2dgD//wD//wD//wD//wDY2ACnpwA6OgBfXwCzswD29gDOzgAgIAAdHQD//wD9/QDq6gDQ0ABtbQAHBwCEhAD8/ADh4QA/PwCamgD//wD//wD//wD//wDu7gDMzADExACamgAJCQCHhwDl5QDr6wCLiwDh4QD9/QD//wD//wD//wDv7wC6
#   ugCurgBMTAAWFQB9fAB1cADb2gDBwQDe3gDm5gD6+gD//wD//wDk5ADExAB6egKjqBZbZSpSXTp3cSVlJgXCsgG9vgDKygDU1AD39wD//wCXmQBjawBCSwFibzBQWlEuIhw+OxlmZgCOjgCkpADw8AD//wAiKwA9TQE9SkcgICETEwIcHBIfHw6DgwD//wAEBQAVGgAlJycMDAweHh4GBgQAAAABAQEAAAAEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAADHswAPDwA2NgBdXQB0iHd7joxRYRJQYDBabmpdcm4jIy
#   IiJw0rLyA7Pj4+QUEJCQkDAwMfHyAAAAABAQEDAwMDAwMBAQEEBAT////bfgUcAAAAtnRSTlMAAAAAAAAAAAAADDVGMgoAAAM8pb+hNwIAAgUHBgxq5+NiBgAEDRcdHBxg1PXOUQQABBAkO1JOOT51tWcaAAELIkh9p6B4RDiNGQAEFDl3uOngtW9FlhIGKnW57v/lrXitLBMGAAtTx/P7//ntvtCJcDMHDmXk/P78/P/h7e/gdhoGRrXy9vv39fjF7/3zhx8eqO799vjo8dzCUw4S0PL6/PjJHQA23e752SSQ
#   /v/8V5P////+WUJFFrYAAAABYktHRM702fL/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wQdFiYdwDwd5wAAAQdJREFUCNdjYAADRiYubh5ePmZGEJuRX4BFUEhYRFRMHMhnlJCUkpaRlZPfpqCoxMjAqKyiqqauoamlraOrp8/IYGBoZGxiamZuYWllbWPLyGBn7+Do5Ozi6ubu4enFyMjg7ePr5x8QGBQcEhrGCjQuPCIyKnp7TGxcfEJiUnIKQ2paekbmjqzsnNy8/ILCIobiktKdZeUVlVXVNb
#   V19Q0MjU3NLa1t7R2dXd09vX39DAwTJk6avGv3lKnTps+YOWs2A9ucuXv27ts/b/6BBQsXLV7CwL502cFDh48sX3H02PGVqzgYGFafOHHy1Ok1a0+cObtuPScDw4YTG4Fg0+aNG09s2coAANV6WR2+KyzWAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE1LTA0LTMwVDAwOjM4OjA5KzAyOjAwPqZVxAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNS0wNC0zMFQwMDozODowOSswMjowME/77XgAAAAASUVORK5CYII=
# x-png-src: https://openclipart.org/detail/101737/vacuum-tubes

#
# PRF is a privately maintained directory of international
# radio stations, scheduled broadcasting programs, and
# internet streams grouped by location/genre/format/topics.
#
# This plugin is just browsing the format categories, uses a
# static genre list. Podcasts, scheduled programs aren't fetched.







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#   iVBORw0KGgoAAAANSUhEUgAAAA8AAAAQCAMAAAD+iNU2AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACbVBMVEUAAAD//wDR0QDd3QD//wAfHwAhKQALDgAICAYAAADo6ADd3QD8/ADb2wDm5gD//wD//wD//wCxsQClpQDt7QCjowCurgD//wD//wD//wD//wD//wD//wD//wCdnQClowCioACYmAD//wD//wD//wD//wD//wD//wD//wD//w
#   CurgCbmwCEgQCWlgCiogD//wD//wD//wD//wD//wDt7QDHxwDV1QD5+QDq6gCysgBYWQCkpADQ0AD//wD//wD//wD//wDm5gDDwwCOjgCoqADLywD+/gDJyQAgIAB2dgD//wD//wD//wD//wDY2ACnpwA6OgBfXwCzswD29gDOzgAgIAAdHQD//wD9/QDq6gDQ0ABtbQAHBwCEhAD8/ADh4QA/PwCamgD//wD//wD//wD//wDu7gDMzADExACamgAJCQCHhwDl5QDr6wCLiwDh4QD9/QD//wD//wD//wDv7wC6
#   ugCurgBMTAAWFQB9fAB1cADb2gDBwQDe3gDm5gD6+gD//wD//wDk5ADExAB6egKjqBZbZSpSXTp3cSVlJgXCsgG9vgDKygDU1AD39wD//wCXmQBjawBCSwFibzBQWlEuIhw+OxlmZgCOjgCkpADw8AD//wAiKwA9TQE9SkcgICETEwIcHBIfHw6DgwD//wAEBQAVGgAlJycMDAweHh4GBgQAAAABAQEAAAAEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAADHswAPDwA2NgBdXQB0iHd7joxRYRJQYDBabmpdcm4jIy
#   IiJw0rLyA7Pj4+QUEJCQkDAwMfHyAAAAABAQEDAwMDAwMBAQEEBAT////bfgUcAAAAtnRSTlMAAAAAAAAAAAAADDVGMgoAAAM8pb+hNwIAAgUHBgxq5+NiBgAEDRcdHBxg1PXOUQQABBAkO1JOOT51tWcaAAELIkh9p6B4RDiNGQAEFDl3uOngtW9FlhIGKnW57v/lrXitLBMGAAtTx/P7//ntvtCJcDMHDmXk/P78/P/h7e/gdhoGRrXy9vv39fjF7/3zhx8eqO799vjo8dzCUw4S0PL6/PjJHQA23e752SSQ
#   /v/8V5P////+WUJFFrYAAAABYktHRM702fL/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wQdFiYdwDwd5wAAAQdJREFUCNdjYAADRiYubh5ePmZGEJuRX4BFUEhYRFRMHMhnlJCUkpaRlZPfpqCoxMjAqKyiqqauoamlraOrp8/IYGBoZGxiamZuYWllbWPLyGBn7+Do5Ozi6ubu4enFyMjg7ePr5x8QGBQcEhrGCjQuPCIyKnp7TGxcfEJiUnIKQ2paekbmjqzsnNy8/ILCIobiktKdZeUVlVXVNb
#   V19Q0MjU3NLa1t7R2dXd09vX39DAwTJk6avGv3lKnTps+YOWs2A9ucuXv27ts/b/6BBQsXLV7CwL502cFDh48sX3H02PGVqzgYGFafOHHy1Ok1a0+cObtuPScDw4YTG4Fg0+aNG09s2coAANV6WR2+KyzWAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE1LTA0LTMwVDAwOjM4OjA5KzAyOjAwPqZVxAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNS0wNC0zMFQwMDozODowOSswMjowME/77XgAAAAASUVORK5CYII=
# x-png-src: https://openclipart.org/detail/101737/vacuum-tubes
# extraction-method: regex
#
# PRF is a privately maintained directory of international
# radio stations, scheduled broadcasting programs, and
# internet streams grouped by location/genre/format/topics.
#
# This plugin is just browsing the format categories, uses a
# static genre list. Podcasts, scheduled programs aren't fetched.

Modified contrib/radionet.py from [0e376ccfde] to [a8d2a6968a].

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
# encoding: UTF-8
# api: streamtuner2
# title: radio.net
# description: Europe's biggest radio platform
# url: http://radio.net/
# version: 0.5
# type: channel
# category: radio
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAt0lEQVR42mNgYGD4r+Ar/F/BDwkD+SBxojBMs1mLPBArgGlFqEEENYMNQNLsukIDYkirAvGu
#   ABsA1OC6XOP/5f8nwIaYAg0k2gBFsAsgTgcZkvnfDugFEeK9AFKsCPMG0CU6eZJgQ4R1eP8H7LLEivWyFJANQcQCLPBAmkGG4MJohmA6C6QA5gI5OxEUDNII
#   MwSvASBFIA3ociCxkWQAKMDICkSQIpgh2LDnSmP80YhsCFEJiRIMADpmeUOpqgjRAAAAAElFTkSuQmCC
# priority: optional

#
# Radio.net lists around 20.000 worldwide radio stations.
# A maximum of three pages from each genre are fetched here,
# some of the empty categories already omitted.
#
# The website heavily depends on JavaScript, a Flash player,
# some social tracking cookies. But still feasible to access













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# encoding: UTF-8
# api: streamtuner2
# title: radio.net
# description: Europe's biggest radio platform
# url: http://radio.net/
# version: 0.5
# type: channel
# category: radio
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAt0lEQVR42mNgYGD4r+Ar/F/BDwkD+SBxojBMs1mLPBArgGlFqEEENYMNQNLsukIDYkirAvGu
#   ABsA1OC6XOP/5f8nwIaYAg0k2gBFsAsgTgcZkvnfDugFEeK9AFKsCPMG0CU6eZJgQ4R1eP8H7LLEivWyFJANQcQCLPBAmkGG4MJohmA6C6QA5gI5OxEUDNII
#   MwSvASBFIA3ociCxkWQAKMDICkSQIpgh2LDnSmP80YhsCFEJiRIMADpmeUOpqgjRAAAAAElFTkSuQmCC
# priority: optional
# extraction-method: regex
#
# Radio.net lists around 20.000 worldwide radio stations.
# A maximum of three pages from each genre are fetched here,
# some of the empty categories already omitted.
#
# The website heavily depends on JavaScript, a Flash player,
# some social tracking cookies. But still feasible to access

Modified contrib/radiosure.py from [e1d926fd86] to [3ff12fd005].

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
# encoding: UTF-8
# api: streamtuner2
# title: RadioSure
# description: Huge radio station collection
# version: 0.5
# type: channel
# category: radio
# url: http://radiosure.com/
# config: -
# priority: extra
# png: 
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEULDgpKTEmQko/19/S0inLcAAAAUklEQVQI12P4DwQMDvuBBIs92zcGHh2G
#   BQw+FvUPGDwq/n9gaPoj/5DB6b/TQwaH/18uMrjs/yPI4FP2R4kh1vBHPUO8SsAnBn8P9ocMYFNABADRrSa61FmXoAAAAABJRU5ErkJggg==

#
# RadioSure is a Windows freeware/shareware for playing internet
# stations. It comes with a huge database of streams.
#
# Fetches and keeps the ZIP/CSV database at maximum once per day.
# (Not updated more frequently.)














>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# encoding: UTF-8
# api: streamtuner2
# title: RadioSure
# description: Huge radio station collection
# version: 0.5
# type: channel
# category: radio
# url: http://radiosure.com/
# config: -
# priority: extra
# png: 
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEULDgpKTEmQko/19/S0inLcAAAAUklEQVQI12P4DwQMDvuBBIs92zcGHh2G
#   BQw+FvUPGDwq/n9gaPoj/5DB6b/TQwaH/18uMrjs/yPI4FP2R4kh1vBHPUO8SsAnBn8P9ocMYFNABADRrSa61FmXoAAAAABJRU5ErkJggg==
# extraction-method: csv
#
# RadioSure is a Windows freeware/shareware for playing internet
# stations. It comes with a huge database of streams.
#
# Fetches and keeps the ZIP/CSV database at maximum once per day.
# (Not updated more frequently.)

Modified contrib/reciva.py from [497ae97678] to [d18660a1dc].

8
9
10
11
12
13
14

15
16
17
18
19
20
21
# category: radio
# config: -
# priority: contrib
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAGFBMVEXiMATfORfhQyTrZk7uh3Tzs6n10879+/iUjtOkAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAA
#    CxMBAJqcGAAAAAd0SU1FB+AEBw4nI8D7wUYAAACISURBVAjXDc09D4JAFETREcParl/UvKdoKxi1JgZoiYnQSiJua2ST+ftud3KLGZDvYteT4DRTifqAFCvVmPBRl6um
#    DsOWP1W5oUw42dQaFBu2lckqqJwxHg8Burx+u0WGXOW5nuoYZUhN6xMMKr03ryYMyj36WAee5OJaE7687R5zF8Cx2DvyD3ZIHyPRcAnIAAAAAElFTkSuQmCC

#
# Reciva is a mobile app. They have a web directory though.
# It's a bit difficult to query, and streaming urls aren't
# directly accessible. But allows to fetch all stations from
# a category at once; so still a quick database.
#
# They probably have an API somewhere, but no public docs.







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# category: radio
# config: -
# priority: contrib
# png:
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAGFBMVEXiMATfORfhQyTrZk7uh3Tzs6n10879+/iUjtOkAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAA
#    CxMBAJqcGAAAAAd0SU1FB+AEBw4nI8D7wUYAAACISURBVAjXDc09D4JAFETREcParl/UvKdoKxi1JgZoiYnQSiJua2ST+ftud3KLGZDvYteT4DRTifqAFCvVmPBRl6um
#    DsOWP1W5oUw42dQaFBu2lckqqJwxHg8Burx+u0WGXOW5nuoYZUhN6xMMKr03ryYMyj36WAee5OJaE7687R5zF8Cx2DvyD3ZIHyPRcAnIAAAAAElFTkSuQmCC
# extraction-method: dom, action-handler
#
# Reciva is a mobile app. They have a web directory though.
# It's a bit difficult to query, and streaming urls aren't
# directly accessible. But allows to fetch all stations from
# a category at once; so still a quick database.
#
# They probably have an API somewhere, but no public docs.
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from channels import *


# Reciva directory
class reciva (ChannelPlugin):

    # module attributes
    module = __name__
    listformat = "pls"
    has_search = True
    categories = ['60s', '70s', '80s', '90s', 'Adult', ['Adult Contemporary'], 'Alternative', 'Ambient', 'Bluegrass', 'Blues', 'Bollywood', 'Christian', ['Christian Contemporary'], 'Classic Rock', 'Classical', 'College', 'Comedy', 'Contemporary', 'Country', 'Dance', 'Discussion', 'Easy', 'Electronica', 'Experimental', 'Folk', 'Gospel', 'Greek', 'Hip Hop', 'Indian', 'Indie', ['Indie Rock'], 'Jazz', 'Jungle', 'Kids', 'Latin Hits', 'New Age', 'News', ['News Talk', 'News Updates'], 'Oldies', 'Pop', 'Public', 'Punk', 'Rap', 'Reggae', 'Religious', 'Rock', 'Short Wave Radio', 'Soft Rock', 'Spanish', 'Sports', 'Talk', 'Top 40', 'Unknown', 'Varied', 'World', ['World Africa', 'World Asia', 'World Caribbean', 'World Europe', 'World Mediterranean', 'World Middle East', 'World Tropical']]
    catmap = { 'classical': '14', 'dance': '18', 'bluegrass': '52', 'contemporary': '16', 'pop': '34', 'spanish': '66', 'college': '15', 'rap': '38', 'ambient': '69', 'talk': '43', 'alternative': '9', 'religious': '39', 'blues': '10', 'folk': '23', 'classic rock': '13', '90s': '7', 'adult contemporary': '8', 'oldies': '33', 'indie rock': '54', 'electronica': '21', 'unknown': '45', 'discussion': '19', 'news talk': '31', 'world mediterranean': '55', 'sports': '42', 'new age': '51', 'indie': '27', 'indian': '65', 'easy': '20', '80s': '6', 'world africa': '67', 'comedy': '62', 'public': '35', 'jungle': '72', 'reggae': '48', 'world middle east': '50', 'christian': '11', 'world caribbean': '68', '60s': '58', 'world europe': '56', 'jazz': '28', '70s': '5', 'soft rock': '41', 'top 40': '44', 'adult': '57', 'news': '30', 'bollywood': '60', 'world tropical': '53', 'latin hits': '29', 'varied': '46', 'christian contemporary': '12', 'kids': '59', 'short wave radio': '73', 'world': '49', 'world asia': '47', 'country': '17', 'news updates': '32', 'punk': '36', 'greek': '25', 'hip hop': '26', 'rock': '40', 'gospel': '24', 'experimental': '22' }
    titles = dict( genre="Genre", title="Station", playing="Location", bitrate="Bitrate", listeners=False )
    base_url = "https://radios.reciva.com/stations/genre/%s?&start=0&count=%s"
    







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from channels import *


# Reciva directory
class reciva (ChannelPlugin):

    # module attributes
    module = 'reciva'
    listformat = "pls"
    has_search = True
    categories = ['60s', '70s', '80s', '90s', 'Adult', ['Adult Contemporary'], 'Alternative', 'Ambient', 'Bluegrass', 'Blues', 'Bollywood', 'Christian', ['Christian Contemporary'], 'Classic Rock', 'Classical', 'College', 'Comedy', 'Contemporary', 'Country', 'Dance', 'Discussion', 'Easy', 'Electronica', 'Experimental', 'Folk', 'Gospel', 'Greek', 'Hip Hop', 'Indian', 'Indie', ['Indie Rock'], 'Jazz', 'Jungle', 'Kids', 'Latin Hits', 'New Age', 'News', ['News Talk', 'News Updates'], 'Oldies', 'Pop', 'Public', 'Punk', 'Rap', 'Reggae', 'Religious', 'Rock', 'Short Wave Radio', 'Soft Rock', 'Spanish', 'Sports', 'Talk', 'Top 40', 'Unknown', 'Varied', 'World', ['World Africa', 'World Asia', 'World Caribbean', 'World Europe', 'World Mediterranean', 'World Middle East', 'World Tropical']]
    catmap = { 'classical': '14', 'dance': '18', 'bluegrass': '52', 'contemporary': '16', 'pop': '34', 'spanish': '66', 'college': '15', 'rap': '38', 'ambient': '69', 'talk': '43', 'alternative': '9', 'religious': '39', 'blues': '10', 'folk': '23', 'classic rock': '13', '90s': '7', 'adult contemporary': '8', 'oldies': '33', 'indie rock': '54', 'electronica': '21', 'unknown': '45', 'discussion': '19', 'news talk': '31', 'world mediterranean': '55', 'sports': '42', 'new age': '51', 'indie': '27', 'indian': '65', 'easy': '20', '80s': '6', 'world africa': '67', 'comedy': '62', 'public': '35', 'jungle': '72', 'reggae': '48', 'world middle east': '50', 'christian': '11', 'world caribbean': '68', '60s': '58', 'world europe': '56', 'jazz': '28', '70s': '5', 'soft rock': '41', 'top 40': '44', 'adult': '57', 'news': '30', 'bollywood': '60', 'world tropical': '53', 'latin hits': '29', 'varied': '46', 'christian contemporary': '12', 'kids': '59', 'short wave radio': '73', 'world': '49', 'world asia': '47', 'country': '17', 'news updates': '32', 'punk': '36', 'greek': '25', 'hip hop': '26', 'rock': '40', 'gospel': '24', 'experimental': '22' }
    titles = dict( genre="Genre", title="Station", playing="Location", bitrate="Bitrate", listeners=False )
    base_url = "https://radios.reciva.com/stations/genre/%s?&start=0&count=%s"
    

Modified contrib/record_stop.py from [6675e32df1] to [658cb7ac5c].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# a streamripper kill switch.

import action
from config import log, conf

# Stop button
class record_stop(object):
    module = __name__

    # button + hook
    def __init__(self, parent):
        btn = parent.stop
        btn.show()
        btn.set_property("visible", True)
        btn.set_property("visible_horizontal", True)







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# a streamripper kill switch.

import action
from config import log, conf

# Stop button
class record_stop(object):
    module = 'record_stop'

    # button + hook
    def __init__(self, parent):
        btn = parent.stop
        btn.show()
        btn.set_property("visible", True)
        btn.set_property("visible_horizontal", True)

Modified contrib/startup_workdir.py from [080458f838] to [588e781680].

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# for streamripper with a parameter.

from config import conf
import os, os.path

# Stop button
class startup_workdir(object):
    module = __name__

    # button + hook
    def __init__(self, parent):
        os.chdir(
            os.path.expandvars(
                os.path.expanduser(
                    conf.start_dir
                )
            )
        )








|











17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# for streamripper with a parameter.

from config import conf
import os, os.path

# Stop button
class startup_workdir(object):
    module = 'startup_workdir'

    # button + hook
    def __init__(self, parent):
        os.chdir(
            os.path.expandvars(
                os.path.expanduser(
                    conf.start_dir
                )
            )
        )

Modified contrib/tmp_clean_multiurl.py from [d5e6d3c789] to [ff0e04e075].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import re
from channels import GenericChannel
from config import log, conf


# filter
class tmp_clean_multiurl(object):
    module = __name__
    rx_space = re.compile(r"\s")
    rx_nonurl = re.compile(r"(^|\s)(?!\w+:)\S+")

    # Hook
    def __init__(self, parent):
        GenericChannel.postprocess_filters.append(self.filter_rows)








|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import re
from channels import GenericChannel
from config import log, conf


# filter
class tmp_clean_multiurl(object):
    module = 'tmp_clean_multiurl'
    rx_space = re.compile(r"\s")
    rx_nonurl = re.compile(r"(^|\s)(?!\w+:)\S+")

    # Hook
    def __init__(self, parent):
        GenericChannel.postprocess_filters.append(self.filter_rows)

Modified contrib/tuner2.py from [16795f1b01] to [44865cadc2].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVElEQVR42mWTfUzUdRzH738f8IDBQWVPLu84rrsLCRRZmGXnMCtCgnt+APSOFOWoWzJFRBPhIK4LTsY1m6mtU4FVo7BsrXO52ajmJl62xXTpam5t/pfwu736HPQX/fHe9/v9fPb9PL7fqnyzj6XIe6aRPLMXjclHgSDX
#    7JK7vI3N4m8k3+hGY87YfahWFTlYiiydk+zMXWun9KW97D84ykBsjGPDYziCJ1hb1SZ+G+oiO6qszIclWCmObAlyoO8MV6/NEo6M49gXZ9vOGBZvlOItHTxR5idHa80EcPI/6Lxk6+vwtUXZFehiNBrh0sdDjI2EqXUeYn3tUdaU76bQ4JYAOilVoNbZJXOmAhf5JT563vuIuzNfo0wf
#    Zv5KG3M3BklfP84v8Xpq9sQxbO7g8eIGCaB1ota6WV7kliA2tto7uZX6CWXMxmzbY4x4nuV0Vy3pVD9z31hIRcvwdk1Qsq2bPEmsUktGtfS7UmfFHxphfvZL/t77CDsrK8jNzEPfsDDQ+9fHSZ8pZvxIAM+hBCZLSCqWFlZoHRSsC9C4L4JySz77V1Gxbju5soFleis5az10dAwyN1HD
#    r91mBk8lqW4/y6NGqyR1odq4/R1mbqT456+fUXp19L5uIkvvEthRFzs4emyY+fEd3HtLzflPJwjGkhi3tMsKbQsrV30xdZm5+3dQbsZRIoV817eZZlsznQeO89ulKMpACXfa85lKnKP//DUs9iPScr1w5L8Af9y+TfreNMqPHh5MVjD//csoyQDKh8/xoHUZNw+WcuHCRaKTM9Q0HWaF
#    tkk4YpUKFkmnupxMovx5hfR0kHTCgPLBaub7NdztfopEeD89p3+gNfotla+8TY6seqE1Gbpal2GsMNG0wUMiNsDvn4e4+smbfDYYYOjdHlrCk9SEzrKpOU5llRPjRg9PV/oof2EXz7+6m03VftaYhYnLDVY0Ukpv9xAnv0qxtWmUDe4TlL4Rocz6PmW2YdZ7T1LVcgpL6Byu8EV8vVNU
#    VLeyWv+a8EBW8aRhB8HOYepbeqnfE6ZBTmtLHzY56wJiC/RQ5+/BGYzSFIpR/mKAHOHHQgsFpkaRqntRphkpCzQi5TyxF4p8C0wiYZH0QyLnh00uCsweFv4YF+X8L6KBLpzwswJYAAAAAElFTkSuQmCC
# priority: optional

#
# A station list website featuring a map. (Uncovered via streamripper
# homepage, which however mentions those streams not being recordable).
# Most entries are AAC+. Else MP3. No Vorbis streams.
#
# Furthermore no homepages, and playing= field is only sometimes set.
# Gotostationpage URLs don't work either. The website seems a bit







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVElEQVR42mWTfUzUdRzH738f8IDBQWVPLu84rrsLCRRZmGXnMCtCgnt+APSOFOWoWzJFRBPhIK4LTsY1m6mtU4FVo7BsrXO52ajmJl62xXTpam5t/pfwu736HPQX/fHe9/v9fPb9PL7fqnyzj6XIe6aRPLMXjclHgSDX
#    7JK7vI3N4m8k3+hGY87YfahWFTlYiiydk+zMXWun9KW97D84ykBsjGPDYziCJ1hb1SZ+G+oiO6qszIclWCmObAlyoO8MV6/NEo6M49gXZ9vOGBZvlOItHTxR5idHa80EcPI/6Lxk6+vwtUXZFehiNBrh0sdDjI2EqXUeYn3tUdaU76bQ4JYAOilVoNbZJXOmAhf5JT563vuIuzNfo0wf
#    Zv5KG3M3BklfP84v8Xpq9sQxbO7g8eIGCaB1ota6WV7kliA2tto7uZX6CWXMxmzbY4x4nuV0Vy3pVD9z31hIRcvwdk1Qsq2bPEmsUktGtfS7UmfFHxphfvZL/t77CDsrK8jNzEPfsDDQ+9fHSZ8pZvxIAM+hBCZLSCqWFlZoHRSsC9C4L4JySz77V1Gxbju5soFleis5az10dAwyN1HD
#    r91mBk8lqW4/y6NGqyR1odq4/R1mbqT456+fUXp19L5uIkvvEthRFzs4emyY+fEd3HtLzflPJwjGkhi3tMsKbQsrV30xdZm5+3dQbsZRIoV817eZZlsznQeO89ulKMpACXfa85lKnKP//DUs9iPScr1w5L8Af9y+TfreNMqPHh5MVjD//csoyQDKh8/xoHUZNw+WcuHCRaKTM9Q0HWaF
#    tkk4YpUKFkmnupxMovx5hfR0kHTCgPLBaub7NdztfopEeD89p3+gNfotla+8TY6seqE1Gbpal2GsMNG0wUMiNsDvn4e4+smbfDYYYOjdHlrCk9SEzrKpOU5llRPjRg9PV/oof2EXz7+6m03VftaYhYnLDVY0Ukpv9xAnv0qxtWmUDe4TlL4Rocz6PmW2YdZ7T1LVcgpL6Byu8EV8vVNU
#    VLeyWv+a8EBW8aRhB8HOYepbeqnfE6ZBTmtLHzY56wJiC/RQ5+/BGYzSFIpR/mKAHOHHQgsFpkaRqntRphkpCzQi5TyxF4p8C0wiYZH0QyLnh00uCsweFv4YF+X8L6KBLpzwswJYAAAAAElFTkSuQmCC
# priority: optional
# extraction-method: regex
#
# A station list website featuring a map. (Uncovered via streamripper
# homepage, which however mentions those streams not being recordable).
# Most entries are AAC+. Else MP3. No Vorbis streams.
#
# Furthermore no homepages, and playing= field is only sometimes set.
# Gotostationpage URLs don't work either. The website seems a bit

Modified contrib/url_soundcloud.py from [aca8213856] to [f1736bf432].

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# rewrite by above handler. Should turn faux "audio/soundcloud" URL into
# plain/longwinded MP3 streaming address.
#
# Would need more generalized processing of custom URL schemes. But so
# far only the reddit module uses them anyway.
#
class url_soundcloud(object):
    module = __name__

    # override action.play() with wrapper
    def __init__(self, parent, *a, **kw):
        conf.play[fmt] = "false / convert"
        #conf.filter_walledgardens = False
        action.handler[fmt] = sndcl_convert








|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# rewrite by above handler. Should turn faux "audio/soundcloud" URL into
# plain/longwinded MP3 streaming address.
#
# Would need more generalized processing of custom URL schemes. But so
# far only the reddit module uses them anyway.
#
class url_soundcloud(object):
    module = 'url_soundcloud'

    # override action.play() with wrapper
    def __init__(self, parent, *a, **kw):
        conf.play[fmt] = "false / convert"
        #conf.filter_walledgardens = False
        action.handler[fmt] = sndcl_convert

Modified contrib/vtuner.py from [9e9c5bde27] to [feab3a3374].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
#   { name: vtuner_order,  value: POP,  type: select,  select: "POP=Popularity|AA=Alphabetically|HBR=Quality|RELI=Uptime|OP=Country",  description: "Station sorting order." }
# priority: contrib
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhFBMVEUAAACIowCIowCIowCIowAkWlsAP3yIowCIowATTWoAP3wAP3xrjhsAP3wAP3yIowAAP3wAP3wAP3wMSHEbU2MAP3wV
#   TmkAP3wAP3wAP3yIowAAP3wJRXQzZU5Vfi9ehCcRTG1EcT4aUmWAnQgiWF0rXlVmih88a0Z3lxBNdzZvkBf///9k8C2HAAAAGnRSTlMAML8QgO8wIJ9wj3DfEN9wr2BAr++/z1Cfzypf+6cAAAABYktHRCskueQIAAAAB3RJTUUH4AQEFxQcg7S+WgAAAJFJREFUGNNVjlkWgjAMRSOiOCJzMa9SQGit
#   +1+gQ5CD+ct9Q0JEtArW9Dchb7ZEUTiDaLc/0PHEC885pvgSLFNJmizXLC9Q5Nm8p/rWGNO06U8H0DH3wOQpAXNnHjRKAdAjM1tAQ8DYOgHoBbgGsPx4R0YBFetvK1wlQHmr4fnZd2q6W/vhU+vr+TN1HTpXif4CK/0NNsIh2vQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMDQtMDVUMDE6MjA6MjAr
#   MDI6MDD2b3oJAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTA0LTA1VDAxOjIwOjIwKzAyOjAwhzLCtQAAAABJRU5ErkJggg==

#
#
# vTuner is a rather large station directory. The website is somewhat
# slow though. So fetching large results sets isn't advisable.
#
# There's an C API of sorts, but no publically available docs. So
# querying the website for stations. Personal/non-commercial use







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#   { name: vtuner_order,  value: POP,  type: select,  select: "POP=Popularity|AA=Alphabetically|HBR=Quality|RELI=Uptime|OP=Country",  description: "Station sorting order." }
# priority: contrib
# png:
#   iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhFBMVEUAAACIowCIowCIowCIowAkWlsAP3yIowCIowATTWoAP3wAP3xrjhsAP3wAP3yIowAAP3wAP3wAP3wMSHEbU2MAP3wV
#   TmkAP3wAP3wAP3yIowAAP3wJRXQzZU5Vfi9ehCcRTG1EcT4aUmWAnQgiWF0rXlVmih88a0Z3lxBNdzZvkBf///9k8C2HAAAAGnRSTlMAML8QgO8wIJ9wj3DfEN9wr2BAr++/z1Cfzypf+6cAAAABYktHRCskueQIAAAAB3RJTUUH4AQEFxQcg7S+WgAAAJFJREFUGNNVjlkWgjAMRSOiOCJzMa9SQGit
#   +1+gQ5CD+ct9Q0JEtArW9Dchb7ZEUTiDaLc/0PHEC885pvgSLFNJmizXLC9Q5Nm8p/rWGNO06U8H0DH3wOQpAXNnHjRKAdAjM1tAQ8DYOgHoBbgGsPx4R0YBFetvK1wlQHmr4fnZd2q6W/vhU+vr+TN1HTpXif4CK/0NNsIh2vQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMDQtMDVUMDE6MjA6MjAr
#   MDI6MDD2b3oJAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTA0LTA1VDAxOjIwOjIwKzAyOjAwhzLCtQAAAABJRU5ErkJggg==
# extraction-method: regex
#
#
# vTuner is a rather large station directory. The website is somewhat
# slow though. So fetching large results sets isn't advisable.
#
# There's an C API of sorts, but no publically available docs. So
# querying the website for stations. Personal/non-commercial use
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from channels import *


# vTuner directory
class vtuner (ChannelPlugin):

    # module attributes
    module = __name__
    listformat = "pls"
    has_search = False
    categories = [
        'Alternative', 'Ambient', 'Big Band', 'Bluegrass', 'Blues',
        'Business News', 'Celtic', 'Christian Contemporary', 'Christian Rock',
        'Classic Rock', 'Classical', 'College', 'Country', 'Dance',
        'Electronica', 'Folk', 'Gospel', 'Hard Rock', 'Hip Hop', 'Holiday',







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from channels import *


# vTuner directory
class vtuner (ChannelPlugin):

    # module attributes
    module = 'vtuner'
    listformat = "pls"
    has_search = False
    categories = [
        'Alternative', 'Ambient', 'Big Band', 'Bluegrass', 'Blues',
        'Business News', 'Celtic', 'Christian Contemporary', 'Christian Rock',
        'Classic Rock', 'Classical', 'College', 'Country', 'Dance',
        'Electronica', 'Folk', 'Gospel', 'Hard Rock', 'Hip Hop', 'Holiday',