Gonzalo Odiard | 1 May 2010 06:05
Picon

Re: Keyboard navigability of the Sugar UI

I would like to work with 0.84 and port to 0.90.
I have read your bug #1969 and contacted a blind programmer to check the selected keys.
We can write in the wiki a plan and work together with small patches.

Gonzalo


On Fri, Apr 30, 2010 at 5:08 PM, Bernie Innocenti <bernie <at> codewiz.org> wrote:
El Wed, 28-04-2010 a las 17:14 +0200, Tomeu Vizoso escribió:
> On Tue, Apr 27, 2010 at 16:25, Bernie Innocenti <bernie <at> codewiz.org> wrote:
> > Today I filed a bug to keep track of an issue that has been bothering me
> > for a long time:
>
> There's interest from the people at La Rioja on this, how can we agree
> on a plan together and resource it?
>
> http://lists.laptop.org/pipermail/olpc-sur/2010-April/005849.html


Very good, indeed!

Gonzalo, would you and your team like to take over this task for the
0.90 release cycle?

In case you missed the original post of this thread:

--------- Mensaje reenviado --------
De: Bernie Innocenti <bernie <at> codewiz.org>
Para: Sugar Devel <sugar-devel <at> lists.sugarlabs.org>
Cc: Christian Marc Schmidt <christianmarc <at> gmail.com>, Eben Eliason <eben.eliason <at> gmail.com>
Asunto: [Sugar-devel] Keyboard navigability of the Sugar UI
Fecha: Tue, 27 Apr 2010 10:25:16 -0400

Today I filed a bug to keep track of an issue that has been bothering me
for a long time:

 http://bugs.sugarlabs.org/ticket/1969

Being an important UI issue, we'd need a good discussion with the design
team. Unfortunately, we cannot always follow existing Gnome conventions
for keyboard shortcuts. For example, rename cannot be done with F2
because it's already used for the buddy view.

-----8<----------8<----------8<----------8<----------8<-----

The Sugar UI should be 100% navigable without using a mouse.

Besides being an accessibility issue, it's important for quick
navigation, especially for users stuck with a broken XO touchpads.

Some proposed changes:

 * Favorites view
  * Search should be enabled in the shell view
  * A caret should appear when the user starts to type
  * Non-matching activities should be grayed out
  * TAB should cycle through possible completions
  * Cursor keys should cycle through the icons

 * Journal
  * Cursor up/down should scroll a caret on the list
  * ENTER should open the selected item (Linux/Windows style)
  * Rename item: TBD (just type something?)
  * Go to proprieties: TBD (cursor right?)
  * Change volume: TBD
  * Unmount all hot pluggable devices: TBD

 * Activities list view
  * Should behave like the journal

 * Network Neighborhood
  * Similar to favorites view

 * Toolbars
  * There should be a key to move the focus to the toolbars
    (alt-space?)

--
  // Bernie Innocenti - http://codewiz.org/
 \X/  Sugar Labs       - http://sugarlabs.org/




--
Gonzalo Odiard
Responsable de Desarrollo
Sistemas Australes

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Bernie Innocenti | 1 May 2010 08:56
Favicon
Gravatar

Re: Keyboard navigability of the Sugar UI

El Sat, 01-05-2010 a las 01:05 -0300, Gonzalo Odiard escribió:
> I would like to work with 0.84 and port to 0.90.

At Paraguay Educa we've been also focusing a lot on 0.84 lately.

However, I'm starting to worry the history will repeat once again: many
deployments have been patching 0.82 with fixes and new features that
were never upstreamed, making the transition to 0.84 much more painful
that it would have been otherwise.

Now we're trying to minimize the gap between development versions of
Sugar and what deployments ship. The good news is that there should be
pretty good activity compatibility across 0.84, 0.86 and 0.88.

In Paraguay we're about to start a new development cycle to rebase the
Fedora 11 builds on Sugar 0.88. Much of the stabilization effort of the
0.84 cycle actually went into the OS and activities, so I'm quite
optimist.

