Exemple #1
0
 def func(self):
     """returns the list of online characters"""
     count_accounts = (SESSIONS.account_count())
     self.caller.msg("[%s] Through the fog you see:" % self.key)
     session_list = SESSIONS.get_sessions()
     table = evtable.EvTable(border='none')
     table.add_row('Character', 'On for', 'Idle',  'Location')
     for session in session_list:
         if not session.logged_in:
             continue
         delta_cmd = time.time() - session.cmd_last_visible
         delta_conn = time.time() - session.conn_time
         puppet = session.get_puppet()
         location = puppet.location.key if puppet and puppet.location else 'Nothingness'
         table.add_row(puppet.key if puppet else 'None', utils.time_format(delta_conn, 0),
                       utils.time_format(delta_cmd, 1), location)
     table.reformat_column(0, width=25, align='l')
     table.reformat_column(1, width=12, align='l')
     table.reformat_column(2, width=7, align='l')
     table.reformat_column(3, width=25, align='l')
     is_one = count_accounts == 1
     string = '%s' % 'A' if is_one else str(count_accounts)
     string += ' single ' if is_one else ' unique '
     plural = ' is' if is_one else 's are'
     string += 'account%s logged in.' % plural
     self.caller.msg(table)
     self.caller.msg(string)
Exemple #2
0
    def func(self):
        """
        Get all connected players by polling session.
        """

        player = self.player
        session_list = SESSIONS.get_sessions()

        session_list = sorted(session_list, key=lambda o: o.player.key)

        if self.cmdstring == "doing":
            show_session_data = False
        else:
            show_session_data = player.check_permstring(
                "Immortals") or player.check_permstring("Wizards")

        nplayers = (SESSIONS.player_count())
        if show_session_data:
            # privileged info
            table = prettytable.PrettyTable([
                "{wPlayer Name", "{wOn for", "{wIdle", "{wPuppeting", "{wRoom",
                "{wCmds", "{wProtocol", "{wHost"
            ])
            for session in session_list:
                if not session.logged_in: continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                player = session.get_player()
                puppet = session.get_puppet()
                location = puppet.location.key if puppet else "None"
                table.add_row([
                    utils.crop(player.name, width=25),
                    utils.time_format(delta_conn, 0),
                    utils.time_format(delta_cmd, 1),
                    utils.crop(puppet.key if puppet else "None", width=25),
                    utils.crop(location, width=25), session.cmd_total,
                    session.protocol_key,
                    isinstance(session.address, tuple) and session.address[0]
                    or session.address
                ])
        else:
            # unprivileged
            table = prettytable.PrettyTable(
                ["{wPlayer name", "{wOn for", "{wIdle"])
            for session in session_list:
                if not session.logged_in:
                    continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                player = session.get_player()
                table.add_row([
                    utils.crop(player.key, width=25),
                    utils.time_format(delta_conn, 0),
                    utils.time_format(delta_cmd, 1)
                ])

        isone = nplayers == 1
        string = "{wPlayers:{n\n%s\n%s unique account%s logged in." % (
            table, "One" if isone else nplayers, "" if isone else "s")
        self.msg(string)
Exemple #3
0
 def func(self):
     """hook function"""
     account = self.account
     bye = '|RDisconnecting|n'
     exit_msg = 'Hope to see you again, soon! A survey is available at https://goo.gl/forms/yCyLpF6JsAhhUgGz2 for your thoughts'
     reason = self.args.strip() if self.args else 'Quitting'
     if reason:
         bye += " ( |w%s|n ) " % reason
     if 'all' in self.switches:
         for session in account.sessions.all():
             session_online_time = utils.time_format(time.time() - session.conn_time, 1)
             msg = bye + ' all sessions after ' + session_online_time + ' online. '
             account.msg(msg, session=session)
             account.msg(exit_msg, session=session)
             account.disconnect_session_from_account(session, reason=reason)
     else:
         session_count = len(account.sessions.all())
         online = utils.time_format(time.time() - self.session.conn_time, 1)
         if session_count == 2:
             msg = bye
             others = [x for x in self.account.sessions.get() if x is not self.session]
             account.msg(msg + 'after ' + online + ' online.', session=self.session)
             account.msg(msg + 'your other session. |gThis session remains connected.|n', session=others)
         elif session_count > 2:
             msg = bye + "%i sessions are still connected."
             account.msg(msg % (session_count - 1))
         else:
             # If quitting the last available session, give connect time.
             msg = bye + 'after ' + online + ' online. '
             account.msg(msg, session=self.session)
         account.msg(exit_msg, session=self.session)
         account.disconnect_session_from_account(self.session, reason=reason)
Exemple #4
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))
Exemple #5
0
 def func(self):
     """returns the list of online characters"""
     count_accounts = (SESSIONS.account_count())
     self.caller.msg('[%s] Through the fog you see:' % self.key)
     session_list = SESSIONS.get_sessions()
     table = evtable.EvTable(border='none')
     table.add_row('Character', 'On for', 'Idle',  'Location')
     for session in session_list:
         puppet = session.get_puppet()
         if not session.logged_in or not puppet:
             continue
         delta_cmd = time.time() - session.cmd_last_visible
         delta_conn = time.time() - session.conn_time
         location = puppet.location.key if puppet and puppet.location else 'Nothingness'
         table.add_row(puppet.key if puppet else 'None', utils.time_format(delta_conn, 0),
                       utils.time_format(delta_cmd, 1), location)
     table.reformat_column(0, width=25, align='l')
     table.reformat_column(1, width=12, align='l')
     table.reformat_column(2, width=7, align='l')
     table.reformat_column(3, width=25, align='l')
     is_one = count_accounts == 1
     string = '%s' % 'A' if is_one else str(count_accounts)
     string += ' single ' if is_one else ' unique '
     plural = ' is' if is_one else 's are'
     string += 'account%s logged in.' % plural
     self.caller.msg(table)
     self.caller.msg(string)
Exemple #6
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.LocationInfo(timezone='UTC', latitude=lat, longitude=lon)
        obsr = astral.Observer(latitude=lat, longitude=lon, elevation=ele)


        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 = astral.sun.sun(date=datetime.date.today(), observer=obsr)
        except Exception as e:
            return
        else:
            past = here.tags.get('past', category='realm')
            moon = astral.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)
            up = self.cmdstring == 'uptime'  # User asking for uptime mode
            self.msg(('Current uptime: ' + utils.time_format(gametime.uptime(), 3)) if up else str(table1))
            if past:  # Astral events are to be displayed while in past realm
                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)
                self.msg(str(table2) if self.cmdstring == 'events' else ('\n' + str(table2)))
Exemple #7
0
 def func(self):
     "Show server time data in a table."
     table = prettytable.PrettyTable(["{wserver time statistic","{wtime"])
     table.align = 'l'
     table.add_row(["Current server uptime", utils.time_format(gametime.uptime(), 3)])
     table.add_row(["Total server running time", utils.time_format(gametime.runtime(), 2)])
     table.add_row(["Total in-game time (realtime x %g)" % (gametime.TIMEFACTOR), utils.time_format(gametime.gametime(), 2)])
     table.add_row(["Server time stamp", datetime.datetime.now()])
     self.caller.msg(str(table))
Exemple #8
0
    def func(self):
        """
        Get all connected players by polling session.
        """

        player = self.player
        session_list = SESSIONS.get_sessions()

        session_list = sorted(session_list, key=lambda o: o.player.key)

        if self.cmdstring == "doing":
            show_session_data = False
        else:
            show_session_data = player.check_permstring("Immortals") or player.check_permstring("Wizards")

        nplayers = (SESSIONS.player_count())
        if show_session_data:
            # privileged info
            table = prettytable.PrettyTable(["{wИмя игрока",
                                             "{wВ игре",
                                             "{wIdle",
                                             "{wУправляет",
                                             "{wКомната",
                                             "{wCmds",
                                             "{wПротокол",
                                             "{wХост"])
            for session in session_list:
                if not session.logged_in: continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                player = session.get_player()
                puppet = session.get_puppet()
                location = puppet.location.key if puppet and puppet.location else "None"
                table.add_row([utils.crop(player.name, width=25),
                               utils.time_format(delta_conn, 0),
                               utils.time_format(delta_cmd, 1),
                               utils.crop(puppet.key if puppet else "None", width=25),
                               utils.crop(location, width=25),
                               session.cmd_total,
                               session.protocol_key,
                               isinstance(session.address, tuple) and session.address[0] or session.address])
        else:
            # unprivileged
            table = prettytable.PrettyTable(["{wИмя игрока", "{wВ игре", "{wIdle"])
            for session in session_list:
                if not session.logged_in:
                    continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                player = session.get_player()
                table.add_row([utils.crop(player.key, width=25),
                               utils.time_format(delta_conn, 0),
                               utils.time_format(delta_cmd, 1)])

        isone = nplayers == 1
        string = "{wИгроков:{n\n%s\n%s уникальных аккаунтов%s залогинено." % (table, "Один" if isone else nplayers, "" if isone else "")
        self.msg(string)
Exemple #9
0
    def func(self):
        """
        Get all connected players by polling session.
        """

        player = self.player
        session_list = SESSIONS.get_sessions()

        session_list = sorted(session_list, key=lambda o: o.player.key)

        if self.cmdstring == "doing":
            show_session_data = False
        else:
            show_session_data = player.check_permstring("Immortals") or player.check_permstring("Wizards")

        nplayers = (SESSIONS.player_count())
        if show_session_data:
            # privileged info
            table = prettytable.PrettyTable(["{wPlayer Name",
                                             "{wOn for",
                                             "{wIdle",
                                             "{wPuppeting",
                                             "{wRoom",
                                             "{wCmds",
                                             "{wProtocol",
                                             "{wHost"])
            for session in session_list:
                if not session.logged_in: continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                player = session.get_player()
                puppet = session.get_puppet()
                location = puppet.location.key if puppet else "None"
                table.add_row([utils.crop(player.name, width=25),
                               utils.time_format(delta_conn, 0),
                               utils.time_format(delta_cmd, 1),
                               utils.crop(puppet.key if puppet else "None", width=25),
                               utils.crop(location, width=25),
                               session.cmd_total,
                               session.protocol_key,
                               isinstance(session.address, tuple) and session.address[0] or session.address])
        else:
            # unprivileged
            table = prettytable.PrettyTable(["{wPlayer name", "{wOn for", "{wIdle"])
            for session in session_list:
                if not session.logged_in:
                    continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                player = session.get_player()
                table.add_row([utils.crop(player.key, width=25),
                               utils.time_format(delta_conn, 0),
                               utils.time_format(delta_cmd, 1)])

        isone = nplayers == 1
        string = "{wPlayers:{n\n%s\n%s unique account%s logged in." % (table, "One" if isone else nplayers, "" if isone else "s")
        self.msg(string)
Exemple #10
0
    def func(self):
        """
        Get all connected accounts by polling session.
        """

        account = self.account
        session_list = SESSIONS.get_sessions()

        session_list = sorted(session_list, key=lambda o: o.account.key)

        if self.cmdstring == "doing":
            show_session_data = False
        else:
            show_session_data = account.check_permstring("Developer") or account.check_permstring("Admins")

        naccounts = (SESSIONS.account_count())
        if show_session_data:
            # privileged info
            table = evtable.EvTable("|wAccount Name",
                                    "|wOn for",
                                    "|wIdle",
                                    "|wPuppeting",
                                    "|wRoom",
                                    "|wCmds",
                                    "|wProtocol",
                                    "|wHost")
            for session in session_list:
                if not session.logged_in:
                    continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                account = session.get_account()
                puppet = session.get_puppet()
                location = puppet.location.key if puppet and puppet.location else "None"
                table.add_row(utils.crop(account.name, width=25),
                              utils.time_format(delta_conn, 0),
                              utils.time_format(delta_cmd, 1),
                              utils.crop(puppet.key if puppet else "None", width=25),
                              utils.crop(location, width=25),
                              session.cmd_total,
                              session.protocol_key,
                              isinstance(session.address, tuple) and session.address[0] or session.address)
        else:
            # unprivileged
            table = evtable.EvTable("|wAccount name", "|wOn for", "|wIdle")
            for session in session_list:
                if not session.logged_in:
                    continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                account = session.get_account()
                table.add_row(utils.crop(account.key, width=25),
                              utils.time_format(delta_conn, 0),
                              utils.time_format(delta_cmd, 1))
        is_one = naccounts == 1
        self.msg("|wAccounts:|n\n%s\n%s unique account%s logged in."
                 % (table, "One" if is_one else naccounts, "" if is_one else "s"))
Exemple #11
0
    def func(self):
        """
        Get all connected accounts by polling session.
        """

        account = self.account
        session_list = SESSIONS.get_sessions()

        session_list = sorted(session_list, key=lambda o: o.account.key)

        if self.cmdstring == "doing":
            show_session_data = False
        else:
            show_session_data = account.check_permstring(
                "Developer") or account.check_permstring("Admins")

        naccounts = SESSIONS.account_count()
        if show_session_data:
            # privileged info
            table = self.styled_table("|wAccount Name", "|wOn for", "|wIdle",
                                      "|wPuppeting", "|wRoom", "|wCmds",
                                      "|wProtocol", "|wHost")
            for session in session_list:
                if not session.logged_in:
                    continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                account = session.get_account()
                puppet = session.get_puppet()
                location = puppet.location.key if puppet and puppet.location else "None"
                table.add_row(
                    utils.crop(account.get_display_name(account), width=25),
                    utils.time_format(delta_conn, 0),
                    utils.time_format(delta_cmd, 1),
                    utils.crop(
                        puppet.get_display_name(account) if puppet else "None",
                        width=25), utils.crop(location, width=25),
                    session.cmd_total, session.protocol_key,
                    isinstance(session.address, tuple) and session.address[0]
                    or session.address)
        else:
            # unprivileged
            table = self.styled_table("|wAccount name", "|wOn for", "|wIdle")
            for session in session_list:
                if not session.logged_in:
                    continue
                delta_cmd = time.time() - session.cmd_last_visible
                delta_conn = time.time() - session.conn_time
                account = session.get_account()
                table.add_row(
                    utils.crop(account.get_display_name(account), width=25),
                    utils.time_format(delta_conn, 0),
                    utils.time_format(delta_cmd, 1))
        is_one = naccounts == 1
        self.msg(
            "|wAccounts:|n\n%s\n%s unique account%s logged in." %
            (table, "One" if is_one else naccounts, "" if is_one else "s"))
Exemple #12
0
    def func(self):
        session_list = SESSIONS.get_sessions()

        table = evtable.EvTable(" |w|uName:|n",
                                "|w|uIdle:|n",
                                "|w|uConn:|n",
                                "|w|uClearance:|n",
                                table=None,
                                border=None,
                                width=78)

        for session in session_list:
            player = session.get_account()
            idle = time.time() - session.cmd_last_visible
            conn = time.time() - session.conn_time
            clearance = session.get_puppet().db.clearance
            flag = None
            if player.locks.check_lockstring(player, "dummy:perm(Admin)"):
                flag = "|y!|n"
            elif player.locks.check_lockstring(player, "dummy:perm(Builder)"):
                flag = "|g&|n"
            elif player.locks.check_lockstring(player, "dummy:perm(Helper)"):
                flag = "|r$|n"
            else:
                flag = " "
            table.add_row(
                flag + utils.crop(player.name), utils.time_format(idle, 0),
                utils.time_format(conn, 0),
                "|{}{}|n".format(clearance_color(CLEARANCE.get(clearance)),
                                 CLEARANCE.get(clearance)))

        table.reformat_column(0, width=24)
        table.reformat_column(1, width=12)
        table.reformat_column(2, width=12)
        table.reformat_column(3, width=30)

        self.caller.msg("|w_|n" * 78)
        title = ansi.ANSIString("|[002|w|u{}|n".format(settings.SERVERNAME))
        self.caller.msg(title.center(78, '^').replace('^', "|[002|w_|n"))

        self.caller.msg(table)
        self.caller.msg("|w_|n" * 78)
        self.caller.msg("Total Connected: %s" % SESSIONS.account_count())
        whotable = evtable.EvTable("", "", "", header=False, border=None)
        whotable.reformat_column(0, width=26)
        whotable.reformat_column(1, width=26)
        whotable.reformat_column(2, width=26)
        whotable.add_row("|y!|n - Administrators", "|g&|n - Storytellers",
                         "|r$|n - Player Helpers")
        self.caller.msg(whotable)
        self.caller.msg("|w_|n" * 78 + "\n")
Exemple #13
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))
Exemple #14
0
    def func(self):
        """Main function for this command."""
        filename = self.args.strip()
        if "." not in filename:
            filename += ".log"

        path = os.path.join("server/logs", filename)
        now = datetime.datetime.now()
        if not os.path.exists(path) or not os.path.isfile(path):
            self.msg("The {} log file doesn't exist.".format(filename))
        else:
            lines = tail_log_file(filename, 0, 20)
            render = []
            for line in lines:
                line = line.decode("utf-8")
                if line.count(" ") >= 2:
                    date, time, message = line.split(" ", 2)
                    try:
                        entry = datetime.datetime.strptime(date + " " + time, "%Y-%m-%d %H:%M:%S,%f")
                    except ValueError:
                        continue
                    else:
                        seconds = round((now - entry).total_seconds())
                        format = time_format(seconds, 1)
                        render.append("{:>4}: {}".format(format, message))

            if render:
                self.msg("\n".join(render))
            else:
                self.msg("|rNo message could be found in this log file.|n")
Exemple #15
0
 def board_timeout_posts(self, lhs, rhs):
     boardname, postnums = lhs.split('/', 1)
     boardname.strip()
     postnums.strip()
     try:
         board_group = self.board_group
         board = board_group.find_board(find_name=boardname, checker=self.character)
         posts = board.parse_postnums(player=self.player, check=postnums)
     except ValueError as err:
         self.error(unicode(err))
         return
     if not board.timeout:
         self.error("'%s' has disabled timeouts." % board)
         return
     admin = board.perm_check(self.caller, 'admin')
     new_timeout = duration_from_string(rhs)
     if new_timeout.total_seconds() == 0 and not admin:
         self.error("Only board admins may sticky a post.")
         return
     if new_timeout > board.timeout and not admin:
         self.error("Only admin may set post timeouts above the board timeout.")
         return
     for post in posts:
         if not post.can_edit(self.player):
             self.error("Cannot Edit post '%s: %s' - Permission denied." % (post.order, post.subject))
         else:
             post.timeout = new_timeout
             post.save(update_fields=['timeout'])
             self.sys_msg("Timeout set for post '%s: %s' - now %s" % (post.order, post.subject,
                                                                      time_format(new_timeout, style=1)))
Exemple #16
0
 def display_buckets(self):
     message = list()
     message.append(self.styled_header('Job Buckets'))
     col_color = self.account.options.column_names_color
     message.append(
         f"|{col_color}Name     Description                        Pen  App  Dny  Cnc  Over Due  Anon|n"
     )
     message.append(self.styled_separator())
     for bucket in evennia.GLOBAL_SCRIPTS.jobs.visible_buckets(
             self.account):
         bkey = bucket.key[:8].ljust(8)
         description = bucket.description
         if not description:
             description = ""
         pending = str(
             bucket.jobs.filter(status=0).count()).rjust(3).ljust(4)
         approved = str(
             bucket.jobs.filter(status=1).count()).rjust(3).ljust(4)
         denied = str(
             bucket.jobs.filter(status=2).count()).rjust(3).ljust(4)
         canceled = str(
             bucket.jobs.filter(status=3).count()).rjust(3).ljust(4)
         anon = 'No'
         now = datetime.datetime.utcnow()
         overdue = str(
             bucket.jobs.filter(status=0,
                                due_date__lt=now).count()).rjust(3).ljust(4)
         due = time_format(bucket.due.total_seconds(), style=1).rjust(3)
         message.append(
             f"{bkey} {description[:34].ljust(34)} {pending} {approved} {denied} {canceled} {overdue} {due}  {anon}"
         )
     message.append(self.styled_footer())
     self.msg('\n'.join(str(l) for l in message))
Exemple #17
0
 def func(self):
     "Show server time data in a table."
     table = prettytable.PrettyTable(["{wserver time statistic", "{wtime"])
     table.align = 'l'
     table.add_row(
         ["Current server uptime",
          utils.time_format(gametime.uptime(), 3)])
     table.add_row([
         "Total server running time",
         utils.time_format(gametime.runtime(), 2)
     ])
     table.add_row([
         "Total in-game time (realtime x %g)" % (gametime.TIMEFACTOR),
         utils.time_format(gametime.gametime(), 2)
     ])
     table.add_row(["Server time stamp", datetime.datetime.now()])
     self.caller.msg(str(table))
Exemple #18
0
    def last_modified_ago(self):
        """Return the X {unit}{s} ago."""
        revision = self.last_revision
        if revision:
            seconds = (now() - revision.created_on).total_seconds()
            ago = time_format(seconds, 4)
            return "{} ago".format(ago)

        return "never"
Exemple #19
0
 def func(self):
     """hook function"""
     account = self.account
     bye = '|RDisconnecting|n'
     quit_msg = settings.QUIT_MESSAGE
     cmd = self.cmdstring
     opt = self.switches
     char = self.character
     here = None if char is None else char.location
     sess = self.session
     if 'qhome' in cmd or 'home' in opt and char and here:  # Go home before quitting.
         char.execute_cmd('home')
     reason = self.args.strip() + '(Quitting)'
     if reason:
         bye += " ( |w%s|n ) " % reason
     boot = ('bootme' in cmd) or 'boot' in opt
     if 'all' in opt or boot:
         for session in account.sessions.all():
             if boot:
                 if session is sess:
                     continue  # Exclude booting current session
                 else:  # and boot the rest.
                     session.msg(quit_msg + reason + '/BOOT',
                                 session=session)
                     account.disconnect_session_from_account(
                         session, reason + '/BOOT')
             else:  # Disconnect them all!
                 session.msg(bye + reason + '/ALL|/' + quit_msg,
                             session=session)
                 account.disconnect_session_from_account(
                     session, reason + '/ALL')
         if boot:
             self.msg(
                 bye +
                 'all other sessions. |gThis session remains connected.|n')
     else:
         session_count = len(account.sessions.all())
         online = utils.time_format(time.time() - sess.conn_time, 1)
         if session_count == 2:
             msg = bye
             others = [
                 x for x in self.account.sessions.get() if x is not sess
             ]
             self.msg(msg + 'after ' + online + ' online.')
             self.msg(
                 msg +
                 'your other session. |gThis session remains connected.|n',
                 session=others)
         elif session_count > 2:
             msg = bye + "%i sessions are still connected."
             self.msg(msg % (session_count - 1))
         else:
             # If quitting the last available session, give connect time.
             msg = bye + 'after ' + online + ' online. '
             self.msg(msg)
         self.msg(quit_msg)
         account.disconnect_session_from_account(sess, reason)
Exemple #20
0
 def display_line(self, account, admin, mode=None):
     start = f"{self.unread_star(account, admin)}{self.status_letter()}"
     num = str(self.id).rjust(4).ljust(5)
     owner_link = self.owner
     owner = str(self.owner) if owner_link else ''
     owner = owner[:15].ljust(16)
     title = self.title[:29].ljust(30)
     claimed = self.handler_names()[:12].ljust(13)
     now = utcnow().timestamp()
     last_updated = self.public_update.timestamp()
     if admin:
         last_updated = max(self.admin_update.timestamp(), last_updated)
     due = self.due_date.timestamp() - now
     if due <= 0:
         due = ANSIString("|rOVER|n")
     else:
         due = time_format(due, 1)
     due = due.rjust(6).ljust(7)
     last = time_format(now - last_updated, 1).rjust(4)
     return f"{start} {num}{owner}{title}{claimed}{due}{last}"
Exemple #21
0
 def func(self):
     """hook function"""
     account = self.account
     bye = '|RDisconnecting|n'
     exit_msg = 'Hope to see you again, soon! A survey is available at https://goo.gl/forms/yCyLpF6JsAhhUgGz2 for your thoughts'
     reason = self.args.strip() if self.args else 'Quitting'
     if reason:
         bye += " ( |w%s|n ) " % reason
     if 'all' in self.switches:
         for session in account.sessions.all():
             session_online_time = utils.time_format(
                 time.time() - session.conn_time, 1)
             msg = bye + ' all sessions after ' + session_online_time + ' online. '
             account.msg(msg, session=session)
             account.msg(exit_msg, session=session)
             account.disconnect_session_from_account(session, reason=reason)
     else:
         session_count = len(account.sessions.all())
         online = utils.time_format(time.time() - self.session.conn_time, 1)
         if session_count == 2:
             msg = bye
             others = [
                 x for x in self.account.sessions.get()
                 if x is not self.session
             ]
             account.msg(msg + 'after ' + online + ' online.',
                         session=self.session)
             account.msg(
                 msg +
                 'your other session. |gThis session remains connected.|n',
                 session=others)
         elif session_count > 2:
             msg = bye + "%i sessions are still connected."
             account.msg(msg % (session_count - 1))
         else:
             # If quitting the last available session, give connect time.
             msg = bye + 'after ' + online + ' online. '
             account.msg(msg, session=self.session)
         account.msg(exit_msg, session=self.session)
         account.disconnect_session_from_account(self.session,
                                                 reason=reason)
Exemple #22
0
    def ago(self):
        """Return the time since the notification was created."""
        if self.timestamp is None:
            return "now"

        gtime = gametime.gametime(absolute=True)
        seconds = gtime - self.timestamp
        if seconds < 5:
            return "a few seconds ago"

        ago = time_format(seconds, 4)
        return "{} ago".format(ago)
Exemple #23
0
    def sent_ago(self):
        """Return the human-readable time since sent (X units ago)."""
        global _GAMETIME
        if not _GAMETIME:
            from evennia.utils import gametime as _GAMETIME

        gtime = datetime.datetime.fromtimestamp(
            _GAMETIME.gametime(absolute=True))
        gtime = make_aware(gtime)

        seconds = (gtime - self.date_sent).total_seconds()
        ago = time_format(seconds, 4)
        return "{} ago".format(ago)
Exemple #24
0
 def board_timeout_board_set(self, lhs, rhs):
     try:
         board_group = self.board_group
         board = board_group.find_board(find_name=lhs, group=self.group, checker=self.character)
     except ValueError as err:
         self.error(unicode(err))
         return
     if not board.perm_check(self.player, 'admin'):
         self.error("Permission denied.")
         return
     new_timeout = duration_from_string(rhs)
     timeout_string = time_format(new_timeout.total_seconds(), style=1) if new_timeout else '0 - Permanent'
     board.timeout = new_timeout
     board.save(update_fields=['timeout'])
     self.sys_msg("'%s' timeout set to: %s" % (board, timeout_string))
Exemple #25
0
 def board_timeout_list(self, lhs, rhs):
     try:
         board_group = self.board_group
     except ValueError as err:
         self.error(unicode(err))
         return
     message = list()
     message.append(self.board_header())
     bbtable = self.player.render.make_table(["ID", "RWA", "Name", "Timeout"], width=[4, 4, 23, 47])
     for board in board_group.visible_boards(checker=self.player):
         bbtable.add_row(mxp(board.order, "+bbread %s" % board.order),
                         board.display_permissions(self.character), mxp(board, "+bbread %s" % board.order),
                         time_format(board.timeout.total_seconds()) if board.timeout else '0 - Permanent')
     message.append(bbtable)
     message.append(self.player.render.footer())
     self.msg_lines(message)
Exemple #26
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))
Exemple #27
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))
Exemple #28
0
    def execute_cmd(self, session=None, txt=None, **kwargs):
        """
        Take incoming data and send it to connected channel. This is
        triggered by the bot_data_in Inputfunc.

        Args:
            session (Session, optional): Session responsible for this
                command. Note that this is the bot.
            txt (str, optional):  Command string.
        Kwargs:
            user (str): The name of the user who sent the message.
            channel (str): The name of channel the message was sent to.
            type (str): Nature of message. Either 'msg', 'action', 'nicklist' or 'ping'.
            nicklist (list, optional): Set if `type='nicklist'`. This is a list of nicks returned by calling
                the `self.get_nicklist`. It must look for a list `self._nicklist_callers`
                which will contain all callers waiting for the nicklist.
            timings (float, optional): Set if `type='ping'`. This is the return (in seconds) of a
                ping request triggered with `self.ping`. The return must look for a list
                `self._ping_callers` which will contain all callers waiting for the ping return.

        """
        if kwargs["type"] == "nicklist":
            # the return of a nicklist request
            if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel, self.db.irc_network, self.db.irc_port)
                nicklist = ", ".join(sorted(kwargs["nicklist"], key=lambda n: n.lower()))
                for obj in self._nicklist_callers:
                    obj.msg("Nicks at %s:\n %s" % (chstr, nicklist))
                self._nicklist_callers = []
            return

        elif kwargs["type"] == "ping":
            # the return of a ping
            if hasattr(self, "_ping_callers") and self._ping_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel, self.db.irc_network, self.db.irc_port)
                for obj in self._ping_callers:
                    obj.msg("IRC ping return from %s took %ss." % (chstr, kwargs["timing"]))
                self._ping_callers = []
            return

        elif kwargs["type"] == "privmsg":
            # A private message to the bot - a command.
            user = kwargs["user"]

            if txt.lower().startswith("who"):
                # return server WHO list (abbreviated for IRC)
                global _SESSIONS
                if not _SESSIONS:
                    from evennia.server.sessionhandler import SESSIONS as _SESSIONS
                whos = []
                t0 = time.time()
                for sess in _SESSIONS.get_sessions():
                    delta_cmd = t0 - sess.cmd_last_visible
                    delta_conn = t0 - session.conn_time
                    player = sess.get_player()
                    whos.append("%s (%s/%s)" % (utils.crop("|w%s|n" % player.name, width=25),
                                                utils.time_format(delta_conn, 0),
                                                utils.time_format(delta_cmd, 1)))
                text = "Who list (online/idle): %s" % ", ".join(sorted(whos, key=lambda w: w.lower()))
            elif txt.lower().startswith("about"):
                # some bot info
                text = "This is an Evennia IRC bot connecting from '%s'." % settings.SERVERNAME
            else:
                text = "I understand 'who' and 'about'."
            super(IRCBot, self).msg(privmsg=((text,), {"user": user}))
        else:
            # something to send to the main channel
            if kwargs["type"] == "action":
                # An action (irc pose)
                text = "%s@%s %s" % (kwargs["user"], kwargs["channel"], txt)
            else:
                # msg - A normal channel message
                text = "%s@%s: %s" % (kwargs["user"], kwargs["channel"], txt)

            if not self.ndb.ev_channel and self.db.ev_channel:
                # cache channel lookup
                self.ndb.ev_channel = self.db.ev_channel
            if self.ndb.ev_channel:
                self.ndb.ev_channel.msg(text, senders=self.id)
Exemple #29
0
    def execute_cmd(self, session=None, txt=None, **kwargs):
        """
        Take incoming data and make the appropriate action. This acts as a
        CommandHandler of sorts for the various "type" of actions the Portal
        bot returns to the Server. This is triggered by the bot_data_in
        Inputfunc.

        Args:
            session (Session, optional): Session responsible for this
                command. Note that this is the bot.
            txt (str, optional):  Command string.
        Kwargs:
            user (str): The name of the user who sent the message.
            channel (str): The name of channel the message was sent to.
            nicklist (list, optional): Set if `type='nicklist'`. This is a
                                       list of nicks returned by calling
                                       the `self.get_nicklist`. It must look
                                       for a list `self._nicklist_callers`
                                       which will contain all callers waiting
                                       for the nicklist.
            timings (float, optional): Set if `type='ping'`. This is the return
                                       (in seconds) of a ping request triggered
                                       with `self.ping`. The return must look
                                       for a list `self._ping_callers` which
                                       will contain all callers waiting for
                                       the ping return.
            type (str): The type of response returned by the IRC bot.
                        Including:
                        "nicklist": Returned when first joining a channel.
                        "joined": Returned when a new user joins a channel.
                        "left": Returned when a user leaves a channel.
                        "privmsg": Returned when the bot is directly messaged.
                        "action": Returned when a user uses /me in IRC
                        Everything else is assumed to be text to speak.
        """
        if kwargs["type"] == "nicklist":
            """
            Returned when first joining a channel.
            """
            if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                nicklist = ", ".join(
                    sorted(kwargs["nicklist"], key=lambda n: n.lower()))
                for obj in self._nicklist_callers:
                    obj.msg("Nicks at %s:\n %s" % (chstr, nicklist))
                self._nicklist_callers = []
                return

            else:
                # Prepare blank reference dictionary.
                self.db.puppetdict = {}

                # Prepare listener.
                self.prep_listener()

                # Prepare puppets.
                for nick in kwargs["nicklist"]:
                    self.prep_puppet(ansi.strip_ansi(nick))

                # Hide stale puppets.
                for puppet in search.search_tag(self.key + "-puppet"):
                    if puppet.location is not None \
                            and puppet not in self.db.puppetdict.values():
                        puppet.move_to(None, to_none=True)
                return

        elif kwargs["type"] == "ping":
            """
            Returned by the ping command.
            """
            if hasattr(self, "_ping_callers") and self._ping_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                for obj in self._ping_callers:
                    obj.msg("IRC ping return from %s took %ss." %
                            (chstr, kwargs["timing"]))
                self._ping_callers = []
            return

        elif kwargs["type"] == "joined":
            """
            Returned when a new user joins a channel.
            """
            # Prepare puppet.
            for nick in kwargs["nicklist"]:
                self.prep_puppet(ansi.strip_ansi(nick))
            return

        elif kwargs["type"] == "renamed":
            """
            Returned when IRC user changes nick.
            """
            puppetdict = self.db.puppetdict
            newname = kwargs["newname"]
            oldname = kwargs["oldname"]
            newkey = self.db.puppetprefix + newname + self.db.puppetsuffix
            oldkey = self.db.puppetprefix + oldname + self.db.puppetsuffix

            # List of puppet objects matching newname.
            puppetlist = [
                puppet for puppet in search.search_tag(self.key + "-puppet")
                if puppet.key == newkey
            ]

            # Use an existing puppet.
            if puppetlist:
                # Set up new puppet
                puppetdict[newname] = puppetlist[0]
                if not puppetdict[newname].location == self.db.ev_location:
                    puppetdict[newname].move_to(self.db.ev_location,
                                                quiet=True)
                    self.db.ev_location.msg_contents(oldkey + " has become " +
                                                     newkey)
                # Pack up old puppet
                self.db.puppetdict[oldname].move_to(None, to_none=True)
                del self.db.puppetdict[oldname]

            # Else recycle old puppet.
            elif oldname in puppetdict:
                print('Reusing puppetbot from puppetdict: ', oldname,
                      puppetdict[oldname])
                puppetdict[oldname].key = newkey
                puppetdict[newname] = puppetdict.pop(oldname)
                self.db.ev_location.msg_contents(oldkey + " has become " +
                                                 newkey)
                return

        elif kwargs["type"] == "left":
            """
            Returned when a user leaves a channel.
            """
            # Pack up puppet.
            for nick in kwargs["nicklist"]:
                nick = ansi.strip_ansi(nick)
                if nick in self.db.puppetdict:
                    self.db.puppetdict[nick].move_to(None, to_none=True)
                    self.db.ev_location.msg_contents(
                        self.db.puppetdict[nick].key + self.db.puppetexitmsg)
                    del self.db.puppetdict[nick]
            return

        elif kwargs["type"] == "privmsg":
            """
            Returned when the bot is directly messaged.
            Users can issue commands to the Server bot through IRC PM.
            "Who" - Return a list of current users in the MUD
            "About" - Describes the bot and the connected MUD
            "Look" - Look at the Evennia location and those within it.
            "whisper" - Whisper in-game account "whisper user = msg"
            "Desc" - If empty, shows in-game bots description. Else, sets bots
                     in-game bot description to given value.
            All other messages return a help message.
            """

            user = kwargs["user"]

            # Who command - Returns online users in game.
            if txt.lower().startswith("who"):
                # return server WHO list (abbreviated for IRC)
                global _SESSIONS
                if not _SESSIONS:
                    from evennia.server.sessionhandler import \
                        SESSIONS as _SESSIONS
                whos = []
                t0 = time.time()
                for sess in _SESSIONS.get_sessions():
                    delta_cmd = t0 - sess.cmd_last_visible
                    delta_conn = t0 - session.conn_time
                    account = sess.get_account()
                    whos.append("%s (%s/%s)" %
                                (utils.crop("|w%s|n" % account.name, width=25),
                                 utils.time_format(delta_conn, 0),
                                 utils.time_format(delta_cmd, 1)))
                text = "Who list (online/idle): %s" % ", ".join(
                    sorted(whos, key=lambda w: w.lower()))

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # About command - Return a blurb explaining origin of bot.
            elif txt.lower().startswith("about"):
                # some bot info
                text = self.db.botdesc

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # Look command - Look at the Evennia location and those within it.
            elif txt.lower().startswith("look"):
                # Mirror in-game look command.
                txt = txt.partition(" ")[2]
                if not txt:
                    target = self.db.ev_location
                else:
                    result = search.object_search(
                        txt, candidates=self.db.ev_location.contents)
                    target = result[0] if len(result) > 0 else None

                if not target:
                    text = "'%s' could not be located." % txt
                else:
                    text = target.return_appearance(
                        self.db.puppetdict[user]).replace('\n', ' ')

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # Desc command - If empty, shows in-game bots description. Else,
            # sets bots in-game bot description to given value.
            elif txt.lower().startswith("desc"):
                # Split text - set desc as text or return current desc if none.
                txt = txt.partition(" ")[2]
                if not txt:
                    text = self.db.puppetdict[user].db.desc
                else:
                    self.db.puppetdict[user].db.desc = txt
                    text = "Desc changed to: " + txt

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # Whisper command - Whisper a user in game through a puppet.
            elif txt.lower().startswith("whisper"):

                # Parse input. Must be in form 'whisper nick = msg'
                txt = txt.split(" ", 1)[1]
                try:
                    nick, msg = txt.split("=")
                except Exception:
                    text = "Whisper Usage: 'Whisper Character = Msg'"
                    super(ServerBot, self).msg(privmsg=((text, ), {
                        "user": user
                    }))
                    return

                if not nick or not msg:
                    text = "Whisper Usage: 'Whisper Character = Msg'"
                    super(ServerBot, self).msg(privmsg=((text, ), {
                        "user": user
                    }))
                    return

                puppet = self.db.puppetdict[ansi.strip_ansi(user)]
                target = puppet.search(nick)

                if not target:
                    text = "Whisper Aborted: Character could not be found."
                    # Return Message.
                    super(ServerBot, self).msg(privmsg=((text, ), {
                        "user": user
                    }))
                    return

                puppet.execute_cmd("whisper " + nick + "=" + msg)
                text = 'You whisper to ' + nick + ', "' + msg + '"'
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))
                return

            # Default message - Acts as help information.
            else:
                text = (
                    "Command list: \n"
                    '   "Who": Return a list of online users on %s.\n'
                    '   "About": Returns information about %s.\n'
                    '   "Look": Look at the Evennia location and those within it.\n'
                    '   "Desc": If empty, shows in-game bots description. Else, sets\n'
                    '   "whisper" - Whisper in-game account "whisper user = msg"\n'
                    '           bots in-game bot description to given value.\n'
                    '   All other messages return this help message.') % (
                        settings.SERVERNAME, settings.SERVERNAME)

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

        elif kwargs["type"] == "action":
            """
            Returned when a user uses /me in IRC
            """
            # Cause puppet to act out pose.
            if ansi.strip_ansi(kwargs["user"]) in self.db.puppetdict:
                user = ansi.strip_ansi(kwargs["user"])
                self.db.puppetdict[user].execute_cmd("pose " + txt)
            return

        else:
            """
            Everything else is assumed to be text to speak.
            """
            # Cause the puppet to say the message.
            if ansi.strip_ansi(kwargs["user"]) in self.db.puppetdict:
                user = ansi.strip_ansi(kwargs["user"])
                self.db.puppetdict[user].execute_cmd("say " + txt)
            return
