Elias207 commited on
Commit
0b7c7f4
·
verified ·
1 Parent(s): 6be7f17

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +198 -275
index.html CHANGED
@@ -3,350 +3,273 @@
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: 20px;
17
- flex-wrap: wrap;
 
 
 
 
 
18
  }
19
  .container {
20
- background-color: #ffffff;
21
- padding: 25px;
22
- border-radius: 8px;
23
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
24
- width: 100%;
25
- max-width: 450px;
26
  display: flex;
27
- flex-direction: column;
28
- gap: 15px;
29
- }
30
- h2 {
31
- text-align: center;
32
- color: #0d6efd;
33
- margin-top: 0;
34
- border-bottom: 2px solid #eee;
35
- padding-bottom: 10px;
36
  }
37
- label, button, input {
38
- font-size: 16px;
 
 
 
 
 
39
  }
40
- textarea, input[type="file"] {
41
- width: 100%;
42
  padding: 10px;
43
- border-radius: 6px;
44
- border: 1px solid #ddd;
45
- box-sizing: border-box;
46
- resize: vertical;
47
  }
48
  button {
49
- background-color: #0d6efd;
50
  color: white;
 
51
  border: none;
52
- padding: 12px 20px;
53
- border-radius: 6px;
54
  cursor: pointer;
55
- transition: background-color 0.3s;
56
- width: 100%;
57
  }
58
  button:hover {
59
- background-color: #0b5ed7;
60
  }
61
  button:disabled {
62
- background-color: #6c757d;
63
  cursor: not-allowed;
64
  }
65
- .result-box {
66
- margin-top: 15px;
67
- padding: 15px;
68
- border: 1px dashed #ccc;
69
- border-radius: 6px;
 
70
  min-height: 50px;
71
- display: flex;
72
- justify-content: center;
73
- align-items: center;
74
- text-align: center;
75
- position: relative;
76
  }
77
- #qr-image {
78
  max-width: 100%;
79
  height: auto;
80
- border-radius: 4px;
 
81
  }
82
- .loader {
83
  font-style: italic;
84
  color: #666;
85
- }
86
- #read-result {
87
- word-break: break-all;
88
- white-space: pre-wrap;
89
- }
90
- .copy-btn {
91
- position: absolute;
92
- top: 8px;
93
- left: 8px;
94
- background-color: #6c757d;
95
- color: white;
96
- padding: 5px 10px;
97
- border-radius: 4px;
98
- font-size: 12px;
99
- cursor: pointer;
100
- width: auto;
101
- }
102
- .copy-btn:hover {
103
- background-color: #5a6268;
104
- }
105
- /* بخش دیباگ */
106
- .debug-section {
107
- margin-top: 15px;
108
- border: 1px solid #e0e0e0;
109
- border-radius: 6px;
110
- }
111
- .debug-section summary {
112
- padding: 10px;
113
- background-color: #f8f9fa;
114
- cursor: pointer;
115
- font-weight: bold;
116
- }
117
- .debug-content {
118
- padding: 10px;
119
- background-color: #fff;
120
- }
121
- .debug-content h4 {
122
- margin-top: 0;
123
- display: flex;
124
- justify-content: space-between;
125
- align-items: center;
126
- }
127
- .debug-content pre {
128
- background-color: #e9ecef;
129
- padding: 10px;
130
- border-radius: 4px;
131
- white-space: pre-wrap;
132
- word-break: break-all;
133
- font-size: 13px;
134
- max-height: 150px;
135
- overflow-y: auto;
136
- }
137
- .copy-json-btn {
138
- background-color: #198754;
139
- padding: 2px 8px;
140
- font-size: 12px;
141
- width: auto;
142
- border-radius: 4px;
143
  }
144
  </style>
 
 
 
 
145
  </head>
146
  <body>
147
 