> I have read your bug #1969 and contacted a blind programmer to check
> the selected keys. We can write in the wiki a plan and work together
> with small patches.

Great! Small patches have a higher potential to apply cleanly to both
0.84 and 0.90.

--

-- 
   // Bernie Innocenti - http://codewiz.org/
 \X/  Sugar Labs       - http://sugarlabs.org/

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Sascha Silbe | 1 May 2010 14:55

[PATCH] battery frame device: replace HAL with UPower

HAL is deprecated, UPower is the designated replacement w.r.t. power
supplies. As a bonus the time displayed is now correct (calculated at
run-time by UPower, self-adjusting to changes in power consumption).

Tested on XO-1 running Debian Squeeze with stock UPower (0.9.2-1) and kernel
patches that are in the process of getting included upstream (i.e. at OLPC).
---
 extensions/deviceicon/battery.py |  219 +++++++++++++++++++------------------
 1 files changed, 112 insertions(+), 107 deletions(-)

diff --git a/extensions/deviceicon/battery.py b/extensions/deviceicon/battery.py
index edfcce4..ee4ad55 100644
--- a/extensions/deviceicon/battery.py
+++ b/extensions/deviceicon/battery.py
 <at>  <at>  -16,8 +16,9  <at>  <at> 

 import logging
 from gettext import gettext as _
-import gconf
+import sys

+import gconf
 import gobject
 import gtk
 import dbus
 <at>  <at>  -30,6 +31,7  <at>  <at>  from sugar.graphics.xocolor import XoColor

 from jarabe.frame.frameinvoker import FrameWidgetInvoker

+
 _ICON_NAME = 'battery'

 _STATUS_CHARGING = 0
 <at>  <at>  -37,34 +39,35  <at>  <at>  _STATUS_DISCHARGING = 1
 _STATUS_FULLY_CHARGED = 2
 _STATUS_NOT_PRESENT = 3

-_LEVEL_PROP = 'battery.charge_level.percentage'
-_CHARGING_PROP = 'battery.rechargeable.is_charging'
-_DISCHARGING_PROP = 'battery.rechargeable.is_discharging'
-_PRESENT_PROP = 'battery.present'
+_UP_TYPE_BATTERY = 2
+
+_UP_STATE_UNKNOWN = 0
+_UP_STATE_CHARGING = 1
+_UP_STATE_DISCHARGING = 2
+_UP_STATE_EMPTY = 3
+_UP_STATE_FULL = 4
+_UP_STATE_CHARGE_PENDING = 5
+_UP_STATE_DISCHARGE_PENDING = 6
+
+_WARN_MIN_PERCENTAGE = 15
+

 class DeviceView(TrayIcon):

     FRAME_POSITION_RELATIVE = 102

-    def __init__(self, udi):
-        client = gconf.client_get_default()        
+    def __init__(self, battery):
+        client = gconf.client_get_default()
         self._color = XoColor(client.get_string('/desktop/sugar/user/color'))

         TrayIcon.__init__(self, icon_name=_ICON_NAME, xo_color=self._color)

         self.set_palette_invoker(FrameWidgetInvoker(self))

-        self._model = DeviceModel(udi)
+        self._model = DeviceModel(battery)
         self.palette = BatteryPalette(_('My Battery'))
         self.palette.set_group_id('frame')
-
-        self._model.connect('notify::level',
-                            self._battery_status_changed_cb)
-        self._model.connect('notify::charging',
-                            self._battery_status_changed_cb)
-        self._model.connect('notify::discharging',
-                            self._battery_status_changed_cb)
-        self._model.connect('notify::present',
+        self._model.connect('updated',
                             self._battery_status_changed_cb)
         self._update_info()

 <at>  <at>  -86,27 +89,30  <at>  <at>  class DeviceView(TrayIcon):
                                           style.COLOR_WHITE.get_svg()))
         elif self._model.props.discharging:
             status = _STATUS_DISCHARGING
