Elias207 commited on
Commit
18d97af
·
verified ·
1 Parent(s): 3e8c659

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +185 -166
index.html CHANGED
@@ -3,247 +3,266 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>استفاده از API کد QR (نسخه نهایی)</title>
7
  <style>
8
  body {
9
- font-family: 'Vazirmatn', sans-serif;
10
- background-color: #f4f7f6;
11
- color: #333;
12
- max-width: 800px;
13
- margin: 20px auto;
14
- padding: 20px;
15
- border-radius: 10px;
16
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
17
- }
18
- h1, h2 {
19
- color: #0056b3;
20
- border-bottom: 2px solid #0056b3;
21
- padding-bottom: 10px;
22
- }
23
- .container {
24
  display: flex;
 
 
 
 
25
  flex-wrap: wrap;
26
- gap: 40px;
27
  }
28
- .section {
29
- flex: 1;
30
- min-width: 300px;
31
  background-color: #fff;
32
- padding: 20px;
33
  border-radius: 8px;
34
- border: 1px solid #ddd;
 
 
 
 
 
 
 
 
 
 
35
  }
36
- input[type="text"], input[type="file"] {
37
- width: calc(100% - 20px);
38
  padding: 10px;
39
- margin-bottom: 10px;
40
  border: 1px solid #ccc;
41
  border-radius: 4px;
 
 
42
  }
43
  button {
44
  background-color: #007bff;
45
  color: white;
46
- padding: 10px 15px;
47
  border: none;
48
  border-radius: 4px;
49
  cursor: pointer;
50
  font-size: 16px;
51
- margin-bottom: 10px;
52
- }
53
- button:hover {
54
- background-color: #0056b3;
55
  }
56
  button:disabled {
57
- background-color: #ccc;
58
  cursor: not-allowed;
59
  }
60
- .result {
61
- margin-top: 20px;
62
- padding: 10px;
63
- background-color: #e9ecef;
64
- border: 1px solid #ced4da;
 
 
65
  border-radius: 4px;
66
  min-height: 50px;
67
- word-wrap: break-word;
68
- text-align: center;
 
 
69
  }
70
- .result img {
71
  max-width: 100%;
72
  height: auto;
73
- display: block;
74
- margin: 0 auto;
75
- }
76
- .status {
77
- font-style: italic;
78
- color: #666;
79
- height: 20px;
80
- margin-bottom: 10px;
81
- }
82
- .download-links a {
83
- display: inline-block;
84
- margin: 5px;
85
- padding: 8px 12px;
86
- background-color: #28a745;
87
- color: white;
88
- text-decoration: none;
89
- border-radius: 4px;
90
  }
