Esempio n. 1
0
    def preprocess(self):
        message = XML.dig(self.xml, "message")
        if not message:
            raise XML.XMLValidityError("A Message's root node must be named 'message'")

        # Stamp it with the current time if it has no timestamp yet
        if not XML.dig(message, "timestamp"):
            XML.addElement(message, "timestamp", "%d" % time.time())
Esempio n. 2
0
    def render_rows(self, context):
        if not self.message:
            return []
        rows = []

        timestamp = XML.dig(self.message.xml, "message", "timestamp")
        if timestamp:
            rows.append(self.format_timestamp(timestamp))

        generator = XML.dig(self.message.xml, "message", "generator")
        if generator:
            rows.append(self.format_generator(generator))

        return rows
Esempio n. 3
0
    def component_files(self, element, args):
        """Format the contents of our <files> tag as a tree with nested lists"""
        from cia.LibCIA.Web import Template

        files = XML.dig(args.message.xml, "message", "body", "commit", "files")
        if not (files and XML.hasChildElements(files)):
            return []

        # First we organize the files into a tree of nested dictionaries.
        # The dictionary we ultimately have FileTree render maps each node
        # (file or directory) to a dictionary of its contents. The keys
        # in these dictionaries can be any Nouvelle-renderable object
        # produced by format_file.
        #
        # As a first step, we build a dictionary mapping path segment to
        # [fileTag, children] lists. We then create a visual representation
        # of each fileTag and generate the final dictionary.
        fileTree = {}
        for fileTag in XML.getChildElements(files):
            if fileTag.nodeName == 'file':
                # Separate the file into path segments and walk into our tree
                node = [None, fileTree]
                for segment in XML.shallowText(fileTag).split('/'):
                    if segment:
                        node = node[1].setdefault(segment, [None, {}])
                # The leaf node owns this fileTag
                node[0] = fileTag

        return [Template.FileTree(self.format_file_tree(fileTree))]
Esempio n. 4
0
 def format(self, args):
     # Format each package inside each result set
     packages = []
     for results in XML.getChildElements(XML.dig(args.message.xml, "message", "body", "builder")):
         if results.nodeName == 'results':
             for package in XML.getChildElements(results):
                 if package.nodeName == 'package':
                     packages.append(self.format_package(package))
     return self.joinMessage(args.message, packages)
Esempio n. 5
0
 def textComponent(self, element, args, *path):
     """A convenience function for defining components that just look for a node
        in the message and return its shallowText.
        """
     element = XML.dig(args.message.xml, *path)
     if element:
         return [XML.shallowText(element)]
     else:
         return [MarkAsHidden()]
Esempio n. 6
0
 def format(self, args):
     if not args.input:
         return
     project = XML.dig(args.message.xml, "message", "source", "project")
     if project:
         from cia.LibCIA.IRC.Formatting import format
         prefix = format("%s:" % XML.shallowText(project), 'bold') + " "
         return "\n".join([prefix + line for line in args.input.split("\n")])
     else:
         return args.input
Esempio n. 7
0
    def postprocessMessage(self, xml):
        """Gets a chance to modify all XML messages before they're loaded
           and dispatched to the Hub. This does the following:
             - If there is no <generator> at all, adds a generic one
             - Removes any <mailHeaders> tag that may already exist in <generator>
             - Adds a correct <mailHeaders> tag to the <generator>
           """
        # Create the <generator> tag if it doesn't exist
        if not XML.dig(xml, "message", "generator"):
            xml.documentElement.appendChild(self.getLocalGenerator(xml))
        generator = XML.dig(xml, "message", "generator")

        # Delete an existing <mailHeaders>
        for child in list(XML.getChildElements(generator)):
            if child.nodeName == "mailHeaders":
                generator.removeChild(child)

        # Add a new <mailHeaders>
        generator.appendChild(self.getXMLMailHeaders(xml))
        return xml
Esempio n. 8
0
    def component_log(self, element, args):
        log = XML.dig(args.message.xml, "message", "body", "commit", "log")
        if not log:
            return [Message.MarkAsHidden()]

        if self.crunchWhitespace:
            inputLines = [Util.getCrunchedLog(log)]
        else:
            inputLines = Util.getNormalizedLog(log)

        # Break the log string into wrapped lines
        lines = []
        for line in inputLines:
            # Ignore blank lines
            if not line:
                continue

            # Wrap long lines
            if self.widthLimit and len(line) > self.widthLimit:
                lines.extend(Util.wrapLine(line, self.wrapWidth))
            else:
                lines.append(line)

        # If our lineLimit is 1, don't bother starting long logs on the
        # next line since there will be no long logs. Instead of the
        # long (log message trimmed), just add an ellipsis.
        if self.lineLimit == 1:
            if len(lines) > 1:
                lines[0] += ' ...'
                del lines[1:]

        # Multiline logs shouldn't start on the same line as the metadata
        elif len(lines) > 1:
            lines.insert(0, '')

            # Truncate long log messages if we have a limit
            if self.lineLimit and len(lines) > self.lineLimit + 1:
                lines[0] = "(log message trimmed)"
                del lines[self.lineLimit + 1:]

        # Reassemble the log message and send it to the default formatter
        return ["\n".join(lines)]
