<commit_before>import getpass
import glob
import json
import os
from string import Template
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, ProcessProtocol
from twisted.internet.task import LoopingCall
from twisted.protocols.basic import LineReceiver
import psutil
import urwid
import properties
from shared import console_repr
from twisted.python import log


class TabEvent:
    fail = None
    def __init__(self, line, players):
        pos = line.rfind(' ')+1
        if pos == 0:
            self.left, right = "", line
        else:
            self.left, right = line[:pos], line[pos:]

        self.players = filter(lambda p: p.startswith(right), players)
        if len(self.players) == 0:
            self.fail = line
        self.index = 0

    def next(self):
        if self.fail:
            return self.fail
        i = self.index % len(self.players)
        self.index += 1
        return self.left + self.players[i]



class Prompt(urwid.Edit):
    def __init__(self, get_players, run_command, *a, **k):
        self.history = ['']
        self.history_pos = 0
        self.tab = None

        self.get_players = get_players
        self.run_command = run_command

        urwid.Edit.__init__(self, *a, **k)

    def get_prompt(self):
        return self.get_edit_text()

    def set_prompt(self, x):
        self.set_edit_text(x)
        self.set_edit_pos(len(x))

    def save_prompt(self):
        self.history[self.history_pos] = self.get_prompt()

    def load_prompt(self):
        self.set_prompt(self.history[self.history_pos])

    def keypress(self, size, key):
        if key != 'tab':
            self.tab = None

        if key == 'up':
            if self.history_pos > 0:
                self.save_prompt()
                self.history_pos -= 1
                self.load_prompt()
        elif key == 'down':
            if self.history_pos < len(self.history)-1:
                self.save_prompt()
                self.history_pos += 1
                self.load_prompt()
        elif key == 'enter':
            text = self.get_prompt()
            self.run_command(text)
            self.history_pos = len(self.history) - 1
            if self.history[self.history_pos-1] == text:
                self.set_prompt('')
                self.cursor = 0
                self.save_prompt()
            else:
                self.save_prompt()
                self.history.append('')
                self.history_pos += 1
                self.load_prompt()
        elif key == 'tab':
            text = self.get_prompt()
            if text == '':
                self.set_prompt('say ')
            else:
                if self.tab is None:
                    self.tab = TabEvent(text, self.get_players())
                self.set_prompt(self.tab.next())
        else:
            return urwid.Edit.keypress(self, size, key)


class PMenuButton(urwid.Button):
    def __init__(self, caption, *a):
        super(PMenuButton, self).__init__(caption, *a)
        self._w = urwid.SelectableIcon(caption, 0)

