示例#1
0
文件: door.py 项目: splaice/x84
    def __init__(self, cmd='/bin/uname', args=(), env=None, cp437=False):
        """
        Class initializer.

        :param str cmd: full path of command to execute.
        :param tuple args: command arguments as tuple.
        :param bool cp437: When true, forces decoding of external program as
                           codepage 437.  This is the most common encoding used
                           by DOS doors.
        :param dict env: Environment variables to extend to the sub-process.
                         You should more than likely specify values for TERM,
                         PATH, HOME, and LANG.
        """
        self._session, self._term = getsession(), getterminal()
        self.cmd = cmd
        if isinstance(args, tuple):
            self.args = (self.cmd,) + args
        elif isinstance(args, list):
            self.args = [self.cmd, ] + args
        else:
            raise ValueError('args must be tuple or list')

        self.log = logging.getLogger(__name__)
        self.env = (env or {}).copy()
        self.env.update(
            {'LANG': env.get('LANG', 'en_US.UTF-8'),
             'TERM': env.get('TERM', self._term.kind),
             'PATH': env.get('PATH', get_ini('door', 'path')),
             'HOME': env.get('HOME', os.getenv('HOME')),
             'LINES': str(self._term.height),
             'COLUMNS': str(self._term.width),
             })

        self.cp437 = cp437
        self._utf8_decoder = codecs.getincrementaldecoder('utf8')()
示例#2
0
文件: modem.py 项目: tcummings19/3x84
def send_modem(stream,
               protocol='xmodem1k',
               retry=16,
               timeout=30,
               callback=None):
    """
    Send a file using 'xmodem1k' or 'xmodem' protocol.

    Currently, these are the only protocols supported.  Returns ``True`` upon
    successful transmission, otherwise ``False``.

    :param stream: The file-like stream object to send data from.
    :param int retry: The maximum number of times to try to resend a failed
                      packet before failing.
    :param int timeout: seconds to elapse for response before failing.
    :param callable callback: Reference to a callback function that has the
           following signature. This is useful for getting
           status updates while a transfer is underway::

               def callback(total_count, success_count, error_count)
    """
    # get protocol implementation class
    supported_protocols = ('xmodem', 'xmodem1k')
    assert protocol in supported_protocols, (protocol, supported_protocols)
    Modem = {
        'xmodem': xmodem.XMODEM,
        'xmodem1k': xmodem.XMODEM1k,
    }[protocol]

    # the session's 'input' event buffer is used for receiving
    # transmissions.  It arrives in raw bytes, and session.write
    # is used, sending "unicode" data as encoding iso8859-1.
    session = getsession()

    def getc(size, timeout=10):
        """ Callback function for (X)Modem interface. """
        val = b''
        while len(val) < size:
            next_val = session.read_event('input', timeout=timeout)
            if next_val is None:
                break
            val += next_val
        if len(val) > size:
            session.buffer_input(val[size:])
        return val[:size] or None

    def putc(data, timeout=10):
        # pylint: disable=W0613
        #         Unused argument 'timeout'
        """ Callback function for (X)Modem interface. """
        session.write(data.decode('iso8859-1'), 'iso8859-1')

    modem = Modem(getc, putc)
    return modem.send(stream=stream,
                      retry=retry,
                      timeout=timeout,
                      quiet=True,
                      callback=callback)
示例#3
0
def echo(ucs):
    """
    Display unicode terminal sequence.
    """
    session = getsession()
    if not isinstance(ucs, unicode):
        warnings.warn('non-unicode: %r' % (ucs, ), UnicodeWarning, 2)
        return session.write(ucs.decode('iso8859-1'))
    return session.write(ucs)
示例#4
0
文件: output.py 项目: quastdog/x84
def echo(ucs):
    """
    Display unicode terminal sequence.
    """
    session = getsession()
    if not isinstance(ucs, unicode):
        warnings.warn('non-unicode: %r' % (ucs,), UnicodeWarning, 2)
        return session.write(ucs.decode('iso8859-1'))
    return session.write(ucs)
示例#5
0
文件: output.py 项目: jonny290/x84
 def _decode(what):
     # pylint: disable=C0111
     #         Missing function docstring (col 8)
     session = getsession()
     if session.encoding == 'utf8':
         return what.decode(encoding)
     elif session.encoding == 'cp437':
         return what.decode('cp437')
     else:
         return what
示例#6
0
文件: output.py 项目: tehmaze/x84
 def _decode(what):
     # pylint: disable=C0111
     #         Missing function docstring (col 8)
     session = getsession()
     if session.encoding == 'utf8':
         return what.decode(encoding)
     elif session.encoding == 'cp437':
         return what.decode('cp437')
     else:
         return what
示例#7
0
文件: pager.py 项目: quastdog/x84
 def read(self):
     """
     Reads input until ESCAPE key is pressed (Blocking).  Returns None.
     """
     from x84.bbs.session import getsession
     from x84.bbs.output import echo
     session = getsession()
     self._quit = False
     echo(self.refresh())
     while not self.quit:
         echo(self.process_keystroke(session.read_event('input')))
示例#8
0
文件: dbproxy.py 项目: hick/x84
 def __init__(self, schema, table='unnamed', use_session=True):
     """
     Arguments:
         schema: database key, to become basename of .sqlite3 files.
     """
     from x84.bbs.session import getsession
     self.log = logging.getLogger(__name__)
     self.schema = schema
     self.table = table
     self._tap_db = should_tapdb()
     self.session = use_session and getsession()
示例#9
0
 def __init__(self, recipient=None, subject=u'', body=u''):
     from x84.bbs.session import getsession
     self._ctime = datetime.datetime.now()
     self._stime = None
     self.author = getsession().handle
     self.recipient = recipient
     self.subject = subject
     self.body = body
     self.tags = set()
     # reply-to tracking
     self.children = set()
     self.parent = None
示例#10
0
 def read(self):
     """
     Reads input until ESCAPE key is pressed (Blocking).  Returns None.
     """
     from x84.bbs import getch
     from x84.bbs.session import getsession
     from x84.bbs.output import echo
     session = getsession()
     self._quit = False
     echo(self.refresh())
     while not self.quit:
         echo(self.process_keystroke(getch()))
示例#11
0
文件: modem.py 项目: adammendoza/x84
def send_modem(stream, protocol='xmodem1k', retry=16, timeout=30,
               callback=None):
    """
    Send a file using 'xmodem1k' or 'xmodem' protocol.

    Currently, these are the only protocols supported.  Returns ``True`` upon
    successful transmission, otherwise ``False``.

    :param stream: The file-like stream object to send data from.
    :param int retry: The maximum number of times to try to resend a failed
                      packet before failing.
    :param int timeout: seconds to elapse for response before failing.
    :param callable callback: Reference to a callback function that has the
           following signature. This is useful for getting
           status updates while a transfer is underway::

               def callback(total_count, success_count, error_count)
    """
    # get protocol implementation class
    supported_protocols = ('xmodem', 'xmodem1k')
    assert protocol in supported_protocols, (protocol, supported_protocols)
    Modem = {
        'xmodem': xmodem.XMODEM,
        'xmodem1k': xmodem.XMODEM1k,
    }[protocol]

    # the session's 'input' event buffer is used for receiving
    # transmissions.  It arrives in raw bytes, and session.write
    # is used, sending "unicode" data as encoding iso8859-1.
    session = getsession()

    def getc(size, timeout=10):
        """ Callback function for (X)Modem interface. """
        val = b''
        while len(val) < size:
            next_val = session.read_event('input', timeout=timeout)
            if next_val is None:
                break
            val += next_val
        if len(val) > size:
            session.buffer_input(val[size:])
        return val[:size] or None

    def putc(data, timeout=10):
        # pylint: disable=W0613
        #         Unused argument 'timeout'
        """ Callback function for (X)Modem interface. """
        session.write(data.decode('iso8859-1'), 'iso8859-1')

    modem = Modem(getc, putc)
    return modem.send(stream=stream, retry=retry, timeout=timeout,
                      quiet=True, callback=callback)
示例#12
0
    def __init__(self, recipient=None, subject=u'', body=u''):
        self.author = None
        session = getsession()
        if session:
            self.author = session.user.handle

        self._ctime = datetime.datetime.now()
        self._stime = None
        self.recipient = recipient
        self.subject = subject
        self.body = body
        self.tags = set()
        self.children = set()
        self.parent = None
        self.idx = None
示例#13
0
文件: ansiwin.py 项目: donfanning/x84
 def init_theme(self):
     """
     This initializer sets glyphs and colors appropriate for a "theme",
     override this method to create a common color and graphic set.
     """
     session = getsession()
     term = getterminal()
     self.colors['normal'] = term.normal
     if term.number_of_colors != 0:
         self.colors['border'] = term.cyan
     # start with default 'ascii'
     self.glyphs = GLYPHSETS['ascii'].copy()
     # PC-DOS 'thin' on smart terminals
     if session.env.get('TERM') != 'unknown':
         self.glyphs = GLYPHSETS['thin'].copy()
示例#14
0
 def init_theme(self):
     """
     This initializer sets glyphs and colors appropriate for a "theme",
     override this method to create a common color and graphic set.
     """
     session = getsession()
     term = getterminal()
     self.colors['normal'] = term.normal
     if term.number_of_colors != 0:
         self.colors['border'] = term.cyan
     # start with default 'ascii'
     self.glyphs = GLYPHSETS['ascii'].copy()
     # PC-DOS 'thin' on smart terminals
     if session.env.get('TERM') != 'unknown':
         self.glyphs = GLYPHSETS['thin'].copy()
示例#15
0
    def __init__(self, recipient=None, subject=u'', body=u''):
        self.author = None
        session = getsession()
        if session:
            self.author = session.user.handle

        self._ctime = datetime.datetime.now()
        self._stime = None
        self.recipient = recipient
        self.subject = subject
        self.body = body
        self.tags = set()
        self.children = set()
        self.parent = None
        self.idx = None
示例#16
0
文件: msgbase.py 项目: ztaylor/x84
    def __init__(self, recipient=None, subject=u'', body=u''):
        from x84.bbs.session import getsession
        self.author = None
        session = getsession()
        if session:
            self.author = session.handle

        # msg attributes (todo: create method ..)
        self._ctime = datetime.datetime.now()
        self._stime = None
        self.recipient = recipient
        self.subject = subject
        self.body = body
        self.tags = set()
        self.children = set()
        self.parent = None
示例#17
0
    def __init__(self, recipient=None, subject=u'', body=u''):
        from x84.bbs.session import getsession
        self.author = None
        session = getsession()
        if session:
            self.author = session.handle

        # msg attributes (todo: create method ..)
        self._ctime = datetime.datetime.now()
        self._stime = None
        self.recipient = recipient
        self.subject = subject
        self.body = body
        self.tags = set()
        self.children = set()
        self.parent = None
示例#18
0
文件: selector.py 项目: quastdog/x84
 def read(self):
     """
     Reads input until the ENTER or ESCAPE key is pressed (Blocking).
     Allows backspacing. Returns unicode text, or None when cancelled.
     """
     from x84.bbs.session import getsession
     from x84.bbs.output import echo
     session = getsession()
     self._selected = False
     self._quit = False
     echo(self.refresh())
     while not (self.selected or self.quit):
         echo(self.process_keystroke(session.read_event('input')) or u'')
     if self.quit:
         return None
     return self.selection
示例#19
0
文件: dbproxy.py 项目: tehmaze/x84
    def __init__(self, schema, table='unnamed', use_session=True):
        """
        Class constructor.

        :param str scheme: database key, becomes basename of .sqlite3 file.
        :param str table: optional database table.
        :param bool use_session: Whether iterable returns should be sent over
                                 an IPC pipe (client is a
                                 :class:`x84.bbs.session.Session` instance),
                                 or returned directly (such as used by the main
                                 thread engine components.)
        """
        self.log = logging.getLogger(__name__)
        self.schema = schema
        self.table = table
        self._tap_db = get_ini('session', 'tab_db', getter='getboolean')
        self.session = use_session and getsession()
示例#20
0
文件: editor.py 项目: sweenzor/x84
    def read(self):
        """
        Reads input until the ENTER or ESCAPE key is pressed (Blocking).
        Allows backspacing. Returns unicode text, or None when cancelled.
        """
        from x84.bbs.session import getsession
        from x84.bbs.output import echo

        session = getsession()
        echo(self.refresh())
        self._quit = False
        self._carriage_returned = False
        while not (self.quit or self.carriage_returned):
            inp = session.read_event("input")
            echo(self.process_keystroke(inp))
        if not self.quit:
            return self.content
        return None
示例#21
0
文件: ipc.py 项目: tcummings19/3x84
 def emit(self, record):
     """ Emit log record via IPC output queue. """
     try:
         e_inf = record.exc_info
         if e_inf:
             # a strange side-effect,
             # sets record.exc_text
             dummy = self.format(record)  # NOQA
             record.exc_info = None
         record.handle = None
         session = getsession()
         if session:
             record.handle = session.user.handle
         self.oqueue.send(('logger', record))
     except (KeyboardInterrupt, SystemExit):
         raise
     except Exception:
         self.handleError(record)
示例#22
0
文件: ipc.py 项目: tehmaze/x84
 def emit(self, record):
     """ Emit log record via IPC output queue. """
     try:
         e_inf = record.exc_info
         if e_inf:
             # a strange side-effect,
             # sets record.exc_text
             dummy = self.format(record)  # NOQA
             record.exc_info = None
         record.handle = None
         session = getsession()
         if session:
             record.handle = session.handle
         self.oqueue.send(('logger', record))
     except (KeyboardInterrupt, SystemExit):
         raise
     except Exception:
         self.handleError(record)
