CDK_Change/app.py
2025-03-06 17:52:20 +08:00

235 lines
7.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, render_template, request, jsonify, flash, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
import requests
from bs4 import BeautifulSoup
import os
from dotenv import load_dotenv
import random
import string
import pymysql
import re
from config import AD_TEMPLATE, SERVER_INFO, VERIFICATION_CONFIG, NAME_TYPES
from sqlalchemy import create_engine
# 设置PyMySQL作为MySQL驱动
pymysql.install_as_MySQLdb()
load_dotenv()
app = Flask(__name__)
# 设置 Flask secret key
app.secret_key = os.getenv('SECRET_KEY', 'dev_key_123') # 在生产环境中使用环境变量设置
# 数据库配置
database_url = os.getenv('DATABASE_URL')
app.config['SQLALCHEMY_DATABASE_URI'] = database_url
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 创建数据库连接
def create_database():
try:
# 解析数据库URL
url_parts = database_url.split('/')
db_name = url_parts[-1]
base_url = '/'.join(url_parts[:-1])
# 创建数据库引擎(不指定数据库名)
engine = create_engine(base_url)
# 连接并创建数据库
with engine.connect() as conn:
conn.execute(f"CREATE DATABASE IF NOT EXISTS {db_name}")
print(f"数据库 {db_name} 创建成功")
except Exception as e:
print(f"创建数据库失败:{str(e)}")
db = SQLAlchemy(app)
# 定义CDK模型
class CDKCode(db.Model):
__tablename__ = '兑换码'
ID = db.Column(db.Integer, primary_key=True)
兑换码 = db.Column(db.String(20), unique=True, nullable=False)
奖励模板ID = db.Column(db.Integer, nullable=False)
# 定义已使用的CDK记录
class UsedCDK(db.Model):
__tablename__ = 'used_cdks'
id = db.Column(db.Integer, primary_key=True)
character_name = db.Column(db.String(50), nullable=False)
post_url = db.Column(db.String(255), nullable=False)
cdk = db.Column(db.String(20), nullable=False)
used_at = db.Column(db.DateTime, server_default=db.func.now())
def verify_ad_content(content, character_name):
# 检查必须包含的关键词
for keyword in VERIFICATION_CONFIG['required_keywords']:
if keyword not in content:
return False
# 检查必须匹配的模式
for pattern in VERIFICATION_CONFIG['required_patterns']:
if not re.search(pattern, content):
return False
# 确保包含角色名
if character_name not in content:
return False
return True
@app.route('/')
def index():
return render_template('index.html')
@app.route('/generate')
def generate():
return render_template('generate.html', server_info=SERVER_INFO)
@app.route('/create-ad', methods=['POST'])
def create_ad():
character_name = request.form.get('character_name')
name_type = request.form.get('name_type', 'character')
if not character_name:
return jsonify({'success': False, 'message': '请输入名称'})
ad_content = AD_TEMPLATE.format(
server_name=SERVER_INFO['server_name'],
name_type=NAME_TYPES[name_type],
name=character_name,
server_features=SERVER_INFO['server_features'],
website=SERVER_INFO['website']
)
return jsonify({
'success': True,
'ad_content': ad_content
})
@app.route('/verify', methods=['POST'])
def verify_post():
character_name = request.form.get('character_name')
post_url = request.form.get('post_url')
if not character_name or not post_url:
return jsonify({'success': False, 'message': '请填写所有必要信息'})
# 检查该角色是否已经领取过CDK
used = UsedCDK.query.filter_by(character_name=character_name).first()
if used:
return jsonify({'success': False, 'message': '该角色已经领取过CDK'})
try:
# 获取帖子内容
response = requests.get(post_url)
soup = BeautifulSoup(response.text, 'html.parser')
post_content = soup.get_text()
# 验证广告内容
if not verify_ad_content(post_content, character_name):
return jsonify({'success': False, 'message': '未找到有效的宣传内容,请确保完整复制宣传模板'})
# 获取未使用的CDK
cdk = CDKCode.query.filter(
~CDKCode.兑换码.in_(
db.session.query(UsedCDK.cdk)
)
).first()
if not cdk:
return jsonify({'success': False, 'message': 'CDK已经用完请联系管理员'})
# 记录使用情况
used_cdk = UsedCDK(
character_name=character_name,
post_url=post_url,
cdk=cdk.兑换码
)
db.session.add(used_cdk)
db.session.commit()
return jsonify({
'success': True,
'message': '验证成功!',
'cdk': cdk.兑换码
})
except Exception as e:
return jsonify({'success': False, 'message': f'验证失败:{str(e)}'})
@app.route('/redeem', methods=['GET', 'POST'])
def redeem():
if request.method == 'POST':
post_url = request.form.get('link')
if not post_url:
flash('请输入宣传链接', 'danger')
return redirect(url_for('redeem'))
try:
response = requests.get(post_url)
soup = BeautifulSoup(response.text, 'html.parser')
post_content = soup.get_text()
# 使用正则表达式提取角色名
character_match = re.search(r'推荐(角色|账号)([^\n\r]+)', post_content)
if not character_match:
flash('未在帖子中找到有效的推荐信息', 'danger')
return redirect(url_for('redeem'))
character_name = character_match.group(2).strip()
# 验证广告内容
if not verify_ad_content(post_content, character_name):
flash('未找到有效的宣传内容,请确保完整复制宣传模板', 'danger')
return redirect(url_for('redeem'))
# 检查是否已经领取过
used = UsedCDK.query.filter_by(character_name=character_name).first()
if used:
flash('该角色已经领取过CDK', 'danger')
return redirect(url_for('redeem'))
# 获取未使用的CDK
cdk = CDKCode.query.filter(
~CDKCode.兑换码.in_(
db.session.query(UsedCDK.cdk)
)
).first()
if not cdk:
flash('CDK已经用完请联系管理员', 'danger')
return redirect(url_for('redeem'))
# 记录使用情况
used_cdk = UsedCDK(
character_name=character_name,
post_url=post_url,
cdk=cdk.兑换码
)
db.session.add(used_cdk)
db.session.commit()
flash(f'恭喜您的CDK是{cdk.兑换码}', 'success')
return redirect(url_for('redeem'))
except Exception as e:
flash(f'验证失败:{str(e)}', 'danger')
return redirect(url_for('redeem'))
return render_template('redeem.html', server_info=SERVER_INFO)
if __name__ == '__main__':
# 创建数据库
create_database()
with app.app_context():
try:
# 创建所有表
db.create_all()
print("数据库表创建成功")
except Exception as e:
print(f"数据库表创建失败:{str(e)}")
app.run(debug=True)