from sugar.activity import activity from sugar.graphics.toolbarbox import ToolbarBox from sugar.graphics.objectchooser import ObjectChooser from sugar.datastore import datastore from sugar import mime from sugar.logger import logging from gettext import gettext as _ import gtk import os import statvfs import zipfile import gio ACTION_ICONS = { 'sound' : gtk.STOCK_MEDIA_PLAY, 'video' : gtk.STOCK_MEDIA_PLAY, 'next' : gtk.STOCK_GO_FORWARD, } class Secuencia(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) self.toolbox = activity.ActivityToolbox(self) self.set_toolbox(self.toolbox) self.toolbox.show() main_box = gtk.VBox() frame = gtk.Frame() main_box.pack_start(frame) frame.show() frame_vbox = gtk.VBox() frame.add(frame_vbox) frame_vbox.show() self.text = gtk.Label() frame_vbox.pack_start(self.text) self.text.show() self.image = gtk.Image() frame_vbox.pack_start(self.image) self.image.show() self.action_icon = gtk.Image() main_box.pack_start(self.action_icon, False) self.action_icon.show() self.set_canvas(main_box) main_box.show() # A list of (filename, mimetype) tuples self.list = [] self.current_pos = -1 self.executed_action = True if self.shared_activity: pass elif handle.object_id is not None: self.list = self.metadata['files'] else: self._show_journal_object_picker() self.connect('button-press-event', lambda w, e: self._next()) self.show_all() self._next() def _next(self): if not self.executed_action: card = self.list[self.current_pos] self._execute(card) self.executed_action = True else: self.current_pos += 1 try: card = self.list[self.current_pos] except IndexError: self.current_pos = -1 self._next() else: self._show_card(card) self.executed_action = False def _execute(self, card): if 'sound' in card: # Play sound pass elif 'video' in card: # Play video pass def _show_card(self, card): if 'image' in card: self.image.set_from_file(os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'], 'tmp', card['image'])) else: self.image.set_from_stock(gtk.STOCK_MISSING_IMAGE) if 'action' in card: self.action_icon.set_from_stock(ACTION_ICONS[card['action']], gtk.ICON_SIZE_LARGE_TOOLBAR) else: self.action_icon.set_from_stock(ACTION_ICONS['next'], gtk.ICON_SIZE_LARGE_TOOLBAR) self.text.set_text(card['title']) def _show_journal_object_picker(self): """Show the journal object picker to load a document. This is for if Read is launched without a document. """ chooser = ObjectChooser(_('Choose document'), self, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, what_filter=mime.GENERIC_TYPE_TEXT) #FIXME: Filter by this activity's type try: result = chooser.run() if result == gtk.RESPONSE_ACCEPT: logging.debug('ObjectChooser: %r' % chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: self.list = jobject.metadata['files'] self.read_file(jobject.file_path) finally: chooser.destroy() del chooser def read_file(self, path): zip = zipfile.ZipFile(path) info = zip.infolist() size = reduce(lambda s, i: s+i.file_size, info, 0) stat = os.stavfs(os.environ['SUGAR_ACTIVITY_ROOT']) if stat[statvfs.F_BSIZE]*stat[statvfs.F_BAVAIL] < size: #TODO: Alert: Not enough free space for member in zip.infolist(): try: data = member.read() self.list.append((member.filename, gio.content_type_guess(None, data)) f = open(os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'], 'tmp', member.filename), 'w') f.write(data) del data finally: f.close() def write_file(self, path): pass