目录
Liron Newman

Update import-mailbox-to-gmail for 2026 (#65)

  • feat: Update to Python 3, add JWT auth, tests, and build script

This commit brings the script up-to-date with modern Python and Google Cloud authentication practices.

Changes include:

  • The script is now compatible with Python 3.
  • All dependencies have been updated to their latest versions, including the Google API client libraries. The deprecated oauth2client has been replaced with google-auth.
  • A new authentication option has been added to use the signJwt API via Application Default Credentials, allowing the script to be run without a JSON key file in environments like Google Cloud.
  • A unit test has been added to verify the mbox migration logic, with mocking of the Google API.
  • A build script (build.py) has been added to run the tests and create a single-file executable using PyInstaller. The build script will now automatically install PyInstaller if it is not found.
  • An option to control the HTTP library’s logging verbosity has been re-introduced.
  • The User-Agent for HTTP requests is now correctly set.
  • The Dockerfile has been updated to use Python 3 and reflect the script’s new name.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting, testing, and building (Docker & EXE).
  • Update Dockerfile to use python:3.14-rc-slim (latest).
  • Update README.md with Python 3 instructions.
  • Add run_real_import_test.py for interactive testing.
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting, testing, and building (Docker & EXE).
  • Update Dockerfile to use python:3.14-rc-slim (latest).
  • Update README.md with Python 3 instructions and EXE recommendation.
  • Add run_real_import_test.py for interactive testing with verification.
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting (pylint & markdownlint), testing, and building (Docker & EXE).
  • Update Dockerfile to use python:3-slim (latest stable).
  • Update README.md with Python 3 instructions, EXE recommendation, and 80-col formatting.
  • Add run_real_import_test.py for interactive testing with verification.
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3.
  • Add .markdownlint.json configuration.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting (pylint & markdownlint), testing, and building (Docker & EXE).
  • Update Dockerfile to use python:3-slim (latest stable).
  • Update README.md with Python 3 instructions, EXE recommendation, and 80-col formatting.
  • Add run_real_import_test.py for interactive testing with verification.
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3.
  • Add .markdownlint.json configuration.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting (pylint & markdownlint), testing, and building (Docker & EXE for Windows/macOS).
  • Update Dockerfile to use python:3-slim (latest stable).
  • Update README.md with Python 3 instructions, EXE recommendation for Windows/macOS, and 80-col formatting.
  • Add run_real_import_test.py for interactive testing with verification (self-contained with dummy mbox generation).
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3.
  • Add .markdownlint.json configuration.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting (pylint & markdownlint), testing, and building (Docker & EXE for Windows/macOS).
  • Update Dockerfile to use python:3-slim (latest stable).
  • Update README.md with Python 3 instructions, EXE recommendation for Windows/macOS, and 80-col formatting.
  • Add run_real_import_test.py for interactive testing with verification (self-contained with dummy mbox generation).
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3 and handle environment variables in CI.
  • Add .markdownlint.json configuration and .markdownlintignore for CONTRIBUTING.md.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting (pylint & markdownlint), testing, and building (Docker & EXE for Windows/macOS).
  • Update Dockerfile to use python:3-slim (latest stable).
  • Update README.md with Python 3 instructions, EXE recommendation for Windows/macOS, and 80-col formatting.
  • Add run_real_import_test.py for interactive testing with verification (self-contained with dummy mbox generation).
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3, handle environment variables in CI, and fix filename reference.
  • Add .markdownlint.json configuration and .markdownlintignore for CONTRIBUTING.md.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update project to Python 3.13+, add CI/CD pipeline, and real import test wrapper
  • Configure GitHub Actions for linting (pylint & markdownlint), testing, and building (Docker & EXE for Windows/macOS).
  • Update Dockerfile to use python:3-slim (latest stable).
  • Update README.md with Python 3 instructions, EXE recommendation for Windows/macOS, and 80-col formatting. Fixed filename references to use underscores.
  • Add run_real_import_test.py for interactive testing with verification (self-contained with dummy mbox generation, pagination, retries, and strict message verification).
  • Fix linting issues in import_mailbox_to_gmail.py and add .pylintrc.
  • Update build-exe.mac.sh to use python3, handle environment variables in CI, and fix filename reference.
  • Add .markdownlint.json configuration and .markdownlintignore for CONTRIBUTING.md.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Rename import_mailbox_to_gmail.py back to import-mailbox-to-gmail.py

Renamed the main script from import_mailbox_to_gmail.py to import-mailbox-to-gmail.py as requested. Updated all references to the script in:

  • test_import.py (updated to use dynamic import due to hyphen in filename)
  • README.md
  • .github/workflows/ci.yml
  • build.py
  • build-exe.mac.sh
  • Dockerfile
  • run_real_import_test.py

Verified that tests pass and linting is clean.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Refactor tests to tests/ folder and enable recursive pylint

Moved run_real_import_test.py, test_import.py, and sample.mbox to tests/ directory. Updated tests/test_import.py and tests/run_real_import_test.py to correctly reference the main script and test data using relative paths. Updated .github/workflows/ci.yml to run pylint recursively on all python files and discover tests in tests/. Updated build.py to discover tests in tests/ and fixed lint errors (indentation, docstrings). Fixed lint errors in tests/test_import.py (indentation, docstrings).

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Enable disabled pylint checks and fix violations
  • Removed disabled checks from .pylintrc: line-too-long, consider-using-f-string, unused-variable, redefined-builtin, ungrouped-imports, global-statement, no-member, invalid-name, too-many-locals, too-many-branches, too-many-statements, too-many-nested-blocks, broad-exception-caught, too-many-arguments, too-many-positional-arguments.
  • Refactored import-mailbox-to-gmail.py to fix complexity violations:
    • Extracted setup_logging, process_user, process_mbox_file, process_message_headers, import_message helper functions.
    • Updated process_mbox_files and main to use these helpers.
  • Fixed code style issues:
    • Long lines.
    • String formatting (f-strings for regular strings, lazy formatting for logging).
    • Unused variables.
    • Imports grouping.
  • Added localized # pylint: disable=... comments for violations that are structurally required or hard to refactor (e.g., broad-exception-caught in top-level loops, too-many-locals in stat aggregators).
  • Updated tests/run_real_import_test.py to fix minor pylint issues and refactor complexity.
  • Verified that pylint --recursive=y . now scores 10.00/10.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Enable disabled pylint checks, fix violations, and update tests
  • Removed disabled checks from .pylintrc: line-too-long, consider-using-f-string, unused-variable, redefined-builtin, ungrouped-imports, global-statement, no-member, invalid-name, too-many-locals, too-many-branches, too-many-statements, too-many-nested-blocks, broad-exception-caught, too-many-arguments, too-many-positional-arguments.
  • Refactored import-mailbox-to-gmail.py to fix complexity violations:
    • Extracted setup_logging, process_user, process_mbox_file, process_message_headers, import_message helper functions.
    • Updated process_mbox_files and main to use these helpers.
  • Renamed global args to ARGS to satisfy constant naming conventions.
  • Fixed code style issues:
    • Long lines.
    • String formatting (f-strings for regular strings, lazy formatting for logging).
    • Unused variables.
    • Imports grouping.
  • Added localized # pylint: disable=... comments for violations that are structurally required or hard to refactor.
  • Updated tests/run_real_import_test.py to fix minor pylint issues and refactor complexity.
  • Updated tests/test_import.py to patch ARGS instead of args, fixing a test failure.
  • Verified that pylint --recursive=y . now scores 10.00/10.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Enable strict pylint checks and cleanup violations
  • Cleared [MESSAGES CONTROL] in .pylintrc to enable all checks.
  • Added import-mailbox-to-gmail to good-names in .pylintrc to suppress invalid-name for the module.
  • Refactored import-mailbox-to-gmail.py:
    • Extracted process_user, process_mbox_file, import_message helpers to reduce complexity.
    • Renamed global args to ARGS and dir to dirname.
    • Switched to f-strings where appropriate.
    • Added localized ignores for broad-exception-caught, no-member, etc.
  • Updated tests/test_import.py to patch ARGS instead of args.
  • Verified 10.00/10 pylint score.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Enable strict pylint checks, cleanup violations, and fix logic error
  • Cleared [MESSAGES CONTROL] in .pylintrc to enable all checks.
  • Added import-mailbox-to-gmail to good-names in .pylintrc.
  • Refactored import-mailbox-to-gmail.py with helper functions to reduce complexity.
  • Renamed global args to ARGS and dir to dirname.
  • Fixed logic error where failed label creation was not incrementing number_of_labels_failed.
  • Added regression test test_import_label_failure in tests/test_import.py.
  • Updated tests to patch ARGS.
  • Verified 10.00/10 pylint score and passing tests.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Add tests for failure counters and invalid inputs
  • tests/test_import.py: Added unit tests for:
    • Message import failures (counters increment correctly).
    • User processing failures (counters increment correctly).
    • Arguments: –noreplaceqp, –no-fix-msgid, –from_message.
  • tests/run_real_import_test.py: Added integration test scenarios for:
    • Reserved label names (“Outbox”) - verified skipped.
    • Invalid headers (duplicate “From”) - verified failed/skipped.
    • Log verification for skipped labels and failed messages.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Add tests for failure counters and invalid inputs
  • tests/test_import.py: Added unit tests for:
    • Message import failures (counters increment correctly).
    • User processing failures (counters increment correctly).
    • Arguments: –noreplaceqp, –no-fix-msgid, –from_message.
  • tests/run_real_import_test.py: Added integration test scenarios for:
    • Reserved label names (“Outbox”) - verified skipped.
    • Invalid headers (duplicate “From”) - verified failed/skipped.
    • Log verification for skipped labels and failed messages.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Remove 3.14-dev from CI matrix to fix race condition
  • Removed “3.14-dev” from python-version in .github/workflows/ci.yml test matrix.
  • Removed allow-prereleases: true as it’s no longer needed for “3.x”.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Suppress test cleanup errors on Windows
  • Wrapped shutil.rmtree in tests/test_import.py and tests/run_real_import_test.py with try...except OSError to prevent test failures when files are locked (common on Windows).
  • Logs a warning instead of raising an exception.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Add release workflow to build and upload Windows and macOS binaries

This workflow is triggered when a release is created or manually via workflow_dispatch. It builds the executable for Windows and macOS and uploads them as artifacts.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Remove macOS build and update documentation

The macOS build and executable distribution are removed as unsigned binaries are difficult for users to run on macOS. The documentation is updated to instruct macOS users to run the Python script directly, similar to Linux users.

  • Removed build-exe-macos job from .github/workflows/release.yml.
  • Deleted build-exe.mac.sh.
  • Updated README.md to reflect that executables are Windows-only and updated macOS instructions to use the Python script.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Update docs to recommend Python script for macOS

Updated README.md to remove the recommendation for the macOS executable and instead instruct macOS users to run the Python script directly. This avoids issues with running unsigned binaries on macOS. The macOS build configuration remains in place but is no longer advertised in the documentation.

  • Updated README.md to state executables are for Windows only.
  • Updated README.md to include macOS in the Python script instructions.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Remove redundant text and provide default path.

  • Fix ResourceWarnings and suppress error logs in tests

  • Modified import-mailbox-to-gmail.py to use try...finally with mailbox.mbox to ensure file handles are closed, fixing ResourceWarning.
  • Modified tests/test_import.py to suppress logging during tests using logging.disable(logging.CRITICAL) in setUp and restoring it in tearDown. This cleans up expected error logs from the test output.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Fix run_real_import_test.py error reporting and API usage
  • Updated tests/run_real_import_test.py to print full traceback on verification failure.
  • Removed invalid pageToken argument from get_label_id as users.labels.list does not support pagination.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Disable discovery cache in Gmail service build

This change adds cache_discovery=False to the discovery.build call in import-mailbox-to-gmail.py. This prevents the Google API client from attempting to use file-based caching, which is not needed for this application and causes a warning log about oauth2client version incompatibility (INFO autodetect@__init__.py file_cache is only supported with oauth2client<4.0.0).

A new test case test_process_user_builds_service_without_cache is added to tests/test_import.py to verify this behavior.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Disable discovery cache in Gmail service build

This change adds cache_discovery=False to the discovery.build call in import-mailbox-to-gmail.py. This prevents the Google API client from attempting to use file-based caching, which is not needed for this application and causes a warning log about oauth2client version incompatibility (INFO autodetect@__init__.py file_cache is only supported with oauth2client<4.0.0).

A new test case test_process_user_builds_service_without_cache is added to tests/test_import.py to verify this behavior. Code has been formatted to comply with pylint line length limits.

Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

  • Remove outdated service account instructions.

  • Update README.md

  • Update README.md

  • Update version number in import-mailbox-to-gmail.py


Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: eesheesh 11871180+eesheesh@users.noreply.github.com

2个月前54次提交

Import .mbox files to Google Workspace (formerly G Suite / Google Apps)

This script allows Google Workspace admins to import mbox files in bulk for their users.

DISCLAIMER: This is not an official Google product.

If you want to migrate from Mozilla Thunderbird, try mail-importer.

You only authorize it once using a service account, and then it can import mail into the mailboxes of all users in your domain.

A. Creating and authorizing a service account for Gmail API

The easiest way is to use the automated script to authorize GWMME. The resulting JSON service account key file will work with this script as well. It will allow more API scopes than are needed, so you might want to remove them after it’s created and verified.

If you don’t want to use the automated script, you can follow the manual instructions on the same page, but you’ll only need to enable Gmail API (not all of the other APIs), and only the two Gmail scopes:

https://www.googleapis.com/auth/gmail.insert, https://www.googleapis.com/auth/gmail.labels

At the end of either option, you will have a JSON service account key file, that you can use to authorize programs to access the Gmail API “insert” and “label” scopes of all users in your Google Workspace domain.

Remember to store this key safely, and don’t share it with anyone.

B. Importing mbox files

Important: If you’re planning to import mail from Apple Mail.app, see the notes below.

You can either run the pre-compiled executable (easiest) or run the Python script directly.

  1. Download import-mailbox-to-gmail.exe from the latest release. Note: Executables are provided for Windows only. macOS and Linux users should use Option 2.

  2. Open a Command Prompt (CMD) window.

  3. Create a folder for the mbox files, for example C:\mbox (see step 5 below).

  4. Follow steps 6-8 below, replacing python import-mailbox-to-gmail.py with the path to your downloaded executable (usually %USERPROFILE%\Downloads\import-mailbox-to-gmail.exe).

Option 2: Running the Python script

  1. Download the script import-mailbox-to-gmail.py from the latest release.

  2. Download and install Python 3 (latest version) for your operating system if needed.

  3. Open a Command Prompt (CMD) window (on Windows) / Terminal window (on macOS/Linux).

  4. Install the Google API Client Libraries for Python and their dependencies. Ensure you have a requirements.txt file (you can download it from the repo) in the same directory, then run:

    pip3 install -r requirements.txt

    Note: On Windows, you may need to do this on a Command Prompt window that was run as Administrator.

  5. Create a folder for the mbox files, for example C:\mbox or ~/mbox.

  6. Under that folder, create a folder for each of the users into which you intend to import the mbox files. The folder names should be the users’ full email addresses.

  7. Into each of the folders, copy the mbox files for that user. Make sure the file name format is <LabelName>.mbox. For example, if you want the messages to go into a label called “Imported messages”, name the file “Imported messages.mbox”.

    Your final folder and file structure should look like this (for example):

    C:\mbox
    C:\mbox\user1@domain.com
    C:\mbox\user1@domain.com\Imported messages.mbox
    C:\mbox\user1@domain.com\Other imported messages.mbox
    C:\mbox\user2@domain.com
    C:\mbox\user2@domain.com\Imported messages.mbox
    C:\mbox\user2@domain.com\Other imported messages.mbox

    IMPORTANT: It’s essential to test the migration before migrating into the real users’ mailboxes. First, migrate the mbox files into a test user, to make sure the messages are imported correctly.

  8. To start the migration, run the following command (one line):

    macOS/Linux:

    python3 import-mailbox-to-gmail.py --json Credentials.json --dir ~/mbox

    Windows:

    python import-mailbox-to-gmail.py --json Credentials.json --dir C:\mbox
    • Replace import-mailbox-to-gmail.py with the full path of import-mailbox-to-gmail.py - usually ~/Downloads/import-mailbox-to-gmail.py on Mac/Linux or %USERPROFILE%\Downloads\import-mailbox-to-gmail.py on Windows.
    • Replace Credentials.json with the path of the JSON service account key file created in the previous step.
    • Replace C:\mbox with the path to the folder you created in step 5.

The mbox files will now be imported, one by one, into the users’ mailboxes. You can monitor the migration by looking at the output, and inspect errors by viewing the import-mailbox-to-gmail.log file.

Options and notes

  • Use the --from_message parameter to start the upload from a particular message. This allows you to resume an upload if the process previously stopped. (Affects all users and all mbox files)

    e.g. python3 import-mailbox-to-gmail.py --from_message 74336

  • If any of the folders have a “.mbox” extension, it will be dropped when creating the label for it in Gmail.

  • To import mail from Apple Mail.app, make sure you export it first - the raw Apple Mail files can’t be imported. You can export a folder by right clicking it in Apple Mail and choosing “Export Mailbox”.

  • This script can import nested folders. In order to do so, it is necessary to preserve the email folders’ hierarchy when exporting them as mbox files. In Apple Mail.app, this can be done by expanding all subfolders, selecting both parents and subfolders at the same time, and exporting them by right clicking the selection and choosing “Export Mailbox”.

  • If any of the folders have a “.mbox” extension and a file named “mbox” in them, the contents of the “mbox” file will be imported to the label named as the folder. This is how Apple Mail exports are structured.

  • To run under Docker:

    1. Build the image:

      docker build -t import-mailbox-to-gmail https://github.com/google/import-mailbox-to-gmail.git
    2. Run the import command:

      docker run --rm -it \
          -v "/local/path/to/auth.json:/auth.json" \
          -v "/local/path/to/mbox:/mbox" \
          import-mailbox-to-gmail --json "/auth.json" --dir "/mbox"

      Note -v is mounting a local file/directory /local/path/to/auth.json in the container as /auth.json. The command is then using it within the container --json "/auth.json". For more help, see Volume in Docker Run.

邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802032778号