Browse Source

feature: notes & anonymous & change UI

master
欧醚 3 years ago
parent
commit
e1ee8f6a20
2 changed files with 92 additions and 73 deletions
  1. +16
    -4
      app.py
  2. +76
    -69
      templates/list.html

+ 16
- 4
app.py View File

@ -30,6 +30,8 @@ class Paper(db.Model):
teacher = db.Column(db.String(10), index=True)
year = db.Column(db.Integer, index=True)
author = db.Column(db.String(30), index=True)
notes = db.Column(db.String(200))
anon = db.Column(db.Boolean)
create_date = db.Column(db.Date)
like_num = db.Column(db.Integer, index=True, default=0)
file_hash = db.Column(db.String(64))
@ -50,6 +52,9 @@ def list():
ipfs_base_url = C.ipfs_base_url
return render_template('list.html', **locals())
def check_length(x, limit=30, allow_null=False):
return (x and len(x) <= limit) or (allow_null and not x)
@app.route('/pastExam/upload', methods=['POST'])
@limiter.limit("10 / hour")
def upload():
@ -58,8 +63,14 @@ def upload():
teacher = request.form.get('teacher')
year = request.form.get('year')
year = year and year.isdigit() and int(year) or 0
# TODO 检查长度
notes = request.form.get('notes', '')
anon = request.form.get('anon') == 'on'
if not (check_length(name) and check_length(teacher, 10) and check_length(notes, 200, True)):
abort(422)
print(request.form)
files = request.files.getlist('files[]')
dir_name = username + str(datetime.now())
@ -67,7 +78,6 @@ def upload():
os.mkdir(base_path)
for f in files:
filename = f.filename.replace('/','_')
print(f, filename)
f.save(os.path.join(base_path, filename))
res = ipfs_client.add(base_path)
@ -83,6 +93,8 @@ def upload():
course=name,
teacher=teacher,
year=year,
notes=notes,
anon=anon,
author=username,
create_date=date.today(),
file_hash=file_hash
@ -90,5 +102,5 @@ def upload():
db.session.add(paper)
db.session.commit()
return redirect('.')
return redirect('.#part2')

+ 76
- 69
templates/list.html View File