示例#23
0
    def __init__(self, schema, table='unnamed', use_session=True):
        """
        Class initializer.

        :param str scheme: database key, becomes basename of .sqlite3 file.
        :param str table: optional database table.
        :param bool use_session: Whether iterable returns should be sent over
                                 an IPC pipe (client is a
                                 :class:`x84.bbs.session.Session` instance),
                                 or returned directly (such as used by the main
                                 thread engine components.)
        """
        self.log = logging.getLogger(__name__)
        self.schema = schema
        self.table = table
        self._tap_db = get_ini('session', 'tab_db', getter='getboolean')

        from x84.bbs.session import getsession
        self._session = use_session and getsession()
示例#24
0
 def read(self):
     """
     Reads input until the ENTER or ESCAPE key is pressed (Blocking).
     Allows backspacing. Returns unicode text, or None when canceled.
     """
     from x84.bbs import getch
     from x84.bbs.output import echo
     from x84.bbs.session import getsession, getterminal
     session, term = getsession(), getterminal()
     self._carriage_returned = False
     self._quit = False
     echo(self.refresh())
     while not (self.quit or self.carriage_returned):
         inp = getch()
         echo(self.process_keystroke(inp))
     echo(term.normal)
     if not self.quit:
         return self.content
     return None
示例#25
0
文件: door.py 项目: tehmaze/x84
    def __init__(self, cmd='/bin/uname', args=(), env_lang='en_US.UTF-8',
                 env_term=None, env_path=None, env_home=None, cp437=False,
                 env=None):
        """
        Class constructor.

        :param str cmd: full path of command to execute.
        :param tuple args: command arguments as tuple.
        :param str env_lang: exported as environment variable ``LANG``.
        :param str env_term: exported as environment variable ``TERM``.  When
                             unspecified, it is determined by the same
                             TERM value the original ``blessed.Terminal``
                             instance is used.
        :param str env_path: exported as environment variable ``PATH``.
                             When None (default), the .ini ``env_path``
                             value of section ``[door]`` is
        :param str env_home: exported as environment variable ``HOME``.
                             When env_home is ``None``, the environment
                             value of the main process is used.
        :param bool cp437: When true, forces decoding of external program as
                           codepage 437.  This is the most common encoding used
                           by DOS doors.
        :param dict env: Additional environment variables to extend to the
                         sub-process.
        """
        self._session, self._term = getsession(), getterminal()
        self.cmd = cmd
        if isinstance(args, tuple):
            self.args = (self.cmd,) + args
        elif isinstance(args, list):
            self.args = [self.cmd, ] + args
        else:
            raise ValueError('args must be tuple or list')
        self.env_lang = env_lang
        self.env_term = env_term or self._term.kind
        self.env_path = env_path or get_ini('door', 'path')
        self.env_home = env_home or os.getenv('HOME')
        self.env = env or {}
        self.cp437 = cp437
        self._utf8_decoder = codecs.getincrementaldecoder('utf8')()
示例#26
0
文件: output.py 项目: quastdog/x84
    def __len__(self):
        """
        Return the printed length of a string that contains (some types) of
        ansi sequences. Although accounted for, strings containing sequences
        such as cls() will not give accurate returns. backspace, delete, and
        double-wide east-asian
        """
        # 'nxt' points to first *ch beyond current ansi sequence, if any.
        # 'width' is currently estimated display length.
        nxt, width = 0, 0

        # i regret the heavy re-instantiation of Ansi() ..
        for idx in range(0, unicode.__len__(self)):
            width += Ansi(self[idx:]).anspadd()
            if idx == nxt:
                nxt = idx + Ansi(self[idx:]).seqlen()
            if nxt <= idx:
                ucs = self[idx]
                if getsession().encoding == 'cp437':
                    wide = 1
                else:
                    # 'East Asian Fullwidth' and 'East Asian Wide' characters
                    # can take 2 cells, see
                    # http://www.unicode.org/reports/tr11/
                    # http://www.gossamer-threads.com/lists/python/bugs/972834
                    # we just use wcswidth, since that is what terminal
                    # client implementors seem to be using ..
                    wide = wcswidth(ucs)

                # TODO
                # my own NVT addition: allow -1 to be added to width when
                # 127 and 8 are used (BACKSPACE, DEL); as well as \x0f .!?
#                assert wide != -1 or ucs in (u'\b',
#                                            unichr(127),
#                                            unichr(15)), (
#                    'indeterminate length %r in %r' % (self[idx], self))
                width += wide if wide != -1 else 0
                nxt = idx + Ansi(self[idx:]).seqlen() + 1
        return width
