Example #1
0
    def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None, receiver=None, cmdstring=None, obj=None):
        """
        Test a command by assigning all the needed
        properties to cmdobj and  running
            cmdobj.at_pre_cmd()
            cmdobj.parse()
            cmdobj.func()
            cmdobj.at_post_cmd()
        The msgreturn value is compared to eventual
        output sent to caller.msg in the game

        Returns:
            msg (str): The received message that was sent to the caller.

        """
        caller = caller if caller else self.char1
        receiver = receiver if receiver else caller
        cmdobj.caller = caller
        cmdobj.cmdstring = cmdstring if cmdstring else cmdobj.key
        cmdobj.args = args
        cmdobj.cmdset = cmdset
        cmdobj.session = SESSIONS.session_from_sessid(1)
        cmdobj.player = self.player
        cmdobj.raw_string = cmdobj.key + " " + args
        cmdobj.obj = obj or (caller if caller else self.char1)
        # test
        old_msg = receiver.msg
        returned_msg = ""
        try:
            receiver.msg = Mock()
            cmdobj.at_pre_cmd()
            cmdobj.parse()
            cmdobj.func()
            cmdobj.at_post_cmd()
        except InterruptCommand:
            pass
        finally:
            # clean out prettytable sugar. We only operate on text-type
            stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
                    for name, args, kwargs in receiver.msg.mock_calls]
            # Get the first element of a tuple if msg received a tuple instead of a string
            stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
            if msg is not None:
                returned_msg = "||".join(_RE.sub("", mess) for mess in stored_msg)
                returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
                if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
                    sep1 = "\n" + "="*30 + "Wanted message" + "="*34 + "\n"
                    sep2 = "\n" + "="*30 + "Returned message" + "="*32 + "\n"
                    sep3 = "\n" + "="*78
                    retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
                    raise AssertionError(retval)
            else:
                returned_msg = "\n".join(str(msg) for msg in stored_msg)
                returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
            receiver.msg = old_msg

        return returned_msg
Example #2
0
    def send_text(self, *args, **kwargs):
        """
        Send text data. This is an in-band telnet operation.

        Args:
            text (str): The first argument is always the text string to send. No other arguments
                are considered.
        Kwargs:
            options (dict): Send-option flags
                   - mxp: Enforce MXP link support.
                   - ansi: Enforce no ANSI colors.
                   - xterm256: Enforce xterm256 colors, regardless of TTYPE setting.
                   - nocolor: Strip all colors.
                   - raw: Pass string through without any ansi processing
                        (i.e. include Evennia ansi markers but do not
                        convert them into ansi tokens)
                   - echo: Turn on/off line echo on the client. Turn
                        off line echo for client, for example for password.
                        Note that it must be actively turned back on again!

        """
        # print "telnet.send_text", args,kwargs  # DEBUG
        text = args[0] if args else ""
        if text is None:
            return
        text = to_str(text, force_string=True)

        # handle arguments
        options = kwargs.get("options", {})
        flags = self.protocol_flags
        xterm256 = options.get("xterm256", flags.get('XTERM256', True))
        useansi = options.get("ansi", flags.get('ANSI', True))
        raw = options.get("raw", flags.get("RAW", False))
        nocolor = options.get("nocolor", flags.get("NOCOLOR") or not (xterm256 or useansi))
        # echo = options.get("echo", None)  # DEBUG
        screenreader = options.get("screenreader", flags.get("SCREENREADER", False))

        if screenreader:
            # screenreader mode cleans up output
            text = ansi.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
            text = _RE_SCREENREADER_REGEX.sub("", text)

        if raw:
            # no processing
            self.sendLine(text)
            return
        else:
            # we need to make sure to kill the color at the end in order
            # to match the webclient output.
            linetosend = ansi.parse_ansi(_RE_N.sub("", text) + ("||n" if text.endswith("|") else "|n"),
                                         strip_ansi=nocolor, xterm256=xterm256, mxp=False)
            self.sendLine(linetosend)
Example #3
0
    def parse_msg_mock(char):
        """Separates text and prompt updates from a mocked msg."""
        msg = [args[0] if args else kwargs.get("text", "")
               for name, args, kwargs in char.msg.mock_calls]
        msg = "||".join(_RE.sub("", mess) for mess in msg if mess)
        msg = ansi.parse_ansi(msg, strip_ansi=True).strip()
        prompt = [kwargs.get("prompt", "") for name, args, kwargs
                  in char.msg.mock_calls if "prompt" in kwargs]
        prompt = "&".join(p for p in prompt)
        prompt = ansi.parse_ansi(prompt, strip_ansi=True).strip()
        char.msg.reset_mock()

        return msg, prompt
Example #4
0
 def data_out(self, text=None, **kwargs):
     """
     Send Evennia -> User
     """
     text = text if text else ""
     if _INLINEFUNC_ENABLED and not "raw" in kwargs:
         text = parse_inlinefunc(text, strip="strip_inlinefunc" in kwargs, session=self)
     if self.screenreader:
         global _ANSI
         if not _ANSI:
             from evennia.utils import ansi as _ANSI
         text = _ANSI.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
         text = _RE_SCREENREADER_REGEX.sub("", text)
     session = kwargs.pop('session', None)
     session = session or self
     self.sessionhandler.data_out(session, text=text, **kwargs)
Example #5
0
    def send_text(self, *args, **kwargs):
        """
        Send text data. This will pre-process the text for
        color-replacement, conversion to html etc.

        Args:
            text (str): Text to send.

        Kwargs:
            options (dict): Options-dict with the following keys understood:
                - raw (bool): No parsing at all (leave ansi-to-html markers unparsed).
                - nocolor (bool): Remove all color.
                - screenreader (bool): Use Screenreader mode.
                - send_prompt (bool): Send a prompt with parsed html

        """
        if args:
            args = list(args)
            text = args[0]
            if text is None:
                return
        else:
            return

        flags = self.protocol_flags
        text = utils.to_str(text, force_string=True)

        options = kwargs.pop("options", {})
        raw = options.get("raw", flags.get("RAW", False))
        xterm256 = options.get("xterm256", flags.get('XTERM256', True))
        useansi = options.get("ansi", flags.get('ANSI', True))
        nocolor = options.get("nocolor", flags.get("NOCOLOR") or not (xterm256 or useansi))
        screenreader = options.get("screenreader", flags.get("SCREENREADER", False))
        prompt = options.get("send_prompt", False)

        if screenreader:
            # screenreader mode cleans up output
            text = parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
            text = _RE_SCREENREADER_REGEX.sub("", text)
        cmd = "prompt" if prompt else "text"
        if raw:
            args[0] = text
        else:
            args[0] = parse_html(text, strip_ansi=nocolor)

        # send to client on required form [cmdname, args, kwargs]
        self.client.lineSend(self.csessid, [cmd, args, kwargs])
