summarylogtreecommitdiffstats
path: root/03_upstream_repo.patch
diff options
context:
space:
mode:
authorJonathon Fernyhough2017-07-05 20:13:26 +0100
committerJonathon Fernyhough2017-07-05 20:18:41 +0100
commit3c9c7800ce3f679629c4bcb7ad9e9ce4e1eabba3 (patch)
treec27f2c0fd5ec0ae2ec49999ccfb4de09356a2393 /03_upstream_repo.patch
parent5cbd981499397a21b36e7e64165b1b25e5f1c061 (diff)
downloadaur-3c9c7800ce3f679629c4bcb7ad9e9ce4e1eabba3.tar.gz
Massive overhaul for GStreamer 1.0 and GTK3.
Massive props to Debian maintainers - this PKGBUILD includes three patches lifted directly from the Debian package, with a small change to ensure python2 is used in radiotray_runner. I also switched from a source-based install to a bdist; this cuts the package size though it also means you can't link to radiotray any more (is that needed?).
Diffstat (limited to '03_upstream_repo.patch')
-rw-r--r--03_upstream_repo.patch1880
1 files changed, 1880 insertions, 0 deletions
diff --git a/03_upstream_repo.patch b/03_upstream_repo.patch
new file mode 100644
index 00000000000..9e822e99d9c
--- /dev/null
+++ b/03_upstream_repo.patch
@@ -0,0 +1,1880 @@
+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
+
+--- radiotray.orig/data/bookmarks.xml
++++ radiotray/data/bookmarks.xml
+@@ -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: radiotray/data/plugins/HelloWorldPlugin.py
+===================================================================
+--- radiotray.orig/data/plugins/HelloWorldPlugin.py
++++ radiotray/data/plugins/HelloWorldPlugin.py
+@@ -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: radiotray/data/plugins/HistoryPlugin.py
+===================================================================
+--- radiotray.orig/data/plugins/HistoryPlugin.py
++++ radiotray/data/plugins/HistoryPlugin.py
+@@ -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
+ from lib import utils
+ from lib.common import SYSTEM_PLUGIN_PATH, USER_PLUGIN_PATH
+ import os
+@@ -72,5 +72,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: radiotray/data/plugins/NotificationPlugin.py
+===================================================================
+--- radiotray.orig/data/plugins/NotificationPlugin.py
++++ radiotray/data/plugins/NotificationPlugin.py
+@@ -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: radiotray/data/plugins/SleepTimerPlugin.py
+===================================================================
+--- radiotray.orig/data/plugins/SleepTimerPlugin.py
++++ radiotray/data/plugins/SleepTimerPlugin.py
+@@ -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(), False)
+ 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: radiotray/data/plugins/StationSwitcher.plugin
+===================================================================
+--- /dev/null
++++ radiotray/data/plugins/StationSwitcher.plugin
+@@ -0,0 +1,6 @@
++[RadioTrayPlugin]
++name=StationSwitcher
++desc=Allows cycling through stations
++script=StationSwitcherPlugin.py
++class=StationSwitcherPlugin
++author=Mark F
+Index: radiotray/data/plugins/StationSwitcherPlugin.py
+===================================================================
+--- /dev/null
++++ radiotray/data/plugins/StationSwitcherPlugin.py
+@@ -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: radiotray/data/plugins/history.glade
+===================================================================
+--- radiotray.orig/data/plugins/history.glade
++++ radiotray/data/plugins/history.glade
+@@ -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
+===================================================================
+--- radiotray.orig/radiotray
++++ radiotray/radiotray
+@@ -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: radiotray/src/AppIndicatorGui.py
+===================================================================
+--- radiotray.orig/src/AppIndicatorGui.py
++++ radiotray/src/AppIndicatorGui.py
+@@ -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: radiotray/src/AudioPlayerGStreamer.py
+===================================================================
+--- radiotray.orig/src/AudioPlayerGStreamer.py
++++ radiotray/src/AudioPlayerGStreamer.py
+@@ -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: radiotray/src/BookmarkConfiguration.py
+===================================================================
+--- radiotray.orig/src/BookmarkConfiguration.py
++++ radiotray/src/BookmarkConfiguration.py
+@@ -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: radiotray/src/GuiChooserConfiguration.py
+===================================================================
+--- radiotray.orig/src/GuiChooserConfiguration.py
++++ radiotray/src/GuiChooserConfiguration.py
+@@ -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: radiotray/src/NotificationManager.py
+===================================================================
+--- radiotray.orig/src/NotificationManager.py
++++ radiotray/src/NotificationManager.py
+@@ -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: radiotray/src/Plugin.py
+===================================================================
+--- radiotray.orig/src/Plugin.py
++++ radiotray/src/Plugin.py
+@@ -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: radiotray/src/PluginConfiguration.py
+===================================================================
+--- radiotray.orig/src/PluginConfiguration.py
++++ radiotray/src/PluginConfiguration.py
+@@ -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: radiotray/src/RadioTray.py
+===================================================================
+--- radiotray.orig/src/RadioTray.py
++++ radiotray/src/RadioTray.py
+@@ -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: radiotray/src/SysTray.py
+===================================================================
+--- radiotray.orig/src/SysTray.py
++++ radiotray/src/SysTray.py
+@@ -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
+@@ -46,7 +48,6 @@ from SysTrayGui import SysTrayGui
+ from AppIndicatorGui import AppIndicatorGui
+ from TooltipManager import TooltipManager
+ from Context import Context
+-from glib import glib_version
+
+ import dbus
+ import textwrap
+@@ -96,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")
+@@ -114,7 +115,6 @@ class SysTray(object):
+
+
+
+-
+ if self.gui_engine == "appindicator":
+ self.app_indicator_enabled = True
+ else:
+@@ -138,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()
+@@ -155,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)
+@@ -183,13 +183,10 @@ class SysTray(object):
+
+
+ def run(self):
+- if glib_version < (2, 41, 0):
+- gtk.gdk.threads_init()
+- gtk.main()
++ Gdk.threads_init()
++ Gtk.main()
+
+
+-
+-
+
+ def reload_bookmarks(self, data):
+ self.provider.loadFromFile()
+Index: radiotray/src/SysTrayGui.py
+===================================================================
+--- radiotray.orig/src/SysTrayGui.py
++++ radiotray/src/SysTrayGui.py
+@@ -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"), False)
++ self.turnOnOff2 = Gtk.MenuItem(_("Turned Off"), False)
+ 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, False)
+ 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, False)
+ 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(Gtk.STOCK_ABOUT)
++ menu_item2 = Gtk.ImageMenuItem(Gtk.STOCK_QUIT)
+ 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", False)
++ 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.status_icon_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.status_icon_position_menu, 0, event.get_time(), widget)
+ 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.status_icon_position_menu, 2, event.get_time(), widget)
+
+
+ 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, False)
+ 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, False)
+ radio.show()
+ radio.connect('activate', self.handler.on_start, radio_name)
+ user_data.append(radio)
+Index: radiotray/src/XmlDataProvider.py
+===================================================================
+--- radiotray.orig/src/XmlDataProvider.py
++++ radiotray/src/XmlDataProvider.py
+@@ -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: radiotray/src/about.py
+===================================================================
+--- radiotray.orig/src/about.py
++++ radiotray/src/about.py
+@@ -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: radiotray/src/lib/i18n.py
+===================================================================
+--- radiotray.orig/src/lib/i18n.py
++++ radiotray/src/lib/i18n.py
+@@ -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: radiotray/src/lib/utils.py
+===================================================================
+--- radiotray.orig/src/lib/utils.py
++++ radiotray/src/lib/utils.py
+@@ -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: radiotray/src/radiotray.py
+===================================================================
+--- radiotray.orig/src/radiotray.py
++++ /dev/null
+@@ -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: radiotray/src/radiotray_runner.py
+===================================================================
+--- /dev/null
++++ radiotray/src/radiotray_runner.py
+@@ -0,0 +1,42 @@
++#!/usr/bin/env python2
++# -*- 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:])