Example #1
0
 def list_flashbacks(self):
     from evennia.utils.evtable import EvTable
     table = EvTable("ID", "Title", "Owner", "New Posts", width=78, border="cells")
     for flashback in self.roster_entry.valid_flashbacks:
         table.add_row(flashback.id, flashback.title, flashback.owner,
                       str(len(flashback.get_new_posts(self.roster_entry))))
     self.msg(str(table))
Example #2
0
    def weekly_resonance_update(self):

        results = []

        for practitioner in self.get_active_practitioners().all():
            result = self.advance_weekly_resonance(practitioner)
            if result:
                results.append(result)

        from typeclasses.bulletin_board.bboard import BBoard
        board = BBoard.objects.get(db_key__iexact="staff")
        table = EvTable("{wName{n",
                        "{wGain{n",
                        "{wUnspent{n",
                        "{wMax{n",
                        border="cells",
                        width=78)
        for result in results:
            table.add_row(result['name'], result['gain'],
                          "%.2f" % result['resonance'], result['potential'])
        board.bb_post(poster_obj=self,
                      msg=str(table),
                      subject="Magic Resonance Gains",
                      poster_name="Magic System")
        inform_staff("List of magic resonance gains posted.")
Example #3
0
def format_script_list(scripts):
    """Takes a list of scripts and formats the output."""
    if not scripts:
        return "<No scripts>"

    table = EvTable("|wdbref|n", "|wobj|n", "|wkey|n", "|wintval|n", "|wnext|n",
                    "|wrept|n", "|wdb", "|wtypeclass|n", "|wdesc|n",
                    align='r', border="tablecols")
    for script in scripts:
        nextrep = script.time_until_next_repeat()
        if nextrep is None:
            nextrep = "PAUS" if script.db._paused_time else "--"
        else:
            nextrep = "%ss" % nextrep

        maxrepeat = script.repeats
        if maxrepeat:
            rept = "%i/%i" % (maxrepeat - script.remaining_repeats(), maxrepeat)
        else:
            rept = "-/-"

        table.add_row(script.id,
                      script.obj.key if (hasattr(script, 'obj') and script.obj) else "<Global>",
                      script.key,
                      script.interval if script.interval > 0 else "--",
                      nextrep,
                      rept,
                      "*" if script.persistent else "-",
                      script.typeclass_path.rsplit('.', 1)[-1],
                      crop(script.desc, width=20))
    return "%s" % table
Example #4
0
 def list_tickets(self):
     """List tickets for goalupdates"""
     table = EvTable("{wID{n", "{wPlayer{n", "{wGoal{n")
     for ticket in self.tickets:
         table.add_row(ticket.id, str(ticket.submitting_player),
                       ticket.goal_update.goal.summary)
     self.msg(str(table))
Example #5
0
def format_script_list(scripts):
    """Takes a list of scripts and formats the output."""
    if not scripts:
        return "<No scripts>"

    table = EvTable("|wdbref|n", "|wobj|n", "|wkey|n", "|wintval|n", "|wnext|n",
                    "|wrept|n", "|wdb", "|wtypeclass|n", "|wdesc|n",
                    align='r', border="tablecols")
    for script in scripts:
        nextrep = script.time_until_next_repeat()
        if nextrep is None:
            nextrep = "PAUS" if script.db._paused_time else "--"
        else:
            nextrep = "%ss" % nextrep

        maxrepeat = script.repeats
        if maxrepeat:
            rept = "%i/%i" % (maxrepeat - script.remaining_repeats(), maxrepeat)
        else:
            rept = "-/-"

        table.add_row(script.id,
                      script.obj.key if (hasattr(script, 'obj') and script.obj) else "<Global>",
                      script.key,
                      script.interval if script.interval > 0 else "--",
                      nextrep,
                      rept,
                      "*" if script.persistent else "-",
                      script.typeclass_path.rsplit('.', 1)[-1],
                      crop(script.desc, width=20))
    return "%s" % table
Example #6
0
def _test():
    "test evform. This is used by the unittest system."
    form = EvForm("evennia.utils.evform_test")

    # add data to each tagged form cell
    form.map(
        cells={
            "AA": "|gTom the Bouncer",
            2: "|yGriatch",
            3: "A sturdy fellow",
            4: 12,
            5: 10,
            6: 5,
            7: 18,
            8: 10,
            9: 3
        })
    # create the EvTables
    tableA = EvTable("HP",
                     "MV",
                     "MP",
                     table=[["**"], ["*****"], ["***"]],
                     border="incols")
    tableB = EvTable("Skill",
                     "Value",
                     "Exp",
                     table=[["Shooting", "Herbalism", "Smithing"], [12, 14, 9],
                            ["550/1200", "990/1400", "205/900"]],
                     border="incols")
    # add the tables to the proper ids in the form
    form.map(tables={"A": tableA, "B": tableB})
    # unicode is required since the example contains non-ascii characters
    return unicode(form)
Example #7
0
    def list_actions(self):
        """Prints a table of the actions we've taken"""
        table = EvTable("ID", "Crisis", "Date", "Owner", "Status")
        actions = self.actions_and_invites
        attending = list(
            actions.filter(
                Q(dompc=self.dompc, attending=True)
                | Q(assisting_actions__dompc=self.dompc,
                    assisting_actions__attending=True)))
        for action in actions:
            date = "--"
            if action.date_submitted:
                date = action.date_submitted.strftime("%x")

            def color_unsubmitted(string):
                """Colors the status display for assisting actions of the player that aren't ready to submit"""
                if action.status == PlotAction.DRAFT and action.check_unready_assistant(
                        self.dompc):
                    return "|r%s|n" % string
                return string

            is_attending = action in attending
            id_str = "{w*%s{n" % action.id if is_attending else str(action.id)
            table.add_row(id_str,
                          str(action.plot)[:20], date, str(action.dompc),
                          color_unsubmitted(action.get_status_display()))
        msg = "\nActions you're attending will be highlighted with {w*{n."
        self.msg(str(table) + msg)
Example #8
0
def _list_bots():
    """
    Helper function to produce a list of all IRC bots.

    Returns:
        bots (str): A table of bots or an error message.

    """
    ircbots = [
        bot for bot in PlayerDB.objects.filter(db_is_bot=True,
                                               username__startswith="ircbot-")
    ]
    if ircbots:
        from evennia.utils.evtable import EvTable
        table = EvTable("|w#dbref|n",
                        "|wbotname|n",
                        "|wev-channel|n",
                        "|wirc-channel|n",
                        "|wSSL|n",
                        maxwidth=_DEFAULT_WIDTH)
        for ircbot in ircbots:
            ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel,
                                      ircbot.db.irc_network,
                                      ircbot.db.irc_port)
            table.add_row("#%i" % ircbot.id, ircbot.db.irc_botname,
                          ircbot.db.ev_channel, ircinfo, ircbot.db.irc_ssl)
        return table
    else:
        return "No irc bots found."
Example #9
0
 def list_goals(self):
     """Displays our goals for our caller"""
     if "old" in self.switches:
         qs = self.goals.exclude(status=Goal.ACTIVE)
     else:
         qs = self.goals.filter(status=Goal.ACTIVE)
     table = EvTable("{wID{n", "{wSummary{n", "{wPlot{n")
     for ob in qs:
         table.add_row(ob.id, ob.summary, ob.plot)
     self.msg(str(table))
