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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [780f0ca590]

Overview
Comment:Compress gtkBuilder file with zlib for distribution. (gzip not usable without workarounds in Python2)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 780f0ca590c0d302246b05e50b20bb3e69dc6205
User & Date: mario on 2015-04-04 06:06:09
Other Links: manifest | tags
Context
2015-04-04
10:00
Add plugin defaults now really on initialization. Safeguard in configwin. Always use gtk.STOCK_NEW for empty app fields in config_dialog (not just for new lines). check-in: 8178f6832b user: mario tags: trunk
06:06
Compress gtkBuilder file with zlib for distribution. (gzip not usable without workarounds in Python2) check-in: 780f0ca590 user: mario tags: trunk
06:03
Convert shell _pack script into sectioned Makefile. check-in: b2a6fd9de3 user: mario tags: trunk
Changes

Modified config.py from [f0017cbe55] to [5baf9d2d63].

22
23
24
25
26
27
28

29
30
31
32
33
34
35

import os
import sys
import json
import gzip
import platform
import re

import zipfile
import inspect
import pkgutil

# find_executable() is only needed by channels/configwin
try:
    from distutils.spawn import find_executable







>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

import os
import sys
import json
import gzip
import platform
import re
import zlib
import zipfile
import inspect
import pkgutil

# find_executable() is only needed by channels/configwin
try:
    from distutils.spawn import find_executable
277
278
279
280
281
282
283
284
285
286


287
288
289
290
291
292
293
            if server in netrc:
                return netrc[server]
        


# Retrieve content from install path or pyzip archive (alias for pkgutil.get_data)
#
def get_data(fn, decode=False):
    try:
        bin = pkgutil.get_data("config", fn)


        if decode:
            return bin.decode("utf-8")
        else:
            return str(bin)
    except:
        pass








|


>
>







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
            if server in netrc:
                return netrc[server]
        


# Retrieve content from install path or pyzip archive (alias for pkgutil.get_data)
#
def get_data(fn, decode=False, z=False):
    try:
        bin = pkgutil.get_data("config", fn)
        if z:
            bin = zlib.decompress(bin)
        if decode:
            return bin.decode("utf-8")
        else:
            return str(bin)
    except:
        pass

Modified gtk3.xml.zlib from [3be7b6b7e5] to [68caf400e4].

cannot compute difference between binary files

Modified st2.py from [fe8224f3c5] to [a24c95cdd7].

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# url: http://freshcode.club/projects/streamtuner2
# config:  
#   { type: env, name: http_proxy, description: proxy for HTTP access }
#   { type: env, name: XDG_CONFIG_HOME, description: relocates user .config subdirectory }
# category: sound
# depends: pygtk | gi, threading, requests, pyquery, lxml
# id: streamtuner2
# pack: *.py, gtk*.xml, bin, channels/__init__.py, bundle/*.py, CREDITS, help/index.page,
#   streamtuner2.desktop=/usr/share/applications/, README=/usr/share/doc/streamtuner2/,
#   help/streamtuner2.1=/usr/share/man/man1/, NEWS.gz=/usr/share/doc/streamtuner2/changelog.gz,
#   logo.png=/usr/share/pixmaps/streamtuner2.png
# architecture: all
#
# Streamtuner2 is a GUI for browsing internet radio directories, music
# collections, and video services - grouped by genres or categories.







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# url: http://freshcode.club/projects/streamtuner2
# config:  
#   { type: env, name: http_proxy, description: proxy for HTTP access }
#   { type: env, name: XDG_CONFIG_HOME, description: relocates user .config subdirectory }
# category: sound
# depends: pygtk | gi, threading, requests, pyquery, lxml
# id: streamtuner2
# pack: *.py, gtk3.xml.zlib, bin, channels/__init__.py, bundle/*.py, CREDITS, help/index.page,
#   streamtuner2.desktop=/usr/share/applications/, README=/usr/share/doc/streamtuner2/,
#   help/streamtuner2.1=/usr/share/man/man1/, NEWS.gz=/usr/share/doc/streamtuner2/changelog.gz,
#   logo.png=/usr/share/pixmaps/streamtuner2.png
# architecture: all
#
# Streamtuner2 is a GUI for browsing internet radio directories, music
# collections, and video services - grouped by genres or categories.
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    def channel(self):
        return self.channels[self.current_channel]

    # List of module titles for channel tabs
    @property
    def channel_names(self):
        n = self.notebook_channels
        return [n.get_menu_label_text(n.get_nth_page(i)) for i in xrange(0, n.get_n_pages())]

    # Returns the currently selected directory/channel object (from gtk)
    def current_channel_gtk(self):
        return self.channel_names[self.notebook_channels.get_current_page()]
    
        
    # Notebook tab has been clicked (receives numeric page_num), but *NOT* yet changed (visually).