Esempio n. 9
0
    def component_files(self, element, args):
        """Break up our list of files into a common prefix and a sensibly-sized
           list of filenames after that prefix.
           """
        files = XML.dig(args.message.xml, "message", "body", "commit", "files")
        if not (files and XML.hasChildElements(files)):
            return [Message.MarkAsHidden()]

        prefix, endings = self.consolidateFiles(files)
        endingStr = " ".join(endings)
        if len(endingStr) > self.filesWidthLimit:
            # If the full file list is too long, give a file summary instead
            endingStr = self.summarizeFiles(endings)
        if prefix.startswith('/'):
            prefix = prefix[1:]

        if endingStr:
            return ["%s (%s)" % (prefix, endingStr)]
        else:
            return [prefix]
Esempio n. 10
0
 def format(self, args):
     return Util.extractSummary(XML.dig(args.message.xml, "message", "body", "colorText"))
Esempio n. 11
0
 def format(self, args):
     colorText = XML.dig(args.message.xml, "message", "body", "colorText")
     return self.Parser(colorText).result
Esempio n. 12
0
    def component_headers(self, element, args):
        """Format all relevant commit metadata in an email-style header box"""

        message   = args.message
        commit    = XML.dig(message.xml, "message", "body", "commit")
        source    = XML.dig(message.xml, "message", "source")
        author    = XML.dig(commit, "author")
        version   = XML.dig(commit, "version")
        revision  = XML.dig(commit, "revision")
        diffLines = XML.dig(commit, "diffLines")
        url       = XML.dig(commit, "url")
        log       = XML.dig(commit, "log")
        project   = XML.dig(source, "project")
        module    = XML.dig(source, "module")
        branch    = XML.dig(source, "branch")
        headers   = OrderedDict()

        if author:
            headers['Author'] = XML.shallowText(author)
        if project:
            headers['Project'] = XML.shallowText(project)
        if module:
            headers['Module'] = XML.shallowText(module)
        if branch:
            headers['Branch'] = XML.shallowText(branch)
        if version:
            headers['Version'] = XML.shallowText(version)
        if revision:
            headers['Revision'] = XML.shallowText(revision)
        if diffLines:
            headers['Changed Lines'] = XML.shallowText(diffLines)
        if url:
            headers['URL'] = tag('a', href=XML.shallowText(url))[ Util.extractSummary(url) ]

        return [Template.MessageHeaders(headers)]
Esempio n. 13
0
    def component_log(self, element, args):
        """Convert the log message to HTML. If the message seems to be preformatted
           (it has some lines with indentation) it is stuck into a <pre>. Otherwise
           it is converted to HTML by replacing newlines with <br> tags and converting
           bulletted lists.
           """
        log = XML.dig(args.message.xml, "message", "body", "commit", "log")
        if not log:
            return []
        content = []
        lines = Util.getNormalizedLog(log)
        nonListItemLines = []
        listItems = []

        if lines:
            # Scan the message, applying a few heuristics. If we see lines
            # that are still starting with a space after getNormalizedLog
            # has done its thing, assume the text is preformatted. Also
            # look for lines that appear to be list items.
            isPreFormatted = False
            for line in lines:
                if line and line[0] == ' ':
                    isPreFormatted = True

                if line.startswith("* ") or line.startswith("- "):
                    # Assume this is a list item, and convert the bullets to
                    # a proper XHTML list.
                    listItems.append(line[2:])
                else:
                    if listItems:
                        # It's a continuation of the last item
                        listItems[-1] = listItems[-1] + " " + line.strip()
                    else:
                        # If we haven't seen a list yet, stick this in nonListItemLines.
                        # If this log message isn't a list at all, everything will end
                        # up there but it will be safely ignored
                        nonListItemLines.append(line)

            if listItems:
                # It looks like a bulleted list. First output the nonListItemLines,
                # then stick the items inside a list.
                for line in nonListItemLines:
                    if content:
                        content.append(tag('br'))
                    content.append(line)
                content = [
                    tag('p')[ content ],
                    tag('ul')[[ tag('li')[item] for item in listItems ]],
                    ]

            elif isPreFormatted:
                # This is probably a preformatted message, stick it in a <pre>
                content.append(tag('pre')[ "\n".join(lines) ])

            else:
                # Plain old text, just stick <br>s between the lines
                for line in lines:
                    if content:
                        content.append(tag('br'))
                    content.append(line)
        else:
            content.append(tag('i')["No log message"])

        return self.hyperlinker.apply(content)
Esempio n. 14
0
 def component_url(self, element, args):
     element = XML.dig(args.message.xml, "message", "body", "commit", "url")
     if element:
         return [tag('a', href=XML.shallowText(element))[ 'link' ]]
     else:
         return [Message.MarkAsHidden()]
Esempio n. 15
0
 def format(self, args):
     log = XML.dig(args.message.xml, "message", "body", "commit", "log")
     if log:
         return Util.extractSummary(log)
Esempio n. 16
0
 def format(self, args):
     colorText = XML.dig(args.message.xml, "message", "body", "colorText")
     if self.color:
         return self.formatter.parse(colorText)
     else:
         return XML.allText(colorText)
Esempio n. 17
0
 def getValue(self, message):
     project = XML.dig(message.xml, "message", "source", "project")
     if project:
         return XML.shallowText(project)