Merge
This commit is contained in:
		
						commit
						0c47294dbd
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -25,7 +25,6 @@ missing
 | 
			
		||||
py-compile
 | 
			
		||||
stamp-h1
 | 
			
		||||
dbus-installed.conf
 | 
			
		||||
dbus-installed-094.conf
 | 
			
		||||
intltool-extract
 | 
			
		||||
intltool-extract.in
 | 
			
		||||
intltool-merge
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ SUBDIRS = activities lib po shell sugar services tools
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
 | 
			
		||||
dbusconfdir = $(pkgdatadir)
 | 
			
		||||
dbusconf_DATA = dbus-installed.conf dbus-installed-094.conf
 | 
			
		||||
dbusconf_DATA = dbus-installed.conf
 | 
			
		||||
 | 
			
		||||
bin_SCRIPTS = 			\
 | 
			
		||||
	sugar-emulator		\
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,6 @@ AM_GLIB_GNU_GETTEXT
 | 
			
		||||
AC_OUTPUT([
 | 
			
		||||
Makefile
 | 
			
		||||
dbus-installed.conf
 | 
			
		||||
dbus-installed-094.conf
 | 
			
		||||
activities/Makefile
 | 
			
		||||
activities/web/Makefile
 | 
			
		||||
activities/chat/Makefile
 | 
			
		||||
@ -72,6 +71,13 @@ shell/view/Makefile
 | 
			
		||||
shell/view/home/Makefile
 | 
			
		||||
shell/view/frame/Makefile
 | 
			
		||||
shell/model/Makefile
 | 
			
		||||
shell/console/Makefile
 | 
			
		||||
shell/console/plugins/Makefile
 | 
			
		||||
shell/console/plugins/clean_size/Makefile
 | 
			
		||||
shell/console/plugins/cpu/Makefile
 | 
			
		||||
shell/console/plugins/dirty_size/Makefile
 | 
			
		||||
shell/console/plugins/memphis_init/Makefile
 | 
			
		||||
shell/console/procmem/Makefile
 | 
			
		||||
sugar/Makefile
 | 
			
		||||
sugar/__installed__.py
 | 
			
		||||
sugar/activity/Makefile
 | 
			
		||||
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
<!-- This configuration file controls the per-user-login-session message bus.
 | 
			
		||||
     Add a session-local.conf and edit that rather than changing this 
 | 
			
		||||
     file directly. -->
 | 
			
		||||
 | 
			
		||||
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 | 
			
		||||
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 | 
			
		||||
<busconfig>
 | 
			
		||||
  <!-- Our well-known bus type, don't change this -->
 | 
			
		||||
  <type>session</type>
 | 
			
		||||
 | 
			
		||||
  <listen>unix:tmpdir=/tmp</listen>
 | 
			
		||||
 | 
			
		||||
  <servicedir>@prefix@/share/sugar/activities</servicedir>
 | 
			
		||||
  <servicedir>@prefix@/share/sugar/services</servicedir>
 | 
			
		||||
  <servicedir>/tmp/sugar-services</servicedir>
 | 
			
		||||
 | 
			
		||||
  <policy context="default">
 | 
			
		||||
    <!-- Allow everything to be sent -->
 | 
			
		||||
    <allow send_destination="*"/>
 | 
			
		||||
    <!-- Allow everything to be received -->
 | 
			
		||||
    <allow eavesdrop="true"/>
 | 
			
		||||
    <!-- Allow anyone to own anything -->
 | 
			
		||||
    <allow own="*"/>
 | 
			
		||||
  </policy>
 | 
			
		||||
 | 
			
		||||
</busconfig>
 | 
			
		||||
@ -1,25 +0,0 @@
 | 
			
		||||
<!-- This configuration file controls the per-user-login-session message bus.
 | 
			
		||||
     Add a session-local.conf and edit that rather than changing this 
 | 
			
		||||
     file directly. -->
 | 
			
		||||
 | 
			
		||||
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 | 
			
		||||
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 | 
			
		||||
<busconfig>
 | 
			
		||||
  <!-- Our well-known bus type, don't change this -->
 | 
			
		||||
  <type>session</type>
 | 
			
		||||
 | 
			
		||||
  <listen>unix:tmpdir=/tmp</listen>
 | 
			
		||||
 | 
			
		||||
  <servicedir>/tmp/sugar</servicedir>
 | 
			
		||||
  <servicedir>/tmp/sugar-services</servicedir>
 | 
			
		||||
 | 
			
		||||
  <policy context="default">
 | 
			
		||||
    <!-- Allow everything to be sent -->
 | 
			
		||||
    <allow send_destination="*"/>
 | 
			
		||||
    <!-- Allow everything to be received -->
 | 
			
		||||
    <allow eavesdrop="true"/>
 | 
			
		||||
    <!-- Allow anyone to own anything -->
 | 
			
		||||
    <allow own="*"/>
 | 
			
		||||
  </policy>
 | 
			
		||||
 | 
			
		||||
</busconfig>
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
SUBDIRS = conf data model view
 | 
			
		||||
SUBDIRS = conf data model view console
 | 
			
		||||
 | 
			
		||||
bin_SCRIPTS = 				\
 | 
			
		||||
	sugar-activity			\
 | 
			
		||||
	sugar-activity-factory		\
 | 
			
		||||
	sugar-log-viewer		\
 | 
			
		||||
	sugar-shell			\
 | 
			
		||||
	sugar-shutdown
 | 
			
		||||
	sugar-shutdown			\
 | 
			
		||||
	sugar-devel-console		
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell
 | 
			
		||||
sugar_PYTHON =				\
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								shell/console/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								shell/console/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
SUBDIRS = plugins procmem
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell/console
 | 
			
		||||
sugar_PYTHON =				\
 | 
			
		||||
	__init__.py			\
 | 
			
		||||
	console.py			\
 | 
			
		||||
	memphis.py			\
 | 
			
		||||
	logviewer.py			\
 | 
			
		||||
	terminal.py			\
 | 
			
		||||
	plugin.py			
 | 
			
		||||
							
								
								
									
										1
									
								
								shell/console/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								shell/console/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								shell/console/console.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										43
									
								
								shell/console/console.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
 | 
			
		||||
import gtk
 | 
			
		||||
 | 
			
		||||
# Console interfaces
 | 
			
		||||
import memphis
 | 
			
		||||
import logviewer
 | 
			
		||||
import terminal
 | 
			
		||||
 | 
			
		||||
window = gtk.Window()
 | 
			
		||||
window.set_title('Developer console')
 | 
			
		||||
 | 
			
		||||
width = gtk.gdk.screen_width() * 95 / 100
 | 
			
		||||
height = gtk.gdk.screen_height() * 95 / 100
 | 
			
		||||
 | 
			
		||||
window.set_default_size(width, height)
 | 
			
		||||
 | 
			
		||||
window.realize()
 | 
			
		||||
window.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
 | 
			
		||||
 | 
			
		||||
# Memphis interface
 | 
			
		||||
memphis_widget = memphis.Interface().widget
 | 
			
		||||
memphis_widget.show()
 | 
			
		||||
 | 
			
		||||
# Log viewer interface
 | 
			
		||||
logviewer_widget = logviewer.Interface().widget
 | 
			
		||||
logviewer_widget.show()
 | 
			
		||||
 | 
			
		||||
# Terminal interface
 | 
			
		||||
terminal_widget	= terminal.Interface().widget
 | 
			
		||||
terminal_widget.show()
 | 
			
		||||
 | 
			
		||||
# Notebook
 | 
			
		||||
notebook = gtk.Notebook()
 | 
			
		||||
notebook.append_page(memphis_widget, gtk.Label('Memphis'))
 | 
			
		||||
notebook.append_page(logviewer_widget, gtk.Label('Log Viewer'))
 | 
			
		||||
notebook.append_page(terminal_widget, gtk.Label('Terminal'))
 | 
			
		||||
 | 
			
		||||
notebook.show()
 | 
			
		||||
 | 
			
		||||
window.add(notebook)
 | 
			
		||||
window.show()
 | 
			
		||||
gtk.main()
 | 
			
		||||
							
								
								
									
										21
									
								
								shell/sugar-log-viewer → shell/console/logviewer.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										21
									
								
								shell/sugar-log-viewer → shell/console/logviewer.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@ -91,18 +91,11 @@ class MultiLogView(gtk.Notebook):
 | 
			
		||||
 | 
			
		||||
		return True
 | 
			
		||||
 | 
			
		||||
window = gtk.Window()
 | 
			
		||||
window.set_default_size(gtk.gdk.screen_width() * 3 / 4,
 | 
			
		||||
						gtk.gdk.screen_height() * 3 / 4)
 | 
			
		||||
class Interface:
 | 
			
		||||
 | 
			
		||||
window.realize()
 | 
			
		||||
window.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
 | 
			
		||||
 | 
			
		||||
path = os.path.join(env.get_profile_path(), 'logs')
 | 
			
		||||
viewer = MultiLogView(path)
 | 
			
		||||
window.add(viewer)
 | 
			
		||||
viewer.show()
 | 
			
		||||
 | 
			
		||||
window.show()
 | 
			
		||||
 | 
			
		||||
gtk.main()
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		path = os.path.join(env.get_profile_path(), 'logs')
 | 
			
		||||
		viewer = MultiLogView(path)
 | 
			
		||||
		viewer.show()
 | 
			
		||||
		self.widget = viewer
 | 
			
		||||
		
 | 
			
		||||
							
								
								
									
										182
									
								
								shell/console/memphis.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								shell/console/memphis.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,182 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
 | 
			
		||||
import sys, os
 | 
			
		||||
import string
 | 
			
		||||
import wnck
 | 
			
		||||
import plugin
 | 
			
		||||
 | 
			
		||||
from procmem import proc
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
	import gtk
 | 
			
		||||
	import gtk.gdk
 | 
			
		||||
	import gobject
 | 
			
		||||
except:
 | 
			
		||||
	sys.exit(1)
 | 
			
		||||
 | 
			
		||||
class Interface:
 | 
			
		||||
	
 | 
			
		||||
	store_data_types = []
 | 
			
		||||
	store_data_types_details = []
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self):	
 | 
			
		||||
		
 | 
			
		||||
		# Our GtkTree (Treeview)
 | 
			
		||||
		self.treeview = gtk.TreeView()
 | 
			
		||||
		self.widget = self.treeview
 | 
			
		||||
		
 | 
			
		||||
		# Loading plugins
 | 
			
		||||
		self.plg = plugin.Plugin()
 | 
			
		||||
				
 | 
			
		||||
		# TOP data types (columns)
 | 
			
		||||
		self.store_data_types = []
 | 
			
		||||
		
 | 
			
		||||
		for plg in self.plg.list:
 | 
			
		||||
			plg_data = plg.INTERNALS
 | 
			
		||||
			
 | 
			
		||||
			# 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)
 | 
			
		||||
		self.data = Data(self.treeview, self.plg.list)
 | 
			
		||||
	
 | 
			
		||||
class Data:
 | 
			
		||||
 | 
			
		||||
	treeview = None
 | 
			
		||||
	last_col_index = 0
 | 
			
		||||
 | 
			
		||||
	store_data_cols = []
 | 
			
		||||
	store_data_types = []
 | 
			
		||||
	store_data_types_details = []
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self, treeview, plg_list):
 | 
			
		||||
		
 | 
			
		||||
		# Top data types
 | 
			
		||||
		self.plg_list = plg_list
 | 
			
		||||
		
 | 
			
		||||
		for plg in self.plg_list:
 | 
			
		||||
 | 
			
		||||
			if plg.INTERNALS['top_data'] != None:
 | 
			
		||||
				last_dt = len(self.store_data_types)
 | 
			
		||||
	
 | 
			
		||||
				if last_dt > 0:
 | 
			
		||||
					last_dt -= 1
 | 
			
		||||
	
 | 
			
		||||
				len_dt = len(plg.INTERNALS['top_data'])
 | 
			
		||||
	
 | 
			
		||||
				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)
 | 
			
		||||
		
 | 
			
		||||
		# Set global treeview
 | 
			
		||||
		self.treeview = treeview
 | 
			
		||||
		
 | 
			
		||||
		# Basic columns 
 | 
			
		||||
		index = 0
 | 
			
		||||
		for column_name in self.store_data_cols:
 | 
			
		||||
			self.add_column(column_name, index)
 | 
			
		||||
			index += 1
 | 
			
		||||
		
 | 
			
		||||
		self.store = gtk.TreeStore(*self.store_data_types)
 | 
			
		||||
		treeview.set_model(self.store)
 | 
			
		||||
 | 
			
		||||
		# Update information every 1 second
 | 
			
		||||
		gobject.timeout_add(500, self.load_data, treeview)
 | 
			
		||||
 | 
			
		||||
	# 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)
 | 
			
		||||
		
 | 
			
		||||
		self.treeview.append_column(col_tv)
 | 
			
		||||
		
 | 
			
		||||
		# 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
 | 
			
		||||
			
 | 
			
		||||
			index += 1
 | 
			
		||||
 | 
			
		||||
		self.store.set_sort_column_id(index, gtk.SORT_DESCENDING)
 | 
			
		||||
		
 | 
			
		||||
	def load_data(self, treeview):
 | 
			
		||||
		self.store.clear()
 | 
			
		||||
		
 | 
			
		||||
		# Getting procfs data
 | 
			
		||||
		self.procdata = proc.ProcInfo()
 | 
			
		||||
		self.process_list = []
 | 
			
		||||
 | 
			
		||||
		pids = []
 | 
			
		||||
		screen = wnck.screen_get_default()
 | 
			
		||||
		windows =  screen.get_windows()
 | 
			
		||||
	
 | 
			
		||||
		current_pid = os.getpid()
 | 
			
		||||
		
 | 
			
		||||
		for win in windows:
 | 
			
		||||
			pid = int(win.get_pid())
 | 
			
		||||
			if current_pid != pid:
 | 
			
		||||
				pids.append(pid)
 | 
			
		||||
	
 | 
			
		||||
		self.process_list = set(pids)
 | 
			
		||||
		
 | 
			
		||||
		# Sort rows using pid
 | 
			
		||||
		#self.process_list.sort(key=operator.itemgetter('pid'))
 | 
			
		||||
		self.process_iter = []
 | 
			
		||||
	
 | 
			
		||||
		for pid in self.process_list:
 | 
			
		||||
			pi = self.build_row(self.store, None, self.procdata, pid)
 | 
			
		||||
			self.process_iter.append(pi)
 | 
			
		||||
	
 | 
			
		||||
		treeview.set_rules_hint(True)
 | 
			
		||||
		treeview.expand_all()
 | 
			
		||||
 | 
			
		||||
		return True
 | 
			
		||||
	
 | 
			
		||||
	def build_row(self, store, parent_iter, proc_data, pid):
 | 
			
		||||
		data = []
 | 
			
		||||
	
 | 
			
		||||
		pinfo = proc_data.MemoryInfo(pid)
 | 
			
		||||
			
 | 
			
		||||
		# Look for plugins that need to update the top data treeview
 | 
			
		||||
		for plg in self.plg_list:
 | 
			
		||||
			plg_data = []
 | 
			
		||||
			
 | 
			
		||||
			if plg.INTERNALS['top_data'] != None:
 | 
			
		||||
				# data = [xxx, yyy,zzz,...]
 | 
			
		||||
				plg_data = plg.info.plg_on_top_data_refresh(plg, pinfo)
 | 
			
		||||
								
 | 
			
		||||
			for field in plg_data:
 | 
			
		||||
				data.append(field)
 | 
			
		||||
										
 | 
			
		||||
		pi = self.insert_row(store, parent_iter, data)
 | 
			
		||||
	
 | 
			
		||||
		return pi
 | 
			
		||||
		
 | 
			
		||||
	# Insert a Row in our TreeView
 | 
			
		||||
	def insert_row(self, store, parent, row_data):
 | 
			
		||||
		iter = store.insert_after(parent, None)
 | 
			
		||||
 | 
			
		||||
		index = 0
 | 
			
		||||
		
 | 
			
		||||
		for data in row_data:
 | 
			
		||||
			store.set_value(iter, index , data)
 | 
			
		||||
			index += 1
 | 
			
		||||
			
 | 
			
		||||
		return iter
 | 
			
		||||
							
								
								
									
										50
									
								
								shell/console/plugin.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								shell/console/plugin.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
