上传2025_04_29备份作为记录

This commit is contained in:
2026-04-24 22:11:13 +08:00
parent abdf1b4258
commit 695b5af8fa
64 changed files with 418 additions and 1446 deletions

21
.gitignore vendored
View File

@@ -1,21 +0,0 @@
# python/cache
**/__pycache__
**/venv/*
**/.venv/*
# databases
**/*.db
**/*.sql
**/*.db.back
databases/*
# flask folder
mirrors/*
blueprint/kami_views.py
blueprint/massage_views.py
templates/kami/*
templates/message/*
static/upload/*
static/counter.txt
static/message/*
static/test/*

0
LICENSE Executable file → Normal file
View File

27
README.md Executable file → Normal file
View File

@@ -1,34 +1,13 @@
<a href="https://ww3.tw/">点击访问</a>
## 2025.12.23
迁移后端至python
现已完毕
--
# 感谢列表:
- 感谢bilibili麦叔的教程视频
- 感谢互联网
- 感谢自己
**署名**
<a href="https://wiki.ww3.tw/doku.php?id=zh_cn:skimrme">skimrme</a>
<hr>
#
#
## 2025.7.20
open-ww3-project-ww3-tw
个人博客地址(预计)
---
# 感谢列表:
- 感谢谷歌Genmini的指导
- 感谢互联网
- 感谢自己
<br>
**署名**
<a href="https://wiki.ww3.tw/doku.php?id=zh_cn:skimrme">skimrme</a>
skimrme

View File

@@ -1,41 +0,0 @@
from flask import Blueprint
import json
import sqlite3
api_api = Blueprint('/api/', __name__)
json_title = {'Content-Type': 'application/json'} # 设定json的类型
# 引入数据库
def get_owp_db_conn():
conn = sqlite3.connect('/var/open-ww3-project-ww3-tw/databases/sqlite/owp.db')
conn.row_factory = sqlite3.Row
return conn
# 获取日志内容
@api_api.get("/get/logs/")
def get_logs():
# 获取并查询数据库日志内容
conn = get_owp_db_conn()
sql_logs = "SELECT * FROM logs;"
logs = conn.execute(sql_logs).fetchall()
conn.close()
data_logs = [
dict(row) for row in logs
]
return (json.dumps(data_logs, ensure_ascii=False), json_title)
@api_api.get("/get/posts/")
def get_posts():
# 获取并查询数据库日志内容
conn = get_owp_db_conn()
sql_posts = "SELECT * FROM posts WHERE status=1;"
posts = conn.execute(sql_posts).fetchall()
conn.close()
data_posts = [
dict(row) for row in posts
]
return (json.dumps(data_posts, ensure_ascii=False), json_title)

View File

@@ -1,7 +0,0 @@
from flask import Blueprint
docs_api = Blueprint('/api/docs', __name__)
@docs_api.get("/")
def home():
return "123"

View File

@@ -1,205 +0,0 @@
from flask import Blueprint, render_template, request, url_for, flash, redirect, send_from_directory, make_response, current_app
from database import get_owp_db
from flask_autoindex import AutoIndex
from werkzeug.utils import secure_filename
from datetime import datetime
import os
import sqlite3
import time
import json
import shutil
def get_owp_db_conn():
conn = sqlite3.connect('/var/open-ww3-project-ww3-tw/databases/sqlite/owp.db')
conn.row_factory = sqlite3.Row
return conn
def get_message_db_conn():
conn = sqlite3.connect('/var/open-ww3-project-ww3-tw/databases/sqlite/message.db')
conn.row_factory = sqlite3.Row
return conn
blog_bp = Blueprint('blog', __name__)
index_path = '/var/open-ww3-project-ww3-tw/mirrors/'
index = AutoIndex(blog_bp, browse_root=index_path, add_url_rules=False)
# 重定向
@blog_bp.route('/mirrors/re/')
def re():
return('404 not found<br><a style="color: white;">这是你不该知道的地方</a><br><iframe src="//player.bilibili.com/player.html?isOutside=true&aid=115578442356850&bvid=BV12CCdBkEL6&cid=34120008494&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width: 100%; height: 100%;"></iframe>')
@blog_bp.route('/mirrors/paint/2024.2.13/临摹出来的乐色/不好说的人物/')
@blog_bp.route('/mirrors/paint/2024.2.13/临摹出来的乐色/不好说的人物/<path:subpath>')
def no_say_man(subpath=None):
return redirect(url_for('blog.re'))
@blog_bp.route('/mirrors/game/')
@blog_bp.route('/mirrors/game/<path:subpath>')
def no_game(subpath=None):
return redirect(url_for('blog.re'))
# 重定向
@blog_bp.route('/')
def home():
db = get_owp_db()
conn = get_owp_db_conn()
sql_logs = "SELECT * from logs;"
sql_posts = "SELECT * from posts where status= 1;"
logs = conn.execute(sql_logs).fetchall()
posts = conn.execute(sql_posts).fetchall()
conn.close()
count_file = '/var/open-ww3-project-ww3-tw/static/counter.txt'
def load_couter():
if os.path.exists(count_file):
with open(count_file, 'r') as f:
return int(f.read().strip())
return 0
def save_couter(couter):
with open(count_file, 'w') as f:
f.write(str(couter))
counter = load_couter()
counter += 1
save_couter(counter)
return render_template('blog/home.html', logs=logs[::-1], posts=posts[::-1], counter=counter)
@blog_bp.route('/about/')
def about():
return render_template('blog/about.html')
pass
@blog_bp.route('/posts/')
def posts_list():
conn = get_owp_db_conn()
sql_posts = "SELECT * from posts where status= 1;"
posts = conn.execute(sql_posts).fetchall()
conn.close()
return render_template('blog/list.html', posts=posts[::-1])
@blog_bp.route('/posts/<int:posts_id>/')
def show_posts_id(posts_id):
message_path = f"/var/open-ww3-project-ww3-tw/static/message/{posts_id}"
if not os.path.exists(message_path):
os.makedirs(message_path)
message_json = f"{message_path}/chat.json"
if not os.path.exists(message_json):
with open(message_json, 'w', encoding='utf-8') as file:
json.dump([], file, ensure_ascii=False)
message_ss = json.load(open(message_json, 'r', encoding='utf-8'))
conn = get_owp_db_conn()
conn_message = get_message_db_conn()
sql_posts = "SELECT * FROM posts WHERE status = 1 AND id = ?"
posts = conn.execute(sql_posts, (posts_id,)).fetchone()
sql_message = "SELECT * FROM messages WHERE posts_id = ?"
message = conn_message.execute(sql_message, (posts_id,)).fetchall()
conn.close()
conn_message.close()
if posts is None:
shutil.rmtree(message_path)
return f'未找到该文章{posts_id}<title>未找到该文章{posts_id}/</title>', 404
return render_template('blog/posts.html', posts=posts, message=message[::-1], message_ss=message_ss[::-1])
# posts 留言
@blog_bp.route('/posts/<int:posts_id>/chat/', methods=['POST', 'GET'])
def posts_chat(posts_id):
message_path = f"/var/open-ww3-project-ww3-tw/static/message/{posts_id}/chat.json"
if request.method == "POST":
name = request.form.get("name", None)
data = request.form.get("data", None)
date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
json_push = {
"name": name,
"data": data,
"date": date
}
with open(message_path, 'r', encoding='utf-8') as f:
old_date_data = json.load(f)
old_date_data.append(json_push)
with open(message_path, 'w', encoding='utf-8') as f:
json.dump(old_date_data, f, ensure_ascii=False, indent=4)
return "留言成功<br><a href='../'>返回文章</a>"
return "GET"
# 数据库测试
@blog_bp.route('/db_test/')
def test_db():
db = get_owp_db()
try:
cur = db.execute('SELECT sqlite_version();')
ver = cur.fetchone()[0]
return f"数据库连接成功SQLite 版本是: {ver}"
except Exception as e:
return f"连接失败: {str(e)}"
######
## 网站地图 及其 robots 配置
@blog_bp.route('/robots.txt/')
def robots():
return send_from_directory(current_app.static_folder, 'robots.txt')
@blog_bp.route('/google02f6a3f6004a32c6.html')
def google02f6a3f6004a32c6():
return send_from_directory(blog_bp.static_folder, 'google02f6a3f6004a32c6.html')
@blog_bp.route('/sitemap.xml/')
def sitemap():
conn = get_owp_db_conn()
sql_posts = "SELECT * from posts where status = 1;"
posts = conn.execute(sql_posts).fetchall()
conn.close()
template = render_template('blog/sitemap.xml', posts=posts[::-1], base_url="https://open-ww3-project.ww3.tw/blog/")
response = make_response(template)
response.headers['Content-Type'] = 'application/xml'
return response
@blog_bp.route('/kami/')
def kami():
return redirect(url_for('kami.home'))
@blog_bp.route('/mirrors/')
@blog_bp.route('/mirrors/<path:path>')
def autoindex(path='.'):
return index.render_autoindex(path, template='blog/mirrors.html')
@blog_bp.route('/upload/', methods=['POST' , 'GET'])
def upload():
if request.method == "POST":
f = request.files.get('img')
filename = f.filename
with open(f'/var/open-ww3-project-ww3-tw/static/upload/img/{filename}', 'wb') as tf:
tf.write(f.read())
return '上传成功<meta http-equiv="refresh" content="1.2;url=https://ww3.tw/blog/upload/">'
img_files = '/var/open-ww3-project-ww3-tw/static/upload/img/'
images = [img for img in os.listdir(img_files) if img.endswith(('.png', '.jpg', '.jpeg', '.gif'))]
return render_template('blog/upload.html', images=images)
@blog_bp.route('/message/')
def messages():
return render_template('message/home.html')
@blog_bp.route('/paint/')
def paint():
paint_path = "/var/open-ww3-project-ww3-tw/static/upload/paint_data"
paint_json = f"{paint_path}/paint.json"
paint_open = json.load(open(paint_json, 'r', encoding='utf-8'))
return render_template('blog/paint.html', paint_open=paint_open)
@blog_bp.route('/paint/upload/', methods=['POST',])
def paint_upload():
if request.method == "POST":
return "POST"
@blog_bp.route('/new_page/')
@blog_bp.route('/new_page/<page_name>/')
def new_page(page_name=None):
return send_from_directory(os.path.join(current_app.static_folder, 'new_page'), f'{page_name}.html')

View File

@@ -1,17 +0,0 @@
from flask import Blueprint, render_template, url_for, redirect
import sqlite3
import os
index_bp = Blueprint('/', __name__)
@index_bp.route('/')
def repage():
return redirect(url_for('blog.home'))
@index_bp.route('/mirrors/')
def mirrors():
return redirect(url_for('blog.autoindex'))
@index_bp.route('/greet/<name>/')
def greet(name):
return f'Hello, {name}!'

View File

@@ -1,96 +0,0 @@
from flask import Blueprint, render_template, request, url_for, flash, redirect
import os
import sqlite3
study_bp = Blueprint('study', __name__)
def get_db_conn():
conn = sqlite3.connect('/var/open-ww3-project-ww3-tw/databases/database.db')
conn.row_factory = sqlite3.Row
return conn
def get_posts(posts_id):
conn = get_db_conn()
posts = conn.execute("SELECT *, datetime(created, '+8 hours') AS created_8 FROM posts WHERE id = ?", (posts_id,)).fetchone()
conn.close()
return posts
@study_bp.route('/')
def home():
conn = get_db_conn()
sql = "SELECT *, datetime(created, '+8 hours') AS created_8 FROM posts;"
posts = conn.execute(sql).fetchall()
conn.close()
return render_template('study/home.html', posts=posts[::-1])
@study_bp.route('/about/')
def about():
return render_template('study/about.html')
@study_bp.route('/posts/<int:posts_id>')
def show_posts_id(posts_id):
conn = get_db_conn()
posts = get_posts(posts_id)
if posts is None:
return '抱歉,未查到该文章'
return render_template('study/posts.html', posts=posts)
@study_bp.route('/posts/new/', methods=('GET', 'POST'))
def new():
if request.method == "POST":
title = request.form['title']
content = request.form['content']
if not title:
flash('标题不能为空')
elif not content:
flash('内容不能为空')
else:
conn = get_db_conn()
conn.execute('insert into posts (title, content) values (?, ?)', (title, content))
conn.commit()
conn.close()
flash('文章发布成功')
return redirect(url_for('study.home'))
return render_template('study/new.html')
@study_bp.route('/posts/<int:posts_id>/edit', methods=('GET', 'POST'))
def edit_posts_id(posts_id):
posts = get_posts(posts_id)
if request.method == "POST":
title = request.form['title']
content = request.form['content']
if not title:
flash('标题不能为空')
elif not content:
flash('内容不能为空')
else:
conn = get_db_conn()
conn.execute('update posts set title= ?, content = ? where id = ?', (title, content, posts_id))
conn.commit()
conn.close()
return redirect(url_for('study.home'))
return render_template('study/edit.html', posts=posts)
@study_bp.route('/posts/<int:posts_id>/delete/', methods=['POST' , 'GET'])
def delete_posts_id(posts_id):
if request.method == "POST":
posts = get_posts(posts_id)
conn = get_db_conn()
conn.execute('DELETE FROM posts WHERE id = ?', (posts_id,))
conn.commit()
conn.close()
flash('删除成功')
return redirect(url_for('study.home'))
elif request.method == "GET":
posts = get_posts(posts_id)
conn = get_db_conn()
conn.execute('DELETE FROM posts WHERE id = ?', (posts_id,))
conn.commit()
conn.close()
return render_template('study/delete.html', posts=posts)

View File

@@ -1,11 +0,0 @@
import sqlite3
from flask import g
DATABASE_owp = '/var/open-ww3-project-ww3-tw/databases/sqlite/owp.db'
def get_owp_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(DATABASE_owp)
db.row_factory = sqlite3.Row
return db

110
main.py
View File

@@ -1,110 +0,0 @@
from flask import Flask, render_template, redirect, url_for, send_from_directory, make_response, g
import os
import sqlite3
import secrets
# 引入蓝图
from blueprint.blog_views import blog_bp
from blueprint.study_views import study_bp
from flask_autoindex import AutoIndex
from blueprint.kami_views import kami_bp
from blueprint.index_views import index_bp
# 引入api
from api.docs import docs_api
from api.api import api_api
def get_owp_db_conn():
conn = sqlite3.connect('/var/open-ww3-project-ww3-tw/databases/sqlite/owp.db')
conn.row_factory = sqlite3.Row
return conn
app = Flask(__name__, static_url_path='/static/')
# session
# 随机数生成
key_hex = secrets.token_hex(32)
app.secret_key = key_hex
# 注册蓝图
app.register_blueprint(blog_bp, url_prefix='/blog')
app.register_blueprint(study_bp, url_prefix='/study')
app.register_blueprint(kami_bp, url_prefix='/kami')
app.register_blueprint(index_bp, url_prefix='/')
# 注册api
app.register_blueprint(docs_api, url_prefix='/api/docs')
app.register_blueprint(api_api, url_prefix='/api/s/')
# 全局清理关闭数据库连接
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
@app.errorhandler(400)
def bad_request(error):
return (
'400 Bad Request<br>'
'请求有误,请检查参数是否正确'
'<title>400 Bad Request</title>',
400
)
@app.errorhandler(401)
def unauthorized(error):
return (
'401 Unauthorized<br>'
'请先登录或提供有效凭证'
'<title>401 Unauthorized</title>',
401
)
@app.errorhandler(403)
def forbidden(error):
return (
'403 Forbidden<br>'
'你没有权限访问此资源'
'<title>403 Forbidden</title>',
403
)
@app.errorhandler(404)
def not_found(error):
return (
'404 Not Found<br>'
'这里什么都没有'
'<title>404 Not Found</title>',
404
)
@app.errorhandler(405)
def method_not_allowed(error):
return (
'405 Method Not Allowed<br>'
'请求方法不被允许'
'<title>405 Method Not Allowed</title>',
405
)
@app.errorhandler(500)
def internal_server_error(error):
return (
'500 Internal Server Error<br>'
'服务器开小差了,请稍后再试'
'<title>500 Internal Server Error</title>',
500
)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8085, debug=True)

0
packages/__init__.py → public/about/index.html Normal file → Executable file
View File

View File

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 268 KiB

120
public/blog/index.php Executable file
View File

@@ -0,0 +1,120 @@
<html>
<head>
<title>首页 | ww3</title>
<meta charset="utf-8" lang="zh-CN">
<meta name="viewport" content="width=1366px, initial-scale=1.0"> <!-- 页面等比例缩小 -->
<link rel="icon" type="image/x-icon" href="./icon/original.ico">
</head>
<body>
<div id="black_block">
<div id="navbar1">
<table border="0" style="background-color: rgba(147, 185, 255, 0.644);">
<tbody>
<tr>
<td id="td_navbar_40px"><b><a href="https://ww3.tw/" id="url_">首页</a></b></td>
<td id="td_navbar_40px"><b><a href="https://ww3.tw/about/" id="url_">关于</a></b></td>
<td id="td_navbar_75px"><b><a href="https://ww3.tw/jumping-message/" id="url_">弹幕留言</a></b></td>
<td id="td_navbar_75px"><b><a href="https://ww3.tw/short-url/" id="url_">短链生成</a></b></td>
<td id="td_navbar_52px"><b><a href="https://gitea.ww3.tw/skimrme/" id="url_">gitea</a></b></td>
<td id="td_navbar_135px"><b><a href="https://ww3.tw/docker-registry/" id="url_">docker-registry</a></b></td>
<td id="td_navbar_40px"><b><a href="https://api.ww3.tw/" id="url_">api</a></b></td>
<td id="td_navbar_40px"><b><a href="https://wiki.ww3.tw/" id="url_">wiki</a></b></td>
</tr>
</tbody>
</table>
</div>
<br>
<!-- 屑站日志 -->
<div id="logs">
<h3>屑站日志:<br></h3>
<font size="3.2">
<table border="0">
<tbody>
<tr>
<td id="td_logs">2025.07.26</td>
<td id="td_logs_content">新增<a href="https://wiki.ww3.tw">wiki</a>页面</td>
</tr>
<tr>
<td id="td_logs">2025.07.20</td>
<td id="td_logs_content">新增<a href="https://gitea.ww3.tw/skimrme">gitea</a><a href="https://ww3.tw/docker-registry/">docker-registry</a>页面</td>
</tr>
<tr>
<td id="td_logs">2025.07.09</td>
<td id="td_logs_content">建立页面</td>
</tr>
</tbody>
</table>
</font>
</div>
<!-- 屑站日志 -->
<div id="js_date"></div>
<script>
</script>
</div>
</body>
</html>
<?php
include "../static/html/black-block.html";
?>
<style>
body
{
background-color: rgba(147, 185, 255, 0.644);
}
#url_
{
text-decoration: none;
color: rgb(0, 0, 0);
}
#logs
{
height: 220px;
width: 450px;
overflow: auto;
background: #ffffffbc;
/* up、right、down、left */
margin: 40px 0px 0px 0px;
}
#td_navbar_40px
{
width: 40px;
}
#td_navbar_52px
{
width: 52px;;
}
#td_navbar_75px
{
width: 75px;
}
#td_navbar_135px
{
width: 135px;
}
#td_logs
{
width: 75px;
padding-bottom: 5px;
}
#td_logs_content
{
color: rgb(132, 132, 132);
padding-left: 10px;
padding-bottom: 5px;
}
#js_date{
color: rgb(55, 0, 255);
font-size: 200%;
}
</style>