148
- <!-- بخش ساخت QR Code -->
149
- <div class="container">
150
- <h2>ساخت QR Code</h2>
151
- <label for="qr-text">متن مورد نظر را وارد کنید:</label>
152
- <textarea id="qr-text" rows="4" placeholder="مثال: https://google.com">سلام دنیا</textarea>
153
- <button id="generate-btn" onclick="generateQRCode()">ساخت QR Code</button>
154
- <div id="generate-result-box" class="result-box">
155
- <span class="loader">تصویر QR Code اینجا نمایش داده می‌شود.</span>
156
- </div>
157
- <!-- بخش دیباگ برای ساخت -->
158
- <details class="debug-section">
159
- <summary>اطلاعات دیباگ (ساخت کد)</summary>
160
- <div class="debug-content">
161
- <h4>
162
- <span>Request Payload (JSON ارسالی)</span>
163
- <button class="copy-json-btn" onclick="copyToClipboard(document.getElementById('generate-req-payload').textContent)">کپی</button>
164
- </h4>
165
- <pre id="generate-req-payload">هنوز درخواستی ارسال نشده است.</pre>
166
- <h4>
167
- <span>Server Response (پاسخ دریافتی)</span>
168
- <button class="copy-json-btn" onclick="copyToClipboard(document.getElementById('generate-res-payload').textContent)">کپی</button>
169
- </h4>
170
- <pre id="generate-res-payload">هنوز پاسخی دریافت نشده است.</pre>
171
- </div>
172
- </details>
173
- </div>
174
 
175
- <!-- بخش خواندن QR Code -->
176
  <div class="container">
177
- <h2>خواندن QR Code</h2>
178
- <label for="qr-file">فایل تصویر QR Code را انتخاب کنید:</label>
179
- <input type="file" id="qr-file" accept="image/*">
180
- <button id="read-btn" onclick="readQRCode()">خواندن از تصویر</button>
181
- <div id="read-result-box" class="result-box">
182
- <p id="read-result" class="loader">متن خوانده شده اینجا نمایش داده می‌شود.</p>
 
 
 
 
183
  </div>
184
- <!-- بخش دیباگ برای خواندن -->
185
- <details class="debug-section">
186
- <summary>اطلاعات دیباگ (خواندن کد)</summary>
187
- <div class="debug-content">
188
- <h4>
189
- <span>Request Payload (JSON ارسالی)</span>
190
- <button class="copy-json-btn" onclick="copyToClipboard(document.getElementById('read-req-payload').textContent)">کپی</button>
191
- </h4>
192
- <pre id="read-req-payload">هنوز درخواستی ارسال نشده است.</pre>
193
- <h4>
194
- <span>Server Response (پاسخ دریافتی)</span>
195
- <button class="copy-json-btn" onclick="copyToClipboard(document.getElementById('read-res-payload').textContent)">کپی</button>
196
- </h4>
197
- <pre id="read-res-payload">هنوز پاسخی دریافت نشده است.</pre>
198
  </div>
199
- </details>
200
  </div>
201
 
202
  <script>
203
- // *** خط زیر اصلاح شد ***
204
- // آدرس API صحیح برای اسپیس Elias207/QRcode
205
- const API_URL = "https://elias207-qrcode.hf.space/run/predict/";
206
-
207
- // گرفتن ارجاع به عناصر HTML
208
- const generateBtn = document.getElementById('generate-btn');
209
- const readBtn = document.getElementById('read-btn');
210
- const qrTextInput = document.getElementById('qr-text');
211
- const qrFileInput = document.getElementById('qr-file');
212
- const generateResultBox = document.getElementById('generate-result-box');
213
- const readResultBox = document.getElementById('read-result-box');
214
- const readResultP = document.getElementById('read-result');
215
-
216
- // عناصر دیباگ
217
- const genReqPayload = document.getElementById('generate-req-payload');
218
- const genResPayload = document.getElementById('generate-res-payload');
219
- const readReqPayload = document.getElementById('read-req-payload');
220
- const readResPayload = document.getElementById('read-res-payload');
221
-
222
- // تابع کمکی برای کپی در کلیپ‌بورد
223
- function copyToClipboard(text) {
224
- navigator.clipboard.writeText(text).then(() => {
225
- alert("متن کپی شد!");
226
- }).catch(err => {
227
- console.error('Failed to copy: ', err);
228
- alert("کپی کردن با خطا مواجه شد.");
229
- });
230
  }
231
 
