예제 #1
0
def send_email(to_whom_list, title, content):
    msg = email.mime.multipart.MIMEMultipart()
    msg['from'] = EMAIL_HOST
    msg['to'] = ";".join(to_whom_list)
    msg['subject'] = title
    txt = email.mime.text.MIMEText(content)
    msg.attach(txt)

    have_exception = False
    try:
        smtp = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT)
        smtp.login(EMAIL_HOST, EMAIL_PASS)
        result = smtp.sendmail(EMAIL_HOST, to_whom_list, str(msg))
    except Exception as e:
        ERROR('exception when send_email...')
        ERROR(str(e))
        have_exception = True
    finally:
        smtp.quit()
        if have_exception:
            ERROR('finally raise e: {0}'.format(str(e)))
            raise e
        else:
            INFO('finally no exception raise')
    return result
예제 #2
0
파일: miraiapi.py 프로젝트: MDeath/qqbot
 def ErrorCode(self, code):
     if code == 1:
         ERROR('错误的verify key')
         self.verifyKey = input('verifyKey:')
     elif code == 2:
         ERROR('指定的Bot不存在')
         self.qq = int(input('qq:'))
     elif code == 3:
         WARNING('Session失效或不存在')
         self.Verify()
         return 1
     elif code == 4:
         WARNING('Session未认证(未激活)')
         self.Bind()
         return 1
     elif code == 5:
         WARNING('发送消息目标不存在(指定对象不存在)')
     elif code == 6:
         WARNING('指定文件不存在,出现于发送本地图片')
     elif code == 10:
         WARNING('无操作权限,指Bot没有对应操作的限权')
     elif code == 20:
         WARNING('Bot被禁言,指Bot当前无法向指定群发送消息')
     elif code == 30:
         WARNING('消息过长')
     elif code == 400:
         WARNING('错误的访问,如参数错误等')
     return 0
예제 #3
0
    def send(self, to_whom_list, title, content):
        """发送邮件的主体逻辑:
        1)待发送邮件=以前发送失败的+现在要发送的
        2)逐封邮件发送(可能需要调整一个发送间隔,因为太快连续发送,会导致邮件服务器拒绝服务;
        3)收集这一次发送失败的邮件;
        4)清空原来的“发送失败”数据库,把新的数据保存进去。
        """
        emails_to_send = self.db.get_all()  # 以前发送失败的邮件
        if len(emails_to_send) > 0:
            INFO('有{0}封发送失败的邮件'.format(len(emails_to_send)))
        # 由于收件人是一个列表,对于数据库的一个字段,所以需要存入时先序列化为字符串,读取则反过来
        for i in range(0, len(emails_to_send)):
            emails_to_send[i][0] = emails_to_send[i][0].splite(self.delimiter)
        emails_to_send.append([to_whom_list, title, content])
        now_fail_emails = []  # 当前发送失败的邮件列表

        for email in emails_to_send:
            try:
                result = send_email(email[0], email[1], email[2])
            except Exception as e:
                result = str(e)
                ERROR('smtplib error happend.......................')
                ERROR('send_result:{0}'.format(result))
            INFO('send_result:{0}'.format(result))
            if len(result) > 0:
                now_fail_emails.append(email)

        self.db.delete_all()
        INFO("fail:{0} ".format(len(now_fail_emails)))
        for email in now_fail_emails:
            email[0] = self.delimiter.join(email[0])
            self.db.insert(email)
        return len(now_fail_emails) == 0
    def getTargetContent(self):
        """获取指定页面的目标内容:
        1)指定页面由SinglePageSpider获取;
        2)目标内容由正则表达式匹配得到。

        Returns: a list of update chapters' relative path and its title
        such as [('http://dazhuzai.net.cn/dazhuzai-1309.html', 'title 1'), ]
        """
        try:
            page = SinglePageSpider().getPage(self.url, self.coding)
            result = re.findall(self.pattern, page)
            if result:
                if self.url_prefix:
                    for i in range(len(result)):
                        chapter_url = self.url_prefix + result[i][0]
                        if len(result[i]) >= 3:
                            data = result[i][1:len(result[i])]
                            chapter_title = '  '.join(reversed(data))
                        else:
                            chapter_title = result[i][1]
                        result[i] = (chapter_url, chapter_title)
                INFO('正则匹配成功:{0}{1}'.format(len(result), self.tips))
                return result
            else:
                INFO('!!!!!!!!!!正则匹配size = 0!!!!!!!!!!!')
                return None
        except Exception as e:
            ERROR('-------获取网页失败:-------')
            ERROR(e)
            return None
