Пример #1
0
def show_thread(request, board_id, post_id):
    if not request.user.is_authenticated or request.user.username == "":
        return render(request, 'login.html', {})

    try:
        post = Post.objects.get(pk=post_id)
        board = post.db_board

        if not board.access(request.user, access_type="read", default=False):
            context = {'board': board}
            return render(request, 'board_noperm.html', context)

        can_post = board.access(request.user, access_type="post", default=False)

        plaintext = ansi.strip_ansi(post.db_text)
        setattr(post, 'plaintext', plaintext)
        post.mark_read(request.user, True)

        replies = Post.objects.filter(db_parent=post).order_by('db_date_created')
        for r in replies:
            plaintext = ansi.strip_ansi(r.db_text)
            setattr(r, 'plaintext', plaintext)
            r.mark_read(request.user, True)

        form = ReplyForm()
        context = {'board': board, 'post': post, 'replies': replies, 'can_post': can_post,
                   'board_id': board, 'post_id': post, 'form': form}

        return render(request, 'thread.html', context)

    except (Post.DoesNotExist, Post.MultipleObjectsReturned):
        return Http404("Error accessing boards.")
Пример #2
0
 def post_map(post_to_map, bulletin_board):
     """Returns dict of information about each individual post to add to context"""
     return {
         "id": post_to_map.id,
         "poster": bulletin_board.get_poster(post_to_map),
         "subject": ansi.strip_ansi(post_to_map.db_header),
         "date": post_to_map.db_date_created.strftime("%x"),
         "text": ansi.strip_ansi(post_to_map.db_message),
     }
Пример #3
0
 def post_map(post_to_map, bulletin_board):
     """Returns dict of information about each individual post to add to context"""
     return {
         'id': post_to_map.id,
         'poster': bulletin_board.get_poster(post_to_map),
         'subject': ansi.strip_ansi(post_to_map.db_header),
         'date': post_to_map.db_date_created.strftime("%x"),
         'text': ansi.strip_ansi(post_to_map.db_message)
     }
Пример #4
0
 def post_map(post):
     """Returns dict of information about each individual post to add to context"""
     return {
         'id': post.id,
         'board': post.bulletin_board.key,
         'poster': post.poster_name,
         'subject': ansi.strip_ansi(post.db_header),
         'date': post.db_date_created.strftime("%x"),
         'text': ansi.strip_ansi(post.db_message)
     }
Пример #5
0
def trail(string, length=26, tail="...", dir="left", delim=" "):
    l = length - len(tail)

    if len(strip_ansi(string)) <= l:
        if dir.lower() == 'left':
            return string + delim * (length - len(strip_ansi(string)))
        else:
            return delim * (length - len(strip_ansi(string))) + string
    else:
        return string[:l] + tail
Пример #6
0
    def _add_keys_choice(self):
        """Add the choices' keys if some choices don't have valid keys."""
        # If choices have been added without keys, try to guess them
        for choice in self.choices:
            if not choice.key:
                title = strip_ansi(choice.title.strip()).lower()
                length = self.min_shortcut
                while length <= len(title):
                    i = 0
                    while i < len(title) - length + 1:
                        guess = title[i:i + length]
                        if guess not in self.cmds:
                            choice.key = guess
                            break

                        i += 1

                    if choice.key:
                        break

                    length += 1

                if choice.key:
                    self.cmds[choice.key] = choice
                else:
                    raise ValueError(
                        "Cannot guess the key for {}".format(choice))
Пример #7
0
    def _add_keys_choice(self):
        """Add the choices' keys if some choices don't have valid keys."""
        # If choices have been added without keys, try to guess them
        for choice in self.choices:
            if not choice.key:
                title = strip_ansi(choice.title.strip()).lower()
                length = self.min_shortcut
                while length <= len(title):
                    i = 0
                    while i < len(title) - length + 1:
                        guess = title[i:i + length]
                        if guess not in self.cmds:
                            choice.key = guess
                            break

                        i += 1

                    if choice.key:
                        break

                    length += 1

                if choice.key:
                    self.cmds[choice.key] = choice
                else:
                    raise ValueError("Cannot guess the key for {}".format(choice))
Пример #8
0
 def test_node_allocate_skills_above_ten(self):
     """test invalid skill allocation above 10"""
     archetypes.apply_archetype(self.char1, 'arcanist')
     traits = self.char1.traits
     traits.VIT.mod = 2
     traits.DEX.mod = 2
     traits.INT.mod = 3
     traits.BM.base = 8
     races.apply_race(self.char1, 'elf', 'spirit')
     archetypes.calculate_secondary_traits(self.char1.traits)
     archetypes.finalize_traits(self.char1.traits)
     skills.apply_skills(self.char1)
     self.session.execute_cmd('@charcreate Char')
     # -1's
     self.session.execute_cmd('9')
     self.session.execute_cmd('9')
     self.session.execute_cmd('9')
     # +1's
     self.session.execute_cmd('7')
     self.session.execute_cmd('7')
     self.assertEqual(self.char1.skills.appraise.plus, 1)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn('Skills cannot be increased above ten.', last_msg)
     self.assertIn("Please allocate two '+1' counters.", last_msg)
Пример #9
0
    def no_match(self, string):
        """A no match has been entered, perhaps an application name."""
        string = string.strip()
        app = self.type.apps.get(string, "app")
        if not app:
            string = string.lower()
            matches = []
            for app in self.type.apps:
                if type(app).folder == "app" and strip_ansi(app.display_name).lower().startswith(string):
                    matches.append(app)

            # If only one match, just move there
            if len(matches) == 1:
                app = matches[0]
            elif len(matches) == 0:
                self.user.msg("|gNo app name matches these letters.|n")
                return True
            else:
                names = [type(app).display_name for app in matches]
                names.sort(key=lambda name: name.lower())
                self.user.msg("Which app do you want to open? {}".format(", ".join(names)))
                return True

        screen = type(app).start_screen
        self.next(screen, app)
        return True