示例#27
0
    def __len__(self):
        """
        Return the printed length of a string that contains (some types) of
        ansi sequences. Although accounted for, strings containing sequences
        such as cls() will not give accurate returns. backspace, delete, and
        double-wide east-asian
        """
        # 'nxt' points to first *ch beyond current ansi sequence, if any.
        # 'width' is currently estimated display length.
        nxt, width = 0, 0

        # i regret the heavy re-instantiation of Ansi() ..
        for idx in range(0, unicode.__len__(self)):
            width += Ansi(self[idx:]).anspadd()
            if idx == nxt:
                nxt = idx + Ansi(self[idx:]).seqlen()
            if nxt <= idx:
                ucs = self[idx]
                if getsession().encoding == 'cp437':
                    wide = 1
                else:
                    # 'East Asian Fullwidth' and 'East Asian Wide' characters
                    # can take 2 cells, see
                    # http://www.unicode.org/reports/tr11/
                    # http://www.gossamer-threads.com/lists/python/bugs/972834
                    # we just use wcswidth, since that is what terminal
                    # client implementors seem to be using ..
                    wide = wcswidth(ucs)

                # TODO
                # my own NVT addition: allow -1 to be added to width when
                # 127 and 8 are used (BACKSPACE, DEL); as well as \x0f .!?
#                assert wide != -1 or ucs in (u'\b',
#                                            unichr(127),
#                                            unichr(15)), (
#                    'indeterminate length %r in %r' % (self[idx], self))
                width += wide if wide != -1 else 0
                nxt = idx + Ansi(self[idx:]).seqlen() + 1
        return width
示例#28
0
文件: door.py 项目: splaice/x84
 def node(self):
     """ User's node number. """
     return self._node or getsession().node
示例#29
0
文件: ipc.py 项目: hick/x84
 def session(self):
     if self._session is None:
         from x84.bbs.session import getsession
         self._session = getsession()
     return self._session
示例#30
0
文件: msgbase.py 项目: ztaylor/x84
    def save(self, send_net=True, ctime=None):
        """
        Save message in 'Msgs' sqlite db, and record index in 'tags' db.
        """
        from x84.bbs.ini import CFG
        from x84.bbs import getsession

        session = getsession()
        use_session = bool(session is not None)
        log = logging.getLogger(__name__)
        new = self.idx is None or self._stime is None

        # persist message record to MSGDB
        db_msg = DBProxy(MSGDB, use_session=use_session)
        with db_msg:
            if new:
                self.idx = max([int(key) for key in db_msg.keys()] or [-1]) + 1
                if ctime is not None:
                    self._ctime = self._stime = ctime
                else:
                    self._stime = datetime.datetime.now()
                new = True
            db_msg['%d' % (self.idx,)] = self

        # persist message idx to TAGDB
        db_tag = DBProxy(TAGDB, use_session=use_session)
        with db_tag:
            for tag in db_tag.keys():
                msgs = db_tag[tag]
                if tag in self.tags and self.idx not in msgs:
                    msgs.add(self.idx)
                    db_tag[tag] = msgs
                    log.debug("msg {self.idx} tagged '{tag}'"
                              .format(self=self, tag=tag))
                elif tag not in self.tags and self.idx in msgs:
                    msgs.remove(self.idx)
                    db_tag[tag] = msgs
                    log.info("msg {self.idx} removed tag '{tag}'"
                             .format(self=self, tag=tag))
            for tag in [_tag for _tag in self.tags if _tag not in db_tag]:
                db_tag[tag] = set([self.idx])

        # persist message as child to parent;
        if not hasattr(self, 'parent'):
            self.parent = None
        assert self.parent not in self.children
        if self.parent is not None:
            parent_msg = get_msg(self.parent)
            if self.idx != parent_msg.idx:
                parent_msg.children.add(self.idx)
                parent_msg.save()
            else:
                log.error('Parent idx same as message idx; stripping')
                self.parent = None
                with db_msg:
                    db_msg['%d' % (self.idx)] = self

        if send_net and new and CFG.has_option('msg', 'network_tags'):
            self.queue_for_network()

        log.info(
            u"saved {new}{public}msg {post}, addressed to '{self.recipient}'."
            .format(new='new ' if new else '',
                    public='public ' if 'public' in self.tags else '',
                    post='post' if self.parent is None else 'reply',
                    self=self))
