Skip to content

Repository files navigation

MDriveExtract

Gom nhiều file ZIP của một lượt tải Google Drive thành một thư mục duy nhất.

Combine the several ZIP files a large Google Drive download arrives in, into one folder. (English below.)


Vấn đề

Khi bạn tải một thư mục lớn từ Google Drive, Drive không đưa bạn một file. Nó cắt thành nhiều ZIP độc lập:

Ảnh cưới-20240101T093000Z-001.zip
Ảnh cưới-20240101T093000Z-002.zip
Ảnh cưới-20240101T093000Z-003.zip

Giải nén từng file sẽ ra ba thư mục rời, cây thư mục gốc bị vỡ vụn, và những file trùng tên giữa các phần thì bạn phải tự xử lý.

MDriveExtract nhận cả nhóm, giải nén từng ZIP độc lập, rồi gom lại thành đúng một thư mục.

Dùng thế nào

  1. Kéo tất cả file ZIP vào cửa sổ app (hoặc bấm Chọn file ZIP…).
  2. Kiểm tên thư mục và nơi lưu — app tự đoán từ tên file.
  3. Bấm Gom lại.

Yêu cầu macOS 14 Sonoma trở lên. Universal, chạy native cả Apple silicon lẫn Intel.

Cách nó làm việc an toàn

Đây là chỗ đáng đọc, vì phần lớn công cụ "gộp ZIP" trên mạng làm sai.

  • Không nối byte. Các ZIP của Google Drive là những file độc lập, không phải một archive bị chia nhỏ. Nối chúng lại bằng cat sẽ hỏng dữ liệu. App giải nén riêng từng file rồi mới hợp cây thư mục.
  • Không có gì hiện ra cho tới khi mọi thứ xong. Toàn bộ quá trình chạy trong một thư mục tạm ẩn nằm cùng ổ đĩa với đích đến. Chỉ khi tất cả ZIP đã giải nén và kiểm tra xong, thư mục kết quả mới được chuyển ra — bằng một thao tác đổi tên, gần như tức thì.
  • File nguồn không bị đụng tới. App không xoá ZIP của bạn. Bạn tự xoá sau khi đã kiểm tra kết quả.
  • Trùng tên thì đánh số kiểu Finder. Hai phần cùng chứa shared.txt sẽ thành shared.txtshared 2.txt. Không có gì bị ghi đè — chuyện ghi đè không tồn tại trong thiết kế này.
  • Chặn zip bomb và symlink thoát thư mục. Có giới hạn số mục, giới hạn dung lượng giải nén, và mọi symlink trỏ ra ngoài thư mục tạm đều bị từ chối trước khi publish.
  • Huỷ giữa chừng là sạch sẽ. Không để lại rác cạnh file nguồn.

Về quyền truy cập file

App không chạy trong sandbox, và điều đó là cố ý.

Thư mục tạm phải được tạo bên trong thư mục đích thì bước cuối mới là một lệnh đổi tên cùng ổ đĩa. Dưới sandbox, việc kéo-thả chỉ cấp quyền cho các file được thả, không cấp cho thư mục chứa chúng — nên app sẽ phải bắt bạn chọn lại thư mục đầu ra trong một hộp thoại thứ hai, mỗi lần chạy, cho đúng cái thư mục mà ZIP của bạn đang nằm sẵn.

Đánh đổi nói thẳng: app đọc/ghi được ở mọi nơi tài khoản của bạn đọc/ghi được, chỉ bị macOS chặn qua TCC. Source công khai chính là thứ thay cho sandbox — bạn tự kiểm chứng được nó chỉ đụng vào thư mục đích. Lần đầu ghi vào Downloads/Desktop/Documents macOS vẫn sẽ hỏi quyền như bình thường.

Build từ source

make verify   # localization + test package + test app + build Debug
make run      # build rồi mở app
make dmg      # archive → ký → notarize → dựng DMG (cần Developer ID)