Пример #10
0
def wod_header(title=None,
               align="l",
               linecolor="W",
               textcolor="w",
               accentcolor="w"):
    '''
    Shows a 78 character wide header.  Optional header imbedded in it.

    :param title: String that will be shown in white over the header, optional.
    :param align: "l", "c", or "r" alignment.  Only used if title is provided.
    :param linecolor: Single character color code, default is 'W' (Light grey)
    :param textcolor: Single character color code, default is 'w' (White)
    :param accentcolor: Single character color code, default is 'w' (White)
    '''
    if title:
        fulltitle = "|%s===|%s|||%s %s |%s|||%s===" % (
            linecolor, accentcolor, textcolor, title, accentcolor, linecolor)
        w = len(strip_ansi(fulltitle))
        if align == "r":
            line = '|%s%s|n' % (linecolor, ANSIString(fulltitle).rjust(
                width=78, fillchar="="))
        elif align == "c":
            line = '|%s%s|n' % (linecolor, ANSIString(fulltitle).center(
                width=78, fillchar="="))
        else:
            line = '|%s%s|n' % (linecolor, ANSIString(fulltitle).ljust(
                width=78, fillchar="="))
    else:
        line = '|%s%s|n' % (linecolor, pad('', width=78, fillchar='='))
    return line
Пример #11
0
 def test_node_allocate_skills_startover(self):
     """test starting over after allocating some skill counters"""
     archetypes.apply_archetype(self.char1, 'scout')
     traits = self.char1.traits
     traits.INT.mod = traits.DEX.mod = traits.CHA.mod = 1
     traits.VIT.mod = 5
     races.apply_race(self.char1, 'human', 'cunning')
     archetypes.calculate_secondary_traits(self.char1.traits)
     archetypes.finalize_traits(self.char1.traits)
     skills.apply_skills(self.char1)
     self.session.execute_cmd('@charcreate Char')
     # -1's
     self.session.execute_cmd('7')
     self.session.execute_cmd('8')
     self.session.execute_cmd('9')
     # +1's
     self.session.execute_cmd('4')
     self.session.execute_cmd('5')
     # start over
     self.session.execute_cmd('16')
     sk = self.char1.skills
     for s in sk.all:
         self.assertEqual(sk[s].minus, 0)
         self.assertEqual(sk[s].plus, 0)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn("Please allocate three '-1' counters.", last_msg)
Пример #12
0
 def test_node_allocate_skills_startover(self):
     """test starting over after allocating some skill counters"""
     archetypes.apply_archetype(self.char1, 'scout')
     traits = self.char1.traits
     traits.INT.mod = traits.DEX.mod = traits.CHA.mod = 1
     traits.VIT.mod = 5
     races.apply_race(self.char1, 'human', 'cunning')
     archetypes.calculate_secondary_traits(self.char1.traits)
     archetypes.finalize_traits(self.char1.traits)
     skills.apply_skills(self.char1)
     self.session.execute_cmd('@charcreate Char')
     # -1's
     self.session.execute_cmd('7')
     self.session.execute_cmd('8')
     self.session.execute_cmd('9')
     # +1's
     self.session.execute_cmd('4')
     self.session.execute_cmd('5')
     # start over
     self.session.execute_cmd('16')
     sk = self.char1.skills
     for s in sk.all:
         self.assertEqual(sk[s].minus, 0)
         self.assertEqual(sk[s].plus, 0)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn("Please allocate three '-1' counters.", last_msg)
Пример #13
0
    def func(self):

        caller = self.caller

        #if they use an =, we know something is wrong
        if self.rhs:
            syntax_error(caller, self.key)
            return

        #if the arg is "delete", we just delete their name colors and ignore everything else
        if self.args == "delete":
            del caller.db.colorname
            return

        #strip the ANSI from the submitted name and make sure they aren't trying to impostor someone else
        stripped = strip_ansi(self.args)
        #if the stripped name doesn't equal their name, error
        if stripped != caller.name:
            caller.msg(
                "That name doesn't match yours! Your name must not change, only add color codes."
            )
            return

        if stripped == caller.name:
            caller.db.colorname = self.args
            caller.msg("Your name colors have been set to %s" %
                       caller.db.colorname)
Пример #14
0
 def test_node_allocate_skills_above_ten(self):
     """test invalid skill allocation above 10"""
     archetypes.apply_archetype(self.char1, 'arcanist')
     traits = self.char1.traits
     traits.VIT.mod = 2
     traits.DEX.mod = 2
     traits.INT.mod = 3
     traits.BM.base = 8
     races.apply_race(self.char1, 'elf', 'spirit')
     archetypes.calculate_secondary_traits(self.char1.traits)
     archetypes.finalize_traits(self.char1.traits)
     skills.apply_skills(self.char1)
     self.session.execute_cmd('@charcreate Char')
     # -1's
     self.session.execute_cmd('9')
     self.session.execute_cmd('9')
     self.session.execute_cmd('9')
     # +1's
     self.session.execute_cmd('7')
     self.session.execute_cmd('7')
     self.assertEqual(self.char1.skills.appraise.plus, 1)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn('Skills cannot be increased above ten.', last_msg)
     self.assertIn("Please allocate two '+1' counters.", last_msg)