View File

@@ -0,0 +1,25 @@
<?php
// 1. 定义你的 Docker Registry 地址
// 请将 'http://localhost:5000' 替换为你的实际 Registry 地址。
// 例如:如果你的 Registry 是 'my-registry.io',就改为 'https://my-registry.io'
$registryUrl = "https://regw.ww3.tw/";
// 2. 定义你要获取的 API 端点
// 这个端点用于获取所有仓库列表。
$endpoint = "/v2/_catalog";
// 3. 组合完整的 URL
$fullUrl = $registryUrl . $endpoint;
// 4. 使用 file_get_contents() 获取 JSON 内容
// @ 符号用来抑制可能出现的错误或警告,让输出更干净。
$jsonContent = @file_get_contents($fullUrl);
// 5. 直接输出 JSON 内容
// 如果成功获取到内容,就直接打印出来。
// 如果获取失败会打印一个空字符串或PHP的错误信息如果没用@抑制)。
header('Content-Type: application/json'); // 告诉浏览器这是一个JSON响应
echo $jsonContent;
?>

View File

@@ -0,0 +1,11 @@
<html>
<head>
<title>docker-registry</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
<a href="./all-images/index.php">查看所有镜像</a>
<p>tags/list</p>
</body>
</html>

1
public/index.html Executable file
View File

