From 6edbaea69df53a023798945372d19165a99697e9 Mon Sep 17 00:00:00 2001 From: Jad Date: Fri, 1 Jan 2021 15:02:52 +0800 Subject: [PATCH 01/15] fix: wrong total sign day, fixed #71 --- genshin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/genshin.py b/genshin.py index 3a147d9..13bf6b5 100755 --- a/genshin.py +++ b/genshin.py @@ -201,9 +201,6 @@ class Sign(object): notify(sckey, '失败', message) exit(-1) else: - today = infoList[i]['data']['today'] - totalSignDay = infoList[i]['data']['total_sign_day'] - award = Roles(self._cookie).get_awards()['data']['awards'][totalSignDay - 1] uid = str(self._uidList[i]).replace( str(self._uidList[i])[3:6], '***', 1) data = { @@ -226,6 +223,10 @@ class Sign(object): # -5003: already signed in if code == 0: status = '成功' + today = infoList[i]['data']['today'] + totalSignDay = infoList[i]['data']['total_sign_day'] + 1 + award = Roles(self._cookie).get_awards()['data']['awards'][totalSignDay - 1] + messageList.append(self.message().format(today, self._regionNameList[i], uid, award['name'], award['cnt'], totalSignDay, jdict['message'], '')) From d8d5f90e20b038042b5cfad9b6712ccc02df0058 Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 09:01:39 +0800 Subject: [PATCH 02/15] docs: update README.md --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 075c6e6..8c9cf66 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Genshin Impact Helper 可以自动化为你获取原神每日福利。 - [x] **自动签到** 程序会在每天早上自动执行签到流程,也可以随时通过部署教程的`步骤4`手动触发,具体时间参照[此处](.github/workflows/main.yml) - [x] **支持订阅** 通过配置`SCKEY`开启订阅,每天将签到结果推送到微信上 -- [x] **支持多账号** 不同账号的`Cookie`之间用`#`分隔,如:`yourCookie1#yourCookie2` +- [x] **支持多账号** 不同账号的`Cookie`之间用`#`分隔,如:`myCookie1#myCookie2` - [x] **支持多角色** 支持绑定官服和B站渠道服角色的米游社账号 ## 📐部署 @@ -46,7 +46,11 @@ Genshin Impact Helper 可以自动化为你获取原神每日福利。 - 项目地址:[github/genshin-impact-helper](https://github.com/y1ndan/genshin-impact-helper) - 点击右上角`Fork`到自己的账号下 -> ![fork](https://i.loli.net/2020/10/28/qpXowZmIWeEUyrJ.png) +![fork](https://i.loli.net/2020/10/28/qpXowZmIWeEUyrJ.png) + +- 打开`Fork`后的仓库,将仓库默认分支设置为 master 分支 + +![default-master](https://i.loli.net/2021/01/04/eRYf8hTAvcOQnBI.jpg) ### 2. 获取 Cookie @@ -57,7 +61,9 @@ Genshin Impact Helper 可以自动化为你获取原神每日福利。 - 按`F12`,打开`开发者工具`,找到`Network`并点击 - 按`F5`刷新页面,按下图复制`Cookie` -> ![cookie](https://i.loli.net/2020/10/28/TMKC6lsnk4w5A8i.png) +![cookie](https://i.loli.net/2020/10/28/TMKC6lsnk4w5A8i.png) + +- 当触发`debugger`时,可尝试将`javascript:(function(){var i=setTimeout(function(){while(--i)clearTimeout(i)})}())`加入浏览器书签,然后点击一次该书签,便可绕过 debug 策略。来源[#56](https://github.com/y1ndan/genshin-impact-helper/issues/56#issuecomment-752985709) #### 2.2 方法二 @@ -82,7 +88,7 @@ if (ask == true) { - 回到项目页面,依次点击`Settings`-->`Secrets`-->`New secret` -> ![new-secret.png](https://i.loli.net/2020/10/28/sxTuBFtRvzSgUaA.png) +![new-secret.png](https://i.loli.net/2020/10/28/sxTuBFtRvzSgUaA.png) - 建立名为`COOKIE`的 secret,值为`步骤2`中复制的`Cookie`内容,最后点击`Add secret` @@ -90,7 +96,7 @@ if (ask == true) { - secret名字必须为`COOKIE`! - secret名字必须为`COOKIE`! -> ![add-secret](https://i.loli.net/2020/10/28/sETkVdmrNcCUpgq.png) +![add-secret](https://i.loli.net/2020/10/28/sETkVdmrNcCUpgq.png) ### 4. 启用 Actions From 13f13d407625a69232a30bab6d27a6fd7f30bf2a Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 09:34:32 +0800 Subject: [PATCH 03/15] docs: update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c9cf66..7c37b4d 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Genshin Impact Helper 可以自动化为你获取原神每日福利。 ![cookie](https://i.loli.net/2020/10/28/TMKC6lsnk4w5A8i.png) -- 当触发`debugger`时,可尝试将`javascript:(function(){var i=setTimeout(function(){while(--i)clearTimeout(i)})}())`加入浏览器书签,然后点击一次该书签,便可绕过 debug 策略。来源[#56](https://github.com/y1ndan/genshin-impact-helper/issues/56#issuecomment-752985709) +- 当触发`Debugger`时,可尝试按`Ctrl + F8`关闭,然后再次刷新页面,最后复制`Cookie` #### 2.2 方法二 @@ -104,7 +104,7 @@ if (ask == true) { 返回项目主页面,点击上方的`Actions`,再点击左侧的`Genshin Impact Helper`,再点击`Run workflow` -> ![run](https://i.loli.net/2020/10/28/5ylvgdYf9BDMqAH.png) +![run](https://i.loli.net/2020/10/28/5ylvgdYf9BDMqAH.png) From ea76e7bc26b0a3ea9b98b8106a48909f02eaa8ab Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 11:31:38 +0800 Subject: [PATCH 04/15] refactor: change random sleep into workflow --- .github/workflows/main.yml | 1 + genshin.py | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 27d9925..dc313da 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,5 +39,6 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt + sleep $(shuf -i 10-300 -n 1) echo "${{ secrets.COOKIE }}" | tr '#' "\n" | sed 's/$/&#${{ secrets.SCKEY }}/g' | xargs -I {} sh -c 'echo "{}" | python3 ./genshin.py' diff --git a/genshin.py b/genshin.py index 13bf6b5..c199255 100755 --- a/genshin.py +++ b/genshin.py @@ -276,11 +276,6 @@ if __name__ == '__main__': secret.append('') cookie = secret[0] sckey = secret[1] - seconds = random.randint(10, 300) - #seconds = random.randint(1, 3) - - logging.info('将在 {} 秒后开始任务...'.format(seconds)) - time.sleep(seconds) Sign(cookie).run() From 1532a06cb4cea0c19eb6612306f33ef29ee584a4 Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 14:13:57 +0800 Subject: [PATCH 05/15] refactor: use argparse to get args --- genshin.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/genshin.py b/genshin.py index c199255..31641b0 100755 --- a/genshin.py +++ b/genshin.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import requests +import argparse import json import uuid import logging @@ -272,10 +273,11 @@ def notify(sckey, status, message): if __name__ == '__main__': - secret = input().strip().split('#') - secret.append('') - cookie = secret[0] - sckey = secret[1] + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--cookie', required=True, type=str, default='') + parser.add_argument('-s', '--sckey', type=str, default='') + args = parser.parse_args() + sckey = args.sckey - Sign(cookie).run() + Sign(args.cookie).run() From f195f08e3835d4e0b83b7517ce89f556d6acd956 Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 15:01:18 +0800 Subject: [PATCH 06/15] refactor: sleep in schedule event; update run sign --- .github/workflows/main.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dc313da..57019ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,10 +35,13 @@ jobs: with: python-version: 3.8 + - name: Random sleep + if: github.event_name == 'schedule' + sleep $(shuf -i 10-300 -n 1) + - name: Run sign run: | python -m pip install --upgrade pip pip install -r requirements.txt - sleep $(shuf -i 10-300 -n 1) - echo "${{ secrets.COOKIE }}" | tr '#' "\n" | sed 's/$/&#${{ secrets.SCKEY }}/g' | xargs -I {} sh -c 'echo "{}" | python3 ./genshin.py' + echo '${{ secrets.COOKIE }}' | tr '#' '\n' | sed 's/^/-c &/g' | sed 's/$/&${{ secrets.SCKEY }}/g' | xargs -I {} sh -c 'echo "{}" | python3 ./genshin.py' From 73981ad2ef93b4aef9ff55b45cc0f33fc5d562af Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 15:07:25 +0800 Subject: [PATCH 07/15] docs: update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7c37b4d..a21426b 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ Error: Process completed with exit code 255. - 使用 GitHub 登录 [sc.ftqq.com](http://sc.ftqq.com/?c=github&a=login) 创建账号 - 点击「[发送消息](http://sc.ftqq.com/?c=code)」,获取`SCKEY` - 点击「[微信推送](http://sc.ftqq.com/?c=wechat&a=bind)」,完成微信绑定 -- 建立名为`SCKEY`的 secret,并添加获取的 SCKEY 值,开启订阅推送 +- 建立名为`SCKEY`的 secret,并添加获取的 SCKEY 值,即可开启订阅推送。注意必须加上`-s`,例子:`-s ` ## ❗️协议 From dcf3a66782c3241c40210312cd1b2250228fa1be Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 17:48:43 +0800 Subject: [PATCH 08/15] refactor: update code - add more output info - optimize logic judgment - fix wrong award output --- genshin.py | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/genshin.py b/genshin.py index 31641b0..6270105 100755 --- a/genshin.py +++ b/genshin.py @@ -115,6 +115,7 @@ class Roles(object): try: jdict + logging.info('账号信息获取完毕') except AttributeError: raise Exception(errstr) @@ -164,9 +165,7 @@ class Sign(object): try: rolesList = roles['data']['list'] except Exception as e: - message = roles['message'] - notify(sckey, '失败', message) - exit(-1) + notify(sckey, '失败', roles['message']) else: logging.info('当前账号绑定了 {} 个角色'.format(len(rolesList))) infoList = [] @@ -183,6 +182,7 @@ class Sign(object): try: infoList.append(json.loads(requests.Session().get( info_url, headers = self.get_header()).text)) + logging.info('签到信息获取完毕') except Exception as e: logging.error(e) @@ -192,18 +192,23 @@ class Sign(object): logging.info('任务开始') messageList = [] infoList = self.get_info() + status = '失败' for i in range(len(infoList)): + today = infoList[i]['data']['today'] + totalSignDay = infoList[i]['data']['total_sign_day'] + awards = Roles(self._cookie).get_awards()['data']['awards'] + uid = str(self._uidList[i]).replace( + str(self._uidList[i])[3:6], '***', 1) if infoList[i]['data']['is_sign'] is True: #if infoList[i]['data']['is_sign'] is False: - message = '旅行者 {} 号,你已经签到过了'.format(i + 1) - notify(sckey, '成功', message) + status = '成功' + messageList.append(self.message().format(today, + self._regionNameList[i], uid, + awards[totalSignDay - 1]['name'], awards[totalSignDay - 1]['cnt'], + totalSignDay, '旅行者 {} 号,你已经签到过了'.format(i + 1), '')) elif infoList[i]['data']['first_bind'] is True: - message = '旅行者 {} 号,请先前往米游社绑定账号'.format(i + 1) - notify(sckey, '失败', message) - exit(-1) + messageList.append(' 旅行者 {} 号为首次绑定,请先前往米游社App手动签到一次'.format(i + 1)) else: - uid = str(self._uidList[i]).replace( - str(self._uidList[i])[3:6], '***', 1) data = { 'act_id': Conf.act_id, 'region': self._regionList[i], @@ -211,11 +216,12 @@ class Sign(object): } logging.info('准备为旅行者 {} 号签到...' \ - '\nRegion: {}\nUID: {}'.format(i + 1, self._regionNameList[i], uid)) + '\n区服: {}\nUID: {}'.format(i + 1, self._regionNameList[i], uid)) try: jdict = json.loads(requests.Session().post( Conf.sign_url, headers = self.get_header(), data = json.dumps(data, ensure_ascii=False)).text) + logging.info('签到完毕') except Exception as e: raise else: @@ -224,18 +230,15 @@ class Sign(object): # -5003: already signed in if code == 0: status = '成功' - today = infoList[i]['data']['today'] - totalSignDay = infoList[i]['data']['total_sign_day'] + 1 - award = Roles(self._cookie).get_awards()['data']['awards'][totalSignDay - 1] messageList.append(self.message().format(today, - self._regionNameList[i], uid, award['name'], award['cnt'], - totalSignDay, jdict['message'], '')) + self._regionNameList[i], uid, + awards[totalSignDay]['name'], awards[totalSignDay]['cnt'], + totalSignDay + 1, jdict['message'], '')) else: - status = '失败' - messageList = jdict + messageList.append(jdict) - return notify(sckey, status, messageList) + return notify(sckey, status, messageList) def message(self): return ''' @@ -249,6 +252,7 @@ class Sign(object): def notify(sckey, status, message): + logging.info('签到{}: {}'.format(status, message)) if sckey.startswith('SC'): logging.info('准备推送通知...') url = 'https://sc.ftqq.com/{}.send'.format(sckey) @@ -266,10 +270,11 @@ def notify(sckey, status, message): else: logging.error('{}: {}'.format('推送失败', jdict)) else: - logging.info('未配置SCKEY,正在跳过推送') + logging.info('未配置 SCKEY,正在跳过通知推送') - logging.info('签到{}: {}'.format(status, message)) - return logging.info('任务结束') + logging.info('任务结束') + if status == '失败': + return exit(-1) if __name__ == '__main__': From 76acf6946874f64a808b1134b04b975cf2f15327 Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 17:57:37 +0800 Subject: [PATCH 09/15] fix: syntax error --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 57019ca..e7782be 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,7 +37,7 @@ jobs: - name: Random sleep if: github.event_name == 'schedule' - sleep $(shuf -i 10-300 -n 1) + run: sleep $(shuf -i 10-300 -n 1) - name: Run sign run: | From 2ec09677e8b95e5d6878072ccff19f677651c2f9 Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 19:32:07 +0800 Subject: [PATCH 10/15] Revert to old get args method --- .github/workflows/main.yml | 2 +- README.md | 6 ++---- genshin.py | 11 +++++------ 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e7782be..3dd943d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,5 +43,5 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt - echo '${{ secrets.COOKIE }}' | tr '#' '\n' | sed 's/^/-c &/g' | sed 's/$/&${{ secrets.SCKEY }}/g' | xargs -I {} sh -c 'echo "{}" | python3 ./genshin.py' + echo '${{ secrets.COOKIE }}' | tr '#' '\n' | sed 's/$/&#${{ secrets.SCKEY }}/g' | xargs -I {} sh -c 'echo "{}" | python3 ./genshin.py' diff --git a/README.md b/README.md index a21426b..37e3a7f 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,7 @@ Genshin Impact Helper 可以自动化为你获取原神每日福利。 ![fork](https://i.loli.net/2020/10/28/qpXowZmIWeEUyrJ.png) -- 打开`Fork`后的仓库,将仓库默认分支设置为 master 分支 - -![default-master](https://i.loli.net/2021/01/04/eRYf8hTAvcOQnBI.jpg) +- 将仓库默认分支设置为 master 分支 ### 2. 获取 Cookie @@ -155,7 +153,7 @@ Error: Process completed with exit code 255. - 使用 GitHub 登录 [sc.ftqq.com](http://sc.ftqq.com/?c=github&a=login) 创建账号 - 点击「[发送消息](http://sc.ftqq.com/?c=code)」,获取`SCKEY` - 点击「[微信推送](http://sc.ftqq.com/?c=wechat&a=bind)」,完成微信绑定 -- 建立名为`SCKEY`的 secret,并添加获取的 SCKEY 值,即可开启订阅推送。注意必须加上`-s`,例子:`-s ` +- 建立名为`SCKEY`的 secret,并添加获取的 SCKEY 值,即可开启订阅推送 ## ❗️协议 diff --git a/genshin.py b/genshin.py index 6270105..7183160 100755 --- a/genshin.py +++ b/genshin.py @@ -278,11 +278,10 @@ def notify(sckey, status, message): if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('-c', '--cookie', required=True, type=str, default='') - parser.add_argument('-s', '--sckey', type=str, default='') - args = parser.parse_args() - sckey = args.sckey + secret = input().strip().split('#') + secret.append('') + cookie = secret[0] + sckey = secret[1] - Sign(args.cookie).run() + Sign(cookie).run() From 2194fbfe5d67d9f89dcd78265f41e23a37183ad9 Mon Sep 17 00:00:00 2001 From: y1ndan Date: Mon, 4 Jan 2021 19:37:49 +0800 Subject: [PATCH 11/15] fix: syntax error --- genshin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genshin.py b/genshin.py index 7183160..2cd038c 100755 --- a/genshin.py +++ b/genshin.py @@ -278,7 +278,7 @@ def notify(sckey, status, message): if __name__ == '__main__': - secret = input().strip().split('#') + secret = input().strip().split('#') secret.append('') cookie = secret[0] sckey = secret[1] From 27770f9aba5ce3af4a79ef2fa8de238a629ca1d7 Mon Sep 17 00:00:00 2001 From: y1ndan Date: Tue, 5 Jan 2021 13:23:25 +0800 Subject: [PATCH 12/15] refactor: output improvements --- genshin.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/genshin.py b/genshin.py index 2cd038c..0eb2ef0 100755 --- a/genshin.py +++ b/genshin.py @@ -216,7 +216,7 @@ class Sign(object): } logging.info('准备为旅行者 {} 号签到...' \ - '\n区服: {}\nUID: {}'.format(i + 1, self._regionNameList[i], uid)) + '\n 区服: {}\n UID: {}'.format(i + 1, self._regionNameList[i], uid)) try: jdict = json.loads(requests.Session().post( Conf.sign_url, headers = self.get_header(), @@ -238,7 +238,7 @@ class Sign(object): else: messageList.append(jdict) - return notify(sckey, status, messageList) + return notify(sckey, status, ",".join(messageList)) def message(self): return ''' @@ -247,8 +247,7 @@ class Sign(object): 今日奖励: {} × {} 本月累签: {} 天 签到结果: {} - {:#^30} - ''' + {:#^30}''' def notify(sckey, status, message): From 8006bd471ea5491f7e7214b283fee2b3714470dc Mon Sep 17 00:00:00 2001 From: y1ndan <53508617+y1ndan@users.noreply.github.com> Date: Tue, 5 Jan 2021 19:46:52 +0800 Subject: [PATCH 13/15] rm --- genshin.py | 285 ----------------------------------------------------- 1 file changed, 285 deletions(-) diff --git a/genshin.py b/genshin.py index 0eb2ef0..e5a0d9b 100755 --- a/genshin.py +++ b/genshin.py @@ -1,286 +1 @@ #!/usr/bin/env python3 - -import requests -import argparse -import json -import uuid -import logging -import time -import random -import hashlib -import string -from requests.exceptions import * - -logging.basicConfig( - level = logging.INFO, - format = '%(asctime)s %(levelname)s %(message)s', - datefmt = '%Y-%m-%dT%H:%M:%S') - - -class ConfMeta(type): - @property - def ref_url(self): - return 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?' \ - 'bbs_auth_required={}&act_id={}&utm_source={}&utm_medium={}&' \ - 'utm_campaign={}'.format('true', self.act_id, 'bbs', 'mys', 'icon') - - @property - def award_url(self): - return 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/home?' \ - 'act_id={}'.format(self.act_id) - - @property - def role_url(self): - return 'https://api-takumi.mihoyo.com/binding/api/' \ - 'getUserGameRolesByCookie?game_biz={}'.format('hk4e_cn') - - @property - def info_url(self): - return 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?' \ - 'region={}&act_id={}&uid={}' - - @property - def sign_url(self): - return 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign' - - @property - def app_version(self): - return '2.3.0' - - @property - def ua(self): - return 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) Apple' \ - 'WebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/{}'.format(self.app_version) - - @property - def act_id(self): - return 'e202009291139501' - - -class Conf(metaclass=ConfMeta): - pass - - -class Roles(object): - def __init__(self, cookie:str=None): - if type(cookie) is not str: - raise TypeError('%s want a %s but got %s' %( - self.__class__, type(__name__), type(cookie))) - self._cookie = cookie - - def get_header(self): - return { - 'User-Agent': Conf.ua, - 'Referer': Conf.ref_url, - 'Accept-Encoding': 'gzip, deflate, br', - 'Cookie': self._cookie - } - - def get_awards(self): - try: - jdict = json.loads( - requests.Session().get( - Conf.award_url, headers = self.get_header()).text) - except Exception as e: - logging.error(e) - - return jdict - - def get_roles(self): - logging.info('准备获取账号信息...') - errstr = None - - for i in range(1, 4): - try: - jdict = json.loads(requests.Session().get( - Conf.role_url, headers = self.get_header()).text) - except HTTPError as e: - logging.error('HTTP error when get user game roles, ' \ - 'retry %s time(s) ...' %(i)) - logging.error('error is %s' %(e)) - errstr = str(e) - continue - except KeyError as e: - logging.error('Wrong response to get user game roles, ' \ - 'retry %s time(s) ...' %(i)) - logging.error('response is %s' %(e)) - errstr = str(e) - continue - except Exception as e: - logging.error('Unknown error %s, die' %(e)) - errstr = str(e) - raise - else: - break - - try: - jdict - logging.info('账号信息获取完毕') - except AttributeError: - raise Exception(errstr) - - return jdict - - -class Sign(object): - def __init__(self, cookie:str=None): - if type(cookie) is not str: - raise TypeError('%s want a %s but got %s' %( - self.__class__, type(__name__), type(cookie))) - self._cookie = cookie - - def md5(self, text): - md5 = hashlib.md5() - md5.update(text.encode()) - return md5.hexdigest() - - def get_DS(self): - # n = self.md5(2.1.0) # v2.1.0 @Steesha - # n = 'cx2y9z9a29tfqvr1qsq6c7yz99b5jsqt' # v2.2.0 @Womsxd - n = 'h8w582wxwgqvahcdkpvdhbh2w9casgfl' # v2.3.0 web @povsister & @journey-ad - i = str(int(time.time())) - r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6)) - c = self.md5('salt=' + n + '&t='+ i + '&r=' + r) - return '{},{},{}'.format(i, r, c) - - def get_header(self): - return { - 'x-rpc-device_id': str(uuid.uuid3( - uuid.NAMESPACE_URL, self._cookie)).replace('-','').upper(), - # 1: ios - # 2: android - # 4: pc web - # 5: mobile web - 'x-rpc-client_type': '5', - 'Accept-Encoding': 'gzip, deflate, br', - 'User-Agent': Conf.ua, - 'Referer': Conf.ref_url, - 'x-rpc-app_version': Conf.app_version, - 'DS': self.get_DS(), - 'Cookie': self._cookie - } - - def get_info(self): - roles = Roles(self._cookie).get_roles() - try: - rolesList = roles['data']['list'] - except Exception as e: - notify(sckey, '失败', roles['message']) - else: - logging.info('当前账号绑定了 {} 个角色'.format(len(rolesList))) - infoList = [] - # cn_gf01: 天空岛 - # cn_qd01: 世界树 - self._regionList = [(i.get('region', 'NA')) for i in rolesList] - self._regionNameList = [(i.get('region_name', 'NA')) for i in rolesList] - self._uidList = [(i.get('game_uid', 'NA')) for i in rolesList] - - logging.info('准备获取签到信息...') - for i in range(len(self._uidList)): - info_url = Conf.info_url.format(self._regionList[i], - Conf.act_id, self._uidList[i]) - try: - infoList.append(json.loads(requests.Session().get( - info_url, headers = self.get_header()).text)) - logging.info('签到信息获取完毕') - except Exception as e: - logging.error(e) - - return infoList - - def run(self): - logging.info('任务开始') - messageList = [] - infoList = self.get_info() - status = '失败' - for i in range(len(infoList)): - today = infoList[i]['data']['today'] - totalSignDay = infoList[i]['data']['total_sign_day'] - awards = Roles(self._cookie).get_awards()['data']['awards'] - uid = str(self._uidList[i]).replace( - str(self._uidList[i])[3:6], '***', 1) - if infoList[i]['data']['is_sign'] is True: - #if infoList[i]['data']['is_sign'] is False: - status = '成功' - messageList.append(self.message().format(today, - self._regionNameList[i], uid, - awards[totalSignDay - 1]['name'], awards[totalSignDay - 1]['cnt'], - totalSignDay, '旅行者 {} 号,你已经签到过了'.format(i + 1), '')) - elif infoList[i]['data']['first_bind'] is True: - messageList.append(' 旅行者 {} 号为首次绑定,请先前往米游社App手动签到一次'.format(i + 1)) - else: - data = { - 'act_id': Conf.act_id, - 'region': self._regionList[i], - 'uid': self._uidList[i] - } - - logging.info('准备为旅行者 {} 号签到...' \ - '\n 区服: {}\n UID: {}'.format(i + 1, self._regionNameList[i], uid)) - try: - jdict = json.loads(requests.Session().post( - Conf.sign_url, headers = self.get_header(), - data = json.dumps(data, ensure_ascii=False)).text) - logging.info('签到完毕') - except Exception as e: - raise - else: - code = jdict['retcode'] - # 0: success - # -5003: already signed in - if code == 0: - status = '成功' - - messageList.append(self.message().format(today, - self._regionNameList[i], uid, - awards[totalSignDay]['name'], awards[totalSignDay]['cnt'], - totalSignDay + 1, jdict['message'], '')) - else: - messageList.append(jdict) - - return notify(sckey, status, ",".join(messageList)) - - def message(self): - return ''' - {:#^30} - 🔅[{}]{} - 今日奖励: {} × {} - 本月累签: {} 天 - 签到结果: {} - {:#^30}''' - - -def notify(sckey, status, message): - logging.info('签到{}: {}'.format(status, message)) - if sckey.startswith('SC'): - logging.info('准备推送通知...') - url = 'https://sc.ftqq.com/{}.send'.format(sckey) - data = {'text': '原神签到小助手 签到{}'.format(status), 'desp': message} - try: - jdict = json.loads( - requests.Session().post(url, data = data).text) - except Exception as e: - logging.error(e) - raise HTTPError - else: - errmsg = jdict['errmsg'] - if errmsg == 'success': - logging.info('推送成功') - else: - logging.error('{}: {}'.format('推送失败', jdict)) - else: - logging.info('未配置 SCKEY,正在跳过通知推送') - - logging.info('任务结束') - if status == '失败': - return exit(-1) - - -if __name__ == '__main__': - secret = input().strip().split('#') - secret.append('') - cookie = secret[0] - sckey = secret[1] - - Sign(cookie).run() - From 4cf05465adb1c7de9741394ad4b899c5001d92e6 Mon Sep 17 00:00:00 2001 From: PomeloWang Date: Tue, 5 Jan 2021 20:13:19 +0800 Subject: [PATCH 14/15] Refactor code --- .github/workflows/main.yml | 2 ++ .gitignore | 56 ++++++++++++++++++++++++++++++++++++++ .python-version | 1 + README.md | 43 +++++++++++++++++++++++++++++ settings.py | 46 +++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+) create mode 100644 .gitignore create mode 100644 .python-version create mode 100644 settings.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3dd943d..f8b7f34 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,6 +8,8 @@ on: env: # auto merge from y1ndan/genshin-impact-helper, default: false ALLOW_MERGE: 'false' + RUN_ENV: 'prod' + TZ: 'Asia/Shanghai' jobs: build: diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..291a53d --- /dev/null +++ b/.gitignore @@ -0,0 +1,56 @@ +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +__pycache__ + +# Installer logs +pip-log.txt + +# Unit tmp / coverage reports +.coverage +.tox +nosetests.xml +.pytest_cache + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# temp file +.DS_Store +*.pkl + +# venv +.venv/ + +# Cookiecutter +output/ + +# vscode +.vscode + +# notebooks +notebooks/ + +# idea +.idea diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..530716d --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +genshin-impact-helper diff --git a/README.md b/README.md index 37e3a7f..5bd7c33 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,49 @@ Error: Process completed with exit code 255. +## 🔨开发 + +如果需要重构或增加额外功能参考以下数据 + +```python +roles = Roles(cookie).get_roles() +roles = { + 'retcode': 0, + 'message': 'OK', + 'data': { + 'list': [ + { + 'game_biz': 'hk4e_cn', + 'region': 'cn_gf01', + 'game_uid': '111111111', + 'nickname': '酸柚子', + 'level': 48, + 'is_chosen': False, + 'region_name': '天空岛', + 'is_official': True + } + ] + } +} +``` +```python +infos = Sign(cookie).get_info() +infos = [ + { + 'retcode': 0, + 'message': 'OK', + 'data': { + 'total_sign_day': 5, + 'today': '2021-01-05', + 'is_sign': True, + 'first_bind': False, + 'is_sub': False, + 'month_first': False + } + } +] + +``` ## 🔔订阅 若开启订阅推送,无论成功与否,都会收到微信通知。 diff --git a/settings.py b/settings.py new file mode 100644 index 0000000..e5b2abb --- /dev/null +++ b/settings.py @@ -0,0 +1,46 @@ +# settings +import logging + +import os + +__all__ = ['log', 'CONFIG'] + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s %(levelname)s %(message)s', + datefmt='%Y-%m-%dT%H:%M:%S') + + +log = logger = logging + + +class _Config: + ACT_ID = 'e202009291139501' + APP_VERSION = '2.3.0' + REFERER_URL = 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?' \ + 'bbs_auth_required={}&act_id={}&utm_source={}&utm_medium={}&' \ + 'utm_campaign={}'.format('true', ACT_ID, 'bbs', 'mys', 'icon') + AWARD_URL = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/home?act_id={}'.format(ACT_ID) + ROLE_URL = 'https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz={}'.format('hk4e_cn') + INFO_URL = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?region={}&act_id={}&uid={}' + SIGN_URL = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign' + USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) ' \ + 'miHoYoBBS/{}'.format(APP_VERSION) + + +class ProductionConfig(_Config): + LOG_LEVEL = logging.INFO + + +class DevelopmentConfig(_Config): + LOG_LEVEL = logging.DEBUG + + +RUN_ENV = os.environ.get('RUN_ENV', 'dev') +if RUN_ENV == 'dev': + CONFIG = DevelopmentConfig() +else: + CONFIG = ProductionConfig() + +log.basicConfig(level=CONFIG.LOG_LEVEL) + From 5d2af3b42281114229ee25e6dd44390a150f3833 Mon Sep 17 00:00:00 2001 From: PomeloWang Date: Tue, 5 Jan 2021 20:46:31 +0800 Subject: [PATCH 15/15] refactor: genshin.py --- genshin.py | 492 +++++++++++++++++++++++++---------------------------- 1 file changed, 232 insertions(+), 260 deletions(-) mode change 100755 => 100644 genshin.py diff --git a/genshin.py b/genshin.py old mode 100755 new mode 100644 index 0eb2ef0..958c15e --- a/genshin.py +++ b/genshin.py @@ -1,286 +1,258 @@ -#!/usr/bin/env python3 +import hashlib +import json +import random +import string +import time +import uuid import requests -import argparse -import json -import uuid -import logging -import time -import random -import hashlib -import string from requests.exceptions import * -logging.basicConfig( - level = logging.INFO, - format = '%(asctime)s %(levelname)s %(message)s', - datefmt = '%Y-%m-%dT%H:%M:%S') +from settings import * -class ConfMeta(type): - @property - def ref_url(self): - return 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?' \ - 'bbs_auth_required={}&act_id={}&utm_source={}&utm_medium={}&' \ - 'utm_campaign={}'.format('true', self.act_id, 'bbs', 'mys', 'icon') - - @property - def award_url(self): - return 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/home?' \ - 'act_id={}'.format(self.act_id) - - @property - def role_url(self): - return 'https://api-takumi.mihoyo.com/binding/api/' \ - 'getUserGameRolesByCookie?game_biz={}'.format('hk4e_cn') - - @property - def info_url(self): - return 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?' \ - 'region={}&act_id={}&uid={}' - - @property - def sign_url(self): - return 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign' - - @property - def app_version(self): - return '2.3.0' - - @property - def ua(self): - return 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) Apple' \ - 'WebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/{}'.format(self.app_version) - - @property - def act_id(self): - return 'e202009291139501' - - -class Conf(metaclass=ConfMeta): - pass - - -class Roles(object): - def __init__(self, cookie:str=None): - if type(cookie) is not str: - raise TypeError('%s want a %s but got %s' %( - self.__class__, type(__name__), type(cookie))) - self._cookie = cookie - - def get_header(self): - return { - 'User-Agent': Conf.ua, - 'Referer': Conf.ref_url, - 'Accept-Encoding': 'gzip, deflate, br', - 'Cookie': self._cookie - } - - def get_awards(self): - try: - jdict = json.loads( - requests.Session().get( - Conf.award_url, headers = self.get_header()).text) - except Exception as e: - logging.error(e) - - return jdict - - def get_roles(self): - logging.info('准备获取账号信息...') - errstr = None - - for i in range(1, 4): - try: - jdict = json.loads(requests.Session().get( - Conf.role_url, headers = self.get_header()).text) - except HTTPError as e: - logging.error('HTTP error when get user game roles, ' \ - 'retry %s time(s) ...' %(i)) - logging.error('error is %s' %(e)) - errstr = str(e) - continue - except KeyError as e: - logging.error('Wrong response to get user game roles, ' \ - 'retry %s time(s) ...' %(i)) - logging.error('response is %s' %(e)) - errstr = str(e) - continue - except Exception as e: - logging.error('Unknown error %s, die' %(e)) - errstr = str(e) - raise - else: - break - - try: - jdict - logging.info('账号信息获取完毕') - except AttributeError: - raise Exception(errstr) - - return jdict - - -class Sign(object): - def __init__(self, cookie:str=None): - if type(cookie) is not str: - raise TypeError('%s want a %s but got %s' %( - self.__class__, type(__name__), type(cookie))) - self._cookie = cookie - - def md5(self, text): +def hexdigest(text): md5 = hashlib.md5() md5.update(text.encode()) return md5.hexdigest() - def get_DS(self): - # n = self.md5(2.1.0) # v2.1.0 @Steesha - # n = 'cx2y9z9a29tfqvr1qsq6c7yz99b5jsqt' # v2.2.0 @Womsxd - n = 'h8w582wxwgqvahcdkpvdhbh2w9casgfl' # v2.3.0 web @povsister & @journey-ad - i = str(int(time.time())) - r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6)) - c = self.md5('salt=' + n + '&t='+ i + '&r=' + r) - return '{},{},{}'.format(i, r, c) - def get_header(self): - return { - 'x-rpc-device_id': str(uuid.uuid3( - uuid.NAMESPACE_URL, self._cookie)).replace('-','').upper(), - # 1: ios - # 2: android - # 4: pc web - # 5: mobile web - 'x-rpc-client_type': '5', - 'Accept-Encoding': 'gzip, deflate, br', - 'User-Agent': Conf.ua, - 'Referer': Conf.ref_url, - 'x-rpc-app_version': Conf.app_version, - 'DS': self.get_DS(), - 'Cookie': self._cookie - } +class Base(object): + def __init__(self, cookies: str = None): + if not isinstance(cookies, str): + raise TypeError('%s want a %s but got %s' % ( + self.__class__, type(__name__), type(cookies))) + self._cookie = cookies - def get_info(self): - roles = Roles(self._cookie).get_roles() - try: - rolesList = roles['data']['list'] - except Exception as e: - notify(sckey, '失败', roles['message']) - else: - logging.info('当前账号绑定了 {} 个角色'.format(len(rolesList))) - infoList = [] - # cn_gf01: 天空岛 - # cn_qd01: 世界树 - self._regionList = [(i.get('region', 'NA')) for i in rolesList] - self._regionNameList = [(i.get('region_name', 'NA')) for i in rolesList] - self._uidList = [(i.get('game_uid', 'NA')) for i in rolesList] + def get_header(self): + header = { + 'User-Agent': CONFIG.USER_AGENT, + 'Referer': CONFIG.REFERER_URL, + 'Accept-Encoding': 'gzip, deflate, br', + 'Cookie': self._cookie + } + return header - logging.info('准备获取签到信息...') - for i in range(len(self._uidList)): - info_url = Conf.info_url.format(self._regionList[i], - Conf.act_id, self._uidList[i]) + @staticmethod + def to_python(json_str: str): + return json.loads(json_str) + + @staticmethod + def to_json(obj): + return json.dumps(obj, indent=4, ensure_ascii=False) + + +class Roles(Base): + def get_awards(self): + response = dict try: - infoList.append(json.loads(requests.Session().get( - info_url, headers = self.get_header()).text)) - logging.info('签到信息获取完毕') - except Exception as e: - logging.error(e) + content = requests.Session().get(CONFIG.AWARD_URL, headers=self.get_header()).text + response = self.to_python(content) + except json.JSONDecodeError as e: + log.error(e) - return infoList + return response - def run(self): - logging.info('任务开始') - messageList = [] - infoList = self.get_info() - status = '失败' - for i in range(len(infoList)): - today = infoList[i]['data']['today'] - totalSignDay = infoList[i]['data']['total_sign_day'] - awards = Roles(self._cookie).get_awards()['data']['awards'] - uid = str(self._uidList[i]).replace( - str(self._uidList[i])[3:6], '***', 1) - if infoList[i]['data']['is_sign'] is True: - #if infoList[i]['data']['is_sign'] is False: - status = '成功' - messageList.append(self.message().format(today, - self._regionNameList[i], uid, - awards[totalSignDay - 1]['name'], awards[totalSignDay - 1]['cnt'], - totalSignDay, '旅行者 {} 号,你已经签到过了'.format(i + 1), '')) - elif infoList[i]['data']['first_bind'] is True: - messageList.append(' 旅行者 {} 号为首次绑定,请先前往米游社App手动签到一次'.format(i + 1)) - else: - data = { - 'act_id': Conf.act_id, - 'region': self._regionList[i], - 'uid': self._uidList[i] + def get_roles(self, max_attempt_number: int = 4): + log.info('准备获取账号信息...') + error = None + response = dict() + + for i in range(1, max_attempt_number): + try: + content = requests.Session().get(CONFIG.ROLE_URL, headers=self.get_header()).text + response = self.to_python(content) + except HTTPError as error: + log.error('HTTP error when get user game roles, retry %s time(s) ...' % i) + log.error('error is %s' % error) + continue + except KeyError as error: + log.error('Wrong response to get user game roles, retry %s time(s) ...' % i) + log.error('response is %s' % error) + continue + except Exception as error: + log.error('Unknown error %s, die' % error) + raise error + error = None + break + + if error: + log.error('Maximum retry times have been reached, error is %s ' % error) + raise error + if response.get('retcode', 1) != 0 or response.get('data', None) is None: + log.error(response) + exit(-1) + + log.info("账号信息获取完毕") + return response + + +class Sign(Base): + def __init__(self, cookies: str = None): + super(Sign, self).__init__(cookies) + self._region_list = [] + self._region_name_list = [] + self._uid_list = [] + + @staticmethod + def get_ds(): + n = 'h8w582wxwgqvahcdkpvdhbh2w9casgfl' # v2.3.0 web @povsister & @journey-ad + i = str(int(time.time())) + r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6)) + c = hexdigest('salt=' + n + '&t=' + i + '&r=' + r) + return '{},{},{}'.format(i, r, c) + + def get_header(self): + header = super(Sign, self).get_header() + header.update({ + 'x-rpc-device_id': str(uuid.uuid3(uuid.NAMESPACE_URL, self._cookie)).replace('-', '').upper(), + # 1: ios + # 2: android + # 4: pc web + # 5: mobile web + 'x-rpc-client_type': '5', + 'x-rpc-app_version': CONFIG.APP_VERSION, + 'DS': self.get_ds(), + }) + return header + + def get_info(self): + user_game_roles = Roles(self._cookie).get_roles() + role_list = user_game_roles.get('data', {}).get('list', []) + + # role list empty + if not role_list: + notify(sc_secret, '失败', user_game_roles.get('message', 'role list empty')) + exit(-1) + + log.info('当前账号绑定了 {} 个角色'.format(len(role_list))) + info_list = [] + # cn_gf01: 天空岛 + # cn_qd01: 世界树 + self._region_list = [(i.get('region', 'NA')) for i in role_list] + self._region_name_list = [(i.get('region_name', 'NA')) for i in role_list] + self._uid_list = [(i.get('game_uid', 'NA')) for i in role_list] + + log.info('准备获取签到信息...') + for i in range(len(self._uid_list)): + info_url = CONFIG.INFO_URL.format(self._region_list[i], CONFIG.ACT_ID, self._uid_list[i]) + try: + content = requests.Session().get(info_url, headers=self.get_header()).text + info_list.append(self.to_python(content)) + except Exception as e: + log.error(e) + + if not info_list: + log.error("user sign info list is empty, exit...") + exit(-1) + log.info("签到信息获取完毕") + return info_list + + def run(self): + log.info('任务开始') + status = "成功" + messages = { + 'success': [], + 'failed': [], + 'already_signed_in': [], } - logging.info('准备为旅行者 {} 号签到...' \ - '\n 区服: {}\n UID: {}'.format(i + 1, self._regionNameList[i], uid)) + info_list = self.get_info() + for i in range(len(info_list)): + today = info_list[i]['data']['today'] + total_sign_day = info_list[i]['data']['total_sign_day'] + award = Roles(self._cookie).get_awards()['data']['awards'] + uid = str(self._uid_list[i]).replace(str(self._uid_list[i])[3:6], '***', 1) + + # 已经签到, 处理下一个用户 + if info_list[i]['data']['is_sign'] is True: + messages.get('already_signed_in', []).append("旅行者 {} 号, 你已经签到过了".format(i + 1)) + continue + if info_list[i]['data']['first_bind'] is True: + messages.get('failed', []).append("旅行者 {} 号, 请先前往米游社App手动签到一次".format(i + 1)) + exit(-1) + + data = { + 'act_id': CONFIG.ACT_ID, + 'region': self._region_list[i], + 'uid': self._uid_list[i] + } + + log.info('准备为旅行者 {} 号签到... {}'.format(i + 1, self.to_json({ + 'Region': self._region_name_list[i], + 'UID': uid + }))) + try: + content = requests.Session().post( + CONFIG.SIGN_URL, + headers=self.get_header(), + data=json.dumps(data, ensure_ascii=False)).text + response = self.to_python(content) + except Exception as e: + raise e + code = response.get('retcode', 99999) + # 0: success + # -5003: already signed in + if code == 0: + message = self.message.format( + today, + self._region_name_list[i], + uid, + award['name'], + award['cnt'], + total_sign_day + 1, + response['message'], + '' + ) + messages.get('success', []).append(message) + else: + messages.get('failed', []).append(response) + + if messages.get('failed', []): + status = "失败" + + return notify(sc_secret, status, messages) + + @property + def message(self): + return ''' + {:#^30} + 🔅[{}]{} + 今日奖励: {} × {} + 本月累签: {} 天 + 签到结果: {} + {:#^30} + ''' + + +def notify(secret: str, status: str, message): + if secret.startswith('SC'): + log.info('准备推送通知...') + url = 'https://sc.ftqq.com/{}.send'.format(secret) + data = {'text': '原神签到小助手 签到{}'.format(status), 'desp': message} try: - jdict = json.loads(requests.Session().post( - Conf.sign_url, headers = self.get_header(), - data = json.dumps(data, ensure_ascii=False)).text) - logging.info('签到完毕') + response = Sign.to_python(requests.Session().post(url, data=data).text) except Exception as e: - raise + log.error(e) + raise HTTPError else: - code = jdict['retcode'] - # 0: success - # -5003: already signed in - if code == 0: - status = '成功' - - messageList.append(self.message().format(today, - self._regionNameList[i], uid, - awards[totalSignDay]['name'], awards[totalSignDay]['cnt'], - totalSignDay + 1, jdict['message'], '')) - else: - messageList.append(jdict) - - return notify(sckey, status, ",".join(messageList)) - - def message(self): - return ''' - {:#^30} - 🔅[{}]{} - 今日奖励: {} × {} - 本月累签: {} 天 - 签到结果: {} - {:#^30}''' - - -def notify(sckey, status, message): - logging.info('签到{}: {}'.format(status, message)) - if sckey.startswith('SC'): - logging.info('准备推送通知...') - url = 'https://sc.ftqq.com/{}.send'.format(sckey) - data = {'text': '原神签到小助手 签到{}'.format(status), 'desp': message} - try: - jdict = json.loads( - requests.Session().post(url, data = data).text) - except Exception as e: - logging.error(e) - raise HTTPError + errmsg = response['errmsg'] + if errmsg == 'success': + log.info('推送成功') + else: + log.error('{}: {}'.format('推送失败', response)) else: - errmsg = jdict['errmsg'] - if errmsg == 'success': - logging.info('推送成功') - else: - logging.error('{}: {}'.format('推送失败', jdict)) - else: - logging.info('未配置 SCKEY,正在跳过通知推送') - - logging.info('任务结束') - if status == '失败': - return exit(-1) + log.info('未配置SCKEY,正在跳过推送') + if isinstance(message, list) or isinstance(message, dict): + message = Sign.to_json(message) + log.info('签到{}: {}'.format(status, message)) + return log.info('任务结束') if __name__ == '__main__': - secret = input().strip().split('#') - secret.append('') - cookie = secret[0] - sckey = secret[1] - - Sign(cookie).run() + secret = input().strip().split('#') + secret.append('') + cookie = secret[0] + sc_secret = secret[1] + Sign(cookie).run()