File radiotray-port-gst1-gtk3.patch of Package radiotray
Description: port radiotray to GTK-3 and GStreamer 1.0
This patch switch radiotray to GTK-3 and Gstreamer 1.0
from upstream repository.
Forwarded: no
Author: Carlos Ribeyro <carlosmribeiro1@gmail.com>
Last-Update: 2015-10-18
Index: data/bookmarks.xml
===================================================================
--- data/bookmarks.xml.orig 2016-05-07 17:25:19.930842069 +0200
+++ data/bookmarks.xml 2016-05-07 17:25:23.254886055 +0200
@@ -9,14 +9,14 @@
<bookmark name="The Breeze" url="mmsh://wms-rly.181.fm/181-breeze?MSWMExt=.asf"/>
</group>
<group name="Latin">
- <bookmark name="Onda Tropical" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=506392"/>
+ <bookmark name="Onda Tropical" url="http://monkey.wavestreamer.com:2958/listen.m3u?sid=1"/>
<bookmark name="Top Latino Radio" url="http://online.radiodifusion.net:8020/listen.pls"/>
<bookmark name="Salsa Stream" url="http://listen.sky.fm/public3/salsa.pls"/>
<bookmark name="Reggaeton 24/7" url="http://cc.net2streams.com/tunein.php/reggaeton/playlist.pls"/>
- <bookmark name="Suave 107" url="http://grupomedrano.com.do/suave107/suave107.m3u"/>
+ <bookmark name="Suave" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=1572149"/>
</group>
<group name="Classic Rock">
- <bookmark name="181.FM Classic Hits" url="http://sc-rly.181.fm:80/stream/1094"/>
+ <bookmark name="181.FM Classic Hits" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=153501"/>
<bookmark name=".977 Classic Rock" url="http://www.977music.com/tunein/web/classicrock.asx"/>
<bookmark name="80s Sky.FM" url="http://listen.sky.fm/public3/the80s.pls"/>
<bookmark name="Covers" url="http://somafm.com/covers.pls"/>
@@ -30,21 +30,22 @@
<bookmark name="SKY.fm Mostly Classical" url="http://listen.sky.fm/public1/classical.pls"/>
</group>
<group name="Pop / Rock">
- <bookmark name="Radio Paradise" url="http://www.radioparadise.com/musiclinks/rp_128aac.m3u"/>
- <bookmark name=".977 The Hitz Channel" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=1280356"/>
- <bookmark name="Enjoy Station" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=1377285"/>
+ <bookmark name="Radio Paradise" url="http://www.radioparadise.com/musiclinks/rp_128.m3u"/>
+ <bookmark name=".977 The Hitz Channel" url="http://www.977music.com/tunein/web/hitz.asx"/>
+ <bookmark name="Enjoy Station" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=1463895"/>
<bookmark name="SKY.fm Top Hits" url="http://listen.sky.fm/public1/tophits.pls"/>
<bookmark name="Indie Pop Rocks!" url="http://somafm.com/indiepop.pls"/>
<bookmark name="PopTron" url="http://somafm.com/poptron.pls"/>
</group>
<group name="Oldies">
<bookmark name="AM 1710" url="http://lin2.ash.fast-serv.com:9022/listen.pls"/>
+ <bookmark name="AM 600" url="http://redmanstreams.com:8740/listen.pls"/>
<bookmark name="WNAR" url="http://live.wnar-am.com:8500/listen.pls"/>
<bookmark name="SKY.fm Oldies" url="http://listen.sky.fm/public1/oldies.pls"/>
</group>
<group name="Chill">
- <bookmark name="181.FM" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=1275050"/>
- <bookmark name="Lounge Radio" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=1288934"/>
+ <bookmark name="181.FM" url="http://yp.shoutcast.com/sbin/tunein-station.pls?id=35402"/>
+ <bookmark name="Lounge Radio" url="http://www.lounge-radio.com/listen128.m3u"/>
<bookmark name="Beat Blender" url="http://somafm.com/beatblender.pls"/>
<bookmark name="Secret Agent" url="http://somafm.com/secretagent.pls"/>
<bookmark name="Groove Salad" url="http://somafm.com/groovesalad.pls"/>
@@ -64,6 +65,7 @@
<bookmark name="cliqhop idm" url="http://somafm.com/cliqhop.pls"/>
<bookmark name="Black Rock FM" url="http://somafm.com/brfm.pls"/>
<bookmark name="New Dance Radio" url="http://jbstream.net/tunein.php/blackoutworm/playlist.asx"/>
+ <bookmark name="DubStep Beyond" url="http://somafm.com/play/dubstep32"/>
</group>
<group name="Community">
<bookmark name="Jupiter Broadcast" url="http://jblive.fm/"/>
Index: data/plugins/HelloWorldPlugin.py
===================================================================
--- data/plugins/HelloWorldPlugin.py.orig 2016-05-07 17:25:19.930842069 +0200
+++ data/plugins/HelloWorldPlugin.py 2016-05-07 17:25:23.254886055 +0200
@@ -20,7 +20,7 @@
from events.EventSubscriber import EventSubscriber
from events.EventManager import EventManager
from Plugin import Plugin
-import gtk
+from gi.repository import Gtk
import time
# Basic example of a plugin
Index: data/plugins/HistoryPlugin.py
===================================================================
--- data/plugins/HistoryPlugin.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ data/plugins/HistoryPlugin.py 2016-05-07 17:25:23.258886108 +0200
@@ -20,7 +20,8 @@
from events.EventSubscriber import EventSubscriber
from events.EventManager import EventManager
from Plugin import Plugin
-import gtk
+from gi.repository import GLib
+from gi.repository import Gtk
from lib import utils
from lib.common import SYSTEM_PLUGIN_PATH, USER_PLUGIN_PATH
import os
@@ -36,9 +37,7 @@ class HistoryPlugin(Plugin):
- def activate(self):
- self.eventSubscriber.bind(EventManager.SONG_CHANGED, self.on_song_changed)
-
+ def activate_gtk(self, data):
if os.path.exists(os.path.join(USER_PLUGIN_PATH, "history.glade")):
self.gladefile = utils.load_ui_file(os.path.join(USER_PLUGIN_PATH, "history.glade"))
elif os.path.exists(os.path.join(SYSTEM_PLUGIN_PATH, "history.glade")):
@@ -54,6 +53,9 @@ class HistoryPlugin(Plugin):
#dic = { "on_close_clicked" : self.on_close_clicked}
self.gladefile.connect_signals(self)
+ def activate(self):
+ self.eventSubscriber.bind(EventManager.SONG_CHANGED, self.on_song_changed)
+ GLib.idle_add(self.activate_gtk, None)
def on_song_changed(self, data):
@@ -72,5 +74,9 @@ class HistoryPlugin(Plugin):
self.window.hide()
return True
+ def on_delete_event(self, widget, event, data=None):
+ self.window.hide()
+ return True
+
def hasMenuItem(self):
return True
Index: data/plugins/NotificationPlugin.py
===================================================================
--- data/plugins/NotificationPlugin.py.orig 2016-05-07 17:25:19.930842069 +0200
+++ data/plugins/NotificationPlugin.py 2016-05-07 17:25:23.254886055 +0200
@@ -20,9 +20,10 @@
from Plugin import Plugin
-import gtk
-import gobject
-import pynotify
+from gi.repository import Gtk
+from gi.repository import GObject
+from gi.repository import Notify
+from gi.repository import GdkPixbuf
from lib.common import APP_ICON, APPNAME
from events.EventManager import EventManager
@@ -61,18 +62,18 @@ class NotificationPlugin(Plugin):
if self.notif == None:
- if pynotify.init(APPNAME):
- self.notif = pynotify.Notification(title, message)
- self.notif.set_urgency(pynotify.URGENCY_LOW)
+ if Notify.init(APPNAME):
+ self.notif = Notify.Notification.new(title, message, None)
+ self.notif.set_urgency(Notify.Urgency.LOW)
self.set_icon(data)
- self.notif.set_timeout(pynotify.EXPIRES_DEFAULT)
+ self.notif.set_timeout(Notify.EXPIRES_DEFAULT)
self.notif.show()
else:
self.log.error('Error: there was a problem initializing the pynotify module')
else:
self.set_icon(data)
- self.notif.update(title, message)
+ self.notif.update(title, message, None)
self.notif.show()
@@ -81,12 +82,12 @@ class NotificationPlugin(Plugin):
if('icon' in data.keys()):
try:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(data['icon'], 48, 48)
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(data['icon'], 48, 48)
self.notif.set_icon_from_pixbuf(pixbuf)
except Exception, e:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(APP_ICON, 48, 48)
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(APP_ICON, 48, 48)
self.notif.set_icon_from_pixbuf(pixbuf)
print e
else:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(APP_ICON, 48, 48)
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(APP_ICON, 48, 48)
self.notif.set_icon_from_pixbuf(pixbuf)
Index: data/plugins/SleepTimerPlugin.py
===================================================================
--- data/plugins/SleepTimerPlugin.py.orig 2016-05-07 17:25:19.942842228 +0200
+++ data/plugins/SleepTimerPlugin.py 2016-05-07 17:25:23.258886108 +0200
@@ -19,8 +19,8 @@
##########################################################################
from Plugin import Plugin
-import gtk
-import gobject
+from gi.repository import Gtk
+from gi.repository import GObject
from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF
class SleepTimerPlugin(Plugin):
@@ -38,7 +38,7 @@ class SleepTimerPlugin(Plugin):
self.cfgProvider = cfgProvider
self.mediator = mediator
self.tooltip = tooltip
- self.menuItem = gtk.CheckMenuItem(self.getName(), False)
+ self.menuItem = Gtk.CheckMenuItem(self.getName())
self.menuItem.connect('activate', self.on_menu)
self.menuItem.show()
@@ -108,19 +108,19 @@ class SleepTimerPlugin(Plugin):
def populate_tooltip(self):
if self.sleep_timer_id != None:
- return _("Sleep: %smin") % str(self.min_to_sleep)
+ return _("Sleep: %s min") % str(self.min_to_sleep)
else:
return None
def start_sleep_timer(self, interval, display_msg):
- self.sleep_timer_id = gobject.timeout_add(interval*60000, self.on_sleep_timer)
+ self.sleep_timer_id = GObject.timeout_add(60000, self.on_sleep_timer)
self.min_to_sleep = interval
self.min_to_sleep_selected = interval
if display_msg:
self.eventManagerWrapper.notify(_("Sleep Timer"), _("%s minute sleep timer started") % str(interval))
def stop_sleep_timer(self, display_msg):
- gobject.source_remove(self.sleep_timer_id)
+ GObject.source_remove(self.sleep_timer_id)
self.sleep_timer_id = None
if display_msg:
self.eventManagerWrapper.notify(_("Sleep Timer"), _("Sleep timer stopped"))
@@ -128,15 +128,15 @@ class SleepTimerPlugin(Plugin):
def get_sleep_timer_value(self, default_value):
- #gtk.gdk.threads_enter()
+ #Gdk.threads_enter()
- dialog = gtk.Dialog(_("Edit Sleep Timer"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+ dialog = Gtk.Dialog(_("Edit Sleep Timer"), None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT, Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
- entry = gtk.Entry(4)
+ entry = Gtk.Entry(4)
entry.set_text(str(default_value))
- hbox = gtk.HBox()
- hbox.pack_start(gtk.Label(_("Minutes:")), False, 5, 5)
+ hbox = Gtk.HBox()
+ hbox.pack_start(Gtk.Label(_("Minutes:", True, True, 0)), False, 5, 5)
hbox.pack_end(entry, True, True, 5)
dialog.vbox.pack_end(hbox, True, True, 20)
dialog.set_icon_from_file(APP_ICON_ON)
@@ -146,13 +146,13 @@ class SleepTimerPlugin(Plugin):
sleep_timer_value = 0
- if ret == gtk.RESPONSE_ACCEPT:
+ if ret == Gtk.ResponseType.ACCEPT:
if entry.get_text().isdigit():
sleep_timer_value = int(entry.get_text())
dialog.destroy()
- #gtk.gdk.threads_leave()
+ #Gdk.threads_leave()
return sleep_timer_value
def on_menu(self, data):
Index: data/plugins/StationSwitcher.plugin
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ data/plugins/StationSwitcher.plugin 2016-05-07 17:25:23.254886055 +0200
@@ -0,0 +1,6 @@
+[RadioTrayPlugin]
+name=StationSwitcher
+desc=Allows cycling through stations
+script=StationSwitcherPlugin.py
+class=StationSwitcherPlugin
+author=Mark F
Index: data/plugins/StationSwitcherPlugin.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ data/plugins/StationSwitcherPlugin.py 2016-05-07 17:25:23.258886108 +0200
@@ -0,0 +1,115 @@
+##########################################################################
+# Copyright 2009 Carlos Ribeiro
+#
+# This file is part of Radio Tray
+#
+# Radio Tray is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 1 of the License, or
+# (at your option) any later version.
+#
+# Radio Tray is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Radio Tray. If not, see <http://www.gnu.org/licenses/>.
+#
+##########################################################################
+
+# author Mark F Jan 2013
+from Plugin import Plugin
+from gi.repository import Gtk
+import random
+
+class StationSwitcherPlugin(Plugin):
+
+ # Set by parent Plugin.py
+ # self.name = name
+ # self.eventManagerWrapper = eventManagerWrapper
+ # self.eventSubscriber = eventSubscriber
+ # self.provider = provider
+ # self.cfgProvider = cfgProvider
+ # self.mediator = mediator
+ # self.tooltip = tooltip
+
+ def __init__(self):
+ super(StationSwitcherPlugin, self).__init__()
+ self.shuffle = False # way to set this property from RadioTray not implemented yet
+
+ def getName(self):
+ return self.name
+
+ def activate(self):
+ # only Next >> button added to avoid cluttering menu. Play previous can be triggered using other means
+ nextMenuItem = Gtk.MenuItem("Next >>")
+
+ # locate the turn on/off menu item and add next button after
+ i = 0
+ insertIndex = 0
+ for child in self.tooltip.gui.radioMenu.get_children():
+ if not isinstance(child, Gtk.SeparatorMenuItem):
+ if child.get_label().startswith("Turn"):
+ insertIndex = i+1
+ break
+ # break statement is required due to bug/feature in Gtk. Examining MenuItem labels on 'separators' causes
+ # them not to be displayed correctly. If gui classes are modified to use SeparatorMenuItem break can be removed
+ i+=1
+
+ self.tooltip.gui.radioMenu.insert(nextMenuItem,insertIndex)
+ nextMenuItem.connect('activate', self.on_next)
+ nextMenuItem.show()
+
+ def on_next(self,data):
+ self.playNextRadio()
+
+ def playPreviousRadio(self):
+ self.mediator.play(self.getPreviousRadio())
+
+ def playNextRadio(self):
+ self.mediator.play(self.getNextRadio())
+
+ def getNextRadio(self):
+ if self.shuffle: return self.getRandomRadio()
+
+ allRadios = self.provider.listRadioNames()
+ lastStation = self.mediator.cfg_provider.getConfigValue("last_station")
+ lastStationIndex = allRadios.index(lastStation)
+
+ if lastStationIndex==len(allRadios)-1: nextStationIndex=0
+ else: nextStationIndex=lastStationIndex+1
+
+ return allRadios[nextStationIndex]
+
+ def getPreviousRadio(self):
+ if self.shuffle: return self.getRandomRadio()
+
+ allRadios = self.provider.listRadioNames()
+ lastStation = self.mediator.cfg_provider.getConfigValue("last_station")
+ lastStationIndex = allRadios.index(lastStation)
+
+ if lastStationIndex==0: previousStationIndex=len(allRadios)-1
+ else: previousStationIndex=lastStationIndex-1
+
+ return allRadios[previousStationIndex]
+
+ def getRandomRadio(self):
+
+ allRadios = self.provider.listRadioNames()
+ lastStation = self.mediator.cfg_provider.getConfigValue("last_station")
+ lastStationIndex = allRadios.index(lastStation)
+
+ randomStationIndex = lastStationIndex
+ while (randomStationIndex==lastStationIndex):
+ randomStationIndex = random.randint(0, len(allRadios)-1)
+
+ return allRadios[randomStationIndex]
+
+ def hasMenuItem(self):
+ return False
+
+ def on_menu(self, data):
+ #plugin config gui goes here. Need to add option for random station select
+ print ""
+
Index: data/plugins/history.glade
===================================================================
--- data/plugins/history.glade.orig 2016-05-07 17:25:19.934842122 +0200
+++ data/plugins/history.glade 2016-05-07 17:25:23.258886108 +0200
@@ -3,37 +3,23 @@
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkDialog" id="dialog1">
+ <property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Song History</property>
<property name="default_width">320</property>
<property name="default_height">260</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">normal</property>
+ <signal name="delete-event" handler="on_delete_event" swapped="no"/>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="spacing">2</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <object class="GtkTextView" id="textview1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
@@ -44,8 +30,9 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
- <signal name="clicked" handler="on_close_clicked"/>
+ <signal name="clicked" handler="on_close_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -56,10 +43,31 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkTextView" id="textview1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
</child>
<action-widgets>
Index: radiotray
===================================================================
--- radiotray.orig 2016-05-07 17:25:19.934842122 +0200
+++ radiotray 2016-05-07 17:25:23.258886108 +0200
@@ -4,12 +4,12 @@ import sys,os
from os.path import dirname, join, pardir
try:
- from radiotray import radiotray
+ from radiotray import radiotray_runner
except ImportError:
basedir = os.path.dirname(os.path.realpath(__file__))
workdir = join(basedir,'src')
sys.path.insert(0, workdir)
os.chdir(workdir)
- import radiotray
+ import radiotray_runner
-radiotray.main(sys.argv[1:])
+radiotray_runner.main(sys.argv[1:])
Index: src/AppIndicatorGui.py
===================================================================
--- src/AppIndicatorGui.py.orig 2016-05-07 17:25:19.934842122 +0200
+++ src/AppIndicatorGui.py 2016-05-07 17:25:23.258886108 +0200
@@ -20,10 +20,10 @@
import sys
from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF, APP_INDICATOR_ICON_CONNECT, IMAGE_PATH
try:
- import gtk
- import gtk.glade
- import gobject
-except:
+ from gi.repository import Gtk
+ #import Gtk.glade
+except Exception as e:
+ print e
sys.exit(1)
import textwrap
import logging
@@ -36,110 +36,113 @@ class AppIndicatorGui:
self.mediator = mediator
self.cfg_provider = cfg_provider
self.provider = provider
+ self.menu_plugins_item = None
self.log = logging.getLogger('radiotray')
def buildMenu(self):
- try:
- import appindicator
- self.app_indicator = appindicator.Indicator(APPNAME, APP_INDICATOR_ICON_OFF , appindicator.CATEGORY_APPLICATION_STATUS)
- self.app_indicator.set_status(appindicator.STATUS_ACTIVE)
+ try:
+ from gi.repository import AppIndicator3
+ self.app_indicator = AppIndicator3.Indicator.new(APPNAME, APP_INDICATOR_ICON_OFF , AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
+ self.app_indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
except Exception as e:
self.log.debug(e)
self.log.warn("Failed to create an Application Indicator!")
self.app_indicator = None
+ return
self.app_indicator.set_icon_theme_path(IMAGE_PATH)
self.turnOnOff = None
self.metadata_menu_item = None
self.perferences_submenu = None
- self.preferences_menu = None
- self.radioMenu = gtk.Menu()
+ self.preferences_menu = None
+ self.radioMenu = Gtk.Menu()
self.build_app_indicator_menu(self.radioMenu)
self.app_indicator.set_menu(self.radioMenu)
self.handler.updateTooltip()
+ try:
+ self.app_indicator.connect("scroll-event", self.app_indicator_scroll)
+ except:
+ # not available in this version of app indicator
+ self.log.info("App indicator scroll events are not available.")
+
def build_app_indicator_menu(self, menu):
- # config menu
- if self.turnOnOff == None:
+ # config menu
+ if self.turnOnOff == None:
if not self.mediator.context.station:
- self.turnOnOff = gtk.MenuItem(_("Turned Off"), False)
+ self.turnOnOff = Gtk.MenuItem(_("Turned Off"))
self.turnOnOff.set_sensitive(False)
else:
- self.turnOnOff = gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False)
+ self.turnOnOff = Gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station)
self.turnOnOff.set_sensitive(True)
-
+
self.turnOnOff.connect('activate', self.handler.on_turn_on_off)
-
-
+
# stream metadata info
if self.metadata_menu_item == None:
- self.metadata_menu_item = gtk.MenuItem("Idle", False)
+ self.metadata_menu_item = Gtk.MenuItem("Idle")
self.metadata_menu_item.set_sensitive(False)
-
- # if self.sleep_timer_menu_item == None:
- # self.sleep_timer_menu_item = gtk.CheckMenuItem(_("Sleep Timer"))
-
+
+ # if self.sleep_timer_menu_item == None:
+ # self.sleep_timer_menu_item = Gtk.CheckMenuItem(_("Sleep Timer"))
+
if self.preferences_menu == None:
- self.preferences_menu = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
-
- menu_config_radios = gtk.MenuItem(_("Configure Radios..."))
- menu_reload_bookmarks = gtk.MenuItem(_("Reload Bookmarks"))
- menu_config_plugin = gtk.MenuItem(_("Configure Plugins..."))
+ self.preferences_menu = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_PREFERENCES, None)
+ self.preferences_menu.set_always_show_image(True)
+
+ menu_config_radios = Gtk.MenuItem(_("Configure Radios..."))
+ menu_reload_bookmarks = Gtk.MenuItem(_("Reload Bookmarks"))
+ menu_config_plugin = Gtk.MenuItem(_("Configure Plugins..."))
#Check bookmarks file status
menu_config_radios.set_sensitive(self.provider.isBookmarkWritable())
- # build
- menu.append(self.turnOnOff)
- menu.append(gtk.MenuItem())
+ # build
+ menu.append(self.turnOnOff)
+ menu.append(Gtk.MenuItem())
menu.append(self.metadata_menu_item)
- menu.append(gtk.MenuItem())
-
+ menu.append(Gtk.MenuItem())
+
self.provider.walk_bookmarks(self.group_callback, self.bookmark_callback, menu)
-
+
menu_config_radios.connect('activate', self.handler.on_preferences)
menu_reload_bookmarks.connect('activate', self.handler.reload_bookmarks)
menu_config_plugin.connect('activate', self.handler.on_plugin_preferences)
-
-
- menu.append(gtk.MenuItem())
-
+
+
+ menu.append(Gtk.MenuItem())
+
# build preferences
menu.append(self.preferences_menu)
-
- if self.perferences_submenu == None:
- self.perferences_submenu = gtk.Menu()
- self.preferences_menu.set_submenu(self.perferences_submenu)
- #self.perferences_submenu.append(gtk.MenuItem())
+
+ if self.perferences_submenu == None:
+ self.perferences_submenu = Gtk.Menu()
+ self.preferences_menu.set_submenu(self.perferences_submenu)
+ #self.perferences_submenu.append(Gtk.MenuItem())
self.perferences_submenu.append(menu_config_radios)
self.perferences_submenu.append(menu_reload_bookmarks)
# plugins submenu
- menu_plugins_item = gtk.MenuItem("Plugins", False)
- self.menu_plugins = gtk.Menu()
- self.menu_plugins.append(menu_config_plugin)
- self.menu_plugins.append(gtk.MenuItem()) #add separator
- menu_plugins_item.set_submenu(self.menu_plugins)
+ if self.menu_plugins_item == None:
+ self.menu_plugins_item = Gtk.MenuItem("Plugins")
+ self.menu_plugins = Gtk.Menu()
+ self.menu_plugins.append(menu_config_plugin)
+ self.menu_plugins.append(Gtk.MenuItem()) #add separator
+ self.menu_plugins_item.set_submenu(self.menu_plugins)
- menu.append(menu_plugins_item)
+ menu.append(self.menu_plugins_item)
- menu_about = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
- menu_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+ menu_about = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_ABOUT, None)
+ menu_quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
menu_quit.connect('activate', self.handler.on_quit)
menu_about.connect('activate', self.handler.on_about)
menu.append(menu_about)
menu.append(menu_quit)
menu.show_all()
-
- try:
- self.app_indicator.connect("scroll-event", self.app_indicator_scroll)
- except:
- # not available in this version of app indicator
- self.log.info("App indicator scroll events are not available.")
def app_indicator_scroll(self, indicator, delta, direction):
@@ -159,26 +162,26 @@ class AppIndicatorGui:
def group_callback(self, group_name, user_data):
new_user_data = None
-
+
if group_name != 'root':
- group = gtk.MenuItem(group_name, False)
- user_data.append(group)
- new_user_data = gtk.Menu()
+ group = Gtk.MenuItem(group_name)
+ user_data.append(group)
+ new_user_data = Gtk.Menu()
group.set_submenu(new_user_data)
else:
new_user_data = self.radioMenu
-
+
return new_user_data
def bookmark_callback(self, radio_name, user_data):
if radio_name.startswith("[separator-"):
- separator = gtk.MenuItem()
+ separator = Gtk.MenuItem()
user_data.append(separator)
separator.show()
- else:
- radio = gtk.MenuItem(radio_name, False)
+ else:
+ radio = Gtk.MenuItem(radio_name)
radio.show()
radio.connect('activate', self.handler.on_start, radio_name)
user_data.append(radio)
@@ -193,9 +196,9 @@ class AppIndicatorGui:
station = data['station']
self.turnOnOff.set_label(C_('Turns off the current radio.', 'Turn Off "%s"') % station)
self.turnOnOff.set_sensitive(True)
-
+
self.app_indicator.set_icon(APP_INDICATOR_ICON_ON)
-
+
elif(state == 'paused'):
if not self.mediator.context.station:
self.turnOnOff.set_label(_('Turned Off'))
@@ -203,9 +206,9 @@ class AppIndicatorGui:
else:
self.turnOnOff.set_label(_('Turn On "%s"' % self.mediator.context.station))
self.turnOnOff.set_sensitive(True)
-
+
self.app_indicator.set_icon(APP_INDICATOR_ICON_OFF)
-
+
elif(state == 'connecting'):
station = data['station']
self.turnOnOff.set_sensitive(True)
@@ -223,15 +226,15 @@ class AppIndicatorGui:
if (self.mediator.getContext().state == 'playing'):
if(songInfo):
- otherInfo = "(vol: %s%%)" % (volume)
-
+ otherInfo = "(vol: %s%%)" % (volume)
+
# don't break volume info...
text = textwrap.wrap(songInfo, 30)
if (30 - len(text[-1])) >= (len(otherInfo)+1):
text[-1] += " " + otherInfo
else:
text.append(otherInfo)
-
+
return "\n".join(text)
else:
return C_("Playing status tooltip information", "Playing (vol: %s%%)") % (volume)
Index: src/AudioPlayerGStreamer.py
===================================================================
--- src/AudioPlayerGStreamer.py.orig 2016-05-07 17:25:19.934842122 +0200
+++ src/AudioPlayerGStreamer.py 2016-05-07 17:25:23.258886108 +0200
@@ -18,10 +18,21 @@
#
##########################################################################
import sys, os
-import pygtk, gtk, gobject
-import pygst
-pygst.require("0.10")
-import gst
+try:
+ import gi
+ gi.require_version("Gtk", "3.0")
+ gi.require_version('Gst', '1.0')
+except:
+ pass
+try:
+ from gi.repository import Gtk
+ from gi.repository import GObject
+ GObject.threads_init()
+ from gi.repository import Gst
+ Gst.init(None)
+except Exception as e:
+ print e
+
from StreamDecoder import StreamDecoder
from lib.common import USER_AGENT
from events.EventManager import EventManager
@@ -40,11 +51,13 @@ class AudioPlayerGStreamer:
self.log = logging.getLogger('radiotray')
# init player
- self.souphttpsrc = gst.element_factory_make("souphttpsrc", "source")
+ self.log.debug("Initializing gstreamer...")
+ self.souphttpsrc = Gst.ElementFactory.make("souphttpsrc", "source")
self.souphttpsrc.set_property("user-agent", USER_AGENT)
- self.player = gst.element_factory_make("playbin2", "player")
- fakesink = gst.element_factory_make("fakesink", "fakesink")
+ self.log.debug("Loading playbin...");
+ self.player = Gst.ElementFactory.make("playbin", "player")
+ fakesink = Gst.ElementFactory.make("fakesink", "fakesink")
self.player.set_property("video-sink", fakesink)
#buffer size
@@ -60,6 +73,8 @@ class AudioPlayerGStreamer:
bus.add_signal_watch()
bus.connect("message", self.on_message)
+ self.log.debug("GStreamer initialized.")
+
def start(self, uri):
urlInfo = self.decoder.getMediaStreamInfo(uri)
@@ -103,10 +118,10 @@ class AudioPlayerGStreamer:
def playStream(self, uri):
self.player.set_property("uri", uri)
- self.player.set_state(gst.STATE_PAUSED) # buffer before starting playback
+ self.player.set_state(Gst.State.PAUSED) # buffer before starting playback
def stop(self):
- self.player.set_state(gst.STATE_NULL)
+ self.player.set_state(Gst.State.NULL)
self.eventManager.notify(EventManager.STATE_CHANGED, {'state':'paused'})
def volume_up(self, volume_increment):
@@ -120,30 +135,30 @@ class AudioPlayerGStreamer:
def on_message(self, bus, message):
t = message.type
- stru = message.structure
+ stru = message.get_structure()
if(stru != None):
name = stru.get_name()
if(name == 'redirect'):
- slef.log.info("redirect received")
- self.player.set_state(gst.STATE_NULL)
+ self.log.info("redirect received")
+ self.player.set_state(Gst.State.NULL)
stru.foreach(self.redirect, None)
- if t == gst.MESSAGE_EOS:
+ if t == Gst.MessageType.EOS:
self.log.debug("Received MESSAGE_EOS")
- self.player.set_state(gst.STATE_NULL)
+ self.player.set_state(Gst.State.NULL)
self.playNextStream()
- elif t == gst.MESSAGE_BUFFERING:
- percent = message.structure['buffer-percent']
+ elif t == Gst.MessageType.BUFFERING:
+ percent = message.parse_buffering()
if percent < 100:
self.log.debug("Buffering %s" % percent)
- self.player.set_state(gst.STATE_PAUSED)
+ self.player.set_state(Gst.State.PAUSED)
else:
- self.player.set_state(gst.STATE_PLAYING)
- elif t == gst.MESSAGE_ERROR:
+ self.player.set_state(Gst.State.PLAYING)
+ elif t == Gst.MessageType.ERROR:
self.log.debug("Received MESSAGE_ERROR")
- self.player.set_state(gst.STATE_NULL)
+ self.player.set_state(Gst.State.NULL)
err, debug = message.parse_error()
self.log.warn(err)
self.log.warn(debug)
@@ -153,15 +168,15 @@ class AudioPlayerGStreamer:
else:
self.eventManager.notify(EventManager.STATION_ERROR, {'error':debug})
- elif t == gst.MESSAGE_STATE_CHANGED:
+ elif t == Gst.MessageType.STATE_CHANGED:
oldstate, newstate, pending = message.parse_state_changed()
self.log.debug(("Received MESSAGE_STATE_CHANGED (%s -> %s)") % (oldstate, newstate))
- if newstate == gst.STATE_PLAYING:
+ if newstate == Gst.State.PLAYING:
self.retrying = False
station = self.mediator.getContext().station
self.eventManager.notify(EventManager.STATE_CHANGED, {'state':'playing', 'station':station})
- elif oldstate == gst.STATE_PLAYING and newstate == gst.STATE_PAUSED:
+ elif oldstate == Gst.State.PLAYING and newstate == Gst.State.PAUSED:
self.log.info("Received PAUSE state.")
if self.retrying == False:
@@ -172,22 +187,35 @@ class AudioPlayerGStreamer:
- elif t == gst.MESSAGE_TAG:
+ elif t == Gst.MessageType.TAG:
taglist = message.parse_tag()
- #if there is no song information, there's no point in triggering song change event
- if('artist' in taglist.keys() or 'title' in taglist.keys()):
- station = self.mediator.getContext().station
- metadata = {}
+ #for (tag, value) in taglist.items():
+ # print "TT: " + tag + " - " + value
- for key in taglist.keys():
- metadata[key] = taglist[key]
+ (present, value) = taglist.get_string('title')
+ if present:
+ metadata = {}
+ station = self.mediator.getContext().station
+ metadata['title'] = value
metadata['station'] = station
-
+
self.eventManager.notify(EventManager.SONG_CHANGED, metadata)
+ #if there is no song information, there's no point in triggering song change event
+ #if('artist' in taglist.keys() or 'title' in taglist.keys()):
+ # station = self.mediator.getContext().station
+ # metadata = {}
+
+ # for key in taglist.keys():
+ # metadata[key] = taglist[key]
+
+ # metadata['station'] = station
+
+ # self.eventManager.notify(EventManager.SONG_CHANGED, metadata)
+
return True
def redirect(self, name, value, data):
Index: src/BookmarkConfiguration.py
===================================================================
--- src/BookmarkConfiguration.py.orig 2016-05-07 17:25:19.934842122 +0200
+++ src/BookmarkConfiguration.py 2016-05-07 17:25:23.258886108 +0200
@@ -18,18 +18,19 @@
#
##########################################################################
import sys
+import pdb
try:
- import pygtk
- pygtk.require("2.0")
+ import gi
+ gi.require_version("Gtk", "3.0")
except:
pass
try:
- import gtk
- import gtk.glade
- import gobject
+ from gi.repository import Gtk, Gdk
+ #import Gtk.glade
import os
-except:
+except Exception as e:
+ print e
sys.exit(1)
from XmlDataProvider import XmlDataProvider
@@ -39,8 +40,9 @@ from lib import i18n
import uuid
import logging
-drop_yes = ("drop_yes", gtk.TARGET_SAME_WIDGET, 0)
-drop_no = ("drop_no", gtk.TARGET_SAME_WIDGET, 0)
+drop_yes = [Gtk.TargetEntry.new(target = "drop_yes", flags = Gtk.TargetFlags.SAME_WIDGET, info = 0)]
+drop_no = [Gtk.TargetEntry.new(target = "drop_no", flags = Gtk.TargetFlags.SAME_WIDGET, info = 0)]
+targets = [('data',Gtk.TargetFlags.SAME_APP,0)]
class BookmarkConfiguration(object):
@@ -92,23 +94,23 @@ class BookmarkConfiguration(object):
self.load_data()
# config tree ui
- cell = gtk.CellRendererText()
- tvcolumn = gtk.TreeViewColumn(_('Radio Name'), cell)
+ cell = Gtk.CellRendererText()
+ tvcolumn = Gtk.TreeViewColumn(_('Radio Name'), cell)
self.list.append_column(tvcolumn)
tvcolumn.add_attribute(cell, 'text', 0)
# config combo ui
- cell2 = gtk.CellRendererText()
+ cell2 = Gtk.CellRendererText()
self.parentGroup.pack_start(cell2, True)
self.parentGroup.add_attribute(cell2, 'text', 0)
# config add radio group combo ui
- cell4 = gtk.CellRendererText()
+ cell4 = Gtk.CellRendererText()
self.radioGroup.pack_start(cell4, True)
self.radioGroup.add_attribute(cell4, 'text', 0)
# separator new group combo ui
- cell3 = gtk.CellRendererText()
+ cell3 = Gtk.CellRendererText()
self.sepGroup.pack_start(cell3, True)
self.sepGroup.add_attribute(cell3, 'text', 0)
@@ -128,12 +130,14 @@ class BookmarkConfiguration(object):
self.wTree.connect_signals(self)
# enable drag and drop support
- self.list.enable_model_drag_source(
- gtk.gdk.BUTTON1_MASK, [drop_yes], gtk.gdk.ACTION_MOVE)
- self.list.enable_model_drag_dest(
- [drop_yes], gtk.gdk.ACTION_MOVE)
- self.list.connect("drag-data-received", self.onDragDataReceived)
- self.list.connect("drag-motion", self.onDragMotion)
+ self.list.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.MOVE)
+ self.list.enable_model_drag_dest([], Gdk.DragAction.MOVE)
+ print "config"
+ self.list.drag_dest_add_text_targets()
+ self.list.drag_source_add_text_targets()
+
+ self.list.connect("drag_data_received", self.onDragDataReceived)
+ self.list.connect("drag_data_get", self.onDataGet)
# Connect row activation with bookmarks conf
self.list.connect("row-activated", self.on_row_activated)
@@ -141,7 +145,7 @@ class BookmarkConfiguration(object):
def load_data(self):
# the meaning of the three columns is: description, id, type
- treestore = gtk.TreeStore(str, str, str)
+ treestore = Gtk.TreeStore(str, str, str)
root = self.dataProvider.getRootGroup()
self.add_group_data(root, None, treestore)
self.list.set_model(treestore)
@@ -152,17 +156,19 @@ class BookmarkConfiguration(object):
def checkSanity(self, model, source, target):
source_path = model.get_path(source)
target_path = model.get_path(target)
- if target_path[0:len(source_path)] == source_path:
+ if target_path[0:len(source_path)] == list(source_path):
return False
else:
return True
#drag and drop support
def checkParentability(self, model, target, drop_position):
- if (drop_position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE
- or drop_position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER) \
- and (model.get_value(target, 2) == self.RADIO_TYPE or model.get_value(target, 2) == self.SEPARATOR_TYPE):
- return False
+
+ if (drop_position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or drop_position == Gtk.TreeViewDropPosition.INTO_OR_AFTER):
+ if(model.get_value(target, 2) == self.RADIO_TYPE or model.get_value(target, 2) == self.SEPARATOR_TYPE):
+ return False
+ else:
+ return True
else:
return True
@@ -174,27 +180,45 @@ class BookmarkConfiguration(object):
#drag and drop support
def copyRow(self, treeview, model, source, target, drop_position):
-
- source_row = model[source]
- if drop_position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE:
- new = model.prepend(target, source_row)
- elif drop_position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER:
- new = model.append(target, source_row)
- elif drop_position == gtk.TREE_VIEW_DROP_BEFORE:
- new = model.insert_before(None, target, source_row)
- elif drop_position == gtk.TREE_VIEW_DROP_AFTER:
- new = model.insert_after(None, target, source_row)
+
+ #source_is_expanded = treeview.row_expanded(model.get_path(source))
+ new = None
+
+ if (drop_position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE) or (drop_position == Gtk.TreeViewDropPosition.INTO_OR_AFTER):
+ new = model.append(target, model[source][:])
+
+ elif drop_position == Gtk.TreeViewDropPosition.BEFORE:
+ parent = model.iter_parent(target)
+ new = model.insert_before(parent, target, model[source][:])
+
+ elif drop_position == Gtk.TreeViewDropPosition.AFTER:
+ parent = model.iter_parent(target)
+ new = model.insert_after(parent, target, model[source][:])
+
+ else:
+ print "No data copied!"
+ return
- for n in range(model.iter_n_children(source)):
- child = model.iter_nth_child(source, n)
- self.copyRow(treeview, model, child, new,
- gtk.TREE_VIEW_DROP_INTO_OR_BEFORE)
+ nrChild = range(model.iter_n_children(source))
+ while(model.iter_n_children(source) > 0):
+ child = model.iter_nth_child(source, 0)
+ self.copyRow(treeview, model, child, new, Gtk.TreeViewDropPosition.INTO_OR_BEFORE)
+
+ model.remove(source)
+
- source_is_expanded = treeview.row_expanded(model.get_path(source))
- if source_is_expanded:
- self.expandToPath(treeview, model.get_path(new))
+
+ #if source_is_expanded:
+ # self.expandToPath(treeview, model.get_path(new))
+ def onDataGet(self, widget, context, selection, info, time):
+ treeselection = widget.get_selection()
+ model, iter = treeselection.get_selected()
+ data = model.get_value(iter, 0)
+ selection.set(selection.get_target(), 8, data)
+ return
+
#drag and drop support
def onDragDataReceived(self, treeview, drag_context, x, y, selection_data, info, eventtime):
@@ -208,13 +232,17 @@ class BookmarkConfiguration(object):
target = model.get_iter(target_path)
sourceName = model.get_value(source,1)
targetName = model.get_value(target,1)
+
+ print "source: " + sourceName + " , target: " + targetName;
is_sane = self.checkSanity(model, source, target)
is_parentable = self.checkParentability(model, target, drop_position)
+
if is_sane and is_parentable:
+
self.copyRow(treeview, model, source, target, drop_position)
- if (drop_position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE
- or drop_position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
+ if (drop_position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE
+ or drop_position == Gtk.TreeViewDropPosition.INTO_OR_AFTER):
treeview.expand_row(target_path, False)
drag_context.finish(True, True, eventtime)
@@ -223,21 +251,6 @@ class BookmarkConfiguration(object):
drag_context.finish(False, False, eventtime)
- #drag and drop support
- def onDragMotion(self, treeview, drag_context, x, y, eventtime):
- try:
- target_path, drop_position = treeview.get_dest_row_at_pos(x, y)
- model, source = treeview.get_selection().get_selected()
- target = model.get_iter(target_path)
- except:
- return
- is_sane = self.checkSanity(model, source, target)
- is_parentable = self.checkParentability(model, target, drop_position)
- if is_sane and is_parentable:
- treeview.enable_model_drag_dest([drop_yes], gtk.gdk.ACTION_MOVE)
- else:
- treeview.enable_model_drag_dest([drop_no], gtk.gdk.ACTION_MOVE)
-
@@ -278,7 +291,7 @@ class BookmarkConfiguration(object):
self.radioGroupLabel.show()
# populate groups
- liststore = gtk.ListStore(str)
+ liststore = Gtk.ListStore(str)
for group in self.dataProvider.listGroupNames():
liststore.append([group])
@@ -327,7 +340,7 @@ class BookmarkConfiguration(object):
selectedName = model.get_value(iter,1)
selectedType = model.get_value(iter, 2)
- liststore = gtk.ListStore(str)
+ liststore = Gtk.ListStore(str)
for group in self.dataProvider.listGroupNames():
liststore.append([group])
@@ -456,11 +469,11 @@ class BookmarkConfiguration(object):
# if separator then just remove it
if not separatorFlag.startswith("[separator-"):
- confirmation = gtk.MessageDialog(
+ confirmation = Gtk.MessageDialog(
self.window,
- gtk.DIALOG_MODAL,
- gtk.MESSAGE_QUESTION,
- gtk.BUTTONS_YES_NO,
+ Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.QUESTION,
+ Gtk.ButtonsType.YES_NO,
_("Are you sure you want to delete \"%s\"?") % selectedRadioName
)
@@ -490,7 +503,7 @@ class BookmarkConfiguration(object):
# close the window and quit
def on_delete_event(self, widget, event, data=None):
if self.standalone:
- gtk.main_quit()
+ Gtk.main_quit()
return False
def on_nameEntry_activated(self, widget):
@@ -509,7 +522,7 @@ class BookmarkConfiguration(object):
self.groupNameEntry.grab_focus()
# populate parent groups
- liststore = gtk.ListStore(str)
+ liststore = Gtk.ListStore(str)
for group in self.dataProvider.listGroupNames():
liststore.append([group])
Index: src/GuiChooserConfiguration.py
===================================================================
--- src/GuiChooserConfiguration.py.orig 2016-05-07 17:25:19.934842122 +0200
+++ src/GuiChooserConfiguration.py 2016-05-07 17:25:23.258886108 +0200
@@ -20,16 +20,16 @@
import sys
try:
- import pygtk
- pygtk.require("2.0")
+ import gi
+ gi.require_version("Gtk", "3.0")
except:
pass
try:
- import gtk
- import gtk.glade
- import gobject
+ from gi.repository import Gtk
+ #import Gtk.glade
import os
-except:
+except Exception as e:
+ print e
sys.exit(1)
from lib.common import APP_ICON_ON
Index: src/NotificationManager.py
===================================================================
--- src/NotificationManager.py.orig 2016-05-07 17:25:19.934842122 +0200
+++ src/NotificationManager.py 2016-05-07 17:25:23.258886108 +0200
@@ -30,22 +30,23 @@ class NotificationManager(object):
self.eventManagerWrapper = eventManagerWrapper
self.log = logging.getLogger('radiotray')
self.lastState = None
-
+
def on_state_changed(self, data):
-
+
state = data['state']
-
+
if(state == 'playing' and state != self.lastState):
station = data['station']
- self.lastState = state
self.eventManagerWrapper.notify(_('Radio Tray Playing'), station)
-
+ self.lastState = state
+
+
def on_song_changed(self, data):
-
+
self.log.debug(data)
-
+
station = data['station']
msgTitle = "%s - %s" % (APPNAME , station)
msg = None
@@ -53,7 +54,7 @@ class NotificationManager(object):
if('artist' in data.keys() and 'title' in data.keys()):
artist = data['artist']
title = data['title']
- msg = "%s - %s" % (artist, title)
+ msg = "%s - %s" % (artist, title)
elif('artist' in data.keys()):
msg = data['artist']
elif('title' in data.keys()):
@@ -70,24 +71,24 @@ class NotificationManager(object):
try:
f.write(pix)
except Exception, e:
- log.warn('Error saving icon')
+ self.log.warn('Error saving icon')
finally:
f.close()
self.eventManagerWrapper.notify_icon(msgTitle, msg, ICON_FILE)
-
+
except Exception, e:
traceback.print_exc()
self.eventManagerWrapper.notify(msgTitle, msg)
else:
self.eventManagerWrapper.notify(msgTitle, msg)
-
+
def on_station_error(self, data):
-
+
self.eventManagerWrapper.notify(_('Radio Error'), str(data['error']))
def on_bookmarks_reloaded(self, data):
self.eventManagerWrapper.notify(_("Bookmarks Reloaded"), _("Bookmarks Reloaded"))
-
-
+
+
Index: src/Plugin.py
===================================================================
--- src/Plugin.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ src/Plugin.py 2016-05-07 17:25:23.258886108 +0200
@@ -19,7 +19,7 @@
##########################################################################
import threading
-import gtk
+from gi.repository import Gtk
import logging
# This class should be extended by plugins implementations
@@ -38,7 +38,7 @@ class Plugin(threading.Thread):
self.cfgProvider = cfgProvider
self.mediator = mediator
self.tooltip = tooltip
- self.menuItem = gtk.MenuItem(self.getName(), False)
+ self.menuItem = Gtk.MenuItem(self.getName())
self.menuItem.connect('activate', self.on_menu)
self.menuItem.show()
Index: src/PluginConfiguration.py
===================================================================
--- src/PluginConfiguration.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ src/PluginConfiguration.py 2016-05-07 17:25:23.258886108 +0200
@@ -20,19 +20,20 @@
import sys
try:
- import pygtk
- pygtk.require("2.0")
+ import gi
+ gi.require_version("Gtk", "3.0")
except:
pass
try:
- import gtk
- import gtk.glade
- import gobject
+ from gi.repository import Gtk
+ #import Gtk.glade
+ from gi.repository import GObject
+ GObject.threads_init()
import os
from lib import utils
from lib.common import APP_ICON_ON
-except:
- sys.exit(1)
+except Exception as e:
+ print e
import logging
class PluginConfiguration(object):
@@ -58,17 +59,17 @@ class PluginConfiguration(object):
# config plugins view
- cell1 = gtk.CellRendererToggle()
+ cell1 = Gtk.CellRendererToggle()
cell1.set_property('activatable', True)
cell1.set_activatable(True)
- cell1.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+ cell1.set_property('mode', Gtk.CellRendererMode.ACTIVATABLE)
cell1.connect( 'toggled', self.on_toggle, liststore )
- tvcolumn1 = gtk.TreeViewColumn(_('Active'), cell1)
+ tvcolumn1 = Gtk.TreeViewColumn(_('Active'), cell1)
tvcolumn1.add_attribute( cell1, "active", 0)
- cell2 = gtk.CellRendererText()
- tvcolumn2 = gtk.TreeViewColumn(_('Name'), cell2, text=1)
+ cell2 = Gtk.CellRendererText()
+ tvcolumn2 = Gtk.TreeViewColumn(_('Name'), cell2, text=1)
self.list.append_column(tvcolumn1)
self.list.append_column(tvcolumn2)
@@ -88,7 +89,7 @@ class PluginConfiguration(object):
# self.cfgProvider.setConfigValue('active_plugins'
- liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING)
+ liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING)
plugins = self.pluginManager.getPlugins()
for p in plugins:
Index: src/RadioTray.py
===================================================================
--- src/RadioTray.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ src/RadioTray.py 2016-05-07 17:25:23.258886108 +0200
@@ -73,6 +73,7 @@ class RadioTray(object):
# tooltip manager
tooltipManager = TooltipManager()
+ self.logger.debug("Tooltip manager initialized.")
# chooser
if(url == '--config'):
@@ -82,7 +83,7 @@ class RadioTray(object):
url = None
# load gui
self.systray = SysTray(self.mediator, self.provider, self.cfg_provider, self.default_cfg_provider, eventManager, tooltipManager)
-
+ self.logger.debug("GUI initialized")
# notification manager
Index: src/SysTray.py
===================================================================
--- src/SysTray.py.orig 2016-05-07 17:25:19.882841433 +0200
+++ src/SysTray.py 2016-05-07 17:28:34.865395809 +0200
@@ -20,17 +20,19 @@
import sys,os
import time
try:
- import pygtk
- pygtk.require("2.1")
- import gtk
-except:
+ import gi
+ gi.require_version("Gtk", "3.0")
+ from gi.repository import Gtk
+ from gi.repository import Gdk
+except Exception as e:
+ print e
pass
-try:
- import gtk
- import gtk.glade
- import gobject
-except:
- sys.exit(1)
+#try:
+ #from gi.repository import Gtk
+ #import Gtk.glade
+#except Exception as e:
+# print e
+# sys.exit(1)
from AudioPlayerGStreamer import AudioPlayerGStreamer
from XmlDataProvider import XmlDataProvider
@@ -95,7 +97,7 @@ class SysTray(object):
# execute gui chooser
try:
- import appindicator
+ from gi.repository import AppIndicator3
self.gui_engine = self.cfg_provider.getConfigValue("gui_engine")
if(self.gui_engine == None):
self.gui_engine = default_cfg_provider.getConfigValue("gui_engine")
@@ -113,7 +115,6 @@ class SysTray(object):
-
if self.gui_engine == "appindicator":
self.app_indicator_enabled = True
else:
@@ -137,10 +138,10 @@ class SysTray(object):
###### Action Events #######
def scroll(self,widget, event):
- if event.direction == gtk.gdk.SCROLL_UP:
+ if event.direction == Gdk.ScrollDirection.UP:
self.mediator.volume_up()
- if event.direction == gtk.gdk.SCROLL_DOWN:
+ if event.direction == Gdk.ScrollDirection.DOWN:
self.mediator.volume_down()
def volume_up(self, menu_item):
self.mediator.volume_up()
@@ -154,7 +155,7 @@ class SysTray(object):
def on_quit(self, data):
self.log.info('Exiting...')
- gtk.main_quit()
+ Gtk.main_quit()
def on_about(self, data):
about_dialog(parent=None)
@@ -182,9 +183,8 @@ class SysTray(object):
def run(self):
- gtk.gdk.threads_init()
- gtk.gdk.threads_enter()
- gtk.main()
+ Gdk.threads_init()
+ Gtk.main()
Index: src/SysTrayGui.py
===================================================================
--- src/SysTrayGui.py.orig 2016-05-07 17:25:19.942842228 +0200
+++ src/SysTrayGui.py 2016-05-07 17:25:23.258886108 +0200
@@ -18,16 +18,16 @@
#
##########################################################################
try:
- import pygtk
- pygtk.require("2.1")
- import gtk
+ import gi
+ pyGtk.require("2.1")
+ from gi.repository import Gtk
except:
pass
try:
- import gtk
- import gtk.glade
- import gobject
-except:
+ from gi.repository import Gtk
+ #import Gtk.glade
+except Exception as e:
+ print e
sys.exit(1)
from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF
@@ -46,17 +46,17 @@ class SysTrayGui:
def buildMenu(self):
# radios menu
- self.radioMenu = gtk.Menu()
+ self.radioMenu = Gtk.Menu()
if not self.mediator.context.station:
- self.turnOnOff = gtk.MenuItem(_("Turned Off"), False)
- self.turnOnOff2 = gtk.MenuItem(_("Turned Off"), False)
+ self.turnOnOff = Gtk.MenuItem(_("Turned Off"))
+ self.turnOnOff2 = Gtk.MenuItem(_("Turned Off"))
self.turnOnOff.set_sensitive(False)
self.turnOnOff2.set_sensitive(False)
else:
- self.turnOnOff = gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False)
+ self.turnOnOff = Gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station)
self.turnOnOff.set_sensitive(True)
- self.turnOnOff2 = gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False)
+ self.turnOnOff2 = Gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station)
self.turnOnOff2.set_sensitive(True)
self.turnOnOff.connect('activate', self.handler.on_turn_on_off)
@@ -64,34 +64,34 @@ class SysTrayGui:
self.update_radios()
# config menu
- self.menu = gtk.Menu()
- self.turnOnOff2 = gtk.MenuItem(_("Turned Off"))
+ self.menu = Gtk.Menu()
+ self.turnOnOff2 = Gtk.MenuItem(_("Turned Off"))
self.turnOnOff2.connect('activate', self.handler.on_turn_on_off)
self.turnOnOff2.set_sensitive(False)
- separator = gtk.MenuItem()
- menu_item1 = gtk.MenuItem(_("Configure Radios..."))
+ separator = Gtk.MenuItem()
+ menu_item1 = Gtk.MenuItem(_("Configure Radios..."))
#Check bookmarks file status
menu_item1.set_sensitive(self.provider.isBookmarkWritable())
- menu_item4 = gtk.MenuItem(_("Reload Bookmarks"))
- menu_item3 = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
- menu_item2 = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+ menu_item4 = Gtk.MenuItem(_("Reload Bookmarks"))
+ menu_item3 = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_ABOUT, None)
+ menu_item2 = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
self.menu.append(self.turnOnOff2)
self.menu.append(separator)
self.menu.append(menu_item1)
# plugins sub-menu
- menu_plugins_item = gtk.MenuItem("Plugins", False)
- self.menu_plugins = gtk.Menu()
+ menu_plugins_item = Gtk.MenuItem("Plugins")
+ self.menu_plugins = Gtk.Menu()
menu_plugins_item.set_submenu(self.menu_plugins)
- menu_item5 = gtk.MenuItem(_("Configure Plugins..."))
+ menu_item5 = Gtk.MenuItem(_("Configure Plugins..."))
self.menu_plugins.append(menu_item5)
- self.menu_plugins.append(gtk.MenuItem()) #add separator
+ self.menu_plugins.append(Gtk.MenuItem()) #add separator
self.menu.append(menu_plugins_item)
self.menu.append(menu_item4)
- self.menu.append(gtk.MenuItem())
+ self.menu.append(Gtk.MenuItem())
self.menu.append(menu_item3)
self.menu.append(menu_item2)
menu_item1.show()
@@ -112,7 +112,7 @@ class SysTrayGui:
self.menu.show_all()
- self.icon = gtk.status_icon_new_from_file(APP_ICON_OFF)
+ self.icon = Gtk.StatusIcon.new_from_file(APP_ICON_OFF)
self.icon.set_tooltip_markup(_("Idle (vol: %s%%)") % (self.mediator.getVolume()))
self.icon.connect('button_press_event', self.button_press)
self.icon.connect('scroll_event', self.handler.scroll)
@@ -121,7 +121,7 @@ class SysTrayGui:
def button_press(self,widget,event):
if(event.button == 1):
- self.radioMenu.popup(None, None, gtk.status_icon_position_menu, 0, event.get_time(), widget)
+ self.radioMenu.popup(None, None, Gtk.StatusIcon.position_menu, widget, 0, event.get_time())
elif (event.button == 2):
if (self.mediator.getContext().state == 'playing'):
self.mediator.stop()
@@ -129,7 +129,7 @@ class SysTrayGui:
if self.mediator.getContext().station:
self.mediator.play(self.mediator.getContext().station)
else:
- self.menu.popup(None, None, gtk.status_icon_position_menu, 2, event.get_time(), widget)
+ self.menu.popup(None, None, Gtk.StatusIcon.position_menu, widget, 2, event.get_time())
def update_radios(self):
@@ -141,7 +141,7 @@ class SysTrayGui:
self.radioMenu.append(self.turnOnOff)
self.turnOnOff.show()
- separator = gtk.MenuItem()
+ separator = Gtk.MenuItem()
self.radioMenu.append(separator)
separator.show()
@@ -155,9 +155,9 @@ class SysTrayGui:
new_user_data = None
if group_name != 'root':
- group = gtk.MenuItem(group_name, False)
+ group = Gtk.MenuItem(group_name)
user_data.append(group)
- new_user_data = gtk.Menu()
+ new_user_data = Gtk.Menu()
group.set_submenu(new_user_data)
else:
new_user_data = self.radioMenu
@@ -168,11 +168,11 @@ class SysTrayGui:
def bookmark_callback(self, radio_name, user_data):
if radio_name.startswith("[separator-"):
- separator = gtk.MenuItem()
+ separator = Gtk.MenuItem()
user_data.append(separator)
separator.show()
else:
- radio = gtk.MenuItem(radio_name, False)
+ radio = Gtk.MenuItem(radio_name)
radio.show()
radio.connect('activate', self.handler.on_start, radio_name)
user_data.append(radio)
Index: src/XmlDataProvider.py
===================================================================
--- src/XmlDataProvider.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ src/XmlDataProvider.py 2016-05-07 17:25:23.258886108 +0200
@@ -20,7 +20,7 @@
##########################################################################
import os
from lxml import etree
-import gtk
+from gi.repository import Gtk
import logging
class XmlDataProvider:
@@ -317,13 +317,13 @@ class XmlDataProvider:
index = itemTarget.getparent().index(itemTarget)
- if (position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER):
+ if (position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or position == Gtk.TreeViewDropPosition.INTO_OR_AFTER):
itemTarget.append(itemToMove)
- elif position == gtk.TREE_VIEW_DROP_BEFORE:
+ elif position == Gtk.TreeViewDropPosition.BEFORE:
itemTarget.getparent().insert(index, itemToMove)
- elif position == gtk.TREE_VIEW_DROP_AFTER:
+ elif position == Gtk.TreeViewDropPosition.AFTER:
itemTarget.getparent().insert(index+1, itemToMove)
self.log.debug('%s moved with success', str(source))
Index: src/about.py
===================================================================
--- src/about.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ src/about.py 2016-05-07 17:25:23.258886108 +0200
@@ -1,29 +1,29 @@
# -*- coding: utf-8 -*-
-import gtk
+from gi.repository import Gtk, GObject, Gdk, GdkPixbuf
from lib import i18n
import lib.common as common
def on_email(about, mail):
- gtk.show_uri(gtk.gdk.Screen(), "mailto:%s" % mail, 0L)
+ Gtk.show_uri(Gdk.Screen(), "mailto:%s" % mail, 0L)
def on_url(about, link):
- gtk.show_uri(gtk.gdk.Screen(), link, 0L)
+ Gtk.show_uri(Gdk.Screen(), link, 0L)
-gtk.about_dialog_set_email_hook(on_email)
-gtk.about_dialog_set_url_hook(on_url)
+#Gtk.about_dialog_set_email_hook(on_email)
+#Gtk.about_dialog_set_url_hook(on_url)
TRANSLATORS = _("translator-credits")
-class AboutDialog(gtk.AboutDialog):
+class AboutDialog(Gtk.AboutDialog):
def __init__(self, parent = None):
- gtk.AboutDialog.__init__(self)
+ GObject.GObject.__init__(self)
self.set_icon_from_file(common.APP_ICON)
self.set_name(common.APPNAME)
self.set_version(common.APPVERSION)
self.set_copyright(common.COPYRIGHTS)
- self.set_logo(gtk.gdk.pixbuf_new_from_file(common.APP_ICON))
+ self.set_logo(GdkPixbuf.Pixbuf.new_from_file(common.APP_ICON))
self.set_translator_credits(TRANSLATORS)
self.set_license(common.LICENSE)
self.set_website(common.WEBSITE)
Index: src/lib/i18n.py
===================================================================
--- src/lib/i18n.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ src/lib/i18n.py 2016-05-07 17:25:23.258886108 +0200
@@ -12,7 +12,8 @@ try:
from gettext import gettext as _, ngettext
gettext.install(program, unicode=True)
gettext.textdomain(program)
- locale.textdomain(program)
+ if hasattr(locale, 'textdomain'):
+ locale.textdomain(program)
def C_(ctx, s):
"""Provide qualified translatable strings via context.
Index: src/lib/utils.py
===================================================================
--- src/lib/utils.py.orig 2016-05-07 17:25:19.938842174 +0200
+++ src/lib/utils.py 2016-05-07 17:25:23.258886108 +0200
@@ -20,15 +20,15 @@
from os.path import exists, join
try:
- import pygtk
- pygtk.require("2.0")
+ import gi
+ gi.require_version("Gtk", "3.0")
import dbus
import dbus.service
except:
pass
try:
- import gtk
+ from gi.repository import Gtk
except ImportError, e:
print str(e)
raise SystemExit
@@ -36,7 +36,7 @@ except ImportError, e:
def load_ui_file(name):
import common
- ui = gtk.Builder()
+ ui = Gtk.Builder()
ui.add_from_file(join(common.DEFAULT_CFG_PATH, name))
return ui
Index: src/radiotray.py
===================================================================
--- src/radiotray.py 2016-05-07 17:25:19.938842174 +0200
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import dbus
-import sys, os, string
-from RadioTray import RadioTray
-from dbus import DBusException
-from dbus.mainloop.glib import threads_init
-
-threads_init()
-current_path = os.path.realpath(__file__)
-basedir = os.path.dirname(os.path.realpath(__file__))
-if not os.path.exists(os.path.join(basedir, "radiotray.py")):
- if os.path.exists(os.path.join(os.getcwd(), "radiotray.py")):
- basedir = os.getcwd()
-sys.path.insert(0, basedir)
-os.chdir(basedir)
-
-def main(argv):
- if(len(argv) == 1):
- print "Trying to load URL: " + argv[0]
-
- try:
- bus = dbus.SessionBus()
- radiotray = bus.get_object('net.sourceforge.radiotray', '/net/sourceforge/radiotray')
-
-
- if argv[0] == '--config':
- print "Radio Tray already running."
- else:
- print "Setting current radio through DBus..."
-
- playUrl = radiotray.get_dbus_method('playUrl', 'net.sourceforge.radiotray')
- playUrl(argv[0])
-
- except DBusException:
- RadioTray(argv[0])
- else:
- RadioTray()
-
-if __name__ == "__main__":
- main(sys.argv[1:])
Index: src/radiotray_runner.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ src/radiotray_runner.py 2016-05-07 17:25:23.258886108 +0200
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import dbus
+import sys, os, string
+from RadioTray import RadioTray
+from dbus import DBusException
+from dbus.mainloop.glib import threads_init
+
+threads_init()
+current_path = os.path.realpath(__file__)
+basedir = os.path.dirname(os.path.realpath(__file__))
+if not os.path.exists(os.path.join(basedir, "radiotray.py")):
+ if os.path.exists(os.path.join(os.getcwd(), "radiotray.py")):
+ basedir = os.getcwd()
+sys.path.insert(0, basedir)
+os.chdir(basedir)
+
+def main(argv):
+ if(len(argv) == 1):
+ print "Trying to load URL: " + argv[0]
+
+ try:
+ bus = dbus.SessionBus()
+ radiotray = bus.get_object('net.sourceforge.radiotray', '/net/sourceforge/radiotray')
+
+
+ if argv[0] == '--config':
+ print "Radio Tray already running."
+ else:
+ print "Setting current radio through DBus..."
+
+ playUrl = radiotray.get_dbus_method('playUrl', 'net.sourceforge.radiotray')
+ playUrl(argv[0])
+
+ except DBusException:
+ RadioTray(argv[0])
+ else:
+ RadioTray()
+
+if __name__ == "__main__":
+ main(sys.argv[1:])