Exemple #30
0
 def test_style_4(self):
     """Test the style 4 of time_format."""
     self.assertEqual(utils.time_format(0, 4), "0 seconds")
     self.assertEqual(utils.time_format(28, 4), "28 seconds")
     self.assertEqual(utils.time_format(92, 4), "a minute")
     self.assertEqual(utils.time_format(300, 4), "5 minutes")
     self.assertEqual(utils.time_format(660, 4), "11 minutes")
     self.assertEqual(utils.time_format(3600, 4), "an hour")
     self.assertEqual(utils.time_format(3725, 4), "an hour")
     self.assertEqual(utils.time_format(86350, 4), "23 hours")
     self.assertEqual(utils.time_format(86800, 4), "a day")
     self.assertEqual(utils.time_format(130800, 4), "a day")
     self.assertEqual(utils.time_format(530800, 4), "6 days")
     self.assertEqual(utils.time_format(3030800, 4), "a month")
     self.assertEqual(utils.time_format(7030800, 4), "2 months")
     self.assertEqual(utils.time_format(40030800, 4), "a year")
     self.assertEqual(utils.time_format(90030800, 4), "2 years")
Exemple #31
0
 def generate_substitutions(self, viewer):
     modes = (0, 1, 2, 3)
     return {
         f"style_{mode}": time_format(self.data.total_seconds(), style=mode)
         for mode in modes
     }
Exemple #32
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)
Exemple #33
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))
Exemple #34
0
 def func(self):
     """Get all connected accounts by polling session."""
     you = self.account
     session_list = SESSIONS.get_sessions()
     cmd = self.cmdstring
     show_session_data = you.check_permstring(
         'Immortals') and not you.attributes.has('_quell')
     account_count = (SESSIONS.account_count())
     table = evtable.EvTable(border='none',
                             pad_width=0,
                             border_width=0,
                             maxwidth=79)
     if cmd == 'wa' or cmd == 'where':
         # Example output expected:
         # Occ, Location,  Avg Time, Top 3 Active, Directions
         # #3 	Park 		5m 		Rulan, Amber, Tria		Taxi, Park
         # Other possible sort methods: Alphabetical by name, by occupant count, by activity, by distance
         # Nick = Global Nick (no greater than five A/N or randomly created if not a Global Nick
         #
         # WA with name parameters to pull up more extensive information about the direction
         # Highest Occupants (since last reboot), Last Visited, Last Busy (3+) etc. (more ideas here)
         table.add_header('|wOcc', '|wLocation', '|wAvg Time',
                          '|cTop 3 Active', '|gDirections')
         table.reformat_column(0, width=4, align='l')
         table.reformat_column(1, width=25, align='l')
         table.reformat_column(2, width=6, align='l')
         table.reformat_column(3, width=16, pad_right=1, align='l')
         table.reformat_column(4, width=20, align='l')
         locations = {
         }  # Create an empty dictionary to gather locations information.
         for session in session_list:  # Go through connected list and see who's where.
             if not session.logged_in:
                 continue
             character = session.get_puppet()
             if not character:
                 continue
             if character.location not in locations:
                 locations[character.location] = []
             locations[character.location].append(
                 character)  # Build the list of who's in a location
         for place in locations:
             location = place.get_display_name(
                 you) if place else '|222Nothingness|n'
             table.add_row(
                 len(locations[place]), location, '?', ', '.join(
                     each.get_display_name(you)
                     for each in locations[place]), 'Summon or walk')
     elif cmd == 'ws':
         my_character = self.caller.get_puppet(self.session)
         if not (my_character and my_character.location):
             self.msg("You can't see anyone here.")
             return
         table.add_header('|wCharacter', '|wOn for', '|wIdle')
         table.reformat_column(0, width=45, align='l')
         table.reformat_column(1, width=8, align='l')
         table.reformat_column(2, width=7, pad_right=1, align='r')
         for element in my_character.location.contents:
             if not element.has_account:
                 continue
             delta_cmd = time.time() - max(
                 [each.cmd_last_visible for each in element.sessions.all()])
             delta_con = time.time() - min(
                 [each.conn_time for each in element.sessions.all()])
             name = element.get_display_name(you)
             type = element.attributes.get('species', default='')
             table.add_row(name + ', ' + type if type else name,
                           utils.time_format(delta_con, 0),
                           utils.time_format(delta_cmd, 1))
     elif cmd == 'what' or cmd == 'wot':
         table.add_header('|wCharacter  - Doing', '|wIdle')
         table.reformat_column(0, width=72, align='l')
         table.reformat_column(1, width=7, align='r')
         for session in session_list:
             if not session.logged_in or not session.get_puppet():
                 continue
             delta_cmd = time.time() - session.cmd_last_visible
             character = session.get_puppet()
             doing = character.get_display_name(you, pose=True)
             table.add_row(doing, utils.time_format(delta_cmd, 1))
     else:  # Default to displaying who
         if show_session_data:  # privileged info shown to Immortals and higher only when not quelled
             table.add_header('|wCharacter', '|wAccount', '|wQuell',
                              '|wCmds', '|wProtocol', '|wAddress')
             table.reformat_column(0, align='l')
             table.reformat_column(1, align='r')
             table.reformat_column(2, width=7, align='r')
             table.reformat_column(3, width=6, pad_right=1, align='r')
             table.reformat_column(4, width=11, align='l')
             table.reformat_column(5, width=16, align='r')
             session_list = sorted(session_list,
                                   key=lambda o: o.account.key)
             for session in session_list:
                 if not session.logged_in:
                     continue
                 account = session.get_account()
                 puppet = session.get_puppet()
                 table.add_row(
                     puppet.get_display_name(you) if puppet else 'None',
                     account.get_display_name(you), '|gYes|n'
                     if account.attributes.get('_quell') else '|rNo|n',
                     session.cmd_total, session.protocol_key,
                     isinstance(session.address, tuple)
                     and session.address[0] or session.address)
         else:  # unprivileged info shown to everyone, including Immortals and higher when quelled
             table.add_header('|wCharacter', '|wOn for', '|wIdle')
             table.reformat_column(0, width=40, align='l')
             table.reformat_column(1, width=8, align='l')
             table.reformat_column(2, width=7, align='r')
             for session in session_list:
                 if not session.logged_in:
                     continue
                 delta_cmd = time.time() - session.cmd_last_visible
                 delta_conn = time.time() - session.conn_time
                 character = session.get_puppet()
                 if not character:
                     continue
                 table.add_row(character.get_display_name(you),
                               utils.time_format(delta_conn, 0),
                               utils.time_format(delta_cmd, 1))
     is_one = account_count == 1
     string = '%s' % 'A' if is_one else str(account_count)
     string += ' single ' if is_one else ' unique '
     plural = ' is' if is_one else 's are'
     string += 'account%s logged in.' % plural
     self.msg(table)
     self.msg(string)
Exemple #35
0
 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 ''))
Exemple #36
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))
Exemple #37
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 not callback_name 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))
Exemple #38
0
 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 ''))
