Skip to content

Commit

Permalink
Plugins Data (#8)
Browse files Browse the repository at this point in the history
* Add plugin data class
* Refactor codes using plugin data class
* Add status badge
* Add TestBuild in Azure pipelines
* Update readme
  • Loading branch information
he0119 authored Mar 19, 2019
1 parent 723635d commit a0c9ea3
Show file tree
Hide file tree
Showing 22 changed files with 316 additions and 211 deletions.
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
# 聊天机器人
[![Build Status](https://dev.azure.com/he0119/CoolQBot/_apis/build/status/he0119.CoolQBot?branchName=master)](https://dev.azure.com/he0119/CoolQBot/_build/latest?definitionId=5&branchName=master)

该机器人利用了
[酷Q](https://cqp.cc/)
[CoolQ HTTP API 插件](https://github.com/richardchien/coolq-http-api)
以及
[aiocqhttp](https://github.com/richardchien/python-aiocqhttp)
来实现发送消息的功能
[CQHttp Python SDK with Asynchronous I/O](https://github.com/richardchien/python-aiocqhttp)
来实现消息接收和发送的功能

这只是一个随便写写的机器人,主要工作就是按照一定的规则进行复读 ~~(模仿人类)~~,其他功能都是增加可玩性的。

## 运行
1. 新建一个`coolq`文件夹,并在`/coolq/bot/`文件夹下复制并重命名`bot.conf.example``bot.conf`填入对应配置。

2. 提供了`Docker Image`,使用以下命令即可运行。
```shell
sudo docker pull he0119/coolqbot:latest && \
sudo docker run -d --restart always --name cqhttp
-v $(pwd)/coolq:/home/user/coolq \ # 将宿主目录挂载到容器内用于持久化酷 Q 的程序文件
-p 9000:9000 \ # noVNC 端口,用于从浏览器控制酷 Q
-e COOLQ_ACCOUNT=2062765419 \ # 要登录的 QQ 账号,可选但建议填
-e VNC_PASSWD=12345687 \ # noVNC 的密码(官方说不能超过 8 个字符,但实测可以超过)
he0119/coolqbot:latest

# docker run -ti --rm --name cqhttp-test \
# -e COOLQ_URL=http://dlsec.cqp.me/cqp-tuling \ #专业版
```
42 changes: 31 additions & 11 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,37 @@
trigger:
- master

pool:
vmImage: 'Ubuntu-16.04'
jobs:
- job: 'TestBuild'
condition: eq(variables['Build.Reason'], 'PullRequest')
pool:
vmImage: 'Ubuntu-16.04'

variables:
imageName: 'coolqbot'
variables:
imageName: 'coolqbot:test'

steps:
- script: docker build -f Dockerfile -t $(dockerId)/$(imageName) .
displayName: 'docker build'
steps:
- script: docker build -f Dockerfile -t $(dockerId)/$(imageName) .
displayName: 'docker build'

- script: |
docker login -u $(dockerId) -p $(pswd)
docker push $(dockerId)/$(imageName)
displayName: 'docker push'
- script: |
docker login -u $(dockerId) -p $(pswd)
docker push $(dockerId)/$(imageName)
displayName: 'docker push'
- job: 'DeployBuild'
condition: ne(variables['Build.Reason'], 'PullRequest')
pool:
vmImage: 'Ubuntu-16.04'

variables:
imageName: 'coolqbot'

steps:
- script: docker build -f Dockerfile -t $(dockerId)/$(imageName) .
displayName: 'docker build'

- script: |
docker login -u $(dockerId) -p $(pswd)
docker push $(dockerId)/$(imageName)
displayName: 'docker push'
11 changes: 0 additions & 11 deletions run.sh

This file was deleted.

File renamed without changes.
3 changes: 2 additions & 1 deletion src/coolqbot/bot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
'''Bot'''
""" Bot
"""
from aiocqhttp import CQHttp

bot = CQHttp(enable_http_post=False)
23 changes: 12 additions & 11 deletions src/coolqbot/config.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
'''配置文件,不同平台设置不同'''
""" 配置文件,不同平台设置不同
"""
import configparser
import logging
import os
import platform
from pathlib import Path

HOME_DIR_PATH = Path(__file__).parents[1]

if platform.system() == 'Linux':
LOG_FILE_PATH = Path('/home/user/coolq/coolqbot.log')
RECORDER_FILE_PATH = Path('/home/user/coolq/recorder.pkl')
HISTORY_DIR_PATH = Path('/home/user/coolq/history')
CONFIG_PATH = Path('/home/user/coolq/coolq.conf')
CONFIG_PATH = Path('/home/user/coolq/bot/bot.conf')
LOG_FILE_PATH = Path('/home/user/coolq/bot/bot.log')
DATA_DIR_PATH = Path('/home/user/coolq/bot/data')
else:
LOG_FILE_PATH = Path('coolqbot.log')
RECORDER_FILE_PATH = Path('recorder.pkl')
HISTORY_DIR_PATH = Path(__file__).parents[1] / 'history'
CONFIG_PATH = Path('coolq.conf')
CONFIG_PATH = Path('bot.conf')
LOG_FILE_PATH = Path('bot.log')
DATA_DIR_PATH = HOME_DIR_PATH / 'data'

PLUGINS_DIR_PATH = Path(__file__).parents[1] / 'plugins'
PLUGINS_DIR_PATH = HOME_DIR_PATH / 'plugins'

# 读取配置文件
config = configparser.ConfigParser()
Expand All @@ -34,7 +35,7 @@ def init_logger(logger):

# create file handler and set level to debug
fh = logging.FileHandler(LOG_FILE_PATH, encoding='UTF-8')
fh.setLevel(logging.DEBUG)
fh.setLevel(logging.INFO)

# create formatter
formatter = logging.Formatter(
Expand Down
4 changes: 3 additions & 1 deletion src/coolqbot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ def main(debug=False):
init_logger(bot.logger)
if debug:
bot.logger.setLevel(logging.DEBUG)
bot.logger.info('Initializing...')
bot.logger.debug('Initializing...')

plugin_manager.load_plugin()
scheduler.start()

bot.run(host='127.0.0.1', port=8080, loop=asyncio.get_event_loop())


Expand Down
62 changes: 59 additions & 3 deletions src/coolqbot/plugin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
""" 插件相关
"""
import configparser
import os
import pickle

from coolqbot.bot import bot
from coolqbot.config import PLUGINS_DIR_PATH
from coolqbot.config import DATA_DIR_PATH, PLUGINS_DIR_PATH


class PluginManager(object):
class PluginManager:
""" 插件管理器
"""

def __init__(self):
self._plugin_prefix = 'plugins'
Expand All @@ -17,8 +23,58 @@ def load_plugin(self):
for plugin_name in filenames:
try:
__import__(self._get_plugin_name(plugin_name))
bot.logger.info(f'Plugin [{plugin_name}] loaded.')
bot.logger.debug(f'Plugin [{plugin_name}] loaded.')
except ImportError as e:
bot.logger.error(
f'Import error: can not import [{plugin_name}], because {e}'
)


class PluginData:
""" 插件数据管理
将插件数据保存在对应的`data`文件夹下。
提供保存和读取文件/数据的方法。
"""

def __init__(self, name, config=False):
# 插件名,用来确定插件的文件夹位置
self._name = name
self._base_path = DATA_DIR_PATH / f'plugin-{name}'
# 如果文件夹不存在则自动新建
if not DATA_DIR_PATH.exists():
DATA_DIR_PATH.mkdir()
if not self._base_path.exists():
self._base_path.mkdir()
# 如果需要则初始化并加载配置
if config:
self.config = configparser.ConfigParser()
self._load_config()

def save_pkl(self, data, filename):
with self.open(filename, 'wb') as f:
pickle.dump(data, f)

def load_pkl(self, filename):
with self.open(filename, 'rb') as f:
data = pickle.load(f)
return data

def _load_config(self):
path = self._base_path / f'{self._name}.conf'
self.config.read(path)

def _save_config(self):
filename = f'{self._name}.conf'
with self.open(filename, 'w') as configfile:
self.config.write(configfile)

def open(self, filename, open_mode='r'):
path = self._base_path / filename
return open(path, open_mode)

def exists(self, filename):
""" 判断文件是否存在
"""
path = self._base_path / filename
return path.exists()
107 changes: 0 additions & 107 deletions src/coolqbot/recorder.py

This file was deleted.

3 changes: 3 additions & 0 deletions src/coolqbot/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
""" 一些工具
"""
from apscheduler.schedulers.asyncio import AsyncIOScheduler

from coolqbot.plugin import PluginManager

plugin_manager = PluginManager()
scheduler = AsyncIOScheduler()


def get_history_pkl_name(dt):
return dt.strftime('%Y-%m')
3 changes: 2 additions & 1 deletion src/plugins/ban.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" 自主禁言插件 """
""" 自主禁言插件
"""
import re

from coolqbot.bot import bot
Expand Down
Loading

0 comments on commit a0c9ea3

Please sign in to comment.