图片现在能看了。
This commit is contained in:
198
main.py
198
main.py
@@ -43,6 +43,10 @@ class SuanPlugin(Star):
|
||||
# 生成 HTML 内容
|
||||
html_content = self._generate_schedule_html(schedule_dict, title)
|
||||
|
||||
# 额外保存一份到指定路径,用于样式调试
|
||||
with open('/home/fanfan/test.html', 'w', encoding='utf-8') as f:
|
||||
f.write(html_content)
|
||||
|
||||
# 创建临时文件
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False, encoding='utf-8') as f:
|
||||
f.write(html_content)
|
||||
@@ -57,9 +61,10 @@ class SuanPlugin(Star):
|
||||
# 尝试使用 wkhtmltoimage(如果安装了)
|
||||
cmd = [
|
||||
'wkhtmltoimage',
|
||||
'--width', '1200',
|
||||
'--width', '1680',
|
||||
'--quality', '90',
|
||||
'--enable-local-file-access',
|
||||
'--transparent',
|
||||
html_path,
|
||||
png_path
|
||||
]
|
||||
@@ -159,30 +164,24 @@ class SuanPlugin(Star):
|
||||
logger.warning(f"清理临时文件失败 {path}: {e}")
|
||||
|
||||
def _generate_schedule_html(self, schedule: list[dict], title: str) -> str:
|
||||
"""生成课程表 HTML"""
|
||||
"""生成课程表 HTML - 清新薄荷绿风格(静态图片版)"""
|
||||
|
||||
# 星期映射
|
||||
weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
|
||||
|
||||
# 初始化课表网格: 12节课 x 7天
|
||||
# grid[节次][星期] = 课程列表
|
||||
weekday_short = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
grid = [[[] for _ in range(7)] for _ in range(12)]
|
||||
|
||||
# 填充课程数据
|
||||
for course in schedule:
|
||||
name = course.get('name', '未知课程')
|
||||
teacher = course.get('teacher') or ''
|
||||
classroom = course.get('classroom') or ''
|
||||
weeks = course.get('weeks', [])
|
||||
day = course.get('day', 1) # 1-7
|
||||
day = course.get('day', 1)
|
||||
classes = course.get('classes', [])
|
||||
|
||||
# 调整 day 为 0-based 索引
|
||||
day_idx = day - 1
|
||||
if day_idx < 0 or day_idx > 6:
|
||||
continue
|
||||
|
||||
# 构建课程显示文本
|
||||
course_text = f"<b>{name}</b>"
|
||||
if teacher:
|
||||
course_text += f"<br><small>{teacher}</small>"
|
||||
@@ -191,12 +190,10 @@ class SuanPlugin(Star):
|
||||
if weeks:
|
||||
course_text += f"<br><small>第{self._format_weeks(weeks)}周</small>"
|
||||
|
||||
# 放入对应格子
|
||||
for class_idx in classes:
|
||||
if 1 <= class_idx <= 12:
|
||||
grid[class_idx - 1][day_idx].append(course_text)
|
||||
|
||||
# 构建 HTML
|
||||
html = f'''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -208,79 +205,151 @@ class SuanPlugin(Star):
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}}
|
||||
|
||||
body {{
|
||||
font-family: "Microsoft YaHei", "SimHei", sans-serif;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
font-family: "WenQuanYi Micro Hei", "Noto Sans CJK SC", "Microsoft YaHei", sans-serif;
|
||||
background: transparent;
|
||||
padding: 40px;
|
||||
}}
|
||||
|
||||
.container {{
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width: 1600px;
|
||||
background: #1a1a2e;
|
||||
border-radius: 20px;
|
||||
padding: 40px;
|
||||
}}
|
||||
h1 {{
|
||||
|
||||
.header {{
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
color: #333;
|
||||
margin-bottom: 30px;
|
||||
}}
|
||||
|
||||
h1 {{
|
||||
font-size: 32px;
|
||||
color: #e0f7fa;
|
||||
letter-spacing: 2px;
|
||||
}}
|
||||
|
||||
table {{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 12px;
|
||||
table-layout: fixed;
|
||||
border-collapse: separate;
|
||||
border-spacing: 10px;
|
||||
font-size: 14px;
|
||||
}}
|
||||
th, td {{
|
||||
border: 1px solid #ccc;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
|
||||
col.time-col {{
|
||||
width: 90px;
|
||||
}}
|
||||
|
||||
col.day-col {{
|
||||
width: 14.28%;
|
||||
}}
|
||||
|
||||
th {{
|
||||
background: #f5f5f5;
|
||||
background: #006064;
|
||||
color: #e0f7fa;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
padding: 15px 10px;
|
||||
border-radius: 12px;
|
||||
}}
|
||||
.time-col {{
|
||||
background: #f9f9f9;
|
||||
font-weight: bold;
|
||||
width: 60px;
|
||||
}}
|
||||
.course-cell {{
|
||||
min-height: 60px;
|
||||
}}
|
||||
.course-item {{
|
||||
background: #e3f2fd;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
margin: 2px 0;
|
||||
line-height: 1.4;
|
||||
}}
|
||||
.course-item b {{
|
||||
color: #1976d2;
|
||||
|
||||
th .weekday-en {{
|
||||
font-size: 11px;
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: #80deea;
|
||||
}}
|
||||
|
||||
td.time-col {{
|
||||
background: #00796b;
|
||||
color: #e0f7fa;
|
||||
font-weight: bold;
|
||||
padding: 15px 10px;
|
||||
border-radius: 12px;
|
||||
text-align: center;
|
||||
}}
|
||||
|
||||
td.time-col .period-num {{
|
||||
font-size: 18px;
|
||||
display: block;
|
||||
}}
|
||||
|
||||
td.time-col .period-time {{
|
||||
font-size: 11px;
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: #b2ebf2;
|
||||
}}
|
||||
|
||||
td.day-cell {{
|
||||
background: #263238;
|
||||
border-radius: 12px;
|
||||
padding: 10px;
|
||||
vertical-align: top;
|
||||
height: 110px;
|
||||
}}
|
||||
|
||||
.course-item {{
|
||||
background: #00838f;
|
||||
border-radius: 10px;
|
||||
padding: 6px;
|
||||
margin: 2px 0;
|
||||
color: #e0f7fa;
|
||||
line-height: 1.1;
|
||||
font-size: 17px;
|
||||
height: 180px;
|
||||
}}
|
||||
|
||||
.course-item b {{
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1px;
|
||||
color: #ffffff;
|
||||
}}
|
||||
|
||||
.course-item small {{
|
||||
color: #666;
|
||||
font-size: 9px;
|
||||
}}tr:nth-child(even) td {{
|
||||
background: #fafafa;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
color: #b2ebf2;
|
||||
}}
|
||||
|
||||
.course-item small + small {{
|
||||
margin-top: 0px;
|
||||
}}
|
||||
|
||||
.course-item.type-a {{ background: #0277bd; }}
|
||||
.course-item.type-b {{ background: #2e7d32; }}
|
||||
.course-item.type-c {{ background: #7b1fa2; }}
|
||||
.course-item.type-d {{ background: #c6278e; }}
|
||||
.course-item.type-e {{ background: #ef6c00; }}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>{title}</h1>
|
||||
</div>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col class="time-col">
|
||||
<col class="day-col"><col class="day-col"><col class="day-col">
|
||||
<col class="day-col"><col class="day-col"><col class="day-col">
|
||||
<col class="day-col">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>节次</th>
|
||||
{''.join(f'<th>{w}</th>' for w in weekdays)}
|
||||
<th>TIME</th>
|
||||
{''.join(f'<th>{w}<span class="weekday-en">{weekday_short[i]}</span></th>' for i, w in enumerate(weekdays))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{self._generate_table_body(grid)}
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="text-align: right; margin-top: 20px; font-size: 12px; color: #b0bec5;">Powered by <芒果酸> suan.mangofanfan.cn</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>'''
|
||||
@@ -290,30 +359,37 @@ class SuanPlugin(Star):
|
||||
def _generate_table_body(self, grid: list) -> str:
|
||||
"""生成表格主体 HTML"""
|
||||
rows = []
|
||||
course_type_counter = 0
|
||||
type_classes = ['type-a', 'type-b', 'type-c', 'type-d', 'type-e']
|
||||
|
||||
for period in range(12):
|
||||
# 计算时间显示
|
||||
start_time = self._get_period_time(period + 1)
|
||||
|
||||
row_html = f'<tr><td class="time-col">{period + 1}<br><small>{start_time}</small></td>'
|
||||
row_html = f'''<tr>
|
||||
<td class="time-col">
|
||||
<span class="period-num">{period + 1}</span>
|
||||
<span class="period-time">{start_time}</span>
|
||||
</td>'''
|
||||
|
||||
for day in range(7):
|
||||
courses = grid[period][day]
|
||||
if courses:
|
||||
cell_content = ''.join(
|
||||
f'<div class="course-item">{c}</div>'
|
||||
for c in courses
|
||||
)
|
||||
cell_content = ''
|
||||
for c in courses:
|
||||
type_class = type_classes[course_type_counter % len(type_classes)]
|
||||
course_type_counter += 1
|
||||
cell_content += f'<div class="course-item {type_class}">{c}</div>'
|
||||
else:
|
||||
cell_content = ''
|
||||
|
||||
row_html += f'<td class="course-cell">{cell_content}</td>'
|
||||
row_html += f'<td class="day-cell">{cell_content}</td>'
|
||||
|
||||
row_html += '</tr>'
|
||||
rows.append(row_html)
|
||||
|
||||
return '\n'.join(rows)
|
||||
|
||||
|
||||
def _get_period_time(self, period: int) -> str:
|
||||
"""获取节次对应的时间(南邮标准时间)"""
|
||||
# 南邮标准作息时间,可根据需要调整
|
||||
|
||||
Reference in New Issue
Block a user