2006-11-16 13:09:07 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
2007-01-02 02:39:01 +01:00
|
|
|
# Copyright (C) 2006, Eduardo Silva (edsiper@gmail.com).
|
|
|
|
#
|
|
|
|
# This program 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 program 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
2007-01-04 20:17:10 +01:00
|
|
|
import sys
|
|
|
|
import os
|
2006-11-16 13:09:07 +01:00
|
|
|
import string
|
|
|
|
import wnck
|
|
|
|
import plugin
|
|
|
|
|
|
|
|
from procmem import proc
|
|
|
|
|
|
|
|
try:
|
2006-12-04 20:12:24 +01:00
|
|
|
import gtk
|
|
|
|
import gtk.gdk
|
|
|
|
import gobject
|
2006-11-16 13:09:07 +01:00
|
|
|
except:
|
2006-12-04 20:12:24 +01:00
|
|
|
sys.exit(1)
|
2006-11-16 13:09:07 +01:00
|
|
|
|
|
|
|
class Interface:
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
store_data_types = []
|
|
|
|
store_data_types_details = []
|
2007-01-04 20:17:10 +01:00
|
|
|
|
|
|
|
def __init__(self):
|
2006-12-04 20:12:24 +01:00
|
|
|
|
2007-01-04 20:17:10 +01:00
|
|
|
# Our GtkTree (Treeview)
|
2006-12-04 20:12:24 +01:00
|
|
|
self.treeview = gtk.TreeView()
|
2007-01-04 20:17:10 +01:00
|
|
|
self.treeview.show()
|
|
|
|
|
|
|
|
self.button_start = gtk.Button('Start Memphis')
|
|
|
|
self.button_stop = gtk.Button('Stop Memphis')
|
|
|
|
|
|
|
|
fixed = gtk.Fixed()
|
|
|
|
fixed.add(self.button_start)
|
|
|
|
fixed.add(self.button_stop)
|
|
|
|
|
|
|
|
vbox = gtk.VBox(False)
|
|
|
|
vbox.set_border_width(5)
|
|
|
|
vbox.pack_start(fixed, True, True, 0)
|
|
|
|
|
|
|
|
# Our GtkTree (Treeview)
|
2007-01-04 03:51:08 +01:00
|
|
|
self.treeview = gtk.TreeView()
|
2007-01-04 20:17:10 +01:00
|
|
|
t_width = gtk.gdk.screen_width()
|
|
|
|
t_height = gtk.gdk.screen_height() * 83 / 100
|
|
|
|
|
2007-01-04 03:51:08 +01:00
|
|
|
self.treeview.set_size_request(t_width, t_height)
|
2007-01-04 20:17:10 +01:00
|
|
|
vbox.pack_start(self.treeview, True, True, 0)
|
|
|
|
vbox.show_all()
|
|
|
|
self.widget = vbox
|
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Loading plugins
|
|
|
|
self.plg = plugin.Plugin()
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# TOP data types (columns)
|
|
|
|
self.store_data_types = []
|
|
|
|
|
|
|
|
for plg in self.plg.list:
|
|
|
|
plg_data = plg.INTERNALS
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Give plugin object to plugin
|
|
|
|
plg.INTERNALS['Plg'] = self.plg
|
|
|
|
|
|
|
|
# Creating a store model and loading process data to Treeview
|
|
|
|
# self.store_data_types, ex [int, str, str, str, int,...]
|
|
|
|
#self.store = gtk.TreeStore(*self.store_data_types)
|
2007-01-04 03:51:08 +01:00
|
|
|
self.data = Data(self, self.treeview, self.plg.list)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
|
|
|
self.button_stop.hide()
|
|
|
|
self.button_start.connect('clicked', self.data._start_memphis)
|
|
|
|
self.button_stop.connect('clicked', self.data._stop_memphis)
|
|
|
|
|
2006-11-16 13:09:07 +01:00
|
|
|
class Data:
|
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
last_col_index = 0
|
|
|
|
|
|
|
|
store_data_cols = []
|
|
|
|
store_data_types = []
|
|
|
|
store_data_types_details = []
|
|
|
|
|
2007-01-04 03:51:08 +01:00
|
|
|
_running_status = False
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2007-01-04 03:51:08 +01:00
|
|
|
def __init__(self, interface, treeview, plg_list):
|
2007-01-04 20:17:10 +01:00
|
|
|
|
|
|
|
self.interface = interface
|
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Top data types
|
|
|
|
self.plg_list = plg_list
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
for plg in self.plg_list:
|
|
|
|
|
|
|
|
if plg.INTERNALS['top_data'] != None:
|
|
|
|
last_dt = len(self.store_data_types)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
if last_dt > 0:
|
|
|
|
last_dt -= 1
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
len_dt = len(plg.INTERNALS['top_data'])
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
self.store_data_types_details.append({"plugin": plg, "init": last_dt, "end": last_dt + len_dt})
|
|
|
|
|
|
|
|
for dt in plg.INTERNALS['top_data']:
|
|
|
|
self.store_data_types.append(dt)
|
|
|
|
|
|
|
|
for col in plg.INTERNALS['top_cols']:
|
|
|
|
self.store_data_cols.append(col)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Set global treeview
|
|
|
|
self.treeview = treeview
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Basic columns
|
|
|
|
index = 0
|
|
|
|
for column_name in self.store_data_cols:
|
|
|
|
self.add_column(column_name, index)
|
|
|
|
index += 1
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
self.store = gtk.TreeStore(*self.store_data_types)
|
|
|
|
treeview.set_model(self.store)
|
|
|
|
|
2007-01-04 03:51:08 +01:00
|
|
|
def _start_memphis(self, button):
|
2007-01-04 20:17:10 +01:00
|
|
|
|
|
|
|
# Update information every 1.5 second
|
2007-01-04 03:51:08 +01:00
|
|
|
button.hide()
|
2007-01-04 20:17:10 +01:00
|
|
|
self.interface.button_stop.show()
|
|
|
|
self._running_status = True
|
|
|
|
gobject.timeout_add(1500, self.load_data, self.treeview)
|
2007-01-04 03:51:08 +01:00
|
|
|
|
|
|
|
def _stop_memphis(self, button):
|
2007-01-04 20:17:10 +01:00
|
|
|
|
|
|
|
self._running_status = False
|
|
|
|
button.hide()
|
|
|
|
self.interface.button_start.show()
|
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Add a new column to the main treeview
|
|
|
|
def add_column(self, column_name, index):
|
|
|
|
cell = gtk.CellRendererText()
|
|
|
|
col_tv = gtk.TreeViewColumn(column_name, cell, text=index)
|
|
|
|
col_tv.set_resizable(True)
|
|
|
|
col_tv.connect('clicked', self.sort_column_clicked)
|
|
|
|
col_tv.set_property('clickable', True)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
self.treeview.append_column(col_tv)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Set the last column index added
|
|
|
|
self.last_col_index = index
|
|
|
|
|
|
|
|
# Sorting
|
|
|
|
def sort_column_clicked(self, TreeViewColumn):
|
|
|
|
cols = self.treeview.get_columns()
|
|
|
|
|
|
|
|
# Searching column index
|
|
|
|
index = 0
|
|
|
|
for col in cols:
|
|
|
|
if col == TreeViewColumn:
|
|
|
|
break
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
index += 1
|
|
|
|
|
|
|
|
self.store.set_sort_column_id(index, gtk.SORT_DESCENDING)
|
|
|
|
|
|
|
|
def load_data(self, treeview):
|
|
|
|
self.store.clear()
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Getting procfs data
|
|
|
|
self.procdata = proc.ProcInfo()
|
|
|
|
self.process_list = []
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
pids = []
|
|
|
|
screen = wnck.screen_get_default()
|
|
|
|
windows = screen.get_windows()
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
current_pid = os.getpid()
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
for win in windows:
|
|
|
|
pid = int(win.get_pid())
|
|
|
|
if current_pid != pid:
|
|
|
|
pids.append(pid)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
self.process_list = set(pids)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Sort rows using pid
|
|
|
|
#self.process_list.sort(key=operator.itemgetter('pid'))
|
|
|
|
self.process_iter = []
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
for pid in self.process_list:
|
|
|
|
pi = self.build_row(self.store, None, self.procdata, pid)
|
|
|
|
self.process_iter.append(pi)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
treeview.set_rules_hint(True)
|
|
|
|
treeview.expand_all()
|
|
|
|
|
2007-01-04 03:51:08 +01:00
|
|
|
return self._running_status
|
2006-12-04 20:12:24 +01:00
|
|
|
|
|
|
|
def build_row(self, store, parent_iter, proc_data, pid):
|
|
|
|
data = []
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
pinfo = proc_data.MemoryInfo(pid)
|
|
|
|
|
|
|
|
# Look for plugins that need to update the top data treeview
|
|
|
|
for plg in self.plg_list:
|
|
|
|
plg_data = []
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
if plg.INTERNALS['top_data'] != None:
|
|
|
|
# data = [xxx, yyy,zzz,...]
|
|
|
|
plg_data = plg.info.plg_on_top_data_refresh(plg, pinfo)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
for field in plg_data:
|
|
|
|
data.append(field)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
pi = self.insert_row(store, parent_iter, data)
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
return pi
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
# Insert a Row in our TreeView
|
|
|
|
def insert_row(self, store, parent, row_data):
|
|
|
|
iter = store.insert_after(parent, None)
|
|
|
|
|
|
|
|
index = 0
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
for data in row_data:
|
|
|
|
store.set_value(iter, index , data)
|
|
|
|
index += 1
|
2007-01-04 20:17:10 +01:00
|
|
|
|
2006-12-04 20:12:24 +01:00
|
|
|
return iter
|