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

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


Check-in [aa18167fee]

Overview
Comment:Introduce wiki/links source for according bookmarks category.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: aa18167feea5a9f0b369cadb18f29444f2a5b656
User & Date: mario on 2020-05-18 17:27:27
Other Links: manifest | tags
Context
2020-05-20
07:00
Remove radioreddit, update some of the categories, and implement full subreddit extraction from wiki page. check-in: 0041f793e7 user: mario tags: trunk
2020-05-18
17:27
Introduce wiki/links source for according bookmarks category. check-in: aa18167fee user: mario tags: trunk
14:02
Bug was from wgetยดs --local-encoding (select:/Combobox option) check-in: 48dc4b4834 user: mario tags: trunk
Changes

Modified channels/bookmarks.py from [b8e07c8df6] to [e8e6929736].

48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81







+



















-







        "scripts": [],
        "timer": [],
        "history": []
    }
    default = "favourite"
    fixed_size = [32,24]
    reserved_names = ["favourite", "radiotray", "scripts", "search", "timer", "history", "links", "themes"] #+ self.parent.features.keys()
    category_plugins = {}


    # cache list, to determine if a PLS url is bookmarked
    urls = []

    def gui(self, parent):
        parent.notebook_channels.set_menu_label_text(parent.v_bookmarks, "bookmarks")
        self.update_categories()
        GenericChannel.gui(self, parent)
        uikit.tree_column(self.gtk_cat, "Group")

    # custom categories are shown as subfolder below `favourite`
    def update_categories(self):
        cust_cats = list(set(self.streams.keys()) - set(self.reserved_names))
        if len(self.categories) < 2 or type(self.categories[1]) is not list:
            self.categories.insert(1, [])
        self.categories[1] = cust_cats
        
    # but category sub-plugins might provide a hook
    category_plugins = {}
    def update_streams(self, cat):
        if cat in self.category_plugins:
            return self.category_plugins[cat].update_streams(cat) or []
        else:
            return self.streams.get(cat, [])

        

Modified channels/links.py from [d07c682e01] to [2d54644218].


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18

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

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64

65
66
67
68
69
70
71




72
73
74
75
76


77
78
79

80
81
82
83
84
85
86
87
88
89
90
91



92
93
94
95
96
97
98
99
100
101
102

103
104
105
















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

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

33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58

59
60
61
62
63
64
65
66
67





68
69
70
71


72


73
74
75
76

77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
+

















+
-
+












-



+





-















-


-
+





+


-
-
-
-
-
+
+
+
+
-
-

-
-
+
+


-
+










-
-
+
+
+










-
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# encoding: utf-8
# api: streamtuner2
# title: Links to directory services
# description: Static list of various music directory websites.
# type: group
# category: web
# version: 0.3
# priority: standard
# config: -
#
# Simply adds a "links" entry in bookmarks tab, where known services
# are listed with homepage links. Registered plugins automatically
# end up on top of that list.
#


from config import *
from channels import *
import ahttp
import copy
import copy, json, re



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

    # list
    streams = [    ]
    default = [
        ("stream", "rad.io", "http://www.rad.io/"),
        ("stream", "RadioTower", "http://www.radiotower.com/"),
        ("stream", "8tracks", "http://8tracks.com/"),
        ("stream", "TuneIn", "http://tunein.com/"),
        ("stream", "Jango", "http://www.jango.com/"),
        ("stream", "last.fm", "http://www.last.fm/"),
        ("stream", "StreamFinder", "http://www.streamfinder.com/"),
        ("stream", "RadioTower", "http://radiotower.com/"),
        ("stream", "Rhapsody (US-only)", "http://www.rhapsody.com/"),
        ("stream", "Pirateradio Network", "http://www.pirateradionetwork.com/"),
        ("stream", "radio-locator", "http://www.radio-locator.com/"),
        ("stream", "Radio Station World", "http://radiostationworld.com/"),
        ("stream", "iHeart", "http://www.iheartradio.com/"),
        ("stream", "MusicGOAL", "http://www.musicgoal.com/"),
        ("download", "Live Music Archive(.org)", "https://archive.org/details/etree"),
        ("download", "FMA, free music archive", "http://freemusicarchive.org/"),
        ("download", "Audiofarm", "http://audiofarm.org/"),
        ("stream", "SoundCloud", "https://soundcloud.com/"),
        ("download", "ccMixter", "http://dig.ccmixter.org/"),
        ("download", "mySpoonful", "http://myspoonful.com/"),
        ("download", "NoiseTrade", "http://noisetrade.com/"),
        ("stream", "Hype Machine", "http://hypem.com/"),
        ("download", "Amazon Free MP3s", "http://www.amazon.com/b/ref=dm_hp_bb_atw?node=7933257011"),
        ("stream", "Shuffler.fm", "http://shuffler.fm/"),
        ("download", "ccTrax", "http://www.cctrax.com/"),
        ("list", "WP: Streaming music services", "http://en.wikipedia.org/wiki/Comparison_of_on-demand_streaming_music_services"),
        ("list", "WP: Music databases", "http://en.wikipedia.org/wiki/List_of_online_music_databases"),
        ("commercial", "Google Play Music", "https://play.google.com/about/music/"),
        ("commercial", "Deezer", "http://www.deezer.com/features/music.html"),
       #("stream", "SurfMusik.de", "http://www.surfmusic.de/"),
    ]
    
    

    
    # prepare gui
    def init2(self, parent):
        if not parent:
            return
        self.bookmarks = parent.bookmarks

        # prepare target category
        bookmarks = parent.bookmarks
        if not bookmarks.streams.get(self.module):
            bookmarks.streams[self.module] = []
        bookmarks.add_category(self.module)
        
        if not self.bookmarks.streams.get(self.module):
            self.bookmarks.streams[self.module] = self.streams
        self.bookmarks.add_category(self.module, self)

        # fill it up later
        parent.hooks["init"].append(self.populate)


    def populate(self, parent):
    def update_streams(self, cat="links"):
        #log.PROC("links.update_streams")
    
        # Collect links from channel plugins
        for name,channel in parent.channels.items():
        for name,channel in self.parent.channels.items():
            try:
                self.streams.append({
                    "favourite": 1,
                    "genre": "channel",
                    "title": channel.meta.get("title", channel.module),
                    "homepage": channel.meta.get("url", ""),
                    "format": "text/html",
                })
            except Exception as e:
                log.ERR("links: adding entry failed:", e)

        # Add built-in link list
        
        # Add wiki or built-in link list
        self.from_wiki()
        for row in self.default:
            (genre, title, homepage) = row
            self.streams.append({
                "genre": genre,
                "title": title,
                "homepage": homepage,
                "type": "text/html",
            })

        # add to bookmarks
        parent.bookmarks.streams[self.module] = self.streams
        return self.streams

        # redraw category
#        parent.bookmarks.reload_if_current(self.module)


    # retrieve links from repository wiki page (via JSON API /json/wiki/get/โ€ฆ)
    def from_wiki(self):
        src = ahttp.get("https://fossil.include-once.org/streamtuner2/json/wiki/get/links", timeout=2)
        if not src:
            return
        wiki = json.loads(src)
        if not wiki or not wiki.get("payload"):
            return
        wiki = wiki["payload"]["content"]
        pairs = re.findall("(?:(\w+)\s*\|\s*)?\[([\w\s(&,;!:#+\-)]+)\]\((http[^)\s]+)\)", wiki)
        if not pairs:
            return
        self.default = [(cat if cat else "site", title, url) for cat,title,url in pairs]