|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    def channel(self):
        return self.channels[self.current_channel]

    # List of module titles for channel tabs
    @property
    def channel_names(self):
        n = self.notebook_channels
        return [n.get_menu_label_text(n.get_nth_page(i)) for i in range(0, n.get_n_pages())]

    # Returns the currently selected directory/channel object (from gtk)
    def current_channel_gtk(self):
        return self.channel_names[self.notebook_channels.get_current_page()]
    
        
    # Notebook tab has been clicked (receives numeric page_num), but *NOT* yet changed (visually).
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
        if event == 2 or event.type == gtk.gdk._2BUTTON_PRESS:
            __print__(dbg.UI, "dblclick")
            url = self.channel().meta.get("url", "https://duckduckgo.com/?q=" + self.channel().module)
            self.action.browser(url)

    # Reload stream list in current channel-category
    def on_reload_clicked(self, widget=None, reload=1):
        __print__(dbg.UI, "reload", reload, self.current_channel, self.channels[self.current_channel], self.channel().current)
        category = self.channel().current
        self.thread(

            lambda: (  self.channel().load(category,reload), reload and self.bookmarks.heuristic_update(self.current_channel,category)  )
        )

    # Thread a function, add to worker pool (for utilizing stop button)
    def thread(self, target, *args):
        thread = Thread(target=target, args=args)
        thread.start()







|


>







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
        if event == 2 or event.type == gtk.gdk._2BUTTON_PRESS:
            __print__(dbg.UI, "dblclick")
            url = self.channel().meta.get("url", "https://duckduckgo.com/?q=" + self.channel().module)
            self.action.browser(url)

    # Reload stream list in current channel-category
    def on_reload_clicked(self, widget=None, reload=1):
        __print__(dbg.UI, "on_reload_clicked()", "reload=", reload, "current_channel=", self.current_channel, "c=", self.channels[self.current_channel], "cat=", self.channel().current)
        category = self.channel().current
        self.thread(
                       #@TODO: should get a wrapper, for HTTP errors, and optionalize bookamrks
            lambda: (  self.channel().load(category,reload), reload and self.bookmarks.heuristic_update(self.current_channel,category)  )
        )

    # Thread a function, add to worker pool (for utilizing stop button)
    def thread(self, target, *args):
        thread = Thread(target=target, args=args)
        thread.start()

Modified uikit.py from [e7bfffdeb1] to [f968e46470].

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    import gtk
    import gobject
    GdkPixbuf = gtk.gdk
    empty_pixbuf = GdkPixbuf.Pixbuf(gtk.gdk.COLORSPACE_RGB,True,8,16,16)
    empty_pixbuf.fill(0xFFFFFFFF)

# prepare gtkbuilder data
ui_xml = get_data("gtk3.xml", decode=True)
if ver == 2:
    ui_xml = ui_xml.replace('version="3.0"', 'version="2.16"')



# simplified gtk constructors               ---------------------------------------------
class uikit:







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    import gtk
    import gobject
    GdkPixbuf = gtk.gdk
    empty_pixbuf = GdkPixbuf.Pixbuf(gtk.gdk.COLORSPACE_RGB,True,8,16,16)
    empty_pixbuf.fill(0xFFFFFFFF)

# prepare gtkbuilder data
ui_xml = get_data("gtk3.xml.zlib", decode=True, z=True) or get_data("gtk3.xml", decode=True)
if ver == 2:
    ui_xml = ui_xml.replace('version="3.0"', 'version="2.16"')



# simplified gtk constructors               ---------------------------------------------
class uikit: