templates文件夹和app.py在同一目录下。
templates文件夹下包括2个文件:index.html login.html
app.py代码如下:
import os
import time
from flask import Flask, render_template, request, redirect, session, make_response
import mysql.connector
from contextlib import contextmanager
app = Flask(__name__)
app.secret_key = 'your_secret_key'
# MySQL 连接配置
mysql_config = {
'host': 'localhost',
'user': '数据库用户名',
'password': '密码',
'database': '数据库名称',
'buffered': True
}
# 数据库连接上下文管理器
@contextmanager
def get_db_connection():
try:
cnx = mysql.connector.connect(**mysql_config)
yield cnx
except mysql.connector.Error as err:
print(f"MySQL 操作出错: {err}")
finally:
if 'cnx' in locals() and cnx.is_connected():
cnx.close()
# 从 MySQL 获取用户名和密码
def get_user_credentials(username):
with get_db_connection() as cnx:
cursor = cnx.cursor()
query = "SELECT password FROM users WHERE username = %s"
cursor.execute(query, (username,))
result = cursor.fetchone()
cursor.close()
return result[0] if result else None
# 模拟按钮点击时间记录
class ButtonClickManager:
def __init__(self, cooldown=3):
self.last_click_time = 0
self.cooldown = cooldown
def can_click(self):
current_time = time.time()
if current_time - self.last_click_time < self.cooldown:
return False
self.last_click_time = current_time
return True
button_manager = ButtonClickManager()
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
stored_password = get_user_credentials(username)
if stored_password and stored_password == password:
session['username'] = username
return redirect('/')
else:
return render_template('login.html', error='用户名或密码错误')
return render_template('login.html')
@app.route('/', methods=['GET', 'POST'])
def index():
if 'username' not in session:
return redirect('/login')
return render_template('index.html', username=session['username'])
@app.route('/send_email', methods=['POST'])
def send_email():
if not button_manager.can_click():
return "操作过于频繁,请稍后再试", 429
try:
# 调用脚本
os.system("/home/auto/sendemail.sh")
return "邮件发送脚本已执行"
except Exception as e:
return f"执行脚本时出错: {str(e)}", 500
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect('/login')
if __name__ == '__main__':
app.run(debug=True, port=5001)
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>主页</title>
<style>
body {
font-family: "微软雅黑", sans-serif;
text-align: center;
padding-top: 50px;
}
button {
padding: 10px 20px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
</style>
<script>
function sendEmail() {
const button = document.getElementById('send-email-button');
button.disabled = true;
fetch('/send_email', {
method: 'POST'
})
.then(response => response.text())
.then(data => {
alert(data);
})
.catch(error => {
alert('出错了: ' + error.message);
})
.finally(() => {
setTimeout(() => {
button.disabled = false;
}, 3000);
});
}
</script>
</head>
<body>
<h1>欢迎,{{ username }}</h1>
<button id="send-email-button" onclick="sendEmail()">点我发送邮件</button>
<a href="/logout">退出登录</a>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
<style>
body {
font-family: "微软雅黑", sans-serif;
}
form {
width: 300px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
}
input {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 3px;
}
button {
width: 100%;
padding: 10px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
.error {
color: red;
text-align: center;
margin-bottom: 10px;
}
</style>
</head>
<body>
{% if error %}
<p class="error">{{ error }}</p>
{% endif %}
<form method="post">
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<button type="submit">登录</button>
</form>
</body>
</html>
在CENTOS上启动5001端口的服务器:
nohup /root/anaconda3/envs/py39/bin/gunicorn -w 4 -b 0.0.0.0:5001 app:app > /home/log/sendemail_code_gunicorn_log.txt 2>&1 &