Esempio n. 1
0
        conn = self.conn
        id_list = conn.search(None, '(UNSEEN)')[1][0].split()
        try:
            email_id = id_list[i]
        except IndexError:
            return None
        data = conn.fetch(email_id, '(BODY.PEEK[HEADER.FIELDS (SUBJECT)])')[1]
        # if not PY3:
        msg = message_from_string(data[0][1])
        s, encoding = decode_header(msg['Subject'])[0]
        subject = s.decode(encoding or 'utf-8').encode('utf-8')
        return subject


if __name__ == '__main__':
    from qqbot.qconf import QConf

    conf = QConf(['-u', 'xxx'])
    conf.Display()

    ma = MailAgent(conf.mailAccount, conf.mailAuthCode)

    with ma.SMTP() as s:
        s.send(conf.mailAccount, 'hello', 'faf房间多啦')
    print('send ok')

    with ma.IMAP() as i:
        subject = i.getSubject(-1)
        print('latest email: ' + str(subject))
    print('recv ok')
Esempio n. 2
0
class QQBot(GroupManager, TermBot):

    def Login(self, argv=None):
        self.init(argv)
        session, contactdb = QLogin(self.conf)
        self.session, self.contactdb = session, contactdb

        # main thread
        self.SendTo = session.Copy().SendTo
        self.groupKick = session.GroupKick
        self.groupSetAdmin = session.GroupSetAdmin
        self.groupShut = session.GroupShut
        self.groupSetCard = session.GroupSetCard
        
        # main thread
        self.List = contactdb.List
        self.Update = contactdb.Update
        self.StrOfList = contactdb.StrOfList
        self.ObjOfList = contactdb.ObjOfList
        self.findSender = contactdb.FindSender
        self.firstFetch = contactdb.FirstFetch
        self.Delete = contactdb.db.Delete
        self.Modify = contactdb.db.Modify
        
        # child thread 1
        self.poll = session.Copy().Poll

    def Run(self):
        if self.conf.startAfterFetch:
            self.firstFetch()

        self.onPlug()
        self.onStartupComplete()
        
        # child thread 1~4
        StartDaemonThread(self.pollForever)
        StartDaemonThread(self.intervalForever)
        StartDaemonThread(QTermServer(self.conf.termServerPort, self.onTermCommand).Run)
        self.scheduler.start()

        self.started = True
        
        try:
            MainLoop()
        except SystemExit as e:
            self.onExit(e.code, getReason(e.code), None)
            raise
        except Exception as e:
            ERROR('', exc_info=True)
            ERROR('Mainloop 发生未知错误:%r', e)
            self.onExit(1, 'unknown-error', e)
            raise SystemExit(1)
    
    def Stop(self):
        sys.exit(0)
    
    def Restart(self):
        sys.exit(RESTART)
    
    def FreshRestart(self):
        sys.exit(FRESH_RESTART)
    
    # child thread 1
    def pollForever(self):
        while True:
            try:
                result = self.poll()
            except RequestError:
                Put(sys.exit, LOGIN_EXPIRE)
                break
            except:
                ERROR('qsession.Poll 方法出错', exc_info=True)
            else:
                Put(self.onPollComplete, *result)

    def onPollComplete(self, ctype, fromUin, membUin, content):
        if ctype == 'timeout':
            return

        contact, member, nameInGroup = \
            self.findSender(ctype, fromUin, membUin, self.conf.qq, content)
        
        if contact.ctype == 'group' and member == 'SYSTEM-MESSAGE':
            INFO('来自 %s 的系统消息: "%s"', contact, content)
            return

        if self.detectAtMe(nameInGroup, content):
            INFO('有人 @ 我:%s[%s]' % (contact, member))
            content = '[@ME] ' + content.replace('@'+nameInGroup, '')
        else:
            content = content.replace('@ME', '@Me')
                
        if ctype == 'buddy':
            INFO('来自 %s 的消息: "%s"' % (contact, content))
        else:
            INFO('来自 %s[%s] 的消息: "%s"' % (contact, member, content))

        self.onQQMessage(contact, member, content)
    
    def detectAtMe(self, nameInGroup, content):
        return nameInGroup and ('@'+nameInGroup) in content

    # child thread 2
    def intervalForever(self):
        while True:
            time.sleep(300)
            Put(self.onInterval)
    
    def __init__(self):        
        self.scheduler = BackgroundScheduler(daemon=True)
        self.schedTable = defaultdict(list)
        self.slotsTable = {
            'onInit': [],
            'onQrcode': [],
            'onStartupComplete': [],
            'onQQMessage': [],
            'onInterval': [],
            'onUpdate': [],
            'onPlug': [],
            'onUnplug': [],
            'onExit': [],
        }
        self.started = False
        self.plugins = {}
    
    def init(self, argv):
        for name, slots in self.slotsTable.items():
            setattr(self, name, self.wrap(slots))

        self.conf = QConf(argv)
        self.conf.Display()

        for pluginName in self.conf.plugins:
            self.Plug(pluginName)
        
        self.onInit()       
    
    def wrap(self, slots):
        def func(*args, **kwargs):
            for f in slots:
                _call(f, self, *args, **kwargs)
        return func
    
    def AddSlot(self, func):
        self.slotsTable[func.__name__].append(func)
        return func

    def AddSched(self, **triggerArgs):
        def wrapper(func):
            job = lambda: Put(_call, func, self)
            job.__name__ = func.__name__
            j = self.scheduler.add_job(job, 'cron', **triggerArgs)
            self.schedTable[func.__module__].append(j)
            return func
        return wrapper
    
    def unplug(self, moduleName, removeJob=True):
        for slots in self.slotsTable.values():
            i = 0
            while i < len(slots):
                if slots[i].__module__ == moduleName:
                    slots[i] = slots[-1]
                    slots.pop()
                else:
                    i += 1

        if removeJob:
            for job in self.schedTable.pop(moduleName, []):
                job.remove()
            self.plugins.pop(moduleName, None)
    
    def Plug(self, moduleName):
        self.unplug(moduleName)
        try:
            module = Import(moduleName)
        except Exception as e:
            result = '错误:无法加载插件 %s ,%s: %s' % (moduleName, type(e), e)
            ERROR('', exc_info=True)
            ERROR(result)
            self.unplug(moduleName)
        else:
            self.unplug(moduleName, removeJob=False)

            names = []
            for slotName in self.slotsTable.keys():
                if hasattr(module, slotName):
                    self.slotsTable[slotName].append(getattr(module, slotName))
                    names.append(slotName)

            if (not names) and (moduleName not in self.schedTable):
                result = '警告:插件 %s 中没有定义回调函数或定时任务' % moduleName
                WARN(result)
            else:
                self.plugins[moduleName] = module
                    
                jobs = self.schedTable.get(moduleName, [])
                jobNames = [f.func.__name__ for f in jobs]
                result = '成功:加载插件 %s(回调函数%s、定时任务%s)' % \
                         (moduleName, names, jobNames)
                INFO(result)

                if self.started and hasattr(module, 'onPlug'):
                    _call(module.onPlug, self)

        return result
    
    def Unplug(self, moduleName):
        if moduleName not in self.plugins:
            result = '警告:试图卸载未安装的插件 %s' % moduleName
            WARN(result)
            return result
        else:
            module = self.plugins[moduleName]
            self.unplug(moduleName)
            if hasattr(module, 'onUnplug'):
                _call(module.onUnplug, self)
            result = '成功:卸载插件 %s' % moduleName
            INFO(result)
            return result
    
    def Plugins(self):
        return list(self.plugins.keys())