Module: Larch

Defined in:
lib/larch.rb,
lib/larch/imap.rb,
lib/larch/config.rb,
lib/larch/errors.rb,
lib/larch/logger.rb,
lib/larch/version.rb,
lib/larch/db/account.rb,
lib/larch/db/mailbox.rb,
lib/larch/db/message.rb

Defined Under Namespace

Modules: Database Classes: Config, Error, IMAP, Logger

Constant Summary collapse

EXCLUDE_COMMENT =
/#.*$/
EXCLUDE_REGEX =
/^\s*\/(.*)\/\s*/
GLOB_PATTERNS =
{'*' => '.*', '?' => '.'}
LIB_DIR =
File.join(File.dirname(File.expand_path(__FILE__)), 'larch')
APP_NAME =
'Larch'
APP_VERSION =
'1.0.2.3'
APP_AUTHOR =
'Ryan Grove'
APP_EMAIL =
'[email protected]'
APP_URL =
'http://github.com/rgrove/larch/'
'Copyright (c) 2009 Ryan Grove <[email protected]>. All ' <<
'rights reserved.'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configObject (readonly)

Returns the value of attribute config.



26
27
28
# File 'lib/larch.rb', line 26

def config
  @config
end

.dbObject (readonly)

Returns the value of attribute db.



26
27
28
# File 'lib/larch.rb', line 26

def db
  @db
end

.excludeObject (readonly)

Returns the value of attribute exclude.



26
27
28
# File 'lib/larch.rb', line 26

def exclude
  @exclude
end

.logObject (readonly)

Returns the value of attribute log.



26
27
28
# File 'lib/larch.rb', line 26

def log
  @log
end

Class Method Details

.copy_all(imap_from, imap_to, subscribed_only = false) ⇒ Object

Recursively copies all messages in all folders from the source to the destination.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/larch.rb', line 60

def copy_all(imap_from, imap_to, subscribed_only = false)
  raise ArgumentError, "imap_from must be a Larch::IMAP instance" unless imap_from.is_a?(IMAP)
  raise ArgumentError, "imap_to must be a Larch::IMAP instance" unless imap_to.is_a?(IMAP)

  @copied = 0
  @failed = 0
  @total  = 0

  imap_from.each_mailbox do |mailbox_from|
    next if excluded?(mailbox_from.name)
    next if subscribed_only && !mailbox_from.subscribed?

    mailbox_to = imap_to.mailbox(mailbox_from.name, mailbox_from.delim)
    mailbox_to.subscribe if mailbox_from.subscribed?

    copy_messages(mailbox_from, mailbox_to)
  end

rescue => e
  @log.fatal e.message

ensure
  summary
end

.copy_folder(imap_from, imap_to) ⇒ Object

Copies the messages in a single IMAP folder and all its subfolders (recursively) from the source to the destination.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/larch.rb', line 87

def copy_folder(imap_from, imap_to)
  raise ArgumentError, "imap_from must be a Larch::IMAP instance" unless imap_from.is_a?(IMAP)
  raise ArgumentError, "imap_to must be a Larch::IMAP instance" unless imap_to.is_a?(IMAP)

  @copied = 0
  @failed = 0
  @total  = 0

  mailbox_from = imap_from.mailbox(imap_from.uri_mailbox || 'INBOX')
  mailbox_to   = imap_to.mailbox(imap_to.uri_mailbox || 'INBOX')

  copy_mailbox(mailbox_from, mailbox_to)

  imap_from.disconnect
  imap_to.disconnect

rescue => e
  @log.fatal e.message

ensure
  summary
end

.init(config) ⇒ Object

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/larch.rb', line 33

def init(config)
  raise ArgumentError, "config must be a Larch::Config instance" unless config.is_a?(Config)

  @config = config
  @log    = Logger.new(@config[:verbosity])
  @db     = open_db(@config[:database])

  @exclude = @config[:exclude].map do |e|
    if e =~ EXCLUDE_REGEX
      Regexp.new($1, Regexp::IGNORECASE)
    else
      glob_to_regex(e.strip)
    end
  end

  load_exclude_file(@config[:exclude_file]) if @config[:exclude_file]

  Net::IMAP.debug = true if @log.level == :insane

  # Stats
  @copied = 0
  @failed = 0
  @total  = 0
end

.open_db(database) ⇒ Object

Opens a connection to the Larch message database, creating it if necessary.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/larch.rb', line 112

def open_db(database)
  filename  = File.expand_path(database)
  directory = File.dirname(filename)

  unless File.exist?(directory)
    FileUtils.mkdir_p(directory)
    File.chmod(0700, directory)
  end

  begin
    db = Sequel.connect("sqlite://#{filename}")
    db.test_connection
  rescue => e
    @log.fatal "unable to open message database: #{e}"
    abort
  end

  # Ensure that the database schema is up to date.
  migration_dir = File.join(LIB_DIR, 'db', 'migrate')

  unless Sequel::Migrator.get_current_migration_version(db) ==
      Sequel::Migrator.latest_migration_version(migration_dir)
    begin
      Sequel::Migrator.apply(db, migration_dir)
    rescue => e
      @log.fatal "unable to migrate message database: #{e}"
      abort
    end
  end

  require 'larch/db/message'
  require 'larch/db/mailbox'
  require 'larch/db/account'

  db
end

.summaryObject



149
150
151
# File 'lib/larch.rb', line 149

def summary
  @log.info "#{@copied} message(s) copied, #{@failed} failed, #{@total - @copied - @failed} untouched out of #{@total} total"
end