@@ -0,0 +1 @@
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/blog/">

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>弹幕留言 | jumping-message</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
</body>
</html>

173
public/message/index.php Executable file
View File

@@ -0,0 +1,173 @@
<html>
<head>
<meta charset="utf-8" lang="zh-CN">
<meta name="viewport" content="width=1366px, initial-scale=1.0"> <!-- 页面等比例缩小 -->
<link rel="stylesheet" type="text/css" href="./static/css/navbar/body_color.css">
<link rel="icon" type="img/icon" href="./static/icon/original.ico">
</head>
<body>
<?php
$title = "Message | 留言";
// title 变量
echo "<title>" . "$title" . "</title>";
// 页面标题
?>
<body id="body_color">
<div id="message_block">
<div id="content_page">
<?php
echo "<h1>欢迎来到 $title</h1>";
// 欢迎语
echo "感谢您的访问" . " " . "<br>" . "顾名思义" . "$title" . "就是用来记录留言的地方";
// 介绍部分
?>
<div id="back_blok">
<!-- 返回主页 -->
<a id="back_url" href="https://ww3.tw/"><b>..返回主页</b></a>
</div>
<div id="message_video">
<video src="./static/src/video/cirno-up-down.mp4" controls width="640" height="360">
您的浏览器不支持视频播放。
</video>
</div>
<div id="message_com">
<div id="push_message">
<label for="message">输入内容 : </label>
<input type="text" id="message" placeholder="qwq">
<button onclick="push_message()">发送弹幕</button>
<br>
<p>弹幕列表</p>
<pre id="get_message"></pre>
</div>
<div>
</div>
</div>
</body>
</body>
</html>
<!-- php 引入 -->
<?php
include "./static/css/navbar/index-css.html";
// 引入navbar-css
?>
<!-- php 引入 -->
<style>
/* 这里是专属css */
#content_page
{
color: rgb(255, 74, 74);
text-align: left;
font-size: 18px;
}
#message_video
{
background-color: rgba(0, 0, 0, 0);
color: white;
text-align: center;
width: 700px;
height: 410px;
/* 页面边距 上、右、下、左 */
margin: 1.89% 0px 0px 0%;
}
#message_com
{
background-color: rgba(0, 0, 0, 0);
width: 360px;
height: 410px;
/* 页面边距 上、右、下、左 */
margin: -405px 0px 0px 63.8%;
}
#back_blok{
/* 返回主页 */
color: rgb(0, 0, 0);
width: 20%;
height: 4%;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* 页面边距 上、右、下、左 */
margin: 4% 0px 0px 36.8%;
}
#back_url
{
color: black;
text-decoration: none;
}
</style>
<!--这里是专属js-->
<script>
function push_message() {
const messageInput = document.getElementById('message'); // 获取输入框元素本身
const messageContent = messageInput.value.trim(); // 获取输入框的值
if (messageContent === "") {
alert("弹幕内容不能为空!");
return;
}
messageInput.value = '';
// *** 在这里清空输入框 ***
messageInput.focus();
// 如果你想让输入框在清空后立即获得焦点,方便用户继续输入
}
</script>
<script>
const API_URL = 'https://api.ww3.tw/public/danmu/get.php'; //连接api的地址
// 使用 DOMContentLoaded 事件,确保页面 HTML 结构加载完成后再执行 JavaScript
document.addEventListener('DOMContentLoaded', async () => {
// 获取用于显示内容的 <pre> 元素
const getMessageElement = document.getElementById('get_message');
try {
// 发送 GET 请求到 API
const response = await fetch(API_URL);
// 检查 HTTP 响应状态码。如果不是 2xx成功说明有错误
if (!response.ok) {
// 尝试解析 API 返回的错误信息
let errorDetails;
try {
// 假设 API 错误信息也是 JSON 格式
errorDetails = await response.json();
} catch (e) {
// 如果不是 JSON就作为纯文本处理
errorDetails = await response.text();
}
// 抛出带有详细信息的错误
throw new Error(`HTTP 错误! 状态码: ${response.status} - ${typeof errorDetails === 'object' && errorDetails !== null ? (errorDetails.message || JSON.stringify(errorDetails)) : errorDetails}`);
}
// 你的 PHP API 返回的是 message.txt 的纯文本内容,所以这里使用 .text() 方法解析响应体
const content = await response.text();
// **** 核心修改:将获取到的内容直接赋值给 <pre> 元素的 textContent ****
getMessageElement.textContent = content;
getMessageElement.classList.remove('loading'); // 移除加载提示样式
} catch (error) {
// 如果在请求或处理过程中发生任何错误,捕获并显示
console.error('获取弹幕内容失败:', error);
getMessageElement.textContent = `错误: ${error.message}`;
getMessageElement.classList.remove('loading'); // 移除加载提示样式
getMessageElement.classList.add('error'); // 添加错误样式
}
});
</script>

