From 3a340cf8d2a28b1ffe1ee33636277780eb14e328 Mon Sep 17 00:00:00 2001 From: Tony Anderson Date: Fri, 28 Aug 2009 10:12:23 +0000 Subject: version 1 --- diff --git a/activity/activity.info b/activity/activity.info index bdb6d9e..790a935 100755 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,7 +1,7 @@ [Activity] -name = Data Manager +name = DataManager service_name = org.olenepal.DataManager class = datamanager.DataManager icon = datamanager-activity -activity_version = 2 +activity_version = 1 show_launcher = yes diff --git a/activity/datamanager-activity.svg b/activity/datamanager-activity.svg index 1ae35db..0049daa 100755..100644 --- a/activity/datamanager-activity.svg +++ b/activity/datamanager-activity.svg @@ -1,11 +1,33 @@ - - -]> - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/activity/permissions.info b/activity/permissions.info deleted file mode 100755 index 585d713..0000000 --- a/activity/permissions.info +++ /dev/null @@ -1 +0,0 @@ -constant-uid diff --git a/datamanager.py b/datamanager.py index 548b262..4732e72 100644 --- a/datamanager.py +++ b/datamanager.py @@ -21,12 +21,15 @@ from sugar.activity import activity from sugar.datastore import datastore from sugar.graphics.toolbutton import ToolButton -from sugar.graphics.alert import Alert from sugar.graphics.menuitem import MenuItem -import os, sys +import os, sys, time import subprocess + +import pygtk +pygtk.require('2.0') import gtk + from path import path from datetime import datetime from time import strftime @@ -43,11 +46,14 @@ COMMONSPATH = path("/library/Commons") LOCALPATH = path("/home/olpc/.sugar/default/datastore/store") DATEFORMAT = "%Y-%m-%d %H:%M:%S" +ACTIVITYTOOLBAR = 0 USAGETOOLBAR = 1 +DEFAULTTOOLBAR = ACTIVITYTOOLBAR class DataManager(activity.Activity): def __init__(self, handle): + global store print 'activity started' global SERIALNUMBER activity.Activity.__init__(self, handle) @@ -58,52 +64,42 @@ class DataManager(activity.Activity): SERIALNUMBER = t[:11] print 'serial-number', SERIALNUMBER subprocess.call("mkdir -p " + WORKPATH, shell=True) - #set up alert - #self.alert = Alert() - #self.alert.props.title='Updating Datastore' - #self.alert.props.msg='Please be patient - updating store' #Create the usage toolbar self.usageTB = UsageToolbar(self) #Create the standard activity toolbox toolbox = activity.ActivityToolbox(self) toolbox.add_toolbar("Usage", self.usageTB) - toolbox.set_current_toolbar(USAGETOOLBAR) + toolbox.set_current_toolbar(DEFAULTTOOLBAR) self.set_toolbox(toolbox) toolbox.show() self.viewer = Listview() - #treeView = self.viewer.get_treeView() - #treeView.set_model(self.viewer.create_model(self.usageTB)) #set up main screen self.main_screen = gtk.VBox() - #self.main_screen.pack_start(self.alert, False, False, 0) self.main_screen.pack_start(self.viewer, True, True, 0) self.set_canvas(self.main_screen) print 'canvas set' self.show_all() self.viewer.set_label('canvas set') - #self.alert.hide() - - def start_cb(self, widget): treeView = self.viewer.get_treeView() treeView.set_model(self.viewer.create_model(self.usageTB)) + txt = 'ready: ' + str(len(store)) + ' documents ' + txt = txt + str(MB) + '/1000 ' + str(PCT) + '%' + self.viewer.set_label(txt) - def close_cb(self, widget): - #debug switch to cancel uploads - #return True + def write_file(self, file_path): global SERIALNUMBER global store global online action_request = 5 status = 4 + f = open(file_path, 'w') + f.write('this is a dummy file') + f.close() if not online: return True self.viewer.set_label('closing - online') - self.logger('') - self.logger('can_close_online') print 'can_close online' #now the real work begins - #self.alert.show() - self.logger('showing alert') remove_list = [] for row in store: self.viewer.set_label('reviewing status: ' + row[0]) @@ -117,32 +113,27 @@ class DataManager(activity.Activity): row[action_request] = +1 if row[action_request] < 0: remove_list.append(row[0]) - if row[action_request] == 1: + if row[action_request] == 1 and row[status] == 'Red': #upload it self.viewer.set_label('reviewing status: ' + row[0] + ' upload') - self.logger('upload' + row[0] + '.metadata') mname = row[0] + '.metadata' fname = row[0] - src = LOCALPATH / mname - pfx = SERIALNUMBER + '@schoolserver:' - dst = STOREPATH / SERIALNUMBER - cmd = 'scp ' + src + ' ' + pfx + dst - print 'metadata upload', cmd - self.logger('call scp') - subprocess.call(cmd, shell=True) - self.logger('metadata uploaded') - src = LOCALPATH / fname - cmd = 'scp ' + src + ' ' + pfx + dst - if src.exists(): + srcm = LOCALPATH / mname + srcf = LOCALPATH / fname + if srcm.exists() and srcf.exists(): + pfx = SERIALNUMBER + '@schoolserver:' + dst = STOREPATH / SERIALNUMBER + cmd = 'scp ' + srcm + ' ' + pfx + dst + print 'metadata upload', cmd + subprocess.call(cmd, shell=True) + cmd = 'scp ' + srcf + ' ' + pfx + dst print 'file upload', cmd subprocess.call(cmd, shell=True) - self.logger('file uploaded') else: - print 'src path does not exist', src - if row[action_request] > 1 and row[status] == "light green": + print 'upload request but no document', row[1], srcf + if row[action_request] > 1 and row[status] == "Green": #download from schoolserver self.viewer.set_label('reviewing status: ' + row[0] + ' download') - self.logger('download ' + row[0] ) mname = row[0] + '.metadata' fname = row[0] dst = LOCALPATH @@ -151,65 +142,89 @@ class DataManager(activity.Activity): cmd = 'scp ' + pfx + src + ' ' + dst print 'metadata download', cmd subprocess.call(cmd, shell=True) - self.logger('metadata downloaded') src = STOREPATH / SERIALNUMBER / fname cmd = 'scp ' + pfx + src + ' ' + dst + print 'file download', cmd subprocess.call(cmd, shell=True) - self.logger('file downloaded') if row[action_request] > 1 and row[status] == "cyan": #download from Commons self.viewer.set_label('reviewing status: ' + row[0] + ' download') - self.logger('download from Commons: ' + row[0]) #if mime_type is activity - install it mname = row[0] + '.metadata' fname = row[0] dst = LOCALPATH pfx = SERIALNUMBER + '@schoolserver:' - src = COMMONSPATH / SERIALNUMBER / mname + src = COMMONSPATH / mname cmd = 'scp ' + pfx + src + ' ' + dst print 'metadata download', cmd subprocess.call(cmd, shell=True) - src = COMMONSPATH / SERIALNUMBER / fname + src = COMMONSPATH / fname cmd = 'scp ' + pfx + src + ' ' + dst + print 'file download', cmd + subprocess.call(cmd, shell=True) + if row[action_request] == 1 and row[status] == 'cyan': + #upload entry to Commons + self.viewer.set_label('reviewing status: ' + row[0] + ' upload') + #if mime_type is activity - install it + mname = row[0] + '.metadata' + fname = row[0] + dst = COMMONSPATH / mname + pfx = SERIALNUMBER + '@schoolserver:' + src = LOCALPATH / mname + cmd = 'scp ' + src + ' ' + pfx + dst + print 'metadata upload', cmd + subprocess.call(cmd, shell=True) + src = LOCALPATH / fname + cmd = 'scp ' + src + ' ' + pfx + dst + print 'file upload', cmd subprocess.call(cmd, shell=True) #now remove - self.logger('now remove') - try: - ds_objects,num_objects = datastore.find(dict()) - except: - print 'datastore.find failed', sys.exc_info()[0] - num_objects = 0 - #self.logger(str(num_objects) + ', ' + str(len(remove_list))) - self.logger('datastore.find complete') - print 'remove_list', len(remove_list), remove_list - for i in xrange(0, num_objects, 1): - ds_objects[i].destroy() - obj = ds_objects[i].object_id - self.viewer.set_label('checking files ' + obj) - if str(obj) in remove_list: - datastore.delete(obj) - self.logger(obj + ' deleted') - txt = 'deleted ' + obj - self.viewer.set_label('checking files ' + obj + ' deleted') - #self.remove_alert(self.alert) - self.logger('done') - self.viewer.set_label('done') - return - - def logger(self, log): - l = '' - logpth = path('/tmp/log') - if logpth.exists(): - f = open(logpth,'r') - l = f.read() - f.close() - l = l + log + '\n' - if len(log) == 0: - l = '' - f = open(logpth, 'w') - f.write(l) + self.viewer.set_label('removing files ...') + + count = 0 + for obj in remove_list: + pth = LOCALPATH / obj + if pth.exists(): + pth.remove() + fn = obj + '.metadata' + pth = LOCALPATH / fn + if pth.exists(): + pth.remove() + #datastore.delete(obj) + count += 1 + txt = 'done ' + str(count) + ' files deleted' + self.viewer.set_label(txt) + + def show_properties(self, widget): + treeView = self.viewer.get_treeView() + treeselection = treeView.get_selection() + model, row = treeselection.get_selected() + obj = model[row][0] + fn = obj + '.metadata' + pth = LOCALPATH / fn + print 'on_activated:', pth + f = open(pth,'r') + metadata = eval(f.read()) f.close() + tstr = "" + for k, v in metadata.iteritems(): + try: + if len(str(v)) > 0: + tstr = tstr + k + ':' + v + '\n' + except: + tstr = tstr + k + ':' + "" + '\n' + self.viewer.label.set_text(tstr) + + def upload_commons(self, widget): + treeView = self.viewer.get_treeView() + treeselection = treeView.get_selection() + model, selection = treeselection.get_selected() + row = model[selection] + if row[4] == 'Green': + row[4] = 'cyan' + row[5] = 1 + # based on PyGTK tutorial by jan bodnar, zetcode.com, February 2009 class Listview(gtk.VBox): def __init__(self): @@ -225,6 +240,7 @@ class Listview(gtk.VBox): self.treeView = gtk.TreeView() self.treeView.connect("row-activated", self.on_activated) self.treeView.set_rules_hint(True) + self.treeView.show_all() sw.add(self.treeView) print 'create_columns' @@ -235,7 +251,7 @@ class Listview(gtk.VBox): print 'set up metadata display' self.label = gtk.Label("") self.label.show() - self.frame = gtk.Frame(label='metadata') + self.frame = gtk.Frame(label='Status') self.frame.add(self.label) self.frame.show() self.pack_start(self.frame, False, False, 0) @@ -247,6 +263,8 @@ class Listview(gtk.VBox): def set_label(self, txt): self.label.set_text(txt) + while gtk.events_pending(): + gtk.main_iteration(False) def create_model(self, tb): global online @@ -300,8 +318,13 @@ class Listview(gtk.VBox): #is this file already on the schoolserver? if f.namebase not in storelist and f.ext == '.metadata': m = open(f, 'r') - metadata = eval(m.read()) + mstr = m.read() m.close() + try: + metadata = eval(mstr) + except: + metadata = {} + print 'metadata eval failed', sys.exc_info()[0] obj = f.namebase try: title = metadata['title'] @@ -331,9 +354,26 @@ class Listview(gtk.VBox): fpath = LOCALPATH / obj if fpath.exists(): color = 'Red' + if mime_type == 'application/zip': + fn = metadata['filename'] + if fn.find('.smxo') > 0: + mime_type = 'application/x-smile' + if fn.find('.cpxo') > 0: + mime_type = 'application/x-classroompresenter' + if fn.find('.iqxo') > 0: + mime_type = 'application/x-imagequiz' + if not mime_type == 'application/zip': + metadata['mime_type'] = mime_type + mstr = repr(metadata) + m = open(f, 'w') + m.write(mstr) + m.close() + if metadata['activity'] == 'org.olenepal.DataManager': + color = 'White' else: color = 'White' store.append([obj, title, mime_type, date, color, 0]) + store.set_sort_column_id(3, gtk.SORT_DESCENDING) print 'return store' return store @@ -344,6 +384,10 @@ class Listview(gtk.VBox): treeView = self.get_treeView() soup = BeautifulSoup(response) entry_candidates = soup.findAll('a') + if source == "Blue": + base = COMMONSPATH + else: + base = STOREPATH / SERIALNUMBER for entry in entry_candidates: t = str(entry) pos = t.find('metadata') @@ -351,19 +395,25 @@ class Listview(gtk.VBox): pos2 = t.find('href=') obj = t[pos2+6:pos-1] fn = t[pos2+6:pos+8] - if source == "blue": - pth = COMMONSPATH / fn - else: - pth = STOREPATH / SERIALNUMBER / fn + pth = base / fn cmd = "scp " + SERIALNUMBER + "@schoolserver:" + pth cmd = cmd + " " + WORKPATH subprocess.call(cmd, shell=True) pth = WORKPATH / fn - f = open(pth, 'r') - t = f.read() - f.close() + if pth.exists(): + f = open(pth, 'r') + t = f.read() + f.close() + else: + print 'addentries: no f', f.name subprocess.call("rm -rf pth", shell=True) - metadata = eval(t) + try: + metadata = eval(t) + except: + print 'addentries eval failed', sys.exc_info()[0] + print 'addentries eval failed', f.name + print 'addentries eval failed', len(t), t + metadata = {} try: title = metadata['title'] except: @@ -371,12 +421,20 @@ class Listview(gtk.VBox): title = metadata['title:text'] except: title = '' - mime_type = metadata['mime_type'] - mtime = metadata['mtime'].replace('T',' ') - pos = mtime.find('.') - date = mtime[:pos] + try: + mime_type = metadata['mime_type'] + except: + mime_type = "" + try: + mtime = metadata['mtime'].replace('T',' ') + pos = mtime.find('.') + date = mtime[:pos] + except: + date = "" store.append([obj, title, mime_type, date, source, 0]) treeView.set_model(store) + treeView.scroll_to_cell(len(store)-1) + self.set_label(title) def create_columns(self, treeView): @@ -397,34 +455,34 @@ class Listview(gtk.VBox): column.set_sort_column_id(3) treeView.append_column(column) - def on_activated(self, widget, row, col): + def on_activated(self, widget, selection, col): #what we really want to do #is define a request to upload/remove/download an entry - print 'on_activated', widget, row, col model = widget.get_model() - obj = model[row][0] - fn = obj + '.metadata' - pth = LOCALPATH / fn - print 'on_activated:', pth - f = open(pth,'r') - metadata = eval(f.read()) - f.close() - - 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) - print 'on_activated', tstr + row = model[selection] + row4 = row[4] + row5 = row[5] + if row[4] == 'light green': + row[4] = 'Green' + row[5] = 2 + elif row[4] == 'cyan': + row[4] = 'Blue' + row[5] = 2 + elif row[4] == 'Green': + row[4] = 'light green' + row[5] = -1 + elif row[4] == 'Blue': + row[4] = 'cyan' + row[5] = -1 + print 'on_activiated', row[1], row4, '->', row[4], row5, '->', row[5] class UsageToolbar(gtk.Toolbar): def __init__(self, activity): global SERIALNUMBER + global MB + global PCT gtk.Toolbar.__init__(self) self.lbl1 = gtk.Label("XO ") @@ -453,9 +511,12 @@ class UsageToolbar(gtk.Toolbar): print 'df', len(t), t totalsize = t.split('\n') t1 = totalsize[1] + pos = t1.find('M') + MB = t1[pos-4:pos].strip() pos = t1.find('%') rslt = t1[pos-4:pos].strip() print 'rslt', float(rslt) * .01 + PCT = rslt self.fuelguage1.set_fraction(float(rslt) * .01) self.fuelguage1.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT) self.fuelguage1.show() @@ -490,12 +551,14 @@ class UsageToolbar(gtk.Toolbar): self.item2.add(self.fuelguage2) self.insert(self.item2, -1) - self.startbtn = ToolButton('btngo') - self.startbtn.connect('clicked', activity.start_cb) - self.startbtn.show() - self.insert(self.startbtn, -1) - - self.closebtn = ToolButton("btncancel") - self.closebtn.connect('clicked', activity.close_cb) - self.closebtn.show() - self.insert(self.closebtn, -1) + self.__infobtn = ToolButton('info') + self.__infobtn.set_tooltip("Show properties") + self.__infobtn.connect('clicked', activity.show_properties) + self.insert(self.__infobtn, -1) + self.__infobtn.show() + + self.__uploadbtn = ToolButton('up_arrow') + self.__uploadbtn.set_tooltip("Upload document to Commons") + self.__uploadbtn.connect('clicked', activity.upload_commons) + self.insert(self.__uploadbtn, -1) + self.__uploadbtn.show() diff --git a/icons/btncancel.png b/icons/btncancel.png deleted file mode 100755 index fb13ad5..0000000 --- a/icons/btncancel.png +++ /dev/null Binary files differ diff --git a/icons/btngo.png b/icons/btngo.png deleted file mode 100755 index b67609b..0000000 --- a/icons/btngo.png +++ /dev/null Binary files differ diff --git a/icons/info.svg b/icons/info.svg new file mode 100755 index 0000000..10cf3a8 --- /dev/null +++ b/icons/info.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/up_arrow.svg b/icons/up_arrow.svg new file mode 100644 index 0000000..4df2d33 --- /dev/null +++ b/icons/up_arrow.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + -- cgit v0.9.1