Exemple #1
0
    def _handle_tcp_stream(self, tcp):
        ((shost, sport), (dhost, dport)) = tcp.addr

        if tcp.nids_state == nids.NIDS_JUST_EST:
            if dport in (80, 8000, 8080, 443, 8888):
                tcp.client.collect = 1
                tcp.server.collect = 1

        elif tcp.nids_state == nids.NIDS_DATA:
            # keep all of the stream's new data
            tcp.discard(0)

        elif tcp.nids_state in _END_STATES:

            ddata = tcp.server.data[:tcp.server.count]
            sdata = tcp.client.data[:tcp.client.count]
            
            # Parse la data del stream tcp y genero todos los
            # http_streams que sean necesarios
            http_streams = HTTPStream.create_streams(
                shost, sport, sdata,
                dhost, dport, ddata)
            
            for http_stream in http_streams:
                self._callback(http_stream)
Exemple #2
0
    def __init__(self, qid, pwd):
        self.qid = qid               # QQ 号
        self.__pwd = pwd             # QQ密码
        self.nickname = None         # 初始化QQ昵称
        self.http_stream = HTTPStream.instance()       # HTTP 流
        self.msg_dispatch = MessageDispatch(self)

        self.aid = 1003903                                    # aid 固定
        self.clientid = random.randrange(11111111, 99999999)  # 客户端id 随机固定
        self.msg_id = random.randrange(1111111, 99999999)     # 消息id, 随机初始化

        self.require_check = False   # 是否需要验证码
        self.poll_and_heart = False  # 开始拉取消息和心跳

        # 初始化WebQQ登录期间需要保存的数据
        self.check_code = None
        self.skey = None
        self.ptwebqq = None

        self.check_data = None       # 初始化检查时返回的数据
        self.blogin_data = None      # 初始化登录前返回的数据

        self.friend_info = {}        # 初始化好友列表
        self.group_info = {}         # 初始化组列表
        self.group_members_info = {} # 初始化组成员列表

        self.hb_time = int(time.time() * 1000)

        self.login_time = None       # 登录的时间
        self.last_group_msg_time = time.time()
        self.last_msg_content = None
        self.last_msg_numbers = 0    # 剩余位发送的消息数量
Exemple #3
0
    def __init__(self, qid, pwd):
        self.qid = qid  # QQ 号
        self.__pwd = pwd  # QQ密码
        self.nickname = None  # 初始化QQ昵称
        self.http_stream = HTTPStream.instance()  # HTTP 流
        self.msg_dispatch = MessageDispatch(self)

        self.aid = 1003903  # aid 固定
        self.clientid = random.randrange(11111111, 99999999)  # 客户端id 随机固定
        self.msg_id = random.randrange(1111111, 99999999)  # 消息id, 随机初始化

        self.require_check = False  # 是否需要验证码
        self.poll_and_heart = False  # 开始拉取消息和心跳

        # 初始化WebQQ登录期间需要保存的数据
        self.check_code = None
        self.skey = None
        self.ptwebqq = None

        self.check_data = None  # 初始化检查时返回的数据
        self.blogin_data = None  # 初始化登录前返回的数据

        self.friend_info = {}  # 初始化好友列表
        self.group_info = {}  # 初始化组列表
        self.group_members_info = {}  # 初始化组成员列表

        self.hb_time = int(time.time() * 1000)

        self.login_time = None  # 登录的时间
        self.last_group_msg_time = time.time()
        self.last_msg_content = None
        self.last_msg_numbers = 0  # 剩余位发送的消息数量
Exemple #4
0
 def __init__(self, message_bus):
     self._message_bus = message_bus   # 消息总线
     self._logger = get_logger()       # 日志
     self._http_stream = HTTPStream.instance()
