Sorry! I thought the attachments would remain as is. I'll git send-email this.
On Thu, Jul 29, 2010 at 1:09 AM, Anish Mangal <anishmangal2...@gmail.com> wrote: > Thank you for reviewing this patch. However, after receiving feedback > from Py. I've modified some of its functionality. The two patches > attached implement that functionality. I've updated the parallel > thread "[DESIGN] Displaying the current status of system resources > (such as memory, cpu)" to augment further discussion on this. > > -- > Anish > > On Sat, Jul 10, 2010 at 3:09 PM, Marco Pesenti Gritti <ma...@marcopg.org> > wrote: >> On 10 Jul 2010, at 08:43, Anish Mangal <anishmangal2...@gmail.com> wrote: >>>> diff --git a/extensions/deviceicon/resources.py >>>> b/extensions/deviceicon/resources.py >>>> new file mode 100644 >>>> index 0000000..7503bef >>>> --- /dev/null >>>> +++ b/extensions/deviceicon/resources.py >>>> @@ -0,0 +1,188 @@ >>>> +# Copyright (C) Anish Mangal <anishmangal2...@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 >>>> + >>>> +from gettext import gettext as _ >>>> +import logging >>>> +import os >>>> + >>>> +import gobject >>>> +import gtk >>>> +import gconf >>>> + >>>> +from sugar.graphics.tray import TrayIcon >>>> +from sugar.graphics.xocolor import XoColor >>>> +from sugar.graphics.palette import Palette >>>> +from sugar.graphics import style >>>> + >>>> +from jarabe.frame.frameinvoker import FrameWidgetInvoker >>>> + >>>> +class DeviceView(TrayIcon): >>>> + >>>> + FRAME_POSITION_RELATIVE = 500 >>>> + >>>> + def __init__(self): >>>> + client = gconf.client_get_default() >>>> + color = XoColor(client.get_string('/desktop/sugar/user/color')) >>>> + TrayIcon.__init__(self, icon_name='computer', xo_color=color) >>>> + self.set_palette_invoker(FrameWidgetInvoker(self)) >>>> + >>>> + def create_palette(self): >>>> + palette = ResourcePalette(_('System resources')) >>>> + palette.set_group_id('frame') >>>> + return palette >>>> + >>>> +class ResourcePalette(Palette): >>>> + >>>> + def __init__(self, primary_text): >>>> + Palette.__init__(self, label=primary_text) >>>> + >>>> + self._popup_cb_id = self.connect('popup', self._popup_cb) >>>> + self._popdown_cb_id = self.connect('popdown', self._popdown_cb) >>>> + >>>> + self.vbox = gtk.VBox() >>>> + self.set_content(self.vbox) >>>> + >>>> + self._cpu_text = gtk.Label() >>>> + self.vbox.pack_start(self._cpu_text, >>>> padding=style.DEFAULT_PADDING) >>>> + self._cpu_text.show() >>>> + >>>> + self._cpu_bar = gtk.ProgressBar() >>>> + self._cpu_bar.set_size_request( >>>> + style.zoom(style.GRID_CELL_SIZE * 4), -1) >>>> + self.vbox.pack_start(self._cpu_bar, padding=style.DEFAULT_PADDING) >>>> + self._cpu_bar.show() >>>> + >>>> + self._memory_text = gtk.Label() >>>> + self.vbox.pack_start(self._memory_text, >>>> padding=style.DEFAULT_PADDING) >>>> + self._memory_text.show() >>>> + >>>> + self._memory_bar = gtk.ProgressBar() >>>> + self._memory_bar.set_size_request( >>>> + style.zoom(style.GRID_CELL_SIZE * 4), -1) >>>> + self.vbox.pack_start(self._memory_bar, >>>> padding=style.DEFAULT_PADDING) >>>> + self._memory_bar.show() >>>> + >>>> + self.vbox.show() >>>> + >>>> + try: >>>> + self._cpu_times = self._get_cpu_times_list() >>>> + except Exception: >>>> + logging.exception('An error ocurred while attempting to ' >>>> + 'read /proc/stat') >> >> Which exceptions do you expect to happen and in which situations? Catch all >> exceptions are generally a bad idea. >> >> >>>> + self._remove_callbacks() >>>> + >>>> + def _get_cpu_times_list(self): >>>> + """Return various cpu times as read from /proc/stat >>>> + >>>> + This method returns the following cpu times measured >>>> + in jiffies (1/100 of a second for x86 systems) >>>> + as an ordered list of numbers - [user, nice, >>>> + system, idle, iowait] where, >>>> + >>>> + user: normal processes executing in user mode >>>> + nice: niced processes executing in user mode >>>> + system: processes executing in kernel mode >>>> + idle: twiddling thumbs >>>> + iowait: waiting for I/O to complete >>>> + >>>> + Note: For systems having 2 or more CPU's, the above >>>> + numbers would be the cumulative sum of these times >>>> + for all CPU's present in the system. >>>> + >>>> + """ >>>> + return [int(count) >>>> + for count in file('/proc/stat').readline().split()[1:6]] >>>> + >>>> + def _percentage_cpu_available(self): >>>> + """ >>>> + Return free CPU resources as a percentage >>>> + >>>> + """ >>>> + _cpu_times_new = self._get_cpu_times_list() >>>> + _cpu_times_current = [(new - old) >>>> + for new, old in zip(_cpu_times_new, self._cpu_times)] >>>> + user, nice, system, idle, iowait = _cpu_times_current >>>> + cpu_free = (idle + iowait) * 100.0 / sum(_cpu_times_current) >>>> + self._cpu_times = self._get_cpu_times_list() >>>> + return cpu_free >>>> + >>>> + def _percentage_memory_available(self): >>>> + """ >>>> + Return free memory as a percentage >>>> + >>>> + """ >>>> + for line in file('/proc/meminfo'): >>>> + name, value, unit = line.split()[:3] >>>> + if 'MemTotal:' == name: >>>> + total = int(value) >>>> + elif 'MemFree:' == name: >>>> + free = int(value) >>>> + elif 'Buffers:' == name: >>>> + buffers = int(value) >>>> + elif 'Cached:' == name: >>>> + cached = int(value) >>>> + elif 'Active:' == name: >>>> + break >>>> + return (free + buffers + cached) * 100.0 / total >>>> + >>>> + def __timer_cb(self): >>>> + try: >>>> + cpu_free = self._percentage_cpu_available() >>>> + memory_free = self._percentage_memory_available() >>>> + self._cpu_text.set_label(_('CPU free: %d%%' % cpu_free)) >>>> + self._cpu_bar.set_fraction(cpu_free/100.0) >> >> Space around the operator >> >>>> + self._memory_text.set_label(_('Memory free: %d%%' % >>>> memory_free)) >>>> + self._memory_bar.set_fraction(memory_free/100.0) >> >> Same >> >> >>>> + return True >>>> + except Exception: >>>> + logging.exception('An error ocurred while trying to ' >>>> + 'retrieve resource usage statistics') >>>> + self._remove_callbacks() >>>> + return False >> >> Same here. Also the UI code should be moved outside the try so that we don't >> cover errors in it. >> >>>> >>>> + def _remove_callbacks(self): >>>> + """ >>>> + Stop computing usage statistics and display and error message >>>> + since we've hit an exception. >>>> + >>>> + """ >>>> + self.disconnect(self._popup_cb_id) >>>> + self.disconnect(self._popdown_cb_id) >>>> + >>>> + # Use the existing _cpu_text label to display the error. Remove >>>> + # everything else. >>>> + self._cpu_text.set_size_request( >>>> + style.zoom(style.GRID_CELL_SIZE * 4), -1) >>>> + self._cpu_text.set_line_wrap(True) >>>> + self._cpu_text.set_text(_('Cannot compute CPU and memory usage ' >>>> + 'statistics!')) >>>> + self.vbox.remove(self._cpu_bar) >>>> + self.vbox.remove(self._memory_text) >>>> + self.vbox.remove(self._memory_bar) >> >> This method does a lot more than disconnecting callbacks. The naming should >> reflect that or the method should be split. >> >> Thanks! >> Marco > _______________________________________________ Sugar-devel mailing list Sugar-devel@lists.sugarlabs.org http://lists.sugarlabs.org/listinfo/sugar-devel