Class: IMAPProcessor::Archive

Inherits:
IMAPProcessor show all
Defined in:
lib/imap_processor/archive.rb

Overview

Archives old mail on IMAP server by moving it to dated mailboxen.

Constant Summary

Constants inherited from IMAPProcessor

VERSION

Instance Attribute Summary collapse

Attributes inherited from IMAPProcessor

#imap, #options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IMAPProcessor

add_move, #capability, #connect, #create_mailbox, #delete_messages, #each_message, #each_part, #log, #mime_parts, #move_messages, #noop?, run, #show_messages, #verbose?

Constructor Details

#initialize(options) ⇒ Archive

Returns a new instance of Archive.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/imap_processor/archive.rb', line 43

def initialize(options)
  super

  puts "Archiving #{options[:Host]}"

  @list = options[:List]
  @move = options[:Move]
  @sep  = options[:Sep] || '.'
  @split = options[:Split]

  connection = connect

  @imap = connection.imap
end

Instance Attribute Details

#listObject (readonly)

Returns the value of attribute list.



8
9
10
# File 'lib/imap_processor/archive.rb', line 8

def list
  @list
end

#moveObject (readonly)

Returns the value of attribute move.



8
9
10
# File 'lib/imap_processor/archive.rb', line 8

def move
  @move
end

#sepObject (readonly)

Returns the value of attribute sep.



8
9
10
# File 'lib/imap_processor/archive.rb', line 8

def sep
  @sep
end

#splitObject (readonly)

Returns the value of attribute split.



8
9
10
# File 'lib/imap_processor/archive.rb', line 8

def split
  @split
end

Class Method Details

.process_args(args) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/imap_processor/archive.rb', line 10

def self.process_args(args)
  required_options = {
    :List => true,
    :Move => false,
    :Split => false,
  }

  super __FILE__, args, required_options do |opts, options|
    opts.banner << <<-EOF
imap_archive archives old mail on IMAP server by moving it to dated mailboxen.
    EOF

    opts.on("--[no-]list", "Display messages (on by default)") do |list|
      options[:List] = list
    end

    opts.on("--[no-]move", "Move the messages (off by default)") do |move|
      options[:Move] = move
    end

    opts.on("--[no-]split", "Split mailbox into multiple months (off by default)") do |move|
      options[:Split] = move
    end

    opts.on("-s", "--sep SEPARATOR",
            "Mailbox date separator character",
            "Default: Read from ~/.#{@@opts_file_name}",
            "Options file name: :Sep") do |sep|
      options[:Sep] = sep
    end
  end
end

Instance Method Details

#make_searchObject

Makes a SEARCH argument set from keywords



66
67
68
# File 'lib/imap_processor/archive.rb', line 66

def make_search
  %W[SENTBEFORE #{the_first.imapdate}]
end

#runObject



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/imap_processor/archive.rb', line 70

def run
  @boxes.each do |mailbox|
    log "SELECT #{mailbox}"
    imap.select mailbox

    uids_by_date = self.uids_by_date

    next if uids_by_date.empty?

    unless split then
      d = the_first - 1       # one second back into last month
      latest = [d.year, d.month]

      uids_by_date = {
        latest => uids_by_date.values.flatten(1)
      }
    end

    uids_by_date.sort.each do |date, uids|
      next if uids.empty?
      destination = "#{mailbox}#{sep}%4d-%02d" % date
      puts "#{destination}:"
      puts
      show_messages uids
      move_messages uids, destination, false if move
    end

    log "EXPUNGE"
    imap.expunge unless noop?
  end
end

#the_firstObject



58
59
60
61
# File 'lib/imap_processor/archive.rb', line 58

def the_first
  t = Time.now
  Time.local(t.year, t.month, 1)
end

#uids_by_dateObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/imap_processor/archive.rb', line 102

def uids_by_date
  search = make_search
  log "SEARCH #{search.join ' '}"
  uids = imap.search search

  return {} if uids.empty?

  payload = imap.fetch(uids, 'BODY.PEEK[HEADER.FIELDS (DATE)]')

  mail = Hash[uids.zip(payload).map { |uid, m|
    date = m.attr["BODY[HEADER.FIELDS (DATE)]"].strip.split(/:\s*/, 2).last
    date = Time.parse(date) rescue Time.now
    [uid, date]
  }]

  mail.keys.group_by { |uid|
    date = mail[uid]
    [date.year, date.month]
  }
end