class PMenuWrap(urwid.WidgetPlaceholder):
    names = ('players', 'actions', 'reasons')
    def __init__(self, actions, reasons, dispatch, escape):
        self.dispatch = dispatch
        self.escape = escape
        self._pmenu_lists   = [ (n, urwid.SimpleListWalker([])) for n    in self.names        ]
        self._pmenu_widgets = [ (n, urwid.ListBox(l))           for n, l in self._pmenu_lists ]

        self.fill(1, zip(actions, actions))
        self.fill(2, reasons)

        self.first()

        super(PMenuWrap, self).__init__(self._pmenu_widgets[0][1])

    def fill(self, index, items):
        name, contents = self._pmenu_lists[index]
        del contents[0:len(contents)]
        for name, result in items:
            e = urwid.AttrMap(PMenuButton(name, self.next, result), 'menu_item', 'menu_item_focus')
            contents.append(e)

    def first(self):
        self._pmenu_acc = []
        self._pmenu_stage = 0
        self.original_widget = self._pmenu_widgets[0][1]


    def next(self, widget, result):
        acc = self._pmenu_acc
        acc.append(result)
        #run command?
        if (self._pmenu_stage == 1 and not (result in ('kick', 'ban') and len(self._pmenu_lists[2][1]) > 0)) or\
           (self._pmenu_stage == 2):
            self.dispatch(' '.join([acc[1]] + [acc[0]] + acc[2:]))
            self.first()
        #next menu
        else:
            self._pmenu_stage += 1
            self.original_widget = self._pmenu_widgets[self._pmenu_stage][1]

    def prev(self):
        self._pmenu_acc.pop()
        self._pmenu_stage -= 1
        self.original_widget = self._pmenu_widgets[self._pmenu_stage][1]

    def keypress(self, size, key):
        if key == 'esc':
            if self._pmenu_stage == 0:
                self.escape()
            else:
                self.first()
        elif key == 'backspace':
            if self._pmenu_stage == 0:
                self.escape()
            else:
                self.prev()
        else:
            return self.original_widget.keypress(size, key)

    def set_players(self, players):
        content = self._pmenu_lists[0][1]
        diff = lambda a, b: [[e for e in d if not e in c] for c, d in ((a, b),(b, a))]

        add, remove = diff([b.original_widget.label for b in list(content)], players)

        #first remove players who logged off
        for b in list(content):
            if b.original_widget.label in remove:
                content.remove(b)

        #now add new players
        i=0
        while len(add)>0:
            a = add.pop(0)
            while i < len(content)-1 and content[i].original_widget.label < a:
                i+=1
            content.insert(i, urwid.AttrMap(PMenuButton(a, self.next, a), 'menu_item', 'menu_item_focus'))
            i += 1


class UI:
    loop = None
    def __init__(self, palette, get_players, run_command, switch_server, pmenu_actions, pmenu_reasons):
        self.palette = palette
        self.get_players = get_players
        self.run_command = run_command
        self.switch_server = switch_server

        self.pmenu_actions = pmenu_actions
        self.pmenu_reasons = pmenu_reasons
<commit_msg>client: fix new players being added to the player list with case-sensitive ordering.<commit_after>import getpass
import glob
import json
import os
from string import Template
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, ProcessProtocol
from twisted.internet.task import LoopingCall
from twisted.protocols.basic import LineReceiver
import psutil
import urwid
import properties
from shared import console_repr
from twisted.python import log


class TabEvent:
    fail = None
    def __init__(self, line, players):
        pos = line.rfind(' ')+1
        if pos == 0:
            self.left, right = "", line
        else:
            self.left, right = line[:pos], line[pos:]

        self.players = filter(lambda p: p.startswith(right), players)
        if len(self.players) == 0:
            self.fail = line
        self.index = 0

    def next(self):
        if self.fail:
            return self.fail
        i = self.index % len(self.players)
        self.index += 1
        return self.left + self.players[i]



class Prompt(urwid.Edit):
    def __init__(self, get_players, run_command, *a, **k):
        self.history = ['']
        self.history_pos = 0
        self.tab = None

        self.get_players = get_players
        self.run_command = run_command

        urwid.Edit.__init__(self, *a, **k)

    def get_prompt(self):
        return self.get_edit_text()

    def set_prompt(self, x):
        self.set_edit_text(x)
        self.set_edit_pos(len(x))

    def save_prompt(self):
        self.history[self.history_pos] = self.get_prompt()

    def load_prompt(self):
        self.set_prompt(self.history[self.history_pos])

    def keypress(self, size, key):
        if key != 'tab':
            self.tab = None

        if key == 'up':
            if self.history_pos > 0:
                self.save_prompt()
                self.history_pos -= 1
                self.load_prompt()
        elif key == 'down':
            if self.history_pos < len(self.history)-1:
                self.save_prompt()
                self.history_pos += 1
                self.load_prompt()
        elif key == 'enter':
            text = self.get_prompt()
            self.run_command(text)
            self.history_pos = len(self.history) - 1
            if self.history[self.history_pos-1] == text:
                self.set_prompt('')
                self.cursor = 0
                self.save_prompt()
            else:
                self.save_prompt()
                self.history.append('')
                self.history_pos += 1
                self.load_prompt()
        elif key == 'tab':
            text = self.get_prompt()
            if text == '':
                self.set_prompt('say ')
            else:
                if self.tab is None:
                    self.tab = TabEvent(text, self.get_players())
                self.set_prompt(self.tab.next())
        else:
            return urwid.Edit.keypress(self, size, key)