Example #10
0
    def page_formatter(self, page):
        """Input is a queryset page from django.Paginator"""
        caller = self._caller

        # get use-permissions of readonly attributes (edit is always False)
        display_tuples = []

        table = EvTable(
            "|wKey|n",
            "|wSpawn/Edit|n",
            "|wTags|n",
            "|wDesc|n",
            border="tablecols",
            crop=True,
            width=self.width,
        )

        for prototype in page:
            lock_use = caller.locks.check_lockstring(caller,
                                                     prototype.get(
                                                         "prototype_locks",
                                                         ""),
                                                     access_type="spawn",
                                                     default=True)
            if not self.show_non_use and not lock_use:
                continue
            if prototype.get("prototype_key", "") in _MODULE_PROTOTYPES:
                lock_edit = False
            else:
                lock_edit = caller.locks.check_lockstring(
                    caller,
                    prototype.get("prototype_locks", ""),
                    access_type="edit",
                    default=True)
            if not self.show_non_edit and not lock_edit:
                continue
            ptags = []
            for ptag in prototype.get("prototype_tags", []):
                if is_iter(ptag):
                    if len(ptag) > 1:
                        ptags.append("{}".format(ptag[0]))
                    else:
                        ptags.append(ptag[0])
                else:
                    ptags.append(str(ptag))

            table.add_row(
                prototype.get("prototype_key", "<unset>"),
                "{}/{}".format("Y" if lock_use else "N",
                               "Y" if lock_edit else "N"),
                ", ".join(list(set(ptags))),
                prototype.get("prototype_desc", "<unset>"),
            )

        return str(table)
Example #11
0
 def do_work_switches(self):
     """List all the works written by the character"""
     if self.args:
         work = self.get_work(self.args)
         self.msg(str(work.body))
         return
     table = EvTable("|wID|n", "|wTitle|n", width=78)
     qs = self.caller.authored_works.all()
     for work in qs:
         table.add_row(work.id, work.pretty_title)
     self.msg(str(table))
Example #12
0
 def list_all_checks(self):
     checks = self.caller.traits.known_checks
     self.msg("|wAll checks:|n")
     table = EvTable("|wName", "|wCategory", "|wSystem", width=78, border="cells")
     for check in checks:
         table.add_row(
             check.name,
             check.category,
             check.dice_system.display_system_for_character(self.caller),
         )
     self.msg(str(table))
Example #13
0
 def post_inactives(self):
     """Makes a board post of inactive characters"""
     date = datetime.now()
     cutoffdate = date - timedelta(days=30)
     qs = Account.objects.filter(roster__roster__name="Active", last_login__isnull=False).filter(
         last_login__lte=cutoffdate)
     board = BBoard.objects.get(db_key__iexact="staff")
     table = EvTable("{wName{n", "{wLast Login Date{n", border="cells", width=78)
     for ob in qs:
         table.add_row(ob.key.capitalize(), ob.last_login.strftime("%x"))
     board.bb_post(poster_obj=self, msg=str(table), subject="Inactive List", poster_name="Inactives")
     inform_staff("List of Inactive Characters posted.")
Example #14
0
    def page_formatter(self, scripts):
        """Takes a page of scripts and formats the output
        into an EvTable."""

        if not scripts:
            return "<No scripts>"

        table = EvTable(
            "|wdbref|n",
            "|wobj|n",
            "|wkey|n",
            "|wintval|n",
            "|wnext|n",
            "|wrept|n",
            "|wdb",
            "|wtypeclass|n",
            "|wdesc|n",
            align="r",
            border="tablecols",
            width=self.width
        )

        for script in scripts:

            nextrep = script.time_until_next_repeat()
            if nextrep is None:
                nextrep = "PAUSED" if script.db._paused_time else "--"
            else:
                nextrep = "%ss" % nextrep

            maxrepeat = script.repeats
            remaining = script.remaining_repeats() or 0
            if maxrepeat:
                rept = "%i/%i" % (maxrepeat - remaining, maxrepeat)
            else:
                rept = "-/-"

            table.add_row(
                script.id,
                f"{script.obj.key}({script.obj.dbref})"
                if (hasattr(script, "obj") and script.obj)
                else "<Global>",
                script.key,
                script.interval if script.interval > 0 else "--",
                nextrep,
                rept,
                "*" if script.persistent else "-",
                script.typeclass_path.rsplit(".", 1)[-1],
                crop(script.desc, width=20),
            )

        return str(table)
Example #15
0
 def list_crises(self):
     qs = self.viewable_crises
     resolved = "old" in self.switches
     qs = qs.filter(usage=Plot.CRISIS, resolved=resolved)
     table = EvTable("{w#{n", "{wName{n", "{wDesc{n", "{wUpdates On{n", width=78, border="cells")
     for ob in qs:
         date = "--" if not ob.end_date else ob.end_date.strftime("%m/%d")
         table.add_row(ob.id, ob.name, ob.headline, date)
     table.reformat_column(0, width=7)
     table.reformat_column(1, width=20)
     table.reformat_column(2, width=40)
     table.reformat_column(3, width=11)
     self.msg(table)
Example #16
0
 def func(self):
     from evennia import TICKER_HANDLER
     all_subs = TICKER_HANDLER.all_display()
     if not all_subs:
         self.caller.msg("No tickers are currently active.")
         return
     table = EvTable("interval (s)", "object", "path/methodname", "idstring", "db")
     for sub in all_subs:
         table.add_row(sub[3],
                       "%s%s" % (sub[0] or "[None]", sub[0] and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "") or ""),
                       sub[1] if sub[1] else sub[2],
                       sub[4] or "[Unset]",
                       "*" if sub[5] else "-")
     self.caller.msg("|wActive tickers|n:\n" + unicode(table))
Example #17
0
 def list_flashbacks(self):
     from evennia.utils.evtable import EvTable
     roster = self.roster_entry
     flashbacks = roster.flashbacks.all()
     if not flashbacks:
         self.msg("No flashbacks available to list. Why not create one?")
         return
     table = EvTable("ID", "Flashback", "Owner", "New Posts", width=78, border="cells")
     for flashback in flashbacks:
         new_posts = str(flashback.get_new_posts(roster).count())
         color = "|g" if flashback.posts_allowed_by(self.caller) else ""
         fb_id = "%s%s|n" % (color, flashback.id)
         table.add_row(fb_id, flashback.title, flashback.owner, new_posts)
     self.msg(str(table))
Example #18
0
    def func(self):
        """List the accounts"""

        caller = self.caller
        if self.args and self.args.isdigit():
            nlim = int(self.args)
        else:
            nlim = 10

        naccounts = AccountDB.objects.count()

        # typeclass table
        dbtotals = AccountDB.objects.object_totals()
        typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
        for path, count in dbtotals.items():
            typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
        # last N table
        plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim):]
        latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l")
        for ply in plyrs:
            latesttable.add_row(utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path)

        string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
        string += "\n|wLast %s Accounts created:|n\n%s" % (min(naccounts, nlim), latesttable)
        caller.msg(string)
Example #19
0
 def func(self):
     from evennia import TICKER_HANDLER
     all_subs = TICKER_HANDLER.all_display()
     if not all_subs:
         self.caller.msg("No tickers are currently active.")
         return
     table = EvTable("interval (s)", "object", "path/methodname", "idstring", "db")
     for sub in all_subs:
         table.add_row(sub[3],
                       "%s%s" % (sub[0] or "[None]",
                                 sub[0] and " (#%s)" % (sub[0].id if hasattr(sub[0], "id") else "") or ""),
                       sub[1] if sub[1] else sub[2],
                       sub[4] or "[Unset]",
                       "*" if sub[5] else "-")
     self.caller.msg("|wActive tickers|n:\n" + unicode(table))
Example #20
0
    def ldesc(self):
        """Returns a formatted description of the Archetype."""
        desc = "Archetype: |c{archetype}|n\n"
        desc += '~' * (11 + len(self.name)) + '\n'
        desc += self.desc
        desc += '\n\n'
        desc += "|c{archetype}s|n start with the following base primary traits:"
        desc += "\n{traits}\n"
        desc += "  Base |CMovement Points|n:    |w{mv:>2d}|n\n"
        desc += "  |CStamina|n Modifier:        |w{sp_mod:+>2d}|n\n"
        desc += "  |CPower Points|n Modifier:   |w{pp_mod:+>2d}|n\n"
        desc += "  |CReflex Save|n Modifier:    |w{refl_mod:+>2d}|n\n"
        desc += ("  When leveling up, |c{archetype}s|n gain "
                 "|w{health_roll}|C HP|n.\n")

        data = []
        for i in list(range(3)):
            data.append([
                self._format_trait_3col(self.traits[t])
                for t in PRIMARY_TRAITS[i::3]
            ])
        traits = EvTable(header=False, table=data)

        return desc.format(archetype=self.name,
                           traits=traits,
                           health_roll=self.health_roll,
                           mv=self.traits['MV']['base'],
                           sp_mod=self.traits['SP']['mod'],
                           pp_mod=self.traits['PP']['base'],
                           refl_mod=self.traits['REFL']['mod'])
