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