示例#31
0
文件: door.py 项目: tehmaze/x84
def launch(dos=None, cp437=True, drop_type=None,
           drop_folder=None, name=None, args='',
           forcesize=None, activity=None, command=None,
           nodes=None, forcesize_func=None, env_term=None):
    r"""
    Helper function for launching an external program as a "Door".

    the forcesize_func may be overridden if the sysop wants to use
    their own function for presenting the screen resize prompt.

    virtual node pools are per-door, based on the 'name' argument, up
    to a maximum determined by the 'nodes' argument.
    name='Netrunner' nodes=4 would mean that the door, Netrunner, has
    a virtual node pool with 4 possible nodes in it. When 4 people
    are already playing the game, additional users will be notified
    that there are no nodes available for play until one of them is
    released.

    for DOS doors, the [dosemu] section of default.ini is used for
    defaults::

        default.ini
        ---
        [dosemu]
        bin = /usr/bin/dosemu
        home = /home/bbs
        path = /usr/bin:/usr/games:/usr/local/bin
        opts = -u virtual -f /home/bbs/dosemu.conf \
               -o /home/bbs/dosemu%%#.log %%c 2> /home/bbs/dosemu_boot%%#.log
        dropdir = /home/bbs/dos
        nodes = 4

    in 'opts', %%# becomes the virtual node number, %%c becomes the 'command'
    argument.

    'dropdir' is where dropfiles will be created if unspecified. you can
    give each door a dropdir for each node if you like, for ultimate
    compartmentalization -- just set the 'dropdir' argument when calling
    this function.

    -u virtual can be used to add a section to your dosemu.conf for
    virtualizing the com port (which allows you to use the same dosemu.conf
    locally by omitting '-u virtual')::

        dosemu.conf
        ---
        $_cpu = (80386)
        $_hogthreshold = (20)
        $_layout = "us"
        $_external_charset = "utf8"
            $_internal_charset = "cp437"
        $_term_update_freq = (4)
        $_rdtsc = (on)
        $_cpuspeed = (166.666)
        ifdef u_virtual
                $_com1 = "virtual"
        endif
    """
    session, term = getsession(), getterminal()
    logger = logging.getLogger()
    echo(term.clear)

    with term.fullscreen():
        store_rows, store_cols = None, None
        env_term = env_term or term.kind
        strnode = None
        (dosbin, doshome, dospath, dosopts, dosdropdir, dosnodes) = (
            get_ini('dosemu', 'bin'),
            get_ini('dosemu', 'home'),
            get_ini('dosemu', 'path'),
            get_ini('dosemu', 'opts'),
            get_ini('dosemu', 'dropdir'),
            get_ini('dosemu', 'nodes', getter='getint'))

        if drop_folder is not None and drop_type is None:
            drop_type = 'DOORSYS'

        if drop_type is not None and drop_folder is None:
            drop_folder = dosdropdir

        if drop_folder or drop_type:
            assert name is not None, (
                'name required for door using node pools')

            for node in range(nodes if nodes is not None else dosnodes):
                event = 'lock-%s/%d' % (name, node)
                session.send_event(event, ('acquire', None))
                data = session.read_event(event)

                if data is True:
                    strnode = str(node + 1)
                    break

            if strnode is None:
                logger.warn('No virtual nodes left in pool: %s', name)
                echo(term.bold_red(u'This door is currently at maximum '
                                   u'capacity. Please try again later.'))
                term.inkey(3)
                return

            logger.info('Requisitioned virtual node %s-%s', name, strnode)
            dosopts = dosopts.replace('%#', strnode)
            dosdropdir = dosdropdir.replace('%#', strnode)
            drop_folder = drop_folder.replace('%#', strnode)
            args = args.replace('%#', strnode)

        try:
            if dos is not None or forcesize is not None:
                if forcesize is None:
                    forcesize = (80, 25,)
                else:
                    assert len(forcesize) == 2, forcesize

                # pylint: disable=W0633
                #         Attempting to unpack a non-sequence
                want_cols, want_rows = forcesize

                if want_cols != term.width or want_rows != term.height:
                    store_cols, store_rows = term.width, term.height
                    echo(u'\x1b[8;%d;%dt' % (want_rows, want_cols,))
                    term.inkey(timeout=0.25)

                dirty = True

                if not (term.width == want_cols and term.height == want_rows):
                    if forcesize_func is not None:
                        forcesize_func()
                    else:
                        while not (term.width == want_cols and
                                   term.height == want_rows):
                            if session.poll_event('refresh'):
                                dirty = True

                            if dirty:
                                dirty = False
                                echo(term.clear)
                                echo(term.bold_cyan(
                                    u'o' + (u'-' * (forcesize[0] - 2))
                                    + u'>\r\n'
                                    + (u'|\r\n' * (forcesize[1] - 2))))
                                echo(u''.join(
                                    (term.bold_cyan(u'V'),
                                     term.bold(u' Please resize your screen '
                                               u'to %sx%s and/or press ENTER '
                                               u'to continue' % (want_cols,
                                                                 want_rows)))))

                            ret = term.inkey(timeout=0.25)

                            if ret in (term.KEY_ENTER, u'\r', u'\n'):
                                break

                if term.width != want_cols or term.height != want_rows:
                    echo(u'\r\nYour dimensions: %s by %s; '
                         u'emulating %s by %s' % (term.width, term.height,
                                                  want_cols, want_rows,))

                    # hand-hack, its ok ... really
                    store_cols, store_rows = term.width, term.height
                    term.columns, term.rows = want_cols, want_rows
                    term.inkey(timeout=1)

            if activity is not None:
                session.activity = activity
            elif name is not None:
                session.activity = 'Playing %s' % name
            else:
                session.activity = 'Playing a door game'

            if drop_folder is not None:
                if not os.path.isabs(drop_folder):
                    drop_folder = os.path.join(dosdropdir, drop_folder)

                Dropfile(getattr(Dropfile, drop_type)).save(drop_folder)

            door = None

            if dos is not None:
                # launch a dosemu door
                cmd = None

                if command is not None:
                    cmd = command
                else:
                    cmd = dosbin
                    args = dosopts.replace('%c', '"' + args + '"')

                door = DOSDoor(cmd, shlex.split(args), cp437=True,
                               env_home=doshome, env_path=dospath,
                               env_term=env_term)
            else:
                # launch a unix program
                door = Door(command, shlex.split(args), cp437=cp437,
                            env_term=env_term)

            door.run()
        finally:
            if store_rows is not None and store_cols is not None:
                term.rows, term.columns = store_rows, store_cols
                echo(u'\x1b[8;%d;%dt' % (store_rows, store_cols,))
                term.inkey(timeout=0.25)

            if name is not None and drop_type:
                session.send_event(
                    event='lock-%s/%d' % (name, int(strnode) - 1),
                    data=('release', None))
                logger.info('Released virtual node %s-%s', name, strnode)
示例#32
0
    def save(self, send_net=True, ctime=None):
        """
        Save message in 'Msgs' sqlite db, and record index in 'tags' db.
        """
        from x84.bbs.ini import CFG
        from x84.bbs import getsession

        session = getsession()
        use_session = bool(session is not None)
        log = logging.getLogger(__name__)
        new = self.idx is None or self._stime is None

        # persist message record to MSGDB
        db_msg = DBProxy(MSGDB, use_session=use_session)
        with db_msg:
            if new:
                self.idx = max(map(int, db_msg.keys()) or [-1]) + 1
                if ctime is not None:
                    self._ctime = self._stime = ctime
                else:
                    self._stime = datetime.datetime.now()
                new = True
            db_msg['%d' % (self.idx, )] = self

        # persist message idx to TAGDB
        db_tag = DBProxy(TAGDB, use_session=use_session)
        with db_tag:
            for tag in db_tag.keys():
                msgs = db_tag[tag]
                if tag in self.tags and self.idx not in msgs:
                    msgs.add(self.idx)
                    db_tag[tag] = msgs
                    log.debug("msg {self.idx} tagged '{tag}'".format(self=self,
                                                                     tag=tag))
                elif tag not in self.tags and self.idx in msgs:
                    msgs.remove(self.idx)
                    db_tag[tag] = msgs
                    log.info("msg {self.idx} removed tag '{tag}'".format(
                        self=self, tag=tag))
            for tag in [_tag for _tag in self.tags if _tag not in db_tag]:
                db_tag[tag] = set([self.idx])

        # persist message as child to parent;
        if not hasattr(self, 'parent'):
            self.parent = None
        assert self.parent not in self.children
        if self.parent is not None:
            parent_msg = get_msg(self.parent)
            if self.idx != parent_msg.idx:
                parent_msg.children.add(self.idx)
                parent_msg.save()
            else:
                log.error('Parent idx same as message idx; stripping')
                self.parent = None
                with db_msg:
                    db_msg['%d' % (self.idx)] = self

        if send_net and new and CFG.has_option('msg', 'network_tags'):
            self.queue_for_network()

        log.info(
            u"saved {new}{public}msg {post}, addressed to '{self.recipient}'.".
            format(new='new ' if new else '',
                   public='public ' if 'public' in self.tags else '',
                   post='post' if self.parent is None else 'reply',
                   self=self))
示例#33
0
文件: door.py 项目: splaice/x84
 def lastcall_date(self):
     """ Date of last call (format is ``%m/%d/%y``). """
     return time.strftime(
         '%m/%d/%y', time.localtime(getsession().user.lastcall))
示例#34
0
文件: door.py 项目: splaice/x84
 def lastcall_time(self):
     """ Time of last call (format is ``%H:%M``). """
     return time.strftime(
         '%H:%M', time.localtime(getsession().user.lastcall))