Пример #15
0
    def func(self):
        """Redirect most inputs to the screen, if found."""
        raw_string = self.raw_string.rstrip()
        if getattr(self, "screen", None) is None:
            main.error("The CmdSet doesn't have a screen attribute.")
            self.msg("An error occurred.  Closing the interface...")
            self.caller.cmdset.delete(ComputerCmdSet)
            return

        screen = self.screen
        if screen.user is not self.caller:
            main.error(
                "The recorded screen has user {} while the CmdSet has caller {}"
                .format(screen.user, self.caller))
            self.msg("An error occurred.  Closing the interface...")
            self.caller.cmdset.delete(ComputerCmdSet)
            screen.close()
            return

        # Handle "back" and "quit"
        if raw_string.lower() == "back" and screen.can_back:
            # Move one step ahead
            if screen.previous:
                screen.back()
            else:
                self.msg("You cannot go back.")
        elif raw_string.lower() == "exit" and screen.can_quit:
            self.msg("You quit the interface of {}.".format(
                screen.obj.get_display_name(self.caller)))
            screen.close()
            screen.type.quit()
        else:
            ret = screen.no_match(strip_ansi(raw_string))
            if not ret:
                screen.wrong_input(raw_string)
Пример #16
0
    def log(self, message, caller=None):
        """
        Log to a file specificially for this room.
        """
        caller = f"[caller.key]: " if caller else ""

        logger.log_file(strip_ansi(f"{caller}{message.strip()}"),
                        filename=self.tagcategory + ".log")
Пример #17
0
 def test_node_welcome(self):
     """test welcome node output"""
     self.session.new_char = self.char1
     (text, help), options = menunode_welcome_archetypes(self.session)
     opt_texts = [ansi.strip_ansi(o['desc']) for o in options]
     self.assertEqual(opt_texts, ['Arcanist', 'Scout', 'Warrior',
                                  'Warrior-Scout', 'Warrior-Arcanist',
                                  'Arcanist-Scout'])
Пример #18
0
def header(string,
           fill="|113-|n",
           length="78",
           lframe="|113[|n",
           rframe="|113]|n",
           just="left",
           offset=0):
    """
    Create a header for different areas of the game.
    """
    str_len = int(length) - round(
        len(strip_ansi(string)) + len(strip_ansi(lframe)) +
        len(strip_ansi(lframe))) - offset
    if just.lower() == "left":
        return fill * offset + lframe + string + rframe + fill * str_len + "\n"
    else:
        return fill * str_len + lframe + string + rframe + fill * offset + "\n"
Пример #19
0
 def test_node_welcome(self):
     """test welcome node output"""
     self.session.new_char = self.char1
     (text, help), options = menunode_welcome_archetypes(self.session)
     opt_texts = [ansi.strip_ansi(o['desc']) for o in options]
     self.assertEqual(opt_texts, ['Arcanist', 'Scout', 'Warrior',
                                  'Warrior-Scout', 'Warrior-Arcanist',
                                  'Arcanist-Scout'])
Пример #20
0
 def post_map(post, bulletin_board, read_posts_list):
     """Helper function to get dict of post information to add to context per post"""
     return {
         'id': post.id,
         'poster': bulletin_board.get_poster(post),
         'subject': ansi.strip_ansi(post.db_header),
         'date': post.db_date_created.strftime("%x"),
         'unread': post not in read_posts_list
     }
Пример #21
0
 def post_map(post, bulletin_board, read_posts_list):
     """Helper function to get dict of post information to add to context per post"""
     return {
         "id": post.id,
         "poster": bulletin_board.get_poster(post),
         "subject": ansi.strip_ansi(post.db_header),
         "date": post.db_date_created.strftime("%x"),
         "unread": post not in read_posts_list,
     }
Пример #22
0
    def get_text(self):
        """Display the installed apps."""
        string = dedent("""
            AvenOS 12.0            [6G]           [Bluetooth]           [96%}
        """.lstrip("\n")) + "\n    "
        i = 0
        for app in self.type.apps:
            if i > 0 and i % 4 == 0:
                string = string.rstrip(" ") + "\n" + " " * 4
            text = app.get_display_name()
            no_ansi_text = strip_ansi(text)
            string += "{name}".format(name=self.format_cmd(text, strip_ansi(app.display_name).lower(), upper=False))
            string += " " * (15 - len(no_ansi_text))

        string = string.rstrip(" ") + "\n\n" + dedent("""
            Enter the first letters to open this app.  Type |hEXIT|n to quit the interface."
        """.lstrip("\n"))
        return string
Пример #23
0
 def _simple_form(self, form):
     cellsdict = {1: "Apple", 2: "Banana", 3: "Citrus", 4: "Durian"}
     formdict = {"FORMCHAR": 'x', "TABLECHAR": 'c', "FORM": form}
     form = evform.EvForm(form=formdict)
     form.map(cellsdict)
     form = ansi.strip_ansi(str(form))
     # this is necessary since editors/black tend to strip lines spaces
     # from the end of lines for the comparison strings.
     form = "\n".join(line.rstrip() for line in form.split("\n"))
     return form
Пример #24
0
 def test_node_allocate_traits_toomany(self):
     """test trait allocation node"""
     archetypes.apply_archetype(self.char1, 'warrior')
     self.session.execute_cmd('@charcreate Char')
     for i in list(range(5)):
         self.session.execute_cmd('1')
     self.assertEqual(self.char1.traits.STR.actual, 10)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn('Cannot allocate more than 10 points to one trait!', last_msg)
Пример #25
0
 def test_node_allocate_traits_toomany(self):
     """test trait allocation node"""
     archetypes.apply_archetype(self.char1, 'warrior')
     self.session.execute_cmd('@charcreate Char')
     for i in xrange(5):
         self.session.execute_cmd('1')
     self.assertEqual(self.char1.traits.STR.actual, 10)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn('Cannot allocate more than 10 points to one trait!', last_msg)
