#!/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)