Class: Mailmate::SourceResolver
- Inherits:
-
Object
- Object
- Mailmate::SourceResolver
- Defined in:
- lib/mailmate/source_resolver.rb
Constant Summary collapse
- SPECIAL_DIRS =
Standard-mailbox name patterns. Each special UUID maps to one or more ‘*.mailbox` directories per account. Gmail nests system folders under `[Gmail]/…`; iCloud is flat with different names.
{ "INBOX" => ["INBOX.mailbox"], "DRAFTS" => ["[Gmail].mailbox/Drafts.mailbox", "Drafts.mailbox"], "SENT" => ["[Gmail].mailbox/Sent Mail.mailbox", "Sent Messages.mailbox"], "ARCHIVE" => ["[Gmail].mailbox/Archive.mailbox", "Archive.mailbox"], "JUNK" => ["[Gmail].mailbox/Spam.mailbox", "Junk.mailbox"], "TRASH" => ["[Gmail].mailbox/Trash.mailbox", "Deleted Messages.mailbox"], }.freeze
- ALL_MESSAGES_EXCLUDES =
ALL_MESSAGES: union of INBOX/SENT/DRAFTS/ARCHIVE plus any custom labels. Excludes Trash/Junk (per MailMate help: “All Messages” is everything except deleted/junk).
%r{/(?:Trash|Junk|Spam|Deleted Messages)\.mailbox/Messages/?\z}.freeze
Instance Method Summary collapse
- #all_message_dirs ⇒ Object
-
#initialize(graph) ⇒ SourceResolver
constructor
A new instance of SourceResolver.
- #per_account_dirs(suffixes) ⇒ Object
-
#resolve(spec) ⇒ Object
Resolve a mailbox spec to filters:.
- #special_dirs(uuid) ⇒ Object
Constructor Details
#initialize(graph) ⇒ SourceResolver
Returns a new instance of SourceResolver.
31 32 33 |
# File 'lib/mailmate/source_resolver.rb', line 31 def initialize(graph) @graph = graph end |
Instance Method Details
#all_message_dirs ⇒ Object
86 87 88 89 90 |
# File 'lib/mailmate/source_resolver.rb', line 86 def Dir.glob("#{Mailmate.config.imap_root}/*/**/Messages") .select { |p| File.directory?(p) } .reject { |p| p =~ ALL_MESSAGES_EXCLUDES } end |
#per_account_dirs(suffixes) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/mailmate/source_resolver.rb', line 92 def per_account_dirs(suffixes) result = [] Dir.glob("#{Mailmate.config.imap_root}/*").each do |account| next unless File.directory?(account) suffixes.each do |suffix| d = "#{account}/#{suffix}/Messages" result << d if File.directory?(d) end end result end |
#resolve(spec) ⇒ Object
Resolve a mailbox spec to filters:. ‘spec` may be a UUID, a name, or a special UUID literal. Returns:
:dirs => Array<String> of absolute paths to `Messages/` directories
:filters => Array<String> of filter expressions to AND together
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/mailmate/source_resolver.rb', line 40 def resolve(spec) filters = [] uuid = spec visited = [] loop do raise ArgumentError, "Cycle in mailbox resolution: #{visited.inspect}" if visited.include?(uuid) visited << uuid m = @graph.by_uuid[uuid] || @graph.by_uuid[@graph.by_name[uuid]] # Collect this node's filter (if it has one). The special UUIDs # FLAGGED / SENT / etc. can themselves be smart mailboxes (e.g. # Brian's "Flagged" with filter `#flags.flag = '\Flagged'`); the # filter has to be picked up before we resolve the special to dirs. filters << m[:filter] if m && m[:filter] next_uuid = m && m[:set] # If `set` points elsewhere, walk to it (handles nested smart mailboxes). if next_uuid && next_uuid != uuid uuid = next_uuid next end # Terminal — resolve to on-disk dirs. if MailboxGraph::SPECIAL_UUIDS.include?(uuid) return { dirs: special_dirs(uuid), filters: filters } end raise ArgumentError, "Mailbox #{spec.inspect} can't be resolved to disk paths " \ "(uuid=#{uuid}, name=#{m && m[:name].inspect})" end end |
#special_dirs(uuid) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/mailmate/source_resolver.rb', line 74 def special_dirs(uuid) case uuid when "ALL_MESSAGES" when "INBOX", "DRAFTS", "SENT", "ARCHIVE", "JUNK", "TRASH" per_account_dirs(SPECIAL_DIRS[uuid]) else # Unknown special — return empty list and let the caller fail loudly. [] end end |