###############################################
 | 
			
		||||
# Memphis Plugin Support
 | 
			
		||||
###############################################
 | 
			
		||||
 | 
			
		||||
import sys, os, time
 | 
			
		||||
import gtk, gobject
 | 
			
		||||
 | 
			
		||||
from procmem import proc, proc_smaps, analysis
 | 
			
		||||
 | 
			
		||||
class Plugin:
 | 
			
		||||
 | 
			
		||||
	# Plugin list
 | 
			
		||||
	list = []
 | 
			
		||||
	proc = proc.ProcInfo()
 | 
			
		||||
	
 | 
			
		||||
	internal_plugin = "memphis_init"
 | 
			
		||||
	plg_path = os.path.dirname(os.path.abspath(__file__)) + "/plugins"
 | 
			
		||||
	
 | 
			
		||||
	# Frequency timer, managed by main program
 | 
			
		||||
	freq_timer = 0
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		
 | 
			
		||||
		sys.path.insert(0, self.plg_path)
 | 
			
		||||
		
 | 
			
		||||
		# Including memphis plugin
 | 
			
		||||
		self.list.append(__import__(self.internal_plugin))
 | 
			
		||||
		
 | 
			
		||||
		if os.path.isdir(self.plg_path):
 | 
			
		||||
			# around dir entries
 | 
			
		||||
			for plg in os.listdir(self.plg_path):
 | 
			
		||||
				
 | 
			
		||||
				if plg == self.internal_plugin:
 | 
			
		||||
					continue
 | 
			
		||||
				
 | 
			
		||||
				if os.path.isdir(self.plg_path + "/" + plg):
 | 
			
		||||
					p = __import__(plg)
 | 
			
		||||
					self.list.append(__import__(plg))
 | 
			
		||||
			
 | 
			
		||||
	# Parse /proc/PID/smaps information
 | 
			
		||||
	def proc_get_smaps(self, pid):
 | 
			
		||||
		return proc_smaps.ProcSmaps(pid)
 | 
			
		||||
	
 | 
			
		||||
	# Parse /proc/PID/maps information
 | 
			
		||||
	def proc_get_maps(self, pid):
 | 
			
		||||
		return proc_smaps.ProcMaps(pid)
 | 
			
		||||
 | 
			
		||||
	def proc_analysis(self, pid):
 | 
			
		||||
		return analysis.Analysis(pid)
 | 
			
		||||
	
 | 
			
		||||
							
								
								
									
										4
									
								
								shell/console/plugins/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								shell/console/plugins/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