示例#35
0
文件: door.py 项目: splaice/x84
 def securitylevel(self):
     """ User security level. Always 30, or 100 for sysop. """
     return 100 if getsession().user.is_sysop else 30
示例#36
0
文件: door.py 项目: splaice/x84
 def numcalls(self):
     """ Number of calls by user. """
     return getsession().user.calls
示例#37
0
 def session(self):
     """ Session associated with this terminal. """
     if self._session is None:
         from x84.bbs.session import getsession
         self._session = getsession()
     return self._session
示例#38
0
文件: door.py 项目: splaice/x84
 def fullname(self):
     """ User fullname. Returns ``<handle> <handle>``. """
     return '%s %s' % (
         getsession().user.handle,
         getsession().user.handle,)
示例#39
0
    def save(self, send_net=True, ctime=None):
        """
        Save message to database, recording 'tags' db.

        As a side-effect, it may queue message for delivery to
        external systems, when configured.
        """
        log = logging.getLogger(__name__)
        session = getsession()
        use_session = bool(session is not None)
        new = self.idx is None or self._stime is None

        # persist message record to MSGDB
        with DBProxy(MSGDB, use_session=use_session) as db_msg:
            if new:
                self.idx = max(map(int, db_msg.keys()) or [-1]) + 1
                if ctime is not None:
                    self._ctime = self._stime = ctime
                else:
                    self._stime = datetime.datetime.now()
                new = True
            db_msg['%d' % (self.idx, )] = self

        # persist message idx to TAGDB
        with DBProxy(TAGDB, use_session=use_session) as db_tag:
            for tag in db_tag.keys():
                msgs = db_tag[tag]
                if tag in self.tags and self.idx not in msgs:
                    msgs.add(self.idx)
                    db_tag[tag] = msgs
                    log.debug("msg {self.idx} tagged '{tag}'".format(self=self,
                                                                     tag=tag))
                elif tag not in self.tags and self.idx in msgs:
                    msgs.remove(self.idx)
                    db_tag[tag] = msgs
                    log.info("msg {self.idx} removed tag '{tag}'".format(
                        self=self, tag=tag))
            for tag in [_tag for _tag in self.tags if _tag not in db_tag]:
                db_tag[tag] = set([self.idx])

        # persist message as child to parent;
        assert self.parent not in self.children, ('circular reference',
                                                  self.parent, self.children)
        if self.parent is not None:
            try:
                parent_msg = get_msg(self.parent)
            except KeyError:
                log.warn('Child message {0}.parent = {1}: '
                         'parent does not exist!'.format(
                             self.idx, self.parent))
            else:
                if self.idx != parent_msg.idx:
                    parent_msg.children.add(self.idx)
                    parent_msg.save()
                else:
                    log.error('Parent idx same as message idx; stripping')
                    self.parent = None
                    with db_msg:
                        db_msg['%d' % (self.idx)] = self

        # persist message record to PRIVDB
        if 'public' not in self.tags:
            with DBProxy(PRIVDB, use_session=use_session) as db_priv:
                db_priv[self.recipient] = (db_priv.get(self.recipient, set())
                                           | set([self.idx]))

        # if either any of 'server_tags' or 'network_tags' are enabled,
        # then queue for potential delivery.
        if send_net and new and (get_ini(section='msg', key='network_tags')
                                 or get_ini(section='msg', key='server_tags')):
            self.queue_for_network()

        log.info(u"saved {new} {public_or_private} {message_or_reply}"
                 u", addressed to '{self.recipient}'.".format(
                     new='new ' if new else '',
                     public_or_private=('public' if 'public' in self.tags else
                                        'private'),
                     message_or_reply=('message'
                                       if self.parent is None else 'reply'),
                     self=self))
示例#40
0
 def session(self):
     """ Session associated with this terminal. """
     if self._session is None:
         from x84.bbs.session import getsession
         self._session = getsession()
     return self._session
示例#41
0
文件: door.py 项目: splaice/x84
 def alias(self):
     """ current session's handle. """
     return getsession().user.handle
示例#42
0
文件: door.py 项目: splaice/x84
 def usernum(self):
     """ User record number. """
     try:
         return list_users().index(getsession().user.handle)
     except ValueError:
         return 999
示例#43
0
文件: door.py 项目: splaice/x84
 def time_used(self):
     """ Time used (session duration) in seconds. """
     return int(time.time() - getsession().connect_time)
示例#44
0
文件: door.py 项目: splaice/x84
 def location(self):
     """ User location. """
     return getsession().user.location
示例#45
0
文件: terminal.py 项目: tehmaze/x84
 def session(self):
     if self._session is None:
         from x84.bbs.session import getsession
         self._session = getsession()
     return self._session