def from_string(self, string): """ Reads the entire experiment from a string. Arguments: string -- The definition string. """ debug.msg(u"building experiment") s = iter(string.split("\n")); line = next(s, None) while line != None: get_next = True try: l = self.split(line) except ValueError as e: raise exceptions.script_error( \ u"Failed to parse script. Maybe it contains illegal characters or unclosed quotes?") if len(l) > 0: self.parse_variable(line) # Parse definitions if l[0] == u"define": if len(l) != 3: raise exceptions.script_error( \ u"Failed to parse definition '%s'" \ % line) item_type = l[1] item_name = self.sanitize(l[2]) line, def_str = self.read_definition(s) get_next = False self.parse_definition(item_type, item_name, def_str) # Advance to next line if get_next: line = next(s, None)
def from_string(self, string): """ Reads an experiment from a string """ s = iter(string.split("\n")); line = next(s, None) while line != None: get_next = True try: l = shlex.split(line) except ValueError as e: raise exceptions.script_error("Failed to parse line '%s'. Maybe it contains illegal characters or unclosed quotes?" % line) if len(l) > 0: self.parse_variable(line) # Parse definitions if l[0] == "define": if len(l) != 3: raise exceptions.script_error("Failed to parse definition '%s'" % line) item_type = l[1] item_name = self.sanitize(l[2]) line, def_str = self.read_definition(s) get_next = False self.parse_definition(item_type, item_name, def_str) if get_next: line = next(s, None)
def parse_definition(self, item_type, item_name, string): """ Initialize a single definition, using the string, and add it to the dictionary of items Arguments: item_type -- the type of the item item_name -- the name of the item string -- the string containing the definition """ if plugins.is_plugin(item_type): # Load a plug-in if debug.enabled: debug.msg(u"loading plugin '%s'" % item_type) item = plugins.load_plugin(item_type, item_name, self, string, \ self.item_prefix()) else: try: item = plugins.load_plugin(item_type, item_name, self, \ string, self.item_prefix()) except: raise exceptions.script_error(u"Failed load plugin '%s'" % \ item_type) self.items[item_name] = item else: # Load the module from the regular items debug.msg(u"loading core plugin '%s'" % item_type) if debug.enabled: exec("from %s import %s" % (self.module_container(), item_type)) try: if not self.debug: exec("from %s import %s" % (self.module_container(), \ item_type)) except: raise exceptions.script_error( \ u"Failed to import item '%s' as '%s'. " \ % (item_type, item_name) + "Perhaps the experiment requires a plug-in that is not available on your system.", \ full=False) cmd = '%(item_type)s.%(item_type)s("%(item_name)s", self, u"""%(string)s""")' \ % {"item_type" : item_type, "item_name" : item_name, "string" \ : string.replace(u'"', u'\\"')} if debug.enabled: bytecode = compile(cmd, "<string>", "eval") self.items[item_name] = eval(bytecode) else: try: bytecode = compile(cmd, "<string>", "eval") self.items[item_name] = eval(bytecode) except Exception as e: raise exceptions.script_error( \ u"Failed to instantiate module '%s' as '%s': %s" % \ (item_type, item_name, e))
def parse_variable(self, line): """ Reads a single variable from a single definition line Arguments: line -- a single definition line Returns: True on succes, False on failure """ # It is a little ugly to call parse_comment() here, but otherwise # all from_string() derivatives need to be modified if self.parse_comment(line): return True l = self.split(line.strip()) try: l = self.split(line.strip()) except Exception as e: raise exceptions.script_error( \ u"Error parsing '%s' in item '%s': %s" % (line, self.name, e)) if len(l) > 0 and l[0] == u'set': if len(l) != 3: raise exceptions.script_error( \ u"Error parsing variable definition: '%s'" % line) else: self.set(l[1], l[2]) return True return False
def from_string(self, string): """ Reads the entire experiment from a string. Arguments: string -- The definition string. """ debug.msg(u"building experiment") s = iter(string.split("\n")) line = next(s, None) while line != None: get_next = True try: l = self.split(line) except ValueError as e: raise exceptions.script_error( \ u"Failed to parse script. Maybe it contains illegal characters or unclosed quotes?") if len(l) > 0: self.parse_variable(line) # Parse definitions if l[0] == u"define": if len(l) != 3: raise exceptions.script_error( \ u"Failed to parse definition '%s'" \ % line) item_type = l[1] item_name = self.sanitize(l[2]) line, def_str = self.read_definition(s) get_next = False self.parse_definition(item_type, item_name, def_str) # Advance to next line if get_next: line = next(s, None)
def parse_definition(self, item_type, item_name, string): """ Initializes a single definition, using the string, and adds it to the dictionary of items. Arguments: item_type -- The item's type. item_name -- The item's name. string -- The item's definition string. """ if plugins.is_plugin(item_type): # Load a plug-in if debug.enabled: debug.msg(u"loading plugin '%s'" % item_type) item = plugins.load_plugin(item_type, item_name, self, string, \ self.item_prefix()) else: try: item = plugins.load_plugin(item_type, item_name, self, \ string, self.item_prefix()) except: raise exceptions.script_error(u"Failed load plugin '%s'" % \ item_type) self.items[item_name] = item else: # Load one of the core items debug.msg(u"loading core item '%s' from '%s'" % (item_type, \ self.module_container())) item_module = __import__(u'%s.%s' % (self.module_container(), \ item_type), fromlist=[u'dummy']) item_class = getattr(item_module, item_type) item = item_class(item_name, self, string) self.items[item_name] = item
def parse_rect_ellipse(self, line, l, item, item_type): """ Parse a rectangle Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish item_type -- type of the current item Returns: A finished sketchpad element """ if len(l) < 6: raise exceptions.script_error( "Invalid draw %s command '%s', expecting 'draw %s [x] [y] [w] [h]'" % (item_type, line, item_type) ) item["type"] = item_type item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["w"] = self.auto_type(l[4]) item["h"] = self.auto_type(l[5]) return item
def parse_line_arrow(self, line, l, item, item_type): """ Parse a line or arrow Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish item_type -- type of the current item Returns: A finished sketchpad element """ if len(l) < 6: raise exceptions.script_error("Invalid draw %s command '%s', expecting 'draw %s [x1] [y1] [x2] [y2]'" \ % (item_type, line, item_type)) item["type"] = item_type item["x1"] = self.auto_type(l[2]) item["y1"] = self.auto_type(l[3]) item["x2"] = self.auto_type(l[4]) item["y2"] = self.auto_type(l[5]) return item
def parse_circle(self, line, l, item): """ Parse a circle Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish Returns: A finished sketchpad element """ if len(l) < 5: raise exceptions.script_error( "Invalid draw circle command '%s', expecting 'draw circle [x] [y] [r]'" % line ) item["type"] = "circle" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["r"] = self.auto_type(l[4]) return item
def color_check(self, col): """<DOC> Checks whether a string is a valid color name Example: >>> # Ok >>> print self.color_check('red') >>> # Ok >>> print self.color_check('#FFFFFF') >>> # Raises runtime_error >>> print self.color_check('this is not a color') Arguments: col -- the color to check Exceptions: Raises a runtime_error if col is not a valid color </DOC>""" try: if type(col) == unicode: col = str(col) pygame.Color(col) except Exception as e: raise exceptions.script_error( \ u"'%s' is not a valid color. See http://www.w3schools.com/html/html_colornames.asp for an overview of valid color names" \ % self.unistr(col))
def color_check(self, col): """<DOC> Checks whether a string is a valid color name. Arguments: col -- The color to check. Exceptions: Raises a runtime_error if col is not a valid color. Example: >>> # Ok >>> print self.color_check('red') >>> # Ok >>> print self.color_check('#FFFFFF') >>> # Raises runtime_error >>> print self.color_check('this is not a color') </DOC>""" try: if type(col) == unicode: col = str(col) pygame.Color(col) except Exception as e: raise exceptions.script_error( \ u"'%s' is not a valid color. See http://www.w3schools.com/html/html_colornames.asp for an overview of valid color names" \ % self.unistr(col))
def parse_line(self, line): """ Allows for arbitrary line parsing, for item-specific requirements Arguments: line -- a single definition line """ l = self.split(line.strip()) if len(l) < 6 or l[0] != 'widget': return # Verify that the position variables are integers try: col = int(l[1]) row = int(l[2]) colspan = int(l[3]) rowspan = int(l[4]) except: raise exceptions.script_error( \ _('Widget column and row should be numeric')) # Parse the widget into a dictionary and store it in the list of # widgets w = self.parse_keywords(line) w['type'] = l[5] w['col'] = col w['row'] = row w['colspan'] = colspan w['rowspan'] = rowspan self._widgets.append(w)
def parse_image(self, line, l, item): """ Parse image Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish Returns: A finished sketchpad element """ if len(l) < 3: raise exceptions.script_error("Invalid draw image command '%s', expecting 'draw image [x] [y] [file]' or 'draw textline [file]'" \ % line) item["type"] = u"image" try: item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["file"] = l[4] except: item["x"] = self.get("width") / 2 item["y"] = self.get("height") / 2 item["file"] = l[2] return item
def parse_image(self, line, l, item): """ Parse image Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish Returns: A finished sketchpad element """ if len(l) < 3: raise exceptions.script_error("Invalid draw image command '%s', expecting 'draw image [x] [y] [file]' or 'draw textline [file]'" \ % line) item["type"] = "image" try: item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["file"] = l[4] except: item["x"] = self.get("width") / 2 item["y"] = self.get("height") / 2 item["file"] = l[2] return item
def from_string(self, string): """ Read a sketchpad from string Arguments: string -- the unicode string containing the sketchpad definition """ for line in string.split(u'\n'): if not self.parse_variable(line): l = self.split(line) if len(l) > 0: if l[0] == u'draw': if len(l) == 1: raise exceptions.script_error( \ "Incomplete draw command '%s'" % line) item = self.parse_item(l, line) if l[1] in ("circle",): item = self.parse_circle(line, l, item) elif l[1] in ("rectangle", "rect"): item = self.parse_rect_ellipse(line, l, item, \ "rect") elif l[1] in ("fixdot", "fixation"): item = self.parse_fixdot(line, l, item) elif l[1] in ("ellipse", "oval"): item = self.parse_rect_ellipse(line, l, item, \ "ellipse") elif l[1] in ("arrow",): item = self.parse_line_arrow(line, l, item, "arrow") elif l[1] in ("line",): item = self.parse_line_arrow(line, l, item, "line") elif l[1] in ("textline",): item = self.parse_textline(line, l, item) elif l[1] in ("image", "bitmap"): item = self.parse_image(line, l, item) elif l[1] in ("gabor"): item = self.parse_gabor(line, l, item) elif l[1] in ("noise"): item = self.parse_noise(line, l, item) else: raise exceptions.script_error( \ "Unknown draw command '%s'" % line) self.items.append(item) else: raise exceptions.script_error("Unknown command '%s'" \ % line)
def from_string(self, string): """ Read a sketchpad from string Arguments: string -- the unicode string containing the sketchpad definition """ for line in string.split(u'\n'): if not self.parse_variable(line): l = self.split(line) if len(l) > 0: if l[0] == u'draw': if len(l) == 1: raise exceptions.script_error( \ "Incomplete draw command '%s'" % line) item = self.parse_item(l, line) if l[1] in ("circle", ): item = self.parse_circle(line, l, item) elif l[1] in ("rectangle", "rect"): item = self.parse_rect_ellipse(line, l, item, \ "rect") elif l[1] in ("fixdot", "fixation"): item = self.parse_fixdot(line, l, item) elif l[1] in ("ellipse", "oval"): item = self.parse_rect_ellipse(line, l, item, \ "ellipse") elif l[1] in ("arrow", ): item = self.parse_line_arrow( line, l, item, "arrow") elif l[1] in ("line", ): item = self.parse_line_arrow(line, l, item, "line") elif l[1] in ("textline", ): item = self.parse_textline(line, l, item) elif l[1] in ("image", "bitmap"): item = self.parse_image(line, l, item) elif l[1] in ("gabor"): item = self.parse_gabor(line, l, item) elif l[1] in ("noise"): item = self.parse_noise(line, l, item) else: raise exceptions.script_error( \ "Unknown draw command '%s'" % line) self.items.append(item) else: raise exceptions.script_error("Unknown command '%s'" \ % line)
def from_string(self, string): """ Read a sketchpad from string """ for line in string.split("\n"): if not self.parse_variable(line): l = shlex.split(line) if len(l) > 0: if l[0] == "draw": item = self.parse_item(l) if l[1] in ("circle", ): item = self.parse_circle(line, l, item) elif l[1] in ("rectangle", "rect"): item = self.parse_rect_ellipse( line, l, item, "rect") elif l[1] in ("fixdot", "fixation"): item = self.parse_fixdot(line, l, item) elif l[1] in ("ellipse", "oval"): item = self.parse_rect_ellipse( line, l, item, "ellipse") elif l[1] in ("arrow", ): item = self.parse_line_arrow( line, l, item, "arrow") elif l[1] in ("line", ): item = self.parse_line_arrow(line, l, item, "line") elif l[1] in ("textline", ): item = self.parse_textline(line, l, item) elif l[1] in ("image", "bitmap"): item = self.parse_image(line, l, item) elif l[1] in ("gabor"): item = self.parse_gabor(line, l, item) elif l[1] in ("noise"): item = self.parse_noise(line, l, item) else: raise exceptions.script_error( "Unknown draw command '%s'" % line) self.items.append(item) else: raise exceptions.script_error("Unknown command '%s'" % line)
def parse_definition(self, item_type, item_name, string): """ Initialize a single definition, using the string, and add it to the dictionary of items """ if plugins.is_plugin(item_type): if self.debug: print "experiment.parse_definition(): loading plugin '%s'" % item_type try: item = plugins.load_plugin(item_type, item_name, self, string, self.item_prefix()) except: raise exceptions.script_error("Failed load plugin '%s'" % item_type) self.items[item_name] = item else: # Load the module from the regular items if self.debug: print "experiment.parse_definition(): loading core plugin '%s'" % item_type if self.debug: exec("from %s import %s" % (self.module_container(), item_type)) try: if not self.debug: exec("from %s import %s" % (self.module_container(), item_type)) except: raise exceptions.script_error("Failed to import module '%s' as '%s'" % (item_type, item_name)) cmd = "%(item_type)s.%(item_type)s(\"%(item_name)s\", self, \"\"\"%(string)s\"\"\")" % \ {"item_type" : item_type, "item_name" : item_name, "string" : string.replace("\"", "\\\"")} if self.debug: bytecode = compile(cmd, "<string>", "eval") self.items[item_name] = eval(bytecode) else: try: bytecode = compile(cmd, "<string>", "eval") self.items[item_name] = eval(bytecode) except Exception as e: raise exceptions.script_error("Failed to instantiate module '%s' as '%s': %s" % (item_type, item_name, e))
def from_string(self, string): """ Read a sketchpad from string """ for line in string.split("\n"): if not self.parse_variable(line): l = shlex.split(line) if len(l) > 0: if l[0] == "draw": item = self.parse_item(l) if l[1] in ("circle",): item = self.parse_circle(line, l, item) elif l[1] in ("rectangle", "rect"): item = self.parse_rect_ellipse(line, l, item, "rect") elif l[1] in ("fixdot", "fixation"): item = self.parse_fixdot(line, l, item) elif l[1] in ("ellipse", "oval"): item = self.parse_rect_ellipse(line, l, item, "ellipse") elif l[1] in ("arrow",): item = self.parse_line_arrow(line, l, item, "arrow") elif l[1] in ("line",): item = self.parse_line_arrow(line, l, item, "line") elif l[1] in ("textline",): item = self.parse_textline(line, l, item) elif l[1] in ("image", "bitmap"): item = self.parse_image(line, l, item) elif l[1] in ("gabor"): item = self.parse_gabor(line, l, item) elif l[1] in ("noise"): item = self.parse_noise(line, l, item) else: raise exceptions.script_error("Unknown draw command '%s'" % line) self.items.append(item) else: raise exceptions.script_error("Unknown command '%s'" % line)
def parse_noise(self, line, l, item): """ Parse Gabor patch """ if len(l) < 4: raise exceptions.script_error("Invalid draw image command '%s', expecting 'draw noise [x] [y]'" % line) item["type"] = "noise" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) return item
def parse_noise(self, line, l, item): """ Parse Gabor patch """ if len(l) < 4: raise exceptions.script_error( "Invalid draw image command '%s', expecting 'draw noise [x] [y]'" % line) item["type"] = "noise" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) return item
def parse_circle(self, line, l, item): """ Parse a circle """ if len(l) < 5: raise exceptions.script_error("Invalid draw circle command '%s', expecting 'draw circle [x] [y] [r]'" % line) item["type"] = "circle" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["r"] = self.auto_type(l[4]) return item
def color_check(self, s): """<DOC> Checks whether a string is a valid color name Arguments: s -- the string to check Returns: True i the string is a color, False otherwise </DOC>""" try: pygame.Color(s) except: raise exceptions.script_error("'%s' is not a valid color. See http://www.w3schools.com/html/html_colornames.asp for an overview of valid color names" % s)
def parse_circle(self, line, l, item): """ Parse a circle """ if len(l) < 5: raise exceptions.script_error( "Invalid draw circle command '%s', expecting 'draw circle [x] [y] [r]'" % line) item["type"] = "circle" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["r"] = self.auto_type(l[4]) return item
def color_check(self, s): """<DOC> Checks whether a string is a valid color name Arguments: s -- the string to check Returns: True i the string is a color, False otherwise </DOC>""" try: pygame.Color(s) except: raise exceptions.script_error( \ "'%s' is not a valid color. See http://www.w3schools.com/html/html_colornames.asp for an overview of valid color names" \ % s)
def parse_line_arrow(self, line, l, item, item_type): """ Parse a line or arrow """ if len(l) < 6: raise exceptions.script_error("Invalid draw %s command '%s', expecting 'draw %s [x1] [y1] [x2] [y2]'" % (item_type, line, item_type)) item["type"] = item_type item["x1"] = self.auto_type(l[2]) item["y1"] = self.auto_type(l[3]) item["x2"] = self.auto_type(l[4]) item["y2"] = self.auto_type(l[5]) return item
def parse_rect_ellipse(self, line, l, item, item_type): """ Parse a rectangle """ if len(l) < 6: raise exceptions.script_error("Invalid draw %s command '%s', expecting 'draw %s [x] [y] [w] [h]'" % (item_type, line, item_type)) item["type"] = item_type item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["w"] = self.auto_type(l[4]) item["h"] = self.auto_type(l[5]) return item
def parse_line_arrow(self, line, l, item, item_type): """ Parse a line or arrow """ if len(l) < 6: raise exceptions.script_error( "Invalid draw %s command '%s', expecting 'draw %s [x1] [y1] [x2] [y2]'" % (item_type, line, item_type)) item["type"] = item_type item["x1"] = self.auto_type(l[2]) item["y1"] = self.auto_type(l[3]) item["x2"] = self.auto_type(l[4]) item["y2"] = self.auto_type(l[5]) return item
def parse_rect_ellipse(self, line, l, item, item_type): """ Parse a rectangle """ if len(l) < 6: raise exceptions.script_error( "Invalid draw %s command '%s', expecting 'draw %s [x] [y] [w] [h]'" % (item_type, line, item_type)) item["type"] = item_type item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["w"] = self.auto_type(l[4]) item["h"] = self.auto_type(l[5]) return item
def parse_image(self, line, l, item): """ Parse image """ if len(l) < 3: raise exceptions.script_error("Invalid draw image command '%s', expecting 'draw image [x] [y] [file]' or 'draw textline [file]'" % line) item["type"] = "image" try: item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["file"] = l[4] except: item["x"] = self.get("width") / 2 item["y"] = self.get("height") / 2 item["file"] = l[2] return item
def parse_noise(self, line, l, item): """ Parse noise patch Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish Returns: A finished sketchpad element """ if len(l) < 4: raise exceptions.script_error("Invalid draw image command '%s', expecting 'draw noise [x] [y]'" % line) item["type"] = "noise" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) return item
def parse_noise(self, line, l, item): """ Parse noise patch Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish Returns: A finished sketchpad element """ if len(l) < 4: raise exceptions.script_error("Invalid draw image command '%s', expecting 'draw noise [x] [y]'" \ % line) item["type"] = "noise" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) return item
def parse_gabor(self, line, l, item): """ Parse Gabor patch Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish Returns: A finished sketchpad element """ if len(l) < 4: raise exceptions.script_error("Invalid draw image command '%s', expecting 'draw gabor [x] [y] [orient] [freq]'" \ % line) item["type"] = u"gabor" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) return item
def parse_image(self, line, l, item): """ Parse image """ if len(l) < 3: raise exceptions.script_error( "Invalid draw image command '%s', expecting 'draw image [x] [y] [file]' or 'draw textline [file]'" % line) item["type"] = "image" try: item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["file"] = l[4] except: item["x"] = self.get("width") / 2 item["y"] = self.get("height") / 2 item["file"] = l[2] return item
def split(self, u): """ Splits a unicode string in the same way as shlex.split(). Unfortunately, shlex doesn't handle unicode properly, so this wrapper function is required. Arguments: u -- a unicode string Returns: A list of unicode strings, split as described here: http://docs.python.org/library/shlex.html#shlex.split """ import shlex try: return [chunk.decode(self.encoding) for chunk in shlex.split( \ u.encode(self.encoding))] except: raise exceptions.script_error( \ u'Failed to parse line "%s". Is there a closing quotation missing?' \ % u)
def parse_rect_ellipse(self, line, l, item, item_type): """ Parse a rectangle Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish item_type -- type of the current item Returns: A finished sketchpad element """ if len(l) < 6: raise exceptions.script_error("Invalid draw %s command '%s', expecting 'draw %s [x] [y] [w] [h]'" \ % (item_type, line, item_type)) item["type"] = item_type item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["w"] = self.auto_type(l[4]) item["h"] = self.auto_type(l[5]) return item
def parse_circle(self, line, l, item): """ Parse a circle Arguments: line -- a definition line l -- a definition list item -- sketchpad element to finish Returns: A finished sketchpad element """ if len(l) < 5: raise exceptions.script_error("Invalid draw circle command '%s', expecting 'draw circle [x] [y] [r]'" \ % line) item["type"] = "circle" item["x"] = self.auto_type(l[2]) item["y"] = self.auto_type(l[3]) item["r"] = self.auto_type(l[4]) return item