View File

View File

@@ -0,0 +1,4 @@
#body_color
{
background-color: rgba(147, 185, 255, 0.644);
}

View File

@@ -0,0 +1,14 @@
<style>
#message_block
{
background-color: rgba(0, 0, 0, 0.68);
position: fixed;
width: 1150px;
height: 100%;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
</style>

View File

View File

@@ -0,0 +1,3 @@
<style>
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

View File

View File

@@ -0,0 +1,26 @@
<!-- 谷歌翻译 -->
<div id="google_translate_element"></div>
<!-- 翻译选项 -->
<!-- js 部分 -->
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({pageLanguage: 'zh-CN'}, 'google_translate_element');
}
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<!-- js 部分 -->
<style>
#google_translate_element
{
display: flex;
position: fixed;
/* 页面边距 上、右、下、左 */
margin: -7.6px 0px 0px 0px;
overflow: hidden;
}
</style>
<!-- 谷歌翻译 -->

View File

@@ -0,0 +1 @@
这是测试

View File

@@ -0,0 +1 @@
测试

BIN
public/short-url/icon/icon.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

12
public/short-url/index.php Executable file
View File

@@ -0,0 +1,12 @@
<html>
<head>
<title>short_url | 短链</title>
<meta charset="utf-8" lang="zh-CN">
<link rel="icon" type="image/x-icon" href="./icon/icon.jpg">
</head>
<body>
<h1>
ww3-short-url | 短链
</h1>
</body>
</html>