-            if current_level <= 15:
+            if current_level <= _WARN_MIN_PERCENTAGE:
                 badge_name = 'emblem-warning'
         else:
             status = _STATUS_FULLY_CHARGED

-        self.icon.props.icon_name = get_icon_state(name, current_level, step=-5)
+        self.icon.props.icon_name = get_icon_state(name, current_level,
+            step=-5)
         self.icon.props.xo_color = xo_color
         self.icon.props.badge_name = badge_name

-        self.palette.set_level(current_level)
-        self.palette.set_status(status)
+        self.palette.set_info(current_level, self._model.props.time_remaining,
+            status)

-    def _battery_status_changed_cb(self, pspec, param):
+    def _battery_status_changed_cb(self, *args):
         self._update_info()

+
 class BatteryPalette(Palette):

     def __init__(self, primary_text):
         Palette.__init__(self, primary_text)
-            
         self._level = 0
+        self._time = 0
+        self._status = _STATUS_NOT_PRESENT
         self._progress_bar = gtk.ProgressBar()
         self._progress_bar.set_size_request(
             style.zoom(style.GRID_CELL_SIZE * 4), -1)
 <at>  <at>  -122,29 +128,29  <at>  <at>  class BatteryPalette(Palette):
         self._progress_widget = vbox
         self.set_content(self._progress_widget)

-    def set_level(self, percent):
+    def set_info(self, percent, seconds, status):
         self._level = percent
-        fraction = percent / 100.0
-        self._progress_bar.set_fraction(fraction)
+        self._time = seconds
+        self._status = status
+        self._progress_bar.set_fraction(percent / 100.0)
+        self._update_secondary()

-    def set_status(self, status):
-        current_level = self._level
+    def _update_secondary(self):
         secondary_text = ''
-        status_text = '%s%%' % current_level
+        status_text = '%s%%' % self._level

         progress_widget = self._progress_widget
-        if status == _STATUS_NOT_PRESENT:
+        if self._status == _STATUS_NOT_PRESENT:
             secondary_text = _('Removed')
             progress_widget = None
-        elif status == _STATUS_CHARGING:
+        elif self._status == _STATUS_CHARGING:
             secondary_text = _('Charging')
-        elif status == _STATUS_DISCHARGING:
-            if current_level <= 15:
+        elif self._status == _STATUS_DISCHARGING:
+            if self._level <= _WARN_MIN_PERCENTAGE:
                 secondary_text = _('Very little power remaining')
             else:
-                #TODO: make this less of an wild/educated guess
-                minutes_remaining = int(current_level / 0.59)
-                remaining_hourpart = minutes_remaining / 60
+                minutes_remaining = self._time // 60
+                remaining_hourpart = minutes_remaining // 60
                 remaining_minpart = minutes_remaining % 60
                 secondary_text = _('%(hour)d:%(min).2d remaining') % \
                         {'hour': remaining_hourpart, 'min': remaining_minpart}
 <at>  <at>  -155,97 +161,96  <at>  <at>  class BatteryPalette(Palette):
         self.props.secondary_text = secondary_text
         self._status_label.set_text(status_text)

+
 class DeviceModel(gobject.GObject):
     __gproperties__ = {
-        'level'       : (int, None, None, 0, 100, 0,
-                         gobject.PARAM_READABLE),
-        'charging'    : (bool, None, None, False,
-                         gobject.PARAM_READABLE),
-        'discharging' : (bool, None, None, False,
-                         gobject.PARAM_READABLE),
-        'present'     : (bool, None, None, False,
-                         gobject.PARAM_READABLE)
+        'level': (int, None, None, 0, 100, 0, gobject.PARAM_READABLE),
+        'time-remaining': (int, None, None, 0, sys.maxint, 0,
+            gobject.PARAM_READABLE),  # unit: seconds
+        'charging': (bool, None, None, False, gobject.PARAM_READABLE),
+        'discharging': (bool, None, None, False, gobject.PARAM_READABLE),
+        'present': (bool, None, None, False, gobject.PARAM_READABLE),
     }

