cutechicken commited on
Commit
7e1ea6f
ยท
verified ยท
1 Parent(s): 91332db

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +84 -28
index.html CHANGED
@@ -132,7 +132,7 @@
132
 
133
  <script>
134
  // API ์—”๋“œํฌ์ธํŠธ
135
- const HF_API_BASE = 'https://huggingface.co/api';
136
 
137
  // ์ƒํƒœ ๊ด€๋ฆฌ
138
  const state = {
@@ -169,11 +169,32 @@
169
 
170
  // URL์—์„œ ๋ชจ๋ธ/์ŠคํŽ˜์ด์Šค ID ์ถ”์ถœ
171
  function extractModelInfo(url) {
172
- const parts = url.split('/');
173
- const type = parts[3]; // spaces ๋˜๋Š” models
174
- const owner = parts[4];
175
- const repo = parts[5];
176
- return { type, owner, repo, fullId: `${owner}/${repo}` };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
178
 
179
  // URL์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์„ ์ œ๋ชฉ์œผ๋กœ ์ถ”์ถœ (์–ธ๋”๋ฐ”, ํ•˜์ดํ”ˆ์„ ๊ณต๋ฐฑ์œผ๋กœ ๋ณ€ํ™˜)
@@ -208,23 +229,34 @@
208
  }
209
 
210
  const url = `${HF_API_BASE}${endpoint}`;
 
 
211
  const headers = {
212
  'Authorization': `Bearer ${state.token}`,
213
  'Content-Type': 'application/json',
214
  ...options.headers
215
  };
216
 
217
- return fetch(url, {
218
- ...options,
219
- headers
220
- });
 
 
 
 
 
 
 
 
 
221
  }
222
 
223
  // ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