1
public/short_url/index.php Executable file
View File

@@ -0,0 +1 @@
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/short-url/">

View File

@@ -0,0 +1,14 @@
<style>
#black_block
{
background-color: rgba(0, 0, 0, 0.68);
position: fixed;
width: 1150px;
height: 100%;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
</style>

View File

@@ -1,10 +0,0 @@
blinker==1.9.0
click==8.3.1
Flask==3.1.2
Flask-AutoIndex==0.6.6
Flask-Silk==0.2
future==1.0.0
itsdangerous==2.2.0
Jinja2==3.1.6
MarkupSafe==3.0.3
Werkzeug==3.1.4

View File

@@ -1,58 +0,0 @@
/* css页面蓝图 */
/* 外部背景 */
html, body {
height: 100%;
width: 100%;
margin: 0; /*外边框*/
padding: 0; /*内边框*/
overflow: hidden; /* 防止滚动条 */
background-color: #333; /* 背景颜色 */
}
/* 内部容器 */
#app-canvas {
width: 1280px;
height: 800px;
background-color: rgba(147, 185, 255, 0.644);
border: 5px solid #0056b3; /* 定义边框 5px 实线 蓝色 */
/* transform-origin: 0 0; /* 定义缩放起点 左上角 */
position:fixed; /* 固定页面,不滚动 */
left: 50%; /* 调整左边缘位置到中央 */
top: 50%; /* 调整上边缘位置到中央 */
padding: 30px; /* 内部间距 30px */
}
header {
margin-bottom: 30px; /* 外部间距 30px */
text-align: center; /* 文字居中 */
}
h1 {
font-size: 48px;
color: #fff;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
#content-area {
display: flex;
justify-content: space-around;
gap: 40px;
}
/* 自带 */
.box {
width: 500px;
height: 600px;
background-color: #ffffffcc;
border: 1px solid #ccc;
padding: 20px;
font-size: 20px;
text-align: left;
overflow: auto;
}

View File

@@ -1,6 +0,0 @@
h1 {
border: 2px;
color:brown;
text-align: center;
padding: 10px;
}

View File

@@ -1 +0,0 @@
google-site-verification: google02f6a3f6004a32c6.html

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

File diff suppressed because one or more lines are too long

View File

@@ -1,29 +0,0 @@
// js目前不会先靠ai
function resizeCanvas() {
// 定义设计基准尺寸
const designWidth = 1280;
const designHeight = 800;
// 获取当前浏览器视口尺寸
const currentWidth = window.innerWidth;
const currentHeight = window.innerHeight;
const canvas = document.getElementById('app-canvas');
// 计算缩放比例
const scaleX = currentWidth / designWidth;
const scaleY = currentHeight / designHeight;
const scaleFactor = Math.min(scaleX, scaleY);
// 确保元素中心与 left: 50%; top: 50%; 对齐
canvas.style.transform = `translate(-50%, -50%) scale(${scaleFactor})`;
}
// 首次加载时执行
document.addEventListener('DOMContentLoaded', resizeCanvas);
// 监听窗口大小变化时执行,保持动态缩放
window.addEventListener('resize', resizeCanvas);
// 确保在某些情况下也能正确初始化
resizeCanvas();

View File

@@ -1,33 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<!-- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
fetch('https://open-ww3-project.ww3.tw/api/s/get/logs/')
.then(response => response.json())
.then(data => {
const textContent = JSON.stringify(data, null, 2);
str = textContent
arrayStr = JSON.parse(str)
arr = arrayStr.map(obj => obj.content)
document.write(arr)
})
</script>
</body>
</html> -->

View File

@@ -1,7 +0,0 @@
User-agent: *
Allow: /
Disallow: /kami/
Sitemap: https://open-ww3-project.ww3.tw/blog/sitemap.xml

View File

@@ -1,45 +0,0 @@
<html>
<head>
<title>推荐网页</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
<center>
<h3>漫画</h3>
<th>
<td id="font_a">
<a href="https://xmanhua.com/">xmanhua</a>
</td>
</th>
<th>
<td id="font_a">
<a href="https://komiic.com/">komiic</a>
</td>
</th>
<th>
<td id="font_a">
<a href="https://mangadex.org/">mangadex</a>
</td>
</th>
<th>
<td id="font_a">
<a href="https://mangabz.com/">mangabz</a>
</td>
</th>
<h3>动漫</h3>
<th>
<td id="font_a">
<a href="https://www.agedm.com">age动漫 | 尽量不要开梯</a>
</td>
</th>
</center>
</body>
</html>
<style>
#font_a {
width: 50px;
}
</style>

View File

@@ -1 +0,0 @@
<iframe src="//player.bilibili.com/player.html?isOutside=true&aid=115578442356850&bvid=BV12CCdBkEL6&cid=34120008494&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width: 100%; height: 100%;"></iframe>

View File

