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

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


Check-in [2877d4a4bb]

Overview
Comment:Release as 2.2.1
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | 2.2.1
Files: files | file ages | folders
SHA1: 2877d4a4bbe9ed314ec31e92819d6dd2fac1e20e
User & Date: mario on 2018-12-31 11:33:25
Other Links: manifest | tags
Context
2018-12-31
11:42
Add DBUS play_url() support with `play` option. check-in: 06514f3645 user: mario tags: trunk
11:33
Release as 2.2.1 check-in: 2877d4a4bb user: mario tags: trunk, 2.2.1
2018-12-21
23:03
Fix dict error for new categories. check-in: ceba1060dd user: mario tags: trunk
Changes

Modified Makefile from [b1c5fbeb8f] to [0488466410].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Requires 
# ยท http://fossil.include-once.org/versionnum/
# ยท http://fossil.include-once.org/xpm/

SHELL   := /bin/bash #(for brace expansion)
NAME    := streamtuner2
VERSION := $(shell version get:plugin st2.py || echo 2.1dev)
DEST    := /usr/share/streamtuner2
INST    := install -m 644
PACK    := xpm
DEPS    := -n $(NAME) -d python -d python-pyquery -d python-gtk2 -d python-requests -d python-keybinder
DEPS_A  := -n $(NAME) -d pygtk -d python2 -d python2-cssselect -d python2-keybinder2 -d python2-lxml -d python2-pillow -d python2-pyquery -d python2-xdg -d python2-requests --provides streamtuner-python
OPTS    := -s src -u packfile,fixperms -f --prefix=$(DEST) --deb-compression=xz --rpm-compression=xz --exe-autoextract







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Requires 
# ยท http://fossil.include-once.org/versionnum/
# ยท http://fossil.include-once.org/xpm/

SHELL   := /bin/bash #(for brace expansion)
NAME    := streamtuner2
VERSION := $(shell version get:plugin st2.py || echo 2.2dev)
DEST    := /usr/share/streamtuner2
INST    := install -m 644
PACK    := xpm
DEPS    := -n $(NAME) -d python -d python-pyquery -d python-gtk2 -d python-requests -d python-keybinder
DEPS_A  := -n $(NAME) -d pygtk -d python2 -d python2-cssselect -d python2-keybinder2 -d python2-lxml -d python2-pillow -d python2-pyquery -d python2-xdg -d python2-requests --provides streamtuner-python
OPTS    := -s src -u packfile,fixperms -f --prefix=$(DEST) --deb-compression=xz --rpm-compression=xz --exe-autoextract

67
68
69
70
71
72
73

74
75
76
77
78
79
80
check:
	dpkg-deb -c streamtuner2*deb
	dpkg-deb -I streamtuner2*deb
	rpm -qpil *rpm
	
upload:
	scp *.{deb,rpm,exe,pyz,arch.txz,txz} io:st2/


# manual installation
install:
	mkdir	-p				$(DEST)/channels
	mkdir	-p				/usr/share/doc/streamtuner2/help/img
	install -m 755		bin		/usr/bin/streamtuner2
	$(INST)		*py		-t $(DEST)







>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
check:
	dpkg-deb -c streamtuner2*deb
	dpkg-deb -I streamtuner2*deb
	rpm -qpil *rpm
	
upload:
	scp *.{deb,rpm,exe,pyz,arch.txz,txz} io:st2/
	scp *.{deb,rpm,exe,pyz,arch.txz,txz} sf:/home/frs/project/streamtuner2/

# manual installation
install:
	mkdir	-p				$(DEST)/channels
	mkdir	-p				/usr/share/doc/streamtuner2/help/img
	install -m 755		bin		/usr/bin/streamtuner2
	$(INST)		*py		-t $(DEST)

Modified NEWS from [a8565fdf67] to [05101f3e8b].



















1
2
3
4
5
6
7



















2.2.0 (2016-12-31)
 * Adds new plugins for RCast, Streema, vTuner2, Liveradio.ie, RadioSure,
   house-mixes, and Reciva.
 * Feature extensions include the Cache Reset, Config import/export,
   Gtk theme setting and installer, and Specbuttons for custom shortcuts,
   and script stations.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
2.2.1 (2018-12-31)
 * Fix missing import for find_executable fallback.
 * Fixed shoutcast base url, and added format option.
 * Updates to extraction for radiolist.net, delicast, streema.
 * Optional bookmark subcategories.
 * Radiotray-NG support.
 * Optional toolbar button for search dialog.
 * Added plugin to highlight Vorbis and Opus streams.
 * New recordflags plugin with additional command options.
 * Support for internal calls in specbuttons.
 * Disable man page compression.
 * New st2subprocess plugin for alternative player invocation schemes (mostly Windows).
 * UI changes for player/application configuration and feature settings,
   colorization and icons in main statusbar.
 * More streamlined heuristic for URL and format guessing.
 * Logging and broader plugin dependency checking.
 * Minor text fixes.
 * Windows fixes related to paths and encoding.