Example #21
0
 def count_poses(self):
     """Makes a board post of characters with insufficient pose-counts"""
     qs = ObjectDB.objects.filter(roster__roster__name="Active")
     min_poses = 20
     low_activity = []
     for ob in qs:
         if (ob.posecount < min_poses and (ob.tags.get("rostercg")and ob.player_ob
                                           and not ob.player_ob.tags.get("staff_alt"))):
             low_activity.append(ob)
         ob.db.previous_posecount = ob.posecount
         ob.posecount = 0
     board = BBoard.objects.get(db_key__iexact="staff")
     table = EvTable("{wName{n", "{wNum Poses{n", border="cells", width=78)
     for ob in low_activity:
         table.add_row(ob.key, ob.db.previous_posecount)
     board.bb_post(poster_obj=self, msg=str(table), subject="Inactive by Poses List")
Example #22
0
    def func(self):
        caller = self.caller
        if self.args:

            target = caller.search(self.args)

            if not target:
                return

            if not target.access(caller, "equip"):
                caller.msg("You cannot equip {}.".format(
                    target.get_display_name(caller)))
                return

            ok = caller.ndb.combat_handler.add_action(action="equip",
                                                      character=self.caller,
                                                      target=target,
                                                      duration=1)

            if ok:
                caller.msg("You add 'equip {}' to the combat queue.".format(
                    target.get_display_name(caller)))
            else:
                caller.msg(
                    "You have already entered all actions for your turn.")

            # tell the handler to check if turn is over
            caller.ndb.combat_handler.check_end_turn()
        else:
            # no arguments; display current equip
            data = []
            s_width = max(len(s) for s in caller.equip.slots)
            for slot, item in caller.equip:
                if not item or not item.access(caller, 'view'):
                    continue
                stat = " "
                if item.attributes.has('damage'):
                    stat += "(|rDamage: {:>2d}|n) ".format(item.db.damage)
                if item.attributes.has('toughness'):
                    stat += "(|yToughness: {:>2d}|n)".format(item.db.toughness)
                if item.attributes.has('range'):
                    stat += "(|G{}|n) ".format(item.db.range.capitalize())

                data.append(
                    "  |b{slot:>{swidth}.{swidth}}|n: {item:<20.20} {stat}".
                    format(
                        slot=slot.capitalize(),
                        swidth=s_width,
                        item=item.name,
                        stat=stat,
                    ))
            if len(data) <= 0:
                output = "You have nothing in your equipment."
            else:
                table = EvTable(header=False, border=None, table=[data])
                output = "|YYour equipment:|n\n{}".format(table)

            caller.msg(output)
Example #23
0
    def view_plots_table(self,
                         old=False,
                         only_open_tickets=False,
                         only_recruiting=False):
        """Returns an EvTable chock full of spicy Plots."""
        from evennia.utils.evtable import EvTable

        qs = (self.filter(resolved=old).exclude(
            Q(usage=self.model.CRISIS)
            | Q(parent_plot__isnull=False)).distinct())
        if only_open_tickets:
            from web.helpdesk.models import Ticket

            qs = qs.filter(tickets__status=Ticket.OPEN_STATUS)
        if only_recruiting:
            from .models import PCPlotInvolvement

            qs = qs.filter(
                Q(dompc_involvement__activity_status=PCPlotInvolvement.ACTIVE)
                & Q(dompc_involvement__admin_status__gte=PCPlotInvolvement.
                    RECRUITER)
                & ~Q(dompc_involvement__recruiter_story="")).distinct()
        alt_header = "Resolved " if old else ""
        table = EvTable(
            "|w#|n",
            "|w%sPlot (owner)|n" % alt_header,
            "|wSummary|n",
            width=78,
            border="cells",
        )
        for plot in qs:

            def get_plot_name_and_owner(plotmato):
                owner = (" (%s)" %
                         plotmato.first_owner) if plotmato.first_owner else ""
                return "%s%s" % (str(plotmato), owner)

            def add_subplots_rows(subplot, color_num):
                sub_name = get_plot_name_and_owner(subplot)
                table.add_row("|%s35%s|n" % (color_num, subplot.id), sub_name,
                              subplot.headline)
                color_num += 1
                if color_num > 5:
                    color_num = 0
                for subplotmato in subplot.subplots.filter(resolved=old):
                    add_subplots_rows(subplotmato, color_num)

            plot_name = get_plot_name_and_owner(plot)
            table.add_row(plot.id, plot_name, plot.headline)
            for subploterino in plot.subplots.filter(resolved=old):
                add_subplots_rows(subploterino, color_num=0)
        table.reformat_column(0, width=7)
        table.reformat_column(1, width=25)
        table.reformat_column(2, width=46)
        return table
Example #24
0
def _list_bots():
    """
    Helper function to produce a list of all IRC bots.

    Returns:
        bots (str): A table of bots or an error message.

    """
    ircbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
    if ircbots:
        from evennia.utils.evtable import EvTable
        table = EvTable("|w#dbref|n", "|wbotname|n", "|wev-channel|n",
                        "|wirc-channel|n", "|wSSL|n", maxwidth=_DEFAULT_WIDTH)
        for ircbot in ircbots:
            ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel, ircbot.db.irc_network, ircbot.db.irc_port)
            table.add_row("#%i" % ircbot.id, ircbot.db.irc_botname, ircbot.db.ev_channel, ircinfo, ircbot.db.irc_ssl)
        return table
    else:
        return "No irc bots found."
Example #25
0
    def func(self):
        if "set" in self.switches:
            try:
                factor = float(self.args)
                gametime.set_time_factor(factor)
                self.msg("IC time now runs at {}:1 scale.".format(factor))
            except ValueError:
                self.msg(
                    "You need to provide a number for the new time factor.")
            return

        elif "history" in self.switches:
            from datetime import datetime
            from evennia.utils.evtable import EvTable

            table = EvTable("Real Time", "Game Date", "Multiplier")
            for tdict in gametime.time_intervals():
                dt = datetime.fromtimestamp(tdict["real"])
                ic_time = gametime._format(
                    tdict["game"],
                    gametime.YEAR,
                    gametime.MONTH,
                    gametime.WEEK,
                    gametime.DAY,
                    gametime.HOUR,
                    gametime.MIN,
                )
                month, day, year = ic_time[1] + 1, ic_time[3] + 1, ic_time[
                    0] + 1001

                real_time = dt.strftime("%m/%d/%Y %H:%M")
                ic_timestamp = "{}/{}/{} {}:{}".format(month, day, year,
                                                       ic_time[4], ic_time[5])

                multiplier = tdict["multiplier"]

                table.add_row(real_time, ic_timestamp, multiplier)

            self.msg(table)
            return

        factor = gametime.time_factor()
        self.msg("IC time is running at {}:1 scale".format(factor))