Cần XcodeGenMDriveExtract.xcodeproj được sinh ra từ project.yml và không nằm trong repo. Đừng sửa file project hay Info.plist bằng tay, make gen sẽ ghi đè.

Chạy test riêng:

cd Packages/MDriveExtractKit && swift test

Bộ test có một bài chạy thật 7zz đi kèm để gom hai ZIP thật — nếu binary không nạp được trên máy bạn thì test đỏ ngay, chứ không đợi tới lúc người dùng gặp.

Ghi công

Tính năng này được bóc ra từ MFinder, nơi nó sống dưới dạng một mục trong menu chuột phải của Finder. Bản này là app độc lập, hạ sàn xuống macOS 14 và bỏ hết phần còn lại.

Có sử dụng 7-Zip 24.09 của Igor Pavlov, phát hành theo GNU LGPL. Binary được đóng gói nguyên bản, không sửa đổi, kèm nguyên văn giấy phép tại Vendor/7Zip-24.09/License.txt và trong app tại Contents/Resources/Licenses/7-Zip/.

Vì sao là 24.09 chứ không phải bản mới nhất: các bản 7-Zip 26.x đóng dấu LC_BUILD_VERSION minos 26.0, nên dyld từ chối nạp trên macOS dưới 26 — dù bản thân code không dùng gì mới hơn libSystem/libc++ cổ điển. 24.09 là bản mới nhất còn cho phép chạy ở sàn macOS 14. make release có chốt chặn tự động fail nếu ai đó vendor lại một binary có minos cao hơn.

7zz chạy như một tiến trình riêng biệt, không phải thư viện được nạp vào app, nên đây là mere aggregation — giấy phép LGPL của nó và GPL của app này không xung đột.

Giấy phép

GPL-3.0. Nếu bạn fork và phát hành bản sửa đổi, hãy mở source theo.


English

MDriveExtract combines the several ZIP files a large Google Drive folder download arrives in, into one folder.

Google Drive splits big folder downloads into independent ZIPs (Photos-20240101T093000Z-001.zip, -002.zip, …). Extracting them one by one leaves you with several fragments of one directory tree, and duplicate names across parts to sort out by hand. Drop the whole group on MDriveExtract and it publishes exactly one folder.

Requires macOS 14 Sonoma or later. Universal (Apple silicon + Intel).

How it stays safe. ZIP bytes are never concatenated — those files are independent archives, not a split one, and cat-ing them corrupts the data. Each is extracted independently into a hidden staging directory on the same volume as the destination; only after every archive passes extraction and traversal validation is the result published, as a single near-instant rename. Sources are never modified. Duplicate names get Finder-style numbered copies (shared.txt, shared 2.txt) — overwriting is not representable in the design. Entry-count and expansion-size caps stop zip bombs, and symlinks resolving outside staging are rejected before anything is published. Cancelling leaves nothing behind.

Not sandboxed, deliberately. Staging must be created inside the destination folder for the final publish to be a same-volume rename. Under App Sandbox, drag-and-drop grants access to the dropped files, not their parent directory — so the app would have to make you pick the output folder in a second panel, every run, for the folder your ZIPs already sit in. The honest trade: the app can read and write wherever your account can, limited only by TCC. Public source is what stands in for the sandbox.

Building. make verify runs localization checks, package tests, app tests and a Debug build. make dmg cuts a signed, notarized release. Needs XcodeGen; the .xcodeproj is generated from project.yml and is not in the repo.

Credits. Extracted from MFinder, where this lives as a Finder context-menu item. Bundles unmodified 7-Zip 24.09 (GNU LGPL) — see Vendor/7Zip-24.09/README.md for why that version specifically. 7zz runs as a separate process, not a linked library.

License. GPL-3.0.

About

Gom nhiều file ZIP của một lượt tải Google Drive thành một thư mục duy nhất. macOS 14+, universal.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages