-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhello.py
206 lines (172 loc) · 7.45 KB
/
hello.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#-*- coding: UTF-8 -*-
from flask import Flask,render_template,request,redirect,session,url_for
from flask import send_file, send_from_directory,app
from openpyxl import Workbook
import sys, os
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import TextAreaField, SubmitField
from wtforms.fields.html5 import EmailField
from threading import Thread
from wtforms.validators import DataRequired,InputRequired,Email
#fuzzywuzzy 注意重名
#from .fuzzycompare import compare2list 包引用重构时候再说
from fuzzywuzzy import process as fuzzyprocess,fuzz
import logging
# Flask 用这个参数确定应用的位置,进而找到应用中其他文件的位置,例如图像和模板。
app = Flask(__name__)
#using fuzzywuzzy
def compare2list(leftl,rightl,resultdict):
'''
2 list, using right one to match left one
'''
for item in range(len(leftl)):
resultdict[item]=[leftl[item],fuzzyprocess.extractOne(leftl[item], rightl,scorer=fuzz.token_sort_ratio)]
#数据库
from flask_sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(64), unique=True)
cnt= db.Column(db.Integer)
def __repr__(self):
return '<Role %r>' % self.name
sys.path.append(os.getcwd())
#表单key
bootstrap = Bootstrap(app)
app.config['SECRET_KEY'] = 'fuzzyflask' #表单类使用为了增强安全性,密钥不应该直接写入源码,而要保存在环境变量中。这一技术在第 7 章介绍。
#邮件
from flask_mail import Mail
app.config.update(dict(
DEBUG = True,
MAIL_SERVER = 'smtp.qq.com',#'smtp.gmail.com',
MAIL_PORT = '465',#
MAIL_USE_TLS = False,#587
MAIL_USE_SSL = True,#465
MAIL_USERNAME = '[email protected]',#os.environ.get('MAIL_USERNAME'),
MAIL_PASSWORD = 'lvjgwyfpbzatgibc',# os.environ.get('MAIL_PASSWORD') export MAIL_PASSWORD=
MAIL_DEFAULT_SENDER = '[email protected]',
))
mail = Mail(app)#connection refused
from flask_mail import Message
app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[matchfuzzydata]'
app.config['FLASKY_MAIL_SENDER'] = 'matchfuzzydata <[email protected]>'
#send_email() 函数的参数分别为收件人地址、主题、渲染邮件正文的模板和关键字参数列表。
# 调用者传入的关键字参数将传给 render_template() 函数,作为模板变量提供给
# 模板使用,用于生成电子邮件正文。 todo我们可以把执行 send_async_email() 函数的操作发给 Celery 任务队列。
def send_email(to, subject, template, **kwargs):
msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.html', **kwargs)
with app.open_resource("static/"+to+".xlsx") as fp:
msg.attach("static/"+to+".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fp.read())
thr = Thread(target=send_async_email, args=[app, msg])
thr.start()
return thr
def send_async_email(app, msg):
with app.app_context():
mail.send(msg)
#@app.route('/') 主页
# 定义路由的最简便方式,是使用应用实例提供的app.route 装饰器
@app.route('/',methods=['GET','POST'] )
def index():
form = NameForm()#表单模型初始化
if form.validate_on_submit(): #刷新不重复提交post,这里没啥用……
session['leftl'] = form.leftl.data
session['rightl'] = form.leftl.data
return redirect(url_for('index'))
#print("show index")
return render_template('index.html',form=form,leftl=session.get('leftl'), \
rightl=session.get('rightl'),email=session.get('email'),submit=session.get('submit'))
#about页面
@app.route('/about',methods=['GET','POST'] )
def about():
return render_template('about.html')
#主程序,邮件版本
@app.route('/process',methods=['GET','POST'] )
def process():
print("start process")
form = NameForm()
#string to list flask处理request的方法不一样
leftl=request.form.get('leftl').split("\r\n")
rightl=request.form.get('rightl').split("\r\n")
email=form.email.data
resultdic={}
compare2list(leftl,rightl,resultdic)
#生成excel
wb = Workbook()
ws = wb.active
#表头
ws.cell(column=1 , row=1, value="顺序")
ws.cell(column=2 , row=1, value="非标准名称")
ws.cell(column=3 , row=1, value="标准名称")
ws.cell(column=4 , row=1, value="相似度")
next_row=2
#依次生成
for (key,value) in resultdic.items():
ws.cell(column=1 , row=next_row, value=key)
ws.cell(column=2 , row=next_row, value=value[0])
ws.cell(column=3 , row=next_row, value=value[1][0])
ws.cell(column=4 , row=next_row, value=value[1][1])
next_row += 1
#数据库处理邮件地址,判断使用次数 3次
#print(email)
user=User.query.filter_by(email=email).first()
if user is None:#新客户
user=User(email=email)
db.session.add(user)
user.cnt=1
db.session.add(user)
db.session.commit()
#sendfile(address)
# downloadfile(address)
elif user.cnt<3:
user.cnt+=1
db.session.add(user)
db.session.commit()
#sendfile(address)
# downloadfile(address)
else:#超过3次,付费后send file
user.cnt+=1
db.session.add(user)
db.session.commit()
#print("first wechat payment part")
#sendfile(address)
# downloadfile(address)
#todo 付款环节
#返回处理后的结果 ,更新form显示,处理结果已经生成,等待下载
#按客户邮箱命名文件
filename=email+str(user.cnt)+".xlsx"
wb.save("donefiles/"+filename)
#return render_template('results.html',form=form,leftl=leftl,rightl=rightl,email=email)
#本地测试下载——最后直接用nginx了
return send_file("donefiles/"+filename,
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
attachment_filename=filename,
as_attachment=True)
#nginx在线返回静态附件url——nginx post有点问题啊
#print(url_for('process',_external=True)+'/'+filename)
#url_for('user', name='john', _external=True) 的返回结果是 http://localhost:5000/user/john
#return redirect(url_for('process',_external=True)+'/'+filename)
#快速生成bootstrap风格表单
class NameForm(FlaskForm):
leftl = TextAreaField('待匹配的非标准名称列', validators=[DataRequired()])
rightl = TextAreaField('用来匹配的标准名称列', validators=[DataRequired()])
email = EmailField("你的邮箱~", validators=[InputRequired("Please enter your email address"), Email("Please enter your email address.")])
submit = SubmitField('发送匹配结果:)')
downloadfile=SubmitField('下载结果')
@app.route('/user/<name>')#动态路由获得参数例子
def user(name):
return render_template('user.html', name=name)
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'),404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
if __name__ == '__main__':
app.run()