更改验证码,简化目录

This commit is contained in:
不胜舟
2022-12-27 20:48:50 +08:00
parent c811b895d7
commit 078b838374
12 changed files with 142 additions and 45 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_DATABASE=PearAdminFlask
MYSQL_USERNAME=root
MYSQL_PASSWORD=123456
MYSQL_PASSWORD=root
# Redis 配置
# REDIS_HOST=127.0.0.1
+1 -1
View File
@@ -19,7 +19,7 @@ COPY . /app
WORKDIR /app
RUN pip --no-cache-dir install -i ${PIPURL} --upgrade pip \
&& pip --no-cache-dir install -i ${PIPURL} -r requirement/requirement-dev.txt \
&& pip --no-cache-dir install -i ${PIPURL} -r requirement/dev.txt \
&& pip --no-cache-dir install -i ${PIPURL} gunicorn \
&& chmod +x start.sh
CMD ./start.sh
+1 -1
View File
@@ -96,7 +96,7 @@ Pear Admin Flask
git clone https://gitee.com/pear-admin/pear-admin-flask
# 安 装
pip install -r requirement\requirement-dev.txt
pip install -r requirement\dev.txt
# 配 置
.env
+4 -3
View File
@@ -4,7 +4,7 @@ from io import BytesIO
from flask import session, make_response, current_app
from flask_login import current_user
from applications.common.utils.gen_captcha import gen_captcha
from applications.common.utils.gen_captcha import vieCode
from applications.schemas import PowerOutSchema
@@ -36,7 +36,7 @@ def make_menu_tree():
if p.enable == 0:
continue
# 一二级菜单
if int(p.type) in [0,1] and p not in powers:
if int(p.type) in [0, 1] and p not in powers:
powers.append(p)
power_schema = PowerOutSchema(many=True) # 用已继承 ma.ModelSchema 类的自定制类生成序列化类
@@ -61,7 +61,8 @@ def make_menu_tree():
# 生成验证码
def get_captcha():
code, image = gen_captcha()
image, code = vieCode().GetCodeImage()
code = ''.join(code).lower()
out = BytesIO()
session["code"] = code
image.save(out, 'png')
+1 -1
View File
@@ -55,6 +55,6 @@ def init_db():
return
if init_database():
print('数据库%s创建成功' % str(DATABASE))
execute_fromfile('test/pear.sql')
execute_fromfile('pear.sql')
print('表创建成功')
print('欢迎使用pear-admin-flask,请使用 flask run 命令启动程序')
Binary file not shown.
+119 -12
View File
@@ -1,14 +1,121 @@
from captcha.image import ImageCaptcha
from PIL import Image
from random import choices
import random, math
from PIL import Image, ImageDraw, ImageFont, ImageFilter
def gen_captcha(content='2345689abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ'):
""" 生成验证码 """
image = ImageCaptcha()
# 获取字符串
captcha_text = "".join(choices(content, k=4)).lower()
# 生成图像
captcha_image = Image.open(image.generate(captcha_text))
return captcha_text, captcha_image
class vieCode:
__fontSize = 20 # 字体大小
__width = 120 # 画布宽度
__heigth = 45 # 画布高度
__length = 4 # 验证码长度
__draw = None # 画布
__img = None # 图片资源
__code = None # 验证码字符
__str = None # 自定义验证码字符集
__inCurve = True # 是否画干扰线
__inNoise = True # 是否画干扰点
__type = 2 # 验证码类型 1、纯字母 2、数字字母混合
__fontPatn = 'applications/common/utils/fonts/1.ttf' # 字体
def GetCodeImage(self, size=80, length=4):
'''获取验证码图片
@param int size 验证码大小
@param int length 验证码长度
'''
# 准备基础数据
self.__length = length
self.__fontSize = size
self.__width = self.__fontSize * self.__length
self.__heigth = int(self.__fontSize * 1.5)
# 生成验证码图片
self.__createCode()
self.__createImage()
self.__createNoise()
self.__printString()
self.__cerateFilter()
return self.__img, self.__code
def __cerateFilter(self):
'''模糊处理'''
self.__img = self.__img.filter(ImageFilter.BLUR)
filter = ImageFilter.ModeFilter(8)
self.__img = self.__img.filter(filter)
def __createCode(self):
'''创建验证码字符'''
# 是否自定义字符集合
if not self.__str:
# 源文本
number = "3456789"
srcLetter = "qwertyuipasdfghjkzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
srcUpper = srcLetter.upper()
if self.__type == 1:
self.__str = number
else:
self.__str = srcLetter + srcUpper + number
# 构造验证码
self.__code = random.sample(self.__str, self.__length)
def __createImage(self):
'''创建画布'''
bgColor = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255))
self.__img = Image.new('RGB', (self.__width, self.__heigth), bgColor)
self.__draw = ImageDraw.Draw(self.__img)
def __createNoise(self):
'''画干扰点'''
if not self.__inNoise:
return
font = ImageFont.truetype(self.__fontPatn, int(self.__fontSize / 1.5))
for i in range(5):
# 杂点颜色
noiseColor = (random.randint(150, 200), random.randint(150, 200), random.randint(150, 200))
putStr = random.sample(self.__str, 2)
for j in range(2):
# 绘杂点
size = (random.randint(-10, self.__width), random.randint(-10, self.__heigth))
self.__draw.text(size, putStr[j], font=font, fill=noiseColor)
pass
def __createCurve(self):
'''画干扰线'''
if not self.__inCurve:
return
x = y = 0
# 计算曲线系数
a = random.uniform(1, self.__heigth / 2)
b = random.uniform(-self.__width / 4, self.__heigth / 4)
f = random.uniform(-self.__heigth / 4, self.__heigth / 4)
t = random.uniform(self.__heigth, self.__width * 2)
xend = random.randint(self.__width / 2, self.__width * 2)
w = (2 * math.pi) / t
# 画曲线
color = (random.randint(30, 150), random.randint(30, 150), random.randint(30, 150))
for x in range(xend):
if w != 0:
for k in range(int(self.__heigth / 10)):
y = a * math.sin(w * x + f) + b + self.__heigth / 2
i = int(self.__fontSize / 5)
while i > 0:
px = x + i
py = y + i + k
self.__draw.point((px, py), color)
i -= i
def __printString(self):
'''打印验证码字符串'''
font = ImageFont.truetype(self.__fontPatn, self.__fontSize)
x = 0
# 打印字符到画板
for i in range(self.__length):
# 设置字体随机颜色
color = (random.randint(30, 150), random.randint(30, 150), random.randint(30, 150))
# 计算座标
x = random.uniform(self.__fontSize * i * 0.95, self.__fontSize * i * 1.1)
y = self.__fontSize * random.uniform(0.3, 0.5)
# 打印字符
self.__draw.text((x, y), self.__code[i], font=font, fill=color)
-2
View File
@@ -2,7 +2,6 @@ from flask import Flask
from .init_sqlalchemy import db, ma, init_databases
from .init_login import init_login_manager
from .init_debug_tool import init_debug_tool
from .init_template_directives import init_template_directives
from .init_error_views import init_error_views
from .init_mail import init_mail
@@ -12,7 +11,6 @@ from .init_dotenv import init_dotenv
def init_plugs(app: Flask) -> None:
# init_debug_tool(app)
init_login_manager(app)
init_databases(app)
init_template_directives(app)
@@ -1,7 +0,0 @@
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
def init_debug_tool(app: Flask):
toolbar = DebugToolbarExtension()
toolbar.init_app(app)
View File
+15
View File
@@ -0,0 +1,15 @@
Flask
Flask-APScheduler
Flask-Migrate
Flask-Login
Flask_Reuploaded
Flask-SQLAlchemy
flask-marshmallow
marshmallow-sqlalchemy
PyMySQL
psutil
Flask-Mail
sqlparse
Pillow
python-dotenv
webargs
-17
View File
@@ -1,17 +0,0 @@
Flask==2.1.1
Flask-APScheduler==1.12.2
Flask-DebugToolbar==0.11.0
Flask-Migrate==3.1.0
Flask-Login==0.6.0
Flask_Reuploaded==0.5.0
Flask-SQLAlchemy==2.5.1
flask-marshmallow==0.14.0
marshmallow-sqlalchemy==0.26.1
PyMySQL==1.0.2
psutil==5.8.0
Flask-Mail==0.9.1
sqlparse==0.4.2
captcha==0.3
Pillow==8.2.0
python-dotenv==0.19.1
webargs==8.0.1