diff --git a/README.md b/README.md index b4f7ddc..d46b6a5 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,38 @@ + +## 如何使用本仓库内容 + +在青龙创建一个订阅 + +拉库命令 `ql repo https://github.com/Fansirsqi/dailycheckin.git null null null main` + +配置执行后运行的命令 +`pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && pip install requests pycrypto pycryptodome && cd /ql/data/repo/Fansirsqi_dailycheckin_main && python setup.py develop` + +在脚本管理根目录创建`config.json`配置文件可以参考官方配置,这里只是增加了一段 + +[配置示例](https://gist.githubusercontent.com/Fansirsqi/9e238bb3e432fdb7bee1caa46da81519/raw/5a7d599b526564c68b0120e9a275ce6f414757df/config.json) + +``` +, + "TESTNOTICE": [ + { + "test1": "test1mesg" + } + ] +``` +强烈建议您在`https://www.json.cn/`这个网站检查您的配置 + +最后在定时任务里创建一个测试任务 + +`task dailycheckin --include TESTNOTICE`运行并查看日志 + +![1715763862230.png](https://pic2.ziyuan.wang/user/fansir/2024/05/1715763862230_5344cb6724871.png) + +![1715763931708.png](https://pic2.ziyuan.wang/user/fansir/2024/05/1715763931708_ec7c766df87c4.png) + ## ✨ 特性 - 📦 支持 Pypi 包安装 @@ -65,6 +97,27 @@ ## 💬 通知列表 +- [PushDeer](https://www.pushdeer.com/) +- [wxPusher](https://wxpusher.zjiecode.com/docs/#/) + +> [PushDeer预览](https://pic2.ziyuan.wang/user/fansir/2024/05/1715593565981_39b4eff978354.png) +> +> [wxPusher预览](https://pic2.ziyuan.wang/user/fansir/2024/05/1715593114657_e53ec9acf7e1e.png) +> +> 新增以上渠道配置如下 + +```json +{ + "PUSHKEY": "", //PushDeer 的 pushkey + "WXPUSHER_TK": "", //wxpusher_token + "WXPUSHER_UID": "", //wxpusher_uid + //以上是新增内容 + "BARK_URL": "", + ... +} +``` + + - dingtalk(钉钉) - 企业微信群机器人(企业微信) - 企业微信应用消息(企业微信) diff --git a/dailycheckin/configs.py b/dailycheckin/configs.py index b8c0da1..f572933 100755 --- a/dailycheckin/configs.py +++ b/dailycheckin/configs.py @@ -16,6 +16,9 @@ def checkin_map(): checkin_map = checkin_map() notice_map = { + "PUSHKEY": "", + "WXPUSHER_TK": "", + "WXPUSHER_UID": "", "BARK_URL": "", "COOLPUSHEMAIL": "", "COOLPUSHQQ": "", diff --git a/dailycheckin/main.py b/dailycheckin/main.py index 7de5773..f461ac4 100755 --- a/dailycheckin/main.py +++ b/dailycheckin/main.py @@ -49,12 +49,8 @@ def check_config(task_list): for one_check, _ in checkin_map.items(): if one_check in task_list: if _check_info.get(one_check.lower()): - for _, check_item in enumerate( - _check_info.get(one_check.lower(), []) - ): - if "xxxxxx" not in str(check_item) and "多账号" not in str( - check_item - ): + for _, check_item in enumerate(_check_info.get(one_check.lower(), [])): + if "xxxxxx" not in str(check_item) and "多账号" not in str(check_item): if one_check.lower() not in check_info.keys(): check_info[one_check.lower()] = [] check_info[one_check.lower()].append(check_item) @@ -63,16 +59,13 @@ def check_config(task_list): print(e) return False, False else: - print( - "未找到 config.json 配置文件\n请在下方任意目录中添加「config.json」文件:\n" - + "\n".join(config_path_list) - ) + print("未找到 config.json 配置文件\n请在下方任意目录中添加「config.json」文件:\n" + "\n".join(config_path_list)) return False, False def checkin(): start_time = time.time() - utc_time = (datetime.utcnow() + timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S") + utc_time = (datetime.now() + timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S") # update: Deprecated since version 3.12: Use datetime.now() with UTC instead. print(f"当前时间: {utc_time}\n当前版本: {__version__}") args = parse_arguments() include = args.include @@ -88,12 +81,7 @@ def checkin(): task_list = list(set(include) - set(exclude)) notice_info, check_info = check_config(task_list) if check_info: - task_name_str = "\n".join( - [ - f"「{checkin_map.get(one.upper())[0]}」账号数 : {len(value)}" - for one, value in check_info.items() - ] - ) + task_name_str = "\n".join([f"「{checkin_map.get(one.upper())[0]}」账号数 : {len(value)}" for one, value in check_info.items()]) print(f"\n---------- 本次执行签到任务如下 ----------\n\n{task_name_str}\n\n") content_list = [] for one_check, check_list in check_info.items(): @@ -111,18 +99,13 @@ def checkin(): try: url = "https://pypi.org/pypi/dailycheckin/json" latest_version = requests.get(url=url, timeout=30).json()["info"]["version"] - except: + except: # noqa: E722 print("获取最新版本失败") latest_version = "0.0.0" - content_list.append( - f"开始时间: {utc_time}\n" - f"任务用时: {int(time.time() - start_time)} 秒\n" - f"当前版本: {__version__}\n" - f"最新版本: {latest_version}\n" - f"项目地址: https://github.com/Sitoi/dailycheckin" - ) + content_list.append(f"开始时间: {utc_time}\n" f"任务用时: {int(time.time() - start_time)} 秒\n" f"当前版本: {__version__}\n" f"最新版本: {latest_version}\n" f"项目地址: https://github.com/Sitoi/dailycheckin") push_message(content_list=content_list, notice_info=notice_info) return + # push_message(content_list=content_list, notice_info=notice_info) if __name__ == "__main__": diff --git a/dailycheckin/test/__init__.py b/dailycheckin/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dailycheckin/test/main.py b/dailycheckin/test/main.py new file mode 100644 index 0000000..ec4dc69 --- /dev/null +++ b/dailycheckin/test/main.py @@ -0,0 +1,23 @@ +from dailycheckin import CheckIn +import os +import json + + +class TestNotice(CheckIn): + name = "通知测试" + + def __init__(self, check_item): + self.check_item = check_item + + def main(self): + return f"测试内容{self.check_item}" + + +if __name__ == "__main__": + with open( + os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"), + encoding="utf-8", + ) as f: + datas = json.loads(f.read()) + _check_item = datas.get("TestNotice", [])[0] + print(TestNotice(check_item=_check_item).main()) diff --git a/dailycheckin/utils/message.py b/dailycheckin/utils/message.py index f92795a..3df9cb1 100755 --- a/dailycheckin/utils/message.py +++ b/dailycheckin/utils/message.py @@ -7,36 +7,57 @@ from urllib.parse import quote_plus import requests +from pypushdeer import PushDeer + + +def message2pushdeer(pushkey: str, content: str): # 效果展示 https://pic2.ziyuan.wang/user/fansir/2024/05/1715593565981_39b4eff978354.png + print("PushDeer 推送开始") + pushdeer = PushDeer(pushkey=pushkey) + pushdeer.send_text(content, desp="dailycheckin 每日签到") + + +def message2wxpuser(wxpuser_tk: str, wxpusher_uid: str, content: str): # 效果展示 https://pic2.ziyuan.wang/user/fansir/2024/05/1715593114657_e53ec9acf7e1e.png + print("wxpuser 推送开始") + url = "https://wxpusher.zjiecode.com/api/send/message" + headers = {"Content-Type": "application/json"} + content = content.replace("\n", "
") + data = f'