SUBDIRS = clean_size cpu dirty_size memphis_init
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell/console/plugins
 | 
			
		||||
sugar_PYTHON = 
 | 
			
		||||
							
								
								
									
										6
									
								
								shell/console/plugins/clean_size/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								shell/console/plugins/clean_size/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell/console/plugins/clean_size
 | 
			
		||||
sugar_PYTHON =				\
 | 
			
		||||
	README				\
 | 
			
		||||
	__init__.py			\
 | 
			
		||||
	info.py				
 | 
			
		||||
							
								
								
									
										2
									
								
								shell/console/plugins/clean_size/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								shell/console/plugins/clean_size/README
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
This plugin give support to get the clean size memory usage 
 | 
			
		||||
by process using the /proc/PID/maps file. 
 | 
			
		||||
							
								
								
									
										16
									
								
								shell/console/plugins/clean_size/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								shell/console/plugins/clean_size/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
 | 
			
		||||
import info
 | 
			
		||||
 | 
			
		||||
INTERNALS = {
 | 
			
		||||
			# Basic information
 | 
			
		||||
			'PLGNAME': "Clean Size",
 | 
			
		||||
			'TABNAME': None,
 | 
			
		||||
			'AUTHOR': "Eduardo Silva",
 | 
			
		||||
			'DESC': "Print the approx real memory usage",
 | 
			
		||||
 | 
			
		||||
			# Plugin API
 | 
			
		||||
			'Plg': None, # Plugin object
 | 
			
		||||
 | 
			
		||||
			'top_data': [int], # Top data types needed by memphis core plugin
 | 
			
		||||
			'top_cols': ["Approx Real Usage (kb)"]
 | 
			
		||||
		}
 | 
			
		||||
							
								
								
									
										15
									
								
								shell/console/plugins/clean_size/info.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								shell/console/plugins/clean_size/info.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
###########################################################
 | 
			
		||||
# Main function:
 | 
			
		||||
# -----------------
 | 
			
		||||
# self:  self plugin object
 | 
			
		||||
# mself: memphis object / principal class
 | 
			
		||||
# pinfo: row with information about current tracing process
 | 
			
		||||
############################################################
 | 
			
		||||
 | 
			
		||||
