コード例 #1
0
ファイル: Commit.py プロジェクト: Kays/cia-vc
    def consolidateFiles(self, xmlFiles):
        """Given a <files> element, find the directory common to all files
           and return a 2-tuple with that directory followed by
           a list of files within that directory.
           """
        files = []
        if xmlFiles:
            for fileTag in XML.getChildElements(xmlFiles):
                if fileTag.nodeName == 'file':
                    files.append(XML.shallowText(fileTag))

        # If we only have one file, return it as the prefix.
        # This prevents the below regex from deleting the filename
        # itself, assuming it was a partial filename.
        if len(files) == 1:
            return files[0], []

        # Start with the prefix found by commonprefix,
        # then actually make it end with a directory rather than
        # possibly ending with part of a filename.
        prefix = re.sub("[^/]*$", "", posixpath.commonprefix(files))

        endings = []
        for file in files:
            ending = file[len(prefix):].strip()
            if ending == '':
                    ending = '.'
            endings.append(ending)
        return prefix, endings
コード例 #2
0
    def parse(self, message):
        """Given a string of text in the original CIA commit format, return a <colorText>
           element representing it as a DOM tree.
           """
        # Initialize our model of the current text format in the original message
        self.parsedState = ColorState()

        self.document = XML.createRootNode()

        # Initialize our stack of (element, ColorState) tuples representing
        # the state of the XML document being generated. This starts out with
        # our root element in it.
        self.elementStack = [
            (XML.addElement(self.document, "colorText"), ColorState())
            ]

        # Break up the message into lines, each with its whitespace stripped.
        # Run our lexical scanner on each line separately, turning it into
        # a stream of events. Insert <br/> tags between lines.
        lines = []
        for line in message.split("\n"):
            # Ignore extra whitespace
            line = line.strip()
            # Ignore blank lines
            if line:
                lines.append(line)
        for i in xrange(len(lines)):
            if i != 0:
                XML.addElement(self.elementStack[-1][0], 'br')
            self.lex(lines[i])
            self.closeTags()

        return self.document
コード例 #3
0
ファイル: Commit.py プロジェクト: Kays/cia-vc
    def component_files(self, element, args):
        """Format the contents of our <files> tag as a tree with nested lists"""
        from 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))]
コード例 #4
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
    def component_files(self, element, args):
        """Format the contents of our <files> tag as a tree with nested lists"""
        from 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))]
コード例 #5
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
    def consolidateFiles(self, xmlFiles):
        """Given a <files> element, find the directory common to all files
           and return a 2-tuple with that directory followed by
           a list of files within that directory.
           """
        files = []
        if xmlFiles:
            for fileTag in XML.getChildElements(xmlFiles):
                if fileTag.nodeName == 'file':
                    files.append(XML.shallowText(fileTag))

        # If we only have one file, return it as the prefix.
        # This prevents the below regex from deleting the filename
        # itself, assuming it was a partial filename.
        if len(files) == 1:
            return files[0], []

        # Start with the prefix found by commonprefix,
        # then actually make it end with a directory rather than
        # possibly ending with part of a filename.
        prefix = re.sub("[^/]*$", "", posixpath.commonprefix(files))

        endings = []
        for file in files:
            ending = file[len(prefix):].strip()
            if ending == '':
                ending = '.'
            endings.append(ending)
        return prefix, endings
コード例 #6
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)
コード例 #7
0
ファイル: Other.py プロジェクト: Kays/cia-vc
 def format(self, args):
     if not args.input:
         return
     project = XML.dig(args.message.xml, "message", "source", "project")
     if project:
         from 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
コード例 #8
0
ファイル: Other.py プロジェクト: scanlime/cia-vc
 def format(self, args):
     if not args.input:
         return
     project = XML.dig(args.message.xml, "message", "source", "project")
     if project:
         from 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
コード例 #9
0
ファイル: MessageViewer.py プロジェクト: scanlime/cia-vc
    def format_generator(self, gen):
        """Format the information contained in this message's <generator> tag"""
        name = XML.digValue(gen, str, "name")
        url = XML.digValue(gen, str, "url")
        version = XML.digValue(gen, str, "version")

        if url:
            name = tag('a', href=url)[ name ]
        items = ["Generated by ", Template.value[ name ]]
        if version:
            items.extend([" version ", version])
        return items
