[Sugar-devel] [RFC PATCH 8/8] Expandedentry: Try to use the filesize property.

2010-05-01 Thread Andrés Ambrois
Instead of calling the datastore again.

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/expandedentry.py |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/jarabe/journal/expandedentry.py 
b/src/jarabe/journal/expandedentry.py
index c8e40c1..ffb6a63 100644
--- a/src/jarabe/journal/expandedentry.py
+++ b/src/jarabe/journal/expandedentry.py
@@ -260,8 +260,9 @@ class ExpandedEntry(hippo.CanvasBox):
 lines = [
 _('Kind: %s') % (self._metadata.get('mime_type') or _('Unknown'),),
 _('Date: %s') % (self._format_date(),),
-_('Size: %s') % (format_size(model.get_file_size(
-self._metadata['uid'])),)]
+_('Size: %s') % (format_size(int(self._metadata.get('filesize')) or
+model.get_file_size(self._metadata['uid'])),),
+]
 
 for line in lines:
 text = hippo.CanvasText(text=line,
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [RFC PATCH 6/8] Add sort_by method to the journal list view.

2010-05-01 Thread Andrés Ambrois
This method triggers the actual sorting. This is done by placing a 'order_by'
value in the query, and calling the datastore to retrieve the sorted data set.
The sort_column is also modified to display the property we are sorting by.

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/listview.py |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
index 375a8ee..ad0390a 100644
--- a/src/jarabe/journal/listview.py
+++ b/src/jarabe/journal/listview.py
@@ -250,6 +250,18 @@ class BaseListView(gtk.Bin):
 metadata['keep'] = '1'
 model.write(metadata, update_mtime=False)
 
+def sort_by(self, property, order):
+cell_text = self.sort_column.get_cell_renderers()[0]
+self.sort_column.set_attributes(cell_text,
+text=getattr(ListModel, 'COLUMN_' + property.upper(),
+ ListModel.COLUMN_TIMESTAMP))
+if order == gtk.SORT_ASCENDING:
+sign = '+'
+else:
+sign = '-'
+self._query['order_by'] = [sign + property]
+self.refresh()
+
 def update_with_query(self, query_dict):
 logging.debug('ListView.update_with_query')
 self._query = query_dict
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [RFC PATCH 7/8] Call sort_by in the list view when sorting is selected in the toolbar.

2010-05-01 Thread Andrés Ambrois
Connect the sort-property-changed signal in the toolbar to the sort_by
method the view.

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/journalactivity.py |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/src/jarabe/journal/journalactivity.py 
b/src/jarabe/journal/journalactivity.py
index 0559560..f5e101b 100644
--- a/src/jarabe/journal/journalactivity.py
+++ b/src/jarabe/journal/journalactivity.py
@@ -165,6 +165,7 @@ class JournalActivity(Window):
 
 search_toolbar = self._main_toolbox.search_toolbar
 search_toolbar.connect('query-changed', self._query_changed_cb)
+search_toolbar.connect('sort-property-changed', self._sort_changed_cb)
 search_toolbar.set_mount_point('/')
 
 def _setup_secondary_view(self):
@@ -196,6 +197,10 @@ class JournalActivity(Window):
 self._list_view.update_with_query(query)
 self.show_main_view()
 
+def _sort_changed_cb(self, toolbar, property, order):
+self._list_view.sort_by(property, order)
+self.show_main_view()
+
 def show_main_view(self):
 if self.toolbar_box != self._main_toolbox:
 self.set_toolbar_box(self._main_toolbox)
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [RFC PATCH 5/8] Rename the date column to 'sort_column'

2010-05-01 Thread Andrés Ambrois
As it will be used to display the currently active sorting property.

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/listview.py |   22 +++---
 1 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
index 9e19f70..375a8ee 100644
--- a/src/jarabe/journal/listview.py
+++ b/src/jarabe/journal/listview.py
@@ -97,7 +97,7 @@ class BaseListView(gtk.Bin):
 self.cell_title = None
 self.cell_icon = None
 self._title_column = None
-self.date_column = None
+self.sort_column = None
 self._add_columns()
 
 self.tree_view.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
@@ -190,15 +190,15 @@ class BaseListView(gtk.Bin):
 date = util.timestamp_to_elapsed_string(timestamp)
 date_width = self._get_width_for_string(date)
 
-self.date_column = gtk.TreeViewColumn()
-self.date_column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
-self.date_column.props.fixed_width = date_width
-self.date_column.set_alignment(1)
-self.date_column.props.resizable = True
-self.date_column.props.clickable = True
-self.date_column.pack_start(cell_text)
-self.date_column.add_attribute(cell_text, 'text', 
ListModel.COLUMN_DATE)
-self.tree_view.append_column(self.date_column)
+self.sort_column = gtk.TreeViewColumn()
+self.sort_column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
+self.sort_column.props.fixed_width = date_width
+self.sort_column.set_alignment(1)
+self.sort_column.props.resizable = True
+self.sort_column.props.clickable = True
+self.sort_column.pack_start(cell_text)
+self.sort_column.add_attribute(cell_text, 'text', 
ListModel.COLUMN_TIMESTAMP)
+self.tree_view.append_column(self.sort_column)
 
 def _get_width_for_string(self, text):
 # Add some extra margin
@@ -415,7 +415,7 @@ class BaseListView(gtk.Bin):
 
 while True:
 x, y, width, height = self.tree_view.get_cell_area(path,
-   
self.date_column)
+   
self.sort_column)
 x, y = self.tree_view.convert_tree_to_widget_coords(x, y)
 self.tree_view.queue_draw_area(x, y, width, height)
 if path == end_path:
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [RFC PATCH 4/8] Add a ListViewButton to the journal search toolbar.

