Skip to content

Commit

Permalink
初步重构完成。
Browse files Browse the repository at this point in the history
  • Loading branch information
sfyc23 committed Jun 13, 2019
1 parent 10c0c4c commit 5819da3
Show file tree
Hide file tree
Showing 17 changed files with 1,046 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.7
FROM python:3.6

COPY . /app
WORKDIR /app
Expand Down
40 changes: 23 additions & 17 deletions _config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,45 @@
# https://ansible-tran.readthedocs.io/en/latest/docs/YAMLSyntax.html
# http://einverne.github.io/post/2015/08/yaml.html

# 定时时间
alarm_timed: '9:30'

# 格言渠道
# 1 : ONE●一个
# 2 : 词霸(每日英语,双语)
# 3 : 土味情话(失效中)
# 4 : 一言
dictum_channel: 4
# 是否开启自动回复
is_auto_relay: True

#图灵机器人(http://www.tuling123.com/)免费用户每天可用 100 条。
#在官网注册并申请 apikey ,userID。
turing_conf:
# 是否开启自动回复,只可选 False && True
is_turing: False
# 是否开启自动回复,只可选 False && True
apiKey: ''
userId: ''

# 指定自动回复的好友名单。
# - '好友1'
# - '好友2'
auto_reply_names:
- '古典'

#------------------------ 定时时间功能--------------------------
alarm_info:
#True 开启定时提醒,False 关闭
is_alarm: True
#定时发送时间
alarm_timed: '9:30'

# 格言渠道(1 : ONE●一个, 2 : 词霸(每日英语,双语) 3 : 土味情话(失效中) 4 : 一言
dictum_channel: 2
girlfriend_infos:
- #女友微信昵称或者备注名,不能输入微信号。
wechat_name: '古典'
#女友所在桂林
#女友所在城市,用于发送天气。(可空)
city_name: '桂林'
# 从那天开始勾搭的(可空)
# 从那天开始勾搭的(可空)(最终效果为:宝贝这是我们在一起的第 111 天)
start_date: '2017-10-10'
# 短句的最后留言(可空)
# 后缀(可空)
sweet_words: '来自最爱你的我。'

