├── README.md ├── 下个节假日.py ├── 今日热搜.py ├── 和风天气.py ├── 天行语录.py ├── 彩云天气.py ├── 每天60s读懂世界.py ├── 每日语录.py ├── 科技玩家.js ├── 重要日倒计时.py ├── 重要日倒计时阴历+阳历版.py └── 阿里云盘.py /README.md: -------------------------------------------------------------------------------- 1 | # QinglongScript 2 | 自用的青龙容器脚本,天气预报、每天60s读懂世界、阿里云盘签到、天翼云盘签到、重要日倒计时、科技玩家签到等等 3 | -------------------------------------------------------------------------------- /下个节假日.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | 5 | import requests 6 | import json 7 | import notify 8 | 9 | title = "下个节假日" 10 | 11 | dateurl = 'https://date.appworlds.cn/next' 12 | date1url = 'https://date.appworlds.cn/next/days' 13 | holiday = requests.get(dateurl) 14 | holiday1 = requests.get(date1url) 15 | 16 | desc = json.loads(holiday.text) 17 | desc1 = json.loads(holiday1.text) 18 | 19 | daytime = desc['data']['date'] 20 | dayname = desc['data']['name'] 21 | Remain = desc1['data'] 22 | 23 | info = f""" 24 | 下个节假日是{Remain}天后的{dayname}({daytime}) 25 | """ 26 | print(info) 27 | notify.send(title, info) 28 | -------------------------------------------------------------------------------- /今日热搜.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | # 默认百度,可在第8行修改其他源:1.Baidu 2.DouYin 3.SoGou 4.So 5.WeiBo 6.ZhiHu 7.TouTiao 8.KuaiShou 9.BiliBli 10.BaiduTieBa 5 | import requests 6 | import json 7 | import notify 8 | orig = 'Baidu' #如需改成抖音就填DouYin,以此类推 9 | url = f'https://api.gumengya.com/Api/{orig}Hot?format=json' 10 | resp = requests.get(url) 11 | data = json.loads(resp.text) 12 | news = "" 13 | for i in range(8): 14 | item = data['data'][i] 15 | news += item['title'] + ' ' + item['url'] + "\n" + "\n" 16 | notify.send("今日热搜", news) 17 | -------------------------------------------------------------------------------- /和风天气.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import notify 4 | 5 | #填写下面的信息,loca应填的数字请自行去和风官网查找,使用青龙自带的推送 6 | api = "你的和风天气API key" 7 | loca = "数字,代表你所在位置" 8 | 9 | # 和风天气获取 10 | api_url = f"https://devapi.qweather.com/v7/weather/now?location={loca}&key={api}" 11 | apim_url = f"https://devapi.qweather.com/v7/minutely/5m?location={loca}&key={api}" 12 | apiw_url = f"https://devapi.qweather.com/v7/warning/now?location={loca}&key={api}" 13 | apii_url = f"https://devapi.qweather.com/v7/indices/1d?type=3,5,13&location={loca}&key={api}" 14 | response = requests.get(api_url) 15 | data = json.loads(response.text) 16 | weather = data['now'] 17 | responsem = requests.get(apim_url) 18 | datam = json.loads(responsem.text) 19 | weatherm = datam['summary'] 20 | responsew = requests.get(apiw_url) 21 | dataw = json.loads(responsew.text) 22 | weatherw = dataw['warning'] 23 | responsei = requests.get(apii_url) 24 | datai = json.loads(responsei.text) 25 | weatheri = datai['daily'] 26 | 27 | if weatherw: 28 | tip = weatherw[0]['text'] 29 | else: 30 | tip = "" 31 | 32 | #汇总信息 33 | info = f""" 34 | {weather['text']},{weather['windDir']}{weather['windScale']}级 35 | 温度:{weather['temp']}°C 体感温度:{weather['feelsLike']}°C 36 | 湿度:{weather['humidity']}% 37 | 能见度:{weather['vis']}KM 38 | {weatheri[0]['text']} 39 | {weatheri[1]['text']} 40 | {weatheri[2]['text']} 41 | 预测:{weatherm} 42 | {tip} 43 | """ 44 | infot = f""" 45 | {weather['obsTime']} 46 | """ 47 | notify.send(infot, info) 48 | -------------------------------------------------------------------------------- /天行语录.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | # 自行修改19、20、21三行,其中20行的api必填. 5 | # 需要在天行提前注册获取api(https://www.tianapi.com/console/,数据管理-我的密钥key)并申请相应接口才能使用,https://www.tianapi.com/list/ 6 | import requests 7 | import json 8 | import notify 9 | pyurl = f'https://apis.tianapi.com/pyqwenan/index?key={api}' #朋友圈文案 10 | hsurl = f'https://apis.tianapi.com/hsjz/index?key={api}' #失恋分手句子 11 | caurl = f'https://apis.tianapi.com/caihongpi/index?key={api}' #彩虹屁 12 | tiurl = f'https://apis.tianapi.com/tiangou/index?key={api}' #舔狗日志 13 | duurl = f'https://apis.tianapi.com/dujitang/index?key={api}' #毒鸡汤 14 | zhurl = f'https://apis.tianapi.com/zhanan/index?key={api}' #渣男语录 15 | zaurl = f'https://apis.tianapi.com/zaoan/index?key={api}' #早安心语 16 | waurl = f'https://apis.tianapi.com/wanan/index?key={api}' #晚安心语 17 | saurl = f'https://apis.tianapi.com/saylove/index?key={api}' #土味情话 18 | 19 | urls = [pyurl, tiurl, duurl] # 按照格式填写你要推送的内容对应的url,默认是朋友圈文案、舔狗日志和毒鸡汤 20 | api = "你的天行API key" 21 | count = 2 # 相同类型推文的数量,默认是两条 22 | 23 | contents = "" 24 | for url in urls: 25 | for i in range(count): 26 | response = requests.get(url) 27 | data = json.loads(response.text) 28 | contents += data['result']['content'] + "\n" + "\n" 29 | notify.send("语录", contents) 30 | -------------------------------------------------------------------------------- /彩云天气.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | 5 | import requests 6 | import json 7 | import notify 8 | #填写下面的信息,经纬度请自行百度,使用青龙自带的推送 9 | key = "你的彩云天气API key" 10 | lon = "你所在位置的经度" 11 | lat = "你所在位置的纬度" 12 | 13 | #下面的不用管了 14 | api_url = f"https://api.caiyunapp.com/v2.6/{key}/{lon},{lat}/weather?alert=true&realtime&minutely" 15 | response = requests.get(api_url) 16 | data = json.loads(response.text) 17 | weather = data['result'] 18 | 19 | if weather['alert']['content']: 20 | tip = weather['alert']['content'][0]['description'] 21 | else: 22 | tip = "" 23 | 24 | info = f""" 25 | 实时天气: 26 | 天气现象:{weather['realtime']['skycon']} 27 | 温度:{weather['realtime']['temperature']}°C 28 | 体感温度:{weather['realtime']['apparent_temperature']}°C 29 | 湿度:{weather['realtime']['humidity']} 30 | 能见度:{weather['realtime']['visibility']}KM 31 | 紫外线强度:{weather['realtime']['life_index']['ultraviolet']['desc']} 32 | 空气质量:{weather['realtime']['air_quality']['description']['chn']} 33 | 总体感觉:{weather['realtime']['life_index']['comfort']['desc']} 34 | 35 | 全天: 36 | 温度:{weather['daily']['temperature'][0]['min']} - {weather['daily']['temperature'][0]['max']}°C, 白天温度:{weather['daily']['temperature_08h_20h'][0]['min']} - {weather['daily']['temperature_08h_20h'][0]['max']}°C, 夜间温度:{weather['daily']['temperature_20h_32h'][0]['min']} - {weather['daily']['temperature_20h_32h'][0]['max']}°C 37 | 紫外线强度{weather['daily']['life_index']['ultraviolet'][0]['desc']},总体感觉{weather['daily']['life_index']['comfort'][0]['desc']} 38 | 39 | 预测:{weather['minutely']['description']},{weather['hourly']['description']} 40 | {tip} 41 | """ 42 | 43 | print(info) 44 | notify.send("彩云天气", info) 45 | -------------------------------------------------------------------------------- /每天60s读懂世界.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | # 使用青龙自带的通知,某些推送不支持较长的文本推送,故默认分片推送,如果需要合并推送请将25和26行加#注释掉,29行去除#注释即可。 5 | import requests 6 | import json 7 | import notify 8 | 9 | url = 'https://60s.viki.moe/?encoding=text' 10 | resp = requests.get(url) 11 | content = resp.text 12 | # 分片处理 13 | pieces = resp.text.split('\n', 8) 14 | content1 = '\n'.join(pieces[:8]) 15 | content2 = '\n'.join(pieces[8:]) 16 | 17 | info1 = f""" 18 | {content1} 19 | """ 20 | info2 = f""" 21 | {content2} 22 | """ 23 | 24 | # 发送分片推送 25 | notify.send("每天60s读懂世界", info1 + "\n\n") 26 | notify.send("每天60s读懂世界", info2) 27 | 28 | # 全文整段发送推送 29 | # notify.send("每天60s读懂世界", content) 30 | -------------------------------------------------------------------------------- /每日语录.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | # 用的故梦api,https://api.gumengya.com/ 5 | # 要自定义请自行修改15、16行,默认是2条随机一言和2条随机笑话 6 | import requests 7 | import json 8 | import notify 9 | Yiurl = 'https://api.gumengya.com/Api/YiYan?format=json' #随机一言 10 | Xiurl = 'https://api.gumengya.com/Api/Xiaohua?format=json' #随机笑话 11 | Dourl = 'https://api.gumengya.com/Api/Dog?format=json' #随机舔狗日记 12 | Waurl = 'https://api.gumengya.com/Api/WaSentence?format=json' #随机文案 13 | Lourl = 'https://api.gumengya.com/Api/LoveSentence?format=json' #随机土味情话 14 | 15 | urls = [Yiurl, Xiurl] # 按照格式填写你要推送的内容对应的url 16 | count = 2 # 相同类型推文的数量 17 | 18 | contents = "" 19 | for url in urls: 20 | for i in range(count): 21 | response = requests.get(url) 22 | data = json.loads(response.text) 23 | contents += data['data']['text'] + "\n" + "\n" 24 | notify.send("每日语录", contents) 25 | -------------------------------------------------------------------------------- /科技玩家.js: -------------------------------------------------------------------------------- 1 | # 似乎已经失效,应该是网站后端的API和流程发生改变,需求不大我也懒得改了。 2 | # 不是我写的,不是我写的,不是我写的!在作者的基础上仅仅修改了关注数变为1个人,如有侵权请提issue 3 | /** 4 | 作者:临渊 5 | 日期:6-15 6 | 网站:科技玩家 7 | 功能:签到、关注 8 | 变量:kjwj='账号&密码' 多个账号用换行分割 9 | 定时:一天一次 10 | cron:10 10 * * * 11 | 因为用Leaf大佬的会莫名其妙报错,所以就用Leaf大佬的源码改了一下,感谢Leaf大佬的源码(大佬的代码真优雅) 12 | 13 | 6-29 增加了关注,但可能会被风控取消 14 | */ 15 | 16 | const $ = new Env('科技玩家'); 17 | const notify = $.isNode() ? require('./sendNotify') : ''; 18 | const {log} = console; 19 | const Notify = 1; //0为关闭通知,1为打开通知,默认为1 20 | const debug = 0; //0为关闭调试,1为打开调试,默认为0 21 | ////////////////////// 22 | let kjwj = process.env.kjwj; 23 | let kjwjArr = []; 24 | let data = ''; 25 | let msg = ''; 26 | let loginBack = 0; 27 | let token = ''; 28 | let name = ''; 29 | 30 | 31 | !(async () => { 32 | 33 | if (!(await Envs())) 34 | return; 35 | else { 36 | 37 | 38 | 39 | log(`\n\n============================================= \n脚本执行 - 北京时间(UTC+8):${new Date( 40 | new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 + 41 | 8 * 60 * 60 * 1000).toLocaleString()} \n=============================================\n`); 42 | 43 | await poem(); 44 | 45 | log(`\n=================== 共找到 ${kjwjArr.length} 个账号 ===================`) 46 | 47 | if (debug) { 48 | log(`【debug】 这是你的全部账号数组:\n ${kjwjArr}`); 49 | } 50 | 51 | 52 | for (let index = 0; index < kjwjArr.length; index++) { 53 | 54 | 55 | let num = index + 1 56 | log(`\n========= 开始【第 ${num} 个账号】=========\n`) 57 | 58 | kjwj = kjwjArr[index].split('&'); 59 | 60 | if (debug) { 61 | log(`\n 【debug】 这是你第 ${num} 账号信息:\n ${data}\n`); 62 | } 63 | 64 | msg += `\n第${num}个账号运行结果:` 65 | 66 | log('【开始登录】'); 67 | await login(); 68 | await $.wait(2 * 1000); 69 | 70 | if (loginBack != 1){ 71 | 72 | log('【开始查询签到状态】'); 73 | await getSign(); 74 | await $.wait(2 * 1000); 75 | 76 | for (let i = 0; i < 1; i++) { 77 | log(`【开始第${i+1}次关注】`); 78 | await doFollow(); 79 | await $.wait(randomInt(15000,25000)); 80 | } 81 | } 82 | 83 | } 84 | await SendMsg(msg); 85 | } 86 | 87 | })() 88 | .catch((e) => log(e)) 89 | .finally(() => $.done()) 90 | 91 | /** 92 | * 登录 93 | */ 94 | function login(timeout = 3 * 1000) { 95 | return new Promise((resolve) => { 96 | let url = { 97 | url: `https://www.kejiwanjia.com/wp-json/jwt-auth/v1/token`, 98 | headers: { 99 | "Host": "www.kejiwanjia.com", 100 | "Connection": "keep-alive", 101 | "Accept": "application/json, text/plain, */*", 102 | "User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002;) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", 103 | "Content-Type": "application/x-www-form-urlencoded" 104 | }, 105 | body: `nickname=&username=${kjwj[0]}&password=${kjwj[1]}&code=&img_code=&invitation_code=&token=&smsToken=&luoToken=&confirmPassword=&loginType=`, 106 | } 107 | 108 | if (debug) { 109 | log(`\n【debug】=============== 这是 登录 请求 url ===============`); 110 | log(JSON.stringify(url)); 111 | } 112 | 113 | $.post(url, async (error, response, data) => { 114 | try { 115 | if (debug) { 116 | log(`\n\n【debug】===============这是 登录 返回data==============`); 117 | log(data) 118 | } 119 | 120 | let result = JSON.parse(data); 121 | if (result.code == 1) { 122 | 123 | loginBack = 1; 124 | log(`【登录失败】${result.message} `) 125 | msg += `\n【登陆失败】${result.message}` 126 | 127 | } else { 128 | 129 | log(`\n账号[${result.name}]登录成功,现有积分:${result.credit}`) 130 | token = result.token; 131 | name = result.name; 132 | 133 | } 134 | 135 | } catch (e) { 136 | log(e) 137 | } finally { 138 | resolve(); 139 | } 140 | }, timeout) 141 | }) 142 | } 143 | 144 | /** 145 | * 查询签到状态 146 | */ 147 | function getSign(timeout = 3 * 1000) { 148 | return new Promise((resolve) => { 149 | let url = { 150 | url: `https://www.kejiwanjia.com/wp-json/b2/v1/getUserMission`, 151 | headers: { 152 | "Host": "www.kejiwanjia.com", 153 | "Connection": "keep-alive", 154 | "Accept": "application/json, text/plain, */*", 155 | "User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002;) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", 156 | "Content-Type": "application/x-www-form-urlencoded", 157 | "Authorization": `Bearer ${token}`, 158 | "Cookie": `b2_token=${token};` 159 | }, 160 | body: 'count=5&paged=1', 161 | } 162 | 163 | if (debug) { 164 | log(`\n【debug】=============== 这是 查询签到状态 请求 url ===============`); 165 | log(JSON.stringify(url)); 166 | } 167 | 168 | $.post(url, async (error, response, data) => { 169 | try { 170 | if (debug) { 171 | log(`\n\n【debug】===============这是 查询签到状态 返回data==============`); 172 | log(data) 173 | } 174 | 175 | let result = JSON.parse(data); 176 | if (result.code == 1) { 177 | 178 | log(`查询签到状态失败`) 179 | 180 | } else { 181 | 182 | if(result.mission.credit == 0) { 183 | await $.wait(1000); 184 | await signin(); 185 | } else { 186 | log(`账号[${name}]今天已签到,获得了${result.mission.credit}积分`) 187 | msg += `账号[${name}]今天已签到,获得了${result.mission.credit}积分` 188 | } 189 | 190 | } 191 | 192 | } catch (e) { 193 | log(e) 194 | } finally { 195 | resolve(); 196 | } 197 | }, timeout) 198 | }) 199 | } 200 | 201 | /** 202 | * 签到 203 | */ 204 | function signin(timeout = 3 * 1000) { 205 | return new Promise((resolve) => { 206 | let url = { 207 | url: `https://www.kejiwanjia.com/wp-json/b2/v1/userMission`, 208 | headers: { 209 | "Host": "www.kejiwanjia.com", 210 | "Connection": "keep-alive", 211 | "Accept": "application/json, text/plain, */*", 212 | "User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002;) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", 213 | "Content-Type": "application/x-www-form-urlencoded", 214 | "Authorization": `Bearer ${token}`, 215 | "Cookie": `b2_token=${token};` 216 | }, 217 | body: ``, 218 | } 219 | 220 | if (debug) { 221 | log(`\n【debug】=============== 这是 签到 请求 url ===============`); 222 | log(JSON.stringify(url)); 223 | } 224 | 225 | $.post(url, async (error, response, data) => { 226 | try { 227 | if (debug) { 228 | log(`\n\n【debug】===============这是 签到 返回data==============`); 229 | log(data) 230 | } 231 | 232 | let result = JSON.parse(data); 233 | if (result.code == 1) { 234 | 235 | log(`账号[${name}]签到失败:${result}`) 236 | msg += `账号[${name}]签到失败:${result}` 237 | 238 | } else { 239 | 240 | if(result.credit) { 241 | log(`账号[${name}]签到成功,获得${result.credit}积分,现有积分:${result.mission.my_credit}`) 242 | msg += `\n账号[${name}]签到成功,获得${result.credit}积分,现有积分:${result.mission.my_credit}` 243 | } 244 | 245 | } 246 | 247 | } catch (e) { 248 | log(e) 249 | } finally { 250 | resolve(); 251 | } 252 | }, timeout) 253 | }) 254 | } 255 | 256 | /** 257 | * 关注 258 | */ 259 | function doFollow(timeout = 3 * 1000) { 260 | return new Promise((resolve) => { 261 | let user_id = randomInt(0,1000) 262 | let url = { 263 | url: `https://www.kejiwanjia.com/wp-json/b2/v1/AuthorFollow`, 264 | headers: { 265 | "Host": "www.kejiwanjia.com", 266 | "Connection": "keep-alive", 267 | "Accept": "application/json, text/plain, */*", 268 | "User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002;) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", 269 | "Content-Type": "application/x-www-form-urlencoded", 270 | "Authorization": `Bearer ${token}`, 271 | "Cookie": `b2_token=${token};` 272 | }, 273 | body: `user_id=${user_id}`, 274 | } 275 | 276 | if (debug) { 277 | log(`\n【debug】=============== 这是 关注 请求 url ===============`); 278 | log(JSON.stringify(url)); 279 | } 280 | 281 | $.post(url, async (error, response, data) => { 282 | try { 283 | if (debug) { 284 | log(`\n\n【debug】===============这是 关注 返回data==============`); 285 | log(data) 286 | } 287 | 288 | if (data == "true") { 289 | 290 | log(`账号[${name}]关注id[${user_id}]用户成功`) 291 | msg += `\n账号[${name}]关注id[${user_id}]用户成功` 292 | 293 | } else { 294 | 295 | log(`账号[${name}]关注id[${user_id}]用户失败`) 296 | msg += `\n账号[${name}]关注id[${user_id}]用户失败` 297 | 298 | } 299 | 300 | } catch (e) { 301 | log(e) 302 | } finally { 303 | resolve(); 304 | } 305 | }, timeout) 306 | }) 307 | } 308 | // ============================================变量检查============================================ \\ 309 | async function Envs() { 310 | if (kjwj) { 311 | if (kjwj.indexOf("\n") != -1) { 312 | kjwj.split("\n").forEach((item) => { 313 | kjwjArr.push(item); 314 | }); 315 | } else { 316 | kjwjArr.push(kjwj); 317 | } 318 | } else { 319 | log(`\n 【${$.name}】:未填写变量 kjwj`) 320 | return; 321 | } 322 | 323 | return true; 324 | } 325 | 326 | // ============================================发送消息============================================ \\ 327 | async function SendMsg(message) { 328 | if (!message) 329 | return; 330 | 331 | if (Notify > 0) { 332 | if ($.isNode()) { 333 | var notify = require('./sendNotify'); 334 | await notify.sendNotify($.name, message); 335 | } else { 336 | $.msg(message); 337 | } 338 | } else { 339 | log(message); 340 | } 341 | } 342 | 343 | /** 344 | * 随机数生成 345 | */ 346 | function randomString(e) { 347 | e = e || 32; 348 | var t = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890", 349 | a = t.length, 350 | n = ""; 351 | for (i = 0; i < e; i++) 352 | n += t.charAt(Math.floor(Math.random() * a)); 353 | return n 354 | } 355 | 356 | /** 357 | * 随机整数生成 358 | */ 359 | function randomInt(min, max) { 360 | return Math.round(Math.random() * (max - min) + min) 361 | } 362 | 363 | /** 364 | * 获取毫秒时间戳 365 | */ 366 | function timestampMs(){ 367 | return new Date().getTime(); 368 | } 369 | 370 | /** 371 | * 获取秒时间戳 372 | */ 373 | function timestampS(){ 374 | return Date.parse(new Date())/1000; 375 | } 376 | 377 | /** 378 | * 获取随机诗词 379 | */ 380 | function poem(timeout = 3 * 1000) { 381 | return new Promise((resolve) => { 382 | let url = { 383 | url: `https://v1.jinrishici.com/all.json` 384 | } 385 | $.get(url, async (err, resp, data) => { 386 | try { 387 | data = JSON.parse(data) 388 | log(`${data.content} \n————《${data.origin}》${data.author}`); 389 | } catch (e) { 390 | log(e, resp); 391 | } finally { 392 | resolve() 393 | } 394 | }, timeout) 395 | }) 396 | } 397 | 398 | /** 399 | * 修改配置文件 400 | */ 401 | function modify() { 402 | 403 | fs.readFile('/ql/data/config/config.sh','utf8',function(err,dataStr){ 404 | if(err){ 405 | return log('读取文件失败!'+err) 406 | } 407 | else { 408 | var result = dataStr.replace(/regular/g,string); 409 | fs.writeFile('/ql/data/config/config.sh', result, 'utf8', function (err) { 410 | if (err) {return log(err);} 411 | }); 412 | } 413 | }) 414 | } 415 | 416 | function Env(t, e) { "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0); class s { constructor(t) { this.env = t } send(t, e = "GET") { t = "string" == typeof t ? { url: t } : t; let s = this.get; return "POST" === e && (s = this.post), new Promise((e, i) => { s.call(this, t, (t, s, r) => { t ? i(t) : e(s) }) }) } get(t) { return this.send.call(this.env, t) } post(t) { return this.send.call(this.env, t, "POST") } } return new class { constructor(t, e) { this.name = t, this.http = new s(this), this.data = null, this.dataFile = "box.dat", this.logs = [], this.isMute = !1, this.isNeedRewrite = !1, this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, e), this.log("", `🔔${this.name}, 开始!`) } isNode() { return "undefined" != typeof module && !!module.exports } isQuanX() { return "undefined" != typeof $task } isSurge() { return "undefined" != typeof $httpClient && "undefined" == typeof $loon } isLoon() { return "undefined" != typeof $loon } toObj(t, e = null) { try { return JSON.parse(t) } catch { return e } } toStr(t, e = null) { try { return JSON.stringify(t) } catch { return e } } getjson(t, e) { let s = e; const i = this.getdata(t); if (i) try { s = JSON.parse(this.getdata(t)) } catch { } return s } setjson(t, e) { try { return this.setdata(JSON.stringify(t), e) } catch { return !1 } } getScript(t) { return new Promise(e => { this.get({ url: t }, (t, s, i) => e(i)) }) } runScript(t, e) { return new Promise(s => { let i = this.getdata("@chavy_boxjs_userCfgs.httpapi"); i = i ? i.replace(/\n/g, "").trim() : i; let r = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout"); r = r ? 1 * r : 20, r = e && e.timeout ? e.timeout : r; const [o, h] = i.split("@"), n = { url: `http://${h}/v1/scripting/evaluate`, body: { script_text: t, mock_type: "cron", timeout: r }, headers: { "X-Key": o, Accept: "*/*" } }; this.post(n, (t, e, i) => s(i)) }).catch(t => this.logErr(t)) } loaddata() { if (!this.isNode()) return {}; { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), e = this.path.resolve(process.cwd(), this.dataFile), s = this.fs.existsSync(t), i = !s && this.fs.existsSync(e); if (!s && !i) return {}; { const i = s ? t : e; try { return JSON.parse(this.fs.readFileSync(i)) } catch (t) { return {} } } } } writedata() { if (this.isNode()) { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), e = this.path.resolve(process.cwd(), this.dataFile), s = this.fs.existsSync(t), i = !s && this.fs.existsSync(e), r = JSON.stringify(this.data); s ? this.fs.writeFileSync(t, r) : i ? this.fs.writeFileSync(e, r) : this.fs.writeFileSync(t, r) } } lodash_get(t, e, s) { const i = e.replace(/\[(\d+)\]/g, ".$1").split("."); let r = t; for (const t of i) if (r = Object(r)[t], void 0 === r) return s; return r } lodash_set(t, e, s) { return Object(t) !== t ? t : (Array.isArray(e) || (e = e.toString().match(/[^.[\]]+/g) || []), e.slice(0, -1).reduce((t, s, i) => Object(t[s]) === t[s] ? t[s] : t[s] = Math.abs(e[i + 1]) >> 0 == +e[i + 1] ? [] : {}, t)[e[e.length - 1]] = s, t) } getdata(t) { let e = this.getval(t); if (/^@/.test(t)) { const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), r = s ? this.getval(s) : ""; if (r) try { const t = JSON.parse(r); e = t ? this.lodash_get(t, i, "") : e } catch (t) { e = "" } } return e } setdata(t, e) { let s = !1; if (/^@/.test(e)) { const [, i, r] = /^@(.*?)\.(.*?)$/.exec(e), o = this.getval(i), h = i ? "null" === o ? null : o || "{}" : "{}"; try { const e = JSON.parse(h); this.lodash_set(e, r, t), s = this.setval(JSON.stringify(e), i) } catch (e) { const o = {}; this.lodash_set(o, r, t), s = this.setval(JSON.stringify(o), i) } } else s = this.setval(t, e); return s } getval(t) { return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null } setval(t, e) { return this.isSurge() || this.isLoon() ? $persistentStore.write(t, e) : this.isQuanX() ? $prefs.setValueForKey(t, e) : this.isNode() ? (this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0) : this.data && this.data[e] || null } initGotEnv(t) { this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar)) } get(t, e = (() => { })) { t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? (this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, { "X-Surge-Skip-Scripting": !1 })), $httpClient.get(t, (t, s, i) => { !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i) })) : this.isQuanX() ? (this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, { hints: !1 })), $task.fetch(t).then(t => { const { statusCode: s, statusCode: i, headers: r, body: o } = t; e(null, { status: s, statusCode: i, headers: r, body: o }, o) }, t => e(t))) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, e) => { try { if (t.headers["set-cookie"]) { const s = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString(); s && this.ckjar.setCookieSync(s, null), e.cookieJar = this.ckjar } } catch (t) { this.logErr(t) } }).then(t => { const { statusCode: s, statusCode: i, headers: r, body: o } = t; e(null, { status: s, statusCode: i, headers: r, body: o }, o) }, t => { const { message: s, response: i } = t; e(s, i, i && i.body) })) } post(t, e = (() => { })) { if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), t.headers && delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, { "X-Surge-Skip-Scripting": !1 })), $httpClient.post(t, (t, s, i) => { !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i) }); else if (this.isQuanX()) t.method = "POST", this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, { hints: !1 })), $task.fetch(t).then(t => { const { statusCode: s, statusCode: i, headers: r, body: o } = t; e(null, { status: s, statusCode: i, headers: r, body: o }, o) }, t => e(t)); else if (this.isNode()) { this.initGotEnv(t); const { url: s, ...i } = t; this.got.post(s, i).then(t => { const { statusCode: s, statusCode: i, headers: r, body: o } = t; e(null, { status: s, statusCode: i, headers: r, body: o }, o) }, t => { const { message: s, response: i } = t; e(s, i, i && i.body) }) } } time(t, e = null) { const s = e ? new Date(e) : new Date; let i = { "M+": s.getMonth() + 1, "d+": s.getDate(), "H+": s.getHours(), "m+": s.getMinutes(), "s+": s.getSeconds(), "q+": Math.floor((s.getMonth() + 3) / 3), S: s.getMilliseconds() }; /(y+)/.test(t) && (t = t.replace(RegExp.$1, (s.getFullYear() + "").substr(4 - RegExp.$1.length))); for (let e in i) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : ("00" + i[e]).substr(("" + i[e]).length))); return t } msg(e = t, s = "", i = "", r) { const o = t => { if (!t) return t; if ("string" == typeof t) return this.isLoon() ? t : this.isQuanX() ? { "open-url": t } : this.isSurge() ? { url: t } : void 0; if ("object" == typeof t) { if (this.isLoon()) { let e = t.openUrl || t.url || t["open-url"], s = t.mediaUrl || t["media-url"]; return { openUrl: e, mediaUrl: s } } if (this.isQuanX()) { let e = t["open-url"] || t.url || t.openUrl, s = t["media-url"] || t.mediaUrl; return { "open-url": e, "media-url": s } } if (this.isSurge()) { let e = t.url || t.openUrl || t["open-url"]; return { url: e } } } }; if (this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(e, s, i, o(r)) : this.isQuanX() && $notify(e, s, i, o(r))), !this.isMuteLog) { let t = ["", "==============📣系统通知📣=============="]; t.push(e), s && t.push(s), i && t.push(i), console.log(t.join("\n")), this.logs = this.logs.concat(t) } } log(...t) { t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(t.join(this.logSeparator)) } logErr(t, e) { const s = !this.isSurge() && !this.isQuanX() && !this.isLoon(); s ? this.log("", `❗️${this.name}, 错误!`, t.stack) : this.log("", `❗️${this.name}, 错误!`, t) } wait(t) { return new Promise(e => setTimeout(e, t)) } done(t = {}) { const e = (new Date).getTime(), s = (e - this.startTime) / 1e3; this.log("", `🔔${this.name}, 结束! 🕛 ${s} 秒`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t) } }(t, e) } 417 | -------------------------------------------------------------------------------- /重要日倒计时.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | # 使用方法:第10行填入阳历(公历)生日,30行可以自定义需要的重要日名称和日期(请按照模板中现有的格式填写,多个请用@分隔)。需要阴历(农历)倒计时请看另一个版本。 5 | 6 | import notify 7 | from datetime import datetime 8 | 9 | # 在这里填入你的阳历生日,格式为 "月-日" 10 | solar_birthday_str = "01-01" 11 | 12 | # 获取当前日期(并转换为仅日期格式) 13 | now = datetime.now().date() 14 | 15 | # 获取今年的阳历生日 16 | solar_birthday_this_year = datetime.strptime(f"{now.year}-{solar_birthday_str}", "%Y-%m-%d").date() 17 | 18 | # 如果今年的阳历生日已经过去,那么下一次阳历生日就是明年的生日 19 | if now > solar_birthday_this_year: 20 | next_solar_birthday = datetime.strptime(f"{now.year + 1}-{solar_birthday_str}", "%Y-%m-%d").date() 21 | else: 22 | next_solar_birthday = solar_birthday_this_year 23 | 24 | # 计算距离下一次阳历生日还有多少天 25 | solar_days_left = (next_solar_birthday - now).days 26 | 27 | info = f"距离你下一次的阳历生日还有 {solar_days_left} 天。" 28 | 29 | # 在这里填入你的自定义事件的名称和日期,格式为 "事件名:月-日@事件名:月-日@..." 30 | custom_event_str = "纪念日:01-01@毕业日:01-01" 31 | 32 | # 分割多个自定义事件 33 | custom_events = custom_event_str.split("@") 34 | 35 | for custom_event in custom_events: 36 | # 获取自定义事件的名称和日期 37 | custom_event_name, custom_event_date_str = custom_event.split(":") 38 | 39 | # 获取今年的自定义事件日期 40 | custom_event_date_this_year = datetime.strptime(f"{now.year}-{custom_event_date_str}", "%Y-%m-%d").date() 41 | 42 | # 如果今年的自定义事件日期已经过去,那么下一次自定义事件日期就是明年 43 | if now > custom_event_date_this_year: 44 | next_custom_event_date = datetime.strptime(f"{now.year + 1}-{custom_event_date_str}", "%Y-%m-%d").date() 45 | else: 46 | next_custom_event_date = custom_event_date_this_year 47 | 48 | # 计算距离下一次自定义事件还有多少天 49 | custom_event_days_left = (next_custom_event_date - now).days 50 | 51 | info += f" 距离 {custom_event_name} 还有 {custom_event_days_left} 天。" 52 | 53 | # 发送通知 54 | notify.send("重要日倒计时", info) 55 | -------------------------------------------------------------------------------- /重要日倒计时阴历+阳历版.py: -------------------------------------------------------------------------------- 1 | # @author Sten 2 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 3 | # 觉得不错麻烦点个star谢谢 4 | # 注:需要导入依赖zhdate,pip3 install zhdate或其他方式将依赖添加到青龙环境中。 5 | # 使用方法:第12行填入阳历生日,32行填入阴历生日,50行和74行可以分别自定义重要节日的阳历和阴历的倒计时(请按照模板中现有的格式填写,多个请用@分隔)。 6 | 7 | import notify 8 | from datetime import datetime 9 | from zhdate import ZhDate 10 | 11 | # 在这里填入你的阳历生日,格式为 "月-日" 12 | solar_birthday_str = "01-01" 13 | 14 | # 获取当前日期(并转换为日期格式) 15 | now = datetime.now().date() 16 | 17 | # 获取今年的阳历生日 18 | solar_birthday_this_year = datetime.strptime(f"{now.year}-{solar_birthday_str}", "%Y-%m-%d").date() 19 | 20 | # 如果今年的阳历生日已经过去,那么下一次阳历生日就是明年的生日 21 | if now > solar_birthday_this_year: 22 | next_solar_birthday = datetime.strptime(f"{now.year + 1}-{solar_birthday_str}", "%Y-%m-%d").date() 23 | else: 24 | next_solar_birthday = solar_birthday_this_year 25 | 26 | # 计算距离下一次阳历生日还有多少天 27 | solar_days_left = (next_solar_birthday - now).days 28 | 29 | info = f"距离你下一次的阳历生日还有 {solar_days_left} 天。" 30 | 31 | # 在这里填入你的阴历生日,格式为 "月-日" 32 | lunar_birthday_str = "01-01" 33 | 34 | # 获取今年的阴历生日 35 | lunar_birthday_month, lunar_birthday_day = map(int, lunar_birthday_str.split("-")) 36 | lunar_birthday_this_year = ZhDate(now.year, lunar_birthday_month, lunar_birthday_day).to_datetime().date() 37 | 38 | # 如果今年的阴历生日已经过去,那么下一次阴历生日就是明年的生日 39 | if now > lunar_birthday_this_year: 40 | next_lunar_birthday = ZhDate(now.year + 1, lunar_birthday_month, lunar_birthday_day).to_datetime().date() 41 | else: 42 | next_lunar_birthday = lunar_birthday_this_year 43 | 44 | # 计算距离下一次阴历生日还有多少天 45 | lunar_days_left = (next_lunar_birthday - now).days 46 | 47 | info += f" 阴历生日还有 {lunar_days_left} 天。" 48 | 49 | # 在这里填入你的自定义事件的名称和日期,格式为 "事件名:月-日@事件名:月-日@..." 50 | custom_event_str = "纪念日:01-01@毕业日:01-01" 51 | 52 | # 分割多个自定义事件 53 | custom_events = custom_event_str.split("@") 54 | 55 | for custom_event in custom_events: 56 | # 获取自定义事件的名称和日期 57 | custom_event_name, custom_event_date_str = custom_event.split(":") 58 | 59 | # 获取今年的自定义事件日期 60 | custom_event_date_this_year = datetime.strptime(f"{now.year}-{custom_event_date_str}", "%Y-%m-%d").date() 61 | 62 | # 如果今年的自定义事件日期已经过去,那么下一次自定义事件日期就是明年 63 | if now > custom_event_date_this_year: 64 | next_custom_event_date = datetime.strptime(f"{now.year + 1}-{custom_event_date_str}", "%Y-%m-%d").date() 65 | else: 66 | next_custom_event_date = custom_event_date_this_year 67 | 68 | # 计算距离下一次自定义事件还有多少天 69 | custom_event_days_left = (next_custom_event_date - now).days 70 | 71 | info += f" 距离 {custom_event_name} 还有 {custom_event_days_left} 天。" 72 | 73 | # 在这里填入你的自定义阴历事件的名称和日期,格式为 "事件名:月-日@事件名:月-日@..." 74 | custom_lunar_event_str = "纪念日:01-01@毕业日:01-01" 75 | 76 | # 分割多个自定义阴历事件 77 | custom_lunar_events = custom_lunar_event_str.split("@") 78 | 79 | for custom_lunar_event in custom_lunar_events: 80 | # 获取自定义阴历事件的名称和日期 81 | custom_lunar_event_name, custom_lunar_event_date_str = custom_lunar_event.split(":") 82 | 83 | # 获取今年的自定义阴历事件日期 84 | custom_lunar_event_month, custom_lunar_event_day = map(int, custom_lunar_event_date_str.split("-")) 85 | custom_lunar_event_date_this_year = ZhDate(now.year, custom_lunar_event_month, custom_lunar_event_day).to_datetime().date() 86 | 87 | # 如果今年的自定义阴历事件日期已经过去,那么下一次自定义阴历事件日期就是明年 88 | if now > custom_lunar_event_date_this_year: 89 | next_custom_lunar_event_date = ZhDate(now.year + 1, custom_lunar_event_month, custom_lunar_event_day).to_datetime().date() 90 | else: 91 | next_custom_lunar_event_date = custom_lunar_event_date_this_year 92 | 93 | # 计算距离下一次自定义阴历事件还有多少天 94 | custom_lunar_event_days_left = (next_custom_lunar_event_date - now).days 95 | 96 | info += f" 距离 {custom_lunar_event_name} 还有 {custom_lunar_event_days_left} 天。" 97 | 98 | # 发送通知 99 | notify.send("重要日倒计时", info) 100 | -------------------------------------------------------------------------------- /阿里云盘.py: -------------------------------------------------------------------------------- 1 | # 在原作者的基础上更换成青龙通用的通知接口,其他代码全部照搬的,如有侵权请告知,立即删除。 2 | # @author Sten 3 | # 作者仓库:https://github.com/aefa6/QinglongScript.git 4 | # 觉得不错麻烦点个star谢谢 5 | 6 | #!/usr/bin/python 7 | # coding=utf-8 8 | ''' 9 | File: aliyunpan_sign.py 10 | Author: canhetingsky 11 | Date: 2023/2/19 10:00 12 | cron: 0 30 8 * * * 13 | new Env('阿里云盘4月自动签到'); 14 | ''' 15 | import sys 16 | import notify 17 | import os 18 | import traceback 19 | import requests 20 | from loguru import logger 21 | SIGN_LOG = 'logs/aliyunpan_sign.log' 22 | 23 | logger.remove() 24 | logger.add(sys.stdout, level='INFO') 25 | 26 | work_path = os.path.dirname(os.path.abspath(__file__)) 27 | SIGN_LOG_FILE = os.path.join(work_path, SIGN_LOG) 28 | logger.add(SIGN_LOG_FILE, encoding='utf8') 29 | 30 | # 请在阿里云盘网页端获取:JSON.parse(localStorage.getItem("token")).refresh_token 31 | refresh_token = "" 32 | if refresh_token is None: 33 | logger.error("请先在环境变量里添加阿里云盘的refresh_token") 34 | exit(0) 35 | 36 | def post_msg(url: str, data: dict) -> bool: 37 | response = requests.post(url, data=data) 38 | code = response.status_code 39 | if code == 200: 40 | return True 41 | else: 42 | return False 43 | 44 | def get_access_token(token): 45 | access_token = '' 46 | try: 47 | url = "https://auth.aliyundrive.com/v2/account/token" 48 | 49 | data_dict = { 50 | "refresh_token": token, 51 | "grant_type": "refresh_token" 52 | } 53 | headers = { 54 | "accept": "application/json, text/plain, */*", 55 | "accept-language": "zh-CN,zh;q=0.9", 56 | "cache-control": "no-cache", 57 | "content-type": "application/json;charset=UTF-8", 58 | "origin": "https://www.aliyundrive.com", 59 | "pragma": "no-cache", 60 | "referer": "https://www.aliyundrive.com/", 61 | "sec-fetch-dest": "empty", 62 | "sec-fetch-mode": "cors", 63 | "sec-fetch-site": "same-site", 64 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", 65 | } 66 | 67 | resp = requests.post(url, json=data_dict, headers=headers) 68 | resp_json = resp.json() 69 | logger.debug(f"resp_json={resp_json}") 70 | 71 | token = {} 72 | token['access_token'] = resp_json.get('access_token', "") 73 | token['refresh_token'] = resp_json.get('refresh_token', "") 74 | token['expire_time'] = resp_json.get('expire_time', "") 75 | logger.info( 76 | f"获取得到新的access_token={token['access_token'][:10]}......,新的refresh_token={token['refresh_token']},过期时间={token['expire_time']}") 77 | access_token = token['access_token'] 78 | except: 79 | logger.error(f"获取异常:{traceback.format_exc()}") 80 | 81 | return access_token 82 | 83 | 84 | class ALiYunPan(object): 85 | def __init__(self, access_token): 86 | # 获取JSON.parse(localStorage.getItem("token")).access_token 87 | # 请自行更新填写access_token,有效期7200s 88 | self.access_token = access_token 89 | 90 | def sign_in(self): 91 | sign_in_days_lists = [] 92 | not_sign_in_days_lists = [] 93 | 94 | try: 95 | token = self.access_token 96 | url = 'https://member.aliyundrive.com/v1/activity/sign_in_list' 97 | headers = { 98 | "Content-Type": "application/json", 99 | "Authorization": token, 100 | "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 D/C501C6D2-FAF6-4DA8-B65B-7B8B392901EB" 101 | } 102 | body = {} 103 | 104 | resp = requests.post(url, json=body, headers=headers) 105 | resp_text = resp.text 106 | resp_json = resp.json() 107 | 108 | # 未登录 109 | # {"code":"AccessTokenInvalid","message":"not login","requestId":"0a0080e216757311048316214ed958"} 110 | code = resp_json.get('code', '') 111 | if code == "AccessTokenInvalid": 112 | logger.warning(f"请检查token是否正确") 113 | elif code is None: 114 | # success = resp_json.get('success', '') 115 | # logger.debug(f"success={success}") 116 | 117 | result = resp_json.get('result', {}) 118 | sign_in_logs_list = result.get("signInLogs", []) 119 | sign_in_count = result.get("signInCount", 0) 120 | title = '阿里云盘签到提醒' 121 | msg = '' 122 | 123 | if len(sign_in_logs_list) > 0: 124 | for i, sign_in_logs_dict in enumerate(sign_in_logs_list, 1): 125 | 126 | status = sign_in_logs_dict.get('status', '') 127 | day = sign_in_logs_dict.get('day', '') 128 | isReward = sign_in_logs_dict.get('isReward', 'false') 129 | if status == "": 130 | logger.info( 131 | f"sign_in_logs_dict={sign_in_logs_dict}") 132 | logger.error(f"签到信息获取异常:{resp_text}") 133 | elif status == "miss": 134 | # logger.warning(f"第{day}天未打卡") 135 | not_sign_in_days_lists.append(day) 136 | elif status == "normal": 137 | reward = {} 138 | if not isReward: # 签到但未领取奖励 139 | reward = self.get_reward(day) 140 | else: 141 | reward = sign_in_logs_dict.get('reward', {}) 142 | # 获取签到奖励内容 143 | if reward: 144 | name = reward.get('name', '') 145 | description = reward.get('description', '') 146 | else: 147 | name = '无奖励' 148 | description = '' 149 | today_info = '✅' if day == sign_in_count else '☑' 150 | log_info = f"{today_info}打卡第{day}天,获得奖励:**[{name}->{description}]**" 151 | logger.info(log_info) 152 | msg = log_info + '\n\n' + msg 153 | sign_in_days_lists.append(day) 154 | 155 | log_info = f"🔥打卡进度:{sign_in_count}/{len(sign_in_logs_list)}" 156 | logger.info(log_info) 157 | 158 | msg = log_info + '\n\n' + msg 159 | notify.send(title, msg) 160 | else: 161 | logger.warning(f"resp_json={resp_json}") 162 | else: 163 | logger.warning(f"resp_json={resp_json}") 164 | # logger.debug(f"code={code}") 165 | 166 | except: 167 | logger.error(f"签到异常={traceback.format_exc()}") 168 | 169 | def get_reward(self, day): 170 | try: 171 | token = self.access_token 172 | url = 'https://member.aliyundrive.com/v1/activity/sign_in_reward' 173 | headers = { 174 | "Content-Type": "application/json", 175 | "Authorization": token, 176 | "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 D/C501C6D2-FAF6-4DA8-B65B-7B8B392901EB" 177 | } 178 | body = { 179 | 'signInDay': day 180 | } 181 | 182 | resp = requests.post(url, json=body, headers=headers) 183 | resp_text = resp.text 184 | logger.debug(f"resp_json={resp_text}") 185 | 186 | resp_json = resp.json() 187 | result = resp_json.get('result', {}) 188 | name = result.get('name', '') 189 | description = result.get('description', '') 190 | return {'name': name, 'description': description} 191 | except: 192 | logger.error(f"获取签到奖励异常={traceback.format_exc()}") 193 | 194 | return {'name': 'null', 'description': 'null'} 195 | 196 | 197 | def main(): 198 | if ',' in refresh_token: 199 | tokens = refresh_token.split(',') 200 | elif ',' in refresh_token: 201 | tokens = refresh_token.split(',') 202 | else: 203 | tokens = [refresh_token] 204 | for token in tokens: 205 | access_token = get_access_token(token) 206 | if access_token: 207 | ali = ALiYunPan(access_token) 208 | ali.sign_in() 209 | 210 | 211 | if __name__ == '__main__': 212 | main() 213 | --------------------------------------------------------------------------------