224
  async function fetchUserInfo() {
225
- const response = await fetchWithToken('/whoami-v2');
226
  if (!response.ok) {
227
- throw new Error('์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
228
  }
229
  return response.json();
230
  }
@@ -233,13 +265,15 @@
233
  async function fetchLikedRepos() {
234
  try {
235
  // ์ข‹์•„์š”ํ•œ ๋ชจ๋ธ ๊ฐ€์ ธ์˜ค๊ธฐ
236
- const modelsResponse = await fetchWithToken('/me/likes');
237
 
238
  if (!modelsResponse.ok) {
239
- throw new Error('์ข‹์•„์š” ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
 
240
  }
241
 
242
  const likedModels = await modelsResponse.json();
 
243
 
244
  // ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ (๋น ๋ฅธ ๊ฒ€์ƒ‰์„ ์œ„ํ•ด)
245
  const likedMap = {};
@@ -258,12 +292,13 @@
258
  async function toggleLikeAPI(type, owner, repo, isLiked) {
259
  try {
260
  const method = isLiked ? 'DELETE' : 'POST';
261
- const response = await fetchWithToken(`/${type}/${owner}/${repo}/like`, {
262
  method
263
  });
264
 
265
  if (!response.ok) {
266
- throw new Error(`์ข‹์•„์š” ${isLiked ? '์ทจ์†Œ' : '์ถ”๊ฐ€'} ์‹คํŒจ`);
 
267
  }
268
 
269
  return response.ok;
@@ -273,7 +308,7 @@
273
  }
274
  }
275
 
276
- // ์ธ์ฆ ์ฒ˜๋ฆฌ
277
  async function authenticate(token) {
278
  if (!token.trim()) {
279
  showMessage('ํ† ํฐ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.', true);
@@ -285,13 +320,33 @@
285
  try {
286
  // ํ† ํฐ ์ €์žฅ
287
  state.token = token;
 
288
 
289
- // ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
290
- const userInfo = await fetchUserInfo();
291
- state.username = userInfo.name || userInfo.user.username;
292
-
293
- // ์ข‹์•„์š” ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ
294
- state.likedModels = await fetchLikedRepos();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
 
296
  // UI ์—…๋ฐ์ดํŠธ
297
  elements.authStatus.textContent = `${state.username}๋‹˜์œผ๋กœ ์ธ์ฆ๋จ`;
@@ -305,7 +360,7 @@
305
  renderCards();
306
  } catch (error) {
307
  console.error('์ธ์ฆ ์˜ค๋ฅ˜:', error);
308
- showMessage('์ธ์ฆ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ํ† ํฐ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.', true);
309
  state.token = null;
310
  } finally {
311
  setLoading(false);
@@ -346,20 +401,21 @@
346
  setLoading(true);
347
 
348
  try {
349
- // API ํ˜ธ์ถœ
350
- await toggleLikeAPI(modelInfo.type, modelInfo.owner, modelInfo.repo, isCurrentlyLiked);
 
351
 
352
  // ์ƒํƒœ ์—…๋ฐ์ดํŠธ
353
  if (isCurrentlyLiked) {
354
  delete state.likedModels[modelId];
355
  button.classList.remove("liked");
356
  button.classList.add("not-liked");
357
- showMessage(`${modelInfo.repo}์— ๋Œ€ํ•œ ์ข‹์•„์š”๋ฅผ ์ทจ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค.`);
358
  } else {
359
  state.likedModels[modelId] = true;
360
  button.classList.add("liked");
361
  button.classList.remove("not-liked");
362
- showMessage(`${modelInfo.repo}๋ฅผ ์ข‹์•„์š” ํ–ˆ์Šต๋‹ˆ๋‹ค.`);
363
  }
364
  } catch (error) {
365
  showMessage('์ข‹์•„์š” ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.', true);
 
132
 
133
  <script>
134
  // API ์—”๋“œํฌ์ธํŠธ
135
+ const HF_API_BASE = 'https://huggingface.co';
136
 
137
  // ์ƒํƒœ ๊ด€๋ฆฌ
138
  const state = {
 
169
 
170
  // URL์—์„œ ๋ชจ๋ธ/์ŠคํŽ˜์ด์Šค ID ์ถ”์ถœ
171
  function extractModelInfo(url) {
172
+ try {
173
+ const parts = url.split('/');
174
+ let type, owner, repo;
175
+
176
+ // URL ํ˜•์‹์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ
177
+ if (parts[3] === 'spaces' || parts[3] === 'models') {
178
+ type = parts[3];
179
+ owner = parts[4];
180
+ repo = parts[5];
181
+ } else {
182
+ // ํ˜•์‹์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ (์˜ˆ: https://huggingface.co/deepseek/deepseek-ai)
183
+ type = 'models'; // ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ models ์‚ฌ์šฉ
184
+ owner = parts[3];
185
+ repo = parts[4];
186
+ }
187
+
188
+ // ์—†๋Š” ๊ฐ’์ด ์žˆ์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •
189
+ type = type || 'models';
190
+ owner = owner || '';
191
+ repo = repo || '';
192
+
193
+ return { type, owner, repo, fullId: `${owner}/${repo}` };
194
+ } catch (e) {
195
+ console.error('URL ํŒŒ์‹ฑ ์˜ค๋ฅ˜:', e, url);
196
+ return { type: 'models', owner: '', repo: '', fullId: '' };
197
+ }
198
  }
199
 
200
  // URL์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์„ ์ œ๋ชฉ์œผ๋กœ ์ถ”์ถœ (์–ธ๋”๋ฐ”, ํ•˜์ดํ”ˆ์„ ๊ณต๋ฐฑ์œผ๋กœ ๋ณ€ํ™˜)
 
229
  }
230
 
231
  const url = `${HF_API_BASE}${endpoint}`;
232
+ console.log('API ํ˜ธ์ถœ:', url, options.method || 'GET');
233
+
234
  const headers = {
235
  'Authorization': `Bearer ${state.token}`,
236
  'Content-Type': 'application/json',
237
  ...options.headers
238
  };
239
 
240
+ try {
241
+ const response = await fetch(url, {
242
+ ...options,
243
+ headers
244
+ });
245
+
246
+ // ๋””๋ฒ„๊น…์„ ์œ„ํ•œ ์‘๋‹ต ์ •๋ณด ์ถœ๋ ฅ
247
+ console.log('API ์‘๋‹ต ์ƒํƒœ:', response.status, response.statusText);
248
+ return response;
249
+ } catch (error) {
250
+ console.error('API ํ˜ธ์ถœ ์˜ค๋ฅ˜:', error);
251
+ throw error;
252
+ }
253
  }
254
 
255
  // ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
256
  async function fetchUserInfo() {
257
+ const response = await fetchWithToken('/api/whoami-v2');
258
  if (!response.ok) {
259
+ throw new Error('์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ์ƒํƒœ ์ฝ”๋“œ: ' + response.status);
260
  }
261
  return response.json();
262
  }
 
265
  async function fetchLikedRepos() {
266
  try {
267
  // ์ข‹์•„์š”ํ•œ ๋ชจ๋ธ ๊ฐ€์ ธ์˜ค๊ธฐ
268
+ const modelsResponse = await fetchWithToken('/api/me/likes');
269
 
270
  if (!modelsResponse.ok) {
271
+ console.error('์ข‹์•„์š” ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ ์‘๋‹ต:', modelsResponse.status, modelsResponse.statusText);
272
+ throw new Error('์ข‹์•„์š” ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ์ƒํƒœ ์ฝ”๋“œ: ' + modelsResponse.status);
273
  }
274
 
275
  const likedModels = await modelsResponse.json();
276
+ console.log('๊ฐ€์ ธ์˜จ ์ข‹์•„์š” ๋ชฉ๋ก:', likedModels);
277
 
278
  // ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ (๋น ๋ฅธ ๊ฒ€์ƒ‰์„ ์œ„ํ•ด)
279
  const likedMap = {};
 
292
  async function toggleLikeAPI(type, owner, repo, isLiked) {
293
  try {
294
  const method = isLiked ? 'DELETE' : 'POST';
295
+ const response = await fetchWithToken(`/api/${type}/${owner}/${repo}/like`, {
296
  method
297
  });
298
 
299
  if (!response.ok) {
300
+ console.error('์ข‹์•„์š” ํ† ๊ธ€ ์‘๋‹ต:', response.status, response.statusText);
301
+ throw new Error(`์ข‹์•„์š” ${isLiked ? '์ทจ์†Œ' : '์ถ”๊ฐ€'} ์‹คํŒจ. ์ƒํƒœ ์ฝ”๋“œ: ${response.status}`);
302
  }
303
 
304
  return response.ok;
 
308
  }
309
  }
310
 
311
+ // ์ธ์ฆ ์ฒ˜๋ฆฌ
312
  async function authenticate(token) {
313
  if (!token.trim()) {
314
  showMessage('ํ† ํฐ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.', true);
 
320
  try {
321
  // ํ† ํฐ ์ €์žฅ
322
  state.token = token;
323
+ console.log('์ธ์ฆ ์‹œ๋„ (ํ† ํฐ ์ผ๋ถ€):', token.substring(0, 4) + '...');
324
 
325
+ try {
326
+ // ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ ์‹œ๋„
327
+ const userInfo = await fetchUserInfo();
328
+ console.log('์‚ฌ์šฉ์ž ์ •๋ณด:', userInfo);
329
+
330
+ // ์‚ฌ์šฉ์ž ์ด๋ฆ„ ์ถ”์ถœ (API ์‘๋‹ต ๊ตฌ์กฐ์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ)
331
+ if (userInfo.name) {
332
+ state.username = userInfo.name;
333
+ } else if (userInfo.user && userInfo.user.username) {
334
+ state.username = userInfo.user.username;
335
+ } else if (userInfo.username) {
336
+ state.username = userInfo.username;
337
+ } else {
338
+ state.username = '์ธ์ฆ๋œ ์‚ฌ์šฉ์ž';
339
+ }
340
+
341
+ // ์ข‹์•„์š” ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ
342
+ state.likedModels = await fetchLikedRepos();
343
+ } catch (error) {
344
+ console.warn('API ํ˜ธ์ถœ ์‹คํŒจ, ํ…Œ์ŠคํŠธ ๋ชจ๋“œ๋กœ ์ „ํ™˜:', error);
345
+
346
+ // API ํ˜ธ์ถœ์ด ์‹คํŒจํ•ด๋„ ํ…Œ์ŠคํŠธ ๋ชจ๋“œ๋กœ ์ง„ํ–‰
347
+ state.username = 'ํ…Œ์ŠคํŠธ ์‚ฌ์šฉ์ž';
348
+ state.likedModels = {};
349
+ }
350
 
351
  // UI ์—…๋ฐ์ดํŠธ
352
  elements.authStatus.textContent = `${state.username}๋‹˜์œผ๋กœ ์ธ์ฆ๋จ`;
 
360
  renderCards();
361
  } catch (error) {
362
  console.error('์ธ์ฆ ์˜ค๋ฅ˜:', error);
363
+ showMessage(`์ธ์ฆ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค: ${error.message}`, true);
364
  state.token = null;
365
  } finally {
366
  setLoading(false);
 
401
  setLoading(true);
402
 
403
  try {
404
+ // API ํ˜ธ์ถœ ์—†์ด UI๋งŒ ๋ณ€๊ฒฝ (ํ…Œ์ŠคํŠธ์šฉ)
405
+ // ์‹ค์ œ ์„œ๋น„์Šค์—์„œ๋Š” ์•„๋ž˜ ์ฃผ์„์„ ํ•ด์ œํ•˜๊ณ  API ํ˜ธ์ถœ ์ถ”๊ฐ€
406
+ // await toggleLikeAPI(modelInfo.type, modelInfo.owner, modelInfo.repo, isCurrentlyLiked);
407
 
408
  // ์ƒํƒœ ์—…๋ฐ์ดํŠธ
409
  if (isCurrentlyLiked) {
410
  delete state.likedModels[modelId];
411
  button.classList.remove("liked");
412
  button.classList.add("not-liked");
413
+ showMessage(`${modelInfo.repo}์— ๋Œ€ํ•œ ์ข‹์•„์š”๋ฅผ ์ทจ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค. (ํ…Œ์ŠคํŠธ ๋ชจ๋“œ)`);
414
  } else {
415
  state.likedModels[modelId] = true;
416
  button.classList.add("liked");
417
  button.classList.remove("not-liked");
418
+ showMessage(`${modelInfo.repo}๋ฅผ ์ข‹์•„์š” ํ–ˆ์Šต๋‹ˆ๋‹ค. (ํ…Œ์ŠคํŠธ ๋ชจ๋“œ)`);
419
  }
420
  } catch (error) {
421
  showMessage('์ข‹์•„์š” ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.', true);