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

⌈⌋ branch:  streamtuner2


Diff

Differences From Artifact [6c5e20937c]:

To Artifact [7f404124e6]:


1
2
3
4
5
6

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

6
7
8
9
10
11
12
13





-
+






#!/usr/bin/env python
# encoding: UTF-8
# api: python
# type: application
# title: streamtuner2
# description: directory browser for internet radio / audio streams
# description: Directory browser for internet radio / audio streams
# depends: pygtk | pygi, threading, pyquery, kronos, requests
# version: 2.1.1
# author: mario salzer
# license: public domain
# url: http://freshmeat.net/projects/streamtuner2
# config: <env name="http_proxy" value="" description="proxy for HTTP access" />  <env name="XDG_CONFIG_HOME" description="relocates user .config subdirectory" />
# category: multimedia
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104







-
+






import ahttp
import action  # needs workaround... (action.main=main)
import channels
from channels import *
import favicon


__version__ = "2.1.0"
__version__ = "2.1.1"


# this represents the main window
# and also contains most application behaviour
main = None
class StreamTunerTwo(gtk.Builder):
184
185
186
187
188
189
190
191
192
193
194




195
196
197
198
199
200
201
202
184
185
186
187
188
189
190




191
192
193
194

195
196
197
198
199
200
201







-
-
-
-
+
+
+
+
-






                "menu_toolbar_size_small": lambda w: (self.toolbar.set_icon_size(gtk.ICON_SIZE_SMALL_TOOLBAR)),
                "menu_toolbar_size_medium": lambda w: (self.toolbar.set_icon_size(gtk.ICON_SIZE_DND)),
                "menu_toolbar_size_large": lambda w: (self.toolbar.set_icon_size(gtk.ICON_SIZE_DIALOG)),
                # else
                "menu_properties": config_dialog.open,
                "config_cancel": config_dialog.hide,
                "config_save": config_dialog.save,
                "config_player_edited": config_dialog.edited_player_row,
                "config_player_edited_2": config_dialog.edited_player_row_2,
                "config_record_edited": config_dialog.edited_record_row,
                "config_record_edited_2": config_dialog.edited_record_row_2,
                "config_play_list_edit_col0": lambda w,path,txt: (config_dialog.list_edit(self.config_play, path, 0, txt)),
                "config_play_list_edit_col1": lambda w,path,txt: (config_dialog.list_edit(self.config_play, path, 1, txt)),
                "config_record_list_edit_col0": lambda w,path,txt: (config_dialog.list_edit(self.config_record, path, 0, txt)),
                "config_record_list_edit_col1": lambda w,path,txt: (config_dialog.list_edit(self.config_record, path, 1, txt)),
                "update_categories": self.update_categories,
                "update_favicons": self.update_favicons,
                "app_state": self.app_state,
                "bookmark": self.bookmark,
                "save_as": self.save_as,
                "menu_about": lambda w: AboutStreamtuner2(),
                "menu_help": action.action.help,
                "menu_onlineforum": lambda w: action.browser("http://sourceforge.net/projects/streamtuner2/forums/forum/1173108"),
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320







-
+






                self.channel().play(row)
                [hook(row) for hook in self.hooks["play"]]


        # streamripper
        def on_record_clicked(self, widget):
            row = self.row()
            action.record(row.get("url"), "audio/mpeg", "url/direct", row=row)
            action.record(row.get("url"), row.get("format", "audio/mpeg"), "url/direct", row=row)


        # browse stream
        def on_homepage_stream_clicked(self, widget):
            url = self.selected("homepage")             
            action.browser(url)
794
795
796
797
798
799
800
801
802
803
804
805





806
807
808
809
810
811
812
813
814
815
816
793
794
795
796
797
798
799





800
801
802
803
804




805
806
807
808
809
810
811







-
-
-
-
-
+
+
+
+
+
-
-
-
-






                        config[key] = {}
                        for row in w:
                            if row[0] and row[1]:
                                config[key][row[0]] = row[1]
                __print__(dbg.CONF, "config save", prefix+key, val)

        
        # Gtk callback to update ListStore when entries get edited
        def edited_player_row(self, cell, path, new_text, user_data=None, column=0):
            main.config_play[path][column] = new_text
        def edited_player_row_2(self, cell, path, new_text, user_data=None):
            self.edited_player_row(cell, path, new_text, column=1)
        # Generic Gtk callback to update ListStore when entries get edited
        def list_edit(self, liststore, path, column, new_text):
            liststore[path][column] = new_text
            # The signal_connect() dict actually prepares individual lambda functions
            # to bind the correct ListStore and column id.
        def edited_record_row(self, cell, path, new_text, user_data=None, column=0):
            main.config_record[path][column] = new_text
        def edited_record_row_2(self, cell, path, new_text, user_data=None):
            self.edited_record_row(cell, path, new_text, column=1)


        # list of Gtk themes in dropdown
        def combobox_theme(self):
            # find themes
            themedirs = (conf.share+"/themes", conf.dir+"/themes", "/usr/share/themes")
            themes = ["no theme"]