コード例 #10
0
ファイル: MessageViewer.py プロジェクト: Kays/cia-vc
    def format_generator(self, gen):
        """Format the information contained in this message's <generator> tag"""
        name = XML.digValue(gen, str, "name")
        url = XML.digValue(gen, str, "url")
        version = XML.digValue(gen, str, "version")

        if url:
            name = tag("a", href=url)[name]
        items = ["Generated by ", Template.value[name]]
        if version:
            items.extend([" version ", version])
        return items
コード例 #11
0
ファイル: MessageViewer.py プロジェクト: scanlime/cia-vc
    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
コード例 #12
0
ファイル: MessageViewer.py プロジェクト: Kays/cia-vc
    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
コード例 #13
0
ファイル: Info.py プロジェクト: Kays/cia-vc
 def getSvnRevision(self):
     """Return the current Subversion repository revision, or None
        if we're not in an svn working copy or it can't be parsed.
        """
     try:
         entries = XML.parseString(open(".svn/entries").read()).documentElement
         highestRev = 0
         for tag in XML.getChildElements(entries):
             if tag.nodeName == 'entry':
                 rev = tag.getAttributeNS(None, 'committed-rev')
                 if rev and rev > highestRev:
                     highestRev = rev
         return highestRev
     except:
         return None
コード例 #14
0
ファイル: models.py プロジェクト: Kays/cia-vc
    def syncFromServer(self):
        """Update this Bot from the RPC server, if necessary.
           Right now the only task this performs is to store the
           server's ruleset if filterMode is 'unknown'.
           """
        if self.filter_mode != FILTER.UNKNOWN:
            return

        ruleset = self._loadRuleset()
        if not ruleset:
            # If there's no ruleset, mark the bot as inactive.
            self.filter_mode = FILTER.INACTIVE
            self.save()
            return

        # Parse the ruleset using LibCIA's XML library
        from LibCIA import XML
        dom = XML.parseString(ruleset)

        # XXX: We should try to reduce the ruleset to one of
        #      the other FILTER.* modes if possible. For now,
        #      we'll always import existing rulesets as
        #      FILTER.CUSTOM.

        # Flatten the contents of the <ruleset> element, clean up
        # the resulting text, and save that as a custom filter.

        text = ''.join([n.toxml() for n in dom.documentElement.childNodes])
        self.filter_mode = FILTER.CUSTOM
        self.custom_ruleset = clean_up_text(text)
        self.save()
コード例 #15
0
ファイル: MessageViewer.py プロジェクト: Kays/cia-vc
    def render_message(self, context):
        if not self.message:
            context["request"].setResponseCode(404)
            return self.notFoundMessage

        # Try to format it using several media, in order of decreasing preference.
        # The 'xhtml-long' formatter lets messages define a special formatter to
        # use when an entire page is devoted to their one message, possibly showing
        # it in greater detail. 'xhtml' is the formatter most messages should have.
        # 'plaintext' is a nice fallback.
        #
        # This default list of media to try can be overridden with an argument in our URL.

        if "media" in context["args"]:
            mediaList = context["args"]["media"][0].split()
        else:
            mediaList = ("xhtml-long", "xhtml", "plaintext")

        for medium in mediaList:
            try:
                formatted = Formatters.getFactory().findMedium(medium, self.message).formatMessage(self.message)
            except Message.NoFormatterError:
                continue
            return formatted

        # Still no luck? Display a warning message and a pretty-printed XML tree
        return [tag("h1")["No formatter available"], XML.htmlPrettyPrint(self.message.xml)]
コード例 #16
0
 def format_results(self, package):
     """Given a package, returns a formatted representation of all results for that package"""
     results = []
     for element in XML.getChildElements(package):
         f = getattr(self, 'result_' + element.nodeName, None)
         if f:
             results.append(f(element))
