Exemplo n.º 1
0
class MacDef(structure.Structure):
    """A macro definition within an RD.

	The macro defined is available on the parent.
	"""
    name_ = "macDef"

    _name = attrdef.UnicodeAttribute("name",
                                     description="Name the macro"
                                     " will be available as",
                                     copyable=True,
                                     default=utils.Undefined)
    _content = structure.DataContent(description="Replacement text of the"
                                     " macro")

    def validate(self):
        self._validateNext(MacDef)
        if len(self.name) < 2:
            raise common.LiteralParseError(
                "name",
                self.name,
                hint="Macro names must have at least two characters.")

    def onElementComplete(self):
        self._onElementCompleteNext(MacDef)

        def mac():
            return self.content_

        setattr(self.parent, "macro_" + self.name, mac)
Exemplo n.º 2
0
    def getAttribute(self, name):
        try:
            return DelayedReplayBase.getAttribute(self, name)
        except common.StructureError:  # no "real" attribute, it's a macro def

            def m():
                return getattr(self, name)

            setattr(self, "macro_" + name.strip(), m)
            self.managedAttrs[name] = attrdef.UnicodeAttribute(name)
            return self.managedAttrs[name]
Exemplo n.º 3
0
 def __init__(self,
              name,
              default=[],
              itemAttD=attrdef.UnicodeAttribute("listItem"),
              **kwargs):
     attrdef.AttributeDef.__init__(self,
                                   name,
                                   default=attrdef.Computed,
                                   **kwargs)
     self.xmlName_ = itemAttD.name_
     self.itemAttD = itemAttD
     self.realDefault = default
Exemplo n.º 4
0
 def __init__(self,
              name,
              description="Undocumented",
              itemAttD=attrdef.UnicodeAttribute("value"),
              keyName="key",
              inverted=False,
              **kwargs):
     attrdef.AttributeDef.__init__(self, name, attrdef.Computed,
                                   description, **kwargs)
     self.xmlName_ = itemAttD.name_
     self.itemAttD = itemAttD
     self.keyName = keyName
     self.inverted = inverted
class DBProfile(structure.Structure):
	"""is a profile for DB access.
	"""
	name_ = "dbProfile"
	profileName = "anonymous"

	_name = attrdef.UnicodeAttribute("name", default=attrdef.Undefined,
		description="An identifier for this profile")
	_host = attrdef.UnicodeAttribute("host", default="", description="Host"
		" the database runs on")
	_port = attrdef.IntAttribute("port", default=None, description=
		"Port the DB server listens on")
	_database = attrdef.UnicodeAttribute("database", default=attrdef.Undefined,
		description="Name of the database to connect to")
	_user = attrdef.UnicodeAttribute("user", default="", description=
		"User to log into DB as")
	_pw = attrdef.UnicodeAttribute("password", default="", description=
		"Password for user")
	_sslmode = attrdef.UnicodeAttribute("sslmode", default="allow", description=
		"SSL negotiation mode (disable, allow, prefer, require, verify-*)")

	def getDsn(self):
		parts = []
		for key, part in [("host", "host"), ("port", "port"), 
				("sslmode", "sslmode"), ("database", "dbname"), 
				("user", "user"), ("password", "password")]:
			if getattr(self, part):
				parts.append("%s=%s"%(key, getattr(self, part)))
		return " ".join(parts)
	
	def getArgs(self):
		"""returns a dictionary suitable as keyword arguments to psycopg2's
		connect.
		"""
		res = {}
		for key in ["database", "user", "password", "host", "port", "sslmode"]:
			if getattr(self, key):
				res[key] = getattr(self, key)
		if res.keys()==["sslmode"]:
			raise utils.logOldExc(utils.StructureError("Insufficient information"
			" to connect to the database in profile '%s'."%(
				self.profileName)))
		return res

	@property
	def roleName(self):
		"""returns the database role used by this profile.

		This normally is user, but in the special case of the empty user,
		we return the logged users' name.
		"""
		if self.user:
			return self.user
		else:
			return os.getlogin()
Exemplo n.º 6
0
class Edit(EmbeddedStream):
    """an event stream targeted at editing other structures.
	"""
    name_ = "EDIT"

    _ref = attrdef.UnicodeAttribute(
        "ref",
        description="Destination of"
        " the edits, in the form elementName[<name or id>]",
        default=utils.Undefined)

    refPat = re.compile(
        r"([A-Za-z_][A-Za-z0-9_]*)\[([A-Za-z_][A-Za-z0-9_]*)\]")

    def onElementComplete(self):
        mat = self.refPat.match(self.ref)
        if not mat:
            raise common.LiteralParseError(
                "ref",
                self.ref,
                hint="edit references have the form <element name>[<value of"
                " name or id attribute>]")
        self.triggerEl, self.triggerId = mat.groups()