def plg_on_top_data_refresh(self, pinfo):
 | 
			
		||||
		
 | 
			
		||||
	# Get clean size
 | 
			
		||||
	maps = self.INTERNALS['Plg'].proc_get_maps(pinfo['pid'])
 | 
			
		||||
 | 
			
		||||
	size = (maps.clean_size/1024)
 | 
			
		||||
	return [size]
 | 
			
		||||
							
								
								
									
										6
									
								
								shell/console/plugins/cpu/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								shell/console/plugins/cpu/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell/console/plugins/cpu
 | 
			
		||||
sugar_PYTHON =				\
 | 
			
		||||
	README				\
 | 
			
		||||
	__init__.py			\
 | 
			
		||||
	info.py				
 | 
			
		||||
							
								
								
									
										2
									
								
								shell/console/plugins/cpu/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								shell/console/plugins/cpu/README
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
This plugin give support to draw the Virtual Memory Size 
 | 
			
		||||
usage by the current tracing process. 
 | 
			
		||||
							
								
								
									
										23
									
								
								shell/console/plugins/cpu/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								shell/console/plugins/cpu/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
import os
 | 
			
		||||
import info
 | 
			
		||||
 | 
			
		||||
INTERNALS = {
 | 
			
		||||
			'PLGNAME': "cpu",
 | 
			
		||||
			'TABNAME': None,
 | 
			
		||||
			'AUTHOR': "Eduardo Silva",
 | 
			
		||||
			'DESC': "Print CPU usage",
 | 
			
		||||
 | 
			
		||||
			# Plugin API
 | 
			
		||||
			'Plg': None, # Plugin object
 | 
			
		||||
			'current_plg': None, # Current plugin object
 | 
			
		||||
			'current_page': None, # Current page number
 | 
			
		||||
 | 
			
		||||
			# Top process view requirements
 | 
			
		||||
			'top_data': [int], # Top data types needed by memphis core plugin
 | 
			
		||||
			'top_cols': ["%CPU "] # Column names
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
# Get CPU frequency 
 | 
			
		||||
cpu_hz = os.sysconf(2)
 | 
			
		||||
 | 
			
		||||
pids_ujiffies = {}
 | 
			
		||||
							
								
								
									
										48
									
								
								shell/console/plugins/cpu/info.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								shell/console/plugins/cpu/info.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
###########################################################
 | 
			
		||||
# Main function:
 | 
			
		||||
# -----------------
 | 
			
		||||
# self:  self plugin object
 | 
			
		||||
# mself: memphis object / principal class
 | 
			
		||||
# pinfo: row with information about current tracing process
 | 
			
		||||
############################################################
 | 
			
		||||
 | 
			
		||||
def plg_on_top_data_refresh(self, pinfo):
 | 
			
		||||
	PI = self.INTERNALS['Plg'].proc
 | 
			
		||||
	
 | 
			
		||||
	pid = pinfo['pid']
 | 
			
		||||
	
 | 
			
		||||
	# Get JIFFIES CPU usage
 | 
			
		||||
	used_jiffies = pinfo['utime'] + pinfo['stime']
 | 
			
		||||
	last_ujiffies = get_pid_ujiffies(self, pid)
 | 
			
		||||
	
 | 
			
		||||
	cpu_usage = PI.get_CPU_usage(self.cpu_hz, used_jiffies, pinfo['start_time'])
 | 
			
		||||
 | 
			
		||||
	# Get PERCENT CPU usage
 | 
			
		||||
	if last_ujiffies == 0.0:
 | 
			
		||||
		pcpu = 0.0
 | 
			
		||||
		set_pid_ujiffies(self, pid, cpu_usage['used_jiffies'])
 | 
			
		||||
		data = [int(pcpu)]
 | 
			
		||||
		return data
 | 
			
		||||
				
 | 
			
		||||
	used_jiffies  = cpu_usage['used_jiffies'] - last_ujiffies
 | 
			
		||||
 | 
			
		||||
	# Available jiffies are
 | 
			
		||||
	avail_jiffies = (500/1000.0)*self.cpu_hz # 500 = 0.5 second
 | 
			
		||||
	pcpu = ((used_jiffies*100)/avail_jiffies)
 | 
			
		||||
	
 | 
			
		||||
	set_pid_ujiffies(self, pid, cpu_usage['used_jiffies'])
 | 
			
		||||
		
 | 
			
		||||
	data = [int(pcpu)]
 | 
			
		||||
	return data
 | 
			
		||||
 | 
			
		||||
def get_pid_ujiffies(self, pid):
 | 
			
		||||
	
 | 
			
		||||
	if pid in self.pids_ujiffies:
 | 
			
		||||
		return self.pids_ujiffies[pid]
 | 
			
		||||
	else:
 | 
			
		||||
		set_pid_ujiffies(self, pid, 0)
 | 
			
		||||
		return self.pids_ujiffies[pid]
 | 
			
		||||
 | 
			
		||||
def set_pid_ujiffies(self, pid, ujiffies):
 | 
			
		||||
	self.pids_ujiffies[pid] = ujiffies
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								shell/console/plugins/dirty_size/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								shell/console/plugins/dirty_size/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell/console/plugins/dirty_size
 | 
			
		||||
sugar_PYTHON =				\
 | 
			
		||||
	README				\
 | 
			
		||||
	__init__.py			\
 | 
			
		||||
	info.py				
 | 
			
		||||
							
								
								
									
										2
									
								
								shell/console/plugins/dirty_size/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								shell/console/plugins/dirty_size/README
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
This plugin give support to get the public and shared dirty memory usage 
 | 
			
		||||
by process using the /proc/PID/smaps file. 
 | 
			
		||||
							
								
								
									
										17
									
								
								shell/console/plugins/dirty_size/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								shell/console/plugins/dirty_size/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
 | 
			
		||||
import info
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
INTERNALS = {
 | 
			
		||||
			# Basic information
 | 
			
		||||
			'PLGNAME': "Dirty Size",
 | 
			
		||||
			'TABNAME': None, # No tabbed plugin
 | 
			
		||||
			'AUTHOR': "Eduardo Silva",
 | 
			
		||||
			'DESC': "Get dirty size memory usage",
 | 
			
		||||
 | 
			
		||||
			# Plugin API
 | 
			
		||||
			'Plg': None, # Plugin object
 | 
			
		||||
 | 
			
		||||
			'top_data': [int], # Top data types needed by memphis core plugin
 | 
			
		||||
			'top_cols': ["PDRSS (kb)"]
 | 
			
		||||
		}
 | 
			
		||||
							
								
								
									
										20
									
								
								shell/console/plugins/dirty_size/info.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								shell/console/plugins/dirty_size/info.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
###########################################################
 | 
			
		||||
# Main function:
 | 
			
		||||
# -----------------
 | 
			
		||||
# self:  self plugin object
 | 
			
		||||
# mself: memphis object / principal class
 | 
			
		||||
# pinfo: row with information about current tracing process
 | 
			
		||||
############################################################
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def plg_on_top_data_refresh(self, ppinfo):
 | 
			
		||||
 | 
			
		||||
	dirty_sizes = get_dirty(self, ppinfo['pid'])
 | 
			
		||||
	
 | 
			
		||||
	# memhis need an array 
 | 
			
		||||
	return [dirty_sizes['private']]
 | 
			
		||||
 | 
			
		||||
def get_dirty(pself, pid):
 | 
			
		||||
	ProcAnalysis = pself.INTERNALS['Plg'].proc_analysis(pid)
 | 
			
		||||
 | 
			
		||||
	return ProcAnalysis.DirtyRSS()
 | 
			
		||||
							
								
								
									
										6
									
								
								shell/console/plugins/memphis_init/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								shell/console/plugins/memphis_init/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell/console/plugins/memphis_init
 | 
			
		||||
sugar_PYTHON =				\
 | 
			
		||||
	README				\
 | 
			
		||||
	__init__.py			\
 | 
			
		||||
	info.py				
 | 
			
		||||
							
								
								
									
										2
									
								
								shell/console/plugins/memphis_init/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								shell/console/plugins/memphis_init/README
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
This plugin give support to draw the Virtual Memory Size 
 | 
			
		||||
usage by the current tracing process. 
 | 
			
		||||
							
								
								
									
										15
									
								
								shell/console/plugins/memphis_init/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								shell/console/plugins/memphis_init/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
import info
 | 
			
		||||
 | 
			
		||||
INTERNALS = {
 | 
			
		||||
			'PLGNAME': "memphis",
 | 
			
		||||
			'TABNAME': None,
 | 
			
		||||
			'AUTHOR': "Eduardo Silva",
 | 
			
		||||
			'DESC': "Print basic process information",
 | 
			
		||||
 | 
			
		||||
			# Plugin API
 | 
			
		||||
			'Plg': None, # Plugin object
 | 
			
		||||
 | 
			
		||||
			# Top process view requirements
 | 
			
		||||
			'top_data': [int, str, str], # Top data types needed by memphis core plugin
 | 
			
		||||
			'top_cols': ["PID", "Process Name", "Status"] # Column names
 | 
			
		||||
		}
 | 
			
		||||
							
								
								
									
										13
									
								
								shell/console/plugins/memphis_init/info.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								shell/console/plugins/memphis_init/info.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
###########################################################
 | 
			
		||||
# Main function:
 | 
			
		||||
# -----------------
 | 
			
		||||
# self:  self plugin object
 | 
			
		||||
# mself: memphis object / principal class
 | 
			
		||||
# pinfo: row with information about current tracing process
 | 
			
		||||
############################################################
 | 
			
		||||
 | 
			
		||||
def plg_on_top_data_refresh(self, ppinfo):
 | 
			
		||||
 | 
			
		||||
	data = [ppinfo['pid'], ppinfo['name'], ppinfo['state_name']]
 | 
			
		||||
		
 | 
			
		||||
	return data
 | 
			
		||||
							
								
								
									
										8
									
								
								shell/console/procmem/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								shell/console/procmem/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
 | 
			
		||||
sugardir = $(pkgdatadir)/shell/console/procmem
 | 
			
		||||
 | 
			
		||||
sugar_PYTHON =				\
 | 
			
		||||
	__init__.py			\
 | 
			
		||||
	proc.py				\
 | 
			
		||||
	proc_smaps.py			\
 | 
			
		||||
	analysis.py			
 | 
			
		||||
							
								
								
									
										0
									
								
								shell/console/procmem/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								shell/console/procmem/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										30
									
								
								shell/console/procmem/analysis.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								shell/console/procmem/analysis.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
import proc, proc_smaps
 | 
			
		||||
 | 
			
		||||
class Analysis:
 | 
			
		||||
	
 | 
			
		||||
	pid = 0
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self, pid):
 | 
			
		||||
		self.pid = pid
 | 
			
		||||
	
 | 
			
		||||
	def DirtyRSS(self):
 | 
			
		||||
		smaps =	proc_smaps.ProcSmaps(self.pid)
 | 
			
		||||
		dirty = []
 | 
			
		||||
 | 
			
		||||
		private = 0
 | 
			
		||||
		shared = 0
 | 
			
		||||
		
 | 
			
		||||
		for map in smaps.mappings:
 | 
			
		||||
			private += map.private_dirty
 | 
			
		||||
			shared  += map.shared_dirty
 | 
			
		||||
 | 
			
		||||
		dirty = {"private": int(private), "shared": int(shared)}
 | 
			
		||||
 | 
			
		||||
		return dirty
 | 
			
		||||
	
 | 
			
		||||
	def ApproxRealMemoryUsage(self):
 | 
			
		||||
		maps = proc_smaps.ProcMaps(self.pid)
 | 
			
		||||
		size = (maps.clean_size/1024)
 | 
			
		||||
 | 
			
		||||
		return size
 | 
			
		||||
	
 | 
			
		||||
							
								
								
									
										100
									
								
								shell/console/procmem/proc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								shell/console/procmem/proc.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
 | 
			
		||||
