boartty/gertty/commentlink.py
Jay Pipes 74877d2499 Allow gertty to run in Py3K environments
In environments without py27, gertty was unable to run. This patch
addresses all the Py3K issues discovered when getting gertty running in
a py34-only environment.

Change-Id: I32a06f9768bdeaf8e95ddf9a9e54c79059fbaa2f
2016-01-15 09:10:31 -08:00

123 lines
4.0 KiB
Python

# Copyright 2014 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import collections
try:
import ordereddict
except:
pass
import re
import six
import urwid
from gertty import mywid
try:
OrderedDict = collections.OrderedDict
except AttributeError:
OrderedDict = ordereddict.OrderedDict
class TextReplacement(object):
def __init__(self, config):
if isinstance(config, six.string_types):
self.color = None
self.text = config
else:
self.color = config.get('color')
self.text = config['text']
def replace(self, app, data):
if self.color:
return (self.color.format(**data), self.text.format(**data))
return (None, self.text.format(**data))
class LinkReplacement(object):
def __init__(self, config):
self.url = config['url']
self.text = config['text']
def replace(self, app, data):
link = mywid.Link(self.text.format(**data), 'link', 'focused-link')
urwid.connect_signal(link, 'selected',
lambda link:self.activate(app, self.url.format(**data)))
return link
def activate(self, app, url):
result = app.parseInternalURL(url)
if result is not None:
return app.openInternalURL(result)
return app.openURL(url)
class SearchReplacement(object):
def __init__(self, config):
self.query = config['query']
self.text = config['text']
def replace(self, app, data):
link = mywid.Link(self.text.format(**data), 'link', 'focused-link')
urwid.connect_signal(link, 'selected',
lambda link:app.doSearch(self.query.format(**data)))
return link
class CommentLink(object):
def __init__(self, config):
self.match = re.compile(config['match'], re.M)
self.test_result = config.get('test-result', None)
self.replacements = []
for r in config['replacements']:
if 'text' in r:
self.replacements.append(TextReplacement(r['text']))
if 'link' in r:
self.replacements.append(LinkReplacement(r['link']))
if 'search' in r:
self.replacements.append(SearchReplacement(r['search']))
def getTestResults(self, app, text):
if self.test_result is None:
return {}
ret = OrderedDict()
for line in text.split('\n'):
m = self.match.search(line)
if m:
repl = [r.replace(app, m.groupdict()) for r in self.replacements]
job = self.test_result.format(**m.groupdict())
ret[job] = repl + ['\n']
return ret
def run(self, app, chunks):
ret = []
for chunk in chunks:
if not isinstance(chunk, six.string_types):
# We don't currently support nested commentlinks; if
# we have something that isn't a string, just append
# it to the output.
ret.append(chunk)
continue
if not chunk:
ret += [chunk]
while chunk:
m = self.match.search(chunk)
if not m:
ret.append(chunk)
break
before = chunk[:m.start()]
after = chunk[m.end():]
if before:
ret.append(before)
ret += [r.replace(app, m.groupdict()) for r in self.replacements]
chunk = after
return ret