Exemplo n.º 7
0
class Loop(ReplayedEventsWithFreeAttributesBase):
    """An active tag that replays a feed several times, each time with
	different values.
	"""
    name_ = "LOOP"

    _csvItems = attrdef.UnicodeAttribute(
        "csvItems",
        default=None,
        description="The items to loop over, in CSV-with-labels format.",
        strip=True)
    _listItems = attrdef.UnicodeAttribute(
        "listItems",
        default=None,
        description="The items to loop over, as space-separated single"
        " items.  Each item will show up once, as 'item' macro.",
        strip=True)
    _codeItems = GeneratorAttribute(
        "codeItems",
        default=None,
        description="A python generator body that yields dictionaries"
        " that are then used as loop items.  You can access the parse context"
        " as the context variable in these code snippets.",
        strip=False)

    def maybeExpand(self, val):
        if "\\" in val:
            el = self.parent
            while el:
                if hasattr(el, "expand"):
                    return el.expand(val)
                el = el.parent
        return val

    def _makeRowIteratorFromListItems(self):
        if self.listItems is None:
            return None

        def rowIterator():
            for item in self.maybeExpand(self.listItems).split():
                yield {"item": item}

        return rowIterator()

    def _makeRowIteratorFromCSV(self):
        if self.csvItems is None:
            return None
        # I'd rather not do the encode below, but 2.7 csv can't handle
        # unicode.  We'll need to decode stuff again.
        src = self.maybeExpand(self.csvItems).strip().encode("utf-8")

        def encodeValues(row):
            return dict((key, str(val).decode("utf-8"))
                        for key, val in row.iteritems())

        return (
            encodeValues(row)
            for row in csv.DictReader(StringIO(src), skipinitialspace=True))

    def _makeRowIteratorFromCode(self):
        if self.codeItems is None:
            return None
        return self.iterRowsFromCode()

    def _getRowIterator(self):
        rowIterators = [
            ri for ri in [
                self._makeRowIteratorFromListItems(),
                self._makeRowIteratorFromCSV(),
                self._makeRowIteratorFromCode()
            ] if ri
        ]
        if len(rowIterators) != 1:
            raise common.StructureError("Must give exactly one data source in"
                                        " LOOP")
        return rowIterators[0]

    def completeElement(self, ctx):
        self._completeElementNext(Loop, ctx)
        for row in self._getRowIterator():
            for name, value in row.iteritems():
                if value:
                    value = value.strip()
                if name is None:
                    raise utils.StructureError(
                        "Too many CSV items (extra data: %s)" % value)
                setattr(self, "macro_" + name.strip(), lambda v=value: v)
            self._replayer()
Exemplo n.º 8
0
class RecordingBase(structure.Structure):
    """An "abstract base" for active tags doing event recording.

	The recorded events are available in the events attribute.
	"""
    name_ = None

    _doc = attrdef.UnicodeAttribute(
        "doc",
        description="A description of"
        " this stream (should be restructured text).",
        strip=False)
    _defaults = complexattrs.StructAttribute(
        "DEFAULTS",
        childFactory=Defaults,
        description="A mapping giving"
        " defaults for macros expanded in this stream.  Macros"
        " not defaulted will fail when not given in a FEED's attributes.",
        default=None)

    def __init__(self, *args, **kwargs):
        self.events_ = []
        self.tagStack_ = []
        structure.Structure.__init__(self, *args, **kwargs)

    def feedEvent(self, ctx, type, name, value):
        # keep _EXPANDED_VALUE rather than feed the value to protect it from
        # further expansion by subordinate structures (except if we, the
        # active tag, is the final recipient, in which case we gobble the thing
        # ourselves).
        if (type is _EXPANDED_VALUE and name not in self.managedAttrs):
            self.events_.append((_EXPANDED_VALUE, name, value, ctx.pos))
            return self
        else:
            return structure.Structure.feedEvent(self, ctx, type, name, value)

    def start_(self, ctx, name, value):
        if name in self.managedAttrs and not self.tagStack_:
            res = structure.Structure.start_(self, ctx, name, value)
        else:
            self.events_.append(("start", name, value, ctx.pos))
            res = self
            self.tagStack_.append(name)
        return res

    def end_(self, ctx, name, value):
        if name in self.managedAttrs and not self.tagStack_:
            structure.Structure.end_(self, ctx, name, value)
        else:
            self.events_.append(("end", name, value, ctx.pos))
        self.tagStack_.pop()
        return self

    def value_(self, ctx, name, value):
        if name in self.managedAttrs and not self.tagStack_:
            # our attribute
            structure.Structure.value_(self, ctx, name, value)
        else:
            self.events_.append(("value", name, value, ctx.pos))
        return self

    def getEventSource(self):
        """returns an object suitable as event source in xmlstruct.
		"""
        return _PreparedEventSource(self.events_)

    def unexpandMacros(self):
        """undoes the marking of expanded values as expanded.

		This is when, as with mixins, duplicate expansion of macros during
		replay is desired.
		"""
        for ind, ev in enumerate(self.events_):
            if ev[0] == _EXPANDED_VALUE:
                self.events_[ind] = ("value", ) + ev[1:]

    # This lets us feedFrom these
    iterEvents = getEventSource