Example #6
0
    def send_text(self, *args, **kwargs):
        """
        Send text data. This will pre-process the text for
        color-replacement, conversion to html etc.

        Args:
            text (str): Text to send.

        Kwargs:
            options (dict): Options-dict with the following keys understood:
                - raw (bool): No parsing at all (leave ansi-to-html markers unparsed).
                - nomarkup (bool): Clean out all ansi/html markers and tokens.
                - screenreader (bool): Use Screenreader mode.
                - send_prompt (bool): Send a prompt with parsed html

        """
        if args:
            args = list(args)
            text = args[0]
            if text is None:
                return
        else:
            return

        flags = self.protocol_flags
        text = to_str(text, force_string=True)

        options = kwargs.pop("options", {})
        raw = options.get("raw", flags.get("RAW", False))
        nomarkup = options.get("nomarkup", flags.get("NOMARKUP", False))
        screenreader = options.get("screenreader", flags.get("SCREENREADER", False))
        prompt = options.get("send_prompt", False)

        if screenreader:
            # screenreader mode cleans up output
            text = parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
            text = _RE_SCREENREADER_REGEX.sub("", text)
        cmd = "prompt" if prompt else "text"
        if raw:
            args[0] = text
        else:
            args[0] = parse_html(text, strip_ansi=nomarkup)
        print "send_text:", cmd, args, kwargs

        # send to client on required form [cmdname, args, kwargs]
        self.sendLine(json.dumps([cmd, args, kwargs]))
Example #7
0
 def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None, receiver=None):
     """
     Test a command by assigning all the needed
     properties to cmdobj and  running
         cmdobj.at_pre_cmd()
         cmdobj.parse()
         cmdobj.func()
         cmdobj.at_post_cmd()
     The msgreturn value is compared to eventual
     output sent to caller.msg in the game
     """
     caller = caller if caller else self.char1
     receiver = receiver if receiver else caller
     cmdobj.caller = caller
     cmdobj.cmdstring = cmdobj.key
     cmdobj.args = args
     cmdobj.cmdset = cmdset
     cmdobj.sessid = 1
     cmdobj.session = SESSIONS.session_from_sessid(1)
     cmdobj.player = self.player
     cmdobj.raw_string = cmdobj.key + " " + args
     cmdobj.obj = caller if caller else self.char1
     # test
     old_msg = receiver.msg
     try:
         receiver.msg = Mock()
         cmdobj.at_pre_cmd()
         cmdobj.parse()
         cmdobj.func()
         cmdobj.at_post_cmd()
         # clean out prettytable sugar
         stored_msg = [args[0] for name, args, kwargs in receiver.msg.mock_calls]
         returned_msg = "|".join(_RE.sub("", mess) for mess in stored_msg)
         returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
         if msg is not None:
             if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
                 sep1 = "\n" + "="*30 + "Wanted message" + "="*34 + "\n"
                 sep2 = "\n" + "="*30 + "Returned message" + "="*32 + "\n"
                 sep3 = "\n" + "="*78
                 retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
                 raise AssertionError(retval)
     finally:
         receiver.msg = old_msg
Example #8
0
    def data_out(self, text=None, **kwargs):
        """
        Send Evennia -> User

        Kwargs:
            text (str): A text to relay
            kwargs (any): Other parameters to the protocol.

        """
        # from evennia.server.profiling.timetrace import timetrace
        # text = timetrace(text, "ServerSession.data_out")

        text = text if text else ""
        if _INLINEFUNC_ENABLED and not "raw" in kwargs:
            text = parse_inlinefunc(text, strip="strip_inlinefunc" in kwargs, session=self)
        if self.screenreader:
            global _ANSI
            if not _ANSI:
                from evennia.utils import ansi as _ANSI
            text = _ANSI.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
            text = _RE_SCREENREADER_REGEX.sub("", text)
        self.sessionhandler.data_out(self, text=text, **kwargs)
Example #9
0
    def data_out(self, text=None, **kwargs):
        """
        Data Evennia -> User access hook. 'data' argument is a dict
        parsed for string settings.

        Kwargs:
            text (str): Text to send.
            raw (bool): Leave all ansi markup and tokens unparsed
            nomarkup (bool): Remove all ansi markup.

        """
        try:
            text = utils.to_str(text if text else "", encoding=self.encoding)
        except Exception as e:
            self.lineSend(str(e))
            return
        raw = kwargs.get("raw", False)
        nomarkup = kwargs.get("nomarkup", False)
        if raw:
            self.lineSend(text)
        else:
            self.lineSend(ansi.parse_ansi(text.strip("{r") + "{r", strip_ansi=nomarkup))
Example #10
0
 def add_gmnote(self, eventid, msg):
     msg = parse_ansi(msg, strip_ansi=True)
     msg = "\n" + msg + "\n"
     with open(self.get_gmlog_path(eventid), "a+") as log:
         log.write(msg)
Example #11
0
    def test_exit(self):
        """Test the callbacks of an exit."""
        self.char1.key = "char1"
        code = dedent("""
            if character.key == "char1":
                character.msg("You can leave.")
            else:
                character.msg("You cannot leave.")
                deny()
        """.strip("\n"))
        # Enforce self.exit.destination since swapping typeclass lose it
        self.exit.destination = self.room2

        # Try the can_traverse callback
        self.handler.add_callback(self.exit, "can_traverse", code,
                author=self.char1, valid=True)

        # Have char1 move through the exit
        self.call(ExitCommand(), "", "You can leave.", obj=self.exit)
        self.assertIs(self.char1.location, self.room2)

        # Have char2 move through this exit
        self.call(ExitCommand(), "", "You cannot leave.", obj=self.exit,
                caller=self.char2)
        self.assertIs(self.char2.location, self.room1)

        # Try the traverse callback
        self.handler.del_callback(self.exit, "can_traverse", 0)
        self.handler.add_callback(self.exit, "traverse", "character.msg('Fine!')",
                author=self.char1, valid=True)

        # Have char2 move through the exit
        self.call(ExitCommand(), "", obj=self.exit, caller=self.char2)
        self.assertIs(self.char2.location, self.room2)
        self.handler.del_callback(self.exit, "traverse", 0)

        # Move char1 and char2 back
        self.char1.location = self.room1
        self.char2.location = self.room1

        # Test msg_arrive and msg_leave
        code = 'message = "{character} goes out."'
        self.handler.add_callback(self.exit, "msg_leave", code,
                author=self.char1, valid=True)

        # Have char1 move through the exit
        old_msg = self.char2.msg
        try:
            self.char2.msg = Mock()
            self.call(ExitCommand(), "", obj=self.exit)
            stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
                    for name, args, kwargs in self.char2.msg.mock_calls]
            # Get the first element of a tuple if msg received a tuple instead of a string
            stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
            returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
            self.assertEqual(returned_msg, "char1 goes out.")
        finally:
            self.char2.msg = old_msg

        # Create a return exit
        back = create_object("evennia.objects.objects.DefaultExit",
                key="in", location=self.room2, destination=self.room1)
        code = 'message = "{character} goes in."'
        self.handler.add_callback(self.exit, "msg_arrive", code,
                author=self.char1, valid=True)

        # Have char1 move through the exit
        old_msg = self.char2.msg
        try:
            self.char2.msg = Mock()
            self.call(ExitCommand(), "", obj=back)
            stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
                    for name, args, kwargs in self.char2.msg.mock_calls]
            # Get the first element of a tuple if msg received a tuple instead of a string
            stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
            returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
            self.assertEqual(returned_msg, "char1 goes in.")
        finally:
            self.char2.msg = old_msg
Example #12
0
    def send_text(self, *args, **kwargs):
        """
        Send text data. This is an in-band telnet operation.

        Args:
            text (str): The first argument is always the text string to send. No other arguments
                are considered.
        Kwargs:
            options (dict): Send-option flags
                   - mxp: Enforce MXP link support.
                   - ansi: Enforce no ANSI colors.
                   - xterm256: Enforce xterm256 colors, regardless of TTYPE.
                   - noxterm256: Enforce no xterm256 color support, regardless of TTYPE.
                   - nomarkup: Strip all ANSI markup. This is the same as noxterm256,noansi
                   - raw: Pass string through without any ansi processing
                        (i.e. include Evennia ansi markers but do not
                        convert them into ansi tokens)
                   - echo: Turn on/off line echo on the client. Turn
                        off line echo for client, for example for password.
                        Note that it must be actively turned back on again!

        """
        text = args[0] if args else ""
        if text is None:
            return
        text = to_str(text, force_string=True)

        # handle arguments
        options = kwargs.get("options", {})
        flags = self.protocol_flags
        xterm256 = options.get("xterm256", flags.get('XTERM256', False) if flags["TTYPE"] else True)
        useansi = options.get("ansi", flags.get('ANSI', False) if flags["TTYPE"] else True)
        raw = options.get("raw", flags.get("RAW", False))
        nomarkup = options.get("nomarkup", flags.get("NOMARKUP", not (xterm256 or useansi)))
        echo = options.get("echo", None)
        mxp = options.get("mxp", flags.get("MXP", False))
        screenreader =  options.get("screenreader", flags.get("SCREENREADER", False))

        if screenreader:
            # screenreader mode cleans up output
            text = ansi.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
            text = _RE_SCREENREADER_REGEX.sub("", text)

        if options.get("send_prompt"):
            # send a prompt instead.
            if not raw:
                # processing
                prompt = ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=xterm256)
                if mxp:
                    prompt = mxp_parse(prompt)
            prompt = prompt.replace(IAC, IAC + IAC).replace('\n', '\r\n')
            prompt += IAC + GA
            self.transport.write(mccp_compress(self, prompt))
        else:
            if echo is not None:
                # turn on/off echo. Note that this is a bit turned around since we use
                # echo as if we are "turning off the client's echo" when telnet really
                # handles it the other way around.
                if echo:
                    # by telling the client that WE WON'T echo, the client knows
                    # that IT should echo. This is the expected behavior from
                    # our perspective.
                    self.transport.write(mccp_compress(self, IAC+WONT+ECHO))
                else:
                    # by telling the client that WE WILL echo, the client can
                    # safely turn OFF its OWN echo.
                    self.transport.write(mccp_compress(self, IAC+WILL+ECHO))
            if raw:
                # no processing
                self.sendLine(text)
                return
            else:
                # we need to make sure to kill the color at the end in order
                # to match the webclient output.
                linetosend = ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=xterm256, mxp=mxp)
                if mxp:
                    linetosend = mxp_parse(linetosend)
                self.sendLine(linetosend)
Example #13
0
from evennia.comms.models import ChannelDB

from evennia.commands.cmdset import CmdSet
from evennia.utils import create, logger, utils, ansi
from evennia.commands.default.muxcommand import MuxCommand
from evennia.commands.cmdhandler import CMD_LOGINSTART

# limit symbol import for API
__all__ = ("CmdUnconnectedConnect", "CmdUnconnectedCreate",
           "CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp")

MULTISESSION_MODE = settings.MULTISESSION_MODE
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
CONNECTION_SCREEN = ""
try:
    CONNECTION_SCREEN = ansi.parse_ansi(utils.random_string_from_module(CONNECTION_SCREEN_MODULE))
except Exception:
    pass
if not CONNECTION_SCREEN:
    CONNECTION_SCREEN = "\nEvennia: Error in CONNECTION_SCREEN MODULE (randomly picked connection screen variable is not a string). \nEnter 'help' for aid."


class CmdUnconnectedConnect(MuxCommand):
    """
    Connect to the game.

    Usage (at login screen):
        connect <email> <password>

    Use the create command to first create an account before logging in.
    """
Example #14
0
        raw = kwargs.get("raw", False)
        nomarkup = kwargs.get("nomarkup", not (xterm256 or useansi))
        prompt = kwargs.get("prompt")
        echo = kwargs.get("echo", None)
        mxp = kwargs.get("mxp", self.protocol_flags.get("MXP", False))

        #print "telnet kwargs=%s, message=%s" % (kwargs, text)
        #print "xterm256=%s, useansi=%s, raw=%s, nomarkup=%s, init_done=%s" % (xterm256, useansi, raw, nomarkup, ttype.get("init_done"))
        if raw:
            # no processing whatsoever
            self.sendLine(text)
        elif text:
            # we need to make sure to kill the color at the end in order
            # to match the webclient output.
            #print "telnet data out:", self.protocol_flags, id(self.protocol_flags), id(self), "nomarkup: %s, xterm256: %s" % (nomarkup, xterm256)
            linetosend = ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=xterm256, mxp=mxp)
            if mxp:
                linetosend = mxp_parse(linetosend)
            self.sendLine(linetosend)

        if prompt:
            # Send prompt separately
            prompt = ansi.parse_ansi(_RE_N.sub("", prompt) + "{n", strip_ansi=nomarkup, xterm256=xterm256)
            if mxp:
                prompt = mxp_parse(prompt)
            prompt = prompt.replace(IAC, IAC + IAC).replace('\n', '\r\n')
            prompt += IAC + GA
            self.transport.write(mccp_compress(self, prompt))
        if echo:
            self.transport.write(mccp_compress(self, IAC+WONT+ECHO))
        elif echo == False:
def convert_descs_to_written_works(apps, schema_editor):
    """
    This iterates over all the Readable typeclassed objects we have,
    and tries to convert their descriptions into WrittenWorks. In
    cases where their descs are built up of templates or translated
    texts, those are converted to WrittenWorks first, and then the
    BookChapters are created to associate the works with the book.

    For descs, a WrittenWork is created, which we'll compare future
    descs against to see if there's duplicates.
    """
    ObjectDB = apps.get_model("objects", "ObjectDB")
    WrittenWork = apps.get_model("templates", "WrittenWork")
    BookChapter = apps.get_model("templates", "BookChapter")
    ChapterSignature = apps.get_model("templates", "ChapterSignature")
    readable = ObjectDB.objects.filter(
        db_typeclass_path="typeclasses.readable.readable.Readable"
    )
    # different mappings
    desc_to_work = {}
    template_to_work = {}
    authors = {}

    def get_author(book_object):
        try:
            author_tuple = book_object.db_attributes.get(db_key="author").db_value
            return get_dbobj_from_tuple(author_tuple)
        except (ObjectDoesNotExist, TypeError, IndexError):
            return None

    def get_dbobj_from_tuple(obj_tuple):
        try:
            obj_pk = obj_tuple[-1]
            if obj_pk in authors:
                return authors[obj_pk]
            else:
                author_obj = ObjectDB.objects.get(id=obj_pk)
                authors[obj_pk] = author_obj
                return author_obj
        except (ObjectDoesNotExist, TypeError, IndexError):
            return None

    def get_desc(book_object):
        try:
            desc_attr = book_object.db_attributes.get(db_key="desc")
        except ObjectDoesNotExist:
            # if they have no desc, it's an empty book. skip it
            return
        # if its desc was that it's a blank book, delete the attribute and skip it
        if desc_attr.db_value == OLD_BASE_DESC:
            desc_attr.delete()
            return
        return desc_attr

    def get_signers(book_object):
        try:
            signed_attr = book_object.db_attributes.get(db_key="signed")
            signers_objects = []
            for tup in signed_attr.db_value:
                obj = get_dbobj_from_tuple(tup)
                if obj:
                    signers_objects.append(obj)
            signed_attr.delete()
            return signers_objects
        except (ObjectDoesNotExist, ValueError, TypeError):
            return []

    def add_work_and_chapter_for_desc(book_object, desc_attr, chapter_num, author_obj):
        # check if work already exists
        body = desc_attr.db_value
        if body in desc_to_work:
            work_obj = desc_to_work[body]
        else:
            work_title = book_object.db_key
            num_matches = WrittenWork.objects.filter(
                title__startswith=book_object.db_key
            ).count()
            if num_matches:
                work_title += f" {num_matches + 1}"
            # create the work_obj for the body
            work_obj = WrittenWork.objects.create(
                body=desc_attr.db_value, title=work_title, author=author_obj
            )
            desc_to_work[body] = work_obj
        # create chapter
        return BookChapter.objects.get_or_create(
            defaults=dict(number=chapter_num),
            written_work=work_obj,
            objectdb=book_object,
        )[0]

    def get_max_chapter_num(book_object):
        agg = book_object.book_chapters.aggregate(max_chapter=models.Max("number"))
        return agg.get("max_chapter", 0) or 0

    readable.update(db_cmdset_storage=None)

    for book in readable:
        chapter_number = 1
        desc = get_desc(book)
        if not desc:
            continue
        templates = book.template_set.all()
        if templates:
            # if we have templates, the desc is assumed it just be a list of templates
            # we'll convert templates to WrittenWorks and add chapters for them
            print(f"Processing templates for {book.db_key} (ID #{book.id})")
            for template in templates:
                if template.id in template_to_work:
                    new_work = template_to_work[template.id]
                elif template.desc in desc_to_work:
                    new_work = desc_to_work[template.desc]
                else:
                    colored_title = sub_old_ansi(template.title)
                    title = parse_ansi(colored_title, strip_ansi=True)
                    if colored_title == title:
                        colored_title = ""
                    # try to get author
                    author = get_author(book)
                    # check for unique title
                    title_matches = WrittenWork.objects.filter(
                        title__startswith=title
                    ).count()
                    if title_matches:
                        title += f" {title_matches + 1}"
                        colored_title += f" {title_matches + 1}"
                    new_work = WrittenWork.objects.create(
                        body=template.desc,
                        title=title,
                        colored_title=colored_title,
                        owner=template.owner,
                        author=author,
                    )
                    template_to_work[template.id] = new_work
                    desc_to_work[template.desc] = new_work
                # add work to chapters for the book
                BookChapter.objects.get_or_create(
                    defaults=dict(number=chapter_number),
                    written_work=new_work,
                    objectdb=book,
                )
                chapter_number += 1
            # get rid of old desc and move on
            desc.delete()
            continue

        # convert books with translated descs
        translations = book.translations.all()
        if translations:
            print(f"Processing translations for {book.db_key} (ID #{book.id})")
            base_title = book.db_key
            chapter_number = get_max_chapter_num(book) + 1
            # desc should be first chapter
            author = get_author(book)
            add_work_and_chapter_for_desc(book, desc, chapter_number, author)
            for translation in translations:
                chapter_number += 1
                if translation.description in desc_to_work:
                    work = desc_to_work[translation.description]
                else:
                    # convert translations into WrittenWorks of appropriate language
                    title = base_title
                    if chapter_number > 1:
                        title += f" Chapter {chapter_number}"
                    work = WrittenWork.objects.create(
                        language=translation.language,
                        body=translation.description,
                        title=title,
                        author=author,
                    )
                    desc_to_work[translation.description] = work
                # add bookchapter for each converted translation
                BookChapter.objects.get_or_create(
                    defaults=dict(number=chapter_number),
                    written_work=work,
                    objectdb=book,
                )
                # get rid of old translation
                translation.delete()
            desc.delete()
            continue
        print(f"Processing book {book.db_key} (ID #{book.id})")
        author = get_author(book)
        chapter = add_work_and_chapter_for_desc(book, desc, 1, author)
        desc.delete()
        signers = get_signers(book)
        for signer in signers:
            ChapterSignature.objects.create(book_chapter=chapter, signer=signer)
