from gi.repository import Gtk
from gi.repository import Gio
import sys
import os
import urllib.parse
import shlex, subprocess
import time
class VentanaPrincipal(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Putty Tray")
self.set_border_width(10)
self.set_default_size(800, 600)
self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.add(self.vbox)
self.stack = Gtk.Stack()
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
self.stack.set_transition_duration(1000)
self.stack_switcher = Gtk.StackSwitcher()
self.stack_switcher.set_stack(self.stack)
self.vbox.pack_start(self.stack_switcher, False, True, 0)
self.vbox.pack_start(self.stack, True, True, 0)
def plug_event(self, garb):
print("Un putty fue insertado")
def addPutty(self, pid, session):
print("Putty window_id: " + str(pid))
socket = Gtk.Socket()
socket.connect("plug-added", self.plug_event)
self.stack.add_titled(socket, session, session)
socket.add_id(pid)
#self.stack.grab_focus()
#self.get_toplevel().child_focus(Gtk.DIR_TAB_FORWARD)
socket.grab_focus()
self.show_all()
socket.grab_focus()
class IconoTray:
pids = []
def __init__(self, iconname):
self.menu = Gtk.Menu()
APPIND_SUPPORT = 1
try: from gi.repository import AppIndicator3
except: APPIND_SUPPORT = 0
if APPIND_SUPPORT == 1:
self.ind = AppIndicator3.Indicator.new("putty", iconname, AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
self.ind.set_status (AppIndicator3.IndicatorStatus.ACTIVE)
self.ind.set_menu(self.menu)
else:
self.myStatusIcon = Gtk.StatusIcon()
self.myStatusIcon.set_from_icon_name(iconname)
self.myStatusIcon.connect('popup-menu', self.right_click_event_statusicon)
def add_seperator(self):
aMenuitem = Gtk.SeparatorMenuItem()
self.menu.append(aMenuitem)
self.menu.show_all()
def get_tray_menu(self):
return self.menu
def right_click_event_statusicon(self, icon, button, time):
self.get_tray_menu()
def pos(menu, aicon):
return (Gtk.StatusIcon.position_menu(menu, aicon))
self.menu.popup(None, None, pos, icon, button, time)
def display_message_dialog(self, message_type):
messagedialog = Gtk.MessageDialog(message_format="MessageDialog")
messagedialog.set_property("message-type", message_type)
messagedialog.run()
messagedialog.destroy()
def add_menu_item(self, command, title, session=""):
aMenuitem = Gtk.MenuItem()
aMenuitem.set_label(title)
aMenuitem.connect("activate", command, session)
self.menu.append(aMenuitem)
self.menu.show_all()
def add_menu_item_s(self, command, title, session=""):
aMenuitem = Gtk.MenuItem()
aMenuitem.set_label(title)
aMenuitem.connect("activate", command,session)
self.menu_sessions.append(aMenuitem)
self.menu_sessions.show_all()
self.menu.show_all()
def addpid(self, par, p_session):
aMenuitem = Gtk.MenuItem()
aMenuitem.set_label(par)
#aMenuitem.connect("activate", command, session)
self.menu.append(aMenuitem)
self.menu.show_all()
def children_pid(self, ppid):
"""get the list of the children pids of a pid (linux only)"""
import subprocess as SP
print("Parent PID: "+str(ppid))
proc = SP.Popen('ps -o pid,ppid ax | grep "'+str(ppid)+'"', shell=True, stdout=SP.PIPE)
pidppid = [x.split() for x in proc.communicate()[0].split(b"\n") if x]
return list(int(p) for p, pp in pidppid if int(pp) == ppid)
def new_session(self, par, p_session):
if len(self.pids) < 1:
self.appmain = VentanaPrincipal()
self.appmain.show_all()
p = subprocess.Popen('/usr/bin/putty -load '+ p_session, shell=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
childrenpid=self.children_pid(p.pid)
print(childrenpid[0])
self.pids.append(childrenpid)
#Relacionar PID con el window_id
#xwininfo -tree -root | grep -i putty -> All_Windows_ID
#xprop -id Windows_ID[i] | grep _NET_WM_PID(CARDINAL)
#_NET_WM_PID(CARDINAL) = 21151
#shell(./find_windows.sh PID)
print ("PID: " + str(childrenpid[0]))
time.sleep(1)
proc = subprocess.Popen("/home/roberto/Projects/puttytray/find_windows.sh "+ str(childrenpid[0]), shell=True, stdout=subprocess.PIPE)
proc.wait()
for line in proc.stdout:
#the real code does filtering here
print (b"test:" + line.rstrip())
win_id_hex=line.strip()
#win_id_hex=os.popen("/home/robeto/Projects/puttytray/find_windows.sh "+ str(childrenpid)).read()
win_id = int(win_id_hex, 0)
print("WIN_ID: " + str(win_id))
self.appmain.addPutty(win_id, p_session)
self.add_menu_item( self.addpid, str(p.pid), "\""+p_session+"\"")
def add_menu_sessions(self):
self.menu_sessions = Gtk.Menu()
submenuitem = Gtk.MenuItem(label="Sessiones")
submenuitem.set_submenu(self.menu_sessions)
self.menu.append(submenuitem)
def quit(self, par, p_session):
Gtk.main_quit()
#test/debug stuff below here
def main():
app = IconoTray("putty") #rhythmbox
app.add_menu_sessions()
dirputty = "/home/roberto/.putty/sessions"
onlyfiles = [f for f in os.listdir(dirputty) if os.path.isfile(os.path.join(dirputty, f))]
for filessessionhtml in onlyfiles:
filessession = urllib.parse.unquote(filessessionhtml)
app.add_menu_item_s( app.new_session, filessession, "\""+filessession+"\"")
#app.add_menu_item_s( app.new_session, filessession, filessession)
app.add_seperator()
app.add_menu_item( app.quit, "Salir", "Salir")
if __name__ == '__main__':
Gtk.main()
main()