Exemple #5
0
class Command(object):
    http_stream = HTTPStream.instance()

    def url_info(self, url, callback, isredirect=False):
        """ 获取url信息
        Arguments:
            `url`   -   链接
            `callback`  -   发送消息的回调
            `isredirect` -   是否是重定向
        """
        request = self.http_stream.make_get_request(url)
        _url_info = partial(self._url_info,
                            callback=callback,
                            url=url,
                            isredirect=isredirect)
        _eurl_info = partial(self._eurl_info, callback=callback, url=url)
        self.http_stream.add_request(request, _url_info, _eurl_info)

    def _url_info(self, resp, callback, url, isredirect=False):
        """ 读取url_info的回调 """
        meta_charset = re.compile(
            br'<meta\s+http-equiv="?content-type"?'
            '\s+content="?[^;]+;\s*charset=([^">]+'
            ')"?\s*/?>|<meta\s+charset="?([^">/"]+'
            ')"?\s*/?>', re.IGNORECASE)
        body = ""
        content = resp.read()
        c_type = resp.headers.get("Context-Type", "text/html")
        if resp.code in [200]:
            if c_type == "text/html":
                charset = meta_charset.findall(content)
                logging.info("Found charset {0!r} in url {1}".format(
                    charset, url))
                if len(charset) == 1 and len(charset[0]) == 2:
                    charset = charset[0][0] if charset[0][0] else charset[0][1]
                else:
                    charset = ""

                if charset.lower().strip() == "gb2312":
                    charset = "gbk"

                if charset:
                    ucont = content.lower().decode(charset).encode(
                        "utf-8").decode("utf-8")
                else:
                    ucont = content.lower().decode("utf-8")
                parser = etree.HTML(ucont)
                title = parser.xpath(u"//title")
                title = title[0].text if len(title) >= 1 else None
                if title:
                    body += u"网页标题: " + title.replace("\r", "").replace(
                        "\n", "")
                if isredirect:
                    body += u"(重定向到:{0})".format(url)
        elif resp.code in [302, 301]:
            dst = resp.headers.get("Location")
            self.url_info(dst, callback, True)
        else:
            body = u"({0} {1} {2})".format(url, resp.code,
                                           httplib.responses[resp.code])

        if body:
            callback(body)

    def _eurl_info(self, errcode, errmsg, url, callback):
        """ 处理url_info错误 """
        body = u"({0} {1})".format(url, errmsg)
        callback(body)

    def py(self, code, callback):
        """ 执行Python代码
        Arguments:
            `code`      -   要执行的代码
            `callback`  -   发送消息的回调
        """
        url = "http://pythonec.appspot.com/run"
        #url = "http://localhost:8080/run"
        params = [("code", code.encode("utf-8"))]

        request = self.http_stream.make_post_request(url, params)
        read_py = partial(self.read_py, callback=callback)
        self.http_stream.add_request(request, read_py)

    def read_py(self, resp, callback):
        """ 读取执行Python代码的返回 """
        data = resp.read()
        try:
            result = json.loads(data)
            status = result.get("status")
            if status:
                content = u"OK: " + result.get("out")
            else:
                content = u"ERR: " + result.get("err")

        except ValueError:
            content = u"我出错了, 没办法执行, 我正在改"
        callback(content)

    def shell(self, session, statement, callback):
        """ 实现Python Shell
        Arguments:
            `session`   -   区别用户的shell
            `statement` -   Python语句
            `callback`  -   发送结果的回调
        """
        if statement.strip() in ["cls", "clear"]:
            url = "http://pythonec.appspot.com/drop"
            params = [
                ("session", session),
            ]
        else:
            url = "http://pythonec.appspot.com/shell"
            #url = "http://localhost:8080/shell"
            params = [("session", session),
                      ("statement", statement.encode("utf-8"))]
        request = self.http_stream.make_get_request(url, params)

        def read_shell(resp, callback):
            data = resp.read()
            if not data:
                data = "OK"
            callback(data.decode("utf-8"))
            return

        self.http_stream.add_request(request,
                                     partial(read_shell, callback=callback))

    def paste(self, code, callback, typ="text"):
        """ 贴代码 """
        url = "http://paste.linuxzen.com"
        params = [("class", typ), ("code", code.encode("utf-8")),
                  ("paste", "ff")]

        request = self.http_stream.make_post_request(url, params)
        read_back = partial(self.read_paste, oldurl=url, callback=callback)

        self.http_stream.add_request(request, read_back)

    def read_paste(self, resp, oldurl, callback):
        """ 读取贴代码结果, 并发送消息 """
        if resp.code == 302:
            url = resp.headers.get("Location")
        else:
            url = resp.url
        if url != oldurl:
            content = url
            callback(content)

    def cetr(self, source, callback, web=False):
        """ 调用有道接口进行英汉互译 """
        key = YOUDAO_KEY
        keyfrom = YOUDAO_KEYFROM
        source = source.encode("utf-8")
        url = "http://fanyi.youdao.com/openapi.do"
        params = [("keyfrom", keyfrom), ("key", key), ("type", "data"),
                  ("doctype", "json"), ("version", 1.1), ("q", source)]

        request = self.http_stream.make_get_request(url, params)
        read_back = partial(self.read_cetr, callback=callback, web=web)
        self.http_stream.add_request(request, read_back)

    def read_cetr(self, resp, callback, web):
        """ 读取英汉翻译的结果 """
        source = resp.read()
        body = None
        try:
            buf = StringIO(source)
            with gzip.GzipFile(mode="rb", fileobj=buf) as gf:
                data = gf.read()
        except:
            data = source

        try:
            result = json.loads(data)
        except ValueError:
            body = u"error"
        else:
            errorCode = result.get("errorCode")
            if errorCode == 0:
                query = result.get("query")
                r = " ".join(result.get("translation"))
                basic = result.get("basic", {})
                body = u"{0}\n{1}".format(query, r)
                phonetic = basic.get("phonetic")
                if phonetic:
                    ps = phonetic.split(",")
                    if len(ps) == 2:
                        pstr = u"读音: 英 [{0}] 美 [{1}]".format(*ps)
                    else:
                        pstr = u"读音: {0}".format(*ps)
                    body += u"\n" + pstr

                exp = basic.get("explains")
                if exp:
                    body += u"\n其他释义:\n\t{0}".format(u"\n\t".join(exp))

                if web:
                    body += u"\n网络释义:\n"
                    web = result.get("web", [])
                    if web:
                        for w in web:
                            body += u"\t{0}\n".format(w.get("key"))
                            vs = u"\n\t\t".join(w.get("value"))
                            body += u"\t\t{0}\n".format(vs)

            if errorCode == 50:
                body = u"无效的有道key"

        if not body:
            body = u"没有结果"

        callback(body)

    def send_msg(self, msg, callback, nick=None):
        if len(msg) <= MAX_LENGTH:
            body = nick + msg if nick else msg
            callback(body)
        else:
            callback = partial(self.send_msg, callback=callback, nick=nick)
            self.paste(msg, callback)
