Convert DovecotMailstore to a plugin, and generalize the main mailshears script to...
[mailshears.git] / src / dovecot_mailstore.rb
1 require 'src/errors'
2 require 'src/filesystem'
3 require 'src/mailstore'
4
5 class DovecotMailstore < Mailstore
6
7 def initialize
8 @domain_root = Configuration::MAIL_ROOT
9 end
10
11 def describe_domain(domain)
12 return get_domain_path(domain)
13 end
14
15 def describe_account(account)
16 return get_account_path(account)
17 end
18
19 def delete_domain(domain)
20 domain_path = self.get_domain_path(domain)
21 FileUtils.rm_rf(domain_path)
22 end
23
24 def delete_account(account)
25 account_path = self.get_account_path(account)
26 FileUtils.rm_rf(account_path)
27 end
28
29 def get_leftover_domains(db_domains)
30 # Get the list of domains according to the filesystem.
31 fs_domains = self.get_domains_from_filesystem()
32
33 # Return the list of domains on the filesystem that aren't in the DB.
34 return (fs_domains - db_domains)
35 end
36
37 def get_leftover_accounts(db_accounts)
38 # Get the list of accounts according to the filesystem.
39 fs_domains = self.get_domains_from_filesystem()
40 fs_accounts = self.get_accounts_from_filesystem(fs_domains)
41
42 # And return the accounts on the filesystem that aren't in the DB.
43 return (fs_accounts - db_accounts)
44 end
45
46 protected;
47
48 def get_domains_from_filesystem()
49 return Filesystem.get_subdirs(@domain_root)
50 end
51
52 def get_accounts_from_filesystem(domains)
53 accounts = []
54
55 domains.each do |domain|
56 begin
57 # Throws a NonexistentDomainError if the domain's path
58 # doesn't exist on the filesystem. In this case, we want
59 # to report zero accounts.
60 domain_path = get_domain_path(domain)
61 usernames = Filesystem.get_subdirs(domain_path)
62
63 usernames.each do |username|
64 accounts << "#{username}@#{domain}"
65 end
66 rescue NonexistentDomainError => e
67 # Party hard.
68 end
69 end
70
71 return accounts
72 end
73
74
75 def get_domain_path(domain)
76 # Return the filesystem path for the given domain.
77 # That is, the directory where its mail is stored.
78 # Only works if the domain directory exists!
79 domain_path = File.join(@domain_root, domain)
80
81 if File.directory?(domain_path)
82 return domain_path
83 else
84 raise NonexistentDomainError.new(domain_path)
85 end
86 end
87
88
89 def get_account_path(account)
90 # Return the filesystem path of this account's mailbox.
91 # Only works if the account exists!
92 if not account.include?('@')
93 raise InvalidAccountError.new("#{account}: Accounts must contain an '@' symbol.")
94 end
95
96 account_parts = account.split('@')
97 user_part = account_parts[0]
98 domain_part = account_parts[1]
99
100 domain_path = get_domain_path(domain_part)
101 account_path = File.join(domain_path, user_part)
102
103 if File.directory?(account_path)
104 return account_path
105 else
106 raise NonexistentAccountError.new(account_path)
107 end
108 end
109
110 end