summaryrefslogtreecommitdiff
path: root/tcosmonitor/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'tcosmonitor/extensions')
-rw-r--r--tcosmonitor/extensions/Makefile15
-rw-r--r--tcosmonitor/extensions/__init__.py47
-rw-r--r--tcosmonitor/extensions/appsmsg.py373
-rw-r--r--tcosmonitor/extensions/audiortp.py542
-rw-r--r--tcosmonitor/extensions/clean.py58
-rw-r--r--tcosmonitor/extensions/dpms.py98
-rw-r--r--tcosmonitor/extensions/info.py616
-rw-r--r--tcosmonitor/extensions/italc.py88
-rw-r--r--tcosmonitor/extensions/livevnc.py220
-rw-r--r--tcosmonitor/extensions/lockscreen.py100
-rw-r--r--tcosmonitor/extensions/logout.py94
-rw-r--r--tcosmonitor/extensions/reboot.py120
-rw-r--r--tcosmonitor/extensions/remotessh.py57
-rw-r--r--tcosmonitor/extensions/restartxorg.py194
-rw-r--r--tcosmonitor/extensions/screenshot.py225
-rw-r--r--tcosmonitor/extensions/sendfiles.py275
-rw-r--r--tcosmonitor/extensions/tcosnetcontroller.py188
-rw-r--r--tcosmonitor/extensions/tcospersonalize.py61
-rw-r--r--tcosmonitor/extensions/videolan.py648
-rw-r--r--tcosmonitor/extensions/viewproc.py139
-rw-r--r--tcosmonitor/extensions/vnc.py513
-rw-r--r--tcosmonitor/extensions/wakeonlan.py100
22 files changed, 4771 insertions, 0 deletions
diff --git a/tcosmonitor/extensions/Makefile b/tcosmonitor/extensions/Makefile
new file mode 100644
index 0000000..e3820c9
--- /dev/null
+++ b/tcosmonitor/extensions/Makefile
@@ -0,0 +1,15 @@
+all:
+ #none
+
+include ../../common.mk
+
+
+clean:
+ rm -f *~ *.pyc
+
+install:
+ install -d $(DESTDIR)/$(PREFIX)/share/$(PACKAGE)/extensions
+ @for ext in $(shell ls *.py |grep -v template); do \
+ echo "install -m 644 $$ext $(DESTDIR)/$(PREFIX)/share/$(PACKAGE)/extensions" ; \
+ install -m 644 $$ext $(DESTDIR)/$(PREFIX)/share/$(PACKAGE)/extensions ; \
+ done
diff --git a/tcosmonitor/extensions/__init__.py b/tcosmonitor/extensions/__init__.py
new file mode 100644
index 0000000..6285c3e
--- /dev/null
+++ b/tcosmonitor/extensions/__init__.py
@@ -0,0 +1,47 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+import glob as __glob__
+import os as __os__
+import sys as __sys__
+
+def __load__():
+ """
+ read contents of extensions dir and put in __all__ list
+ """
+ _ext_dir=__os__.path.dirname( __file__ )
+ _ext=[]
+ for file_ in __glob__.glob(_ext_dir+"/*.py"):
+ if file_ == "__init__.py":
+ continue
+ _ext_name = __os__.path.basename(file_).split('.py')[0]
+ if _ext_name == "__init__":
+ continue
+ _ext.append( _ext_name )
+ try:
+ if __sys__.version_info[0:3] < (2, 5, 0):
+ __import__('tcosmonitor.extensions.' + _ext_name, globals(), locals(), ['extensions'] )
+ else:
+ __import__('tcosmonitor.extensions.' + _ext_name, fromlist = ['extensions'] )
+ except Exception, err:
+ print ("Exception importing extension='%s', err='%s'"%(_ext_name, err))
+ return _ext
+
+__all__=__load__()
diff --git a/tcosmonitor/extensions/appsmsg.py b/tcosmonitor/extensions/appsmsg.py
new file mode 100644
index 0000000..88e34bd
--- /dev/null
+++ b/tcosmonitor/extensions/appsmsg.py
@@ -0,0 +1,373 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+import gtk
+from time import time
+import os
+import sys
+import glob
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+def crono(start, txt):
+ print_debug ("crono(), %s get %f seconds" %(txt, (time() - start)) )
+ return
+
+class AppsAndMsgs(TcosExtension):
+ def register(self):
+ self.init_ask()
+ self.main.classview.class_external_exe=self.exe_app_external
+ self.main.actions.button_action_exe=self.exe_app_all
+ self.main.actions.button_action_text=self.send_msg_all
+
+ self.main.menus.register_simple( _("Exec app on user display") , "menu_exec.png", 1, self.exe_app, "exe")
+ self.main.menus.register_simple( _("Send a text message to user") , "menu_msg.png", 1, self.send_msg, "text")
+
+ self.main.menus.register_all( _("Exec same app in all connected users") , "menu_exec.png", 1, self.exe_app_all, "exe")
+ self.main.menus.register_all( _("Send a text message to all connected users") , "menu_msg.png", 1, self.send_msg_all, "text")
+
+##############################################################################
+ def askfor(self, mode="mess", msg="", users=None, users_txt=None):
+ if users == None or users_txt == None:
+ users=[]
+ self.ask_usernames=[]
+ if len(users) == 0 or users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("Clients not connected") )
+ return
+ else:
+ self.ask_usernames=users
+
+ #users_txt=""
+ #counter=1
+ #for user in self.ask_usernames:
+ # users_txt+="%s, " %(user)
+ # print_debug("askfor() counter=%s" %(counter) )
+ # if counter % 4 == 0:
+ # users_txt+="\n"
+ # counter=int(counter+1)
+
+ #if users_txt[-2:] == "\n": users_txt=users_txt[:-2]
+ #if users_txt[-2:] == ", ": users_txt=users_txt[:-2]
+
+ if mode == "exec":
+ # enable drag & drop
+ self.main.ask_fixed.show()
+ self.main.ask_dragdrop.show()
+ self.main.image_entry.show()
+ self.main.image_entry.set_from_stock(gtk.STOCK_DIALOG_QUESTION, 4)
+ self.main.ask_label.set_markup( _("<b>Exec app in user(s) screen(s)\nor open web address to:</b>\n%s" ) %( users_txt ) )
+ elif mode == "mess":
+ self.main.ask_label.set_markup( _("<b>Send a message to:</b>\n%s" ) %( users_txt ) )
+ elif mode == "any":
+ self.main.ask_label.set_markup( msg )
+ self.ask_mode=mode
+ self.main.ask.show()
+ return True
+
+
+ def on_ask_exec_click(self, widget):
+ app=self.main.ask_entry.get_text()
+ if app != "":
+ self.exe_app_in_client_display(app)
+ return
+
+
+ def on_ask_cancel_click(self, widget):
+ self.main.ask.hide()
+ self.main.ask_entry.set_text("")
+ # disable drag & drop
+ self.main.ask_fixed.hide()
+ self.main.image_entry.hide()
+ self.main.ask_dragdrop.hide()
+ return
+##############################################################################
+
+ def exe_app_external(self, filename=None, txt=None):
+ if self.main.classview.ismultiple() or txt != None:
+ if not self.get_all_clients():
+ return
+ elif not self.get_client():
+ return
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't exec application, user is not logged") )
+ return
+ #print_debug("user=%s data=%s" %(self.connected_users, data)
+ app=""
+ self.ask_usernames=self.connected_users
+ self.ask_mode="exec"
+
+ if txt != None:
+ app="x-www-browser %s" %txt
+ self.exe_app_in_client_display(app)
+ return
+
+ print_debug("open_file() reading data from \"%s\"..." \
+ %(filename) )
+ try:
+ fd=file(filename, 'r')
+ data=fd.readlines()
+ fd.close()
+ except Exception, err:
+ shared.error_msg( _("%s is not a valid application") %(os.path.basename(filename)) )
+ return
+
+ for line in data:
+ if line != '\n':
+ if line.startswith("Exec="):
+ line=line.replace('\n', '')
+ action, app=line.split("=",1)
+ app=app.replace("%U","").replace("%u","").replace("%F","").replace("%f","").replace("%c","").replace("%i","").replace("%m","")
+
+ if len(app) <1:
+ shared.error_msg( _("%s is not a valid application") %(os.path.basename(filename)) )
+
+ if app != "":
+ self.exe_app_in_client_display(app)
+ return
+
+
+ def exe_app(self, w, ip):
+ if not self.get_client():
+ return
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't exec application, user is not logged") )
+ return
+ self.askfor(mode="exec", users=self.connected_users, users_txt=self.connected_users_txt)
+
+
+ def send_msg(self, w, ip):
+ if not self.get_client():
+ return
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't send message, user is not logged") )
+ return
+ self.askfor(mode="mess", users=self.connected_users, users_txt=self.connected_users_txt)
+
+ def exe_app_all(self, *args):
+ if not self.get_all_clients():
+ return
+ self.askfor(mode="exec", users=self.connected_users, users_txt=self.connected_users_txt)
+
+ def send_msg_all(self, *args):
+ if not self.get_all_clients():
+ return
+ self.askfor(mode="mess", users=self.connected_users, users_txt=self.connected_users_txt)
+
+
+####################### INIT ############################################
+ def init_ask(self):
+ self.main.ask_ip=None
+
+ self.ui = gtk.Builder()
+ self.ui.set_translation_domain(shared.PACKAGE)
+ self.ui.add_from_file(shared.GLADE_DIR + 'tcosmonitor-askwindow.ui')
+
+ self.main.ask = self.ui.get_object('askwindow')
+ self.main.ask.connect('delete-event', self.askwindow_close )
+ self.main.ask.set_icon_from_file(shared.IMG_DIR +'tcos-icon-32x32.png')
+
+
+ self.main.ask_label = self.ui.get_object('txt_asklabel')
+ ## arrastrar y soltar
+ self.main.ask_fixed = self.ui.get_object('ask_fixed')
+ self.main.ask_dragdrop = self.ui.get_object('label99')
+ self.main.image_entry = self.ui.get_object('image_askentry')
+ self.main.image_entry.drag_dest_set( gtk.DEST_DEFAULT_ALL, [( 'text/uri-list', 0, 2 ), ], gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_COPY)
+ self.main.image_entry.connect( 'drag_data_received', self.on_drag_data_received)
+ self.main.ask_fixed.hide()
+ self.main.image_entry.hide()
+ self.main.ask_dragdrop.hide()
+ ## fin arrastrar y soltar
+ self.liststore = gtk.ListStore(str)
+ for s in shared.appslist:
+ self.liststore.append([s])
+
+ self.main.ask_entry = self.ui.get_object('txt_askentry')
+ self.main.ask_completion = gtk.EntryCompletion()
+ self.main.ask_completion.set_model(self.liststore)
+ self.main.ask_entry.set_completion(self.main.ask_completion)
+ self.main.ask_completion.set_text_column(0)
+
+ self.main.ask_completion.connect('match-selected', self.match_cb)
+ self.main.ask_entry.connect('activate', self.activate_cb)
+
+ self.main.ask_cancel = self.ui.get_object('ask_cancelbutton')
+ self.main.ask_exec = self.ui.get_object('ask_exebutton')
+
+ # buttons signals
+ self.main.ask_exec.connect('clicked', self.on_ask_exec_click)
+ self.main.ask_cancel.connect('clicked', self.on_ask_cancel_click)
+
+
+ def askwindow_close(self, widget, event):
+ print_debug ( "askwindow_close() closing ask window" )
+ self.main.ask.hide()
+ return True
+
+ def on_drag_data_received( self, widget, context, x, y, selection, targetType, dtime):
+ files = selection.data.split('\n', 1)
+ start1=time()
+ print_debug("on_drag_data_received() files=%s dtime=%s"%(files, dtime))
+ for f in files:
+ if f:
+ desktop = f.strip().replace('%20', ' ')
+ break
+
+ if desktop.startswith('file:///') and desktop.lower().endswith('.desktop') and os.path.isfile(desktop[7:]):
+ print_debug("open_file() reading data from \"%s\"..." \
+ %(desktop[7:]) )
+ fd=file(desktop[7:], 'r')
+ data=fd.readlines()
+ fd.close()
+
+ # try to load gnome theme with gconf
+ mytheme=[]
+ theme=self.main.common.get_icon_theme()
+ print_debug("on_drag_data_received() gconf theme=%s"%theme)
+
+ str_image=""
+ files=[]
+
+ if theme and os.path.isdir("/usr/share/icons/%s"%theme):
+ files+=glob.glob("/usr/share/icons/%s/48x48/*.png"%(theme))
+
+ files+=glob.glob("/usr/share/icons/hicolor/48x48/*/*.png") + \
+ glob.glob("/usr/share/icons/gnome/48x48/*/*.png") + \
+ glob.glob("/usr/share/pixmaps/*png") +\
+ glob.glob("/usr/share/pixmaps/*xpm")
+
+ for line in data:
+ if line != '\n':
+ if line.startswith("Exec="):
+ line=line.replace('\n', '')
+ action, str_exec=line.split("=",1)
+ str_exec=str_exec.replace("%U","").replace("%u","").replace("%F","").replace("%f","").replace("%c","").replace("%i","").replace("%m","")
+ elif line.startswith("Icon="):
+ line=line.replace('\n', '')
+ action, image_name=line.split("=",1)
+ if not os.path.isfile(image_name):
+ start2=time()
+ for f in files:
+ if image_name in f or image_name.replace('_', '-') in f:
+ str_image=f
+ crono(start2, "on_drag_data_received() ICON FOUND AT %s"%f )
+ break
+ else:
+ str_image=image_name
+
+ if len(str_exec) <1:
+ shared.error_msg( _("%s is not application") %(os.path.basename(desktop[7:])) )
+ else:
+ if len(str_image) <1:
+ print_debug("on_drag_data_received() image '%s' not found"%image_name)
+ self.main.image_entry.set_from_stock(gtk.STOCK_DIALOG_QUESTION, 4)
+ else:
+ self.main.image_entry.set_from_file(str_image)
+ self.main.ask_entry.set_text(str_exec)
+ else:
+ shared.error_msg( _("%s is not application") %(os.path.basename(desktop[7:])) )
+ crono(start1, "on_drag_data_received() end" )
+ return True
+
+ def match_cb(self, completion, model, iter):
+ print_debug ( "match_cb() " )
+ print_debug( "%s was selected" %(model[iter][0]) )
+ self.exe_app_in_client_display(model[iter][0])
+ return
+
+
+ def activate_cb(self, entry):
+ text = self.main.ask_entry.get_text()
+ print_debug ( "activate_cb() text=%s" %(text) )
+
+ # append to liststore
+ if text:
+ if text not in [row[0] for row in self.liststore]:
+ self.liststore.append([text])
+ #self.main.ask_entry.set_text('')
+
+ # exe app
+ self.exe_app_in_client_display(text)
+ return
+
+ def exe_app_in_client_display(self, arg):
+ usernames=self.ask_usernames
+ newusernames=[]
+ print_debug("exe_app_in_client_display() usernames=%s" %usernames)
+
+ if arg.startswith('rm ') or arg.find(" rm ") != -1 \
+ or arg.startswith('mv ') or arg.find(" mv ") != -1 \
+ or arg.startswith('cp ') or arg.find(" cp ") != -1:
+ arg=""
+
+ #if self.ask_mode == "mess":
+ # arg=arg.replace("'", "´")
+ if self.ask_mode == "exec":
+ if arg.startswith('http://') or arg.startswith('https://') or arg.startswith('ftp://'):
+ arg="xdg-open %s" %arg
+
+ for user in usernames:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ print_debug("exe_app_in_client_display() STANDALONE username=%s ip=%s" %(usern, ip))
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus(self.ask_mode, arg)
+ else:
+ newusernames.append(user)
+
+ # we have a thin client user
+ if self.ask_mode == "exec":
+ result = self.main.dbus_action.do_exec( newusernames , arg )
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason: %s") %( self.main.dbus_action.get_error_msg() ) )
+ else:
+ self.main.ask.hide()
+ self.main.ask_entry.set_text("")
+ elif self.ask_mode == "mess":
+ result = self.main.dbus_action.do_message( newusernames , arg)
+ if not result:
+ shared.error_msg ( _("Error while send message:\nReason: %s") %( self.main.dbus_action.get_error_msg() ) )
+ self.main.ask_dragdrop.hide()
+ self.main.ask_fixed.hide()
+ self.main.image_entry.hide()
+ self.main.ask.hide()
+ self.main.ask_entry.set_text("")
+ dbus_action=None
+ self.ask_mode=None
+ return
+
+__extclass__=AppsAndMsgs
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/audiortp.py b/tcosmonitor/extensions/audiortp.py
new file mode 100644
index 0000000..3914ae3
--- /dev/null
+++ b/tcosmonitor/extensions/audiortp.py
@@ -0,0 +1,542 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import gtk
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+COL_N, COL_ACTIVE,COL_B,COL_BOOL= range(4)
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class AudioRTP(TcosExtension):
+ def register(self):
+ self.rtp_count={}
+ self.rtp_control_count={}
+ self.control_list=False
+ self.init_chat()
+ self.main.actions.button_action_audio=self.rtp_all
+ self.main.actions.button_action_chat=self.rtp_chat
+ self.main.actions.button_action_list=self.control_chat
+
+ self.main.menus.register_all( _("Send audio conference") , "menu_rtp.png", 2, self.rtp_all, "conference")
+ self.main.menus.register_all( _("Audio chat conference") , "menu_chat.png", 2, self.rtp_chat, "conference")
+ self.main.menus.register_all( _("Audio chat list") , "menu_list.png", 2, self.control_chat, "conference")
+ self.main.menus.register_simple( _("Send audio conference (from this host)") , "menu_rtp.png", 2, self.rtp_simple, "conference")
+
+
+ def init_chat(self):
+ print_debug ("init chat control")
+ self.selected_emission=None
+
+ self.model=gtk.ListStore(str, gtk.gdk.Pixbuf, str, 'gboolean')
+
+ self.ui = gtk.Builder()
+ self.ui.set_translation_domain(shared.PACKAGE)
+
+ self.ui.add_from_file(shared.GLADE_DIR + 'tcosmonitor-chatwindow.ui')
+
+ self.main.chatwindow=self.ui.get_object('chatwindow')
+ self.main.chatwindow.connect('delete-event', self.chat_exit )
+
+ self.main.chatlist = self.ui.get_object('chatlist')
+ self.main.chatlist.set_model (self.model)
+
+ cell1 = gtk.CellRendererText ()
+ column1 = gtk.TreeViewColumn (_("Emission"), cell1, text = COL_N)
+ column1.set_resizable (True)
+ column1.set_sort_column_id(COL_N)
+ self.main.chatlist.append_column (column1)
+
+ cell2 = gtk.CellRendererPixbuf()
+ column2 = gtk.TreeViewColumn (_("State"), cell2, pixbuf = COL_ACTIVE)
+ self.main.chatlist.append_column (column2)
+
+ cell3 = gtk.CellRendererText ()
+ column3 = gtk.TreeViewColumn (_("Channel"), cell3, text = COL_B)
+ column3.set_resizable (True)
+ column3.set_sort_column_id(COL_B)
+ self.main.chatlist.append_column (column3)
+
+ self.table_file = self.main.chatlist.get_selection()
+ self.table_file.connect("changed", self.on_chat_list_change)
+
+ self.main.chat_button_disconnect=self.ui.get_object('button_chat_disconnect')
+ self.main.chat_button_disconnect.connect('clicked', self.chat_disconnect)
+
+ self.main.chat_button_connect=self.ui.get_object('button_chat_connect')
+ self.main.chat_button_connect.connect('clicked', self.chat_connect)
+
+ self.main.chat_button_exit=self.ui.get_object('button_exit')
+ self.main.chat_button_exit.connect('clicked', self.chat_exit)
+
+ self.main.chat_button_disconnect.set_sensitive(False)
+ self.main.chat_button_connect.set_sensitive(False)
+
+ self.main.chatwindow.hide()
+
+ def control_chat(self, *args):
+ #if len(self.rtp_count) < 1:
+ # shared.info_msg( _("No active chats to manage") )
+ # return
+
+ self.populate_data(self.rtp_count)
+ self.main.chatwindow.show()
+ self.control_list=True
+
+ def populate_data(self, data):
+ self.image_noactive = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'no.png')
+ self.image_active = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'ok.png')
+
+ for item in data:
+ if data[item] not in self.rtp_control_count.keys():
+ continue
+ self.new_line=True
+ model=self.main.chatlist.get_model()
+ model.foreach(self.line_exists, data[item])
+
+ if self.new_line:
+ self.iter = self.model.append (None)
+ name="Chat %s" %item
+ self.model.set_value (self.iter, COL_N, name )
+ self.model.set_value (self.iter, COL_B, data[item] )
+ if len(self.rtp_control_count[data[item]]) < 1:
+ self.model.set_value (self.iter, COL_ACTIVE, self.image_noactive )
+ self.model.set_value (self.iter, COL_BOOL, False )
+
+ else:
+ self.model.set_value (self.iter, COL_ACTIVE, self.image_active )
+ self.model.set_value (self.iter, COL_BOOL, True )
+
+ def control_buttons(self, active):
+ if active:
+ self.main.chat_button_disconnect.set_sensitive(True)
+ self.main.chat_button_connect.set_sensitive(False)
+ else:
+ self.main.chat_button_disconnect.set_sensitive(False)
+ self.main.chat_button_connect.set_sensitive(True)
+
+ def on_chat_list_change (self, data):
+ (model, iter) = self.main.chatlist.get_selection().get_selected()
+ if not iter:
+ self.control_buttons(False)
+ return
+ self.selected_num=model.get_value(iter,0)
+ self.selected_channel=model.get_value(iter, 2)
+ self.connected_rtp=model.get_value(iter, 3)
+ print_debug("selected_num=%s selected_channel=%s connected=%s" %(self.selected_num, self.selected_channel, self.connected_rtp))
+ if self.connected_rtp:
+ self.control_buttons(True)
+ else:
+ self.control_buttons(False)
+
+ def chat_disconnect(self, *args):
+ (model, iter) = self.main.chatlist.get_selection().get_selected()
+ if not iter:
+ self.control_buttons(False)
+ return
+ self.selected_channel=model.get_value(iter, 2)
+ self.main.common.exe_cmd("pactl unload-module %s" %self.rtp_control_count[self.selected_channel][0])
+ self.main.common.exe_cmd("pactl unload-module %s" %self.rtp_control_count[self.selected_channel][1])
+ self.rtp_control_count[self.selected_channel]=[]
+ print_debug("chat_connects %s" %self.rtp_control_count)
+ model.foreach(self.line_changer, [self.selected_channel, self.image_noactive, False])
+ self.main.chat_button_disconnect.set_sensitive(False)
+ self.main.chat_button_connect.set_sensitive(True)
+ return True
+
+ def chat_connect(self, *args):
+ (model, iter) = self.main.chatlist.get_selection().get_selected()
+ if not iter:
+ self.control_buttons(False)
+ return
+ self.selected_channel=model.get_value(iter, 2)
+ output_send = self.main.common.exe_cmd("pactl load-module module-rtp-send format=s16be channels=2 rate=44100 source=@DEFAULT_SOURCE@ loop=0 destination=%s" %self.selected_channel)
+ output_recv = self.main.common.exe_cmd("pactl load-module module-rtp-recv sap_address=%s" %self.selected_channel)
+ if output_send != "" or output_recv != "":
+ self.rtp_control_count[self.selected_channel]=[output_send, output_recv]
+ print_debug("chat_connects %s" %self.rtp_control_count)
+ model.foreach(self.line_changer, [self.selected_channel, self.image_active, True])
+ self.main.chat_button_disconnect.set_sensitive(True)
+ self.main.chat_button_connect.set_sensitive(False)
+ return True
+
+ def chat_exit(self, *args):
+ self.main.chatwindow.hide()
+ self.model.clear()
+ self.control_list=False
+ return True
+
+ def line_exists(self, model, path, iter, args):
+ ip = args
+ # change mac if ip is the same.
+ if model.get_value(iter, 2) == ip:
+ self.new_line=False
+
+ def line_changer(self, model, path, iter, args):
+ ip, image, active = args
+ # change mac if ip is the same.
+ if model.get_value(iter, 2) == ip:
+ model.set_value(iter, 1, image)
+ model.set_value(iter, 3, active)
+
+ def line_delete(self, model, path, iter, args):
+ ip = args
+ if model.get_value(iter, 2) == ip:
+ self.delete_iter=iter
+
+ def chat_delete(self, data):
+ print_debug("chat_delete() data=%s" %data)
+ model=self.main.chatlist.get_model()
+ self.delete_iter=None
+ model.foreach(self.line_delete, data)
+ # delete iter if found
+ if self.delete_iter is not None:
+ model.remove(self.delete_iter)
+
+ def rtp_all(self, *args):
+ if not self.get_all_clients():
+ return
+ # conference mode
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("No users logged.") )
+ return
+
+ cmd=("LC_ALL=C LC_MESSAGES=C pactl --version 2>/dev/null | awk '{print $2}' | awk -F\".\" '{if ((int($2) >= 9) && (int($3) >= 10)) printf 1}'")
+ output=self.main.common.exe_cmd(cmd)
+ if output != "1":
+ shared.error_msg( _("Your pulseaudio server is too old.\nIs required pulseaudio version >= 0.9.10") )
+ return
+
+ msg=_( _("Do you want to start audio conference to the following users: %s?" )%(self.connected_users_txt) )
+
+ if not shared.ask_msg ( msg ):
+ return
+
+ remote_msg=_("You have entered in audio conference")
+ eth=self.main.config.GetVar("network_interface")
+ max_uip=255
+ uip=0
+ while uip <= max_uip:
+ uip_cmd="225.0.0.%s" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0" and uip_cmd not in self.rtp_count.values():
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_broadcast="%s" %uip_cmd
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+ result = self.main.localdata.Route("route-add", ip_broadcast, "255.255.255.255", eth)
+ if result == "error":
+ print_debug("Add multicast-ip route failed")
+ return
+ self.main.common.exe_cmd("/usr/lib/tcos/pactl-controller.sh start-server")
+ output = self.main.common.exe_cmd("pactl load-module module-rtp-send format=s16be channels=2 rate=44100 source=@DEFAULT_SOURCE@ loop=0 destination=%s" %ip_broadcast)
+
+ self.main.write_into_statusbar( _("Waiting for start audio conference...") )
+
+ total=0
+ for client in self.newallclients:
+ self.main.xmlrpc.rtp("startrtp-recv", client, ip_broadcast )
+ total+=1
+
+ if total < 1:
+ self.main.write_into_statusbar( _("No users logged.") )
+ # kill x11vnc
+ self.main.common.exe_cmd("pactl unload-module %s" %output)
+ result = self.main.localdata.Route("route-del", ip_broadcast, "255.255.255.255", eth)
+ if result == "error":
+ print_debug("Del multicast-ip route failed")
+ if len(self.rtp_count.keys()) == 0:
+ self.main.common.exe_cmd("/usr/lib/tcos/pactl-controller.sh stop-server")
+ else:
+ newusernames=[]
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus("mess", remote_msg)
+ else:
+ newusernames.append(user)
+
+ self.main.dbus_action.do_message( newusernames, remote_msg )
+ self.main.write_into_statusbar( _("Running in audio conference with %s clients.") %(total) )
+ # new mode Stop Button
+ if len(self.rtp_count.keys()) != 0:
+ count=len(self.rtp_count.keys())-1
+ nextkey=self.rtp_count.keys()[count]+1
+ self.rtp_count[nextkey]=ip_broadcast
+ else:
+ nextkey=1
+ self.rtp_count[nextkey]=ip_broadcast
+ #self.main.menus.broadcast_count[ip_broadcast]=None
+ self.add_progressbox( {"target": "rtp", "pid":output, "allclients":self.newallclients, "ip":"", "ip_broadcast":ip_broadcast, "iface":eth, "key":nextkey}, _("Running in audio conference from server. Conference Nº %s") %(nextkey) )
+
+
+ def rtp_simple(self, widget, ip_simple):
+ if not self.get_client():
+ return
+
+ client_simple=self.connected_users_txt
+
+ # conference mode
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("Can't start conference mode, user is not logged") )
+ return
+
+ cmd=("LC_ALL=C LC_MESSAGES=C pactl --version 2>/dev/null | awk '{print $2}' | awk -F\".\" '{if ((int($2) >= 9) && (int($3) >= 10)) printf 1}'")
+ output=self.main.common.exe_cmd(cmd)
+ if output != "1":
+ shared.error_msg( _("Your pulseaudio server is too old.\nIs required pulseaudio version >= 0.9.10") )
+ return
+
+ msg=_( _("Do you want audio conference from user %s?" ) %(client_simple) )
+ if not shared.ask_msg ( msg ):
+ return
+
+
+ # Allow one client
+ # if len(self.allclients) == 0: return
+ remote_msg=_("You have entered in audio conference from user %s") %client_simple
+ eth=self.main.config.GetVar("network_interface")
+ max_uip=255
+ uip=0
+ while uip <= max_uip:
+ uip_cmd="225.0.0.%s" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0" and uip_cmd not in self.rtp_count.values():
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_broadcast="%s" %uip_cmd
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+
+ if not self.get_all_clients():
+ return
+
+ result = self.main.localdata.Route("route-add", ip_broadcast, "255.255.255.255", eth)
+ if result == "error":
+ print_debug("Add multicast-ip route failed")
+ return
+
+ #self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.rtp("startrtp-send", ip_simple, ip_broadcast )
+ self.main.write_into_statusbar( _("Waiting for start audio conference from user %s...") %(client_simple) )
+
+ output = self.main.common.exe_cmd("pactl load-module module-rtp-recv sap_address=%s" %ip_broadcast)
+
+ newallclients2=[]
+ total=1
+ for client in self.newallclients:
+ self.main.localdata.newhost(client)
+ if client != ip_simple:
+ self.main.xmlrpc.rtp("startrtp-recv", client, ip_broadcast )
+ total+=1
+ newallclients2.append(client)
+
+ if total < 1:
+ self.main.write_into_statusbar( _("No users logged.") )
+ self.main.common.exe_cmd("pactl unload-module %s" %output)
+ self.main.xmlrpc.rtp("stoprtp-send", ip_simple )
+ result = self.main.localdata.Route("route-del", ip_broadcast, "255.255.255.255", eth)
+ if result == "error":
+ print_debug("Del multicast-ip route failed")
+ else:
+ newusernames=[]
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus("mess", remote_msg)
+ else:
+ newusernames.append(user)
+ self.main.dbus_action.do_message( newusernames, remote_msg )
+ self.main.write_into_statusbar( _("Running in audio conference with %s clients.") %(total) )
+ # new mode Stop Button
+ if len(self.rtp_count.keys()) != 0:
+ count=len(self.rtp_count.keys())-1
+ nextkey=self.rtp_count.keys()[count]+1
+ self.rtp_count[nextkey]=ip_broadcast
+ else:
+ nextkey=1
+ self.rtp_count[nextkey]=ip_broadcast
+ #self.main.menus.broadcast_count[ip_broadcast]=None
+ self.add_progressbox( {"target": "rtp", "pid":output, "allclients":newallclients2, "ip":ip_simple, "ip_broadcast":ip_broadcast, "iface":eth, "key":nextkey}, _("Running in audio conference from user %(host)s. Conference Nº %(count)s") %{"host":client_simple, "count":nextkey} )
+
+ def rtp_chat(self, *args):
+ if not self.get_all_clients():
+ return
+ # conference mode
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("No users logged.") )
+ return
+
+ cmd=("LC_ALL=C LC_MESSAGES=C pactl --version 2>/dev/null | awk '{print $2}' | awk -F\".\" '{if ((int($2) >= 9) && (int($3) >= 10)) printf 1}'")
+ output=self.main.common.exe_cmd(cmd)
+ if output != "1":
+ shared.error_msg( _("Your pulseaudio server is too old.\nIs required pulseaudio version >= 0.9.10") )
+ return
+
+ msg=_( _("Do you want to start audio chat conference to the following users: %s?" )%(self.connected_users_txt) )
+
+ if not shared.ask_msg ( msg ):
+ return
+
+ remote_msg=_("You have entered in audio chat conference. Participants: %s") %self.connected_users_txt
+ eth=self.main.config.GetVar("network_interface")
+ max_uip=255
+ uip=0
+ while uip <= max_uip:
+ uip_cmd="225.0.0.%s" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0" and uip_cmd not in self.rtp_count.values():
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_broadcast="%s" %uip_cmd
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+ result = self.main.localdata.Route("route-add", ip_broadcast, "255.255.255.255", eth)
+ if result == "error":
+ print_debug("Add multicast-ip route failed")
+ return
+
+ self.main.write_into_statusbar( _("Waiting for start audio chat conference...") )
+
+ output_send=""
+ output_recv=""
+ self.rtp_control_count[ip_broadcast]=[]
+ self.main.common.exe_cmd("/usr/lib/tcos/pactl-controller.sh start-server")
+ msg=_( "Do you want to connect to this audio chat conference now?" )
+ if shared.ask_msg ( msg ):
+ output_send = self.main.common.exe_cmd("pactl load-module module-rtp-send format=s16be channels=2 rate=44100 source=@DEFAULT_SOURCE@ loop=0 destination=%s" %ip_broadcast)
+ output_recv = self.main.common.exe_cmd("pactl load-module module-rtp-recv sap_address=%s" %ip_broadcast)
+ self.rtp_control_count[ip_broadcast]=[output_send, output_recv]
+ total=0
+ for client in self.newallclients:
+ self.main.xmlrpc.rtp("startrtp-chat", client, ip_broadcast )
+ total+=1
+
+ if total < 1:
+ self.main.write_into_statusbar( _("No users logged.") )
+ # kill x11vnc
+ if output_send != "" or output_recv != "":
+ self.main.common.exe_cmd("pactl unload-module %s" %output_send)
+ self.main.common.exe_cmd("pactl unload-module %s" %output_recv)
+ del self.rtp_control_count[ip_broadcast]
+ result = self.main.localdata.Route("route-del", ip_broadcast, "255.255.255.255", eth)
+ if result == "error":
+ print_debug("Del multicast-ip route failed")
+ if len(self.rtp_count.keys()) == 0:
+ self.main.common.exe_cmd("/usr/lib/tcos/pactl-controller.sh stop-server")
+ else:
+ newusernames=[]
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus("mess", remote_msg)
+ else:
+ newusernames.append(user)
+ self.main.dbus_action.do_message( newusernames, remote_msg )
+
+ self.main.write_into_statusbar( _("Running in audio chat conference with %s clients.") %(total) )
+ # new mode Stop Button
+ if len(self.rtp_count.keys()) != 0:
+ count=len(self.rtp_count.keys())-1
+ nextkey=self.rtp_count.keys()[count]+1
+ self.rtp_count[nextkey]=ip_broadcast
+ else:
+ nextkey=1
+ self.rtp_count[nextkey]=ip_broadcast
+ if self.control_list:
+ self.populate_data(self.rtp_count)
+ #self.main.menus.broadcast_count[ip_broadcast]=None
+ self.add_progressbox( {"target": "rtp-chat", "pid_send":output_send, "pid_recv":output_recv, "allclients":self.newallclients, "ip":"", "ip_broadcast":ip_broadcast, "iface":eth, "key":nextkey}, _("Running in audio chat conference. Conference Nº %s") %(nextkey) )
+
+ def on_progressbox_click(self, widget, args, box):
+ box.destroy()
+ print_debug("on_progressbox_click() widget=%s, args=%s, box=%s" %(widget, args, box) )
+
+ if not args['target']:
+ return
+
+ self.main.stop_running_actions.remove(widget)
+
+ if args['target'] == "rtp":
+ del self.rtp_count[args['key']]
+ if args['ip_broadcast'] != "":
+ result = self.main.localdata.Route("route-del", args['ip_broadcast'], "255.255.255.255", args['iface'])
+ if result == "error":
+ print_debug("Del multicast-ip route failed")
+ #del self.main.menus.broadcast_count[args['ip_broadcast']]
+ for client in args['allclients']:
+ self.main.xmlrpc.rtp("stoprtp-recv", client)
+ if "pid" in args:
+ self.main.common.exe_cmd("pactl unload-module %s" %args['pid'])
+ if args['ip'] != "":
+ self.main.xmlrpc.rtp("stoprtp-send", args['ip'] )
+ if len(self.rtp_count.keys()) == 0:
+ self.main.common.exe_cmd("/usr/lib/tcos/pactl-controller.sh stop-server")
+ self.main.write_into_statusbar( _("Conference mode off.") )
+
+ if args['target'] == "rtp-chat":
+ del self.rtp_count[args['key']]
+ if args['ip_broadcast'] != "":
+ result = self.main.localdata.Route("route-del", args['ip_broadcast'], "255.255.255.255", args['iface'])
+ if result == "error":
+ print_debug("Del multicast-ip route failed")
+ #del self.main.menus.broadcast_count[args['ip_broadcast']]
+ for client in args['allclients']:
+ self.main.xmlrpc.rtp("stoprtp-chat", client)
+ if self.rtp_control_count.has_key(args['ip_broadcast']) and len(self.rtp_control_count[args['ip_broadcast']]) > 0:
+ self.main.common.exe_cmd("pactl unload-module %s" %self.rtp_control_count[args['ip_broadcast']][0])
+ self.main.common.exe_cmd("pactl unload-module %s" %self.rtp_control_count[args['ip_broadcast']][1])
+ del self.rtp_control_count[args['ip_broadcast']]
+ if self.control_list:
+ self.chat_delete(args['ip_broadcast'])
+ if len(self.rtp_count.keys()) == 0:
+ self.main.common.exe_cmd("/usr/lib/tcos/pactl-controller.sh stop-server")
+ self.main.write_into_statusbar( _("Audio chat conference off.") )
+
+
+
+__extclass__=AudioRTP
diff --git a/tcosmonitor/extensions/clean.py b/tcosmonitor/extensions/clean.py
new file mode 100644
index 0000000..2aa63c9
--- /dev/null
+++ b/tcosmonitor/extensions/clean.py
@@ -0,0 +1,58 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class Clean(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple(_("Clean info about terminal"), "menu_clear.png", 0, self.clean, "clean")
+ self.main.menus.register_all( _("Clean info about terminal"), "menu_clear.png", 0, self.clean, "clean")
+
+ def clean(self, *args):
+ print_debug("clean()")
+ self.main.datatxt.clean()
+ self.main.write_into_statusbar('')
+
+
+
+
+
+
+__extclass__=Clean
+
+
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/dpms.py b/tcosmonitor/extensions/dpms.py
new file mode 100644
index 0000000..44b35d5
--- /dev/null
+++ b/tcosmonitor/extensions/dpms.py
@@ -0,0 +1,98 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class Dpms(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("DPMS Power off monitor"), "menu_dpms_off.png", 0, self.dpms_off, "dpms")
+ self.main.menus.register_all( _("DPMS Power off monitors"), "menu_dpms_off.png", 0, self.dpms_off_all, "dpms")
+ self.main.menus.register_simple( _("DPMS Power on monitor"), "menu_dpms_on.png", 0, self.dpms_on, "dpms")
+ self.main.menus.register_all( _("DPMS Power on monitors"), "menu_dpms_on.png", 0, self.dpms_on_all, "dpms")
+
+ def dpms_off(self, w, ip):
+ if not self.get_client():
+ return
+ # DPMS off
+ self.main.xmlrpc.dpms('off')
+ self.change_lockscreen(self.main.selected_ip)
+
+ def dpms_on(self, w, ip):
+ if not self.get_client():
+ return
+ # DPMS on
+ self.main.xmlrpc.dpms('on')
+ self.change_lockscreen(self.main.selected_ip)
+
+ def real_action(self, ip, action):
+ print_debug("real_action() ip=%s action='%s'"%(ip, action) )
+
+ if action == 'dpmsoff':
+ result=self.main.xmlrpc.dpms('off')
+ print_debug("real_action() DPMS OFF result=%s"%result)
+ self.main.common.threads_enter("extensions/dpms::real_action dpms off")
+ self.change_lockscreen(ip)
+ self.main.common.threads_leave("extensions/dpms::real_action dpms off")
+ elif action == 'dpmson':
+ result=self.main.xmlrpc.dpms('on')
+ print_debug("real_action() DPMS ON result=%s"%result)
+ self.main.common.threads_enter("extensions/dpms::real_action dpms on")
+ self.change_lockscreen(ip)
+ self.main.common.threads_leave("extensions/dpms::real_action dpms on")
+
+
+ def dpms_off_all(self, *args):
+ if not self.get_all_clients():
+ return
+ msg=_( _("Do you want to switch off the following monitors: %s?" ) %(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, \
+ self.allclients_logged, "dpmsoff" )
+
+ def dpms_on_all(self, *args):
+ if not self.get_all_clients():
+ return
+ msg=_( _("Do you want to switch on the following monitors: %s?" ) %(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, \
+ self.allclients_logged, "dpmson" )
+
+
+__extclass__=Dpms
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/info.py b/tcosmonitor/extensions/info.py
new file mode 100644
index 0000000..80fefab
--- /dev/null
+++ b/tcosmonitor/extensions/info.py
@@ -0,0 +1,616 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+from time import time
+import gtk
+import os
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+from tcosmonitor.ping import PingPort
+
+def crono(start, txt):
+ print_debug ("crono(), %s get %f seconds" %(txt, (time() - start)) )
+ return
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class Info(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple(_("Refresh terminal info"), "menu_refresh.png", 0, self.get_info, "info")
+ # register file click event target
+ self.main.listview.populate_datatxt=self.populate_datatxt
+
+ def get_info(self, widget, ip):
+ if not self.get_client():
+ return
+ print_debug("get_info() ip=%s"%(ip))
+ self.main.xmlrpc.ip=ip
+ self.main.worker=shared.Workers( self.main,\
+ target=self.populate_datatxt, args=(ip,) ).start()
+
+
+ def populate_datatxt(self, ip):
+ start1=time()
+ print_debug ("populate_datatxt() INIT ip %s"%ip)
+
+ if not self.main.xmlrpc.connected:
+ print_debug ( "populate_datatxt(%s) NO CONNECTION" %(ip) )
+ crono(start1, "populate_datatxt(%s)" %(ip) )
+ return
+
+ # dictionary with all data
+ tcos_vars={}
+
+ self.datatxt = self.main.datatxt
+
+ # clear datatxt
+ self.main.common.threads_enter("TcosActions:populate_datatxt clean datatxt")
+ self.datatxt.clean()
+ self.main.common.threads_leave("TcosActions:populate_datatxt clean datatxt")
+ tcos_vars["get_client"] = self.main.xmlrpc.ReadInfo("get_client")
+ print_debug ( "Client type=%s" %(tcos_vars["get_client"]) )
+
+ # print into statusbar
+ self.main.common.threads_enter("TcosActions:populate_datatxt show progressbar")
+
+ if shared.disable_textview_on_update and self.main.listview.isactive():
+ self.main.tabla.set_sensitive(True)
+
+ #self.main.write_into_statusbar( _("Connecting with %s to retrieve some info..." ) %(ip) )
+
+ self.main.progressbar.show()
+ #self.main.progressbutton.show()
+ self.main.actions.set_progressbar( _("Connecting with %s to retrieve some info..." ) %(ip) , 0, show_percent=False)
+
+ self.main.common.threads_leave("TcosActions:populate_datatxt show progressbar")
+
+
+ info_percent=0.0
+ info_items=0
+ for elem in self.main.config.vars:
+ # elem can have 2 or 3 elements (don't use key,value in for)
+ key=elem[0]
+ value=elem[1]
+ if self.main.config.GetVar(key) == 1:
+ info_items += 1
+ if info_items != 0:
+ percent_step=float((100/info_items))
+ percent_step=percent_step/100
+
+
+
+ if self.main.config.GetVar("tcosinfo") == 1:
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ if tcos_vars["get_client"] == "tcos":
+ self.datatxt.insert_block( _("Tcos info") , image=shared.IMG_DIR + "tcos-icon-32x32.png" )
+
+ elif tcos_vars["get_client"] == "pxes":
+ self.datatxt.insert_block( _("PXES info") , image="/usr/share/pixmaps/pxesconfig/2X.png" )
+
+ elif tcos_vars["get_client"] == "ltsp":
+ self.datatxt.insert_block( _("LTSP info") , image=shared.IMG_DIR + "ltsp_logo.png" )
+
+ elif tcos_vars["get_client"] == "standalone":
+ self.datatxt.insert_block( _("Standalone info") , image=shared.IMG_DIR + "standalone.png" )
+
+ elif tcos_vars["get_client"] == "multiseat":
+ self.datatxt.insert_block( _("Multiseat info") , image=shared.IMG_DIR + "standalone.png" )
+
+ else:
+ self.datatxt.insert_block( _("Unknow client info") )
+
+ tcos_vars["hostname"]=self.main.localdata.GetHostname(ip)
+ tcos_vars["version"]=self.main.xmlrpc.GetVersion()
+
+ if not tcos_vars["version"]:
+ tcos_vars["version"]=_("unknow")
+
+ self.datatxt.insert_list( [
+ [ _("Hostname: "), tcos_vars["hostname"] ] , \
+ [ _("Ip address: "), ip ] , \
+ [ _("TcosXmlRpc version: "), tcos_vars["version"] ]
+ ] )
+
+ tcos_vars["tcos_version"]=self.main.xmlrpc.ReadInfo("tcos_version")
+ tcos_vars["tcos_generation_date"]=self.main.xmlrpc.ReadInfo("tcos_generation_date")
+ tcos_vars["tcos_date"]=self.main.xmlrpc.ReadInfo("tcos_date")
+ tcos_vars["tcos_uptime"]=self.main.xmlrpc.ReadInfo("tcos_uptime")
+
+ self.datatxt.insert_list( [ \
+ [_("Tcos image version: "), tcos_vars["tcos_version"] ], \
+ [_("Tcos image date: "), tcos_vars["tcos_generation_date"] ], \
+ [_("Date of thin client: "), tcos_vars["tcos_date"] ],
+ [_("Uptime: "), tcos_vars["tcos_uptime"] ]
+ ] )
+
+
+
+ if self.main.config.GetVar("kernelmodulesinfo") == 1:
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ self.datatxt.insert_block( _("Kernel info"), image=shared.IMG_DIR + "info_kernel.png" )
+
+ tcos_vars["kernel_version"]=self.main.xmlrpc.ReadInfo("kernel_version")
+ tcos_vars["kernel_complete_version"]=self.main.xmlrpc.ReadInfo("kernel_complete_version")
+ tcos_vars["modules_loaded"]=self.main.xmlrpc.ReadInfo("modules_loaded")
+ tcos_vars["modules_notfound"]=self.main.xmlrpc.ReadInfo("modules_notfound")
+
+ if tcos_vars["modules_notfound"] != "OK" and tcos_vars["get_client"] == "tcos":
+
+ blabel=_("Force download and mount all modules")
+ self.main.action_button=gtk.Button( label=blabel )
+ self.main.action_button.connect("clicked", self.on_downloadallmodules_click)
+ self.main.action_button.show()
+
+ tcos_vars["modules_notfound"] = """
+ <span style='color:red'>%s </span>
+ <input type='button' name='%s' label='%s' />
+ """ % (tcos_vars["modules_notfound"], "self.main.action_button" , blabel)
+
+ else:
+ tcos_vars["modules_notfound"] = _("None")
+
+ self.datatxt.insert_list( [ \
+ [_("Kernel version: "), tcos_vars["kernel_version"] ], \
+ [_("Kernel complete version: "), tcos_vars["kernel_complete_version"] ], \
+ [_("Loaded Modules: "), tcos_vars["modules_loaded"] ], \
+ [_("Modules not found: "), tcos_vars["modules_notfound"] ]
+ ] )
+
+
+ cpuinfo=self.main.config.GetVar("cpuinfo")
+ pciinfo=self.main.config.GetVar("pcibusinfo")
+ ramswapinfo=self.main.config.GetVar("ramswapinfo")
+ networkinfo=self.main.config.GetVar("networkinfo")
+
+
+ if cpuinfo == 1:
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ self.datatxt.insert_block( _("Cpu info: "), image=shared.IMG_DIR + "info_cpu.png" )
+
+ tcos_vars["cpu_model"]=self.main.xmlrpc.ReadInfo("cpu_model")
+ tcos_vars["cpu_vendor"]=self.main.xmlrpc.ReadInfo("cpu_vendor")
+ tcos_vars["cpu_speed"]=self.main.xmlrpc.ReadInfo("cpu_speed")
+
+ self.datatxt.insert_list( [ \
+ [_("Cpu model: "), tcos_vars["cpu_model"] ], \
+ [_("Cpu vendor: "), tcos_vars["cpu_vendor"] ], \
+ [_("Cpu speed: "), tcos_vars["cpu_speed"] ]
+ ] )
+
+
+ if pciinfo == 1:
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ # PCI info
+ self.datatxt.insert_block( _("PCI buses: ") , image=shared.IMG_DIR + "info_pci.png" )
+
+ pcilist=[]
+ try:
+ allpci=self.main.xmlrpc.tc.tcos.pci("pci_all").split(' ')
+ except Exception, err:
+ print_debug("info() Exception pci error %s"%err)
+ self.main.xmlrpc.CheckSSL(err)
+
+ for pci_id in allpci:
+ if pci_id != "":
+ try:
+ pci_info=self.main.xmlrpc.tc.tcos.pci(pci_id)
+ pcilist.append( [pci_id + " ", pci_info] )
+ except Exception, err:
+ print_debug("info() Exception pci error %s"%err)
+ self.main.xmlrpc.CheckSSL(err)
+
+ self.datatxt.insert_list( pcilist )
+
+
+
+ if self.main.config.GetVar("processinfo") == 1 and tcos_vars["get_client"] != "standalone":
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ self.datatxt.insert_block( _("Process running: "), image=shared.IMG_DIR + "info_proc.png" )
+
+ proclist=[]
+ allprocess=self.main.xmlrpc.ReadInfo("get_process").split('|')
+ self.datatxt.insert_proc( allprocess )
+
+
+ if ramswapinfo == 1:
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ self.datatxt.insert_block( _("Ram info: "), image=shared.IMG_DIR + "info_ram.png" )
+
+ tcos_vars["ram_total"]=self.main.xmlrpc.ReadInfo("ram_total")
+ tcos_vars["ram_free"]=self.main.xmlrpc.ReadInfo("ram_free")
+ tcos_vars["ram_active"]=self.main.xmlrpc.ReadInfo("ram_active")
+
+ self.datatxt.insert_list( [ \
+ [_("Total Ram: "), tcos_vars["ram_total"] ], \
+ [_("Free RAM: "), tcos_vars["ram_free"] ], \
+ [_("Active RAM: "), tcos_vars["ram_active"] ]
+ ] )
+
+ self.datatxt.insert_block( _("Swap info: "), image=shared.IMG_DIR + "info_swap.png" )
+ tcos_vars["swap_avalaible"]=self.main.xmlrpc.ReadInfo("swap_avalaible")
+ tcos_vars["swap_total"]=self.main.xmlrpc.ReadInfo("swap_total")
+ tcos_vars["swap_used"]=self.main.xmlrpc.ReadInfo("swap_used")
+
+ self.datatxt.insert_list( [ \
+ [_("Swap enabled: "), tcos_vars["swap_avalaible"] ], \
+ [_("Total Swap: "), tcos_vars["swap_total"] ], \
+ [_("Used Swap: "), tcos_vars["swap_used"] ]
+ ] )
+
+
+
+ if networkinfo == 1:
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+ self.datatxt.insert_block( _("Network info: ") , image=shared.IMG_DIR + "info_net.png" )
+
+ tcos_vars["network_hostname"]=self.main.xmlrpc.ReadInfo("network_hostname")
+ tcos_vars["network_ip"]=self.main.xmlrpc.ReadInfo("network_ip")
+ tcos_vars["network_mask"]=self.main.xmlrpc.ReadInfo("network_mask")
+ tcos_vars["network_mac"]=self.main.xmlrpc.ReadInfo("network_mac")
+ tcos_vars["network_rx"]=self.main.xmlrpc.ReadInfo("network_rx")
+ tcos_vars["network_tx"]=self.main.xmlrpc.ReadInfo("network_tx")
+
+ self.datatxt.insert_list( [ \
+ [_("Network hostname: "), tcos_vars["network_hostname"] ], \
+ [_("Network IP: "), tcos_vars["network_ip"] ], \
+ [_("Network MASK: "), tcos_vars["network_mask"] ], \
+ [_("Network MAC: "), tcos_vars["network_mac"] ], \
+ [_("Data received(rx): "), tcos_vars["network_rx"] ], \
+ [_("Data send(tx): "), tcos_vars["network_tx"] ]
+ ] )
+
+
+ if self.main.config.GetVar("xorginfo") == 1 and tcos_vars["get_client"] != "standalone":
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ self.datatxt.insert_block( _("Xorg info") , image=shared.IMG_DIR + "info_xorg.png" )
+
+ xorglist=[]
+ try:
+ alldata=self.main.xmlrpc.tc.tcos.xorg("get", "", \
+ self.main.config.GetVar("xmlrpc_username"), \
+ self.main.config.GetVar("xmlrpc_password") ).split()
+ except Exception, err:
+ print_debug("info() Exception networking error %s"%err)
+ self.main.xmlrpc.CheckSSL(err)
+
+ print_debug ( "populate_datatxt() %s" %( " ".join(alldata) ) )
+ if alldata[0].find("error") == 0:
+ #shared.error_msg( _("Error getting Xorg info:\n%s" ) %( " ".join(alldata)) )
+ pass
+ else:
+ for data in alldata:
+ try:
+ (key, value)=data.split('=')
+ except Exception, err:
+ print_debug("populate_datatxt() Exception spliting data=%s, err=%s"%(data, err))
+ key=data
+ value=""
+
+ if value== "1":
+ value = _("enabled")
+ elif value == "0":
+ value = _("disabled")
+
+ if key == "xsession":
+ key=_("X Session Type")
+ elif key == "xdriver":
+ key=_("Xorg Driver")
+ elif key == "xres":
+ key=_("Xorg Resolution")
+ elif key == "xdepth":
+ key=_("Xorg Color depth")
+ elif key == "xdpms":
+ key=_("DPMS energy monitor control")
+ elif key == "xdontzap":
+ key=_("Disable kill X with Ctrl+Alt+Backspace")
+ elif key == "xmousewheel":
+ key=_("Enable mouse wheel")
+ elif key == "xrefresh":
+ key=_("Refresh rate")
+ elif key == "xfontserver":
+ key = _("Xorg font server")
+ elif key == "xmousedev":
+ key = _("Mouse device")
+ elif key == "xmouseprotocol":
+ key = _("Mouse protocol")
+ elif key == "xhorizsync":
+ key = _("X Horiz sync")
+ elif key == "xvertsync":
+ key = _("X Vert sync")
+ xorglist.append( [key + " " , value] )
+ self.datatxt.insert_list(xorglist)
+
+
+ if self.main.config.GetVar("soundserverinfo") == 1:
+ info_percent+=percent_step
+ self.main.common.threads_enter("TcosActions:populate_datatxt update progressbar")
+ self.main.actions.update_progressbar( info_percent )
+ self.main.common.threads_leave("TcosActions:populate_datatxt update progressbar")
+
+ # make a ping to port
+ if tcos_vars["get_client"] == "standalone" or PingPort(ip, shared.pulseaudio_soundserver_port, 0.5).get_status() == "OPEN":
+ self.datatxt.insert_block ( _("PulseAudio Sound server is running"), image=shared.IMG_DIR + "info_sound_ok.png" )
+
+ channel_list=[]
+ tcos_sound_vars={}
+ #tcos_sound_vars["allchannels"]=self.main.xmlrpc.GetSoundChannels()
+ tcos_sound_vars["allchannels"]=self.main.xmlrpc.GetSoundChannelsContents()
+ #print_debug ( "populate_datatxt() sound channels=%s" %(tcos_sound_vars["allchannels"]) )
+
+ counter=0
+ self.main.volume_sliders=[]
+ self.main.volume_checkboxes=[]
+
+ self.datatxt.insert_html("""
+ <br />
+ <div style='text-align:center; background-color:#f3d160 ; margin-left: 25%%; margin-right: 25%%'>
+ <img file="%s" />
+ <span style='font-weight: bold; font-size: 150%%'>%s</span>
+ </div>
+ """ %( shared.IMG_DIR + "icon_mixer.png", _("Remote Sound Mixer")) )
+
+
+ for channel in tcos_sound_vars["allchannels"]:
+ volumebutton=None
+ # only show channel in list
+ if not channel['name'] in shared.sound_only_channels:
+ print_debug("populate_datatxt() *** AUDIO CHANNEL HIDDEN*** channel=%s"%channel)
+ continue
+ txt="""
+ <div style='text-align:center; background-color:#f3d160 ; margin-left: 25%%; margin-right: 25%%'>
+ <span style='font-size: 120%%'>%s: </span>
+ """ %(channel['name'])
+
+
+ #value=self.main.xmlrpc.GetSoundInfo(channel, mode="--getlevel")
+ #value=value.replace('%','')
+ value=channel['level']
+ try:
+ value=float(value)
+ except Exception, err:
+ print_debug("populate_datatxt() Exception getting volume=%s, err=%s"%(value, err) )
+ value=0.0
+
+ #ismute=self.main.xmlrpc.GetSoundInfo(channel, mode="--getmute")
+ ismute=channel['mute']
+ if ismute == "off":
+ ismute = True
+ else:
+ ismute = False
+
+ ctype=channel['type']
+ print_debug ( "populate_datatxt() channel=%s ismute=%s volume level=%s ctype=%s" %(channel['name'], ismute, value, ctype) )
+ ############ mute checkbox ##################
+ volume_checkbox=gtk.CheckButton(label=_("Mute"), use_underline=True)
+ volume_checkbox.set_active(ismute)
+ volume_checkbox.connect("toggled", self.checkbox_value_changed, channel['name'], ip)
+ if "switch" in ctype:
+ volume_checkbox.show()
+ else:
+ volume_checkbox.hide()
+ self.main.volume_checkboxes.append(volume_checkbox)
+
+ txt+="<input type='checkbox' name='self.main.volume_checkboxes' index='%s' />" %(counter)
+
+
+ ############# volume slider ###################
+ adjustment = gtk.Adjustment(value=0,
+ lower=0,
+ upper=100,
+ step_incr=1,
+ page_incr=1)
+ volume_slider = gtk.HScale(adjustment)
+ volume_slider.set_size_request(100, 30)
+ volume_slider.set_value_pos(gtk.POS_RIGHT)
+ volume_slider.set_digits(0)
+ volume_slider.set_value( value )
+ volume_slider.connect("button_release_event", self.slider_value_changed, adjustment, channel['name'], ip)
+ volume_slider.connect("scroll_event", self.slider_value_changed, adjustment, channel['name'], ip)
+ if "volume" in ctype:
+ volume_slider.show()
+ else:
+ volume_slider.hide()
+ self.main.volume_sliders.append(volume_slider)
+ txt+="<input type='slider' name='self.main.volume_sliders' index='%s' />" %(counter)
+
+ txt+="</div>"
+ self.datatxt.insert_html(txt)
+ counter+=1
+
+ if tcos_vars["get_client"] == "tcos":
+ # PulseAudio utils
+ self.main.openvolumecontrol_button=None
+ self.main.openvolumecontrol_button=gtk.Button(label=_("PulseAudio Control") )
+ self.main.openvolumecontrol_button.connect("clicked", self.on_openvolumecontrol_button_click, ip)
+ self.main.openvolumecontrol_button.show()
+
+ self.main.openvolumemeter_button=None
+ self.main.openvolumemeter_button=gtk.Button(label=_("PulseAudio Meter") )
+ self.main.openvolumemeter_button.connect("clicked", self.on_openvolumemeter_button_click, ip)
+ self.main.openvolumemeter_button.show()
+
+ self.main.volumemanager_button=None
+ self.main.volumemanager_button=gtk.Button(label=_("PulseAudio Manager") )
+ self.main.volumemanager_button.connect("clicked", self.on_volumemanager_button_click, ip)
+ self.main.volumemanager_button.show()
+
+ self.datatxt.insert_block(_("PulseAudio utils: ") + """
+ <input type='button' name='self.main.volumemanager_button' />
+ <input type='button' name='self.main.openvolumecontrol_button' />
+ <input type='button' name='self.main.openvolumemeter_button' />
+ """)
+
+ self.datatxt.insert_block( _("PulseAudio stats") )
+ pulseaudioinfo=self.main.xmlrpc.GetSoundInfo(channel="", mode="--getserverinfo").split('|')
+ #print pulseaudioinfo
+ allpulseaudioinfo=[]
+ allpulseaudioinfo_trans=[]
+ output=[]
+ for line in pulseaudioinfo:
+ if line != "" and line.find(":") != -1:
+ key, value = line.split(':')
+ allpulseaudioinfo.append([ key+":", value ])
+ allpulseaudioinfo_trans.append(value)
+ if len(allpulseaudioinfo_trans) == 11:
+ output.append( ["%s:" %( _("Currently in use")), allpulseaudioinfo_trans[0] ])
+ output.append( ["%s:" %( _("Allocated during whole lifetime")), allpulseaudioinfo_trans[1] ])
+ output.append( ["%s:" %( _("Sample cache size")), allpulseaudioinfo_trans[2] ])
+ output.append( ["%s:" %( _("User name")), allpulseaudioinfo_trans[3] ])
+ output.append( ["%s:" %( _("Host Name")), allpulseaudioinfo_trans[4] ])
+ output.append( ["%s:" %( _("Server Name")), allpulseaudioinfo_trans[5] ])
+ output.append( ["%s:" %( _("Server Version")), allpulseaudioinfo_trans[6] ])
+ output.append( ["%s:" %( _("Default Sample Specification")), allpulseaudioinfo_trans[7] ])
+ output.append( ["%s:" %( _("Default Sink")), allpulseaudioinfo_trans[8] ])
+ output.append( ["%s:" %( _("Default Source")), allpulseaudioinfo_trans[9] ])
+ output.append( ["%s:" %( _("Cookie")), allpulseaudioinfo_trans[10] ])
+ self.datatxt.insert_list( output )
+ else:
+ self.datatxt.insert_list( allpulseaudioinfo )
+
+ else:
+ self.datatxt.insert_block ( _("Sound server is not running"), image=shared.IMG_DIR + "info_sound_ko.png")
+
+ self.main.common.threads_enter("TcosActions:populate_datatxt end")
+ self.datatxt.display()
+ self.main.actions.update_progressbar( 1 )
+ self.main.progressbar.hide()
+
+ if shared.disable_textview_on_update and self.main.iconview.isactive():
+ self.main.tabla.set_sensitive(True)
+
+ self.main.common.threads_leave("TcosActions:populate_datatxt end")
+
+ crono(start1, "populate_datatxt(%s)" %(ip) )
+ return False
+
+ def on_downloadallmodules_click(self, widget):
+ print_debug ( "on_downloadallmodules_click() ################" )
+ if self.main.selected_ip != None:
+ print_debug( "on_downloadallmodules_click() downloading modules for %s" %(self.main.selected_ip) )
+ # download allmodules.squashfs and mount it
+ self.main.xmlrpc.Exe("useallmodules.sh")
+ return
+
+
+ def slider_value_changed(self, widget, adjustment, event, channel, ip):
+ value=widget.get_value()
+ print_debug ( "slider_value_changed() ip=%s channel=%s value=%s" %(ip, channel, value) )
+
+ self.main.write_into_statusbar( \
+ _("Changing value of %(channel)s channel, to %(value)s%%..." )\
+ %{"channel":channel, "value":value} )
+
+ tmp=self.main.xmlrpc.SetSound(ip, channel, str(value)+"%")
+ newvalue="%2d%%"%int(tmp['level'])
+
+ self.main.write_into_statusbar( \
+ _("Changed value of %(channel)s channel, to %(value)s" ) \
+ %{"channel":channel, "value":newvalue} )
+
+ def checkbox_value_changed(self, widget, channel, ip):
+ value=widget.get_active()
+ if not value:
+ value="off"
+ self.main.write_into_statusbar( _("Unmuting %s channel..." ) %(channel) )
+ tmp=self.main.xmlrpc.SetSound(ip, channel, value="", mode="--setunmute")
+ newvalue=tmp['mute']
+ else:
+ value="on"
+ self.main.write_into_statusbar( _("Muting %s channel..." ) %(channel) )
+ tmp=self.main.xmlrpc.SetSound(ip, channel, value="", mode="--setmute")
+ newvalue=tmp['mute']
+ self.main.write_into_statusbar( _("Status of %(channel)s channel, is \"%(newvalue)s\"" )\
+ %{"channel":channel, "newvalue":newvalue} )
+
+
+ def on_openvolumecontrol_button_click(self, widget, ip):
+ print_debug ( "on_openvolumecontrol_button_click() ip=%s" %(ip) )
+ cmd="PULSE_SERVER=\"%s\" pavucontrol" %(ip)
+ if os.path.isdir("/dev/shm"):
+ self.main.common.exe_cmd( cmd, verbose=0, background=True )
+ else:
+ shared.error_msg ( _("PulseAudio apps need /dev/shm.") )
+
+ def on_openvolumemeter_button_click(self, widget, ip):
+ print_debug ( "on_openvolumemeter_button_click() ip=%s" %(ip) )
+ cmd="PULSE_SERVER=\"%s\" pavumeter" %(ip)
+ if os.path.isdir("/dev/shm"):
+ self.main.common.exe_cmd( cmd, verbose=0, background=True )
+ else:
+ shared.error_msg ( _("PulseAudio apps need /dev/shm.") )
+
+ def on_volumemanager_button_click(self, widget, ip):
+ print_debug ( "on_volumemanager_button_click() ip=%s" %(ip) )
+ cmd="PULSE_SERVER=\"%s\" paman" %(ip)
+ if os.path.isdir("/dev/shm"):
+ self.main.common.exe_cmd( cmd, verbose=0, background=True )
+ else:
+ shared.error_msg ( _("PulseAudio apps need /dev/shm.") )
+
+
+
+__extclass__=Info
+
+
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/italc.py b/tcosmonitor/extensions/italc.py
new file mode 100644
index 0000000..00bfe59
--- /dev/null
+++ b/tcosmonitor/extensions/italc.py
@@ -0,0 +1,88 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+from time import sleep
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class iTalc(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Connect to remote screen (iTALC)"), "menu_remote.png", 1, self.ivs, "italc")
+
+
+ def ivs(self, w, ip):
+ if not self.get_client():
+ return
+
+ if len(self.allclients_logged) == 0:
+ shared.error_msg( _("No user logged.") )
+ return
+
+ self.main.worker=shared.Workers(self.main, target=self.start_ivs, args=(self.allclients_logged) )
+ self.main.worker.start()
+
+ def start_ivs(self, ip):
+ self.main.xmlrpc.newhost(ip)
+ # check if remote proc is running
+ if not self.main.xmlrpc.GetStatus("ivs"):
+ self.main.common.threads_enter("TcosActions:start_ivs write connecting msg")
+ self.main.write_into_statusbar( "Connecting with %s to start iTALC support" %(ip) )
+ self.main.common.threads_leave("TcosActions:start_ivs write connecting msg")
+
+ try:
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.Exe("startivs")
+ self.main.common.threads_enter("TcosActions:start_ivs write waiting msg")
+ self.main.write_into_statusbar( "Waiting for start of IVS server..." )
+ self.main.common.threads_leave("TcosActions:start_ivs write waiting msg")
+ sleep(5)
+ except Exception, err:
+ print_debug("start_ivs() Exception, error=%s"%err)
+ self.main.common.threads_enter("TcosActions:start_ivs write error msg")
+ shared.error_msg ( _("Can't start IVS, please add iTALC support") )
+ self.main.common.threads_leave("TcosActions:start_ivs write error msg")
+ return
+
+ cmd = "icv " + ip + " root"
+ print_debug ( "start_process() threading \"%s\"" %(cmd) )
+ self.main.common.exe_cmd (cmd, verbose=0, background=True)
+
+ self.main.common.threads_enter("TcosActions:start_ivs END")
+ self.main.write_into_statusbar( "" )
+ self.main.common.threads_leave("TcosActions:start_ivs END")
+
+__extclass__=iTalc
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/livevnc.py b/tcosmonitor/extensions/livevnc.py
new file mode 100644
index 0000000..cfbc511
--- /dev/null
+++ b/tcosmonitor/extensions/livevnc.py
@@ -0,0 +1,220 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+from gettext import gettext as _
+
+
+import gtk
+import sys
+
+# needed for get_screenshot
+from time import sleep
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+from tcosmonitor.ping import PingPort
+
+import gtkvnc
+from random import Random
+import string
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+
+class LiveVNC(TcosExtension):
+ def register(self):
+ self.main.menus.register_all( _("Live view screens with VNC") , "menu_remote.png", 1, self.live_all, "livevnc")
+ self.main.livevnc={}
+ self.vncpasswd=""
+ self.vncxres={}
+ self.main.triggers['clean.datatxt']=self.__cleandatatxt
+ self.main.stop_liveview_button=None
+
+ ########### MULTIPLE HOSTS ###############
+
+ def live_all(self, widget):
+ if not self.get_all_clients():
+ return
+ self.vncpasswd=''.join( Random().sample(string.letters+string.digits, 12) )
+
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, self.allclients, 'livevnc' )
+
+
+ def start_action(self, *args):
+ print_debug("START_ACTION")
+ self.main.datatxt.clean()
+ self.main.stop_liveview_button=gtk.Button(_("Stop") )
+ self.main.stop_liveview_button.connect("clicked", self.__cleandatatxt, 'force')
+ self.main.stop_liveview_button.show()
+
+ self.main.datatxt.insert_block( _("Live view of all hosts") )
+ #"""<span> </span><input type='button' name="self.main.stop_liveview_button" />""" )
+ self.main.datatxt.insert_html("<br/>")
+
+ def real_action(self, ip, action):
+ #print_debug("real_action() ip=%s self.main.livevnc=%s" %(ip, self.main.livevnc) )
+ max_wait=10
+
+
+ # generate pass on client
+ #self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.vnc("genpass", ip, self.vncpasswd)
+
+
+ # start x11vnc
+ result=self.main.xmlrpc.vnc("startscale", ip)
+ print_debug("real_action() start remote x11vnc result=%s"%result)
+ if result.find("error") != -1:
+ return
+
+ # wait for start
+ status = "CLOSED"
+
+ wait=0
+ while status != "OPEN":
+ status=PingPort(ip, 5900).get_status()
+ if status == "CLOSED":
+ sleep(1)
+ wait+=1
+ if wait > max_wait:
+ break
+
+ # start vnc and save in self.main.vnc dict
+ self.main.livevnc[ip]=gtkvnc.Display()
+ self.main.livevnc[ip].set_credential(gtkvnc.CREDENTIAL_PASSWORD, self.vncpasswd)
+ self.main.livevnc[ip].set_credential(gtkvnc.CREDENTIAL_CLIENTNAME, self.main.name)
+
+ self.main.livevnc[ip].connect("vnc-auth-credential", self._vnc_auth_cred, ip)
+ #self.main.livevnc[ip].connect("size-request", self._force_resize, ip)
+ self.main.livevnc[ip].connect("vnc-connected", self._vnc_connected, ip)
+ #self.main.livevnc[ip].connect("clicked", self._vnc_clicked, ip)
+ self.main.livevnc[ip].connect("button-press-event", self.on_iconview_click, ip)
+ # this freeze GUI
+ #self.main.livevnc[ip].set_tooltip_text("%s"%ip)
+
+ #print dir(self.main.livevnc[ip])
+
+ print_debug("real_action() vnc started!!! ")
+
+ def _vnc_clicked(self, vnc, ip):
+ print_debug("_vnc_clicked() vnc=%s ip=%s"%(vnc, ip))
+
+
+ def on_iconview_click(self, widget, event, ip):
+ if event.button == 3:
+ self.main.force_selected_ip=ip
+ # right click show menu
+ self.main.menus.RightClickMenuOne( None , None, ip)
+ self.main.menu.popup( None, None, None, event.button, event.time)
+ return True
+
+
+ def _vnc_auth_cred(self, *args):
+ #print_debug("vnc_auth_cred() args=%s"%args)
+ return
+
+
+ def _force_resize(self, src, size, ip):
+ #print_debug("_force_resize() src=%s size=%s ip=%s"%(src, size, ip))
+ w, h = src.get_size_request()
+ #print "_force_resize() w=%s h=%s"%(w, h)
+ if w == -1 or h == -1:
+ print_debug("_force_resize() returning w=%s h=%s ip=%s"%(w, h, ip))
+ return
+ width=300
+ height=200
+ if self.vncxres.has_key(ip):
+ # cached data
+ width=self.vncxres[ip][0]
+ height=self.vncxres[ip][1]
+ else:
+ self.vncxres[ip]=[width, height]
+ try:
+ screensize=self.main.xmlrpc.ReadInfo("screensize")
+ if screensize != '':
+ width=int(screensize.split('x')[0]) * 100 / int(self.main.config.GetVar("miniscrot_size"))
+ height=int(screensize.split('x')[1]) * 100 / int(self.main.config.GetVar("miniscrot_size"))
+ self.vncxres[ip]=[width, height]
+ print_debug("_force_resize() RESIZE w=%s h=%s"%(width, height))
+ except Exception, err:
+ print_debug("_force_resize() Exception err=%s"%err)
+ width=300
+ height=200
+ self.vncxres[ip]=[width, height]
+ self.main.livevnc[ip].set_size_request(self.vncxres[ip][0], self.vncxres[ip][1])
+
+
+ def _vnc_connected(self, vnc, ip):
+ print_debug("_vnc_connected() vnc=%s livevnc[ip]=%s ip=%s"%(vnc, self.main.livevnc[ip], ip))
+ self.main.livevnc[ip].show()
+ self.main.livevnc[ip].realize()
+
+
+ def finish_action(self, *args):
+ for ip in self.main.livevnc:
+ #self.main.livevnc[ip]
+ hostname=self.main.localdata.GetUsername(ip)
+ if hostname == shared.NO_LOGIN_MSG:
+ hostname=self.main.localdata.GetHostname(ip)
+ self.main.datatxt.insert_html(
+ "<span style='background-color:#f3d160'>" +
+ "\n\t<livevnc ip='%s' objdict='livevnc' title='%s' title_rotate='90'/> " %(ip, hostname) +
+ "<span style='background-color:#f3d160; color:#f3d160'>__</span>\n</span>"+
+ "")
+ self.main.livevnc[ip].open_host(ip, '5900')
+ #self.main.livevnc[ip].set_scaling(True)
+ self.main.livevnc[ip].set_read_only(True)
+ self.main.livevnc[ip].show()
+ # draw widgets
+ self.main.datatxt.display()
+ stopargs={"target": "livevnc"}
+ self.add_progressbox( stopargs, _("Running in LiveView mode") )
+
+ def on_progressbox_click(self, widget, args, box):
+ try:
+ box.destroy()
+ except:
+ pass
+ self.__cleandatatxt(None, 'force')
+
+
+
+ def __cleandatatxt(self, *args):
+ # stop all livevnc connections
+ for ip in self.main.livevnc:
+ print_debug("__cleandatatxt() STOPPING ip=%s"%ip)
+ self.main.livevnc[ip].close()
+ # stop server (don't wait)
+ self.main.xmlrpc.vnc("stopserver", ip )
+ self.main.livevnc={}
+
+ if len(args) == 2 and args[1] == 'force':
+ self.main.datatxt.clean()
+ self.main.stop_liveview_button=None
+
+
+
+__extclass__=LiveVNC
+
diff --git a/tcosmonitor/extensions/lockscreen.py b/tcosmonitor/extensions/lockscreen.py
new file mode 100644
index 0000000..02b8317
--- /dev/null
+++ b/tcosmonitor/extensions/lockscreen.py
@@ -0,0 +1,100 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class LockUnlockScreen(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Lock screen"), "menu_lock.png", 0, self.lock, "lock")
+ self.main.menus.register_all( _("Lock all screens"), "menu_lock.png", 0, self.lock_all, "lock")
+ self.main.menus.register_simple( _("Unlock screen"), "menu_unlock.png", 0, self.unlock, "lock")
+ self.main.menus.register_all( _("Unlock all screens"), "menu_unlock.png", 0, self.unlock_all, "lock")
+
+ def lock(self, w, ip):
+ if not self.get_client():
+ return
+ if not self.main.xmlrpc.lockscreen():
+ shared.error_msg( _("Can't connect to tcosxmlrpc.\nPlease verify user and password in prefences!") )
+ return
+ self.change_lockscreen(ip)
+
+ def unlock(self, w, ip):
+ if not self.get_client():
+ return
+ if not self.main.xmlrpc.unlockscreen():
+ shared.error_msg( _("Can't connect to tcosxmlrpc.\nPlease verify user and password in prefences!") )
+ return
+ self.change_lockscreen(ip)
+
+ def real_action(self, ip, action):
+ print_debug("real_action() ip=%s action='%s'"%(ip, action) )
+
+ if action == 'lockscreen':
+ self.main.xmlrpc.lockscreen()
+ # update icon
+ self.main.common.threads_enter("extensions/lockscreen::real_action lockscreen")
+ self.change_lockscreen(ip)
+ self.main.common.threads_leave("extensions/lockscreen::real_action lockscreen")
+ elif action == 'unlockscreen':
+ self.main.xmlrpc.unlockscreen()
+ # update icon
+ self.main.common.threads_enter("extensions/lockscreen::real_action unlockscreen")
+ self.change_lockscreen(ip)
+ self.main.common.threads_leave("extensions/lockscreen::real_action unlockscreen")
+
+
+ def lock_all(self, *args):
+ if not self.get_all_clients():
+ return
+ msg=_( _("Do you want to lock the following screens: %s?" )%(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, \
+ self.allclients_logged, "lockscreen" )
+
+ def unlock_all(self, *args):
+ if not self.get_all_clients():
+ return
+ msg=_( _("Do you want to unlock the following screens: %s?" )%(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, \
+ self.allclients_logged, "unlockscreen" )
+
+
+__extclass__=LockUnlockScreen
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/logout.py b/tcosmonitor/extensions/logout.py
new file mode 100644
index 0000000..bab6441
--- /dev/null
+++ b/tcosmonitor/extensions/logout.py
@@ -0,0 +1,94 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class LogOut(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Logout client"), "menu_restartx.png", 0, self.logout, "restartx")
+ self.main.menus.register_all( _("Logout clients"), "menu_restartx.png" , 0, self.logout_all, "restartx")
+
+
+ def logout(self, w, ip):
+ if not self.get_client():
+ return
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("User not logged") )
+ return
+
+ msg=_( _("Do you want to logout user: %s?" ) %(self.connected_users_txt) )
+ if shared.ask_msg ( msg ):
+ newusernames=[]
+ timeout=self.main.config.GetVar("actions_timeout")
+ msg=_("Session will close in %s seconds") %timeout
+ remote_cmd="/usr/lib/tcos/session-cmd-send LOGOUT %s %s" %(timeout, msg.replace("'", "´"))
+
+ if self.connected_users[0].find(":") != -1:
+ # we have a standalone user...
+ self.main.xmlrpc.DBus("exec", remote_cmd )
+ else:
+ newusernames.append(self.connected_users[0])
+
+ self.main.dbus_action.do_exec(newusernames, remote_cmd )
+
+ def logout_all(self, widget):
+ if not self.get_all_clients():
+ return
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("User not logged") )
+ return
+ msg=_( _("Do you want to logout the following users: %s?" )%(self.connected_users_txt) )
+ if shared.ask_msg ( msg ):
+ newusernames=[]
+ timeout=self.main.config.GetVar("actions_timeout")
+ msg=_("Session will close in %s seconds") %timeout
+ remote_cmd="/usr/lib/tcos/session-cmd-send LOGOUT %s %s" %(timeout, msg.replace("'", "´"))
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus("exec", remote_cmd )
+ else:
+ newusernames.append(user)
+
+ self.main.dbus_action.do_exec( newusernames, remote_cmd )
+
+__extclass__=LogOut
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/reboot.py b/tcosmonitor/extensions/reboot.py
new file mode 100644
index 0000000..be943cb
--- /dev/null
+++ b/tcosmonitor/extensions/reboot.py
@@ -0,0 +1,120 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class RebootPoweroff(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple(_("Reboot"), "menu_reboot.png", 0, self.reboot, "reboot")
+ self.main.menus.register_all( _("Reboot all clients"), "menu_reboot.png", 0, self.reboot_all, "reboot")
+ self.main.menus.register_simple( _("Poweroff"), "menu_poweroff.png", 0, self.poweroff, "reboot")
+ self.main.menus.register_all( _("Poweroff all clients"), "menu_poweroff.png", 0, self.poweroff_all, "reboot")
+
+ def reboot(self, w, ip):
+ if not self.get_client():
+ return
+ msg=_( _("Do you want to reboot: %s?" ) %(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ timeout=self.main.config.GetVar("actions_timeout")
+ msg=(_("Pc will reboot in %s seconds") %timeout)
+ self.exe_app_in_client("reboot", timeout, msg, users=[ip], connected_users=self.connected_users)
+
+
+ def reboot_all(self, *args):
+ if not self.get_all_clients():
+ return
+ msg=_( _("Do you want to reboot the following clients: %s?" ) %(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ timeout=self.main.config.GetVar("actions_timeout")
+ msg=(_("Pc will reboot in %s seconds") %timeout)
+ self.exe_app_in_client("reboot", timeout, msg, users=self.allclients, connected_users=self.connected_users)
+
+ def poweroff(self, w, ip):
+ if not self.get_client():
+ return
+ msg=_( _("Do you want to poweroff: %s?" ) %(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ timeout=self.main.config.GetVar("actions_timeout")
+ msg=(_("Pc will shutdown in %s seconds") %timeout)
+ self.exe_app_in_client("poweroff", timeout, msg, users=[ip], connected_users=self.connected_users)
+
+
+ def poweroff_all(self, *args):
+ if not self.get_all_clients():
+ return
+ msg=_( _("Do you want to poweroff the following clients: %s?" )%(self.connected_users_txt_all) )
+ if shared.ask_msg ( msg ):
+ timeout=self.main.config.GetVar("actions_timeout")
+ msg=(_("Pc will shutdown in %s seconds") %timeout)
+ self.exe_app_in_client("poweroff", timeout, msg, users=self.allclients, connected_users=self.connected_users)
+
+ def real_action(self, ip, action):
+ print_debug("real_action() ip=%s action='%s'"%(ip, action) )
+ self.main.xmlrpc.Exe(action)
+
+
+ def exe_app_in_client(self, mode, timeout=0, msg="", users=[], connected_users=[]):
+ remote_cmd=("/usr/lib/tcos/session-cmd-send %s %s %s" %(mode.upper(), timeout, msg.replace("'", "´")))
+ action="down-controller %s %s" %(mode, timeout)
+ print_debug("exe_app_in_client() usernames=%s" %users)
+
+ if len(connected_users) != 0 and connected_users[0] != shared.NO_LOGIN_MSG:
+ newusernames=[]
+ for user in connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus("exec", remote_cmd )
+ else:
+ # we have a thin client
+ newusernames.append(user)
+
+ result = self.main.dbus_action.do_exec( newusernames, remote_cmd )
+
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason:%s") %( self.main.dbus_action.get_error_msg() ) )
+
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, users, action )
+ return
+
+
+
+
+__extclass__=RebootPoweroff
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/remotessh.py b/tcosmonitor/extensions/remotessh.py
new file mode 100644
index 0000000..bafd35b
--- /dev/null
+++ b/tcosmonitor/extensions/remotessh.py
@@ -0,0 +1,57 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class RemoteSSH(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Give a remote xterm"), "menu_xterm.png", 0, self.remotessh, "shell")
+
+
+ def remotessh(self, w, ip):
+ if not self.get_client():
+ return
+ # give a remote xterm throught SSH
+ pass_msg=_("Enter password of remote thin client (if asked for it)")
+ cmd="xterm -e \"echo '%s'; ssh %s@%s || sleep 5\"" %(pass_msg, self.main.config.GetVar("ssh_remote_username"),ip)
+ print_debug ( "remotessh() cmd=%s" %(cmd) )
+ th=self.main.common.exe_cmd( cmd, verbose=0, background=True )
+
+
+
+__extclass__=RemoteSSH
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/restartxorg.py b/tcosmonitor/extensions/restartxorg.py
new file mode 100644
index 0000000..5f3420f
--- /dev/null
+++ b/tcosmonitor/extensions/restartxorg.py
@@ -0,0 +1,194 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import gtk
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class RestartXorg(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Restart X session with new settings"), "menu_newconf.png", 0, self.restartx, "xorg")
+ self.main.menus.register_all( _("Restart X session of all clients"), "menu_newconf.png" , 0, self.restartx_all, "xorg")
+
+
+ def restartx(self, w, ip):
+ if not self.get_client():
+ return
+ # restart xorg with new settings
+ # thin client must download again XXX.XXX.XXX.XXX.conf and rebuild xorg.conf
+ if self.client_type == "tcos":
+ msg=_( "Restart X session of %s with new config?" ) %(self.host)
+ if shared.ask_msg ( msg ):
+ # see xmlrpc/xorg.h, rebuild will download and sed xorg.conf.tpl
+ try:
+ self.main.xmlrpc.tc.tcos.xorg("rebuild", "--restartxorg", \
+ self.main.config.GetVar("xmlrpc_username"), \
+ self.main.config.GetVar("xmlrpc_password") )
+ except Exception, err:
+ print_debug("restartx() Exception error %s"%err)
+ self.main.xmlrpc.CheckSSL(err)
+
+ self.refresh_client_info(ip)
+ else:
+ shared.info_msg( _("%s is not supported to restart Xorg!") %(self.client_type) )
+
+ def restartx_all(self, widget):
+ if not self.get_all_clients():
+ return
+ onlythinclients=[]
+ onlythinclients_txt=""
+
+ for client in self.allclients:
+ if not self.main.xmlrpc.IsStandalone(client):
+ onlythinclients.append(client)
+ onlythinclients_txt+="\n %s" %(client)
+
+ if len(onlythinclients) == 0:
+ shared.error_msg( _("No thin clients found.") )
+ return
+
+ msg=_( _("Do you want to restart X screens (only thin clients):%s?" )%(onlythinclients_txt) )
+ if shared.ask_msg ( msg ):
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, onlythinclients, "restartx" )
+
+
+ def real_action(self, ip, action):
+ print_debug("real_action() ip=%s action='%s'"%(ip, action) )
+ self.main.xmlrpc.Exe(action)
+
+
+ def refresh_client_info(self, ip):
+ print_debug ( "refresh_client_info() updating host data..." )
+
+ inactive_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'inactive.png')
+ active_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'active.png')
+ active_ssl_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'active_ssl.png')
+
+ logged_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'logged.png')
+ unlogged_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'unlogged.png')
+
+ locked_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'locked.png')
+ locked_net_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'locked_net.png')
+ locked_net_screen_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'locked_net_screen.png')
+ unlocked_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'unlocked.png')
+ dpms_off_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'menu_dpms_off.png')
+ dpms_on_image = gtk.gdk.pixbuf_new_from_file(shared.IMG_DIR + 'menu_dpms_on.png')
+
+ # disable cache
+ self.main.localdata.cache_timeout=0
+
+ data={}
+ data['ip']=ip
+ print_debug("refresh_client_info() => get username")
+ data['username']=self.main.localdata.GetUsername(ip)
+
+ print_debug("refresh_client_info() => get hostname")
+ data['hostname']=self.main.localdata.GetHostname(ip)
+
+ if data['username'].startswith('error: tcos-last'):
+ data['username']="---"
+
+ try:
+ print_debug("refresh_client_info() => get num process")
+ data['num_process']=self.main.localdata.GetNumProcess(ip)
+ except Exception, err:
+ print_debug("refresh_client_info() Exception error=%s"%err)
+ data['num_process']="---"
+
+ print_debug("refresh_client_info() => get time logged")
+ data['time_logged']=self.main.localdata.GetTimeLogged(ip)
+
+ if not data['time_logged'] or data['time_logged'] == "" or data['time_logged'].startswith('error: tcos-last'):
+ data['time_logged']="---"
+
+ print_debug("refresh_client_info() => get active connection")
+ if self.main.localdata.IsActive(ip):
+ if self.main.xmlrpc.sslconnection:
+ data['image_active']=active_ssl_image
+ else:
+ data['image_active']=active_image
+ else:
+ data['image_active']=inactive_image
+
+ print_debug("refresh_client_info() => get is logged")
+ if self.main.localdata.IsLogged(ip):
+ data['image_logged']=logged_image
+ else:
+ data['image_logged']=unlogged_image
+
+ print_debug("refresh_client_info() => get is blocked")
+ if self.main.localdata.IsBlocked(ip):
+ data['blocked_screen']=True
+ else:
+ data['blocked_screen']=False
+
+ print_debug("refresh_client_info() => get is blocked net")
+ if self.main.localdata.IsBlockedNet(ip, data['username']):
+ data['blocked_net']=True
+ else:
+ data['blocked_net']=False
+
+ if self.main.xmlrpc.dpms('status', ip) == "Off":
+ data['dpms_off']=True
+ else:
+ data['dpms_off']=False
+
+ if data['dpms_off']:
+ data['image_blocked']=dpms_off_image
+ elif data['blocked_screen'] and data['blocked_net']:
+ data['image_blocked']=locked_net_screen_image
+ elif data['blocked_screen'] == False and data['blocked_net']:
+ data['image_blocked']=locked_net_image
+ elif data['blocked_screen'] and data['blocked_net'] == False:
+ data['image_blocked']=locked_image
+ else:
+ data['image_blocked']=unlocked_image
+
+ #enable cache again
+ self.main.localdata.cache_timeout=shared.cache_timeout
+
+ if self.main.classview.isactive():
+ self.main.classview.change_lockscreen(ip, data['image_blocked'], data['blocked_screen'], data['blocked_net'])
+ if self.main.iconview.isactive():
+ self.main.iconview.change_lockscreen(ip, data['image_blocked'], data['blocked_screen'], data['blocked_net'])
+ if self.main.listview.isactive():
+ self.main.listview.refresh_client_info(ip, data['image_blocked'])
+
+
+
+__extclass__=RestartXorg
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/screenshot.py b/tcosmonitor/extensions/screenshot.py
new file mode 100644
index 0000000..96dce48
--- /dev/null
+++ b/tcosmonitor/extensions/screenshot.py
@@ -0,0 +1,225 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+from gettext import gettext as _
+
+
+# needed for get_screenshot
+from time import localtime
+import gtk
+import os
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class Screenshot(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Screenshot"), "menu_screenshot.png", 2, self.take_screenshot, "screenshots")
+ self.main.menus.register_all( _("Capture All clients screens") , "menu_screenshot.png", 2, self.take_all_screenshots, "screenshots")
+ self.main.screenshots_action=None
+ self.__screenshot_counter=0
+ self.__screenshot_data={}
+
+ ########### SIMPLE HOST ###############
+
+ def take_screenshot(self, widget, ip):
+ if not self.get_client():
+ return
+ print_debug("take_screenshot() widget=%s ip=%s"%(widget, ip))
+
+ self.main.worker=shared.Workers(self.main, target=self.get_screenshot, args=(ip,) )
+ self.main.worker.start()
+
+ def get_screenshot(self, ip):
+ self.main.xmlrpc.newhost(ip)
+ if not self.main.xmlrpc.connected:
+ print_debug ( "get_screenshot(%s) NO CONNECTION" %(ip) )
+ self.main.common.threads_enter("TcosActions::get_screenshot writing error msg")
+ self.main.write_into_statusbar( _("Can't make screenshot, error: %s") %"NO CONNECTION" )
+ self.main.common.threads_leave("TcosActions::get_screenshot writing error msg")
+ return
+
+ # get_size
+ print_debug ( "get_screenshot() scrot_size=%s" %(self.main.config.GetVar("scrot_size")) )
+
+ # write into statusbar
+ self.main.common.threads_enter("TcosActions::get_screenshot writing wait msg")
+ self.main.write_into_statusbar ( _("Trying to order terminal to do a screenshot...") )
+ self.main.common.threads_leave("TcosActions::get_screenshot writing wait msg")
+
+ # use Base64 screenshot
+ scrot=self.main.xmlrpc.getscreenshot( self.main.config.GetVar("scrot_size") )
+ if scrot[0] != "ok":
+ #if not self.main.xmlrpc.screenshot( self.main.config.GetVar("scrot_size") ):
+ self.main.common.threads_enter("TcosActions::get_screenshot writing error msg")
+ self.main.write_into_statusbar( _("Can't make screenshot, error: %s") %scrot[1] )
+ self.main.common.threads_leave("TcosActions::get_screenshot writing error msg")
+ return False
+
+ slabel=_("Get another screenshot")
+ self.main.common.threads_enter("TcosActions::get_screenshot creating button")
+ self.main.another_screenshot_button=None
+ self.main.another_screenshot_button=gtk.Button(label=slabel )
+ self.main.another_screenshot_button.connect("clicked", self.take_screenshot, ip)
+ self.main.another_screenshot_button.show()
+ self.main.common.threads_leave("TcosActions::get_screenshot creating button")
+
+
+ print_debug ( "get_screenshot() creating button..." )
+ year, month, day, hour, minute, seconds ,wdy, yday, isdst= localtime()
+ datetxt="%02d/%02d/%4d %02d:%02d:%02d" %(day, month, year, hour, minute, seconds)
+ print_debug ( "get_screenshot() date=%s" %(datetxt) )
+
+ hostname=self.main.localdata.GetUsername(ip)
+ if hostname == shared.NO_LOGIN_MSG:
+ hostname=self.main.localdata.GetHostname(ip)
+ block_txt=_("Screenshot of <span style='font-style: italic'>%s</span>")%(hostname)
+ block_txt+="<span style='font-size: medium'> %s </span>" %(datetxt)
+ block_txt+="<span> </span><input type='button' name='self.main.another_screenshot_button' label='%s' />" %( slabel )
+
+ self.main.common.threads_enter("TcosActions::get_screenshot show capture")
+ #url="http://%s:%s/capture-thumb.jpg" %(ip, shared.httpd_port)
+ self.main.datatxt.clean()
+ self.main.datatxt.insert_block( block_txt )
+
+ #self.main.datatxt.insert_html( "<img src='%s' alt='%s'/>\n"\
+ # %(url, _("Screenshot of %s" %(ip) )) )
+
+ # Use Base64 data
+ self.main.screenshots_action=self.on_screenshot_click
+ self.__screenshot_counter=0
+ savedatetxt="%02d-%02d-%4d_%02d-%02d" %(day, month, year, hour, minute)
+ self.__screenshot_data["%s"%self.__screenshot_counter]={'hostname':hostname, 'ip':ip, 'date':savedatetxt}
+ self.main.datatxt.insert_html("""\n<img onclick="%s" base64="%s" />\n"""%(self.__screenshot_counter, scrot[1]))
+
+ self.main.common.threads_leave("TcosActions::get_screenshot show capture")
+
+ self.main.common.threads_enter("TcosActions::get_screenshot END")
+ self.main.datatxt.display()
+ self.main.write_into_statusbar ( _("Screenshot of %s, done.") %(ip) )
+ self.main.common.threads_leave("TcosActions::get_screenshot END")
+
+ return False
+
+ def on_screenshot_click(self, eventbox, event, number, pixbuf):
+ if event.button == 3:
+ ip=self.__screenshot_data[number]['ip']
+ self.main.force_selected_ip=ip
+ # right click show menu
+ self.main.menus.RightClickMenuOne( None , None, ip)
+ self.main.menu.popup( None, None, None, event.button, event.time)
+ return True
+ menu=gtk.Menu()
+ save_scrot = gtk.ImageMenuItem(_("Save Screenshot"), True)
+ icon = gtk.Image()
+ icon.set_from_stock (gtk.STOCK_SAVE, gtk.ICON_SIZE_BUTTON)
+ save_scrot.set_image(icon)
+ save_scrot.connect("activate", self.save_screenshot, number, pixbuf)
+ save_scrot.show()
+ menu.append(save_scrot)
+ menu.popup( None, None, None, event.button, event.time)
+
+ def save_screenshot(self, image, number, pixbuf):
+ data=self.__screenshot_data[number]
+
+ dialog = gtk.FileChooserDialog(title=_("Select file to save screenshot..."),
+ action=gtk.FILE_CHOOSER_ACTION_SAVE,
+ buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ dialog.set_current_name( _("screenshot_of_%(hostname)s_date_%(date)s.png") %{'hostname':data['hostname'], 'date':data['date']} )
+ folder = _folder = os.environ['HOME']
+ dialog.set_current_folder(folder)
+ _filter = gtk.FileFilter()
+ _filter.set_name( _("Image Files ( *.png, *.jpg)") )
+ file_types=["*.png", "*.jpg"]
+ for elem in file_types:
+ _filter.add_pattern( elem )
+ dialog.add_filter(_filter)
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ filename=dialog.get_filename()
+ fext=filename.split('.')[-1]
+ if not fext in ['png', 'jpg']:
+ shared.error_msg( _("File must be png or jpg.") )
+ dialog.destroy()
+ return
+ params={}
+# if fext == "jpeg":
+# {"quality":"100"}
+ pixbuf.save(filename, fext, params)
+ dialog.destroy()
+
+ ########### MULTIPLE HOSTS ###############
+
+ def take_all_screenshots(self, widget):
+ if not self.get_all_clients():
+ return
+ self.main.screenshots_action=self.on_screenshot_click
+ self.main.worker=shared.Workers(self.main, None, None)
+ self.main.worker.set_for_all_action(self.action_for_clients, self.allclients, 'screenshot' )
+
+
+ def start_action(self, *args):
+ self.__screenshot_counter=0
+ self.__screenshot_data={}
+ self.main.datatxt.clean()
+ self.main.datatxt.insert_block( _("Screenshots of all hosts") )
+ self.main.datatxt.insert_html("<br/>")
+
+ def real_action(self, ip, action):
+ print_debug("real_action() ip=%s" %ip)
+ self.main.xmlrpc.newhost(ip)
+ scrot=self.main.xmlrpc.getscreenshot(self.main.config.GetVar("miniscrot_size"))
+ if scrot and scrot[0] == "ok":
+ self.__screenshot_counter+=1
+ hostname=self.main.localdata.GetUsername(ip)
+ if hostname == shared.NO_LOGIN_MSG:
+ hostname=self.main.localdata.GetHostname(ip)
+ self.main.common.threads_enter("extensions/screenshot::real_action screenshot")
+ year, month, day, hour, minute, seconds ,wdy, yday, isdst= localtime()
+ savedatetxt="%02d-%02d-%4d_%02d-%02d" %(day, month, year, hour, minute)
+ self.__screenshot_data["%s"%self.__screenshot_counter]={'hostname':hostname, 'ip':ip, 'date':savedatetxt}
+ self.main.datatxt.insert_html(
+ "<span style='background-color:#f3d160'>" +
+ "\n\t<img onclick='%s' base64='%s' title='%s' title_rotate='90' /> " %(self.__screenshot_counter, scrot[1],_( "Screenshot of %s" ) %(hostname) ) +
+ "<span style='background-color:#f3d160; color:#f3d160'>__</span>\n</span>"+
+ "")
+ self.main.common.threads_leave("extensions/screenshot::real_action screenshot")
+
+ def finish_action(self, *args):
+ self.main.datatxt.display()
+
+__extclass__=Screenshot
+
+
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/sendfiles.py b/tcosmonitor/extensions/sendfiles.py
new file mode 100644
index 0000000..c43f10e
--- /dev/null
+++ b/tcosmonitor/extensions/sendfiles.py
@@ -0,0 +1,275 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+import netifaces
+
+from shutil import copy
+import os
+import gtk
+import sys
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class SendFiles(TcosExtension):
+ def register(self):
+ self.main.actions.button_action_send=self.send_all
+ self.main.classview.class_external_send=self.send_external
+
+ self.main.menus.register_simple( _("Send files") , "menu_send.png", 2, self.send_one, "send")
+ self.main.menus.register_all( _("Send files") , "menu_send.png", 2, self.send_all, "send")
+
+ def get_ip_address(self, ifname):
+ print_debug("get_ip_address() ifname=%s" %(ifname) )
+ if not ifname in netifaces.interfaces():
+ return None
+ ip=netifaces.ifaddresses(ifname)
+ if ip.has_key(netifaces.AF_INET):
+ return ip[netifaces.AF_INET][0]['addr']
+ return None
+
+ def send_external(self, filenames):
+ if self.main.classview.ismultiple():
+ if not self.get_all_clients():
+ return
+ elif not self.get_client():
+ return
+ # action sent by vidal_joshur at gva dot es
+ # send files
+ # search for connected users
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't send files, user is not logged") )
+ return
+
+ if not os.path.isdir("/tmp/tcos_share"):
+ shared.info_msg( _("TcosMonitor: FTP+TLS server is not running.") )
+ return
+
+ for filename in os.listdir("/tmp/tcos_share/"):
+ if os.path.isfile("/tmp/tcos_share/%s" %filename):
+ os.remove("/tmp/tcos_share/%s" %filename)
+
+ open="True"
+ basenames = ""
+ for filename in filenames:
+ basenames += "%s\n" % ( os.path.basename(filename[7:]) )
+ copy(filename[7:], "/tmp/tcos_share/")
+ os.chmod("/tmp/tcos_share/%s" %os.path.basename(filename[7:]), 0644)
+ self.main.write_into_statusbar( _("Waiting for send files...") )
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ usern, ip=user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ server=self.main.xmlrpc.GetStandalone("get_server")
+ self.main.xmlrpc.DBus("sendfiles", "%s %s %s" %(_("Teacher"), server, open) )
+ self.main.xmlrpc.DBus("mess", _("Teacher has sent some files to %(teacher)s folder:\n\n%(basenames)s") %{"teacher":_("Teacher"), "basenames":basenames})
+ else:
+ newusernames.append(user)
+
+ interface=self.main.config.GetVar("network_interface")
+ # maybe we the x remote display is other than tcosmonitor server
+ server=self.get_ip_address(interface)
+ result = self.main.dbus_action.do_sendfiles( newusernames , _("Teacher"), server, open)
+
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason:%s") %( self.main.dbus_action.get_error_msg() ) )
+ self.main.write_into_statusbar( _("Error creating destination folder.") )
+ else:
+ result = self.main.dbus_action.do_message(newusernames ,
+ _("Teacher has sent some files to %(teacher)s folder:\n\n%(basenames)s") %{"teacher":_("Teacher"), "basenames":basenames} )
+
+ self.main.write_into_statusbar( _("Files sent.") )
+
+
+ def send_one(self, widget, ip):
+ if not self.get_client():
+ return
+ # action sent by vidal_joshur at gva dot es
+ # send files
+ # search for connected users
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't send files, user is not logged") )
+ return
+
+ str_scapes=[" ", "(", ")", "*", "!", "?", "\"", "`", "[", "]", "{", "}", ";", ":", ",", "=", "$"]
+
+ dialog = gtk.FileChooserDialog( _("Select file or files..."),
+ None,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ #dialog.set_select_multiple(select_multiple)
+ dialog.set_select_multiple(True)
+ self.folder = self._folder = os.environ['HOME']
+ dialog.set_current_folder(self.folder)
+ filter = gtk.FileFilter()
+ filter.set_name("All files")
+ filter.add_pattern("*")
+ dialog.add_filter(filter)
+
+
+ if not os.path.isdir("/tmp/tcos_share"):
+ shared.info_msg( _("TcosMonitor: FTP+TLS server is not running.") )
+ return
+
+ for filename in os.listdir("/tmp/tcos_share/"):
+ if os.path.isfile("/tmp/tcos_share/%s" %filename):
+ os.remove("/tmp/tcos_share/%s" %filename)
+
+ response = dialog.run()
+
+ if response == gtk.RESPONSE_OK:
+
+ filenames = dialog.get_filenames()
+
+ open="False"
+ basenames = ""
+ for filename in filenames:
+ basenames += "%s\n" % ( os.path.basename(filename) )
+ copy(filename, "/tmp/tcos_share/")
+ os.chmod("/tmp/tcos_share/%s" %os.path.basename(filename), 0644)
+ self.main.write_into_statusbar( _("Waiting for send files...") )
+
+ msg=_( "Do you want open file(s) on client?" )
+ if shared.ask_msg ( msg ):
+ open="True"
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ #usern, ip=user.split(":")
+ #self.main.xmlrpc.newhost(ip)
+ server=self.main.xmlrpc.GetStandalone("get_server")
+ self.main.xmlrpc.DBus("sendfiles", "%s %s %s" %(_("Teacher"), server, open) )
+ self.main.xmlrpc.DBus("mess", _("Teacher has sent some files to %(teacher)s folder:\n\n%(basenames)s") %{"teacher":_("Teacher"), "basenames":basenames})
+ else:
+ newusernames.append(user)
+
+ interface=self.main.config.GetVar("network_interface")
+ # maybe we the x remote display is other than tcosmonitor server
+ server=self.get_ip_address(interface)
+ result = self.main.dbus_action.do_sendfiles( newusernames , _("Teacher"), server, open)
+
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason:%s") %( self.main.dbus_action.get_error_msg() ) )
+ self.main.write_into_statusbar( _("Error creating destination folder.") )
+ else:
+ result = self.main.dbus_action.do_message(newusernames ,
+ _("Teacher has sent some files to %(teacher)s folder:\n\n%(basenames)s") %{"teacher":_("Teacher"), "basenames":basenames} )
+ self.main.write_into_statusbar( _("Files sent.") )
+ dialog.destroy()
+
+ def send_all(self, *args):
+ if not self.get_all_clients():
+ return
+ # action sent by vidal_joshur at gva dot es
+ # send files
+ # search for connected users
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("No users logged.") )
+ return
+
+ str_scapes=[" ", "(", ")", "*", "!", "?", "\"", "`", "[", "]", "{", "}", ";", ":", ",", "=", "$"]
+
+ dialog = gtk.FileChooserDialog( _("Select file or files..."),
+ None,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ #dialog.set_select_multiple(select_multiple)
+ dialog.set_select_multiple(True)
+ self.folder = self._folder = os.environ['HOME']
+ dialog.set_current_folder(self.folder)
+ filter = gtk.FileFilter()
+ filter.set_name("All files")
+ filter.add_pattern("*")
+ dialog.add_filter(filter)
+
+
+ if not os.path.isdir("/tmp/tcos_share"):
+ shared.info_msg( _("TcosMonitor: FTP+TLS server is not running.") )
+ return
+
+ for filename in os.listdir("/tmp/tcos_share/"):
+ if os.path.isfile("/tmp/tcos_share/%s" %filename):
+ os.remove("/tmp/tcos_share/%s" %filename)
+
+ response = dialog.run()
+
+ if response == gtk.RESPONSE_OK:
+
+ filenames = dialog.get_filenames()
+
+ open="False"
+ basenames = ""
+ for filename in filenames:
+ basenames += "%s\n" % ( os.path.basename(filename) )
+ copy(filename, "/tmp/tcos_share/")
+ os.chmod("/tmp/tcos_share/%s" %os.path.basename(filename), 0644)
+ self.main.write_into_statusbar( _("Waiting for send files...") )
+
+ msg=_( "Do you want open file(s) on client?" )
+ if shared.ask_msg ( msg ):
+ open="True"
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ usern, ip=user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ server=self.main.xmlrpc.GetStandalone("get_server")
+ self.main.xmlrpc.DBus("sendfiles", "%s %s %s" %(_("Teacher"), server, open) )
+ self.main.xmlrpc.DBus("mess", _("Teacher has sent some files to %(teacher)s folder:\n\n%(basenames)s") %{"teacher":_("Teacher"), "basenames":basenames})
+ else:
+ newusernames.append(user)
+
+ interface=self.main.config.GetVar("network_interface")
+ # maybe we the x remote display is other than tcosmonitor server
+ server=self.get_ip_address(interface)
+ result = self.main.dbus_action.do_sendfiles( newusernames , _("Teacher"), server, open)
+
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason:%s") %( self.main.dbus_action.get_error_msg() ) )
+ self.main.write_into_statusbar( _("Error creating destination folder.") )
+ else:
+ result = self.main.dbus_action.do_message(newusernames ,
+ _("Teacher has sent some files to %(teacher)s folder:\n\n%(basenames)s") %{"teacher":_("Teacher"), "basenames":basenames} )
+
+ self.main.write_into_statusbar( _("Files sent.") )
+ dialog.destroy()
+
+
+__extclass__=SendFiles
diff --git a/tcosmonitor/extensions/tcosnetcontroller.py b/tcosmonitor/extensions/tcosnetcontroller.py
new file mode 100644
index 0000000..ff31be7
--- /dev/null
+++ b/tcosmonitor/extensions/tcosnetcontroller.py
@@ -0,0 +1,188 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class TcosNetController(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Lock internet"), "menu_locknet.png", 1, self.locknet_simple, "net")
+ self.main.menus.register_simple( _("Unlock internet"), "menu_unlocknet.png", 1, self.unlocknet_simple, "net")
+
+ self.main.menus.register_all( _("Lock internet in all connected users"), "menu_locknet.png", 1, self.locknet_all, "net")
+ self.main.menus.register_all( _("Unlock internet in all connected users"), "menu_unlocknet.png", 1, self.unlocknet_all, "net")
+
+ def locknet_simple(self, w, ip):
+ if not self.get_client():
+ return
+ # lock net
+ eth=self.main.config.GetVar("network_interface")
+ ports="--ports=%s" %self.main.config.GetVar("ports_tnc")
+ remote_msg=_("Internet connection has been disabled")
+ act="disable-internet"
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't disable internet, user is not logged") )
+ return
+
+ if self.client_type == "tcos":
+ if not self.main.localdata.user_in_group(None, 'tcos'):
+ msg=(_("In order to lock and unlock internet you need to be in 'tcos' group.\n\nExe by root: adduser %s tcos" ) %(self.main.localdata.get_username()))
+ shared.error_msg ( msg )
+ return
+ result = self.main.localdata.BlockNet(act, self.connected_users[0], ports, eth)
+ if result == "disabled":
+ self.main.dbus_action.do_message( self.connected_users, remote_msg )
+ else:
+ result = self.main.xmlrpc.tnc(act, self.connected_users[0].split(":")[0], ports)
+ if result == "disabled":
+ self.main.xmlrpc.DBus("mess", remote_msg)
+
+ self.change_lockscreen(ip)
+
+
+ def unlocknet_simple(self, w, ip):
+ if not self.get_client():
+ return
+ # unlock net
+ remote_msg=_("Internet connection has been enabled")
+ act="enable-internet"
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't enable internet, user is not logged") )
+ return
+ if self.client_type == "tcos":
+ if not self.main.localdata.user_in_group(None, 'tcos'):
+ msg=(_("In order to lock and unlock internet you need to be in 'tcos' group.\n\nExe by root: adduser %s tcos" ) %(self.main.localdata.get_username()))
+ shared.error_msg ( msg )
+ return
+ result = self.main.localdata.BlockNet(act, self.connected_users[0])
+ if result == "enabled":
+ self.main.dbus_action.do_message( self.connected_users, remote_msg )
+ else:
+ result = self.main.xmlrpc.tnc(act, self.connected_users[0].split(":")[0])
+ if result == "enabled":
+ self.main.xmlrpc.DBus("mess", remote_msg)
+
+ self.change_lockscreen(ip)
+
+
+ def locknet_all(self, *args):
+ if not self.get_all_clients():
+ return
+ if not self.main.localdata.user_in_group(None, 'tcos'):
+ msg=(_("In order to lock and unlock internet you need to be in 'tcos' group.\n\nExe by root: adduser %s tcos" ) %(self.main.localdata.get_username()))
+ shared.error_msg ( msg )
+ return
+ # disable internet
+ eth=self.main.config.GetVar("network_interface")
+ ports="--ports=%s" %self.main.config.GetVar("ports_tnc")
+ remote_msg=_("Internet connection has been disabled")
+ act="disable-internet"
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("No users logged.") )
+ return
+
+ msg=_( _("Do you want disable internet to following users: %s?" )%(self.connected_users_txt) )
+
+ if not shared.ask_msg ( msg ):
+ return
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ usern, ip=user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ result = self.main.xmlrpc.tnc(act, usern, ports)
+ if result == "disabled":
+ self.main.xmlrpc.DBus("mess", remote_msg)
+ else:
+ result = self.main.localdata.BlockNet(act, user, ports, eth)
+ if result == "disabled":
+ newusernames.append(user)
+
+ result = self.main.dbus_action.do_message( newusernames, remote_msg )
+
+ for client in self.newallclients:
+ self.main.localdata.newhost(client)
+ self.main.xmlrpc.newhost(client)
+ self.change_lockscreen(client)
+
+
+ def unlocknet_all(self, *args):
+ if not self.get_all_clients():
+ return
+ if not self.main.localdata.user_in_group(None, 'tcos'):
+ msg=(_("In order to lock and unlock internet you need to be in 'tcos' group.\n\nExe by root: adduser %s tcos" ) %(self.main.localdata.get_username()))
+ shared.error_msg ( msg )
+ return
+ # enable internet
+ remote_msg=_("Internet connection has been enabled")
+ act="enable-internet"
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("No users logged.") )
+ return
+
+ msg=_( _("Do you want enable internet to following users: %s?" )%(self.connected_users_txt) )
+
+ if not shared.ask_msg ( msg ):
+ return
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ usern, ip=user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ result = self.main.xmlrpc.tnc(act, usern)
+ if result == "enabled":
+ self.main.xmlrpc.DBus("mess", remote_msg)
+ else:
+ result = self.main.localdata.BlockNet(act, user)
+ if result == "enabled":
+ newusernames.append(user)
+
+ result = self.main.dbus_action.do_message( newusernames, remote_msg )
+
+ for client in self.newallclients:
+ self.main.localdata.newhost(client)
+ self.main.xmlrpc.newhost(client)
+ self.change_lockscreen(client)
+
+
+__extclass__=TcosNetController
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/tcospersonalize.py b/tcosmonitor/extensions/tcospersonalize.py
new file mode 100644
index 0000000..14b574f
--- /dev/null
+++ b/tcosmonitor/extensions/tcospersonalize.py
@@ -0,0 +1,61 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import os
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class TcosPersonalize(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Configure this host"), "menu_configure.png", 0, self.launch_tcospersonalize, "personalize")
+
+
+ def launch_tcospersonalize(self, w, ip):
+ if not self.get_client():
+ return
+ if self.client_type == "tcos":
+ if self.main.ingroup_tcos == False and os.getuid() != 0:
+ cmd="gksu \"tcospersonalize --host=%s\"" %(ip)
+ else:
+ cmd="tcospersonalize --host=%s" %(ip)
+ print_debug ( "launch_tcospersonalize() cmd=%s" %(cmd) )
+ th=self.main.common.exe_cmd( cmd, verbose=0, background=True )
+ else:
+ shared.info_msg( _("%s is not supported to personalize!") %(self.client_type) )
+
+
+
+__extclass__=TcosPersonalize
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/videolan.py b/tcosmonitor/extensions/videolan.py
new file mode 100644
index 0000000..3824d1f
--- /dev/null
+++ b/tcosmonitor/extensions/videolan.py
@@ -0,0 +1,648 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+import os
+import gtk
+import subprocess
+import signal
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class VideoOne(TcosExtension):
+ def register(self):
+ self.vlc_count={}
+ self.main.classview.class_external_video=self.video_external
+ self.main.actions.button_action_video=self.video_all
+
+ self.main.menus.register_simple( _("Send Audio/Video broadcast") , "menu_broadcast.png", 2, self.video_one, "video")
+ self.main.menus.register_all( _("Send Audio/Video broadcast") , "menu_broadcast.png", 2, self.video_all, "video")
+
+
+
+ def video_external(self, filename):
+ if self.main.classview.ismultiple():
+ if not self.get_all_clients():
+ return
+ elif not self.get_client():
+ return
+ # action sent by vidal_joshur at gva dot es
+ # start video broadcast mode
+ # Stream to single client unicast
+ eth=self.main.config.GetVar("network_interface")
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't send video broadcast, user is not logged") )
+ return
+
+ str_scapes=[" ", "(", ")", "*", "!", "?", "\"", "`", "[", "]", "{", "}", ";", ":", ",", "=", "$"]
+ lock="disable"
+ volume="85"
+
+ if self.main.pref_vlc_method_send.get_active() == 0:
+ vcodec=shared.vcodecs[0]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 1:
+ vcodec=shared.vcodecs[1]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 2:
+ vcodec=shared.vcodecs[2]
+ venc=shared.vencs[1]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 3:
+ vcodec=shared.vcodecs[3]
+ venc=shared.vencs[2]
+ acodec=shared.acodecs[1]
+ aenc=shared.aencs[1]
+ access=shared.accesss[1]
+ mux=shared.muxs[1]
+ elif self.main.pref_vlc_method_send.get_active() == 4:
+ vcodec=shared.vcodecs[1]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[1]
+ aenc=shared.aencs[1]
+ access=shared.accesss[1]
+ mux=shared.muxs[1]
+
+ if access == "udp":
+ max_uip=255
+ uip=0
+ while uip <= max_uip:
+ uip_cmd="239.254.%s.0" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0":
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_broadcast="%s:1234" %uip_cmd
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+ else:
+ max_uip=50255
+ uip=50000
+ while uip <= max_uip:
+ uip_cmd=":%s" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0":
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_broadcast=uip_cmd
+ uip_cmd=""
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+
+ if uip_cmd != "":
+ result = self.main.localdata.Route("route-add", uip_cmd, "255.255.255.0", eth)
+ if result == "error":
+ print_debug("Add multicast-ip route failed")
+ return
+
+ if filename.find(" ") != -1:
+ msg=_("Not allowed white spaces in \"%s\".\nPlease rename it." %os.path.basename(filename) )
+ shared.info_msg( msg )
+ return
+
+ if access == "udp":
+ remote_cmd_standalone="vlc udp://@%s --udp-caching=1000 --aout=alsa --brightness=2.000000 --volume=300 --fullscreen --aspect-ratio=4:3 --loop" %(ip_broadcast)
+ remote_cmd_thin="vlc udp://@%s --udp-caching=1000 --aout=alsa --brightness=2.000000 --volume=300 --aspect-ratio=4:3 --loop" %(ip_broadcast)
+
+ p=subprocess.Popen(["vlc", "file://%s" %filename, "--sout=#duplicate{dst=display{delay=1000},dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=800,ab=112,channels=2,soverlay}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_broadcast), "--miface=%s" %eth, "--ttl=12", "--brightness=2.000000"], shell=False, bufsize=0, close_fds=True)
+
+ self.main.write_into_statusbar( _("Waiting for start video transmission...") )
+
+ #msg=_("First select the DVD chapter or play movie\nthen press enter to send client..." )
+ #shared.info_msg( msg )
+
+ # check if vlc is running or fail like check ping in demo mode
+ running = p.poll() is None
+ if not running:
+ self.main.write_into_statusbar( _("Error while exec app"))
+ return
+
+ #msg=_( "Lock keyboard and mouse on client?" )
+ #if shared.ask_msg ( msg ):
+ # lock="enable"
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ if access == "http":
+ server=self.main.xmlrpc.GetStandalone("get_server")
+ remote_cmd_standalone="vlc http://%s%s --aout=alsa --brightness=2.000000 --volume=300 --fullscreen --aspect-ratio=4:3 --http-reconnect --loop" %(server, ip_broadcast)
+ self.main.xmlrpc.DBus("exec", remote_cmd_standalone )
+ else:
+ newusernames.append(user)
+
+ if access == "http":
+ remote_cmd_thin="vlc http://localhost%s --aout=alsa --brightness=2.000000 --volume=300 --aspect-ratio=4:3 --http-reconnect --loop" % (ip_broadcast)
+
+ result = self.main.dbus_action.do_exec( newusernames, remote_cmd_thin )
+
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason:%s") %( self.main.dbus_action.get_error_msg() ) )
+
+ for client in self.newallclients:
+ self.main.xmlrpc.vlc( client, volume, lock )
+
+ self.main.write_into_statusbar( _("Running in broadcast video transmission.") )
+ # new mode to Stop Button
+ if len(self.vlc_count.keys()) != 0:
+ count=len(self.vlc_count.keys())-1
+ nextkey=self.vlc_count.keys()[count]+1
+ self.vlc_count[nextkey]=uip_cmd
+ else:
+ nextkey=1
+ self.vlc_count[nextkey]=uip_cmd
+ self.add_progressbox( {"target": "vlc", "pid":p.pid, "lock":lock, "allclients":self.newallclients, "ip":uip_cmd, "iface":eth, "key":nextkey}, _("Running in broadcast video transmission to user %(host)s. Broadcast Nº %(count)s") %{"host":self.connected_users_txt, "count":nextkey} )
+
+ def video_one(self, widget, ip):
+ if not self.get_client():
+ return
+ # action sent by vidal_joshur at gva dot es
+ # start video broadcast mode
+ # Stream to single client unicast
+ eth=self.main.config.GetVar("network_interface")
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't send video broadcast, user is not logged") )
+ return
+
+ str_scapes=[" ", "(", ")", "*", "!", "?", "\"", "`", "[", "]", "{", "}", ";", ":", ",", "=", "$"]
+ lock="disable"
+ volume="85"
+
+ if self.main.pref_vlc_method_send.get_active() == 0:
+ vcodec=shared.vcodecs[0]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 1:
+ vcodec=shared.vcodecs[1]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 2:
+ vcodec=shared.vcodecs[2]
+ venc=shared.vencs[1]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 3:
+ vcodec=shared.vcodecs[3]
+ venc=shared.vencs[2]
+ acodec=shared.acodecs[1]
+ aenc=shared.aencs[1]
+ access=shared.accesss[1]
+ mux=shared.muxs[1]
+ elif self.main.pref_vlc_method_send.get_active() == 4:
+ vcodec=shared.vcodecs[1]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[1]
+ aenc=shared.aencs[1]
+ access=shared.accesss[1]
+ mux=shared.muxs[1]
+
+
+ if access == "udp":
+ if self.client_type == "tcos":
+ max_uip=255
+ uip=0
+ while uip <= max_uip:
+ uip_cmd="239.254.%s.0" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0":
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_unicast="%s:1234" %uip_cmd
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+ remote_cmd="vlc udp://@%s --udp-caching=1000 --aout=alsa --brightness=2.000000 --volume=300 --aspect-ratio=4:3 --loop" %(ip_unicast)
+ else:
+ uip_cmd=""
+ ip_unicast="%s:1234" %self.main.selected_ip
+ remote_cmd="vlc udp://@:1234 --udp-caching=1000 --aout=alsa --brightness=2.000000 --volume=300 --fullscreen --aspect-ratio=4:3 --loop"
+ else:
+ max_uip=50255
+ uip=50000
+ while uip <= max_uip:
+ uip_cmd=":%s" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0":
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_unicast=uip_cmd
+ uip_cmd=""
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+ if self.client_type == "tcos":
+ remote_cmd="vlc http://localhost%s --aout=alsa --brightness=2.000000 --volume=300 --aspect-ratio=4:3 --http-reconnect --loop" %(ip_unicast)
+
+ if uip_cmd != "":
+ result = self.main.localdata.Route("route-add", uip_cmd, "255.255.255.0", eth)
+ if result == "error":
+ print_debug("Add multicast-ip route failed")
+ return
+
+ dialog = gtk.FileChooserDialog(_("Select audio/video file.."),
+ None,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (_("Play DVD"), 1,
+ _("Play SVCD/VCD"), 2,
+ _("Play AudioCD"), 3,
+ gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ self.folder = self._folder = os.environ['HOME']
+ dialog.set_current_folder(self.folder)
+ filter = gtk.FileFilter()
+ filter.set_name("Media Files ( *.avi, *.mpg, *.mpeg, *.mp3, *.wav, etc.. )")
+ file_types=["*.avi", "*.mpg", "*.mpeg", "*.ogg", "*.ogm", "*.asf", "*.divx",
+ "*.wmv", "*.vob", "*.m2v", "*.m4v", "*.mp2", "*.mp4", "*.ac3",
+ "*.ogg", "*.mp1", "*.mp2", "*.mp3", "*.wav", "*.wma"]
+ for elem in file_types:
+ filter.add_pattern( elem )
+
+ dialog.add_filter(filter)
+
+ filter = gtk.FileFilter()
+ filter.set_name("All Files")
+ filter.add_pattern("*.*")
+ dialog.add_filter(filter)
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK or response == 1 or response == 2 or response == 3:
+
+ filename=dialog.get_filename()
+ dialog.destroy()
+
+ #for scape in str_scapes:
+ # filename=filename.replace("%s" %scape, "\%s" %scape)
+
+ if response == gtk.RESPONSE_OK:
+ if filename.find(" ") != -1:
+ msg=_("Not allowed white spaces in \"%s\".\nPlease rename it." %os.path.basename(filename) )
+ shared.info_msg( msg )
+ return
+ p=subprocess.Popen(["vlc", "file://%s" %filename, "--sout=#duplicate{dst=display{delay=1000},dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=800,ab=112,channels=2,soverlay}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_unicast), "--miface=%s" %eth, "--ttl=12", "--brightness=2.000000"], shell=False, bufsize=0, close_fds=True)
+ elif response == 1:
+ p=subprocess.Popen(["vlc", "dvdsimple:///dev/cdrom", "--sout=#duplicate{dst=display{delay=700},dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=800,ab=112,channels=2,soverlay}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_unicast), "--miface=%s" %eth, "--ttl=12", "--loop", "--brightness=2.000000"], shell=False, bufsize=0, close_fds=True)
+ elif response == 2:
+ p=subprocess.Popen(["vlc", "vcd:///dev/cdrom", "--sout=#duplicate{dst=display{delay=1000},dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=800,ab=112,channels=2,soverlay}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_unicast), "--miface=%s" %eth, "--ttl=12", "--brightness=2.000000"], shell=False, bufsize=0, close_fds=True)
+ elif response == 3:
+ p=subprocess.Popen(["vlc", "cdda:///dev/cdrom", "--sout=#duplicate{dst=display,dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=200,ab=112,channels=2}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_unicast), "--miface=%s" %eth, "--ttl=12"], shell=False, bufsize=0, close_fds=True)
+ # exec this app on client
+
+ self.main.write_into_statusbar( _("Waiting for start video transmission...") )
+
+ msg=_("First select the DVD chapter or play movie\nthen press enter to send clients..." )
+ shared.info_msg( msg )
+
+ # check if vlc is running or fail like check ping in demo mode
+ running = p.poll() is None
+ if not running:
+ self.main.write_into_statusbar( _("Error while exec app"))
+ return
+
+ msg=_( "Lock keyboard and mouse on client?" )
+ if shared.ask_msg ( msg ):
+ lock="enable"
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ if access == "http":
+ server=self.main.xmlrpc.GetStandalone("get_server")
+ remote_cmd="vlc http://%s%s --aout=alsa --brightness=2.000000 --volume=300 --fullscreen --aspect-ratio=4:3 --http-reconnect --loop" %(server, ip_unicast)
+ self.main.xmlrpc.DBus("exec", remote_cmd )
+ else:
+ newusernames.append(user)
+
+ result = self.main.dbus_action.do_exec( newusernames, remote_cmd )
+
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason:%s") %( self.main.dbus_action.get_error_msg() ) )
+
+ self.main.xmlrpc.vlc( self.main.selected_ip, volume, lock )
+
+ self.main.write_into_statusbar( _("Running in broadcast video transmission.") )
+ # new mode to Stop Button
+ if len(self.vlc_count.keys()) != 0:
+ count=len(self.vlc_count.keys())-1
+ nextkey=self.vlc_count.keys()[count]+1
+ self.vlc_count[nextkey]=uip_cmd
+ else:
+ nextkey=1
+ self.vlc_count[nextkey]=uip_cmd
+ self.add_progressbox( {"target": "vlc", "pid":p.pid, "lock":lock, "allclients":self.newallclients, "ip":uip_cmd, "iface":eth, "key":nextkey}, _("Running in broadcast video transmission to user %(host)s. Broadcast Nº %(count)s") %{"host":self.connected_users_txt, "count":nextkey} )
+ else:
+ dialog.destroy()
+
+ def on_progressbox_click(self, widget, args, box):
+ box.destroy()
+ print_debug("on_progressbox_click() widget=%s, args=%s, box=%s" %(widget, args, box) )
+
+ if not args['target']:
+ return
+
+ self.main.stop_running_actions.remove(widget)
+
+ if args['target'] == "vlc":
+ del self.vlc_count[args['key']]
+ if args['ip'] != "":
+ result = self.main.localdata.Route("route-del", args['ip'], "255.255.255.0", args['iface'])
+ if result == "error":
+ print_debug("Del multicast-ip route failed")
+ connected_users=[]
+ for client in args['allclients']:
+ self.main.localdata.newhost(client)
+ if self.main.localdata.IsLogged(client):
+ if args['lock'] == "enable":
+ self.main.xmlrpc.unlockcontroller("lockvlc", client)
+ connected_users.append(self.main.localdata.GetUsernameAndHost(client))
+
+ newusernames=[]
+
+ for user in connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user... in some cases or after much time need SIGKILL vlc
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus("killall", "-s KILL vlc" )
+ else:
+ newusernames.append(user)
+
+ result = self.main.dbus_action.do_killall( newusernames , "-s KILL vlc" )
+
+ if "pid" in args:
+ os.kill(args['pid'], signal.SIGKILL)
+ else:
+ self.main.common.exe_cmd("killall -s KILL vlc", verbose=0, background=True)
+ self.main.write_into_statusbar( _("Video broadcast stopped.") )
+
+
+ def video_all(self, *args):
+ if not self.get_all_clients():
+ return
+ # action sent by vidal_joshur at gva dot es
+ # start video broadcast mode
+ # search for connected users
+ # Stream to multiple clients
+ eth=self.main.config.GetVar("network_interface")
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("No users logged.") )
+ return
+
+ str_scapes=[" ", "(", ")", "*", "!", "?", "\"", "`", "[", "]", "{", "}", ";", ":", ",", "=", "$"]
+
+ if self.main.pref_vlc_method_send.get_active() == 0:
+ vcodec=shared.vcodecs[0]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 1:
+ vcodec=shared.vcodecs[1]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 2:
+ vcodec=shared.vcodecs[2]
+ venc=shared.vencs[1]
+ acodec=shared.acodecs[0]
+ aenc=shared.aencs[0]
+ access=shared.accesss[0]
+ mux=shared.muxs[0]
+ elif self.main.pref_vlc_method_send.get_active() == 3:
+ vcodec=shared.vcodecs[3]
+ venc=shared.vencs[2]
+ acodec=shared.acodecs[1]
+ aenc=shared.aencs[1]
+ access=shared.accesss[1]
+ mux=shared.muxs[1]
+ elif self.main.pref_vlc_method_send.get_active() == 4:
+ vcodec=shared.vcodecs[1]
+ venc=shared.vencs[0]
+ acodec=shared.acodecs[1]
+ aenc=shared.aencs[1]
+ access=shared.accesss[1]
+ mux=shared.muxs[1]
+
+ if access == "udp":
+ max_uip=255
+ uip=0
+ while uip <= max_uip:
+ uip_cmd="239.254.%s.0" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0":
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_broadcast="%s:1234" %uip_cmd
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+ else:
+ max_uip=50255
+ uip=50000
+ while uip <= max_uip:
+ uip_cmd=":%s" %(uip)
+ cmd=("LC_ALL=C LC_MESSAGES=C netstat -putan 2>/dev/null | grep -c %s" %(uip_cmd) )
+ print_debug("Check broadcast ip %s." %(uip_cmd) )
+ output=self.main.common.exe_cmd(cmd)
+ uip+=1
+ if output == "0":
+ print_debug("Broadcast ip found: %s" %(uip_cmd))
+ ip_broadcast=uip_cmd
+ uip_cmd=""
+ break
+ elif uip == max_uip:
+ print_debug("Not found an available broadcast ip")
+ return
+
+ lock="disable"
+ volume="85"
+
+ if uip_cmd != "":
+ result = self.main.localdata.Route("route-add", uip_cmd, "255.255.255.0", eth)
+ if result == "error":
+ print_debug("Add multicast-ip route failed")
+ return
+
+ dialog = gtk.FileChooserDialog(_("Select audio/video file.."),
+ None,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (_("Play DVD"), 1,
+ _("Play SVCD/VCD"), 2,
+ _("Play AudioCD"), 3,
+ gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ self.folder = self._folder = os.environ['HOME']
+ dialog.set_current_folder(self.folder)
+ filter = gtk.FileFilter()
+ filter.set_name("Media Files ( *.avi, *.mpg, *.mpeg, *.mp3, *.wav, etc.. )")
+ file_types=["*.avi", "*.mpg", "*.mpeg", "*.ogg", "*.ogm", "*.asf", "*.divx",
+ "*.wmv", "*.vob", "*.m2v", "*.m4v", "*.mp2", "*.mp4", "*.ac3",
+ "*.ogg", "*.mp1", "*.mp2", "*.mp3", "*.wav", "*.wma"]
+ for elem in file_types:
+ filter.add_pattern( elem )
+
+ dialog.add_filter(filter)
+
+ filter = gtk.FileFilter()
+ filter.set_name("All Files")
+ filter.add_pattern("*.*")
+ dialog.add_filter(filter)
+
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK or response == 1 or response == 2 or response == 3:
+
+ filename=dialog.get_filename()
+ dialog.destroy()
+
+ #for scape in str_scapes:
+ # filename=filename.replace("%s" %scape, "\%s" %scape)
+
+ if response == gtk.RESPONSE_OK:
+ if filename.find(" ") != -1:
+ msg=_("Not allowed white spaces in \"%s\".\nPlease rename it." %os.path.basename(filename) )
+ shared.info_msg( msg )
+ return
+ p=subprocess.Popen(["vlc", "file://%s" %filename, "--sout=#duplicate{dst=display{delay=1000},dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=800,ab=112,channels=2,soverlay}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_broadcast), "--miface=%s" %eth, "--ttl=12", "--brightness=2.000000"], shell=False, bufsize=0, close_fds=True)
+ elif response == 1:
+ p=subprocess.Popen(["vlc", "dvdsimple:///dev/cdrom", "--sout=#duplicate{dst=display{delay=700},dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=800,ab=112,channels=2,soverlay}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_broadcast), "--miface=%s" %eth, "--ttl=12", "--loop", "--brightness=2.000000"], shell=False, bufsize=0, close_fds=True)
+ elif response == 2:
+ p=subprocess.Popen(["vlc", "vcd:///dev/cdrom", "--sout=#duplicate{dst=display{delay=1000},dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=800,ab=112,channels=2,soverlay}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_broadcast), "--miface=%s" %eth, "--ttl=12", "--brightness=2.000000"], shell=False, bufsize=0, close_fds=True)
+ elif response == 3:
+ p=subprocess.Popen(["vlc", "cdda:///dev/cdrom", "--sout=#duplicate{dst=display,dst=\"transcode{vcodec=%s,venc=%s,acodec=%s,aenc=%s,vb=200,ab=112,channels=2}:standard{access=%s,mux=%s,dst=%s}\"}" %(vcodec, venc, acodec, aenc, access, mux, ip_broadcast), "--miface=%s" %eth, "--ttl=12"], shell=False, bufsize=0, close_fds=True)
+ # exec this app on client
+
+ if access == "udp":
+ remote_cmd_standalone="vlc udp://@%s --udp-caching=1000 --aout=alsa --brightness=2.000000 --volume=300 --fullscreen --aspect-ratio=4:3 --loop" %(ip_broadcast)
+ remote_cmd_thin="vlc udp://@%s --udp-caching=1000 --aout=alsa --brightness=2.000000 --volume=300 --aspect-ratio=4:3 --loop" %(ip_broadcast)
+
+ self.main.write_into_statusbar( _("Waiting for start video transmission...") )
+
+ msg=_("First select the DVD chapter or play movie\nthen press enter to send clients..." )
+ shared.info_msg( msg )
+
+ # check if vlc is running or fail like check ping in demo mode
+ running = p.poll() is None
+ if not running:
+ self.main.write_into_statusbar( _("Error while exec app"))
+ return
+
+ msg=_( "Lock keyboard and mouse on clients?" )
+ if shared.ask_msg ( msg ):
+ lock="enable"
+
+ newusernames=[]
+
+ for user in self.connected_users:
+ if user.find(":") != -1:
+ # we have a standalone user...
+ usern, ip = user.split(":")
+ self.main.xmlrpc.newhost(ip)
+ if access == "http":
+ server=self.main.xmlrpc.GetStandalone("get_server")
+ remote_cmd_standalone="vlc http://%s%s --aout=alsa --brightness=2.000000 --volume=300 --fullscreen --aspect-ratio=4:3 --http-reconnect --loop" %(server, ip_broadcast)
+ self.main.xmlrpc.DBus("exec", remote_cmd_standalone )
+ else:
+ newusernames.append(user)
+
+ if access == "http":
+ remote_cmd_thin="vlc http://localhost%s --aout=alsa --brightness=2.000000 --volume=300 --aspect-ratio=4:3 --http-reconnect --loop" % (ip_broadcast)
+
+ result = self.main.dbus_action.do_exec( newusernames, remote_cmd_thin )
+
+ if not result:
+ shared.error_msg ( _("Error while exec remote app:\nReason:%s") %( self.main.dbus_action.get_error_msg() ) )
+
+ for client in self.newallclients:
+ self.main.xmlrpc.vlc( client, volume, lock )
+
+ self.main.write_into_statusbar( _("Running in broadcast video transmission.") )
+ # new mode Stop Button
+ if len(self.vlc_count.keys()) != 0:
+ count=len(self.vlc_count.keys())-1
+ nextkey=self.vlc_count.keys()[count]+1
+ self.vlc_count[nextkey]=uip_cmd
+ else:
+ nextkey=1
+ self.vlc_count[nextkey]=uip_cmd
+ self.add_progressbox( {"target": "vlc", "pid":p.pid, "lock":lock, "allclients": self.newallclients, "ip":uip_cmd, "iface":eth, "key":nextkey}, _("Running in broadcast video transmission. Broadcast Nº %s") %(nextkey) )
+ else:
+ dialog.destroy()
+
+
+
+__extclass__=VideoOne
diff --git a/tcosmonitor/extensions/viewproc.py b/tcosmonitor/extensions/viewproc.py
new file mode 100644
index 0000000..6d7923e
--- /dev/null
+++ b/tcosmonitor/extensions/viewproc.py
@@ -0,0 +1,139 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+import gtk
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class ViewProc(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Show running apps of this client") , "menu_proc.png", 1, self.viewproc, "show")
+
+
+ def viewproc(self, widget, ip):
+ if not self.get_client():
+ return
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't show runnings apps, user is not logged") )
+ return
+ self.get_user_processes(ip)
+
+
+ def get_user_processes(self, ip):
+ """get user processes in session"""
+ print_debug( "get_user_processes(%s) __init__" %ip )
+ #check user is connected
+ if not self.main.localdata.IsLogged(ip):
+ shared.info_msg( _("User not connected, no processes.") )
+ return
+
+
+ if self.main.xmlrpc.IsStandalone(ip):
+ username=self.main.localdata.GetUsernameAndHost(ip)
+ tmp=self.main.xmlrpc.ReadInfo("get_process")
+ if tmp != "":
+ process=tmp.split('|')[0:-1]
+ else:
+ process=["PID COMMAND", "66000 can't read process list"]
+ else:
+ username=self.main.localdata.GetUsername(ip)
+ cmd="LANG=C ps U \"%s\" -o pid,command | /usr/lib/tcos/clean_string.sh " %(self.main.localdata.GetUserID(username))
+ print_debug ( "get_user_processes(%s) cmd=%s " %(ip, cmd) )
+ process=self.main.common.exe_cmd(cmd, verbose=0)
+
+ self.main.datatxt.clean()
+ self.main.datatxt.insert_block( _("Running processes for user \"%s\": " ) %(username), image=shared.IMG_DIR + "info_proc.png" )
+
+ if self.main.config.GetVar("systemprocess") == "0":
+ self.main.datatxt.insert_block ( \
+ _("ALERT: There are some system process hidden. Enable it in Preferences dialog.") \
+ , image=shared.IMG_DIR + "icon_alert.png" ,\
+ color="#f08196", size="medium" )
+
+ self.main.datatxt.insert_html ( """
+ <br/><div style='margin-left: 135px; margin-right: 200px;background-color:#ead196;color:blue'>""" + _("Pid") + "\t"
+ + "\t" + _("Process command") +"</div>" )
+
+ counter=0
+ self.main.kill_proc_buttons=None
+ self.main.kill_proc_buttons=[]
+ blabel=_("Kill this process")
+
+ for proc in process:
+ is_hidden=False
+ if proc.split()[0]== "PID":
+ continue
+ pid=proc.split()[0] # not convert to int DBUS need string
+ name=" ".join(proc.split()[1:])
+ name=name.replace('<','&lt;').replace('>','&gt;')
+ name=name.replace('&','&amp;')
+
+ if int(self.main.config.GetVar("systemprocess")) == 0:
+ for hidden in shared.system_process:
+ if hidden in name:
+ is_hidden=True
+
+ if is_hidden:
+ continue
+
+ kill_button=gtk.Button(label=blabel)
+ kill_button.connect("clicked", self.on_kill_button_click, pid, username)
+ kill_button.show()
+ self.main.kill_proc_buttons.append(kill_button)
+
+ self.main.datatxt.insert_html("""
+ <span style='background-color: red; margin-left: 5px; margin-right: 0px'>
+ <input type='button' name='self.main.kill_proc_buttons' index='%d' label='%s' /></span>
+ <span style='color: red; margin-left: 140px; margin-right: 0px'> %6s</span>
+ <span style='color: blue; margin-left: 350px; margin-right: 0px'> %s</span><br />
+ """ %(counter, blabel, pid, name) )
+ counter+=1
+
+ self.main.datatxt.display()
+ return
+
+ def on_kill_button_click(self, widget, pid, username):
+ print_debug ( "on_kill_button_click() pid=%s username=%s" %(pid, username) )
+ if shared.ask_msg ( _("Are you sure you want to stop this process?") ):
+ print_debug ( "KILL KILL KILL" )
+ if username.find(":") != -1 :
+ usern, ip = username.split(":")
+ self.main.xmlrpc.newhost(ip)
+ self.main.xmlrpc.DBus("kill", str(pid) )
+ else:
+ result = self.main.dbus_action.do_kill( [username] , str(pid) )
+ if not result:
+ shared.error_msg ( _("Error while killing app:\nReason: %s") %( self.main.dbus_action.get_error_msg() ) )
+ else:
+ print_debug ( "on_kill_button_click() KILLED ;)" )
+ self.get_user_processes(self.main.selected_ip)
+
+__extclass__=ViewProc
diff --git a/tcosmonitor/extensions/vnc.py b/tcosmonitor/extensions/vnc.py
new file mode 100644
index 0000000..f8af01f
--- /dev/null
+++ b/tcosmonitor/extensions/vnc.py
@@ -0,0 +1,513 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+import os
+from random import Random
+from time import sleep
+import string
+import subprocess
+import signal
+
+from tcosmonitor.ping import PingPort
+
+import gtkvnc
+import gtk
+import traceback
+import sys
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class VNC(TcosExtension):
+ def register(self):
+ self.vnc_count={}
+ self.main.menus.register_simple( _("Connect to remote screen (VNC)"), "menu_remote.png", 1, self.vnc_simple, "vnc")
+ self.main.menus.register_simple( _("Demo mode (from this host)") , "menu_tiza.png", 1, self.vnc_demo_simple, "demo")
+
+ self.main.menus.register_all( _("Enter demo mode, all connected users see my screen") , "menu_tiza.png", 1, self.vnc_demo_all, "demo")
+ self.vnc={}
+ self.vncwindow={}
+ self.is_fullscreen={}
+
+ def vnc_demo_all(self, *args):
+ if not self.get_all_clients():
+ return
+ # demo mode
+ #generate password vnc
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg( _("No users logged.") )
+ return
+
+ msg=_( _("Do you want to start demo mode the following users: %s?" )%(self.connected_users_txt) )
+
+ if not shared.ask_msg ( msg ):
+ return
+
+ passwd=''.join( Random().sample(string.letters+string.digits, 12) )
+ self.main.common.exe_cmd("x11vnc -storepasswd %s %s >/dev/null 2>&1" \
+ %(passwd, os.path.expanduser('~/.tcosvnc')), verbose=0, background=True )
+
+ # start x11vnc in local
+ p=subprocess.Popen(["x11vnc", "-shared", "-noshm", "-viewonly", "-forever", "-rfbauth", "%s" %( os.path.expanduser('~/.tcosvnc') ) ], shell=False, bufsize=0, close_fds=True)
+
+ self.main.write_into_statusbar( _("Waiting for start demo mode...") )
+
+ # need to wait for start, PingPort loop
+ status = "CLOSED"
+ max_wait=10
+ wait=0
+ while status != "OPEN":
+ status=PingPort("127.0.0.1", 5900).get_status()
+ if status == "CLOSED":
+ sleep(1)
+ wait+=1
+ if wait > max_wait:
+ break
+
+ if status != "OPEN":
+ self.main.write_into_statusbar( _("Error while exec app"))
+ return
+
+ total=0
+ for client in self.newallclients:
+ self.main.xmlrpc.vnc("genpass", client, passwd )
+ # get server ip
+ server_ip=self.main.xmlrpc.GetStandalone("get_server")
+ print_debug("menu_event_all() vnc server ip=%s" %(server_ip))
+ # start vncviewer
+ self.main.xmlrpc.vnc("startclient", client, server_ip )
+ total+=1
+
+ if total < 1:
+ self.main.write_into_statusbar( _("No users logged.") )
+ # kill x11vnc
+ os.kill(p.pid, signal.SIGKILL)
+ else:
+ self.main.write_into_statusbar( _("Running in demo mode with %s clients.") %(total) )
+ #server_ip=self.main.xmlrpc.GetStandalone("get_server")
+ #hostname=self.main.localdata.GetHostname(server_ip)
+ # new mode Stop Button
+ if len(self.vnc_count.keys()) != 0:
+ count=len(self.vnc_count.keys())-1
+ nextkey=self.vnc_count.keys()[count]+1
+ self.vnc_count[nextkey]=None
+ else:
+ nextkey=1
+ self.vnc_count[nextkey]=None
+ self.add_progressbox( {"target": "vnc", "ip":"", "pid":p.pid, "allclients":self.newallclients, "key":nextkey}, _("Running in demo mode from server. Demo Nº %s") %(nextkey) )
+
+
+ def vnc_simple(self, w, ip):
+ if not self.get_client():
+ return
+
+ if len(self.allclients_logged) == 0:
+ shared.error_msg( _("No user logged.") )
+ return
+
+ self.main.worker=shared.Workers(self.main, target=self.start_vnc, args=(self.allclients_logged) )
+ self.main.worker.start()
+
+ def start_vnc(self, ip):
+ # force kill x11vnc in client
+ self.main.xmlrpc.newhost(ip)
+ host=self.main.localdata.GetHostname(self.main.selected_ip)
+
+ max_wait=5
+ wait=0
+ self.main.common.threads_enter("TcosActions:start_vnc print status msg")
+ self.main.write_into_statusbar( _("Connecting with %s to start VNC support") %(host) )
+ self.main.common.threads_leave("TcosActions:start_vnc print status msg")
+
+ status="OPEN"
+ while status != "CLOSED":
+ status=PingPort(ip, 5900).get_status()
+ self.main.xmlrpc.vnc("stopserver", ip )
+ print_debug("start_vnc() waiting to kill x11vnc...")
+ sleep(1)
+ wait+=1
+ if wait > max_wait:
+ print_debug("max_wait, returning")
+ # fixme show error message
+ return
+
+ # gen password in thin client
+ passwd=''.join( Random().sample(string.letters+string.digits, 12) )
+
+ self.main.xmlrpc.vnc("genpass", ip, passwd)
+ os.system("x11vnc -storepasswd %s %s >/dev/null 2>&1" \
+ %(passwd, os.path.expanduser('~/.tcosvnc')) )
+
+ try:
+
+ # before starting server, vnc-controller.sh exec killall x11vnc, not needed to stop server
+ #self.main.xmlrpc.vnc("stopserver", ip )
+ result=self.main.xmlrpc.vnc("startserver", ip)
+ if result.find("error") != -1:
+ self.main.common.threads_enter("TcosActions:start_vnc print error msg")
+ shared.error_msg ( _("Can't start VNC, error:\n%s") %(result) )
+ self.main.common.threads_leave("TcosActions:start_vnc print error msg")
+ return
+ self.main.common.threads_enter("TcosActions:start_vnc print waiting msg")
+ self.main.write_into_statusbar( _("Waiting for start of VNC server...") )
+ self.main.common.threads_leave("TcosActions:start_vnc print waiting msg")
+
+ # need to wait for start, PingPort loop
+
+ status = "CLOSED"
+
+ wait=0
+ while status != "OPEN":
+ status=PingPort(ip, 5900).get_status()
+ if status == "CLOSED":
+ sleep(1)
+ wait+=1
+ if wait > max_wait:
+ break
+ if status == "OPEN":
+ #cmd=("LC_ALL=C LC_MESSAGES=C vncviewer --version 2>&1| grep built |grep -c \"4.1\"")
+ #output=self.main.common.exe_cmd(cmd)
+ #if output == "1":
+ # cmd = ("vncviewer " + ip + " -UseLocalCursor=0 -passwd %s" %os.path.expanduser('~/.tcosvnc') )
+ #else:
+ # cmd = ("vncviewer " + ip + " -passwd %s" %os.path.expanduser('~/.tcosvnc') )
+ #print_debug ( "start_process() threading \"%s\"" %(cmd) )
+ #self.main.common.exe_cmd (cmd, verbose=0, background=True)
+ self.main.common.threads_enter("TcosActions:start_vnc print x11vnc support msg")
+ self.vncviewer(ip, passwd)
+ self.main.common.threads_leave("TcosActions:start_vnc print x11vnc support msg")
+ except Exception, err:
+ print_debug("start_vnc() Exception, error=%s"%err)
+ traceback.print_exc(file=sys.stderr)
+ self.main.common.threads_enter("TcosActions:start_vnc print x11vnc support msg")
+ shared.error_msg ( _("Can't start VNC, please add X11VNC support") )
+ self.main.common.threads_leave("TcosActions:start_vnc print x11vnc support msg")
+ return
+
+ self.main.common.threads_enter("TcosActions:start_vnc clean status msg")
+ self.main.write_into_statusbar( "" )
+ self.main.common.threads_leave("TcosActions:start_vnc clean status msg")
+
+ def vncviewer_destroy(self, window, ip):
+ try:
+ self.vncwindow[ip].hide()
+ self.vncwindow[ip].destroy()
+ except Exception, err:
+ print_debug("vncviewer_destroy() Cant hide/destroy vncviewer window, err=%s"%err)
+ print_debug("vncviewer_destroy() self.vnc=%s"%self.vnc)
+ if self.vnc.has_key(ip):
+ self.vnc[ip].close()
+ self.vnc.pop(ip)
+ if self.vncwindow.has_key(ip):
+ self.vncwindow.pop(ip)
+
+ def vncviewer_fullcontrol(self, button, ip):
+ image=gtk.Image()
+
+ if self.vnc[ip].get_read_only():
+ self.vnc[ip].set_read_only(False)
+ button.set_label( _("Switch to view only") )
+ image.set_from_stock('gtk-find', gtk.ICON_SIZE_BUTTON)
+ button.set_image(image)
+ else:
+ self.vnc[ip].set_read_only(True)
+ button.set_label( _("Switch to full control") )
+ image.set_from_stock('gtk-find-and-replace', gtk.ICON_SIZE_BUTTON)
+ button.set_image(image)
+
+ def vncviewer_force_resize(self, vnc, size, ip):
+ w, h = vnc.get_size_request()
+ if w == -1 or h == -1:
+ print_debug("_force_resize() returning w=%s h=%s ip=%s"%(w, h, ip))
+ return
+ vnc.set_size_request(w/2, h/2)
+
+
+ def on_fullscreenbutton_click(self, button, ip):
+ image=gtk.Image()
+ if self.is_fullscreen[ip]:
+ self.vncwindow[ip].unfullscreen()
+ self.is_fullscreen[ip]=False
+ image.set_from_stock('gtk-fullscreen', gtk.ICON_SIZE_BUTTON)
+ else:
+ self.vncwindow[ip].fullscreen()
+ self.is_fullscreen[ip]=True
+ image.set_from_stock('gtk-leave-fullscreen', gtk.ICON_SIZE_BUTTON)
+ button.set_image(image)
+
+ def vncviewer(self, ip, passwd, stoptarget=None, stopargs=None):
+ self.vncwindow[ip] = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ self.vncwindow[ip].set_icon_from_file(shared.IMG_DIR + 'tcos-icon-32x32.png')
+ self.vncwindow[ip].set_title( _("VNC host %s") %(ip) )
+ self.vncwindow[ip].connect("destroy", self.vncviewer_destroy, ip)
+ box1 = gtk.HBox(True, 10)
+
+ button = gtk.Button( _("Switch to full control") )
+ button.connect("clicked", self.vncviewer_fullcontrol, ip)
+ image=gtk.Image()
+ image.set_from_stock('gtk-find-and-replace', gtk.ICON_SIZE_BUTTON)
+ button.set_image(image)
+ box1.pack_start(button, False, False, 0)
+ button.show_all()
+
+ fbutton = gtk.Button( _("Switch to fullscreen") )
+ fbutton.connect("clicked", self.on_fullscreenbutton_click, ip)
+ image=gtk.Image()
+ image.set_from_stock('gtk-fullscreen', gtk.ICON_SIZE_BUTTON)
+ fbutton.set_image(image)
+ box1.pack_start(fbutton, False, False, 0)
+ fbutton.show_all()
+
+ if stoptarget:
+ sbutton = gtk.Button( _("Stop") )
+ sbutton.connect("clicked", stoptarget, stopargs, None)
+ image=gtk.Image()
+ image.set_from_stock('gtk-stop', gtk.ICON_SIZE_BUTTON)
+ sbutton.set_image(image)
+ box1.pack_start(sbutton, False, False, 0)
+ sbutton.show_all()
+
+ lastbutton = gtk.Button( _("Quit") )
+ image=gtk.Image()
+ image.set_from_stock('gtk-quit', gtk.ICON_SIZE_BUTTON)
+ lastbutton.set_image(image)
+ lastbutton.connect("clicked", self.vncviewer_destroy, ip)
+ box1.pack_start(lastbutton, False, False, 0)
+ lastbutton.show_all()
+
+ self.vnc[ip]=gtkvnc.Display()
+ self.vnc[ip].set_credential(gtkvnc.CREDENTIAL_PASSWORD, passwd)
+ self.vnc[ip].set_credential(gtkvnc.CREDENTIAL_CLIENTNAME, self.main.name)
+
+ #self.vnc[ip].connect("vnc-auth-credential", self._vnc_auth_cred, ip)
+ self.vnc[ip].connect("size-request", self.vncviewer_force_resize, ip)
+ #self.vnc[ip].connect("vnc-connected", self._vnc_connected, ip)
+ # this freeze GUI, search another way
+ #self.vnc[ip].set_tooltip_text("%s"%ip)
+
+ self.vnc[ip].open_host(ip, '5900')
+ self.vnc[ip].set_scaling(True)
+ self.vnc[ip].set_read_only(True)
+ self.vnc[ip].show()
+
+ # Show the box
+ box1.show()
+
+ box2 = gtk.VBox(False, 0)
+ box2.pack_start(box1, False, False, 0)
+ box2.pack_start(self.vnc[ip], True, True, 0)
+
+
+ # Show the window
+ self.vncwindow[ip].add(box2)
+ self.vncwindow[ip].show_all()
+ self.is_fullscreen[ip]=False
+
+
+ def vnc_demo_simple(self, widget, ip):
+ if not self.get_client():
+ return
+
+ client_simple=self.connected_users_txt
+
+ if len(self.connected_users) == 0 or self.connected_users[0] == shared.NO_LOGIN_MSG:
+ shared.error_msg ( _("Can't start demo mode, user is not logged") )
+ return
+
+ msg=_( _("Do you want demo mode from user %s?" ) %(client_simple) )
+ if not shared.ask_msg ( msg ):
+ return
+
+ if self.main.iconview.ismultiple():
+ self.allclients=self.main.iconview.get_multiple()
+
+ elif self.main.classview.ismultiple():
+ self.allclients=self.main.classview.get_multiple()
+
+ elif self.main.listview.isactive() and self.main.config.GetVar("selectedhosts") == 1:
+ self.allclients=self.main.listview.getmultiple()
+ if len(self.allclients) == 0:
+ self.allclients=self.main.localdata.allclients
+ else:
+ # get all clients connected
+ self.allclients=self.main.localdata.allclients
+
+ # Allow one client
+ # if len(self.allclients) == 0: return
+
+ # force kill x11vnc in client
+ self.main.xmlrpc.newhost(ip)
+ max_wait=5
+ wait=0
+ self.main.write_into_statusbar( _("Connecting with %s to start VNC support") %(client_simple) )
+
+ status="OPEN"
+ while status != "CLOSED":
+ status=PingPort(ip, 5900).get_status()
+ self.main.xmlrpc.vnc("stopserver", ip )
+ print_debug("start_vnc() waiting to kill x11vnc...")
+ sleep(1)
+ wait+=1
+ if wait > max_wait:
+ print_debug("max_wait, returning")
+ # fixme show error message
+ return
+
+ #generate password vnc
+ passwd=''.join( Random().sample(string.letters+string.digits, 12) )
+ self.main.common.exe_cmd("x11vnc -storepasswd %s %s >/dev/null 2>&1" \
+ %(passwd, os.path.expanduser('~/.tcosvnc')), verbose=0, background=True )
+
+ # start x11vnc in remote host
+ self.main.xmlrpc.vnc("genpass", ip, passwd )
+ self.main.xmlrpc.vnc("startserver", ip )
+
+ self.main.write_into_statusbar( _("Waiting for start demo mode from user %s...") %(client_simple) )
+
+ # need to wait for start, PingPort loop
+ status = "CLOSED"
+ max_wait=10
+ wait=0
+ while status != "OPEN":
+ status=PingPort(ip, 5900).get_status()
+ if status == "CLOSED":
+ sleep(1)
+ wait+=1
+ if wait > max_wait:
+ break
+
+ if status != "OPEN":
+ self.main.write_into_statusbar( _("Error while exec app"))
+ return
+
+ # start in 1 (teacher)
+ newallclients=[]
+ total=1
+ for client in self.allclients:
+ self.main.localdata.newhost(client)
+ if self.main.localdata.IsLogged(client) and client != ip:
+ self.main.xmlrpc.vnc("genpass", client, passwd )
+ self.main.xmlrpc.vnc("startclient", client, ip )
+ total+=1
+ newallclients.append(client)
+
+ if total < 1:
+ self.main.write_into_statusbar( _("No users logged.") )
+ # kill x11vnc in host
+ self.main.xmlrpc.vnc("stopserver", ip )
+ else:
+ self.main.write_into_statusbar( _("Running in demo mode with %s clients.") %(total) )
+ #cmd=("LC_ALL=C LC_MESSAGES=C vncviewer --version 2>&1| grep built |grep -c \"4.1\"")
+ #output=self.main.common.exe_cmd(cmd)
+ #if output == "1":
+ # p=subprocess.Popen(["vncviewer", ip, "-UseLocalCursor=0", "-PasswordFile", "%s" %os.path.expanduser('~/.tcosvnc')], shell=False, bufsize=0, close_fds=True)
+ #else:
+ # p=subprocess.Popen(["vncviewer", ip, "-passwd", "%s" %os.path.expanduser('~/.tcosvnc')], shell=False, bufsize=0, close_fds=True)
+
+ # new mode for stop button
+ if len(self.vnc_count.keys()) != 0:
+ count=len(self.vnc_count.keys())-1
+ nextkey=self.vnc_count.keys()[count]+1
+ self.vnc_count[nextkey]=None
+ else:
+ nextkey=1
+ self.vnc_count[nextkey]=None
+
+ stopargs={"target": "vnc", "ip": ip, "allclients":newallclients, "key":nextkey}
+ self.vncviewer(ip, passwd, stoptarget=self.on_progressbox_click, stopargs=stopargs)
+ #self.add_progressbox( {"target": "vnc", "pid":p.pid, "ip": ip, "allclients":newallclients, "key":nextkey}, _("Running in demo mode from user %(host)s. Demo Nº %(count)s") %{"host":client_simple, "count":nextkey} )
+ self.add_progressbox( stopargs, _("Running in demo mode from user %(host)s. Demo Nº %(count)s") %{"host":client_simple, "count":nextkey} )
+
+ def on_progressbox_click(self, widget, args, box):
+ if box:
+ box.destroy()
+ else:
+ for table in self.main.progressbox.get_children():
+ #[<gtk.Label>, <gtk.Button>]
+ # read key from label
+ tlabel=table.get_children()[0]
+ tbutton=table.get_children()[1]
+ key=int(tlabel.get_text().split('Nº ')[1])
+ if args['key'] == key:
+ # we have found IP in label !!! destroy table
+ table.destroy()
+ widget=tbutton
+ print_debug("on_progressbox_click() widget=%s, args=%s, box=%s" %(widget, args, box) )
+
+ if not args['target']:
+ return
+
+ try:
+ self.main.stop_running_actions.remove(widget)
+ except Exception, err:
+ print_debug("on_progressbox_click() can't remove widget=%s err=%s"%(widget, err))
+
+ if args['target'] == "vnc":
+ del self.vnc_count[args['key']]
+ if args['ip'] != "":
+ for client in args['allclients']:
+ self.main.localdata.newhost(client)
+ if self.main.localdata.IsLogged(client):
+ self.main.xmlrpc.newhost(client)
+ self.main.xmlrpc.vnc("stopclient", client)
+ # kill only in server one vncviewer
+ #if "pid" in args:
+ # os.kill(args['pid'], signal.SIGKILL)
+ #else:
+ # self.main.common.exe_cmd("killall -s KILL vncviewer", verbose=0, background=True)
+
+ self.vncviewer_destroy(None, args['ip'])
+
+ self.main.xmlrpc.newhost(args['ip'])
+ self.main.xmlrpc.vnc("stopserver", args['ip'] )
+ else:
+ # get all users at this demo mode and not kill others demo modes, in some cases need SIGKILL
+ for client in args['allclients']:
+ self.main.localdata.newhost(client)
+ if self.main.localdata.IsLogged(client):
+ self.main.xmlrpc.newhost(client)
+ self.main.xmlrpc.vnc("stopclient", client)
+ if "pid" in args:
+ os.kill(args['pid'], signal.SIGKILL)
+ else:
+ self.main.common.exe_cmd("killall -s KILL x11vnc", verbose=0, background=True)
+
+ self.main.write_into_statusbar( _("Demo mode off.") )
+
+
+
+
+
+__extclass__=VNC
+
+
+
+
+
+
diff --git a/tcosmonitor/extensions/wakeonlan.py b/tcosmonitor/extensions/wakeonlan.py
new file mode 100644
index 0000000..0f827f8
--- /dev/null
+++ b/tcosmonitor/extensions/wakeonlan.py
@@ -0,0 +1,100 @@
+# -*- coding: UTF-8 -*-
+# TcosMonitor version __VERSION__
+#
+# Copyright (c) 2006-2011 Mario Izquierdo <mariodebian@gmail.com>
+#
+# This package 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 2 of the License, or
+# (at your option) any later version.
+#
+#
+# This package 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+""" template extension """
+
+from gettext import gettext as _
+import sys
+
+from tcosmonitor import shared
+from tcosmonitor.TcosExtensions import TcosExtension
+
+from tcosmonitor.WakeOnLan import WakeOnLan
+
+def print_debug(txt):
+ if shared.debug:
+ print >> sys.stderr, "%s::%s" % (__name__, txt)
+ #print("%s::%s" % (__name__, txt), file=sys.stderr)
+
+
+class WOL(TcosExtension):
+ def register(self):
+ self.main.menus.register_simple( _("Boot client (WakeOnLan)") , "menu_wol.png", 0, self.wol_one, "wakeonlan")
+ self.main.menus.register_all( _("Boot All clients (WakeOnLan)") , "menu_wol.png", 0, self.wol_all, "wakeonlan")
+
+
+ def wol_one(self, widget, ip):
+ if not self.get_client():
+ print_debug("wol_one() no client")
+ return
+ if self.main.config.GetVar("scan_network_method") != "static":
+ msg=(_("Wake On Lan only works with static list.\n\nEnable scan method \"static\" in Preferences\nand (wake on lan) support in bios of clients." ))
+ shared.info_msg ( msg )
+ return
+
+ msg=_( _("Do you want boot %s client?" %ip))
+ if shared.ask_msg ( msg ):
+ data=[]
+ hostslist=self.main.config.GetVar("statichosts")
+ #eth=self.main.config.GetVar("network_interface")
+ if hostslist == "":
+ return
+ data=hostslist.split("#")
+ data=data[:-1]
+ for host in data:
+ mip, mac=host.split("|")
+ print_debug("wol_one() ip=%s mac=%s" %(mip, mac) )
+ if mip == self.main.selected_ip:
+ if mac == "":
+ self.main.write_into_statusbar(_("No register MAC address for ip: \"%s\"")%ip)
+ continue
+ print_debug("Send magic packet to mac=%s" %mac)
+ if not WakeOnLan("%s"%mac):
+ self.main.write_into_statusbar(_("Not valid MAC address: \"%s\"")%mac)
+
+ def wol_all(self, *args):
+ if self.main.config.GetVar("scan_network_method") != "static":
+ msg=(_("Wake On Lan only works with static list.\n\nEnable scan method \"static\" in Preferences\nand (wake on lan) support in bios of clients." ))
+ shared.info_msg ( msg )
+ return
+
+ msg=_( _("Do you want boot all clients?" ))
+ if shared.ask_msg ( msg ):
+ data=[]
+ hostslist=self.main.config.GetVar("statichosts")
+ #eth=self.main.config.GetVar("network_interface")
+ if hostslist == "":
+ return
+ data=hostslist.split("#")
+ data=data[:-1]
+ errors=[]
+ for host in data:
+ mac=host.split("|")[1]
+ if mac == "":
+ self.main.write_into_statusbar(_("No register MAC address for ip: \"%s\"")%host)
+ continue
+ print_debug("Send magic packet to mac=%s" %mac)
+ if not WakeOnLan("%s"%mac):
+ errors.append(mac)
+ if len(errors) >1:
+ print_debug("menu_event_all() errors=%s"%errors)
+ self.main.write_into_statusbar(_("Not valid MAC address: \"%s\"")%" ".join(errors))
+
+
+__extclass__=WOL