91
- .download-links a:hover {
92
- background-color: #218838;
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
94
  </style>
95
- <!-- افزودن فونت وزیر از گوگل -->
96
- <link rel="preconnect" href="https://fonts.googleapis.com">
97
- <link rel="preconnect" href="https://fonts.gstatic" crossorigin>
98
- <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet">
99
  </head>
100
  <body>
101
 
102
- <h1>ابزار کار با کد QR (توسط API)</h1>
103
- <p>این صفحه از API موجود در Hugging Face Space با آدرس <code>CultriX/QRcode-read-generate</code> استفاده می‌کند.</p>
104
-
105
  <div class="container">
106
- <!-- بخش ساخت کد QR -->
107
- <div class="section">
108
- <h2>۱. ساخت کد QR از متن</h2>
109
- <label for="qr-text">متن مورد نظر:</label>
110
- <input type="text" id="qr-text" placeholder="متن خود را اینجا وارد کنید..." value="سلام دنیا!">
111
- <button id="generate-btn" onclick="generateQRCode()">ساخت کد</button>
112
- <div id="generate-status" class="status"></div>
113
- <div id="generate-result" class="result">
114
- <!-- تصویر کد QR اینجا نمایش داده می‌شود -->
115
- </div>
116
- <div id="download-links" class="download-links" style="display: none; text-align: center; margin-top: 10px;">
117
- <a id="download-png" href="#" download="qrcode.png">دانلود PNG</a>
118
- <a id="download-txt" href="#" download="qrcode_base64.txt">دانلود Base64 (TXT)</a>
119
- </div>
120
  </div>
 
121
 
122
- <!-- بخش خواندن کد QR -->
123
- <div class="section">
124
- <h2>۲. خواندن متن از کد QR</h2>
125
- <label for="qr-file">فایل تصویر کد QR را انتخاب کنید:</label>
126
- <input type="file" id="qr-file" accept="image/*">
127
- <button id="read-btn" onclick="readQRCode()">خواندن کد</button>
128
- <div id="read-status" class="status"></div>
129
- <div id="read-result" class="result">
130
- <!-- متن خوانده شده اینجا نمایش داده می‌شود -->
131
- </div>
132
  </div>
133
  </div>
134
 
135
  <script>
136
- const API_BASE_URL = "https://cultrix-qrcode-read-generate.hf.space";
137
 
138
- function toggleButtons(disabled) {
139
- document.getElementById('generate-btn').disabled = disabled;
140
- document.getElementById('read-btn').disabled = disabled;
141
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
- // تابع برای تبدیل فایل به رشته Base64
144
- function fileToBase64(file) {
145
  return new Promise((resolve, reject) => {
146
- const reader = new FileReader();
147
- reader.readAsDataURL(file);
148
- reader.onload = () => resolve(reader.result);
149
- reader.onerror = error => reject(error);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  });
151
  }
152
 
153
- // تابع برای ساخت کد QR
154
  async function generateQRCode() {
155
- const textInput = document.getElementById('qr-text').value;
156
- if (!textInput) {
157
- alert('لطفاً متنی را برای ساخت کد QR وارد کنید.');
158
  return;
159
  }
160
 
161
- const statusElement = document.getElementById('generate-status');
162
- const resultElement = document.getElementById('generate-result');
163
- const downloadLinks = document.getElementById('download-links');
 
164
 
165
- toggleButtons(true);
166
- statusElement.textContent = 'در حال ساخت کد QR...';
167
- resultElement.innerHTML = '';
168
- downloadLinks.style.display = 'none';
169
 
170
  try {
171
- const response = await fetch(`${API_BASE_URL}/run/generate_qr_interface`, {
172
- method: 'POST',
173
- headers: { 'Content-Type': 'application/json' },
174
- body: JSON.stringify({
175
- "data": [textInput]
176
- })
177
- });
178
-
179
- if (!response.ok) throw new Error(`خطای سرور: ${response.statusText}`);
180
-
181
- const result = await response.json();
182
- const outputData = result.data;
183
-
184
- // نمایش تصویر QR (خروجی اول)
185
- resultElement.innerHTML = outputData[0];
186
-
187
- // تنظیم لینک‌های دانلود (خروجی دوم و سوم)
188
- document.getElementById('download-png').href = outputData[1].url;
189
- document.getElementById('download-txt').href = outputData[2].url;
190
- downloadLinks.style.display = 'block';
191
 
192
- statusElement.textContent = 'کد QR با موفقیت ساخته شد.';
 
 
 
 
 
 
193
 
194
  } catch (error) {
195
- statusElement.textContent = `خطا: ${error.message}`;
196
- console.error(error);
 
197
  } finally {
198
- toggleButtons(false);
 
199
  }
200
  }
201
-
202
- // تابع برای خواندن کد QR
203
  async function readQRCode() {
204
- const fileInput = document.getElementById('qr-file');
205
  if (fileInput.files.length === 0) {
206
- alert('لطفاً یک فایل تصویر را انتخاب کنید.');
207
  return;
208
  }
209
-
210
  const file = fileInput.files[0];
211
- const statusElement = document.getElementById('read-status');
212
- const resultElement = document.getElementById('read-result');
213
 
214
- toggleButtons(true);
215
- statusElement.textContent = 'در حال خواندن کد...';
216
- resultElement.textContent = '';
217
-
 
 
 
 
218
  try {
219
- // تبدیل فایل به Base64 برای ارسال به API
220
- const base64File = await fileToBase64(file);
221
-
222
- const response = await fetch(`${API_BASE_URL}/run/decode_qr`, {
223
- method: 'POST',
224
- headers: { 'Content-Type': 'application/json' },
225
- body: JSON.stringify({
226
- "data": [
227
- base64File
228
- ]
229
- })
230
  });
231
-
232
- if (!response.ok) throw new Error(`خطای سرور: ${response.statusText}`);
233
-
234
- const result = await response.json();
235
 
236
- // نمایش متن خوانده شده
237
- resultElement.textContent = result.data[0];
238
- statusElement.textContent = 'کد با موفقیت خوانده شد.';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
  } catch (error) {
241
- statusElement.textContent = `خطا: ${error.message}`;
242
- console.error(error);
243
  } finally {
244
- toggleButtons(false);
 
245
  }
246
  }
247
  </script>
 
248
  </body>
249
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>کلاینت QR Code</title>
7
  <style>
8
  body {
9
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
10
+ background-color: #f0f2f5;
11
+ color: #1c1e21;
 
 
 
 
 
 
 
 
 
 
 
 
12
  display: flex;
13
+ justify-content: center;
14
+ align-items: flex-start;
15
+ padding: 20px;
16
+ gap: 30px;
17
  flex-wrap: wrap;
 
18
  }
19
+ .container {
 
 
20
  background-color: #fff;
21
+ padding: 25px;
22
  border-radius: 8px;
23
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
24
+ width: 400px;
25
+ display: flex;
26
+ flex-direction: column;
27
+ gap: 15px;
28
+ }
29
+ h2 {
30
+ margin: 0 0 10px 0;
31
+ color: #0056b3;
32
+ border-bottom: 2px solid #0056b3;
33
+ padding-bottom: 5px;
34
  }
35
+ textarea, input[type="file"] {
36
+ width: 100%;
37
  padding: 10px;
 
38
  border: 1px solid #ccc;
39
  border-radius: 4px;
40
+ box-sizing: border-box;
41
+ resize: vertical;
42
  }
43
  button {
44
  background-color: #007bff;
45
  color: white;
46
+ padding: 12px 20px;
47
  border: none;
48
  border-radius: 4px;
49
  cursor: pointer;
50
  font-size: 16px;
51
+ transition: background-color 0.3s;
 
 
 
52
  }
53
  button:disabled {
54
+ background-color: #a0c9ff;
55
  cursor: not-allowed;
56
  }
57
+ button:hover:not(:disabled) {
58
+ background-color: #0056b3;
59
+ }
60
+ .result-box {
61
+ margin-top: 15px;
62
+ padding: 15px;
63
+ border: 1px dashed #ddd;
64
  border-radius: 4px;
65
  min-height: 50px;
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ background-color: #fafafa;
70
  }
71
+ #qr-image {
72
  max-width: 100%;
73
  height: auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
+ .loader {
76
+ border: 4px solid #f3f3f3;
77
+ border-radius: 50%;
78
+ border-top: 4px solid #3498db;
79
+ width: 30px;
80
+ height: 30px;
81
+ animation: spin 1s linear infinite;
82
+ }
83
+ @keyframes spin {
84
+ 0% { transform: rotate(0deg); }
85
+ 100% { transform: rotate(360deg); }
86
+ }
87
+ .hidden {
88
+ display: none;
89
  }
90
  </style>
 
 
 
 
91
  </head>
92
  <body>
93
 
94
+ <!-- بخش ساخت QR Code -->
 
 
95
  <div class="container">
96
+ <h2>ساخت QR Code</h2>
97
+ <textarea id="text-input" placeholder="متن مورد نظر را اینجا وارد کنید..." rows="4">دنیا</textarea>
98
+ <button id="generate-btn" onclick="generateQRCode()">ساخت کد</button>
99
+ <div id="generate-result" class="result-box">
100
+ <div id="generate-loader" class="loader hidden"></div>
101
+ <img id="qr-image" src="" alt="QR Code" class="hidden" />
102
+ <span id="generate-placeholder">تصویر QR Code اینجا نمایش داده می‌شود.</span>
 
 
 
 
 
 
 
103
  </div>
104
+ </div>
105
 
106
+ <!-- بخش خواندن QR Code -->
107
+ <div class="container">
108
+ <h2>خواندن QR Code</h2>
109
+ <input type="file" id="file-input" accept="image/*">
110
+ <button id="read-btn" onclick="readQRCode()">خواندن کد</button>
111
+ <div id="read-result" class="result-box">
112
+ <div id="read-loader" class="loader hidden"></div>
113
+ <p id="read-text">نتیجه خواندن کد اینجا نمایش داده می‌شود.</p>
 
 
114
  </div>
115
  </div>
116
 
117
  <script>
118
+ const API_BASE_URL = "https://cultrix-qrcode-read-generate.hf.space/gradio_api/";
119
 
120
+ // یک session_hash تصادفی ایجاد می‌کند
121
+ function generateSessionHash() {
122
+ return Math.random().toString(36).substring(2, 11);
123
  }
124
+
125
+ // تابع برای ارسال درخواست به API و دریافت نتیجه
126
+ async function callGradioApi(fnIndex, data, sessionHash) {
127
+ // Step 1: Join the queue
128
+ const joinResponse = await fetch(API_BASE_URL + "queue/join?", {
129
+ method: "POST",
130
+ headers: { "Content-Type": "application/json" },
131
+ body: JSON.stringify({
132
+ "fn_index": fnIndex,
133
+ "data": data,
134
+ "session_hash": sessionHash,
135
+ }),
136
+ });
137
+ if (!joinResponse.ok) throw new Error("Failed to join queue.");
138
 
139
+ // Step 2: Poll for the result
 
140
  return new Promise((resolve, reject) => {
141
+ const interval = setInterval(async () => {
142
+ try {
143
+ const dataResponse = await fetch(API_BASE_URL + `queue/data?session_hash=${sessionHash}`);
144
+ if (!dataResponse.ok) {
145
+ clearInterval(interval);
146
+ reject(new Error("Failed to get data."));
147
+ return;
148
+ }
149
+ const result = await dataResponse.json();
150
+
151
+ // پیام‌های مختلفی از Gradio می‌آید. ما منتظر process_completed هستیم.
152
+ if (result.msg === "process_completed") {
153
+ clearInterval(interval);
154
+ resolve(result);
155
+ } else if (result.msg === "queue_full" || result.msg === "unexpected_error") {
156
+ clearInterval(interval);
157
+ reject(new Error("API Error: " + result.msg));
158
+ }
159
+ // اگر در حال پردازش بود (processing) یا در صف بود (estimation) منتظر می‌مانیم.
160
+ } catch (error) {
161
+ clearInterval(interval);
162
+ reject(error);
163
+ }
164
+ }, 1000); // هر ۱ ثانیه چک کن
165
  });
166
  }
167
 
168
+ // --- بخش ساخت QR Code ---
169
  async function generateQRCode() {
170
+ const textInput = document.getElementById('text-input').value;
171
+ if (!textInput.trim()) {
172
+ alert("لطفاً متنی را برای ساخت QR Code وارد کنید.");
173
  return;
174
  }
175
 
176
+ const generateBtn = document.getElementById('generate-btn');
177
+ const loader = document.getElementById('generate-loader');
178
+ const placeholder = document.getElementById('generate-placeholder');
179
+ const qrImage = document.getElementById('qr-image');
180
 
181
+ generateBtn.disabled = true;
182
+ loader.classList.remove('hidden');
183
+ placeholder.classList.add('hidden');
184
+ qrImage.classList.add('hidden');
185
 
186
  try {
187
+ const sessionHash = generateSessionHash();
188
+ const data = [textInput];
189
+ const result = await callGradioApi(0, data, sessionHash); // fn_index=0 برای ساخت
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
 
191
+ if (result.output && result.output.data && result.output.data[0]) {
192
+ const imageUrl = result.output.data[0].url;
193
+ qrImage.src = imageUrl;
194
+ qrImage.classList.remove('hidden');
195
+ } else {
196
+ throw new Error("پاسخ دریافتی از سرور معتبر نیست.");
197
+ }
198
 
199
  } catch (error) {
200
+ console.error("Error generating QR Code:", error);
201
+ alert("خطا در ساخت QR Code: " + error.message);
202
+ placeholder.classList.remove('hidden');
203
  } finally {
204
+ generateBtn.disabled = false;
205
+ loader.classList.add('hidden');
206
  }
207
  }
208
+
209
+ // --- بخش خواندن QR Code ---
210
  async function readQRCode() {
211
+ const fileInput = document.getElementById('file-input');
212
  if (fileInput.files.length === 0) {
213
+ alert("لطفاً یک فایل تصویر QR Code انتخاب کنید.");
214
  return;
215
  }
 
216
  const file = fileInput.files[0];
 
 
217
 
218
+ const readBtn = document.getElementById('read-btn');
219
+ const loader = document.getElementById('read-loader');
220
+ const readText = document.getElementById('read-text');
221
+
222
+ readBtn.disabled = true;
223
+ loader.classList.remove('hidden');
224
+ readText.textContent = "در حال پردازش...";
225
+
226
  try {
227
+ // Step 1: Upload the file
228
+ const formData = new FormData();
229
+ formData.append("files", file);
230
+ const uploadResponse = await fetch(API_BASE_URL + "upload", {
231
+ method: "POST",
232
+ body: formData,
 
 
 
 
 
233
  });
234
+ if (!uploadResponse.ok) throw new Error("آپلود فایل با خطا مواجه شد.");
 
 
 
235
 
236
+ const uploadResult = await uploadResponse.json();
237
+ const tempFilePath = uploadResult[0]; // مسیر موقت فایل در سرور
238
+
239
+ // Step 2: Call the API with the uploaded file path
240
+ const sessionHash = generateSessionHash();
241
+ const data = [{
242
+ "path": tempFilePath,
243
+ "url": null, // URL لازم نیست
244
+ "orig_name": file.name,
245
+ "size": file.size,
246
+ "mime_type": file.type,
247
+ "meta": {"_type": "gradio.FileData"}
248
+ }];
249
+ const result = await callGradioApi(1, data, sessionHash); // fn_index=1 برای خواندن
250
+
251
+ if (result.output && result.output.data && typeof result.output.data[0] === 'string') {
252
+ readText.textContent = "نتیجه: " + result.output.data[0];
253
+ } else {
254
+ readText.textContent = "نتیجه‌ای یافت نشد یا فرمت پاسخ نامعتبر است.";
255
+ }
256
 
257
  } catch (error) {
258
+ console.error("Error reading QR Code:", error);
259
+ readText.textContent = "خطا در خواندن QR Code: " + error.message;
260
  } finally {
261
+ readBtn.disabled = false;
262
+ loader.classList.add('hidden');
263
  }
264
  }
265
  </script>
266
+
267
  </body>
268
  </html>