Mega - cái tên cloud storage cũng khá lâu đời có tên có tuổi trong làng cloud, mình còn nhớ nó có từ thời sinh viên, và đến giờ cũng khoảng hơn chục năm. Vừa check thấy từ 2013, để cho thấy rằng thằng này khá uy tín ấy chứ, sống lâu phết ngang với mediafire, box, dropbox,... =))
Đang làm con project crawl ebook, mà sáng mở mắt ra thấy có 1 trang nó cũng đang sử dụng thằng này để store ebook file, mà mình thì đang muốn crawl nên ngồi mò luôn. Tính search get direct link mega.nz trên gu gồ mà không thấy, có thấy 1 link gist mà nó chạy = bash shell nên không hứng thú lắm, với lại cũng vừa thử thì ko chạy dc, ko hiểu sao có 1 số người vẫn comment là "Yes, working great in 2024", và thấy 1 số comment khác là do macos nên phải change 1 số cái đại loại như sửa hex các thứ. choán luôn. từ bỏ hoặc nó là phương án cuối cùng để dùng.
Lại quay lại con chatgpt với claude để hỏi xem nó có ngu kiến gì không, thì hỏi tới hỏi lui rồi paste cả đoạn script bashshell trên để bảo nó làm bằng code js thì thấy nó dùng luôn megajs. Ôi đậu má, sao mình k nghĩ ra để tìm. 😭 wft.
Thế là lên github xem docs thì thấy commit 3 tuần trc. hêhe, xong với anh. Nghĩa là nó vẫn maintain.
Rồi bắt đầu thôi. Nhảy luôn vào trang docs của nó: Mega JS
Thấy nó hỗ trợ downloadBuffer, với file lớn, thì dùng buffer để lưu vào memory ok hơn. như docs nó nói:
Those are useful when dealing with huge files as .downloadBuffer() stores the entire file in memory. In the other hand, because of that, .download() can't return a promise. Also, you can still use callbacks with .download() like in V0.
const stream = file.download();
stream.on("progress", (info) => {
console.log("Loaded", info.bytesLoaded, "bytes of", info.bytesTotal);
});
thế là quay sang dùng buffer và writeFile.
Ngó ngó xuống dưới thấy nó còn đề cập đến cả retry khi error. vậy là lắp thêm đoạn code của nó.
import { File } from "megajs";
File.defaultHandleRetries = (tries, error, cb) => {
if (tries > 8) {
// Give up after eight retries
cb(error);
} else {
// Wait some time then try again
setTimeout(cb, 1000 * Math.pow(2, tries));
}
};
Cuối cùng sau tất cả - Erik không làm tôi vui mà chỉ có code mới là cái làm tôi vui, chúng ta có full code:
import { Storage, File } from "megajs";
import { writeFile, mkdir } from "node:fs/promises";
import path from "path";
import fs from "fs";
File.defaultHandleRetries = (tries, error, cb) => {
if (tries > 8) {
// Give up after eight retries
cb(error);
console.log("error download retried: " + error);
} else {
// Wait some time then try again
setTimeout(cb, 1000 * Math.pow(2, tries));
}
};
const getMega = async (url) => {
// check mega folder already exists, if it doesn't exist then create it
if (!fs.existsSync("./mega")) {
await fs.mkdirSync("./mega", { recursive: true });
}
const storage = new Storage({
email: "your-mega-account",
password: "your-mega-password",
});
storage.once("ready", () => {
// User is now logged in
// console.log("logged");
});
storage.once("error", (error) => {
// Some error happened
console.log("errr");
});
// Get the file object from the URL
const file = File.fromURL(url);
// Load file attributes
const att = await file.loadAttributes();
// Then finally download the file like usual
const data = await file.downloadBuffer();
const targetFile = path.join("mega", file?.name);
await writeFile(targetFile, data);
// using with streaming
// const stream = file.download();
// stream.on("error", (error) => console.error(error));
// stream.pipe(fs.createWriteStream(targetFile));
};
getMega(
"https://mega.nz/file/L80EUC4B#5E35FfijzinuMp7TPdjtmwgS2BIUN_Ja6iFP8s0Ov5M"
);
Conclusion:
Đây chỉ là 1 đoạn code bằng js để download file từ mega.nz, nhưng đôi khi mình cần phải thay đổi cách nghĩ cách search để tìm ra được kết quả.
Thích thì cứ mò thôi, ngại gì =))