Example #26
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"))
Example #27
0
def menunode_allocate_traits(caller, raw_string):
    """Discretionary trait point allocation menu node."""
    char = caller.new_char
    text = ""
    raw_string = raw_string.strip()
    if raw_string.isdigit() and int(raw_string) <= len(
            archetypes.PRIMARY_TRAITS):
        chartrait = char.traits[archetypes.PRIMARY_TRAITS[int(raw_string) - 1]]
        if chartrait.actual < 10:
            chartrait.mod += 1
        else:
            text += "|rCannot allocate more than 10 points to one trait!|n\n"

    remaining = archetypes.get_remaining_allocation(char.traits)

    text += "Your character's traits influence combat abilities and skills.\n"
    text += "Type 'help' to see individual trait definitions.\n\n"
    text += "Allocate additional trait points as you choose.\n"
    text += "\n  |w{}|n Points Remaining\n".format(remaining)
    text += "Please select a trait to increase:"

    help = "Traits:\n"
    help += "  Strength - affects melee attacks, fortitude saves, and physical tasks\n"
    help += "  Perception - affects ranged attacks, reflex saves, and perception tasks\n"
    help += "  Intelligence - affects skill bonuses, will saves, and magic\n"
    help += "  Dexterity - affects unarmed attacks, defense, and dexterity-based skills\n"
    help += "  Charisma - affects skills related to interaction with others\n"
    help += "  Vitality - affects health and stamina points"

    options = [{
        "desc": _format_trait_opts(char.traits[t]),
        "goto": "menunode_allocate_traits"
    } for t in archetypes.PRIMARY_TRAITS]
    options.append({
        "desc":
        "Start Over",
        "exec":
        lambda s: archetypes.apply_archetype(
            char, char.db.archetype, reset=True),
        "goto":
        "menunode_allocate_traits"
    })

    if remaining > 0:
        return (text, help), options
    else:
        data = []
        for i in xrange(3):
            data.append([
                _format_trait_opts(char.traits[t])
                for t in archetypes.PRIMARY_TRAITS[i::3]
            ])
        table = EvTable(header=False, table=data)
        return menunode_races(caller, "Final Skills:\n{}".format(table))
Example #28
0
    def list_tasks(self):
        """List the active tasks."""
        obj = self.obj
        callback_name = self.callback_name
        handler = self.handler
        tasks = [(k, v[0], v[1], v[2]) for k, v in handler.db.tasks.items()]
        if obj:
            tasks = [task for task in tasks if task[2] is obj]
        if callback_name:
            tasks = [task for task in tasks if task[3] == callback_name]

        tasks.sort()
        table = EvTable("ID", "Object", "Callback", "In", width=78)
        table.reformat_column(0, align="r")
        now = datetime.now()
        for task_id, future, obj, callback_name in tasks:
            key = obj.get_display_name(self.caller)
            delta = time_format((future - now).total_seconds(), 1)
            table.add_row(task_id, key, callback_name, delta)

        self.msg(unicode(table))
Example #29
0
    def func(self):
        "List the players"

        caller = self.caller
        if self.args and self.args.isdigit():
            nlim = int(self.args)
        else:
            nlim = 10

        nplayers = PlayerDB.objects.count()

        # typeclass table
        dbtotals = PlayerDB.objects.object_totals()
        typetable = EvTable("{wtypeclass{n", "{wcount{n", "{w%%{n", border="cells", align="l")
        for path, count in dbtotals.items():
            typetable.add_row(path, count, "%.2f" % ((float(count) / nplayers) * 100))
        # last N table
        plyrs = PlayerDB.objects.all().order_by("db_date_created")[max(0, nplayers - nlim):]
        latesttable = EvTable("{wcreated{n", "{wdbref{n", "{wname{n", "{wtypeclass{n", border="cells", align="l")
        for ply in plyrs:
            latesttable.add_row(utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path)

        string = "\n{wPlayer typeclass distribution:{n\n%s" % typetable
        string += "\n{wLast %s Players created:{n\n%s" % (min(nplayers, nlim), latesttable)
        caller.msg(string)
Example #30
0
    def func(self):
        """List the accounts"""

        caller = self.caller
        if self.args and self.args.isdigit():
            nlim = int(self.args)
        else:
            nlim = 10

        naccounts = AccountDB.objects.count()

        # typeclass table
        dbtotals = AccountDB.objects.object_totals()
        typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
        for path, count in dbtotals.items():
            typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
        # last N table
        plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim):]
        latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l")
        for ply in plyrs:
            latesttable.add_row(utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path)

        string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
        string += "\n|wLast %s Accounts created:|n\n%s" % (min(naccounts, nlim), latesttable)
        caller.msg(string)
Example #31
0
def _format_item_details(item):
    print(item)
    # The hackiest solution in the world
    # Todo: Evaluate replacing this method
    value = [i for i in item['attrs'] if i[0] == 'value'][0][1]
    weight = [i for i in item['attrs'] if i[0] == 'weight'][0][1]
    """Returns a piece of equipment's details and description."""
    stats = [[
        "          |CPrice|n: {}".format(as_price(value)),
        "         |CWeight|n: |w{}|n".format(weight)
    ], []]
    col1, col2 = stats
    # this is somewhat awkward because we're using prototype dicts instead
    # of instances of these classes.
    if item['typeclass'] in ("typeclasses.weapons.Weapon",
                             "typeclasses.weapons.TwoHandedWeapon",
                             "typeclasses.weapons.RangedWeapon",
                             "typeclasses.weapons.TwoHandedRanged",
                             "typeclasses.armors.Shield"):
        col2.append("     |CHandedness|n: |c{}H|n".format(
            2 if 'TwoHanded' in item['typeclass'] else 1))

    if item['typeclass'] in ("typeclasses.weapons.Weapon",
                             "typeclasses.weapons.TwoHandedWeapon",
                             "typeclasses.weapons.RangedWeapon",
                             "typeclasses.weapons.TwoHandedRanged"):
        col2.append("         |CDamage|n: |r{}|n".format(item['damage']))

    if item['typeclass'] in ("typeclasses.weapons.RangedWeapon",
                             "typeclasses.weapons.TwoHandedRanged"):
        col2.append("          |CRange|n: |G{}|n".format(", ".join(
            [r.capitalize() for r in item['range']])))

    if item['typeclass'] in ("typeclasses.armors.Armor",
                             "typeclasses.armors.Shield"):
        col2.append("      |CToughness|n: |y{}|n".format(item['toughness']))

    if 'quantity' in item:
        col2.append("       |CQuantity|n: |w{}|n".format(item['quantity']))

    table = EvTable(header=False, table=stats, border=None)

    text = "|Y{name}|n\n"
    text += "{desc}\n"
    text += "{stats}\n"
    if 'ammunition' in item:
        text += "  This weapon requires ammunition: |w{ammo}|n\n"

    return text.format(name=item['key'].title(),
                       desc=fill(item['desc']),
                       stats=table,
                       ammo=item.get('ammunition', ''))
Example #32
0
    def pretty_print(self, looker, filter_stats=None, print_stats = True):
        # Get the currently equipped armor/weapons.
        data = []
        s_width = 0;

        table = EvTable("|wLimb|n",
                        "|wSlot|n",
                        "|wItem|n",
                        "|wLevel|n",
                        "|wRarity|n",
                        "|wDurability|n",
                        border = "cells")

# ISSUE 1480 - still under pull request
        if print_stats:
            table.add_column(header="|wStats|n")

        for slot, obj in self:
            wearName = slot

            if obj and not obj.access(looker, "view"):
                continue

            if not obj:
                objString = ""
                objLevel = ""
                objRarity = ""
                objDurability = ""
            else:
                # construct the string for the object.
                objString = "{name}".format(name=obj.name)
                objLevel = obj.get_level()
                objRarity = obj.get_rarity()
                objDurability = "{} %".format(obj.get_durability_percentage())

            if (self.limbs):
                # For limbs, use the named limb instead.
                for limbName, slots in self.limbs.iteritems():
                    if slot in slots: # Check if limb attached to slot
                        wearName = limbName # Set wearname to limb name.

            s_width = max(len(wearName), s_width)

            rowData = [wearName, slot, objString, objLevel, objRarity, objDurability]
            if print_stats and obj is not None:
                rowData.append(obj.pp_stats(looker=self.obj, excludeStats=["level", "rarity", "durability"]))

            table.add_row(*rowData)

