From a1b765e8cba0809a95127b525d035d16d3a1f5b3 Mon Sep 17 00:00:00 2001 From: Joe Yates Date: Sat, 30 Mar 2024 11:50:47 +0100 Subject: [PATCH 1/2] Rename script --- contrib/README.md | 4 ++-- contrib/{import-from-csv => import-accounts-from-csv} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename contrib/{import-from-csv => import-accounts-from-csv} (100%) diff --git a/contrib/README.md b/contrib/README.md index 0b616b31..ad72ca42 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -3,7 +3,7 @@ This directory contains contributed scripts that relate to imap-backup -# import-from-csv +# import-accounts-from-csv This script reads a CSV file and merges the supplied information into an imap-backup configuration file. @@ -19,5 +19,5 @@ An example CSV file `contrib/example_users.csv` is provided. You can try out the script as follows: ```sh -contrib/import-from-csv --csv contrib/example_users.csv --config example-config.json --verbose +contrib/import-accounts-from-csv --csv contrib/example_users.csv --config example-config.json --verbose ``` diff --git a/contrib/import-from-csv b/contrib/import-accounts-from-csv similarity index 100% rename from contrib/import-from-csv rename to contrib/import-accounts-from-csv From bd2dbd66dce6ca024af35f0aa935e87cf6fcc910 Mon Sep 17 00:00:00 2001 From: Joe Yates Date: Sat, 30 Mar 2024 21:10:18 +0100 Subject: [PATCH 2/2] Add example script for import from Thunderbird --- contrib/README.md | 11 ++++ contrib/import-thunderbird-folder | 92 +++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100755 contrib/import-thunderbird-folder diff --git a/contrib/README.md b/contrib/README.md index ad72ca42..a3bf87bf 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -21,3 +21,14 @@ You can try out the script as follows: ```sh contrib/import-accounts-from-csv --csv contrib/example_users.csv --config example-config.json --verbose ``` + +# import-messages-from-thunderbird + +This script imports all messages from a Thunderbird folder. + +Obviously, Thunderbird must be installed and the folder in question must +have the Thunderbird setting "Select this folder for offline use". + +```sh +contrib/import-thunderbird-folder --config example-config.json --verbose +``` diff --git a/contrib/import-thunderbird-folder b/contrib/import-thunderbird-folder new file mode 100755 index 00000000..fc7ba698 --- /dev/null +++ b/contrib/import-thunderbird-folder @@ -0,0 +1,92 @@ +#!/usr/bin/env ruby + +# This script is an example of how to import messages from a Thunderbird +# folder into imap-backup. It is not meant to be a general-purpose +# Thunderbird importer, but rather a starting point for writing your own. +# Please adapt it to your specific needs. + +require "bundler/inline" + +gemfile do + source "https://rubygems.org" + + gem "imap-backup" + gem "optparse" + gem "thunderbird", "~> 0.5.0" +end + +require "imap/backup/logger" +require "imap/backup/configuration" +require "imap/backup/serializer" +require "thunderbird/mbox" + +class Options + attr_accessor :email + attr_accessor :config_path + attr_accessor :folder + attr_accessor :mbox_path + attr_accessor :verbose + attr_accessor :quiet + + def parse! + OptionParser.new do |opts| + opts.banner = <<~BANNER + Usage: #{$PROGRAM_NAME} [options]" + + Import email messages from a Thunderbird folder into imap-backup. + + BANNER + + opts.on("--config=CONFIG", "The path to an existing (or new) imap-backup config file") do |v| + self.config_path = v + end + opts.on("--email=EMAIL", "The email address configured in imap-backup") do |v| + self.email = v + end + opts.on("--folder=FOLDER", "The folder name to import into") do |v| + self.folder = v + end + opts.on("--mbox=MBOX_PATH", "The path to a Thunderbird folder") do |v| + self.mbox_path = v + end + opts.on("-q", "--quiet", "Do not print any output") do + self.quiet = true + end + opts.on("-v", "--[no-]verbose", "Run verbosely") do |v| + self.verbose = v + end + end.parse! + + raise "Please supply a --config PATH option" if !config_path + raise "Please supply a --email EMAIL option" if !email + raise "Please supply a --folder FOLDER option" if !folder + raise "Please supply a --mbox PATH option" if !mbox_path + end + + def for_logging + {verbose: [verbose], quiet: quiet} + end +end + +options = Options.new.tap(&:parse!) + +Imap::Backup::Logger.setup_logging(options.for_logging) + +config = Imap::Backup::Configuration.new(path: options.config_path) + +account = config.accounts.find { |a| a.username == options.email } +raise "No account found for email address '#{options.email}'" if account.nil? + +mbox = Thunderbird::Mbox.new(path: options.mbox_path) + +serializer = Imap::Backup::Serializer.new(account.local_path, options.folder) +serializer.force_uid_validity(mbox.uid_validity) + +mbox.each do |id, message| + uid = id.to_i + next if serializer.uids.include?(uid) + + # Remove Thunderbird mbox "From" line + message.sub!(/^From[\s\r\n]*/m, "") + serializer.append(id, message, []) +end