From 176262f2e9357c08735bbd4476327fc92d8d5827 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Thu, 25 Oct 2007 14:04:04 +0200 Subject: [PATCH 1/8] Added morgs NotifyAlert (timed one button alert) to the alert api --- NEWS | 2 ++ lib/sugar/graphics/alert.py | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 3230ecef..27daa4a4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* Added morgs NotifyAlert (timed one button alert) to the alert api (erikos) + Snapshot fdb4e49b14 * Save journal files on nand, not tmpfs (tomeu) diff --git a/lib/sugar/graphics/alert.py b/lib/sugar/graphics/alert.py index dd1bcec5..ef649b2a 100644 --- a/lib/sugar/graphics/alert.py +++ b/lib/sugar/graphics/alert.py @@ -32,9 +32,8 @@ class Alert(gtk.EventBox, gobject.GObject): Alerts are used inside the activity window instead of being a separate popup window. They do not hide canvas content. You can use add_alert(widget) and remove_alert(widget) inside your activity - to add and remove the alert. You can set the position (bottom=-1, - top=0,1) for alerts global for the window by changing alert_position, - default is bottom. + to add and remove the alert. The position of the alert is below the + toolbox or top in fullscreen mode. Properties: 'title': the title of the alert, @@ -225,3 +224,31 @@ class TimeoutAlert(Alert): self._response(gtk.RESPONSE_OK) return False return True + + +class NotifyAlert(Alert): + """Timeout alert with only an "OK" button - just for notifications""" + + def __init__(self, timeout=5, **kwargs): + Alert.__init__(self, **kwargs) + + self._timeout = timeout + + self._timeout_text = _TimeoutIcon( + text=self._timeout, + color=style.COLOR_BUTTON_GREY.get_int(), + background_color=style.COLOR_WHITE.get_int()) + canvas = hippo.Canvas() + canvas.set_root(self._timeout_text) + canvas.show() + self.add_button(gtk.RESPONSE_OK, _('OK'), canvas) + + gobject.timeout_add(1000, self.__timeout) + + def __timeout(self): + self._timeout -= 1 + self._timeout_text.props.text = self._timeout + if self._timeout == 0: + self._response(gtk.RESPONSE_OK) + return False + return True From 91c97ba0188fa87eb91ab59bdf4edc4288146943 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Sat, 27 Oct 2007 00:14:43 +0200 Subject: [PATCH 2/8] Snapshot 176262f2e9. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 27daa4a4..191dcff1 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +Snapshot 176262f2e9 + * Added morgs NotifyAlert (timed one button alert) to the alert api (erikos) Snapshot fdb4e49b14 From 4d26d307109c4db2bfcf1fa43ecb475f1ab37c27 Mon Sep 17 00:00:00 2001 From: Pascal Scheffers Date: Sun, 28 Oct 2007 16:56:05 +0100 Subject: [PATCH 3/8] #4358 pydoc strings for activity.py --- NEWS | 2 + lib/sugar/activity/activity.py | 244 +++++++++++++++++++++++++++++++-- 2 files changed, 234 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 191dcff1..fa2e1233 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* #4358: pydoc strings for sugar.activity.Activity + Snapshot 176262f2e9 * Added morgs NotifyAlert (timed one button alert) to the alert api (erikos) diff --git a/lib/sugar/activity/activity.py b/lib/sugar/activity/activity.py index 731a88aa..14cadd76 100644 --- a/lib/sugar/activity/activity.py +++ b/lib/sugar/activity/activity.py @@ -1,7 +1,31 @@ -"""Base class for Python-coded activities +"""Base class for activities written in Python -This is currently the only reference for what an +This is currently the only definitive reference for what an activity must do to participate in the Sugar desktop. + + A Basic Activity + +All activities must implement a class derived from 'Activity' in this class. +The convention is to call it ActivitynameActivity, but this is not required as +the activity.info file associated with your activity will tell the sugar-shell +which class to start. + +For example the most minimal Activity: + + + from sugar.activity import activity + + class ReadActivity(activity.Activity): + pass + +To get a real, working activity, you will at least have to implement: + __init__(), read_file() and write_file() + +Aditionally, you will probably need a at least a Toolbar so you can have some +interesting buttons for the user, like for example 'exit activity' + +See the methods of the Activity class below for more information on what you +will need for a real activity. """ # Copyright (C) 2006-2007 Red Hat, Inc. # @@ -49,6 +73,11 @@ SCOPE_INVITE_ONLY = "invite" # shouldn't be shown in UI, it's implicit when you SCOPE_NEIGHBORHOOD = "public" class ActivityToolbar(gtk.Toolbar): + """The Activity toolbar with the Journal entry title, sharing, Keep and Stop buttons + + All activities should have this toolbar. It is easiest to add it to your + Activity by using the ActivityToolbox. + """ def __init__(self, activity): gtk.Toolbar.__init__(self) @@ -169,6 +198,38 @@ class ActivityToolbar(gtk.Toolbar): self._update_share() class EditToolbar(gtk.Toolbar): + """Provides the standard edit toolbar for Activities. + + Members: + undo -- the undo button + redo -- the redo button + copy -- the copy button + paste -- the paste button + separator -- A separator between undo/redo and copy/paste + + This class only provides the 'edit' buttons in a standard layout, your activity + will need to either hide buttons which make no sense for your Activity, or you + need to connect the button events to your own callbacks: + + ## Example from Read.activity: + # Create the edit toolbar: + self._edit_toolbar = EditToolbar(self._view) + # Hide undo and redo, they're not needed + self._edit_toolbar.undo.props.visible = False + self._edit_toolbar.redo.props.visible = False + # Hide the separator too: + self._edit_toolbar.separator.props.visible = False + + # As long as nothing is selected, copy needs to be insensitive: + self._edit_toolbar.copy.set_sensitive(False) + # When the user clicks the button, call _edit_toolbar_copy_cb() + self._edit_toolbar.copy.connect('clicked', self._edit_toolbar_copy_cb) + + # Add the edit toolbar: + toolbox.add_toolbar(_('Edit'), self._edit_toolbar) + # And make it visible: + self._edit_toolbar.show() + """ def __init__(self): gtk.Toolbar.__init__(self) @@ -198,6 +259,23 @@ class EditToolbar(gtk.Toolbar): self.paste.show() class ActivityToolbox(Toolbox): + """Creates the Toolbox for the Activity + + By default, the toolbox contains only the ActivityToolbar. After creating the + toolbox, you can add your activity specific toolbars, for example the + EditToolbar. + + To add the ActivityToolbox to your Activity in MyActivity.__init__() do: + + # Create the Toolbar with the ActivityToolbar: + toolbox = activity.ActivityToolbox(self) + ... your code, inserting all other toolbars you need, like EditToolbar ... + + # Add the toolbox to the activity frame: + self.set_toolbox(toolbox) + # And make it visible: + toolbox.show() + """ def __init__(self, activity): Toolbox.__init__(self) @@ -209,7 +287,71 @@ class ActivityToolbox(Toolbox): return self._activity_toolbar class Activity(Window, gtk.Container): - """Base Activity class that all other Activities derive from.""" + """This is the base Activity class that all other Activities derive from. This is where your activity starts. + + To get a working Activity: + 0. Derive your Activity from this class: + class MyActivity(activity.Activity): + ... + + 1. implement an __init__() method for your Activity class. + + Use your init method to create your own ActivityToolbar which will + contain some standard buttons: + toolbox = activity.ActivityToolbox(self) + + Add extra Toolbars to your toolbox. + + You should setup Activity sharing here too. + + Finaly, your Activity may need some resources which you can claim + here too. + + The __init__() method is also used to make the distinction between + being resumed from the Journal, or starting with a blank document. + + 2. Implement read_file() and write_file() + Most activities revolve around creating and storing Journal entries. + For example, Write: You create a document, it is saved to the Journal + and then later you resume working on the document. + + read_file() and write_file() will be called by sugar to tell your + Activity that it should load or save the document the user is working + on. + + 3. Implement our Activity Toolbars. + The Toolbars are added to your Activity in step 1 (the toolbox), but + you need to implement them somewhere. Now is a good time. + + There are a number of standard Toolbars. The most basic one, the one + your almost absolutely MUST have is the ActivityToolbar. Without + this, you're not really making a proper Sugar Activity (which may be + okay, but you should really stop and think about why not!) You do + this with the ActivityToolbox(self) call in step 1. + + Usually, you will also need the standard EditToolbar. This is the one + which has the standard copy and paste buttons. You need to derive + your own EditToolbar class from sugar.EditToolbar: + class EditToolbar(activity.EditToolbar): + ... + + See EditToolbar for the methods you should implement in your class. + + Finaly, your Activity will very likely need some activity specific + buttons and options you can create your own toolbars by deriving a + class from gtk.Toolbar: + class MySpecialToolbar(gtk.Toolbar): + ... + + 4. Use your creativity. Make your Activity something special and share + it with your friends! + + Read through the methods of the Activity class below, to learn more about + how to make an Activity work. + + Hint: A good and simple Activity to learn from is the Read activity. To + create your own activity, you may want to copy it and use it as a template. + """ __gtype_name__ = 'SugarActivity' __gsignals__ = { @@ -248,6 +390,11 @@ class Activity(Window, gtk.Container): Creates an ActivityService (self._bus) servicing this application. + + Usage: + If your Activity implements __init__(), it should call + the base class __init()__ before doing Activity specific things. + """ Window.__init__(self) @@ -360,12 +507,25 @@ class Activity(Window, gtk.Container): return self._max_participants def get_id(self): + """Returns the activity id of the current instance of your activity. + + The activity id is sort-of-like the unix process id (PID). However, + unlike PIDs it is only different for each new instance (with + create_jobject = True set) and stays the same everytime a user + resumes an activity. This is also the identity of your Activity to other + XOs for use when sharing. + """ return self._activity_id def get_bundle_id(self): + """Returns the bundle_id from the activity.info file""" return os.environ['SUGAR_BUNDLE_ID'] def set_canvas(self, canvas): + """Sets the 'work area' of your activity with the canvas of your choice. + + One commonly used canvas is gtk.ScrolledWindow + """ Window.set_canvas(self, canvas) canvas.connect('map', self.__canvas_map_cb) @@ -380,10 +540,17 @@ class Activity(Window, gtk.Container): logging.debug("Error creating activity datastore object: %s" % err) def get_activity_root(self): - """ - Return the appropriate location in the fs where to store activity related - data that doesn't pertain to the current execution of the activity and - thus cannot go into the DataStore. + """Returns a path for saving Activity specific preferences, etc. + + Returns a path to the location in the filesystem where the activity can + store activity related data that doesn't pertain to the current + execution of the activity and thus cannot go into the DataStore. + + Currently, this will return something like ~/.sugar/default/MyActivityName/ + + Activities should ONLY save settings, user preferences and other data + which isn't specific to a journal item here. If (meta-)data is in anyway + specific to a journal entry, it MUST be stored in the DataStore. """ if os.environ.has_key('SUGAR_ACTIVITY_ROOT') and \ os.environ['SUGAR_ACTIVITY_ROOT']: @@ -395,6 +562,17 @@ class Activity(Window, gtk.Container): """ Subclasses implement this method if they support resuming objects from the journal. 'file_path' is the file to read from. + + You should immediately open the file from the file_path, because the + file_name will be deleted immediately after returning from read_file(). + Once the file has been opened, you do not have to read it immediately: + After you have opened it, the file will only be really gone when you + close it. + + Although not required, this is also a good time to read all meta-data: + the file itself cannot be changed externally, but the title, description + and other metadata['tags'] may change. So if it is important for you to + notice changes, this is the time to record the originals. """ raise NotImplementedError @@ -402,6 +580,17 @@ class Activity(Window, gtk.Container): """ Subclasses implement this method if they support saving data to objects in the journal. 'file_path' is the file to write to. + + If the user did make changes, you should create the file_path and save + all document data to it. + + Additionally, you should also write any metadata needed to resume your + activity. For example, the Read activity saves the current page and zoom + level, so it can display the page. + + Note: Currently, the file_path *WILL* be different from the one you + received in file_read(). Even if you kept the file_path from file_read() + open until now, you must still write the entire file to this file_path. """ raise NotImplementedError @@ -466,7 +655,13 @@ class Activity(Window, gtk.Container): self._preview = self._get_preview() def save(self): - """Request that the activity is saved to the Journal.""" + """Request that the activity is saved to the Journal. + + This method is called by the close() method below. In general, + activities should not override this method. This method is part of the + public API of an Acivity, and should behave in standard ways. Use your + own implementation of write_file() to save your Activity specific data. + """ logging.debug('Activity.save: %r' % self._jobject.object_id) @@ -507,6 +702,11 @@ class Activity(Window, gtk.Container): error_handler=self.__save_error_cb) def copy(self): + """Request that the activity 'Keep in Journal' the current state of the activity. + + Activities should not override this method. Instead, like save() do any + copy work that needs to be done in write_file() + """ logging.debug('Activity.copy: %r' % self._jobject.object_id) self._preview = self._get_preview() self.save() @@ -570,6 +770,12 @@ class Activity(Window, gtk.Container): logging.error('Cannot invite %s, no such buddy.' % buddy_key) def invite(self, buddy_key): + """Invite a buddy to join this Activity. + + Side Effects: + Calls self.share(True) to privately share the activity if it wasn't + shared before. + """ self._invites_queue.append(buddy_key) if (self._shared_activity is None @@ -598,6 +804,11 @@ class Activity(Window, gtk.Container): self._pservice.share_activity(self, private=private) def close(self): + """Request that the activity be stopped and saved to the Journal + + Activities should not override this method, but should implement write_file() to + do any state saving instead. + """ self.save() if self._shared_activity: @@ -617,6 +828,17 @@ class Activity(Window, gtk.Container): return True def get_metadata(self): + """Returns the jobject metadata or None if there is no jobject. + + Activities can set metadata in write_file() using: + self.metadata['MyKey'] = "Something" + + and retrieve metadata in read_file() using: + self.metadata.get('MyKey', 'aDefaultValue') + + Note: Make sure your activity works properly if one or more of the + metadata items is missing. Never assume they will all be present. + """ if self._jobject: return self._jobject.metadata else: @@ -625,12 +847,10 @@ class Activity(Window, gtk.Container): metadata = property(get_metadata, None) def get_bundle_name(): - """Return the bundle name for the current process' bundle - """ + """Return the bundle name for the current process' bundle""" return os.environ['SUGAR_BUNDLE_NAME'] def get_bundle_path(): - """Return the bundle path for the current process' bundle - """ + """Return the bundle path for the current process' bundle""" return os.environ['SUGAR_BUNDLE_PATH'] From 18f9a0ef9251fa3fa109fe32dad7550326c35493 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Mon, 29 Oct 2007 14:36:14 +0100 Subject: [PATCH 4/8] Initial push for the sugar control panel --- NEWS | 1 + shell/controlpanel/control.py | 425 +++++++++++++++++++++++++++++++ shell/controlpanel/sugar-control | 71 ++++++ 3 files changed, 497 insertions(+) create mode 100644 shell/controlpanel/control.py create mode 100755 shell/controlpanel/sugar-control diff --git a/NEWS b/NEWS index fa2e1233..7a301eb5 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* Initial push for the sugar control panel (erikos) * #4358: pydoc strings for sugar.activity.Activity Snapshot 176262f2e9 diff --git a/shell/controlpanel/control.py b/shell/controlpanel/control.py new file mode 100644 index 00000000..cf2b688b --- /dev/null +++ b/shell/controlpanel/control.py @@ -0,0 +1,425 @@ +# Copyright (C) 2007, One Laptop Per Child +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# +# The language config is based on the system-config-language +# (http://fedoraproject.org/wiki/SystemConfig/language) tool +# and the timezone config on the system-config-date +# (http://fedoraproject.org/wiki/SystemConfig/date) tool. +# Parts of the code were reused. +# + +import os +import string +import shutil +from gettext import gettext as _ + +from sugar import profile +from sugar.graphics.xocolor import XoColor + + +_COLORS = {'red': {'dark':'#b20008', 'medium':'#e6000a', 'light':'#ffadce'}, + 'orange': {'dark':'#9a5200', 'medium':'#c97e00', 'light':'#ffc169'}, + 'yellow': {'dark':'#807500', 'medium':'#be9e00', 'light':'#fffa00'}, + 'green': {'dark':'#008009', 'medium':'#00b20d', 'light':'#8bff7a'}, + 'blue': {'dark':'#00588c', 'medium':'#005fe4', 'light':'#bccdff'}, + 'purple': {'dark':'#5e008c', 'medium':'#7f00bf', 'light':'#d1a3ff'} + } + +_MODIFIERS = ('dark', 'medium', 'light') + +_TIMEZONE_CONFIG = '/etc/sysconfig/clock' + +_LANGUAGES = { + 'Afrikaans/South_Africa': ('af_ZA', 'lat0-sun16'), + 'Albanian': ('sq_AL.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Algeria': ('ar_DZ.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Bahrain': ('ar_BH.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Egypt': ('ar_EG.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/India': ('ar_IN.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Iraq': ('ar_IQ.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Jordan': ('ar_JO.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Kuwait': ('ar_KW.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Lebanon': ('ar_LB.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Libyan_Arab_Jamahiriya': ('ar_LY.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Morocco': ('ar_MA.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Oman': ('ar_OM.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Qatar': ('ar_QA.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Saudi_Arabia': ('ar_SA.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Sudan': ('ar_SD.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Syrian_Arab_Republic': ('ar_SY.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Tunisia': ('ar_TN.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/United_Arab_Emirates': ('ar_AE.UTF-8', 'latarcyrheb-sun16'), + 'Arabic/Yemen': ('ar_YE.UTF-8', 'latarcyrheb-sun16'), + 'Basque/Spain': ('eu_ES.UTF-8', 'latarcyrheb-sun16'), + 'Belarusian': ('be_BY.UTF-8', 'latarcyrheb-sun16'), + 'Bengali/BD': ('bn_BD.UTF-8', 'latarcyrheb-sun16'), + 'Bengali/India': ('bn_IN.UTF-8', 'latarcyrheb-sun16'), + 'Bosnian/Bosnia_and_Herzegowina': ('bs_BA', 'lat2-sun16'), + 'Breton/France': ('br_FR', 'lat0-sun16'), + 'Bulgarian': ('bg_BG.UTF-8', 'latarcyrheb-sun16'), + 'Catalan/Spain': ('ca_ES.UTF-8', 'latarcyrheb-sun16'), + 'Chinese/Hong_Kong': ('zh_HK.UTF-8', 'latarcyrheb-sun16'), + 'Chinese/P.R._of_China': ('zh_CN.UTF-8', 'lat0-sun16'), + 'Chinese/Taiwan': ('zh_TW.UTF-8', 'lat0-sun16'), + 'Cornish/Britain': ('kw_GB.UTF-8', 'latarcyrheb-sun16'), + 'Croatian': ('hr_HR.UTF-8', 'latarcyrheb-sun16'), + 'Czech': ('cs_CZ.UTF-8', 'latarcyrheb-sun16'), + 'Danish': ('da_DK.UTF-8', 'latarcyrheb-sun16'), + 'Dutch/Belgium': ('nl_BE.UTF-8', 'latarcyrheb-sun16'), + 'Dutch/Netherlands': ('nl_NL.UTF-8', 'latarcyrheb-sun16'), + 'English/Australia': ('en_AU.UTF-8', 'latarcyrheb-sun16'), + 'English/Botswana': ('en_BW.UTF-8', 'latarcyrheb-sun16'), + 'English/Canada': ('en_CA.UTF-8', 'latarcyrheb-sun16'), + 'English/Denmark': ('en_DK.UTF-8', 'latarcyrheb-sun16'), + 'English/Great_Britain': ('en_GB.UTF-8', 'latarcyrheb-sun16'), + 'English/Hong_Kong': ('en_HK.UTF-8', 'latarcyrheb-sun16'), + 'English/India': ('en_IN.UTF-8', 'latarcyrheb-sun16'), + 'English/Ireland': ('en_IE.UTF-8', 'latarcyrheb-sun16'), + 'English/New_Zealand': ('en_NZ.UTF-8', 'latarcyrheb-sun16'), + 'English/Philippines': ('en_PH.UTF-8', 'latarcyrheb-sun16'), + 'English/Singapore': ('en_SG.UTF-8', 'latarcyrheb-sun16'), + 'English/South_Africa': ('en_ZA.UTF-8', 'latarcyrheb-sun16'), + 'English/USA': ('en_US.UTF-8', 'latarcyrheb-sun16'), + 'English/Zimbabwe': ('en_ZW.UTF-8', 'latarcyrheb-sun16'), + 'Estonian': ('et_EE.UTF-8', 'latarcyrheb-sun16'), + 'Faroese/Faroe_Islands': ('fo_FO.UTF-8', 'latarcyrheb-sun16'), + 'Finnish': ('fi_FI.UTF-8', 'latarcyrheb-sun16'), + 'French/Belgium': ('fr_BE.UTF-8', 'latarcyrheb-sun16'), + 'French/Canada': ('fr_CA.UTF-8', 'latarcyrheb-sun16'), + 'French/France': ('fr_FR.UTF-8', 'latarcyrheb-sun16'), + 'French/Luxemburg': ('fr_LU.UTF-8', 'latarcyrheb-sun16'), + 'French/Switzerland': ('fr_CH.UTF-8', 'latarcyrheb-sun16'), + 'Galician/Spain': ('gl_ES.UTF-8', 'latarcyrheb-sun16'), + 'German/Austria': ('de_AT.UTF-8', 'latarcyrheb-sun16'), + 'German/Belgium': ('de_BE.UTF-8', 'latarcyrheb-sun16'), + 'German/Germany': ('de_DE.UTF-8', 'latarcyrheb-sun16'), + 'German/Luxemburg': ('de_LU.UTF-8', 'latarcyrheb-sun16'), + 'German/Switzerland': ('de_CH.UTF-8', 'latarcyrheb-sun16'), + 'Greek': ('el_GR.UTF-8', 'latarcyrheb-sun16'), + 'Greenlandic/Greenland': ('kl_GL.UTF-8', 'latarcyrheb-sun16'), + 'Gujarati/India': ('gu_IN.UTF-8', 'latarcyrheb-sun16'), + 'Hebrew/Israel': ('he_IL.UTF-8', 'latarcyrheb-sun16'), + 'Hindi/India': ('hi_IN.UTF-8', 'latarcyrheb-sun16'), + 'Hungarian': ('hu_HU.UTF-8', 'latarcyrheb-sun16'), + 'Icelandic': ('is_IS.UTF-8', 'latarcyrheb-sun16'), + 'Indonesian': ('id_ID.UTF-8', 'latarcyrheb-sun16'), + 'Irish': ('ga_IE.UTF-8', 'latarcyrheb-sun16'), + 'Italian/Italy': ('it_IT.UTF-8', 'latarcyrheb-sun16'), + 'Italian/Switzerland': ('it_CH.UTF-8', 'latarcyrheb-sun16'), + 'Japanese': ('ja_JP.UTF-8', 'lat0-sun16'), + 'Korean/Republic_of_Korea': ('ko_KR.UTF-8', 'lat0-sun16'), + 'Lao/Laos': ('lo_LA.UTF-8', 'latarcyrheb-sun16'), + 'Latvian/Latvia': ('lv_LV.UTF-8', 'latarcyrheb-sun16'), + 'Lithuanian': ('lt_LT.UTF-8', 'latarcyrheb-sun16'), + 'Macedonian': ('mk_MK.UTF-8', 'latarcyrheb-sun16'), + 'Malay/Malaysia': ('ms_MY.UTF-8', 'latarcyrheb-sun16'), + 'Maltese/malta': ('mt_MT.UTF-8', 'latarcyrheb-sun16'), + 'Manx/Britain': ('gv_GB.UTF-8', 'latarcyrheb-sun16'), + 'Marathi/India': ('mr_IN.UTF-8', 'latarcyrheb-sun16'), + 'Northern/Norway': ('se_NO', 'latarcyrheb-sun16'), + 'Norwegian': ('nb_NO.UTF-8', 'latarcyrheb-sun16'), + 'Norwegian,/Norway': ('nn_NO.UTF-8', 'latarcyrheb-sun16'), + 'Occitan/France': ('oc_FR', 'lat0-sun16'), + 'Oriya/India': ('or_IN.UTF-8', 'latarcyrheb-sun16'), + 'Persian/Iran': ('fa_IR.UTF-8', 'latarcyrheb-sun16'), + 'Polish': ('pl_PL.UTF-8', 'latarcyrheb-sun16'), + 'Portuguese/Brasil': ('pt_BR.UTF-8', 'latarcyrheb-sun16'), + 'Portuguese/Portugal': ('pt_PT.UTF-8', 'latarcyrheb-sun16'), + 'Punjabi/India': ('pa_IN.UTF-8', 'latarcyrheb-sun16'), + 'Romanian': ('ro_RO.UTF-8', 'latarcyrheb-sun16'), + 'Russian': ('ru_RU.UTF-8', 'latarcyrheb-sun16'), + 'Russian/Ukraine': ('ru_UA.UTF-8', 'latarcyrheb-sun16'), + 'Serbian': ('sr_CS.UTF-8', 'latarcyrheb-sun16'), + 'Serbian/Latin': ('sr_CS.UTF-8@Latn', 'latarcyrheb-sun16'), + 'Slovak': ('sk_SK.UTF-8', 'latarcyrheb-sun16'), + 'Slovenian/Slovenia': ('sl_SI.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Argentina': ('es_AR.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Bolivia': ('es_BO.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Chile': ('es_CL.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Colombia': ('es_CO.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Costa_Rica': ('es_CR.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Dominican_Republic': ('es_DO.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/El_Salvador': ('es_SV.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Equador': ('es_EC.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Guatemala': ('es_GT.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Honduras': ('es_HN.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Mexico': ('es_MX.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Nicaragua': ('es_NI.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Panama': ('es_PA.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Paraguay': ('es_PY.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Peru': ('es_PE.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Puerto_Rico': ('es_PR.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Spain': ('es_ES.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/USA': ('es_US.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Uruguay': ('es_UY.UTF-8', 'latarcyrheb-sun16'), + 'Spanish/Venezuela': ('es_VE.UTF-8', 'latarcyrheb-sun16'), + 'Swedish/Finland': ('sv_FI.UTF-8', 'latarcyrheb-sun16'), + 'Swedish/Sweden': ('sv_SE.UTF-8', 'latarcyrheb-sun16'), + 'Tagalog/Philippines': ('tl_PH', 'lat0-sun16'), + 'Tamil/India': ('ta_IN.UTF-8', 'latarcyrheb-sun16'), + 'Telugu/India': ('te_IN.UTF-8', 'latarcyrheb-sun16'), + 'Thai': ('th_TH.UTF-8', 'latarcyrheb-sun16'), + 'Turkish': ('tr_TR.UTF-8', 'latarcyrheb-sun16'), + 'Ukrainian': ('uk_UA.UTF-8', 'latarcyrheb-sun16'), + 'Urdu/Pakistan': ('ur_PK', 'latarcyrheb-sun16'), + 'Uzbek/Uzbekistan': ('uz_UZ', 'lat0-sun16'), + 'Walloon/Belgium': ('wa_BE@euro', 'lat0-sun16'), + 'Welsh/Great_Britain': ('cy_GB.UTF-8', 'latarcyrheb-sun16'), + 'Xhosa/South_Africa': ('xh_ZA.UTF-8', 'latarcyrheb-sun16'), + 'Zulu/South_Africa': ('zu_ZA.UTF-8', 'latarcyrheb-sun16') + } + +_timezones = [] + +def _initialize(): + _timezones = _read_zonetab() + j=0 + for timezone in _timezones: + set_timezone.__doc__ += timezone+', ' + j+=1 + if j%3 == 0: + set_timezone.__doc__ += '\n' + + if not os.access(_TIMEZONE_CONFIG, os.R_OK): + #Theres no /etc/sysconfig/clock file, so make one + fd = open(_TIMEZONE_CONFIG, 'w') + f.write(' The ZONE parameter is only evaluated by sugarcontrol.\n') + f.write('The timezone of the system' + + ' is defined by the contents of /etc/localtime.\n') + f.write('ZONE="America/NEW_York"\n') + f.close() + + keys = _LANGUAGES.keys() + keys.sort() + i = 0 + for key in keys: + set_language.__doc__ += key+', ' + i+=1 + if i%3 == 0: + set_language.__doc__ += '\n' + +def get_jabber(): + pro = profile.get_profile() + return pro.jabber_server + +def print_jabber(): + print get_jabber() + +def set_jabber(server): + """Set the jabber server + server : 'olpc.collabora.co.uk' + """ + pro = profile.get_profile() + pro.jabber_server = server + pro.save() + +def get_color(): + return profile.get_color() + +def print_color(): + print get_color().to_string() + +def set_color(stroke, fill, modstroke='medium', modfill='medium'): + """Set the system color. + fill : 'red, orange, yellow, blue, purple' + stroke : 'red, orange, yellow, blue, purple' + modstroke : 'dark, medium, light' + modfill : ''dark, medium, light' + """ + + if modstroke not in _MODIFIERS or modfill not in _MODIFIERS: + print (_("Error in specified color modifiers.")) + return + if stroke not in _COLORS or fill not in _COLORS: + print (_("Error in specified colors.")) + return + + if modstroke == modfill: + if modfill == medium: + modfill = light + else: + modfill = medium + + color = _COLORS[stroke][modstroke] + ',' + _COLORS[fill][modfill] + pro = profile.get_profile() + pro.color = XoColor(color) + pro.save() + +def get_nick(): + return profile.get_nick_name() + +def print_nick(): + print get_nick() + +def set_nick(nick): + """Set the nickname. + nick : 'erikos' + """ + pro = profile.get_profile() + pro.nick_name = nick + pro.save() + +def get_radio(state): + return '' + +def print_radio(self): + print get_radio() + +def set_radio(state): + """Turn Radio off + state : 'on/off' + """ + if state == 'on': + cmd = '/sbin/iwconfig eth0 txpower on' + handle = os.popen(cmd, 'r') + print string.join(handle.readlines()) + handle.close() + elif state == 'off': + cmd = '/sbin/iwconfig eth0 txpower off' + handle = os.popen(cmd, 'r') + print string.join(handle.readlines()) + handle.close() + else: + print (_("Error in specified radio argument use on/off.")) + +def get_timezone(): + fd = open(_TIMEZONE_CONFIG, "r") + lines = fd.readlines() + fd.close() + try: + for line in lines: + line = string.strip(line) + if len (line) and line[0] == '#': + continue + try: + tokens = string.split(line, "=") + if tokens[0] == "ZONE": + timezone = string.replace(tokens[1], '"', '') + return timezone + except Exception, e: + print (_("get_timezone: %s") % e) + except Exception, e: + print (_("get_timezone: %s") % e) + return None + +def print_timezone(): + timezone = get_timezone() + if timezone is None: + print (_("Error in reading timezone")) + else: + print timezone + +def set_timezone(timezone): + """Set the system timezone + timezone : + """ + if timezone in _timezones: + fromfile = os.path.join("/usr/share/zoneinfo/", timezone) + try: + shutil.copyfile(fromfile, "/etc/localtime") + except OSError, (errno, msg): + print (_("Error copying timezone (from %s): %s")%(fromfile, msg)) + return + try: + os.chmod("/etc/localtime", 0644) + except OSError, (errno, msg): + print (_("Changing permission of timezone: %s") % (msg)) + return + + # Write info to the /etc/sysconfig/clock file + fd = open(_TIMEZONE_CONFIG, "w") + fd.write('# The ZONE parameter is only evaluated by sugarcontrol.\n') + fd.write('# The timezone of the system ' + + 'is defined by the contents of /etc/localtime.\n') + fd.write('ZONE="%s"\n' % timezone) + fd.close() + else: + print (_("Error timezone does not exist.")) + +def _read_zonetab(fn='/usr/share/zoneinfo/zone.tab'): + fd = open (fn, 'r') + lines = fd.readlines() + fd.close() + timezones = [] + for line in lines: + if line.startswith('#'): + continue + line = line.split() + if len(line) > 1: + timezones.append(line[2]) + timezones.sort() + return timezones + +def _remove_encoding(lang): + if '.' in lang: + langBase = lang.split('.') + return langBase[0] + elif '@' in lang: + langBase = lang.split('@') + return langBase[0] + else: + return lang + +def _writeI18N(lang, sysfont): + path = '/etc/sysconfig/i18n' + if os.access(path, os.R_OK) == 0: + print(_("Could not access %s")%path) + else: + fd = open(path, 'w') + fd.write('LANG="' + lang + '"\n') + fd.write('SYSFONT="' + sysfont + '"\n') + fd.close() + +def get_language(): + originalFile = None + path = '/etc/sysconfig/i18n' + if os.access(path, os.R_OK) == 0: + return None + else: + fd = open(path, "r") + originalFile = fd.readlines() + fd.close() + + lang = None + + for line in originalFile: + if line[:5] == "LANG=": + lang = line[5:].replace('"', '') + lang = lang.strip() + + if lang: + lang = _remove_encoding(lang) + else: + lang = "en_US" + return lang + +def print_language(): + print get_language() + +def set_language(language): + """Set the system language. + languages : + """ + if language in _LANGUAGES: + _writeI18N(_LANGUAGES[language][0], _LANGUAGES[language][1]) + else: + print (_("Sorry I do not speak \'%s\'.")%language) + + +# inilialize the docstrings for the timezone and language +_initialize() diff --git a/shell/controlpanel/sugar-control b/shell/controlpanel/sugar-control new file mode 100755 index 00000000..4bee092d --- /dev/null +++ b/shell/controlpanel/sugar-control @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +# Copyright (C) 2007, One Laptop Per Child +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +import getopt, sys + +import control + +def cmd_help(): + print 'Usage: sugar-control [ option ] key [ args ... ] \n\ + Control for the sugar environment. \n\ + Options: \n\ + -h, --help show this help message and exit \n\ + -h key show information about this key \n\ + -g key get the current value of the key \n\ + -s key set the current value for the key \n\ + ' + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "h:s:g:", ["help"]) + except getopt.GetoptError: + cmd_help() + sys.exit(2) + + output = None + verbose = False + + for opt, key in opts: + if opt in ("-h"): + method = getattr(control, 'set_' + key, None) + if method is None: + cmd_help() + sys.exit() + else: + print method.__doc__ + if opt in ("-g"): + method = getattr(control, 'print_' + key, None) + if method is None: + cmd_help() + sys.exit() + else: + method() + if opt in ("-s"): + method = getattr(control, 'set_' + key, None) + if method is None: + cmd_help() + sys.exit() + else: + try: + method(*args) + except Exception, e: + print "sugar-control: %s"% e + +if __name__ == '__main__': + main() From 9ddfb74a6124c2b971d0adf497bf7f8476ef2f46 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Mon, 29 Oct 2007 15:35:09 +0100 Subject: [PATCH 5/8] Make the output of get_timezone and get_color more clear --- shell/controlpanel/control.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/shell/controlpanel/control.py b/shell/controlpanel/control.py index cf2b688b..89870514 100644 --- a/shell/controlpanel/control.py +++ b/shell/controlpanel/control.py @@ -232,7 +232,15 @@ def get_color(): return profile.get_color() def print_color(): - print get_color().to_string() + color = get_color().to_string() + str = color.split(',') + + for color in _COLORS: + for hue in _COLORS[color]: + if _COLORS[color][hue] == str[0]: + print 'stroke: color=%s hue=%s'%(color, hue) + if _COLORS[color][hue] == str[1]: + print 'fill: color=%s hue=%s'%(color, hue) def set_color(stroke, fill, modstroke='medium', modfill='medium'): """Set the system color. @@ -365,16 +373,6 @@ def _read_zonetab(fn='/usr/share/zoneinfo/zone.tab'): timezones.sort() return timezones -def _remove_encoding(lang): - if '.' in lang: - langBase = lang.split('.') - return langBase[0] - elif '@' in lang: - langBase = lang.split('@') - return langBase[0] - else: - return lang - def _writeI18N(lang, sysfont): path = '/etc/sysconfig/i18n' if os.access(path, os.R_OK) == 0: @@ -402,15 +400,20 @@ def get_language(): lang = line[5:].replace('"', '') lang = lang.strip() - if lang: - lang = _remove_encoding(lang) - else: + if not lang: lang = "en_US" + return lang def print_language(): - print get_language() - + code = get_language() + + for lang in _LANGUAGES: + if _LANGUAGES[lang][0] == code: + print lang + return + print (_("Language for code=%s could not be determined.")%code) + def set_language(language): """Set the system language. languages : From 702a89077074d57ab4c7bc8ecd770dece4d86691 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 29 Oct 2007 15:49:17 +0100 Subject: [PATCH 6/8] Revert to the trial-3 frame behavior (always visible on the home page). Readapt things which are changed in the meantime. --- NEWS | 2 + configure.ac | 1 - data/Makefile.am | 2 - data/icons/Makefile.am | 9 ---- data/icons/arrow_NE.svg | 7 --- data/icons/arrow_NW.svg | 7 --- data/icons/arrow_SE.svg | 7 --- data/icons/arrow_SW.svg | 7 --- shell/view/Shell.py | 17 +++++- shell/view/frame/frame.py | 107 ++++++++++--------------------------- shell/view/home/HomeBox.py | 52 ++++-------------- 11 files changed, 57 insertions(+), 161 deletions(-) delete mode 100644 data/icons/Makefile.am delete mode 100644 data/icons/arrow_NE.svg delete mode 100644 data/icons/arrow_NW.svg delete mode 100644 data/icons/arrow_SE.svg delete mode 100644 data/icons/arrow_SW.svg diff --git a/NEWS b/NEWS index 191dcff1..da1a6cc9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* #4428 Revert to the trial-3 frame behavior (marco) + Snapshot 176262f2e9 * Added morgs NotifyAlert (timed one button alert) to the alert api (erikos) diff --git a/configure.ac b/configure.ac index 15f82433..d5cb1856 100644 --- a/configure.ac +++ b/configure.ac @@ -45,7 +45,6 @@ AC_OUTPUT([ Makefile bin/Makefile data/Makefile -data/icons/Makefile lib/Makefile lib/sugar/Makefile lib/sugar/activity/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 400186e7..addfb594 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,5 +1,3 @@ -SUBDIRS = icons - sugar.gtkrc: gtkrc.em $(srcdir)/em.py -D theme=\'sugar\' $(srcdir)/gtkrc.em > \ $(top_builddir)/data/sugar.gtkrc diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am deleted file mode 100644 index 0fdf78ca..00000000 --- a/data/icons/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -iconsdir = $(pkgdatadir)/data/icons -icons_DATA = \ - arrow_NE.svg \ - arrow_NW.svg \ - arrow_SE.svg \ - arrow_SW.svg - -EXTRA_DIST = \ - $(icons_DATA) diff --git a/data/icons/arrow_NE.svg b/data/icons/arrow_NE.svg deleted file mode 100644 index e06363d5..00000000 --- a/data/icons/arrow_NE.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/data/icons/arrow_NW.svg b/data/icons/arrow_NW.svg deleted file mode 100644 index d02978a7..00000000 --- a/data/icons/arrow_NW.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/data/icons/arrow_SE.svg b/data/icons/arrow_SE.svg deleted file mode 100644 index 0a5d0247..00000000 --- a/data/icons/arrow_SE.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/data/icons/arrow_SW.svg b/data/icons/arrow_SW.svg deleted file mode 100644 index 5e712e27..00000000 --- a/data/icons/arrow_SW.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/shell/view/Shell.py b/shell/view/Shell.py index ec88aa3c..541fb2e5 100644 --- a/shell/view/Shell.py +++ b/shell/view/Shell.py @@ -57,6 +57,7 @@ class Shell(gobject.GObject): self._current_host = None self._pending_host = None self._screen_rotation = 0 + self._zoom_level = ShellModel.ZOOM_HOME self._key_handler = KeyHandler(self) @@ -73,6 +74,8 @@ class Shell(gobject.GObject): home_model.connect('pending-activity-changed', self._pending_activity_changed_cb) + self._model.connect('notify::zoom-level', self._zoom_level_changed_cb) + gobject.idle_add(self._start_journal_idle) def _start_journal_idle(self): @@ -172,8 +175,7 @@ class Shell(gobject.GObject): activity.get_service().TakeScreenshot() def set_zoom_level(self, level): - old_level = self._model.get_zoom_level() - if level == old_level: + if level == self._zoom_level: return self.take_activity_screenshot() @@ -187,6 +189,17 @@ class Shell(gobject.GObject): self._screen.toggle_showing_desktop(True) self._home_window.set_zoom_level(level) + def _zoom_level_changed_cb(self, model, pspec): + new_level = model.props.zoom_level + + if new_level == ShellModel.ZOOM_HOME: + self._frame.show(Frame.MODE_HOME) + + if self._zoom_level == ShellModel.ZOOM_HOME: + self._frame.hide() + + self._zoom_level = new_level + def toggle_activity_fullscreen(self): if self._model.get_zoom_level() == ShellModel.ZOOM_ACTIVITY: self.get_current_activity().toggle_fullscreen() diff --git a/shell/view/frame/frame.py b/shell/view/frame/frame.py index f77f662e..c5072628 100644 --- a/shell/view/frame/frame.py +++ b/shell/view/frame/frame.py @@ -33,16 +33,11 @@ from view.frame.framewindow import FrameWindow from view.frame.clipboardpanelwindow import ClipboardPanelWindow from model.shellmodel import ShellModel -MODE_NONE = 0 -MODE_MOUSE = 1 -MODE_KEYBOARD = 2 -MODE_FORCE = 3 - _FRAME_HIDING_DELAY = 500 class _Animation(animator.Animation): def __init__(self, frame, end): - start = frame.get_current_position() + start = frame.current_position animator.Animation.__init__(self, start, end) self._frame = frame @@ -55,19 +50,16 @@ class _MouseListener(object): self._hide_sid = 0 def mouse_enter(self): - if self._frame.mode == MODE_NONE or \ - self._frame.mode == MODE_MOUSE: - self._show_frame() + self._show_frame() def mouse_leave(self): - if self._frame.mode == MODE_MOUSE: + if self._frame.mode == Frame.MODE_MOUSE: self._hide_frame() def _show_frame(self): if self._hide_sid != 0: gobject.source_remove(self._hide_sid) - self._frame.show() - self._frame.mode = MODE_MOUSE + self._frame.show(Frame.MODE_MOUSE) def _hide_frame_timeout_cb(self): self._frame.hide() @@ -80,52 +72,23 @@ class _MouseListener(object): _FRAME_HIDING_DELAY, self._hide_frame_timeout_cb) class _KeyListener(object): - _HIDDEN = 1 - _SHOWN_PRESSED = 2 - _SHOWN_REPEAT = 3 - _SHOWN_RELEASED = 4 - def __init__(self, frame): self._frame = frame - self._state = _KeyListener._HIDDEN def key_press(self): - if self._frame.mode != MODE_NONE and \ - self._frame.mode != MODE_KEYBOARD: - return - if self._frame.visible: - self._frame.hide() + if self._frame.mode == Frame.MODE_KEYBOARD: + self._frame.hide() else: - self._frame.show() - self._frame.mode = MODE_KEYBOARD - - """ - if self._state == _KeyListener._HIDDEN: - self._frame.show() - self._frame.mode = MODE_KEYBOARD - self._state = _KeyListener._SHOWN_PRESSED - elif self._state == _KeyListener._SHOWN_PRESSED: - self._state = _KeyListener._SHOWN_REPEAT - elif self._state == _KeyListener._SHOWN_RELEASED: - self._frame.hide() - self._state = _KeyListener._HIDDEN - """ - - def key_release(self): - pass - """ - if self._state == _KeyListener._SHOWN_PRESSED: - self._state = _KeyListener._SHOWN_RELEASED - elif self._state == _KeyListener._SHOWN_REPEAT: - self._frame.hide() - self._state = _KeyListener._HIDDEN - """ + self._frame.show(Frame.MODE_KEYBOARD) class Frame(object): + MODE_MOUSE = 0 + MODE_KEYBOARD = 1 + MODE_HOME = 2 + def __init__(self, shell): - self.mode = MODE_NONE - self.visible = False + self.mode = None self._palette_group = palettegroup.get_group('frame') self._palette_group.connect('popdown', self._palette_group_popdown_cb) @@ -136,7 +99,7 @@ class Frame(object): self._bottom_panel = None self._shell = shell - self._current_position = 0.0 + self.current_position = 0.0 self._animator = None self._event_area = EventArea() @@ -157,9 +120,12 @@ class Frame(object): self._key_listener = _KeyListener(self) self._mouse_listener = _MouseListener(self) - def hide(self, force=False): - if not self.visible: - return + self.move(1.0) + + def is_visible(self): + return self.current_position != 0.0 + + def hide(self): if self._animator: self._animator.stop() @@ -169,16 +135,9 @@ class Frame(object): self._event_area.show() - self.visible = False - if force: - self.mode = MODE_NONE - else: - self.mode = MODE_FORCE - self._animator.connect('completed', self._hide_completed_cb) - - def show(self): - self.mode = MODE_FORCE + self.mode = None + def show(self, mode): if self.visible: return if self._animator: @@ -186,19 +145,16 @@ class Frame(object): self._shell.take_activity_screenshot() + self.mode = mode + self._animator = animator.Animator(0.5) self._animator.add(_Animation(self, 1.0)) self._animator.start() self._event_area.hide() - self.visible = True - - def get_current_position(self): - return self._current_position - def move(self, pos): - self._current_position = pos + self.current_position = pos self._update_position() def _is_hover(self): @@ -266,21 +222,18 @@ class Frame(object): screen_h = gtk.gdk.screen_height() screen_w = gtk.gdk.screen_width() - self._move_panel(self._top_panel, self._current_position, + self._move_panel(self._top_panel, self.current_position, 0, - self._top_panel.size, 0, 0) - self._move_panel(self._bottom_panel, self._current_position, + self._move_panel(self._bottom_panel, self.current_position, 0, screen_h, 0, screen_h - self._bottom_panel.size) - self._move_panel(self._left_panel, self._current_position, + self._move_panel(self._left_panel, self.current_position, - self._left_panel.size, 0, 0, 0) - self._move_panel(self._right_panel, self._current_position, + self._move_panel(self._right_panel, self.current_position, screen_w, 0, screen_w - self._right_panel.size, 0) - def _hide_completed_cb(self, animator): - self.mode = MODE_NONE - def _size_changed_cb(self, screen): self._update_position() @@ -316,6 +269,4 @@ class Frame(object): def notify_key_press(self): self._key_listener.key_press() - def notify_key_release(self): - self._key_listener.key_release() - + visible = property(is_visible, None) diff --git a/shell/view/home/HomeBox.py b/shell/view/home/HomeBox.py index 6b5de5fc..5b135650 100644 --- a/shell/view/home/HomeBox.py +++ b/shell/view/home/HomeBox.py @@ -48,55 +48,17 @@ class HomeBox(hippo.CanvasBox, hippo.CanvasItem): shell_model = shell.get_model() - top_box = hippo.CanvasBox(yalign=hippo.ALIGNMENT_START, - box_height=style.GRID_CELL_SIZE, - orientation=hippo.ORIENTATION_HORIZONTAL) - self.append(top_box, hippo.PACK_EXPAND) - - nw_arrow = CanvasIcon(icon_name='arrow_NW', - xalign=hippo.ALIGNMENT_START) - top_box.append(nw_arrow) - - arrows_separator = hippo.CanvasBox() - top_box.append(arrows_separator, hippo.PACK_EXPAND) - - ne_arrow = CanvasIcon(icon_name='arrow_NE', - xalign=hippo.ALIGNMENT_END) - top_box.append(ne_arrow) - self._donut = ActivitiesDonut(shell) - self.append(self._donut) - - bottom_box = hippo.CanvasBox(yalign=hippo.ALIGNMENT_END, - box_height=style.GRID_CELL_SIZE, - orientation=hippo.ORIENTATION_HORIZONTAL) - self.append(bottom_box, hippo.PACK_EXPAND) + self.append(self._donut, hippo.PACK_FIXED) self._my_icon = _MyIcon(shell, style.XLARGE_ICON_SIZE) self.append(self._my_icon, hippo.PACK_FIXED) - sw_arrow = CanvasIcon(icon_name='arrow_SW', - xalign=hippo.ALIGNMENT_START) - bottom_box.append(sw_arrow) - - devices_box = _DevicesBox(shell_model.get_devices()) - bottom_box.append(devices_box, hippo.PACK_EXPAND) - - se_arrow = CanvasIcon(icon_name='arrow_SE', - xalign=hippo.ALIGNMENT_END) - bottom_box.append(se_arrow) - - self._arrows = [ nw_arrow, ne_arrow, sw_arrow, se_arrow ] + self._devices_box = _DevicesBox(shell_model.get_devices()) + self.append(self._devices_box, hippo.PACK_FIXED) shell_model.connect('notify::state', self._shell_state_changed_cb) - shell_model.connect('notify::zoom-level', - self._shell_zoom_level_changed_cb) - - def _shell_zoom_level_changed_cb(self, model, pspec): - for arrow in self._arrows: - arrow.destroy() - self._arrows = [] def _shell_state_changed_cb(self, model, pspec): # FIXME implement this @@ -106,9 +68,17 @@ class HomeBox(hippo.CanvasBox, hippo.CanvasItem): def do_allocate(self, width, height, origin_changed): hippo.CanvasBox.do_allocate(self, width, height, origin_changed) + [donut_width, donut_height] = self._donut.get_allocation() + self.set_position(self._donut, (width - donut_width) / 2, + (height - donut_height) / 2) + [icon_width, icon_height] = self._my_icon.get_allocation() self.set_position(self._my_icon, (width - icon_width) / 2, (height - icon_height) / 2) + + [box_width, box_height] = self._devices_box.get_allocation() + self.set_position(self._devices_box, (width - icon_width) / 2, + height - style.GRID_CELL_SIZE * 3) _REDRAW_TIMEOUT = 5 * 60 * 1000 # 5 minutes From 4d5fd7243b1c18cefb4dae51f1c5f9264dcfc8dc Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 29 Oct 2007 16:46:00 +0100 Subject: [PATCH 7/8] Remove activity uploading since it's not useful with the new build system. --- lib/sugar/activity/bundlebuilder.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/sugar/activity/bundlebuilder.py b/lib/sugar/activity/bundlebuilder.py index c2e32780..927b6957 100644 --- a/lib/sugar/activity/bundlebuilder.py +++ b/lib/sugar/activity/bundlebuilder.py @@ -348,22 +348,6 @@ def cmd_release(bundle_name, manifest): print 'Creating the bundle...' cmd_dist(bundle_name, manifest) - if os.environ.has_key('ACTIVITIES_REPOSITORY'): - print 'Uploading to the activities repository...' - repo = os.environ['ACTIVITIES_REPOSITORY'] - - server, path = repo.split(':') - retcode = subprocess.call(['ssh', server, 'rm', - '%s/%s*' % (path, bundle_name)]) - if retcode: - print 'ERROR - cannot remove old bundles from the repository.' - - bundle_path = os.path.join(_get_source_path(), - _get_package_name(bundle_name)) - retcode = subprocess.call(['scp', bundle_path, repo]) - if retcode: - print 'ERROR - cannot upload the bundle to the repository.' - print 'Done.' def cmd_clean(): From 6768a4216fad97711faeeffcfa9c43e8adc8491b Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 30 Oct 2007 12:15:42 +0100 Subject: [PATCH 8/8] Remove the console. Eduardo is moving the functionalities out to the log and analyze activities. --- configure.ac | 17 - services/Makefile.am | 2 +- services/console/Makefile.am | 20 - services/console/README | 12 - services/console/__init__.py | 1 - services/console/console.py | 94 --- services/console/interface/Makefile.am | 6 - services/console/interface/__init__.py | 0 .../console/interface/logviewer/Makefile.am | 4 - .../console/interface/logviewer/__init__.py | 1 - .../console/interface/logviewer/logviewer.py | 228 ------ .../console/interface/memphis/Makefile.am | 8 - .../console/interface/memphis/__init__.py | 1 - services/console/interface/memphis/memphis.py | 235 ------ services/console/interface/memphis/plugin.py | 48 -- .../interface/memphis/plugins/Makefile.am | 4 - .../memphis/plugins/clean_size/Makefile.am | 6 - .../memphis/plugins/clean_size/README | 2 - .../memphis/plugins/clean_size/__init__.py | 16 - .../memphis/plugins/clean_size/info.py | 15 - .../interface/memphis/plugins/cpu/Makefile.am | 6 - .../interface/memphis/plugins/cpu/README | 2 - .../interface/memphis/plugins/cpu/__init__.py | 23 - .../interface/memphis/plugins/cpu/info.py | 48 -- .../memphis/plugins/memphis_init/Makefile.am | 6 - .../memphis/plugins/memphis_init/README | 2 - .../memphis/plugins/memphis_init/__init__.py | 15 - .../memphis/plugins/memphis_init/info.py | 14 - .../memphis/plugins/smaps/Makefile.am | 6 - .../interface/memphis/plugins/smaps/README | 2 - .../memphis/plugins/smaps/__init__.py | 17 - .../interface/memphis/plugins/smaps/info.py | 19 - .../console/interface/network/Makefile.am | 4 - .../console/interface/network/__init__.py | 1 - services/console/interface/network/network.py | 103 --- services/console/interface/ps_watcher.py | 729 ------------------ services/console/interface/xo/Makefile.am | 7 - services/console/interface/xo/__init__.py | 2 - services/console/interface/xo/cpu.py | 111 --- services/console/interface/xo/nandflash.py | 119 --- services/console/interface/xo/system.py | 91 --- services/console/interface/xo/xo.py | 57 -- .../console/interface/xserver/Makefile.am | 4 - .../console/interface/xserver/__init__.py | 1 - services/console/interface/xserver/xserver.py | 111 --- services/console/label.py | 51 -- services/console/lib/Makefile.am | 6 - services/console/lib/graphics/Makefile.am | 7 - services/console/lib/graphics/__init__.py | 0 services/console/lib/graphics/box.py | 101 --- services/console/lib/graphics/frequency.py | 147 ---- services/console/lib/net/Makefile.am | 7 - services/console/lib/net/__init__.py | 0 services/console/lib/net/device.py | 94 --- services/console/lib/procmem/Makefile.am | 8 - services/console/lib/procmem/__init__.py | 0 services/console/lib/procmem/analysis.py | 32 - services/console/lib/procmem/proc.py | 109 --- services/console/lib/procmem/proc_smaps.py | 138 ---- services/console/lib/pyxres.py | 256 ------ services/console/lib/ui/Makefile.am | 5 - services/console/lib/ui/__init__.py | 0 services/console/lib/ui/treeview.py | 73 -- .../org.laptop.sugar.Console.service.in | 4 - services/console/sugar-console | 20 - shell/view/keyhandler.py | 12 - 66 files changed, 1 insertion(+), 3289 deletions(-) delete mode 100644 services/console/Makefile.am delete mode 100644 services/console/README delete mode 100644 services/console/__init__.py delete mode 100755 services/console/console.py delete mode 100644 services/console/interface/Makefile.am delete mode 100644 services/console/interface/__init__.py delete mode 100644 services/console/interface/logviewer/Makefile.am delete mode 100644 services/console/interface/logviewer/__init__.py delete mode 100644 services/console/interface/logviewer/logviewer.py delete mode 100644 services/console/interface/memphis/Makefile.am delete mode 100644 services/console/interface/memphis/__init__.py delete mode 100644 services/console/interface/memphis/memphis.py delete mode 100644 services/console/interface/memphis/plugin.py delete mode 100644 services/console/interface/memphis/plugins/Makefile.am delete mode 100644 services/console/interface/memphis/plugins/clean_size/Makefile.am delete mode 100644 services/console/interface/memphis/plugins/clean_size/README delete mode 100644 services/console/interface/memphis/plugins/clean_size/__init__.py delete mode 100644 services/console/interface/memphis/plugins/clean_size/info.py delete mode 100644 services/console/interface/memphis/plugins/cpu/Makefile.am delete mode 100644 services/console/interface/memphis/plugins/cpu/README delete mode 100644 services/console/interface/memphis/plugins/cpu/__init__.py delete mode 100644 services/console/interface/memphis/plugins/cpu/info.py delete mode 100644 services/console/interface/memphis/plugins/memphis_init/Makefile.am delete mode 100644 services/console/interface/memphis/plugins/memphis_init/README delete mode 100644 services/console/interface/memphis/plugins/memphis_init/__init__.py delete mode 100644 services/console/interface/memphis/plugins/memphis_init/info.py delete mode 100644 services/console/interface/memphis/plugins/smaps/Makefile.am delete mode 100644 services/console/interface/memphis/plugins/smaps/README delete mode 100644 services/console/interface/memphis/plugins/smaps/__init__.py delete mode 100644 services/console/interface/memphis/plugins/smaps/info.py delete mode 100644 services/console/interface/network/Makefile.am delete mode 100644 services/console/interface/network/__init__.py delete mode 100644 services/console/interface/network/network.py delete mode 100644 services/console/interface/ps_watcher.py delete mode 100644 services/console/interface/xo/Makefile.am delete mode 100644 services/console/interface/xo/__init__.py delete mode 100644 services/console/interface/xo/cpu.py delete mode 100644 services/console/interface/xo/nandflash.py delete mode 100644 services/console/interface/xo/system.py delete mode 100644 services/console/interface/xo/xo.py delete mode 100644 services/console/interface/xserver/Makefile.am delete mode 100644 services/console/interface/xserver/__init__.py delete mode 100644 services/console/interface/xserver/xserver.py delete mode 100644 services/console/label.py delete mode 100644 services/console/lib/Makefile.am delete mode 100644 services/console/lib/graphics/Makefile.am delete mode 100644 services/console/lib/graphics/__init__.py delete mode 100644 services/console/lib/graphics/box.py delete mode 100644 services/console/lib/graphics/frequency.py delete mode 100644 services/console/lib/net/Makefile.am delete mode 100644 services/console/lib/net/__init__.py delete mode 100644 services/console/lib/net/device.py delete mode 100644 services/console/lib/procmem/Makefile.am delete mode 100644 services/console/lib/procmem/__init__.py delete mode 100644 services/console/lib/procmem/analysis.py delete mode 100644 services/console/lib/procmem/proc.py delete mode 100644 services/console/lib/procmem/proc_smaps.py delete mode 100644 services/console/lib/pyxres.py delete mode 100644 services/console/lib/ui/Makefile.am delete mode 100644 services/console/lib/ui/__init__.py delete mode 100644 services/console/lib/ui/treeview.py delete mode 100644 services/console/org.laptop.sugar.Console.service.in delete mode 100755 services/console/sugar-console diff --git a/configure.ac b/configure.ac index d5cb1856..78444554 100644 --- a/configure.ac +++ b/configure.ac @@ -66,22 +66,5 @@ shell/view/home/Makefile shell/model/Makefile shell/model/devices/Makefile shell/model/devices/network/Makefile -services/console/lib/Makefile -services/console/lib/graphics/Makefile -services/console/lib/procmem/Makefile -services/console/lib/net/Makefile -services/console/lib/ui/Makefile -services/console/Makefile -services/console/interface/Makefile -services/console/interface/xo/Makefile -services/console/interface/memphis/plugins/clean_size/Makefile -services/console/interface/memphis/plugins/smaps/Makefile -services/console/interface/memphis/plugins/Makefile -services/console/interface/memphis/plugins/memphis_init/Makefile -services/console/interface/memphis/plugins/cpu/Makefile -services/console/interface/memphis/Makefile -services/console/interface/network/Makefile -services/console/interface/logviewer/Makefile -services/console/interface/xserver/Makefile po/Makefile.in ]) diff --git a/services/Makefile.am b/services/Makefile.am index e230030d..d7c539dc 100644 --- a/services/Makefile.am +++ b/services/Makefile.am @@ -1 +1 @@ -SUBDIRS = shell console +SUBDIRS = shell diff --git a/services/console/Makefile.am b/services/console/Makefile.am deleted file mode 100644 index 2cd3ab10..00000000 --- a/services/console/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -SUBDIRS = interface lib - -servicedir = $(datadir)/dbus-1/services -service_in_files = org.laptop.sugar.Console.service.in -service_DATA = $(service_in_files:.service.in=.service) - -$(service_DATA): $(service_in_files) Makefile - @sed -e "s|\@bindir\@|$(bindir)|" $< > $@ - -sugardir = $(pkgdatadir)/services/console -sugar_PYTHON = \ - __init__.py \ - console.py \ - label.py - -bin_SCRIPTS = sugar-console - -DISTCLEANFILES = $(service_DATA) - -EXTRA_DIST = $(service_in_files) $(bin_SCRIPTS) diff --git a/services/console/README b/services/console/README deleted file mode 100644 index a3aa6e1a..00000000 --- a/services/console/README +++ /dev/null @@ -1,12 +0,0 @@ -Defining new tabs in the developer console -========================================== - -The tabs are top-level packages inside 'interface/'. - -Each package used as a tab must have a class Interface, instantiatable -with no arguments, with an attribute 'widget' that is a Gtk widget to be -placed in the tab. That's it. - -Tabs are automatically run under the GLib main loop, dbus-python is set up -to use it, and the shared dbus-python session-bus connection is expected to -exist. diff --git a/services/console/__init__.py b/services/console/__init__.py deleted file mode 100644 index 8b137891..00000000 --- a/services/console/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/services/console/console.py b/services/console/console.py deleted file mode 100755 index 9ad79fae..00000000 --- a/services/console/console.py +++ /dev/null @@ -1,94 +0,0 @@ -# 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 - -import dbus -import dbus.glib -import dbus.service -import os -import sys -import gtk -import gobject - -sys.path.append(os.path.dirname(__file__)) -sys.path.append(os.path.dirname(__file__) + '/lib') -sys.path.append(os.path.dirname(__file__) + '/interface') - -CONSOLE_BUS = 'org.laptop.sugar.Console' -CONSOLE_PATH = '/org/laptop/sugar/Console' -CONSOLE_IFACE = 'org.laptop.sugar.Console' - -class Console: - - def __init__(self): - # Main Window - self.window = gtk.Window() - self.window.set_title('Developer console') - self.window.connect("delete-event", self._delete_event_cb) - - self.default_width = gtk.gdk.screen_width() * 95 / 100 - self.default_height = gtk.gdk.screen_height() * 95 / 100 - - self.window.set_default_size(self.default_width, self.default_height) - - self.window.realize() - self.window.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) - - # Notebook - self.notebook = gtk.Notebook() - - self._load_interface('xo', 'XO Resources') - self._load_interface('network', 'Network') - self._load_interface('xserver', 'X Server') - self._load_interface('memphis', 'Memphis') - self._load_interface('logviewer', 'Log Viewer') - self._load_interface('ps_watcher', 'Presence') - - main_hbox = gtk.HBox() - main_hbox.pack_start(self.notebook, True, True, 0) - main_hbox.show() - - self.notebook.show() - self.window.add(main_hbox) - - def _load_interface(self, interface, label): - mod = __import__(interface) - widget = mod.Interface().widget - widget.show() - - self.notebook.append_page(widget, gtk.Label(label)) - - def _delete_event_cb(self, window, gdkevent): - gtk.main_quit() - -class Service(dbus.service.Object): - def __init__(self, bus, object_path=CONSOLE_PATH): - dbus.service.Object.__init__(self, bus, object_path) - self._console = Console() - - @dbus.service.method(CONSOLE_IFACE) - def ToggleVisibility(self): - window = self._console.window - if not window.props.visible: - window.present() - else: - window.hide() - -bus = dbus.SessionBus() -name = dbus.service.BusName(CONSOLE_BUS, bus) - -obj = Service(name) - -gtk.main() diff --git a/services/console/interface/Makefile.am b/services/console/interface/Makefile.am deleted file mode 100644 index f3b286b7..00000000 --- a/services/console/interface/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -SUBDIRS = memphis network logviewer xo xserver - -sugardir = $(pkgdatadir)/services/console/interface -sugar_PYTHON = \ - __init__.py \ - ps_watcher.py diff --git a/services/console/interface/__init__.py b/services/console/interface/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/services/console/interface/logviewer/Makefile.am b/services/console/interface/logviewer/Makefile.am deleted file mode 100644 index 9194684f..00000000 --- a/services/console/interface/logviewer/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -sugardir = $(pkgdatadir)/services/console/interface/logviewer -sugar_PYTHON = \ - __init__.py \ - logviewer.py diff --git a/services/console/interface/logviewer/__init__.py b/services/console/interface/logviewer/__init__.py deleted file mode 100644 index 614ed67c..00000000 --- a/services/console/interface/logviewer/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from logviewer import Interface diff --git a/services/console/interface/logviewer/logviewer.py b/services/console/interface/logviewer/logviewer.py deleted file mode 100644 index 7352199f..00000000 --- a/services/console/interface/logviewer/logviewer.py +++ /dev/null @@ -1,228 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# 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 - - -# Rewritten by Eduardo Silva, edsiper@gmail.com - -import os - -import pygtk -import gtk -import gobject -import pango -import gnomevfs - -from sugar import env - -class MultiLogView(gtk.VBox): - def __init__(self, path, extra_files): - self._logs_path = path - self._active_log = None - self._extra_files = extra_files - - # Creating Main treeview with Actitivities list - self._tv_menu = gtk.TreeView() - self._tv_menu.connect('cursor-changed', self._load_log) - self._tv_menu.set_rules_hint(True) - - # Set width - box_width = gtk.gdk.screen_width() * 80 / 100 - self._tv_menu.set_size_request(box_width*25/100, 0) - - self._store_menu = gtk.TreeStore(str) - self._tv_menu.set_model(self._store_menu) - - self._add_column(self._tv_menu, 'Sugar logs', 0) - self._logs = {} - - # Activities menu - self.hbox = gtk.HBox(False, 3) - self.hbox.pack_start(self._tv_menu, True, True, 0) - - # Activity log, set width - self._view = LogView() - self._view.set_size_request(box_width*75/100, 0) - - self.hbox.pack_start(self._view, True, True, 0) - self.hbox.show_all() - self._configure_watcher() - self._create_log_view() - - - def _configure_watcher(self): - # Setting where gnomeVFS will be watching - gnomevfs.monitor_add('file://' + self._logs_path, - gnomevfs.MONITOR_DIRECTORY, - self._log_file_changed_cb) - - for f in self._extra_files: - gnomevfs.monitor_add('file://' + f, - gnomevfs.MONITOR_FILE, - self._log_file_changed_cb) - - def _log_file_changed_cb(self, monitor_uri, info_uri, event): - path = info_uri.split('file://')[-1] - filename = self._get_filename_from_path(path) - - if event == gnomevfs.MONITOR_EVENT_CHANGED: - self._logs[filename].update() - elif event == gnomevfs.MONITOR_EVENT_DELETED: - self._delete_log_file_view(filename) - elif event == gnomevfs.MONITOR_EVENT_CREATED: - self._add_log_file(path) - - # Load the log information in View (textview) - def _load_log(self, treeview): - treeselection = treeview.get_selection() - treestore, iter = treeselection.get_selected() - - # Get current selection - act_log = self._store_menu.get_value(iter, 0) - - # Set buffer and scroll down - self._view.textview.set_buffer(self._logs[act_log]) - self._view.textview.scroll_to_mark(self._logs[act_log].get_insert(), 0) - self._active_log = act_log - - def _create_log_view(self): - # Searching log files - for logfile in os.listdir(self._logs_path): - full_log_path = os.path.join(self._logs_path, logfile) - self._add_log_file(full_log_path) - - for ext in self._extra_files: - self._add_log_file(ext) - - return True - - def _delete_log_file_view(self, logkey): - self._store_menu.remove(self._logs[logkey].iter) - del self._logs[logkey] - - def _get_filename_from_path(self, path): - return path.split('/')[-1] - - def _add_log_file(self, path): - if os.path.isdir(path): - return False - - if not os.path.exists(path): - print "ERROR: %s don't exists" - return False - - logfile = self._get_filename_from_path(path) - - if not self._logs.has_key(logfile): - iter = self._add_log_row(logfile) - model = LogBuffer(path, iter) - self._logs[logfile] = model - - self._logs[logfile].update() - written = self._logs[logfile]._written - - # Load the first iter - if self._active_log == None: - self._active_log = logfile - iter = self._tv_menu.get_model().get_iter_root() - self._tv_menu.get_selection().select_iter(iter) - self._load_log(self._tv_menu) - - if written > 0 and self._active_log == logfile: - self._view.textview.scroll_to_mark(self._logs[logfile].get_insert(), 0) - - - def _add_log_row(self, name): - return self._insert_row(self._store_menu, None, name) - - # Add a new column to the main treeview, (code from Memphis) - def _add_column(self, treeview, column_name, index): - cell = gtk.CellRendererText() - col_tv = gtk.TreeViewColumn(column_name, cell, text=index) - col_tv.set_resizable(True) - col_tv.set_property('clickable', True) - - treeview.append_column(col_tv) - - # Set the last column index added - self.last_col_index = index - - # Insert a Row in our TreeView - def _insert_row(self, store, parent, name): - iter = store.insert_before(parent, None) - index = 0 - store.set_value(iter, index , name) - - return iter - -class LogBuffer(gtk.TextBuffer): - def __init__(self, logfile, iter=None): - gtk.TextBuffer.__init__(self) - - self._logfile = logfile - self._pos = 0 - self.iter = iter - self.update() - - def update(self): - try: - f = open(self._logfile, 'r') - init_pos = self._pos - - f.seek(self._pos) - self.insert(self.get_end_iter(), f.read()) - self._pos = f.tell() - f.close() - - self._written = (self._pos - init_pos) - except: - self.insert(self.get_end_iter(), "Console error: can't open the file\n") - self._written = 0 - -class LogView(gtk.ScrolledWindow): - def __init__(self): - gtk.ScrolledWindow.__init__(self) - - self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - - self.textview = gtk.TextView() - self.textview.set_wrap_mode(gtk.WRAP_WORD) - - font = pango.FontDescription('Sans 8') - font.set_weight(pango.WEIGHT_LIGHT) - self.textview.modify_font(font) - - # Set background color - bgcolor = gtk.gdk.color_parse("#FFFFFF") - self.textview.modify_base(gtk.STATE_NORMAL, bgcolor) - - self.textview.set_editable(False) - - self.add(self.textview) - self.textview.show() - -class Interface: - def __init__(self): - # Main path to watch: ~/.sugar/someuser/logs... - main_path = os.path.join(env.get_profile_path(), 'logs') - - # extra files to watch in logviewer - ext_files = [] - ext_files.append("/var/log/Xorg.0.log") - ext_files.append("/var/log/syslog") - ext_files.append("/var/log/messages") - - viewer = MultiLogView(main_path, ext_files) - self.widget = viewer.hbox diff --git a/services/console/interface/memphis/Makefile.am b/services/console/interface/memphis/Makefile.am deleted file mode 100644 index 4d4de4e7..00000000 --- a/services/console/interface/memphis/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -SUBDIRS = plugins - -sugardir = $(pkgdatadir)/services/console/interface/memphis -sugar_PYTHON = \ - __init__.py \ - memphis.py \ - plugin.py - diff --git a/services/console/interface/memphis/__init__.py b/services/console/interface/memphis/__init__.py deleted file mode 100644 index 145d9d4f..00000000 --- a/services/console/interface/memphis/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from memphis import Interface diff --git a/services/console/interface/memphis/memphis.py b/services/console/interface/memphis/memphis.py deleted file mode 100644 index 5b1ce405..00000000 --- a/services/console/interface/memphis/memphis.py +++ /dev/null @@ -1,235 +0,0 @@ -# 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 - -import sys -import 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.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) - self.treeview = gtk.TreeView() - t_width = gtk.gdk.screen_width() - t_height = gtk.gdk.screen_height() * 83 / 100 - - self.treeview.set_size_request(t_width, t_height) - vbox.pack_start(self.treeview, True, True, 0) - vbox.show_all() - self.widget = vbox - - # 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, self.treeview, self.plg.list) - - self.button_stop.hide() - self.button_start.connect('clicked', self.data._start_memphis) - self.button_stop.connect('clicked', self.data._stop_memphis) - -class Data: - - last_col_index = 0 - - store_data_cols = [] - store_data_types = [] - store_data_types_details = [] - - _running_status = False - - def __init__(self, interface, treeview, plg_list): - - self.interface = interface - - # 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) - - def _start_memphis(self, button): - # Update information every 1.5 second - button.hide() - self.interface.button_stop.show() - self._running_status = True - self._gid = gobject.timeout_add(1500, self.load_data, self.treeview) - - def _stop_memphis(self, button): - gobject.source_remove(self._gid) - self._running_status = False - button.hide() - self.interface.button_start.show() - - # 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 self._running_status - - 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 diff --git a/services/console/interface/memphis/plugin.py b/services/console/interface/memphis/plugin.py deleted file mode 100644 index 5ee8eb7e..00000000 --- a/services/console/interface/memphis/plugin.py +++ /dev/null @@ -1,48 +0,0 @@ -############################################### -# Memphis Plugin Support -############################################### - -import sys, os -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) - diff --git a/services/console/interface/memphis/plugins/Makefile.am b/services/console/interface/memphis/plugins/Makefile.am deleted file mode 100644 index d026419d..00000000 --- a/services/console/interface/memphis/plugins/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -SUBDIRS = clean_size cpu smaps memphis_init - -sugardir = $(pkgdatadir)/services/console/interface/memphis/plugins -sugar_PYTHON = diff --git a/services/console/interface/memphis/plugins/clean_size/Makefile.am b/services/console/interface/memphis/plugins/clean_size/Makefile.am deleted file mode 100644 index aa4ea115..00000000 --- a/services/console/interface/memphis/plugins/clean_size/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ - -sugardir = $(pkgdatadir)/services/console/interface/memphis/plugins/clean_size -sugar_PYTHON = \ - README \ - __init__.py \ - info.py diff --git a/services/console/interface/memphis/plugins/clean_size/README b/services/console/interface/memphis/plugins/clean_size/README deleted file mode 100644 index 3dd3ae33..00000000 --- a/services/console/interface/memphis/plugins/clean_size/README +++ /dev/null @@ -1,2 +0,0 @@ -This plugin give support to get the clean size memory usage -by process using the /proc/PID/maps file. diff --git a/services/console/interface/memphis/plugins/clean_size/__init__.py b/services/console/interface/memphis/plugins/clean_size/__init__.py deleted file mode 100644 index 75ce1d1f..00000000 --- a/services/console/interface/memphis/plugins/clean_size/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -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)"] - } diff --git a/services/console/interface/memphis/plugins/clean_size/info.py b/services/console/interface/memphis/plugins/clean_size/info.py deleted file mode 100644 index 25ed0448..00000000 --- a/services/console/interface/memphis/plugins/clean_size/info.py +++ /dev/null @@ -1,15 +0,0 @@ -########################################################### -# 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] diff --git a/services/console/interface/memphis/plugins/cpu/Makefile.am b/services/console/interface/memphis/plugins/cpu/Makefile.am deleted file mode 100644 index c8b8584b..00000000 --- a/services/console/interface/memphis/plugins/cpu/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ - -sugardir = $(pkgdatadir)/services/console/interface/memphis/plugins/cpu -sugar_PYTHON = \ - README \ - __init__.py \ - info.py diff --git a/services/console/interface/memphis/plugins/cpu/README b/services/console/interface/memphis/plugins/cpu/README deleted file mode 100644 index 9c7d6f31..00000000 --- a/services/console/interface/memphis/plugins/cpu/README +++ /dev/null @@ -1,2 +0,0 @@ -This plugin give support to draw the Virtual Memory Size -usage by the current tracing process. diff --git a/services/console/interface/memphis/plugins/cpu/__init__.py b/services/console/interface/memphis/plugins/cpu/__init__.py deleted file mode 100644 index e22a4134..00000000 --- a/services/console/interface/memphis/plugins/cpu/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -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 = {} diff --git a/services/console/interface/memphis/plugins/cpu/info.py b/services/console/interface/memphis/plugins/cpu/info.py deleted file mode 100644 index 9cb1ad42..00000000 --- a/services/console/interface/memphis/plugins/cpu/info.py +++ /dev/null @@ -1,48 +0,0 @@ -########################################################### -# 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 - diff --git a/services/console/interface/memphis/plugins/memphis_init/Makefile.am b/services/console/interface/memphis/plugins/memphis_init/Makefile.am deleted file mode 100644 index 3b2035d3..00000000 --- a/services/console/interface/memphis/plugins/memphis_init/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ - -sugardir = $(pkgdatadir)/services/console/interface/memphis/plugins/memphis_init -sugar_PYTHON = \ - README \ - __init__.py \ - info.py diff --git a/services/console/interface/memphis/plugins/memphis_init/README b/services/console/interface/memphis/plugins/memphis_init/README deleted file mode 100644 index 9c7d6f31..00000000 --- a/services/console/interface/memphis/plugins/memphis_init/README +++ /dev/null @@ -1,2 +0,0 @@ -This plugin give support to draw the Virtual Memory Size -usage by the current tracing process. diff --git a/services/console/interface/memphis/plugins/memphis_init/__init__.py b/services/console/interface/memphis/plugins/memphis_init/__init__.py deleted file mode 100644 index f5ada7ea..00000000 --- a/services/console/interface/memphis/plugins/memphis_init/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -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 - } diff --git a/services/console/interface/memphis/plugins/memphis_init/info.py b/services/console/interface/memphis/plugins/memphis_init/info.py deleted file mode 100644 index 667645c5..00000000 --- a/services/console/interface/memphis/plugins/memphis_init/info.py +++ /dev/null @@ -1,14 +0,0 @@ -########################################################### -# 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 - diff --git a/services/console/interface/memphis/plugins/smaps/Makefile.am b/services/console/interface/memphis/plugins/smaps/Makefile.am deleted file mode 100644 index 1f81dfbb..00000000 --- a/services/console/interface/memphis/plugins/smaps/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ - -sugardir = $(pkgdatadir)/services/console/interface/memphis/plugins/dirty_size -sugar_PYTHON = \ - README \ - __init__.py \ - info.py diff --git a/services/console/interface/memphis/plugins/smaps/README b/services/console/interface/memphis/plugins/smaps/README deleted file mode 100644 index ee4d1a5e..00000000 --- a/services/console/interface/memphis/plugins/smaps/README +++ /dev/null @@ -1,2 +0,0 @@ -This plugin give support to get the public and shared dirty memory usage -by process using the /proc/PID/smaps file. diff --git a/services/console/interface/memphis/plugins/smaps/__init__.py b/services/console/interface/memphis/plugins/smaps/__init__.py deleted file mode 100644 index 5977d4bd..00000000 --- a/services/console/interface/memphis/plugins/smaps/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ - -import info - - -INTERNALS = { - # Basic information - 'PLGNAME': "SMaps", - 'TABNAME': None, # No tabbed plugin - 'AUTHOR': "Eduardo Silva", - 'DESC': "Get dirty size and reference memory usage", - - # Plugin API - 'Plg': None, # Plugin object - - 'top_data': [int, int], # Top data types needed by memphis core plugin - 'top_cols': ["PDRSS (kb)", "Referenced (kb)"] - } diff --git a/services/console/interface/memphis/plugins/smaps/info.py b/services/console/interface/memphis/plugins/smaps/info.py deleted file mode 100644 index 998a1a25..00000000 --- a/services/console/interface/memphis/plugins/smaps/info.py +++ /dev/null @@ -1,19 +0,0 @@ -########################################################### -# 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): - smaps = get_data(self, ppinfo['pid']) - - # memphis need an array - return [smaps['private_dirty'], smaps['referenced']] - -def get_data(pself, pid): - ProcAnalysis = pself.INTERNALS['Plg'].proc_analysis(pid) - - return ProcAnalysis.SMaps() diff --git a/services/console/interface/network/Makefile.am b/services/console/interface/network/Makefile.am deleted file mode 100644 index a16f55e5..00000000 --- a/services/console/interface/network/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -sugardir = $(pkgdatadir)/services/console/interface/network -sugar_PYTHON = \ - __init__.py \ - network.py diff --git a/services/console/interface/network/__init__.py b/services/console/interface/network/__init__.py deleted file mode 100644 index ddc3f797..00000000 --- a/services/console/interface/network/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from network import Interface diff --git a/services/console/interface/network/network.py b/services/console/interface/network/network.py deleted file mode 100644 index 1f226905..00000000 --- a/services/console/interface/network/network.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright (C) 2007, Eduardo Silva -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import gobject -from net.device import Device -from ui.treeview import TreeView - -class NetworkView(TreeView): - def __init__(self): - col_names = [] - col_names.append({'index': 0, 'name': 'Interface'}) - col_names.append({'index': 1, 'name': 'IP Address'}) - col_names.append({'index': 2, 'name': 'NetMask'}) - col_names.append({'index': 3, 'name': 'MAC Address'}) - col_names.append({'index': 4, 'name': 'Bytes Recv'}) - col_names.append({'index': 5, 'name': 'Bytes Sent'}) - col_names.append({'index': 6, 'name': 'Packets Recv'}) - col_names.append({'index': 7, 'name': 'Packets Sent'}) - - self._iface_iter = [] - cols_type = [str, str, str, str, str, str, str, str] - TreeView.__init__(self, cols_type, col_names) - - self._dev = Device() - self.show_all() - gobject.timeout_add(1500, self._update_data) - - def _update_data(self): - interfaces = self._dev.get_interfaces() - for iface in interfaces: - info = self._dev.get_iface_info(iface['interface']) - row = [] - row.append({'index':0, 'info': iface['interface']}) - - if info[0]: - row.append({'index':1, 'info': info[0]}) - if info[1]: - row.append({'index':2, 'info': info[1]}) - if info[2]: - row.append({'index':3, 'info': info[2]}) - - row.append({'index': 4, 'info': iface['bytes_sent']}) - row.append({'index': 5, 'info': iface['packets_sent']}) - row.append({'index': 6, 'info': iface['bytes_recv']}) - row.append({'index': 7, 'info': iface['packets_recv']}) - - iter = self._get_iface_iter(iface['interface']) - if not iter: - iter = self.add_row(row) - self._set_iface_iter(iter, iface['interface']) - else: - self.update_row(iter, row) - - self._clear_down_interfaces(interfaces) - return True - - def _set_iface_iter(self, iter, iface): - self._iface_iter.append([iter, iface]) - - def _remove_iface_iter(self, search_iter): - i = 0 - for [iter, interface] in self._iface_iter: - if iter == search_iter: - del self._iface_iter[i] - return - i+=1 - - def _get_iface_iter(self, iface): - for [iter, interface] in self._iface_iter: - if iface == interface: - return iter - - return None - - def _clear_down_interfaces(self, interfaces): - for [iter, iface] in self._iface_iter: - found = False - for dev in interfaces: - if dev['interface']==iface: - found = True - break - - if not found: - self.remove_row(iter) - self._remove_iface_iter(iter) - -class Interface(object): - def __init__(self): - self.widget = NetworkView() diff --git a/services/console/interface/ps_watcher.py b/services/console/interface/ps_watcher.py deleted file mode 100644 index 6ee7e572..00000000 --- a/services/console/interface/ps_watcher.py +++ /dev/null @@ -1,729 +0,0 @@ -# Copyright (C) 2007 Collabora Ltd. -# -# 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 - -import logging -from hashlib import sha1 - -import dbus -from gtk import VBox, Label, TreeView, Expander, ListStore, CellRendererText,\ - ScrolledWindow, CellRendererToggle, TextView, VPaned -from gobject import timeout_add - - -logger = logging.getLogger('ps_watcher') -#logging.basicConfig(filename='/tmp/ps_watcher.log') -#logging.getLogger().setLevel(1) - - -PS_NAME = 'org.laptop.Sugar.Presence' -PS_PATH = '/org/laptop/Sugar/Presence' -PS_IFACE = PS_NAME -ACTIVITY_IFACE = PS_IFACE + '.Activity' -BUDDY_IFACE = PS_IFACE + '.Buddy' - -# keep these in sync with the calls to ListStore() -ACT_COL_PATH = 0 -ACT_COL_WEIGHT = 1 -ACT_COL_STRIKE = 2 -ACT_COL_ID = 3 -ACT_COL_COLOR = 4 -ACT_COL_TYPE = 5 -ACT_COL_NAME = 6 -ACT_COL_CONN = 7 -ACT_COL_CHANNELS = 8 -ACT_COL_BUDDIES = 9 -BUDDY_COL_PATH = 0 -BUDDY_COL_WEIGHT = 1 -BUDDY_COL_STRIKE = 2 -BUDDY_COL_NICK = 3 -BUDDY_COL_OWNER = 4 -BUDDY_COL_COLOR = 5 -BUDDY_COL_IP4 = 6 -BUDDY_COL_CUR_ACT = 7 -BUDDY_COL_KEY_ID = 8 -BUDDY_COL_ACTIVITIES = 9 -BUDDY_COL_HANDLES = 10 - - -class ActivityWatcher(object): - - def __init__(self, ps_watcher, object_path): - self.ps_watcher = ps_watcher - self.bus = ps_watcher.bus - self.proxy = self.bus.get_object(self.ps_watcher.unique_name, - object_path) - self.iface = dbus.Interface(self.proxy, ACTIVITY_IFACE) - self.object_path = object_path - self.appearing = True - self.disappearing = False - timeout_add(5000, self._finish_appearing) - - self.id = '?' - self.color = '?' - self.type = '?' - self.name = '?' - self.conn = '?' - self.channels = None - self.buddies = None - - self.iter = self.ps_watcher.add_activity(self) - - self.iface.GetId(reply_handler=self._on_get_id_success, - error_handler=self._on_get_id_failure) - - self.iface.GetColor(reply_handler=self._on_get_color_success, - error_handler=self._on_get_color_failure) - - self.iface.GetType(reply_handler=self._on_get_type_success, - error_handler=self._on_get_type_failure) - - self.iface.GetName(reply_handler=self._on_get_name_success, - error_handler=self._on_get_name_failure) - - self.iface.connect_to_signal('NewChannel', self._on_new_channel) - self.iface.GetChannels(reply_handler=self._on_get_channels_success, - error_handler=self._on_get_channels_failure) - - self.iface.connect_to_signal('BuddyJoined', self._on_buddy_joined) - self.iface.connect_to_signal('BuddyLeft', self._on_buddy_left) - self.iface.GetJoinedBuddies(reply_handler=self._on_get_buddies_success, - error_handler=self._on_get_buddies_failure) - - def _on_buddy_joined(self, buddy): - if self.buddies is None: - return - if buddy.startswith('/org/laptop/Sugar/Presence/Buddies/'): - buddy = '.../' + buddy[35:] - self.ps_watcher.log('INFO: Activity %s emitted BuddyJoined("%s") ' - 'or mentioned the buddy in GetJoinedBuddies', - self.object_path, buddy) - self.buddies.append(buddy) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, - ' '.join(self.buddies)) - - def _on_buddy_left(self, buddy): - if self.buddies is None: - return - if buddy.startswith('/org/laptop/Sugar/Presence/Buddies/'): - buddy = '.../' + buddy[35:] - self.ps_watcher.log('INFO: Activity %s emitted BuddyLeft("%s")', - self.object_path, buddy) - try: - self.buddies.remove(buddy) - except ValueError: - pass - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, - ' '.join(self.buddies)) - - def _on_get_buddies_success(self, buddies): - self.buddies = [] - for buddy in buddies: - self._on_buddy_joined(buddy) - - def _on_get_buddies_failure(self, e): - self.log('ERROR: .GetJoinedBuddies(): %s', - self.object_path, e) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, - '!') - - def _on_new_channel(self, channel): - if self.channels is None: - return - if channel.startswith(self.full_conn): - channel = '...' + channel[len(self.full_conn):] - self.ps_watcher.log('INFO: Activity %s emitted NewChannel("%s") ' - 'or mentioned the channel in GetChannels()', - self.object_path, channel) - self.channels.append(channel) - # FIXME: listen for Telepathy Closed signal! - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CHANNELS, - ' '.join(self.channels)) - - def _on_get_channels_success(self, service, conn, channels): - self.full_conn = conn - if conn.startswith('/org/freedesktop/Telepathy/Connection/'): - self.conn = '.../' + conn[38:] - else: - self.conn = conn - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CONN, - self.conn) - self.channels = [] - for channel in channels: - self._on_new_channel(channel) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CHANNELS, - ' '.join(self.channels)) - - def _on_get_channels_failure(self, e): - self.ps_watcher.log('ERROR: .GetChannels(): %s', - self.object_path, e) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CONN, - '!') - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CHANNELS, - '!') - - def _on_get_id_success(self, ident): - self.id = ident - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_ID, ident) - - def _on_get_id_failure(self, e): - self.ps_watcher.log('ERROR: .GetId(): %s', - self.object_path, e) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_ID, - '!') - - def _on_get_color_success(self, color): - self.color = color - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_COLOR, - color) - - def _on_get_color_failure(self, e): - self.ps_watcher.log('ERROR: .GetColor(): %s', - self.object_path, e) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_COLOR, - '!') - - def _on_get_type_success(self, type_): - self.type = type_ - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_TYPE, - type_) - - def _on_get_type_failure(self, e): - self.ps_watcher.log('ERROR: .GetType(): %s', - self.object_path, e) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_TYPE, - '!') - - def _on_get_name_success(self, name): - self.name = name - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_NAME, - name) - - def _on_get_name_failure(self, e): - self.ps_watcher.log('ERROR: .GetName(): %s', - self.object_path, e) - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_NAME, - '!') - - def _finish_appearing(self): - self.appearing = False - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_WEIGHT, - 400) - return False - - def disappear(self): - self.disappearing = True - self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_STRIKE, - True) - timeout_add(5000, self._finish_disappearing) - - def _finish_disappearing(self): - self.ps_watcher.remove_activity(self) - return False - - -class BuddyWatcher(object): - - def __init__(self, ps_watcher, object_path): - self.ps_watcher = ps_watcher - self.bus = ps_watcher.bus - self.proxy = self.bus.get_object(self.ps_watcher.unique_name, - object_path) - self.iface = dbus.Interface(self.proxy, BUDDY_IFACE) - self.object_path = object_path - self.appearing = True - self.disappearing = False - timeout_add(5000, self._finish_appearing) - - self.nick = '?' - self.owner = False - self.color = '?' - self.ipv4 = '?' - self.cur_act = '?' - self.keyid = '?' - self.activities = None - self.handles = None - - self.iter = self.ps_watcher.add_buddy(self) - - self.iface.connect_to_signal('PropertyChanged', self._on_props_changed, - byte_arrays=True) - self.ps_watcher.log('Calling .GetProperties()', object_path) - self.iface.GetProperties(reply_handler=self._on_get_props_success, - error_handler=self._on_get_props_failure, - byte_arrays=True) - - self.iface.connect_to_signal('JoinedActivity', self._on_joined) - self.iface.connect_to_signal('LeftActivity', self._on_left) - self.ps_watcher.log('Calling .GetJoinedActivities()', - object_path) - self.iface.GetJoinedActivities(reply_handler=self._on_get_acts_success, - error_handler=self._on_get_acts_failure) - - self.iface.connect_to_signal('TelepathyHandleAdded', - self._on_handle_added) - self.iface.connect_to_signal('TelepathyHandleRemoved', - self._on_handle_removed) - self.ps_watcher.log('Calling .GetTelepathyHandles()', - object_path) - self.iface.GetTelepathyHandles( - reply_handler=self._on_get_handles_success, - error_handler=self._on_get_handles_failure) - - def _on_handle_added(self, service, conn, handle): - if self.handles is None: - return - self.ps_watcher.log('INFO: Buddy %s emitted Telepathy HandleAdded(' - '"%s", "%s", %u) or mentioned the handle in ' - 'GetTelepathyHandles()', - self.object_path, service, conn, handle) - if conn.startswith('/org/freedesktop/Telepathy/Connection/'): - conn = '.../' + conn[38:] - self.handles.append('%u@%s' % (handle, conn)) - self.ps_watcher.buddies_list_store.set(self.iter, - BUDDY_COL_HANDLES, - ' '.join(self.handles)) - - def _on_handle_removed(self, service, conn, handle): - if self.handles is None: - return - if conn.startswith('/org/freedesktop/Telepathy/Connection/'): - conn = '.../' + conn[38:] - self.ps_watcher.log('INFO: Buddy %s emitted HandleRemoved("%s", ' - '"%s", %u)', self.object_path, service, conn, - handle) - try: - self.handles.remove('%u@%s' % (handle, conn)) - except ValueError: - pass - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_HANDLES, - ' '.join(self.handles)) - - def _on_get_handles_success(self, handles): - self.handles = [] - for service, conn, handle in handles: - self._on_handle_added(service, conn, handle) - - def _on_get_handles_failure(self, e): - self.ps_watcher.log('ERROR: .GetTelepathyHandles(): %s', - self.object_path, e) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_HANDLES, - '!') - - def _on_joined(self, act): - if self.activities is None: - return - if act.startswith('/org/laptop/Sugar/Presence/Activities/'): - act = '.../' + act[38:] - self.ps_watcher.log('INFO: Buddy %s emitted ActivityJoined("%s") ' - 'or mentioned it in GetJoinedActivities()', - self.object_path, act) - self.activities.append(act) - self.ps_watcher.buddies_list_store.set(self.iter, - BUDDY_COL_ACTIVITIES, - ' '.join(self.activities)) - - def _on_left(self, act): - if self.activities is None: - return - if act.startswith('/org/laptop/Sugar/Presence/Activities/'): - act = '.../' + act[38:] - self.ps_watcher.log('INFO: Buddy %s emitted ActivityLeft("%s")', - self.object_path, act) - try: - self.activities.remove(act) - except ValueError: - pass - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_ACTIVITIES, - ' '.join(self.activities)) - - def _on_get_acts_success(self, activities): - self.activities = [] - for act in activities: - self._on_joined(act) - - def _on_get_acts_failure(self, e): - self.ps_watcher.log('ERROR: .GetJoinedActivities(): %s', - self.object_path, e) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_ACTIVITIES, - '!') - - def _on_props_changed(self, props): - try: - logger.debug('PropertyChanged(%s, %s)', self, props) - self.ps_watcher.log('INFO: emitted PropertyChanged(%r)', - self.object_path, props) - self._props_changed(props) - except Exception, e: - self.ps_watcher.log('INTERNAL ERROR: %s', e) - - def _on_get_props_success(self, props): - try: - logger.debug('GetProperties(%s, %s)', self, props) - self.ps_watcher.log('INFO: .GetProperties() -> %r', - self.object_path, props) - self._props_changed(props) - except Exception, e: - self.ps_watcher.log('INTERNAL ERROR: %s', e) - - def _props_changed(self, props): - logger.debug('Begin _props_changed') - if 'nick' in props: - self.nick = props.get('nick', '?') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_NICK, - self.nick) - if 'owner' in props: - self.owner = bool(props.get('owner', False)) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_OWNER, - self.owner) - if 'color' in props: - self.color = props.get('color', '?') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_COLOR, - self.color) - if 'ip4-address' in props: - self.ipv4 = props.get('ip4-address', '?') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_IP4, - self.ipv4) - if 'current-activity' in props: - self.cur_act = props.get('current-activity', '?') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_CUR_ACT, - self.cur_act) - if 'key' in props: - key = props.get('key', None) - if key: - self.keyid = '%d bytes, sha1 %s' % (len(key), - sha1(key).hexdigest()) - else: - # could be '' (present, empty value) or None (absent). Either way: - self.keyid = '?' - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_KEY_ID, - self.keyid) - logger.debug('End _props_changed') - - def _on_get_props_failure(self, e): - self.ps_watcher.log('ERROR: .GetProperties(): %s', - self.object_path, e) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_NICK, '!') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_OWNER, - False) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_COLOR, '!') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_IP4, '!') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_CUR_ACT, - '!') - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_KEY_ID, - '!') - - def _finish_appearing(self): - self.appearing = False - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_WEIGHT, - 400) - return False - - def disappear(self): - self.disappearing = True - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_STRIKE, - True) - timeout_add(5000, self._finish_disappearing) - - def _finish_disappearing(self): - self.ps_watcher.remove_buddy(self) - return False - - -class PresenceServiceWatcher(VBox): - - def __init__(self, bus, unique_name, log): - VBox.__init__(self) - - self.bus = bus - self.unique_name = unique_name - self.proxy = bus.get_object(unique_name, PS_PATH) - self.iface = dbus.Interface(self.proxy, PS_IFACE) - self.log = log - - self.activities = None - self.iface.connect_to_signal('ActivityAppeared', - self._on_activity_appeared) - self.iface.connect_to_signal('ActivityDisappeared', - self._on_activity_disappeared) - self.iface.GetActivities(reply_handler=self._on_get_activities_success, - error_handler=self._on_get_activities_failure) - - self.buddies = None - self.iface.connect_to_signal('BuddyAppeared', - self._on_buddy_appeared) - self.iface.connect_to_signal('BuddyDisappeared', - self._on_buddy_disappeared) - self.iface.GetBuddies(reply_handler=self._on_get_buddies_success, - error_handler=self._on_get_buddies_failure) - - # keep this in sync with the ACT_COL_ constants - self.activities_list_store = ListStore(str, # object path - int, # weight (bold if new) - bool, # strikethrough (dead) - str, # ID - str, # color - str, # type - str, # name - str, # conn - str, # channels - str, # buddies - ) - - self.pack_start(Label('Activities:'), False, False) - - self.activities_list = TreeView(self.activities_list_store) - c = self.activities_list.insert_column_with_attributes(0, - 'Object path', CellRendererText(), text=ACT_COL_PATH, - weight=ACT_COL_WEIGHT, strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(ACT_COL_PATH) - c = self.activities_list.insert_column_with_attributes(1, 'ID', - CellRendererText(), text=ACT_COL_ID, - weight=ACT_COL_WEIGHT, strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(ACT_COL_ID) - c = self.activities_list.insert_column_with_attributes(2, 'Color', - CellRendererText(), text=ACT_COL_COLOR, - weight=ACT_COL_WEIGHT, strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(ACT_COL_COLOR) - c = self.activities_list.insert_column_with_attributes(3, 'Type', - CellRendererText(), text=ACT_COL_TYPE, weight=ACT_COL_WEIGHT, - strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(ACT_COL_TYPE) - c = self.activities_list.insert_column_with_attributes(4, 'Name', - CellRendererText(), text=ACT_COL_NAME, weight=ACT_COL_WEIGHT, - strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(ACT_COL_NAME) - c = self.activities_list.insert_column_with_attributes(5, 'Connection', - CellRendererText(), text=ACT_COL_CONN, weight=ACT_COL_WEIGHT, - strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(ACT_COL_CONN) - c = self.activities_list.insert_column_with_attributes(6, 'Channels', - CellRendererText(), text=ACT_COL_CHANNELS, weight=ACT_COL_WEIGHT, - strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - c = self.activities_list.insert_column_with_attributes(7, 'Buddies', - CellRendererText(), text=ACT_COL_BUDDIES, weight=ACT_COL_WEIGHT, - strikethrough=ACT_COL_STRIKE) - c.set_resizable(True) - - scroller = ScrolledWindow() - scroller.add(self.activities_list) - self.pack_start(scroller) - - # keep this in sync with the BUDDY_COL_ constants - self.buddies_list_store = ListStore(str, int, bool, str, bool, - str, str, str, str, str, str) - - self.pack_start(Label('Buddies:'), False, False) - self.buddies_list = TreeView(self.buddies_list_store) - c = self.buddies_list.insert_column_with_attributes(0, 'Object path', - CellRendererText(), text=BUDDY_COL_PATH, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_PATH) - c = self.buddies_list.insert_column_with_attributes(1, 'Pubkey', - CellRendererText(), text=BUDDY_COL_KEY_ID, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_KEY_ID) - c = self.buddies_list.insert_column_with_attributes(2, 'Nick', - CellRendererText(), text=BUDDY_COL_NICK, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_NICK) - c = self.buddies_list.insert_column_with_attributes(3, 'Owner', - CellRendererToggle(), active=BUDDY_COL_OWNER) - c = self.buddies_list.insert_column_with_attributes(4, 'Color', - CellRendererText(), text=BUDDY_COL_COLOR, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_OWNER) - c = self.buddies_list.insert_column_with_attributes(5, 'IPv4', - CellRendererText(), text=BUDDY_COL_IP4, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_IP4) - c = self.buddies_list.insert_column_with_attributes(6, 'CurAct', - CellRendererText(), text=BUDDY_COL_CUR_ACT, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_CUR_ACT) - c = self.buddies_list.insert_column_with_attributes(7, 'Activities', - CellRendererText(), text=BUDDY_COL_ACTIVITIES, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_ACTIVITIES) - c = self.buddies_list.insert_column_with_attributes(8, 'Handles', - CellRendererText(), text=BUDDY_COL_HANDLES, - weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) - c.set_resizable(True) - c.set_sort_column_id(BUDDY_COL_HANDLES) - - scroller = ScrolledWindow() - scroller.add(self.buddies_list) - self.pack_start(scroller) - - self.iface.connect_to_signal('ActivityInvitation', - self._on_activity_invitation) - self.iface.connect_to_signal('PrivateInvitation', - self._on_private_invitation) - - def _on_get_activities_success(self, paths): - self.log('INFO: PS GetActivities() returned %r', paths) - self.activities = {} - for path in paths: - self.activities[path] = ActivityWatcher(self, path) - - def _on_get_activities_failure(self, e): - self.log('ERROR: PS GetActivities() failed with %s', e) - - def add_activity(self, act): - path = act.object_path - if path.startswith('/org/laptop/Sugar/Presence/Activities/'): - path = '.../' + path[38:] - return self.activities_list_store.append((path, 700, False, - act.id, act.color, act.type, act.name, act.conn, '?', '?')) - - def remove_activity(self, act): - self.activities.pop(act.object_path, None) - self.activities_list_store.remove(act.iter) - - def _on_activity_appeared(self, path): - if self.activities is None: - return - self.log('INFO: PS emitted ActivityAppeared("%s")', path) - self.activities[path] = ActivityWatcher(self, path) - - def _on_activity_disappeared(self, path): - if self.activities is None: - return - self.log('INFO: PS emitted ActivityDisappeared("%s")', path) - act = self.activities.get(path) - if act is None: - self.log('WARNING: Trying to remove activity "%s" which is ' - 'already absent', path) - else: - # we don't remove the activity straight away, just cross it out - act.disappear() - - def _on_activity_invitation(self, path): - self.log('INFO: PS emitted ActivityInvitation("%s")', path) - - def _on_private_invitation(self, bus_name, conn, channel): - self.log('INFO: PS emitted PrivateInvitation("%s", "%s", "%s")', - bus_name, conn, channel) - - def _on_get_buddies_success(self, paths): - self.log('INFO: PS GetBuddies() returned %r', paths) - self.buddies = {} - for path in paths: - self.buddies[path] = BuddyWatcher(self, path) - - def _on_get_buddies_failure(self, e): - self.log('ERROR: PS GetBuddies() failed with %s', e) - - def add_buddy(self, b): - path = b.object_path - if path.startswith('/org/laptop/Sugar/Presence/Buddies/'): - path = '.../' + path[35:] - return self.buddies_list_store.append((path, 700, False, - b.nick, b.owner, b.color, b.ipv4, b.cur_act, b.keyid, - '?', '?')) - - def remove_buddy(self, b): - self.buddies.pop(b.object_path, None) - self.buddies_list_store.remove(b.iter) - - def _on_buddy_appeared(self, path): - if self.buddies is None: - return - self.log('INFO: PS emitted BuddyAppeared("%s")', path) - self.buddies[path] = BuddyWatcher(self, path) - - def _on_buddy_disappeared(self, path): - if self.buddies is None: - return - self.log('INFO: PS emitted BuddyDisappeared("%s")', path) - b = self.buddies.get(path) - if b is None: - self.log('ERROR: Trying to remove buddy "%s" which is already ' - 'absent', path) - else: - # we don't remove the activity straight away, just cross it out - b.disappear() - - -class PresenceServiceNameWatcher(VBox): - - def __init__(self, bus): - VBox.__init__(self) - - self.bus = bus - - logger.debug('Running...') - self.label = Label('Looking for Presence Service...') - self.errors = ListStore(str) - - errors_tree = TreeView(model=self.errors) - errors_tree.insert_column_with_attributes(0, 'Log', CellRendererText(), - text=0) - scroller = ScrolledWindow() - scroller.add(errors_tree) - - self.paned = VPaned() - self.paned.pack1(scroller) - - self.pack_start(self.label, False, False) - self.pack_end(self.paned) - - bus.watch_name_owner(PS_NAME, self.on_name_owner_change) - self.ps_watcher = Label('-') - self.paned.pack2(self.ps_watcher) - - self.show_all() - - def log(self, format, *args): - self.errors.append((format % args,)) - - def on_name_owner_change(self, owner): - try: - if owner: - self.label.set_text('Presence Service running: unique name %s' - % owner) - if self.ps_watcher is not None: - self.paned.remove(self.ps_watcher) - self.ps_watcher = PresenceServiceWatcher(self.bus, owner, - self.log) - self.paned.pack2(self.ps_watcher) - self.show_all() - else: - self.label.set_text('Presence Service not running') - if self.ps_watcher is not None: - self.paned.remove(self.ps_watcher) - self.ps_watcher = Label('-') - self.paned.pack2(self.ps_watcher) - except Exception, e: - self.log('ERROR: %s', e) - - -class Interface(object): - def __init__(self): - self.widget = PresenceServiceNameWatcher(dbus.SessionBus()) diff --git a/services/console/interface/xo/Makefile.am b/services/console/interface/xo/Makefile.am deleted file mode 100644 index dbc96c40..00000000 --- a/services/console/interface/xo/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -sugardir = $(pkgdatadir)/services/console/interface/xo -sugar_PYTHON = \ - __init__.py \ - xo.py \ - cpu.py \ - system.py \ - nandflash.py diff --git a/services/console/interface/xo/__init__.py b/services/console/interface/xo/__init__.py deleted file mode 100644 index 491017d4..00000000 --- a/services/console/interface/xo/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from xo import Interface - diff --git a/services/console/interface/xo/cpu.py b/services/console/interface/xo/cpu.py deleted file mode 100644 index 6f6a5a79..00000000 --- a/services/console/interface/xo/cpu.py +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright (C) 2007, 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 - -import os -import sys -import gtk -import string -import gobject -import cairo -import procmem - -from graphics.frequency import HorizontalGraphic - -class CPU_Usage: - _CPU_HZ = 0 - _last_jiffies = 0 - _times = 0 - - def __init__(self): - self._CPU_HZ = os.sysconf(2) - - def _get_CPU_data(self): - # Uptime info - stat_file = "/proc/stat" - - try: - infile = file(stat_file, "r") - except: - print "Error trying uptime file" - return -1 - - stat_line = infile.readline() - cpu_info = string.split(stat_line, ' ') - infile.close() - - return cpu_info - - def _get_CPU_usage(self): - - cpu_info = self._get_CPU_data() - - used_jiffies = (int(cpu_info[2]) + int(cpu_info[3]) + int(cpu_info[4])) - - if self._times ==0: - self._last_jiffies = used_jiffies - self._times +=1 - return 0 - - new_ujiffies = (used_jiffies - self._last_jiffies) - new_ajiffies = ((self.frequency/1000) * self._CPU_HZ) - - if new_ajiffies <= 0: - pcpu = 0.0 - else: - pcpu = ((new_ujiffies*100)/new_ajiffies) - - if pcpu >100: - pcpu = 100 - - self._times +=1 - self._last_jiffies = used_jiffies - - return pcpu - -class XO_CPU(gtk.Frame): - _frequency_timer = 1 - - def __init__(self): - gtk.Frame.__init__(self, 'System CPU Usage') - self.set_border_width(10) - - width = (gtk.gdk.screen_width() * 99 / 100) - 50 - height = (gtk.gdk.screen_height() * 15 / 100) - 20 - - # Create graphic - self._graphic = HorizontalGraphic() - self._graphic.set_size_request(width, height) - - fixed = gtk.Fixed() - fixed.set_border_width(10) - fixed.add(self._graphic) - - self.add(fixed) - - self._DRW_CPU = CPU_Usage() - self._DRW_CPU.frequency = 1000 # 1 Second - - gobject.timeout_add(self._DRW_CPU.frequency, self._update_cpu_usage) - - def _update_cpu_usage(self): - print "update XO CPU" - self._cpu = self._DRW_CPU._get_CPU_usage() - self.set_label('System CPU Usage: ' + str(self._cpu) + '%') - - # Draw the value into the graphic - self._graphic.draw_value(self._cpu) - - return True diff --git a/services/console/interface/xo/nandflash.py b/services/console/interface/xo/nandflash.py deleted file mode 100644 index d70379d4..00000000 --- a/services/console/interface/xo/nandflash.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright (C) 2007, 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 - -import gtk -import gobject - -from os import statvfs -from label import Label -from graphics.box import * - -class XO_NandFlash(gtk.Fixed): - _MOUNT_POINT = '/' - - def __init__(self): - gtk.Fixed.__init__(self) - - self._frame_text = 'Nand Flash' - self._frame = gtk.Frame(self._frame_text) - self.set_border_width(10) - - - self._nandflash_box = BoxGraphic(color_mode=COLOR_MODE_REVERSE) - self._nandflash_box.set_size_request(70, 150) - - fixed = gtk.Fixed(); - fixed.set_border_width(10) - fixed.add(self._nandflash_box) - - hbox = gtk.HBox(False, 0) - hbox.pack_start(fixed, False, False, 4) - - # Battery info - table = gtk.Table(2, 3) - table.set_border_width(5) - table.set_col_spacings(7) - table.set_row_spacings(7) - - label_total_size = Label('Total: ' , Label.DESCRIPTION) - self._label_total_value = Label('0 KB', Label.DESCRIPTION) - - label_used_size = Label('Used: ' , Label.DESCRIPTION) - self._label_used_value = Label('0 KB', Label.DESCRIPTION) - - label_free_size = Label('Free: ' , Label.DESCRIPTION) - self._label_free_value = Label('0 KB', Label.DESCRIPTION) - - # Total - table.attach(label_total_size, 0, 1, 0, 1) - table.attach(self._label_total_value, 1,2, 0,1) - # Used - table.attach(label_used_size, 0, 2, 1, 2) - table.attach(self._label_used_value, 1,3, 1,2) - # Free - table.attach(label_free_size, 0, 3, 2, 3) - table.attach(self._label_free_value, 1,4, 2,3) - - alignment = gtk.Alignment(0,0,0,0) - alignment.add(table) - - hbox.pack_start(alignment, False, False, 0) - self._frame.add(hbox) - self.add(self._frame) - self.show() - self.update_status() - - def update_status(self): - nand = StorageDevice(self._MOUNT_POINT) - - # Byte values - total = (nand.f_bsize*nand.f_blocks) - free = (nand.f_bsize*nand.f_bavail) - used = (total - free) - - self._label_total_value.set_label(str(total/1024) + ' KB') - self._label_used_value.set_label(str(used/1024) + ' KB') - self._label_free_value.set_label(str(free/1024) + ' KB') - self._usage_percent = ((used*100)/total) - - frame_label = self._frame_text + ': ' + str(self._usage_percent) + '%' - self._frame.set_label(frame_label) - self._nandflash_box.set_capacity(self._usage_percent) - -class StorageDevice: - f_bsize = 0 - f_frsize = 0 - f_blocks = 0 - f_bfree = 0 - f_bavail = 0 - f_files = 0 - f_ffree = 0 - f_favail = 0 - f_flag = 0 - f_namemax = 0 - - def __init__(self, mount_point): - self.f_bsize, self.f_frsize, self.f_blocks, self.f_bfree, \ - self.f_bavail, self.f_files, self.f_ffree, \ - self.f_favail, self.f_flag, self.f_namemax = statvfs(mount_point) - -""" -w = gtk.Window() -a = XO_NandFlash() -w.add(a) -w.show_all() -gtk.main() -""" diff --git a/services/console/interface/xo/system.py b/services/console/interface/xo/system.py deleted file mode 100644 index 03846f9d..00000000 --- a/services/console/interface/xo/system.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (C) 2007, 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 - -import os -import gtk -import pango - -from label import Label -from label import Style - -class XO_System(gtk.Fixed): - - def __init__(self): - gtk.Fixed.__init__(self) - self.set_border_width(12) - - table = gtk.Table(2, 2) - table.set_border_width(15) - table.set_col_spacings(7) - table.set_row_spacings(7) - - # BUILD - build = self._read_file('/boot/olpc_build') - label_build = Label('OLPC Build:', Label.DESCRIPTION) - label_build_value = Label(str(build), Label.DESCRIPTION) - - # KERNEL - sysinfo = os.uname() - label_kernel = Label('Kernel Version:', Label.DESCRIPTION) - label_kernel_value = Label(sysinfo[0] + '-' + sysinfo[2],\ - Label.DESCRIPTION) - - # FIRMWARE - firmware = self._read_file('/ofw/openprom/model') - label_firmware = Label('XO Firmware:', Label.DESCRIPTION) - label_firmware_value = Label(firmware, Label.DESCRIPTION) - - # SERIAL NUMBER - serial = self._read_file('/ofw/serial-number') - label_serial = Label('XO Serial Number:', Label.DESCRIPTION) - label_serial_value = Label(serial, Label.DESCRIPTION) - - # OLPC Build - table.attach(label_build, 0, 1, 0, 1) - table.attach(label_build_value, 1,2, 0,1) - - # Kernel Version - table.attach(label_kernel, 0, 1, 1, 2) - table.attach(label_kernel_value, 1, 2, 1, 2) - - # XO Firmware - table.attach(label_firmware, 0, 1, 2, 3) - table.attach(label_firmware_value, 1, 2, 2, 3) - - # XO Serial Number - table.attach(label_serial, 0, 1, 3, 4) - table.attach(label_serial_value, 1, 2, 3, 4) - - frame = gtk.Frame('System Information') - style = Style() - style.set_title_font(frame); - frame.add(table) - - self.add(frame) - self.show_all() - - def _read_file(self, path): - try: - f = open(path, 'r') - value = f.read() - f.close() - - value = value.split('\n')[0] - if value[len(value) - 1] == '\x00': - value = value[:len(value) - 1] - return value - except: - return "None" diff --git a/services/console/interface/xo/xo.py b/services/console/interface/xo/xo.py deleted file mode 100644 index d2056058..00000000 --- a/services/console/interface/xo/xo.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2007, 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 - -import os -import gtk -import gobject -import gtk.gdk -import cairo -import string - -from cpu import XO_CPU -from system import XO_System -from nandflash import XO_NandFlash - -class Interface: - - def __init__(self): - self.widget = self.vbox = gtk.VBox(False, 3) - - # System information - xo_system = XO_System() - self.vbox.pack_start(xo_system, False, False, 0) - - # CPU usage / Graph - xo_cpu = XO_CPU() - self.vbox.pack_start(xo_cpu, False, False, 0) - - # Graphics: Battery Status, NandFlash - self._xo_nandflash = XO_NandFlash() - - hbox = gtk.HBox(False, 2) - hbox.pack_start(self._xo_nandflash, False, False, 0) - - self.vbox.pack_start(hbox, False, False, 0) - self.vbox.show_all() - - # Update every 5 seconds - gobject.timeout_add(5000, self._update_components) - - def _update_components(self): - self._xo_nandflash.update_status() - - return True - diff --git a/services/console/interface/xserver/Makefile.am b/services/console/interface/xserver/Makefile.am deleted file mode 100644 index c77cca20..00000000 --- a/services/console/interface/xserver/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -sugardir = $(pkgdatadir)/services/console/interface/xserver -sugar_PYTHON = \ - __init__.py \ - xserver.py diff --git a/services/console/interface/xserver/__init__.py b/services/console/interface/xserver/__init__.py deleted file mode 100644 index 88b634fe..00000000 --- a/services/console/interface/xserver/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from xserver import Interface diff --git a/services/console/interface/xserver/xserver.py b/services/console/interface/xserver/xserver.py deleted file mode 100644 index 2ab1860f..00000000 --- a/services/console/interface/xserver/xserver.py +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright (C) 2007, Eduardo Silva -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import gobject -from pyxres import XRes -from ui.treeview import TreeView - -class XorgView(TreeView): - def __init__(self): - col_names = [] - col_names.append({'index': 0, 'name': 'PID'}) - col_names.append({'index': 1, 'name': 'Resource Base'}) - col_names.append({'index': 2, 'name': 'Pixmap Bytes'}) - col_names.append({'index': 3, 'name': 'Other'}) - col_names.append({'index': 4, 'name': 'Total'}) - col_names.append({'index': 5, 'name': 'Window Name'}) - - self._window_iter = [] - - cols_type = [str, str, str, str, str, str] - TreeView.__init__(self, cols_type, col_names) - - self._xres = XRes() - self._display = self._xres.open_display() - self.show_all() - gobject.timeout_add(1500, self._update_data) - - def _nice_bytes(self, bytes): - prefix = "B" - value = bytes - - if bytes/1024: - prefix = "K" - value = (bytes/1024) - - return "%s%s" % (value, prefix) - - def _update_data(self): - windows = self._xres.get_windows(self._display) - print windows - for w in windows: - row = [] - row.append({'index':0, 'info': w.pid}) - - bytes = self._nice_bytes(w.pixmap_bytes) - obytes = self._nice_bytes(w.other_bytes) - tbytes = self._nice_bytes(w.pixmap_bytes+w.other_bytes) - - row.append({'index':1, 'info': hex(w.resource_base)}) - row.append({'index':2, 'info': bytes}) - row.append({'index':3, 'info': obytes}) - row.append({'index':4, 'info': tbytes}) - row.append({'index':5, 'info': w.wm_name}) - - iter = self._get_window_iter(w.pid) - if not iter: - iter = self.add_row(row) - self._set_window_iter(iter, w.pid) - else: - self.update_row(iter, row) - - self._clear_down_windows(windows) - return True - - def _set_window_iter(self, iter, pid): - self._window_iter.append([iter, pid]) - - def _remove_iface_iter(self, search_iter): - i = 0 - for [iter, pid] in self._window_iter: - if iter == search_iter: - del self._window_iter[i] - return - i+=1 - - def _get_window_iter(self, wpid): - for [iter, pid] in self._window_iter: - if wpid == pid: - return iter - - return None - - def _clear_down_windows(self, windows): - for [iter, pid] in self._window_iter: - found = False - for w in windows: - if w.pid == pid: - found = True - break - - if not found: - self.remove_row(iter) - self._remove_window_iter(iter) - -class Interface(object): - def __init__(self): - self.widget = XorgView() diff --git a/services/console/label.py b/services/console/label.py deleted file mode 100644 index 3418eea2..00000000 --- a/services/console/label.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (C) 2007, 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 - -import gtk -import pango - -class Label(gtk.Label): - TITLE = 0 - DESCRIPTION = 1 - - def __init__(self, text, font_type): - gtk.Label.__init__(self) - - self.set_text(text) - self.set_alignment(0.0, 0.5) - - s = { - self.TITLE: self._set_title_font, - self.DESCRIPTION: self._set_description_font - }[font_type]() - - def _set_title_font(self): - font = pango.FontDescription('Sans 12') - font.set_weight(pango.WEIGHT_NORMAL) - self.modify_font(font) - - def _set_description_font(self): - font = pango.FontDescription('Sans 8') - font.set_weight(pango.WEIGHT_NORMAL) - self.modify_font(font) - -class Style: - - def set_title_font(self, object): - font = pango.FontDescription('Sans 20') - font.set_weight(pango.WEIGHT_NORMAL) - object.modify_font(font) - diff --git a/services/console/lib/Makefile.am b/services/console/lib/Makefile.am deleted file mode 100644 index c48a0c1a..00000000 --- a/services/console/lib/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -SUBDIRS = procmem graphics net ui - -sugardir = $(pkgdatadir)/services/console/lib -sugar_PYTHON = \ - pyxres.py - diff --git a/services/console/lib/graphics/Makefile.am b/services/console/lib/graphics/Makefile.am deleted file mode 100644 index 159f2bb0..00000000 --- a/services/console/lib/graphics/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -sugardir = $(pkgdatadir)/services/console/lib/graphics - -sugar_PYTHON = \ - __init__.py \ - box.py \ - frequency.py diff --git a/services/console/lib/graphics/__init__.py b/services/console/lib/graphics/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/services/console/lib/graphics/box.py b/services/console/lib/graphics/box.py deleted file mode 100644 index 653950cb..00000000 --- a/services/console/lib/graphics/box.py +++ /dev/null @@ -1,101 +0,0 @@ -# Copyright (C) 2007, 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 - -import gtk -import gobject -import cairo - -COLOR_MODE_NORMAL = 0 -COLOR_MODE_REVERSE = 1 - -class BoxGraphic(gtk.DrawingArea): - __gtype_name__ = 'ConsoleBoxGraphic' - - __gproperties__ = { - 'color-mode': (gobject.TYPE_INT, None, None, 0, 1, COLOR_MODE_NORMAL, - gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT_ONLY) - - } - - _color_status_high = [0, 0, 0] - _color_status_medium = [0, 0, 0] - _color_status_low = [0, 0, 0] - - _limit_high = 0 - _limit_medium = 0 - _limit_low = 0 - - def __init__(self, **kwargs): - gobject.GObject.__init__(self, **kwargs) - gtk.DrawingArea.__init__(self) - self.connect("expose-event", self.do_expose) - self.connect('size-allocate', self._change_size_cb) - - def do_expose(self, widget, event): - context = widget.window.cairo_create() - context.rectangle(0, 0, self._width, self._height) - - context.set_source_rgb (0,0,0) - context.fill_preserve() - context.stroke() - - self._draw_content(context, self._percent) - - def do_set_property(self, pspec, value): - if pspec.name == 'color-mode': - self._configure(mode=value) - else: - raise AssertionError - - def set_capacity(self, percent): - self._percent = percent - self.queue_draw() - - def _configure(self, mode): - # Normal mode configure the box as a battery - # full is good, empty is bad - if mode == COLOR_MODE_NORMAL: - self._color_status_high = [0, 1, 0] - self._color_status_medium = [1,1,0] - self._color_status_low = [1,0,0] - self._limit_high = 60 - self._limit_medium = 10 - # Reverse mode configure the box as a storage device - # full is bad, empty is good - elif mode == COLOR_MODE_REVERSE: - self._color_status_high = [1,0,0] - self._color_status_medium = [1,1,0] - self._color_status_low = [0, 1, 0] - self._limit_high = 85 - self._limit_medium = 40 - - def _draw_content(self, context, percent): - usage_height = (percent*self._height)/100 - context.rectangle(0, self._height - usage_height, self._width, self._height) - - if self._percent > self._limit_high: - context.set_source_rgb(*self._color_status_high) - elif self._percent >= self._limit_medium and self._percent <= self._limit_high: - context.set_source_rgb(*self._color_status_medium) - elif self._percent < self._limit_medium: - context.set_source_rgb(*self._color_status_low) - - context.fill_preserve() - - def _change_size_cb(self, widget, allocation): - self._width = allocation.width - self._height = allocation.height - self.queue_draw() diff --git a/services/console/lib/graphics/frequency.py b/services/console/lib/graphics/frequency.py deleted file mode 100644 index 94c55cf1..00000000 --- a/services/console/lib/graphics/frequency.py +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright (C) 2007, 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 - -import gtk - -class HorizontalGraphic(gtk.DrawingArea): - _MARGIN = 5 - _LINE_WIDTH = 2 - _GRAPH_OFFSET = 7 - _range_x = [] - _range_y = [] - _frequency_timer = 0 - - def __init__(self): - gtk.DrawingArea.__init__(self) - self._width = 0 - self._height = 0 - self._buffer = [0] - self.connect('expose-event', self.do_expose) - self.connect('size-allocate', self._change_size_cb) - - def do_expose(self, widget, event): - context = widget.window.cairo_create() - context.rectangle(0, 0, self._width - 1, self._height - 1) - context.set_source_rgb (0,0,0) - context.fill_preserve() - context.set_line_width(self._LINE_WIDTH) - - if event.area.x == 0: - draw_all = True - self._draw_border_lines(context) - context.stroke() - else: - draw_all = False - context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) - context.clip() - - context.set_source_rgb(1, 1, 1) - self._draw_buffer(event, widget, context, draw_all) - context.stroke() - - self._updated = False - return False - - def draw_value(self, percent): - redraw_all = False - - if (len(self._buffer) + 1) *self._GRAPH_OFFSET >= self._width: - redraw_all = True - self._buffer = [self._buffer[-1]] - length = 1 - else: - length = len(self._buffer) - 1 - - self._buffer.append(percent) - self._updated = True - - if redraw_all: - area_x = 0 - area_y = 0 - height = self._height - width = self._width - else: - area_x = self._graph_x + (length*self._GRAPH_OFFSET) - area_y = self._graph_y - width = self._GRAPH_OFFSET*2 - height = self._graph_height - - self.queue_draw_area(area_x, area_y, width, height) - self._frequency_timer += 1 - - return True - - def _draw_border_lines(self, context): - context.set_source_rgb(1, 1, 1) - self._draw_line(context, self._MARGIN, self._MARGIN, self._MARGIN, self._height - self._MARGIN) - self._draw_line(context, self._MARGIN, self._height - self._MARGIN - 1, self._width - self._MARGIN, self._height - self._MARGIN - 1) - - def _draw_line(self, context, from_x, from_y, to_x, to_y): - context.move_to(from_x, from_y) - context.line_to(to_x, to_y) - - def _draw_buffer(self, event, drwarea, context, draw_all=True): - buffer_offset = 0 - freq = 1 # Frequency timer - - length = len(self._buffer) - - if length == 0: - return - - # Context properties - context.set_line_width(self._LINE_WIDTH) - context.set_source_rgb(0,1,0) - - if draw_all == True: - buffer_offset = 0 - freq = 0 - else: - freq = buffer_offset = (event.area.x/self._GRAPH_OFFSET) - - for percent in self._buffer[buffer_offset:length]: - if buffer_offset == 0: - from_y = self._get_y(self._buffer[0]) - from_x = self._graph_x - else: - from_y = self._get_y(self._buffer[buffer_offset-1]) - from_x = (freq * self._GRAPH_OFFSET) - - to_x = (freq+1) * self._GRAPH_OFFSET - to_y = self._get_y(percent) - - self._draw_line(context, from_x, from_y, to_x, to_y) - buffer_offset+=1 - freq+=1 - - context.stroke() - - def _get_y(self, percent): - if percent==0: - percent = 1 - - graph_y = ((self._height)/(100 - 1))*(percent - 1) - y = self._LINE_WIDTH + abs(abs(self._height - graph_y) - self._MARGIN*2) - return int(y) - - def _change_size_cb(self, widget, allocation): - self._width = allocation.width - self._height = allocation.height - - self._graph_x = self._MARGIN + self._LINE_WIDTH - self._graph_y = self._MARGIN - self._graph_width = self._width - (self._MARGIN*2 + self._LINE_WIDTH) - self._graph_height = self._height - ((self._MARGIN*2 + self._LINE_WIDTH)) diff --git a/services/console/lib/net/Makefile.am b/services/console/lib/net/Makefile.am deleted file mode 100644 index c9d88ed5..00000000 --- a/services/console/lib/net/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -sugardir = $(pkgdatadir)/services/console/lib/net - -sugar_PYTHON = \ - __init__.py \ - device.py - diff --git a/services/console/lib/net/__init__.py b/services/console/lib/net/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/services/console/lib/net/device.py b/services/console/lib/net/device.py deleted file mode 100644 index 17b0ecc2..00000000 --- a/services/console/lib/net/device.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (C) 2007, Eduardo Silva -# -# 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 - -import socket -import fcntl -import struct -import string - -class Device: - def __init__(self): - self._dev = self.get_interfaces() - - def get_interfaces(self): - netdevfile = "/proc/net/dev" - dev = [] - - try: - infile = file(netdevfile, "r") - except: - print "Error trying " + netdevfile - - skip = 0 - for line in infile: - # Skip first two lines - skip += 1 - if skip <= 2: - continue - - iface = string.split(line, ":",1) - arr = string.split(iface[1]) - - if len(arr) < 10: - continue - - info = {'interface': iface[0].strip(), \ - 'bytes_recv': arr[0],\ - 'bytes_sent': arr[8],\ - 'packets_recv': arr[1], - 'packets_sent': arr[9]} - - dev.append(info) - return dev - - def get_iface_info(self, ifname): - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - hwaddr = [] - try: - ip = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, \ - struct.pack('256s', ifname[:15]))[20:24]) - except: - ip = None - - try: - netmask = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x891b, \ - struct.pack('256s', ifname[:15]))[20:24]) - except: - netmask = None - - try: - mac = [] - info = fcntl.ioctl(s.fileno(), 0x8927, \ - struct.pack('256s', ifname[:15])) - for char in info[18:24]: - hdigit = hex(ord(char))[2:] - if len(hdigit): - mac.append(hdigit) - except: - mac = None - - mac_string = self.mac_to_string(mac) - return [ip, netmask, mac_string] - - def mac_to_string(self, hexa): - string = '' - for value in hexa: - if len(string)==0: - string = value - else: - string += ':'+value - - return string diff --git a/services/console/lib/procmem/Makefile.am b/services/console/lib/procmem/Makefile.am deleted file mode 100644 index bdbe6d18..00000000 --- a/services/console/lib/procmem/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ - -sugardir = $(pkgdatadir)/services/console/lib/procmem - -sugar_PYTHON = \ - __init__.py \ - proc.py \ - proc_smaps.py \ - analysis.py diff --git a/services/console/lib/procmem/__init__.py b/services/console/lib/procmem/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/services/console/lib/procmem/analysis.py b/services/console/lib/procmem/analysis.py deleted file mode 100644 index e9d7aec8..00000000 --- a/services/console/lib/procmem/analysis.py +++ /dev/null @@ -1,32 +0,0 @@ -import proc, proc_smaps - -class Analysis: - - pid = 0 - - def __init__(self, pid): - self.pid = pid - - def SMaps(self): - smaps = proc_smaps.ProcSmaps(self.pid) - private_dirty = 0 - shared_dirty = 0 - referenced = 0 - - for map in smaps.mappings: - private_dirty += map.private_dirty - shared_dirty += map.shared_dirty - referenced += map.referenced - - smaps = {"private_dirty": int(private_dirty), \ - "shared_dirty": int(shared_dirty),\ - "referenced": int(referenced)} - - return smaps - - def ApproxRealMemoryUsage(self): - maps = proc_smaps.ProcMaps(self.pid) - size = (maps.clean_size/1024) - - return size - \ No newline at end of file diff --git a/services/console/lib/procmem/proc.py b/services/console/lib/procmem/proc.py deleted file mode 100644 index d50242be..00000000 --- a/services/console/lib/procmem/proc.py +++ /dev/null @@ -1,109 +0,0 @@ -import os -import re -import sys -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 - stat_data = infile.read() - infile.close() - - process_name = self._get_process_name(stat_data) - data = self._get_safe_split(stat_data) - - 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': 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 - - # Return the process name - def _get_process_name(self, data): - m = re.search("\(.*\)", data) - return m.string[m.start()+1:m.end()-1] - - def _get_safe_split(self, data): - new_data = re.sub("\(.*\)", '()', data) - return new_data.split() - - # 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 - diff --git a/services/console/lib/procmem/proc_smaps.py b/services/console/lib/procmem/proc_smaps.py deleted file mode 100644 index 422866cc..00000000 --- a/services/console/lib/procmem/proc_smaps.py +++ /dev/null @@ -1,138 +0,0 @@ -#################################################################### -# This class open the /proc/PID/maps and /proc/PID/smaps files -# to get useful information about the real memory usage -#################################################################### - -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 - # Referenced: 4 kb -> Introduced in kernel 2.6.22 - - 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]) - referenced = self.parse_smaps_size_line (lines[line_idx + 7]) - name = name.strip () - - mapping = Mapping (size, rss, shared_clean, shared_dirty, \ - private_clean, private_dirty, referenced, permissions, name) - self.mappings.append (mapping) - - num_lines -= 8 - line_idx += 8 - - self._clear_reference(pid) - - def _clear_reference(self, pid): - os.system("echo 1 > /proc/%s/clear_refs" % pid) - - # 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, referenced, 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.referenced = referenced - 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 diff --git a/services/console/lib/pyxres.py b/services/console/lib/pyxres.py deleted file mode 100644 index 91c3542e..00000000 --- a/services/console/lib/pyxres.py +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env python - -# Copyright (C) 2007, Eduardo Silva -# -# 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 ctypes import * - -# XText Property -class _XTextProperty(Structure): - pass - -_XTextProperty._fields_ = [("value", c_char_p),\ - ("encoding", c_ulong),\ - ("format", c_int),\ - ("nitems", c_ulong)] - -# XResType Structure -class _XResTypeStruct(Structure): - pass - -_XResTypeStruct._fields_ = [("resource_type", c_ulong),\ - ("count", c_uint)] - -_ATOMNAMES = ["PIXMAP",\ - "WINDOW",\ - "GC",\ - "FONT",\ - "GLYPHSET",\ - "PICTURE",\ - "COLORMAP ENTRY",\ - "PASSIVE GRAB",\ - "CURSOR",\ - "_NET_CLIENT_LIST",\ - "_NET_WM_PID",\ - "_NET_WM_NAME",\ - "UTF8_STRING",\ - "WM_NAME", # FIXME! - "CARDINAL" # FIXME! - ] - -_ATOM_PIXMAP = 0 -_ATOM_WINDOW = 1 -_ATOM_GC = 2 -_ATOM_FONT = 3 -_ATOM_GLYPHSET = 4 -_ATOM_PICTURE = 5 -_ATOM_COLORMAP_ENTRY = 6 -_ATOM_PASSIVE_GRAB = 7 -_ATOM_CURSOR = 8 -_ATOM_NET_CLIENT_LIST = 9 -_ATOM_NET_WM_PID = 10 -_ATOM_NET_WM_NAME = 11 -_ATOM_UTF8_STRING = 12 -_ATOM_WM_NAME = 13 -_ATOM_CARDINAL = 14 - -# XText Property -class _XTextProperty(Structure): - pass - -_XTextProperty._fields_ = [("value", c_char_p),\ - ("encoding", c_ulong),\ - ("format", c_int),\ - ("nitems", c_ulong)] - -class XRes(object): - _XRESLIB = "libXRes.so" - _XMULIB = "libXmu.so.6" - - def __init__(self): - self._lib = CDLL(self._XRESLIB) - self._lib_xmu = CDLL(self._XMULIB) - - def _set_atoms(self, display): - self.atoms = [] - for atom in _ATOMNAMES: - atom_value = self._lib.XInternAtom(display, atom, True) - self.atoms.append(atom_value) - - def open_display(self, display=None): - display = self._lib.XOpenDisplay(display) - self._set_atoms(display) - return display - - # Return an array with XRestTypes: - # - # XResType.resource_type (Atom_type) - # XResTyoe.count - def get_resources(self, display, resource_base): - n_types = c_long() - types = pointer(_XResTypeStruct()) - self._lib.XResQueryClientResources(display, resource_base, \ - byref(n_types), byref(types)) - - pytypes = [] - for t in types[:n_types.value]: - pytypes.append(t) - - return pytypes - - def get_windows(self, display): - self._windows = [] - root = self._lib.XDefaultRootWindow(display) - self._lookat(display, root) - return self._windows - - def _lookat(self, display, win_root): - wp = self._get_window_properties (display, win_root) - - if wp: - self._windows.append(wp) - - w = None - dummy = self._Window() - children = self._Window() - nchildren = c_uint() - - r = self._lib.XQueryTree(display, win_root, byref(dummy), \ - byref(dummy), byref(children), byref(nchildren)) - - for client in children[:nchildren.value]: - cli = self._lib_xmu.XmuClientWindow (display, client) - if client is not None: - wp = self._get_window_properties (display, cli) - if wp: - self._windows.append(wp) - - def _get_window_properties(self, display, w): - cliargv = c_char_p() - cliargc = c_long() - machtp = pointer(_XTextProperty()) - nametp = _XTextProperty() - w_name = None - - if not self._lib.XGetWMClientMachine (display, w, byref(machtp)): - machtp.value = None - machtp.encoding = None - - if not self._lib.XGetCommand(display, w, byref(cliargv), byref(cliargc)): - return - - if self._lib.XGetWMName(display, w, byref(nametp)): - w_name = nametp.value - - bytes = c_ulong() - self._lib.XResQueryClientPixmapBytes(display, w, byref(bytes)) - w_pixmaps = bytes.value - - type = self._Atom() - format = c_int() - n_items = c_ulong() - bytes_after = c_int() - w_pid = pointer(c_long()) - wname = c_char_p() - - self._lib.XGetWindowProperty(display, w,\ - self.atoms[_ATOM_NET_WM_PID], - 0, 2L,\ - False, self.atoms[_ATOM_CARDINAL],\ - byref(type), byref(format), \ - byref(n_items), byref(bytes_after), \ - byref(w_pid)) - - - # Calc aditional X resources by window - res = self.get_resources(display, w) - - n_windows = 0 - n_gcs = 0 - n_pictures = 0 - n_glyphsets = 0 - n_fonts = 0 - n_colormaps = 0 - n_passive_grabs = 0 - n_cursors = 0 - n_other = 0 - - for r in res: - if r.resource_type == self.atoms[_ATOM_WINDOW]: - n_windows += r.count - elif r.resource_type == self.atoms[_ATOM_GC]: - n_gcs += r.count - elif r.resource_type == self.atoms[_ATOM_PICTURE]: - n_pictures += r.count - elif r.resource_type == self.atoms[_ATOM_GLYPHSET]: - n_glyphsets += r.count - elif r.resource_type == self.atoms[_ATOM_FONT]: - n_fonts += r.count - elif r.resource_type == self.atoms[_ATOM_COLORMAP_ENTRY]: - n_colormaps += r.count - elif r.resource_type == self.atoms[_ATOM_PASSIVE_GRAB]: - n_passive_grabs += r.count - elif r.resource_type == self.atoms[_ATOM_CURSOR]: - n_cursors += r.count - else: - n_other += r.count - - other_bytes = n_windows * 24 - other_bytes += n_gcs * 24 - other_bytes += n_pictures * 24 - other_bytes += n_glyphsets * 24 - other_bytes += n_fonts * 1024 - other_bytes += n_colormaps * 24 - other_bytes += n_passive_grabs * 24 - other_bytes += n_cursors * 24 - other_bytes += n_other * 24 - - window = Window(w, w_pid.contents.value, w_pixmaps, \ - n_windows, n_gcs, n_fonts, n_glyphsets, n_pictures,\ - n_colormaps, n_passive_grabs, n_cursors, n_other,\ - other_bytes, w_name) - - return window - - # Data types - def _Window(self): - return pointer(c_ulong()) - - def _Atom(self, data=0): - return pointer(c_ulong(data)) - -class Window(object): - def __init__(self, resource_base, pid, pixmap_bytes=0,\ - n_windows=0, n_gcs=0, n_fonts=0, n_glyphsets=0, n_pictures=0,\ - n_colormaps=0, n_passive_grabs=0, n_cursors=0, n_other=0,\ - other_bytes=0, wm_name=None): - - self.resource_base = resource_base - self.pid = pid - self.pixmap_bytes = pixmap_bytes - - self.n_windows = n_windows - self.n_gcs = n_gcs - self.n_fonts = n_fonts - self.n_glyphsets = n_glyphsets - self.n_pictures = n_pictures - self.n_colormaps = n_colormaps - self.n_passive_grabs = n_passive_grabs - self.n_cursors = n_cursors - self.n_other = n_other - - self.other_bytes = other_bytes - self.wm_name = wm_name diff --git a/services/console/lib/ui/Makefile.am b/services/console/lib/ui/Makefile.am deleted file mode 100644 index a75f7a1a..00000000 --- a/services/console/lib/ui/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -sugardir = $(pkgdatadir)/services/console/lib/ui - -sugar_PYTHON = \ - __init__.py \ - treeview.py diff --git a/services/console/lib/ui/__init__.py b/services/console/lib/ui/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/services/console/lib/ui/treeview.py b/services/console/lib/ui/treeview.py deleted file mode 100644 index 5f5dc968..00000000 --- a/services/console/lib/ui/treeview.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (C) 2007, Eduardo Silva -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import gtk - -class TreeView(gtk.ScrolledWindow): - iters = [] # Iters index - - # Create a window with a treeview object - # - # cols = List of dicts, ex: - # - # cols = [] - # cols.append({'index': integer_index_position, 'name': string_col_name}) - def __init__(self, cols_def, cols_name): - gtk.ScrolledWindow.__init__(self) - - self._iters = [] - self._treeview = gtk.TreeView() - - # Creating column data types - self._store = gtk.TreeStore(*cols_def) - - # Columns definition - cell = gtk.CellRendererText() - tv_cols = [] - - i=0 - for col in cols_name: - col_tv = gtk.TreeViewColumn(col['name'], cell, text=i) - col_tv.set_reorderable(True) - col_tv.set_resizable(True) - tv_cols.append(col_tv) - i+=1 - - # Setting treeview properties - self._treeview.set_model(self._store) - self._treeview.set_enable_search(True) - self._treeview.set_rules_hint(True) - - for col in tv_cols: - self._treeview.append_column(col) - self.add(self._treeview) - - def add_row(self, cols_data): - iter = self._store.insert_after(None, None) - for col in cols_data: - print col['index'],col['info'] - self._store.set_value(iter, int(col['index']) , col['info']) - - self.iters.append(iter) - return iter - - def update_row(self, iter, cols_data): - for col in cols_data: - self._store.set_value(iter, int(col['index']) , str(col['info'])) - - def remove_row(self, iter): - self._store.remove(iter) diff --git a/services/console/org.laptop.sugar.Console.service.in b/services/console/org.laptop.sugar.Console.service.in deleted file mode 100644 index 48206709..00000000 --- a/services/console/org.laptop.sugar.Console.service.in +++ /dev/null @@ -1,4 +0,0 @@ -[D-BUS Service] -Name = org.laptop.sugar.Console -Exec = @bindir@/sugar-console - diff --git a/services/console/sugar-console b/services/console/sugar-console deleted file mode 100755 index 357b7fee..00000000 --- a/services/console/sugar-console +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python - -import pygtk -pygtk.require('2.0') - -import os -import sys -from sugar import env -from sugar import util - -sys.path.append(env.get_service_path('console')) - -# change to the user's home directory if it is set -# root if not -os.chdir(os.environ.get('HOME', '/')) - -#set the process title so it shows up as sugar-console not python -util.set_proc_title('sugar-console') - -import console diff --git a/shell/view/keyhandler.py b/shell/view/keyhandler.py index 9fddee32..768b6c30 100644 --- a/shell/view/keyhandler.py +++ b/shell/view/keyhandler.py @@ -45,8 +45,6 @@ _actions_table = { 'F11' : 'volume_min', 'F12' : 'volume_max', '1' : 'screenshot', - 'equal' : 'console', - '0' : 'console', 'f' : 'frame', '0x93' : 'frame', 'o' : 'overlay', @@ -156,9 +154,6 @@ class KeyHandler(object): def handle_screenshot(self): self._shell.take_screenshot() - def handle_console(self): - gobject.idle_add(self._toggle_console_visibility_cb) - def handle_frame(self): self._shell.get_frame().notify_key_press() @@ -222,10 +217,3 @@ class KeyHandler(object): return True return False - - def _toggle_console_visibility_cb(self): - bus = dbus.SessionBus() - proxy = bus.get_object('org.laptop.sugar.Console', - '/org/laptop/sugar/Console') - console = dbus.Interface(proxy, 'org.laptop.sugar.Console') - console.ToggleVisibility()