#            data.append(
#                "  |b{slot:>{swidth}.{swidth}}|n: {item:<20.20}".format(
#                    slot=wearName.capitalize(),
#                    swidth=s_width,
#                    item=objName,
#                )
#            )

        return str(table)
Example #33
0
def _format_item_details(item, item_attributes):
    """Returns a piece of equipment's details and description."""

    item_typeclass = item['typeclass']
    price_value = as_price(item_attributes.get('value', 0))
    weight = item_attributes.get('weight', 0)

    stats = [[
        f"          |CPrice|n: {price_value}",
        f"         |CWeight|n: |w{weight}|n"],
        []]
    col1, col2 = stats

    # this is somewhat awkward because we're using prototype dicts instead
    # of instances of these classes.
    if item_typeclass in _HANDED_TYPECLASSES:
        handed_str = 2 if 'TwoHanded' in item_typeclass else 1
        col2.append(f"     |CHandedness|n: |c{handed_str}H|n")

    if item_typeclass in _WEAPON_TYPECLASSES:
        damage = item_attributes.get('damage', 0)
        col2.append(f"         |CDamage|n: |r{damage}|n")

    if item_typeclass in _RANGED_TYPECLASSES:
        item_range = item_attributes.get('range', [])
        item_range_str = ", ".join([r.capitalize() for r in item_range])
        col2.append(f"          |CRange|n: |G{item_range_str}|n")

    if item_typeclass in _ARMOR_TYPECLASSES | _SHIELD_TYPECLASSES:
        toughness = item_attributes.get('toughness', 0)
        col2.append(f"      |CToughness|n: |y{toughness}|n")

    quantity = item_attributes.get('quantity')
    if quantity:
        col2.append(f"       |CQuantity|n: |w{quantity}|n")

    stats_table = EvTable(header=False, table=stats, border=None)

    name_title = item['key'].title()
    desc = item_attributes.get('desc', '')
    text = f"|Y{name_title}|n\n" \
           f"{fill(desc)}\n" \
           f"{stats_table}\n"

    ammunition = item_attributes.get('ammunition')
    if ammunition:
        text += f"  This weapon requires ammunition: |w{ammunition}|n\n"

    return text
Example #34
0
 def list_crises(self):
     super(CmdViewCrisis, self).list_crises()
     self.msg("{wYour pending actions:{n")
     table = EvTable("{w#{n", "{wCrisis{n")
     current_actions = [ob for ob in self.current_actions if ob.plot] + [
         ass.plot_action for ass in self.assisted_actions.exclude(
             plot_action__status__in=(PlotAction.PUBLISHED, PlotAction.CANCELLED)) if ass.plot_action.plot]
     for ob in current_actions:
         table.add_row(ob.id, ob.plot)
     self.msg(table)
     past_actions = [ob for ob in self.caller.past_participated_actions if ob.plot]
     if past_actions:
         table = EvTable("{w#{n", "{wCrisis{n")
         self.msg("{wYour past actions:{n")
         for ob in past_actions:
             table.add_row(ob.id, ob.plot)
         self.msg(table)
Example #35
0
    def styled_table(self, *args, **kwargs):
        """
        Create an EvTable styled by on user preferences.

        Args:
            *args (str): Column headers. If not colored explicitly, these will get colors
                from user options.
        Kwargs:
            any (str, int or dict): EvTable options, including, optionally a `table` dict
                detailing the contents of the table.
        Returns:
            table (EvTable): An initialized evtable entity, either complete (if using `table` kwarg)
                or incomplete and ready for use with `.add_row` or `.add_collumn`.

        """
        border_color = self.account.options.get("border_color")
        column_color = self.account.options.get("column_names_color")

        colornames = ["|%s%s|n" % (column_color, col) for col in args]

        h_line_char = kwargs.pop("header_line_char", "~")
        header_line_char = ANSIString(f"|{border_color}{h_line_char}|n")
        c_char = kwargs.pop("corner_char", "+")
        corner_char = ANSIString(f"|{border_color}{c_char}|n")

        b_left_char = kwargs.pop("border_left_char", "||")
        border_left_char = ANSIString(f"|{border_color}{b_left_char}|n")

        b_right_char = kwargs.pop("border_right_char", "||")
        border_right_char = ANSIString(f"|{border_color}{b_right_char}|n")

        b_bottom_char = kwargs.pop("border_bottom_char", "-")
        border_bottom_char = ANSIString(f"|{border_color}{b_bottom_char}|n")

        b_top_char = kwargs.pop("border_top_char", "-")
        border_top_char = ANSIString(f"|{border_color}{b_top_char}|n")

        table = EvTable(
            *colornames,
            header_line_char=header_line_char,
            corner_char=corner_char,
            border_left_char=border_left_char,
            border_right_char=border_right_char,
            border_top_char=border_top_char,
            **kwargs,
        )
        return table
Example #36
0
 def func(self):
     items = [i for i in self.caller.contents if i not in self.caller.equip]
     if not items:
         string = "You are not carrying anything."
     else:
         data = [[], [], []]
         for item in items:
             data[0].append("|C{}|n".format(item.name))
             data[1].append(fill(item.db.desc or "", 50))
             stat = " "
             if item.attributes.has('damage'):
                 stat += "(|rDamage: {:>2d}|n) ".format(item.db.damage)
             if item.attributes.has('range'):
                 stat += "(|GRange: {:>2d}|n) ".format(item.db.range)
             if item.attributes.has('toughness'):
                 stat += "(|yToughness: {:>2d}|n)".format(item.db.toughness)
             data[2].append(stat)
         table = EvTable(header=False, table=data, border=None, valign='t')
         string = "|YYou are carrying:|n\n{}".format(table)
     self.caller.msg(string)
Example #37
0
    def list_callbacks(self):
        """Display the list of callbacks connected to the object."""
        obj = self.obj
        callback_name = self.callback_name
        parameters = self.parameters
        callbacks = self.handler.get_callbacks(obj)
        types = self.handler.get_events(obj)

        if callback_name:
            # Check that the callback name can be found in this object
            created = callbacks.get(callback_name)
            if created is None:
                self.msg("No callback {} has been set on {}.".format(callback_name,
                                                                     obj))
                return

            if parameters:
                # Check that the parameter points to an existing callback
                try:
                    number = int(parameters) - 1
                    assert number >= 0
                    callback = callbacks[callback_name][number]
                except (ValueError, AssertionError, IndexError):
                    self.msg("The callback {} {} cannot be found in {}.".format(
                        callback_name, parameters, obj))
                    return

                # Display the callback's details
                author = callback.get("author")
                author = author.key if author else "|gUnknown|n"
                updated_by = callback.get("updated_by")
                updated_by = updated_by.key if updated_by else "|gUnknown|n"
                created_on = callback.get("created_on")
                created_on = created_on.strftime("%Y-%m-%d %H:%M:%S") if created_on else "|gUnknown|n"
                updated_on = callback.get("updated_on")
                updated_on = updated_on.strftime("%Y-%m-%d %H:%M:%S") if updated_on else "|gUnknown|n"
                msg = "Callback {} {} of {}:".format(callback_name, parameters, obj)
                msg += "\nCreated by {} on {}.".format(author, created_on)
                msg += "\nUpdated by {} on {}".format(updated_by, updated_on)

                if self.is_validator:
                    if callback.get("valid"):
                        msg += "\nThis callback is |rconnected|n and active."
                    else:
                        msg += "\nThis callback |rhasn't been|n accepted yet."

                msg += "\nCallback code:\n"
                msg += raw(callback["code"])
                self.msg(msg)
                return

            # No parameter has been specified, display the table of callbacks
            cols = ["Number", "Author", "Updated", "Param"]
            if self.is_validator:
                cols.append("Valid")

            table = EvTable(*cols, width=78)
            table.reformat_column(0, align="r")
            now = datetime.now()
            for i, callback in enumerate(created):
                author = callback.get("author")
                author = author.key if author else "|gUnknown|n"
                updated_on = callback.get("updated_on")
                if updated_on is None:
                    updated_on = callback.get("created_on")

                if updated_on:
                    updated_on = "{} ago".format(time_format(
                        (now - updated_on).total_seconds(),
                        4).capitalize())
                else:
                    updated_on = "|gUnknown|n"
                parameters = callback.get("parameters", "")

                row = [str(i + 1), author, updated_on, parameters]
                if self.is_validator:
                    row.append("Yes" if callback.get("valid") else "No")
                table.add_row(*row)

            self.msg(unicode(table))
        else:
            names = list(set(list(types.keys()) + list(callbacks.keys())))
            table = EvTable("Callback name", "Number", "Description",
                            valign="t", width=78)
            table.reformat_column(0, width=20)
            table.reformat_column(1, width=10, align="r")
            table.reformat_column(2, width=48)
            for name in sorted(names):
                number = len(callbacks.get(name, []))
                lines = sum(len(e["code"].splitlines()) for e in callbacks.get(name, []))
                no = "{} ({})".format(number, lines)
                description = types.get(name, (None, "Chained event."))[1]
                description = description.strip("\n").splitlines()[0]
                table.add_row(name, no, description)

            self.msg(unicode(table))
