- Add hotspot_source/hotspot_item/hotspot_analysis table definitions - Add MySQL DDL for all three tables with indexes - Create hotspot dashboard UI (index.ui) with stats, tabs for CRUD - Add DSPY endpoints: stats, fetch_now (RSS/API), analyze (auto-classify) - Register paths in load_path.py with logined access - Add '热点雷达' menu entry
56 lines
1.7 KiB
Plaintext
56 lines
1.7 KiB
Plaintext
# 自动分析热点状态:根据时间和热度自动分类
|
|
# rising -> hot -> cooling -> expired
|
|
from datetime import datetime, timedelta
|
|
from sqlor.dbpools import DBPools
|
|
|
|
async def main(request):
|
|
db = DBPools()
|
|
now = datetime.now()
|
|
analyzed = 0
|
|
|
|
async with db.sqlorContext('sage') as sor:
|
|
items = await sor.sqlExe(
|
|
"select * from hotspot_item order by fetch_time desc",
|
|
{}
|
|
)
|
|
|
|
for item in items:
|
|
try:
|
|
fetch_time = datetime.strptime(str(item.get('fetch_time', '')), '%Y-%m-%d %H:%M:%S')
|
|
except:
|
|
fetch_time = now
|
|
|
|
hours_ago = (now - fetch_time).total_seconds() / 3600
|
|
heat = int(item.get('heat_score', 0))
|
|
current_status = item.get('status', 'rising')
|
|
|
|
# 热度衰减计算
|
|
decay_factor = max(0, 1 - hours_ago / 168) # 7天衰减到0
|
|
adjusted_heat = heat * decay_factor
|
|
|
|
# 状态分类
|
|
if hours_ago > 168: # 超过7天
|
|
new_status = 'expired'
|
|
elif hours_ago > 72: # 超过3天
|
|
new_status = 'cooling'
|
|
elif adjusted_heat > 500:
|
|
new_status = 'hot'
|
|
elif adjusted_heat > 100:
|
|
new_status = 'rising'
|
|
else:
|
|
new_status = 'cooling' if hours_ago > 24 else 'rising'
|
|
|
|
if new_status != current_status:
|
|
async with db.sqlorContext('sage') as sor:
|
|
await sor.U('hotspot_item', {
|
|
'id': item['id'],
|
|
'status': new_status,
|
|
'heat_score': int(adjusted_heat),
|
|
})
|
|
analyzed += 1
|
|
|
|
return {
|
|
'analyzed': analyzed,
|
|
'time': now.strftime('%Y-%m-%d %H:%M:%S'),
|
|
}
|