コード例 #1
0
ファイル: app.py プロジェクト: ant9000/webtg
def handle_websocket(ws):
    if not ws:
        bottle.abort(400, 'Expected WebSocket request.')

    logger.debug(ws)

    session = bottle.request.environ.get('beaker.session', {})
    username = session.get('username', 'anonymous')

    response = {
        'event':  "session.state",
        'result': "FAIL",
        'status': "not authenticated",
    }
    if username != 'anonymous' or \
            bottle.request.remote_addr == '127.0.0.1':
        web_clients[ws] = { 'username': username, 'lock': threading.Lock() }
        response = {
            'event':    "session.state",
            'result':   "SUCCESS",
            'status':   "connected",
            'username': username,
        }
        protected_ws_send(ws, response)
    else:
        ws.send(json.dumps(response))
        bottle.abort(401, 'Unauthorized.')
        return

    while True:
        try:
            msg = ws.receive()
            if msg is None:
                continue

            logger.debug('%s@%s %s', username, bottle.request.remote_addr, msg)

            data = DictObject()
            try:
                data = DictObject(json.loads(msg))
            except Exception, e:
                logger.exception('message is not valid json data: %s', e)
                continue
            logger.debug('<%s', data)

            response = DictObject()

            channel, command = data.event.split('.',1)
            if channel == 'session':
                if command == 'state':
                    response.result   = "SUCCESS"
                    response.status   = "connected"
                    response.username = username
                else:
                    logger.error("unknown command '%s'", command)
            elif channel == 'telegram':
                cmd = getattr(tg.sender, command, None)
                if cmd:
                    try:
                        response = cmd(*data.get('args',[]))
                        logger.debug('>%s', response)
                        if type(response) != DictObject:
                            response = DictObject({ 'contents': response })

                        if command == 'dialog_list':
                            for c in response['contents']:
                                last_message = tg.sender.history('%s#%s' % (c.peer_type, c.peer_id), 1)
                                if len(last_message):
                                    c.last_timestamp = last_message[0].date
                                if c.peer_type == 'chat':
                                    info = tg.sender.chat_info('%s#%s' % (c.peer_type, c.peer_id))
                                    c.update(info)
                                elif c.peer_type == 'channel':
                                    try:
                                        admins = tg.sender.channel_get_admins('%s#%s' % (c.peer_type, c.peer_id))
                                        members = tg.sender.channel_get_members('%s#%s' % (c.peer_type, c.peer_id))
                                        c.own = True
                                        for m in members:
                                            if m in admins:
                                                m.admin = True
                                        c.members = members
                                    except IllegalResponseException:
                                        pass
                        elif command == 'history':
                            if response.get('contents'):
                                has_media = False
                                for msg in response['contents']:
                                    if msg.get('media',''):
                                        has_media = True 
                                        msg.media.complete = False
                                if has_media:
                                    threading.Thread(target=history_download_media, args=(ws, data, response)).start()
                    except NoResponse as e:
                        logger.warning('%s', e)
                    except Exception as e:
                        logger.exception('%s', e)
                else:
                    logger.error("unknown command '%s'", command)
            else:
                logger.error("unknown channel '%s'", channel)

            if response:
                response.event = data.event
                if data.get('args'):
                    response.args = data.args
                if data.get('extra'):
                    response.extra = data.extra
                protected_ws_send(ws,response)

        except WebSocketError:
            if ws in web_clients:
                del web_clients[ws]
            break