mirror of
https://github.com/whyour/qinglong.git
synced 2025-07-29 07:56:06 +08:00
add ql bot 所需文件
This commit is contained in:
parent
d14ca52666
commit
9910b93eea
56
repo/dockerbot/jbot/__init__.py
Normal file
56
repo/dockerbot/jbot/__init__.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from telethon import TelegramClient
|
||||
import json
|
||||
import os
|
||||
import logging
|
||||
|
||||
_JdDir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
_ConfigDir = _JdDir + '/config'
|
||||
_ScriptsDir = _JdDir + '/scripts'
|
||||
_OwnDir = _JdDir + '/own'
|
||||
_JdbotDir = _JdDir + '/jbot'
|
||||
_DiyScripts = _JdDir + '/diyscripts'
|
||||
_LogDir = _JdDir + '/log'
|
||||
_shortcut = _ConfigDir + '/shortcut.list'
|
||||
_botlog = _LogDir + '/bot/run.log'
|
||||
_botjson = _ConfigDir + '/bot.json'
|
||||
img_file = _ConfigDir + 'qr.jpg'
|
||||
if not os.path.exists(_LogDir + '/bot'):
|
||||
os.mkdir(_LogDir + '/bot')
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s-%(name)s-%(levelname)s=> [%(funcName)s] %(message)s ', level=logging.INFO, filename=_botlog,
|
||||
filemode='w')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
with open(_botjson, 'r', encoding='utf-8') as f:
|
||||
bot = json.load(f)
|
||||
chat_id = int(bot['user_id'])
|
||||
# 机器人 TOKEN
|
||||
TOKEN = bot['bot_token']
|
||||
# HOSTAPI = bot['apihost']
|
||||
# 发消息的TG代理
|
||||
# my.telegram.org申请到的api_id,api_hash
|
||||
api_id = bot['api_id']
|
||||
api_hash = bot['api_hash']
|
||||
proxystart = bot['proxy']
|
||||
StartCMD = bot['StartCMD']
|
||||
if 'proxy_user' in bot.keys() and bot['proxy_user'] != "代理的username,有则填写,无则不用动":
|
||||
proxy = {
|
||||
'proxy_type': bot['proxy_type'],
|
||||
'addr': bot['proxy_add'],
|
||||
'port': bot['proxy_port'],
|
||||
'username': bot['proxy_user'],
|
||||
'password': bot['proxy_password']}
|
||||
else:
|
||||
proxy = (bot['proxy_type'], bot['proxy_add'], bot['proxy_port'])
|
||||
# 开启tg对话
|
||||
if proxystart and 'noretry' in bot.keys() and bot['noretry']:
|
||||
jdbot = TelegramClient('bot', api_id, api_hash,
|
||||
proxy=proxy).start(bot_token=TOKEN)
|
||||
elif proxystart:
|
||||
jdbot = TelegramClient('bot', api_id, api_hash,
|
||||
proxy=proxy, connection_retries=None).start(bot_token=TOKEN)
|
||||
elif 'noretry' in bot.keys() and bot['noretry']:
|
||||
jdbot = TelegramClient('bot', api_id, api_hash).start(bot_token=TOKEN)
|
||||
else:
|
||||
jdbot = TelegramClient('bot', api_id, api_hash,
|
||||
connection_retries=None).start(bot_token=TOKEN)
|
38
repo/dockerbot/jbot/__main__.py
Normal file
38
repo/dockerbot/jbot/__main__.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env python3
|
||||
# _*_ coding:utf-8 _*_
|
||||
# 0.3 版本开始不再区分ql、V3、V4。运行日志:log/bot/run.log
|
||||
# author: https://github.com/SuMaiKaDe
|
||||
|
||||
from . import jdbot, chat_id, logger,_JdbotDir, _LogDir
|
||||
from .utils import load_diy
|
||||
import os
|
||||
from .bot.update import version,botlog
|
||||
_botuplog = _LogDir + '/bot/up.log'
|
||||
botpath = _JdbotDir + "/bot/"
|
||||
diypath = _JdbotDir + "/diy/"
|
||||
logger.info('loading bot module...')
|
||||
load_diy('bot', botpath)
|
||||
logger.info('loading diy module...')
|
||||
load_diy('diy', diypath)
|
||||
|
||||
async def hello():
|
||||
if os.path.exists(_botuplog):
|
||||
isnew = False
|
||||
with open(_botuplog, 'r', encoding='utf-8') as f:
|
||||
logs = f.readlines()
|
||||
for log in logs:
|
||||
if version in log:
|
||||
isnew = True
|
||||
return
|
||||
if not isnew:
|
||||
with open(_botuplog, 'a', encoding='utf-8') as f:
|
||||
f.writelines([version, botlog])
|
||||
await jdbot.send_message(chat_id, '[机器人上新了](https://github.com/SuMaiKaDe/jddockerbot/tree/master)\n'+botlog+'\n运行日志为log/bot/run.log', link_preview=False)
|
||||
else:
|
||||
with open(_botuplog, 'w+', encoding='utf-8') as f:
|
||||
f.writelines([version, botlog])
|
||||
await jdbot.send_message(chat_id, '[机器人上新了](https://github.com/SuMaiKaDe/jddockerbot/tree/master)\n'+botlog+'\n运行日志为log/bot/run.log', link_preview=False)
|
||||
if __name__ == "__main__":
|
||||
with jdbot:
|
||||
jdbot.loop.create_task(hello())
|
||||
jdbot.loop.run_forever()
|
84
repo/dockerbot/jbot/bot/bean.py
Normal file
84
repo/dockerbot/jbot/bot/bean.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
from PIL import Image, ImageFont, ImageDraw
|
||||
from telethon import events
|
||||
from .. import jdbot, chat_id, _LogDir, _JdbotDir,logger
|
||||
from prettytable import PrettyTable
|
||||
import subprocess
|
||||
from .beandata import get_bean_data
|
||||
IN = _LogDir + '/bean_income.csv'
|
||||
OUT = _LogDir + '/bean_outlay.csv'
|
||||
TOTAL = _LogDir + '/bean_total.csv'
|
||||
_botimg = _LogDir + '/bean.jpg'
|
||||
_font = _JdbotDir + '/font/jet.ttf'
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(chats=chat_id, pattern=r'^/bean'))
|
||||
async def mybean(event):
|
||||
try:
|
||||
await jdbot.send_message(chat_id, '正在查询,请稍后')
|
||||
if len(event.raw_text.split(' ')) > 1:
|
||||
text = event.raw_text.replace('/bean ', '')
|
||||
else:
|
||||
text = None
|
||||
if text and text == 'in':
|
||||
subprocess.check_output(
|
||||
'jcsv', shell=True, stderr=subprocess.STDOUT)
|
||||
creat_bean_counts(IN)
|
||||
await jdbot.send_message(chat_id, '您的近日收入情况', file=_botimg)
|
||||
elif text and text == 'out':
|
||||
subprocess.check_output(
|
||||
'jcsv', shell=True, stderr=subprocess.STDOUT)
|
||||
creat_bean_counts(OUT)
|
||||
await jdbot.send_message(chat_id, '您的近日支出情况', file=_botimg)
|
||||
elif text and int(text):
|
||||
beanin, beanout, beanstotal,date = get_bean_data(int(text))
|
||||
if not beanout:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(beanin))
|
||||
else:
|
||||
creat_bean_count(date,beanin, beanout, beanstotal[1:])
|
||||
await jdbot.send_message(chat_id, f'您的账号{text}收支情况', file=_botimg)
|
||||
else:
|
||||
subprocess.check_output(
|
||||
'jcsv', shell=True, stderr=subprocess.STDOUT)
|
||||
creat_bean_counts(TOTAL)
|
||||
await jdbot.send_message(chat_id, '您的总京豆情况', file=_botimg)
|
||||
except Exception as e:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry'+str(e))
|
||||
|
||||
def creat_bean_count(date,beansin,beansout,beanstotal):
|
||||
tb = PrettyTable()
|
||||
tb.add_column('DATE',date)
|
||||
tb.add_column('BEANIN',beansin)
|
||||
tb.add_column('BEANOUT',beansout)
|
||||
tb.add_column('TOTAL',beanstotal)
|
||||
font = ImageFont.truetype(_font, 18)
|
||||
im = Image.new("RGB", (500, 260), (244, 244, 244))
|
||||
dr = ImageDraw.Draw(im)
|
||||
dr.text((10, 5), str(tb), font=font, fill="#000000")
|
||||
im.save(_botimg)
|
||||
|
||||
def creat_bean_counts(csv_file):
|
||||
with open(csv_file, 'r', encoding='utf-8') as f:
|
||||
data = f.readlines()
|
||||
tb = PrettyTable()
|
||||
num = len(data[-1].split(',')) - 1
|
||||
title = ['DATE']
|
||||
for i in range(0, num):
|
||||
title.append('COUNT'+str(i+1))
|
||||
tb.field_names = title
|
||||
data = data[-7:]
|
||||
for line in data:
|
||||
row = line.split(',')
|
||||
if len(row) > len(title):
|
||||
row = row[:len(title)]
|
||||
elif len(row) < len(title):
|
||||
i = len(title) - len(row)
|
||||
for _ in range(0,i):
|
||||
row.append(0)
|
||||
tb.add_row(row)
|
||||
length = 172 + 100 * num
|
||||
im = Image.new("RGB", (length, 400), (244, 244, 244))
|
||||
dr = ImageDraw.Draw(im)
|
||||
font = ImageFont.truetype(_font, 18)
|
||||
dr.text((10, 5), str(tb), font=font, fill="#000000")
|
||||
im.save(_botimg)
|
114
repo/dockerbot/jbot/bot/beandata.py
Normal file
114
repo/dockerbot/jbot/bot/beandata.py
Normal file
|
@ -0,0 +1,114 @@
|
|||
import requests
|
||||
import datetime
|
||||
import time
|
||||
import json
|
||||
from datetime import timedelta
|
||||
from datetime import timezone
|
||||
from .utils import cookies
|
||||
SHA_TZ = timezone(
|
||||
timedelta(hours=8),
|
||||
name='Asia/Shanghai',
|
||||
)
|
||||
|
||||
|
||||
session = requests.session()
|
||||
|
||||
|
||||
url = "https://api.m.jd.com/api"
|
||||
|
||||
|
||||
def getbody(page):
|
||||
body = {
|
||||
"beginDate": datetime.datetime.utcnow().replace(tzinfo=timezone.utc).astimezone(SHA_TZ).strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"endDate": datetime.datetime.utcnow().replace(tzinfo=timezone.utc).astimezone(SHA_TZ).strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"pageNo": page,
|
||||
"pageSize": 20,
|
||||
}
|
||||
return body
|
||||
|
||||
|
||||
def getparms(page):
|
||||
body = getbody(page)
|
||||
parms = {
|
||||
"functionId": "jposTradeQuery",
|
||||
"appid": "swat_miniprogram",
|
||||
"client": "tjj_m",
|
||||
"sdkName": "orderDetail",
|
||||
"sdkVersion": "1.0.0",
|
||||
"clientVersion": "3.1.3",
|
||||
"timestamp": int(round(time.time() * 1000)),
|
||||
"body": json.dumps(body)
|
||||
}
|
||||
return parms
|
||||
|
||||
|
||||
def getbeans(ck):
|
||||
_7day = True
|
||||
page = 0
|
||||
headers = {
|
||||
"Host": "api.m.jd.com",
|
||||
"Connection": "keep-alive",
|
||||
"charset": "utf-8",
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 9 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2797 MMWEBSDK/201201 Mobile Safari/537.36 MMWEBID/7986 MicroMessenger/8.0.1840(0x2800003B) Process/appbrand4 WeChat/arm64 Weixin NetType/4G Language/zh_CN ABI/arm64 MiniProgramEnv/android",
|
||||
"Content-Type": "application/x-www-form-urlencoded;",
|
||||
"Accept-Encoding": "gzip, compress, deflate, br",
|
||||
"Cookie": ck,
|
||||
"Referer": "https://servicewechat.com/wxa5bf5ee667d91626/141/page-frame.html",
|
||||
}
|
||||
_7days = []
|
||||
for i in range(0, 7):
|
||||
_7days.append(
|
||||
(datetime.date.today() - datetime.timedelta(days=i)).strftime("%Y-%m-%d"))
|
||||
beansin = {key: 0 for key in _7days}
|
||||
beansout = {key: 0 for key in _7days}
|
||||
while _7day:
|
||||
page = page + 1
|
||||
resp = session.get(url, params=getparms(page), headers=headers).text
|
||||
res = json.loads(resp)
|
||||
if res['resultCode'] == 0:
|
||||
for i in res['data']['list']:
|
||||
for date in _7days:
|
||||
if str(date) in i['createDate'] and i['amount'] > 0:
|
||||
beansin[str(date)] = beansin[str(date)] + i['amount']
|
||||
break
|
||||
elif str(date) in i['createDate'] and i['amount'] < 0:
|
||||
beansout[str(date)] = beansout[str(date)] + i['amount']
|
||||
break
|
||||
if i['createDate'].split(' ')[0] not in str(_7days):
|
||||
_7day = False
|
||||
else:
|
||||
return 'error' + str(res), None, None
|
||||
return beansin, beansout, _7days
|
||||
|
||||
|
||||
def getTotal(ck):
|
||||
headers = {
|
||||
"Host": "wxapp.m.jd.com",
|
||||
"Connection": "keep-alive",
|
||||
"charset": "utf-8",
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 9 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2797 MMWEBSDK/201201 Mobile Safari/537.36 MMWEBID/7986 MicroMessenger/8.0.1840(0x2800003B) Process/appbrand4 WeChat/arm64 Weixin NetType/4G Language/zh_CN ABI/arm64 MiniProgramEnv/android",
|
||||
"Content-Type": "application/x-www-form-urlencoded;",
|
||||
"Accept-Encoding": "gzip, compress, deflate, br",
|
||||
"Cookie": ck,
|
||||
}
|
||||
jurl = "https://wxapp.m.jd.com/kwxhome/myJd/home.json"
|
||||
resp = session.get(jurl, headers=headers).text
|
||||
res = json.loads(resp)
|
||||
return res['user']['jingBean']
|
||||
|
||||
|
||||
def get_bean_data(i):
|
||||
ck = cookies[i-1]
|
||||
beansin, beansout, _7days = getbeans(ck)
|
||||
beantotal = getTotal(ck)
|
||||
if not beansout:
|
||||
return str(beansin), None, None,None
|
||||
else:
|
||||
beanin, beanout = [], []
|
||||
beanstotal = [int(beantotal), ]
|
||||
for i in beansin:
|
||||
beantotal = int(beantotal) - int(beansin[i]) - int(beansout[i])
|
||||
beanin.append(beansin[i])
|
||||
beanout.append(int(str(beansout[i]).replace('-', '')))
|
||||
beanstotal.append(beantotal)
|
||||
return beanin[::-1], beanout[::-1], beanstotal[::-1], _7days[::-1]
|
134
repo/dockerbot/jbot/bot/chart.py
Normal file
134
repo/dockerbot/jbot/bot/chart.py
Normal file
|
@ -0,0 +1,134 @@
|
|||
from telethon import events
|
||||
from .. import jdbot, chat_id, _LogDir, logger
|
||||
from ..bot.quickchart import QuickChart
|
||||
from .beandata import get_bean_data
|
||||
_botimg = _LogDir + '/bot/bean.jpeg'
|
||||
|
||||
@jdbot.on(events.NewMessage(chats=chat_id, pattern=r'^/chart'))
|
||||
async def mybean(event):
|
||||
try:
|
||||
await jdbot.send_message(chat_id, '正在查询,请稍后')
|
||||
if len(event.raw_text.split(' ')) > 1:
|
||||
text = event.raw_text.replace('/chart ', '')
|
||||
else:
|
||||
text = None
|
||||
if text and int(text):
|
||||
beanin, beanout, beanstotal, date = get_bean_data(int(text))
|
||||
if not beanout:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(beanin))
|
||||
else:
|
||||
creat_chart(date, '账号'+str(text),
|
||||
beanin, beanout, beanstotal[1:])
|
||||
await jdbot.send_message(chat_id, f'您的账号{text}收支情况', file=_botimg)
|
||||
else:
|
||||
await jdbot.send_message(chat_id, '请正确使用命令\n/chart n n为第n个账号')
|
||||
except Exception as e:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry'+str(e))
|
||||
|
||||
|
||||
def creat_chart(xdata, title, bardata, bardata2, linedate):
|
||||
qc = QuickChart()
|
||||
qc.background_color = '#fff'
|
||||
qc.width = "1000"
|
||||
qc.height = "600"
|
||||
qc.config = {
|
||||
"type": "bar",
|
||||
"data": {
|
||||
"labels": xdata,
|
||||
"datasets": [
|
||||
{
|
||||
"label": "IN",
|
||||
"backgroundColor": [
|
||||
"rgb(255, 99, 132)",
|
||||
"rgb(255, 159, 64)",
|
||||
"rgb(255, 205, 86)",
|
||||
"rgb(75, 192, 192)",
|
||||
"rgb(54, 162, 235)",
|
||||
"rgb(153, 102, 255)",
|
||||
"rgb(255, 99, 132)"
|
||||
],
|
||||
"yAxisID": "y1",
|
||||
"data": bardata
|
||||
},
|
||||
{
|
||||
"label": "OUT",
|
||||
"backgroundColor": [
|
||||
"rgb(255, 99, 132)",
|
||||
"rgb(255, 159, 64)",
|
||||
"rgb(255, 205, 86)",
|
||||
"rgb(75, 192, 192)",
|
||||
"rgb(54, 162, 235)",
|
||||
"rgb(153, 102, 255)",
|
||||
"rgb(255, 99, 132)"
|
||||
],
|
||||
"yAxisID": "y1",
|
||||
"data": bardata2
|
||||
},
|
||||
{
|
||||
"label": "TOTAL",
|
||||
"type": "line",
|
||||
"fill": False,
|
||||
"backgroundColor": "rgb(201, 203, 207)",
|
||||
"yAxisID": "y2",
|
||||
"data": linedate
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"plugins": {
|
||||
"datalabels": {
|
||||
"anchor": 'end',
|
||||
"align": -100,
|
||||
"color": '#666',
|
||||
"font": {
|
||||
"size": 20,
|
||||
}
|
||||
},
|
||||
},
|
||||
"legend": {
|
||||
"labels": {
|
||||
"fontSize": 20,
|
||||
"fontStyle": 'bold',
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"display": True,
|
||||
"text": title + " 收支情况",
|
||||
"fontSize": 24,
|
||||
},
|
||||
"scales": {
|
||||
"xAxes": [{
|
||||
"ticks": {
|
||||
"fontSize": 24,
|
||||
}
|
||||
}],
|
||||
"yAxes": [
|
||||
{
|
||||
"id": "y1",
|
||||
"type": "linear",
|
||||
"display": False,
|
||||
"position": "left",
|
||||
"ticks": {
|
||||
"max": int(int(max([max(bardata), max(bardata2)])+100)*2)
|
||||
},
|
||||
"scaleLabel": {
|
||||
"fontSize": 20,
|
||||
"fontStyle": 'bold',
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "y2",
|
||||
"type": "linear",
|
||||
"display": False,
|
||||
"ticks": {
|
||||
"min": int(min(linedate)*2-(max(linedate))-100),
|
||||
"max": int(int(max(linedate)))
|
||||
},
|
||||
"position": "right"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
qc.to_file(_botimg)
|
26
repo/dockerbot/jbot/bot/cmd.py
Normal file
26
repo/dockerbot/jbot/bot/cmd.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from telethon import events
|
||||
import re
|
||||
from .. import jdbot, StartCMD, chat_id, logger
|
||||
from .utils import cmd
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern='/cmd'))
|
||||
async def mycmd(event):
|
||||
'''接收/cmd命令后执行程序'''
|
||||
if StartCMD:
|
||||
cmdreg = re.compile(r'^/cmd [\s\S]+')
|
||||
text = re.findall(cmdreg, event.raw_text)
|
||||
if len(text) == 0:
|
||||
msg = '''请正确使用/cmd命令,如
|
||||
/cmd jlog # 删除旧日志
|
||||
/cmd jup # 更新所有脚本
|
||||
/cmd jcode # 导出所有互助码
|
||||
/cmd jcsv # 记录豆豆变化情况
|
||||
不建议直接使用cmd命令执行脚本,请使用/node或/snode
|
||||
'''
|
||||
await jdbot.send_message(chat_id, msg)
|
||||
else:
|
||||
logger.info(text)
|
||||
await cmd(text[0].replace('/cmd ', ''))
|
||||
else:
|
||||
await jdbot.send_message(chat_id, '未开启CMD命令,如需使用请修改配置文件')
|
137
repo/dockerbot/jbot/bot/editfile.py
Normal file
137
repo/dockerbot/jbot/bot/editfile.py
Normal file
|
@ -0,0 +1,137 @@
|
|||
from telethon import events, Button
|
||||
import os
|
||||
import shutil
|
||||
from asyncio import exceptions
|
||||
from .. import jdbot, chat_id, _JdDir
|
||||
from .utils import split_list, logger,press_event
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern='/edit'))
|
||||
async def myfileup(event):
|
||||
'''定义编辑文件操作'''
|
||||
SENDER = event.sender_id
|
||||
path = _JdDir
|
||||
page = 0
|
||||
if len(event.raw_text.split(' ')) > 1:
|
||||
text = event.raw_text.replace('/edit ','')
|
||||
else:
|
||||
text =None
|
||||
if text and os.path.isfile(text):
|
||||
try:
|
||||
with open(text,'r',encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
filelist = split_list(lines, 15)
|
||||
path = text
|
||||
except Exception as e:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(e))
|
||||
elif text and os.path.isdir(text):
|
||||
path = text
|
||||
filelist = None
|
||||
elif text:
|
||||
await jdbot.send_message(chat_id, 'please marksure it\'s a dir or a file')
|
||||
filelist = None
|
||||
else:
|
||||
filelist = None
|
||||
async with jdbot.conversation(SENDER, timeout=60) as conv:
|
||||
msg = await conv.send_message('正在查询,请稍后')
|
||||
while path:
|
||||
path, msg, page, filelist = await myedit(conv, SENDER, path, msg, page, filelist)
|
||||
|
||||
|
||||
async def myedit(conv, SENDER, path, msg, page, filelist):
|
||||
mybtn = [Button.inline('上一页', data='up'), Button.inline('下一页', data='next'), Button.inline(
|
||||
'上级', data='updir'), Button.inline('取消', data='cancel')]
|
||||
mybtn2 = [[Button.inline('上一页', data='up'), Button.inline(
|
||||
'下一页', data='next'), Button.inline('取消', data='cancel')], [Button.inline('上十页', data='up10'), Button.inline(
|
||||
'下十页', data='next10'), Button.inline('编辑', data='edit')]]
|
||||
try:
|
||||
if filelist and type(filelist[0][0]) == str:
|
||||
markup = filelist
|
||||
newmarkup = markup[page]
|
||||
msg = await jdbot.edit_message(msg, "".join(newmarkup), buttons=mybtn2)
|
||||
else:
|
||||
if filelist:
|
||||
markup = filelist
|
||||
newmarkup = markup[page]
|
||||
if mybtn not in newmarkup:
|
||||
newmarkup.append(mybtn)
|
||||
else:
|
||||
dir = os.listdir(path)
|
||||
dir.sort()
|
||||
markup = [Button.inline(file, data=str(
|
||||
file)) for file in dir]
|
||||
markup = split_list(markup, 3)
|
||||
if len(markup) > 30:
|
||||
markup = split_list(markup, 30)
|
||||
newmarkup = markup[page]
|
||||
newmarkup.append(mybtn)
|
||||
else:
|
||||
newmarkup = markup
|
||||
if path == _JdDir:
|
||||
newmarkup.append([Button.inline('取消', data='cancel')])
|
||||
else:
|
||||
newmarkup.append(
|
||||
[Button.inline('上级', data='updir'), Button.inline('取消', data='cancel')])
|
||||
msg = await jdbot.edit_message(msg, '请做出您的选择:', buttons=newmarkup)
|
||||
convdata = await conv.wait_event(press_event(SENDER))
|
||||
res = bytes.decode(convdata.data)
|
||||
if res == 'cancel':
|
||||
msg = await jdbot.edit_message(msg, '对话已取消')
|
||||
conv.cancel()
|
||||
return None, None, None, None
|
||||
elif res == 'next':
|
||||
page = page + 1
|
||||
if page > len(markup) - 1:
|
||||
page = 0
|
||||
return path, msg, page, markup
|
||||
elif res == 'up':
|
||||
page = page - 1
|
||||
if page < 0:
|
||||
page = len(markup) - 1
|
||||
return path, msg, page, markup
|
||||
elif res == 'next10':
|
||||
page = page + 10
|
||||
if page > len(markup) - 1:
|
||||
page = 0
|
||||
return path, msg, page, markup
|
||||
elif res == 'up10':
|
||||
page = page - 10
|
||||
if page < 0:
|
||||
page = len(markup) - 1
|
||||
return path, msg, page, markup
|
||||
elif res == 'updir':
|
||||
path = '/'.join(path.split('/')[:-1])
|
||||
if path == '':
|
||||
path = _JdDir
|
||||
return path, msg, page, None
|
||||
elif res == 'edit':
|
||||
await jdbot.send_message(chat_id, '请复制并修改以下内容,修改完成后发回机器人,2分钟内有效')
|
||||
await jdbot.delete_messages(chat_id, msg)
|
||||
msg = await conv.send_message("".join(newmarkup))
|
||||
resp = await conv.get_response()
|
||||
markup[page] = resp.raw_text.split('\n')
|
||||
for a in range(len(markup[page])):
|
||||
markup[page][a] = markup[page][a]+'\n'
|
||||
shutil.copy(path, path+'.bak')
|
||||
with open(path, 'w+', encoding='utf-8') as f:
|
||||
markup = ["".join(a) for a in markup]
|
||||
f.writelines(markup)
|
||||
await jdbot.send_message(chat_id, '文件已修改成功,原文件备份为'+path+'.bak')
|
||||
conv.cancel()
|
||||
return None, None, None, None
|
||||
elif os.path.isfile(path+'/'+res):
|
||||
msg = await jdbot.edit_message(msg, '文件读取中...请稍候')
|
||||
with open(path+'/'+res, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
lines = split_list(lines, 15)
|
||||
page = 0
|
||||
return path+'/'+res, msg, page, lines
|
||||
else:
|
||||
return path+'/'+res, msg, page, None
|
||||
except exceptions.TimeoutError:
|
||||
msg = await jdbot.edit_message(msg, '选择已超时,本次对话已停止')
|
||||
return None, None, None, None
|
||||
except Exception as e:
|
||||
msg = await jdbot.edit_message(msg, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry\n'+str(e))
|
||||
return None, None, None, None
|
176
repo/dockerbot/jbot/bot/getcookie.py
Normal file
176
repo/dockerbot/jbot/bot/getcookie.py
Normal file
|
@ -0,0 +1,176 @@
|
|||
from telethon import events, Button
|
||||
import requests
|
||||
import re
|
||||
import time
|
||||
import qrcode
|
||||
from asyncio import exceptions
|
||||
from .. import jdbot, chat_id, img_file
|
||||
from .utils import press_event
|
||||
|
||||
cookiemsg = ''
|
||||
# 扫码获取cookie 直接采用LOF大佬代码
|
||||
# getSToken请求获取,s_token用于发送post请求是的必须参数
|
||||
s_token = ""
|
||||
# getSToken请求获取,guid,lsid,lstoken用于组装cookies
|
||||
guid, lsid, lstoken = "", "", ""
|
||||
# 由上面参数组装生成,getOKLToken函数发送请求需要使用
|
||||
cookies = ""
|
||||
# getOKLToken请求获取,token用户生成二维码使用、okl_token用户检查扫码登录结果使用
|
||||
token, okl_token = "", ""
|
||||
# 最终获取到的可用的cookie
|
||||
jd_cookie = ""
|
||||
|
||||
|
||||
def getSToken():
|
||||
time_stamp = int(time.time() * 1000)
|
||||
get_url = 'https://plogin.m.jd.com/cgi-bin/mm/new_login_entrance?lang=chs&appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=%s&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport' % time_stamp
|
||||
get_header = {
|
||||
'Connection': 'Keep-Alive',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Accept-Language': 'zh-cn',
|
||||
'Referer': 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=%s&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport' % time_stamp,
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36',
|
||||
'Host': 'plogin.m.jd.com'
|
||||
}
|
||||
resp = requests.get(url=get_url, headers=get_header)
|
||||
parseGetRespCookie(resp.headers, resp.json())
|
||||
|
||||
|
||||
def parseGetRespCookie(headers, get_resp):
|
||||
global s_token
|
||||
global cookies
|
||||
s_token = get_resp.get('s_token')
|
||||
set_cookies = headers.get('set-cookie')
|
||||
guid = re.findall(r"guid=(.+?);", set_cookies)[0]
|
||||
lsid = re.findall(r"lsid=(.+?);", set_cookies)[0]
|
||||
lstoken = re.findall(r"lstoken=(.+?);", set_cookies)[0]
|
||||
cookies = f"guid={guid}; lang=chs; lsid={lsid}; lstoken={lstoken}; "
|
||||
|
||||
|
||||
def getOKLToken():
|
||||
post_time_stamp = int(time.time() * 1000)
|
||||
post_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthreflogurl?s_token=%s&v=%s&remember=true' % (
|
||||
s_token, post_time_stamp)
|
||||
post_data = {
|
||||
'lang': 'chs',
|
||||
'appid': 300,
|
||||
'returnurl': 'https://wqlogin2.jd.com/passport/LoginRedirect?state=%s&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action' % post_time_stamp,
|
||||
'source': 'wq_passport'
|
||||
}
|
||||
post_header = {
|
||||
'Connection': 'Keep-Alive',
|
||||
'Content-Type': 'application/x-www-form-urlencoded; Charset=UTF-8',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Cookie': cookies,
|
||||
'Referer': 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=%s&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport' % post_time_stamp,
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36',
|
||||
'Host': 'plogin.m.jd.com',
|
||||
}
|
||||
try:
|
||||
global okl_token
|
||||
resp = requests.post(
|
||||
url=post_url, headers=post_header, data=post_data, timeout=20)
|
||||
parsePostRespCookie(resp.headers, resp.json())
|
||||
except Exception as error:
|
||||
print("Post网络请求错误", error)
|
||||
|
||||
|
||||
def parsePostRespCookie(headers, data):
|
||||
global token
|
||||
global okl_token
|
||||
token = data.get('token')
|
||||
okl_token = re.findall(r"okl_token=(.+?);", headers.get('set-cookie'))[0]
|
||||
|
||||
|
||||
def parseJDCookies(headers):
|
||||
global jd_cookie
|
||||
set_cookie = headers.get('Set-Cookie')
|
||||
pt_key = re.findall(r"pt_key=(.+?);", set_cookie)[0]
|
||||
pt_pin = re.findall(r"pt_pin=(.+?);", set_cookie)[0]
|
||||
jd_cookie = f'pt_key={pt_key};pt_pin={pt_pin};'
|
||||
|
||||
|
||||
def creatqr(text):
|
||||
'''实例化QRCode生成qr对象'''
|
||||
qr = qrcode.QRCode(
|
||||
version=1,
|
||||
error_correction=qrcode.constants.ERROR_CORRECT_H,
|
||||
box_size=10,
|
||||
border=4
|
||||
)
|
||||
qr.clear()
|
||||
# 传入数据
|
||||
qr.add_data(text)
|
||||
qr.make(fit=True)
|
||||
# 生成二维码
|
||||
img = qr.make_image()
|
||||
# 保存二维码
|
||||
img.save(img_file)
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern=r'^/getcookie'))
|
||||
async def mycookie(event):
|
||||
'''接收/getcookie后执行程序'''
|
||||
login = True
|
||||
msg = await jdbot.send_message(chat_id, '正在获取二维码,请稍后')
|
||||
global cookiemsg
|
||||
try:
|
||||
SENDER = event.sender_id
|
||||
async with jdbot.conversation(SENDER, timeout=30) as conv:
|
||||
getSToken()
|
||||
getOKLToken()
|
||||
url = 'https://plogin.m.jd.com/cgi-bin/m/tmauth?appid=300&client_type=m&token='+token
|
||||
creatqr(url)
|
||||
markup = [Button.inline("已扫码", data='confirm'),
|
||||
Button.inline("取消", data='cancel')]
|
||||
await jdbot.delete_messages(chat_id, msg)
|
||||
cookiemsg = await jdbot.send_message(chat_id, '30s内点击取消将取消本次操作\n如不取消,扫码结果将于30s后显示\n扫码后不想等待点击已扫码', file=img_file, buttons=markup)
|
||||
convdata = await conv.wait_event(press_event(SENDER))
|
||||
res = bytes.decode(convdata.data)
|
||||
if res == 'cancel':
|
||||
login = False
|
||||
await jdbot.delete_messages(chat_id, cookiemsg)
|
||||
msg = await conv.send_message('对话已取消')
|
||||
conv.cancel()
|
||||
else:
|
||||
raise exceptions.TimeoutError()
|
||||
except exceptions.TimeoutError:
|
||||
expired_time = time.time() + 60 * 2
|
||||
while login:
|
||||
check_time_stamp = int(time.time() * 1000)
|
||||
check_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=%s&ou_state=0&okl_token=%s' % (
|
||||
token, okl_token)
|
||||
check_data = {
|
||||
'lang': 'chs',
|
||||
'appid': 300,
|
||||
'returnurl': 'https://wqlogin2.jd.com/passport/LoginRedirect?state=%s&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action' % check_time_stamp,
|
||||
'source': 'wq_passport'
|
||||
}
|
||||
check_header = {
|
||||
'Referer': f'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=%s&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport' % check_time_stamp,
|
||||
'Cookie': cookies,
|
||||
'Connection': 'Keep-Alive',
|
||||
'Content-Type': 'application/x-www-form-urlencoded; Charset=UTF-8',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36',
|
||||
}
|
||||
resp = requests.post(
|
||||
url=check_url, headers=check_header, data=check_data, timeout=30)
|
||||
data = resp.json()
|
||||
if data.get("errcode") == 0:
|
||||
parseJDCookies(resp.headers)
|
||||
await jdbot.delete_messages(chat_id, cookiemsg)
|
||||
await jdbot.send_message(chat_id, '以下为获取到的cookie')
|
||||
await jdbot.send_message(chat_id, jd_cookie)
|
||||
return
|
||||
if data.get("errcode") == 21:
|
||||
await jdbot.delete_messages(chat_id, cookiemsg)
|
||||
await jdbot.send_message(chat_id, '发生了某些错误\n'+data.get("errcode"))
|
||||
return
|
||||
if time.time() > expired_time:
|
||||
await jdbot.delete_messages(chat_id, cookiemsg)
|
||||
await jdbot.send_message(chat_id, '超过3分钟未扫码,二维码已过期')
|
||||
return
|
||||
except Exception as e:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(e))
|
62
repo/dockerbot/jbot/bot/getfile.py
Normal file
62
repo/dockerbot/jbot/bot/getfile.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
from telethon import events, Button
|
||||
import subprocess
|
||||
from asyncio import exceptions
|
||||
from .. import jdbot, chat_id, _ScriptsDir, _ConfigDir, logger
|
||||
from .utils import press_event, backfile, _DiyDir, jdcmd, V4
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id))
|
||||
async def myfile(event):
|
||||
'''定义文件操作'''
|
||||
try:
|
||||
v4btn = [[Button.inline('放入config', data=_ConfigDir), Button.inline('放入scripts', data=_ScriptsDir), Button.inline('放入OWN文件夹', data=_DiyDir)], [
|
||||
Button.inline('放入scripts并运行', data='node1'), Button.inline('放入OWN并运行', data='node'), Button.inline('取消', data='cancel')]]
|
||||
btn = [[Button.inline('放入config', data=_ConfigDir), Button.inline('放入scripts', data=_ScriptsDir)], [
|
||||
Button.inline('放入scripts并运行', data='node1'), Button.inline('取消', data='cancel')]]
|
||||
SENDER = event.sender_id
|
||||
if event.message.file:
|
||||
markup = []
|
||||
filename = event.message.file.name
|
||||
async with jdbot.conversation(SENDER, timeout=30) as conv:
|
||||
msg = await conv.send_message('请选择您要放入的文件夹或操作:\n')
|
||||
if V4:
|
||||
markup = v4btn
|
||||
else:
|
||||
markup = btn
|
||||
msg = await jdbot.edit_message(msg, '请选择您要放入的文件夹或操作:', buttons=markup)
|
||||
convdata = await conv.wait_event(press_event(SENDER))
|
||||
res = bytes.decode(convdata.data)
|
||||
if res == 'cancel':
|
||||
msg = await jdbot.edit_message(msg, '对话已取消')
|
||||
conv.cancel()
|
||||
elif res == 'node':
|
||||
await backfile(_DiyDir+'/'+filename)
|
||||
await jdbot.download_media(event.message, _DiyDir)
|
||||
cmdtext = '{} {}/{} now'.format(jdcmd, _DiyDir, filename)
|
||||
subprocess.Popen(
|
||||
cmdtext, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
await jdbot.edit_message(msg, '脚本已保存到DIY文件夹,并成功在后台运行,请稍后自行查看日志')
|
||||
conv.cancel()
|
||||
elif res == 'node1':
|
||||
await backfile(_ScriptsDir+'/'+filename)
|
||||
await jdbot.download_media(event.message, _ScriptsDir)
|
||||
cmdtext = '{} {}/{} now'.format(jdcmd,
|
||||
_ScriptsDir, filename)
|
||||
subprocess.Popen(
|
||||
cmdtext, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
await jdbot.edit_message(msg, '脚本已保存到scripts文件夹,并成功在后台运行,请稍后自行查看日志')
|
||||
conv.cancel()
|
||||
else:
|
||||
await backfile(res+'/'+filename)
|
||||
await jdbot.download_media(event.message, res)
|
||||
await jdbot.edit_message(msg, filename+'已保存到'+res+'文件夹')
|
||||
if filename == 'crontab.list' and V4:
|
||||
cmdtext = 'crontab '+res+'/'+filename
|
||||
subprocess.Popen(
|
||||
cmdtext, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
await jdbot.edit_message(msg, '定时文件已保存,并更新')
|
||||
except exceptions.TimeoutError:
|
||||
msg = await jdbot.send_message(chat_id, '选择已超时,对话已停止')
|
||||
except Exception as e:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry\n'+str(e))
|
35
repo/dockerbot/jbot/bot/help.py
Normal file
35
repo/dockerbot/jbot/bot/help.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
from telethon import events
|
||||
from .. import jdbot, chat_id
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern='^/help'))
|
||||
async def myhelp(event):
|
||||
'''接收/help命令后执行程序'''
|
||||
if len(event.raw_text) > 6:
|
||||
text = event.raw_text.replace('/help ', '')
|
||||
else:
|
||||
text = 'mhelp'
|
||||
mhelp = '''
|
||||
a-我的自定义快捷按钮
|
||||
bean-获取收支
|
||||
edit-编辑文件
|
||||
start-开始使用本程序
|
||||
node-执行js脚本文件,绝对路径。
|
||||
cmd-执行cmd命令
|
||||
snode-选择脚本后台运行
|
||||
log-选择日志
|
||||
getfile-获取jd目录下文件
|
||||
setshort-设置自定义按钮
|
||||
getcookie-扫码获取cookie'''
|
||||
bean = '/bean 加数字,获取该账户近期收支情况\n/bean in\out获取所有账户近期收或支情况\n/bean 获取账户总豆数量'
|
||||
cmd = '/cmd用于执行cmd命令,如果命令持续10分钟仍未结束,将强行终止,以保障机器人响应'
|
||||
edit = '/edit 进入/jd目录选择文件进行编辑,仅限简易编辑\n/edit /jd/config进入config目录选择文件编辑\n/edit /jd/config/config.sh 直接编辑config.sh文件'
|
||||
getcookie = '/getcookie 扫码获取jdcookie'
|
||||
node = '/node 用于执行js脚本 用法:\n/node /jd/own/abc/def.js'
|
||||
getfile = '/getfile 进入/jd目录选择文件进行获取\n/getfile /jd/config进入config目录选择文件获取\n/getfile /jd/config/config.sh 直接获取config.sh文件'
|
||||
setshort = '/setshort 用于设置快捷方式,格式如下:\n更新-->jup\nAAA-->BBB这种格式使用/a选择\n/bean 1\n/edit /jd/config/config.sh\n以“/”开头的为机器人命令快捷,使用/b选择'
|
||||
snode = '/snode 选择脚本并运行'
|
||||
chart = ''
|
||||
helpme = {'bean': bean, 'cmd': cmd, 'edit': edit, 'getcookie': getcookie, 'node': node,
|
||||
'getfile': getfile, 'setshort': setshort, 'snode': snode, 'chart': chart,'mhelp':mhelp}
|
||||
await jdbot.send_message(chat_id, helpme[text])
|
19
repo/dockerbot/jbot/bot/node.py
Normal file
19
repo/dockerbot/jbot/bot/node.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from telethon import events
|
||||
import re
|
||||
from .. import jdbot, chat_id
|
||||
from .utils import cmd, jdcmd
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern='/node'))
|
||||
async def mynode(event):
|
||||
'''接收/node命令后执行程序'''
|
||||
nodereg = re.compile(r'^/node [\S]+')
|
||||
text = re.findall(nodereg, event.raw_text)
|
||||
if len(text) == 0:
|
||||
res = '''请正确使用/node命令,如
|
||||
/node /abc/123.js 运行abc/123.js脚本
|
||||
/node /own/abc.js 运行own/abc.js脚本
|
||||
'''
|
||||
await jdbot.send_message(chat_id, res)
|
||||
else:
|
||||
await cmd('{} {} now'.format(jdcmd, text[0].replace('/node ', '')))
|
110
repo/dockerbot/jbot/bot/quickchart.py
Normal file
110
repo/dockerbot/jbot/bot/quickchart.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
"""A python client for quickchart.io, a web service that generates static
|
||||
charts."""
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import re
|
||||
try:
|
||||
from urllib import urlencode
|
||||
except:
|
||||
# For Python 3
|
||||
from urllib.parse import urlencode
|
||||
|
||||
FUNCTION_DELIMITER_RE = re.compile('\"__BEGINFUNCTION__(.*?)__ENDFUNCTION__\"')
|
||||
|
||||
|
||||
class QuickChartFunction:
|
||||
def __init__(self, script):
|
||||
self.script = script
|
||||
|
||||
def __repr__(self):
|
||||
return self.script
|
||||
|
||||
|
||||
def serialize(obj):
|
||||
if isinstance(obj, QuickChartFunction):
|
||||
return '__BEGINFUNCTION__' + obj.script + '__ENDFUNCTION__'
|
||||
if isinstance(obj, (datetime.date, datetime.datetime)):
|
||||
return obj.isoformat()
|
||||
return obj.__dict__
|
||||
|
||||
|
||||
def dump_json(obj):
|
||||
ret = json.dumps(obj, default=serialize, separators=(',', ':'))
|
||||
ret = FUNCTION_DELIMITER_RE.sub(
|
||||
lambda match: json.loads('"' + match.group(1) + '"'), ret)
|
||||
return ret
|
||||
|
||||
|
||||
class QuickChart:
|
||||
def __init__(self):
|
||||
self.config = None
|
||||
self.width = 500
|
||||
self.height = 300
|
||||
self.background_color = '#ffffff'
|
||||
self.device_pixel_ratio = 1.0
|
||||
self.format = 'png'
|
||||
self.key = None
|
||||
self.scheme = 'https'
|
||||
self.host = 'quickchart.io'
|
||||
|
||||
def is_valid(self):
|
||||
return self.config is not None
|
||||
|
||||
def get_url_base(self):
|
||||
return '%s://%s' % (self.scheme, self.host)
|
||||
|
||||
def get_url(self):
|
||||
if not self.is_valid():
|
||||
raise RuntimeError(
|
||||
'You must set the `config` attribute before generating a url')
|
||||
params = {
|
||||
'c': dump_json(self.config) if type(self.config) == dict else self.config,
|
||||
'w': self.width,
|
||||
'h': self.height,
|
||||
'bkg': self.background_color,
|
||||
'devicePixelRatio': self.device_pixel_ratio,
|
||||
'f': self.format,
|
||||
}
|
||||
if self.key:
|
||||
params['key'] = self.key
|
||||
return '%s/chart?%s' % (self.get_url_base(), urlencode(params))
|
||||
|
||||
def _post(self, url):
|
||||
try:
|
||||
import requests
|
||||
except:
|
||||
raise RuntimeError('Could not find `requests` dependency')
|
||||
|
||||
postdata = {
|
||||
'chart': dump_json(self.config) if type(self.config) == dict else self.config,
|
||||
'width': self.width,
|
||||
'height': self.height,
|
||||
'backgroundColor': self.background_color,
|
||||
'devicePixelRatio': self.device_pixel_ratio,
|
||||
'format': self.format,
|
||||
}
|
||||
if self.key:
|
||||
postdata['key'] = self.key
|
||||
resp = requests.post(url, json=postdata)
|
||||
if resp.status_code != 200:
|
||||
raise RuntimeError(
|
||||
'Invalid response code from chart creation endpoint')
|
||||
return resp
|
||||
|
||||
def get_short_url(self):
|
||||
resp = self._post('%s/chart/create' % self.get_url_base())
|
||||
parsed = json.loads(resp.text)
|
||||
if not parsed['success']:
|
||||
raise RuntimeError(
|
||||
'Failure response status from chart creation endpoint')
|
||||
return parsed['url']
|
||||
|
||||
def get_bytes(self):
|
||||
resp = self._post('%s/chart' % self.get_url_base())
|
||||
return resp.content
|
||||
|
||||
def to_file(self, path):
|
||||
content = self.get_bytes()
|
||||
with open(path, 'wb') as f:
|
||||
f.write(content)
|
43
repo/dockerbot/jbot/bot/sendfile.py
Normal file
43
repo/dockerbot/jbot/bot/sendfile.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
from telethon import events
|
||||
from .. import jdbot, chat_id, _LogDir, _JdDir
|
||||
from .utils import logbtn
|
||||
import os
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern=r'^/log'))
|
||||
async def mylog(event):
|
||||
'''定义日志文件操作'''
|
||||
SENDER = event.sender_id
|
||||
path = _LogDir
|
||||
page = 0
|
||||
filelist = None
|
||||
async with jdbot.conversation(SENDER, timeout=60) as conv:
|
||||
msg = await conv.send_message('正在查询,请稍后')
|
||||
while path:
|
||||
path, msg, page, filelist = await logbtn(conv, SENDER, path, msg, page, filelist)
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern=r'^/getfile'))
|
||||
async def mygetfile(event):
|
||||
'''定义获取文件命令'''
|
||||
SENDER = event.sender_id
|
||||
path = _JdDir
|
||||
page = 0
|
||||
if len(event.raw_text.split(' ')) > 1:
|
||||
text = event.raw_text.replace('/getfile ','')
|
||||
else:
|
||||
text =None
|
||||
if text and os.path.isfile(text):
|
||||
await jdbot.send_message(chat_id, '请查收文件',file=text)
|
||||
return
|
||||
elif text and os.path.isdir(text):
|
||||
path = text
|
||||
filelist = None
|
||||
elif text:
|
||||
await jdbot.send_message(chat_id, 'please marksure it\'s a dir or a file')
|
||||
filelist = None
|
||||
else:
|
||||
filelist = None
|
||||
async with jdbot.conversation(SENDER, timeout=60) as conv:
|
||||
msg = await conv.send_message('正在查询,请稍后')
|
||||
while path:
|
||||
path, msg, page, filelist = await logbtn(conv, SENDER, path, msg, page, filelist)
|
15
repo/dockerbot/jbot/bot/setshort.py
Normal file
15
repo/dockerbot/jbot/bot/setshort.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
from telethon import events
|
||||
from .. import jdbot, chat_id, _shortcut
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern=r'^/setshort$'))
|
||||
async def setshortcut(event):
|
||||
SENDER = event.sender_id
|
||||
async with jdbot.conversation(SENDER, timeout=60) as conv:
|
||||
await conv.send_message(
|
||||
'60s内回复有效\n请按格式输入您的快捷命令。例如:\n京豆通知-->jtask jd_bean_change\n更新脚本-->jup\n获取互助码-->jcode\nnode运行XX脚本-->node /XX/XX.js\nbash运行abc/123.sh脚本-->bash /abc/123.sh\n-->前边为要显示的名字,-->后边为要运行的命令\n 如添加运行脚本立即执行命令记得在后边添加now\n如不等待运行结果请添加nohup,如京豆通知-->nohup jtask jd_bean_change now\n如不添加nohup 会等待程序执行完,期间不能交互\n建议运行时间短命令不添加nohup\n部分功能青龙可能不支持,请自行测试,自行设定 ')
|
||||
shortcut = await conv.get_response()
|
||||
with open(_shortcut, 'w+', encoding='utf-8') as f:
|
||||
f.write(shortcut.raw_text)
|
||||
await conv.send_message('已设置成功可通过"/a"使用')
|
||||
conv.cancel()
|
57
repo/dockerbot/jbot/bot/short.py
Normal file
57
repo/dockerbot/jbot/bot/short.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
from telethon import events, Button
|
||||
from .utils import split_list, press_event, cmd
|
||||
import subprocess
|
||||
from asyncio import exceptions
|
||||
from .. import jdbot, chat_id, _shortcut, logger
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern=r'^/a$'))
|
||||
async def shortcut(event):
|
||||
markup = []
|
||||
SENDER = event.sender_id
|
||||
msg = await jdbot.send_message(chat_id, '正在查询您的常用命令,请稍后')
|
||||
with open(_shortcut, 'r', encoding='utf-8') as f:
|
||||
shortcuts = f.readlines()
|
||||
try:
|
||||
async with jdbot.conversation(SENDER, timeout=60) as conv:
|
||||
markup = [Button.inline(shortcut.split(
|
||||
'-->')[0], data=str(shortcut.split('-->')[-1])) for shortcut in shortcuts if '-->' in shortcut]
|
||||
markup = split_list(markup, 3)
|
||||
markup.append([Button.inline('取消', data='cancel')])
|
||||
msg = await jdbot.edit_message(msg, '请做出您的选择:', buttons=markup)
|
||||
convdata = await conv.wait_event(press_event(SENDER))
|
||||
res = bytes.decode(convdata.data)
|
||||
if res == 'cancel':
|
||||
msg = await jdbot.edit_message(msg, '对话已取消')
|
||||
conv.cancel()
|
||||
elif 'nohup ' in res:
|
||||
msg = await jdbot.edit_message(msg, '即将执行您的操作'+res)
|
||||
cmdtext = res.replace('nohup ', '')
|
||||
subprocess.Popen(
|
||||
cmdtext, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
msg = await jdbot.edit_message(msg, '已在后台执行您的操作'+res.replace('nohup ', ''))
|
||||
conv.cancel()
|
||||
else:
|
||||
await jdbot.delete_messages(chat_id, msg)
|
||||
await cmd(res)
|
||||
conv.cancel()
|
||||
except exceptions.TimeoutError:
|
||||
msg = await jdbot.edit_message(msg, '选择已超时,对话已停止')
|
||||
except Exception as e:
|
||||
await jdbot.edit_message(msg, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry\n'+str(e))
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern=r'^/b$'))
|
||||
async def shortcut(event):
|
||||
markup = []
|
||||
msg = await jdbot.send_message(chat_id, '正在查询您的常用命令,请稍后')
|
||||
with open(_shortcut, 'r', encoding='utf-8') as f:
|
||||
shortcuts = f.readlines()
|
||||
try:
|
||||
await jdbot.delete_messages(chat_id,msg)
|
||||
markup = [Button.text(shortcut,single_use=True) for shortcut in shortcuts if '-->' not in shortcut]
|
||||
markup = split_list(markup, 3)
|
||||
await jdbot.send_message(chat_id, '请做出您的选择:', buttons=markup)
|
||||
except Exception as e:
|
||||
await jdbot.edit_message(msg, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry\n'+str(e))
|
18
repo/dockerbot/jbot/bot/snode.py
Normal file
18
repo/dockerbot/jbot/bot/snode.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
from telethon import events
|
||||
from .. import jdbot, chat_id, _JdDir
|
||||
from .utils import cmd, nodebtn
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern=r'^/snode'))
|
||||
async def mysnode(event):
|
||||
'''定义supernode文件命令'''
|
||||
SENDER = event.sender_id
|
||||
path = _JdDir
|
||||
page = 0
|
||||
filelist = None
|
||||
async with jdbot.conversation(SENDER, timeout=60) as conv:
|
||||
msg = await conv.send_message('正在查询,请稍后')
|
||||
while path:
|
||||
path, msg, page, filelist = await nodebtn(conv, SENDER, path, msg, page, filelist)
|
||||
if filelist and filelist.startswith('CMD-->'):
|
||||
await cmd(filelist.replace('CMD-->', ''))
|
21
repo/dockerbot/jbot/bot/start.py
Normal file
21
repo/dockerbot/jbot/bot/start.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from telethon import events
|
||||
from .. import jdbot, chat_id
|
||||
|
||||
|
||||
@jdbot.on(events.NewMessage(from_users=chat_id, pattern='/start'))
|
||||
async def mystart(event):
|
||||
'''接收/start命令后执行程序'''
|
||||
msg = '''使用方法如下:
|
||||
/help 获取命令,可直接发送至botfather
|
||||
/a 使用你的自定义快捷按钮
|
||||
/start 开始使用本程序
|
||||
/node 执行js脚本文件,直接输入/node jd_bean_change 如执行其他自己js,需输入绝对路径。即可进行执行。该命令会等待脚本执行完,期间不能使用机器人,建议使用snode命令。
|
||||
/cmd 执行cmd命令,例如/cmd python3 /python/bot.py 则将执行python目录下的bot.py 不建议使用机器人使用并发,可能产生不明原因的崩溃
|
||||
/snode 命令可以选择脚本执行,只能选择/scripts 和/own目录下的脚本,选择完后直接后台运行,不影响机器人响应其他命令
|
||||
/log 选择查看执行日志
|
||||
/getfile 获取jd目录下文件
|
||||
/setshort 设置自定义按钮,每次设置会覆盖原设置
|
||||
/getcookie 扫码获取cookie 增加30s内取消按钮,30s后不能进行其他交互直到2分钟或获取到cookie
|
||||
/edit 从jd目录下选择文件编辑,需要将编辑好信息全部发给机器人,机器人会根据你发的信息进行替换。建议用来编辑config或crontab.list 其他文件慎用!!!
|
||||
此外直接发送文件,会让您选择保存到哪个文件夹,如果选择运行,将保存至own目录下,并立即运行脚本,crontab.list文件会自动更新时间'''
|
||||
await jdbot.send_message(chat_id, msg)
|
10
repo/dockerbot/jbot/bot/update.py
Normal file
10
repo/dockerbot/jbot/bot/update.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
version = 'version :0.3.5'
|
||||
botlog = '''
|
||||
**2021年5月18日**
|
||||
本次更新内容如下:
|
||||
- 修改机器人断网重连
|
||||
- 默认断网自动重连
|
||||
- 如修改请在bot.json内添加括号内内容【```"noretry":true```】
|
||||
- 添加上述内容后,机器人断开连接重连5次,5次不能连接成功将自动结束,如需重新启用需通过终端运行```pm2 start jbot```
|
||||
- 修正bean与chart命令 账号不一致问题
|
||||
'''
|
258
repo/dockerbot/jbot/bot/utils.py
Normal file
258
repo/dockerbot/jbot/bot/utils.py
Normal file
|
@ -0,0 +1,258 @@
|
|||
import os
|
||||
from telethon import events, Button
|
||||
import re
|
||||
from .. import jdbot, chat_id, _LogDir, logger, _JdDir, _OwnDir, _ConfigDir
|
||||
import asyncio
|
||||
import datetime
|
||||
|
||||
bean_log = _LogDir + '/jd_bean_change/'
|
||||
_ConfigFile = _ConfigDir+'/config.sh'
|
||||
V4, QL = False, False
|
||||
if 'JD_DIR' in os.environ.keys():
|
||||
V4 = True
|
||||
_ConfigFile = _ConfigDir+'/config.sh'
|
||||
_DiyDir = _OwnDir
|
||||
jdcmd = 'jtask'
|
||||
elif 'QL_DIR' in os.environ.keys():
|
||||
QL = True
|
||||
_ConfigFile = _ConfigDir+'/cookie.sh'
|
||||
_DiyDir = None
|
||||
jdcmd = 'task'
|
||||
dirs = os.listdir(_LogDir)
|
||||
for mydir in dirs:
|
||||
if 'jd_bean_change' in mydir:
|
||||
bean_log = _LogDir + '/' + mydir
|
||||
break
|
||||
else:
|
||||
_DiyDir = None
|
||||
jdcmd = 'node'
|
||||
|
||||
ckreg = re.compile(r'pt_key=\S*;pt_pin=\S*;')
|
||||
with open(_ConfigFile, 'r', encoding='utf-8') as f:
|
||||
lines = f.read()
|
||||
cookies = ckreg.findall(lines)
|
||||
for ck in cookies:
|
||||
if ck == 'pt_key=xxxxxxxxxx;pt_pin=xxxx;':
|
||||
cookies.remove(ck)
|
||||
break
|
||||
|
||||
|
||||
def split_list(datas, n, row: bool = True):
|
||||
"""一维列表转二维列表,根据N不同,生成不同级别的列表"""
|
||||
length = len(datas)
|
||||
size = length / n + 1 if length % n else length/n
|
||||
_datas = []
|
||||
if not row:
|
||||
size, n = n, size
|
||||
for i in range(int(size)):
|
||||
start = int(i * n)
|
||||
end = int((i + 1) * n)
|
||||
_datas.append(datas[start:end])
|
||||
return _datas
|
||||
|
||||
|
||||
async def backfile(file):
|
||||
'''如果文件存在,则备份,并更新'''
|
||||
if os.path.exists(file):
|
||||
try:
|
||||
os.rename(file, file+'.bak')
|
||||
except WindowsError:
|
||||
os.remove(file+'.bak')
|
||||
os.rename(file, file+'.bak')
|
||||
|
||||
|
||||
def press_event(user_id):
|
||||
return events.CallbackQuery(func=lambda e: e.sender_id == user_id)
|
||||
|
||||
|
||||
async def cmd(cmdtext):
|
||||
'''定义执行cmd命令'''
|
||||
try:
|
||||
msg = await jdbot.send_message(chat_id, '开始执行命令')
|
||||
p = await asyncio.create_subprocess_shell(
|
||||
cmdtext, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
||||
res_bytes, res_err = await p.communicate()
|
||||
res = res_bytes.decode('utf-8')
|
||||
if len(res) == 0:
|
||||
await jdbot.edit_message(msg, '已执行,但返回值为空')
|
||||
elif len(res) <= 4000:
|
||||
await jdbot.delete_messages(chat_id, msg)
|
||||
await jdbot.send_message(chat_id, res)
|
||||
elif len(res) > 4000:
|
||||
_log = _LogDir + '/bot/'+cmdtext.split('/')[-1].split(
|
||||
'.js')[0]+datetime.datetime.now().strftime('%H-%M-%S')+'.log'
|
||||
with open(_log, 'w+', encoding='utf-8') as f:
|
||||
f.write(res)
|
||||
await jdbot.delete_messages(chat_id, msg)
|
||||
await jdbot.send_message(chat_id, '执行结果较长,请查看日志', file=_log)
|
||||
os.remove(_log)
|
||||
except Exception as e:
|
||||
await jdbot.send_message(chat_id, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry'+str(e))
|
||||
|
||||
|
||||
async def getname(path, dir):
|
||||
'''获取文件中文名称,如无则返回文件名'''
|
||||
names = []
|
||||
reg = r'new Env\(\'[\S]+?\'\)'
|
||||
cname = False
|
||||
for file in dir:
|
||||
if os.path.isdir(path+'/'+file):
|
||||
names.append(file)
|
||||
elif file.endswith('.js') and file != 'jdCookie.js' and file != 'getJDCookie.js' and file != 'JD_extra_cookie.js' and 'ShareCode' not in file:
|
||||
with open(path+'/'+file, 'r', encoding='utf-8') as f:
|
||||
resdatas = f.readlines()
|
||||
for data in resdatas:
|
||||
if 'new Env' in data:
|
||||
data = data.replace('\"', '\'')
|
||||
res = re.findall(reg, data)
|
||||
if len(res) != 0:
|
||||
res = res[0].split('\'')[-2]
|
||||
names.append(res+'--->'+file)
|
||||
cname = True
|
||||
break
|
||||
if not cname:
|
||||
names.append(file+'--->'+file)
|
||||
cname = False
|
||||
else:
|
||||
continue
|
||||
return names
|
||||
|
||||
|
||||
async def logbtn(conv, SENDER, path, msg, page, filelist):
|
||||
'''定义log日志按钮'''
|
||||
mybtn = [Button.inline('上一页', data='up'), Button.inline(
|
||||
'下一页', data='next'), Button.inline('上级', data='updir'), Button.inline('取消', data='cancel')]
|
||||
try:
|
||||
if filelist:
|
||||
markup = filelist
|
||||
newmarkup = markup[page]
|
||||
if mybtn not in newmarkup:
|
||||
newmarkup.append(mybtn)
|
||||
else:
|
||||
dir = os.listdir(path)
|
||||
dir.sort()
|
||||
markup = [Button.inline(file, data=str(file))
|
||||
for file in dir]
|
||||
markup = split_list(markup, 3)
|
||||
if len(markup) > 30:
|
||||
markup = split_list(markup, 30)
|
||||
newmarkup = markup[page]
|
||||
newmarkup.append(mybtn)
|
||||
else:
|
||||
newmarkup = markup
|
||||
if path == _JdDir:
|
||||
newmarkup.append([Button.inline('取消', data='cancel')])
|
||||
else:
|
||||
newmarkup.append(
|
||||
[Button.inline('上级', data='updir'), Button.inline('取消', data='cancel')])
|
||||
msg = await jdbot.edit_message(msg, '请做出您的选择:', buttons=newmarkup)
|
||||
convdata = await conv.wait_event(press_event(SENDER))
|
||||
res = bytes.decode(convdata.data)
|
||||
if res == 'cancel':
|
||||
msg = await jdbot.edit_message(msg, '对话已取消')
|
||||
conv.cancel()
|
||||
return None, None, None, None
|
||||
elif res == 'next':
|
||||
page = page + 1
|
||||
if page > len(markup) - 1:
|
||||
page = 0
|
||||
return path, msg, page, markup
|
||||
elif res == 'up':
|
||||
page = page - 1
|
||||
if page < 0:
|
||||
page = len(markup) - 1
|
||||
return path, msg, page, markup
|
||||
elif res == 'updir':
|
||||
path = '/'.join(path.split('/')[:-1])
|
||||
logger.info(path)
|
||||
if path == '':
|
||||
path = _JdDir
|
||||
return path, msg, page, None
|
||||
elif os.path.isfile(path+'/'+res):
|
||||
msg = await jdbot.edit_message(msg, '文件发送中,请注意查收')
|
||||
await conv.send_file(path+'/'+res)
|
||||
msg = await jdbot.edit_message(msg, res+'发送成功,请查收')
|
||||
conv.cancel()
|
||||
return None, None, None, None
|
||||
else:
|
||||
return path+'/'+res, msg, page, None
|
||||
except asyncio.exceptions.TimeoutError:
|
||||
msg = await jdbot.edit_message(msg, '选择已超时,本次对话已停止')
|
||||
return None, None, None, None
|
||||
except Exception as e:
|
||||
msg = await jdbot.edit_message(msg, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry\n'+str(e))
|
||||
return None, None, None, None
|
||||
|
||||
|
||||
async def nodebtn(conv, SENDER, path, msg, page, filelist):
|
||||
'''定义scripts脚本按钮'''
|
||||
mybtn = [Button.inline('上一页', data='up'), Button.inline(
|
||||
'下一页', data='next'), Button.inline('上级', data='updir'), Button.inline('取消', data='cancel')]
|
||||
try:
|
||||
if filelist:
|
||||
markup = filelist
|
||||
newmarkup = markup[page]
|
||||
if mybtn not in newmarkup:
|
||||
newmarkup.append(mybtn)
|
||||
else:
|
||||
if path == _JdDir and V4:
|
||||
dir = ['scripts', _OwnDir.split('/')[-1]]
|
||||
elif path == _JdDir and QL:
|
||||
dir = ['scripts']
|
||||
else:
|
||||
dir = os.listdir(path)
|
||||
dir = await getname(path, dir)
|
||||
dir.sort()
|
||||
markup = [Button.inline(file.split('--->')[0], data=str(file.split('--->')[-1]))
|
||||
for file in dir if os.path.isdir(path+'/'+file) or file.endswith('.js')]
|
||||
markup = split_list(markup, 3)
|
||||
if len(markup) > 30:
|
||||
markup = split_list(markup, 30)
|
||||
newmarkup = markup[page]
|
||||
newmarkup.append(mybtn)
|
||||
else:
|
||||
newmarkup = markup
|
||||
if path == _JdDir:
|
||||
newmarkup.append([Button.inline('取消', data='cancel')])
|
||||
else:
|
||||
newmarkup.append(
|
||||
[Button.inline('上级', data='updir'), Button.inline('取消', data='cancel')])
|
||||
msg = await jdbot.edit_message(msg, '请做出您的选择:', buttons=newmarkup)
|
||||
convdata = await conv.wait_event(press_event(SENDER))
|
||||
res = bytes.decode(convdata.data)
|
||||
if res == 'cancel':
|
||||
msg = await jdbot.edit_message(msg, '对话已取消')
|
||||
conv.cancel()
|
||||
return None, None, None, None
|
||||
elif res == 'next':
|
||||
page = page + 1
|
||||
if page > len(markup) - 1:
|
||||
page = 0
|
||||
return path, msg, page, markup
|
||||
elif res == 'up':
|
||||
page = page - 1
|
||||
if page < 0:
|
||||
page = len(markup) - 1
|
||||
return path, msg, page, markup
|
||||
elif res == 'updir':
|
||||
path = '/'.join(path.split('/')[:-1])
|
||||
if path == '':
|
||||
path = _JdDir
|
||||
return path, msg, page, None
|
||||
elif os.path.isfile(path+'/'+res):
|
||||
conv.cancel()
|
||||
logger.info(path+'/'+res+'脚本即将在后台运行')
|
||||
msg = await jdbot.edit_message(msg, res + '在后台运行成功')
|
||||
cmdtext = '{} {}/{} now'.format(jdcmd, path, res)
|
||||
return None, None, None, 'CMD-->'+cmdtext
|
||||
else:
|
||||
return path+'/'+res, msg, page, None
|
||||
except asyncio.exceptions.TimeoutError:
|
||||
msg = await jdbot.edit_message(msg, '选择已超时,对话已停止')
|
||||
return None, None, None, None
|
||||
except Exception as e:
|
||||
msg = await jdbot.edit_message(msg, 'something wrong,I\'m sorry\n'+str(e))
|
||||
logger.error('something wrong,I\'m sorry\n'+str(e))
|
||||
return None, None, None, None
|
10
repo/dockerbot/jbot/diy/example.py
Normal file
10
repo/dockerbot/jbot/diy/example.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
#引入库文件,基于telethon
|
||||
from telethon import events
|
||||
#从上级目录引入 jdbot,chat_id变量
|
||||
from .. import jdbot,chat_id
|
||||
#格式基本固定,本例子表示从chat_id处接收到包含hello消息后,要做的事情
|
||||
@jdbot.on(events.NewMessage(chats=chat_id,pattern=('hello')))
|
||||
#定义自己的函数名称
|
||||
async def hi(event):
|
||||
#do something
|
||||
await jdbot.send_message(chat_id,'hello')
|
22
repo/dockerbot/jbot/ecosystem.config.js
Normal file
22
repo/dockerbot/jbot/ecosystem.config.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
module.exports = {
|
||||
apps: [{
|
||||
name: "jbot",
|
||||
version: "0.3.5",
|
||||
cwd: "..",
|
||||
script: "python",
|
||||
args: "-m jbot",
|
||||
autorestart: true,
|
||||
watch: ["jbot"],
|
||||
ignore_watch: [
|
||||
"jbot/__pycache__/*",
|
||||
"jbot/bot/__pycache__/*",
|
||||
"jbot/diy/__pycache__/*",
|
||||
"jbot/*.log",
|
||||
"jbot/*/*.log",
|
||||
"jbot/requirements.txt",
|
||||
"jbot/ecosystem.config.js"
|
||||
],
|
||||
watch_delay: 15000,
|
||||
interpreter: ""
|
||||
}]
|
||||
}
|
BIN
repo/dockerbot/jbot/font/jet.ttf
Normal file
BIN
repo/dockerbot/jbot/font/jet.ttf
Normal file
Binary file not shown.
7
repo/dockerbot/jbot/requirements.txt
Normal file
7
repo/dockerbot/jbot/requirements.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
qrcode==6.1
|
||||
Telethon==1.21.1
|
||||
requests==2.25.1
|
||||
Pillow==8.1.2
|
||||
python-socks==1.2.4
|
||||
async_timeout==3.0.1
|
||||
prettytable>=2.1.0
|
22
repo/dockerbot/jbot/utils.py
Normal file
22
repo/dockerbot/jbot/utils.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
import sys
|
||||
import importlib
|
||||
import os
|
||||
from . import logger
|
||||
|
||||
|
||||
def load_diy(module, path):
|
||||
files = os.listdir(path)
|
||||
for file in files:
|
||||
try:
|
||||
if file.endswith('.py'):
|
||||
filename = file.replace('.py', '')
|
||||
name = "jbot.{}.{}".format(module, filename)
|
||||
spec = importlib.util.spec_from_file_location(name, path+file)
|
||||
load = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(load)
|
||||
sys.modules[f"jbot.{module}.{filename}"] = load
|
||||
logger.info("JBot加载 " + filename+" 完成")
|
||||
except Exception as e:
|
||||
logger.info("JBot加载失败"+str(e))
|
||||
continue
|
||||
|
Loading…
Reference in New Issue
Block a user