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

⌈⌋ branch:  streamtuner2


Check-in [1cfacd1296]

Overview
Comment:Semi-fix for brand-new initialization. Set default category from existing categories[] list. Setting the displayed path as well doesn't work yet. (It's just half-way selected after the next restart.)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1cfacd1296e67dc5203954f4e3c7f0f1f5b44f2b
User & Date: mario on 2015-04-19 16:33:28
Other Links: manifest | tags
Context
2015-04-19
16:36
Implement basic exporting and conversion for drag-and-drop. Needs to buffer implicit playlist file, because data_get() gets called excessively. Still support direct M3U/PLS/XSPF transfers (should any other application ever understand it), and direct URL transmission. No import functionality yet, but internal JSON format prepared as target type. check-in: 8c7de37e5e user: mario tags: trunk
16:33
Semi-fix for brand-new initialization. Set default category from existing categories[] list. Setting the displayed path as well doesn't work yet. (It's just half-way selected after the next restart.) check-in: 1cfacd1296 user: mario tags: trunk
16:31
Bring back .base_url instead of .homepage property for HTTP requests. check-in: c6416a18df user: mario tags: trunk
Changes

Modified channels/__init__.py from [9a39b12b72] to [b9ead90d77].

92
93
94
95
96
97
98


99
100
101
102
103
104
105
    placeholder = [dict(genre="./.", title="Subcategory placeholder", playing="./.", url="none:", listeners=0, bitrate=0, homepage="", state="gtkfolder")]
    empty_stub = [dict(genre="./.", title="No categories found (HTTP error)", playing="Try Channel→Reload Categories later..", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-stop")]
    nothing_found = [dict(genre="./.", title="No contents found on directory server", playing="Notice", listeners=0, bitrate=0, state="gtk-info")]
    
    # regex            
    rx_www_url = re.compile("""(www(\.\w+[\w-]+){2,}|(\w+[\w-]+[ ]?\.)+(com|FM|net|org|de|PL|fr|uk))""", re.I)



    __current = None
    @property
    def current(self):
        return self.__current
    @current.setter
    def current(self, newcat):
        print "{}.current:={} ← from {}".format(self.module, newcat, [inspect.stack()[x][3] for x in range(1,4)])







>
>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    placeholder = [dict(genre="./.", title="Subcategory placeholder", playing="./.", url="none:", listeners=0, bitrate=0, homepage="", state="gtkfolder")]
    empty_stub = [dict(genre="./.", title="No categories found (HTTP error)", playing="Try Channel→Reload Categories later..", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-stop")]
    nothing_found = [dict(genre="./.", title="No contents found on directory server", playing="Notice", listeners=0, bitrate=0, state="gtk-info")]
    
    # regex            
    rx_www_url = re.compile("""(www(\.\w+[\w-]+){2,}|(\w+[\w-]+[ ]?\.)+(com|FM|net|org|de|PL|fr|uk))""", re.I)


    #-- keep track of currently selected genre/category
    __current = None
    @property
    def current(self):
        return self.__current
    @current.setter
    def current(self, newcat):
        print "{}.current:={} ← from {}".format(self.module, newcat, [inspect.stack()[x][3] for x in range(1,4)])
416
417
418
419
420
421
422

423
424
425
426
427
428


429
430
431
432
433
434
435
436
437
438
439
440
441
                self.reload_categories()
            except:
                __print__(dbg.ERR, "HTTP error or extraction failure.")
                self.categories = ["empty"]
            self.display_categories()

        # Select first category

        #self.current = self.str_from_struct(self.categories) or None
        #__print__(dbg.STAT, self.module, "→ first_show(); use first category as current =", self.current)
        try:
            self.load(self.current)
        except:
            pass


    
        # put selection/cursor on last position
        if self.shown:
            __print__(dbg.STAT, self.module+".first_show()", "select last known category treelist position =", self.shown)
            try:
                self.gtk_list.get_selection().select_path(self.shown)
            except:
                pass
            
        # Invoke only once
        self.shown = 55555









>
|
|
<
|
|
|
>
>


|


|







418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
                self.reload_categories()
            except:
                __print__(dbg.ERR, "HTTP error or extraction failure.")
                self.categories = ["empty"]
            self.display_categories()

        # Select first category
        if not self.current:
            self.current = self.str_from_struct(self.categories) or None
            __print__(dbg.STAT, self.module, "→ first_show(); use first category as current =", self.current)

            self.shown = 0,

        # Show current category in any case
        __print__(dbg.UI, self.module, "→ first_show(); station list → load(", self.current, ")")
        uikit.do(self.load, self.current)
    
        # put selection/cursor on last position
        if True:#self.shown != None:
            __print__(dbg.STAT, self.module+".first_show()", "select last known category treelist position =", self.shown)
            try:
                uikit.do(lambda:self.gtk_list.get_selection().select_path(self.shown))
            except:
                pass
            
        # Invoke only once
        self.shown = 55555


Modified channels/bookmarks.py from [265184bad9] to [baf2fe6dd0].

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
    streams = {"favourite":[finder_song], "search":[], "scripts":[], "timer":[], "history":[], }


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

    def gui(self, parent):
        GenericChannel.gui(self, parent)
        parent.notebook_channels.set_menu_label_text(parent.v_bookmarks, "bookmarks")


    # this channel does not actually retrieve/parse data from anywhere
    def update_categories(self):
        pass
        
    # 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, [])

        
    # streams are already loaded at instantiation
    #def first_show(self):
    #    pass



    # all entries just come from "bookmarks.json"
    def cache(self):
        # stream list
        cache = conf.load(self.module)
        if (cache):







<

>

















|
>







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
    streams = {"favourite":[finder_song], "search":[], "scripts":[], "timer":[], "history":[], }


    # 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")
        GenericChannel.gui(self, parent)

    # this channel does not actually retrieve/parse data from anywhere
    def update_categories(self):
        pass
        
    # 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, [])

        
    # streams are already loaded at instantiation
    #def first_show(self):
    #    print "first_show", len(self.streams["favourite"])
    #    GenericChannel.first_show(self)


    # all entries just come from "bookmarks.json"
    def cache(self):
        # stream list
        cache = conf.load(self.module)
        if (cache):