Пример #1
0
    def createInputEvent(self, tkevent):
        """ Handles the <KeyPress-Return> event."""
        val = fix_unicode(self.get())
        ##    # JLP: remove special characters
        ##    val = val.replace("à", "a")
        ##    val = val.replace("â", "a")
        ##    val = val.replace("ç", "c")
        ##    val = val.replace("é", "e")
        ##    val = val.replace("è", "e")
        ##    val = val.replace("ê", "e")
        ##    val = val.replace("î", "i")
        ##    val = val.replace("ô", "o")
        ##    val = val.replace("ù", "u")
        ##    val = val.replace("û", "u")
        self._partk.handleinput(val)

        # self._inputstack.insert(0, val)
        # if len(self._inputstack) > 30:
        #   self._inputstack = self._inputstack[:-1]

        if exported.get_config("saveinputhighlight") == 1:
            self.selection_range(0, 'end')
        else:
            self.delete(0, 'end')
        self.hist_index = -1

        if val == exported.get_config("commandchar") + "end":
            self._partk._topframe.quit()
Пример #2
0
def snoop_cmd(ses, args, input):
    """
  Sets the session specified into or out of snooping mode.  When
  a session is in snoop mode, you will see mud data from that session
  regardless of what session is the current session.

  examples:
    #snoop a          -- tells you whether a is in snoop mode
    #snoop a on       -- sets snoop mode for a

  category: commands
  """
    snoopsession = args["session"]
    mode = args["mode"]

    ses = exported.get_session(snoopsession)
    if ses == None:
        exported.write_error("snoop: session '%s' does not exist." %
                             snoopsession)
        return

    if mode != None:
        ses.setSnoop(mode)

    if exported.get_config("snoop", ses, 1) == 1:
        exported.write_message("snoop: snooping is enabled for %s." %
                               snoopsession)
    else:
        exported.write_message("snoop: snooping is disabled for %s." %
                               snoopsession)
Пример #3
0
    def createInputEvent(self, tkevent):
        """ Handles the <KeyPress-Return> event."""
        val = fix_unicode(self.get())
        self._partk.handleinput(val)

        # self._inputstack.insert(0, val)
        # if len(self._inputstack) > 30:
        #   self._inputstack = self._inputstack[:-1]

        if exported.get_config("saveinputhighlight") == 1:
            self.selection_range(0, 'end')
        else:
            self.delete(0, 'end')
        self.hist_index = -1

        if val == exported.get_config("commandchar") + "end":
            self._partk._topframe.quit()
Пример #4
0
  def callBinding(self, tkevent):
    """ Handles arbitrary bindings of function call keypresses."""

    # handle all the function keys except F1
    if tkevent.keysym == "F1":
      self._partk.handleinput(exported.get_config("commandchar") + "help")
      return "break"

    if self._executeBinding("VK_%s" % tkevent.keysym) == 1:
      return "break"
Пример #5
0
    def mudfilter(self, args):
        """
    mud_filter_hook function to perform substitutions on data 
    that comes from the mud.
    """
        ses = args["session"]
        text = args["dataadj"]

        if exported.get_config("ignoresubs", ses, 0) == 0:
            text = self.expand(ses, text)
        return text
Пример #6
0
    def mudfilter(self, args):
        """
    mud_filter_hook function to check for actions when data
    comes from the mud.
    """
        ses = args["session"]
        text = args["dataadj"]

        if exported.get_config("ignoreactions", ses, 0) == 0:
            if self._actions.has_key(ses):
                self._actions[ses].checkActions(text)

        return text