2010-05-01 Thread Andrés Ambrois
Add a button to display the sorting options. Create a sort-property-changed
signal in the toolbar to notify the activity of changes.

Use a RadioToolButton for a future implementation of multiple journal views
(as described in the Journal Design Proposal).

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/journaltoolbox.py |   64 +-
 1 files changed, 63 insertions(+), 1 deletions(-)

diff --git a/src/jarabe/journal/journaltoolbox.py 
b/src/jarabe/journal/journaltoolbox.py
index 7466461..48aeb34 100644
--- a/src/jarabe/journal/journaltoolbox.py
+++ b/src/jarabe/journal/journaltoolbox.py
@@ -30,6 +30,7 @@ from sugar.graphics.toolbox import Toolbox
 from sugar.graphics.toolcombobox import ToolComboBox
 from sugar.graphics.toolbutton import ToolButton
 from sugar.graphics.toggletoolbutton import ToggleToolButton
+from sugar.graphics.radiotoolbutton import RadioToolButton
 from sugar.graphics.combobox import ComboBox
 from sugar.graphics.menuitem import MenuItem
 from sugar.graphics.icon import Icon
@@ -74,7 +75,10 @@ class SearchToolbar(gtk.Toolbar):
 __gsignals__ = {
 'query-changed': (gobject.SIGNAL_RUN_FIRST,
   gobject.TYPE_NONE,
-  ([object]))
+  ([object])),
+'sort-property-changed': (gobject.SIGNAL_RUN_FIRST,
+  gobject.TYPE_NONE,
+  ([str, object]))
 }
 
 def __init__(self):
@@ -109,6 +113,17 @@ class SearchToolbar(gtk.Toolbar):
 self.insert(tool_item, -1)
 tool_item.show()
 
+self._add_separator(expand=True)
+
+self._list_view_button = ListViewButton()
+# TODO: Connect when Grid View is implemented
+#self._list_view.connect('toggled', self.__view_button_toggled_cb)
+self._list_view_button.set_active(True)
+self.insert(self._list_view_button, -1)
+self._list_view_button.connect('sort-property-changed',
+   self.__sort_changed_cb)
+self._list_view_button.show()
+
 # TODO: enable it when the DS supports saving the buddies.
 #self._with_search_combo = self._get_with_search_combo()
 #tool_item = ToolComboBox(self._with_search_combo)
@@ -119,6 +134,9 @@ class SearchToolbar(gtk.Toolbar):
 
 self.refresh_filters()
 
+def __sort_changed_cb(self, button, property, order):
+self.emit('sort-property-changed', property, order)
+
 def give_entry_focus(self):
 self._search_entry.grab_focus()
 
@@ -467,3 +485,47 @@ class EntryToolbar(gtk.Toolbar):
 activity_info.get_bundle_id())
 palette.menu.append(menu_item)
 menu_item.show()