Пример #26
0
 def msg(self,
         text=None,
         from_obj=None,
         session=None,
         options=None,
         **kwargs):
     super().msg(text=ansi.strip_ansi(text),
                 from_obj=from_obj,
                 session=session,
                 options=options**kwargs)
Пример #27
0
def fix_names(apps, schema_editor):
    from evennia.utils.ansi import strip_ansi
    from django.db.models import F, Q
    Agent = apps.get_model("dominion", "Agent")
    Agent.objects.all().update(colored_name=F('name'))
    for agent in Agent.objects.filter(
            Q(name__icontains='{') | Q(name__icontains='|')
            | Q(name__icontains='%')):
        agent.name = strip_ansi(agent.name)
        agent.save()
Пример #28
0
def color(entry, option_key="Color", **kwargs):
    """
    The color should be just a color character, so 'r' if red color is desired.
    """
    if not entry:
        raise ValueError(f"Nothing entered for a {option_key}!")
    test_str = strip_ansi(f"|{entry}|n")
    if test_str:
        raise ValueError(f"'{entry}' is not a valid {option_key}.")
    return entry
 def sendLine(self, line):
     #parse_ansi(line, strip_ansi=True, xterm256=False, mxp=False)
     if self.header and self.ackSent == False:
         self.ackSent = True
         #print("UnrealPlugin sendLine: prefixing data with header: " + self.header)
         line = self.header + line
     line = line + "<EOF>"
     line = strip_ansi(line, parser=ANSI_PARSER)
     #print("UnrealPlugin sendLine: " + line)
     return self.transport.write(line)
Пример #30
0
    def test_working(self):
        self.assertEqual(self.practitioner.anima, 100)
        self.assertFalse(self.practitioner.knows_node(self.node))
        self.assertFalse(self.practitioner.knows_spell(self.spell))
        self.practitioner.open_node(
            self.node,
            SkillNodeResonance.LEARN_FIAT,
            explanation="Learned by test fiat.",
        )
        self.assertTrue(self.practitioner.knows_node(self.node))
        self.assertEqual(self.practitioner.resonance_for_node(self.node), 0)
        self.practitioner.add_resonance_to_node(self.node, 10)
        self.assertEqual(self.practitioner.resonance_for_node(self.node), 10)
        self.assertTrue(self.practitioner.knows_spell(self.spell))
        self.test_object.location = self.practitioner.character.location
        working = Working.objects.create(
            lead=self.practitioner,
            spell=self.spell,
            target_string=self.test_object.name,
        )
        working.add_practitioner(self.practitioner, accepted=True)
        with patch(
                "world.magic.models.Working.successes",
                new_callable=PropertyMock(return_value=10),
        ) as fake_successes:
            self.assertEqual(working.validation_error(), None)
            from evennia.utils.ansi import strip_ansi

            with patch("typeclasses.scripts.combat.attacks.Attack"):
                working.perform(unsafe=False)
                working.finalize()
            self.assertEqual(
                strip_ansi(working.description_string()),
                " ID:                 1                                                        \n"
                " Participants:       Char2                                                    \n"
                " Lead:               Char2                                                    \n"
                " Alignment:          Primal                                                   \n"
                " Type:               Casting                                                  \n"
                " Spell:              Test Spell                                               \n"
                " Calculated:         yes                                                      \n"
                " Performed:          yes                                                      \n"
                " Available Primum:   100                                                      \n"
                " Cost:               8                                                        \n"
                " Danger Level:       relatively safe                                          \n"
                " Successes:          10                                                       \n"
                " Result:             Participants perceive: A spectacular glow.               ",
            )
        self.assertEqual(
            pending_magic_text(),
            "Char2 chants in Arvani and gestures expansively and energetically!\n"
            "As Char2 works magic, the effect spreading out from them resembles a test "
            "pattern atop static.\n"
            "Gazing at Test Object, you perceive: A spectacular glow.",
        )
        self.assertEqual(self.practitioner.anima, 92)