import sys, os
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
class ProcInfo:
 | 
			
		||||
 | 
			
		||||
	dir_path	= "/proc/"	# Our cute Proc File System
 | 
			
		||||
	status_file = "status"
 | 
			
		||||
	stat_file	= "stat"
 | 
			
		||||
	
 | 
			
		||||
	proc_list = [] # Our PID list :D
 | 
			
		||||
	proc_info = [] # 
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self.proc_list = self.Get_PID_List()
 | 
			
		||||
		
 | 
			
		||||
	# Returns Process List
 | 
			
		||||
	def Get_PID_List(self):
 | 
			
		||||
		list = []
 | 
			
		||||
		
 | 
			
		||||
		# Exists our procfs ?
 | 
			
		||||
		if os.path.isdir(self.dir_path):
 | 
			
		||||
			# around dir entries
 | 
			
		||||
			for f in os.listdir(self.dir_path):
 | 
			
		||||
				if os.path.isdir(self.dir_path+f) & str.isdigit(f):
 | 
			
		||||
						list.append(int(f))
 | 
			
		||||
 | 
			
		||||
		return list
 | 
			
		||||
	
 | 
			
		||||
	def MemoryInfo(self, pid):
 | 
			
		||||
		# Path
 | 
			
		||||
		pidfile = self.dir_path + str(pid) + "/stat"
 | 
			
		||||
		try:
 | 
			
		||||
			infile = open(pidfile, "r")
 | 
			
		||||
		except:
 | 
			
		||||
			print "Error trying " + pidfile
 | 
			
		||||
			return None
 | 
			
		||||
 | 
			
		||||
		# Parsing data , check 'man 5 proc' for details
 | 
			
		||||
		data = infile.read().split()
 | 
			
		||||
 | 
			
		||||
		infile.close()
 | 
			
		||||
		
 | 
			
		||||
		state_dic = {
 | 
			
		||||
					'R': 'Running',
 | 
			
		||||
					'S': 'Sleeping', 
 | 
			
		||||
					'D': 'Disk sleep',
 | 
			
		||||
					'Z': 'Zombie', 
 | 
			
		||||
					'T': 'Traced/Stopped', 
 | 
			
		||||
					'W': 'Paging'
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
		# user and group owners
 | 
			
		||||
		pidstat = os.stat(pidfile)
 | 
			
		||||
		
 | 
			
		||||
		info = {
 | 
			
		||||
			'pid':		int(data[0]), # Process ID
 | 
			
		||||
			'name':		data[1].strip('()'), # Process name
 | 
			
		||||
			'state':	data[2], # Process State, ex: R|S|D|Z|T|W
 | 
			
		||||
			'state_name':	state_dic[data[2]], # Process State name, ex: Running, sleeping, Zombie, etc
 | 
			
		||||
			'ppid':		int(data[3]), # Parent process ID
 | 
			
		||||
			'utime':	int(data[13]), # Used jiffies in user mode
 | 
			
		||||
			'stime':	int(data[14]), # Used jiffies in kernel mode
 | 
			
		||||
			'start_time':	int(data[21]), # Process time from system boot (jiffies)
 | 
			
		||||
			'vsize':	int(data[22]), # Virtual memory size used (bytes)
 | 
			
		||||
			'rss':		int(data[23])*4,	# Resident Set Size (bytes)
 | 
			
		||||
			'user_id': pidstat.st_uid, # process owner
 | 
			
		||||
			'group_id': pidstat.st_gid # owner group
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return info
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	# Returns the CPU usage expressed in Jiffies
 | 
			
		||||
	def get_CPU_usage(self, cpu_hz, used_jiffies, start_time):
 | 
			
		||||
		
 | 
			
		||||
		# Uptime info
 | 
			
		||||
		uptime_file = self.dir_path + "/uptime"
 | 
			
		||||
		try:
 | 
			
		||||
			infile = file(uptime_file, "r")
 | 
			
		||||
		except:
 | 
			
		||||
			print "Error trying uptime file"
 | 
			
		||||
			return None
 | 
			
		||||
		
 | 
			
		||||
		uptime_line = infile.readline()
 | 
			
		||||
		uptime = string.split(uptime_line, " ",2)
 | 
			
		||||
		
 | 
			
		||||
		infile.close()
 | 
			
		||||
				
 | 
			
		||||
		# System uptime, from /proc/uptime
 | 
			
		||||
		uptime = float(uptime[0])
 | 
			
		||||
		
 | 
			
		||||
		# Jiffies
 | 
			
		||||
		avail_jiffies = (uptime * cpu_hz) - start_time
 | 
			
		||||
		
 | 
			
		||||
		cpu_usage = {'used_jiffies': used_jiffies, 'avail_jiffies': avail_jiffies}
 | 
			
		||||
 | 
			
		||||
		return cpu_usage
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										129
									
								
								shell/console/procmem/proc_smaps.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								shell/console/procmem/proc_smaps.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,129 @@
 | 
			
		||||
####################################################################
 | 
			
		||||
# This class open the /proc/PID/maps and /proc/PID/smaps files
 | 
			
		||||
# to get useful information about the real memory usage
 | 
			
		||||
####################################################################
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# Parse the /proc/PID/smaps file
 | 
			
		||||
class ProcSmaps:
 | 
			
		||||
 | 
			
		||||
	mappings = [] # Devices information
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self, pid):
 | 
			
		||||
		
 | 
			
		||||
		smapfile = "/proc/%s/smaps" % pid
 | 
			
		||||
		self.mappings = []
 | 
			
		||||
		
 | 
			
		||||
		# Coded by Federico Mena (script)
 | 
			
		||||
		try:
 | 
			
		||||
			infile = open(smapfile, "r")
 | 
			
		||||
			input = infile.read()
 | 
			
		||||
			infile.close()
 | 
			
		||||
		except:
 | 
			
		||||
			print "Error trying " + smapfile
 | 
			
		||||
			return
 | 
			
		||||
		
 | 
			
		||||
		lines = input.splitlines()
 | 
			
		||||
 | 
			
		||||
		num_lines = len (lines)
 | 
			
		||||
		line_idx = 0
 | 
			
		||||
	
 | 
			
		||||
		# 08065000-08067000 rw-p 0001c000 03:01 147613     /opt/gnome/bin/evolution-2.6
 | 
			
		||||
		# Size:                 8 kB
 | 
			
		||||
		# Rss:                  8 kB
 | 
			
		||||
		# Shared_Clean:         0 kB
 | 
			
		||||
		# Shared_Dirty:         0 kB
 | 
			
		||||
		# Private_Clean:        8 kB
 | 
			
		||||
		# Private_Dirty:        0 kB
 | 
			
		||||
	
 | 
			
		||||
		while num_lines > 0:
 | 
			
		||||
			fields = lines[line_idx].split (" ", 5)
 | 
			
		||||
			if len (fields) == 6:
 | 
			
		||||
				(offsets, permissions, bin_permissions, device, inode, name) = fields
 | 
			
		||||
			else:
 | 
			
		||||
				(offsets, permissions, bin_permissions, device, inode) = fields
 | 
			
		||||
				name = ""
 | 
			
		||||
	
 | 
			
		||||
			size          = self.parse_smaps_size_line (lines[line_idx + 1])
 | 
			
		||||
			rss           = self.parse_smaps_size_line (lines[line_idx + 2])
 | 
			
		||||
			shared_clean  = self.parse_smaps_size_line (lines[line_idx + 3])
 | 
			
		||||
			shared_dirty  = self.parse_smaps_size_line (lines[line_idx + 4])
 | 
			
		||||
			private_clean = self.parse_smaps_size_line (lines[line_idx + 5])
 | 
			
		||||
			private_dirty = self.parse_smaps_size_line (lines[line_idx + 6])
 | 
			
		||||
			name = name.strip ()
 | 
			
		||||
 | 
			
		||||
			mapping = Mapping (size, rss, shared_clean, shared_dirty, private_clean, private_dirty, permissions, name)
 | 
			
		||||
			self.mappings.append (mapping)
 | 
			
		||||
 | 
			
		||||
			num_lines -= 7
 | 
			
		||||
			line_idx += 7
 | 
			
		||||
 | 
			
		||||
	# Parses a line of the form "foo: 42 kB" and returns an integer for the "42" field
 | 
			
		||||
	def parse_smaps_size_line (self, line):
 | 
			
		||||
		# Rss:                  8 kB
 | 
			
		||||
		fields = line.split ()
 | 
			
		||||
		return int(fields[1])
 | 
			
		||||
 | 
			
		||||
class Mapping:
 | 
			
		||||
	def __init__ (self, size, rss, shared_clean, shared_dirty, private_clean, private_dirty, permissions, name):
 | 
			
		||||
		self.size = size
 | 
			
		||||
		self.rss = rss
 | 
			
		||||
		self.shared_clean = shared_clean
 | 
			
		||||
		self.shared_dirty = shared_dirty
 | 
			
		||||
		self.private_clean = private_clean
 | 
			
		||||
		self.private_dirty = private_dirty
 | 
			
		||||
		self.permissions = permissions
 | 
			
		||||
		self.name = name
 | 
			
		||||
 | 
			
		||||
# Parse /proc/PID/maps file to get the clean memory usage by process,
 | 
			
		||||
# we avoid lines with backed-files
 | 
			
		||||
class ProcMaps:
 | 
			
		||||
	
 | 
			
		||||
	clean_size = 0
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self, pid):
 | 
			
		||||
		mapfile = "/proc/%s/maps" % pid
 | 
			
		||||
 | 
			
		||||
		try:
 | 
			
		||||
			infile = open(mapfile, "r")
 | 
			
		||||
		except:
 | 
			
		||||
			print "Error trying " + mapfile
 | 
			
		||||
			return None
 | 
			
		||||
			
 | 
			
		||||
		sum = 0
 | 
			
		||||
		to_data_do = {
 | 
			
		||||
			"[anon]": self.parse_size_line,
 | 
			
		||||
			"[heap]": self.parse_size_line
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		for line in infile:
 | 
			
		||||
			arr = line.split()
 | 
			
		||||
			
 | 
			
		||||
			# Just parse writable mapped areas
 | 
			
		||||
			if arr[1][1] != "w":
 | 
			
		||||
				continue
 | 
			
		||||
			
 | 
			
		||||
			if len(arr) == 6:				
 | 
			
		||||
				# if we got a backed-file we skip this info
 | 
			
		||||
				if os.path.isfile(arr[5]):
 | 
			
		||||
					continue
 | 
			
		||||
				else:
 | 
			
		||||
					line_size = to_data_do.get(arr[5], self.skip)(line)
 | 
			
		||||
					sum += line_size
 | 
			
		||||
			else:
 | 
			
		||||
				line_size = self.parse_size_line(line)
 | 
			
		||||
				sum += line_size
 | 
			
		||||
					
 | 
			
		||||
		infile.close()
 | 
			
		||||
		self.clean_size = sum
 | 
			
		||||
		
 | 
			
		||||
	def skip(self, line):
 | 
			
		||||
		return 0
 | 
			
		||||
	
 | 
			
		||||
	# Parse a maps line and return the mapped size
 | 
			
		||||
	def parse_size_line(self, line):
 | 
			
		||||
		start, end = line.split()[0].split('-')
 | 
			
		||||
		size = int(end, 16) - int(start, 16)			
 | 
			
		||||
		return size
 | 
			
		||||
							
								
								
									
										143
									
								
								shell/console/terminal.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								shell/console/terminal.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
			
		||||
import gtk
 | 
			
		||||
import vte
 | 
			
		||||
import pango
 | 
			
		||||
 | 
			
		||||
class Terminal(gtk.HBox):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		gtk.HBox.__init__(self, False, 4)
 | 
			
		||||
 | 
			
		||||
		self._vte = vte.Terminal()
 | 
			
		||||
		self._configure_vte()
 | 
			
		||||
		self._vte.set_size(30, 5)
 | 
			
		||||
		self._vte.set_size_request(200, 450)
 | 
			
		||||
		self._vte.show()
 | 
			
		||||
		self.pack_start(self._vte)
 | 
			
		||||
		
 | 
			
		||||
		self._scrollbar = gtk.VScrollbar(self._vte.get_adjustment())
 | 
			
		||||
		self._scrollbar.show()
 | 
			
		||||
		self.pack_start(self._scrollbar, False, False, 0)
 | 
			
		||||
		
 | 
			
		||||
		self._vte.connect("child-exited", lambda term: term.fork_command())
 | 
			
		||||
 | 
			
		||||
		self._vte.fork_command()
 | 
			
		||||
 | 
			
		||||
	def _configure_vte(self):
 | 
			
		||||
		self._vte.set_font(pango.FontDescription('Monospace 10'))
 | 
			
		||||
		self._vte.set_colors(gtk.gdk.color_parse ('#AAAAAA'),
 | 
			
		||||
							gtk.gdk.color_parse ('#000000'),
 | 
			
		||||
							[])
 | 
			
		||||
		self._vte.set_cursor_blinks(False)
 | 
			
		||||
		self._vte.set_audible_bell(False)
 | 
			
		||||
		self._vte.set_scrollback_lines(100)
 | 
			
		||||
		self._vte.set_allow_bold(True)
 | 
			
		||||
		self._vte.set_scroll_on_keystroke(False)
 | 
			
		||||
		self._vte.set_scroll_on_output(False)
 | 
			
		||||
		self._vte.set_emulation('xterm')
 | 
			
		||||
		self._vte.set_visible_bell(False)
 | 
			
		||||
 | 
			
		||||
	def on_gconf_notification(self, client, cnxn_id, entry, what):
 | 
			
		||||
		self.reconfigure_vte()
 | 
			
		||||
 | 
			
		||||
	def on_vte_button_press(self, term, event):
 | 
			
		||||
		if event.button == 3:
 | 
			
		||||
			self.do_popup(event)
 | 
			
		||||
			return True
 | 
			
		||||
 | 
			
		||||
	def on_vte_popup_menu(self, term):
 | 
			
		||||
		pass
 | 
			
		||||
 | 
			
		||||
class Multiple:
 | 
			
		||||
	
 | 
			
		||||
	page_number = 0
 | 
			
		||||
	
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self.notebook = gtk.Notebook()
 | 
			
		||||
		self.add_new_terminal()
 | 
			
		||||
		
 | 
			
		||||
		open_terminal = gtk.Button('Open a new terminal')
 | 
			
		||||
		open_terminal.connect("clicked", self.add_new_terminal)
 | 
			
		||||
		open_terminal.show()
 | 
			
		||||
				
 | 
			
		||||
		self.notebook.show()
 | 
			
		||||
		
 | 
			
		||||
		self.main_vbox = gtk.VBox(False, 3)
 | 
			
		||||
		self.main_vbox.pack_start(open_terminal, True, True, 2)
 | 
			
		||||
		self.main_vbox.pack_start(self.notebook, True, True, 2)
 | 
			
		||||
 | 
			
		||||
		self.main_vbox.show_all()
 | 
			
		||||
	
 | 
			
		||||
	# Remove a page from the notebook
 | 
			
		||||
	def close_terminal(self, button, child):
 | 
			
		||||
		page = self.notebook.page_num(child)
 | 
			
		||||
 | 
			
		||||
		if page != -1:
 | 
			
		||||
			self.notebook.remove_page(page)
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		pages = self.notebook.get_n_pages()
 | 
			
		||||
		if pages <= 0:
 | 
			
		||||
			self.page_number = 0
 | 
			
		||||
			self.add_new_terminal()
 | 
			
		||||
			
 | 
			
		||||
		# Need to refresh the widget --
 | 
			
		||||
		# This forces the widget to redraw itself.
 | 
			
		||||
		self.notebook.queue_draw_area(0, 0, -1, -1)
 | 
			
		||||
 | 
			
		||||
	def add_icon_to_button(self, button):
 | 
			
		||||
		iconBox = gtk.HBox(False, 0)
 | 
			
		||||
		image = gtk.Image()
 | 
			
		||||
		image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
 | 
			
		||||
		gtk.Button.set_relief(button, gtk.RELIEF_NONE)
 | 
			
		||||
 | 
			
		||||
		settings = gtk.Widget.get_settings (button)
 | 
			
		||||
		(w,h) = gtk.icon_size_lookup_for_settings (settings, gtk.ICON_SIZE_MENU)
 | 
			
		||||
		gtk.Widget.set_size_request (button, w + 4, h + 4)
 | 
			
		||||
		image.show()
 | 
			
		||||
		iconBox.pack_start(image, True, False, 0)
 | 
			
		||||
		button.add(iconBox)
 | 
			
		||||
		iconBox.show()
 | 
			
		||||
 | 
			
		||||
	def add_new_terminal(self, *arguments, **keywords):
 | 
			
		||||
		self.page_number += 1
 | 
			
		||||
 | 
			
		||||
		terminal = Terminal()
 | 
			
		||||
		terminal.show()
 | 
			
		||||
 | 
			
		||||
		eventBox = self.create_custom_tab("Term %d" % self.page_number, terminal)
 | 
			
		||||
		self.notebook.append_page(terminal, eventBox)
 | 
			
		||||
 | 
			
		||||
		# Set the new page
 | 
			
		||||
		pages = gtk.Notebook.get_n_pages(self.notebook)
 | 
			
		||||
		self.notebook.set_current_page(pages - 1)
 | 
			
		||||
		return True
 | 
			
		||||
 | 
			
		||||
	def create_custom_tab(self, text, child):
 | 
			
		||||
		eventBox = gtk.EventBox()
 | 
			
		||||
		tabBox = gtk.HBox(False, 2)
 | 
			
		||||
		tabLabel = gtk.Label(text)
 | 
			
		||||
 | 
			
		||||
		tabButton = gtk.Button()
 | 
			
		||||
		tabButton.connect('clicked', self.close_terminal, child)
 | 
			
		||||
 | 
			
		||||
		# Add a picture on a button
 | 
			
		||||
		self.add_icon_to_button(tabButton)
 | 
			
		||||
		iconBox = gtk.HBox(False, 0)
 | 
			
		||||
 | 
			
		||||
		eventBox.show()
 | 
			
		||||
		tabButton.show()
 | 
			
		||||
		tabLabel.show()
 | 
			
		||||
 | 
			
		||||
		tabBox.pack_start(tabLabel, False)
 | 
			
		||||
		tabBox.pack_start(tabButton, False)
 | 
			
		||||
 | 
			
		||||
		tabBox.show_all()
 | 
			
		||||
		eventBox.add(tabBox)
 | 
			
		||||
		
 | 
			
		||||
		return eventBox
 | 
			
		||||
 | 
			
		||||
class Interface:
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		multiple = Multiple()
 | 
			
		||||
		self.widget = multiple.main_vbox
 | 
			
		||||
		
 | 
			
		||||
@ -6,6 +6,6 @@
 | 
			
		||||
<Alt>p=prev
 | 
			
		||||
<Alt>c=close
 | 
			
		||||
 | 
			
		||||
<Alt><Shift>F12=!sugar-log-viewer
 | 
			
		||||
<Alt><Shift>F12=!sugar-devel-console
 | 
			
		||||
<Alt>q=!sugar-emulator-shutdown
 | 
			
		||||
<Alt><Shift>Escape=!sugar-shutdown
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								shell/sugar-devel-console
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										12
									
								
								shell/sugar-devel-console
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
 | 
			
		||||
# Sugar developer console launcher
 | 
			
		||||
import pygtk
 | 
			
		||||
pygtk.require('2.0')
 | 
			
		||||
 | 
			
		||||
import os, sys
 | 
			
		||||
from sugar import env 
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, os.path.join(env.get_data_dir(), 'shell'))
 | 
			
		||||
 | 
			
		||||
