私有云盘 Nextcloud在线解压开发
缘由:
问:为啥百度网盘会员人家可以在线解压哇???
我:what?那必须安排哇!!!
- python代码如下
from flask import Flask, request, jsonify, abort
from flask_cors import CORS
import sys
import os
import zipfile
import hashlib
import subprocess
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
app = Flask(__name__)
#跨域,允许所有
CORS(app)
def Shell_cmd():
xhel = "chown -R 33.tape /home/nextcloud/data/admin/files" #nextcloud文件目录赋权限
Cmd_run = subprocess.run(xhel,shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode("utf-8")
return Cmd_run
def extract_zip_filename(file_path):
file_name = os.path.basename(file_path) # 获取文件名,包含扩展名
if file_name.endswith('.zip'):
zip_name = file_name[:-4] # 去掉末尾的'.zip'扩展名
return zip_name
else:
return None # 如果文件不是.zip文件,返回None或者适当的错误信息
def unzip_file(file_path, extract_path):
try:
with zipfile.ZipFile(file_path, 'r') as zip_ref:
for member in zip_ref.infolist():
member.filename = member.filename.encode('cp437').decode('gbk')
zip_ref.extract(member, extract_path)
except:
print("111")
def main(zip_file_path):
try:
folder_name = os.path.splitext(os.path.basename(zip_file_path))[0]
extract_path = os.path.join(os.path.dirname(zip_file_path), folder_name)
unzip_file(zip_file_path, extract_path)
except:
print(222)
def find_zip_files(directory):
result = {} # 存储结果的字典
for root, dirs, files in os.walk(directory):
for folder in dirs: # 遍历所有文件夹
folder_path = os.path.join(root, folder)
zip_files = [] # 存储该文件夹内的zip文件路径
for file in os.listdir(folder_path): # 遍历文件夹内的文件
file_path = os.path.join(folder_path, file)
if file.endswith('.zip'): # 判断是否为zip文件
zip_files.append(file_path)
if zip_files: # 如果文件夹内有zip文件,则将其添加到结果字典中
result[folder] = zip_files
return result
@app.route('/unzip', methods=['POST'])
def unzip():
# 获取 POST 请求的 json 数据
data = request.get_json()
mulu_name = data.get('mulu')
path_name = data.get('path')
Authentication = data.get('authentication')
print(data)
if mulu_name is not None and path_name is not None:
if Authentication == "7a1b805e3ffd55luozi":
zip_file_path = f"{path_name}"
main(zip_file_path)
file_path = extract_zip_filename(zip_file_path)
Shell_cmd()
return jsonify(file_path)
@app.route('/update', methods=['POST'])
def update():
# 获取 POST 请求的 json 数据
data = request.get_json()
Authentication = data.get('authentication')
if Authentication == "705e3ffd55luozi":
directory = '/home/nextcloud/data/admin/files/' # 替换为你的目标路径
result_dict = find_zip_files(directory)
return jsonify(result_dict)
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0',port=6080)
- html 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Nextcloud 解压</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
h1 {
text-align: center;
margin-top: 50px;
font-size: 36px;
font-weight: bold;
}
form {
width: 80%;
max-width: 600px;
margin: 50px auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #fff;
/* background-color: #f4f4f4; */
border-radius: 10px;
padding: 30px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
label {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
select {
width: 100%;
height: 40px;
border-radius: 5px;
background-color: #f4f4f4;
border: none;
outline: none;
font-size: 16px;
margin-bottom: 20px;
}
button {
width: 180px;
height: 50px;
font-size: 18px;
font-weight: bold;
background-color: #007aff;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: all 0.2s ease-in-out;
box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.1), 0px 4px 10px rgba(0, 0, 0, 0.05);
}
button:hover {
background-color: #0065cc;
}
.combobox-container {
position: relative;
width: 100%;
height: 40px;
border-radius: 5px;
background-color: #f4f4f4;
border: none;
outline: none;
font-size: 16px;
margin-bottom: 20px;
}
.combobox-input {
width: 100%;
height: 40px;
border-radius: 5px;
padding: 0.375rem 0.75rem;
background-color: #f4f4f4;
font-size: 1rem;
border: 1px solid #f4f4f4;
border-radius: 0.25rem;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.combobox-options {
display: none;
position: absolute;
top: calc(100% + 1px);
left: 0;
z-index: 9999;
width: 100%;
max-height: 200px;
overflow: auto;
background-color: #f4f4f4;
border: 1px solid #f4f4f4;
border-top: none;
border-bottom-right-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
}
.combobox-options div {
padding: 0.375rem 0.75rem;
cursor: pointer;
}
.combobox-options div:hover {
background-color: #f4f4f4;
}
/* 历史日志 */
#text-box {
position: fixed;
top: 10%;
height: 50%;
right: 0.5%;
padding: 10px;
background-color: #f4f4f4;
box-shadow: 0 0 5px #231f47;
}
/* #text-box textarea {
width: 100%;
height: 100%;
background-color: #f4f4f4;
border: none;
resize: none;
} */
</style>
<script src="cdn.bootcdn.net_ajax_libs_jquery_3.6.0_jquery.min.js"></script>
</head>
<body>
<h1>Nextcloud 解压</h1>
<!-- <select id="parentSelect" οnchange="updateChildOptions()">
<option value="">请选择父框</option>
</select> -->
<!-- <select id="childSelect">
<option value="">请选择子框</option>
</select> -->
<form>
<label for="project">文件夹:</label>
<select id="parentSelect" class="combobox-container" onchange="updateChildOptions()">
<option value="">文件夹</option>
</select>
<label for="environment">ZIP包名:</label>
<select id="childSelect" class="combobox-container">
<option value="">ZIP包名:</option>
</select>
<div style="width:100%; display:flex; justify-content: center;">
<!-- 调用deploy()函数 -->
<button type="button" onclick="deploy()">确认</button>
</div>
<p rows="10" cols="50" readonly style="margin-left:30px;width: 400px; height: 95%; " >
解压完毕,需要在你的zip包路径下,创建一个相同的文件夹名字(及完成之后提示的名字)
</p>
</form>
<script>
// 更新父框选项
function updateParentOptions(data) {
var parentSelect = document.getElementById('parentSelect');
for (var key in data) {
if (data.hasOwnProperty(key)) {
var option = document.createElement('option');
option.value = key;
option.text = key;
parentSelect.appendChild(option);
}
}
}
// 更新子框选项
function updateChildOptions() {
var parentSelect = document.getElementById('parentSelect');
var childSelect = document.getElementById('childSelect');
var selectedParent = parentSelect.value;
childSelect.innerHTML = ''; // 清空子框选项
if (selectedParent && data.hasOwnProperty(selectedParent)) {
var childOptions = data[selectedParent];
for (var i = 0; i < childOptions.length; i++) {
var option = document.createElement('option');
option.value = childOptions[i];
option.text = childOptions[i];
childSelect.appendChild(option);
}
}
}
// 发布
function deploy() {
alert('处理中......');
var project = $('#parentSelect').val();
var environment = $('#childSelect').val();
if (project == '') {
alert('请选择要目录');
return;
}
if (environment == '') {
alert('请选择zip包名');
return;
}
const data = {
mulu: project,
path: environment,
authentication: "7a87edec6bfbba4a1b805e3ffd55luozi"
};
$.ajax({
type: 'POST',
url: 'https://www.test.com:66/pi/unzip',
contentType: 'application/json',
data: JSON.stringify(data),
xhrFields: {
withCredentials: true
},
rejectUnauthorized: false,
success: function(data_res) {
var data = data_res
console.log(data)
alert('解压成功请创建目录:' + data);
},
error: function(xhr, status, error) {
if (xhr.status === 403) {
alert('参数错误');
} else if (xhr.status === 401) {
alert('镜像同步失败');
} else {
alert('解压失败');
}
}
});
}
// 发送Ajax请求
function update() {
// alert('处理中......');
const data2 = {
authentication: "7a87edec6bfbba4a1b805e3ffd55luozi"
};
$.ajax({
type: 'POST',
url: 'https://www.test.com:66/update',
contentType: 'application/json',
data: JSON.stringify(data2),
xhrFields: {
withCredentials: true
},
rejectUnauthorized: false,
success: function(responseData) {
// alert('更新成功');dd
var data = responseData; // 将返回的JSON字符串解析为JavaScript对象
// 使用responseData进行进一步操作,例如读取其中的键值对
updateParentOptions(data);
window.data = data;
console.log(data.key1);
console.log(data.key2);
},
error: function(xhr, status, error) {
if (xhr.status === 403) {
alert('参数错误');
} else if (xhr.status === 400) {
alert('写文件失败');
} else {
alert('更新失败');
}
}
});
}
update(); // 发送ajax请求
</script>
</body>
</html>
- nignx配置
...
location /api/ {
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Referer "https://192.168.2.200";
proxy_pass http://192.168.2.200:6080/;
}
...
location /unzip/ {
index index.html index.htm;
alias /data/unzip/;
}
...
- 效果展示