示例#1
0
def register(username=None, email=None, gpgkey=None):
    '''
    register kybyz account
    '''
    if gpgkey is None:
        gpgkey = verify_key(email)
    current = registration()  # see what we already have, if anything
    if username is None or email is None:
        logging.error('Usage: %s %s USERNAME EMAIL_ADDRESS', COMMAND, ARGS[0])
        raise ValueError('Must specify desired username and email address')
    if any(current):
        if (username, email, gpgkey) != current:
            raise ValueError('Previously registered as %s %s %s' % current)
        logging.warning('Already registered as %s %s %s', *current)
    else:
        os.makedirs(os.path.join(CACHE, gpgkey))
        os.symlink(os.path.join(CACHE, gpgkey), os.path.join(CACHE, email))
        os.symlink(os.path.join(CACHE, email), os.path.join(CACHE, username))
        os.symlink(os.path.join(CACHE, username), KYBYZ_HOME)
        logging.info('Now registered as %s %s %s', username, email, gpgkey)
        if CACHED.get('ircbot', None):
            CACHED['ircbot'].nick(username)
            CACHED['ircbot'].leave()  # rejoin to freshen CACHED['irc_id']
            CACHED['ircbot'].join()
        else:
            logging.info('registering outside of running application')
示例#2
0
def process(args):
    '''
    process a kybyz command
    '''
    if args and args[0] in COMMANDS:
        print(eval(args[0])(*args[1:]))  # pylint: disable=eval-used
    elif args:
        logging.error('must specify one of: %s', COMMANDS)
    else:
        logging.info('no command received to process')
示例#3
0
def background():
    '''
    load and maintain cache

    communicate with other kybyz servers
    '''
    delay = int(os.getenv('KB_DELAY') or 600)  # seconds
    CACHED['ircbot'] = IRCBot(nickname=CACHED.get('username', None))
    while True:
        logging.info('kybyz active %s seconds', CACHED['uptime'], **TO_PAGE)
        time.sleep(delay)  # releases the GIL for `serve`
        CACHED['uptime'] += delay
        logging.debug('CACHED: %s, threads: %s',
                      CACHED, threading.enumerate())
示例#4
0
def commandloop():
    '''
    simple repl (read-evaluate-process-loop) for command-line testing
    '''
    time.sleep(10)  # give page a chance to load before starting repl
    args = []
    logging.info('Ready to accept commands; `quit` to terminate input loop')
    while args[0:1] != ['quit']:
        try:
            print(process(args))
            args = shlex.split(input('kbz> '))
        except EXPECTED_ERRORS:
            logging.exception('command failed, please try again')
            args[:] = []
        except EOFError:
            break
    logging.warning('input loop terminated')
示例#5
0
def uwsgi_init():
    '''
    initialize uwsgi application
    '''
    # pylint: disable=import-error, bad-option-value, import-outside-toplevel
    logging.debug('beginning kybyz uwsgi initialization')
    import uwsgi
    if os.getenv('ANDROID_ROOT') is None:
        import webbrowser
    else:
        webbrowser = type(
            '',
            (),
            {'open': lambda url: subprocess.call(['am', 'start', url])}
        )
    port = host = None
    try:
        port = fromfd(uwsgi.sockets[0], AF_INET, SOCK_STREAM).getsockname()[1]
        host = 'localhost:%s' % port
    except AttributeError:
        logging.exception('cannot determine port')
    init()
    if not sys.stdin.isatty():
        logging.info('running as background process, will not launch browser')
    else:
        if host is not None and not os.getenv('WSL'):
            logging.debug('opening browser window to %s', host)
            webbrowser.open('http://%s' % host)
        else:
            logging.exception('cannot open browser to %s', host)
            logging.info("if you're running under WSL (Windows Subsystem for"
                         " Linux), just open Windows browser to %s", host)
    repl = threading.Thread(target=commandloop, name='repl')
    repl.daemon = True
    repl.start()
    logging.debug('uwsgi initialization complete')
示例#6
0
    def monitor(self):
        '''
        wait for input. send a PONG for every PING

        intended to run in a daemon thread

        set ircbot.terminate to True in order to shut it down
        '''
        logging.debug('ircbot monitoring incoming traffic')
        tries = 0
        while tries < 10:
            try:
                received = self.stream.readline().rstrip()
                tries = 0
            except ConnectionResetError:
                tries += 1
                self.connect(self.server, self.port, self.nickname,
                             self.realname)
                continue
            logging.info('received: %r, length: %d', received, len(received))
            end_message = len(received) < 510
            # make sure all words[n] references are accounted for
            words = received.split() + ['', '', '']
            nickname, matched = check_username(words[0])
            if words[0] == 'PING':
                pong = received.replace('I', 'O', 1).rstrip() + CRLF
                logging.info('sending: %r', pong)
                self.client.send(pong.encode())
            elif words[1] == 'JOIN' and matched:
                CACHED['irc_id'] = words[0]
                logging.info("CACHED['irc_id'] = %s", CACHED['irc_id'])
            elif words[1] == 'PRIVMSG':
                sender = nickname
                privacy = 'public' if words[2] == CHANNEL else 'private'
                logging.info('%s message received from %s:', privacy, sender)
                # chop preceding ':' from ':this is a private message'
                CACHED[sender] += ' '.join(words[3:])[1:].rstrip()
                # try decoding what we have so far
                logging.debug('attempting to decode %s', CACHED[sender])
                text, trustlevel = decrypt(CACHED[sender].encode())
                logging.debug('text: %s, trustlevel: %s', text, trustlevel)
                if text or end_message:
                    text = text or CACHED[sender][:256].encode()
                    logging.info(
                        '%s %s message from %s: %s', trustlevel, privacy,
                        sender,
                        text.decode().replace('<',
                                              '&lt;').replace('>', '&gt;'),
                        **TO_PAGE)
                    if JSON.match(CACHED[sender]):
                        POSTS_QUEUE.append(CACHED[sender])
                        logging.debug('appended %r to POSTS_QUEUE',
                                      CACHED[sender])
                    else:
                        logging.debug('Not JSON: %s', CACHED[sender])
                    CACHED[sender] = ''
                elif len(CACHED[sender]) > MAXSIZE:
                    logging.info(
                        'clearing overflow CACHED[%s]: %r..., length %d',
                        sender, CACHED[sender][:256], len(CACHED[sender]))
                    CACHED[sender] = ''
                else:
                    logging.debug('CACHED[%s] now %r', sender, CACHED[sender])
            clearcache()
        logging.warning('ircbot terminated from launching thread')