232
- // تابع برای ساخت QR Code
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  async function generateQRCode() {
234
- const text = qrTextInput.value.trim();
235
- if (!text) {
236
- alert("لطفاً متنی را برای ساخت QR Code وارد کنید.");
237
  return;
238
  }
239
 
240
- generateBtn.disabled = true;
241
- generateResultBox.innerHTML = '<span class="loader">در حال ساخت... لطفاً صبر ��نید.</span>';
242
-
 
 
 
 
243
  const payload = {
244
- "fn_index": 0,
245
- "data": [text]
 
246
  };
247
- genReqPayload.textContent = JSON.stringify(payload, null, 2);
248
- genResPayload.textContent = "در حال دریافت پاسخ...";
249
 
250
  try {
251
- const response = await fetch(API_URL, {
252
- method: "POST",
253
- headers: { "Content-Type": "application/json" },
254
  body: JSON.stringify(payload)
255
  });
256
 
257
- const result = await response.json();
258
- genResPayload.textContent = JSON.stringify(result, null, 2);
259
 
260
- if (!response.ok) {
261
- throw new Error(`خطای سرور: ${response.status} - ${result.error || 'Unknown Error'}`);
262
- }
263
-
264
- const imageData = result.data[0];
265
- if (imageData) {
266
- generateResultBox.innerHTML = `<img id="qr-image" src="${imageData}" alt="Generated QR Code">`;
267
- } else {
268
- throw new Error("پاسخ دریافتی از سرور، شامل تصویر نبود.");
269
- }
270
 
271
  } catch (error) {
272
- console.error('Error generating QR code:', error);
273
- generateResultBox.innerHTML = `<span style="color:red;">خطا: ${error.message}</span>`;
274
- genResPayload.textContent = `Error: ${error.message}`;
275
- } finally {
276
- generateBtn.disabled = false;
277
  }
278
  }
279
 
280
- // تابع برای خواندن QR Code
281
  async function readQRCode() {
282
- const file = qrFileInput.files[0];
283
- if (!file) {
284
- alert("لطفاً یک فایل تصویر را انتخاب کنید.");
285
  return;
286
  }
287
 
288
- readBtn.disabled = true;
289
- readResultP.textContent = 'در حال خواندن تصویر...';
290
- readResultP.style.color = 'inherit';
291
- readResultP.classList.add('loader');
292
- const oldCopyBtn = readResultBox.querySelector('.copy-btn');
293
- if(oldCopyBtn) oldCopyBtn.remove();
294
-
295
- const reader = new FileReader();
296
- reader.readAsDataURL(file);
297
- reader.onload = async () => {
298
- const fileDataUrl = reader.result;
 
 
 
 
 
 
 
299
 
 
 
 
 
 
 
 
300
  const payload = {
301
- "fn_index": 1,
302
- "data": [fileDataUrl]
 
 
 
 
 
 
 
 
303
  };
304
- readReqPayload.textContent = JSON.stringify({...payload, data: [fileDataUrl.substring(0, 50) + '...'] }, null, 2);
305
- readResPayload.textContent = "در حال دریافت پاسخ...";
306
-
307
- try {
308
- const response = await fetch(API_URL, {
309
- method: "POST",
310
- headers: { "Content-Type": "application/json" },
311
- body: JSON.stringify(payload)
312
- });
313
 
314
- const result = await response.json();
315
- readResPayload.textContent = JSON.stringify(result, null, 2);
 
 
 
316
 
317
- if (!response.ok) {
318
- throw new Error(`خطای سرور: ${response.status} - ${result.error || 'Unknown Error'}`);
319
- }
320
-
321
- const decodedText = result.data[0];
322
 
323
- readResultP.textContent = decodedText || "متنی در QR Code یافت نشد.";
324
- readResultP.classList.remove('loader');
325
-
326
- if (decodedText) {
327
- const copyBtn = document.createElement('button');
328
- copyBtn.textContent = 'کپی متن';
329
- copyBtn.className = 'copy-btn';
330
- copyBtn.onclick = () => copyToClipboard(decodedText);
331
- readResultBox.appendChild(copyBtn);
332
- }
333
 
334
- } catch (error) {
335
- console.error('Error reading QR code:', error);
336
- readResultP.textContent = `خطا: ${error.message}`;
337
- readResultP.style.color = 'red';
338
- readResPayload.textContent = `Error: ${error.message}`;
339
- } finally {
340
- readBtn.disabled = false;
341
- }
342
- };
343
-
344
- reader.onerror = error => {
345
- console.error("Error converting file to Base64", error);
346
- readResultP.textContent = "خطا در خواندن فایل.";
347
- readResultP.style.color = 'red';
348
- readBtn.disabled = false;
349
- };
350
  }
351
  </script>
352
  </body>
 
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
  }
52
  button:hover {
53
+ background-color: #0056b3;
54
  }
55
  button:disabled {
56
+ background-color: #ccc;
57
  cursor: not-allowed;
58
  }