import console.console
 | 
			
		||||
@ -76,12 +76,7 @@ for i in range(1, len(sys.argv)):
 | 
			
		||||
emulator = Emulator(fullscreen)
 | 
			
		||||
emulator.start()
 | 
			
		||||
 | 
			
		||||
if env.get_dbus_version() < '0.95':
 | 
			
		||||
	if not os.path.isdir('/tmp/sugar-services'):
 | 
			
		||||
		os.mkdir('/tmp/sugar-services')
 | 
			
		||||
	dbus_config = env.get_dbus_config_094()
 | 
			
		||||
else:
 | 
			
		||||
	dbus_config = env.get_dbus_config()
 | 
			
		||||
dbus_config = env.get_dbus_config()
 | 
			
		||||
 | 
			
		||||
os.execlp('dbus-launch', 'dbus-launch', '--exit-with-session',
 | 
			
		||||
		  '--config-file=%s' % dbus_config, program)
 | 
			
		||||
 | 
			
		||||
@ -4,5 +4,4 @@ sugar_activities_dir = '@prefix@/share/sugar/activities'
 | 
			
		||||
sugar_activity_info_dir = '@prefix@/share/sugar/activities'
 | 
			
		||||
sugar_services_dir = '@prefix@/share/sugar/services'
 | 
			
		||||
sugar_dbus_config = '@prefix@/share/sugar/dbus-installed.conf'
 | 
			
		||||
sugar_dbus_config_094 = '@prefix@/share/sugar/dbus-installed-094.conf'
 | 
			
		||||
sugar_shell_bin_dir = '@prefix@/bin'
 | 
			
		||||
 | 
			
		||||
@ -9,5 +9,4 @@ sugar_services_dir = os.path.join(_sourcedir, 'services')
 | 
			
		||||
sugar_activity_info_dir = _tmpdir
 | 
			
		||||
sugar_activities_dir = os.path.join(_sourcedir, 'activities')
 | 
			
		||||
sugar_dbus_config = os.path.join(_sourcedir, 'dbus-uninstalled.conf')
 | 
			
		||||
sugar_dbus_config_094 = os.path.join(_sourcedir, 'dbus-uninstalled-094.conf')
 | 
			
		||||
sugar_shell_bin_dir = os.path.join(_sourcedir, 'shell')
 | 
			
		||||
 | 
			
		||||
@ -100,6 +100,7 @@ class Activity(gtk.Window):
 | 
			
		||||
 | 
			
		||||
		bus = dbus.SessionBus()
 | 
			
		||||
		xid = self.window.xid
 | 
			
		||||
 | 
			
		||||
		bus_name = dbus.service.BusName(get_service_name(xid), bus=bus)
 | 
			
		||||
		self._bus = ActivityDbusService(bus_name, get_object_path(xid))
 | 
			
		||||
		self._bus.start(self._pservice, self)
 | 
			
		||||
 | 
			
		||||
@ -10,11 +10,7 @@ class _ServiceParser(ConfigParser):
 | 
			
		||||
 | 
			
		||||
class _ServiceManager(object):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		if env.get_dbus_version() < '0.95':
 | 
			
		||||
			self._path = '/tmp/sugar-services'
 | 
			
		||||
		else:
 | 
			
		||||
			self._path = os.path.expanduser('~/.local/share/dbus-1/services')
 | 
			
		||||
 | 
			
		||||
		self._path = os.path.expanduser('~/.local/share/dbus-1/services')
 | 
			
		||||
		if not os.path.isdir(self._path):
 | 
			
		||||
			os.makedirs(self._path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -54,9 +54,6 @@ def get_services_dir():
 | 
			
		||||
def get_dbus_config():
 | 
			
		||||
	return sugar_dbus_config
 | 
			
		||||
 | 
			
		||||
def get_dbus_config_094():
 | 
			
		||||
	return sugar_dbus_config_094
 | 
			
		||||
 | 
			
		||||
def get_shell_bin_dir():
 | 
			
		||||
	return sugar_shell_bin_dir
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user