Exemple #39
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))
Exemple #40
0
 def func(self):
     """Get all connected accounts by polling session."""
     you = self.account
     session_list = SESSIONS.get_sessions()
     cmd = self.cmdstring
     show_session_data = you.check_permstring('Immortals') and not you.attributes.has('_quell')
     account_count = (SESSIONS.account_count())
     table = evtable.EvTable(border='none', pad_width=0, border_width=0, maxwidth=79)
     if cmd == 'wa' or cmd == 'where':
         # Example output expected:
         # Occ, Location,  Avg Time, Top 3 Active, Directions
         # #3 	Park 		5m 		Rulan, Amber, Tria		Taxi, Park
         # Other possible sort methods: Alphabetical by name, by occupant count, by activity, by distance
         # Nick = Global Nick (no greater than five A/N or randomly created if not a Global Nick
         #
         # WA with name parameters to pull up more extensive information about the direction
         # Highest Occupants (since last reboot), Last Visited, Last Busy (3+) etc. (more ideas here)
         table.add_header('|wOcc', '|wLocation', '|wAvg Time', '|cTop 3 Active', '|gDirections')
         table.reformat_column(0, width=4, align='l')
         table.reformat_column(1, width=25, align='l')
         table.reformat_column(2, width=6, align='l')
         table.reformat_column(3, width=16, pad_right=1, align='l')
         table.reformat_column(4, width=20, align='l')
         locations = {}  # Create an empty dictionary to gather locations information.
         for session in session_list:  # Go through connected list and see who's where.
             if not session.logged_in:
                 continue
             character = session.get_puppet()
             if not character:
                 continue
             if character.location not in locations:
                 locations[character.location] = []
             locations[character.location].append(character)  # Build the list of who's in a location
         for place in locations:
             location = place.get_display_name(you) if place else '|222Nothingness|n'
             table.add_row(len(locations[place]), location, '?',
                           ', '.join(each.get_display_name(you) for each in locations[place]),
                           'Summon or walk')
     elif cmd == 'ws':
         my_character = self.caller.get_puppet(self.session)
         if not (my_character and my_character.location):
             self.msg("You can't see anyone here.")
             return
         table.add_header('|wCharacter', '|wOn for', '|wIdle')
         table.reformat_column(0, width=45, align='l')
         table.reformat_column(1, width=8, align='l')
         table.reformat_column(2, width=7, pad_right=1, align='r')
         for element in my_character.location.contents:
             if not element.has_account:
                 continue
             delta_cmd = time.time() - max([each.cmd_last_visible for each in element.sessions.all()])
             delta_con = time.time() - min([each.conn_time for each in element.sessions.all()])
             name = element.get_display_name(you)
             type = element.attributes.get('species', default='')
             table.add_row(name + ', ' + type if type else name,
                           utils.time_format(delta_con, 0), utils.time_format(delta_cmd, 1))
     elif cmd == 'what' or cmd == 'wot':
         table.add_header('|wCharacter  - Doing', '|wIdle')
         table.reformat_column(0, width=72, align='l')
         table.reformat_column(1, width=7, align='r')
         for session in session_list:
             if not session.logged_in or not session.get_puppet():
                 continue
             delta_cmd = time.time() - session.cmd_last_visible
             character = session.get_puppet()
             doing = character.get_display_name(you, pose=True)
             table.add_row(doing, utils.time_format(delta_cmd, 1))
     else:  # Default to displaying who
         if show_session_data:  # privileged info shown to Immortals and higher only when not quelled
             table.add_header('|wCharacter', '|wAccount', '|wQuell', '|wCmds', '|wProtocol', '|wAddress')
             table.reformat_column(0, align='l')
             table.reformat_column(1, align='r')
             table.reformat_column(2, width=7, align='r')
             table.reformat_column(3, width=6, pad_right=1, align='r')
             table.reformat_column(4, width=11, align='l')
             table.reformat_column(5, width=16, align='r')
             session_list = sorted(session_list, key=lambda o: o.account.key)
             for session in session_list:
                 if not session.logged_in:
                     continue
                 account = session.get_account()
                 puppet = session.get_puppet()
                 table.add_row(puppet.get_display_name(you) if puppet else 'None',
                               account.get_display_name(you),
                               '|gYes|n' if account.attributes.get('_quell') else '|rNo|n',
                               session.cmd_total, session.protocol_key,
                               isinstance(session.address, tuple) and session.address[0] or session.address)
         else:  # unprivileged info shown to everyone, including Immortals and higher when quelled
             table.add_header('|wCharacter', '|wOn for', '|wIdle')
             table.reformat_column(0, width=40, align='l')
             table.reformat_column(1, width=8, align='l')
             table.reformat_column(2, width=7, align='r')
             for session in session_list:
                 if not session.logged_in:
                     continue
                 delta_cmd = time.time() - session.cmd_last_visible
                 delta_conn = time.time() - session.conn_time
                 character = session.get_puppet()
                 if not character:
                     continue
                 table.add_row(character.get_display_name(you), utils.time_format(delta_conn, 0),
                               utils.time_format(delta_cmd, 1))
     is_one = account_count == 1
     string = '%s' % 'A' if is_one else str(account_count)
     string += ' single ' if is_one else ' unique '
     plural = ' is' if is_one else 's are'
     string += 'account%s logged in.' % plural
     self.msg(table)
     self.msg(string)
Exemple #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)
Exemple #42
0
 def test_style_0(self):
     """Test the style 0 of time_format."""
     self.assertEqual(utils.time_format(0, 0), "00:00")
     self.assertEqual(utils.time_format(28, 0), "00:00")
     self.assertEqual(utils.time_format(92, 0), "00:01")
     self.assertEqual(utils.time_format(300, 0), "00:05")
     self.assertEqual(utils.time_format(660, 0), "00:11")
     self.assertEqual(utils.time_format(3600, 0), "01:00")
     self.assertEqual(utils.time_format(3725, 0), "01:02")
     self.assertEqual(utils.time_format(86350, 0), "23:59")
     self.assertEqual(utils.time_format(86800, 0), "1d 00:06")
     self.assertEqual(utils.time_format(130800, 0), "1d 12:20")
     self.assertEqual(utils.time_format(530800, 0), "6d 03:26")
Exemple #43
0
    def execute_cmd(self, session=None, txt=None, **kwargs):
        """
        Take incoming data and send it to connected channel. This is
        triggered by the bot_data_in Inputfunc.

        Args:
            session (Session, optional): Session responsible for this
                command. Note that this is the bot.
            txt (str, optional):  Command string.
        Keyword Args:
            user (str): The name of the user who sent the message.
            channel (str): The name of channel the message was sent to.
            type (str): Nature of message. Either 'msg', 'action', 'nicklist'
                or 'ping'.
            nicklist (list, optional): Set if `type='nicklist'`. This is a list
                of nicks returned by calling the `self.get_nicklist`. It must look
                for a list `self._nicklist_callers` which will contain all callers
                waiting for the nicklist.
            timings (float, optional): Set if `type='ping'`. This is the return
                (in seconds) of a ping request triggered with `self.ping`. The
                return must look for a list `self._ping_callers` which will contain
                all callers waiting for the ping return.

        """
        if kwargs["type"] == "nicklist":
            # the return of a nicklist request
            if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
                chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})"
                nicklist = ", ".join(
                    sorted(kwargs["nicklist"], key=lambda n: n.lower()))
                for obj in self._nicklist_callers:
                    obj.msg(
                        _("Nicks at {chstr}:\n {nicklist}").format(
                            chstr=chstr, nicklist=nicklist))
                self._nicklist_callers = []
            return

        elif kwargs["type"] == "ping":
            # the return of a ping
            if hasattr(self, "_ping_callers") and self._ping_callers:
                chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})"
                for obj in self._ping_callers:
                    obj.msg(
                        _("IRC ping return from {chstr} took {time}s.").format(
                            chstr=chstr, time=kwargs["timing"]))
                self._ping_callers = []
            return

        elif kwargs["type"] == "privmsg":
            # A private message to the bot - a command.
            user = kwargs["user"]

            if txt.lower().startswith("who"):
                # return server WHO list (abbreviated for IRC)
                global _SESSIONS
                if not _SESSIONS:
                    from evennia.server.sessionhandler import SESSIONS as _SESSIONS
                whos = []
                t0 = time.time()
                for sess in _SESSIONS.get_sessions():
                    delta_cmd = t0 - sess.cmd_last_visible
                    delta_conn = t0 - session.conn_time
                    account = sess.get_account()
                    whos.append("%s (%s/%s)" % (
                        utils.crop("|w%s|n" % account.name, width=25),
                        utils.time_format(delta_conn, 0),
                        utils.time_format(delta_cmd, 1),
                    ))
                text = f"Who list (online/idle): {', '.join(sorted(whos, key=lambda w: w.lower()))}"
            elif txt.lower().startswith("about"):
                # some bot info
                text = f"This is an Evennia IRC bot connecting from '{settings.SERVERNAME}'."
            else:
                text = "I understand 'who' and 'about'."
            super().msg(privmsg=((text, ), {"user": user}))
        else:
            # something to send to the main channel
            if kwargs["type"] == "action":
                # An action (irc pose)
                text = f"{kwargs['user']}@{kwargs['channel']} {txt}"
            else:
                # msg - A normal channel message
                text = f"{kwargs['user']}@{kwargs['channel']}: {txt}"

            if not self.ndb.ev_channel and self.db.ev_channel:
                # cache channel lookup
                self.ndb.ev_channel = self.db.ev_channel

            if self.ndb.ev_channel:
                self.ndb.ev_channel.msg(text, senders=self)
