[{"data":1,"prerenderedAt":250},["ShallowReactive",2],{"content-\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-upload":3,"children-\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-upload":249},{"id":4,"title":5,"author":6,"body":7,"budget_tier":6,"build_tags":6,"created":6,"description":240,"document_type":241,"extension":242,"game":6,"install":36,"investment_tier":6,"league":6,"meta":243,"navigation":244,"patch":6,"path":245,"plugin":24,"profit_per_hour":6,"ratings":6,"seo":246,"skills_count":6,"status":6,"stem":247,"strategy_tier":6,"tags":6,"updated":6,"version":6,"weight":6,"__hash__":248},"content\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-upload.md","aio-epub-upload",null,{"type":8,"value":9,"toc":227},"minimark",[10,37,42,45,57,62,72,76,81,84,90,94,100,104,110,114,120,124,127,132,135,141,145,148,154,158,207],[11,12,13],"blockquote",{},[14,15,16,17,25,26,25,30,33,34],"p",{},"From plugin ",[18,19,21],"a",{"href":20},"\u002Fplugins\u002Faio-epub-translate",[22,23,24],"strong",{},"aio-epub-translate"," · ",[27,28,29],"code",{},"v4.0.0",[22,31,32],{},"Install:"," ",[27,35,36],{},"\u002Fplugin install aio-epub-translate@aiocean-plugins",[38,39,41],"h1",{"id":40},"epub-upload-prepare","EPUB Upload & Prepare",[14,43,44],{},"Upload an EPUB file to the translation server and prepare it for translation.",[11,46,47],{},[14,48,49,52,53,56],{},[22,50,51],{},"Prerequisite",": Cần có API key. Chưa có? Dùng ",[27,54,55],{},"aio-epub-setup"," trước.",[58,59,61],"h2",{"id":60},"api-setup","API Setup",[63,64,70],"pre",{"className":65,"code":67,"language":68,"meta":69},[66],"language-python","import json, urllib.request, os\n\nBASE = \"https:\u002F\u002Fread-api.aiocean.dev\u002FListBooks.v1.BookService\"\nKEY = os.environ.get(\"AIO_EPUB_API_KEY\", \"duocnv\")\n\ndef api(method, body):\n    data = json.dumps(body).encode('utf-8')\n    req = urllib.request.Request(f\"{BASE}\u002F{method}\", data=data, headers={\n        \"Content-Type\": \"application\u002Fjson\",\n        \"X-License-Key\": KEY\n    })\n    with urllib.request.urlopen(req) as resp:\n        return json.loads(resp.read())\n","python","",[27,71,67],{"__ignoreMap":69},[58,73,75],{"id":74},"workflow","Workflow",[77,78,80],"h3",{"id":79},"_1-upload-epub","1. Upload EPUB",[14,82,83],{},"Read the EPUB file as bytes and upload:",[63,85,88],{"className":86,"code":87,"language":68,"meta":69},[66],"import base64\n\nwith open(\"path\u002Fto\u002Fbook.epub\", \"rb\") as f:\n    epub_bytes = f.read()\n\n# UploadEpub is streaming — use raw HTTP\ndata = json.dumps({\n    \"epubData\": base64.b64encode(epub_bytes).decode(),\n    \"filename\": \"book.epub\"\n}).encode('utf-8')\n\nreq = urllib.request.Request(f\"{BASE}\u002FUploadEpub\", data=data, headers={\n    \"Content-Type\": \"application\u002Fjson\",\n    \"X-License-Key\": KEY\n})\nwith urllib.request.urlopen(req) as resp:\n    result = json.loads(resp.read())\n    book_id = result[\"bookId\"]\n    print(f\"Uploaded: {book_id}\")\n",[27,89,87],{"__ignoreMap":69},[77,91,93],{"id":92},"_2-prepare-book-if-not-auto-prepared","2. Prepare Book (if not auto-prepared)",[63,95,98],{"className":96,"code":97,"language":68,"meta":69},[66],"# PrepareBook cleans HTML, marks translatable content, generates guidelines\nresult = api(\"PrepareBook\", {\"bookId\": book_id})\nprint(result[\"message\"])\n",[27,99,97],{"__ignoreMap":69},[77,101,103],{"id":102},"_3-generate-translation-guideline","3. Generate Translation Guideline",[63,105,108],{"className":106,"code":107,"language":68,"meta":69},[66],"result = api(\"GenerateGuideline\", {\n    \"bookId\": book_id,\n    \"sourceLanguage\": \"en\",\n    \"targetLanguage\": \"vi\",\n    \"templateName\": \"literary\",\n    \"modelId\": \"\"  # uses default model\n})\nprint(result[\"guideline\"])\n",[27,109,107],{"__ignoreMap":69},[77,111,113],{"id":112},"_4-verify-setup","4. Verify Setup",[63,115,118],{"className":116,"code":117,"language":68,"meta":69},[66],"# Check book exists and has content\nbook = api(\"GetBook\", {\"bookId\": book_id})\nprint(f\"Title: {book['book']['title']}\")\nprint(f\"Author: {book['book']['author']}\")\n\n# Check TOC\ntoc = api(\"GetTableOfContent\", {\"bookId\": book_id})\nfor item in toc[\"tableOfContent\"][\"items\"]:\n    print(f\"  {item['title']} -> {item['filePath']}\")\n\n# Check translation progress (should be 0%)\nprogress = api(\"GetTranslationProgress\", {\"bookId\": book_id})\nprint(f\"Progress: {progress['progress']['translationPercentage']:.1f}%\")\n",[27,119,117],{"__ignoreMap":69},[77,121,123],{"id":122},"_5-content-marking-management","5. Content Marking Management",[14,125,126],{},"Sau khi prepare, có thể tinh chỉnh content markings:",[128,129,131],"h4",{"id":130},"unmark-element","Unmark Element",[14,133,134],{},"Bỏ đánh dấu 1 element không cần dịch (ví dụ: code block, số liệu, header trang):",[63,136,139],{"className":137,"code":138,"language":68,"meta":69},[66],"result = api(\"UnmarkElement\", {\n    \"bookId\": book_id,\n    \"filePath\": FILE_PATH,\n    \"contentId\": CONTENT_ID\n})\nprint(result[\"message\"])\n",[27,140,138],{"__ignoreMap":69},[128,142,144],{"id":143},"change-element-tag","Change Element Tag",[14,146,147],{},"Đổi tag của element (ví dụ: đổi từ paragraph sang heading):",[63,149,152],{"className":150,"code":151,"language":68,"meta":69},[66],"result = api(\"ChangeElementTag\", {\n    \"bookId\": book_id,\n    \"filePath\": FILE_PATH,\n    \"contentId\": CONTENT_ID,\n    \"tag\": \"h2\"\n})\nprint(result[\"message\"])\n",[27,153,151],{"__ignoreMap":69},[58,155,157],{"id":156},"bước-tiếp-theo","Bước tiếp theo",[159,160,161,174],"table",{},[162,163,164],"thead",{},[165,166,167,171],"tr",{},[168,169,170],"th",{},"Bạn muốn...",[168,172,173],{},"Dùng skill",[175,176,177,187,197],"tbody",{},[165,178,179,183],{},[180,181,182],"td",{},"Bắt đầu dịch chương đầu tiên",[180,184,185],{},[27,186,24],{},[165,188,189,192],{},[180,190,191],{},"Xem tiến độ và quản lý sách",[180,193,194],{},[27,195,196],{},"aio-epub-manage",[165,198,199,202],{},[180,200,201],{},"Chỉnh sửa guideline trước khi dịch",[180,203,204,206],{},[27,205,196],{}," (phần Guidelines)",[14,208,209,211,212,214,215,214,219,214,221,214,224],{},[22,210,75],{},": ",[27,213,55],{}," → ",[22,216,217],{},[27,218,5],{},[27,220,24],{},[27,222,223],{},"aio-epub-quality",[27,225,226],{},"aio-epub-export",{"title":69,"searchDepth":228,"depth":228,"links":229},2,[230,231,239],{"id":60,"depth":228,"text":61},{"id":74,"depth":228,"text":75,"children":232},[233,235,236,237,238],{"id":79,"depth":234,"text":80},3,{"id":92,"depth":234,"text":93},{"id":102,"depth":234,"text":103},{"id":112,"depth":234,"text":113},{"id":122,"depth":234,"text":123},{"id":156,"depth":228,"text":157},"Upload and prepare EPUB books for translation.","skill","md",{},true,"\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-upload",{"title":5,"description":240},"plugins\u002Faio-epub-translate\u002Faio-epub-upload","6Yum5jB4kC6fdFa1E-8J1JCHMp9-RtFP__duEsr75nU",[],1779707416451]