Пример #7
0
    def __init__(self):
        base.BaseUI.__init__(self)

        locale.setlocale(locale.LC_ALL, "")
        exported.hook_register("startup_hook", startup_hook)
        exported.hook_register("to_user_hook", self.write)
        exported.hook_register("config_change_hook", self.config_changed)
        exported.hook_register("bell_hook", lambda x: sys.stdout.write('\07'))
        exported.hook_register(
            "prompt_hook", lambda x: self.write({
                'message':
                message.Message(x["prompt"], message.MUDDATA, x["session"])
            }))
        exported.hook_register("write_hook", bindings_persist)

        self.unfinished_ = {}

        self.prompt_ = [("", curses.A_NORMAL)]
        self.lines_ = [self.prompt_]
        self.prompt_index_ = 0

        self.running_ = 1

        self.cfg_lazy_ = exported.get_config("curses.lazy")
        self.cfg_maxscrollback_ = exported.get_config("curses.maxscrollback")
        self.cfg_keydebug_ = exported.get_config("curses.keydebug")
        self.cfg_compact_ = exported.get_config("curses.compact")
        self.cfg_echo_ = exported.get_config("mudecho")

        global color_lookup
        self.attr_error_ = color_lookup[exported.get_config(
            "curses.attr.error")]
        self.attr_session_ = color_lookup[exported.get_config(
            "curses.attr.session")]
        self.attr_lyntin_ = color_lookup[exported.get_config(
            "curses.attr.lyntin")]
        self.attr_user_ = color_lookup[exported.get_config("curses.attr.user")]

        self.output_ = os.pipe()  # MUD output signalling pipe
Пример #8
0
    def runui(self):
        global HELP_TEXT
        exported.add_help("textui", HELP_TEXT)
        exported.write_message("For textui help, type \"#help textui\".")

        # termios is the module that allows us to change echo for a terminal
        # but only if the module is present
        try:
            import termios
        except ImportError:
            self._tio = 0
        else:
            self._tio = 1
            echonew = termios.tcgetattr(self._stdin.fileno())
            self._onecho_attr = echonew[3]
            self._offecho_attr = echonew[3] & ~termios.ECHO

        if config.options.has_key("readline"):
            try:
                import readline
            except ImportError:
                self._rline = 0
                exported.write_error("Readline not available for your system.")
            else:
                self._rline = 1

                # we do some stuff to grab the readlinerc file if they have one
                # so the user can set some readline oriented things which makes
                # things a little nicer for the user.
                d = exported.get_config("datadir")

                try:
                    readline.read_init_file(d + "readlinerc")
                except:
                    exported.write_error(
                        "Note: No readlinerc file available in %s." % d)

                exported.write_message("Readline enabled.")

        if self._tio == 0 or self._rline == 1:
            exported.write_error("Warming: echo off is unavailable.  " +
                                 "Your password will be visible.")

        # go into the main loop
        self.run()
Пример #9
0
    def showTextForSession(self, ses):
        """
    Returns whether or not we should show text for this session--it's
    a convenience method.

    We return a 1 if the session is None, it doesn't have a _snoop
    attribute, it's the current session, or get_config("snoop", ses) == 1.

    @param ses: the session we're looking at--if it's None we return a 1
    @type  ses: Session

    @returns: 1 if we should show text, 0 if not
    @rtype: boolean
    """
        if ses == None or getattr(ses, "_snoop", None) == None \
            or exported.get_current_session() == ses \
            or exported.get_config("snoop", ses, 1) == 1:
            return 1
        return 0
Пример #10
0
  def write(self, args):
    """
    Handles writing information from the mud and/or Lyntin
    to the user.
    """
    msg = args["message"]
    if type(msg) == types.StringType:
      msg = message.Message(msg, message.LTDATA)
    if not hasattr(msg, "data"):
      return
    line = msg.data
    ses = msg.session

    if line == '' or self.showTextForSession(ses) == 0:
      return

    # we prepend the session name to the text if this is not the 
    # current session sending text.
    pretext = ""
    if ses != None and ses != exported.get_current_session():
      pretext = "[" + ses.getName() + "] "

    if msg.type == message.ERROR or msg.type == message.LTDATA:
      if msg.type == message.ERROR:
        pretext = "error: " + pretext

      line = pretext + utils.chomp(line).replace("\n", "\n" + pretext)
      self.window.write(line+"\n")
      return

    elif msg.type == message.MUDDATA:
      if "\n" not in msg.data: msg.data = msg.data + "\n"
      self.window.write(msg.data)
      return

    if exported.get_config("ansicolor") == 0:
      if pretext:
        if line.endswith("\n"):
          line = (pretext + line[:-1].replace("\n", "\n" + pretext) + "\n")
        else:
          line = pretext + line.replace("\n", "\n" + pretext)
      self.window.write(line)
      return
