nonebot2/commands/zhihu.py
2016-12-30 22:01:50 +08:00

170 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import re
from datetime import date, timedelta
import requests
from command import CommandRegistry
from commands import core
from commands import scheduler
from interactive import *
from little_shit import SkipException, get_source
__registry__ = cr = CommandRegistry()
@cr.register('zhihu_daily', 'zhihu-daily', 'zhihu', '知乎日报')
def zhihu_daily(args_text, ctx_msg):
arg = args_text.strip()
reply = None
try:
if not arg:
sub_url = '/latest'
else:
m = re.match('(\d{4})-(\d{2})-(\d{2})', arg)
if m and ''.join(m.groups()) >= '20130519':
thedate = date(year=int(m.group(1)), month=int(m.group(2)), day=int(m.group(3)))
sub_url = '/before/' + (thedate + timedelta(days=1)).strftime('%Y%m%d')
else:
reply = '命令格式错误,正确的命令格式:\n' \
'/zhihu\n' \
'\n' \
'/zhihu 2016-11-29\n' \
'注意如果指定日期,格式一定要对,且日期需在 2013-05-19 之后(这一天知乎日报诞生)。'
raise SkipException
full_url = 'https://news-at.zhihu.com/api/4/news' + sub_url
resp = requests.get(
full_url,
headers={
'Host': 'news-at.zhihu.com',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36'
' (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36'
}
)
if resp.status_code == 200:
json = resp.json()
if 'stories' not in json:
reply = '获取知乎日报数据失败,知乎返回了一堆迷之数据'
raise SkipException
reply = ('今天' if sub_url == '/latest' else '这天') + '的知乎日报内容如下:'
core.echo(reply, ctx_msg)
step = 6 # Send 8 items per time
items = list(reversed(json.get('stories')))
for start in range(0, len(items), step):
reply = ''
for item in items[start:min(start + step, len(items))]:
reply += item.get('title') + '\n' + \
'https://daily.zhihu.com/story/' + str(item.get('id')) + '\n\n'
reply = reply.rstrip()
core.echo(reply, ctx_msg)
return
else:
reply = '获取知乎日报数据失败,可能知乎服务器又宕机了(('
raise SkipException
except SkipException:
reply = reply if reply else '发生了未知错误……'
core.echo(reply, ctx_msg)
_cmd_subscribe = 'zhihu.subscribe'
_scheduler_job_id = _cmd_subscribe
@cr.register('订阅知乎日报')
@cr.register('subscribe', hidden=True)
@cr.restrict(group_admin_only=True)
def subscribe(args_text, ctx_msg, allow_interactive=True):
arg = args_text.strip()
source = get_source(ctx_msg)
if allow_interactive and (not arg or has_session(source, _cmd_subscribe)):
# Be interactive
return _subscribe_interactively(args_text, ctx_msg, source)
force = False
if arg.startswith('-f '):
force = True
arg = arg.split(' ', 1)[1].strip()
reply = None
try:
m = re.match('([0-1]\d|[2][0-3])(?::|)?([0-5]\d)', arg)
if m:
job = scheduler.get_job(_scheduler_job_id, ctx_msg, internal=True)
if job and not force:
reply = '已经订阅过了哦~\n' \
+ '下次推送时间:\n' \
+ job.next_run_time.strftime('%Y-%m-%d %H:%M') + '\n' \
+ '如果需要更改推送时间,请先取消订阅再重新订阅,' \
+ '或在订阅命令的时间参数前面加 -f 来强制更新推送时间'
raise SkipException
job = scheduler.add_job(
'-M %s -H %s %s zhihu.zhihu-daily' % (m.group(2), m.group(1), _scheduler_job_id),
ctx_msg,
internal=True
)
if job:
# Succeeded to add a job
reply = '订阅成功,我会在每天 %s 推送哦~' % ':'.join((m.group(1), m.group(2)))
else:
reply = '订阅失败,可能后台出了点问题呢~'
else:
reply = '命令格式错误,正确的命令格式:\n' \
'/zhihu.subscribe\n' \
'\n' \
'/zhihu.subscribe [-f] 20:30\n'
except SkipException:
reply = reply if reply else '发生了未知错误……'
core.echo(reply, ctx_msg)
@cr.register('取消订阅知乎日报')
@cr.register('unsubscribe', hidden=True)
@cr.restrict(group_admin_only=True)
def unsubscribe(_, ctx_msg):
if scheduler.remove_job(_scheduler_job_id, ctx_msg, internal=True):
core.echo('取消订阅成功~', ctx_msg)
else:
core.echo('还没有订阅过哦~', ctx_msg)
_state_machines = {}
def _subscribe_interactively(args_text, ctx_msg, source):
def confirm_override(s, a, c):
job = scheduler.get_job(_scheduler_job_id, c, internal=True)
if job:
core.echo('先前已经订阅过了哦~\n'
+ '下次推送时间:\n'
+ job.next_run_time.strftime('%Y-%m-%d %H:%M') + '\n'
+ '要更改推送时间吗?\n'
+ '回复 1 继续,回复 0 放弃', c)
s.data['need_confirm'] = True
else:
s.data['need_confirm'] = False
wait_for_time(s, a, c)
s.state += 1
def wait_for_time(s, a, c):
if s.data['need_confirm']:
if a.strip() != '1':
# Cancel
core.echo('已放弃更改~', c)
return True
core.echo('请发送想要获取推送的时间(格式如 20:05', c)
s.state += 1
def save(s, a, c):
subscribe('-f ' + a, c, allow_interactive=False)
return True
if _cmd_subscribe not in _state_machines:
_state_machines[_cmd_subscribe] = (
confirm_override, # 0
wait_for_time, # 1
save # 2
)
sess = get_session(source, _cmd_subscribe)
if _state_machines[_cmd_subscribe][sess.state](sess, args_text, ctx_msg):
# Done
remove_session(source, _cmd_subscribe)