@ -13,12 +13,12 @@
<title>华清大学课程攻略</title>
<style>
body {
background: linear-gradient(-45deg,
#fff calc(50% - 1px),
#ddd calc(50%),
background: linear-gradient(-45deg,
#fff calc(50% - 1px),
#ddd calc(50%),
#fff calc(50% + 1px)
);
background-size: 8px 7px;
background-size: 8px 7px;
}
body,
pre {
@ -89,20 +89,20 @@
}
.qbox {
border: 2px black solid;
background: #fffc;
padding: 5px 20px;
color: black;
margin: 5px 5px 40px;
margin: 5px 5px 20px;
}
.new .qbox {
border: 2px black solid;
background: white;
color: black;
border: none;
}
.new .qbox input {
.new .qbox input,
.new .qbox textarea {
border: none;
border-bottom: 1px solid black;
background: transparent;
@ -110,9 +110,9 @@
border-radius: 0;
}
.xnew .qbox .custom-select, .xnew .qbox .custom-file-label {
background-color: black;
color: white;
.new .qbox .custom-control-input:checked~.custom-control-label::before {
background-color: #495057;
border-color: #495057;
}
.qbox .inner {
@ -135,17 +135,16 @@
padding: 0.75em;
}
.new {
position: relative;
margin: 30px 20px 30px 0;
}
.cate {
display: inline-block;
background-color: #ddd;
background-color: #444;
color: white;
margin: 4px;
padding: 2px 4px;
}
.cate a {
text-decoration: none;
}
.footer {
background: black;
@ -177,13 +176,13 @@
<div class="form-group row">
<label class="col-sm-3 col-form-label mb-0">课程名</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="name" required="required" placeholder="课程名">
<input type="text" class="form-control" name="name" required placeholder="课程名" maxlength="30">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">任课教师</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="teacher" required="required" placeholder="任课教师">
<input type="text" class="form-control" name="teacher" required placeholder="教师名" maxlength="10">
</div>
</div>
<div class="form-group row">
@ -197,13 +196,20 @@
</select>
</div>
</div>
<br>
<div class="form-group mt-4 mb-4">
<label>备注(可选)</label>
<textarea class="form-control" name="notes" rows="2" placeholder="如果你上传的不是往年考题而是其他资料,也请在这里注明一下" maxlength="200"></textarea>
</div>
<div class="custom-file">
<input type="file" class="custom-file-input" name="files[]" multiple required>
<label class="custom-file-label" for="customFile" data-browse="浏览">选择文件,可以多选</label>
</div>
<p> TODO: 设置是否匿名展示。勾选匿名发布后,其他人在查看时作者会显示为“匿名”。 </p>
<button type="submit" class="btn btn-link btn-lg mt-4 pr-1">分享</button>
<div class="custom-control custom-switch mb-2 mt-3 ml-1">
<input type="checkbox" class="custom-control-input" id="anon" name="anon">
<label class="custom-control-label" for="anon">匿名发布</label>
</div>
<p> 勾选匿名发布后,其他人在查看时作者会显示为“匿名”。 </p>
<button type="submit" class="btn btn-link btn-lg mt-4 pr-1">提交</button>
<span>
<a href="##" role="button"data-toggle="popover" >
<svg width="20px" viewBox="0 0 24 28"><path d="M15.07 11.25l-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 0 0-2-2a2 2 0 0 0-2 2H8a4 4 0 0 1 4-4a4 4 0 0 1 4 4a3.2 3.2 0 0 1-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10c0-5.53-4.5-10-10-10z" fill="#626262"/></svg>
@ -215,53 +221,52 @@
<div class="part2" id="part2">
<div id="accordion" class="mb-4">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne">
课程
</button>
</h5>
</div>
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
课程
</button>
</h5>
</div>
<div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
{% for c in all_courses %}
<span class="cate"><a href="?course={{c}}">{{c}}</a></span>
{% endfor %}
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h5 class="mb-0">
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
教师
</button>
</h5>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
<div class="card-body">
{% for t in all_teachers %}
<span class="cate"><a href="?teacher={{t}}">{{t}}</a></span>
{% endfor %}
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingThree">
<h5 class="mb-0">
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
年份
</button>
</h5>
</div>
<div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
<div id="collapseOne" class="collapse show" data-parent="#accordion">
<div class="card-body">
{% for c in all_courses %}
<span class="cate"><a href="?course={{c}}#part2">{{c}}</a></span>
{% endfor %}
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h5 class="mb-0">
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseTwo">
教师
</button>
</h5>
</div>
<div id="collapseTwo" class="collapse" data-parent="#accordion">
<div class="card-body">
{% for t in all_teachers %}
<span class="cate"><a href="?teacher={{t}}#part2">{{t}}</a></span>
{% endfor %}
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingThree">
<h5 class="mb-0">
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseThree">
年份
</button>
</h5>
</div>
<div id="collapseThree" class="collapse" data-parent="#accordion">
<div class="card-body">
{% for y in all_years %}
<span class="cate"><a href="?year={{y}}">{{y or '/'}}</a></span>
<span class="cate"><a href="?year={{y}}#part2">{{y or '/'}}</a></span>
{% endfor %}
</div>
</div>
@ -274,17 +279,18 @@
{% if showPrivate %}
<form action="{{c.id}}/delete" method="post">
<input type="hidden" name="key" value="{{key}}">
<button type="submit" class="close" aria-label="Close">
<button type="submit" class="close">
<span>×</span>
</button>
</form>
{% endif %}
<p class="inner">
{{p.course}} - {{p.teacher}} - {{p.year or '/'}}
<small><a href="{{ipfs_base_url}}/{{p.file_hash}}" target="_blank">查看</a></small>
<small class="ml-4"><a href="{{ipfs_base_url}}/{{p.file_hash}}" target="_blank">查看</a></small>
</p>
<p class="inner">{{p.notes}}</p>
<div style="text-align:right;margin: 27px 0 -5px">
<small>@{{p.author}} | {{p.create_date}}</small>
<small>@{{'匿名用户' if p.anon else p.author}} | {{p.create_date}}</small>
<a href="##" class="btn btn-link" id="like-{{p.id}}" onClick="like('{{p.id}}')" style="text-decoration: none;">
<svg viewBox="-20 0 552 512" height="16" class="{{'like'}}">
<path stroke="#000" stroke-width="30" d="M474.644,74.27C449.391,45.616,414.358,29.836,376,29.836c-53.948,0-88.103,32.22-107.255,59.25
@ -365,6 +371,7 @@
title: "说明",
content:"发布内容的版权属于上传者/原作者/公有领域,基于上传前的版权情况。<br>文件可以多选,电脑端一般是按住ctrl选择,移动端一般是直接勾选多个。对文件数量和大小没有限制,总大小不要太过分就行。<br>时间请填写该学期开始时的年份,课程名尽量与已有的保持一致。"
});
$("#anon").bootstrapSwitch({onColor: 'danger'});
})
</script>

Loading…
Cancel
Save