Пример #11
0
    def userfilter(self, args):
        """
    user_filter_hook function to check for speedwalking expansion.
    """
        ses = args["session"]
        internal = args["internal"]
        verbatim = args["verbatim"]
        text = args["dataadj"]

        if not self._hashes.has_key(ses) or exported.get_config(
                "speedwalk", ses) == 0 or verbatim == 1:
            return text

        sdata = self._hashes[ses]

        if not sdata._dirs or not sdata._regexp or text in sdata._excludes \
            or text in sdata._aliases or not sdata._regexp.match(text):
            return text

        swdirs = []
        dir = num = ""
        for char in text:
            if char.isdigit():
                num = num + char
            else:
                dir = dir + char
                if dir in sdata._dirs_available:
                    if num: count = int(num)
                    else: count = 1
                    for i in range(count):
                        swdirs.append(sdata._dirs[dir])
                    dir = num = ""

        output = ";".join(swdirs)
        if output == text:
            return text
        else:
            # anything that gets recursed on should be recursed internally
            exported.lyntin_command(output, 1, ses)
            return None
Пример #12
0
    def handleUserData(self, input, internal=0):
        """
    Handles input in the context of this session specifically.

    @param input: the user data
    @type  input: string

    @param internal: whether the command came from interally.
        we won't spam hooks and may at some point prevent
        output for internal stuff too.  1 if internal, 0 if not.
    @type  internal: boolean
    """
        # this is the point of much recursion.  everything is registered
        # as a filter and recurses accordingly.
        spamargs = {
            "session": self,
            "internal": internal,
            "verbatim": exported.get_config("verbatim", self),
            "data": input,
            "dataadj": input
        }
        spamargs = exported.filter_mapper_hook_spam("user_filter_hook",
                                                    spamargs)

        if spamargs == None:
            return
        else:
            input = spamargs["dataadj"]

        # after this point we don't do any more recursion.  so it's
        # safe to unescape things and such.
        input = input.replace("\\;", ";")
        input = input.replace("\\$", "$")
        input = input.replace("\\%", "%")

        # just regular data to the mud
        self.writeSocket(input + "\n")
Пример #13
0
    def write(self, args):
        """
    Handles writing information from the mud and/or Lyntin
    to the user.
    """
        msg = args["message"]

        if type(msg) == types.StringType:
            msg = message.Message(msg, message.LTDATA)

        line = msg.data
        ses = msg.session

        if line == '' or self.showTextForSession(ses) == 0:
            return

        # we prepend the session name to the text if this is not the
        # current session sending text.
        pretext = ""
        if ses != None and ses != exported.get_current_session():
            pretext = "[" + ses.getName() + "] "

        if msg.type == message.ERROR or msg.type == message.LTDATA:
            if msg.type == message.ERROR:
                pretext = "error: " + pretext
            else:
                pretext = "lyntin: " + pretext

            line = pretext + utils.chomp(line).replace("\n", "\n" + pretext)
            if exported.get_config("ansicolor") == 1:
                line = DEFAULT_ANSI + line
            sys.stdout.write(line + "\n")
            return

        elif msg.type == message.USERDATA:
            # we don't print user data in the textui
            return

        if exported.get_config("ansicolor") == 0:
            if pretext:
                if line.endswith("\n"):
                    line = (pretext + line[:-1].replace("\n", "\n" + pretext) +
                            "\n")
                else:
                    line = pretext + line.replace("\n", "\n" + pretext)
            sys.stdout.write(line)
            sys.stdout.flush()
            return

        # each session has a saved current color for mud data.  we grab
        # that current color--or user our default if we don't have one
        # for the session yet.
        if self._currcolors.has_key(ses):
            color = self._currcolors[ses]
        else:
            # need a copy of the list and not a reference to the list itself.
            color = list(DEFAULT_COLOR)

        # some sessions have an unfinished color as well--in case we
        # got a part of an ansi color code in a mud message, and the other
        # part is in another message.
        if self._unfinishedcolor.has_key(ses):
            leftover = self._unfinishedcolor[ses]
        else:
            leftover = ""

        lines = line.splitlines(1)
        if lines:
            for i in range(0, len(lines)):
                mem = lines[i]
                acolor = ansi.convert_tuple_to_ansi(color)

                color, leftover = ansi.figure_color(mem, color, leftover)

                if pretext:
                    lines[i] = DEFAULT_ANSI + pretext + acolor + mem
                else:
                    lines[i] = DEFAULT_ANSI + acolor + mem

            sys.stdout.write("".join(lines) + DEFAULT_ANSI)
            sys.stdout.flush()

        self._currcolors[ses] = color
        self._unfinishedcolor[ses] = leftover
