add ql bot 所需文件

This commit is contained in:
superbei666 2021-06-09 18:47:34 +08:00
parent d14ca52666
commit 9910b93eea
24 changed files with 1474 additions and 0 deletions

View 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)

View 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()

View 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)

View 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]

View 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)

View 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命令如需使用请修改配置文件')

View 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

View 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))

View 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))

View 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])

View 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 ', '')))

View 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)

View 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)

View 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()

View 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))

View 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-->', ''))

View 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)

View 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命令 账号不一致问题
'''

View 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

View 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')

View 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: ""
}]
}

Binary file not shown.

View 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

View 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