Exemple #44
0
 def test_style_1(self):
     """Test the style 1 of time_format."""
     self.assertEqual(utils.time_format(0, 1), "0s")
     self.assertEqual(utils.time_format(28, 1), "28s")
     self.assertEqual(utils.time_format(92, 1), "1m")
     self.assertEqual(utils.time_format(300, 1), "5m")
     self.assertEqual(utils.time_format(660, 1), "11m")
     self.assertEqual(utils.time_format(3600, 1), "1h")
     self.assertEqual(utils.time_format(3725, 1), "1h")
     self.assertEqual(utils.time_format(86350, 1), "23h")
     self.assertEqual(utils.time_format(86800, 1), "1d")
     self.assertEqual(utils.time_format(130800, 1), "1d")
     self.assertEqual(utils.time_format(530800, 1), "6d")
Exemple #45
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))
Exemple #46
0
 def test_style_2(self):
     """Test the style 2 of time_format."""
     self.assertEqual(utils.time_format(0, 2), "0 minutes")
     self.assertEqual(utils.time_format(28, 2), "0 minutes")
     self.assertEqual(utils.time_format(92, 2), "1 minute")
     self.assertEqual(utils.time_format(300, 2), "5 minutes")
     self.assertEqual(utils.time_format(660, 2), "11 minutes")
     self.assertEqual(utils.time_format(3600, 2), "1 hour, 0 minutes")
     self.assertEqual(utils.time_format(3725, 2), "1 hour, 2 minutes")
     self.assertEqual(utils.time_format(86350, 2), "23 hours, 59 minutes")
     self.assertEqual(utils.time_format(86800, 2),
                      "1 day, 0 hours, 6 minutes")
     self.assertEqual(utils.time_format(130800, 2),
                      "1 day, 12 hours, 20 minutes")
     self.assertEqual(utils.time_format(530800, 2),
                      "6 days, 3 hours, 26 minutes")
Exemple #47
0
 def func(self):
     """Display information about server or target"""
     sessions = self.account.sessions.get()
     session = sessions[-1] if sessions else None
     account = self.account
     char = self.character or account.db._last_puppet
     if not char:
         if account.db._playable_characters[0]:
             char = account.db._playable_characters[0]
         else:
             self.msg('You must have a character to interact with objects.')
             return
     cmd = self.cmdstring
     opt = self.switches
     args = unicode(self.args).strip()
     message = ''
     if args:
         obj = char.search(args, global_search=True)
         if obj:
             display_name = obj.get_display_name(char)
             object_summary = ''
             if obj.db.desc_brief or obj.db.messages and obj.db.messages.get(
                     'summary'):
                 object_summary = '|w' + (
                     obj.db.desc_brief or obj.db.messages
                     and obj.db.messages.get('summary', ''))
             object_name = (display_name + ' is |w' + repr(obj) + ' ' +
                            object_summary +
                            (('|wAliases: |C' +
                              '|w, |C'.join(str(obj.aliases).split(',')))
                             if str(obj.aliases) else '') +
                            ' |gcreated on |g' +
                            str(obj.db_date_created)[:10])
             last_on = 0
             on_count = 0
             if obj.db.puppeted:
                 times_awake = []
                 times_asleep = []
                 for each in obj.db.puppeted.values():
                     times_awake.append(each[0])
                     times_asleep.append(each[1])
                     on_count += each[2]
                 time_awake = max(times_awake) if times_awake else None
                 time_asleep = max(times_asleep) if times_asleep else None
                 last_on_value = abs(time_awake - time_asleep) if (
                     time_awake and time_asleep) else 0
                 last_on = utils.time_format(last_on_value,
                                             2) if last_on_value else 'None'
                 if time_asleep:
                     last_asleep = utils.time_format(
                         int(time.time()) - time_asleep, 2) + ' ago'
                 else:
                     last_asleep = 'and is awake now' if obj.has_account else 'unknown'
             else:
                 last_awake, last_asleep = 'unknown', 'unknown'
             if obj.has_account:  # Object is awake:
                 message = '{} is currently awake.'.format(
                     obj.get_display_name(char))
             elif obj.db.puppeted:
                 message = '{} was last awake {} for {}.'.format(
                     obj.get_display_name(char), last_asleep, last_on)
             else:
                 message = '{} has no known last awake time.'.format(
                     obj.get_display_name(char))
             if 'last' in opt or 'last' in cmd:
                 char.msg(message)
                 return
             # If object has never been puppeted, use a different template that
             # does not include Awake count, awake times, and CPU use.
             from evennia import EvForm, EvTable
             if obj.db.puppeted:
                 time_summary = (message + ' Awake ' + str(on_count) +
                                 ' time' + ('' if on_count == 1 else 's') +
                                 '. CPU use: ' +
                                 str(round(obj.traits.ct.current, 4)) +
                                 ' seconds, ' + str(obj.traits.cc.current) +
                                 ' commands, average ' + str(
                                     round(
                                         obj.traits.ct.current /
                                         obj.traits.cc.current, 4)) +
                                 ' sec each.')
                 form_file = 'awakeformunicode' if session.protocol_flags[
                     'ENCODING'] == 'utf-8' else 'awakeform'
                 form = EvForm('commands/forms/{}.py'.format(form_file))
                 form.map(
                     cells={
                         1:
                         object_name,
                         2:
                         time_summary,
                         3:
                         obj.db.messages
                         and obj.db.messages.get('species', ''),
                         4:
                         obj.db.messages
                         and obj.db.messages.get('gender', ''),
                         5:
                         obj.db.desc
                     })
             else:
                 form_file = 'objectformunicode' if session.protocol_flags[
                     'ENCODING'] == 'utf-8' else 'objectform'
                 form = EvForm('commands/forms/{}.py'.format(form_file))
                 form.map(
                     cells={
                         1:
                         object_name,
                         2:
                         obj.db.messages
                         and obj.db.messages.get('species', ''),
                         3:
                         obj.db.messages
                         and obj.db.messages.get('gender', ''),
                         4:
                         obj.db.desc
                     })
             message = unicode(form)
     else:
         if 'last' in opt or 'last' in cmd:
             message = 'Usage: last <character name>'
         else:
             message = """
             |cEvennia|n %s|n
             MUD/MUX/MU* development system
             |wLicense|n https://opensource.org/licenses/BSD-3-Clause
             |wWeb|n http://evennia.com
             |wIrc|n #evennia on FreeNode
             |wForum|n http://evennia.com/discussions
             |wMaintainer|n (2010-)   Griatch (griatch AT gmail DOT com)
             |wMaintainer|n (2006-10) Greg Taylor
             |wOS|n %s
             |wPython|n %s
             |wTwisted|n %s
             |wDjango|n %s
             """ % (utils.get_evennia_version(), os.name,
                    sys.version.split()[0], twisted.version.short(),
                    django.get_version())
     # char.msg(image=['https://raw.githubusercontent.com/evennia/evennia/'
     #                 'master/evennia/web/website/static/website/images/evennia_logo.png'])
     self.msg((message, {"type": "help"}))
Exemple #48
0
 def test_style_3(self):
     """Test the style 3 of time_format."""
     self.assertEqual(utils.time_format(0, 3), "")
     self.assertEqual(utils.time_format(28, 3), "28 seconds")
     self.assertEqual(utils.time_format(92, 3), "1 minute 32 seconds")
     self.assertEqual(utils.time_format(300, 3), "5 minutes 0 seconds")
     self.assertEqual(utils.time_format(660, 3), "11 minutes 0 seconds")
     self.assertEqual(utils.time_format(3600, 3), "1 hour, 0 minutes")
     self.assertEqual(utils.time_format(3725, 3),
                      "1 hour, 2 minutes 5 seconds")
     self.assertEqual(utils.time_format(86350, 3),
                      "23 hours, 59 minutes 10 seconds")
     self.assertEqual(utils.time_format(86800, 3),
                      "1 day, 0 hours, 6 minutes 40 seconds")
     self.assertEqual(utils.time_format(130800, 3),
                      "1 day, 12 hours, 20 minutes 0 seconds")
     self.assertEqual(utils.time_format(530800, 3),
                      "6 days, 3 hours, 26 minutes 40 seconds")