def test_change_fore_with_no_right_bound(self): ml = Metaline("foobarbaz", RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, None)])) self.la.change_fore(3, None, fg_code(RED, False)) res = self.la.apply(ml) assert res.fores.items() == [(0, fg_code(WHITE, False)), (3, fg_code(RED, False))]
def test_ColourCodeParser_bold_off(): ccp = ColourCodeParser() inline = '\x1b[1mfoo\x1b[22mbar' ml = ccp.parseline(inline) print ml.fores.items() assert ml.fores.items() == [(0, fg_code(WHITE, True)), (3, fg_code(WHITE, False))]
def test_ColourCodeParser_funky_real_example(): ccp = ColourCodeParser() inline = '\x1b[33mfoo\x1b[0m' ml = ccp.parseline(inline) print ml.fores.items() assert ml.fores.items() == [(0, fg_code(YELLOW, False)), (3, fg_code(WHITE, False))] assert ml.backs.items() == [(0, bg_code(BLACK))]
def test_ColourCodeParser_fg_change(): ccp = ColourCodeParser() inline = 'foo\x1b[30mbar' ml = ccp.parseline(inline) assert ml.fores.items() == [(0, fg_code(WHITE, False)), (3, fg_code(BLACK, False))], \ ml.fores.items() assert ml.line == 'foobar'
def setUp(self): self.f = StringIO() self.o = Logger(self.f) self.o.fore.as_hex = self.o.fore.ground = 'fore' self.o.back.as_hex = self.o.back.ground = 'back' self.f1 = fg_code(WHITE, False) self.f2 = fg_code(GREEN, True) self.b1 = bg_code(RED) self.b2 = bg_code(PURPLE)
def test_receives_repeated_normal_CR_LF_in_broken_godwars_mode_fine(self): self.tc.fix_broken_godwars_line_endings = True self.tc.dataReceived("foo\r\n\r\n") expected = [ simpleml("foo", fg_code(WHITE, False), bg_code(BLACK)), simpleml("", fg_code(WHITE, False), bg_code(BLACK)) ] for ml in expected: ml.wrap = True lines = [ line for ((line, ), kwargs) in self.e.metalineReceived.call_args_list ] assert lines == expected, lines
def write(self, line, soft_line_start=False): """Write a line to the screen. This forcibly converts its argument to a Metaline. """ if not isinstance(line, (basestring, Metaline)): line = str(line) if isinstance(line, basestring): metaline = simpleml(line, fg_code(WHITE, False), bg_code(BLACK)) metaline.wrap = False metaline.soft_line_start = soft_line_start else: metaline = line #we don't need to close off the ends of the note, because thanks to #the magic of the ColourCodeParser, each new line is started by the #implied colour, so notes can't bleed out into text (though the #reverse can be true). #this needs to be before the futzing with NLs and GA, because textwrap #obliterates all other newlines. metaline = metaline.wrapped(self.wrapper) #we don't actually append newlines at the end, but the start. This #simplifies things, because we don't use a newline where a soft line #end meets a soft line start, so there's only one place in this code #that can add newlines. if self._last_line_end is not None: if self._last_line_end == 'hard' or not metaline.soft_line_start: metaline.insert(0, '\n') for prot in self.protocols: prot.metalineReceived(metaline) self._last_line_end = metaline.line_end
def setUp(self): self.f = TelnetClientFactory(None, 'ascii', None) self.f.realm = self.e = Mock(spec=RootRealm) self.tc = TelnetClient(self.f) self.tc.transport = FakeTransport() self.fores = RunLengthList([(0, fg_code(WHITE, False))]) self.backs = RunLengthList([(0, bg_code(BLACK))])
def __init__(self, realm, logformat): self.fore = fg_code(WHITE, False) self.back = bg_code(BLACK) self._dirty = False realm.addProtocol(self) self.log = open( time.strftime(logformat) % {'name': realm.factory.name}, 'a') self.log.write(self.log_preamble)
def test_target_seen_highlighting(self): ml = Metaline('bar foo baz', RunLengthList([(0, 'foo')]), RunLengthList([(0, 'bar')])) ti = TriggerMatchingRealm(ml, self.r, self.r, Mock()) a = ti.alterer self.t.target_seen.func(mobj, ti) res = a.apply(ml) assert res.fores.items() == [(0, 'foo'), (4, fg_code(RED, True)), (7, 'foo')]
def test_fixes_LF_CR_normally(self): self.tc.fix_broken_godwars_line_endings = True self.tc.dataReceived("foo\n\r") expected = [simpleml("foo", fg_code(WHITE, False), bg_code(BLACK))] expected[0].wrap = True lines = [ line for ((line, ), kwargs) in self.e.metalineReceived.call_args_list ] assert lines == expected, lines
def test_no_tell_sent_doesnt_cock_up(self): ml = simpleml('Bar tells you, "Blah."', fg_code(WHITE, False), bg_code(BLACK)) self.fact.realm.metalineReceived(ml) ml_written = self.p.metalineReceived.call_args[0][0] colour_expecting = ml_written.fores.get_at(0) self.fact.realm.send("tell baz blah") ml = simpleml("Whom do you wish to tell to?", fg_code(WHITE, False), bg_code(BLACK)) self.fact.realm.metalineReceived(ml) self.fact.realm.send("tell bar blah") ml = simpleml('You tell Bar, "Blah."', fg_code(WHITE, False), bg_code(BLACK)) self.fact.realm.metalineReceived(ml) ml_written_2 = self.p.metalineReceived.call_args[0][0] assert ml_written_2.fores.get_at(10) == colour_expecting
def obj_as_metaline(self, o): desc = self.objs[o] print desc.keys() colour = HexFGCode(0xFF, 0xAA, 0x00) metaline = simpleml('(', colour, bg_code(BLACK)) metaline += simpleml(desc['type'], colour, bg_code(BLACK)) if desc['weapon'] and desc['weapon'] != 'None': metaline += simpleml(',' + desc['weapon'], fg_code(YELLOW, True), bg_code(BLACK)) metaline += simpleml(',' + desc['dmg_str'], fg_code(RED, True), bg_code(BLACK)) metaline += simpleml(',' + '%s' % desc['dmg_avg'], fg_code(RED, True), bg_code(BLACK)) if desc['ac']: metaline += simpleml(',AC:%s' % desc['ac'], fg_code(RED, True), bg_code(BLACK)) if desc['prop'] != '': metaline += simpleml(',' + desc['prop'], fg_code(BLUE, True), bg_code(BLACK)) metaline += simpleml(')', colour, bg_code(BLACK)) return metaline
def parseline(self, line): """Interpret the VT100 codes in line and returns a Metaline, replete with RunLengthLists, that splits the text, foreground and background into three separate channels. """ fores, backs, cleanline = self._parseline(line) rlfores = RunLengthList(((length, fg_code(colour, bold)) for (length, (colour, bold)) in fores), _normalised=True) rlbacks = RunLengthList( ((length, bg_code(colour)) for (length, colour) in backs), _normalised=True) return Metaline(cleanline, rlfores, rlbacks)
def test_lineReceived_parses_colours(self): expected = [ Metaline('foo', RunLengthList([(0, fg_code(RED, False))]), self.backs, wrap=True) ] self.tc.lineReceived('\x1b[31mfoo') lines = [ line for ((line, ), kwargs) in self.e.metalineReceived.call_args_list ] assert lines == expected, lines
def test_change_fore_with_trailing_colours(self): #don't know why, but this test exposed what looked like a quasi-random #failure... ml = Metaline( 'foobars eggs.', RunLengthList([(0, fg_code(CYAN, False)), (13, fg_code(WHITE, False))]), RunLengthList([(0, None)])) self.la.change_fore(0, 7, fg_code(RED, True)) res = self.la.apply(ml) expected = [(0, fg_code(RED, True)), (7, fg_code(CYAN, False)), (13, fg_code(WHITE, False))] assert res.fores.items() == expected, \ res.fores.items()
def anyline(self, match, realm): if self.opozn_flag: s = match.group(1).strip() if s != '': self.obj_desc = '%s\n%s' % (self.obj_desc, s) if self.parse_flag: # logging baz m = RE_BAZ_NEW.match(match.group(1)) print m, match.group(1) if m: w = { 'lot': m.group(1).strip(), 'object': m.group(2).strip(), 'price': m.group(3).strip(), 'date': '%s' % datetime.datetime.now(), } self.baz_log.write('%s\n' % json.dumps(w, encoding="utf-8")) self.baz_log.flush() print 'PPPPP', match.group(1).strip() for res in OBJ_RES: m = res.match(match.group(1)) if m: o = m.group(1).strip() if not self.has_obj(o): print 'Getting from mudportal' desc = self.get_from_mudportal(o) if desc != {}: self.update_obj(o, desc) print o if self.has_obj(o): realm.alterer.insert_metaline(m.start(1) + len(o) + 1, self.obj_as_metaline(o)) else: metaline = simpleml('(?)', fg_code(RED, True), bg_code(BLACK)) realm.alterer.insert_metaline(m.start(1) + len(o) + 1, metaline)
def test_ColourCodeParser_deals_with_blank_colours_as_0(): ccp = ColourCodeParser() inline = 'foo\x1b[30;mbar' ml = ccp.parseline(inline) assert ml.fores.items() == [(0, fg_code(WHITE, False))]
def test_ColourCodeParser_no_line(): ccp = ColourCodeParser() inline = '' ml = ccp.parseline(inline) assert ml.fores.items() == [(0, fg_code(WHITE, False))] assert ml.backs.items() == [(0, bg_code(BLACK))]
def test_ColourCodeParser_redundant_unbolding(): ccp = ColourCodeParser() inline = "foo\x1b[22m" ml = ccp.parseline(inline) assert ml.fores == {0: fg_code(WHITE, False)}
def test_ColourCodeParser_normalises_ANSI_colours(): ccp = ColourCodeParser() inline = '\x1b[01mfoobar' ml = ccp.parseline(inline) assert ml.fores.items() == [(0, fg_code(WHITE, True))], \ ml.fores.items()
def test_ColourCodeParser_bold_on_and_off_remembers_colour(): ccp = ColourCodeParser() inline = '\x1b[30;1mfoo\x1b[22mbar' ml = ccp.parseline(inline) assert ml.fores.items() == [(0, fg_code(BLACK, True)), (3, fg_code(BLACK, False))]
def test_ColourCodeParser_all_reset_bold_change_made(): ccp = ColourCodeParser() inline = "\x1b[1mfoo\x1b[0m" ml = ccp.parseline(inline) assert ml.fores == {0: fg_code(WHITE, True), 3: fg_code(WHITE, False)}, ml.fores
def test_ColourCodeParser_add_reset_fore_change_made(): ccp = ColourCodeParser() inline = "\x1b[30mfoo\x1b[0m" ml = ccp.parseline(inline) assert ml.fores == {0: fg_code(BLACK, False), 3: fg_code(WHITE, False)}, ml.fores
def test_ColOurCodeParser_redundant_fore_reset(): ccp = ColourCodeParser() inline = "foo\x1b[38m" ml = ccp.parseline(inline) assert ml.fores == {0: fg_code(WHITE, False)}
def test_ColourCodeParser_redundant_fore_change(): ccp = ColourCodeParser() inline = 'foo\x1b[37m' ml = ccp.parseline(inline) assert ml.fores == {0: fg_code(WHITE, False)}
def test_ColourCodeParser_all_reset_fore_and_back_not_needed(): ccp = ColourCodeParser() inline = "foo\x1b[0m" ml = ccp.parseline(inline) assert ml.fores == {0: fg_code(WHITE, False)} assert ml.backs == {0: bg_code(BLACK)}
def write_c(self, s, c): self.write(ml(s, fg_code(c, True)))
"""Colour-code your tell conversations by person. For: Achaea. """ from collections import deque from mudpyl.triggers import binding_trigger from mudpyl.aliases import binding_alias from mudpyl.colours import NORMAL_CODES, BLACK, YELLOW, fg_code from mudpyl.modules import BaseModule #exclude unbold black and bold yellow: the first is unreadable and the second #is the default tell colour. We want VIBRANCY. all_colours = set(fg_code(col, True) for col in NORMAL_CODES if col != YELLOW) | \ set(fg_code(col, False) for col in NORMAL_CODES if col != BLACK) class TellColourer(BaseModule): """Keeps track of who you're talking to, and colour-codes tells to and from them. """ def __init__(self, factory): BaseModule.__init__(self, factory) #could use an OrderedDict here instead of these two. self.assigned_colours = {} self.assigned_order = [] self.sending_to = deque() def touch_name(self, name): """Return the colour to display name in.
def test_ColourCodeParser_redundant_bolding(): ccp = ColourCodeParser() inline = '\x1b[1mfoo\x1b[1m' ml = ccp.parseline(inline) assert ml.fores == {0: fg_code(WHITE, True)}, ml.fores