Example #38
0
    def accept_callback(self):
        """Accept a callback."""
        obj = self.obj
        callback_name = self.callback_name
        parameters = self.parameters

        # If no object, display the list of callbacks to be checked
        if obj is None:
            table = EvTable("ID", "Type", "Object", "Name", "Updated by",
                            "On", width=78)
            table.reformat_column(0, align="r")
            now = datetime.now()
            for obj, name, number in self.handler.db.to_valid:
                callbacks = self.handler.get_callbacks(obj).get(name)
                if callbacks is None:
                    continue

                try:
                    callback = callbacks[number]
                except IndexError:
                    continue

                type_name = obj.typeclass_path.split(".")[-1]
                by = callback.get("updated_by")
                by = by.key if by else "|gUnknown|n"
                updated_on = callback.get("updated_on")
                if updated_on is None:
                    updated_on = callback.get("created_on")

                if updated_on:
                    updated_on = "{} ago".format(time_format(
                        (now - updated_on).total_seconds(),
                        4).capitalize())
                else:
                    updated_on = "|gUnknown|n"

                table.add_row(obj.id, type_name, obj, name, by, updated_on)
            self.msg(unicode(table))
            return

        # An object was specified
        callbacks = self.handler.get_callbacks(obj)
        types = self.handler.get_events(obj)

        # If no callback name is specified, display the list of callbacks
        if not callback_name:
            self.list_callbacks()
            return

        # Check that the callback exists
        if callback_name not in callbacks:
            self.msg("The callback name {} can't be found in {}.".format(
                callback_name, obj))
            return

        if not parameters:
            self.msg("Which callback do you wish to accept?  Specify a number.")
            self.list_callbacks()
            return

        # Check that the parameter points to an existing callback
        try:
            number = int(parameters) - 1
            assert number >= 0
            callback = callbacks[callback_name][number]
        except (ValueError, AssertionError, IndexError):
            self.msg("The callback {} {} cannot be found in {}.".format(
                callback_name, parameters, obj))
            return

        # Accept the callback
        if callback["valid"]:
            self.msg("This callback has already been accepted.")
        else:
            self.handler.accept_callback(obj, callback_name, number)
            self.msg("The callback {} {} of {} has been accepted.".format(
                callback_name, parameters, obj))
Example #39
0
def list_prototypes(caller, key=None, tags=None, show_non_use=False, show_non_edit=True):
    """
    Collate a list of found prototypes based on search criteria and access.

    Args:
        caller (Account or Object): The object requesting the list.
        key (str, optional): Exact or partial prototype key to query for.
        tags (str or list, optional): Tag key or keys to query for.
        show_non_use (bool, optional): Show also prototypes the caller may not use.
        show_non_edit (bool, optional): Show also prototypes the caller may not edit.
    Returns:
        table (EvTable or None): An EvTable representation of the prototypes. None
            if no prototypes were found.

    """
    # this allows us to pass lists of empty strings
    tags = [tag for tag in make_iter(tags) if tag]

    # get prototypes for readonly and db-based prototypes
    prototypes = search_prototype(key, tags)

    # get use-permissions of readonly attributes (edit is always False)
    display_tuples = []
    for prototype in sorted(prototypes, key=lambda d: d.get('prototype_key', '')):
        lock_use = caller.locks.check_lockstring(
            caller, prototype.get('prototype_locks', ''), access_type='spawn', default=True)
        if not show_non_use and not lock_use:
            continue
        if prototype.get('prototype_key', '') in _MODULE_PROTOTYPES:
            lock_edit = False
        else:
            lock_edit = caller.locks.check_lockstring(
                caller, prototype.get('prototype_locks', ''), access_type='edit', default=True)
        if not show_non_edit and not lock_edit:
            continue
        ptags = []
        for ptag in prototype.get('prototype_tags', []):
            if is_iter(ptag):
                if len(ptag) > 1:
                    ptags.append("{} (category: {}".format(ptag[0], ptag[1]))
                else:
                    ptags.append(ptag[0])
            else:
                ptags.append(str(ptag))

        display_tuples.append(
            (prototype.get('prototype_key', '<unset>'),
             prototype.get('prototype_desc', '<unset>'),
             "{}/{}".format('Y' if lock_use else 'N', 'Y' if lock_edit else 'N'),
             ",".join(ptags)))

    if not display_tuples:
        return ""

    table = []
    width = 78
    for i in range(len(display_tuples[0])):
        table.append([str(display_tuple[i]) for display_tuple in display_tuples])
    table = EvTable("Key", "Desc", "Spawn/Edit", "Tags", table=table, crop=True, width=width)
    table.reformat_column(0, width=22)
    table.reformat_column(1, width=29)
    table.reformat_column(2, width=11, align='c')
    table.reformat_column(3, width=16)
    return table
Example #40
0
 def func(self):
     """Show server time data in a table."""
     table1 = EvTable("|wServer time", "", align="l", width=78)
     table1.add_row("Current uptime", utils.time_format(gametime.uptime(), 3))
     table1.add_row("Total runtime", utils.time_format(gametime.runtime(), 2))
     table1.add_row("First start", datetime.datetime.fromtimestamp(gametime.server_epoch()))
     table1.add_row("Current time", datetime.datetime.now())
     table1.reformat_column(0, width=30)
     table2 = EvTable("|wIn-Game time", "|wReal time x %g" % gametime.TIMEFACTOR, align="l", width=77, border_top=0)
     epochtxt = "Epoch (%s)" % ("from settings" if settings.TIME_GAME_EPOCH else "server start")
     table2.add_row(epochtxt, datetime.datetime.fromtimestamp(gametime.game_epoch()))
     table2.add_row("Total time passed:", utils.time_format(gametime.gametime(), 2))
     table2.add_row("Current time ", datetime.datetime.fromtimestamp(gametime.gametime(absolute=True)))
     table2.reformat_column(0, width=30)
     self.caller.msg(unicode(table1) + "\n" + unicode(table2))
