note-connector 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/py/pyproject.toml +1 -1
- package/py/src/note_mcp/api/images.py +59 -11
- package/py/src/note_mcp/server.py +6 -2
package/package.json
CHANGED
package/py/pyproject.toml
CHANGED
|
@@ -117,6 +117,43 @@ _MAGIC_BYTES: dict[str, tuple[bytes, int]] = {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
|
|
120
|
+
def _extract_image_url_from_response(response: dict[str, Any]) -> str | None:
|
|
121
|
+
"""Extract image URL from API response, trying multiple possible field names.
|
|
122
|
+
|
|
123
|
+
note.com API may return the URL under different field names.
|
|
124
|
+
This function tries known field names in order of preference.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
response: Full API response dictionary
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Image URL string if found, None otherwise
|
|
131
|
+
"""
|
|
132
|
+
data = response.get("data", {})
|
|
133
|
+
|
|
134
|
+
# Try known field names for image URL
|
|
135
|
+
candidate_keys = [
|
|
136
|
+
"url",
|
|
137
|
+
"image_url",
|
|
138
|
+
"src",
|
|
139
|
+
"download_url",
|
|
140
|
+
"note_image_url",
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
for key in candidate_keys:
|
|
144
|
+
value = data.get(key)
|
|
145
|
+
if value and isinstance(value, str) and value.strip():
|
|
146
|
+
return str(value)
|
|
147
|
+
|
|
148
|
+
# Check if the top-level response itself is a string URL
|
|
149
|
+
for key in candidate_keys:
|
|
150
|
+
value = response.get(key)
|
|
151
|
+
if value and isinstance(value, str) and value.strip():
|
|
152
|
+
return str(value)
|
|
153
|
+
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
|
|
120
157
|
def validate_image_file(file_path: str) -> None:
|
|
121
158
|
"""Validate image file before upload.
|
|
122
159
|
|
|
@@ -207,25 +244,36 @@ async def _upload_image_internal(
|
|
|
207
244
|
async with NoteAPIClient(session) as client:
|
|
208
245
|
response = await client.post(endpoint, files=files, data=data)
|
|
209
246
|
|
|
210
|
-
#
|
|
211
|
-
|
|
247
|
+
# Debug: log full API response for investigation
|
|
248
|
+
logger.debug(
|
|
249
|
+
"Image upload response for note_id=%s, endpoint=%s: %s",
|
|
250
|
+
numeric_note_id,
|
|
251
|
+
endpoint,
|
|
252
|
+
{k: v for k, v in response.items() if k != "data"},
|
|
253
|
+
)
|
|
254
|
+
if "data" in response:
|
|
255
|
+
logger.debug("Image upload response data keys: %s", list(response["data"].keys()))
|
|
256
|
+
logger.debug("Image upload response data: %s", response["data"])
|
|
212
257
|
|
|
213
|
-
#
|
|
214
|
-
|
|
215
|
-
|
|
258
|
+
# Extract image URL from response (tries multiple field names)
|
|
259
|
+
image_url = _extract_image_url_from_response(response)
|
|
260
|
+
|
|
261
|
+
image_data = response.get("data", {})
|
|
216
262
|
image_key = image_data.get("key")
|
|
217
263
|
|
|
218
|
-
|
|
264
|
+
# URL is optional - eyecatch API may not always return it
|
|
265
|
+
# The eyecatch is set server-side even without a URL in the response
|
|
219
266
|
if not image_url:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
267
|
+
logger.warning(
|
|
268
|
+
"Image upload response missing image URL for note_id=%s. Response keys: top=%s, data=%s",
|
|
269
|
+
numeric_note_id,
|
|
270
|
+
list(response.keys()),
|
|
271
|
+
list(image_data.keys()) if image_data else "none",
|
|
224
272
|
)
|
|
225
273
|
|
|
226
274
|
return Image(
|
|
227
275
|
key=str(image_key) if image_key else None,
|
|
228
|
-
url=str(image_url),
|
|
276
|
+
url=str(image_url) if image_url else "",
|
|
229
277
|
original_path=file_path,
|
|
230
278
|
size_bytes=file_size,
|
|
231
279
|
uploaded_at=int(time.time()),
|
|
@@ -285,7 +285,9 @@ async def note_upload_eyecatch(
|
|
|
285
285
|
アップロード結果(画像URLを含む)
|
|
286
286
|
"""
|
|
287
287
|
image = await upload_eyecatch_image(session, file_path, note_id=note_id)
|
|
288
|
-
|
|
288
|
+
if image.url:
|
|
289
|
+
return f"アイキャッチ画像をアップロードしました。URL: {image.url}"
|
|
290
|
+
return "アイキャッチ画像をアップロードしました。"
|
|
289
291
|
|
|
290
292
|
|
|
291
293
|
@mcp.tool()
|
|
@@ -319,7 +321,9 @@ async def note_set_eyecatch_base64(
|
|
|
319
321
|
mime_type=mime_type,
|
|
320
322
|
image_base64=image_base64,
|
|
321
323
|
)
|
|
322
|
-
|
|
324
|
+
if image.url:
|
|
325
|
+
return f"アイキャッチ画像を設定しました。URL: {image.url}"
|
|
326
|
+
return "アイキャッチ画像を設定しました。"
|
|
323
327
|
|
|
324
328
|
|
|
325
329
|
@mcp.tool()
|