class Object

Constants

ADDRESSES_FILE
BCBIFF_FILE
BCBIFF_VERSION
CERTS_PATH
CERTS_PATHS
IDCACHE_FILE
IDCACHE_SIZE

Public Instance Methods

certs_path() click to toggle source
# File lib/bcbiff.rb, line 129
def certs_path
  $certs_path ||= config[:certs_path] || CERTS_PATH
end
check_mails(options) click to toggle source
# File lib/bcbiff.rb, line 161
def check_mails(options)
  #Net::IMAP.debug = true
  mailto = options[:mailto]
  msgids_file = File.expand_path(IDCACHE_FILE % mailto)

  File.open(msgids_file, File::RDWR | File::CREAT, 0600) {|f|
    f.flock(File::LOCK_EX | File::LOCK_NB) or break

    msgids = YAML.load(f) || []

    imap = Net::IMAP.new(options[:host], options[:port], options[:ssl], certs_path, true)
    imap.login(options[:username], options[:password])
    folders = options[:folders] || ['Inbox']

    folders.each { |folder|
      imap.select(folder)
      unseen = imap.search('UNSEEN')
      next if unseen.empty?

      imap.fetch(unseen, item = 'RFC822.HEADER').each { |data|
        mail = Mail.read_from_string(data.attr[item])
        msgid = mail.message_id
        next if msgids.include?(msgid)
        msgids << msgid

        (header = mail.header).fields.map(&:name).each { |name|
          case name
          when /\A(From|Subject|Date)\z/i
            # preserve
          else
            header[name] = nil
          end
        }

        mail.from = mail[:from].field.addrs.map { |addr|
          $display_address[addr.address.downcase] || addr.to_s
        }.join(', ')

        begin
          encoded = mail.encoded
          open("| sendmail #{mailto.shellescape}", 'w') { |sendmail|
            sendmail.print encoded
          }
        rescue => e
          STDERR.puts "%s: %s" % [msgid, e.message]
        end
      }
    }
    msgids.slice!(0...-IDCACHE_SIZE) if msgids.size > IDCACHE_SIZE

    f.rewind
    f.print YAML.dump(msgids)
    f.truncate(f.pos)
  }
end
config() click to toggle source
# File lib/bcbiff.rb, line 96
def config
  $config ||=
    begin
      value = YAML.load_file(File.expand_path(BCBIFF_FILE))
      raise unless value.is_a?(Hash) && value.key?(:accounts)
      value
    end
rescue
  STDERR.puts "Put your configuration in #{BCBIFF_FILE} that looks like below.", ''
  STDERR.print YAML.dump({
    :accounts => [
        {
          :host => 'imap.gmail.com',
          :port => 993,
          :ssl  => true,
          :username => 'your.account',
          :password => 'password1',
          :mailto => 'dead.beef@push.boxcar.io',
        },
        {
          :host => 'imap.gmail.com',
          :port => 993,
          :ssl  => true,
          :username => 'you@your.domain',
          :password => 'password2',
          :mailto => 'feed.babe@push.boxcar.io',
          :folders => %w[Inbox work/important],
        }
    ]
  })
  exit 1
end
main(argv) click to toggle source
# File lib/bcbiff.rb, line 58
def main(argv)
  accounts = config[:accounts]

  maildir = File.dirname(File.expand_path(IDCACHE_FILE))
  Dir.mkdir(maildir, 0700) unless File.directory?(maildir)

  if accounts.any? { |account| account[:ssl] } && !certs_path
    STDERR.print <<-EOS
The system path for SSL certificates is not found.
Install SSL certificates in one of the following locations:
    EOS
    CERTS_PATHS.each { |path|
      STDERR.puts "\t#{path}"
    }
    STDERR.print <<-EOS if RUBY_PLATFORM =~ /darwin/

If you are on OS X and have MacPorts installed, running the
following command is an easy way to have one installed:
\tport install curl-ca-bundle
    EOS
    STDERR.print <<-EOS

Otherwise, refer to the following site and place the pem
file somewhere:
\thttp://curl.haxx.se/docs/caextract.html

Then add `:certs_path: /path/to/pem` to #{BCBIFF_FILE}.
    EOS
    exit 1
  end

  read_addresses

  accounts.each { |options|
    check_mails(options)
  }
end
read_addresses() click to toggle source
# File lib/bcbiff.rb, line 133
def read_addresses
  $display_address = {}

  begin
    content = File.read(ADDRESSES_FILE)
  rescue
    return
  end

  content.each_line { |line|
    line.chomp!
    address, nickname, fullname = line.split("\t").map { |field|
      if m = field.match(/\A"(.*)"\z/)
        m[1].gsub(/\\(.)/, "\\1")
      else
        field
      end
    }
    begin
      addr = Mail::Address.new(address)
      addr.display_name = nickname
      $display_address[address.downcase] = addr.to_s
    rescue
    end
  }
rescue
end