コード例 #17
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
 def param_noColor(self, tag):
     """The <noColor> parameter disables colors.
        This is equivalent to a <format> parameter with CommitFormatter's
        default component tree.
        """
     self.componentTree = XML.parseString(
         CommitFormatter.defaultComponentTree).documentElement
コード例 #18
0
ファイル: models.py プロジェクト: scanlime/cia-vc
    def syncFromServer(self):
        """Update this Bot from the RPC server, if necessary.
           Right now the only task this performs is to store the
           server's ruleset if filterMode is 'unknown'.
           """
        if self.filter_mode != FILTER.UNKNOWN:
            return

        ruleset = self._loadRuleset()
        if not ruleset:
            # If there's no ruleset, mark the bot as inactive.
            self.filter_mode = FILTER.INACTIVE
            self.save()
            return

        # Parse the ruleset using LibCIA's XML library
        from LibCIA import XML
        dom = XML.parseString(ruleset)

        # XXX: We should try to reduce the ruleset to one of
        #      the other FILTER.* modes if possible. For now,
        #      we'll always import existing rulesets as
        #      FILTER.CUSTOM.

        # Flatten the contents of the <ruleset> element, clean up
        # the resulting text, and save that as a custom filter.

        text = ''.join([n.toxml() for n in dom.documentElement.childNodes])
        self.filter_mode = FILTER.CUSTOM
        self.custom_ruleset = clean_up_text(text)
        self.save()
コード例 #19
0
ファイル: Commit.py プロジェクト: Kays/cia-vc
 def param_noColor(self, tag):
     """The <noColor> parameter disables colors.
        This is equivalent to a <format> parameter with CommitFormatter's
        default component tree.
        """
     self.componentTree = XML.parseString(CommitFormatter.defaultComponentTree
                                          ).documentElement
コード例 #20
0
ファイル: MessageViewer.py プロジェクト: scanlime/cia-vc
    def render_message(self, context):
        if not self.message:
            context['request'].setResponseCode(404)
	    return self.notFoundMessage

        # Try to format it using several media, in order of decreasing preference.
        # The 'xhtml-long' formatter lets messages define a special formatter to
        # use when an entire page is devoted to their one message, possibly showing
        # it in greater detail. 'xhtml' is the formatter most messages should have.
        # 'plaintext' is a nice fallback.
        #
        # This default list of media to try can be overridden with an argument in our URL.

        if 'media' in context['args']:
            mediaList = context['args']['media'][0].split()
        else:
            mediaList = ('xhtml-long', 'xhtml', 'plaintext')

        for medium in mediaList:
            try:
                formatted = Formatters.getFactory().findMedium(
                    medium, self.message).formatMessage(self.message)
            except Message.NoFormatterError:
                continue
            return formatted

        # Still no luck? Display a warning message and a pretty-printed XML tree
        return [
            tag('h1')[ "No formatter available" ],
            XML.htmlPrettyPrint(self.message.xml),
            ]
コード例 #21
0
ファイル: Formatting.py プロジェクト: scanlime/cia-vc
def parseColorElement(xml):
    """Given a <color> element, return the corresponding list of color code names"""
    codes = []
    bg = xml.getAttributeNS(None, 'bg')
    fg = xml.getAttributeNS(None, 'fg')

    if bg:
        if bg in ColorText.allowedColors:
            codes.append(bg)
            codes.append('reverse')
        else:
            raise XML.XMLValidityError("%r is not a color" % bg)
    if fg:
        if fg in ColorText.allowedColors:
            codes.append(fg)
        else:
            raise XML.XMLValidityError("%r is not a color" % fg)
    return codes
コード例 #22
0
ファイル: MessageViewer.py プロジェクト: scanlime/cia-vc
    def render(self, request):
        xml = self.target.messages.getMessageById(self.id)
        if xml:
            request.setHeader('content-type', 'text/xml')
            request.write(unicode(XML.toString(xml)).encode('utf-8'))
            request.finish()
        else:
            request.write(error.NoResource("Message not found").render(request))
            request.finish()
	return ""