2.2.0 (2016-12-31)
 * Adds new plugins for RCast, Streema, vTuner2, Liveradio.ie, RadioSure,
   house-mixes, and Reciva.
 * Feature extensions include the Cache Reset, Config import/export,
   Gtk theme setting and installer, and Specbuttons for custom shortcuts,
   and script stations.

Modified channels/bookmarks.py from [0b438ee149] to [b8e07c8df6].

100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
        conf.save(self.module, self.streams, nice=1)


    # checks for existence of an URL in bookmarks store,
    # this method is called by other channel modules' display() method
    def is_in(self, url, once=1):
        if (not self.urls):

            self.urls = [str(row.get("url","urn:x-streamtuner2:no")) for row in self.streams["favourite"]]
        return str(url) in self.urls


    # called from main window / menu / context menu,
    # when bookmark is to be added for a selected stream entry
    def add(self, row, target="favourite"):

        # Add / copy some row attributes
        row["favourite"] = 1
        if not row.get("favicon"):
            pass#   row["favicon"] = favicon.file(row.get("homepage"))
        if not row.get("listformat"):
            row["listformat"] = self.parent.channel().listformat
        if not len(row.get("extra", "")):
            row["extra"] = self.parent.channel().module

        # append to storage
        self.streams[target].append(row)
        self.save()
        self.load(self.default)
        self.urls.append(row["url"])


    # simplified gtk TreeStore display logic (just one category for the moment, always rebuilt)
    def load(self, category, force=False, y=None):
        self.streams[category] = self.update_streams(category)
        GenericChannel.load(self, category, force=False, y=y)







>




















|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        conf.save(self.module, self.streams, nice=1)


    # checks for existence of an URL in bookmarks store,
    # this method is called by other channel modules' display() method
    def is_in(self, url, once=1):
        if (not self.urls):
            #@todo: traverse all categories?
            self.urls = [str(row.get("url","urn:x-streamtuner2:no")) for row in self.streams["favourite"]]
        return str(url) in self.urls


    # called from main window / menu / context menu,
    # when bookmark is to be added for a selected stream entry
    def add(self, row, target="favourite"):

        # Add / copy some row attributes
        row["favourite"] = 1
        if not row.get("favicon"):
            pass#   row["favicon"] = favicon.file(row.get("homepage"))
        if not row.get("listformat"):
            row["listformat"] = self.parent.channel().listformat
        if not len(row.get("extra", "")):
            row["extra"] = self.parent.channel().module

        # append to storage
        self.streams[target].append(row)
        self.save()
        self.load(target)
        self.urls.append(row["url"])


    # simplified gtk TreeStore display logic (just one category for the moment, always rebuilt)
    def load(self, category, force=False, y=None):
        self.streams[category] = self.update_streams(category)
        GenericChannel.load(self, category, force=False, y=y)

Modified releases.json from [29ee987442] to [c37337e9e6].

13
14
15
16
17
18
19