-    def __init__(self, udi):
-        gobject.GObject.__init__(self)
-        
-        bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
-        proxy = bus.get_object('org.freedesktop.Hal', udi,
-                               follow_name_owner_changes=True)
-        self._battery = dbus.Interface(proxy, 'org.freedesktop.Hal.Device')
-        bus.add_signal_receiver(self._battery_changed,
-                                'PropertyModified',
-                                'org.freedesktop.Hal.Device',
-                                'org.freedesktop.Hal',
-                                udi)
-
-        self._level = self._get_level()
-        self._charging = self._get_charging()
-        self._discharging = self._get_discharging()
-        self._present = self._get_present()
-
-    def _get_level(self):
-        try:
-            return self._battery.GetProperty(_LEVEL_PROP)
-        except dbus.DBusException:
-            logging.error('Cannot access %s', _LEVEL_PROP)
-            return 0
-
-    def _get_charging(self):
-        try:
-            return self._battery.GetProperty(_CHARGING_PROP)
-        except dbus.DBusException:
-            logging.error('Cannot access %s', _CHARGING_PROP)
-            return False
+    __gsignals__ = {
+        'updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+    }

-    def _get_discharging(self):
+    def __init__(self, battery):
+        gobject.GObject.__init__(self)
+        self._battery = battery
+        self._battery_props_iface = dbus.Interface(self._battery,
+            'org.freedesktop.DBus.Properties')
+        self._battery.connect_to_signal('Changed', self._battery_changed,
+            dbus_interface='org.freedesktop.UPower.Device')
+        self._fetch()
+
+    def _fetch(self):
+        """Get current values from UPower."""
+        # pylint: disable-msg=W0201
         try:
-            return self._battery.GetProperty(_DISCHARGING_PROP)
+            dbus_props = self._battery_props_iface.GetAll(
+                'org.freedesktop.UPower.Device')
         except dbus.DBusException:
-            logging.error('Cannot access %s', _DISCHARGING_PROP)
-            return False
+            logging.error('Cannot access battery properties')
+            dbus_props = {}

-    def _get_present(self):
-        try:
-            return self._battery.GetProperty(_PRESENT_PROP)
-        except dbus.DBusException:
-            logging.error('Cannot access %s', _PRESENT_PROP)
-            return False
+        self._level = dbus_props.get('Percentage', 0)
+        self._state = dbus_props.get('State', _UP_STATE_UNKNOWN)
+        self._present = dbus_props.get('IsPresent', False)
+        self._time_to_empty = dbus_props.get('TimeToEmpty', 0)
+        self._time_to_full = dbus_props.get('TimeToFull', 0)

     def do_get_property(self, pspec):
+        """Return current value of given GObject property."""
         if pspec.name == 'level':
-            return self._level 
+            return self._level
         if pspec.name == 'charging':
-            return self._charging
+            return self._state == _UP_STATE_CHARGING
         if pspec.name == 'discharging':
-            return self._discharging
+            return self._state == _UP_STATE_DISCHARGING
         if pspec.name == 'present':
             return self._present
+        if pspec.name == 'time-remaining':
+            if self._state == _UP_STATE_CHARGING:
+                return self._time_to_full
+            if self._state == _UP_STATE_DISCHARGING:
+                return self._time_to_empty
+            return 0

     def get_type(self):
         return 'battery'

-    def _battery_changed(self, num_changes, changes_list):
-        for change in changes_list:
-            if change[0] == _LEVEL_PROP:
-                self._level = self._get_level()
-                self.notify('level')
-            elif change[0] == _CHARGING_PROP:
-                self._charging = self._get_charging()
-                self.notify('charging')
-            elif change[0] == _DISCHARGING_PROP:
-                self._discharging = self._get_discharging()
-                self.notify('discharging')
-            elif change[0] == _PRESENT_PROP:
-                self._present = self._get_present()
-                self.notify('present')
+    def _battery_changed(self, *args):
+        old_level = self._level
+        old_state = self._state
+        old_present = self._present
+        old_time = self.props.time_remaining
+        self._fetch()
+        if self._level != old_level:
+            self.notify('level')
+        if self._state != old_state:
+            self.notify('charging')
+            self.notify('discharging')
+        if self._present != old_present:
+            self.notify('present')
+        if self.props.time_remaining != old_time:
+            self.notify('time-remaining')
+
+        self.emit('updated')
+

 def setup(tray):
     bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
-    proxy = bus.get_object('org.freedesktop.Hal',
-                            '/org/freedesktop/Hal/Manager')
-    hal_manager = dbus.Interface(proxy, 'org.freedesktop.Hal.Manager')
-
-    for udi in hal_manager.FindDeviceByCapability('battery'):
-        tray.add_device(DeviceView(udi))
+    up_proxy = bus.get_object('org.freedesktop.UPower',
+                            '/org/freedesktop/UPower')
+    upower = dbus.Interface(up_proxy, 'org.freedesktop.UPower')
+
+    for battery_path in upower.EnumerateDevices():
+        battery = bus.get_object('org.freedesktop.UPower', battery_path)
+        batt_prop_iface = dbus.Interface(battery,
+            'org.freedesktop.DBus.Properties')
+        device_type = batt_prop_iface.Get('org.freedesktop.UPower.Device',
+            'Type')
+        if device_type == _UP_TYPE_BATTERY:
+            tray.add_device(DeviceView(battery))
--

-- 
1.7.0
Andrés Ambrois | 1 May 2010 20:52
Picon

[RFC PATCH v0 0/2] Add ctime and filesize properties to the datastore.

This is in preparation of the Journal work implementing sorting of entries by
these properties.

v0: Initial submission to sugar-devel

Andrés Ambrois (2):
  Add ctime and timestamp properties to the index.
  Add migration from DS v0 code for the new properties.

 src/carquinyol/datastore.py  |   22 ++++++++++++++++++++--
 src/carquinyol/indexstore.py |   17 +++++++++++++++++
 src/carquinyol/migration.py  |   12 +++++++++++-
 3 files changed, 48 insertions(+), 3 deletions(-)

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Andrés Ambrois | 1 May 2010 20:52
Picon

[RFC PATCH 1/2] Add ctime and timestamp properties to the index.


Signed-off-by: Andrés Ambrois <andresambrois <at> gmail.com>
---
 src/carquinyol/datastore.py  |   22 ++++++++++++++++++++--
 src/carquinyol/indexstore.py |   17 +++++++++++++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/src/carquinyol/datastore.py b/src/carquinyol/datastore.py
index a556869..9f0be96 100644
--- a/src/carquinyol/datastore.py
+++ b/src/carquinyol/datastore.py
 <at>  <at>  -154,8 +154,17  <at>  <at>  class DataStore(dbus.service.Object):
         uid = str(uuid.uuid4())
         logging.debug('datastore.create %r', uid)

+        ctime = int(time.time())
         if not props.get('timestamp', ''):
-            props['timestamp'] = int(time.time())
+            props['timestamp'] = ctime
+        if not props.get('ctime', ''):
+            props['ctime'] = ctime
+
+        if os.path.exists(file_path):
+            stat = os.stat(file_path)
+            props['filesize'] = stat.st_size
+        else:
+            props['filesize'] = 0

         self._metadata_store.store(uid, props)
         self._index_store.store(uid, props)
 <at>  <at>  -190,8 +199,17  <at>  <at>  class DataStore(dbus.service.Object):
                async_cb, async_err_cb):
         logging.debug('datastore.update %r', uid)