Пример #31
0
def evtable_options_formatter(optionlist, caller=None):
    """
    Formats the option list display.
    """
    if not optionlist:
        return ""

    # column separation distance
    colsep = 4

    nlist = len(optionlist)

    # get the widest option line in the table.
    table_width_max = -1
    table = []
    for key, desc in optionlist:
        if not (key or desc):
            continue
        table_width_max = max(table_width_max,
                              max(m_len(p) for p in key.split("\n")) +
                              max(m_len(p) for p in desc.split("\n")) + colsep)
        raw_key = strip_ansi(key)
        if raw_key != key:
            # already decorations in key definition
            table.append(ANSIString(" |lc%s|lt%s|le: %s" % (raw_key, key, desc)))
        else:
            # add a default white color to key
            table.append(ANSIString(" |lc%s|lt|w%s|n|le: %s" % (raw_key, raw_key, desc)))

    ncols = (_MAX_TEXT_WIDTH // table_width_max) + 1 # number of ncols
    nlastcol = nlist % ncols # number of elements left in last row

    # get the amount of rows needed (start with 4 rows)
    nrows = 4
    while nrows * ncols < nlist:
        nrows += 1
    ncols = nlist // nrows # number of full columns
    nlastcol = nlist % nrows # number of elements in last column

    # get the final column count
    ncols = ncols + 1 if nlastcol > 0 else ncols
    if ncols > 1:
        # only extend if longer than one column
        table.extend([" " for i in range(nrows - nlastcol)])

    # build the actual table grid
    table = [table[icol * nrows : (icol * nrows) + nrows] for icol in range(0, ncols)]

    # adjust the width of each column
    for icol in range(len(table)):
        col_width = max(max(m_len(p) for p in part.split("\n")) for part in table[icol]) + colsep
        table[icol] = [pad(part, width=col_width + colsep, align="l") for part in table[icol]]

    # format the table into columns
    return unicode(EvTable(table=table, border="none"))
Пример #32
0
def evtable_options_formatter(optionlist, caller=None):
    """
    Formats the option list display.
    """
    if not optionlist:
        return ""

    # column separation distance
    colsep = 4

    nlist = len(optionlist)

    # get the widest option line in the table.
    table_width_max = -1
    table = []
    for key, desc in optionlist:
        if not (key or desc):
            continue
        table_width_max = max(table_width_max,
                              max(m_len(p) for p in key.split("\n")) +
                              max(m_len(p) for p in desc.split("\n")) + colsep)
        raw_key = strip_ansi(key)
        if raw_key != key:
            # already decorations in key definition
            table.append(ANSIString(" |lc%s|lt%s|le: %s" % (raw_key, key, desc)))
        else:
            # add a default white color to key
            table.append(ANSIString(" |lc%s|lt|w%s|n|le: %s" % (raw_key, raw_key, desc)))

    ncols = (_MAX_TEXT_WIDTH // table_width_max) + 1 # number of ncols
    nlastcol = nlist % ncols # number of elements left in last row

    # get the amount of rows needed (start with 4 rows)
    nrows = 4
    while nrows * ncols < nlist:
        nrows += 1
    ncols = nlist // nrows # number of full columns
    nlastcol = nlist % nrows # number of elements in last column

    # get the final column count
    ncols = ncols + 1 if nlastcol > 0 else ncols
    if ncols > 1:
        # only extend if longer than one column
        table.extend([" " for i in range(nrows - nlastcol)])

    # build the actual table grid
    table = [table[icol * nrows : (icol * nrows) + nrows] for icol in range(0, ncols)]

    # adjust the width of each column
    for icol in range(len(table)):
        col_width = max(max(m_len(p) for p in part.split("\n")) for part in table[icol]) + colsep
        table[icol] = [pad(part, width=col_width + colsep, align="l") for part in table[icol]]

    # format the table into columns
    return unicode(EvTable(table=table, border="none"))
Пример #33
0
    def at_pre_cmd(self):
        """
        This hook is called before self.parse() on all commands
        """
        from typeclasses.characters import Character

        if type(self.caller) != Character:
            return

        command = self.cmdstring + self.args

        echo = "\n{icon} |220" + ansi.strip_ansi(command) + "\n\n"

        return self.caller.msg(echo, icon="graf62")
Пример #34
0
 def func(self):
     """Run the spoof command"""
     caller = self.caller
     if not self.args:
         caller.execute_cmd('help spoof')
         return
     if 'self' in self.switches:
         caller.msg(self.args)
         return
     else:  # Strip any markup to secure the spoof.
         spoof = ansi.strip_ansi(self.args)
     # calling the speech hook on the location.
     # An NPC would know who spoofed.
     spoof = caller.location.at_say(caller, spoof)
     caller.location.msg_contents(spoof, options={'raw': True})
Пример #35
0
 def func(self):
     """Run the spoof command"""
     caller = self.caller
     if not self.args:
         caller.execute_cmd('help spoof')
         return
     if 'self' in self.switches:
         caller.msg(self.args)
         return
     else:  # Strip any markup to secure the spoof.
         spoof = ansi.strip_ansi(self.args)
     # calling the speech hook on the location.
     # An NPC would know who spoofed.
     spoof = caller.location.at_say(caller, spoof)
     caller.location.msg_contents(spoof, options={'raw': True})
Пример #36
0
def strip_ansi(text):
    """Stripping out old ansi from a string"""
    from evennia.utils.ansi import strip_ansi
    text = strip_ansi(text)
    text = text.replace('%r', '').replace('%R', '').replace('%t', '').replace(
        '%T', '').replace('%b', '')
    text = text.replace('%cr', '').replace('%cR',
                                           '').replace('%cg', '').replace(
                                               '%cG', '').replace('%cy', '')
    text = text.replace('%cY', '').replace('%cb',
                                           '').replace('%cB', '').replace(
                                               '%cm', '').replace('%cM', '')
    text = text.replace('%cc', '').replace('%cC',
                                           '').replace('%cw', '').replace(
                                               '%cW', '').replace('%cx', '')
    text = text.replace('%cX', '').replace('%ch', '').replace('%cn', '')
    return text
Пример #37
0
 def test_node_allocate_skills_below_one(self):
     """test invalid skill allocation below 1"""
     archetypes.apply_archetype(self.char1, 'scout')
     traits = self.char1.traits
     traits.INT.mod = traits.DEX.mod = traits.CHA.mod = 1
     traits.VIT.mod = 5
     races.apply_race(self.char1, 'human', 'cunning')
     archetypes.calculate_secondary_traits(self.char1.traits)
     archetypes.finalize_traits(self.char1.traits)
     skills.apply_skills(self.char1)
     self.session.execute_cmd('@charcreate Char')
     self.session.execute_cmd('15')
     self.session.execute_cmd('15')
     self.assertEqual(self.char1.skills.leadership.minus, 1)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn('Skills cannot be reduced below one.', last_msg)
     self.assertIn("Please allocate two '-1' counters.", last_msg)
Пример #38
0
 def test_node_allocate_skills_below_one(self):
     """test invalid skill allocation below 1"""
     archetypes.apply_archetype(self.char1, 'scout')
     traits = self.char1.traits
     traits.INT.mod = traits.DEX.mod = traits.CHA.mod = 1
     traits.VIT.mod = 5
     races.apply_race(self.char1, 'human', 'cunning')
     archetypes.calculate_secondary_traits(self.char1.traits)
     archetypes.finalize_traits(self.char1.traits)
     skills.apply_skills(self.char1)
     self.session.execute_cmd('@charcreate Char')
     self.session.execute_cmd('15')
     self.session.execute_cmd('15')
     self.assertEqual(self.char1.skills.leadership.minus, 1)
     # confirm error message
     last_msg = ansi.strip_ansi(self.session.msg.mock_calls[-1][1][0])
     self.assertIn('Skills cannot be reduced below one.', last_msg)
     self.assertIn("Please allocate two '-1' counters.", last_msg)
Пример #39
0
 def test_node_equip_insuff_funds(self):
     """test insufficient funds messaging"""
     archetypes.apply_archetype(self.char1, 'scout')
     traits = self.char1.traits
     traits.INT.mod = traits.DEX.mod = traits.CHA.mod = 1
     traits.VIT.mod = 5
     races.apply_race(self.char1, 'human', 'cunning')
     archetypes.calculate_secondary_traits(self.char1.traits)
     archetypes.finalize_traits(self.char1.traits)
     skills.apply_skills(self.char1)
     skills.finalize_skills(self.char1.skills)
     # check insufficient funds
     self.session.execute_cmd('@charcreate Char')
     self.session.execute_cmd('4')
     self.session.execute_cmd('3')
     self.session.execute_cmd('y')
     messages = [ansi.strip_ansi(args[0]) for n, args, kw
                 in self.session.msg.mock_calls]
     self.assertIn("You do not have enough money to buy a brigandine.", messages)
Пример #40
0
        def _depth_first(menu, tree, visited, indent):

            # we are in a given node here
            nodename = menu.nodename
            options = menu.test_options
            if isinstance(options, dict):
                options = (options, )

            # run validation tests for this node
            compare_text = self.expected_node_texts.get(nodename, None)
            if compare_text is not None:
                compare_text = ansi.strip_ansi(compare_text.strip())
                node_text = menu.test_nodetext
                self.assertIsNotNone(
                    bool(node_text),
                    "node: {}: node-text is None, which was not expected.".format(nodename))
                if isinstance(node_text, tuple):
                    node_text, helptext = node_text
                node_text = ansi.strip_ansi(node_text.strip())
                self.assertTrue(
                    node_text.startswith(compare_text),
                    "\nnode \"{}\':\nOutput:\n{}\n\nExpected (startswith):\n{}".format(
                        nodename, node_text, compare_text))
            compare_options_count = self.expected_node_options_count.get(nodename, None)
            if compare_options_count is not None:
                self.assertEqual(
                    len(options), compare_options_count,
                    "Not the right number of options returned from node {}.".format(nodename))
            compare_options = self.expected_node_options.get(nodename, None)
            if compare_options:
                self.assertEqual(
                    options, compare_options,
                    "Options returned from node {} does not match.".format(nodename))

            self._debug_output(indent, "*{}".format(nodename))
            subtree = []

            if not options:
                # an end node
                if nodename not in visited:
                    visited.append(nodename)
                subtree = nodename
            else:
                for inum, optdict in enumerate(options):

                    key, desc, execute, goto = optdict.get("key", ""), optdict.get("desc", None),\
                                               optdict.get("exec", None), optdict.get("goto", None)

                    # prepare the key to pass to the menu
                    if isinstance(key, (tuple, list)) and len(key) > 1:
                        key = key[0]
                    if key == "_default":
                        key = "test raw input"
                    if not key:
                        key = str(inum + 1)

                    backup_menu = copy.copy(menu)

                    # step the menu
                    menu.parse_input(key)

                    # from here on we are likely in a different node
                    nodename = menu.nodename

                    if menu.close_menu.called:
                        # this was an end node
                        self._debug_output(indent, "    .. menu exited! Back to previous node.")
                        menu = backup_menu
                        menu.close_menu = MagicMock()
                        visited.append(nodename)
                        subtree.append(nodename)
                    elif nodename not in visited:
                        visited.append(nodename)
                        subtree.append(nodename)
                        _depth_first(menu, subtree, visited, indent + 2)
                        #self._debug_output(indent, "    -> arrived at {}".format(nodename))
                    else:
                        subtree.append(nodename)
                        #self._debug_output( indent, "    -> arrived at {} (circular call)".format(nodename))
                    self._debug_output(indent, "-- {} ({}) -> {}".format(key, desc, goto))

            if subtree:
                tree.append(subtree)
Пример #41
0
    def goto(self, nodename, raw_string):
        """
        Run a node by name

        Args:
            nodename (str): Name of node.
            raw_string (str): The raw default string entered on the
                previous node (only used if the node accepts it as an
                argument)

        """
        try:
            # execute the node, make use of the returns.
            nodetext, options = self._execute_node(nodename, raw_string)
        except EvMenuError:
            return

        if self._persistent:
            self.caller.attributes.add("_menutree_saved_startnode", (nodename, raw_string))

        # validation of the node return values
        helptext = ""
        if hasattr(nodetext, "__iter__"):
            if len(nodetext) > 1:
                nodetext, helptext = nodetext[:2]
            else:
                nodetext = nodetext[0]
        nodetext = "" if nodetext is None else str(nodetext)
        options = [options] if isinstance(options, dict) else options

        # this will be displayed in the given order
        display_options = []
        # this is used for lookup
        self.options = {}
        self.default = None
        if options:
            for inum, dic in enumerate(options):
                # fix up the option dicts
                keys = make_iter(dic.get("key"))
                if "_default" in keys:
                    keys = [key for key in keys if key != "_default"]
                    desc = dic.get("desc", dic.get("text", _ERR_NO_OPTION_DESC).strip())
                    goto, execute = dic.get("goto", None), dic.get("exec", None)
                    self.default = (goto, execute)
                else:
                    keys = list(make_iter(dic.get("key", str(inum+1).strip()))) + [str(inum+1)]
                    desc = dic.get("desc", dic.get("text", _ERR_NO_OPTION_DESC).strip())
                    goto, execute = dic.get("goto", None), dic.get("exec", None)

                if keys:
                    display_options.append((keys[0], desc))
                    for key in keys:
                        if goto or execute:
                            self.options[strip_ansi(key).strip().lower()] = (goto, execute)

        self.nodetext = self._format_node(nodetext, display_options)

        # handle the helptext
        if helptext:
            self.helptext = helptext
        elif options:
            self.helptext = _HELP_FULL if self.auto_quit else _HELP_NO_QUIT
        else:
            self.helptext = _HELP_NO_OPTIONS if self.auto_quit else _HELP_NO_OPTIONS_NO_QUIT

        self.display_nodetext()
Пример #42
0
    def func(self):
        """Basic pose, power pose, room posing - all in one"""
        cmd = self.cmdstring
        opt = self.switches
        args = unicode(self.args).strip()
        lhs, rhs = self.lhs, self.rhs
        char = self.character
        account = self.account
        here = char.location if char else None
        power = True if self.cmdstring == 'ppose' or self.cmdstring == 'pp' or self.cmdstring == 'p:' else False

        def parse_pose(text):
            return_text = []
            for each in text.split():
                match = None
                new_each = each
                word_end = ''
                if each.startswith('/'):  # A possible substitution to test
                    if each.endswith('/'):  # Skip this one, it's /italic/
                        return_text.append(new_each)
                        continue
                    search_word = each[1:]
                    if search_word.startswith('/'):  # Skip this one, it's being escaped
                        new_each = each[1:]
                    else:  # Marked for substitution, try to find a match
                        if "'" in each:  # Test for possessive or contraction:  's  (apostrophe before end of grouping)
                            pass
                        if each[-1] in ".,!?":
                            search_word, word_end = search_word[:-1], each[-1]
                        match = char.search(search_word, quiet=True)
                return_text.append(new_each if not match else (match[0].get_display_name(char) + word_end))
            return ' '.join(return_text)

        raw_pose = rhs if rhs and power else args
        raw_pose = parse_pose(raw_pose)
        non_space_chars = ['®', '©', '°', '·', '~', '@', '-', "'", '’', ',', ';', ':', '.', '?', '!', '…']
        magnet = True if raw_pose and raw_pose[0] in non_space_chars or cmd == ";" else False
        doing = True if 'do' in cmd or 'rp' in cmd else False
        pose = ('' if magnet else '|_') + (ansi.strip_ansi(raw_pose) if doing else raw_pose)
        # ---- Setting Room poses as a doing message ----------
        if doing:  # Pose will have no markup when posing on the room, to minimize shenanigans.
            target = char  # Initially assume the setting character is the target.
            if not args and 'reset' not in opt:
                has_pose = char.db.messages and char.db.messages.get('pose')
                if has_pose:  # If target has poses set, display them to the setter.
                    char.msg("Current pose reads: '%s'" % target.get_display_name(char, pose=True))
                    default_pose = target.db.messages and target.db.messages.get('pose_default') or None
                    if default_pose:
                        char.msg('Default pose is \'%s%s\'' % (char.get_display_name(char), default_pose))
                    else:
                        char.msg('Default pose not set.')
                else:
                    char.msg('No pose has been set.|/Usage: rp <pose-text> OR pose <obj> = <pose-text>')
                return
            if len(pose) > 60:  # Pose length in characters, not counting the poser's name.
                char.msg('Your pose is too long.')
                return
            if rhs:  # pose something else other than self.
                target = char.search(lhs)  # Search for a reference to the target.
                if not target:
                    return
                if pose:
                    self.set_doing(char, pose, target)  # Try to set the pose of the target.
            else:  # pose self.
                target = char
            if 'reset' in opt:  # Clears current temp doing, reverts it to default.
                pose = target.db.messages and target.db.messages.get('pose_default', '')
                if not target.db.messages:
                    target.db.messages = {}
                target.db.messages['pose'] = pose
            elif 'default' in opt:  # Sets doing pose default.
                self.set_doing(char, pose, target, True)  # True means "set default", not temp doing.
                char.msg("Default pose is now: '%s%s'" % (target.get_display_name(char), pose))
                return  # Nothing more to do. Default never poses to room, just sets doing message.
            elif not rhs:
                self.set_doing(char, pose)  # Setting temp doing message on the setter...
                if args and not ('silent' in opt or 'quiet' in opt) and char is target:  # Allow set without posing
                    account.execute_cmd(';%s' % pose)  # pose to the room like a normal pose would.
            char.msg("Pose now set to: '%s'" % target.get_display_name(char, pose=True))  # Display name with pose.
        else:  # ---- Action pose, not static Room Pose. ---------------------
            if '|/' in pose:
                pose = pose.split('|/', 1)[0]
            if 'magnet' in opt:
                char.msg("Pose magnet glyphs are %s." % non_space_chars)
            if not (here and char):
                if args:
                    account.execute_cmd('pub :%s' % pose)
                else:
                    account.msg('Usage: pose <message>   to pose to public channel.')
                return
            if args:
                if power and self.rhs and 'o' not in self.switches:
                    char.ndb.power_pose = pose
                    account.execute_cmd(self.rhs)
                else:
                    ooc = 'ooc' in self.switches
                    prepend_ooc = '[OOC] ' if ooc else ''
                    here.msg_contents(('%s{char}%s' % (prepend_ooc, escape_braces(pose)),
                                       {'type': 'pose', 'ooc': ooc}),
                                      from_obj=char, mapping=dict(char=char))
            else:
                account.execute_cmd('help pose')
Пример #43
0
    def _format_node(self, nodetext, optionlist):
        """
        Format the node text + option section

        Args:
            nodetext (str): The node text
            optionlist (list): List of (key, desc) pairs.

        Returns:
            string (str): The options section, including
                all needed spaces.

        Notes:
            This will adjust the columns of the options, first to use
            a maxiumum of 4 rows (expanding in columns), then gradually
            growing to make use of the screen space.

        """
        #
        # handle the node text
        #

        nodetext = dedent(nodetext).strip()

        nodetext_width_max = max(m_len(line) for line in nodetext.split("\n"))

        if not optionlist:
            # return the node text "naked".
            separator1 = "_" * nodetext_width_max + "\n\n" if nodetext_width_max else ""
            separator2 = "\n" if nodetext_width_max else "" + "_" * nodetext_width_max
            return separator1 + nodetext + separator2

        #
        # handle the options
        #

        # column separation distance
        colsep = 4

        nlist = len(optionlist)

        # get the widest option line in the table.
        table_width_max = -1
        table = []
        for key, desc in optionlist:
            table_width_max = max(table_width_max,
                                  max(m_len(p) for p in key.split("\n")) +
                                  max(m_len(p) for p in desc.split("\n")) + colsep)
            raw_key = strip_ansi(key)
            if raw_key != key:
                # already decorations in key definition
                table.append(ANSIString(" {lc%s{lt%s{le: %s" % (raw_key, key, desc)))
            else:
                # add a default white color to key
                table.append(ANSIString(" {lc%s{lt{w%s{n{le: %s" % (raw_key, raw_key, desc)))

        ncols = (_MAX_TEXT_WIDTH // table_width_max) + 1 # number of ncols
        nlastcol = nlist % ncols # number of elements left in last row

        # get the amount of rows needed (start with 4 rows)
        nrows = 4
        while nrows * ncols < nlist:
            nrows += 1
        ncols = nlist // nrows # number of full columns
        nlastcol = nlist % nrows # number of elements in last column

        # get the final column count
        ncols = ncols + 1 if nlastcol > 0 else ncols
        if ncols > 1:
            # only extend if longer than one column
            table.extend([" " for i in xrange(nrows-nlastcol)])

        # build the actual table grid
        table = [table[icol*nrows:(icol*nrows) + nrows] for icol in xrange(0, ncols)]

        # adjust the width of each column
        total_width = 0
        for icol in xrange(len(table)):
            col_width = max(max(m_len(p) for p in part.split("\n")) for part in table[icol]) + colsep
            table[icol] = [pad(part, width=col_width + colsep, align="l") for part in table[icol]]
            total_width += col_width

        # format the table into columns
        table = EvTable(table=table, border="none")

        # build the page
        total_width = max(total_width, nodetext_width_max)
        separator1 = "_" * total_width + "\n\n" if nodetext_width_max else ""
        separator2 = "\n" + "_" * total_width + "\n\n" if total_width else ""
        return separator1 + nodetext + separator2 + unicode(table)
Пример #44
0
 def _debug_output(self, indent, msg):
     if self.debug_output:
         print(" " * indent + ansi.strip_ansi(msg))
Пример #45
0
 def func(self):
     """Run the spoof command"""
     char = self.character
     here = char.location
     opt = self.switches
     args = self.args
     to_self = 'self' in opt or not here
     if not args:
         self.account.execute_cmd('help spoof')
         return
     # Optionally strip any markup /or/ just escape it,
     stripped = ansi.strip_ansi(args)
     spoof = stripped if 'strip' in opt else args.replace('|', '||')
     if 'indent' in opt:
         indent = 20
         if self.rhs:
             args = self.lhs.strip()
             indent = re.sub("[^0123456789]", '', self.rhs) or 20
             indent = int(indent)
         if to_self:
             char.msg(' ' * indent + args.rstrip())
         else:
             here.msg_contents(text=(' ' * indent + escape_braces(args.rstrip()), {'type': 'spoof'}))
     elif 'right' in opt or 'center' in opt or 'news' in opt:
         if self.rhs is not None:  # Equals sign exists.
             parameters = '' if not self.rhs else self.rhs.split()
             args = self.lhs.strip()
             if len(parameters) > 1:
                 if len(parameters) == 2:
                     outside, inside = self.rhs.split()
                 else:
                     outside, inside = [parameters[0], parameters[1]]
                 outside = re.sub("[^0123456789]", '', outside) or 0
                 inside = re.sub("[^0123456789]", '', inside) or 0
                 outside, inside = [int(max(outside, inside)), int(min(outside, inside))]
             else:
                 outside, inside = [72, 20]
         else:
             outside, inside = [72, min(int(self.rhs or 72), 20)]
         block = 'r' if 'right' in opt else 'f'
         block = 'c' if 'center' in opt else block
         for text in justify(args, width=outside, align=block, indent=inside).split('\n'):
             if to_self:
                 char.msg(text.rstrip())
             else:
                 here.msg_contents(text=(escape_braces(text.rstrip()), {'type': 'spoof'}))
     else:
         if 'strip' in opt:  # Optionally strip any markup or escape it,
             if to_self:
                 char.msg(spoof.rstrip(), options={'raw': True})
             else:
                 here.msg_contents(text=(escape_braces(spoof.rstrip()), {'type': 'spoof'}), options={'raw': True})
         elif 'dot' in opt:  # Leave leading spacing intact, remove leading dot.
             spoof = args.lstrip('.')
             if to_self:
                 char.msg(spoof.rstrip(), options={'raw': True})
             else:
                 here.msg_contents(text=(escape_braces(spoof.rstrip()), {'type': 'spoof'}), options={'raw': True})
         else:
             if to_self:
                 char.msg(args.rstrip())
             else:
                 here.msg_contents(text=(escape_braces(spoof.rstrip()), {'type': 'spoof'}))