20
21
22
23
24
25
26
        "rpm": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.rpm",
        "pyz": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.pyz",
        "raw": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.bin.txz",
        "exe": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.exe",
        "arch": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.arch.txz"
    },
    "releases": [








        {
            "version": "2.2.0",
            "state": "stable",
            "scope": "major feature",
            "changes": "Adds new plugins for RCast, Streema, vTuner2, Liveradio.ie, RadioSure, house-mixes, and Reciva. Feature extensions include the Cache Reset, Config import/export, Gtk theme setting and installer, and Specbuttons for custom shortcuts, and script stations. Live365, di.fm and WindowsMediaGuide are gone. Marks the first release with thorough Windows support, and comes with a Python+Gtk post-installer and additional tools for the SFX archive. Comes with a CHM manual version instead. Many typos and stale infos in the manual have been remedied, more details on contrib plugins and station status icons (reddit, dirble, etc), and stream $placeholders have been documented. Internet-Radio now supports the search, its DOM extraction was updated. Other fixes encompass the file browser, MODarchive categories, Radio-Browser submit function, Radionomy icon sizes. Reddit and Record-stop are now distributed plugins. Channels can easier hook new content types and extractors in the action module, the .QTL export format was added, better cross-platform quoting and a multi-URL workaround added. Better channel refresh indication, and colorized status bar. Plugin management has been extended, and a few fixes and option safeguards applied, support for table/dict settings. Other internal changes include plugin init2() callbacks, a secret `conf.cmd` option, `rt` open flag fixes, new unichr() alias, a cmd= flag for run_fmt_url().",
            "download": "http://sourceforge.net/projects/streamtuner2/files/",
            "published": "2016-12-31T20:00:00+0000"







>
>
>
>
>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
        "rpm": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.rpm",
        "pyz": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.pyz",
        "raw": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.bin.txz",
        "exe": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.exe",
        "arch": "http://milki.include-once.org/streamtuner2/streamtuner2-$version.arch.txz"
    },
    "releases": [
        {
            "version": "2.2.1",
            "state": "stable",
            "scope": "minor bugfix",
            "changes": "Fix missing import for find_executable fallback.  Fixed shoutcast base url, and added format option.  Updates to extraction for radiolist.net, delicast, streema.  Optional bookmark subcategories.  Radiotray-NG support.  Optional toolbar button for search dialog.  Added plugin to highlight Vorbis and Opus streams.  New recordflags plugin with additional command options.  Support for internal calls in specbuttons.  Disable man page compression.  New st2subprocess plugin for alternative player invocation schemes (mostly Windows).  UI changes for player/application configuration and feature settings, colorization and icons in main statusbar.  More streamlined heuristic for URL and format guessing.  Logging and broader plugin dependency checking.  Windows fixes related to paths and encoding.  Minor text fixes.",
            "download": "http://sourceforge.net/projects/streamtuner2/files/",
            "published": "2018-12-31T14:00:00+0000"
        },
        {
            "version": "2.2.0",
            "state": "stable",
            "scope": "major feature",
            "changes": "Adds new plugins for RCast, Streema, vTuner2, Liveradio.ie, RadioSure, house-mixes, and Reciva. Feature extensions include the Cache Reset, Config import/export, Gtk theme setting and installer, and Specbuttons for custom shortcuts, and script stations. Live365, di.fm and WindowsMediaGuide are gone. Marks the first release with thorough Windows support, and comes with a Python+Gtk post-installer and additional tools for the SFX archive. Comes with a CHM manual version instead. Many typos and stale infos in the manual have been remedied, more details on contrib plugins and station status icons (reddit, dirble, etc), and stream $placeholders have been documented. Internet-Radio now supports the search, its DOM extraction was updated. Other fixes encompass the file browser, MODarchive categories, Radio-Browser submit function, Radionomy icon sizes. Reddit and Record-stop are now distributed plugins. Channels can easier hook new content types and extractors in the action module, the .QTL export format was added, better cross-platform quoting and a multi-URL workaround added. Better channel refresh indication, and colorized status bar. Plugin management has been extended, and a few fixes and option safeguards applied, support for table/dict settings. Other internal changes include plugin init2() callbacks, a secret `conf.cmd` option, `rt` open flag fixes, new unichr() alias, a cmd= flag for run_fmt_url().",
            "download": "http://sourceforge.net/projects/streamtuner2/files/",
            "published": "2016-12-31T20:00:00+0000"

Modified st2.py from [0aae622bbd] to [841128bca6].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
# encoding: UTF-8
# api: python
# type: application
# title: streamtuner2
# description: Directory browser for internet radio, audio and video streams
# version: 2.2.1-dev20181218
# state: stable
# author: Mario Salzer <mario@include-once.org>
# license: Public Domain
# 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 }






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
# encoding: UTF-8
# api: python
# type: application
# title: streamtuner2
# description: Directory browser for internet radio, audio and video streams
# version: 2.2.1
# state: stable
# author: Mario Salzer <mario@include-once.org>
# license: Public Domain
# 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 }

Modified uikit.py from [12f5bb606e] to [d6b56fa41f].

574
575
576
577
578
579
580
581
582





583


584

585

586
587
588
589

590
591
592
593
594
595
596
                return gtk.STOCK_CANCEL
        else:
            return gtk.STOCK_NEW


    # Attach textual menu entry and callback
    @staticmethod
    def add_menu(menuwidget, label, action, insert=None):
        for where in list(menuwidget):





            m = gtk.MenuItem(label)


            m.connect("activate", action)

            m.show()

            if insert:
                where.insert(m, insert)
            else:
                where.add(m)

        

    # gtk.messagebox
    @staticmethod
    def msg(text, style=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_CLOSE, yes=None):
        m = gtk.MessageDialog(None, 0, style, buttons, message_format=text)
        m.show()







|

>
>
>
>
>
|
>
>
|
>
|
>




>







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
                return gtk.STOCK_CANCEL
        else:
            return gtk.STOCK_NEW


    # Attach textual menu entry and callback
    @staticmethod
    def add_menu(menuwidget, label, action=None, stock=None, submenu=None, insert=None):
        for where in list(menuwidget):
            # plain or image menu item
            if stock:
                m = gtk.ImageMenuItem(stock)
                m.set_label(label)
            else:
                m = gtk.MenuItem(label)
            # callback or submenu
            if action:
                m.connect("activate", action)
            elif submenu:
                m.set_submenu(submenu)
            # insert or append
            if insert:
                where.insert(m, insert)
            else:
                where.add(m)
            m.show()
        

    # gtk.messagebox
    @staticmethod
    def msg(text, style=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_CLOSE, yes=None):
        m = gtk.MessageDialog(None, 0, style, buttons, message_format=text)
        m.show()