document upload/download/delete ok

This commit is contained in:
ridethepig 2022-12-11 23:47:12 +08:00
parent 9f93aa854b
commit 417b2b4470
5 changed files with 212 additions and 92 deletions

3
.gitignore vendored
View File

@ -9,4 +9,5 @@ $*
*.db
venv/
__pycache__/
.vscode/
.vscode/
file_storage/

View File

@ -13,8 +13,10 @@ def create_app(test_config=None):
DATABASE_USER='root',
DATABASE_HOST='localhost',
DATABASE_PASS='lil0,.lil0',
UPLOADDIR=os.path.join("./file_storage"),
)
if not os.path.exists(app.config['UPLOADDIR']):
os.mkdir(app.config['UPLOADDIR'])
if test_config is None:
app.config.from_pyfile('config.py', silent=True)
else:

View File

@ -1,102 +1,123 @@
{% extends 'base.html' %}
{% block header %}
<style>
.maindiv {
height: 100%;
width: 100%;
position: fixed;
z-index: 1;
top: 20;
left: 0;
padding-left: 1.2rem;
padding-right: 2rem;
}
.sidenav {
height: 100%;
max-width: 160px;
z-index: 1;
}
</style>
<style>
.maindiv {
height: 100%;
width: 100%;
position: fixed;
z-index: 1;
top: 20;
left: 0;
padding-left: 1.2rem;
padding-right: 2rem;
}
.sidenav {
height: 100%;
max-width: 160px;
z-index: 1;
}
</style>
{% endblock %}
{% block content %}
<div class="container">
<div class="columns">
<div class="column col-3">
<ul class="nav">
<li class="nav-item">
<a href="/home">主页</a>
</li>
<li class="nav-item">
<a href="/search">搜索</a>
</li>
<li class="nav-item">
<a href="/addbook">增加</a>
</li>
<li class="nav-item">
<a href="/tags">分类</a>
</li>
</ul>
</div>
<div class="column col-9 panel">
<div class="panel-header">
<div class="panel-title h3">{{book['book_name']}}</div>
{%if booktype|length > 0 %}
<div>
<mark>分类标签:</mark>
{% for atype in booktype %}
<span class="chip"> {{atype['type_name']}}</span>
{% endfor %}
</div>
{%endif%}
{%if book['book_author']%}
<div class="py-1">
<mark>作者:</mark><span class="px-2">{{book['book_author']}}</span>
</div>
{% endif %}
{%if book['book_publisher']%}
<div class="py-1">
<mark>出版社:</mark><span class="px-2">{{book['book_publisher']}}</span>
</div>
{% endif %}
{%if book['book_isbn']%}
<div class="py-1">
<mark>ISBN</mark><span class="px-2">{{book['book_isbn']}}</span>
</div>
{% endif %}
{%if book['book_lang']%}
<div class="py-1">
<mark>语言:</mark><span class="px-2">{{book['book_lang']}}</span>
</div>
{% endif %}
<div>
<div class="container">
<div class="columns">
<div class="column col-3">
<ul class="nav">
<li class="nav-item">
<a href="/home">主页</a>
</li>
<li class="nav-item">
<a href="/search">搜索</a>
</li>
<li class="nav-item">
<a href="/addbook">增加</a>
</li>
<li class="nav-item">
<a href="/tags">分类</a>
</li>
</ul>
</div>
<div class="column col-9 panel">
<div class="panel-header">
<div class="panel-title h3">{{book['book_name']}}</div>
{%if booktype|length > 0 %}
<div>
<mark>分类标签:</mark>
{% for atype in booktype %}
<span class="chip"> {{atype['type_name']}}</span>
{% endfor %}
</div>
{%endif%}
{%if book['book_author']%}
<div class="py-1">
<mark>作者:</mark><span class="px-2">{{book['book_author']}}</span>
</div>
{% endif %}
{%if book['book_publisher']%}
<div class="py-1">
<mark>出版社:</mark><span class="px-2">{{book['book_publisher']}}</span>
</div>
{% endif %}
{%if book['book_isbn']%}
<div class="py-1">
<mark>ISBN</mark><span class="px-2">{{book['book_isbn']}}</span>
</div>
{% endif %}
{%if book['book_lang']%}
<div class="py-1">
<mark>语言:</mark><span class="px-2">{{book['book_lang']}}</span>
</div>
{% endif %}
<div class="columns">
<div class="column col-2">
<a href="/book/update/{{book['book_id']}}/" class="btn btn-primary">编辑图书信息</a>
</div>
<div class="divider-vert"></div>
<div class="column col-6">
<form method="post" class="form-group p-centered" action="/doc/upload/{{book['book_id']}}/"
enctype="multipart/form-data">
<input class="form-input form-inline col-9" type="file" name="file" required>
<input class="btn btn-primary input-group-btn form-inline" type="submit" value="上传">
</form>
</div>
<div class="divider-vert"></div>
<div class="column">
<a href="" class="btn btn-primary">加一个评论</a>
</div>
</div>
<div class="panel-body">
<div id="book-docs" class="card">
<div class="card-header">
<div class="card-title h5">文档1</div>
<div class="card-subtitle">
<span>大小:</span>
<span>日期:</span>
<div class="float-right">
<button class="btn btn-primary">下载</button>
<button class="btn">删除</button>
</div>
</div>
<div class="panel-body">
<div class="divider text-center" data-content="文档"></div>
{% for document in documents %}
<div id="doc{{document['doc_id']}}" class="card">
<div class="card-header">
<div class="card-title h5">{{document['doc_name']}}</div>
<div class="card-subtitle">
<span><mark>大小</mark> {{document['doc_size']}} KB</span>
<span><mark>日期</mark>{{document['doc_date']}}</span>
<div class="float-right">
<a href="/doc/download/{{document['doc_id']}}/" class="btn btn-primary">下载</a>
<a href="/doc/delete/{{document['doc_id']}}/" class="btn">删除</a>
</div>
</div>
</div>
<div class="divider"></div>
<div id = "book-notes" class="card">
</div>
{% endfor %}
<div class="divider text-center" data-content="评论"></div>
<div id="book-notes" class="card">
<div class="card-header">
space
</div>
</div>
<div class="panel-footer">
Rendered @ {{cur_time}}
</div>
</div>
<div class="panel-footer">
Rendered @ {{cur_time}}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -45,7 +45,11 @@
</div>
<div class="panel-body">
<p>{{opresult}}</p>
{% if ret_url %}
<p><a href="{{ret_url}}">返回</a></p>
{% else %}
<p><a href="javascript:history.back(-1)">返回</a></p>
{% endif %}
</div>
<div class="panel-footer">
Rendered @ {{cur_time}}

