diff options
Diffstat (limited to 'plugins/make.py')
-rwxr-xr-x | plugins/make.py | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/plugins/make.py b/plugins/make.py new file mode 100755 index 0000000..e6f6189 --- /dev/null +++ b/plugins/make.py @@ -0,0 +1,422 @@ +__PLUGIN_NAME__ = 'make' + +''' + List of Services: + - ImageQuiz.py, Line 37: "Hook-In Services" + - http://wiki.laptop.org/index.php?title=XO_ImageQuiz/Plugins#Overview +''' + +import os, sys + +import pygame +from pygame.locals import * + +from sugar.activity import activity + +# the following line is not needed if pgu is installed +import sys; sys.path.insert(0, "..") + +from pgu import gui + +import pygst +pygst.require("0.10") +import gst + +import ink + +from path import path + +#set up paths to for adding images and sounds +DATAPATH = os.path.join(activity.get_activity_root(), "data") +ACTIVITYPATH = activity.get_bundle_path() +IMAGEPATH = os.path.join(DATAPATH, 'image') +SOUNDPATH = os.path.join(DATAPATH, 'sound') + +clock = pygame.time.Clock() + +class CurrentQuestion: + id = 0 + prompt = u'' + response = u'' + imgfn = u'' + sndfn = u'' + map = u'' + answer_link = u'' + +class EditDialog(gui.Dialog): + def __init__(self, editsave, cq): + max = 100 + title = gui.Label("Edit Question") + + t = gui.Table() + self.form = gui.Form() + + t.tr() + print 'cq.imgfn', len(cq.imgfn.split()), len(cq.imgfn), cq.imgfn + imgpath = path(IMAGEPATH) / 'blank.png' + if len(cq.imgfn) > 0: + temp = path(IMAGEPATH) / cq.imgfn + if temp.exists(): + imgpath = temp + print 'load image', imgpath.exists(), imgpath + self.img = pygame.image.load(imgpath) + t.td(gui.Image(self.img), align=-1, valign=-1, colspan = 8) + + if len(cq.map) > 0: + self.draw_map(cq.map) + + print 'table', t.getRows(), t.getColumns(), t.resize() + + t.tr() + t.td(gui.Label("")) + + t.tr() + t.td(gui.Label("Image: "), align = -1) + t.td(gui.Input(name = 'image', value = cq.imgfn, size = len(cq.imgfn) + 10), align = -1, colspan = 3) + imgBrowseButton = gui.Button("Browse...") + imgBrowseButton.connect(gui.CLICK, imgbrowse, cq) + t.td(imgBrowseButton) + + print 'table0', t.getRows(), t.getColumns(), t.resize() + + t.tr() + t.td(gui.Label("Clip: "), align = -1) + print 'clip', len(cq.sndfn), cq.sndfn + t.td(gui.Input(name = 'sound', value = cq.sndfn, size = len(cq.sndfn) + 10), align = -1, colspan = 3) + clipBrowseButton = gui.Button("Browse...") + clipBrowseButton.connect(gui.CLICK, clipbrowse, cq) + t.td(clipBrowseButton) + clipBrowseButton = gui.Button("Record") + clipBrowseButton.connect(gui.CLICK, record, cq) + t.td(clipBrowseButton) + clipBrowseButton = gui.Button("Stop") + clipBrowseButton.connect(gui.CLICK, stop, cq) + t.td(clipBrowseButton) + clipBrowseButton = gui.Button("Play") + clipBrowseButton.connect(gui.CLICK, play, cq) + t.td(clipBrowseButton) + + print 'table1', t.getRows(), t.getColumns(), t.resize() + + t.tr() + t.td(gui.Label("Prompt: "), align = -1) + sz = len(cq.prompt) + 10 + if sz > max: + sz = max + print 'prompt', sz, len(cq.prompt), cq.prompt + t.td(gui.Input(name = 'prompt', value = cq.prompt, size = sz), align = -1, colspan=6) + + print 'table2', t.getRows(), t.getColumns(), t.resize() + + t.tr() + t.td(gui.Label("Response: "), align = -1) + sz = len(cq.response) + 10 + if sz > max: + sz = max + print 'response',sz, len(cq.response), cq.response + t.td(gui.Input(name = 'response', value = cq.response, size = sz), align = -1, colspan=6) + + print 'table3', t.getRows(), t.getColumns(), t.resize() + + t.tr() + t.td(gui.Label("Answer_link: "), align = -1) + sz = len(cq.answer_link) + 10 + if sz > max: + sz = max + print 'answer_link', sz, len(cq.answer_link), cq.answer_link + t.td(gui.Input(name = 'answer_link', value = cq.answer_link, size = sz), align = -1, colspan=7) + + print 'table4', t.getRows(), t.getColumns(), t.resize() + + t.tr() + t.td(gui.Label("")) + + t.tr() + saveButton = gui.Button("Save") + saveButton.connect(gui.CLICK, editsave, cq) + t.td(saveButton,colspan=3) + + self.t = t + print 'tablef', self.t.getRows(), self.t.getColumns(), self.t.resize() + gui.Dialog.__init__(self,title,self.t) + + def draw_map(self, map): + color = (100,0,0) + pen = 4 + pts = [] + coords = [] + maplst = map.split(',') + for pt in maplst: + try: + coords.append(int(pt)) + except: + pass + i = 0 + while i < len(coords): + pts.append((coords[i],coords[i+1])) + i += 2 + pygame.draw.lines(self.img, color, True, pts, pen) + +def clickOnMake(): + # Select Category + cat_id = -1 + sf.clear_text_items() + sf.clear_question_frame(True) + print 'ask_category', cat_id + ask_category(cat_id) + +def ask_category(cat_id, offset_y = 0): + global c + global new_cat + + i = 1 + y = 110 + offset_y + + sf.clear_text_items() + sf.add_text_item("Next Category:", (280,y)) + + + new_cat = gui.Input(value="new", size = 20) + new_cat.connect(gui.ENTER,add_cat, 0) + c.add(new_cat, 0, 0) + app = sf.app() + app.init(c) + + + #first we need to query for categories + #might be nice to show them in alphabetical order + #when y gets too big, we should change x + if cat_id == -1: + cats = __SERVICES__.db.query("SELECT id, text FROM categories;") + print 'cats', len(cats), cats + for cat in cats: + print 'cat', cat[0], cat[1] + cat_id = cat[0] + category = cat[1] + try: + q = 'SELECT count(*) FROM quizlink WHERE quiz_id=%i' % cat_id + res1 = __SERVICES__.db.query(q) + except: + print 'query error', q + count = res1[0][0] + print 'count=', count + if count > 0: + # this is a quiz, display in green + y += 50 + sf.add_text_item("%s (%s)" % (category, count), (300,y), ask_question, cat_id) + else: + # this is a category - get number of children + q = 'SELECT count(*) FROM catlink WHERE parent_id=%i' % cat_id + res2 = __SERVICES__.db.query(q) + count = res2[0][0] + y += 50 + sf.add_text_item("%s (%s)" % (category, count), (300,y), ask_category, cat_id) + i += 1 + else: + #we need to pass a cat_id from the user's selection + print 'second level selection not implemented - must select quiz' + +def add_cat(params): + global new_cat + global CATID + #add cat to db with new_cat.value as text + CATID= __SERVICES__.db.add_cat(new_cat.value) + #create empty question to pass to startedit + cq = CurrentQuestion() + cq.id = -1 + cq.prompt = "" + cq.response = "" + cq.imgfn = "" + cq.sndfn = "" + cq.map = "" + cq.answer_link = "" + startedit(cq) + +def ask_question(cat_id, offset_y = 0): + global CATID + + print 'ask_question', cat_id, offset_y + + i = 1 + y = 110 + offset_y + CATID = cat_id + + + sf.clear_text_items() + sf.add_text_item("Select question:", (280,y)) + + #we need to query for questions + #when y gets too big, we should change x + try: + q = 'SELECT question_id FROM quizlink WHERE quiz_id=%i' % cat_id + print 'query=', q + res = __SERVICES__.db.query(q) + except: + print 'failure in query', q + print 'res', len(res), res + + count = 0 + for question in res: + count += 1 + try: + q = 'SELECT prompt, response, image_fn, sound_fn, map, answer_link FROM questions WHERE id = %i' % question[0] + print 'query=', q + res2 = __SERVICES__.db.query(q) + except: + print 'error in query', q + print 'res2', len(res2), res2 + res1 = res2[0] + cq = CurrentQuestion() + cq.id = question[0] + cq.prompt = res1[0] + cq.response = res1[1] + cq.imgfn = res1[2] + cq.sndfn = res1[3] + cq.map = res1[4] + cq.answer_link = res1[5] + if len(cq.imgfn) > 0: + ipath = path(IMAGEPATH) /cq.imgfn + if len(cq.imgfn)>0 and ipath.exists(): + y += 50 + image, xy = sf.image_load(ipath) + sf.display_surface(pygame.transform.scale(image,(128,128)), (300,y)) + y += 128 + if len(cq.prompt.strip()) > 0: + sf.add_text_item(cq.prompt,(300,y),startedit, cq) + else: + sf.add_text_item(cq.imgfn,(300,y),startedit, cq) + elif len(cq.prompt.strip()) > 0: + y += 50 + sf.add_text_item(cq.prompt,(300,y),startedit, cq) + else: + y += 50 + sf.add_text_item(cq.sndfn,(300,y), startedit, cq) + +def startedit(question, offset_y = 0): + global edit_d + + cq = question + + #if len(cq.imgfn) > 0 and path(cq.imgfn).exists: + #display cq.imgfn + #else: + #display 'no image' image + #display cq.imgfn entry as caption + #display audio controls (right of sound entry) + #if not (len(cq.imgfn) > 0 and path(cq.imgfn).exists()): + #grey 'play' control + #if len(cq.sndfn) > 0 and path(cq.sndfn) exists(): + #display audio controls (to right of sound entry) + #if sound recorded, ungrey 'play' control + #if sound path changed, reset 'play' control depending on whether path exists + + + i = 1 + print 'i=', i + y = 110 + offset_y + print 'y=', y + + print 'clear text items' + sf.clear_text_items() + + edit_d = EditDialog(editsave, cq) + edit_d.open() + +def editsave(cq): + global CATID + global edit_d + + form = edit_d.form + cq.prompt = form['prompt'].value + cq.response = form['response'].value + cq.imgfn = form['image'].value + cq.sndfn = form['sound'].value + cq.answer_link = form['answer_link'].value + + #if a new question, it needs to be inserted into database + #insert question + #add quizlink with quiz id and question id + + #insert updated question into database + q = "UPDATE questions SET prompt='%s' WHERE id=%i" % (cq.prompt, cq.id) + updatedb(q) + q = "UPDATE questions SET response = '%s' WHERE id = %i" % (cq.response, cq.id) + updatedb(q) + q = "UPDATE questions SET image_fn = '%s' WHERE id = %i" % (cq.imgfn, cq.id) + updatedb(q) + q = "UPDATE questions SET sound_fn = '%s' WHERE id = %i" % (cq.sndfn, cq.id) + updatedb(q) + q = "UPDATE questions SET map = '%s' WHERE id = %i" % (cq.map, cq.id) + updatedb(q) + q = "UPDATE questions SET answer_link = '%s' WHERE id = %i" % (cq.answer_link, cq.id) + updatedb(q) + + edit_d.close() + print 'edit_d closed', edit_d.t.getRows(), edit_d.t.getColumns() + edit_d.t.clear() + print 'edit_d closed and table cleared', edit_d.t.getRows(), edit_d.t.getColumns() + cat_id = CATID + ask_question(cat_id) + +def updatedb(q): + print 'updatedb' + __SERVICES__.db.commit(q) + +def imgbrowse(cq): + print 'imgbrowse not implemented' + +def clipbrowse(cq): + print 'clipbrowse not implemented' + +def record(cq): + global player + global fileout + fileout.set_property("location", os.path.join(SOUNDPATH, cq.sndfn)) + print player.get_state() + player.set_state(gst.STATE_PLAYING) + +def stop(cq): + player.set_state(gst.STATE_READY) + pygame.mixer.stop() + +def play(cq): + sound = sf.sound_load(os.path.join(SOUNDPATH, cq.sndfn)) + sound.play() + while pygame.mixer.get_busy(): + clock.tick(30) + +def debug(): + pass + +def load(): + global sf + global player + global fileout + global c + sf = __SERVICES__.frontend + #print __SERVICES__.db.query("SELECT text FROM categories") + #sf.add_menu_dir('/demodir', 'Demo Directory') + sf.add_menu_item('/', 'Make', clickOnMake) + #initialize audio record pipeline + player = gst.Pipeline("player") + source = gst.element_factory_make("alsasrc", "alsa-source") + player.add(source) + convert = gst.element_factory_make("audioconvert", "converter") + player.add(convert) + enc = gst.element_factory_make("vorbisenc", "vorbis-encoder") + player.add(enc) + create = gst.element_factory_make("oggmux", "ogg-create") + player.add(create) + fileout = gst.element_factory_make("filesink", "sink") + fileout.set_property("location", "test.ogg") + player.add(fileout) + gst.element_link_many(source, convert, enc, create, fileout) + + + #intialize gui + c = gui.Container(width = 400, height = 600) + app = sf.get_app() + app.init(c) + +def close(): + pass |