问题描述
我在flask中实现了简单的应用程序。我也可以获取数据并进行处理,但是如何获得随机创建的文件夹。在这个应用程序中,我尝试将一些数据输入到文本区域。单击导出台按钮后,数据将发布到烧瓶。我也可以获取数据并生成卡组,但无法发送生成的卡组文件或重定向到随机文件夹。
我收到以下错误消息。
raise TypeError(
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.)
那么,我该如何实现呢?重定向到新的随机生成的文件夹或将生成的文件作为下载链接发送。
谢谢
app.py
from flask import Flask,render_template,request,redirect,url_for,flash,send_file,send_from_directory
import image_occ_deck_export
import random,os
app = Flask(__name__)
app.config["CACHE_TYPE"] = "null"
@app.route("/",methods=["GET","POST"])
def home():
if request.method == "POST":
print(request.form['notes'])
notes = request.form['notes']
# random folder
data = request.form['notes']
print(data)
random_f = random.randrange(1 << 30,1 << 31)
create_random_folder(random_f,data)
else:
return render_template("index.html")
def create_random_folder(random_f,data):
directory = str(random_f)
parent_dir = "static/uploads/"
path = os.path.join(parent_dir,directory)
if not os.path.exists(path):
os.mkdir(path)
random_file = directory + ".txt"
random_deck_name = directory + ".apkg"
file_loc = path + "/" + random_file
deck_loc = path + "/" + random_deck_name
with open(file_loc,'w') as f:
f.write(str(data))
image_occ_deck_export.exportDeck(file_loc,deck_loc)
return redirect(url_for('uploaded',path=path))
@app.route('/uploaded/<path>',methods=['GET'])
def uploaded():
return render_template("upload.html")
if __name__ == "__main__":
app.run(debug=False)
index.js
function export() {
var textToExport = document.getElementById("noteData").value;
var formData = new FormData();
formData.append("notes",textToExport);
var request = new XMLHttpRequest();
request.open("POST","/");
request.send(formData);
}
index.html
<html>
<textarea id="noteData"></textarea>
<button onclick="export()">Export Deck</button>
</html>
示例输入
cordova-img-occ-note-1602529000819 <img src='art-1851483_640.jpg'></img> <img src='cordova-img-occ-ques-1602529000819.svg'></img> <img src='cordova-img-occ-ans-1602529000819.svg'></img> <img src='cordova-img-occ-orig-1602529000819.svg'></img>
cordova-img-occ-note-1602529001248 <img src='art-1851483_640.jpg'></img> <img src='cordova-img-occ-ques-1602529001248.svg'></img> <img src='cordova-img-occ-ans-1602529001248.svg'></img> <img src='cordova-img-occ-orig-1602529000819.svg'></img>
cordova-img-occ-note-1602529001673 <img src='art-1851483_640.jpg'></img> <img src='cordova-img-occ-ques-1602529001673.svg'></img> <img src='cordova-img-occ-ans-1602529001673.svg'></img> <img src='cordova-img-occ-orig-1602529000819.svg'></img>
image_occ_deck_export.py 该文件用于从txt生成anki卡组
import random
import genanki
import csv
import traceback
anki_deck_title = "learn"
anki_model_name = "image occ"
model_id = random.randrange(1 << 30,1 << 31)
def exportDeck(data_filename,deck_filename):
try:
# front side
front = """
{{#Image}}
<div id="io-header">{{Header}}</div>
<div id="io-wrapper">
<div id="io-overlay">{{Question Mask}}</div>
<div id="io-original">{{Image}}</div>
</div>
<div id="io-footer">{{Footer}}</div>
<script>
// Prevent original image from loading before mask
aFade = 50,qFade = 0;
var mask = document.querySelector('#io-overlay>img');
function loaded() {
var original = document.querySelector('#io-original');
original.style.visibility = "visible";
}
if (mask === null || mask.complete) {
loaded();
} else {
mask.addEventListener('load',loaded);
}
</script>
{{/Image}}
"""
style = """
/* GENERAL CARD STYLE */
.card {
font-family: "Helvetica LT Std",Helvetica,Arial,Sans;
font-size: 150%;
text-align: center;
color: black;
background-color: white;
}
/* OcclUSION CSS START - don't edit this */
#io-overlay {
position:absolute;
top:0;
width:100%;
z-index:3
}
#io-original {
position:relative;
top:0;
width:100%;
z-index:2;
visibility: hidden;
}
#io-wrapper {
position:relative;
width: 100%;
}
/* OcclUSION CSS END */
/* OTHER STYLES */
#io-header{
font-size: 1.1em;
margin-bottom: 0.2em;
}
#io-footer{
max-width: 80%;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
font-style: italic;
}
#io-extra-wrapper{
/* the wrapper is needed to center the
left-aligned blocks below it */
width: 80%;
margin-left: auto;
margin-right: auto;
margin-top: 0.5em;
}
#io-extra{
text-align:center;
display: inline-block;
}
.io-extra-entry{
margin-top: 0.8em;
font-size: 0.9em;
text-align:left;
}
.io-field-descr{
margin-bottom: 0.2em;
font-weight: bold;
font-size: 1em;
}
#io-revl-btn {
font-size: 0.5em;
}
/* ADJUSTMENTS FOR MOBILE DEVICES */
.mobile .card,.mobile #content {
font-size: 120%;
margin: 0;
}
.mobile #io-extra-wrapper {
width: 95%;
}
.mobile #io-revl-btn {
font-size: 0.8em;
}
"""
# back side
back = """
{{#Image}}
<div id="io-header">{{Header}}</div>
<div id="io-wrapper">
<div id="io-overlay">{{Answer Mask}}</div>
<div id="io-original">{{Image}}</div>
</div>
{{#Footer}}<div id="io-footer">{{Footer}}</div>{{/Footer}}
<button id="io-revl-btn" onclick="toggle();">Toggle Masks</button>
<div id="io-extra-wrapper">
<div id="io-extra">
{{#Remarks}}
<div class="io-extra-entry">
<div class="io-field-descr">Remarks</div>{{Remarks}}
</div>
{{/Remarks}}
{{#Sources}}
<div class="io-extra-entry">
<div class="io-field-descr">Sources</div>{{Sources}}
</div>
{{/Sources}}
{{#Extra 1}}
<div class="io-extra-entry">
<div class="io-field-descr">Extra 1</div>{{Extra 1}}
</div>
{{/Extra 1}}
{{#Extra 2}}
<div class="io-extra-entry">
<div class="io-field-descr">Extra 2</div>{{Extra 2}}
</div>
{{/Extra 2}}
</div>
</div>
<script>
// Toggle answer mask on clicking the image
var toggle = function() {
var amask = document.getElementById('io-overlay');
if (amask.style.display === 'block' || amask.style.display === '')
amask.style.display = 'none';
else
amask.style.display = 'block'
}
// Prevent original image from loading before mask
aFade = 50,loaded);
}
</script>
{{/Image}}
"""
# print(self.fields)
anki_model = genanki.Model(
model_id,anki_model_name,fields=[{"name": "id"},{"name": "Header"},{"name": "Image"},{"name": "Question Mask"},{"name": "Footer"},{"name": "Remarks"},{"name": "Sources"},{"name": "Extra 1"},{"name": "Extra 2"},{"name": "Answer Mask"},{"name": "Original"}],templates=[
{
"name": "Card 1","qfmt": front,"afmt": back,},],css=style,)
anki_notes = []
with open(data_filename,"r",encoding="utf-8") as csv_file:
csv_reader = csv.reader(csv_file,delimiter="\t")
for row in csv_reader:
flds = []
for i in range(len(row)):
flds.append(row[i])
anki_note = genanki.Note(
model=anki_model,fields=flds,)
anki_notes.append(anki_note)
random.shuffle(anki_notes)
anki_deck = genanki.Deck(model_id,anki_deck_title)
anki_package = genanki.Package(anki_deck)
for anki_note in anki_notes:
anki_deck.add_note(anki_note)
anki_package.write_to_file(deck_filename)
print("Deck generated with {} flashcards".format(
len(anki_deck.notes)))
except Exception:
traceback.print_exc()
解决方法
create_random_folder()
返回重定向,但是当您从home()
请求处理程序调用重定向时,您对返回的值不做任何事情,也没有在该代码的分支中返回响应您的home()
处理程序。看来您打算像这样从home()
处理程序返回该重定向:
return create_random_folder(random_f,data)
请记住,当您从函数返回值时,就是将值返回给调用代码,而不是返回给浏览器。如果您从请求处理程序中调用函数并收到返回值,则该返回值不会自动发送回浏览器;您需要从请求处理程序中将其返回。