Example #16
0
    def send_text(self, *args, **kwargs):
        """
        Send text data. This is an in-band telnet operation.

        Args:
            text (str): The first argument is always the text string to send. No other arguments
                are considered.
        Kwargs:
            options (dict): Send-option flags
                   - mxp: Enforce MXP link support.
                   - ansi: Enforce no ANSI colors.
                   - xterm256: Enforce xterm256 colors, regardless of TTYPE setting.
                   - nocolor: Strip all colors.
                   - raw: Pass string through without any ansi processing
                        (i.e. include Evennia ansi markers but do not
                        convert them into ansi tokens)
                   - echo: Turn on/off line echo on the client. Turn
                        off line echo for client, for example for password.
                        Note that it must be actively turned back on again!

        """
        # print "telnet.send_text", args,kwargs  # DEBUG
        text = args[0] if args else ""
        if text is None:
            return
        text = to_str(text)

        # handle arguments
        options = kwargs.get("options", {})
        flags = self.protocol_flags
        xterm256 = options.get("xterm256", flags.get("XTERM256", True))
        useansi = options.get("ansi", flags.get("ANSI", True))
        raw = options.get("raw", flags.get("RAW", False))
        nocolor = options.get(
            "nocolor",
            flags.get("NOCOLOR") or not (xterm256 or useansi))
        # echo = options.get("echo", None)  # DEBUG
        screenreader = options.get("screenreader",
                                   flags.get("SCREENREADER", False))

        if screenreader:
            # screenreader mode cleans up output
            text = ansi.parse_ansi(text,
                                   strip_ansi=True,
                                   xterm256=False,
                                   mxp=False)
            text = _RE_SCREENREADER_REGEX.sub("", text)

        if raw:
            # no processing
            self.sendLine(text)
            return
        else:
            # we need to make sure to kill the color at the end in order
            # to match the webclient output.
            linetosend = ansi.parse_ansi(
                _RE_N.sub("", text) + ("||n" if text.endswith("|") else "|n"),
                strip_ansi=nocolor,
                xterm256=xterm256,
                mxp=False,
            )
            self.sendLine(linetosend)
Example #17
0
    def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None, receiver=None, cmdstring=None, obj=None):
        """
        Test a command by assigning all the needed
        properties to cmdobj and  running
            cmdobj.at_pre_cmd()
            cmdobj.parse()
            cmdobj.func()
            cmdobj.at_post_cmd()
        The msgreturn value is compared to eventual
        output sent to caller.msg in the game

        Returns:
            msg (str): The received message that was sent to the caller.

        """
        caller = caller if caller else self.char1
        receiver = receiver if receiver else caller
        cmdobj.caller = caller
        cmdobj.cmdname = cmdstring if cmdstring else cmdobj.key
        cmdobj.raw_cmdname = cmdobj.cmdname
        cmdobj.cmdstring = cmdobj.cmdname  # deprecated
        cmdobj.args = args
        cmdobj.cmdset = cmdset
        cmdobj.session = SESSIONS.session_from_sessid(1)
        cmdobj.account = self.account
        cmdobj.raw_string = cmdobj.key + " " + args
        cmdobj.obj = obj or (caller if caller else self.char1)
        # test
        old_msg = receiver.msg
        returned_msg = ""
        try:
            receiver.msg = Mock()
            cmdobj.at_pre_cmd()
            cmdobj.parse()
            ret = cmdobj.func()
            if isinstance(ret, types.GeneratorType):
                ret.next()
            cmdobj.at_post_cmd()
        except StopIteration:
            pass
        except InterruptCommand:
            pass
        finally:
            # clean out evtable sugar. We only operate on text-type
            stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
                          for name, args, kwargs in receiver.msg.mock_calls]
            # Get the first element of a tuple if msg received a tuple instead of a string
            stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
            if msg is not None:
                returned_msg = "||".join(_RE.sub("", mess) for mess in stored_msg)
                returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
                if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
                    sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
                    sep2 = "\n" + "=" * 30 + "Returned message" + "=" * 32 + "\n"
                    sep3 = "\n" + "=" * 78
                    retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
                    raise AssertionError(retval)
            else:
                returned_msg = "\n".join(str(msg) for msg in stored_msg)
                returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
            receiver.msg = old_msg

        return returned_msg
Example #18
0
    def data_out(self, text=None, **kwargs):
        """
        Data Evennia -> User. A generic hook method for engine to call
        in order to send data through the telnet connection.

        Kwargs:
            text (str): Text to send.
            oob (list): `[(cmdname,args,kwargs), ...]`, supply an
                Out-of-Band instruction.
            xterm256 (bool): Enforce xterm256 setting. If not given,
                ttype result is used. If client does not suport xterm256,
                the ansi fallback will be used
            mxp (bool): Enforce mxp setting. If not given, enables if
                we detected client support for it
            ansi (bool): Enforce ansi setting. If not given, ttype
                result is used.
            nomarkup (bool): If True, strip all ansi markup (this is
                the same as `xterm256=False, ansi=False`)
            raw (bool):Pass string through without any ansi processing
                (i.e. include Evennia ansi markers but do not convert them
                into ansi tokens)
            prompt (str): Supply a prompt text which gets sent without
                a newline added to the end.
            echo (str): Turn on/off line echo on the client, if the
                client supports it (e.g. for password input). Remember
                that you must manually activate it again later.

        Notes:
            The telnet TTYPE negotiation flags, if any, are used if no kwargs
            are given.

        """
        ## profiling, debugging
        #if text.startswith("TEST_MESSAGE"): 1/0
        #from evennia.server.profiling.timetrace import timetrace
        #text = timetrace(text, "telnet.data_out", final=True)

        try:
            text = utils.to_str(text if text else "", encoding=self.encoding)
        except Exception as e:
            self.sendLine(str(e))
            return
        if "oob" in kwargs and "OOB" in self.protocol_flags:
            # oob is a list of [(cmdname, arg, kwarg), ...]
            for cmdname, args, okwargs in kwargs["oob"]:
                self.oob.data_out(cmdname, *args, **okwargs)

        # parse **kwargs, falling back to ttype if nothing is given explicitly
        ttype = self.protocol_flags.get('TTYPE', {})
        xterm256 = kwargs.get("xterm256", ttype.get('256 COLORS', False) if ttype.get("init_done") else True)
        useansi = kwargs.get("ansi", ttype and ttype.get('ANSI', False) if ttype.get("init_done") else True)
        raw = kwargs.get("raw", False)
        nomarkup = kwargs.get("nomarkup", not (xterm256 or useansi))
        prompt = kwargs.get("prompt")
        echo = kwargs.get("echo", None)
        mxp = kwargs.get("mxp", self.protocol_flags.get("MXP", False))

        if raw:
            # no processing whatsoever
            self.sendLine(text)
        elif text:
            # we need to make sure to kill the color at the end in order
            # to match the webclient output.
            linetosend = ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=xterm256, mxp=mxp)
            if mxp:
                linetosend = mxp_parse(linetosend)
            self.sendLine(linetosend)

        if prompt:
            # Send prompt separately
            prompt = ansi.parse_ansi(_RE_N.sub("", prompt) + "{n", strip_ansi=nomarkup, xterm256=xterm256)
            if mxp:
                prompt = mxp_parse(prompt)
            prompt = prompt.replace(IAC, IAC + IAC).replace('\n', '\r\n')
            prompt += IAC + GA
            self.transport.write(mccp_compress(self, prompt))
        if echo:
            self.transport.write(mccp_compress(self, IAC+WONT+ECHO))
        elif echo == False:
            self.transport.write(mccp_compress(self, IAC+WILL+ECHO))