コード例 #23
0
ファイル: MessageViewer.py プロジェクト: Kays/cia-vc
 def render(self, request):
     xml = self.target.messages.getMessageById(self.id)
     if xml:
         request.setHeader("content-type", "text/xml")
         request.write(unicode(XML.toString(xml)).encode("utf-8"))
         request.finish()
     else:
         request.write(error.NoResource("Message not found").render(request))
         request.finish()
     return ""
コード例 #24
0
class Message:
    serializer = Serializer()
    formatter_factory = OldFormatters.getFactory()

    def __init__(self, (id, xml)):
        self.id = id
        self.hex_id = "%x" % id
        self.oldmsg = OldMessage(xml)

        self.timestamp = datetime.datetime.fromtimestamp(
            XML.digValue(self.oldmsg.xml, float, "message", "timestamp"))

        self.formatter = self.formatter_factory.findMedium(
            'xhtml', self.oldmsg)
        self.is_commit = isinstance(self.formatter, CommitFormatter)
        if self.is_commit:
            for shortcut, path in XML.pathShortcuts.items():
                doc = XML.XPath(path).queryObject(self.oldmsg)
                if doc:
                    setattr(self, shortcut, XML.shallowText(doc[0]))
コード例 #25
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
    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]
コード例 #26
0
ファイル: Commit.py プロジェクト: Kays/cia-vc
    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]
コード例 #27
0
    def joinMessage(self, message, packages):
        content = []

        branch = XML.digValue(message.xml, str, "message", "source", "branch")
        if branch:
            content.append(Nouvelle.tag('strong')[ self.format_branch(branch.strip()) ])

        for package in packages:
            if content:
                content.append(Nouvelle.tag('br'))
            content.append(package)

        return content
コード例 #28
0
    def joinMessage(self, message, packages):
        """Join the results for each package into a final result"""
        content = "builder"

        branch = XML.digValue(message.xml, str, "message", "source", "branch")
        if branch:
            content += " " + self.format_branch(branch.strip())

        # If we have only one package, put it on the same line as the heading
        if len(packages) <= 1:
            content += ": " + packages[0]
        else:
            content += "\n" + "\n".join(packages)
        return content
コード例 #29
0
ファイル: Util.py プロジェクト: scanlime/cia-vc
def extractSummary(element, widthLimit=80):
    """Extract all text from the given XML element, remove extra
       whitespace, and truncate it to no longer than the given width.
       """
    # Extract all text, eating extra whitespace
    text = re.sub("\s+", " ", XML.allText(element)).strip()

    # Use wrapLine to cleanly break it if possible, but
    # truncate it if necessary- wrapLine will not break words in
    # half if they are longer than the wrap width.
    lines = wrapLine(text, widthLimit)
    if lines:
        summary = lines[0][:widthLimit]
        if len(summary) < len(text):
            summary += "..."
        return summary
コード例 #30
0
ファイル: Feed.py プロジェクト: Kays/cia-vc
    def render_item(self, context, id, content):
        url = Link.MessageLink(self.target, id).getURL(context)
        m = Message.Message(content)
        tags = [
            tag('link')[ url ],
            tag('dc:date')[ TimeUtil.formatDateISO8601(XML.digValue(m.xml, int, "message", "timestamp")) ],
            tag('description')[ quote(self.formatMessage(m)) ],
            ]

        # Generate a title if we can, but if we can't don't worry too much
        try:
            tags.append(tag('title')[ Formatters.getFactory().findMedium('title', m).formatMessage(m) ])
        except Message.NoFormatterError:
            pass

        return tag('item', **{'rdf:about': url})[tags]
コード例 #31
0
ファイル: Util.py プロジェクト: Kays/cia-vc
def extractSummary(element, widthLimit=80):
    """Extract all text from the given XML element, remove extra
       whitespace, and truncate it to no longer than the given width.
       """
    # Extract all text, eating extra whitespace
    text = re.sub("\s+", " ", XML.allText(element)).strip()

    # Use wrapLine to cleanly break it if possible, but
    # truncate it if necessary- wrapLine will not break words in
    # half if they are longer than the wrap width.
    lines = wrapLine(text, widthLimit)
    if lines:
        summary = lines[0][:widthLimit]
        if len(summary) < len(text):
            summary += "..."
        return summary
コード例 #32
0
ファイル: Feed.py プロジェクト: Kays/cia-vc
    def messageToItemContent(self, context, m, id):
        """Render an XML message as the content of an RSS <item>"""
        url = Link.MessageLink(self.target, id).getURL(context)
        tags = [
            tag('pubDate')[ TimeUtil.formatDateRFC822(XML.digValue(m.xml, int, "message", "timestamp")) ],
            tag('guid')[url],
            tag('link')[url],
            tag('description')[ quote(self.formatMessage(m)) ],
            ]

        # Generate a title if we can, but if we can't don't worry too much
        try:
            tags.append(tag('title')[ Formatters.getFactory().findMedium('title', m).formatMessage(m) ])
        except Message.NoFormatterError:
            pass

        return tags
コード例 #33
0
    def pushTag(self, name, attributes={}, stateChanges={}):
        """Add a new element to the elementStack, placed at
           the end of the children list for the tag currently
           at the top of the stack.

           name:         The name of the new element
           attributes:   A dict of attributes to set on the new element
           stateChanges: A dict of attributes to change in the new tag's state
           """
        oldTag, oldState = self.elementStack[-1]

        newTag = XML.addElement(self.elementStack[-1][0], name)
        for key, value in attributes.iteritems():
            newTag.setAttributeNS(None, key, value)

        newState = copy.deepcopy(oldState)
        newState.__dict__.update(stateChanges)

        self.elementStack.append((newTag, newState))
コード例 #34
0
ファイル: Util.py プロジェクト: Kays/cia-vc
def getNormalizedLog(xml, tabWidth=8):
    """Given the DOM node for a <log> tag, return a list of
       text lines with whitespace normalized appropriately.
       This strips all whitespace from the right side, and homogeneously
       strips whitespace from the left side as much as possible.
       Leading and trailing blank lines are removed, but internal
       blank lines are not.
       """
    if not xml:
        return []

    lines = []
    maxLeftStrip = None

    for line in XML.shallowText(xml).split("\n"):
        # Expand tabs and strip righthand whitespace
        line = line.replace("\t", " "*tabWidth).rstrip()
        strippedLine = line.lstrip()

        # Blank lines don't count in determining the left strip amount
        if strippedLine:
            # Determine how much we can strip from the left side
            leftStrip = len(line) - len(strippedLine)

            # Determine the maximum amount of space we can strip
            # from the left side homogeneously across the whole text
            if maxLeftStrip is None or leftStrip < maxLeftStrip:
                maxLeftStrip = leftStrip

        # Skip leading blank lines
        if lines or strippedLine:
            lines.append(line)

    # Remove trailing blank lines
    while lines and not lines[-1].strip():
        del lines[-1]

    # Homogeneous left strip
    if maxLeftStrip is None:
        return lines
    else:
        return [line[maxLeftStrip:] for line in lines]
コード例 #35
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
    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)]
コード例 #36
0
ファイル: Util.py プロジェクト: scanlime/cia-vc
def getNormalizedLog(xml, tabWidth=8):
    """Given the DOM node for a <log> tag, return a list of
       text lines with whitespace normalized appropriately.
       This strips all whitespace from the right side, and homogeneously
       strips whitespace from the left side as much as possible.
       Leading and trailing blank lines are removed, but internal
       blank lines are not.
       """
    if not xml:
        return []

    lines = []
    maxLeftStrip = None

    for line in XML.shallowText(xml).split("\n"):
        # Expand tabs and strip righthand whitespace
        line = line.replace("\t", " " * tabWidth).rstrip()
        strippedLine = line.lstrip()

        # Blank lines don't count in determining the left strip amount
        if strippedLine:
            # Determine how much we can strip from the left side
            leftStrip = len(line) - len(strippedLine)

            # Determine the maximum amount of space we can strip
            # from the left side homogeneously across the whole text
            if maxLeftStrip is None or leftStrip < maxLeftStrip:
                maxLeftStrip = leftStrip

        # Skip leading blank lines
        if lines or strippedLine:
            lines.append(line)

    # Remove trailing blank lines
    while lines and not lines[-1].strip():
        del lines[-1]

    # Homogeneous left strip
    if maxLeftStrip is None:
        return lines
    else:
        return [line[maxLeftStrip:] for line in lines]
