Spaces:
Running
Running
| import os | |
| import tempfile | |
| import uuid | |
| from flask import Blueprint, request, jsonify, send_file | |
| from backend.api.books import is_vip_request | |
| from backend.services.translation import get_engine, parse_custom_dict_text | |
| from backend.services import epub_service | |
| epub_bp = Blueprint("epub", __name__, url_prefix="/api/epub") | |
| def api_epub_translate(): | |
| if not is_vip_request(): | |
| return jsonify({"error": "Chức năng Dịch EPUB nâng cao chỉ dành cho thành viên VIP!"}), 403 | |
| if "file" not in request.files: | |
| return jsonify({"error": "Không tìm thấy file EPUB tải lên!"}), 400 | |
| file = request.files["file"] | |
| if file.filename == "": | |
| return jsonify({"error": "Tên file rỗng!"}), 400 | |
| mode = request.form.get("mode", "fast") | |
| limit_chapters = int(request.form.get("limit_chapters", "-1")) | |
| clean_styles = request.form.get("clean_styles", "false").lower() == "true" | |
| strip_images = request.form.get("strip_images", "false").lower() == "true" | |
| strip_fonts = request.form.get("strip_fonts", "false").lower() == "true" | |
| custom_dict_text = request.form.get("custom_dict", "").strip() | |
| custom_dict = parse_custom_dict_text(custom_dict_text) | |
| temp_dir = tempfile.gettempdir() | |
| src_path = os.path.join(temp_dir, f"src_{uuid.uuid4().hex}.epub") | |
| dest_path = os.path.join(temp_dir, f"translated_{uuid.uuid4().hex}.epub") | |
| try: | |
| file.save(src_path) | |
| eng = get_engine() | |
| duration = epub_service.translate_epub_file( | |
| src_path, dest_path, eng, mode=mode, | |
| limit_chapters=limit_chapters, custom_dict=custom_dict, | |
| clean_styles=clean_styles, strip_images=strip_images, strip_fonts=strip_fonts | |
| ) | |
| print(f"[VIP EPUB] Translated {file.filename} in {duration:.2f}s in mode {mode}") | |
| base, ext = os.path.splitext(file.filename) | |
| output_filename = f"{base}_Dich_{mode}{ext}" | |
| return send_file( | |
| dest_path, | |
| as_attachment=True, | |
| download_name=output_filename, | |
| mimetype="application/epub+zip" | |
| ) | |
| except Exception as e: | |
| print(f"[VIP EPUB ERROR] Translate failed: {e}") | |
| return jsonify({"error": f"Lỗi trong quá trình dịch EPUB: {str(e)}"}), 500 | |
| finally: | |
| if os.path.exists(src_path): | |
| try: | |
| os.remove(src_path) | |
| except Exception: | |
| pass | |
| def api_epub_convert_txt(): | |
| if not is_vip_request(): | |
| return jsonify({"error": "Chức năng chuyển đổi truyện sang EPUB chỉ dành cho thành viên VIP!"}), 403 | |
| title = request.form.get("title", "Truyện convert").strip() | |
| author = request.form.get("author", "Vô danh").strip() | |
| description = request.form.get("description", "").strip() | |
| split_regex = request.form.get("split_regex", r"第\s*\d+\s*[章|回|节]").strip() | |
| translate_bool = request.form.get("translate", "false").lower() == "true" | |
| mode = request.form.get("mode", "fast") | |
| custom_dict_text = request.form.get("custom_dict", "").strip() | |
| txt_content = "" | |
| if "file" in request.files: | |
| file = request.files["file"] | |
| if file.filename != "": | |
| txt_content = file.read().decode("utf-8", errors="ignore") | |
| else: | |
| txt_content = request.form.get("text", "").strip() | |
| if not txt_content: | |
| return jsonify({"error": "Nội dung văn bản rỗng!"}), 400 | |
| custom_dict = parse_custom_dict_text(custom_dict_text) | |
| temp_dir = tempfile.gettempdir() | |
| dest_path = os.path.join(temp_dir, f"converted_{uuid.uuid4().hex}.epub") | |
| try: | |
| eng = get_engine() if translate_bool else None | |
| epub_service.convert_txt_to_epub( | |
| txt_content, title, author, split_regex, dest_path, | |
| description=description, engine=eng, | |
| mode=mode if translate_bool else None, custom_dict=custom_dict | |
| ) | |
| return send_file( | |
| dest_path, | |
| as_attachment=True, | |
| download_name=f"{title}.epub", | |
| mimetype="application/epub+zip" | |
| ) | |
| except Exception as e: | |
| print(f"[VIP EPUB ERROR] Convert TXT failed: {e}") | |
| return jsonify({"error": f"Lỗi tạo EPUB: {str(e)}"}), 500 | |
| def api_epub_optimize(): | |
| if not is_vip_request(): | |
| return jsonify({"error": "Chức năng Tối ưu hóa EPUB chỉ dành cho thành viên VIP!"}), 403 | |
| if "file" not in request.files: | |
| return jsonify({"error": "Không tìm thấy file EPUB tải lên!"}), 400 | |
| file = request.files["file"] | |
| if file.filename == "": | |
| return jsonify({"error": "Tên file rỗng!"}), 400 | |
| strip_images = request.form.get("strip_images", "false").lower() == "true" | |
| strip_fonts = request.form.get("strip_fonts", "false").lower() == "true" | |
| temp_dir = tempfile.gettempdir() | |
| src_path = os.path.join(temp_dir, f"opt_src_{uuid.uuid4().hex}.epub") | |
| dest_path = os.path.join(temp_dir, f"opt_dest_{uuid.uuid4().hex}.epub") | |
| try: | |
| file.save(src_path) | |
| class MockEngine: | |
| def translate(self, text, **kwargs): | |
| return text | |
| epub_service.translate_epub_file( | |
| src_path, dest_path, MockEngine(), mode=None, | |
| limit_chapters=-1, custom_dict=None, clean_styles=True, | |
| strip_images=strip_images, strip_fonts=strip_fonts | |
| ) | |
| base, ext = os.path.splitext(file.filename) | |
| return send_file( | |
| dest_path, | |
| as_attachment=True, | |
| download_name=f"{base}_Optimized{ext}", | |
| mimetype="application/epub+zip" | |
| ) | |
| except Exception as e: | |
| return jsonify({"error": f"Lỗi tối ưu EPUB: {str(e)}"}), 500 | |
| finally: | |
| if os.path.exists(src_path): | |
| try: | |
| os.remove(src_path) | |
| except Exception: | |
| pass | |