diff options
| author | Barry Warsaw | 2007-06-09 15:20:32 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2007-06-09 15:20:32 -0400 |
| commit | 3231fd628f6eea30bd6e2be56eb419ed0008d954 (patch) | |
| tree | 176f80a7b4f72c410e30ab9ba3e3fe2deb1bb1fe /Mailman/database/model/mailinglist.py | |
| parent | e5c04e2a93a58d799dd3940a7935853eb1f2e3e4 (diff) | |
| download | mailman-3231fd628f6eea30bd6e2be56eb419ed0008d954.tar.gz mailman-3231fd628f6eea30bd6e2be56eb419ed0008d954.tar.zst mailman-3231fd628f6eea30bd6e2be56eb419ed0008d954.zip | |
Implement the new, simplified membership model. Rosters and RosterSets as
they were previously known are now gone. Rosters, rather than being a
database entity that collects users, is now just a filter on the member
database. This way, we can use generic rosters to search for regular members,
digest members, owners, or moderators. More advanced rosters can do all kinds
of other membership queries. But rosters no longer need to be a database
entity.
Users have a name, password, optional preferences, and a set of addresses, but
users are not subscribed to mailing lists.
Addresses have the email address, some verification information, and optional
preferences.
Members tie an address to a mailing list, through a role, with optional
preferences.
Other changes here include:
MailList.fqdn_listname() moved to the MailingList model entity.
Added MemberRole enum and SystemDefaultPreferences to Mailman.constants.
Profiles are renamed to Preferences (same with the interface), but the files
are not yet moved. This happens later.
We mostly don't need has_*() relationships on the entity classes, because we
generally don't need the reverse relationship. Use belongs_to() because that
creates the foreign key, even though the wording seems counter intuitive.
IAddress.subscribe() added.
Tell Elixir to use shortnames for all tables.
Remove the OldStyleMembership fields from MailingList.
Remove all the interface elements and database fields that talk about rosters
and rostersets.
Convert Version entity to has_field().
Diffstat (limited to 'Mailman/database/model/mailinglist.py')
| -rw-r--r-- | Mailman/database/model/mailinglist.py | 122 |
1 files changed, 14 insertions, 108 deletions
diff --git a/Mailman/database/model/mailinglist.py b/Mailman/database/model/mailinglist.py index 28e2c11dc..edd2eab0d 100644 --- a/Mailman/database/model/mailinglist.py +++ b/Mailman/database/model/mailinglist.py @@ -50,16 +50,6 @@ class MailingList(Entity): has_field('one_last_digest', PickleType), has_field('volume', Integer), has_field('last_post_time', Float), - # OldStyleMemberships attributes, temporarily stored as pickles. - has_field('bounce_info', PickleType), - has_field('delivery_status', PickleType), - has_field('digest_members', PickleType), - has_field('language', PickleType), - has_field('members', PickleType), - has_field('passwords', PickleType), - has_field('topics_userinterest', PickleType), - has_field('user_options', PickleType), - has_field('usernames', PickleType), # Attributes which are directly modifiable via the web u/i. The more # complicated attributes are currently stored as pickles, though that # will change as the schema and implementation is developed. @@ -163,113 +153,29 @@ class MailingList(Entity): has_field('umbrella_member_suffix', Unicode), has_field('unsubscribe_policy', Integer), has_field('welcome_msg', Unicode), - # Indirect relationships - has_field('owner_rosterset', Unicode), - has_field('moderator_rosterset', Unicode), # Relationships ## has_and_belongs_to_many( ## 'available_languages', ## of_kind='Mailman.database.model.languages.Language') + # Options + using_options(shortnames=True) def __init__(self, fqdn_listname): super(MailingList, self).__init__() listname, hostname = split_listname(fqdn_listname) self.list_name = listname self.host_name = hostname - # Create two roster sets, one for the owners and one for the - # moderators. MailingLists are connected to RosterSets indirectly, in - # order to preserve the ability to store user data and list data in - # different databases. - name = fqdn_listname + ' owners' - self.owner_rosterset = name - roster = config.user_manager.create_roster(name) - config.user_manager.create_rosterset(name).add(roster) - name = fqdn_listname + ' moderators' - self.moderator_rosterset = name - roster = config.user_manager.create_roster(name) - config.user_manager.create_rosterset(name).add(roster) - - def delete_rosters(self): - listname = fqdn_listname(self.list_name, self.host_name) - # Delete the list owner roster and roster set. - name = listname + ' owners' - roster = config.user_manager.get_roster(name) - assert roster, 'Missing roster: %s' % name - config.user_manager.delete_roster(roster) - rosterset = config.user_manager.get_rosterset(name) - assert rosterset, 'Missing roster set: %s' % name - config.user_manager.delete_rosterset(rosterset) - name = listname + ' moderators' - roster = config.user_manager.get_roster(name) - assert roster, 'Missing roster: %s' % name - config.user_manager.delete_roster(roster) - rosterset = config.user_manager.get_rosterset(name) - assert rosterset, 'Missing roster set: %s' % name - config.user_manager.delete_rosterset(rosterset) - - # IMailingListRosters + # Create several rosters for filtering out or querying the membership + # table. + from Mailman.database.model import roster + self.owners = roster.OwnerRoster(self) + self.moderators = roster.ModeratorRoster(self) + self.administrators = roster.AdministratorRoster(self) + self.members = roster.MemberRoster(self) + self.regular_members = roster.RegularMemberRoster(self) + self.digest_members = roster.DigestMemberRoster(self) @property - def owners(self): - for user in _collect_users(self.owner_rosterset): - yield user - - @property - def moderators(self): - for user in _collect_users(self.moderator_rosterset): - yield user - - @property - def administrators(self): - for user in _collect_users(self.owner_rosterset, - self.moderator_rosterset): - yield user - - @property - def owner_rosters(self): - rosterset = config.user_manager.get_rosterset(self.owner_rosterset) - for roster in rosterset.rosters: - yield roster - - @property - def moderator_rosters(self): - rosterset = config.user_manager.get_rosterset(self.moderator_rosterset) - for roster in rosterset.rosters: - yield roster - - def add_owner_roster(self, roster): - rosterset = config.user_manager.get_rosterset(self.owner_rosterset) - rosterset.add(roster) - - def delete_owner_roster(self, roster): - rosterset = config.user_manager.get_rosterset(self.owner_rosterset) - rosterset.delete(roster) - - def add_moderator_roster(self, roster): - rosterset = config.user_manager.get_rosterset(self.moderator_rosterset) - rosterset.add(roster) - - def delete_moderator_roster(self, roster): - rosterset = config.user_manager.get_rosterset(self.moderator_rosterset) - rosterset.delete(roster) - - - -def _collect_users(*rosterset_names): - users = set() - for name in rosterset_names: - # We have to indirectly look up the roster set's name in the user - # manager. This is how we enforce separation between the list manager - # and the user manager storages. - rosterset = config.user_manager.get_rosterset(name) - assert rosterset is not None, 'No RosterSet named: %s' % name - for roster in rosterset.rosters: - # Rosters collect addresses. It's not required that an address is - # linked to a user, but it must be the case that all addresses on - # the owner roster are linked to a user. Get the user that's - # linked to each address and add it to the set. - for address in roster.addresses: - user = config.user_manager.get_user(address.address) - assert user is not None, 'Unlinked address: ' + address.address - users.add(user) - return users + def fqdn_listname(self): + """See IMailingListIdentity.""" + return fqdn_listname(self.list_name, self.host_name) |