Example #19
0
    def test_exit(self):
        """Test the callbacks of an exit."""
        self.char1.key = "char1"
        code = dedent("""
            if character.key == "char1":
                character.msg("You can leave.")
            else:
                character.msg("You cannot leave.")
                deny()
        """.strip("\n"))
        # Enforce self.exit.destination since swapping typeclass lose it
        self.exit.destination = self.room2

        # Try the can_traverse callback
        self.handler.add_callback(self.exit,
                                  "can_traverse",
                                  code,
                                  author=self.char1,
                                  valid=True)

        # Have char1 move through the exit
        self.call(ExitCommand(), "", "You can leave.", obj=self.exit)
        self.assertIs(self.char1.location, self.room2)

        # Have char2 move through this exit
        self.call(ExitCommand(),
                  "",
                  "You cannot leave.",
                  obj=self.exit,
                  caller=self.char2)
        self.assertIs(self.char2.location, self.room1)

        # Try the traverse callback
        self.handler.del_callback(self.exit, "can_traverse", 0)
        self.handler.add_callback(self.exit,
                                  "traverse",
                                  "character.msg('Fine!')",
                                  author=self.char1,
                                  valid=True)

        # Have char2 move through the exit
        self.call(ExitCommand(), "", obj=self.exit, caller=self.char2)
        self.assertIs(self.char2.location, self.room2)
        self.handler.del_callback(self.exit, "traverse", 0)

        # Move char1 and char2 back
        self.char1.location = self.room1
        self.char2.location = self.room1

        # Test msg_arrive and msg_leave
        code = 'message = "{character} goes out."'
        self.handler.add_callback(self.exit,
                                  "msg_leave",
                                  code,
                                  author=self.char1,
                                  valid=True)

        # Have char1 move through the exit
        old_msg = self.char2.msg
        try:
            self.char2.msg = Mock()
            self.call(ExitCommand(), "", obj=self.exit)
            stored_msg = [
                args[0] if args and args[0] else kwargs.get(
                    "text", utils.to_str(kwargs, force_string=True))
                for name, args, kwargs in self.char2.msg.mock_calls
            ]
            # Get the first element of a tuple if msg received a tuple instead of a string
            stored_msg = [
                smsg[0] if isinstance(smsg, tuple) else smsg
                for smsg in stored_msg
            ]
            returned_msg = ansi.parse_ansi("\n".join(stored_msg),
                                           strip_ansi=True)
            self.assertEqual(returned_msg, "char1 goes out.")
        finally:
            self.char2.msg = old_msg

        # Create a return exit
        back = create_object("evennia.objects.objects.DefaultExit",
                             key="in",
                             location=self.room2,
                             destination=self.room1)
        code = 'message = "{character} goes in."'
        self.handler.add_callback(self.exit,
                                  "msg_arrive",
                                  code,
                                  author=self.char1,
                                  valid=True)

        # Have char1 move through the exit
        old_msg = self.char2.msg
        try:
            self.char2.msg = Mock()
            self.call(ExitCommand(), "", obj=back)
            stored_msg = [
                args[0] if args and args[0] else kwargs.get(
                    "text", utils.to_str(kwargs, force_string=True))
                for name, args, kwargs in self.char2.msg.mock_calls
            ]
            # Get the first element of a tuple if msg received a tuple instead of a string
            stored_msg = [
                smsg[0] if isinstance(smsg, tuple) else smsg
                for smsg in stored_msg
            ]
            returned_msg = ansi.parse_ansi("\n".join(stored_msg),
                                           strip_ansi=True)
            self.assertEqual(returned_msg, "char1 goes in.")
        finally:
            self.char2.msg = old_msg
Example #20
0
from evennia.commands.cmdset import CmdSet
from evennia.utils import logger, utils, ansi
from evennia.commands.default.muxcommand import MuxCommand
from evennia.commands.cmdhandler import CMD_LOGINSTART
from evennia.commands.default import unloggedin as default_unloggedin  # Used in CmdUnconnectedCreate

# limit symbol import for API
__all__ = ("CmdUnconnectedConnect", "CmdUnconnectedCreate",
           "CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp")

MULTISESSION_MODE = settings.MULTISESSION_MODE
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
CONNECTION_SCREEN = ""
try:
    CONNECTION_SCREEN = ansi.parse_ansi(
        utils.random_string_from_module(CONNECTION_SCREEN_MODULE))
except Exception:
    # malformed connection screen or no screen given
    pass
if not CONNECTION_SCREEN:
    CONNECTION_SCREEN = "\nEvennia: Error in CONNECTION_SCREEN MODULE" \
                        " (randomly picked connection screen variable is not a string). \nEnter 'help' for aid."