class PMenuButton(urwid.Button):
    def __init__(self, caption, *a):
        super(PMenuButton, self).__init__(caption, *a)
        self._w = urwid.SelectableIcon(caption, 0)

class PMenuWrap(urwid.WidgetPlaceholder):
    names = ('players', 'actions', 'reasons')
    def __init__(self, actions, reasons, dispatch, escape):
        self.dispatch = dispatch
        self.escape = escape
        self._pmenu_lists   = [ (n, urwid.SimpleListWalker([])) for n    in self.names        ]
        self._pmenu_widgets = [ (n, urwid.ListBox(l))           for n, l in self._pmenu_lists ]

        self.fill(1, zip(actions, actions))
        self.fill(2, reasons)

        self.first()

        super(PMenuWrap, self).__init__(self._pmenu_widgets[0][1])

    def fill(self, index, items):
        name, contents = self._pmenu_lists[index]
        del contents[0:len(contents)]
        for name, result in items:
            e = urwid.AttrMap(PMenuButton(name, self.next, result), 'menu_item', 'menu_item_focus')
            contents.append(e)

    def first(self):
        self._pmenu_acc = []
        self._pmenu_stage = 0
        self.original_widget = self._pmenu_widgets[0][1]


    def next(self, widget, result):
        acc = self._pmenu_acc
        acc.append(result)
        #run command?
        if (self._pmenu_stage == 1 and not (result in ('kick', 'ban') and len(self._pmenu_lists[2][1]) > 0)) or\
           (self._pmenu_stage == 2):
            self.dispatch(' '.join([acc[1]] + [acc[0]] + acc[2:]))
            self.first()
        #next menu
        else:
            self._pmenu_stage += 1
            self.original_widget = self._pmenu_widgets[self._pmenu_stage][1]

    def prev(self):
        self._pmenu_acc.pop()
        self._pmenu_stage -= 1
        self.original_widget = self._pmenu_widgets[self._pmenu_stage][1]

    def keypress(self, size, key):
        if key == 'esc':
            if self._pmenu_stage == 0:
                self.escape()
            else:
                self.first()
        elif key == 'backspace':
            if self._pmenu_stage == 0:
                self.escape()
            else:
                self.prev()
        else:
            return self.original_widget.keypress(size, key)

    def set_players(self, players):
        content = self._pmenu_lists[0][1]
        diff = lambda a, b: [[e for e in d if not e in c] for c, d in ((a, b),(b, a))]

        add, remove = diff([b.original_widget.label for b in list(content)], players)

        #first remove players who logged off
        for b in list(content):
            if b.original_widget.label in remove:
                content.remove(b)

        #now add new players
        i=0
        while len(add)>0:
            a = add.pop(0)
            while i < len(content)-1 and content[i].original_widget.label.lower() < a.lower():
                i+=1
            content.insert(i, urwid.AttrMap(PMenuButton(a, self.next, a), 'menu_item', 'menu_item_focus'))
            i += 1


class UI:
    loop = None
    def __init__(self, palette, get_players, run_command, switch_server, pmenu_actions, pmenu_reasons):
        self.palette = palette
        self.get_players = get_players
        self.run_command = run_command
        self.switch_server = switch_server

        self.pmenu_actions = pmenu_actions
        self.pmenu_reasons = pmenu_reasons

{'fraction_non_alphanumeric': 0.1136020351379283, 'fraction_numerical': 0.007154781779155735, 'mean_word_length': 1.9317175483570264, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4390014', 'n_tokens_mistral': 3964, 'n_tokens_neox': 3752, 'n_words': 902}