59
+ .result {
60
+ margin-top: 20px;
61
+ padding: 10px;
62
+ background-color: #e9ecef;
63
+ border: 1px solid #ced4da;
64
+ border-radius: 4px;
65
  min-height: 50px;
66
+ word-wrap: break-word;
 
 
 
 
67
  }
68
+ .result img {
69
  max-width: 100%;
70
  height: auto;
71
+ display: block;
72
+ margin: 0 auto;
73
  }
74
+ .status {
75
  font-style: italic;
76
  color: #666;
77
+ height: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
79
  </style>
80
+ <!-- افزودن فونت وزیر از گوگل -->
81
+ <link rel="preconnect" href="https://fonts.googleapis.com">
82
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
83
+ <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet">
84
  </head>
85
  <body>
86
 
87
+ <h1>ابزار کار با کد QR (توسط API)</h1>
88
+ <p>این صفحه از API موجود در Hugging Face Space با آدرس <code>cultrix-qrcode-read-generate</code> استفاده می‌کند.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
 
90
  <div class="container">
91
+ <!-- بخش ساخت کد QR -->
92
+ <div class="section">
93
+ <h2>۱. ساخت کد QR از متن</h2>
94
+ <label for="qr-text">متن مورد نظر:</label>
95
+ <input type="text" id="qr-text" placeholder="متن خود را اینجا وارد کنید...">
96
+ <button id="generate-btn" onclick="generateQRCode()">ساخت کد</button>
97
+ <div id="generate-status" class="status"></div>
98
+ <div id="generate-result" class="result">
99
+ <!-- تصویر کد QR اینجا نمایش داده می‌شود -->
100
+ </div>
101
  </div>
102
+
103
+ <!-- بخش خواندن کد QR -->
104
+ <div class="section">
105
+ <h2>۲. خواندن متن از کد QR</h2>
106
+ <label for="qr-file">فایل تصویر کد QR را انتخاب کنید:</label>
107
+ <input type="file" id="qr-file" accept="image/*">
108
+ <button id="read-btn" onclick="readQRCode()">خواندن کد</button>
109
+ <div id="read-status" class="status"></div>
110
+ <div id="read-result" class="result">
111
+ <!-- متن خوانده شده اینجا نمایش داده می‌شود -->
 
 
 
 
112
  </div>
113
+ </div>
114
  </div>
115
 
116
  <script>
117
+ const API_BASE_URL = "https://cultrix-qrcode-read-generate.hf.space";
118
+
119
+ // یک هش تصادفی برای session ایجاد می‌کند
120
+ function generateSessionHash() {
121
+ return Math.random().toString(36).substring(2);
122
+ }
123
+
124
+ // تابع برای غیرفعال کردن دکمه‌ها در حین پردازش
125
+ function toggleButtons(disabled) {
126
+ document.getElementById('generate-btn').disabled = disabled;
127
+ document.getElementById('read-btn').disabled = disabled;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  }
129
 
130
+ // تابع برای گوش دادن به نتیجه با EventSource
131
+ function pollForResult(sessionHash, resultElement, statusElement, fnIndex) {
132
+ const eventSource = new EventSource(`${API_BASE_URL}/gradio_api/queue/data?session_hash=${sessionHash}`);
133
+
134
+ statusElement.textContent = 'در انتظار نتیجه از سرور...';
135
+
136
+ eventSource.onmessage = function(event) {
137
+ const data = JSON.parse(event.data);
138
+
139
+ if (data.msg === 'process_starts') {
140
+ statusElement.textContent = 'پردازش شروع شد...';
141
+ }
142
+
143
+ if (data.msg === 'process_completed') {
144
+ statusElement.textContent = 'پردازش با موفقیت انجام شد.';
145
+ resultElement.innerHTML = ''; // پاک کردن محتوای قبلی
146
+
147
+ const outputData = data.output.data[0];
148
+
149
+ if (fnIndex === 0) { // ساخت QR
150
+ // نتیجه یک شی حاوی URL تصویر است
151
+ const img = document.createElement('img');
152
+ img.src = `${API_BASE_URL}/gradio_api/file=${outputData.path}`;
153
+ resultElement.appendChild(img);
154
+ } else if (fnIndex === 1) { // خواندن QR
155
+ // نتیجه خود متن است
156
+ resultElement.textContent = outputData;
157
+ }
158
+
159
+ eventSource.close();
160
+ toggleButtons(false);
161
+ }
162
+ };
163
+
164
+ eventSource.onerror = function(err) {
165
+ statusElement.textContent = 'خطا در ارتباط با سرور.';
166
+ console.error("EventSource failed:", err);
167
+ eventSource.close();
168
+ toggleButtons(false);
169
+ };
170
+ }
171
+
172
+ // تابع اصلی برای ساخت کد QR
173
  async function generateQRCode() {
174
+ const textInput = document.getElementById('qr-text').value;
175
+ if (!textInput) {
176
+ alert('لطفاً متنی را برای ساخت کد QR وارد کنید.');
177
  return;
178
  }
179
 
180
+ const statusElement = document.getElementById('generate-status');
181
+ const resultElement = document.getElementById('generate-result');
182
+ resultElement.innerHTML = '';
183
+ statusElement.textContent = 'در حال ارسال درخواست...';
184
+ toggleButtons(true);
185
+
186
+ const sessionHash = generateSessionHash();
187
  const payload = {
188
+ data: [textInput],
189
+ fn_index: 0,
190
+ session_hash: sessionHash
191
  };
 
 
192
 
193
  try {
194
+ const response = await fetch(`${API_BASE_URL}/gradio_api/queue/join?`, {
195
+ method: 'POST',
196
+ headers: { 'Content-Type': 'application/json' },
197
  body: JSON.stringify(payload)
198
  });
199
 
200
+ if (!response.ok) throw new Error('خطا در عضویت در صف');
 
201
 
202
+ pollForResult(sessionHash, resultElement, statusElement, 0);
 
 
 
 
 
 
 
 
 
203
 
204
  } catch (error) {
205
+ statusElement.textContent = `خطا: ${error.message}`;
206
+ console.error(error);
207
+ toggleButtons(false);
 
 
208
  }
209
  }
210
 
211
+ // تابع اصلی برای خواندن کد QR
212
  async function readQRCode() {
213
+ const fileInput = document.getElementById('qr-file');
214
+ if (fileInput.files.length === 0) {
215
+ alert('لطفاً یک فایل تصویر را انتخاب کنید.');
216
  return;
217
  }
218
 
219
+ const file = fileInput.files[0];
220
+ const statusElement = document.getElementById('read-status');
221
+ const resultElement = document.getElementById('read-result');
222
+ resultElement.innerHTML = '';
223
+ statusElement.textContent = 'در حال آپلود فایل...';
224
+ toggleButtons(true);
225
+
226
+ try {
227
+ // مرحله ۱: آپلود فایل
228
+ const formData = new FormData();
229
+ formData.append('files', file);
230
+
231
+ const uploadResponse = await fetch(`${API_BASE_URL}/gradio_api/upload`, {
232
+ method: 'POST',
233
+ body: formData
234
+ });
235
+
236
+ if (!uploadResponse.ok) throw new Error('خطا در آپلود فایل');
237
 
238
+ const uploadedFiles = await uploadResponse.json();
239
+ const uploadedFilePath = uploadedFiles[0];
240
+
241
+ statusElement.textContent = 'فایل آپلود شد. در حال ارسال درخواست پردازش...';
242
+
243
+ // مرحله ۲: ارسال درخواست پردازش با مسیر فایل آپلود شده
244
+ const sessionHash = generateSessionHash();
245
  const payload = {
246
+ data: [{
247
+ "path": uploadedFilePath,
248
+ "url": `${API_BASE_URL}/gradio_api/file=${uploadedFilePath}`,
249
+ "orig_name": file.name,
250
+ "size": file.size,
251
+ "mime_type": file.type,
252
+ "meta": {"_type": "gradio.FileData"}
253
+ }],
254
+ fn_index: 1,
255
+ session_hash: sessionHash
256
  };
 
 
 
 
 
 
 
 
 
257
 
258
+ const joinResponse = await fetch(`${API_BASE_URL}/gradio_api/queue/join?`, {
259
+ method: 'POST',
260
+ headers: { 'Content-Type': 'application/json' },
261
+ body: JSON.stringify(payload)
262
+ });
263
 
264
+ if (!joinResponse.ok) throw new Error('خطا در عضویت در صف برای پردازش فایل');
 
 
 
 
265
 
266
+ pollForResult(sessionHash, resultElement, statusElement, 1);
 
 
 
 
 
 
 
 
 
267
 
268
+ } catch (error) {
269
+ statusElement.textContent = `خطا: ${error.message}`;
270
+ console.error(error);
271
+ toggleButtons(false);
272
+ }
 
 
 
 
 
 
 
 
 
 
 
273
  }
274
  </script>
275
  </body>