#如果你有多个人需要发送,则参照这个样式,复制即可
#如不需要,则删除或注解下面所有的数据
- wechat_name: 'happy'
city_name: '朝阳区'
start_date: '2018-11-11'
sweet_words: '来自你俊美的老公。'
# - wechat_name: 'happy'
# city_name: '朝阳区'
# start_date: '2018-11-11'
# sweet_words: '来自你俊美的老公。'
Empty file added bot/__init__.py
Empty file.
33 changes: 33 additions & 0 deletions bot/qingyunke.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
http://api.qingyunke.com/
青云客智能聊天机器人API
可直接使用
"""
import requests

URL = 'http://api.qingyunke.com/api.php?key=free&appid=0&msg={}'

def get_qingyunke(text):
try:
# print('发出消息:{}'.format(text))
resp = requests.get(URL.format(text))
if resp.status_code == 200:
# print(resp.text)
re_data = resp.json()
if re_data['result'] == 0:
return_text = re_data['content']
return return_text
print('获取数据失败')
return None
except Exception as e:
print(e)
return None
return None


get_auto_reply = get_qingyunke

if __name__ == '__main__':
text = '少年阿宾'
rt = get_qingyunke(text)
print('回复:', rt)
70 changes: 70 additions & 0 deletions bot/tuling123.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'''
图灵机器人自动回复
官网:http://www.tuling123.com/
apiKey,userid 需要去官网申请。
'''

import requests

from main.common import (
get_yaml,
is_json,
)

# 图灵机器人错误码集合
TULING_ERROR_CODE_LIST = [
5000, 6000, 4000, 4001, 4002,
4003, 4005, 4007, 4100, 4200,
4300, 4400, 4500, 4600, 4602,
7002, 8008, 0]
URL = "http://openapi.tuling123.com/openapi/api/v2"


def get_tuling123(text):
"""
获取
:param text:
:return:
"""
info = get_yaml()['turing_conf']
apiKey = info['apiKey']
userId = info['userId']
if not apiKey or not userId: return None
content = {
'perception': {
'inputText': {
'text': text
}
},
'userInfo': {
'apiKey': apiKey,
'userId': userId
}
}
try:
# print('发出消息:{}'.format(text))
resp = requests.post(URL, json=content)
if resp.status_code == 200 and is_json(resp):
# print(resp.text)
re_data = resp.json()
if re_data['intent']['code'] not in TULING_ERROR_CODE_LIST:
return_text = re_data['results'][0]['values']['text']
return return_text
else:
error_text = re_data['results'][0]['values']['text']
print('图灵机器人错误信息:{}'.format(error_text))
print('图灵机器人发送失败')
return None
except Exception as e:
print(e)
return None
return None


get_auto_reply = get_tuling123

if __name__ == '__main__':
text = '雷军 are you ok?'
reply = get_auto_reply(text)
print(reply)
pass
Empty file added main/__init__.py
Empty file.
27 changes: 27 additions & 0 deletions main/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os
import yaml
from simplejson import JSONDecodeError


def get_yaml():
"""
解析 yaml
:return: s 字典
"""
path = os.path.join(os.path.dirname(os.path.dirname(__file__)), '_config.yaml')
with open(path, 'r', encoding='utf-8') as file:
config = yaml.load(file, Loader=yaml.Loader)
return config


def is_json(resp):
"""
判断数据是否能被 Json 化。 True 能,False 否。
:param resp: request.
:return: bool, True 数据可 Json 化;False 不能 JOSN 化。
"""
try:
resp.json()
return True
except JSONDecodeError:
return False
162 changes: 162 additions & 0 deletions main/hongmeng.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
"""
每天定时给多个女友发给微信暖心话
核心代码。
"""
import os
import time
import threading

from apscheduler.schedulers.blocking import BlockingScheduler
import itchat
from itchat.content import TEXT

from main.common import (
get_yaml
)

from main.utils import (
get_bot_info,
get_weather_info,
get_dictum_info,
get_diff_time,
)

reply_name_uuid_list = []
# fire the job again if it was missed within GRACE_PERIOD
GRACE_PERIOD = 15 * 60

def is_online(auto_login=False):
"""
判断是否还在线。
:param auto_login: bool,当为 Ture 则自动重连(默认为 False)。
:return: bool,当返回为 True 时,在线;False 已断开连接。
"""

def _online():
"""
通过获取好友信息,判断用户是否还在线。
:return: bool,当返回为 True 时,在线;False 已断开连接。
"""
try:
if itchat.search_friends():
return True
except IndexError:
return False
return True

if _online(): return True # 如果在线,则直接返回 True
if not auto_login:
print('微信已离线')
return _online() # 仅仅判断是否在线。

for _ in range(2): # 登陆,尝试 2 次。
# 如果需要切换微信,删除 hotReload=True
if os.environ.get('MODE') == 'server':
# 命令行显示登录二维码。
itchat.auto_login(enableCmdQR=2, hotReload=True)
else:
itchat.auto_login(hotReload=True)
if _online():
print('登录成功')
return True

print('登录成功')
return False


@itchat.msg_register([TEXT])
def text_reply(msg):
'''
自动回复内容
:return:
'''
try:
# print(msg)
uuid = msg.fromUserName
if uuid in reply_name_uuid_list:
receive_text = msg.text # 好友发送来的消息
# 通过图灵 api 获取要回复的内容。
reply_text = get_bot_info(receive_text)
time.sleep(1)
if reply_text: # 如内容不为空,回复消息
msg.user.send(reply_text) # 发送回复
print('\n{}发来信息:{}\n回复{}:{}'
.format(msg.user.nickName, receive_text, msg.user.nickName, reply_text))
else:
print('{}发来信息:{}\t自动回复失败'
.format(msg.user.nickName, receive_text))
except Exception as e:
print(str(e))


def init_reply():
"""
初始化自动回复相关数据。
:return:
"""
conf = get_yaml()
for name in conf['auto_reply_names']:
friends = itchat.search_friends(name=name)
if not friends: # 如果用户列表为空,表示用户昵称填写有误。
print('昵称『{}』有误。'.format(name))
break
name_uuid = friends[0].get('UserName') # 取第一个用户的 uuid。
if name_uuid not in reply_name_uuid_list:
reply_name_uuid_list.append(name_uuid)


def init_alarm():
alarm_info = get_yaml().get('alarm_info', None)
if not alarm_info: return
is_alarm = alarm_info.get('is_alarm', False)
if not is_alarm: return
alarm_timed = alarm_info.get('alarm_timed', None)
if not alarm_timed : return
hour, minute = [int(x) for x in alarm_timed.split(':')]

# 定时任务
scheduler = BlockingScheduler()
# 每天9:30左右给女朋友发送每日一句
# scheduler.add_job(get_alarm_msg, 'cron', hour=hour,
# minute=minute, misfire_grace_time=GRACE_PERIOD)
# 每隔 2 分钟发送一条数据用于测试。
scheduler.add_job(get_alarm_msg, 'interval', seconds=120)
print('已开启定时发送提醒功能...')
scheduler.start()

def get_alarm_msg():
conf = get_yaml()
for gf in conf['girlfriend_infos']:
dictum = get_dictum_info()
weather = get_weather_info(gf['city_name'])
diff_time = get_diff_time(gf['start_date'])
sweet_words = gf['sweet_words']
send_msg = '\n'.join(x for x in [dictum, weather, diff_time, sweet_words] if x)
# print(send_msg)
if send_msg and is_online():
authors = itchat.search_friends(nickName=gf['wechat_name'])
if authors:
authors[0].send(send_msg)
print('给『{}』发送的内容是:\n{}\n发送成功...\n'.format(gf['wechat_name'], send_msg))

def run():
if not is_online(auto_login=True):
print('登录失败')
return
conf = get_yaml()
if conf.get('is_auto_relay', False):
def _itchatRun():
itchat.run()
init_reply()
thread = threading.Thread(target=_itchatRun, name='LoopThread')
thread.start()
print('已开启图灵自动回复...')
init_alarm()
thread.join()
else:
init_alarm()


if __name__ == '__main__':
run()
pass
Loading

0 comments on commit 5819da3

Please sign in to comment.