Example #41
0
    def func(self):
        """Show list."""

        global _IDMAPPER
        if not _IDMAPPER:
            from evennia.utils.idmapper import models as _IDMAPPER

        if "flushmem" in self.switches:
            # flush the cache
            prev, _ = _IDMAPPER.cache_size()
            nflushed = _IDMAPPER.flush_cache()
            now, _ = _IDMAPPER.cache_size()
            string = "The Idmapper cache freed |w{idmapper}|n database objects.\n" \
                     "The Python garbage collector freed |w{gc}|n Python instances total."
            self.caller.msg(string.format(idmapper=(prev - now), gc=nflushed))
            return

        # display active processes

        os_windows = os.name == "nt"
        pid = os.getpid()

        if os_windows:
            # Windows requires the psutil module to even get paltry
            # statistics like this (it's pretty much worthless,
            # unfortunately, since it's not specific to the process) /rant
            try:
                import psutil
                has_psutil = True
            except ImportError:
                has_psutil = False

            if has_psutil:
                loadavg = psutil.cpu_percent()
                _mem = psutil.virtual_memory()
                rmem = _mem.used / (1000.0 * 1000)
                pmem = _mem.percent

                if "mem" in self.switches:
                    string = "Total computer memory usage: |w%g|n MB (%g%%)"
                    self.caller.msg(string % (rmem, pmem))
                    return
                # Display table
                loadtable = EvTable("property", "statistic", align="l")
                loadtable.add_row("Total CPU load", "%g %%" % loadavg)
                loadtable.add_row("Total computer memory usage", "%g MB (%g%%)" % (rmem, pmem))
                loadtable.add_row("Process ID", "%g" % pid),
            else:
                loadtable = "Not available on Windows without 'psutil' library " \
                            "(install with |wpip install psutil|n)."

        else:
            # Linux / BSD (OSX) - proper pid-based statistics

            global _RESOURCE
            if not _RESOURCE:
                import resource as _RESOURCE

            loadavg = os.getloadavg()[0]
            rmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "rss")).read()) / 1000.0  # resident memory
            vmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "vsz")).read()) / 1000.0  # virtual memory
            pmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "%mem")).read())  # % of resident memory to total
            rusage = _RESOURCE.getrusage(_RESOURCE.RUSAGE_SELF)

            if "mem" in self.switches:
                string = "Memory usage: RMEM: |w%g|n MB (%g%%), VMEM (res+swap+cache): |w%g|n MB."
                self.caller.msg(string % (rmem, pmem, vmem))
                return

            loadtable = EvTable("property", "statistic", align="l")
            loadtable.add_row("Server load (1 min)", "%g" % loadavg)
            loadtable.add_row("Process ID", "%g" % pid),
            loadtable.add_row("Memory usage", "%g MB (%g%%)" % (rmem, pmem))
            loadtable.add_row("Virtual address space", "")
            loadtable.add_row("|x(resident+swap+caching)|n", "%g MB" % vmem)
            loadtable.add_row("CPU time used (total)", "%s (%gs)"
                              % (utils.time_format(rusage.ru_utime), rusage.ru_utime))
            loadtable.add_row("CPU time used (user)", "%s (%gs)"
                              % (utils.time_format(rusage.ru_stime), rusage.ru_stime))
            loadtable.add_row("Page faults", "%g hard,  %g soft, %g swapouts"
                              % (rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap))
            loadtable.add_row("Disk I/O", "%g reads, %g writes" % (rusage.ru_inblock, rusage.ru_oublock))
            loadtable.add_row("Network I/O", "%g in, %g out" % (rusage.ru_msgrcv, rusage.ru_msgsnd))
            loadtable.add_row("Context switching", "%g vol, %g forced, %g signals"
                              % (rusage.ru_nvcsw, rusage.ru_nivcsw, rusage.ru_nsignals))

        # os-generic

        string = "|wServer CPU and Memory load:|n\n%s" % loadtable

        # object cache count (note that sys.getsiseof is not called so this works for pypy too.
        total_num, cachedict = _IDMAPPER.cache_size()
        sorted_cache = sorted([(key, num) for key, num in cachedict.items() if num > 0],
                              key=lambda tup: tup[1], reverse=True)
        memtable = EvTable("entity name", "number", "idmapper %", align="l")
        for tup in sorted_cache:
            memtable.add_row(tup[0], "%i" % tup[1], "%.2f" % (float(tup[1]) / total_num * 100))

        string += "\n|w Entity idmapper cache:|n %i items\n%s" % (total_num, memtable)

        # return to caller
        self.caller.msg(string)
Example #42
0
    def func(self):
        """Implement command"""

        caller = self.caller
        switches = self.switches

        if switches and switches[0] not in ("list", "start", "stop", "delete"):
            caller.msg("Usage: @service/<list|start|stop|delete> [servicename]")
            return

        # get all services
        service_collection = SESSIONS.server.services

        if not switches or switches[0] == "list":
            # Just display the list of installed services and their
            # status, then exit.
            table = EvTable("|wService|n (use @services/start|stop|delete)", "|wstatus", align="l")
            for service in service_collection.services:
                table.add_row(service.name, service.running and "|gRunning" or "|rNot Running")
            caller.msg(unicode(table))
            return

        # Get the service to start / stop

        try:
            service = service_collection.getServiceNamed(self.args)
        except Exception:
            string = 'Invalid service name. This command is case-sensitive. '
            string += 'See @service/list for valid service name (enter the full name exactly).'
            caller.msg(string)
            return

        if switches[0] in ("stop", "delete"):
            # Stopping/killing a service gracefully closes it and disconnects
            # any connections (if applicable).

            delmode = switches[0] == "delete"
            if not service.running:
                caller.msg('That service is not currently running.')
                return
            if service.name[:7] == 'Evennia':
                if delmode:
                    caller.msg("You cannot remove a core Evennia service (named 'Evennia***').")
                    return
                string = "You seem to be shutting down a core Evennia service (named 'Evennia***'). Note that"
                string += "stopping some TCP port services will *not* disconnect users *already*"
                string += "connected on those ports, but *may* instead cause spurious errors for them. To "
                string += "safely and permanently remove ports, change settings file and restart the server."
                caller.msg(string)

            if delmode:
                service.stopService()
                service_collection.removeService(service)
                caller.msg("Stopped and removed service '%s'." % self.args)
            else:
                service.stopService()
                caller.msg("Stopped service '%s'." % self.args)
            return

        if switches[0] == "start":
            # Attempt to start a service.
            if service.running:
                caller.msg('That service is already running.')
                return
            caller.msg("Starting service '%s'." % self.args)
            service.startService()
Example #43
0
    def func(self):
        "Setup the irc-channel mapping"

        if not settings.IRC_ENABLED:
            string = """IRC is not enabled. You need to activate it in game/settings.py."""
            self.msg(string)
            return

        if 'list' in self.switches:
            # show all connections
            ircbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
            if ircbots:
                from evennia.utils.evtable import EvTable
                table = EvTable("{wdbid{n", "{wbotname{n", "{wev-channel{n", "{wirc-channel{n", "{wSSL{n", maxwidth=_DEFAULT_WIDTH)
                for ircbot in ircbots:
                    ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel, ircbot.db.irc_network, ircbot.db.irc_port)
                    table.add_row(ircbot.id, ircbot.db.irc_botname, ircbot.db.ev_channel, ircinfo, ircbot.db.irc_ssl)
                self.caller.msg(table)
            else:
                self.msg("No irc bots found.")
            return


        if('disconnect' in self.switches or 'remove' in self.switches or
                                                    'delete' in self.switches):
            botname = "ircbot-%s" % self.lhs
            matches = PlayerDB.objects.filter(db_is_bot=True, username=botname)
            dbref = utils.dbref(self.lhs)
            if not matches and dbref:
                # try dbref match
                matches = PlayerDB.objects.filter(db_is_bot=True, id=dbref)
            if matches:
                matches[0].delete()
                self.msg("IRC connection destroyed.")
            else:
                self.msg("IRC connection/bot could not be removed, does it exist?")
            return

        if not self.args or not self.rhs:
            string = "Usage: @irc2chan[/switches] <evennia_channel> = <ircnetwork> <port> <#irchannel> <botname>"
            self.msg(string)
            return

        channel = self.lhs
        self.rhs = self.rhs.replace('#', ' ') # to avoid Python comment issues
        try:
            irc_network, irc_port, irc_channel, irc_botname = \
                       [part.strip() for part in self.rhs.split(None, 3)]
            irc_channel = "#%s" % irc_channel
        except Exception:
            string = "IRC bot definition '%s' is not valid." % self.rhs
            self.msg(string)
            return

        botname = "ircbot-%s" % irc_botname
        irc_ssl = "ssl" in self.switches

        # create a new bot
        bot = PlayerDB.objects.filter(username__iexact=botname)
        if bot:
            # re-use an existing bot
            bot = bot[0]
            if not bot.is_bot:
                self.msg("Player '%s' already exists and is not a bot." % botname)
                return
        else:
            bot = create.create_player(botname, None, None, typeclass=bots.IRCBot)
        bot.start(ev_channel=channel, irc_botname=irc_botname, irc_channel=irc_channel,
                  irc_network=irc_network, irc_port=irc_port, irc_ssl=irc_ssl)
        self.msg("Connection created. Starting IRC bot.")