class CmdUnconnectedConnect(MuxCommand):
    """
    Connect to the game.

    Usage (at login screen):
        connect <email> <password>
Example #21
0
    def send_text(self, *args, **kwargs):
        """
        Send text data. This is an in-band telnet operation.

        Args:
            text (str): The first argument is always the text string to send. No other arguments
                are considered.
        Kwargs:
            options (dict): Send-option flags
                   - mxp: Enforce MXP link support.
                   - ansi: Enforce no ANSI colors.
                   - xterm256: Enforce xterm256 colors, regardless of TTYPE.
                   - noxterm256: Enforce no xterm256 color support, regardless of TTYPE.
                   - nomarkup: Strip all ANSI markup. This is the same as noxterm256,noansi
                   - raw: Pass string through without any ansi processing
                        (i.e. include Evennia ansi markers but do not
                        convert them into ansi tokens)
                   - echo: Turn on/off line echo on the client. Turn
                        off line echo for client, for example for password.
                        Note that it must be actively turned back on again!

        """
        text = args[0] if args else ""
        if text is None:
            return
        text = to_str(text, force_string=True)

        # handle arguments
        options = kwargs.get("options", {})
        flags = self.protocol_flags
        xterm256 = options.get("xterm256", flags.get('XTERM256', False) if flags["TTYPE"] else True)
        useansi = options.get("ansi", flags.get('ANSI', False) if flags["TTYPE"] else True)
        raw = options.get("raw", flags.get("RAW", False))
        nomarkup = options.get("nomarkup", flags.get("NOMARKUP", not (xterm256 or useansi)))
        echo = options.get("echo", None)
        mxp = options.get("mxp", flags.get("MXP", False))
        screenreader =  options.get("screenreader", flags.get("SCREENREADER", False))

        if screenreader:
            # screenreader mode cleans up output
            text = ansi.parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
            text = _RE_SCREENREADER_REGEX.sub("", text)

        if options.get("send_prompt"):
            # send a prompt instead.
            if not raw:
                # processing
                prompt = ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=xterm256)
                if mxp:
                    prompt = mxp_parse(prompt)
            prompt = prompt.replace(IAC, IAC + IAC).replace('\n', '\r\n')
            prompt += IAC + GA
            self.transport.write(mccp_compress(self, prompt))
        else:
            if echo is not None:
                # turn on/off echo. Note that this is a bit turned around since we use
                # echo as if we are "turning off the client's echo" when telnet really
                # handles it the other way around.
                if echo:
                    # by telling the client that WE WON'T echo, the client knows
                    # that IT should echo. This is the expected behavior from
                    # our perspective.
                    self.transport.write(mccp_compress(self, IAC+WONT+ECHO))
                else:
                    # by telling the client that WE WILL echo, the client can
                    # safely turn OFF its OWN echo.
                    self.transport.write(mccp_compress(self, IAC+WILL+ECHO))
            if raw:
                # no processing
                self.sendLine(text)
                return
            else:
                # we need to make sure to kill the color at the end in order
                # to match the webclient output.
                linetosend = ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=xterm256, mxp=mxp)
                if mxp:
                    linetosend = mxp_parse(linetosend)
                self.sendLine(linetosend)
Example #22
0
    def call(self,
             cmdobj,
             args,
             msg=None,
             cmdset=None,
             noansi=True,
             caller=None,
             receiver=None,
             cmdstring=None,
             obj=None):
        """
        Test a command by assigning all the needed
        properties to cmdobj and  running
            cmdobj.at_pre_cmd()
            cmdobj.parse()
            cmdobj.func()
            cmdobj.at_post_cmd()
        The msgreturn value is compared to eventual
        output sent to caller.msg in the game

        Returns:
            msg (str): The received message that was sent to the caller.

        """
        caller = caller if caller else self.char1
        receiver = receiver if receiver else caller
        cmdobj.caller = caller
        cmdobj.cmdstring = cmdstring if cmdstring else cmdobj.key
        cmdobj.args = args
        cmdobj.cmdset = cmdset
        cmdobj.session = SESSIONS.session_from_sessid(1)
        cmdobj.account = self.account
        cmdobj.raw_string = cmdobj.key + " " + args
        cmdobj.obj = obj or (caller if caller else self.char1)
        # test
        old_msg = receiver.msg
        try:
            receiver.msg = Mock()
            if cmdobj.at_pre_cmd():
                return
            cmdobj.parse()
            cmdobj.func()
            cmdobj.at_post_cmd()
        except Exception:
            import traceback
            receiver.msg(traceback.format_exc())
        finally:
            # clean out prettytable sugar. We only operate on text-type
            stored_msg = [
                args[0] if args and args[0] else kwargs.get(
                    "text", utils.to_str(kwargs, force_string=True))
                for name, args, kwargs in receiver.msg.mock_calls
            ]
            # Get the first element of a tuple if msg received a tuple instead of a string
            stored_msg = [
                smsg[0] if hasattr(smsg, '__iter__') else smsg
                for smsg in stored_msg
            ]
            if msg is not None:
                returned_msg = self.format_returned_msg(stored_msg, noansi)
                if msg == "" and returned_msg or returned_msg != msg.strip():
                    sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
                    sep2 = "\n" + "=" * 30 + "Returned message" + "=" * 32 + "\n"
                    sep3 = "\n" + "=" * 78
                    # important - use raw strings for wanted/returned messages so we can see whitespace
                    retval = "%s%r%s%r%s" % (sep1, msg.strip(), sep2,
                                             returned_msg, sep3)
                    raise AssertionError(retval)
            else:
                returned_msg = "\n".join(str(msg) for msg in stored_msg)
                returned_msg = ansi.parse_ansi(returned_msg,
                                               strip_ansi=noansi).strip()
            receiver.msg = old_msg
        return returned_msg
Example #23
0
 def func(self):
     "Show the connect screen."
     connection_screen = ansi.parse_ansi(utils.random_string_from_module(CONNECTION_SCREEN_MODULE))
     if not connection_screen:
         connection_screen = "No connection screen found. Please contact an admin."
     self.caller.msg(connection_screen)
Example #24
0
 def add_gemit(self, msg):
     msg = parse_ansi(msg, strip_ansi=True)
     for event_id in self.db.active_events:
         self.add_msg(event_id, msg)
Example #25
0
    def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None,
             receiver=None, cmdstring=None, obj=None, inputs=None):
        """
        Test a command by assigning all the needed
        properties to cmdobj and  running
            cmdobj.at_pre_cmd()
            cmdobj.parse()
            cmdobj.func()
            cmdobj.at_post_cmd()
        The msgreturn value is compared to eventual
        output sent to caller.msg in the game

        Returns:
            msg (str): The received message that was sent to the caller.

        """
        caller = caller if caller else self.char1
        receiver = receiver if receiver else caller
        cmdobj.caller = caller
        cmdobj.cmdname = cmdstring if cmdstring else cmdobj.key
        cmdobj.raw_cmdname = cmdobj.cmdname
        cmdobj.cmdstring = cmdobj.cmdname  # deprecated
        cmdobj.args = args
        cmdobj.cmdset = cmdset
        cmdobj.session = SESSIONS.session_from_sessid(1)
        cmdobj.account = self.account
        cmdobj.raw_string = cmdobj.key + " " + args
        cmdobj.obj = obj or (caller if caller else self.char1)
        # test
        old_msg = receiver.msg
        inputs = inputs or []

        try:
            receiver.msg = Mock()
            if cmdobj.at_pre_cmd():
                return
            cmdobj.parse()
            ret = cmdobj.func()

            # handle func's with yield in them (generators)
            if isinstance(ret, types.GeneratorType):
                while True:
                    try:
                        inp = inputs.pop() if inputs else None
                        if inp:
                            try:
                                ret.send(inp)
                            except TypeError:
                                ret.next()
                                ret = ret.send(inp)
                        else:
                            ret.next()
                    except StopIteration:
                        break

            cmdobj.at_post_cmd()
        except StopIteration:
            pass
        except InterruptCommand:
            pass

        # clean out evtable sugar. We only operate on text-type
        stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
                      for name, args, kwargs in receiver.msg.mock_calls]
        # Get the first element of a tuple if msg received a tuple instead of a string
        stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
        if msg is not None:
            # set our separator for returned messages based on parsing ansi or not
            msg_sep = "|" if noansi else "||"
            # Have to strip ansi for each returned message for the regex to handle it correctly
            returned_msg = msg_sep.join(_RE.sub("", ansi.parse_ansi(mess, strip_ansi=noansi))
                                        for mess in stored_msg).strip()
            if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
                sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
                sep2 = "\n" + "=" * 30 + "Returned message" + "=" * 32 + "\n"
                sep3 = "\n" + "=" * 78
                retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
                raise AssertionError(retval)
        else:
            returned_msg = "\n".join(str(msg) for msg in stored_msg)
            returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
        receiver.msg = old_msg

        return returned_msg
Example #26
0
        nomarkup = kwargs.get("nomarkup", not (xterm256 or useansi))
        prompt = kwargs.get("prompt")
        echo = kwargs.get("echo", None)
        mxp = kwargs.get("mxp", self.protocol_flags.get("MXP", False))

        #print "telnet kwargs=%s, message=%s" % (kwargs, text)
        #print "xterm256=%s, useansi=%s, raw=%s, nomarkup=%s, init_done=%s" % (xterm256, useansi, raw, nomarkup, ttype.get("init_done"))
        if raw:
            # no processing whatsoever
            self.sendLine(text)
        elif text:
            # we need to make sure to kill the color at the end in order
            # to match the webclient output.
            #print "telnet data out:", self.protocol_flags, id(self.protocol_flags), id(self), "nomarkup: %s, xterm256: %s" % (nomarkup, xterm256)
            linetosend = ansi.parse_ansi(_RE_N.sub("", text) + "{n",
                                         strip_ansi=nomarkup,
                                         xterm256=xterm256,
                                         mxp=mxp)
            if mxp:
                linetosend = mxp_parse(linetosend)
            self.sendLine(linetosend)

        if prompt:
            # Send prompt separately
            prompt = ansi.parse_ansi(_RE_N.sub("", prompt) + "{n",
                                     strip_ansi=nomarkup,
                                     xterm256=xterm256)
            if mxp:
                prompt = mxp_parse(prompt)
            prompt = prompt.replace(IAC, IAC + IAC).replace('\n', '\r\n')
            prompt += IAC + GA
            self.transport.write(mccp_compress(self, prompt))
Example #27
0
    def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None,
             receiver=None, cmdstring=None, obj=None, inputs=None, raw_string=None):
        """
        Test a command by assigning all the needed
        properties to cmdobj and  running
            cmdobj.at_pre_cmd()
            cmdobj.parse()
            cmdobj.func()
            cmdobj.at_post_cmd()
        The msgreturn value is compared to eventual
        output sent to caller.msg in the game

        Returns:
            msg (str): The received message that was sent to the caller.

        """
        caller = caller if caller else self.char1
        receiver = receiver if receiver else caller
        cmdobj.caller = caller
        cmdobj.cmdname = cmdstring if cmdstring else cmdobj.key
        cmdobj.raw_cmdname = cmdobj.cmdname
        cmdobj.cmdstring = cmdobj.cmdname  # deprecated
        cmdobj.args = args
        cmdobj.cmdset = cmdset
        cmdobj.session = SESSIONS.session_from_sessid(1)
        cmdobj.account = self.account
        cmdobj.raw_string = raw_string if raw_string is not None else cmdobj.key + " " + args
        cmdobj.obj = obj or (caller if caller else self.char1)
        # test
        old_msg = receiver.msg
        inputs = inputs or []

        try:
            receiver.msg = Mock()
            if cmdobj.at_pre_cmd():
                return
            cmdobj.parse()
            ret = cmdobj.func()

            # handle func's with yield in them (generators)
            if isinstance(ret, types.GeneratorType):
                while True:
                    try:
                        inp = inputs.pop() if inputs else None
                        if inp:
                            try:
                                ret.send(inp)
                            except TypeError:
                                next(ret)
                                ret = ret.send(inp)
                        else:
                            next(ret)
                    except StopIteration:
                        break

            cmdobj.at_post_cmd()
        except StopIteration:
            pass
        except InterruptCommand:
            pass

        # clean out evtable sugar. We only operate on text-type
        stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs))
                      for name, args, kwargs in receiver.msg.mock_calls]
        # Get the first element of a tuple if msg received a tuple instead of a string
        stored_msg = [str(smsg[0]) if isinstance(smsg, tuple) else str(smsg) for smsg in stored_msg]
        if msg is not None:
            msg = str(msg)  # to be safe, e.g. `py` command may return ints
            # set our separator for returned messages based on parsing ansi or not
            msg_sep = "|" if noansi else "||"
            # Have to strip ansi for each returned message for the regex to handle it correctly
            returned_msg = msg_sep.join(_RE.sub("", ansi.parse_ansi(mess, strip_ansi=noansi))
                                        for mess in stored_msg).strip()
            if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
                sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
                sep2 = "\n" + "=" * 30 + "Returned message" + "=" * 32 + "\n"
                sep3 = "\n" + "=" * 78
                retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
                raise AssertionError(retval)
        else:
            returned_msg = "\n".join(str(msg) for msg in stored_msg)
            returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
        receiver.msg = old_msg

        return returned_msg