@@ -1,33 +0,0 @@
{# 引入base #}
{% extends 'blog/extension/base.html' %}
{# 引入标题 #}
{% block title %}关于{% endblock %}
{% include 'blog/include/head.html' %}
{% block content %}
{% include 'blog/include/navbar.html' %}
<br>
<a href="{{ url_for('blog.home') }}">返回首页</a>__<a href="{{ url_for('blog.sitemap') }}">网页地图</a>
<hr id="hr_2">
本站建立于大概2025年8月前后<br>
差不多是个人博客多次重建后的成果<br>
如今我已经成长很多<br>
<br>
<a href="https://wiki.ww3.tw/doku.php?id=zh_cn:skimrme">站长介绍<a>
<p>2025.12.22</p>
<br>
<br>
<hr id="hr_2">
忘记写了
<br>
所以暂时就不写了
<p>2025.08.05</p>
<p>over</p>
<style>
#hr_2 {
border: 0.3px solid black;
}
</style>
{% endblock %}

View File

@@ -1,57 +0,0 @@
{# base_home模板 #}
<!DOCTYPE html>
<html>
<title>{% block title %}{% endblock %} | ww3</title>
<body>
<div id="content">
{% block content %}
{# 这里存放写入模板的数据 #}
{% endblock %}
</div>
{% block move %}
{# 这里存放更多模板的数据 #}
{% endblock %}
{% include 'blog/include/footer.html' %}
</body>
</html>
{# css部分 #}
<style>
#navbar {
width: 100%;
text-align: center;
}
#url_ {
margin: 0 5px 0 0;
color: black;
font-weight: bold;
}
#content {
margin: 0 0 0 0;
margin-left: 5%;
width: 90%;
height: 640px;
background-color: #93B9FFA4;
}
#navbar1 {
font-size: 125%;
width: 35%;
height: 13px;
background-color: rgba(169, 198, 252, 0);
}
#navbar {
font-size: 125%;
width: 500px;
height: auto;
background-color: rgb(169, 198, 252);
}
html, body {
margin: 0;
}
a {
text-decoration: none;
}
body {
background-color: rgb(92, 92, 92);
}
</style>

View File