Пример #14
0
 def deathHandler(self, tkevent):
     """
 This catches the event where the window is being closed.
 We can't stop it from closing, but we can try to shut down the app.
 """
     self._partk.handleinput(exported.get_config("commandchar") + "end")
Пример #15
0
        else:
            f = open(filename, "r")
            contents = f.readlines()
            f.close()
    except Exception, e:
        exported.write_error(
            "read: file %s cannot be opened.\n%s" % (filename, e), ses)
        return

    contents = [m for m in contents if len(m.strip()) > 0]

    if len(contents) == 0:
        exported.write_message("read: %s had no data." % filename, ses)
        return

    c = exported.get_config("commandchar")
    if not contents[0].startswith(c):
        exported.lyntin_command("%sconfig commandchar %s" %
                                (c, contents[0][0]),
                                internal=1,
                                session=ses)

    command = ""
    continued = 0
    # FIXME - should this be a config setting?
    esc = "\\"

    for mem in contents:
        mem = mem.strip()
        if len(mem) > 0:
            # handle multi-line commands
Пример #16
0
def read_cmd(ses, args, input):
    """
  Reads in a file running each line as a Lyntin command.  This is the
  opposite of #write which allows you to save session settings and
  restore them using #read.

  You can also read in via the commandline when you start Lyntin:

    lyntin --read 3k

  And read can handle HTTP urls:

    lyntin --read http://lyntin.sourceforge.net/lyntinrc

    #read http://lyntin.sourceforge.net/lyntinrc

  Note: the first non-whitespace char is used to set the Lyntin
  command character.  If you use non Lyntin commands in your file,
  make sure the first one is a command char.  If not, use #nop .
  It will skip blank lines.

  If you don't specify a directory, Lyntin will look for the file
  in your datadir.

  category: commands
  """
    filename = args["filename"]

    import os
    if os.sep not in filename and not filename.startswith("http://"):
        filename = config.options["datadir"] + filename

    if filename.startswith("~"):
        filename = os.path.expanduser(filename)

    try:
        # http reading contributed by Sebastian John
        if filename.startswith("http://"):
            contents = utils.http_get(filename).split("\n")
        else:
            f = open(filename, "rb")
            contents = f.readlines()
            f.close()
    except Exception as e:
        exported.write_error(
            "read: file %s cannot be opened.\n%s" % (filename, e), ses)
        return

    contents = [x.decode("utf-8") for x in contents]
    contents = [m for m in contents if len(m.strip()) > 0]

    if len(contents) == 0:
        exported.write_message("read: %s had no data." % filename, ses)
        return

    c = exported.get_config("commandchar")
    if not contents[0].startswith(c):
        exported.lyntin_command("%sconfig commandchar %s" %
                                (c, contents[0][0]),
                                internal=1,
                                session=ses)

    command = ""
    continued = 0
    # FIXME - should this be a config setting?
    esc = "\\"

    for mem in contents:
        mem = mem.strip()
        if len(mem) > 0:
            # handle multi-line commands
            if mem.endswith(esc):
                mem = mem.rstrip(esc)
                continued = 1
            else:
                continued = 0

        command = command + mem
        if not continued:
            exported.lyntin_command(command, internal=1, session=ses)
            command = ""

    exported.write_message("read: file %s read." % filename, ses)