source: mailjam/mailjam/models.py@ 23:adc5b22efd7e

Last change on this file since 23:adc5b22efd7e was 23:adc5b22efd7e, checked in by Borja Lopez <borja@…>, 12 years ago

Added the first version of the CLI client, which implements a shell-like
interface where users can interact with a mailjam server.

This first versions adds no "big" features, but contains the basis to build
a complete shell interface (including history saving support, completion,
help for commands, etc)

Added a custom configuration file (conf/mailjam-cli.conf) for the CLI
client.

Added a new mailjam.config class (CLIClientConfig) that is used by the CLI
client to load its configuration file.

Updated the package information (setup.py, MANIFEST) to include the CLI
client data.

Modified the behaviour of the XMLRPC methods registered in the *XMLRPC classes
within the daemon module. Now instead of raising exceptions directly, they
catch such exceptions, returning only a string representation of the error
to the XMLRPC client. If there is no error, a nice "ok" message is returned.

File size: 3.9 KB
Line 
1# -*- coding: utf-8 -*-
2
3"""
4The mailjam project - models.py
5
6This file is released under the BSD license, see LICENSE for
7more information.
8
9Francisco de Borja Lopez Rio - <borja@codigo23.net>
10Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
11"""
12
13import os
14from tools import validate_email_address
15from storage import JsonStorage as Storage
16import config
17
18class Member():
19
20 """
21 Class that defines a mailing list member
22 """
23
24 def __init__(self, address):
25 self.address = self._validate_address(address)
26
27 def __repr__(self):
28 return "<Member '%s'>" % self.address
29
30 def __str__(self):
31 return self.address
32
33 def _validate_address(self, address):
34 if not validate_email_address(address):
35 raise ValueError(str(address) + ' is not a valid email address')
36 return address
37
38
39class MailingList():
40
41 """
42 Class that defines a mailing list
43 """
44
45 def __init__(self, name, address, members={}, configfile=None):
46 self.configfile = configfile
47 self.storage_config = config.get_config_parameters('storage',
48 configfile)
49 self.archive_config = config.get_config_parameters('archive',
50 configfile)
51 self.mailing_config = config.get_config_parameters('mailing_lists',
52 configfile)
53 self.name = name
54 self.address = address
55 self.members = members
56
57 def __repr__(self):
58 return "<MailingList '%s'>" % self.address
59
60 def __str__(self):
61 return self.address
62
63 def _validate_member_object(self, member=None):
64 if not isinstance(member, Member):
65 raise TypeError(str(member) + ' is not a valid Member instance')
66 return member
67
68 def _validate_member(self, member=None):
69 member = self._validate_member_object(member)
70 return member.address in self.members_addresses()
71
72 def _validate_member_by_address(self, address=None):
73 if not validate_email_address(address):
74 raise ValueError(str(address) + ' is not a valid email address')
75 return address in self.members_addresses()
76
77 @property
78 def storage(self):
79 return Storage(os.path.join(self.storage_config['path'], self.address))
80
81 @property
82 def archive(self):
83 return Storage(os.path.join(self.archive_config['path'], self.address))
84
85 def members_addresses(self):
86 return self.members.keys()
87
88 def add_member(self, member):
89 member = self._validate_member_object(member)
90 if self._validate_member(member):
91 return False
92 self.members[member.address] = member
93 return True
94
95 def add_member_by_address(self, address=None):
96 if self._validate_member_by_address(address):
97 return False
98 member = Member(address)
99 self.members[address] = member
100 return True
101
102 def delete_member(self, member=None):
103 member = self._validate_member_object(member)
104 if not self._validate_member(member):
105 return False
106 del self.members[member.address]
107 return True
108
109 def info(self):
110 """
111 Returns a dict we can use to add this mailing list to a mailjam
112 instance
113 """
114 # FIXME: This code could be replaced with something that
115 # automagically generates the dict from the instance attributes
116 return {'name': self.name, 'address': self.address,
117 'members': self.members, 'configfile': self.configfile}
118
119 def load(self):
120 if self.storage.exists():
121 data = self.storage.read()
122 self.name = data.name
123 self.address = data.address
124 self.members = data.members
125 return True
126 return False
127
128 def save(self):
129 self.storage.write(self)
Note: See TracBrowser for help on using the repository browser.