Example #44
0
    def func(self):
        """Implement the command"""

        caller = self.caller
        nlim = int(self.args) if self.args and self.args.isdigit() else 10
        nobjs = ObjectDB.objects.count()
        base_char_typeclass = settings.BASE_CHARACTER_TYPECLASS
        nchars = ObjectDB.objects.filter(db_typeclass_path=base_char_typeclass).count()
        nrooms = ObjectDB.objects.filter(db_location__isnull=True).exclude(
            db_typeclass_path=base_char_typeclass).count()
        nexits = ObjectDB.objects.filter(db_location__isnull=False, db_destination__isnull=False).count()
        nother = nobjs - nchars - nrooms - nexits
        nobjs = nobjs or 1  # fix zero-div error with empty database

        # total object sum table
        totaltable = EvTable("|wtype|n", "|wcomment|n", "|wcount|n", "|w%%|n", border="table", align="l")
        totaltable.align = 'l'
        totaltable.add_row("Characters", "(BASE_CHARACTER_TYPECLASS)", nchars, "%.2f" % ((float(nchars) / nobjs) * 100))
        totaltable.add_row("Rooms", "(location=None)", nrooms, "%.2f" % ((float(nrooms) / nobjs) * 100))
        totaltable.add_row("Exits", "(destination!=None)", nexits, "%.2f" % ((float(nexits) / nobjs) * 100))
        totaltable.add_row("Other", "", nother, "%.2f" % ((float(nother) / nobjs) * 100))

        # typeclass table
        typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="table", align="l")
        typetable.align = 'l'
        dbtotals = ObjectDB.objects.object_totals()
        for path, count in dbtotals.items():
            typetable.add_row(path, count, "%.2f" % ((float(count) / nobjs) * 100))

        # last N table
        objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim):]
        latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", align="l", border="table")
        latesttable.align = 'l'
        for obj in objs:
            latesttable.add_row(utils.datetime_format(obj.date_created),
                                obj.dbref, obj.key, obj.path)

        string = "\n|wObject subtype totals (out of %i Objects):|n\n%s" % (nobjs, totaltable)
        string += "\n|wObject typeclass distribution:|n\n%s" % typetable
        string += "\n|wLast %s Objects created:|n\n%s" % (min(nobjs, nlim), latesttable)
        caller.msg(string)
Example #45
0
    def func(self):
        "Setup the rss-channel mapping"

        # checking we have all we need
        if not settings.RSS_ENABLED:
            string = """RSS is not enabled. You need to activate it in game/settings.py."""
            self.msg(string)
            return
        try:
            import feedparser
            feedparser   # to avoid checker error of not being used
        except ImportError:
            string = ("RSS requires python-feedparser (https://pypi.python.org/pypi/feedparser). "
                      "Install before continuing.")
            self.msg(string)
            return

        if 'list' in self.switches:
            # show all connections
            rssbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")]
            if rssbots:
                from evennia.utils.evtable import EvTable
                table = EvTable("{wdbid{n", "{wupdate rate{n", "{wev-channel",
                                "{wRSS feed URL{n", border="cells", maxwidth=_DEFAULT_WIDTH)
                for rssbot in rssbots:
                    table.add_row(rssbot.id, rssbot.db.rss_rate, rssbot.db.ev_channel, rssbot.db.rss_url)
                self.caller.msg(table)
            else:
                self.msg("No rss bots found.")
            return

        if('disconnect' in self.switches or 'remove' in self.switches or
                                                    'delete' in self.switches):
            botname = "rssbot-%s" % self.lhs
            matches = PlayerDB.objects.filter(db_is_bot=True, db_key=botname)
            if not matches:
                # try dbref match
                matches = PlayerDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#"))
            if matches:
                matches[0].delete()
                self.msg("RSS connection destroyed.")
            else:
                self.msg("RSS connection/bot could not be removed, does it exist?")
            return

        if not self.args or not self.rhs:
            string = "Usage: @rss2chan[/switches] <evennia_channel> = <rss url>"
            self.msg(string)
            return
        channel = self.lhs
        url = self.rhs

        botname = "rssbot-%s" % url
        # create a new bot
        bot = PlayerDB.objects.filter(username__iexact=botname)
        if bot:
            # re-use existing bot
            bot = bot[0]
            if not bot.is_bot:
                self.msg("Player '%s' already exists and is not a bot." % botname)
                return
        else:
            bot = create.create_player(botname, None, None, typeclass=bots.RSSBot)
        bot.start(ev_channel=channel, rss_url=url, rss_rate=10)
        self.msg("RSS reporter created. Fetching RSS.")
Example #46
0
    def func(self):
        """Show server time data in a table."""
        lat, lon, ele = 33.43, -112.07, 24
        here = self.character.location
        if here:
            x = float(here.tags.get(category="coordx", default=0))
            y = float(here.tags.get(category="coordy", default=0))
            # z = here.tags.get(category="coordz")
            if x and y:
                lat, lon = float(y/10000), float(x/10000)
                print('Using location coordinates: {}, {}'.format(lat, lon))

        place = Astral.Location(info=('', '', lat, lon, 'UTC', ele))
        place.solar_depression = 'civil'

        def time_dif(at, when):
            diff = abs(at - when)
            return 'now' if diff.total_seconds < 60 else (utils.time_format(diff.total_seconds(), 2) +
                                                          (' ago' if at > when else ''))

        def moon_phase(days):
            """
            Summarize the visible portion, given days into cycle
            Args:
                days (int or float): days into current cycle
            Returns:
                phase (str): summary of view of visible portion
            """
            phases = ('new', 'waxing crescent', 'First quarter', 'waxing gibbous',
                      'full', 'waning gibbous', 'last quarter', 'waning crescent')
            percent = float((float(days) + 0.5) / 29.53)
            phase = int((percent - int(percent)) * len(phases))
            return phases[phase]
        try:
            sun = place.sun(date=datetime.date.today(), local=True)
        except Exception:
            return
        else:
            past = here.tags.get('past', category='realm')
            moon = place.moon_phase(date=datetime.date.today())
            now = timezone.now()
            moment = ['dawn', 'sunrise', 'noon', 'sunset', 'dusk']
            events = zip([each.capitalize() + ':' for each in moment], [time_dif(now, sun[each]) for each in moment])
            table1 = EvTable("|wServer", '|wtime', align='l', width=75)
            table1.add_row('Current uptime', utils.time_format(gametime.uptime(), 3))
            table1.add_row('First start', time_dif(datetime.datetime.now(),
                                                   datetime.datetime.fromtimestamp(gametime.server_epoch())))
            if here.tags.get('past', category='realm'):
                table1.add_row('Moon phase', moon_phase(moon))
            table1.reformat_column(0, width=20)
            if past:
                table2 = EvTable("|wEvent", "|wTime until", align="l", width=75)
                for entry in events:
                    table2.add_row(entry[0], entry[1])
                table2.reformat_column(0, width=20)
            if self.cmdstring == 'uptime':
                self.msg('Current uptime: ' + utils.time_format(gametime.uptime(), 3))
            else:
                self.msg(unicode(table1))
            if past:
                if self.cmdstring == 'events':
                    self.msg(unicode(table2))
                else:
                    self.msg("\n" + unicode(table2))