haaaaus commited on
Commit
3947102
·
verified ·
1 Parent(s): fe3b484

Upload 83 files

Browse files
Files changed (2) hide show
  1. requirements.txt +21 -21
  2. templates/translate.html +66 -17
requirements.txt CHANGED
@@ -1,22 +1,22 @@
1
- deep-translator==1.11.4
2
- translators==5.9.1
3
- huggingface-hub==0.22.2
4
- manga-ocr==0.1.11
5
- numpy==1.24.2
6
- opencv-python==4.9.0.80
7
- pillow==10.3.0
8
- ultralytics==8.1.43
9
- Flask==2.2.5
10
- flask-socketio==5.3.6
11
- python-socketio==5.10.0
12
- python-engineio==4.8.1
13
- Werkzeug==3.0.1
14
- gunicorn==21.2.0
15
- tqdm==4.66.2
16
- safetensors==0.4.2
17
- cryptography==42.0.4
18
- torch==2.0.1
19
- torchvision==0.15.2
20
- sentencepiece==0.2.0
21
- chrome-lens-py>=3.0.0
22
  google-generativeai>=0.3.0
 
1
+ deep-translator==1.11.4
2
+ translators==5.9.1
3
+ huggingface-hub==0.22.2
4
+ manga-ocr==0.1.11
5
+ numpy==1.24.2
6
+ opencv-python==4.9.0.80
7
+ pillow==10.3.0
8
+ ultralytics==8.1.43
9
+ Flask==2.2.5
10
+ flask-socketio==5.3.6
11
+ python-socketio==5.10.0
12
+ python-engineio==4.8.1
13
+ Werkzeug==3.0.1
14
+ gunicorn==21.2.0
15
+ tqdm==4.66.2
16
+ safetensors==0.4.2
17
+ cryptography==42.0.4
18
+ torch==2.0.1
19
+ torchvision==0.15.2
20
+ sentencepiece==0.2.0
21
+ chrome-lens-py>=3.0.0
22
  google-generativeai>=0.3.0
templates/translate.html CHANGED
@@ -9,6 +9,9 @@
9
  rel="stylesheet">
10
  </head>
11
 
 
 
 
12
  <body>
13
  <header>
14
  </header>
@@ -40,13 +43,23 @@
40
  <a href="/" class="red">← Quay lại</a>
41
  </div>
42
 
43
- <!-- Hidden form for ZIP download -->
44
- <form id="zip-form" action="/download-zip" method="POST" style="display: none;">
45
- <input type="hidden" name="images_data" id="images-data">
46
- </form>
47
-
48
  </body>
49
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  // Download single image
51
  document.querySelectorAll('.download-btn').forEach(btn => {
52
  btn.addEventListener('click', (e) => {
@@ -60,22 +73,58 @@
60
  });
61
  });
62
 
63
- // Download all images as ZIP
64
- document.getElementById('download-zip').addEventListener('click', (e) => {
65
  e.preventDefault();
66
 
67
- // Collect all images data
68
- const images = [];
69
- document.querySelectorAll('.download-btn').forEach(btn => {
70
- images.push({
71
- name: btn.getAttribute('data-name'),
72
- data: btn.getAttribute('data-image')
 
 
 
 
 
 
 
 
 
 
 
73
  });
74
- });
75
 
76
- // Submit form with images data
77
- document.getElementById('images-data').value = JSON.stringify(images);
78
- document.getElementById('zip-form').submit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  });
80
  </script>
81
 
 
9
  rel="stylesheet">
10
  </head>
11
 
12
+ <!-- JSZip library for client-side ZIP creation (much faster than server-side) -->
13
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
14
+
15
  <body>
16
  <header>
17
  </header>
 
43
  <a href="/" class="red">← Quay lại</a>
44
  </div>
45
 
 
 
 
 
 
46
  </body>
47
  <script>
48
+ // Helper: Convert base64 to binary data
49
+ function base64ToBlob(base64, mimeType = 'image/png') {
50
+ const byteChars = atob(base64);
51
+ const byteArrays = [];
52
+ for (let offset = 0; offset < byteChars.length; offset += 512) {
53
+ const slice = byteChars.slice(offset, offset + 512);
54
+ const byteNumbers = new Array(slice.length);
55
+ for (let i = 0; i < slice.length; i++) {
56
+ byteNumbers[i] = slice.charCodeAt(i);
57
+ }
58
+ byteArrays.push(new Uint8Array(byteNumbers));
59
+ }
60
+ return new Blob(byteArrays, { type: mimeType });
61
+ }
62
+
63
  // Download single image
64
  document.querySelectorAll('.download-btn').forEach(btn => {
65
  btn.addEventListener('click', (e) => {
 
73
  });
74
  });
75
 
76
+ // Download all images as ZIP (client-side - fast!)
77
+ document.getElementById('download-zip').addEventListener('click', async (e) => {
78
  e.preventDefault();
79
 
80
+ const btn = e.target;
81
+ const originalText = btn.textContent;
82
+ btn.textContent = '⏳ Đang tạo ZIP...';
83
+ btn.style.pointerEvents = 'none';
84
+
85
+ try {
86
+ const zip = new JSZip();
87
+ const folder = zip.folder('manga_translated');
88
+
89
+ // Collect all images and add to ZIP
90
+ document.querySelectorAll('.download-btn').forEach((imgBtn, index) => {
91
+ const name = imgBtn.getAttribute('data-name');
92
+ const data = imgBtn.getAttribute('data-image');
93
+
94
+ // Convert base64 to binary and add to ZIP
95
+ const binaryData = atob(data);
96
+ folder.file(`${name}_translated.png`, binaryData, { binary: true });
97
  });
 
98
 
99
+ // Generate ZIP and trigger download
100
+ const content = await zip.generateAsync({
101
+ type: 'blob',
102
+ compression: 'DEFLATE',
103
+ compressionOptions: { level: 6 }
104
+ });
105
+
106
+ // Create download link
107
+ const url = URL.createObjectURL(content);
108
+ const a = document.createElement('a');
109
+ a.href = url;
110
+ a.download = 'manga_translated.zip';
111
+ a.click();
112
+ URL.revokeObjectURL(url);
113
+
114
+ btn.textContent = '✅ Đã tải xong!';
115
+ setTimeout(() => {
116
+ btn.textContent = originalText;
117
+ btn.style.pointerEvents = 'auto';
118
+ }, 2000);
119
+
120
+ } catch (error) {
121
+ console.error('ZIP creation failed:', error);
122
+ btn.textContent = '❌ Lỗi tạo ZIP';
123
+ setTimeout(() => {
124
+ btn.textContent = originalText;
125
+ btn.style.pointerEvents = 'auto';
126
+ }, 2000);
127
+ }
128
  });
129
  </script>
130