Browse Source

feat: 文件夹的上传与下载

master
欧醚 3 years ago
parent
commit
3078900609
2 changed files with 51 additions and 19 deletions
  1. +24
    -14
      app.py
  2. +27
    -5
      templates/list.html

+ 24
- 14
app.py View File

@ -19,7 +19,7 @@ from mastodon import Mastodon
from datetime import date, datetime from datetime import date, datetime
from functools import wraps from functools import wraps
import hashlib import hashlib
from zipfile import ZipFile
import shutil
import random import random
import os import os
import re import re
@ -204,15 +204,17 @@ def upload(username):
abort(422) abort(422)
files = request.files.getlist('files[]') files = request.files.getlist('files[]')
print(files)
dir_name = username + str(datetime.now()) dir_name = username + str(datetime.now())
base_path = os.path.join('/tmp', dir_name) base_path = os.path.join('/tmp', dir_name)
os.mkdir(base_path) os.mkdir(base_path)
for f in files: for f in files:
filename = f.filename.replace('/','_')
filename = f.filename.replace('..','__')
os.makedirs(os.path.dirname(os.path.join(base_path, filename)), exist_ok=True)
f.save(os.path.join(base_path, filename)) f.save(os.path.join(base_path, filename))
res = ipfs_client.add(base_path)
res = ipfs_client.add(base_path, recursive=True)
file_hash = '' file_hash = ''
for r in res: for r in res:
if r.get('Name') == dir_name: if r.get('Name') == dir_name:
@ -250,17 +252,25 @@ def download(pid, username):
p.down_num += 1 p.down_num += 1
db.session.commit() db.session.commit()
if request.args.get('type') == 'zip':
target_file = '/tmp/%s.zip' % pid
if not os.path.exists(target_file):
ipfs_client.get(p.file_hash, target='/tmp')
with ZipFile(target_file, 'w') as z:
for fname in os.listdir(os.path.join('/tmp', p.file_hash)):
z.write(os.path.join('/tmp', p.file_hash, fname), fname)
filename = re.sub('[^\w@_()()-]', '_', '%s_%s_共享计划_%d' %(p.course, p.teacher, p.id)) + '.zip'
return send_file(target_file, as_attachment=True, attachment_filename=filename)
dformat = request.args.get('format')
suff = {
'zip': '.zip',
'tar': '.tar',
'gztar': '.tar.gz'
}
if dformat in suff:
target_file = '/tmp/%s' % pid
target_filename = target_file + suff[dformat]
target_dir = os.path.join('/tmp', p.file_hash)
if not os.path.exists(target_filename):
if not os.path.exists(target_dir):
ipfs_client.get(p.file_hash, target='/tmp')
shutil.make_archive(target_file, dformat, target_dir)
filename = re.sub('[^\w@_()()-]', '_', '%s_%s_共享计划_%d' %(p.course, p.teacher, p.id)) + suff[dformat]
return send_file(target_filename, as_attachment=True, attachment_filename=filename)
return redirect(C.ipfs_base_url + p.file_hash, code=301) # 301减少不必要的请求 return redirect(C.ipfs_base_url + p.file_hash, code=301) # 301减少不必要的请求

+ 27
- 5
templates/list.html View File

@ -229,6 +229,10 @@
.wechat-share img { .wechat-share img {
width: 196px; width: 196px;
} }
.custom-file-label {
overflow: hidden;
}
</style> </style>
</head> </head>
@ -296,6 +300,10 @@
<input type="file" class="custom-file-input" name="files[]" multiple required> <input type="file" class="custom-file-input" name="files[]" multiple required>
<label class="custom-file-label" for="customFile" data-browse="浏览">选择文件,可以多选</label> <label class="custom-file-label" for="customFile" data-browse="浏览">选择文件,可以多选</label>
</div> </div>
<div class="custom-control custom-switch mb-2 mt-3 ml-1">
<input type="checkbox" class="custom-control-input" id="upload-dir" name="upload-dir">
<label class="custom-control-label" for="upload-dir">上传文件夹</label>
</div>
<div class="custom-control custom-switch mb-2 mt-3 ml-1"> <div class="custom-control custom-switch mb-2 mt-3 ml-1">
<input type="checkbox" class="custom-control-input" id="anon" name="anon"> <input type="checkbox" class="custom-control-input" id="anon" name="anon">
<label class="custom-control-label" for="anon">匿名发布</label> <label class="custom-control-label" for="anon">匿名发布</label>
@ -313,7 +321,7 @@
<button class="mask" onclick="alert('目前guest无权限上传')"></button> <button class="mask" onclick="alert('目前guest无权限上传')"></button>
{% endif %} {% endif %}
<div style="font-size:80%;">
<div style="font-size:80%;margin-bottom:70px">
<ul> <ul>
<li> <li>
如果觉得提交太麻烦,也可将资料发给 如果觉得提交太麻烦,也可将资料发给
@ -440,9 +448,9 @@
<span class="sr-only">Toggle Dropdown</span> <span class="sr-only">Toggle Dropdown</span>
</button> </button>
<div class="dropdown-menu" style="min-width: 5rem"> <div class="dropdown-menu" style="min-width: 5rem">
<a class="dropdown-item" href="{{p.id}}/download?type=zip" target="_blank" id="download-zip-{{p.id}}">
<span class="num-info">打包下载</span>
</a>
<a class="dropdown-item" href="{{p.id}}/download?format=zip" target="_blank"><span class="num-info">打包下载 - zip</span></a>
class="p"><a class="dropdown-item" href="{{p.id}}/download?format=tar" target="_blank"><span class="num-info">打包下载 - tar</span></a>
<a class="dropdown-item" href="{{p.id}}/download?format=gztar" target="_blank"><span class="num-info">打包下载 - gzip</span></a>
</div> </div>
</span> </span>
</div> </div>
@ -503,7 +511,21 @@
} }
$(document).ready(function () { $(document).ready(function () {
bsCustomFileInput.init()
bsCustomFileInput.init();
$("#upload-dir").change(function() {
var fi = $('.custom-file-input');
var fl = $('.custom-file-label');
console.log(fi);
if(this.checked) {
fi.attr('webkitdirectory', true);
fl.text('选择文件夹,可以多选');
}
else {
fi.removeAttr('webkitdirectory');
fl.text('选择文件,可以多选');
}
});
$('[data-toggle="popover"]').popover({ $('[data-toggle="popover"]').popover({
html: true, html: true,
placement: "top", placement: "top",

Loading…
Cancel
Save