️ sendat: fix incorrect sleep time bug

close #87
This commit is contained in:
一只瓜 2021-02-15 22:12:54 +08:00 committed by GitHub
parent ffe5609957
commit 7d4ee3a8d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,7 +5,7 @@
imported = True imported = True
import os, sys, time, traceback import sys, time, traceback
try: try:
import dateparser import dateparser
@ -15,9 +15,8 @@ except ImportError:
import asyncio import asyncio
from pagermaid import log from pagermaid import log
from pagermaid.listener import listener from pagermaid.listener import listener
from datetime import datetime
from dateutil import parser
DAY_SECS = 24 * 60 * 60
def logsync(message): def logsync(message):
sys.stdout.writelines(f"{message}\n") sys.stdout.writelines(f"{message}\n")
@ -81,9 +80,9 @@ async def sendat(context):
chat = await context.get_chat() chat = await context.get_chat()
args = " ".join(context.parameter).split("|") args = " ".join(context.parameter).split("|")
if not imported: if not imported:
await context.edit("Please install dateparser first: python3 -m pip install dateparser\nAnd restart your pagermaid process") await context.edit("请先安装依赖:`python3 -m pip install dateparser`\n随后,请重启 pagermaid。")
return return
await context.edit(f"tz data: {time.timezone} {time.tzname} {sign}{offset}") await context.edit(f"debug: tz data: {time.timezone} {time.tzname} {sign}{offset}")
if len(args) != 2: if len(args) != 2:
if args[0].find("rm ") == 0: if args[0].find("rm ") == 0:
# clear timer # clear timer
@ -92,7 +91,7 @@ async def sendat(context):
if target_id.isnumeric(): if target_id.isnumeric():
if len(mem) > int(target_id): if len(mem) > int(target_id):
mem[int(target_id)] = "" mem[int(target_id)] = ""
await context.edit(f"id {target_id} removed.") await context.edit(f"id {target_id} successfully removed.")
else: else:
await context.edit("id out of range.") await context.edit("id out of range.")
return return
@ -112,26 +111,35 @@ async def sendat(context):
time_str = args[0][6:] time_str = args[0][6:]
if time_str.find(":") != -1: if time_str.find(":") != -1:
# then it should be absolute time # then it should be absolute time
sleep_times = [abs(dateparser.parse(time_str, settings=settings).timestamp() - time.time()), 24 * 60 * 60] target = dateparser.parse(time_str, settings=settings).timestamp() % DAY_SECS
index = 0 if target >= DAY_SECS - 6:
# 太接近午夜,小概率直接 sleep 过头,特殊处理
target = 0
mem[mem_id] = "|".join(args) mem[mem_id] = "|".join(args)
await sendmsg(context, chat, f"{args[0]} -> {target} sec after 00:00:00 UTC+0")
await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.") await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.")
while True and mem[mem_id] != "": last_sent = 0
last_time = time.time() while mem[mem_id] != "":
while time.time() < last_time + sleep_times[index] and mem[mem_id] != "": if time.time() % DAY_SECS < target:
# 时间没到
await asyncio.sleep(2) await asyncio.sleep(2)
continue
if time.time() % DAY_SECS >= target and time.time() - last_sent < DAY_SECS - 10:
# 时间过了,第二天的没到
await asyncio.sleep(2)
continue
if mem[mem_id] != "": if mem[mem_id] != "":
await sendmsg(context, chat, args[1]) await sendmsg(context, chat, args[1])
index = 1 last_sent = time.time()
mem[mem_id] = "" mem[mem_id] = ""
return return
sleep_time = abs(dateparser.parse(time_str, settings=settings).timestamp() - time.time()) sleep_time = time.time() - dateparser.parse(time_str, settings=settings).timestamp()
if sleep_time < 5: if sleep_time < 5:
await context.edit(f"Sleep time too short. Should be longer than 5 seconds. Got {sleep_time}") await context.edit(f"Sleep time too short. Should be longer than 5 seconds. Got {sleep_time}")
return return
mem[mem_id] = "|".join(args) mem[mem_id] = "|".join(args)
await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.") await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.")
while True and mem[mem_id] != "": while mem[mem_id] != "":
last_time = time.time() last_time = time.time()
while time.time() < last_time + sleep_time and mem[mem_id] != "": while time.time() < last_time + sleep_time and mem[mem_id] != "":
await asyncio.sleep(2) await asyncio.sleep(2)
@ -144,22 +152,32 @@ async def sendat(context):
rest = " ".join(args[0][1:].split(" ")[1:]) rest = " ".join(args[0][1:].split(" ")[1:])
if rest.find(":") != -1: if rest.find(":") != -1:
# then it should be absolute time # then it should be absolute time
sleep_times = [abs(dateparser.parse(rest, settings=settings).timestamp() - time.time()), 24 * 60 * 60] target = dateparser.parse(rest, settings=settings).timestamp() % DAY_SECS
if target >= DAY_SECS - 6:
# 太接近午夜,小概率直接 sleep 过头,特殊处理
target = 0
count = 0 count = 0
mem[mem_id] = "|".join(args) mem[mem_id] = "|".join(args)
await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.") await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.")
last_sent = 0
while count <= times and mem[mem_id] != "": while count <= times and mem[mem_id] != "":
last_time = time.time() if time.time() % DAY_SECS < target:
while time.time() < last_time + sleep_times[0 if count == 0 else 1] and mem[mem_id] != "": # 时间没到
await asyncio.sleep(2) await asyncio.sleep(2)
continue
if time.time() % DAY_SECS >= target and time.time() - last_sent < DAY_SECS - 10:
# 时间过了,第二天的没到
await asyncio.sleep(2)
continue
if mem[mem_id] != "": if mem[mem_id] != "":
await sendmsg(context, chat, args[1]) await sendmsg(context, chat, args[1])
count += 1 count += 1
last_sent = time.time()
mem[mem_id] = "" mem[mem_id] = ""
return return
sleep_time = abs(dateparser.parse(rest, settings=settings).timestamp() - time.time()) sleep_time = time.time() - dateparser.parse(rest, settings=settings).timestamp()
if sleep_time < 5: if sleep_time < 5:
await context.edit("Sleep time too short. Should be longer than 5 seconds.") await context.edit(f"Sleep time too short. Should be longer than 5 seconds. got {sleep_time}")
return return
count = 0 count = 0
mem[mem_id] = "|".join(args) mem[mem_id] = "|".join(args)
@ -191,15 +209,14 @@ async def sendat(context):
return return
# absolute time # absolute time
dt = parser.parse(args[0]) target_time = dateparser.parse(args[0], settings=settings).timestamp()
delta = dt.timestamp() - time.time() if target_time - time.time() < 3:
if delta < 3:
await context.edit("Target time before now.") await context.edit("Target time before now.")
return return
mem[mem_id] = "|".join(args) mem[mem_id] = "|".join(args)
await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.") await context.edit(f"Registered: id {mem_id}. You can use this id to cancel the timer.")
while delta > 0 and mem[mem_id] != "": while target_time - time.time() > 0 and mem[mem_id] != "":
delta = dt.timestamp() - time.time()
await asyncio.sleep(2) await asyncio.sleep(2)
if mem[mem_id] != "": if mem[mem_id] != "":
await sendmsg(context, chat, args[1]) await sendmsg(context, chat, args[1])