kingcos commited on
Commit
598fd92
·
1 Parent(s): 3e89b9d

Add public timeline API support and update timeline docs

Browse files
Files changed (3) hide show
  1. README.md +44 -12
  2. fanfou_client.py +25 -4
  3. 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
- - `max_id` (str, 可选): 最大 ID,用于分页,默认为空字符串
108
- - `count` (int, 可选): 获取数量,默认 10 条
 
109
 
110
  **返回:**
111
  - 用户时间线列表,包含以下字段:
112
- - `饭否内容`: 饭否消息内容
113
- - `图片链接`: 如果有图片,返回图片的大图链接
 
 
 
 
114
 
115
  ### get_home_timeline
116
 
117
- 获取首页时间线
 
 
 
 
 
118
 
119
  **参数:**
120
- - `count` (int, 可选): 获取数量,默认 20
121
- - `max_id` (str, 可选): 最大 ID,用于分页,默认为空字符串
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 为饭否内容最大 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
- max_id 为饭否内容最大 ID,如果为空,则获取最新时间线
 
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 = 10) -> List[Dict[str, Any]]:
128
  """
129
- 获取用户时间线
130
 
131
  调用饭否 API 的 /statuses/user_timeline.json 接口获取指定用户的时间线。
132
  如果 user_id 为空,则获取当前登录用户的时间线。
133
 
134
  Args:
135
  user_id: 用户 ID,如果为空则获取当前用户时间线
136
- max_id: 最大饭否 ID,用于分页获取更早的内容
137
- count: 获取数量,默认 10 条,最大 60
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 = 20, max_id: str = '') -> List[Dict[str, Any]]:
175
  """
176
- 获取首页时间线
177
 
178
  调用饭否 API 的 /statuses/home_timeline.json 接口获取当前用户的首页时间线,
179
  包含用户关注的所有人的最新消息。
 
 
180
 
181
  Args:
182
- count: 获取数量,默认 20 条,最大 60
183
- max_id: 最大饭否 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()