依赖PIL
pip install pillow
公共方法
import hashlib
import random
import string
from PIL import Image, ImageFont, ImageDraw, ImageFilter
from flask import Flask
app = Flask(__name__)
app.config.from_object("config.DevelopmentConfig") # 从config.py读入配置
def rndColor():
"""随机颜色"""
return random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)
def gene_text():
"""生成4位验证码"""
return ''.join(random.sample(string.ascii_letters + string.digits, 4))
def draw_lines(draw, num, width, height):
"""划线"""
for num in range(num):
x1 = random.randint(0, width / 2)
y1 = random.randint(0, height / 2)
x2 = random.randint(0, width)
y2 = random.randint(height / 2, height)
draw.line(((x1, y1), (x2, y2)), fill='black', width=1)
def get_verify_code():
"""生成验证码图形"""
code = gene_text()
# 图片大小120×50
width, height = 100, 40
# 新图片对象
im = Image.new('RGB', (width, height), 'white')
# 字体
font = ImageFont.truetype('app/static/arial.ttf', 30)
# draw对象
draw = ImageDraw.Draw(im)
# 绘制字符串
for item in range(4):
draw.text((5 + random.randint(-3, 3) + 23 * item, 5 + random.randint(-3, 3)),
text=code[item], fill=rndColor(), font=font)
# 划线
draw_lines(draw, 2, width, height)
# 高斯模糊
im = im.filter(ImageFilter.GaussianBlur(radius=1.5))
return im, code
def salted_password(password):
salt = app.config.get('SALT_KEY')
hsobj = hashlib.sha256(salt.encode("utf-8"))
hsobj.update(password.encode("utf-8"))
return hsobj.hexdigest().upper()
调用
from app import app
from flask import render_template, request, session, redirect, make_response,url_for,flash
from app import db
from app.functions import get_verify_code, salted_password
import re
from app.models import Users,UsersJson,Menus,MenuDto
import datetime
from io import BytesIO
from app.PubFunc.EmailHelp import EmailCls
import json
from datetime import timedelta
import threading
@app.route('/code')
def get_code():
image, code = get_verify_code()
# 图片以二进制形式写入
buf = BytesIO()
image.save(buf, 'jpeg')
buf_str = buf.getvalue()
# 把buf_str作为response返回前端,并设置首部字段
response = make_response(buf_str)
response.headers['Content-Type'] = 'image/gif'
# 将验证码字符串储存在session中
session['verifyCode'] = code
return response
@app.route('/')
def main():
if 'userName' not in session or session['userName'] == None or session['userName'] == '':
return redirect('login')
# email = EmailCls()
# emailInfo = email.getEmail()
# t= threading.Thread(target=email.getEmail)
# t.setDaemon(True)
# t.start()
# t.join()
menus = test_set_subMenus()
return render_template('index.html',userinfo=json.loads(session['userinfo']),emailInfo=None,menus=menus)
@app.route('/logout')
def logout():
session.clear
return redirect('/login')
@app.route('/login', methods=['GET', 'POST'])
def login():
if (request.method == 'GET'):
return render_template('login.html')
else:
username = request.form.get('userlogin')
password = request.form.get('loginpassword')
verifyCode = request.form.get('loginverifycode')
rememberme = request.form.get('rememberme')
remembermemonth = request.form.get('remembermemonth')
if rememberme=='on':
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7) #配置7天有效
session.permanent = timedelta(days=7)
if remembermemonth=='on':
app.config['PERMANENT_SESSION_LIFETIME'] = True # 长期有效,一个月的时间有效
session.permanent = True # 长期有效,一个月的时间有效
if 'verifyCode' not in session or session['verifyCode'] == None or session['verifyCode'] == '':
return redirect('login')
if verifyCode == None or verifyCode == '':
return '请输入验证码'
if verifyCode.upper() != session['verifyCode'].upper():
return '验证码输入不正确'
if username == None or username == '':
return '请输入用户名'
if password == None or password == '':
return '请输入密码'
user = db.session.query(Users).filter_by(user_login=username).first()
if user == None:
return '当前用户尚未注册'
if not user.user_pass == salted_password(password):
return '密码输入不正确'
session['userName'] = username
session['userinfo']=json.dumps(user,default=UsersJson)
return redirect('/')
@app.route('/register', methods=['POST', ])
def register():
username = request.form.get('regusername')
password = request.form.get('regpassword')
verifyCode = request.form.get('regverifycode')
userEmail = request.form.get('regemail')
if username == None or username == '':
return '请输入用户名'
if userEmail == None or userEmail == '':
return '请输入邮箱'
if not re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net,me,org,com.cn.cc.co]{1,3}$', userEmail):
return '邮箱格式不正确'
if password == None or password == '':
return '请输入密码'
if verifyCode.upper() != session['verifyCode'].upper():
return '验证码输入不正确'
user = Users()
user.user_login = username
user.user_email = userEmail
user.user_pass = salted_password(password)
user.user_nicename = username
user.user_registered = datetime.datetime.now()
user.user_status = 1
user.display_name = username
sql = 'SELECT 1 FROM Users where user_login=:username or user_email=:user_email'
userExist = db.session.execute(sql, {'username': username, 'user_email': userEmail})
if len(userExist.fetchall()) > 0:
return '当前用户已存在或者邮箱已被注册'
db.session.add(user)
db.session.commit()
return redirect('/')
@app.route('/welcome_iframe.html')
def elements():
return render_template('welcome_iframe.html')
@app.route('/UI/buttons_iframe.html')
def buttons():
return render_template('UI/buttons_iframe.html')
@app.route('/UI/general_iframe.html')
def general_iframe():
return render_template('UI/general_iframe.html')
@app.route('/UI/icons_iframe.html')
def icons_iframe():
return render_template('UI/icons_iframe.html')
@app.route('/UI/modals_iframe.html')
def modals_iframe():
return render_template('UI/modals_iframe.html')
@app.route('/UI/sliders_iframe.html')
def sliders_iframe():
return render_template('UI/sliders_iframe.html')
@app.route('/UI/timeline_iframe.html')
def timeline_iframe():
return render_template('UI/timeline_iframe.html')
def queryByParent(parentid):
menus = db.session.query(Menus).filter_by(parentid=parentid).all()
return menus
def set_subMenus(id, menus):
"""
根据传递过来的父菜单id,递归设置各层次父菜单的子菜单列表
:param id: 父级id
:param menus: 子菜单列表
:return: 如果这个菜单没有子菜单,返回None;如果有子菜单,返回子菜单列表
"""
# 记录子菜单列表
subMenus = []
# 遍历子菜单
for m in menus:
if m.parentid == id:
subMenus.append(m)
# 把子菜单的子菜单再循环一遍
for sub in subMenus:
menus2 = queryByParent(sub.id)
# 还有子菜单
if len(menus):
sub.subMenus = set_subMenus(sub.id, menus2)
# 子菜单列表不为空
if len(subMenus):
return subMenus
else: # 没有子菜单了
return None
def test_set_subMenus():
# 一级菜单
rootMenus = queryByParent('0')
for menu in rootMenus:
subMenus = queryByParent(menu.id)
menu.subMenus = set_subMenus(menu.id, subMenus)
jsonData = json.dumps(rootMenus,default=MenuDto,ensure_ascii=False)
return jsonData
前台
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>开发框架</title>
<meta name="keywords" content="开发框架" />
<meta name="description" content="开发框架" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- basic styles -->
<link href="/static/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="/static/css/font-awesome.min.css" />
<link rel="shortcut icon" href="/static/img/favicon.ico"/>
<link rel="stylesheet" href="/static/css/font.googleapis.com.css" />
<link rel="stylesheet" href="/static/css/ace.min.css" />
<link rel="stylesheet" href="/static/css/ace-rtl.min.css" />
</head>
<body class="login-layout">
<div class="main-container">
<div class="main-content">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<div class="login-container">
<div class="center">
<h1>
<i class="fa fa-leaf green"></i>
<a href="https://www.erpdev.cn"><span class="red">ErpDev.Cn</span></a>
<br/>
<span class="white">基于Python的开发框架</span>
</h1>
<h4 class="blue">©copy; <a href="https://www.xiangcaowuyu.net">李森的博客</a></h4>
</div>
<div class="space-6"></div>
<div class="position-relative">
<div id="login-box" class="login-box visible widget-box no-border">
<div class="widget-body">
<div class="widget-main">
<h4 class="header blue lighter bigger">
<i class="icon-coffee green"></i>
请输入个人信息
</h4>
<div class="space-6"></div>
<form action="{{ url_for("login") }}" method="post" name="loginform" id="loginform">
<fieldset>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<input type="text" id="userlogin" name="userlogin" class="form-control" placeholder="请输入用户名" required minlength="4" maxlength="30" />
<i class="icon-user"></i>
</span>
</label>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<input type="password" id="loginpassword" name="loginpassword" class="form-control" placeholder="请输入密码" required minlength="8" />
<i class="icon-lock"></i>
</span>
</label>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<div class="row">
<div class="col-sm-4 col-xs-4">
<img id="loginverifycodeImg" src="/code" />
</div>
<div class="col-sm-8 col-xs-8">
<input type="text" id="loginverifycode" name="loginverifycode" class="form-control" placeholder="请输入验证码" required minlength="4" maxlength="4" />
</div>
</div>
<i class="icon-lock"></i>
</span>
</label>
<div class="space"></div>
<div class="clearfix">
<label class="inline">
<input type="checkbox" class="ace" id="rememberme" name="rememberme"/>
<span class="lbl">记住我(7天)</span>
</label>
<label class="inline">
<input type="checkbox" class="ace" id="remembermemonth" name="remembermemonth"/>
<span class="lbl">记住我(1个月)</span>
</label>
<button type="submit" class="width-35 pull-right btn btn-sm btn-primary">
<i class="icon-key"></i>
登录
</button>
</div>
<div class="space-4"></div>
</fieldset>
</form>
<div class="social-or-login center">
<span class="bigger-110">通过以下方式登录</span>
</div>
<div class="social-login center">
<a class="btn btn-primary">
<i class="fa fa-qq"></i>
</a>
<a class="btn btn-info">
<i class="fa fa-wechat"></i>
</a>
<a class="btn btn-danger">
<i class="fa fa-weibo"></i>
</a>
</div>
</div><!-- /widget-main -->
<div class="toolbar clearfix">
<div>
<a href="#" onclick="show_box('forgot-box'); return false;" class="forgot-password-link">
<i class="icon-arrow-left"></i>
忘记密码?
</a>
</div>
<div>
<a href="#" onclick="show_box('signup-box'); return false;" class="user-signup-link">
注册
<i class="icon-arrow-right"></i>
</a>
</div>
</div>
</div><!-- /widget-body -->
</div><!-- /login-box -->
<div id="forgot-box" class="forgot-box widget-box no-border">
<div class="widget-body">
<div class="widget-main">
<h4 class="header red lighter bigger">
<i class="icon-key"></i>
找回密码
</h4>
<div class="space-6"></div>
<p>
请输入邮箱
</p>
<form>
<fieldset>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<input type="email" class="form-control" placeholder="邮箱" />
<i class="icon-envelope"></i>
</span>
</label>
<div class="clearfix">
<button type="button" class="width-35 pull-right btn btn-sm btn-danger">
<i class="icon-lightbulb"></i>
发送
</button>
</div>
</fieldset>
</form>
</div><!-- /widget-main -->
<div class="toolbar center">
<a href="#" onclick="show_box('login-box'); return false;" class="back-to-login-link">
登录
<i class="icon-arrow-right"></i>
</a>
</div>
</div><!-- /widget-body -->
</div><!-- /forgot-box -->
<div id="signup-box" class="signup-box widget-box no-border">
<div class="widget-body">
<div class="widget-main">
<h4 class="header green lighter bigger">
<i class="icon-group blue"></i>
注册
</h4>
<div class="space-6"></div>
<p> 请输入个人信息: </p>
<form action="register" method="POST">
<fieldset>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<input type="email" id="regemail" name="regemail" class="form-control" placeholder="请输入邮箱" required maxlength="100" />
<i class="icon-envelope"></i>
</span>
</label>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<input type="text" id="regusername" name="regusername" class="form-control" placeholder="请输入用户名" required maxlength="30" minlength="4" />
<i class="icon-user"></i>
</span>
</label>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<input type="password" id="regpassword" name="regpassword" class="form-control" placeholder="请输入密码" required minlength="8" maxlength="100" />
<i class="icon-lock"></i>
</span>
</label>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<input type="password" id="regcomfirmpassword" name="regcomfirmpassword" class="form-control" placeholder="请再次输入密码" required equalTo:"#regpassword" />
<i class="icon-retweet"></i>
</span>
</label>
<label class="block clearfix">
<span class="block input-icon input-icon-right">
<div class="row">
<div class="col-sm-4 col-xs-4">
<img src="/code" />
</div>
<div class="col-sm-8 col-xs-8">
<input type="text" id="regverifycode" name="regverifycode" class="form-control" placeholder="验证码" required="true" maxlength="4" minlength="4" />
</div>
</div>
<i class="icon-lock"></i>
</span>
</label>
<label class="block">
<input type="checkbox" class="ace" required />
<span class="lbl">
我同意
<a href="#">用户协议</a>
</span>
</label>
<div class="space-24"></div>
<div class="clearfix">
<button type="reset" class="width-30 pull-left btn btn-sm">
<i class="icon-refresh"></i>
取消
</button>
<button type="submit" class="width-65 pull-right btn btn-sm btn-success">
注册
<i class="icon-arrow-right icon-on-right"></i>
</button>
</div>
</fieldset>
</form>
</div>
<div class="toolbar center">
<a href="#" onclick="show_box('login-box'); return false;" class="back-to-login-link">
<i class="icon-arrow-left"></i>
登录
</a>
</div>
</div><!-- /widget-body -->
</div><!-- /signup-box -->
</div><!-- /position-relative -->
</div>
</div><!-- /.col -->
</div><!-- /.row -->
</div>
</div><!-- /.main-container -->
<!-- basic scripts -->
<!--[if !IE]> -->
<script type="text/javascript">
window.jQuery || document.write("<script src='/static/js/jQuery/jquery-2.2.3.min.js'>"+"<"+"/script>");
</script>
<script type="text/javascript" src="/static/js/jQuery/jquery.validate.min.js"></script>
<!-- <![endif]-->
<!--[if IE]>
<script type="text/javascript">
window.jQuery || document.write("<script src='/static/js/jquery-1.10.2.min.js'>"+"<"+"/script>");
</script>
<![endif]-->
<script type="text/javascript">
if("ontouchend" in document) document.write("<script src='/static/js/jQuery/jquery.mobile.custom.min.js'>"+"<"+"/script>");
</script>
<!-- inline scripts related to this page -->
<script type="text/javascript">
$(function(){
$("#loginverifycodeImg").click(function(){
$('#loginverifycodeImg').attr('src',"/code?t="+Date());
})
})
function show_box(id) {
jQuery('.widget-box.visible').removeClass('visible');
jQuery('#'+id).addClass('visible');
}
</script>
</body>
</html>
Oracle跟踪Sql语句_木子网
呵呵