diff --git a/feapder/core/base_parser.py b/feapder/core/base_parser.py index 6264b5a..a06f9c4 100644 --- a/feapder/core/base_parser.py +++ b/feapder/core/base_parser.py @@ -13,6 +13,9 @@ from feapder.db.mysqldb import MysqlDB from feapder.network.item import UpdateItem from feapder.utils.log import log +from feapder.network.request import Request +from feapder.network.response import Response +from feapder.utils.perfect_dict import PerfectDict class BaseParser(object): @@ -26,7 +29,7 @@ def start_requests(self): pass - def download_midware(self, request): + def download_midware(self, request: Request): """ @summary: 下载中间件 可修改请求的一些参数, 或可自定义下载,然后返回 request, response --------- @@ -37,7 +40,7 @@ def download_midware(self, request): pass - def validate(self, request, response): + def validate(self, request: Request, response: Response): """ @summary: 校验函数, 可用于校验response是否正确 若函数内抛出异常,则重试请求 @@ -53,7 +56,7 @@ def validate(self, request, response): pass - def parse(self, request, response): + def parse(self, request: Request, response: Response): """ @summary: 默认的解析函数 --------- @@ -65,7 +68,7 @@ def parse(self, request, response): pass - def exception_request(self, request, response, e): + def exception_request(self, request: Request, response: Response, e: Exception): """ @summary: 请求或者parser里解析出异常的request --------- @@ -78,7 +81,7 @@ def exception_request(self, request, response, e): pass - def failed_request(self, request, response, e): + def failed_request(self, request: Request, response: Response, e: Exception): """ @summary: 超过最大重试次数的request 可返回修改后的request 若不返回request,则将传进来的request直接人redis的failed表。否则将修改后的request入failed表 @@ -135,7 +138,7 @@ def add_task(self): @result: """ - def start_requests(self, task): + def start_requests(self, task: PerfectDict): """ @summary: --------- diff --git a/feapder/setting.py b/feapder/setting.py index 93d9b89..791373b 100644 --- a/feapder/setting.py +++ b/feapder/setting.py @@ -165,7 +165,8 @@ # 报警 支持钉钉、飞书、企业微信、邮件 # 钉钉报警 DINGDING_WARNING_URL = "" # 钉钉机器人api -DINGDING_WARNING_PHONE = "" # 报警人 支持列表,可指定多个 +DINGDING_WARNING_PHONE = "" # 被@的群成员手机号,支持列表,可指定多个。 +DINGDING_WARNING_USER_ID = "" # 被@的群成员userId,支持列表,可指定多个 DINGDING_WARNING_ALL = False # 是否提示所有人, 默认为False DINGDING_WARNING_SECRET = None # 加签密钥 # 飞书报警 diff --git a/feapder/templates/project_template/setting.py b/feapder/templates/project_template/setting.py index 6109790..4edb55b 100644 --- a/feapder/templates/project_template/setting.py +++ b/feapder/templates/project_template/setting.py @@ -147,7 +147,8 @@ # # 报警 支持钉钉、飞书、企业微信、邮件 # # 钉钉报警 # DINGDING_WARNING_URL = "" # 钉钉机器人api -# DINGDING_WARNING_PHONE = "" # 报警人 支持列表,可指定多个 +# DINGDING_WARNING_PHONE = "" # 被@的群成员手机号,支持列表,可指定多个。 +# DINGDING_WARNING_USER_ID = "" # 被@的群成员userId,支持列表,可指定多个 # DINGDING_WARNING_ALL = False # 是否提示所有人, 默认为False # DINGDING_WARNING_SECRET = None # 加签密钥 # # 飞书报警 diff --git a/feapder/utils/tools.py b/feapder/utils/tools.py index a0ccbf1..8d89d37 100644 --- a/feapder/utils/tools.py +++ b/feapder/utils/tools.py @@ -7,7 +7,6 @@ @author: Boris @email: boris_liu@foxmail.com """ -import hmac import asyncio import base64 import calendar @@ -16,6 +15,7 @@ import datetime import functools import hashlib +import hmac import html import importlib import json @@ -2467,18 +2467,41 @@ def reach_freq_limit(rate_limit, *key): def dingding_warning( - message, message_prefix=None, rate_limit=None, url=None, user_phone=None, secret=None + message, + *, + message_prefix=None, + rate_limit=None, + url=None, + user_phone=None, + user_id=None, + secret=None, ): + """ + 钉钉报警,user_phone与user_id 二选一即可 + Args: + message: + message_prefix: 消息摘要,用于去重 + rate_limit: 包名频率,单位秒,相同的报警内容在rate_limit时间内只会报警一次 + url: 钉钉报警url + user_phone: 被@的群成员手机号,支持列表,可指定多个。 + user_id: 被@的群成员userId,支持列表,可指定多个 + secret: 钉钉报警加签密钥 + Returns: + + """ # 为了加载最新的配置 rate_limit = rate_limit if rate_limit is not None else setting.WARNING_INTERVAL url = url or setting.DINGDING_WARNING_URL user_phone = user_phone or setting.DINGDING_WARNING_PHONE + user_id = user_id or setting.DINGDING_WARNING_USER_ID secret = secret or setting.DINGDING_WARNING_SECRET if secret: timestamp = str(round(time.time() * 1000)) - secret_enc = secret.encode('utf-8') - string_to_sign_enc = f'{timestamp}\n{secret}'.encode('utf-8') - hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest() + secret_enc = secret.encode("utf-8") + string_to_sign_enc = f"{timestamp}\n{secret}".encode("utf-8") + hmac_code = hmac.new( + secret_enc, string_to_sign_enc, digestmod=hashlib.sha256 + ).digest() sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) url = f"{url}×tamp={timestamp}&sign={sign}" @@ -2492,10 +2515,17 @@ def dingding_warning( if isinstance(user_phone, str): user_phone = [user_phone] if user_phone else [] + if isinstance(user_id, str): + user_id = [user_id] if user_id else [] + data = { "msgtype": "text", "text": {"content": message}, - "at": {"atMobiles": user_phone, "isAtAll": setting.DINGDING_WARNING_ALL}, + "at": { + "atMobiles": user_phone, + "atUserIds": user_id, + "isAtAll": setting.DINGDING_WARNING_ALL, + }, } headers = {"Content-Type": "application/json"}