コード例 #37
0
ファイル: Commit.py プロジェクト: Kays/cia-vc
    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)]
コード例 #38
0
 def getValue(self, message):
     try:
         return XML.digValue(message.xml, int, "message", "timestamp")
     except ValueError:
         return None
コード例 #39
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
 def param_widthLimit(self, tag):
     self.widthLimit = int(XML.shallowText(tag))
     if self.wrapWidth > self.widthLimit:
         self.wrapWidth = self.widthLimit
コード例 #40
0
ファイル: Other.py プロジェクト: Kays/cia-vc
 def loadParametersFrom(self, xml):
     self.formattingCode = XML.shallowText(xml).strip()
コード例 #41
0
ファイル: Util.py プロジェクト: Kays/cia-vc
def getCrunchedLog(xml):
    """Given the DOM node for a <log> tag, return the log as
       a string with all groups of one or more whitespace
       characters replaced with a single space.
       """
    return re.sub("\s+", " ", XML.shallowText(xml)).strip()
コード例 #42
0
ファイル: Interface.py プロジェクト: Kays/cia-vc
 def xmlrpc_getLatestMessages(self, path, limit=None):
     """Return 'limit' latest messages delivered to this stats target,
        or all available recent messages if 'limit' isn't specified.
        """
     return [(id, XML.toString(doc)) for id, doc in
             StatsTarget(path).messages.getLatest(limit)]
コード例 #43
0
ファイル: Feed.py プロジェクト: Kays/cia-vc
    def formatItem(self, content):
	# Convert the root node, not the document- we don't want to
	# be outputting another XML declaration inside our larger document.
	return xml(XML.toString(content.childNodes[0]).encode('utf8'))
コード例 #44
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
 def param_wrapWidth(self, tag):
     self.wrapWidth = int(XML.shallowText(tag))
コード例 #45
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
 def param_filesWidthLimit(self, tag):
     self.filesWidthLimit = int(XML.shallowText(tag))
コード例 #46
0
 def getValue(self, message):
     project = XML.dig(message.xml, "message", "source", "project")
     if project:
         return XML.shallowText(project)
コード例 #47
0
ファイル: Commit.py プロジェクト: scanlime/cia-vc
 def param_lineLimit(self, tag):
     self.lineLimit = int(XML.shallowText(tag))
コード例 #48
0
ファイル: ColorText.py プロジェクト: Kays/cia-vc
 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)
コード例 #49
0
ファイル: ColorText.py プロジェクト: Kays/cia-vc
 def format(self, args):
     colorText = XML.dig(args.message.xml, "message", "body", "colorText")
     return self.Parser(colorText).result
コード例 #50
0
ファイル: Other.py プロジェクト: scanlime/cia-vc
 def loadParametersFrom(self, xml):
     self.formattingCode = XML.shallowText(xml).strip()
コード例 #51
0
ファイル: Util.py プロジェクト: scanlime/cia-vc
def getCrunchedLog(xml):
    """Given the DOM node for a <log> tag, return the log as
       a string with all groups of one or more whitespace
       characters replaced with a single space.
       """
    return re.sub("\s+", " ", XML.shallowText(xml)).strip()
コード例 #52
0
ファイル: ColorText.py プロジェクト: Kays/cia-vc
 def format(self, args):
     return Util.extractSummary(XML.dig(args.message.xml, "message", "body", "colorText"))
コード例 #53
0
ファイル: MessageViewer.py プロジェクト: scanlime/cia-vc
 def format_timestamp(self, stamp):
     return ["Received ", Template.value[TimeUtil.formatRelativeDate(int(XML.shallowText(stamp)))]]
コード例 #54
0
ファイル: MessageViewer.py プロジェクト: Kays/cia-vc
 def format_timestamp(self, stamp):
     return ["Received ", Template.value[TimeUtil.formatRelativeDate(int(XML.shallowText(stamp)))]]