diff options
author | Jonathon Fernyhough | 2017-07-05 20:13:26 +0100 |
---|---|---|
committer | Jonathon Fernyhough | 2017-07-05 20:18:41 +0100 |
commit | 3c9c7800ce3f679629c4bcb7ad9e9ce4e1eabba3 (patch) | |
tree | c27f2c0fd5ec0ae2ec49999ccfb4de09356a2393 /03_upstream_repo.patch | |
parent | 5cbd981499397a21b36e7e64165b1b25e5f1c061 (diff) | |
download | aur-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.patch | 1880 |
1 files changed, 1880 insertions, 0 deletions
diff --git a/03_upstream_repo.patch b/03_upstream_repo.patch new file mode 100644 index 000000000000..9e822e99d9cb --- /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:]) |