예제 #5
0
    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
                WARNING(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.Mirai.started and hasattr(module, 'onPlug'):
                    _call(module.onPlug, self)

        return result
예제 #6
0
파일: miraiapi.py 프로젝트: MDeath/qqbot
def Get(*args, **kwargs):
    while True:
        try:
            return requests.get(*args, **kwargs)
        except requests.exceptions.ConnectionError:
            ERROR('无法连接倒Mirai,请检查服务、地址、端口。')
        except:
            raise RequestError
예제 #7
0
    def Run(self):
        self.onStartupComplete()
        self.onPlug()

        StartDaemonThread(self.pollForever)
        StartDaemonThread(self.intervalForever)
        self.scheduler.start()
        Put(self.Update)

        try:
            MainLoop()
        except SystemExit as e:
            raise
        except Exception as e:
            ERROR('', exc_info=True)
            ERROR('Mainloop 发生未知错误:%r', e)
            self.onExit(1, 'unknown-error', e)
            raise SystemExit(1)
예제 #8
0
 def pollForever(self):
     while self.Mirai.started:
         try:
             result = self.Mirai.GetMessage()
         except RequestError:
             Put(sys.exit)
             break
         except:
             ERROR('qsession.Poll 方法出错', exc_info=True)
         else:
             if not result: continue
             for r in result:
                 Put(self.MessageAnalyst, r)
예제 #9
0
파일: qconf.py 프로젝트: MDeath/qqbot
    def LoadQQ(self):
        time.sleep(0.5)
        fn = self.absPath('qq(pid%s)' % os.getpid())

        if not os.path.exists(fn):
            return self.qq

        try:
            with open(fn, 'r') as f:
                qq = f.read()
        except Exception as e:
            ERROR('无法读取上次运行的 QQ 号码, %s', e)
            qq = self.qq
        else:
            self.qq = qq

        try:
            os.remove(fn)
        except OSError:
            pass

        return qq
예제 #10
0
 def urlGet(self, url, data=None, **kw):
     self.session.headers.update(kw)
     try:
         if data is None:
             return self.session.get(url)
         else:
             return self.session.post(url, data=data)
     except (requests.exceptions.SSLError, AttributeError):
         # by @staugur, @pandolia
         if self.session.verify:
             self.session.verify = False
             ERROR('无法和腾讯服务器建立私密连接,'
                   ' 10 秒后将尝试使用非私密连接和腾讯服务器通讯。'
                   '若您不希望使用非私密连接,请按 Ctrl+C 退出本程序。')
             time.sleep(10)
             WARN('已开始尝试使用非私密连接和腾讯服务器通讯。')
             requests.packages.urllib3.disable_warnings(
                 requests.packages.urllib3.exceptions.InsecureRequestWarning
             )
             return self.urlGet(url, data, **kw)
         else:
             raise
예제 #11
0
    def fetchGroups(self, contacts, silence=True):
        if not silence:
            INFO('登录 Step7 - 获取群列表')
            INFO('=' * 60)

        for i in range(5):
            result = self.smartRequest(
                url='http://s.web2.qq.com/api/get_group_name_list_mask2',
                data={
                    'r': JsonDumps({
                        'vfwebqq': self.vfwebqq,
                        'hash': self.hash
                    })
                },
                Referer=('http://d1.web2.qq.com/proxy.html?v=20151105001&'
                         'callback=1&id=2'))
            if 'gmarklist' in result:
                break
            else:
                ERROR('获取群列表出错,等待 3 秒后再次尝试一次')
                time.sleep(3)
        else:
            CRITICAL('无法获取到群列表')
            raise QSession.Error

        markDict = dict((d['uin'], d['markname']) for d in result['gmarklist'])

        qqResult = self.smartRequest(
            url='http://qun.qq.com/cgi-bin/qun_mgr/get_group_list',
            data={'bkn': self.bkn},
            Referer='http://qun.qq.com/member.html')

        qqDict = defaultdict(list)
        for k in ('create', 'manage', 'join'):
            for d in qqResult.get(k, []):
                name = d['gn'].replace(' ', ' ').replace('&', '&')
                qqDict[name].append(d['gc'])

        for info in result['gnamelist']:
            uin = info['gid']
            name = info['name']
            mark = markDict.get(uin, '')

            qqlist = qqDict.get(name, [])
            if len(qqlist) == 1:
                qq = qqlist.pop()
            else:
                qq = self.fetchGroupQQ(uin)
                for x in qqlist:
                    if (qq - x) % 1000000 == 0:
                        qq = x
                        break
                try:
                    qqlist.remove(qq)
                except ValueError:
                    pass

            members = self.fetchGroupMember(info['code'])

            c = contacts.Add('group', str(uin), name, str(qq), '', mark,
                             members)

            if not silence:
                INFO(repr(c))
                for uin, name in members.items():
                    INFO('    成员: %s, uin%s', name, uin)
                INFO('=' * 60)

        if not silence:
            INFO('获取群列表成功,共 %d 个群' % len(result))
예제 #12
0
def _call(func, *args, **kwargs):
    try:
        StartDaemonThread(func, *args, **kwargs)
    except Exception as e:
        ERROR('', exc_info=True)
        ERROR('执行 %s.%s 时出错,%s', func.__module__, func.__name__, e)