diff --git a/README.md b/README.md index 13eccb0..d352784 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ docker部署 ```shell docker pull xingsu1021/pthelper + +仓库地址: https://hub.docker.com/repository/docker/xingsu1021/pthelper ``` 本地部署需要Python3.9+ diff --git a/apps/common/sites_sign.py b/apps/common/sites_sign.py index 02c6bcc..54c5818 100644 --- a/apps/common/sites_sign.py +++ b/apps/common/sites_sign.py @@ -8,7 +8,7 @@ import simplejson as json import re import time from .utils import getSiteUrl -import ddddocr +#import ddddocr from paddleocr import PaddleOCR from thefuzz import fuzz from thefuzz import process @@ -411,8 +411,11 @@ def hares(site_name, site_name_cn, site_url, site_cookie): #msg = "%s(%s) 签到成功,连续签到%s,今日签到得%s积分" % (site_name,site_name_cn,str(days),str(points)) msg = "%s(%s) %s" % (site_name,site_name_cn, msg_ok) else: - #msg = "%s(%s) 提示:%s" % (site_name,site_name_cn,response_msg['msg']) - msg = "%s(%s) %s%s%s" % (site_name,site_name_cn, msg_err_start, response_msg['msg'], msg_err_end) + if '已经签到' in response_msg['msg']: + msg = "%s(%s) %s " % (site_name,site_name_cn, msg_reok) + else: + #msg = "%s(%s) 提示:%s" % (site_name,site_name_cn,response_msg['msg']) + msg = "%s(%s) %s%s%s" % (site_name,site_name_cn, msg_err_start, response_msg['msg'], msg_err_end) return True, msg except: @@ -1120,7 +1123,13 @@ def opencd(site_name, site_name_cn, site_url, site_cookie): logger.info('--------------%s开始签到----------------' % site_name) - ocr = ddddocr.DdddOcr(show_ad=False,old=True) + ocr = PaddleOCR(use_gpu = False, + show_log=False, + rec_model_dir=os.path.join(settings.BASE_DIR, 'paddleocr', 'captcha_rec_model'), + rec_char_dict_path = os.path.join(settings.BASE_DIR, 'paddleocr', 'captcha_rec_model_dic.txt'), + use_angle_cls=True + ) + try: #验证码签到执行3次验证 for i in range(3): @@ -1147,10 +1156,8 @@ def opencd(site_name, site_name_cn, site_url, site_cookie): with open(image_code_name, "wb") as fp: fp.write(response.content) - with open(image_code_name, 'rb') as f: - image = f.read() - - data_ocr = ocr.classification(image) + data_ocr = ocr.ocr(image_code_name, det=False, rec=True, cls=True)[0][0] + logger.info(data_ocr) #验证码不足6未跳过 @@ -1221,8 +1228,13 @@ def hdsky(site_name, site_name_cn, site_url, site_cookie): logger.info('--------------%s开始签到----------------' % site_name) - ocr = ddddocr.DdddOcr(show_ad=False,old=True) - #ocr = ddddocr.DdddOcr(show_ad=False) + #ocr = ddddocr.DdddOcr(show_ad=False,old=True) + ocr = PaddleOCR(use_gpu = False, + show_log=False, + rec_model_dir=os.path.join(settings.BASE_DIR, 'paddleocr', 'captcha_rec_model'), + rec_char_dict_path = os.path.join(settings.BASE_DIR, 'paddleocr', 'captcha_rec_model_dic.txt'), + use_angle_cls=True + ) try: #验证码签到执行3次验证 for i in range(3): @@ -1244,11 +1256,14 @@ def hdsky(site_name, site_name_cn, site_url, site_cookie): with open(image_code_name, "wb") as fp: fp.write(response.content) - with open(image_code_name, 'rb') as f: - image = f.read() + #with open(image_code_name, 'rb') as f: + #image = f.read() - data_ocr = ocr.classification(image) + #data_ocr = ocr.classification(image) + + data_ocr = ocr.ocr(image_code_name, det=False, rec=True, cls=True)[0][0] logger.info(data_ocr) + #验证码不足6未跳过 if len(data_ocr) < 6 : continue diff --git a/apps/common/utils.py b/apps/common/utils.py index 9e3dc13..dcc3dc7 100644 --- a/apps/common/utils.py +++ b/apps/common/utils.py @@ -26,8 +26,8 @@ from email.header import Header import telegram from urllib import parse from wechatpy.enterprise import WeChatClient -#from PIL import Image -#from io import BytesIO +from PIL import Image, ImageDraw, ImageFont +import re logger = logging.getLogger('django') @@ -619,6 +619,41 @@ def send_iyuu(iyuu_key,send_data = [] ,isTest=False): return True,"发送成功" +def send_enwechat(corp_id = None, agent_id = None, agent_secret = None, user_ids = [], send_data = [] ,isTest=False): + """发送企业微信消息""" + + weclient = EnWechat(corp_id=corp_id, agent_id=agent_id, agent_secret=agent_secret) + + now = datetime.datetime.now() + time = now.strftime("%Y-%m-%d %H:%M:%S") + + if isTest: + #发送测试消息 + text = '
测试 %s
' % time + flag, response = weclient.send_text(user_ids, text) + if flag: + msg = "发送成功" + return True, msg + else: + msg = response["errmsg"] + return False, msg + + else: + #生成图片 + image_file_path = create_image(send_data) + #上传图片 + flag, response = weclient.upload_image(image_file_path) + if flag: + #发送文本卡片 + flag, response = weclient.send_text_card(user_ids, response) + if flag: + return True, "发送成功" + else: + return False, response + else: + return False, response + + def getSiteUrl(url): """ 获取官网url @@ -631,7 +666,7 @@ def getSiteUrl(url): def parseUrl(url): """ 拆解url - #scheme='https', netloc='tr.ikaixin.win:10443', path='/', params='', query='', fragment='' + #scheme='https', netloc='127.0.0.1:8080', path='/', params='', query='', fragment='' """ data = {} u = urlparse(url) @@ -647,24 +682,55 @@ def parseUrl(url): return data -#def deal_img(img_name): - #'''图片进行预处理,并返回bytes类型数据''' - #img = Image.open(img_name) - #buf = BytesIO() - ## 将图片转化为灰度图像 - #image = img.convert('L') - ## 设置默认的阈值(可以根据阈值得到更加清晰的验证码图) - #threshold = 128 - #table = [] - #for i in range(256): - #if i < threshold: - #table.append(0) - #else: - #table.append(1) - ## 图片的像素点什么的 - #image = image.point(table,'1') - #image.save(buf,'png') - #return buf.getvalue() +def create_image(msg_content = []): + """ + 图片生成 + msg 生成图片的文字 + """ + + #f = open("e:/test/test.txt","r",encoding='utf-8').readlines() + + if sys.platform == "win32": + # 设置字体及字号,加载宋体,否则中文乱码 + font = ImageFont.truetype("simsun.ttc", 20, encoding="unic") + else: + #linux加载目录下字体 + font = ImageFont.truetype(os.path.join(settings.BASE_DIR, "fonts", "simsun.ttc"), 20, encoding="unic") + + #图片宽度 + image_width = 500 + #图片高度,可以通过font.getbbox(line)[3]获取字体高度 21 + image_high = len(msg_content) * 25 + + # 设置画布大小及背景色(白色) + image = Image.new('RGB', (image_width, image_high), (255,255,255)) + + draw = ImageDraw.Draw(image) + + x = 10 + y = 5 + + for line in msg_content: + #print(line) + if '成功' in line: + fill='green' + else: + fill='red' + #替换掉<>间的内容 + line = re.sub(re.compile('<.*?>') , '', line) + #通过x,y坐标循环写入 + draw.text((x, y), line, font=font, fill=fill) + #print (font.getbbox(line)) + #获取行的字体高度 + y += font.getbbox(line)[3] + + del draw + + image_file_name = os.path.join(settings.TMP_LOG_DIR, "msg.png") + image.save(image_file_name,"PNG") # 保存图片 + + return image_file_name + def cookie_parse(cookie_str): cookie_dict = {} @@ -709,13 +775,15 @@ class EnWechat: def send_text(self, user_ids = [], msg = None): """发送文本消息 + 返回 + {'errcode': 0, 'errmsg': 'ok', 'msgid': 'fcLc6UhB2absSaoEDgOVFJc7rUS6HAUpkVR6y2ltzLhzzjUH_WfDNW5dVl7nScRT2AG7lQ475r8M9qyISlX9BQ'} """ - return True, self.client.message.send_text(self.agent_id, user_ids, msg) - #try: - - #return True, self.client.message.send_text(self.agent_id, user_ids, msg) - #except Exception as e: - #return False, str(e) + r = self.client.message.send_text(self.agent_id, user_ids, msg) + if r['errcode'] == 0: + return True, r['msgid'] + else: + return True, r['errmsg'] + def send_markdown(self, user_ids = [], msg = None): """发送markdown消息 @@ -725,4 +793,69 @@ class EnWechat: #try: #return True, self.client.message.send_markdown(self.agent_id, user_ids, msg) #except Exception as e: - #return False, str(e) \ No newline at end of file + #return False, str(e) + + def send_image(self, user_ids = [], media_id = None): + """发送图片消息 + """ + + return True, self.client.message.send_image(self.agent_id, user_ids, media_id) + + def send_text_card(self, user_ids = [], url = None): + """发送文本卡片消息 + url为上传微信的素材地址 + """ + now = datetime.datetime.now() + time = now.strftime("%Y-%m-%d %H:%M:%S") + description = '
' + time + '
' + title = '签到通知' + + return True, self.client.message.send_text_card(self.agent_id, user_ids, title, description, url) + + def upload_image(self, image_file_path = None): + """ + 上传图片素材(永久,url限制微信使用) + image_file_path 要上传的本地图片路径 + + 返回 url地址 + {'errcode': 0, 'errmsg': 'ok', 'url': 'https://wework.qpic.cn/wwpic/592170_HhXMIUytR62CdSy_1662426978/0'} + """ + + with open(image_file_path, 'rb') as f: + image = f.read() + #上传图片 + reponse = self.client.media.upload_img(image) + + if reponse['errcode'] == 0: + url = reponse['url'] + + return True, url + else: + msg = reponse['errmsg'] + + return False, msg + + def upload(self, media_type = "image", media_file = None): + """ + 上传临时素材(保留3天) + media_type 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) + media_file – 要上传的文件,一个 File-object + + 返回 media_id + {"errcode": 0, "errmsg": "ok", "type": "image", "media_id": "3Y7qMZUYZvhZG13oNoKMKMWaxtNupLKIR4lgUsDc0abqicTjGnuE9APt-NiivZ3tg", "created_at": "1662427932"} + """ + + with open(media_file, 'rb') as f: + file_content = f.read() + + #上传 + reponse = self.client.media.upload(media_type, file_content) + + if reponse['errcode'] == 0: + media_id = reponse['media_id'] + + return True, media_id + else: + msg = reponse['errmsg'] + + return False, msg \ No newline at end of file diff --git a/apps/cron/crontabs.py b/apps/cron/crontabs.py index d72ea0d..23151d1 100644 --- a/apps/cron/crontabs.py +++ b/apps/cron/crontabs.py @@ -7,7 +7,7 @@ import os import logging from bs4 import BeautifulSoup -from common.utils import send_email,send_telegram,send_iyuu, EnWechat +from common.utils import send_email,send_telegram,send_iyuu, send_enwechat from common.sites_sign import signIngress from sites.models import SiteConfig, SiteInfo from .models import Job, Log @@ -328,9 +328,13 @@ def send_msg(crontab_id = None, send_data = []): enwechat_ormdata = NotifyConfig.objects.get(name='enwechat') receiver_users = [x for x in enwechat_ormdata.receive_user.split(',')] - weclient = EnWechat(corp_id=enwechat_ormdata.enwechat_corp_id, agent_id=enwechat_ormdata.enwechat_agent_id, agent_secret=enwechat_ormdata.enwechat_agent_secret) + flag, msg = send_enwechat(corp_id=enwechat_ormdata.enwechat_corp_id, + agent_id=enwechat_ormdata.enwechat_agent_id, + agent_secret=enwechat_ormdata.enwechat_agent_secret, + user_ids = receiver_users, + send_data = send_data + ) - flag,msg = weclient.send_text(receiver_users,"\r\n".join(send_data).replace('','').replace('','')) logger.info("-------------enwechat-------------------") logger.info(msg) diff --git a/apps/notify/templates/notify/enwechat.html b/apps/notify/templates/notify/enwechat.html index fc0c230..8a14b3b 100644 --- a/apps/notify/templates/notify/enwechat.html +++ b/apps/notify/templates/notify/enwechat.html @@ -47,7 +47,7 @@
diff --git a/apps/notify/views_request.py b/apps/notify/views_request.py index cf67166..639a79a 100644 --- a/apps/notify/views_request.py +++ b/apps/notify/views_request.py @@ -10,7 +10,7 @@ from urllib import parse import simplejson as json import telegram import sys -from common.utils import send_email, EnWechat +from common.utils import send_email, send_enwechat #直接使用检查是否管理员 #from django.contrib.auth.decorators import user_passes_test @@ -26,7 +26,7 @@ def iyuutest(request): if _id == '': - response_data={"code":0,"msg":"请先配置IYUU令牌"} + response_data={"code":0,"msg":"请先配置IYUU令牌或刷新页面"} else: @@ -67,7 +67,7 @@ def telegramtest(request): if _id == '': - response_data={"code":0,"msg":"请先配置Telegram"} + response_data={"code":0,"msg":"请先配置Telegram或刷新页面"} else: @@ -110,7 +110,7 @@ def emailtest(request): if _id == '': - response_data={"code":0,"msg":"请先配置邮箱"} + response_data={"code":0,"msg":"请先配置邮箱或刷新页面"} else: @@ -150,7 +150,7 @@ def enwechattest(request): if _id == '': - response_data={"code":0,"msg":"请先配置企业微信"} + response_data={"code":0,"msg":"请先配置企业微信或刷新页面"} else: @@ -164,17 +164,9 @@ def enwechattest(request): for i in receive_user.split(","): receiver_users.append(i) - now = datetime.datetime.now() - time = now.strftime("%Y-%m-%d %H:%M:%S") - try: - weclient = EnWechat(corp_id=enwechat_corp_id, agent_id=enwechat_agent_id, agent_secret=enwechat_agent_secret) - - sendata="""%s [测试]""" % time - - flag,response = weclient.send_markdown(receiver_users,sendata) + flag,response = send_enwechat(corp_id=enwechat_corp_id, agent_id=enwechat_agent_id, agent_secret=enwechat_agent_secret,user_ids=receiver_users, isTest=True) - #response_msg = json.loads(response) response_data={"code":1,"msg":response} except Exception as e: response_data={"code":0,"msg":str(e) } diff --git a/fonts/simsun.ttc b/fonts/simsun.ttc new file mode 100644 index 0000000..e360db7 Binary files /dev/null and b/fonts/simsun.ttc differ diff --git a/paddleocr/captcha_rec_model/inference.pdiparams b/paddleocr/captcha_rec_model/inference.pdiparams new file mode 100644 index 0000000..53bf535 Binary files /dev/null and b/paddleocr/captcha_rec_model/inference.pdiparams differ diff --git a/paddleocr/captcha_rec_model/inference.pdiparams.info b/paddleocr/captcha_rec_model/inference.pdiparams.info new file mode 100644 index 0000000..6900c1b Binary files /dev/null and b/paddleocr/captcha_rec_model/inference.pdiparams.info differ diff --git a/paddleocr/captcha_rec_model/inference.pdmodel b/paddleocr/captcha_rec_model/inference.pdmodel new file mode 100644 index 0000000..9dadd74 Binary files /dev/null and b/paddleocr/captcha_rec_model/inference.pdmodel differ diff --git a/paddleocr/captcha_rec_model_dic.txt b/paddleocr/captcha_rec_model_dic.txt new file mode 100644 index 0000000..b1bda2c --- /dev/null +++ b/paddleocr/captcha_rec_model_dic.txt @@ -0,0 +1,62 @@ +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z \ No newline at end of file diff --git a/pthelper/settings.py b/pthelper/settings.py index db59a57..c382b13 100644 --- a/pthelper/settings.py +++ b/pthelper/settings.py @@ -177,7 +177,7 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' #模板使用变量 SITE_NAME = 'PT助手' SITE_URL = 'https://github.com/xingsu1021/pthelper' -SITE_VERSION = 'Version 2.0.1' +SITE_VERSION = 'Version 2.1.0' SITE_COPYRIGHT = 'copyright © 2022' SITE_NAME_COPYRIGHT = 'copyright © 2022 PT助手' diff --git a/requirements.txt b/requirements.txt index 3d73d24..bea487c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,10 +9,14 @@ lxml >= 4.7.1 beautifulsoup4 >= 4.10.0 wechatpy >= 1.8.18 cryptography -ddddocr +Pillow +#ddddocr typing_extensions GitPython thefuzz +opencv-contrib-python==4.4.0.46 +opencv-python-headless==4.4.0.46 +opencv_python==4.4.0.46 #thefuzz[speedup] #paddlepaddle paddleocr