tiebameow 0.2.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tiebameow/__init__.py +0 -0
- tiebameow/client/__init__.py +4 -0
- tiebameow/client/http_client.py +103 -0
- tiebameow/client/tieba_client.py +517 -0
- tiebameow/models/__init__.py +0 -0
- tiebameow/models/dto.py +391 -0
- tiebameow/models/orm.py +572 -0
- tiebameow/parser/__init__.py +45 -0
- tiebameow/parser/parser.py +362 -0
- tiebameow/parser/rule_parser.py +990 -0
- tiebameow/py.typed +0 -0
- tiebameow/renderer/__init__.py +5 -0
- tiebameow/renderer/config.py +18 -0
- tiebameow/renderer/playwright_core.py +148 -0
- tiebameow/renderer/renderer.py +508 -0
- tiebameow/renderer/static/fonts/NotoSansSC-Regular.woff2 +0 -0
- tiebameow/renderer/style.py +32 -0
- tiebameow/renderer/templates/base.html +270 -0
- tiebameow/renderer/templates/macros.html +100 -0
- tiebameow/renderer/templates/text.html +99 -0
- tiebameow/renderer/templates/text_simple.html +79 -0
- tiebameow/renderer/templates/thread.html +8 -0
- tiebameow/renderer/templates/thread_detail.html +18 -0
- tiebameow/renderer/templates/thread_info.html +35 -0
- tiebameow/schemas/__init__.py +0 -0
- tiebameow/schemas/fragments.py +188 -0
- tiebameow/schemas/rules.py +247 -0
- tiebameow/serializer/__init__.py +15 -0
- tiebameow/serializer/serializer.py +115 -0
- tiebameow/utils/__init__.py +0 -0
- tiebameow/utils/logger.py +129 -0
- tiebameow/utils/time_utils.py +15 -0
- tiebameow-0.2.8.dist-info/METADATA +142 -0
- tiebameow-0.2.8.dist-info/RECORD +36 -0
- tiebameow-0.2.8.dist-info/WHEEL +4 -0
- tiebameow-0.2.8.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
__all__ = ["get_font_style", "font_path", "FONT_URL"]
|
|
4
|
+
|
|
5
|
+
font_path = Path(__file__).parent / "static" / "fonts" / "NotoSansSC-Regular.woff2"
|
|
6
|
+
FONT_URL = "http://tiebameow.local/fonts/NotoSansSC-Regular.woff2"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_font_style(font_size: int = 14) -> str:
|
|
10
|
+
if not font_path.exists():
|
|
11
|
+
return f"""<style>
|
|
12
|
+
body {{
|
|
13
|
+
font-family: "Noto Sans SC", "Noto Sans CJK SC", sans-serif;
|
|
14
|
+
font-size: {font_size}px;
|
|
15
|
+
}}
|
|
16
|
+
</style>
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
return f"""<style>
|
|
20
|
+
@font-face {{
|
|
21
|
+
font-family: 'Noto Sans SC';
|
|
22
|
+
font-style: normal;
|
|
23
|
+
font-weight: 400;
|
|
24
|
+
src: url("{FONT_URL}") format('woff2');
|
|
25
|
+
}}
|
|
26
|
+
|
|
27
|
+
body {{
|
|
28
|
+
font-family: "Noto Sans SC", "Noto Sans CJK SC", sans-serif;
|
|
29
|
+
font-size: {font_size}px;
|
|
30
|
+
}}
|
|
31
|
+
</style>
|
|
32
|
+
"""
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>{% block title %}Renderer{% endblock %}</title>
|
|
8
|
+
{% if style_list %}
|
|
9
|
+
{% for style in style_list %}
|
|
10
|
+
{{ style | safe }}
|
|
11
|
+
{% endfor %}
|
|
12
|
+
{% endif %}
|
|
13
|
+
<style>
|
|
14
|
+
body {
|
|
15
|
+
margin: 0;
|
|
16
|
+
padding: 20px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.container {
|
|
20
|
+
max-width: 800px;
|
|
21
|
+
margin: 0 auto;
|
|
22
|
+
border: 1px solid #ddd;
|
|
23
|
+
padding: 15px;
|
|
24
|
+
padding-bottom: 0px;
|
|
25
|
+
border-radius: 8px;
|
|
26
|
+
word-break: break-all;
|
|
27
|
+
overflow-wrap: break-word;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.header {
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
margin-bottom: 10px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.avatar {
|
|
37
|
+
width: 40px;
|
|
38
|
+
height: 40px;
|
|
39
|
+
border-radius: 50%;
|
|
40
|
+
margin-right: 10px;
|
|
41
|
+
object-fit: cover;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.avatar-placeholder {
|
|
45
|
+
background-color: #ccc;
|
|
46
|
+
color: #666;
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
align-items: center;
|
|
50
|
+
font-size: 24px;
|
|
51
|
+
font-weight: bold;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.user-info {
|
|
55
|
+
display: flex;
|
|
56
|
+
flex-direction: column;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.username {
|
|
60
|
+
font-weight: bold;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.sub {
|
|
64
|
+
font-size: 0.8em;
|
|
65
|
+
color: gray;
|
|
66
|
+
padding: 2px;
|
|
67
|
+
border-radius: 4px;
|
|
68
|
+
/* margin-top: 4px; */
|
|
69
|
+
display: inline-block;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.title {
|
|
73
|
+
font-size: 1.5em;
|
|
74
|
+
font-weight: bold;
|
|
75
|
+
margin-bottom: 8px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.text {
|
|
79
|
+
white-space: pre-wrap;
|
|
80
|
+
line-height: 1.6;
|
|
81
|
+
margin-bottom: 15px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.images {
|
|
85
|
+
display: grid;
|
|
86
|
+
grid-template-columns: repeat(3, 1fr);
|
|
87
|
+
gap: 5px;
|
|
88
|
+
margin-bottom: 15px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.image-item {
|
|
92
|
+
position: relative;
|
|
93
|
+
aspect-ratio: 1 / 1;
|
|
94
|
+
overflow: hidden;
|
|
95
|
+
border-radius: 4px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.image-item img {
|
|
99
|
+
width: 100%;
|
|
100
|
+
height: 100%;
|
|
101
|
+
object-fit: cover;
|
|
102
|
+
display: block;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.image-placeholder {
|
|
106
|
+
width: 100%;
|
|
107
|
+
height: 100%;
|
|
108
|
+
background-color: #eee;
|
|
109
|
+
color: #999;
|
|
110
|
+
display: flex;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
align-items: center;
|
|
113
|
+
font-size: 0.8em;
|
|
114
|
+
text-align: center;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.more-count {
|
|
118
|
+
position: absolute;
|
|
119
|
+
top: 0;
|
|
120
|
+
left: 0;
|
|
121
|
+
width: 100%;
|
|
122
|
+
height: 100%;
|
|
123
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
124
|
+
color: white;
|
|
125
|
+
display: flex;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
align-items: center;
|
|
128
|
+
font-size: 24px;
|
|
129
|
+
font-weight: bold;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.footer {
|
|
133
|
+
margin-top: 20px;
|
|
134
|
+
color: #999;
|
|
135
|
+
font-size: 0.9em;
|
|
136
|
+
text-align: right;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.prefix {
|
|
140
|
+
margin-bottom: 20px;
|
|
141
|
+
padding-bottom: 20px;
|
|
142
|
+
border-bottom: 1px solid #ddd;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.suffix {
|
|
146
|
+
padding: 20px 0;
|
|
147
|
+
border-top: 1px solid #ddd;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* New styles for posts and comments */
|
|
151
|
+
.item {
|
|
152
|
+
margin-bottom: 20px;
|
|
153
|
+
padding-bottom: 20px;
|
|
154
|
+
border-bottom: 1px solid #eee;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.item:last-child {
|
|
158
|
+
border-bottom: none;
|
|
159
|
+
/* margin-bottom: 0; */
|
|
160
|
+
padding-bottom: 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.comments {
|
|
164
|
+
background-color: #f9f9f9;
|
|
165
|
+
padding: 10px;
|
|
166
|
+
border-radius: 4px;
|
|
167
|
+
margin-top: 10px;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.comment-item {
|
|
171
|
+
display: flex;
|
|
172
|
+
margin-bottom: 10px;
|
|
173
|
+
font-size: 0.9em;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.comment-item:last-child {
|
|
177
|
+
margin-bottom: 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.comment-avatar {
|
|
181
|
+
width: 24px;
|
|
182
|
+
height: 24px;
|
|
183
|
+
border-radius: 50%;
|
|
184
|
+
margin-right: 8px;
|
|
185
|
+
object-fit: cover;
|
|
186
|
+
flex-shrink: 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.comment-avatar-placeholder {
|
|
190
|
+
width: 24px;
|
|
191
|
+
height: 24px;
|
|
192
|
+
border-radius: 50%;
|
|
193
|
+
margin-right: 8px;
|
|
194
|
+
background-color: #ccc;
|
|
195
|
+
flex-shrink: 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.comment-content {
|
|
199
|
+
flex: 1;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.comment-user {
|
|
203
|
+
font-weight: bold;
|
|
204
|
+
color: #333;
|
|
205
|
+
margin-right: 5px;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.comment-text {
|
|
209
|
+
color: #555;
|
|
210
|
+
margin-top: 2px;
|
|
211
|
+
margin-bottom: 2px;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.id-label {
|
|
215
|
+
font-size: 0.8em;
|
|
216
|
+
color: gray;
|
|
217
|
+
margin-top: 5px;
|
|
218
|
+
display: block;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.sub-html-item {
|
|
222
|
+
width: 100%;
|
|
223
|
+
border-top: 1px solid #eee;
|
|
224
|
+
margin-top: 10px;
|
|
225
|
+
padding-top: 10px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.forum-bar {
|
|
229
|
+
flex-shrink: 0;
|
|
230
|
+
display: flex;
|
|
231
|
+
align-items: center;
|
|
232
|
+
gap: 8px;
|
|
233
|
+
margin-bottom: 20px;
|
|
234
|
+
background-color: #f5f6fa;
|
|
235
|
+
border-radius: 5px;
|
|
236
|
+
width: fit-content;
|
|
237
|
+
padding: 5px 10px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.forum-icon {
|
|
241
|
+
width: 20px;
|
|
242
|
+
height: 20px;
|
|
243
|
+
border-radius: 2px;
|
|
244
|
+
object-fit: cover;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.forum-icon-placeholder {
|
|
248
|
+
width: 20px;
|
|
249
|
+
height: 20px;
|
|
250
|
+
background-color: #ccc;
|
|
251
|
+
border-radius: 3px;
|
|
252
|
+
}
|
|
253
|
+
</style>
|
|
254
|
+
</head>
|
|
255
|
+
|
|
256
|
+
<body>
|
|
257
|
+
<div class="container">
|
|
258
|
+
{% if prefix_html %}
|
|
259
|
+
<div class="prefix">{{ prefix_html | safe }}</div>
|
|
260
|
+
{% endif %}
|
|
261
|
+
|
|
262
|
+
{% block content %}{% endblock %}
|
|
263
|
+
|
|
264
|
+
{% if suffix_html %}
|
|
265
|
+
<div class="suffix">{{ suffix_html | safe }}</div>
|
|
266
|
+
{% endif %}
|
|
267
|
+
</div>
|
|
268
|
+
</body>
|
|
269
|
+
|
|
270
|
+
</html>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{% macro avatar(url) %}
|
|
2
|
+
{% if url %}
|
|
3
|
+
<img src="{{ url }}" class="avatar" alt="avatar">
|
|
4
|
+
{% else %}
|
|
5
|
+
<div class="avatar avatar-placeholder"></div>
|
|
6
|
+
{% endif %}
|
|
7
|
+
{% endmacro %}
|
|
8
|
+
|
|
9
|
+
{% macro user_info(name, level, time, floor=None, sub_text_list=None) %}
|
|
10
|
+
<div class="user-info">
|
|
11
|
+
<span class="username">{{ name }}</span>
|
|
12
|
+
<span class="sub">Lv.{{ level }} · {{ time | format_date }}
|
|
13
|
+
{% if floor %}· {{ floor }}楼{% endif %}
|
|
14
|
+
{% if sub_text_list %}
|
|
15
|
+
{% for text in sub_text_list %}
|
|
16
|
+
· {{ text }}
|
|
17
|
+
{% endfor %}
|
|
18
|
+
{% endif %}
|
|
19
|
+
</span>
|
|
20
|
+
</div>
|
|
21
|
+
{% endmacro %}
|
|
22
|
+
|
|
23
|
+
{% macro images(image_list, remain_count=0) %}
|
|
24
|
+
{% if image_list and image_list | length > 0 %}
|
|
25
|
+
<div class="images">
|
|
26
|
+
{% for img in image_list %}
|
|
27
|
+
<div class="image-item">
|
|
28
|
+
{% if img %}
|
|
29
|
+
<img src="{{ img }}" alt="Image">
|
|
30
|
+
{% else %}
|
|
31
|
+
<div class="image-placeholder">图片加载失败</div>
|
|
32
|
+
{% endif %}
|
|
33
|
+
{% if loop.last and remain_count > 0 %}
|
|
34
|
+
<div class="more-count">+{{ remain_count }}</div>
|
|
35
|
+
{% endif %}
|
|
36
|
+
</div>
|
|
37
|
+
{% endfor %}
|
|
38
|
+
</div>
|
|
39
|
+
{% endif %}
|
|
40
|
+
{% endmacro %}
|
|
41
|
+
|
|
42
|
+
{% macro forum_bar(forum_name, forum_icon_url) %}
|
|
43
|
+
<div class="forum-bar">
|
|
44
|
+
{% if forum_icon_url %}
|
|
45
|
+
<img src="{{ forum_icon_url }}" class="forum-icon" alt="forum icon">
|
|
46
|
+
{% else %}
|
|
47
|
+
<div class="forum-icon forum-icon-placeholder"></div>
|
|
48
|
+
{% endif %}
|
|
49
|
+
<span class="forum-name">{{ forum_name }}吧</span>
|
|
50
|
+
</div>
|
|
51
|
+
{% endmacro %}
|
|
52
|
+
|
|
53
|
+
{% macro content_item(item, is_thread=False, forum_name=None, forum_icon_url=None) %}
|
|
54
|
+
<div class="item {% if is_thread %}thread-item{% else %}post-item{% endif %}">
|
|
55
|
+
{% if forum_name %}
|
|
56
|
+
{{ forum_bar(forum_name, forum_icon_url) }}
|
|
57
|
+
{% endif %}
|
|
58
|
+
<div class="header">
|
|
59
|
+
{{ avatar(item.portrait_url) }}
|
|
60
|
+
{{ user_info(item.nick_name, item.level, item.create_time, item.floor, item.sub_text_list) }}
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
{% if item.title %}
|
|
64
|
+
<div class="title">{{ item.title }}</div>
|
|
65
|
+
{% endif %}
|
|
66
|
+
|
|
67
|
+
<div class="text">{{ item.text }}</div>
|
|
68
|
+
|
|
69
|
+
{{ images(item.image_url_list, item.remain_image_count) }}
|
|
70
|
+
|
|
71
|
+
{% if item.sub_html_list %}
|
|
72
|
+
{% for html in item.sub_html_list %}
|
|
73
|
+
<div class="sub-html-item">
|
|
74
|
+
{{ html | safe }}
|
|
75
|
+
</div>
|
|
76
|
+
{% endfor %}
|
|
77
|
+
{% endif %}
|
|
78
|
+
|
|
79
|
+
{% if item.comments %}
|
|
80
|
+
<div class="comments">
|
|
81
|
+
{% for comment in item.comments %}
|
|
82
|
+
<div class="comment-item">
|
|
83
|
+
{% if comment.portrait_url %}
|
|
84
|
+
<img src="{{ comment.portrait_url }}" class="comment-avatar" alt="avatar">
|
|
85
|
+
{% else %}
|
|
86
|
+
<div class="comment-avatar-placeholder"></div>
|
|
87
|
+
{% endif %}
|
|
88
|
+
<div class="comment-content">
|
|
89
|
+
<div class="comment-header">
|
|
90
|
+
<span class="comment-user">{{ comment.nick_name }}</span>
|
|
91
|
+
<span class="sub">Lv.{{ comment.level }} · {{ comment.create_time | format_date }}</span>
|
|
92
|
+
</div>
|
|
93
|
+
<div class="comment-text">{{ comment.text }}</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
{% endfor %}
|
|
97
|
+
</div>
|
|
98
|
+
{% endif %}
|
|
99
|
+
</div>
|
|
100
|
+
{% endmacro %}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Text Renderer</title>
|
|
7
|
+
{% if style_list %}
|
|
8
|
+
{% for style in style_list %}
|
|
9
|
+
{{ style | safe }}
|
|
10
|
+
{% endfor %}
|
|
11
|
+
{% endif %}
|
|
12
|
+
<style>
|
|
13
|
+
body {
|
|
14
|
+
margin: 0;
|
|
15
|
+
padding: 20px;
|
|
16
|
+
background-color: #fff;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.container {
|
|
20
|
+
max-width: 800px;
|
|
21
|
+
margin: 0 auto;
|
|
22
|
+
border: 1px solid #ddd;
|
|
23
|
+
border-radius: 8px;
|
|
24
|
+
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
|
25
|
+
background-color: #fff;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.header {
|
|
32
|
+
padding: 8px 15px;
|
|
33
|
+
border-bottom: 1px solid #eee;
|
|
34
|
+
background-color: #f8f9fa;
|
|
35
|
+
font-size: 12px;
|
|
36
|
+
color: #666;
|
|
37
|
+
text-align: right;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.title-container {
|
|
41
|
+
padding: 12px 15px;
|
|
42
|
+
border-bottom: 1px solid #eee;
|
|
43
|
+
background-color: #fff;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.title {
|
|
47
|
+
margin: 0;
|
|
48
|
+
font-size: 18px;
|
|
49
|
+
font-weight: bold;
|
|
50
|
+
color: #333;
|
|
51
|
+
line-height: 1.4;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.content {
|
|
55
|
+
padding: 15px;
|
|
56
|
+
font-size: 16px;
|
|
57
|
+
line-height: 1.6;
|
|
58
|
+
white-space: pre-wrap;
|
|
59
|
+
word-break: break-all;
|
|
60
|
+
color: #333;
|
|
61
|
+
flex: 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.footer {
|
|
65
|
+
padding: 8px 15px;
|
|
66
|
+
border-top: 1px solid #eee;
|
|
67
|
+
background-color: #f8f9fa;
|
|
68
|
+
font-size: 12px;
|
|
69
|
+
color: #666;
|
|
70
|
+
text-align: right;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
73
|
+
</head>
|
|
74
|
+
<body>
|
|
75
|
+
<div class="container">
|
|
76
|
+
{% if header %}
|
|
77
|
+
<div class="header">
|
|
78
|
+
{{ header }}
|
|
79
|
+
</div>
|
|
80
|
+
{% endif %}
|
|
81
|
+
|
|
82
|
+
{% if title %}
|
|
83
|
+
<div class="title-container">
|
|
84
|
+
<h3 class="title">{{ title }}</h3>
|
|
85
|
+
</div>
|
|
86
|
+
{% endif %}
|
|
87
|
+
|
|
88
|
+
<div class="content">
|
|
89
|
+
{{ text }}
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
{% if footer %}
|
|
93
|
+
<div class="footer">
|
|
94
|
+
{{ footer }}
|
|
95
|
+
</div>
|
|
96
|
+
{% endif %}
|
|
97
|
+
</div>
|
|
98
|
+
</body>
|
|
99
|
+
</html>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Text Renderer Simple</title>
|
|
7
|
+
{% if style_list %}
|
|
8
|
+
{% for style in style_list %}
|
|
9
|
+
{{ style | safe }}
|
|
10
|
+
{% endfor %}
|
|
11
|
+
{% endif %}
|
|
12
|
+
<style>
|
|
13
|
+
body {
|
|
14
|
+
margin: 0;
|
|
15
|
+
padding: 2px;
|
|
16
|
+
background-color: #fff;
|
|
17
|
+
display: inline-block;
|
|
18
|
+
}
|
|
19
|
+
.container {
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
min-width: 50px;
|
|
23
|
+
max-width: 100%;
|
|
24
|
+
padding: 5px;
|
|
25
|
+
font-size: 14px;
|
|
26
|
+
line-height: 1.3;
|
|
27
|
+
color: #333;
|
|
28
|
+
word-break: break-all;
|
|
29
|
+
white-space: pre-wrap;
|
|
30
|
+
background-color: #f9f9f9;
|
|
31
|
+
border: 1px solid #e0e0e0;
|
|
32
|
+
border-radius: 3px;
|
|
33
|
+
}
|
|
34
|
+
.header {
|
|
35
|
+
font-size: 10px;
|
|
36
|
+
color: #888;
|
|
37
|
+
text-align: right;
|
|
38
|
+
border-bottom: 1px solid #eee;
|
|
39
|
+
margin-bottom: 2px;
|
|
40
|
+
padding-bottom: 2px;
|
|
41
|
+
}
|
|
42
|
+
.title {
|
|
43
|
+
font-weight: bold;
|
|
44
|
+
font-size: 14px;
|
|
45
|
+
margin-bottom: 3px;
|
|
46
|
+
padding-bottom: 3px;
|
|
47
|
+
border-bottom: 1px solid #eee;
|
|
48
|
+
}
|
|
49
|
+
.content {
|
|
50
|
+
margin: 0;
|
|
51
|
+
}
|
|
52
|
+
.footer {
|
|
53
|
+
margin-top: 3px;
|
|
54
|
+
padding-top: 2px;
|
|
55
|
+
border-top: 1px solid #eee;
|
|
56
|
+
font-size: 10px;
|
|
57
|
+
color: #888;
|
|
58
|
+
text-align: right;
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
61
|
+
</head>
|
|
62
|
+
<body>
|
|
63
|
+
<div class="container">
|
|
64
|
+
{% if header %}
|
|
65
|
+
<div class="header">{{ header }}</div>
|
|
66
|
+
{% endif %}
|
|
67
|
+
|
|
68
|
+
{% if title %}
|
|
69
|
+
<div class="title">{{ title }}</div>
|
|
70
|
+
{% endif %}
|
|
71
|
+
|
|
72
|
+
<div class="content">{{ text }}</div>
|
|
73
|
+
|
|
74
|
+
{% if footer %}
|
|
75
|
+
<div class="footer">{{ footer }}</div>
|
|
76
|
+
{% endif %}
|
|
77
|
+
</div>
|
|
78
|
+
</body>
|
|
79
|
+
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
{% import "macros.html" as macros %}
|
|
3
|
+
|
|
4
|
+
{% block title %}Thread Detail Renderer{% endblock %}
|
|
5
|
+
|
|
6
|
+
{% block content %}
|
|
7
|
+
{# Render the main thread #}
|
|
8
|
+
{{ macros.content_item(thread, is_thread=True, forum_name=forum, forum_icon_url=forum_icon_url) }}
|
|
9
|
+
|
|
10
|
+
{# Render posts #}
|
|
11
|
+
{% if posts %}
|
|
12
|
+
<div class="posts">
|
|
13
|
+
{% for post in posts %}
|
|
14
|
+
{{ macros.content_item(post) }}
|
|
15
|
+
{% endfor %}
|
|
16
|
+
</div>
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% endblock %}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.thread-info {
|
|
3
|
+
display: flex;
|
|
4
|
+
justify-content: space-between;
|
|
5
|
+
padding: 0 24px;
|
|
6
|
+
color: #333;
|
|
7
|
+
font-size: 0.9em;
|
|
8
|
+
align-items: center;
|
|
9
|
+
}
|
|
10
|
+
.info-item {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
gap: 6px;
|
|
14
|
+
}
|
|
15
|
+
.icon {
|
|
16
|
+
width: 1.4em;
|
|
17
|
+
height: 1.4em;
|
|
18
|
+
fill: currentColor;
|
|
19
|
+
vertical-align: -0.3em;
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
22
|
+
<div class="thread-info">
|
|
23
|
+
<span class="info-item">
|
|
24
|
+
<svg t="1767634729661" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6830" width="200" height="200"><path d="M865.922728 583.211878c-16.276708 0-29.580712 13.246699-29.667693 29.727045l0 215.125569c0 17.992793-14.58723 32.637328-32.520671 32.637328L181.762717 860.70182c-17.935488 0-32.520671-14.645558-32.520671-32.637328L149.242046 292.155966c0-17.992793 14.586207-32.637328 32.520671-32.637328l291.230897 0c16.304338-0.029676 29.580712-13.363356 29.580712-29.724998 0-16.392342-13.276375-29.727045-29.610388-29.727045l-295.336402 0c-48.358381 0-87.721901 39.450501-87.721901 87.925538l0 544.205493c0 48.475038 39.36352 87.925538 87.721901 87.925538l630.239961 0c48.358381 0 87.720877-39.450501 87.720877-87.925538L895.588375 612.762915C895.501394 596.458577 882.19739 583.211878 865.922728 583.211878z" fill="#231F20" p-id="6831"></path><path d="M930.818761 338.183256l0-0.318248L727.07645 133.511783l-6.435573-6.259564-0.814552 0.844228c-4.511757-2.532683-9.606799-3.873214-14.876826-3.873214-16.974603 0-30.774911 13.829983-30.774911 30.832216 0 5.298679 1.338485 10.393721 3.873214 14.907525l-0.903579 0.931209 141.845589 142.224212-145.573493 0.057305C436.396091 342.726735 378.197598 489.375723 361.049033 717.050096c0 17.004279 13.800307 30.832216 30.772864 30.832216 13.858636 0 25.620517-9.229199 29.464055-21.893636l1.397836-8.181333c18.022469-215.329207 60.470233-321.567833 251.839749-342.937536l144.466276 0L683.433464 510.804778l-5.502317 7.744381c-1.951445 4.104481-2.969635 9.112542-2.969635 13.654998 0 17.002232 13.799284 30.832216 30.772864 30.832216 4.832052 0 10.160407-1.164522 14.439874-3.37691L929.954067 350.740246c1.860371-1.305739 4.140297-4.52506 4.140297-6.970762C934.093341 341.323782 932.679132 339.488994 930.818761 338.183256z" fill="#231F20" p-id="6832"></path></svg>
|
|
25
|
+
{{ share_num }}
|
|
26
|
+
</span>
|
|
27
|
+
<span class="info-item">
|
|
28
|
+
<svg t="1767634797973" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7908" width="200" height="200"><path d="M622.56056 464.834794c0 27.928073 22.73684 50.64854 50.664913 50.64854 27.956725 0 50.693566-22.720468 50.693566-50.64854 0-27.928073-22.73684-50.66389-50.693566-50.66389C645.2974 414.171927 622.56056 436.907745 622.56056 464.834794" fill="#231F20" p-id="7909"></path><path d="M931.254178 211.459063c0-40.637536-33.05893-73.698512-73.728188-73.698512L166.471964 137.76055c-40.637536 0-73.727165 33.059953-73.727165 73.698512l0 506.796488c0 40.637536 33.088606 73.696466 73.727165 73.696466l251.16846 0 94.343715 94.28641 94.315062-94.28641 251.226788 0c40.669258 0 73.728188-33.05893 73.728188-73.696466l0-82.560344-0.089028-1.282203L931.254178 211.459063zM875.96699 695.220928c0 22.88522-18.558681 41.444924-41.443901 41.444924L579.446623 736.665853l-67.462484 67.490114-67.430762-67.490114L189.506587 736.665853c-22.88522 0-41.4746-18.559705-41.4746-41.444924L148.031986 234.493685c0-22.88522 18.58938-41.488927 41.4746-41.488927l645.01548 0c22.88522 0 41.443901 18.603707 41.443901 41.488927l0 396.579247 0 36.161594L875.965967 695.220928z" fill="#231F20" p-id="7910"></path><path d="M461.321272 464.834794c0 27.928073 22.735817 50.64854 50.662867 50.64854 27.929096 0 50.66389-22.720468 50.66389-50.64854 0-27.928073-22.734794-50.66389-50.66389-50.66389C484.057089 414.171927 461.321272 436.907745 461.321272 464.834794" fill="#231F20" p-id="7911"></path><path d="M300.083008 464.834794c0 27.928073 22.735817 50.64854 50.66389 50.64854 27.927049 0 50.662867-22.720468 50.662867-50.64854 0-27.928073-22.735817-50.66389-50.662867-50.66389C322.817802 414.171927 300.083008 436.907745 300.083008 464.834794" fill="#231F20" p-id="7912"></path></svg>
|
|
29
|
+
{{ reply_num }}
|
|
30
|
+
</span>
|
|
31
|
+
<span class="info-item">
|
|
32
|
+
<svg t="1767634920060" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5533" width="200" height="200"><path d="M194.792475 478.69343c16.167215 0 29.330002-13.163811 29.330002-29.346375 0-16.092513-13.015432-29.212322-29.801746-29.212322-0.086981 0-0.177032 0-0.264013 0l-60.606333 0.177032c-1.560542-0.206708-3.149736-0.325411-4.76963-0.325411-21.291932 0-38.636972 17.537422-38.636972 39.09439l-0.323365 423.853427c0 21.645996 16.9613 38.578644 38.636972 38.578644l1.677199 0.057305c0.707105 0.029676 1.385557 0.059352 2.032286 0.059352 0.823761 0 1.64957-0.029676 1.826602-0.11768l59.926858 0.086981c0.559748 0 1.001817-0.11768 1.089821-0.11768 0 0-0.029676 0-0.116657 0.057305l3.76986-0.147356 0-0.382717c13.517875-2.236947 23.64656-13.84124 23.64656-27.799136 0-13.987572-10.129708-25.589818-23.64656-27.828812l0-0.766456-49.827849 0 1.413186-385.92356L194.792475 478.69036z" fill="#231F20" p-id="5534"></path><path d="M918.228001 436.301947c-18.199501-29.66974-45.204551-44.821835-82.22163-46.322002-1.883907-0.25071-3.799536-0.412392-5.77247-0.412392l-195.744149-0.648776c13.398148-40.359196 20.732184-83.750449 20.732184-122.740462 0-27.255761-3.00545-54.686507-8.894577-81.543178l-1.206478-3.196809-0.089028 0.01535c-12.161994-46.837748-53.477982-79.259158-101.626585-79.259158-55.393611 0-97.18032 46.248324-97.18032 107.576087l-0.059352 3.047406c-0.057305 2.222621-0.116657 4.40124 0.059352 6.16849-2.796696 101.715613-83.869153 187.397041-188.559517 199.324698l-3.358491 0.36839-0.76441 274.43128 0 228.491994 13.930267 0.005117 0.587378 0.11154 3.179412-0.027629 0.01535-0.081864 485.653959 0.198521 8.685823-0.236384c19.84907 0 31.038924-5.03569 48.621371-16.344247 16.22452-10.482749 29.359678-25.266453 37.751812-42.316781 2.562359-3.76986 4.418636-7.862062 5.565762-12.251022l75.30101-336.657506c1.089821-4.225231 1.472538-8.643867 1.149173-12.56006C935.660023 478.42737 930.212964 455.900308 918.228001 436.301947zM879.148961 488.807788l-0.912789 3.799536 0.295735 0.074701-80.129992 355.2387-0.148379 0.353041c-2.296299 5.536087-6.15314 10.160407-11.101849 13.340843-3.415796 2.209318-7.185656 3.622504-11.161201 4.239558-0.470721-0.057305-0.941442-0.057305-1.413186-0.057305l-3.03308 0.086981-462.84344-0.530073-0.177032-392.299781c79.540567-35.986609 148.155295-73.959455 183.080735-167.79868l0.295735 0.074701 1.119497-3.328815c3.709485-11.263531 6.596232-22.350031 8.598842-32.909527 5.447059-28.577872 5.212722-56.422034 5.183046-58.041928-1.766226-13.502525 1.206478-24.738427 8.80555-33.394574 8.598842-9.777691 21.673625-14.151301 30.744211-14.151301 22.586414 0.766456 45.526893 30.966269 45.61592 48.163953 0.029676 0.26606 5.38873 26.945699 5.418406 55.186903 0.057305 27.65178-2.651386 45.277206-3.858888 51.828412l-0.500397 0-0.589424 3.062755c-5.595438 29.522384-15.518438 57.794287-29.41903 84.003206l-0.972141 2.856048 0.118704 0.132006c-1.885953 4.696975-2.856048 9.643638-2.856048 14.709003 0 25.032116 27.121707 25.032116 41.697681 25.032116l233.381351 0.264013 7.15598 0.221034c1.266853 0.045025 2.503007 0.089028 3.592828 0.118704l0 0.425695 5.538133-0.248663c10.453073 0 19.937075 5.344728 25.412786 14.296611C880.709503 471.080032 881.829 480.283648 879.148961 488.807788z" fill="#231F20" p-id="5535"></path></svg>
|
|
33
|
+
{{ agree_num }}
|
|
34
|
+
</span>
|
|
35
|
+
</div>
|
|
File without changes
|