每日签到


{content}


' + _uid = [wxpusher_uid] + _body = { + "appToken": wxpuser_tk, # 必传 + "content": data, # 必传 + "summary": "dailycheckin 每日签到", + "contentType": 2, + "uids": _uid, + "verifyPayType": 0, + } + res = requests.post(url=url, headers=headers, json=_body).json() + print(res) + def message2server(sckey, content): print("server 酱推送开始") data = {"text": "每日签到", "desp": content.replace("\n", "\n\n")} - requests.post(url=f"https://sc.ftqq.com/{sckey}.send", data=data) + requests.post(url=f"https:#sc.ftqq.com/{sckey}.send", data=data) return def message2server_turbo(sendkey, content): print("server 酱 Turbo 推送开始") data = {"text": "每日签到", "desp": content.replace("\n", "\n\n")} - requests.post(url=f"https://sctapi.ftqq.com/{sendkey}.send", data=data) + requests.post(url=f"https:#sctapi.ftqq.com/{sendkey}.send", data=data) return -def message2coolpush( - coolpushskey, - content, - coolpushqq: bool = True, - coolpushwx: bool = False, - coolpushemail: bool = False, -): +def message2coolpush(coolpushskey, content, coolpushqq: bool = True, coolpushwx: bool = False, coolpushemail: bool = False): print("Cool Push 推送开始") params = {"c": content, "t": "每日签到"} if coolpushqq: - requests.post(url=f"https://push.xuthus.cc/send/{coolpushskey}", params=params) + requests.post(url=f"https:#push.xuthus.cc/send/{coolpushskey}", params=params) if coolpushwx: - requests.post(url=f"https://push.xuthus.cc/wx/{coolpushskey}", params=params) + requests.post(url=f"https:#push.xuthus.cc/wx/{coolpushskey}", params=params) if coolpushemail: - requests.post(url=f"https://push.xuthus.cc/email/{coolpushskey}", params=params) + requests.post(url=f"https:#push.xuthus.cc/email/{coolpushskey}", params=params) return @@ -44,9 +65,9 @@ def message2qmsg(qmsg_key, qmsg_type, content): print("qmsg 酱推送开始") params = {"msg": content} if qmsg_type == "group": - requests.get(url=f"https://qmsg.zendee.cn/group/{qmsg_key}", params=params) + requests.get(url=f"https:#qmsg.zendee.cn/group/{qmsg_key}", params=params) else: - requests.get(url=f"https://qmsg.zendee.cn/send/{qmsg_key}", params=params) + requests.get(url=f"https:#qmsg.zendee.cn/send/{qmsg_key}", params=params) return @@ -58,9 +79,9 @@ def message2telegram(tg_api_host, tg_proxy, tg_bot_token, tg_user_id, content): "disable_web_page_preview": "true", } if tg_api_host: - url = f"https://{tg_api_host}/bot{tg_bot_token}/sendMessage" + url = f"https:#{tg_api_host}/bot{tg_bot_token}/sendMessage" else: - url = f"https://api.telegram.org/bot{tg_bot_token}/sendMessage" + url = f"https:#api.telegram.org/bot{tg_bot_token}/sendMessage" if tg_proxy: proxies = { "http": tg_proxy, @@ -75,9 +96,7 @@ def message2telegram(tg_api_host, tg_proxy, tg_bot_token, tg_user_id, content): def message2feishu(fskey, content): print("飞书 推送开始") data = {"msg_type": "text", "content": {"text": content}} - requests.post( - url=f"https://open.feishu.cn/open-apis/bot/v2/hook/{fskey}", json=data - ) + requests.post(url=f"https:#open.feishu.cn/open-apis/bot/v2/hook/{fskey}", json=data) return @@ -87,15 +106,11 @@ def message2dingtalk(dingtalk_secret, dingtalk_access_token, content): secret_enc = dingtalk_secret.encode("utf-8") string_to_sign = f"{timestamp}\n{dingtalk_secret}" string_to_sign_enc = string_to_sign.encode("utf-8") - hmac_code = hmac.new( - secret_enc, string_to_sign_enc, digestmod=hashlib.sha256 - ).digest() + hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest() sign = quote_plus(base64.b64encode(hmac_code)) send_data = {"msgtype": "text", "text": {"content": content}} requests.post( - url="https://oapi.dingtalk.com/robot/send?access_token={}×tamp={}&sign={}".format( - dingtalk_access_token, timestamp, sign - ), + url="https:#oapi.dingtalk.com/robot/send?access_token={}×tamp={}&sign={}".format(dingtalk_access_token, timestamp, sign), headers={"Content-Type": "application/json", "Charset": "UTF-8"}, data=json.dumps(send_data), ) @@ -116,28 +131,18 @@ def message2bark(bark_url: str, content): def message2qywxrobot(qywx_key, content): print("企业微信群机器人推送开始") requests.post( - url=f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={qywx_key}", + url=f"https:#qyapi.weixin.qq.com/cgi-bin/webhook/send?key={qywx_key}", data=json.dumps({"msgtype": "text", "text": {"content": content}}), ) return -def message2qywxapp( - qywx_corpid, - qywx_agentid, - qywx_corpsecret, - qywx_touser, - qywx_media_id, - qywx_origin, - content, -): +def message2qywxapp(qywx_corpid, qywx_agentid, qywx_corpsecret, qywx_touser, qywx_media_id, qywx_origin, content): print("企业微信应用消息推送开始") - base_url = "https://qyapi.weixin.qq.com" + base_url = "https:#qyapi.weixin.qq.com" if qywx_origin: base_url = qywx_origin - res = requests.get( - f"{base_url}/cgi-bin/gettoken?corpid={qywx_corpid}&corpsecret={qywx_corpsecret}" - ) + res = requests.get(f"{base_url}/cgi-bin/gettoken?corpid={qywx_corpid}&corpsecret={qywx_corpsecret}") token = res.json().get("access_token", False) if qywx_media_id: data = { @@ -150,7 +155,7 @@ def message2qywxapp( "title": "Dailycheckin 签到通知", "thumb_media_id": qywx_media_id, "author": "Sitoi", - "content_source_url": "https://github.com/Sitoi/dailycheckin", + "content_source_url": "https:#github.com/Sitoi/dailycheckin", "content": content.replace("\n", "
"), "digest": content, } @@ -165,7 +170,7 @@ def message2qywxapp( "textcard": { "title": "Dailycheckin 签到通知", "description": content, - "url": "https://github.com/Sitoi/dailycheckin", + "url": "https:#github.com/Sitoi/dailycheckin", "btntxt": "开源项目", }, } @@ -186,14 +191,12 @@ def message2pushplus(pushplus_token, content, pushplus_topic=None): } if pushplus_topic: data["topic"] = pushplus_topic - requests.post(url="http://www.pushplus.plus/send", data=json.dumps(data)) + requests.post(url="http:#www.pushplus.plus/send", data=json.dumps(data)) return def important_notice(): - datas = requests.get( - url="https://api.github.com/repos/Sitoi/dailycheckin/issues?state=open&labels=通知" - ).json() + datas = requests.get(url="https://api.github.com/repos/Sitoi/dailycheckin/issues?state=open&labels=通知").json() if datas: data = datas[0] title = data.get("title") @@ -206,6 +209,9 @@ def important_notice(): def push_message(content_list: list, notice_info: dict): + pushkey = notice_info.get("pushkey") + wxpusher_tk = notice_info.get("wxpusher_tk") + wxpusher_uid = notice_info.get("wxpusher_uid") dingtalk_secret = notice_info.get("dingtalk_secret") dingtalk_access_token = notice_info.get("dingtalk_access_token") fskey = notice_info.get("fskey") @@ -231,7 +237,7 @@ def push_message(content_list: list, notice_info: dict): qywx_origin = notice_info.get("qywx_origin") pushplus_token = notice_info.get("pushplus_token") pushplus_topic = notice_info.get("pushplus_topic") - merge_push = notice_info.get("merge_push") + merge_push = notice_info.get("merge_push").lower() == "true" # 转成bool content_str = "\n————————————\n\n".join(content_list) message_list = [content_str] try: @@ -242,27 +248,29 @@ def push_message(content_list: list, notice_info: dict): except Exception as e: print("获取重要通知失败:", e) if merge_push is None: - if ( - qmsg_key - or coolpushskey - or qywx_touser - or qywx_corpsecret - or qywx_agentid - or bark_url - or pushplus_token - ): + if qmsg_key or coolpushskey or qywx_touser or qywx_corpsecret or qywx_agentid or bark_url or pushplus_token: merge_push = False else: merge_push = True if not merge_push: message_list = content_list for message in message_list: - if qmsg_key: + if pushkey: + try: + message2pushdeer(pushkey=pushkey, content=message) + except Exception as e: + print("PushDeer 推送失败", e) + elif wxpusher_tk and wxpusher_uid: + try: + message2wxpuser(wxpuser_tk=wxpusher_tk, wxpusher_uid=wxpusher_uid, content=message) + except Exception as e: + print("wxpuser 推送失败", e) + elif qmsg_key: try: message2qmsg(qmsg_key=qmsg_key, qmsg_type=qmsg_type, content=message) except Exception as e: print("qmsg 推送失败", e) - if coolpushskey: + elif coolpushskey: try: message2coolpush( coolpushskey=coolpushskey, @@ -273,7 +281,7 @@ def push_message(content_list: list, notice_info: dict): ) except Exception as e: print("coolpush 推送失败", e) - if qywx_touser and qywx_corpid and qywx_corpsecret and qywx_agentid: + elif qywx_touser and qywx_corpid and qywx_corpsecret and qywx_agentid: try: message2qywxapp( qywx_corpid=qywx_corpid, @@ -286,12 +294,12 @@ def push_message(content_list: list, notice_info: dict): ) except Exception as e: print("企业微信应用消息推送失败", e) - if bark_url: + elif bark_url: try: message2bark(bark_url=bark_url, content=message) except Exception as e: print("Bark 推送失败", e) - if dingtalk_access_token and dingtalk_secret: + elif dingtalk_access_token and dingtalk_secret: try: message2dingtalk( dingtalk_secret=dingtalk_secret, @@ -300,27 +308,27 @@ def push_message(content_list: list, notice_info: dict): ) except Exception as e: print("钉钉推送失败", e) - if fskey: + elif fskey: try: message2feishu(fskey=fskey, content=message) except Exception as e: print("飞书推送失败", e) - if sckey: + elif sckey: try: message2server(sckey=sckey, content=message) except Exception as e: print("Server 推送失败", e) - if sendkey: + elif sendkey: try: message2server_turbo(sendkey=sendkey, content=message) except Exception as e: print("Server Turbo 推送失败", e) - if qywx_key: + elif qywx_key: try: message2qywxrobot(qywx_key=qywx_key, content=message) except Exception as e: print("企业微信群机器人推送失败", e) - if pushplus_token: + elif pushplus_token: try: message2pushplus( pushplus_token=pushplus_token, @@ -329,7 +337,7 @@ def push_message(content_list: list, notice_info: dict): ) except Exception as e: print("Pushplus 推送失败", e) - if tg_user_id and tg_bot_token: + elif tg_user_id and tg_bot_token: try: message2telegram( tg_api_host=tg_api_host, @@ -340,6 +348,8 @@ def push_message(content_list: list, notice_info: dict): ) except Exception as e: print("Telegram 推送失败", e) + else: + print("未配置任何推送渠道❌") if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index e839041..3e17502 100755 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ pycryptodome==3.17 requests~=2.25.1 rsa~=4.0 urllib3~=1.26.2 +pypushdeer==0.0.3 diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..08e40b1 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,78 @@ +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] + +# Same as Black. +line-length = 320 +indent-width = 4 + +# Assume Python 3.11 +target-version = "py311" + +[lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or +# McCabe complexity (`C901`) by default. +select = ["E4", "E7", "E9", "F"] +ignore = [] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[format] +# Like Black, use double quotes for strings. +quote-style = "double" +# quote-style = "single" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" + +# Enable auto-formatting of code examples in docstrings. Markdown, +# reStructuredText code/literal blocks and doctests are all supported. +# +# This is currently disabled by default, but it is planned for this +# to be opt-out in the future. +docstring-code-format = true + +# Set the line length limit used when formatting code snippets in +# docstrings. +# +# This only has an effect when the `docstring-code-format` setting is +# enabled. +docstring-code-line-length = "dynamic"