View File

@ -1,10 +1,8 @@
from flask import (
Blueprint, flash, g, redirect, render_template, request, url_for
Blueprint, flash, g, redirect, render_template, request, url_for, send_file, current_app,
)
import re
from werkzeug.exceptions import abort
from werkzeug.security import generate_password_hash
import os
from src.auth import login_required
from src.db import get_db
import pymysql
@ -211,8 +209,10 @@ def book(id):
book = cur.fetchone()
cur.execute("select * from v_book_to_types where book_id=%s", (book['book_id'], ))
booktype = cur.fetchall()
cur.execute("select * from document where book_id=%s", (book['book_id'], ))
documents = cur.fetchall()
return render_template("/user/book.html",
book=book, booktype=booktype,
book=book, booktype=booktype, documents=documents,
cur_time=datetime.datetime.now())
@bp.route("/book/update/<int:id>/", methods=("GET", "POST"))
@ -292,4 +292,96 @@ def book_update(id):
booktypestr += k['type_name'] + ';'
return render_template("/user/updatebook.html",
book=bookinfo, booktype=booktypestr, typelist=typelist,
cur_time=datetime.datetime.now())
cur_time=datetime.datetime.now())
@bp.route("/doc/upload/<int:id>/", methods=("POST",))
@login_required
def doc_upload(id):
db = get_db()
cur = db.cursor()
assert(request.method=="POST")
fileobj = request.files['file']
error = None
if fileobj and fileobj.filename:
_, filename = os.path.split(fileobj.filename)
filepath = os.path.join(current_app.config['UPLOADDIR'], filename + f'.{int(datetime.datetime.timestamp(datetime.datetime.now()))}')
fileobj.save(filepath)
filesz = os.stat(filepath).st_size // 1024 # original in bytes
filetype = fileobj.mimetype
print(filetype)
print(filesz)
try:
cur.execute(
"insert into document (`doc_name`,`doc_url`,`doc_size`,`doc_type`,`book_id`,`user_id`)"
"values (%s,%s,%s,%s,%s,%s)",
(filename, filepath, filesz, filetype, id, g.user['user_id'])
)
db.commit()
except pymysql.Error as _e:
error = "未知错误 %s" % (_e)
db.rollback()
else:
error = "未收到有效的文件"
cur.close()
if error is not None:
return render_template("/user/result.html",
opname="上传文件失败", opresult=error,
cur_time=datetime.datetime.now())
return redirect(url_for("user.book", id=id))
@bp.route("/doc/download/<int:docid>/", methods=("GET",))
@login_required
def doc_download(docid):
db = get_db()
cur = db.cursor()
error = None
cur.execute("select * from document where doc_id=%s", (docid,))
document = cur.fetchone()
if document is None:
error = "文件不存在"
else:
docpath = os.path.join(os.getcwd(),document['doc_url'])
if os.path.exists(docpath):
return send_file(docpath, download_name=document['doc_name'], mimetype=document['doc_type'])
else:
error = "文件已被删除,严重的数据不一致,请联系管理员"
return render_template("/user/result.html",
opname="下载文件失败", opresult=error,
cur_time=datetime.datetime.now())
@bp.route("/doc/delete/<int:docid>/", methods=("GET",))
@login_required
def doc_delete(docid):
db = get_db()
cur = db.cursor()
error = None
warning = None
cur.execute("select * from document where doc_id=%s", (docid,))
document = cur.fetchone()
if document is None:
error = "文件不存在"
else:
docpath = os.path.join(os.getcwd(),document['doc_url'])
if os.path.exists(docpath):
os.remove(docpath)
else:
warning = "文件已经删除,但是数据库记录仍存在"
if error is None:
try:
cur.execute("delete from document where `doc_id`=%s", (docid))
db.commit()
except pymysql.Error as _e:
error = "严重错误:%s\n请联系管理员解决问题" % (_e)
cur.close()
if error is not None:
return render_template("/user/result.html",
opname="删除文件失败", opresult=error,
cur_time=datetime.datetime.now())
elif warning is not None:
return render_template("/user/result.html",
opname="删除文件出现了一些意外", opresult=warning,
cur_time=datetime.datetime.now(), ret_url=url_for("user.book", id=document['book_id']))
return redirect(url_for("user.book", id=document['book_id']))