Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/plugins/make.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/make.py')
-rwxr-xr-xplugins/make.py422
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