Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -60,6 +60,7 @@ def get_space_details(space_data):
|
|
| 60 |
'embedUrl': embed_url,
|
| 61 |
'title': title,
|
| 62 |
'owner': owner,
|
|
|
|
| 63 |
'likes_count': likes_count,
|
| 64 |
'tags': tags
|
| 65 |
}
|
|
@@ -282,7 +283,7 @@ if __name__ == '__main__':
|
|
| 282 |
.rank-badge {
|
| 283 |
position: absolute;
|
| 284 |
top: 10px;
|
| 285 |
-
|
| 286 |
background: rgba(0,0,0,0.7);
|
| 287 |
color: white;
|
| 288 |
padding: 5px 15px;
|
|
@@ -308,6 +309,28 @@ if __name__ == '__main__':
|
|
| 308 |
border: none;
|
| 309 |
}
|
| 310 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
.loading {
|
| 312 |
position: fixed;
|
| 313 |
top: 0;
|
|
@@ -409,6 +432,11 @@ if __name__ == '__main__':
|
|
| 409 |
return response.json();
|
| 410 |
}
|
| 411 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
// Load spaces
|
| 413 |
async function loadSpaces() {
|
| 414 |
setLoading(true);
|
|
@@ -429,6 +457,39 @@ if __name__ == '__main__':
|
|
| 429 |
}
|
| 430 |
}
|
| 431 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
// Render grid
|
| 433 |
function renderGrid(spaces) {
|
| 434 |
elements.gridContainer.innerHTML = '';
|
|
@@ -443,7 +504,7 @@ if __name__ == '__main__':
|
|
| 443 |
}
|
| 444 |
|
| 445 |
spaces.forEach((item, index) => {
|
| 446 |
-
const { url, embedUrl, title, likes_count, owner } = item;
|
| 447 |
|
| 448 |
// Skip if owner is 'None'
|
| 449 |
if (owner === 'None') {
|
|
@@ -454,7 +515,7 @@ if __name__ == '__main__':
|
|
| 454 |
const gridItem = document.createElement('div');
|
| 455 |
gridItem.className = 'grid-item';
|
| 456 |
|
| 457 |
-
// Rank badge
|
| 458 |
const rankBadge = document.createElement('div');
|
| 459 |
rankBadge.className = 'rank-badge';
|
| 460 |
rankBadge.textContent = `#${index + 1}`;
|
|
@@ -507,15 +568,26 @@ if __name__ == '__main__':
|
|
| 507 |
const content = document.createElement('div');
|
| 508 |
content.className = 'grid-content';
|
| 509 |
|
| 510 |
-
// Create iframe to display the content
|
| 511 |
const iframe = document.createElement('iframe');
|
| 512 |
-
|
|
|
|
| 513 |
iframe.title = title;
|
| 514 |
iframe.allow = 'accelerometer; camera; encrypted-media; geolocation; gyroscope; microphone; midi';
|
| 515 |
iframe.setAttribute('allowfullscreen', '');
|
| 516 |
iframe.setAttribute('frameborder', '0');
|
| 517 |
iframe.loading = 'lazy'; // Lazy load iframes for better performance
|
| 518 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
content.appendChild(iframe);
|
| 520 |
|
| 521 |
// Add content to grid item
|
|
|
|
| 60 |
'embedUrl': embed_url,
|
| 61 |
'title': title,
|
| 62 |
'owner': owner,
|
| 63 |
+
'name': name, # Space ์ด๋ฆ ์ถ๊ฐ ์ ์ฅ
|
| 64 |
'likes_count': likes_count,
|
| 65 |
'tags': tags
|
| 66 |
}
|
|
|
|
| 283 |
.rank-badge {
|
| 284 |
position: absolute;
|
| 285 |
top: 10px;
|
| 286 |
+
right: 10px; /* ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ */
|
| 287 |
background: rgba(0,0,0,0.7);
|
| 288 |
color: white;
|
| 289 |
padding: 5px 15px;
|
|
|
|
| 309 |
border: none;
|
| 310 |
}
|
| 311 |
|
| 312 |
+
.error-placeholder {
|
| 313 |
+
position: absolute;
|
| 314 |
+
top: 0;
|
| 315 |
+
left: 0;
|
| 316 |
+
width: 100%;
|
| 317 |
+
height: 100%;
|
| 318 |
+
display: flex;
|
| 319 |
+
flex-direction: column;
|
| 320 |
+
justify-content: center;
|
| 321 |
+
align-items: center;
|
| 322 |
+
background-color: #f8f9fa;
|
| 323 |
+
color: #6c757d;
|
| 324 |
+
text-align: center;
|
| 325 |
+
padding: 20px;
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
.error-placeholder .error-icon {
|
| 329 |
+
font-size: 3rem;
|
| 330 |
+
margin-bottom: 1rem;
|
| 331 |
+
color: #dc3545;
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
.loading {
|
| 335 |
position: fixed;
|
| 336 |
top: 0;
|
|
|
|
| 432 |
return response.json();
|
| 433 |
}
|
| 434 |
|
| 435 |
+
// ์ง์ URL ์์ฑ ํจ์ (ํด๋ผ์ด์ธํธ ์ธก์์๋ ๊ตฌํ)
|
| 436 |
+
function createDirectUrl(owner, name) {
|
| 437 |
+
return `https://${owner}-${name}.hf.space`;
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
// Load spaces
|
| 441 |
async function loadSpaces() {
|
| 442 |
setLoading(true);
|
|
|
|
| 457 |
}
|
| 458 |
}
|
| 459 |
|
| 460 |
+
// iframe ๋ก๋ ์๋ฌ ์ฒ๋ฆฌ
|
| 461 |
+
function handleIframeError(iframe, owner, name, title) {
|
| 462 |
+
const container = iframe.parentNode;
|
| 463 |
+
|
| 464 |
+
// ์๋ฌ ๋ฉ์์ง ์ปจํ
์ด๋ ์์ฑ
|
| 465 |
+
const errorPlaceholder = document.createElement('div');
|
| 466 |
+
errorPlaceholder.className = 'error-placeholder';
|
| 467 |
+
|
| 468 |
+
// ์๋ฌ ์์ด์ฝ
|
| 469 |
+
const errorIcon = document.createElement('div');
|
| 470 |
+
errorIcon.className = 'error-icon';
|
| 471 |
+
errorIcon.textContent = 'โ ๏ธ';
|
| 472 |
+
errorPlaceholder.appendChild(errorIcon);
|
| 473 |
+
|
| 474 |
+
// ์๋ฌ ๋ฉ์์ง
|
| 475 |
+
const errorMessage = document.createElement('p');
|
| 476 |
+
errorMessage.textContent = `"${title}" ์คํ์ด์ค๋ฅผ ๋ก๋ํ ์ ์์ต๋๋ค.`;
|
| 477 |
+
errorPlaceholder.appendChild(errorMessage);
|
| 478 |
+
|
| 479 |
+
// ์ง์ ๋งํฌ ์ ๊ณต
|
| 480 |
+
const directLink = document.createElement('a');
|
| 481 |
+
directLink.href = `https://huggingface.co/spaces/${owner}/${name}`;
|
| 482 |
+
directLink.target = '_blank';
|
| 483 |
+
directLink.textContent = '์ง์ ๋ฐฉ๋ฌธํ๊ธฐ';
|
| 484 |
+
directLink.style.color = '#007bff';
|
| 485 |
+
directLink.style.marginTop = '10px';
|
| 486 |
+
errorPlaceholder.appendChild(directLink);
|
| 487 |
+
|
| 488 |
+
// iframe ์จ๊ธฐ๊ณ ์๋ฌ ๋ฉ์์ง ํ์
|
| 489 |
+
iframe.style.display = 'none';
|
| 490 |
+
container.appendChild(errorPlaceholder);
|
| 491 |
+
}
|
| 492 |
+
|
| 493 |
// Render grid
|
| 494 |
function renderGrid(spaces) {
|
| 495 |
elements.gridContainer.innerHTML = '';
|
|
|
|
| 504 |
}
|
| 505 |
|
| 506 |
spaces.forEach((item, index) => {
|
| 507 |
+
const { url, embedUrl, title, likes_count, owner, name } = item;
|
| 508 |
|
| 509 |
// Skip if owner is 'None'
|
| 510 |
if (owner === 'None') {
|
|
|
|
| 515 |
const gridItem = document.createElement('div');
|
| 516 |
gridItem.className = 'grid-item';
|
| 517 |
|
| 518 |
+
// Rank badge - ์ค๋ฅธ์ชฝ ์๋จ์ผ๋ก ์ด๋
|
| 519 |
const rankBadge = document.createElement('div');
|
| 520 |
rankBadge.className = 'rank-badge';
|
| 521 |
rankBadge.textContent = `#${index + 1}`;
|
|
|
|
| 568 |
const content = document.createElement('div');
|
| 569 |
content.className = 'grid-content';
|
| 570 |
|
| 571 |
+
// Create iframe to display the content - ์ง์ URL ์์ฑ
|
| 572 |
const iframe = document.createElement('iframe');
|
| 573 |
+
const directUrl = createDirectUrl(owner, name);
|
| 574 |
+
iframe.src = directUrl;
|
| 575 |
iframe.title = title;
|
| 576 |
iframe.allow = 'accelerometer; camera; encrypted-media; geolocation; gyroscope; microphone; midi';
|
| 577 |
iframe.setAttribute('allowfullscreen', '');
|
| 578 |
iframe.setAttribute('frameborder', '0');
|
| 579 |
iframe.loading = 'lazy'; // Lazy load iframes for better performance
|
| 580 |
|
| 581 |
+
// ๋ก๋ ์๋ฌ ์ฒ๋ฆฌ
|
| 582 |
+
iframe.onerror = function() {
|
| 583 |
+
handleIframeError(iframe, owner, name, title);
|
| 584 |
+
};
|
| 585 |
+
|
| 586 |
+
iframe.onload = function() {
|
| 587 |
+
// iframe์ด ๋ก๋๋์์ง๋ง ์๋ฌ ํ์ด์ง์ผ ์ ์์
|
| 588 |
+
// ์ฌ๊ธฐ์ ์ถ๊ฐ ๊ฒ์ฆ ๋ก์ง ๊ตฌํ ๊ฐ๋ฅ
|
| 589 |
+
};
|
| 590 |
+
|
| 591 |
content.appendChild(iframe);
|
| 592 |
|
| 593 |
// Add content to grid item
|