Exemple #6
0
 def __init__(self, message_bus):
     self._message_bus = message_bus  # 消息总线
     self._logger = get_logger()  # 日志
     self._http_stream = HTTPStream.instance()
Exemple #7
0
class Command(object):
    http_stream = HTTPStream.instance()
    _sim_try = {}
    simsimi_proxy = False

    def url_info(self, url, callback, isredirect = False):
        """ 获取url信息
        Arguments:
            `url`   -   链接
            `callback`  -   发送消息的回调
            `isredirect` -   是否是重定向
        """
        _url_info = partial(self._url_info, callback = callback, url = url,
                            isredirect = isredirect)
        _eurl_info = partial(self._eurl_info, callback = callback, url = url)
        self.http_stream.get(url, readback = _url_info, errorback = _eurl_info)


    def _url_info(self, resp, callback, url, isredirect = False):
        """ 读取url_info的回调 """
        meta_charset = re.compile(br'<meta\s+http-equiv="?content-type"?'
                                  '\s+content="?[^;]+;\s*charset=([^">]+'
                                  ')"?\s*/?>|<meta\s+charset="?([^">/"]+'
                                  ')"?\s*/?>', re.IGNORECASE)
        body = ""
        content = resp.read()
        c_type =  resp.headers.get("Context-Type", "text/html")
        if resp.code in [200]:
            if c_type == "text/html":
                charset = meta_charset.findall(content)
                logging.info("Found charset {0!r} in url {1}".format(charset, url))
                if len(charset) == 1 and len(charset[0]) == 2:
                    charset = charset[0][0] if charset[0][0] else charset[0][1]
                else:
                    charset = ""

                if charset.lower().strip() == "gb2312":
                    charset = "gbk"

                if charset:
                    ucont = content.lower().decode(charset).encode("utf-8").decode("utf-8")
                else:
                    ucont = content.lower().decode("utf-8")
                parser = etree.HTML(ucont)
                title = parser.xpath(u"//title")
                title = title[0].text if len(title) >= 1 else None
                if title:
                    body += u"网页标题: "+title.replace("\r", "").replace("\n", "")
                if isredirect:
                    body += u"(重定向到:{0})".format(url)
        elif resp.code in [302, 301]:
            dst = resp.headers.get("Location")
            self.url_info(dst, callback, True)
        else:
            body = u"({0} {1} {2})".format(url, resp.code,
                                         httplib.responses[resp.code])

        if body:
            callback(body)


    def _eurl_info(self, errcode, errmsg, url, callback):
        """ 处理url_info错误 """
        body = u"({0} {1})".format(url, errmsg)
        callback(body)


    def py(self, code, callback):
        """ 执行Python代码
        Arguments:
            `code`      -   要执行的代码
            `callback`  -   发送消息的回调
        """
        url = "http://pythonec.appspot.com/run"
        #url = "http://localhost:8080/run"
        params = [("code", code.encode("utf-8"))]

        read_py = partial(self.read_py, callback = callback)
        self.http_stream.post(url, params, readback = read_py)

    def read_py(self, resp, callback):
        """ 读取执行Python代码的返回 """
        data = resp.read()
        try:
            result = json.loads(data)
            status = result.get("status")
            if status:
                content = u"OK: " + result.get("out")
            else:
                content = u"ERR: " + result.get("err")

        except ValueError:
            logging.warn(traceback.format_exc())
            content = u"我出错了, 没办法执行, 我正在改"
        callback(content)


    def shell(self, session, statement, callback):
        """ 实现Python Shell
        Arguments:
            `session`   -   区别用户的shell
            `statement` -   Python语句
            `callback`  -   发送结果的回调
        """
        if statement.strip() in ["cls", "clear"]:
            url = "http://pythonec.appspot.com/drop"
            params = [("session", session),]
        else:
            url = "http://pythonec.appspot.com/shell"
            #url = "http://localhost:8080/shell"
            params = [("session", session),
                    ("statement", statement.encode("utf-8"))]

        def read_shell(resp, callback):
            data = resp.read()
            if not data:
                data = "OK"
            callback(data.decode("utf-8"))
            return
        read_back = partial(read_shell, callback = callback)
        self.http_stream.get(url, params, readback = read_back)


    def paste(self, code, callback, typ = "text"):
        """ 贴代码 """
        url = "http://paste.linuxzen.com"
        params = [("class", typ), ("code", code.encode("utf-8")), ("paste", "ff")]

        read_back = partial(self.read_paste, oldurl = url, callback = callback)
        self.http_stream.post(url, params, readback = read_back)


    def read_paste(self, resp, oldurl, callback):
        """ 读取贴代码结果, 并发送消息 """
        if resp.code == 302:
            url = resp.headers.get("Location")
        else:
            url = resp.url
        if url != oldurl:
            content = url
            callback(content)


    def teach(self, say, response):
        url = "http://paste.linuxzen.com/bot/teach"
        params = (("say", say.encode("utf-8")), ("res", response.encode("utf-8")))
        logging.info(u"Teach our bot {0}/{1}".format(say, response))
        self.http_stream.get(url, params)


    def simsimi(self, content, callback):
        """ simsimi 小黄鸡 """
        msg_url = "http://www.simsimi.com/func/req"
        msg_params = (("msg", content.encode("utf-8")), ("lc", "ch"))
        headers = {"Referer": "http://www.simsimi.com/talk.htm?lc=ch",
                   "X-Requested-With": "XMLHttpRequest"}

        def read_simsimi(resp):
            result = resp.read()
            if result:
                try:
                    response = json.loads(result)
                    res = response.get("response")

                    if is_black_msg(res):
                        return self.simsimi(content, callback)

                    if not res or (res and res.startswith("Unauthorized access!.")):
                        if not self._sim_try.has_key(content):
                            self._sim_try[content] = 0
                        if self._sim_try.get(content) < 10:
                            logging.warn("SimSimi error with response {0}".format(res))
                            self._sim_try[content] += 1
                            self.simsimi(content, callback)
                        else:
                            self._sim_try[content] = 0
                            callback(u"T^T ip被SimSimi封了, 无法应答")
                        return
                    else:
                        self._sim_try[content] = 0
                        callback(res)
                        self.teach(content, res)
                except ValueError:
                    logging.warn(traceback.format_exc())
                    logging.warn("SimSimi error with response {0}".format(result))
                    self.simsimi(content, callback)

        kw = {"headers":headers, "readback":read_simsimi}
        if SimSimi_Proxy:
            kw.update(proxy=SimSimi_Proxy)

        self.http_stream.get(msg_url, msg_params, **kw)


    def cetr(self, source, callback,  web = False):
        """ 调用有道接口进行英汉互译 """
        key = YOUDAO_KEY
        keyfrom = YOUDAO_KEYFROM
        source = source.encode("utf-8")
        url = "http://fanyi.youdao.com/openapi.do"
        params = [("keyfrom", keyfrom), ("key", key),("type", "data"),
                  ("doctype", "json"), ("version",1.1), ("q", source)]

        read_back = partial(self.read_cetr, callback = callback, web = web)
        self.http_stream.get(url, params, readback =read_back)


    def read_cetr(self, resp, callback, web):
        """ 读取英汉翻译的结果 """
        source = resp.read()
        body = None
        try:
            buf = StringIO(source)
            with gzip.GzipFile(mode = "rb", fileobj = buf) as gf:
                data = gf.read()
        except:
            logging.warn(traceback.format_exc())
            data = source

        try:
            result = json.loads(data)
        except ValueError:
            logging.warn(traceback.format_exc())
            body = u"error"
        else:
            errorCode = result.get("errorCode")
            if errorCode == 0:
                query = result.get("query")
                r = " ".join(result.get("translation"))
                basic = result.get("basic", {})
                body = u"{0}\n{1}".format(query, r)
                phonetic = basic.get("phonetic")
                if phonetic:
                    ps = phonetic.split(",")
                    if len(ps) == 2:
                        pstr = u"读音: 英 [{0}] 美 [{1}]".format(*ps)
                    else:
                        pstr = u"读音: {0}".format(*ps)
                    body += u"\n" + pstr

                exp = basic.get("explains")
                if exp:
                    body += u"\n其他释义:\n\t{0}".format(u"\n\t".join(exp))

                if web:
                    body += u"\n网络释义:\n"
                    web = result.get("web", [])
                    if web:
                        for w in web:
                            body += u"\t{0}\n".format(w.get("key"))
                            vs = u"\n\t\t".join(w.get("value"))
                            body += u"\t\t{0}\n".format(vs)

            if errorCode == 50:
                body = u"无效的有道key"

        if not body:
            body = u"没有结果"

        callback(body)

    def send_msg(self, msg, callback, nick = None):
        if len(msg) <= MAX_LENGTH:
            body = nick + msg if nick else msg
            callback(body)
        else:
            callback = partial(self.send_msg, callback = callback, nick = nick)
            self.paste(msg, callback)