@@ -1,123 +0,0 @@
{# 引入base #}
{% extends 'blog/extension/base.html' %}
{# 引入标题 #}
{% block title %}首页{% endblock %}
{% include 'blog/include/head.html' %}
{% include 'blog/include/wallpaper.html' %}
{% block content %}
<h1>欢迎访问open-ww3-project</h1>
<!-- 屑站日志 -->
<h3 style="margin: 10px 0 30px 50px;">屑站日志:<br></h3>
<div id="logs">
<font size="3.2">
<table border="0">
<tbody>
{# 调用数据库 #}
{% for logs in logs %}
<tr>
<td id="td_logs">
<a style='font-size: 16.7px;'>
{{ logs['date'].replace('.', '-') }}
</a>
<br>
</td>
<td id="td_logs_content">
{{ logs['content'].replace('&&', '<br>') | safe }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</font>
</div>
<!-- 屑站日志 -->
<div id="posts">
<h1>全部文章</h1>
文章如下↓
<br>
<br>
<div id="posts_list">
{% for posts in posts %}
文章id:{{ posts['id'] }}
<br>
标题: {{ posts['title'] }}
<br>
日期: {{ posts['date'].replace('.', '-')}}
<a href="{{ url_for('blog.posts_list') }}{{ posts['id'] }}">页面跳转</a>
<br>
<br>
{% endfor %}
</div>
</div>
<!-- css 部分 -->
<style>
#posts_list {
height: 300px;
overflow: auto;
}
#posts {
margin: -400px 0 0 60%;
}
/* 日志 */
#logs
{
height: 50%;
width: 40%;
overflow: auto;
background: #ffffffbc;
/* up、right、down、left */
margin: -10px 0px 0px 30px;
}
#td_logs
{
width: 93px;
padding-top: 1.8px;
vertical-align: top;
}
#td_logs_content
{
color: rgb(132, 132, 132);
padding-left: 10px;
padding-bottom: 5px;
}
/* 日志 */
</style>
{% endblock %}
{% block move %}
<div id="class">
<h1></h1>
<h1>更多</h1>
<form action="https://greendam.icu/" method="get">
<button>随机一张格林达姆</button>
<br>
来源: <a href="https://greendam.icu/">https://greendam.icu/</a>
</form>
<a href="./paint/">
<button>paint</button>
</a>
<p style="margin: 870px 0 0 0; text-align: center; color: white;">
主页访问计数: {{counter}}
</p>
</div>
<style>
#class {
margin: 0 0 0 0;
margin-left: 5%;
width: 90%;
height: 640px;
background-color: #93B9FFA4;
}
</style>
{% endblock %}

View File

@@ -1,41 +0,0 @@
<footer style="
text-align: center;
background-color: rgba(0, 0, 0, 0);
color: rgb(255, 255, 255);
padding: 10px;
margin-top: 0;
">
<div style="text-align: left;">
无情ta站:
<a href="https://1win.eu.org/" style="color: rgb(188, 188, 255);">1win</a>
<a href="https://jvav.1win.eu.org/" style="color: rgb(188, 188, 255);">jvav</a>
</div>
<hr>
© 2025-2026 | open-ww3-poject for ww3.tw
<br>
<a href="https://wiki.ww3.tw/doku.php?id=zh_cn:skimrme" style="color: rgb(188, 188, 255);">关于站长</a>
<a href="{{ url_for('blog.sitemap') }}" style="color: rgb(188, 188, 255);">网页地图</a>
<a href="{{ url_for('blog.messages') }}" style="color: rgb(188, 188, 255);">留言小角</a>
<br>
<br>
联系:
<br>
电子邮件: <a style="color: rgb(188, 188, 255);">master@ww3.tw<a>
<br>
社交:
<br>
暂不提供
<br>
其他平台:
<br>
<br>
暂不提供
<br>
<br>
备案区:
<br>
<a href="https://icp.hentioe.dev/sites/20257900" target="_blank">喵ICP备20257900号</a>
<br>
<a href="https://icp.redcha.cn/beian/ICP-2026010278.html" title="茶ICP备2026010278号" target="_blank">茶ICP备2026010278号</a>
<br>
</footer>

View File

@@ -1,5 +0,0 @@
<head>
<meta charset="utf-8" lang="zh_CN">
<meta name="viewport" content="width=device-width, initial-scale=0.4">
<link rel="icon" type="image/x-icon" href="/static/icon/original.ico">
</head>

View File

@@ -1,19 +0,0 @@
{# navbar 部分 #}
{% set navbar_list = [
{"id":1, "name": "首页", "url": url_for('blog.home')},
{"id":2, "name": "关于", "url": url_for('blog.about')},
{"id":3, "name": "文章", "url": url_for('blog.posts_list')},
{"id":4, "name": "mirrors", "url": url_for('blog.autoindex')},
{"id":5, "name": "study", "url": url_for('study.home')},
]%}
<div id="navbar1">
<br>
</div>
<div id="navbar" style="text-align: left;">
{% for navbar in navbar_list %}
<a href="{{ navbar.url }}" id="url_">{{ navbar.name }}</a></td>
{% endfor %}
<a id="url_" href="https://api.ww3.tw">api</a>
<a id="url_" href="https://gitea.ww3.tw">gitea</a>
</div>

View File

@@ -1,52 +0,0 @@
{# 壁纸部分 #}
{% set wallpaper_apis =[
'https://www.loliapi.com/acg/pc/',
'https://api.sretna.cn/api/pc.php',
'https://www.api.plus/api/dongman',
'https://moe.jitsu.top/img/?sort=pc',
'https://www.dmoe.cc/random.php',
'https://api.mtyqx.cn/tapi/random.php'] %}
{% set wallpaper = wallpaper_apis | random %}
<!--'https://api.r10086.com/樱道随机图片api接口.php?图片系列=猫娘1', -->
<head>
<link rel="preload" href="{{ wallpaper }}" as="image">
</head>
<div style="display: none;">
<p>一个致力于分享个人学习到的知识的记录形式的屑站</p>
<p>在这里,我会分享我学到的计算机知识或者记录一些自己经常碰到的问题</p>
</div>
<div id="wallpaper">
{% include 'blog/include/navbar.html' %}
<br>
<div style="text-align: center;
font-weight: bolder;
text-shadow:
3px 3px 0 rgba(0,0,0,0.2),
6px 6px 0 rgba(0,0,0,0.1);
font-size: 300%;
color: rgb(240, 248, 255);
">
<p>open-ww3-poject</p>
</div>
<div>
<p style="text-align: right; margin: 420px 0 0 0;">图片来源: <a href="{{ wallpaper }}" style="color: rgb(247, 74, 74);">{{ wallpaper }}<a></p>
</div>
<div style="text-align: center; color: rgba(255, 255, 255, 0.664); margin: -400px 0 0 0; text-shadow: 3px 3px 5px rgba(47, 79, 79, 0.7);">
<p>一个致力于分享个人学习到的知识的记录形式的屑站</p>
<p>在这里,我会分享我学到的计算机知识或者记录一些自己经常碰到的问题</p>
</div>
</div>
<style>
#wallpaper {
margin-left: 5%;
width: 90%;
height: 640px;
background-color: #93B9FFA4;
background-image: url('{{ wallpaper }}');
background-size: 100% 100%;
background-size: cover;
background-position: center;
}
</style>

View File

@@ -1,54 +0,0 @@
{# 引入base #}
{% extends 'blog/extension/base.html' %}
{# 引入标题 #}
{% block title %}文章列表{% endblock %}
{% include 'blog/include/head.html' %}
{# 随机变换图床api #}
{% set wallpaper_apis =[
'https://www.loliapi.com/acg/pc/',
'https://api.sretna.cn/api/pc.php',
'https://www.api.plus/API/dongman/',
'https://moe.jitsu.top/img/?sort=pc',
'https://www.dmoe.cc/random.php',
'https://api.r10086.com/樱道随机图片api接口.php?图片系列=猫娘1',
'https://api.mtyqx.cn/tapi/random.php'] %}
{% set wallpaper = wallpaper_apis | random %}
{% block content %}
{% include 'blog/include/navbar.html' %}
<center><b><h2>全部文章</h2></b></center>
文章如下↓
<br>
<br>
<div style="overflow: auto; height: 460px; width: 900px;">
{% for posts in posts %}
<br>
文章id:{{ posts['id'] }}
<br>
文章标题:{{ posts['title'] }}
<br>
<a href="{{ url_for('blog.posts_list') }}{{ posts['id'] }}">页面跳转</a>__{{ posts['date'].replace('.', '-') }}
<br>
{% endfor %}
</div>
<style>
#content{
/* background-image: url('{{ wallpaper }}'); */
background-size: cover;
background-repeat: no-repeat;
background-size: 100% 100%;
margin: 0;
}
.div123content {
background-color: blue;
width: auto;
height: 300px;
overflow: auto;
}
</style>
{% endblock %}

View File

@@ -1,28 +0,0 @@
{% extends '__autoindex__/autoindex.html' %}
{% block header %}
<h1 style="width: 80%; background-color: #fbecec7d; margin-left: auto; margin-right: auto;">index of .</h1>
<br>
<br>
<br>
<style>
body {
background-image: url('https://moe.jitsu.top/img/?sort=pc');
background-size: cover;
background-repeat: no-repeat; /*禁止平铺*/
margin: 0; /* 外边框为0 */
}
table {
width: 80%;
margin-left: auto;
margin-right: auto;
}
</style>
{% endblock %}
{% block footer %}
<hr>
<div style="color: #fb8888; text-align: center;">
© 2025 open-ww3-project
</div>
{% endblock %}

View File

@@ -1,13 +0,0 @@
{# 引入base #}
{% extends 'blog/extension/base.html' %}
{# 引入标题 #}
{% block title %}paint{% endblock %}
{% include 'blog/include/head.html' %}
{% block content %}
{% include 'blog/include/navbar.html' %}
{% endblock %}

View File

@@ -1,77 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ posts['title'] }}</title>
<link rel="icon" type="image/x-icon" href="/static/icon/original.ico">
<meta property="og:title" content="{{ posts['title'] }}">
<meta property="og:description" content="{{ posts['content']}}">
<meta property="og:image" content="https://ww3.tw/static/img/open-ww3-project.png">
<meta property="og:url" content="https://ww3.tw/blog/posts/{{ posts['id']}}/">
<meta property="og:type" content="website">
</head>
</head>
<body>
<a href="/blog">返回主页</a>
<br>
<h1>{{ posts['title'] }}</h1>
<br>
<br>
{{ posts['content'].replace('&a&a','<style>a{text-decoration: none;}</style>') | safe}}
<br>
<br>
<br>
最后修改时间: 【{{ posts['update_time'].replace('.', '-') }}】
<br>
<hr>
<h2>留言区: </h2>
<form method="post" action="./chat/">
昵称: (20字)
<input type="text" name="name" maxlength="20" required>
<br>
留言内容: (100字)
<br>
<textarea name="data" maxlength="100" style="height: 60px;" required></textarea>
<button type="submit">发送</button>
</form>
<br>
{% for message_ss in message_ss %}
<span class="msg-date">{{message_ss.date}}</span>
<br>
[{{message_ss.name}}@arch-cat ArchLinux]
<br>
$ {{message_ss.data}}
<br>
<br>
{% endfor %}
</body>
</html>
<style>
body {
background-color: rgb(175, 223, 255);
}
a {
text-decoration: none;
}
</style>
<script>
document.querySelectorAll('.msg-date').forEach(el => {
let dateStr = el.innerText.trim();
if (dateStr) {
// 兼容 ISO 格式,将空格替换为 T 方便解析
let date = new Date(dateStr.replace(' ', 'T'));
// 增加 8 小时
date.setHours(date.getHours() + 8);
// 格式化回 YYYY-MM-DD HH:mm:ss
let formatted = date.getFullYear() + '-' +
String(date.getMonth() + 1).padStart(2, '0') + '-' +
String(date.getDate()).padStart(2, '0') + ' ' +
String(date.getHours()).padStart(2, '0') + ':' +
String(date.getMinutes()).padStart(2, '0') + ':' +
String(date.getSeconds()).padStart(2, '0');
el.innerText = formatted;
}
});
</script>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>{{ base_url }}</loc>
<lastmod>2025-12-22</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
{% for post in posts %}
<url>
<loc>{{ base_url }}posts/{{ post['id'] }}/</loc>
<lastmod>{{ post['date'].replace('.', '-') }}</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
{% endfor %}
<url>
<loc>{{ base_url }}posts/</loc>
<lastmod>2025-12-23</lastmod>
<changefreq>daily</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>{{ base_url }}mirrors/</loc>
<lastmod>2025-12-23</lastmod>
<changefreq>daily</changefreq>
<priority>0.8</priority>
</url>
</urlset>

View File

@@ -1,19 +0,0 @@
<title>上传文件</title>
上传文件
<br>
目前只支持jpg, jpeg, png, gif
<form id="upload-form" enctype="multipart/form-data" method="post" action="./">
<input type="file" name="img" required>
<button type="submit">上传文件</button>
</form>
<br>
<br>
已上传图片
<br>
<br>
<br>
{% for image in images %}
<a href="{{ url_for('static', filename='upload/img/' + image) }}">
<img src="{{ url_for('static', filename='upload/img/' + image) }}" style="width: 10%;" alt="{{ image }}">
</a>
{% endfor %}

View File

@@ -1,12 +0,0 @@
{# 引入base #}
{% extends 'study/base.html' %}
{# 网站标签 #}
{% block title %} 关于页面 {% endblock %}
{% block content %}
大家好......
没有了
{% endblock %}

View File

@@ -1,61 +0,0 @@
{# base模板 #}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" lang="zh_CN">
<title>{% block title %}{% endblock %}</title>
<!--link rel="stylesheet" href="/static/css/style.css"-->
{# 建立一个url来源于static文件夹的文件名字为css文件夹下的style.css #}
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<div style="width: 100%; background-color: rgb(122, 91, 246);">
<table>
<tr>
<td>
<div class="url">
<a href="/study" class="url">home</a>
</div>
</td>
<td>
<div class="url">
<!--a href="/study/about" class="url">about</a-->
<a href="{{ url_for('study.about')}}" class="url">about</a>
</div>
</td>
<td>
<div style="margin: -5px 0 0 10px;" class="url" x-data="{ open: false }">
<div class="url" @click="open = true">子功能</div>
<div x-show="open" @click.away="open = false">
<div>
<a href="/study/posts/new" class="url">新建文章</a>
</div>
</div>
</div>
</td>
</tr>
</table>
</div>
{% for message in get_flashed_messages() %}
<div>{{ message }}</div>
{% endfor %}
{% block content %} {% endblock %}
</body>
</html>
<style>
body {
margin: 0 0 0 0;
background-color: rgb(157, 209, 255);
}
.url {
height: 40px;
margin: 10px 0 0 10px;
color: rgb(0, 0, 0);
text-decoration: none;
}
</style>
<script src="{{ url_for('static', filename='js/alpine.js') }}">vue_global</script>

View File

@@ -1,5 +0,0 @@
<b>确定要删除 "{{ posts['title'] }}" 吗?</b>
<form action="{{ url_for('study.delete_posts_id', posts_id=posts['id']) }}" method="post">
<input type="submit" value="删除文章" class="btn btn-danger htn-sm" onclick="return confirm('确定要删除吗')">
</form>

View File

@@ -1,25 +0,0 @@
{# 引入base #}
{% extends 'study/base.html' %}
{# 网站标签 #}
{% block title %} 编辑 "{{ posts['title'] }}" {% endblock %}
{% block content %}
<form method="post">
<div class="form-group">
<label for="title">标题</label>
<input type="text" name="title" placeholder="标题" class="form-control" value="{{ request.form['title'] or posts['title'] }}">
</inpit>
</div>
<div class="form-group">
<label for="content">内容</label>
<textarea name="content" placeholder="文章内容" class="form-control">{{ request.form['content'] or posts['content'] }}</textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
{% endblock %}

View File

@@ -1,20 +0,0 @@
{# 引入base #}
{% extends 'study/base.html' %}
{# 网站标签 #}
{% block title %}study学习{% endblock %}
{% block content %}
<h1>学习如何搭建一个blog</h1>
<h2>欢迎访问一个学习如何搭建一个blog的页面</h2>
{% for posts in posts %}
<a href="/study/posts/{{ posts['id'] }}">
<!--a href="{{ url_for('study.show_posts_id', posts_id=posts['id']) }}"-->
<h2>{{ posts['title'] }}</h2>
</a>
<span>{{ posts['created_8'] }}</span>
<hr>
<br>
{% endfor %}
{% endblock %}

View File

@@ -1,27 +0,0 @@
{# 引入base #}
{% extends 'study/base.html' %}
{# 网站标签 #}
{% block title %} 新建文章 {% endblock %}
{% block content %}
<br>
<br>
<br>
<form method="post">
<div class="form-group">
<label for="title">标题</label>
<input type="text" name="title" placeholder="标题" class="form-control" value="{{ request.form['title'] }}">
</inpit>
</div>
<div class="form-group">
<label for="content">内容</label>
<textarea name="content" placeholder="文章内容" class="form-control">{{ request.form['content'] }}</textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
{% endblock %}

View File

@@ -1,19 +0,0 @@
{# 引入base #}
{% extends 'study/base.html' %}
{# 网站标签 #}
{% block title %} {{ posts['title'] }} {% endblock %}
{% block content %}
<h1>{{ posts['title'] }}</h1>
<span>{{ posts['created_8'] }}</span>
<a href="./{{ posts['id'] }}/edit">
<span>编辑</span>
</a>
<hr>
<p>{{ posts['content'] }}</p>
{% endblock %}