+
+class ListViewButton(RadioToolButton):
+__gtype_name__ = 'JournalListViewButton'
+
+__gsignals__ = {
+'sort-property-changed': (gobject.SIGNAL_RUN_FIRST,
+  gobject.TYPE_NONE,
+  ([str, object])),
+}
+
+_SORT_OPTIONS = [
+('timestamp', 'view-lastedit', _('View by last edit')),
+('ctime', 'view-created', _('View by creation date')),
+('filesize', 'view-size', _('View by size')),
+]
+
+def __init__(self):
+RadioToolButton.__init__(self)
+
+self.props.tooltip = _('List view')
+self.props.named_icon = 'view-list'
+# TODO: Set accelerator when Grid View is implemented
+#self.props.accelerator = _('2')
+self.props.group = None
+
+for property, icon, label in self._SORT_OPTIONS:
+button = MenuItem(icon_name=icon, text_label=label)
+button.connect('activate',
+   self.__sort_type_changed_cb,
+   property,
+   icon)
+button.show()
+self.props.palette.menu.insert(button, -1)
+
+def __sort_type_changed_cb(self, widget, property, named_icon):
+#FIXME: Implement sorting order
+self.emit('sort-property-changed', property, gtk.SORT_ASCENDING)
+
+self.props.named_icon = named_icon
+
+if not self.props.active:
+self.props.active = True
+else:
+self.emit('toggled')
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [RFC PATCH 3/8] Add add_separator method for convenience.

2010-05-01 Thread Andrés Ambrois

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/journaltoolbox.py |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/src/jarabe/journal/journaltoolbox.py 
b/src/jarabe/journal/journaltoolbox.py
index 61671bc..7466461 100644
--- a/src/jarabe/journal/journaltoolbox.py
+++ b/src/jarabe/journal/journaltoolbox.py
@@ -154,6 +154,17 @@ class SearchToolbar(gtk.Toolbar):
 with_search.connect('changed', self._combo_changed_cb)
 return with_search
 
+def _add_separator(self, expand=False):
+separator = gtk.SeparatorToolItem()
+separator.props.draw = False
+if expand:
+separator.set_expand(True)
+else:
+separator.set_size_request(style.GRID_CELL_SIZE,
+   style.GRID_CELL_SIZE)
+self.insert(separator, -1)
+separator.show()
+
 def _add_widget(self, widget, expand=False):
 tool_item = gtk.ToolItem()
 tool_item.set_expand(expand)
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [RFC PATCH 2/8] Add ctime and filesize columns to the journal list model.

2010-05-01 Thread Andrés Ambrois
Add two columns to the ListModel. This will make it easy to display the
values we are sorting by by simply associating the cell renderer with
one of them.

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/listmodel.py |   22 --
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/jarabe/journal/listmodel.py b/src/jarabe/journal/listmodel.py
index 07f8544..494f1e0 100644
--- a/src/jarabe/journal/listmodel.py
+++ b/src/jarabe/journal/listmodel.py
@@ -48,18 +48,22 @@ class ListModel(gtk.GenericTreeModel, gtk.TreeDragSource):
 COLUMN_ICON = 2
 COLUMN_ICON_COLOR = 3
 COLUMN_TITLE = 4
