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_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 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_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 test_writes_come_after_echoing(self): self.realm.aliases.append(self.noisy_alias) self.realm.send("spam") expecting = [Metaline("spam", RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True), Metaline("\nFOO FOO FOO", RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]))] assert self.lines_gotten == expecting
def test_trace_writes_after_during_matching_triggers(self): self.realm.tracing = True self.realm.triggers.append(self.tracing_trigger) inline = Metaline('baz', set(), set()) self.realm.metalineReceived(inline) expected_lines = [simpleml("\nTRACE: %s matched!" % self.tracing_trigger, fg_code(WHITE, False), bg_code(BLACK)), simpleml("\nTRACE: Foo", fg_code(WHITE, False), bg_code(BLACK))] print self.lines_gotten print expected = [inline] + expected_lines print expected assert self.lines_gotten == expected
def barrier_off(self,match,realm): realm.display_line=False my_target=match.group(1).lower() if not my_target in self.raze_data: self.raze_data[my_target]=ShieldStatus() else: self.raze_data[my_target].barrier=False realm.root.fireEvent('barrierEvent',my_target,0) if realm.root.get_state('target').lower()==my_target: realm.write(simpleml('BARRIER DOWN, BARRIER DOWN',fg_code(YELLOW,True),bg_code(GREEN))) if self.raze_data[my_target].all_stripped: realm.write(simpleml('ALL SHIELDS DOWN, ALL SHIELDS DOWN',fg_code(YELLOW,True),bg_code(GREEN))) if self.on_shields_down!=None: self.on_shields_down(realm, self.raze_data[my_target])
def rebound_off(self, match,realm): realm.display_line=False my_target=match.group(1).lower() if not my_target in self.raze_data: self.raze_data[my_target]=ShieldStatus() else: self.raze_data[my_target].aura=False realm.root.fireEvent('reboundingEvent',my_target,0) if realm.root.get_state('target').lower()==my_target: realm.cwrite('--- REBOUNDING IS ---- %s'%self.raze_data[my_target].aura) realm.write(simpleml('REBOUNDING DOWN, REBOUNDING DOWN',fg_code(YELLOW,True),bg_code(GREEN))) if self.raze_data[my_target].all_stripped: realm.write(simpleml('ALL SHIELDS DOWN, ALL SHIELDS DOWN',fg_code(YELLOW,True),bg_code(GREEN))) if self.on_shields_down!=None: self.on_shields_down(realm, self.raze_data[my_target])
def test_send_uses_echoes_with_soft_line_start(self): self.realm.send("spam") expected = Metaline('spam', RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True) assert self.lines_gotten == [expected]
def test_trace_writes_after_during_alias_matching(self): self.realm.tracing = True self.realm.aliases.append(self.tracing_alias) inline = Metaline('baz', RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True) self.realm.send('baz') expected_lines = [simpleml("\nTRACE: %s matched!" % self.tracing_alias, fg_code(WHITE, False), bg_code(BLACK)), simpleml("\nTRACE: Foo", fg_code(WHITE, False), bg_code(BLACK))] print self.lines_gotten print expected = [inline] + expected_lines print expected assert self.lines_gotten == expected
def test_send_echos_by_default(self): self.realm.send("bar") expected = Metaline('bar', RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True) assert self.lines_gotten == [expected]
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 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 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.active_channels) self._last_line_end = metaline.line_end
def taggedml(line, default_fg=WHITE, default_bg=BLACK): pattern=r'(<(?:\w|\*)+(?::\w+){0,1}>)' matches=re.findall(pattern, line) new_line="" tag_length=0 index=0 fg=RunLengthList([(0,fg_code(default_fg,False))]) bg=RunLengthList([(0,bg_code(default_bg))]) for m in matches: color_tag=m[1:-1].split(':') fg_color_str=color_tag[0] if '*' in fg_color_str: bold=True fg_color_str=fg_color_str.replace('*','') else: bold=False if len(color_tag)==2: bg_color_str=color_tag[1] else: bg_color_str=None if not hasattr(colours, fg_color_str.upper()): continue if bg_color_str!=None and not hasattr(colours, bg_color_str.upper()): continue m_idx=line.find(m,index) new_line=new_line+line[index:m_idx] try: fg_color=getattr(colours, fg_color_str.upper()) if bg_color_str!=None: bg_color=getattr(colours, bg_color_str.upper()) else: bg_color=default_bg except TypeError: return line fg.add_change(m_idx-tag_length, fg_code(fg_color,bold)) if bg_color!=None: bg.add_change(m_idx-tag_length, bg_code(bg_color)) index=line.find(m,index)+len(m) tag_length+=len(m) new_line=new_line+line[index:] return Metaline(new_line, fg,bg)
def test_send_after_default_echoing_is_off(self): self.realm.aliases.append(self.our_alias_1) self.realm.send("bar") expected = [Metaline('bar', RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True)] assert self.lines_gotten == expected
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_send_after_doesnt_echo_if_asked_not_to(self): self.realm.aliases.append(self.our_alias_2) self.realm.send("baz") expected = [Metaline('baz', RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True)] assert self.lines_gotten == expected
def write(self, line, display_line = True): 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 else: metaline = line self.send_to_client('display_line', [metaline_to_json(metaline),int(display_line)])
def barrier_off(self, match, realm): realm.display_line = False my_target = match.group(1).lower() if not my_target in self.raze_data: self.raze_data[my_target] = ShieldStatus() else: self.raze_data[my_target].barrier = False realm.root.fireEvent('barrierEvent', my_target, 0) if realm.root.get_state('target').lower() == my_target: realm.write( simpleml('BARRIER DOWN, BARRIER DOWN', fg_code(YELLOW, True), bg_code(GREEN))) if self.raze_data[my_target].all_stripped: realm.write( simpleml('ALL SHIELDS DOWN, ALL SHIELDS DOWN', fg_code(YELLOW, True), bg_code(GREEN))) if self.on_shields_down != None: self.on_shields_down(realm, self.raze_data[my_target])
def no_target_rebound_on(self, match, realm): realm.display_line=False my_target=realm.root.get_state('target').lower() if not my_target in self.raze_data: self.raze_data[my_target]=ShieldStatus(aura=True) else: self.raze_data[my_target].aura=True realm.write(simpleml('REBOUNDING ON, REBOUNDING ON',fg_code(YELLOW,True),bg_code(RED))) realm.root.fireEvent('reboundingEvent',my_target,1) if self.on_shields_up!=None: self.on_shields_up(realm, self.raze_data[my_target])
def test_write_writes_after_during_alias_matching(self): self.realm.aliases.append(self.noting_alias) inline = Metaline('bar', RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True) self.realm.send('bar') print self.lines_gotten print expected = [inline, self.noting_line] print expected assert self.lines_gotten == expected
def test_aliases_inside_triggers_write_after_trigger_writes(self): self.realm.triggers.append(self.spam_sending_trigger) self.realm.aliases.append(self.bar_writing_alias) noteline = Metaline("\nBAR BAR BAR", RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))])) self.realm.metalineReceived(self.ml) assert self.lines_gotten == [self.ml, noteline]
def __init__(self, realm, logformat): self.fore = fg_code(WHITE, False) self.back = bg_code(BLACK) self.realm = realm self._dirty = False realm.addProtocol(self) logname=time.strftime(logformat)%{'name':self.realm.factory.name} if not os.path.exists(os.path.dirname(logname)): os.makedirs(os.path.dirname(logname)) self.log = open(time.strftime(logformat) % {'name': self.realm.factory.name}, 'w+') self.log.write(self.log_preamble)
def rebound_off(self, match, realm): realm.display_line = False my_target = match.group(1).lower() if not my_target in self.raze_data: self.raze_data[my_target] = ShieldStatus() else: self.raze_data[my_target].aura = False realm.root.fireEvent('reboundingEvent', my_target, 0) if realm.root.get_state('target').lower() == my_target: realm.cwrite('--- REBOUNDING IS ---- %s' % self.raze_data[my_target].aura) realm.write( simpleml('REBOUNDING DOWN, REBOUNDING DOWN', fg_code(YELLOW, True), bg_code(GREEN))) if self.raze_data[my_target].all_stripped: realm.write( simpleml('ALL SHIELDS DOWN, ALL SHIELDS DOWN', fg_code(YELLOW, True), bg_code(GREEN))) if self.on_shields_down != None: self.on_shields_down(realm, self.raze_data[my_target])
def __init__(self, client, logformat): self.fore = fg_code(WHITE, False) self.back = bg_code(BLACK) self.client = client self._dirty = False client.addProtocol(self) logname=time.strftime(logformat)%{'name':self.client.mod.name} if not os.path.exists(os.path.dirname(logname)): os.makedirs(os.path.dirname(logname)) self.log = open(time.strftime(logformat) % {'name': self.client.mod.name}, 'w+') self.log.write(self.log_preamble)
def no_target_rebound_on(self, match, realm): realm.display_line = False my_target = realm.root.get_state('target').lower() if not my_target in self.raze_data: self.raze_data[my_target] = ShieldStatus(aura=True) else: self.raze_data[my_target].aura = True realm.write( simpleml('REBOUNDING ON, REBOUNDING ON', fg_code(YELLOW, True), bg_code(RED))) realm.root.fireEvent('reboundingEvent', my_target, 1) if self.on_shields_up != None: self.on_shields_up(realm, self.raze_data[my_target])
def barrier_on(self, match,realm): realm.display_line=False my_target = match.group(1).lower() if not my_target in self.raze_data: self.raze_data[my_target]=ShieldStatus(barrier=True) else: self.raze_data[my_target].barrier=True realm.root.fireEvent('barrierEvent',my_target,1) if realm.root.get_state('target').lower()==my_target: new_line = 'BARRIER ON, BARRIER ON' realm.write(simpleml(new_line, fg_code(YELLOW,True),bg_code(RED))) if self.on_shields_up!=None: self.on_shields_up(realm,self.raze_data[my_target])
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 barrier_on(self, match, realm): realm.display_line = False my_target = match.group(1).lower() if not my_target in self.raze_data: self.raze_data[my_target] = ShieldStatus(barrier=True) else: self.raze_data[my_target].barrier = True realm.root.fireEvent('barrierEvent', my_target, 1) if realm.root.get_state('target').lower() == my_target: new_line = 'BARRIER ON, BARRIER ON' realm.write(simpleml(new_line, fg_code(YELLOW, True), bg_code(RED))) if self.on_shields_up != None: self.on_shields_up(realm, self.raze_data[my_target])
def test_sends_and_writes_in_a_consistent_order(self): self.realm.aliases.append(self.foo_alias_sends_bar) self.realm.aliases.append(self.bar_alias_sends_baz) self.realm.send("foo", echo = True) expect_write = [Metaline("baz", RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True), Metaline("\nbar", RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True), Metaline("\nfoo", RunLengthList([(0, fg_code(WHITE, False))]), RunLengthList([(0, bg_code(BLACK))]), soft_line_start = True)] expect_send = ['baz', 'bar', 'foo'] sent = [line for ((line,), kwargs) in self.realm.telnet.sendLine.call_args_list] assert self.lines_gotten == expect_write assert sent == expect_send
def rebounding_soon(self, match, realm): #realm.display_line = False my_target=match.group(1).lower() if my_target==realm.root.get_state('target').lower(): realm.write(simpleml('REBOUNDING SOON, REBOUNDING SOON!', fg_code(YELLOW,True),bg_code(RED))) def delayed_aura(realm): realm.write("DONE!") if not my_target in self.raze_data: self.raze_data[my_target]=ShieldStatus(aura=True) else: self.raze_data[my_target].aura=True if self.on_shields_up!=None: self.on_shields_up(realm, self.raze_data[my_target]) self.aura_timer=realm.root.set_timer(7, delayed_aura, realm.root)
def rebounding_soon(self, match, realm): #realm.display_line = False my_target = match.group(1).lower() if my_target == realm.root.get_state('target').lower(): realm.write( simpleml('REBOUNDING SOON, REBOUNDING SOON!', fg_code(YELLOW, True), bg_code(RED))) def delayed_aura(realm): realm.write("DONE!") if not my_target in self.raze_data: self.raze_data[my_target] = ShieldStatus(aura=True) else: self.raze_data[my_target].aura = True if self.on_shields_up != None: self.on_shields_up(realm, self.raze_data[my_target]) self.aura_timer = realm.root.set_timer(7, delayed_aura, realm.root)
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 metaLine(self): line = "Shield|Aura|Barrier" fg = RunLengthList([(0, fg_code(YELLOW, True))]) bg = RunLengthList([(0, bg_code(GREEN))]) if self.shield: bg.add_change(0, bg_code(RED)) else: bg.add_change(0, bg_code(GREEN)) first_separator = line.find('|') if self.aura: bg.add_change(first_separator + 1, RED) else: bg.add_change(first_separator + 1, GREEN) second_separator = line.find('|', first_separator + 1) if self.barrier: bg.add_change(second_separator + 1, RED) else: bg.add_change(second_separator + 1, GREEN) ml = Metaline(line, fg, bg) return ml