__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