main
This commit is contained in:
commit
a67625e48c
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
23
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
23
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="E303" />
|
||||||
|
<option value="E305" />
|
||||||
|
<option value="E302" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredIdentifiers">
|
||||||
|
<list>
|
||||||
|
<option value="kivy.uix.button.*" />
|
||||||
|
<option value="str.fromstring" />
|
||||||
|
<option value="sys._MEIPASS" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.12" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/py_文件api.iml" filepath="$PROJECT_DIR$/.idea/py_文件api.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/py_文件api.iml
generated
Normal file
8
.idea/py_文件api.iml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.12" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
66
file/file.py
Normal file
66
file/file.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_file_list(dir_path: str) -> None | list[dict[str, str | int | None | Any] | dict[str, str | int]] | list[
|
||||||
|
Any] | int:
|
||||||
|
"""
|
||||||
|
获取目录内容列表(包含文件/文件夹信息)
|
||||||
|
返回格式: [
|
||||||
|
{
|
||||||
|
'name': 名称,
|
||||||
|
'type': '<dir>'或'<file>',
|
||||||
|
'size': 文件大小(字节),文件夹为None,
|
||||||
|
'create_time': 创建时间
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if os.path.isfile(dir_path):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if not os.path.exists(dir_path):
|
||||||
|
raise FileNotFoundError(f"路径不存在: {dir_path}")
|
||||||
|
|
||||||
|
if not os.path.isdir(dir_path):
|
||||||
|
raise NotADirectoryError(f"不是有效目录: {dir_path}")
|
||||||
|
|
||||||
|
print(dir_path)
|
||||||
|
|
||||||
|
items = []
|
||||||
|
for item in os.listdir(dir_path):
|
||||||
|
full_path = os.path.join(dir_path, item)
|
||||||
|
stat = os.stat(full_path)
|
||||||
|
|
||||||
|
if os.path.isdir(full_path):
|
||||||
|
items.append({
|
||||||
|
'name': item,
|
||||||
|
'type': '<dir>',
|
||||||
|
'size': '-',
|
||||||
|
'create_time': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat.st_ctime))
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
items.append({
|
||||||
|
'name': item,
|
||||||
|
'type': '<file>',
|
||||||
|
'size': stat.st_size,
|
||||||
|
'create_time': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat.st_ctime))
|
||||||
|
})
|
||||||
|
|
||||||
|
return items if items else []
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"错误: {str(e)}")
|
||||||
|
return 2
|
||||||
|
|
||||||
|
"""
|
||||||
|
result = get_file_list("D:\\")
|
||||||
|
if result:
|
||||||
|
for item in result:
|
||||||
|
size = "-" if item['type'] == '<dir>' else f"{item['size']} bytes"
|
||||||
|
print(f"{item['type']:^6} | {item['name']:>30} | {size:>20} | {item['create_time']}")
|
||||||
|
|
||||||
|
"""
|
68
main.py
Normal file
68
main.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from flask import Flask, render_template, request, send_file, jsonify
|
||||||
|
import make_html
|
||||||
|
import return_api
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
root = "D:\\"
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def home():
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/web/<path:subpath>")
|
||||||
|
@app.route('/web')
|
||||||
|
@app.route('/web/')
|
||||||
|
def webs(subpath=None):
|
||||||
|
request_time = datetime.now()
|
||||||
|
formatted_time = request_time.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
if (subpath is None) or (subpath == "serviceworker.js"):
|
||||||
|
p = root
|
||||||
|
else:
|
||||||
|
if root[-1] == "\\" or "/":
|
||||||
|
p = root + subpath
|
||||||
|
else:
|
||||||
|
p = root + "\\" + subpath
|
||||||
|
|
||||||
|
request_url = request.path
|
||||||
|
return_p = make_html.make(p, request_url, formatted_time, subpath)
|
||||||
|
|
||||||
|
if return_p == 1:
|
||||||
|
return send_file(p, as_attachment=True)
|
||||||
|
if return_p == 2:
|
||||||
|
return render_template("error.html")
|
||||||
|
|
||||||
|
return return_p
|
||||||
|
|
||||||
|
@app.route("/api/<path:subpath>")
|
||||||
|
@app.route('/api')
|
||||||
|
@app.route('/api/')
|
||||||
|
def api(subpath=None):
|
||||||
|
request_time = datetime.now()
|
||||||
|
formatted_time = request_time.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
|
||||||
|
if (subpath is None) or (subpath == "serviceworker.js"):
|
||||||
|
p = root
|
||||||
|
else:
|
||||||
|
if root[-1] == "\\":
|
||||||
|
p = root + subpath
|
||||||
|
else:
|
||||||
|
p = root + "\\" + subpath
|
||||||
|
|
||||||
|
request_url = request.path
|
||||||
|
return_p = return_api.make(p, request_url, formatted_time, subpath)
|
||||||
|
|
||||||
|
if return_p == 1:
|
||||||
|
return send_file(p)
|
||||||
|
if return_p == 2:
|
||||||
|
return render_template("error.html")
|
||||||
|
|
||||||
|
return jsonify(return_p)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True, port=41040)
|
71
make_html.py
Normal file
71
make_html.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
|
from file import file
|
||||||
|
|
||||||
|
# 创建模板环境
|
||||||
|
env = Environment(
|
||||||
|
loader=FileSystemLoader("templates"), # 模板目录
|
||||||
|
autoescape=True, # 自动HTML转义
|
||||||
|
trim_blocks=True, # 去除块首尾空白
|
||||||
|
lstrip_blocks=True # 去除块左侧空白
|
||||||
|
)
|
||||||
|
|
||||||
|
def make_file(file_list, requests_url):
|
||||||
|
c = []
|
||||||
|
d = 0
|
||||||
|
for item in file_list:
|
||||||
|
name = item["name"]
|
||||||
|
name = f'<a href="{requests_url}/{name}">{name}</a>'
|
||||||
|
|
||||||
|
if item['type'] == "<file>":
|
||||||
|
types = " "
|
||||||
|
else:
|
||||||
|
types = "dir"
|
||||||
|
|
||||||
|
size = item['size']
|
||||||
|
|
||||||
|
if d == 0 or d % 2 == 0:
|
||||||
|
a = '<tr style="background: #D0D0D0"><td>' + types + "</td><td>" + name +"</td><td>"+ str(size) + "</td><td>" + item['create_time'] + "</td></tr>"
|
||||||
|
else:
|
||||||
|
a = '<tr><td>' + types + "</td><td>" + name +"</td><td>"+ str(size) + "</td><td>" + item['create_time'] + "</td></tr>"
|
||||||
|
c.append(a)
|
||||||
|
d += 1
|
||||||
|
|
||||||
|
b = "".join(c)
|
||||||
|
return b
|
||||||
|
|
||||||
|
|
||||||
|
def make(p, url, time, server_p):
|
||||||
|
get_p = file.get_file_list(p)
|
||||||
|
|
||||||
|
if get_p == 1:
|
||||||
|
return 1
|
||||||
|
if get_p == 2:
|
||||||
|
return 2
|
||||||
|
|
||||||
|
if server_p is None:
|
||||||
|
server_p = "root\\"
|
||||||
|
else:
|
||||||
|
server_p = "root/ " + server_p
|
||||||
|
|
||||||
|
with open('templates\\zh_ch_moban.html', 'r', encoding='utf-8') as files:
|
||||||
|
template = files.read()
|
||||||
|
|
||||||
|
files = make_file(get_p, url)
|
||||||
|
|
||||||
|
# 定义替换数据
|
||||||
|
data = {
|
||||||
|
"{h3}": "当前路径: "+url,
|
||||||
|
"{time}": "请求开始时间: "+time,
|
||||||
|
"{file_var}": "文件(夹)数量: " + str(len(get_p)),
|
||||||
|
"{server_path}": "服务器内部路径: " + server_p,
|
||||||
|
"{file}": files
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行替换
|
||||||
|
modified_html = template
|
||||||
|
for placeholder, value in data.items():
|
||||||
|
modified_html = modified_html.replace(placeholder, value)
|
||||||
|
|
||||||
|
# 输出结果
|
||||||
|
return modified_html
|
26
return_api.py
Normal file
26
return_api.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from file import file
|
||||||
|
|
||||||
|
|
||||||
|
def make(path, requests_url, time, server_p):
|
||||||
|
get_p = file.get_file_list(path)
|
||||||
|
|
||||||
|
if get_p == 1:
|
||||||
|
return 1
|
||||||
|
if get_p == 2:
|
||||||
|
return 2
|
||||||
|
|
||||||
|
if server_p is None:
|
||||||
|
server_p = "root\\"
|
||||||
|
else:
|
||||||
|
server_p = "root/ " + server_p
|
||||||
|
|
||||||
|
b = {
|
||||||
|
"time": time,
|
||||||
|
"server_path": server_p,
|
||||||
|
"requests_url": requests_url,
|
||||||
|
"file": get_p
|
||||||
|
}
|
||||||
|
|
||||||
|
return b
|
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 264 KiB |
33
templates/error.html
Normal file
33
templates/error.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>
|
||||||
|
<title>500 - 服务器内部错误</title>
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
|
||||||
|
fieldset{padding:0 15px 10px 15px;}
|
||||||
|
h1{font-size:2.4em;margin:0;color:#FFF;}
|
||||||
|
h2{font-size:1.7em;margin:0;color:#CC0000;}
|
||||||
|
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
|
||||||
|
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
|
||||||
|
background-color:#555555;}
|
||||||
|
#content{margin:0 0 0 2%;position:relative;}
|
||||||
|
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header"><h1>服务器错误</h1></div>
|
||||||
|
<div id="content">
|
||||||
|
<div class="content-container"><fieldset>
|
||||||
|
<h2>500 - 服务器内部错误,请求无法完成</h2>
|
||||||
|
<h3>出现此页面,代表本服务器软件正常运行,但因为其他因素导致了错误。</h3>
|
||||||
|
<p>常见的错误包括:</p>
|
||||||
|
<p> 服务器软件没有访问目标目录的权限</p>
|
||||||
|
<p> 访问目标目录时操作系统返回了非期望的内容(可能是文件被锁定,目录不可达等)</p>
|
||||||
|
</fieldset></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
22
templates/index.html
Normal file
22
templates/index.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh_CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
|
||||||
|
<title>File api 主页</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<center>
|
||||||
|
<h1>File API 主页</h1>
|
||||||
|
</center>
|
||||||
|
<hr>
|
||||||
|
<p>  这是本系统的基础页面,包含以下两个可用的请求方式:</p>
|
||||||
|
<br>
|
||||||
|
<p>  web 目录浏览:<a href="web">web</a></p>
|
||||||
|
<p>  api 请求: <a href="api">api</a> </p>
|
||||||
|
<hr>
|
||||||
|
<center>
|
||||||
|
<p> by Da_nuo & branulf | 2025
|
||||||
|
</center>
|
||||||
|
</body>
|
||||||
|
</html>
|
59
templates/zh_ch_moban.html
Normal file
59
templates/zh_ch_moban.html
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh_CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>web 目录浏览</title>
|
||||||
|
<style>
|
||||||
|
.mono-table {
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
white-space: pre;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mono-table td {
|
||||||
|
padding: 0 0.5em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h3>{h3}</h3>
|
||||||
|
<hr>
|
||||||
|
<p>{time}</p> <!-- 开始时间 -->
|
||||||
|
<p>{file_var}</p> <!-- 文件,夹数量 -->
|
||||||
|
<p>{server_path}</p> <!-- 服务器内部路径 -->
|
||||||
|
<a href="#" id="backLink" class="back-link">返回上一级目录</a>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('backLink').addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let currentPath = window.location.pathname;
|
||||||
|
currentPath = currentPath.replace(/\/$/, '');
|
||||||
|
let pathParts = currentPath.split('/');
|
||||||
|
pathParts.pop();
|
||||||
|
let parentPath = pathParts.join('/');
|
||||||
|
if (parentPath === '') parentPath = '/';
|
||||||
|
window.location.href = window.location.origin + parentPath;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<hr>
|
||||||
|
<table class="mono-table">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 6cn">type</td>
|
||||||
|
<td style="width: 60cn">name</td>
|
||||||
|
<td style="width: 30cn">size</td>
|
||||||
|
<td style="width: 30cn">time</td>
|
||||||
|
</tr>
|
||||||
|
<tr></tr>
|
||||||
|
{file}
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p align="center">Powered by Da_nuo & Branulf</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user