-COLUMN_DATE = 5
-COLUMN_PROGRESS = 6
-COLUMN_BUDDY_1 = 7
-COLUMN_BUDDY_2 = 8
-COLUMN_BUDDY_3 = 9
+COLUMN_TIMESTAMP = 5
+COLUMN_CTIME = 6
+COLUMN_FILESIZE = 7
+COLUMN_PROGRESS = 8
+COLUMN_BUDDY_1 = 9
+COLUMN_BUDDY_2 = 10
+COLUMN_BUDDY_3 = 11
 
 _COLUMN_TYPES = {COLUMN_UID:str,
  COLUMN_FAVORITE:   bool,
  COLUMN_ICON:   str,
  COLUMN_ICON_COLOR: object,
  COLUMN_TITLE:  str,
- COLUMN_DATE:   str,
+ COLUMN_TIMESTAMP:  str,
+ COLUMN_CTIME:  str,
+ COLUMN_FILESIZE:   str,
  COLUMN_PROGRESS:   int,
  COLUMN_BUDDY_1:object,
  COLUMN_BUDDY_3:object,
@@ -141,6 +145,12 @@ class ListModel(gtk.GenericTreeModel, gtk.TreeDragSource):
 timestamp = int(metadata.get('timestamp', 0))
 self._cached_row.append(util.timestamp_to_elapsed_string(timestamp))
 
+ctime = int(metadata.get('ctime', 0))
+self._cached_row.append(util.timestamp_to_elapsed_string(ctime))
+
+size = int(metadata.get('filesize', 0))
+self._cached_row.append(util.format_size(size))
+
 self._cached_row.append(int(metadata.get('progress', 100)))
 
 if metadata.get('buddies', ''):
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [RFC PATCH 1/8] Journal: Retrieve ctime and filesize from the datastore.

2010-05-01 Thread Andrés Ambrois
Add the two new properties (ctime and filesize) to the list of
properties we ask the datastore for.

Signed-off-by: Andrés Ambrois 
---
 src/jarabe/journal/model.py |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
index ffc62e0..4f1eb8d 100644
--- a/src/jarabe/journal/model.py
+++ b/src/jarabe/journal/model.py
@@ -36,9 +36,9 @@ DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
 DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
 
 # Properties the journal cares about.
-PROPERTIES = ['uid', 'title', 'mtime', 'timestamp', 'keep', 'buddies',
-  'icon-color', 'mime_type', 'progress', 'activity', 'mountpoint',
-  'activity_id', 'bundle_id']
+PROPERTIES = ['uid', 'title', 'mtime', 'timestamp', 'ctime', 'filesize',
+  'keep', 'buddies', 'icon-color', 'mime_type', 'progress',
+  'activity', 'mountpoint', 'activity_id', 'bundle_id']
 
 MIN_PAGES_TO_CACHE = 3
 MAX_PAGES_TO_CACHE = 5
-- 
1.6.3.3

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


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

2010-05-01 Thread Andrés Ambrois
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@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


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

2010-05-01 Thread Andrés Ambrois
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 
---
 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
@@ -18,7 +18,7 @@ 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@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


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

2010-05-01 Thread Andrés Ambrois
On Saturday 01 May 2010 03:52:46 pm Andrés Ambrois wrote:
> 
> Signed-off-by: Andrés Ambrois 
> ---
>  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


signature.asc
Description: This is a digitally signed message part.
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


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

2010-05-01 Thread Andrés Ambrois

Signed-off-by: Andrés Ambrois 
---
 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
@@ -18,7 +18,7 @@ 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
@@ -45,8 +45,8 @@ 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)
@@ -69,9 +69,22 @@ 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@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


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

2010-05-01 Thread Andrés Ambrois

Signed-off-by: Andrés Ambrois 
---
 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
@@ -45,8 +45,8 @@ 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)
@@ -73,6 +73,16 @@ 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@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


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

2010-05-01 Thread Andrés Ambrois

Signed-off-by: Andrés Ambrois 
---
 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
@@ -154,8 +154,17 @@ 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)
@@ -190,8 +199,17 @@ 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
@@ -28,6 +28,9 @@ 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'
@@ -57,6 +60,8 @@ _QUERY_TERM_MAP = {
 
 _QUERY_VALUE_MAP = {
 'timestamp': {'number': _VALUE_TIMESTAMP, 'type': float},
+'filesize': {'number': _VALUE_FILESIZE, 'type': int},
+'ctime': {'number': _VALUE_CTIME, 'type': int},
 }
 
 
@@ -66,6 +71,10 @@ 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)
 
@@ -280,10 +289,18 @@ 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@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


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

2010-05-01 Thread Andrés Ambrois
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@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH] battery frame device: replace HAL with UPower

2010-05-01 Thread Sascha Silbe
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
@@ -16,8 +16,9 @@
 
 import logging
 from gettext import gettext as _
-import gconf
+import sys
 
+import gconf
 import gobject
 import gtk
 import dbus
@@ -30,6 +31,7 @@ from sugar.graphics.xocolor import XoColor
 
 from jarabe.frame.frameinvoker import FrameWidgetInvoker
 
+
 _ICON_NAME = 'battery'
 
 _STATUS_CHARGING = 0
@@ -37,34 +39,35 @@ _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()
 
@@ -86,27 +89,30 @@ 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)
@@ -122,29 +128,29 @@ 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')