+        timestamp = int(time.time())
+        if not props.get('ctime', ''):
+            props['ctime'] = props.get('timestamp', timestamp)
         if not props.get('timestamp', ''):
-            props['timestamp'] = int(time.time())
+            props['timestamp'] = timestamp
+
+        if os.path.exists(file_path):
+            stat = os.stat(file_path)
+            props['filesize'] = stat.st_size
+        else:
+            props['filesize'] = 0

         self._metadata_store.store(uid, props)
         self._index_store.store(uid, props)
diff --git a/src/carquinyol/indexstore.py b/src/carquinyol/indexstore.py
index 8a69334..49b6c09 100644
--- a/src/carquinyol/indexstore.py
+++ b/src/carquinyol/indexstore.py
 <at>  <at>  -28,6 +28,9  <at>  <at>  from carquinyol.layoutmanager import MAX_QUERY_LIMIT
 _VALUE_UID = 0
 _VALUE_TIMESTAMP = 1
 _VALUE_TITLE = 2
+# 3 reserved for version support
+_VALUE_FILESIZE = 4
+_VALUE_CTIME = 5

 _PREFIX_NONE = 'N'
 _PREFIX_FULL_VALUE = 'F'
 <at>  <at>  -57,6 +60,8  <at>  <at>  _QUERY_TERM_MAP = {

 _QUERY_VALUE_MAP = {
     'timestamp': {'number': _VALUE_TIMESTAMP, 'type': float},
+    'filesize': {'number': _VALUE_FILESIZE, 'type': int},
+    'ctime': {'number': _VALUE_CTIME, 'type': int},
 }

 
 <at>  <at>  -66,6 +71,10  <at>  <at>  class TermGenerator (xapian.TermGenerator):
         document.add_value(_VALUE_TIMESTAMP,
             xapian.sortable_serialise(float(properties['timestamp'])))
         document.add_value(_VALUE_TITLE, properties.get('title', '').strip())
+        document.add_value(_VALUE_FILESIZE,
+            xapian.sortable_serialise(int(properties['filesize'])))
+        document.add_value(_VALUE_CTIME,
+            xapian.sortable_serialise(int(properties['ctime'])))

         self.set_document(document)

 <at>  <at>  -280,10 +289,18  <at>  <at>  class IndexStore(object):
             enquire.set_sort_by_value(_VALUE_TIMESTAMP, True)
         elif order_by == '-timestamp':
             enquire.set_sort_by_value(_VALUE_TIMESTAMP, False)
+        elif order_by == '+ctime':
+            enquire.set_sort_by_value(_VALUE_CTIME, True)
+        elif order_by == '-ctime':
+            enquire.set_sort_by_value(_VALUE_CTIME, False)
         elif order_by == '+title':
             enquire.set_sort_by_value(_VALUE_TITLE, True)
         elif order_by == '-title':
             enquire.set_sort_by_value(_VALUE_TITLE, False)
+        elif order_by == '+filesize':
+            enquire.set_sort_by_value(_VALUE_FILESIZE, True)
+        elif order_by == '-filesize':
+            enquire.set_sort_by_value(_VALUE_FILESIZE, False)
         else:
             logging.warning('Unsupported property for sorting: %s', order_by)

--

-- 
1.6.3.3

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Andrés Ambrois | 1 May 2010 20:52
Picon

[RFC PATCH 2/2] Implement migration for the two new properties (filesize and ctime). Increment CURRENT_LAYOUT_VERSION.


Signed-off-by: Andrés Ambrois <andresambrois <at> gmail.com>
---
 src/carquinyol/layoutmanager.py |    2 +-
 src/carquinyol/migration.py     |   21 +++++++++++++++++----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/carquinyol/layoutmanager.py b/src/carquinyol/layoutmanager.py
index 8402b6d..aee5efb 100644
--- a/src/carquinyol/layoutmanager.py
+++ b/src/carquinyol/layoutmanager.py
 <at>  <at>  -18,7 +18,7  <at>  <at>  import os
 import logging

 MAX_QUERY_LIMIT = 40960
-CURRENT_LAYOUT_VERSION = 4
+CURRENT_LAYOUT_VERSION = 5

 class LayoutManager(object):
     """Provide the logic about how entries are stored inside the datastore
diff --git a/src/carquinyol/migration.py b/src/carquinyol/migration.py
index 95ee391..36c7d57 100644
--- a/src/carquinyol/migration.py
+++ b/src/carquinyol/migration.py
 <at>  <at>  -45,8 +45,8  <at>  <at>  def migrate_from_0():

         logging.debug('Migrating entry %r', uid)
         try:
-            _migrate_metadata(root_path, old_root_path, uid)
             _migrate_file(root_path, old_root_path, uid)
+            _migrate_metadata(root_path, old_root_path, uid)
             _migrate_preview(root_path, old_root_path, uid)
         except Exception:
             logging.exception('Error while migrating entry %r', uid)
 <at>  <at>  -69,9 +69,22  <at>  <at>  def _migrate_metadata(root_path, old_root_path, uid):
     if 'uid' not in metadata:
         metadata['uid'] = uid

-    if 'timestamp' not in metadata and 'mtime' in metadata:
-        metadata['timestamp'] = \
-                time.mktime(time.strptime(metadata['mtime'], DATE_FORMAT))
+    if 'timestamp' not in metadata:
+        if 'mtime' in metadata:
+            metadata['timestamp'] = \
+                    time.mktime(time.strptime(metadata['mtime'], DATE_FORMAT))
+        else:
+            metadata['timestamp'] = int(os.stat(old_metadata_path).st_mtime)
+
+    if 'ctime' not in metadata:
+        metadata['ctime'] = int(os.stat(old_metadata_path).st_ctime)
+
+    file_path = layoutmanager.get_instance().get_data_path(uid)
+    if 'filesize' not in metadata:
+        if os.path.exists(file_path):
+            metadata['filesize'] = int(os.stat(file_path).st_size)
+        else:
+            metadata['filesize'] = 0

     for key, value in metadata.items():
         try:
--

-- 
1.6.3.3

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Andrés Ambrois | 1 May 2010 20:52
Picon

[RFC PATCH 2/2] Add migration from DS v0 code for the new properties.


Signed-off-by: Andrés Ambrois <andresambrois <at> gmail.com>
---
 src/carquinyol/migration.py |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/src/carquinyol/migration.py b/src/carquinyol/migration.py
index 95ee391..80adbae 100644
--- a/src/carquinyol/migration.py
+++ b/src/carquinyol/migration.py
 <at>  <at>  -45,8 +45,8  <at>  <at>  def migrate_from_0():

         logging.debug('Migrating entry %r', uid)
         try:
-            _migrate_metadata(root_path, old_root_path, uid)
             _migrate_file(root_path, old_root_path, uid)
+            _migrate_metadata(root_path, old_root_path, uid)
             _migrate_preview(root_path, old_root_path, uid)
         except Exception:
             logging.exception('Error while migrating entry %r', uid)
 <at>  <at>  -73,6 +73,16  <at>  <at>  def _migrate_metadata(root_path, old_root_path, uid):
         metadata['timestamp'] = \
                 time.mktime(time.strptime(metadata['mtime'], DATE_FORMAT))

+    if 'ctime' not in metadata:
+        metadata['ctime'] = int(os.stat(old_metadata_path).st_ctime)
+
+    file_path = layoutmanager.get_instance().get_data_path(uid)
+    if 'filesize' not in metadata:
+        if os.path.exists(file_path):
+            metadata['filesize'] = int(os.stat(file_path).st_size)
+        else:
+            metadata['filesize'] = 0
+
     for key, value in metadata.items():
         try:
             f = open(os.path.join(metadata_path, key), 'w')
--

-- 
1.6.3.3

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Andrés Ambrois | 1 May 2010 21:00
Picon

Re: [RFC PATCH 2/2] Implement migration for the two new properties (filesize and ctime). Increment CURRENT_LAYOUT_VERSION.

On Saturday 01 May 2010 03:52:46 pm Andrés Ambrois wrote:
> 
> Signed-off-by: Andrés Ambrois <andresambrois <at> gmail.com>
> ---
>  src/carquinyol/layoutmanager.py |    2 +-
>  src/carquinyol/migration.py     |   21 +++++++++++++++++----
>  2 files changed, 18 insertions(+), 5 deletions(-)

Sigh. Disregard this one. Seems I split this one in two but forgot to delete 
it from the patches directory....

--

-- 
  -Andrés
_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Andrés Ambrois | 1 May 2010 21:05
Picon

[RFC PATCH] Increment CURRENT_LAYOUT_VERSION to trigger an index rebuild.

This one was suppoused to be in the previous series. I will resend the whole
patchset once review is complete.

Signed-off-by: Andrés Ambrois <andresambrois <at> gmail.com>
---
 src/carquinyol/layoutmanager.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/carquinyol/layoutmanager.py b/src/carquinyol/layoutmanager.py
index 8402b6d..aee5efb 100644
--- a/src/carquinyol/layoutmanager.py
+++ b/src/carquinyol/layoutmanager.py
 <at>  <at>  -18,7 +18,7  <at>  <at>  import os
 import logging

 MAX_QUERY_LIMIT = 40960
-CURRENT_LAYOUT_VERSION = 4
+CURRENT_LAYOUT_VERSION = 5

 class LayoutManager(object):
     """Provide the logic about how entries are stored inside the datastore
--

-- 
1.6.3.3

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel
Andrés Ambrois | 1 May 2010 21:33
Picon

[RFC PATCH v0 0/8] Journal sorting by file size and creation time.

This patchset implements sorting in the Journal UI as described in [0]. 

This feature was requested in [1] and sponsored by Activity Central [2].

Sorting by filesize is vital in the field where users need to free up disk
space. Currently, the only way to find candidates for deletion is to access
the expanded view of each entry, one by one. This can be a very time consuming
process and often leads to indiscriminate deletion and thus potential loss of
valuable data. This is bad.

Sorting by creation time (ctime) is also implemented as described in the Design
Proposal.

This implementation currently lacks two aspects which I hope will be sorted out
in the review process:

1- The proposal does not include a specification for changing the order of the
sort. This patch assumes an ascending order.

2- There are no icons for the sorting criteria. Or at least I couldn't find the
ones presented in the proposal. I'm sure someone from the design team could
vectorize the ones there.

v0: Initial submission to sugar-devel

[0] http://wiki.sugarlabs.org/go/Design_Team/Proposals/Journal#Extended_list_view_palette
[1] http://bugs.sugarlabs.org/ticket/1915
[2] http://activitycentral.org

Andrés Ambrois (8):
  Journal: Retrieve ctime and filesize from the datastore.
  Add ctime and filesize columns to the journal list model.
  Add add_separator method for convenience.
  Add a ListViewButton to the journal search toolbar.
  Rename the date column to 'sort_column'
  Add sort_by method to the journal list view.
  Call sort_by in the list view when sorting is selected in the
    toolbar.
  Expandedentry: Try to use the filesize property.

 src/jarabe/journal/expandedentry.py   |    5 +-
 src/jarabe/journal/journalactivity.py |    5 ++
 src/jarabe/journal/journaltoolbox.py  |   75 ++++++++++++++++++++++++++++++++-
 src/jarabe/journal/listmodel.py       |   22 +++++++---
 src/jarabe/journal/listview.py        |   34 ++++++++++-----
 src/jarabe/journal/model.py           |    6 +-
 6 files changed, 124 insertions(+), 23 deletions(-)

_______________________________________________
Sugar-devel mailing list
Sugar-devel <at> lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel

Gmane