Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c981130e8 | |||
| df8c73a68e | |||
| 26f3beb031 | |||
| 3dbe393220 |
31
.gitignore
vendored
@@ -1,11 +1,22 @@
|
|||||||
**/__pycache__
|
#### 忽略目录
|
||||||
**/*.db
|
# 数据库
|
||||||
**/*.sql
|
|
||||||
**/*.db.back
|
|
||||||
databases/*
|
databases/*
|
||||||
mirrors/*
|
public/*.sql
|
||||||
blueprint/kami_views.py
|
public/*.db
|
||||||
templates/kami/*
|
|
||||||
static/upload/*
|
##### 博客文档
|
||||||
templates/message/*
|
# 图片
|
||||||
blueprint/massage_views.py
|
src/image/*
|
||||||
|
public/image/*
|
||||||
|
|
||||||
|
|
||||||
|
# 可能未知
|
||||||
|
public/message/static/src/video/*
|
||||||
|
|
||||||
|
# 管理员面板
|
||||||
|
public/blog/admin/*
|
||||||
|
|
||||||
|
|
||||||
|
# 临时区
|
||||||
|
public/blog/md0/*
|
||||||
|
# 临时区
|
||||||
19
README.md
@@ -1,24 +1,5 @@
|
|||||||
<a href="https://ww3.tw/">点击访问</a>
|
<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
|
## 2025.7.20
|
||||||
open-ww3-project-ww3-tw
|
open-ww3-project-ww3-tw
|
||||||
个人博客地址(预计)
|
个人博客地址(预计)
|
||||||
|
|||||||
@@ -1,123 +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
|
|
||||||
import os
|
|
||||||
import sqlite3
|
|
||||||
import time
|
|
||||||
|
|
||||||
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('/')
|
|
||||||
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()
|
|
||||||
return render_template('blog/home.html', logs=logs[::-1], posts=posts[::-1])
|
|
||||||
|
|
||||||
@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):
|
|
||||||
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:
|
|
||||||
return f'未找到该文章{posts_id}<title>未找到该文章{posts_id}</title>', 404
|
|
||||||
return render_template('blog/posts.html', posts=posts, message=message[::-1])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 数据库测试
|
|
||||||
@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')
|
|
||||||
@@ -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}!'
|
|
||||||
@@ -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)
|
|
||||||
11
database.py
@@ -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
|
|
||||||
102
main.py
@@ -1,102 +0,0 @@
|
|||||||
from flask import Flask, render_template, redirect, url_for, send_from_directory, make_response, g
|
|
||||||
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
|
|
||||||
import os
|
|
||||||
import sqlite3
|
|
||||||
|
|
||||||
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
|
|
||||||
#app.secret_key = "508948973a8651f160baf3b26f18c47d"
|
|
||||||
app.secret_key = '玩鵬畝遜溉痕叛課還擇鼇粹拜溜泉聰倡效蘭鱅都凍芝西鄂'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 注册蓝图
|
|
||||||
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='/')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 全局清理关闭数据库连接
|
|
||||||
@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)
|
|
||||||
13
public/blog/about/index.html
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>不想写了</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
忘记写了
|
||||||
|
<br>
|
||||||
|
所以暂时就不写了
|
||||||
|
<p>2025.08.05</p>
|
||||||
|
<p>over</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
0
static/google02f6a3f6004a32c6.html → public/blog/google02f6a3f6004a32c6.html
Executable file → Normal file
|
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 268 KiB |
245
public/blog/index.php
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
<!-- 主页 -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>首页 | ww3</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
<link rel="icon" type="image/x-icon" href="./icon/original.ico">
|
||||||
|
<!-- 引入页面蓝图css -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="./src/css/main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app-canvas">
|
||||||
|
<header>
|
||||||
|
<h1 style="margin: 80px 0 0 0; color:aqua;">open-ww3-project</h1>
|
||||||
|
</header>
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<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/blog/about/" id="url_">关于</a></b></td>
|
||||||
|
<td id="td_navbar_40px"><b><a href="https://ww3.tw/blog/post/" 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_78px"><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_160px"><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>
|
||||||
|
<!-- 倒过来的箱子 真不明白,为什么我会称呼箱子为open-ww3-project-->
|
||||||
|
<div style="margin: 80px -30px -100px 180px;">
|
||||||
|
<img id="open-ww3-project-img" width="10%" src="./src/img/open-ww3-project.png" alt="open-ww3-project-img">
|
||||||
|
</div>
|
||||||
|
<!-- gitea 图标 -->
|
||||||
|
<a style="background-color: blueviolet; position: absolute;" href="https://gitea.ww3.tw/skimrme/open-ww3-project-ww3-tw">
|
||||||
|
<img id="gitea-img" src="https://gitea.ww3.tw/assets/img/logo.svg" width="150px" alt="gitea" >
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<div id="content-area">
|
||||||
|
<!-- 屑站日志 -->
|
||||||
|
<h3 style="margin: 70px 0 30px -50px;">屑站日志:<br></h3>
|
||||||
|
<div id="logs">
|
||||||
|
<font size="3.2">
|
||||||
|
<table border="0">
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
// 引入数据库 sqlite
|
||||||
|
include "./logs.php.text";
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</font>
|
||||||
|
</div>
|
||||||
|
<!-- 屑站日志 -->
|
||||||
|
|
||||||
|
<div id="post_content">
|
||||||
|
<?php
|
||||||
|
//include "post/index.php";
|
||||||
|
// 设定数据库路径
|
||||||
|
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 连接数据库
|
||||||
|
$db = new SQLite3($db_path);
|
||||||
|
// 连接成功输出连接成功
|
||||||
|
echo "<!--数据库连接成功-->";
|
||||||
|
// 如果连接成功,但是内部状态有问题
|
||||||
|
if ($db->lastErrorCode() !==0) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容区
|
||||||
|
// 执行sql命令 查询表单
|
||||||
|
$select_id_date_title_from_posts_btos /*查询posts表单中的id date title id从大到小排列*/ = $db->query('SELECT id, date, title FROM posts ORDER BY id DESC'); // 执行查询posts表单中的id date title id从大到小排列的命令
|
||||||
|
// 循环 写入
|
||||||
|
|
||||||
|
echo "<center><b><h2>全部文章</h2></b></center>";
|
||||||
|
echo "<br>";
|
||||||
|
echo "文章如下↓";
|
||||||
|
echo "<br>";
|
||||||
|
echo "<br>";
|
||||||
|
|
||||||
|
while ($row = $select_id_date_title_from_posts_btos->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
|
||||||
|
echo "文章id: " . $row['id'] . "<br>";
|
||||||
|
echo $row['date'] . " " . "文章标题: " . $row['title'] . "<br>";
|
||||||
|
echo "<a href='https://ww3.tw/blog/post/s/?id=" . $row['id'] . "'>页面跳转</a><br><br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
|
||||||
|
// 捕获php报错
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 私の娘 -->
|
||||||
|
<div id="my_girl" style="margin: -40px 0 0 1100px;"></div>
|
||||||
|
<!-- 私の娘 -->
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- css 部分 -->
|
||||||
|
<style>
|
||||||
|
#navbar1 {
|
||||||
|
margin: -160px 0 100px -30px;
|
||||||
|
}
|
||||||
|
#url_
|
||||||
|
{
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
font-size: 18.8px;
|
||||||
|
}
|
||||||
|
#td_navbar_40px
|
||||||
|
{
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_navbar_52px
|
||||||
|
{
|
||||||
|
width: 52px;;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_navbar_78px
|
||||||
|
{
|
||||||
|
width: 78px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_navbar_160px
|
||||||
|
{
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 日志 */
|
||||||
|
#logs
|
||||||
|
{
|
||||||
|
height: 220px;
|
||||||
|
width: 450px;
|
||||||
|
overflow: auto;
|
||||||
|
background: #ffffffbc;
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 115px 0px 0px -280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_logs
|
||||||
|
{
|
||||||
|
width: 75px;
|
||||||
|
padding-top: 1.8px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_logs_content
|
||||||
|
{
|
||||||
|
color: rgb(132, 132, 132);
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
/* 日志 */
|
||||||
|
|
||||||
|
/* 文章 */
|
||||||
|
#post_content
|
||||||
|
{
|
||||||
|
/*text-align: center;*/
|
||||||
|
height: 500px;
|
||||||
|
width: 490px;
|
||||||
|
color: rgb(202, 202, 202);
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
background-color: rgba(27, 27, 27, 0.010);
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 19px;
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 40px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标 */
|
||||||
|
#open-ww3-pro1ject-img
|
||||||
|
{
|
||||||
|
overflow: auto;
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gitea-img
|
||||||
|
{
|
||||||
|
margin: -150px 0 0 1150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- js 部分-->
|
||||||
|
<script src="./src/js/main.js"> 引入js页面蓝图 </script>
|
||||||
|
|
||||||
|
<!-- 私の娘 -->
|
||||||
|
<!-- https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.css -->
|
||||||
|
<!-- https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.js -->
|
||||||
|
<!-- https://cdnjs.cloudflare.com/ajax/libs/sakana-widget/2.7.1/sakana.min.css -->
|
||||||
|
<!-- https://cdnjs.cloudflare.com/ajax/libs/sakana-widget/2.7.1/sakana.min.js -->
|
||||||
|
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initSakanaWidget(){
|
||||||
|
const customImageUrl = 'https://open-ww3-project.ww3.tw/blog/src/img/my_girl.png';
|
||||||
|
const baseCharacter = SakanaWidget.getCharacter('chisato');
|
||||||
|
const myCharacter = {
|
||||||
|
image: customImageUrl,
|
||||||
|
initialState: baseCharacter.initialState,
|
||||||
|
};
|
||||||
|
|
||||||
|
SakanaWidget.registerCharacter('my_girl', myCharacter);
|
||||||
|
new SakanaWidget({
|
||||||
|
character: 'my_girl',
|
||||||
|
size: 200,
|
||||||
|
autoFit: true,
|
||||||
|
controls: true
|
||||||
|
}).mount('#my_girl');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script
|
||||||
|
async
|
||||||
|
onload="initSakanaWidget()"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.js">
|
||||||
|
</script>
|
||||||
|
<!-- 私の娘 -->
|
||||||
47
public/blog/logs.php.text
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
// 设定数据库路径
|
||||||
|
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 连接数据库
|
||||||
|
$db = new SQLite3($db_path);
|
||||||
|
// 连接成功输出连接成功
|
||||||
|
echo "<!--数据库连接成功-->";
|
||||||
|
// 如果连接成功,但是内部状态有问题
|
||||||
|
if ($db->lastErrorCode() !==0) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容区
|
||||||
|
// 执行sql命令 查询表单
|
||||||
|
$select_id_date_content_from_logs_b_to_s /*查询logs表单中的id date content id从大到小排列*/ = $db->query('SELECT id, date, content FROM logs ORDER BY id DESC'); // 执行查询logs表单中的id date content id从大到小排列的命令
|
||||||
|
|
||||||
|
// 循环 写入
|
||||||
|
while ($row = $select_id_date_content_from_logs_b_to_s->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
// 设定 ' ' 占用19个字符
|
||||||
|
$nbsp_count = 0;
|
||||||
|
// 设定变量是 换行 加上 空格重复19个
|
||||||
|
$br_nbsp = '<br>' . str_repeat(' ',$nbsp_count);
|
||||||
|
// 设定变量是 修改 && 为 换行 加上19个空格
|
||||||
|
$alter_br = str_replace('&&', $br_nbsp, $row['content']);
|
||||||
|
|
||||||
|
// 输出 date content
|
||||||
|
echo "<tr>" . "<td id='td_logs'>" . "<a style='font-size: 18px;'>" . $row['date'] . "</a>" . "</td>" . "<td id='td_logs_content'>" . $alter_br . "<br>" . "</tr>";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
|
||||||
|
// 捕获php报错
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
7
public/blog/md0/114514.md
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
## MD介绍页面
|
||||||
|
|
||||||
|
顾名思义、本文件夹下使用的基本都是markdown
|
||||||
|
|
||||||
|
最后感谢提供php的md插件的开源制作者
|
||||||
|
|
||||||
|
[点击跳转](https://ww3.tw/blog/md/src/php-markdown/)
|
||||||
479
public/blog/md0/MD.php
Executable file
@@ -0,0 +1,479 @@
|
|||||||
|
|
||||||
|
<?php
|
||||||
|
Header('Content:text/html;charset=utf-8');
|
||||||
|
?>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body,ol,ul,li,img,p{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li{
|
||||||
|
list-style-type: square;
|
||||||
|
padding:2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6{
|
||||||
|
margin:10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3{
|
||||||
|
border-bottom:solid 1px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
padding-bottom:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2{
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3{
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,ul{
|
||||||
|
padding:10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
max-width:1024px;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote{
|
||||||
|
border-left:solid 4px #bbb;
|
||||||
|
background-color:#eee;
|
||||||
|
min-height:24px;
|
||||||
|
line-height:24px;
|
||||||
|
padding:0px 10px;
|
||||||
|
margin:0;
|
||||||
|
color:#333;
|
||||||
|
font-size:12px;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: consolas,楷体;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table,td,th{
|
||||||
|
border:solid 1px #ddd;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding:10px;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
margin:10px 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-left{
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-right{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even){
|
||||||
|
background-color:#eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
code,pre{
|
||||||
|
border-radius:5px;
|
||||||
|
border:solid 1px #eee;
|
||||||
|
background-color:#f9f9f9;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
code{
|
||||||
|
padding:2px 12px;
|
||||||
|
display: inline-block;
|
||||||
|
margin:10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre{
|
||||||
|
padding:10px 12px;
|
||||||
|
overflow-x:auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* flag规则:
|
||||||
|
* h1-h6 标题
|
||||||
|
* u1,u2 无序列表
|
||||||
|
* ol 有序列表
|
||||||
|
* p 普通文本
|
||||||
|
* code 代码
|
||||||
|
* table 文本
|
||||||
|
* check 选择
|
||||||
|
* uncheck 未选择
|
||||||
|
* quote 引用
|
||||||
|
* img 图片
|
||||||
|
* url 网址
|
||||||
|
* bold 加粗
|
||||||
|
* italia 斜体
|
||||||
|
* el 空行
|
||||||
|
*
|
||||||
|
* idel 闲置
|
||||||
|
*/
|
||||||
|
class MD{
|
||||||
|
|
||||||
|
private $file; //当前文件
|
||||||
|
private $mdGen; //生成器
|
||||||
|
private $flag; //当前标志
|
||||||
|
private $flag_pre; //上一次的flag
|
||||||
|
private $flag_like; //假定类型
|
||||||
|
|
||||||
|
private $line_count; //总行数
|
||||||
|
private $lines; //所有行
|
||||||
|
private $buf; //缓存行
|
||||||
|
|
||||||
|
public function __construct($filename){
|
||||||
|
$this->file = $filename; //设置当前文件
|
||||||
|
$this->mdGen = $this->content($filename); //获取生成器
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
$this->lines = array(); //所有行状态
|
||||||
|
$this->line_count = 0; //行数归0
|
||||||
|
}
|
||||||
|
|
||||||
|
private function content($file){ //获取生成器
|
||||||
|
if(file_exists($file)){
|
||||||
|
$fh = fopen($file,"r");
|
||||||
|
while(!feof($fh)){
|
||||||
|
yield fgets($fh);
|
||||||
|
}
|
||||||
|
fclose($fh);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历每一个字符
|
||||||
|
private function every($str){
|
||||||
|
$l = strlen($str);
|
||||||
|
for($i=0;$i<$l;$i++)
|
||||||
|
if(ord($str[$i])<0x80)
|
||||||
|
yield $str[$i];
|
||||||
|
else{
|
||||||
|
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
|
||||||
|
$i+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析
|
||||||
|
private function parse(){
|
||||||
|
$ctnt = $this->mdGen; //生成器
|
||||||
|
$ret=array();
|
||||||
|
if($ctnt != null){
|
||||||
|
$ret = array();
|
||||||
|
foreach($ctnt as $line){
|
||||||
|
if($this->flag != 'code')
|
||||||
|
$line=ltrim($line); //删除左边
|
||||||
|
if(strlen($line)){
|
||||||
|
$ch = $line[0]; //判断第一个字符
|
||||||
|
$type=ctype_punct($ch);//标点符号
|
||||||
|
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
|
||||||
|
$ret[] = $this->parseLine($line,$type); //解析行
|
||||||
|
}else{ //空行
|
||||||
|
switch($this->flag){
|
||||||
|
case 'ul':
|
||||||
|
case 'ol':
|
||||||
|
$ret[]="</$this->flag>";
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel';
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
$this->flag = 'idel';
|
||||||
|
$ret[]='</table>';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if($this->flag != 'el') $ret[] = '<br>';
|
||||||
|
$this->flag = 'el'; //空行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->lines = $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成blockquote
|
||||||
|
private function genQuote($level,$content){
|
||||||
|
if($level<=0) return "";
|
||||||
|
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查是否处于某个状态,默认检查是否处于代码状态
|
||||||
|
private function check($value='code'){
|
||||||
|
return ($this->flag == $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成一行新的表格列
|
||||||
|
* $data:需要输入的数据
|
||||||
|
* $type:生成类型
|
||||||
|
* $wrap:最快层包裹
|
||||||
|
* $sep:分隔符
|
||||||
|
*/
|
||||||
|
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
|
||||||
|
$ret='';
|
||||||
|
$mat = explode($sep,$data);
|
||||||
|
foreach($mat as $elem)
|
||||||
|
$ret.="<$type>".$elem."</$type>";
|
||||||
|
return "<$wrap>".$ret."</$wrap>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析行内元素
|
||||||
|
* bold,italic,code,link,pic
|
||||||
|
*/
|
||||||
|
private function parseInner($str){
|
||||||
|
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
|
||||||
|
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
|
||||||
|
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
|
||||||
|
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
|
||||||
|
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照给定规则解析字符串:
|
||||||
|
* type:
|
||||||
|
* true 符号
|
||||||
|
* false 文字
|
||||||
|
* 返回:
|
||||||
|
* array('type'=>类型,'parts'=>array(...))
|
||||||
|
*/
|
||||||
|
private function parseLine($str,$type){
|
||||||
|
if(strlen($str) == 0){
|
||||||
|
return array('type'=>'p','parts'=>[]); //返回空段
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid_str = rtrim($str); //去除右边的空格
|
||||||
|
|
||||||
|
$str = $valid_str;
|
||||||
|
$output = ''; //需要输出的字符串
|
||||||
|
|
||||||
|
if($type == true){ //标点
|
||||||
|
$type_str = ''; //类型字符串
|
||||||
|
$data_str = '';
|
||||||
|
$flag = 0;
|
||||||
|
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
if(!ctype_punct($ch)){
|
||||||
|
$flag = 1;
|
||||||
|
}
|
||||||
|
if($flag == 0)
|
||||||
|
$type_str .= $ch;
|
||||||
|
else
|
||||||
|
$data_str .= $ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type_str){
|
||||||
|
case '#':
|
||||||
|
$wrap = 'h1';
|
||||||
|
$this->flag_like = 'h1';
|
||||||
|
break;
|
||||||
|
case '##':
|
||||||
|
$wrap = 'h2';
|
||||||
|
$this->flag_like = 'h2';
|
||||||
|
break;
|
||||||
|
case '###':
|
||||||
|
$wrap = 'h3';
|
||||||
|
$this->flag_like = 'h3';
|
||||||
|
break;
|
||||||
|
case '####':
|
||||||
|
$wrap = 'h4';
|
||||||
|
$this->flag_like = 'h4';
|
||||||
|
break;
|
||||||
|
case '#####':
|
||||||
|
$wrap = 'h5';
|
||||||
|
$this->flag_like = 'h5';
|
||||||
|
break;
|
||||||
|
case '######':
|
||||||
|
$wrap = 'h6';
|
||||||
|
$this->flag_like = 'h6';
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '```': //代码模式,不进行干扰
|
||||||
|
if($this->flag != 'code'){ //不为code,判断是否为单行代码
|
||||||
|
$output.='<pre>';
|
||||||
|
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
|
||||||
|
$output.="$mat[1]</pre>$mat[2]";
|
||||||
|
$str = '';
|
||||||
|
$data_str = '';
|
||||||
|
}else{
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'code'; //代码
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$output.='</pre>';
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
|
||||||
|
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
|
||||||
|
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'a'; //网址
|
||||||
|
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
|
||||||
|
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
|
||||||
|
}else{
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[-]':
|
||||||
|
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
break;
|
||||||
|
case '![':
|
||||||
|
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'img';
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p'; //没有模式
|
||||||
|
$output.="$str";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*': //斜体
|
||||||
|
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'i';
|
||||||
|
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
|
||||||
|
$str=$mat[1];
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '**': //粗体
|
||||||
|
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'b';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$output.=$str;
|
||||||
|
$this->flag_like = 'html';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!$this->check()){ //非代码模式
|
||||||
|
if(preg_match('/^>+$/',$type_str)){ //引用
|
||||||
|
$level = strlen($type_str);
|
||||||
|
$this->flag_like = 'quote';
|
||||||
|
$output.=$this->genQuote($level,$data_str); //引用
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
|
||||||
|
if($this->flag == 'table'){
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
|
||||||
|
}else{ //非表格格式,上一行没有标题
|
||||||
|
$this->flag_like = 'p'; //没有格式
|
||||||
|
$output.=$this->buf;
|
||||||
|
$this->buf = '';
|
||||||
|
}
|
||||||
|
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
|
||||||
|
$output.='<hr>';
|
||||||
|
$this->flag_like = 'hr';
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p';
|
||||||
|
$output.=$str.'<br>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$br = '';
|
||||||
|
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
|
||||||
|
$data_str = htmlspecialchars($mat[1]);
|
||||||
|
if(!$this->check()){ //代码
|
||||||
|
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
|
||||||
|
}else if($type_str!='```'){
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}
|
||||||
|
}else{ //首个非空字符不为符号
|
||||||
|
if($this->flag == 'code'){ //代码,直接输出
|
||||||
|
$str=str_replace("\t",' ',$str);
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
|
||||||
|
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
|
||||||
|
$this->flag_like = 'ol';
|
||||||
|
$output.=$str;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'idel';
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
$output.=$ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output.='<br>';
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
|
||||||
|
$mat = explode('|',$str);
|
||||||
|
|
||||||
|
if($this->flag!='table'){ //进入表格
|
||||||
|
$this->buf = $str;
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$wrap = '';
|
||||||
|
}else{
|
||||||
|
$output.=$this->genRow($str);
|
||||||
|
}
|
||||||
|
//echo $mat[0].'<br>';
|
||||||
|
//var_dump($mat);
|
||||||
|
}else{ //其他
|
||||||
|
$this->flag = 'p';
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->check()){ //不为代码,设置flag
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = $this->flag_like;
|
||||||
|
if($this->flag_pre == 'table' && $this->flag != 'table')
|
||||||
|
$output='</table>'.$output;
|
||||||
|
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
|
||||||
|
$output='</ul>'.$output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parseInner($output); //输出需要输出的内容
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取输出内容
|
||||||
|
public function output(){
|
||||||
|
$this->parse();
|
||||||
|
echo implode('',$this->lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
public/blog/md0/index.php
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
require './MD.php';
|
||||||
|
|
||||||
|
$md=new MD('114514.md');
|
||||||
|
$md->output();
|
||||||
479
public/blog/md0/src/php-markdown/MD.php
Executable file
@@ -0,0 +1,479 @@
|
|||||||
|
|
||||||
|
<?php
|
||||||
|
Header('Content:text/html;charset=utf-8');
|
||||||
|
?>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body,ol,ul,li,img,p{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li{
|
||||||
|
list-style-type: square;
|
||||||
|
padding:2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6{
|
||||||
|
margin:10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3{
|
||||||
|
border-bottom:solid 1px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
padding-bottom:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2{
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3{
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,ul{
|
||||||
|
padding:10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
max-width:1024px;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote{
|
||||||
|
border-left:solid 4px #bbb;
|
||||||
|
background-color:#eee;
|
||||||
|
min-height:24px;
|
||||||
|
line-height:24px;
|
||||||
|
padding:0px 10px;
|
||||||
|
margin:0;
|
||||||
|
color:#333;
|
||||||
|
font-size:12px;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: consolas,楷体;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table,td,th{
|
||||||
|
border:solid 1px #ddd;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding:10px;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
margin:10px 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-left{
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-right{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even){
|
||||||
|
background-color:#eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
code,pre{
|
||||||
|
border-radius:5px;
|
||||||
|
border:solid 1px #eee;
|
||||||
|
background-color:#f9f9f9;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
code{
|
||||||
|
padding:2px 12px;
|
||||||
|
display: inline-block;
|
||||||
|
margin:10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre{
|
||||||
|
padding:10px 12px;
|
||||||
|
overflow-x:auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* flag规则:
|
||||||
|
* h1-h6 标题
|
||||||
|
* u1,u2 无序列表
|
||||||
|
* ol 有序列表
|
||||||
|
* p 普通文本
|
||||||
|
* code 代码
|
||||||
|
* table 文本
|
||||||
|
* check 选择
|
||||||
|
* uncheck 未选择
|
||||||
|
* quote 引用
|
||||||
|
* img 图片
|
||||||
|
* url 网址
|
||||||
|
* bold 加粗
|
||||||
|
* italia 斜体
|
||||||
|
* el 空行
|
||||||
|
*
|
||||||
|
* idel 闲置
|
||||||
|
*/
|
||||||
|
class MD{
|
||||||
|
|
||||||
|
private $file; //当前文件
|
||||||
|
private $mdGen; //生成器
|
||||||
|
private $flag; //当前标志
|
||||||
|
private $flag_pre; //上一次的flag
|
||||||
|
private $flag_like; //假定类型
|
||||||
|
|
||||||
|
private $line_count; //总行数
|
||||||
|
private $lines; //所有行
|
||||||
|
private $buf; //缓存行
|
||||||
|
|
||||||
|
public function __construct($filename){
|
||||||
|
$this->file = $filename; //设置当前文件
|
||||||
|
$this->mdGen = $this->content($filename); //获取生成器
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
$this->lines = array(); //所有行状态
|
||||||
|
$this->line_count = 0; //行数归0
|
||||||
|
}
|
||||||
|
|
||||||
|
private function content($file){ //获取生成器
|
||||||
|
if(file_exists($file)){
|
||||||
|
$fh = fopen($file,"r");
|
||||||
|
while(!feof($fh)){
|
||||||
|
yield fgets($fh);
|
||||||
|
}
|
||||||
|
fclose($fh);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历每一个字符
|
||||||
|
private function every($str){
|
||||||
|
$l = strlen($str);
|
||||||
|
for($i=0;$i<$l;$i++)
|
||||||
|
if(ord($str[$i])<0x80)
|
||||||
|
yield $str[$i];
|
||||||
|
else{
|
||||||
|
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
|
||||||
|
$i+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析
|
||||||
|
private function parse(){
|
||||||
|
$ctnt = $this->mdGen; //生成器
|
||||||
|
$ret=array();
|
||||||
|
if($ctnt != null){
|
||||||
|
$ret = array();
|
||||||
|
foreach($ctnt as $line){
|
||||||
|
if($this->flag != 'code')
|
||||||
|
$line=ltrim($line); //删除左边
|
||||||
|
if(strlen($line)){
|
||||||
|
$ch = $line[0]; //判断第一个字符
|
||||||
|
$type=ctype_punct($ch);//标点符号
|
||||||
|
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
|
||||||
|
$ret[] = $this->parseLine($line,$type); //解析行
|
||||||
|
}else{ //空行
|
||||||
|
switch($this->flag){
|
||||||
|
case 'ul':
|
||||||
|
case 'ol':
|
||||||
|
$ret[]="</$this->flag>";
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel';
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
$this->flag = 'idel';
|
||||||
|
$ret[]='</table>';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if($this->flag != 'el') $ret[] = '<br>';
|
||||||
|
$this->flag = 'el'; //空行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->lines = $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成blockquote
|
||||||
|
private function genQuote($level,$content){
|
||||||
|
if($level<=0) return "";
|
||||||
|
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查是否处于某个状态,默认检查是否处于代码状态
|
||||||
|
private function check($value='code'){
|
||||||
|
return ($this->flag == $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成一行新的表格列
|
||||||
|
* $data:需要输入的数据
|
||||||
|
* $type:生成类型
|
||||||
|
* $wrap:最快层包裹
|
||||||
|
* $sep:分隔符
|
||||||
|
*/
|
||||||
|
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
|
||||||
|
$ret='';
|
||||||
|
$mat = explode($sep,$data);
|
||||||
|
foreach($mat as $elem)
|
||||||
|
$ret.="<$type>".$elem."</$type>";
|
||||||
|
return "<$wrap>".$ret."</$wrap>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析行内元素
|
||||||
|
* bold,italic,code,link,pic
|
||||||
|
*/
|
||||||
|
private function parseInner($str){
|
||||||
|
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
|
||||||
|
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
|
||||||
|
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
|
||||||
|
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
|
||||||
|
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照给定规则解析字符串:
|
||||||
|
* type:
|
||||||
|
* true 符号
|
||||||
|
* false 文字
|
||||||
|
* 返回:
|
||||||
|
* array('type'=>类型,'parts'=>array(...))
|
||||||
|
*/
|
||||||
|
private function parseLine($str,$type){
|
||||||
|
if(strlen($str) == 0){
|
||||||
|
return array('type'=>'p','parts'=>[]); //返回空段
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid_str = rtrim($str); //去除右边的空格
|
||||||
|
|
||||||
|
$str = $valid_str;
|
||||||
|
$output = ''; //需要输出的字符串
|
||||||
|
|
||||||
|
if($type == true){ //标点
|
||||||
|
$type_str = ''; //类型字符串
|
||||||
|
$data_str = '';
|
||||||
|
$flag = 0;
|
||||||
|
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
if(!ctype_punct($ch)){
|
||||||
|
$flag = 1;
|
||||||
|
}
|
||||||
|
if($flag == 0)
|
||||||
|
$type_str .= $ch;
|
||||||
|
else
|
||||||
|
$data_str .= $ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type_str){
|
||||||
|
case '#':
|
||||||
|
$wrap = 'h1';
|
||||||
|
$this->flag_like = 'h1';
|
||||||
|
break;
|
||||||
|
case '##':
|
||||||
|
$wrap = 'h2';
|
||||||
|
$this->flag_like = 'h2';
|
||||||
|
break;
|
||||||
|
case '###':
|
||||||
|
$wrap = 'h3';
|
||||||
|
$this->flag_like = 'h3';
|
||||||
|
break;
|
||||||
|
case '####':
|
||||||
|
$wrap = 'h4';
|
||||||
|
$this->flag_like = 'h4';
|
||||||
|
break;
|
||||||
|
case '#####':
|
||||||
|
$wrap = 'h5';
|
||||||
|
$this->flag_like = 'h5';
|
||||||
|
break;
|
||||||
|
case '######':
|
||||||
|
$wrap = 'h6';
|
||||||
|
$this->flag_like = 'h6';
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '```': //代码模式,不进行干扰
|
||||||
|
if($this->flag != 'code'){ //不为code,判断是否为单行代码
|
||||||
|
$output.='<pre>';
|
||||||
|
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
|
||||||
|
$output.="$mat[1]</pre>$mat[2]";
|
||||||
|
$str = '';
|
||||||
|
$data_str = '';
|
||||||
|
}else{
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'code'; //代码
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$output.='</pre>';
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
|
||||||
|
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
|
||||||
|
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'a'; //网址
|
||||||
|
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
|
||||||
|
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
|
||||||
|
}else{
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[-]':
|
||||||
|
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
break;
|
||||||
|
case '![':
|
||||||
|
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'img';
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p'; //没有模式
|
||||||
|
$output.="$str";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*': //斜体
|
||||||
|
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'i';
|
||||||
|
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
|
||||||
|
$str=$mat[1];
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '**': //粗体
|
||||||
|
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'b';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$output.=$str;
|
||||||
|
$this->flag_like = 'html';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!$this->check()){ //非代码模式
|
||||||
|
if(preg_match('/^>+$/',$type_str)){ //引用
|
||||||
|
$level = strlen($type_str);
|
||||||
|
$this->flag_like = 'quote';
|
||||||
|
$output.=$this->genQuote($level,$data_str); //引用
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
|
||||||
|
if($this->flag == 'table'){
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
|
||||||
|
}else{ //非表格格式,上一行没有标题
|
||||||
|
$this->flag_like = 'p'; //没有格式
|
||||||
|
$output.=$this->buf;
|
||||||
|
$this->buf = '';
|
||||||
|
}
|
||||||
|
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
|
||||||
|
$output.='<hr>';
|
||||||
|
$this->flag_like = 'hr';
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p';
|
||||||
|
$output.=$str.'<br>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$br = '';
|
||||||
|
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
|
||||||
|
$data_str = htmlspecialchars($mat[1]);
|
||||||
|
if(!$this->check()){ //代码
|
||||||
|
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
|
||||||
|
}else if($type_str!='```'){
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}
|
||||||
|
}else{ //首个非空字符不为符号
|
||||||
|
if($this->flag == 'code'){ //代码,直接输出
|
||||||
|
$str=str_replace("\t",' ',$str);
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
|
||||||
|
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
|
||||||
|
$this->flag_like = 'ol';
|
||||||
|
$output.=$str;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'idel';
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
$output.=$ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output.='<br>';
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
|
||||||
|
$mat = explode('|',$str);
|
||||||
|
|
||||||
|
if($this->flag!='table'){ //进入表格
|
||||||
|
$this->buf = $str;
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$wrap = '';
|
||||||
|
}else{
|
||||||
|
$output.=$this->genRow($str);
|
||||||
|
}
|
||||||
|
//echo $mat[0].'<br>';
|
||||||
|
//var_dump($mat);
|
||||||
|
}else{ //其他
|
||||||
|
$this->flag = 'p';
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->check()){ //不为代码,设置flag
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = $this->flag_like;
|
||||||
|
if($this->flag_pre == 'table' && $this->flag != 'table')
|
||||||
|
$output='</table>'.$output;
|
||||||
|
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
|
||||||
|
$output='</ul>'.$output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parseInner($output); //输出需要输出的内容
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取输出内容
|
||||||
|
public function output(){
|
||||||
|
$this->parse();
|
||||||
|
echo implode('',$this->lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
public/blog/md0/src/php-markdown/demo/index.php
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
require '../MD.php';
|
||||||
|
|
||||||
|
$md=new MD('test.md');
|
||||||
|
$md->output();
|
||||||
81
public/blog/md0/src/php-markdown/demo/test.md
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
# 一级标题
|
||||||
|
## 二级标题
|
||||||
|
### 三级标题
|
||||||
|
#### 四级标题
|
||||||
|
##### 五级标题
|
||||||
|
###### 六级标题
|
||||||
|
*斜体*
|
||||||
|
**粗体**
|
||||||
|
- 项目1
|
||||||
|
- 项目2
|
||||||
|
- 项目3
|
||||||
|
- 项目4
|
||||||
|
+ 项目5
|
||||||
|
+ 项目6
|
||||||
|
+ 项目7
|
||||||
|
|
||||||
|
1. apple
|
||||||
|
2. boy
|
||||||
|
3. cat
|
||||||
|
|
||||||
|
[ ] 选择1
|
||||||
|
[-] 选择2
|
||||||
|
[-] 选择3
|
||||||
|
[ ] 选择4
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
void test();
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
printf("Hello,World!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test(){
|
||||||
|
printf("Hello,World!");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[百度](https://www.baidu.com)
|
||||||
|

|
||||||
|
|
||||||
|
**blockquote使用方法**
|
||||||
|
>引言,这是一句引言
|
||||||
|
>Hello,World!
|
||||||
|
>>二级引言
|
||||||
|
>>>三级引言
|
||||||
|
|
||||||
|
apple|boy|cat
|
||||||
|
---|---|---
|
||||||
|
a|b|c
|
||||||
|
d|e|f
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Apple</th>
|
||||||
|
<th>Boy</th>
|
||||||
|
<th>Cat</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>a</td>
|
||||||
|
<td>b</td>
|
||||||
|
<td>c</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>d</td>
|
||||||
|
<td>e</td>
|
||||||
|
<td>f</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
> I o u
|
||||||
|
> This is just a test...
|
||||||
|
>> Hello
|
||||||
|
> World
|
||||||
1
public/blog/md0/src/php-markdown/index.html
Executable file
@@ -0,0 +1 @@
|
|||||||
|
<meta http-equiv="refresh" content="0.1;url=https://github.com/ixysoft/php-markdown">
|
||||||
100
public/blog/post/index.php
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<head>
|
||||||
|
<link rel="icon" type="image/x-icon" href="https://ww3.tw/blog/icon/original.ico">
|
||||||
|
<title>文章列表</title> <!-- 标题 -->
|
||||||
|
</head>
|
||||||
|
<body id=wallpaper>
|
||||||
|
<!-- 背景 -->
|
||||||
|
<div id="div_1">
|
||||||
|
<?php
|
||||||
|
// 设定数据库路径
|
||||||
|
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 连接数据库
|
||||||
|
$db = new SQLite3($db_path);
|
||||||
|
// 连接成功输出连接成功
|
||||||
|
echo "<!--数据库连接成功-->";
|
||||||
|
// 如果连接成功,但是内部状态有问题
|
||||||
|
if ($db->lastErrorCode() !==0) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容区
|
||||||
|
// 执行sql命令 查询表单
|
||||||
|
$select_id_date_title_from_posts_btos /*查询posts表单中的id date title id从大到小排列*/ = $db->query('SELECT id, date, title FROM posts ORDER BY id DESC'); // 执行查询posts表单中的id date title id从大到小排列的命令
|
||||||
|
// 循环 写入
|
||||||
|
|
||||||
|
echo "<a href='https://ww3.tw' style='background-color: rgba(147, 185, 255, 0.644);position: absolute;'>返回首页</a>";
|
||||||
|
echo "<center><b><h2>全部文章</h2></b></center>";
|
||||||
|
echo "<br>";
|
||||||
|
echo "文章如下↓";
|
||||||
|
echo "<br>";
|
||||||
|
echo "<br>";
|
||||||
|
echo "<br>";
|
||||||
|
|
||||||
|
echo "<div id='content'>"; # 内容排版
|
||||||
|
|
||||||
|
while ($row = $select_id_date_title_from_posts_btos->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
|
||||||
|
echo "文章id: " . $row['id'] . "<br>";
|
||||||
|
echo $row['date'] . " " . "文章标题: " . $row['title'] . "<br>";
|
||||||
|
echo "<a href='https://ww3.tw/blog/post/s/?id=" . $row['id'] . "'>页面跳转</a><br><br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</div>"; # 内容排版
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
|
||||||
|
// 捕获php报错
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机变换图床api
|
||||||
|
|
||||||
|
$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', 'https://api.ww3.tw/touhou'];
|
||||||
|
$suiji_wallpaper = rand(0, count($wallpaper_apis) - 1);
|
||||||
|
$wallpaper = $wallpaper_apis[$suiji_wallpaper];
|
||||||
|
// 显示图床url在页面
|
||||||
|
echo "<div id='wallpaper_url'>图片来源: " . $wallpaper . "</div>";
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#wallpaper {
|
||||||
|
background-image: url(<?php
|
||||||
|
echo $wallpaper;
|
||||||
|
?>); /*图片地址*/ /* https://api.sretna.cn/api/pc.php */
|
||||||
|
background-repeat: no-repeat; /*禁止平铺*/
|
||||||
|
background-size: 100% 100%; /*图片占满100%*/
|
||||||
|
margin: 0; /* 外边框为0 */
|
||||||
|
/*padding: 0;*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#div_1 {
|
||||||
|
height: 100%;
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
font-size: 19px;
|
||||||
|
background-color: rgba(169, 169, 169, 0.48);
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 0px 0px 0px 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wallpaper_url {
|
||||||
|
color: rgba(255, 0, 0, 0.354);
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 20% 0px 0px 75%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
100
public/blog/post/s/index.php
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
// 设置最大接受id
|
||||||
|
const MAX_ARTICLE_ID = 100000;
|
||||||
|
|
||||||
|
// 获取搜索栏url的id
|
||||||
|
$post_id = $_GET['id'] ?? null;
|
||||||
|
|
||||||
|
// 设定数据库路径
|
||||||
|
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2. 严格的输入验证 (健壮性检查)
|
||||||
|
* 拦截所有非数字、无效范围或为空的输入
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
empty($post_id) ||
|
||||||
|
!is_numeric($post_id) ||
|
||||||
|
(int)$post_id <= 0 ||
|
||||||
|
(int)$post_id > MAX_ARTICLE_ID
|
||||||
|
) {
|
||||||
|
http_response_code(400); // HTTP 400 Bad Request
|
||||||
|
|
||||||
|
$error_msg = "错误:文章 ID 格式不正确。ID 必须是 1 到 " . MAX_ARTICLE_ID . " 之间的整数。";
|
||||||
|
die($error_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过检查后,将 ID 强制转换为整数
|
||||||
|
$post_id = (int)$post_id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
/**
|
||||||
|
* 3. 连接 SQLite 数据库
|
||||||
|
* 注意:如果 PHP 运行用户没有读取此路径文件的权限,这里会失败。
|
||||||
|
*/
|
||||||
|
$db = new SQLite3($db_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4. 准备 SQL 查询语句 (核心安全防线:预处理语句)
|
||||||
|
* 使用占位符 :id 代替用户输入。
|
||||||
|
*/
|
||||||
|
$sql = 'SELECT title, content FROM posts WHERE id = :id';
|
||||||
|
|
||||||
|
// 准备语句
|
||||||
|
$stmt = $db->prepare($sql);
|
||||||
|
|
||||||
|
// 绑定参数:将 :id 替换为 $post_id 的值,并明确指定它是一个整数类型
|
||||||
|
$stmt->bindValue(':id', $post_id, SQLITE3_INTEGER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5. 执行查询并获取结果
|
||||||
|
*/
|
||||||
|
$result = $stmt->execute();
|
||||||
|
|
||||||
|
// 从结果集中获取一行数据
|
||||||
|
$row = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 6. 显示内容或 404 错误
|
||||||
|
*/
|
||||||
|
if ($row) {
|
||||||
|
// 使用 htmlspecialchars() 函数防止 XSS 攻击
|
||||||
|
$title = $row['title'];
|
||||||
|
$content = $row['content'];
|
||||||
|
|
||||||
|
// --- 页面输出开始 ---
|
||||||
|
echo "<!DOCTYPE html>";
|
||||||
|
echo "<html lang='zh-CN'>";
|
||||||
|
echo "<head><meta charset='UTF-8'><title>{$title}</title></head>";
|
||||||
|
echo "<body>";
|
||||||
|
echo "<a href='https://ww3.tw'>返回主页</a>";
|
||||||
|
echo "<h1>{$title}</h1>";
|
||||||
|
|
||||||
|
// nl2br 用于将换行符转换成 <br>
|
||||||
|
echo "<article>" . nl2br($content) . "</article>";
|
||||||
|
|
||||||
|
echo "</body>";
|
||||||
|
echo "</html>";
|
||||||
|
// --- 页面输出结束 ---
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 文章未找到
|
||||||
|
http_response_code(404); // 404 Not Found
|
||||||
|
echo "<h1>404 Not Found</h1>";
|
||||||
|
echo "<p>抱歉,ID 为 {$post_id} 的文章不存在。</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 7. 清理资源
|
||||||
|
*/
|
||||||
|
$db->close();
|
||||||
|
//$stmt->close();
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// 处理异常
|
||||||
|
http_response_code(500); // 500 Internal Server Error
|
||||||
|
error_log("SQLite 错误: " . $e->getMessage());
|
||||||
|
die("系统错误,请稍后重试。");
|
||||||
|
}
|
||||||
|
?>
|
||||||
2
static/robots.txt → public/blog/robots.txt
Executable file → Normal file
@@ -2,6 +2,6 @@ User-agent: *
|
|||||||
|
|
||||||
Allow: /
|
Allow: /
|
||||||
|
|
||||||
Disallow: /kami/
|
Disallow: /admin/
|
||||||
|
|
||||||
Sitemap: https://open-ww3-project.ww3.tw/blog/sitemap.xml
|
Sitemap: https://open-ww3-project.ww3.tw/blog/sitemap.xml
|
||||||
23
public/blog/sitemap.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/</loc>
|
||||||
|
<lastmod>2025-12-12</lastmod>
|
||||||
|
<priority>1.0</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/about/</loc>
|
||||||
|
<lastmod>2025-12-12</lastmod>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/post/</loc>
|
||||||
|
<lastmod>2025-12-12</lastmod>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/test.html</loc>
|
||||||
|
<lastmod>2025-12-13</lastmod>
|
||||||
|
<priority>0.1</priority>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
||||||
0
static/css/main.css → public/blog/src/css/main.css
Executable file → Normal file
0
static/img/my_girl.png → public/blog/src/img/my_girl.png
Executable file → Normal file
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 280 KiB |
0
static/js/main.js → public/blog/src/js/main.js
Executable file → Normal file
5033
public/blog/test.html
Normal file
0
static/tui_jian/index.html → public/blog/tui_jian/index.php
Executable file → Normal file
0
static/video.html → public/blog/video.html
Executable file → Normal file
25
public/docker-registry/all-images/index.php
Executable 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;
|
||||||
|
|
||||||
|
?>
|
||||||
11
public/docker-registry/index.html
Executable 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>
|
||||||
29
public/index.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!-- 主路由配置 -->
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
// 定义条件
|
||||||
|
$found_route = false;
|
||||||
|
|
||||||
|
|
||||||
|
switch($request_uri){
|
||||||
|
case '/':
|
||||||
|
include './re_blog.php';
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts 路由
|
||||||
|
// 整改中
|
||||||
|
|
||||||
|
|
||||||
|
// 所有路由匹配结束后,检查是否找到路由
|
||||||
|
if (!$found_route) {
|
||||||
|
// 设置 HTTP 状态码为 404
|
||||||
|
header("HTTP/1.0 404 Not Found");
|
||||||
|
// 包含 404 页面文件
|
||||||
|
//exit();
|
||||||
|
include "../src/views/error/404.html";
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
}
|
||||||
29
public/index.php.back
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
<!-- 主路由配置 -->
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
// 定义条件
|
||||||
|
$found_route = false;
|
||||||
|
|
||||||
|
|
||||||
|
switch($request_uri){
|
||||||
|
case '/':
|
||||||
|
include './re_blog.php';
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts 路由
|
||||||
|
// 整改中
|
||||||
|
|
||||||
|
|
||||||
|
// 所有路由匹配结束后,检查是否找到路由
|
||||||
|
if (!$found_route) {
|
||||||
|
// 设置 HTTP 状态码为 404
|
||||||
|
header("HTTP/1.0 404 Not Found");
|
||||||
|
// 包含 404 页面文件
|
||||||
|
//exit();
|
||||||
|
include "../src/views/error/404.html";
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
}
|
||||||
9
public/jumping-message/index.php
Executable 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
@@ -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>
|
||||||
0
packages/__init__.py → public/message/static/css/message.css
Normal file → Executable file
4
public/message/static/css/navbar/body_color.css
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#body_color
|
||||||
|
{
|
||||||
|
background-color: rgba(147, 185, 255, 0.644);
|
||||||
|
}
|
||||||
14
public/message/static/css/navbar/index-css.html
Executable 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>
|
||||||
0
public/message/static/css/video.css
Executable file
3
public/message/static/html/content_message.html
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
BIN
public/message/static/icon/original.ico
Executable file
|
After Width: | Height: | Size: 268 KiB |
0
public/message/static/js/video.js
Executable file
26
public/message/static/php/google_translate.php
Executable 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>
|
||||||
|
|
||||||
|
<!-- 谷歌翻译 -->
|
||||||
1
public/message/static/txt/message.txt
Executable file
@@ -0,0 +1 @@
|
|||||||
|
这是测试
|
||||||
1
public/message/static/txt/测试.txt
Executable file
@@ -0,0 +1 @@
|
|||||||
|
测试
|
||||||
2
public/re_blog.php
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
<!-- 域名跳转 ./blog/ -->
|
||||||
|
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/blog/">
|
||||||
BIN
public/short-url/icon/icon.jpg
Executable file
|
After Width: | Height: | Size: 17 KiB |
12
public/short-url/index.php
Executable 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
@@ -0,0 +1 @@
|
|||||||
|
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/short-url/">
|
||||||
BIN
public/static/error/cirno-image.jpg
Executable file
|
After Width: | Height: | Size: 18 KiB |
14
public/static/html/black-block.html
Executable 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>
|
||||||
@@ -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
|
|
||||||
11
src/md/1.md
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
# 今天、2025.7.30
|
||||||
|
----
|
||||||
|
|
||||||
|
blog 正式 完工
|
||||||
|
|
||||||
|
测试
|
||||||
|
|
||||||
|
**署名**
|
||||||
|
|
||||||
|
<br>
|
||||||
|
SkimrMe_
|
||||||
479
src/md/MD.php
Executable file
@@ -0,0 +1,479 @@
|
|||||||
|
|
||||||
|
<?php
|
||||||
|
Header('Content:text/html;charset=utf-8');
|
||||||
|
?>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body,ol,ul,li,img,p{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li{
|
||||||
|
list-style-type: square;
|
||||||
|
padding:2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6{
|
||||||
|
margin:10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3{
|
||||||
|
border-bottom:solid 1px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
padding-bottom:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2{
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3{
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,ul{
|
||||||
|
padding:10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
max-width:1024px;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote{
|
||||||
|
border-left:solid 4px #bbb;
|
||||||
|
background-color:#eee;
|
||||||
|
min-height:24px;
|
||||||
|
line-height:24px;
|
||||||
|
padding:0px 10px;
|
||||||
|
margin:0;
|
||||||
|
color:#333;
|
||||||
|
font-size:12px;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: consolas,楷体;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table,td,th{
|
||||||
|
border:solid 1px #ddd;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding:10px;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
margin:10px 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-left{
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-right{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even){
|
||||||
|
background-color:#eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
code,pre{
|
||||||
|
border-radius:5px;
|
||||||
|
border:solid 1px #eee;
|
||||||
|
background-color:#f9f9f9;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
code{
|
||||||
|
padding:2px 12px;
|
||||||
|
display: inline-block;
|
||||||
|
margin:10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre{
|
||||||
|
padding:10px 12px;
|
||||||
|
overflow-x:auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* flag规则:
|
||||||
|
* h1-h6 标题
|
||||||
|
* u1,u2 无序列表
|
||||||
|
* ol 有序列表
|
||||||
|
* p 普通文本
|
||||||
|
* code 代码
|
||||||
|
* table 文本
|
||||||
|
* check 选择
|
||||||
|
* uncheck 未选择
|
||||||
|
* quote 引用
|
||||||
|
* img 图片
|
||||||
|
* url 网址
|
||||||
|
* bold 加粗
|
||||||
|
* italia 斜体
|
||||||
|
* el 空行
|
||||||
|
*
|
||||||
|
* idel 闲置
|
||||||
|
*/
|
||||||
|
class MD{
|
||||||
|
|
||||||
|
private $file; //当前文件
|
||||||
|
private $mdGen; //生成器
|
||||||
|
private $flag; //当前标志
|
||||||
|
private $flag_pre; //上一次的flag
|
||||||
|
private $flag_like; //假定类型
|
||||||
|
|
||||||
|
private $line_count; //总行数
|
||||||
|
private $lines; //所有行
|
||||||
|
private $buf; //缓存行
|
||||||
|
|
||||||
|
public function __construct($filename){
|
||||||
|
$this->file = $filename; //设置当前文件
|
||||||
|
$this->mdGen = $this->content($filename); //获取生成器
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
$this->lines = array(); //所有行状态
|
||||||
|
$this->line_count = 0; //行数归0
|
||||||
|
}
|
||||||
|
|
||||||
|
private function content($file){ //获取生成器
|
||||||
|
if(file_exists($file)){
|
||||||
|
$fh = fopen($file,"r");
|
||||||
|
while(!feof($fh)){
|
||||||
|
yield fgets($fh);
|
||||||
|
}
|
||||||
|
fclose($fh);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历每一个字符
|
||||||
|
private function every($str){
|
||||||
|
$l = strlen($str);
|
||||||
|
for($i=0;$i<$l;$i++)
|
||||||
|
if(ord($str[$i])<0x80)
|
||||||
|
yield $str[$i];
|
||||||
|
else{
|
||||||
|
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
|
||||||
|
$i+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析
|
||||||
|
private function parse(){
|
||||||
|
$ctnt = $this->mdGen; //生成器
|
||||||
|
$ret=array();
|
||||||
|
if($ctnt != null){
|
||||||
|
$ret = array();
|
||||||
|
foreach($ctnt as $line){
|
||||||
|
if($this->flag != 'code')
|
||||||
|
$line=ltrim($line); //删除左边
|
||||||
|
if(strlen($line)){
|
||||||
|
$ch = $line[0]; //判断第一个字符
|
||||||
|
$type=ctype_punct($ch);//标点符号
|
||||||
|
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
|
||||||
|
$ret[] = $this->parseLine($line,$type); //解析行
|
||||||
|
}else{ //空行
|
||||||
|
switch($this->flag){
|
||||||
|
case 'ul':
|
||||||
|
case 'ol':
|
||||||
|
$ret[]="</$this->flag>";
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel';
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
$this->flag = 'idel';
|
||||||
|
$ret[]='</table>';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if($this->flag != 'el') $ret[] = '<br>';
|
||||||
|
$this->flag = 'el'; //空行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->lines = $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成blockquote
|
||||||
|
private function genQuote($level,$content){
|
||||||
|
if($level<=0) return "";
|
||||||
|
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查是否处于某个状态,默认检查是否处于代码状态
|
||||||
|
private function check($value='code'){
|
||||||
|
return ($this->flag == $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成一行新的表格列
|
||||||
|
* $data:需要输入的数据
|
||||||
|
* $type:生成类型
|
||||||
|
* $wrap:最快层包裹
|
||||||
|
* $sep:分隔符
|
||||||
|
*/
|
||||||
|
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
|
||||||
|
$ret='';
|
||||||
|
$mat = explode($sep,$data);
|
||||||
|
foreach($mat as $elem)
|
||||||
|
$ret.="<$type>".$elem."</$type>";
|
||||||
|
return "<$wrap>".$ret."</$wrap>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析行内元素
|
||||||
|
* bold,italic,code,link,pic
|
||||||
|
*/
|
||||||
|
private function parseInner($str){
|
||||||
|
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
|
||||||
|
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
|
||||||
|
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
|
||||||
|
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
|
||||||
|
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照给定规则解析字符串:
|
||||||
|
* type:
|
||||||
|
* true 符号
|
||||||
|
* false 文字
|
||||||
|
* 返回:
|
||||||
|
* array('type'=>类型,'parts'=>array(...))
|
||||||
|
*/
|
||||||
|
private function parseLine($str,$type){
|
||||||
|
if(strlen($str) == 0){
|
||||||
|
return array('type'=>'p','parts'=>[]); //返回空段
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid_str = rtrim($str); //去除右边的空格
|
||||||
|
|
||||||
|
$str = $valid_str;
|
||||||
|
$output = ''; //需要输出的字符串
|
||||||
|
|
||||||
|
if($type == true){ //标点
|
||||||
|
$type_str = ''; //类型字符串
|
||||||
|
$data_str = '';
|
||||||
|
$flag = 0;
|
||||||
|
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
if(!ctype_punct($ch)){
|
||||||
|
$flag = 1;
|
||||||
|
}
|
||||||
|
if($flag == 0)
|
||||||
|
$type_str .= $ch;
|
||||||
|
else
|
||||||
|
$data_str .= $ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type_str){
|
||||||
|
case '#':
|
||||||
|
$wrap = 'h1';
|
||||||
|
$this->flag_like = 'h1';
|
||||||
|
break;
|
||||||
|
case '##':
|
||||||
|
$wrap = 'h2';
|
||||||
|
$this->flag_like = 'h2';
|
||||||
|
break;
|
||||||
|
case '###':
|
||||||
|
$wrap = 'h3';
|
||||||
|
$this->flag_like = 'h3';
|
||||||
|
break;
|
||||||
|
case '####':
|
||||||
|
$wrap = 'h4';
|
||||||
|
$this->flag_like = 'h4';
|
||||||
|
break;
|
||||||
|
case '#####':
|
||||||
|
$wrap = 'h5';
|
||||||
|
$this->flag_like = 'h5';
|
||||||
|
break;
|
||||||
|
case '######':
|
||||||
|
$wrap = 'h6';
|
||||||
|
$this->flag_like = 'h6';
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '```': //代码模式,不进行干扰
|
||||||
|
if($this->flag != 'code'){ //不为code,判断是否为单行代码
|
||||||
|
$output.='<pre>';
|
||||||
|
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
|
||||||
|
$output.="$mat[1]</pre>$mat[2]";
|
||||||
|
$str = '';
|
||||||
|
$data_str = '';
|
||||||
|
}else{
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'code'; //代码
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$output.='</pre>';
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
|
||||||
|
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
|
||||||
|
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'a'; //网址
|
||||||
|
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
|
||||||
|
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
|
||||||
|
}else{
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[-]':
|
||||||
|
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
break;
|
||||||
|
case '![':
|
||||||
|
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'img';
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p'; //没有模式
|
||||||
|
$output.="$str";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*': //斜体
|
||||||
|
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'i';
|
||||||
|
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
|
||||||
|
$str=$mat[1];
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '**': //粗体
|
||||||
|
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'b';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$output.=$str;
|
||||||
|
$this->flag_like = 'html';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!$this->check()){ //非代码模式
|
||||||
|
if(preg_match('/^>+$/',$type_str)){ //引用
|
||||||
|
$level = strlen($type_str);
|
||||||
|
$this->flag_like = 'quote';
|
||||||
|
$output.=$this->genQuote($level,$data_str); //引用
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
|
||||||
|
if($this->flag == 'table'){
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
|
||||||
|
}else{ //非表格格式,上一行没有标题
|
||||||
|
$this->flag_like = 'p'; //没有格式
|
||||||
|
$output.=$this->buf;
|
||||||
|
$this->buf = '';
|
||||||
|
}
|
||||||
|
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
|
||||||
|
$output.='<hr>';
|
||||||
|
$this->flag_like = 'hr';
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p';
|
||||||
|
$output.=$str.'<br>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$br = '';
|
||||||
|
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
|
||||||
|
$data_str = htmlspecialchars($mat[1]);
|
||||||
|
if(!$this->check()){ //代码
|
||||||
|
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
|
||||||
|
}else if($type_str!='```'){
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}
|
||||||
|
}else{ //首个非空字符不为符号
|
||||||
|
if($this->flag == 'code'){ //代码,直接输出
|
||||||
|
$str=str_replace("\t",' ',$str);
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
|
||||||
|
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
|
||||||
|
$this->flag_like = 'ol';
|
||||||
|
$output.=$str;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'idel';
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
$output.=$ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output.='<br>';
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
|
||||||
|
$mat = explode('|',$str);
|
||||||
|
|
||||||
|
if($this->flag!='table'){ //进入表格
|
||||||
|
$this->buf = $str;
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$wrap = '';
|
||||||
|
}else{
|
||||||
|
$output.=$this->genRow($str);
|
||||||
|
}
|
||||||
|
//echo $mat[0].'<br>';
|
||||||
|
//var_dump($mat);
|
||||||
|
}else{ //其他
|
||||||
|
$this->flag = 'p';
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->check()){ //不为代码,设置flag
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = $this->flag_like;
|
||||||
|
if($this->flag_pre == 'table' && $this->flag != 'table')
|
||||||
|
$output='</table>'.$output;
|
||||||
|
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
|
||||||
|
$output='</ul>'.$output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parseInner($output); //输出需要输出的内容
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取输出内容
|
||||||
|
public function output(){
|
||||||
|
$this->parse();
|
||||||
|
echo implode('',$this->lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/md/inite.php
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require '/var/www/owp/open-ww3-project-ww3-tw/src/md/MD.php';
|
||||||
|
|
||||||
|
$md=new MD('/var/www/owp/open-ww3-project-ww3-tw/src/md/inte.md');
|
||||||
|
$md->output();
|
||||||
10
src/md/inte.md
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
## MD介绍页面
|
||||||
|
|
||||||
|
顾名思义、本文件夹下使用的基本都是markdown
|
||||||
|
|
||||||
|
最后感谢提供php的md插件的开源制作者
|
||||||
|
|
||||||
|
[点击跳转](https://ww3.tw/blog/md/src/php-markdown/)
|
||||||
|
|
||||||
|
日期 2025.07.30
|
||||||
|
|
||||||
19
src/views/error/404.html
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-Hant">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>404 Not Found</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 style="font-size: 250%;">到达世界尽头,这里什么都没有哦</h1>
|
||||||
|
<a style="font-size: 150%;" href="/">返回主页</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
background-image: url(https://open-ww3-project.ww3.tw/static/error/cirno-image.jpg);
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
h1 {
|
|
||||||
border: 2px;
|
|
||||||
color:brown;
|
|
||||||
text-align: center;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
@@ -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 %}
|
|
||||||
@@ -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>
|
|
||||||
@@ -1,115 +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: 18px;'>
|
|
||||||
{{ 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>
|
|
||||||
my plan
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
essay
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#class {
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
margin-left: 5%;
|
|
||||||
width: 90%;
|
|
||||||
height: 640px;
|
|
||||||
background-color: #93B9FFA4;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,40 +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>
|
|
||||||
</footer>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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 %}
|
|
||||||
|
|
||||||
@@ -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 %}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{{ posts['title'] }}</title>
|
|
||||||
</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>
|
|
||||||
<h2>留言区: </h2>
|
|
||||||
{% for message in message %}
|
|
||||||
[ {{ message['name'] }} ] >$
|
|
||||||
{{ message['content'] }}<br>
|
|
||||||
{{ message['date'] }}
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
{% endfor %}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background-color: rgb(175, 223, 255);
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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 %}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{# 引入base #}
|
|
||||||
{% extends 'study/base.html' %}
|
|
||||||
|
|
||||||
{# 网站标签 #}
|
|
||||||
{% block title %} 关于页面 {% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
大家好......
|
|
||||||
没有了
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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 %}
|
|
||||||
@@ -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 %}
|
|
||||||
@@ -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 %}
|
|
||||||
@@ -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 %}
|
|
||||||