Spaces:
Sleeping
Sleeping
Add public timeline API support and update timeline docs
Browse files- README.md +44 -12
- fanfou_client.py +25 -4
- main.py +56 -8
README.md
CHANGED
|
@@ -101,32 +101,64 @@ uv run main.py
|
|
| 101 |
|
| 102 |
### get_user_timeline
|
| 103 |
|
| 104 |
-
|
| 105 |
|
| 106 |
**参数:**
|
| 107 |
-
- `
|
| 108 |
-
- `
|
|
|
|
| 109 |
|
| 110 |
**返回:**
|
| 111 |
- 用户时间线列表,包含以下字段:
|
| 112 |
-
- `饭否内容`:
|
| 113 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
### get_home_timeline
|
| 116 |
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
**参数:**
|
| 120 |
-
- `count` (int, 可选): 获取数量,默认
|
| 121 |
-
- `max_id` (str, 可选):
|
| 122 |
|
| 123 |
**返回:**
|
| 124 |
- 首页时间线列表,包含以下字段:
|
| 125 |
-
- `饭否内容`:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
- `发布时间`: 消息发布时间
|
| 127 |
-
- `发布者`:
|
| 128 |
-
- `发布者 ID`: 发布者的用户ID
|
| 129 |
-
- `图片链接`:
|
| 130 |
|
| 131 |
## 许可证
|
| 132 |
|
|
|
|
| 101 |
|
| 102 |
### get_user_timeline
|
| 103 |
|
| 104 |
+
根据用户 ID 获取某个用户发表内容的时间线
|
| 105 |
|
| 106 |
**参数:**
|
| 107 |
+
- `user_id` (str, 可选): 用户 ID,如果为空则获取当前用户时间线
|
| 108 |
+
- `max_id` (str, 可选): 返回列表中内容最新 ID,用于分页获取更早的内容
|
| 109 |
+
- `count` (int, 可选): 获取数量,默认 5 条
|
| 110 |
|
| 111 |
**返回:**
|
| 112 |
- 用户时间线列表,包含以下字段:
|
| 113 |
+
- `饭否内容`: 饭否消息内容(HTML 格式)
|
| 114 |
+
- `饭否 ID`: 消息的唯一标识符
|
| 115 |
+
- `发布时间`: 消息发布时间
|
| 116 |
+
- `发布者`: 发布者的显示名称
|
| 117 |
+
- `发布者 ID`: 发布者的用户 ID
|
| 118 |
+
- `图片链接`: 如果包含图片,则提供图片链接
|
| 119 |
|
| 120 |
### get_home_timeline
|
| 121 |
|
| 122 |
+
获取当前用户首页关注用户及自己的饭否时间线
|
| 123 |
+
|
| 124 |
+
**功能:**
|
| 125 |
+
- 调用饭否 API 的 /statuses/home_timeline.json 接口获取当前用户的首页时间线
|
| 126 |
+
- 包含用户关注的所有人的最新消息
|
| 127 |
+
- 注:通常用户询问「我的饭否」时,指的是该时间线,除非用户明确指出「某个用户的饭否」
|
| 128 |
|
| 129 |
**参数:**
|
| 130 |
+
- `count` (int, 可选): 获取数量,默认 5 条
|
| 131 |
+
- `max_id` (str, 可选): 返回列表中内容最新 ID,用于分页获取更早的内容
|
| 132 |
|
| 133 |
**返回:**
|
| 134 |
- 首页时间线列表,包含以下字段:
|
| 135 |
+
- `饭否内容`: 饭否消息内容(HTML 格式)
|
| 136 |
+
- `饭否 ID`: 消息的唯一标识符
|
| 137 |
+
- `发布时间`: 消息发布时间
|
| 138 |
+
- `发布者`: 发布者的显示名称
|
| 139 |
+
- `发布者 ID`: 发布者的用户 ID
|
| 140 |
+
- `图片链接`: 如果包含图片,则提供图片链接
|
| 141 |
+
|
| 142 |
+
### get_public_timeline
|
| 143 |
+
|
| 144 |
+
获取公开时间线
|
| 145 |
+
|
| 146 |
+
**功能:**
|
| 147 |
+
- 调用饭否 API 的 /statuses/public_timeline.json 接口获取饭否全站最新的公开消息
|
| 148 |
+
- 这些是所有用户可见的公开饭否内容
|
| 149 |
+
|
| 150 |
+
**参数:**
|
| 151 |
+
- `count` (int, 可选): 获取数量,默认 5 条
|
| 152 |
+
- `max_id` (str, 可选): 返回列表中内容最新 ID,用于分页获取更早的内容
|
| 153 |
+
|
| 154 |
+
**返回:**
|
| 155 |
+
- 公开时间线列表,包含以下字段:
|
| 156 |
+
- `饭否内容`: 饭否消息内容(HTML 格式)
|
| 157 |
+
- `饭否 ID`: 消息的唯一标识符
|
| 158 |
- `发布时间`: 消息发布时间
|
| 159 |
+
- `发布者`: 发布者的显示名称
|
| 160 |
+
- `发布者 ID`: 发布者的用户 ID
|
| 161 |
+
- `图片链接`: 如果包含图片,则提供图片链接
|
| 162 |
|
| 163 |
## 许可证
|
| 164 |
|
fanfou_client.py
CHANGED
|
@@ -83,9 +83,10 @@ class FanFou:
|
|
| 83 |
|
| 84 |
def request_user_timeline(self, user_id: str = '', max_id: str = '', count: int = 5) -> List[Dict[str, Any]]:
|
| 85 |
"""
|
| 86 |
-
根据用户 ID
|
|
|
|
| 87 |
user_id 为用户 ID,如果为空,则获取当前用户时间线
|
| 88 |
-
max_id
|
| 89 |
count 为获取数量,默认 5 条
|
| 90 |
"""
|
| 91 |
print('------ request_user_timeline ------')
|
|
@@ -105,8 +106,9 @@ class FanFou:
|
|
| 105 |
|
| 106 |
def get_home_timeline(self, count: int = 5, max_id: str = '') -> List[Dict[str, Any]]:
|
| 107 |
"""
|
| 108 |
-
|
| 109 |
-
|
|
|
|
| 110 |
count 为获取数量,默认 5 条
|
| 111 |
"""
|
| 112 |
print('------ get_home_timeline ------')
|
|
@@ -118,5 +120,24 @@ class FanFou:
|
|
| 118 |
token = oauth2.Token(self.token, self.token_secret)
|
| 119 |
client = oauth2.Client(consumer, token)
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
response, content = client.request(url)
|
| 122 |
return json.loads(content)
|
|
|
|
| 83 |
|
| 84 |
def request_user_timeline(self, user_id: str = '', max_id: str = '', count: int = 5) -> List[Dict[str, Any]]:
|
| 85 |
"""
|
| 86 |
+
根据用户 ID 获取某个用户发表内容的时间线
|
| 87 |
+
|
| 88 |
user_id 为用户 ID,如果为空,则获取当前用户时间线
|
| 89 |
+
max_id 为返回列表中内容最新 ID,如果为空,则获取最新时间线
|
| 90 |
count 为获取数量,默认 5 条
|
| 91 |
"""
|
| 92 |
print('------ request_user_timeline ------')
|
|
|
|
| 106 |
|
| 107 |
def get_home_timeline(self, count: int = 5, max_id: str = '') -> List[Dict[str, Any]]:
|
| 108 |
"""
|
| 109 |
+
获取当前用户首页关注用户及自己的饭否时间线
|
| 110 |
+
|
| 111 |
+
max_id 为返回列表中内容最新 ID,如果为空,则获取最新时间线
|
| 112 |
count 为获取数量,默认 5 条
|
| 113 |
"""
|
| 114 |
print('------ get_home_timeline ------')
|
|
|
|
| 120 |
token = oauth2.Token(self.token, self.token_secret)
|
| 121 |
client = oauth2.Client(consumer, token)
|
| 122 |
|
| 123 |
+
response, content = client.request(url)
|
| 124 |
+
return json.loads(content)
|
| 125 |
+
|
| 126 |
+
def get_public_timeline(self, count: int = 5, max_id: str = '') -> List[Dict[str, Any]]:
|
| 127 |
+
"""
|
| 128 |
+
获取公开时间线,获取饭否全站最新的公开消息
|
| 129 |
+
|
| 130 |
+
max_id 为返回列表中内容最新 ID,如果为空,则获取最新时间线
|
| 131 |
+
count 为获取数量,默认 5 条
|
| 132 |
+
"""
|
| 133 |
+
print('------ get_public_timeline ------')
|
| 134 |
+
url = f"http://api.fanfou.com/statuses/public_timeline.json?count={count}&format=html"
|
| 135 |
+
if max_id:
|
| 136 |
+
url += f"&max_id={max_id}"
|
| 137 |
+
|
| 138 |
+
consumer = oauth2.Consumer(self.api_key, self.api_secret)
|
| 139 |
+
token = oauth2.Token(self.token, self.token_secret)
|
| 140 |
+
client = oauth2.Client(consumer, token)
|
| 141 |
+
|
| 142 |
response, content = client.request(url)
|
| 143 |
return json.loads(content)
|
main.py
CHANGED
|
@@ -124,17 +124,17 @@ def generate_oauth_token() -> Dict[str, str]:
|
|
| 124 |
return {"error": str(e)}
|
| 125 |
|
| 126 |
@mcp.tool()
|
| 127 |
-
def get_user_timeline(user_id: str = '', max_id: str = '', count: int =
|
| 128 |
"""
|
| 129 |
-
|
| 130 |
|
| 131 |
调用饭否 API 的 /statuses/user_timeline.json 接口获取指定用户的时间线。
|
| 132 |
如果 user_id 为空,则获取当前登录用户的时间线。
|
| 133 |
|
| 134 |
Args:
|
| 135 |
user_id: 用户 ID,如果为空则获取当前用户时间线
|
| 136 |
-
max_id:
|
| 137 |
-
count: 获取数量,默认
|
| 138 |
|
| 139 |
Returns:
|
| 140 |
用户时间线列表,每个元素包含:
|
|
@@ -171,16 +171,18 @@ def get_user_timeline(user_id: str = '', max_id: str = '', count: int = 10) -> L
|
|
| 171 |
return [{"error": str(e)}]
|
| 172 |
|
| 173 |
@mcp.tool()
|
| 174 |
-
def get_home_timeline(count: int =
|
| 175 |
"""
|
| 176 |
-
|
| 177 |
|
| 178 |
调用饭否 API 的 /statuses/home_timeline.json 接口获取当前用户的首页时间线,
|
| 179 |
包含用户关注的所有人的最新消息。
|
|
|
|
|
|
|
| 180 |
|
| 181 |
Args:
|
| 182 |
-
count: 获取数量,默认
|
| 183 |
-
max_id:
|
| 184 |
|
| 185 |
Returns:
|
| 186 |
首页时间线列表,每个元素包含:
|
|
@@ -216,6 +218,52 @@ def get_home_timeline(count: int = 20, max_id: str = '') -> List[Dict[str, Any]]
|
|
| 216 |
except Exception as e:
|
| 217 |
return [{"error": str(e)}]
|
| 218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
if __name__ == "__main__":
|
| 220 |
# 启动服务器
|
| 221 |
mcp.run()
|
|
|
|
| 124 |
return {"error": str(e)}
|
| 125 |
|
| 126 |
@mcp.tool()
|
| 127 |
+
def get_user_timeline(user_id: str = '', max_id: str = '', count: int = 5) -> List[Dict[str, Any]]:
|
| 128 |
"""
|
| 129 |
+
根据用户 ID 获取某个用户发表内容的时间线
|
| 130 |
|
| 131 |
调用饭否 API 的 /statuses/user_timeline.json 接口获取指定用户的时间线。
|
| 132 |
如果 user_id 为空,则获取当前登录用户的时间线。
|
| 133 |
|
| 134 |
Args:
|
| 135 |
user_id: 用户 ID,如果为空则获取当前用户时间线
|
| 136 |
+
max_id: 返回列表中内容最新 ID,用于分页获取更早的内容
|
| 137 |
+
count: 获取数量,默认 5 条
|
| 138 |
|
| 139 |
Returns:
|
| 140 |
用户时间线列表,每个元素包含:
|
|
|
|
| 171 |
return [{"error": str(e)}]
|
| 172 |
|
| 173 |
@mcp.tool()
|
| 174 |
+
def get_home_timeline(count: int = 5, max_id: str = '') -> List[Dict[str, Any]]:
|
| 175 |
"""
|
| 176 |
+
获取当前用户首页关注用户及自己的饭否时间线
|
| 177 |
|
| 178 |
调用饭否 API 的 /statuses/home_timeline.json 接口获取当前用户的首页时间线,
|
| 179 |
包含用户关注的所有人的最新消息。
|
| 180 |
+
|
| 181 |
+
注:通常用户询问「我的饭否」时,指的是该时间线,除非用户明确指出「某个用户的饭否」。
|
| 182 |
|
| 183 |
Args:
|
| 184 |
+
count: 获取数量,默认 5 条
|
| 185 |
+
max_id: 返回列表中内容最新 ID,用于分页获取更早的内容
|
| 186 |
|
| 187 |
Returns:
|
| 188 |
首页时间线列表,每个元素包含:
|
|
|
|
| 218 |
except Exception as e:
|
| 219 |
return [{"error": str(e)}]
|
| 220 |
|
| 221 |
+
@mcp.tool()
|
| 222 |
+
def get_public_timeline(count: int = 5, max_id: str = '') -> List[Dict[str, Any]]:
|
| 223 |
+
"""
|
| 224 |
+
获取公开时间线
|
| 225 |
+
|
| 226 |
+
调用饭否 API 的 /statuses/public_timeline.json 接口获取饭否全站最新的公开消息,
|
| 227 |
+
这些是所有用户可见的公开饭否内容。
|
| 228 |
+
|
| 229 |
+
Args:
|
| 230 |
+
count: 获取数量,默认 5 条
|
| 231 |
+
max_id: 返回列表中内容最新 ID,用于分页获取更早的内容
|
| 232 |
+
|
| 233 |
+
Returns:
|
| 234 |
+
公开时间线列表,每个元素包含:
|
| 235 |
+
- 饭否内容: 消息文本内容(HTML 格式)
|
| 236 |
+
- 饭否 ID: 消息的唯一标识符
|
| 237 |
+
- 发布时间: 消息发布时间
|
| 238 |
+
- 发布者: 发布者的显示名称
|
| 239 |
+
- 发布者 ID: 发布者的用户 ID
|
| 240 |
+
- 图片链接: 如果包含图片,则提供图片链接
|
| 241 |
+
"""
|
| 242 |
+
try:
|
| 243 |
+
client = get_fanfou_client()
|
| 244 |
+
raw_data = client.get_public_timeline(count, max_id)
|
| 245 |
+
|
| 246 |
+
# 过滤返回数据,只保留关键信息
|
| 247 |
+
filtered_data = []
|
| 248 |
+
for item in raw_data:
|
| 249 |
+
filtered_item = {
|
| 250 |
+
"饭否内容": item.get("text", ""),
|
| 251 |
+
"饭否 ID": item.get("id", ""),
|
| 252 |
+
"发布时间": item.get("created_at", ""),
|
| 253 |
+
"发布者": item.get("user", {}).get("screen_name", ""),
|
| 254 |
+
"发布者 ID": item.get("user", {}).get("id", "")
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
# 如果有图片,添加 imageurl
|
| 258 |
+
if "photo" in item and item["photo"]:
|
| 259 |
+
filtered_item["图片链接"] = item["photo"].get("largeurl", "")
|
| 260 |
+
|
| 261 |
+
filtered_data.append(filtered_item)
|
| 262 |
+
|
| 263 |
+
return filtered_data
|
| 264 |
+
except Exception as e:
|
| 265 |
+
return [{"error": str(e)}]
|
| 266 |
+
|
| 267 |
if __name__ == "__main__":
|
| 268 |
# 启动服务器
|
| 269 |
mcp.run()
|