107 lines
3.5 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
热点数据模型
"""
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional, List
from enum import Enum
class HotTopicSource(Enum):
"""热点来源"""
WEIBO = "weibo" # 微博热搜
XIAOHONGSHU = "xhs" # 小红书
DOUYIN = "douyin" # 抖音
BAIDU = "baidu" # 百度热搜
BING = "bing" # Bing 搜索
CALENDAR = "calendar" # 节日日历
CUSTOM = "custom" # 自定义
class HotTopicCategory(Enum):
"""热点分类"""
TRAVEL = "travel" # 旅游相关
FOOD = "food" # 美食
FESTIVAL = "festival" # 节日节气
EVENT = "event" # 热门事件
TRENDING = "trending" # 热门话题
SEASON = "season" # 季节性
OTHER = "other" # 其他
@dataclass
class HotTopic:
"""热点话题"""
# 基本信息
title: str # 话题标题
source: HotTopicSource # 来源平台
# 可选信息
rank: Optional[int] = None # 排名
heat: Optional[int] = None # 热度值
category: HotTopicCategory = HotTopicCategory.OTHER
url: Optional[str] = None # 原始链接
description: Optional[str] = None # 描述
tags: List[str] = field(default_factory=list) # 标签
# 时间信息
fetched_at: datetime = field(default_factory=datetime.now)
expires_at: Optional[datetime] = None # 过期时间
# 额外数据
extra: dict = field(default_factory=dict)
def to_dict(self) -> dict:
"""转换为字典"""
return {
'title': self.title,
'source': self.source.value,
'rank': self.rank,
'heat': self.heat,
'category': self.category.value,
'url': self.url,
'description': self.description,
'tags': self.tags,
'fetched_at': self.fetched_at.isoformat(),
'expires_at': self.expires_at.isoformat() if self.expires_at else None,
'extra': self.extra,
}
@classmethod
def from_dict(cls, data: dict) -> 'HotTopic':
"""从字典创建"""
return cls(
title=data['title'],
source=HotTopicSource(data.get('source', 'custom')),
rank=data.get('rank'),
heat=data.get('heat'),
category=HotTopicCategory(data.get('category', 'other')),
url=data.get('url'),
description=data.get('description'),
tags=data.get('tags', []),
fetched_at=datetime.fromisoformat(data['fetched_at']) if data.get('fetched_at') else datetime.now(),
expires_at=datetime.fromisoformat(data['expires_at']) if data.get('expires_at') else None,
extra=data.get('extra', {}),
)
def is_expired(self) -> bool:
"""检查是否过期"""
if self.expires_at is None:
return False
return datetime.now() > self.expires_at
def is_travel_related(self) -> bool:
"""检查是否与旅游相关"""
travel_keywords = [
'旅游', '旅行', '景区', '景点', '酒店', '民宿',
'攻略', '自驾', '度假', '出游', '周边游', '亲子游',
'海边', '沙滩', '温泉', '滑雪', '露营', '徒步',
]
title_lower = self.title.lower()
return any(kw in title_lower for kw in travel_keywords)