diff options
-rw-r--r--[-rwxr-xr-x] | datamanager.py | 182 | ||||
-rwxr-xr-x | filelisting.py | 168 | ||||
-rwxr-xr-x | listview.py | 144 | ||||
-rwxr-xr-x | objectchooser.py | 118 | ||||
-rwxr-xr-x | objectfetch.py | 120 | ||||
-rwxr-xr-x | xoconfig | 25 |
6 files changed, 180 insertions, 577 deletions
diff --git a/datamanager.py b/datamanager.py index 0dc5ba4..212b6a9 100755..100644 --- a/datamanager.py +++ b/datamanager.py @@ -1,12 +1,190 @@ +#!/usr/bin/python +# -*- mode:python; tab-width:4; indent-tabs-mode:t; -*- +# datamanager.py +# +# provides utility to manage datastore locally and on schoolserver +# +# 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 + from sugar.activity import activity -import listview +from sugar.datastore import datastore +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics.menuitem import MenuItem + +import os, sys +import gtk +from path import path + +import urllib2 +from BeautifulSoup import BeautifulSoup + +ACTIVITYPATH = path(activity.get_bundle_path()) + +SERIALNUMBER = '/ofw/serial-number' class DataManager(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) + print 'activity initialized' + self.set_title("Datamanager") + #Create the standard activity toolbox toolbox = activity.ActivityToolbox(self) self.set_toolbox(toolbox) toolbox.show() - listview.pyApp(self) + self.viewer = Listview() + self.child.pack_start(self.viewer, True, True, 0) + treeView = self.viewer.get_treeView() + treeView.set_model(self.viewer.create_model()) + self.show_all() + +# based on PyGTK tutorial by jan bodnar, zetcode.com, February 2009 +class Listview(gtk.VBox): + def __init__(self): + print 'Listview init' + gtk.VBox.__init__(self) + self.connect("destroy", gtk.main_quit) + self.online = False + sw = gtk.ScrolledWindow() + sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.treeView = gtk.TreeView() + self.treeView.connect("row-activated", self.on_activated) + self.treeView.set_rules_hint(True) + sw.add(self.treeView) + + print 'create_columns' + self.create_columns(self.treeView) + print 'pack sw' + self.pack_start(sw, True, True, 0) + + print 'set up metadata display' + self.label = gtk.Label("") + self.label.show() + self.frame = gtk.Frame(label='metadata') + self.frame.add(self.label) + self.frame.show() + self.pack_start(self.frame, False, False, 0) + print 'show all' + self.show_all() + + def get_treeView(self): + return self.treeView + + def create_model(self): + global online + store = gtk.ListStore(object, str, str, str) + #let's display objects from the schoolserver + src = '/ofw/serial-number' + print 'open configf', src + configf = open(src, "r") + xoserial = configf.read() + configf.close() + print 'xoserial:', xoserial[:11] + #temp for testing + if len(xoserial)>0: + url = "http://schoolserver/ds-restore/" + xoserial[:11] + "/datastore-latest" + print 'url', url + try: + response = urllib2.urlopen(url) + except: + print 'schoolserver not found' + response = None + if response: + soup = BeautifulSoup(response) + self.online = True + else: + print 'schoolserver not found at', url + else: + print 'no xoserial' + if self.online: + print 'soup=', soup.prettify() + entries = soup.findAll("li") + print len(entries) + rnge = len(entries) + print 'entries:', rnge + if rnge > 10: + rnge = 10 + for i in range(rnge): + print len(entries[i].contents), entries[i].contents + colx = str(entries[i].contents[0]) + pos1 = colx.find('<') + pos2 = colx.find('>') + col0 = colx[pos1:pos2] + col1 = 'col1' + colx[pos2+1:] + temp = entries[i].contents[1].split(' ') + col2 = 'col2:' + temp[0] + col3 = 'col3:' + temp[1] + store.append([col1, col2, col3]) + #print 'sample', entries[0].toprettyxml() + #objects from the local datastore + results, count = datastore.find(dict()) + print 'number of datastore items', count + color = 0 + firsttime = True + colors = ["red", "yellow", "blue", "green"] + for f in results: + obj = datastore.get(f.object_id) + if firsttime: + firsttime = False + print 'type obj', type(obj) + store.append([obj, obj.metadata['title'], obj.metadata['mime_type'], colors[color] ]) + f.destroy() + color += 1 + if color > 3: + color = 0 + #ignore for the moment + print 'return store' + return store + + def create_columns(self, treeView): + + rendererText = gtk.CellRendererText() + column = gtk.TreeViewColumn("Title", rendererText, text=1) + column.add_attribute(rendererText, "cell-background", 3) + column.set_sort_column_id(0) + treeView.append_column(column) + + rendererText = gtk.CellRendererText() + column = gtk.TreeViewColumn("Mime_type", rendererText, text=2) + column.set_sort_column_id(1) + treeView.append_column(column) + + def on_activated(self, widget, row, col): + + model = widget.get_model() + model[row][3] = "cyan" + obj = model[row][0] + pth = obj.get_file_path() + print 'pth', pth + if len(pth) > 0: + f = open(pth,'r') + text = f.read() + f.close() + tpllist = [] + metakeys = obj.metadata.keys() + for metakey in metakeys: + metavalue = obj.metadata[metakey] + tpllist.append((metakey, metavalue)) + metadata = dict(tpllist) + tstr = "" + for k, v in metadata.iteritems(): + try: + if len(str(v)) > 0: + tstr = tstr + k + ':' + v + '\n' + except: + tstr = tstr + k + ':' + "" + '\n' + self.label.set_text(tstr) diff --git a/filelisting.py b/filelisting.py deleted file mode 100755 index f0a1aa0..0000000 --- a/filelisting.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python - -import os, stat, time -import pygtk -pygtk.require('2.0') -import gtk - -folderxpm = [ - "17 16 7 1", - " c #000000", - ". c #808000", - "X c yellow", - "o c #808080", - "O c #c0c0c0", - "+ c white", - "@ c None", - "@@@@@@@@@@@@@@@@@", - "@@@@@@@@@@@@@@@@@", - "@@+XXXX.@@@@@@@@@", - "@+OOOOOO.@@@@@@@@", - "@+OXOXOXOXOXOXO. ", - "@+XOXOXOXOXOXOX. ", - "@+OXOXOXOXOXOXO. ", - "@+XOXOXOXOXOXOX. ", - "@+OXOXOXOXOXOXO. ", - "@+XOXOXOXOXOXOX. ", - "@+OXOXOXOXOXOXO. ", - "@+XOXOXOXOXOXOX. ", - "@+OOOOOOOOOOOOO. ", - "@ ", - "@@@@@@@@@@@@@@@@@", - "@@@@@@@@@@@@@@@@@" - ] -folderpb = gtk.gdk.pixbuf_new_from_xpm_data(folderxpm) - -filexpm = [ - "12 12 3 1", - " c #000000", - ". c #ffff04", - "X c #b2c0dc", - "X XXX", - "X ...... XXX", - "X ...... X", - "X . ... X", - "X ........ X", - "X . .... X", - "X ........ X", - "X . .. X", - "X ........ X", - "X . .. X", - "X ........ X", - "X X" - ] -filepb = gtk.gdk.pixbuf_new_from_xpm_data(filexpm) - -class FileListingCellDataExample: - column_names = ['Name', 'Size', 'Mode', 'Last Changed'] - - def delete_event(self, widget, event, data=None): - gtk.main_quit() - return False - - def __init__(self, dname = None): - cell_data_funcs = (None, self.file_size, self.file_mode, - self.file_last_changed) - - # Create a new window - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) - - self.window.set_size_request(400, 300) - - self.window.connect("delete_event", self.delete_event) - - listmodel = self.make_list(dname) - - # create the TreeView - self.treeview = gtk.TreeView() - - # create the TreeViewColumns to display the data - self.tvcolumn = [None] * len(self.column_names) - cellpb = gtk.CellRendererPixbuf() - self.tvcolumn[0] = gtk.TreeViewColumn(self.column_names[0], cellpb) - self.tvcolumn[0].set_cell_data_func(cellpb, self.file_pixbuf) - cell = gtk.CellRendererText() - self.tvcolumn[0].pack_start(cell, False) - self.tvcolumn[0].set_cell_data_func(cell, self.file_name) - self.treeview.append_column(self.tvcolumn[0]) - for n in range(1, len(self.column_names)): - cell = gtk.CellRendererText() - self.tvcolumn[n] = gtk.TreeViewColumn(self.column_names[n], cell) - if n == 1: - cell.set_property('xalign', 1.0) - self.tvcolumn[n].set_cell_data_func(cell, cell_data_funcs[n]) - self.treeview.append_column(self.tvcolumn[n]) - - self.treeview.connect('row-activated', self.open_file) - self.scrolledwindow = gtk.ScrolledWindow() - self.scrolledwindow.add(self.treeview) - self.window.add(self.scrolledwindow) - self.treeview.set_model(listmodel) - - self.window.show_all() - return - - def make_list(self, dname=None): - if not dname: - self.dirname = os.path.expanduser('~') - else: - self.dirname = os.path.abspath(dname) - self.window.set_title(self.dirname) - files = [f for f in os.listdir(self.dirname) if f[0] <> '.'] - files.sort() - files = ['..'] + files - listmodel = gtk.ListStore(object) - for f in files: - listmodel.append([f]) - return listmodel - - def open_file(self, treeview, path, column): - model = treeview.get_model() - iter = model.get_iter(path) - filename = os.path.join(self.dirname, model.get_value(iter, 0)) - filestat = os.stat(filename) - if stat.S_ISDIR(filestat.st_mode): - new_model = self.make_list(filename) - treeview.set_model(new_model) - return - - def file_pixbuf(self, column, cell, model, iter): - filename = os.path.join(self.dirname, model.get_value(iter, 0)) - filestat = os.stat(filename) - if stat.S_ISDIR(filestat.st_mode): - pb = folderpb - else: - pb = filepb - cell.set_property('pixbuf', pb) - return - - def file_name(self, column, cell, model, iter): - cell.set_property('text', model.get_value(iter, 0)) - return - - def file_size(self, column, cell, model, iter): - filename = os.path.join(self.dirname, model.get_value(iter, 0)) - filestat = os.stat(filename) - cell.set_property('text', filestat.st_size) - return - - def file_mode(self, column, cell, model, iter): - filename = os.path.join(self.dirname, model.get_value(iter, 0)) - filestat = os.stat(filename) - cell.set_property('text', oct(stat.S_IMODE(filestat.st_mode))) - return - - - def file_last_changed(self, column, cell, model, iter): - filename = os.path.join(self.dirname, model.get_value(iter, 0)) - filestat = os.stat(filename) - cell.set_property('text', time.ctime(filestat.st_mtime)) - return - -def main(): - gtk.main() - -if __name__ == "__main__": - flcdexample = FileListingCellDataExample() - main() - diff --git a/listview.py b/listview.py deleted file mode 100755 index 67b6d6a..0000000 --- a/listview.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/python - -# ZetCode PyGTK tutorial -# -# This example shows a TreeView widget -# in a list view mode -# -# author: jan bodnar -# website: zetcode.com -# last edited: February 2009 - -import sys, os -import gtk -import objectfetch -import urllib2 -from BeautifulSoup import BeautifulSoup -from xml.dom.minidom import parse, parseString -from sugar.activity import activity -from sugar.datastore import datastore -from path import path - -ACTIVITYPATH = path(activity.get_bundle_path()) -global online -online = False - -class PyApp(gtk.Window): - def __init__(self): - super(PyApp, self).__init__() - self.set_size_request(350, 250) - self.set_position(gtk.WIN_POS_CENTER) - - self.connect("destroy", gtk.main_quit) - self.set_title("DataManager") - - vbox = gtk.VBox(False, 8) - - sw = gtk.ScrolledWindow() - sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - - vbox.pack_start(sw, True, True, 0) - - store = self.create_model() - - treeView = gtk.TreeView(store) - treeView.connect("row-activated", self.on_activated) - treeView.set_rules_hint(True) - sw.add(treeView) - - self.create_columns(treeView) - self.statusbar = gtk.Statusbar() - - vbox.pack_start(self.statusbar, False, False, 0) - - self.add(vbox) - self.show_all() - - - def create_model(self): - global online - store = gtk.ListStore(str, str, str) - #let's display objects from the schoolserver - pth = ACTIVITYPATH / 'xoconfig' - configf = open(pth, "r") - config = configf.read() - configf.close() - pos = config.find('[Server]') - if pos < 0: - print 'schoolserver not found' - xoserial = None - store.append(["schoolserver not found", "",""]) - else: - pos = pos + 8 - print 'config', config[pos:] - pos1 = pos + config[pos:].find("= ") + 2 - pos2 = pos + config[pos:].find("@") - xoserial = config[pos1:pos2] - print 'xoserial', xoserial, config[pos1:pos2+1] - #temp for testing - xoserial = 'SHC84201F3B' - if xoserial: - url = "http://schoolserver/ds-restore/" + xoserial + "/datastore-latest" - print 'url', url - try: - response = urllib2.urlopen(url) - except: - print 'schoolserver not found' - response = None - if response: - soup = BeautifulSoup(response) - online = True - else: - print 'schoolserver not found at', url - if online: - print 'soup=', soup.prettify() - entries = soup.findAll("li") - print len(entries) - for i in range(10): - print len(entries[i].contents), entries[i].contents - colx = str(entries[i].contents[0]) - pos1 = colx.find('<') - pos2 = colx.find('>') - col0 = colx[pos1:pos2] - col1 = 'col1' + colx[pos2+1:] - temp = entries[i].contents[1].split(' ') - col2 = 'col2:' + temp[0] - col3 = 'col3:' + temp[1] - store.append([col1, col2, col3]) - #print 'sample', entries[0].toprettyxml() - #objects from the local datastore - results, count = datastore.find(dict()) - print 'number of datastore items', count - for f in results: - obj = datastore.get(f.object_id) - f.destroy() - store.append([obj.get_file_path(), obj.metadata['title'], obj.metadata['mime_type']]) - #ignore for the moment - return store - - - def create_columns(self, treeView): - - rendererText = gtk.CellRendererText() - column = gtk.TreeViewColumn("Title", rendererText, text=1) - column.set_sort_column_id(0) - treeView.append_column(column) - - rendererText = gtk.CellRendererText() - column = gtk.TreeViewColumn("Mime_type", rendererText, text=2) - column.set_sort_column_id(1) - treeView.append_column(column) - - - def on_activated(self, widget, row, col): - - model = widget.get_model() - text = model[row][0] + ", " + model[row][1] + ", " + model[row][2] - self.statusbar.push(0, text) - - - -PyApp() -gtk.main() - diff --git a/objectchooser.py b/objectchooser.py deleted file mode 100755 index 861d0ab..0000000 --- a/objectchooser.py +++ /dev/null @@ -1,118 +0,0 @@ -# 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 logging - -import gobject -import gtk -import dbus - -from sugar.datastore import datastore - -J_DBUS_SERVICE = 'org.laptop.Journal' -J_DBUS_INTERFACE = 'org.laptop.Journal' -J_DBUS_PATH = '/org/laptop/Journal' - -class ObjectChooser(object): - def __init__(self, title=None, parent=None, flags=None, buttons=None): - # For backwards compatibility: - # - We ignore title, flags and buttons. - # - 'parent' can be a xid or a gtk.Window - - if title is not None or flags is not None or buttons is not None: - logging.warning('Invocation of ObjectChooser() has deprecated ' - 'parameters.') - - if parent is None: - parent_xid = 0 - elif hasattr(parent, 'window') and hasattr(parent.window, 'xid'): - parent_xid = parent.window.xid - else: - parent_xid = parent - - self._parent_xid = parent_xid - self._main_loop = None - self._object_id = None - self._bus = None - self._chooser_id = None - self._response_code = gtk.RESPONSE_NONE - - def run(self): - self._object_id = None - - self._main_loop = gobject.MainLoop() - - self._bus = dbus.SessionBus(mainloop=self._main_loop) - self._bus.add_signal_receiver( - self.__name_owner_changed_cb, - signal_name="NameOwnerChanged", - dbus_interface="org.freedesktop.DBus", - arg0=J_DBUS_SERVICE) - - obj = self._bus.get_object(J_DBUS_SERVICE, J_DBUS_PATH) - journal = dbus.Interface(obj, J_DBUS_INTERFACE) - journal.connect_to_signal('ObjectChooserResponse', - self.__chooser_response_cb) - journal.connect_to_signal('ObjectChooserCancelled', - self.__chooser_cancelled_cb) - self._chooser_id = journal.ChooseObject(self._parent_xid) - - gtk.gdk.threads_leave() - try: - self._main_loop.run() - finally: - gtk.gdk.threads_enter() - self._main_loop = None - - return self._response_code - - def get_selected_object(self): - if self._object_id is None: - return None - else: - return datastore.get(self._object_id) - - def destroy(self): - self._cleanup() - - def _cleanup(self): - if self._main_loop is not None: - self._main_loop.quit() - self._main_loop = None - self._bus = None - - def __chooser_response_cb(self, chooser_id, object_id): - if chooser_id != self._chooser_id: - return - logging.debug('ObjectChooser.__chooser_response_cb: %r' % object_id) - self._response_code = gtk.RESPONSE_ACCEPT - self._object_id = object_id - self._cleanup() - - def __chooser_cancelled_cb(self, chooser_id): - if chooser_id != self._chooser_id: - return - logging.debug('ObjectChooser.__chooser_cancelled_cb: %r' % chooser_id) - self._response_code = gtk.RESPONSE_CANCEL - self._cleanup() - - def __name_owner_changed_cb(self, name, old, new): - logging.debug('ObjectChooser.__name_owner_changed_cb') - # Journal service disappeared from the bus - self._response_code = gtk.RESPONSE_CANCEL - self._cleanup() - diff --git a/objectfetch.py b/objectfetch.py deleted file mode 100755 index 6c3bb92..0000000 --- a/objectfetch.py +++ /dev/null @@ -1,120 +0,0 @@ -# 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 logging - -import gobject -import gtk -import dbus - -from sugar.datastore import datastore - -J_DBUS_SERVICE = 'org.laptop.Journal' -J_DBUS_INTERFACE = 'org.laptop.Journal' -J_DBUS_PATH = '/org/laptop/Journal' - -class ObjectChooser(object): - def __init__(self, title=None, parent=None, flags=None, buttons=None): - # For backwards compatibility: - # - We ignore title, flags and buttons. - # - 'parent' can be a xid or a gtk.Window - - if title is not None or flags is not None or buttons is not None: - logging.warning('Invocation of ObjectChooser() has deprecated ' - 'parameters.') - - if parent is None: - parent_xid = 0 - elif hasattr(parent, 'window') and hasattr(parent.window, 'xid'): - parent_xid = parent.window.xid - else: - parent_xid = parent - - self._parent_xid = parent_xid - self._main_loop = None - self._object_id = None - self._bus = None - self._chooser_id = None - self._response_code = gtk.RESPONSE_NONE - - def run(self): - self._object_id = None - - self._main_loop = gobject.MainLoop() - - self._bus = dbus.SessionBus(mainloop=self._main_loop) - self._bus.add_signal_receiver( - self.__name_owner_changed_cb, - signal_name="NameOwnerChanged", - dbus_interface="org.freedesktop.DBus", - arg0=J_DBUS_SERVICE) - - obj = self._bus.get_object(J_DBUS_SERVICE, J_DBUS_PATH) - print 'obj', obj.get_metadata['title'] - print 'obj', obj.file_path - journal = dbus.Interface(obj, J_DBUS_INTERFACE) - journal.connect_to_signal('ObjectChooserResponse', - self.__chooser_response_cb) - journal.connect_to_signal('ObjectChooserCancelled', - self.__chooser_cancelled_cb) - self._chooser_id = journal.ChooseObject(self._parent_xid) - - gtk.gdk.threads_leave() - try: - self._main_loop.run() - finally: - gtk.gdk.threads_enter() - self._main_loop = None - - return self._response_code - - def get_selected_object(self): - if self._object_id is None: - return None - else: - return datastore.get(self._object_id) - - def destroy(self): - self._cleanup() - - def _cleanup(self): - if self._main_loop is not None: - self._main_loop.quit() - self._main_loop = None - self._bus = None - - def __chooser_response_cb(self, chooser_id, object_id): - if chooser_id != self._chooser_id: - return - logging.debug('ObjectChooser.__chooser_response_cb: %r' % object_id) - self._response_code = gtk.RESPONSE_ACCEPT - self._object_id = object_id - self._cleanup() - - def __chooser_cancelled_cb(self, chooser_id): - if chooser_id != self._chooser_id: - return - logging.debug('ObjectChooser.__chooser_cancelled_cb: %r' % chooser_id) - self._response_code = gtk.RESPONSE_CANCEL - self._cleanup() - - def __name_owner_changed_cb(self, name, old, new): - logging.debug('ObjectChooser.__name_owner_changed_cb') - # Journal service disappeared from the bus - self._response_code = gtk.RESPONSE_CANCEL - self._cleanup() - diff --git a/xoconfig b/xoconfig deleted file mode 100755 index 733851b..0000000 --- a/xoconfig +++ /dev/null @@ -1,25 +0,0 @@ -[Sound] -volume = 100 - -[Shell] -favoriteslayout = ring-layout - -[Buddy] -color = #FF8F00,#00B20D -nickname = GOV007 - -[Power] -automaticpm = False -extremepm = False - -[Frame] -hotcorners = 0.0 -warmedges = 1000.0 - -[Date] -timezone = UTC - -[Jabber] -registered = False -server = schoolserver.schoolnet.gov.np - |