url2drive / index.html
iyougame's picture
Sync from GitHub: f8228f1a797d79b8bc0a34f4cfc5308a0e1ea98e
99048c4 verified
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>URL to Google Drive Saver</title>
<style>
:root { --primary: #4F46E5; --bg: #F3F4F6; --card: #ffffff; }
body { font-family: 'Segoe UI', sans-serif; background: var(--bg); display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }
.container { background: var(--card); padding: 2rem; border-radius: 1rem; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1); width: 90%; max-width: 500px; }
h1 { color: #111827; margin-bottom: 0.5rem; font-size: 1.5rem; text-align: center; }
p { color: #6B7280; text-align: center; margin-bottom: 1.5rem; font-size: 0.9rem; }
.input-group { margin-bottom: 1rem; }
input { width: 100%; padding: 0.75rem; border: 1px solid #D1D5DB; border-radius: 0.5rem; box-sizing: border-box; outline: none; transition: border 0.2s; }
input:focus { border-color: var(--primary); ring: 2px var(--primary); }
button { width: 100%; background: var(--primary); color: white; padding: 0.75rem; border: none; border-radius: 0.5rem; font-weight: 600; cursor: pointer; transition: opacity 0.2s; }
button:hover { opacity: 0.9; }
button:disabled { background: #9CA3AF; cursor: not-allowed; }
#status { margin-top: 1rem; padding: 1rem; border-radius: 0.5rem; background: #F9FAFB; border: 1px solid #E5E7EB; white-space: pre-wrap; word-break: break-all; font-size: 0.9rem; display: none; }
.success { border-left: 4px solid #10B981 !important; color: #065F46; }
.error { border-left: 4px solid #EF4444 !important; color: #7F1D1D; }
.spinner { display: inline-block; width: 1rem; height: 1rem; border: 2px solid #fff; border-radius: 50%; border-top-color: transparent; animation: spin 1s linear infinite; margin-right: 0.5rem; vertical-align: middle; }
@keyframes spin { to { transform: rotate(360deg); } }
</style>
</head>
<body>
<div class="container">
<h1>☁️ URL 转存助手</h1>
<p>直接将网络文件保存到您的 Google Drive</p>
<div class="input-group">
<input type="url" id="fileUrl" placeholder="在此粘贴文件 URL (例如 .mp4, .zip)" required>
</div>
<button id="submitBtn" onclick="startUpload()">
<span id="btnText">开始转存</span>
</button>
<div id="status"></div>
</div>
<!-- 引入 Gradio Client -->
<script type="module">
import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
// ⚠️⚠️⚠️【重要】请在此处替换为您的 Hugging Face Space ID ⚠️⚠️⚠️
// 格式: "用户名/空间名"
const HF_SPACE_ID = "iyougame/url2drive";
window.startUpload = async function() {
const urlInput = document.getElementById('fileUrl');
const btn = document.getElementById('submitBtn');
const btnText = document.getElementById('btnText');
const statusDiv = document.getElementById('status');
const url = urlInput.value.trim();
if (!url) {
alert("请输入有效的文件 URL");
return;
}
// UI Reset
btn.disabled = true;
btnText.innerHTML = '<span class="spinner"></span> 处理中...';
statusDiv.style.display = 'block';
statusDiv.className = '';
statusDiv.innerHTML = "⏳ 正在连接后端服务器...";
try {
// 1. 连接 Space
const client = await Client.connect(HF_SPACE_ID);
statusDiv.innerHTML = "🚀 已连接! 正在下载并上传...";
// 2. 调用 API (api_name 对应 app.py 中的 api_name="save_to_drive")
const result = await client.predict("/save_to_drive", {
file_url: url
});
// 3. 处理结果
const responseText = result.data[0]; // Gradio 返回的是数组
// 简单的 Markdown 解析
let htmlContent = responseText
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') // Bold
.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2" target="_blank" style="color:blue;text-decoration:underline;">$1</a>') // Link
.replace(/\n/g, '<br>'); // Newline
statusDiv.innerHTML = htmlContent;
if (responseText.includes("❌")) {
statusDiv.classList.add("error");
btnText.innerText = "重试";
} else {
statusDiv.classList.add("success");
btnText.innerText = "再次转存";
urlInput.value = ""; // Clear input on success
}
} catch (error) {
console.error(error);
statusDiv.classList.add("error");
statusDiv.innerHTML = `❌ **系统错误**: ${error.message}<br>请检查 Space 是否正在运行。`;
btnText.innerText = "重试";
} finally {
btn.disabled = false;
}
}
</script>
</body>
</html>