Barry Warsaw pushed to branch master at mailman / Mailman
Commits:
5a6344a8 by Aurélien Bompard at 2016-01-13T19:36:29-05:00
Allow fuzz search for members in SubscriptionService
- - - - -
bbe2a437 by Aurélien Bompard at 2016-01-13T19:36:29-05:00
Member search can be done using GET requests
- - - - -
a4ebbd16 by Barry Warsaw at 2016-01-13T19:49:16-05:00
Add NEWS and tweak.
- - - - -
6 changed files:
- src/mailman/docs/NEWS.rst
- src/mailman/interfaces/subscriptions.py
- src/mailman/model/docs/subscriptions.rst
- src/mailman/model/subscriptions.py
- src/mailman/rest/docs/membership.rst
- src/mailman/rest/members.py
Changes:
=====================================
src/mailman/docs/NEWS.rst
=====================================
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -79,6 +79,8 @@ Interfaces
same algorithm. (Closes #118)
* ``IMessageStore.delete_message()`` no longer raises a ``LookupError`` when
you attempt to delete a nonexistent message from the message store.
+ * ``ISubscriptionService.find_members()`` accepts asterisks as wildcards in
+ the ``subscriber`` argument string. Given by Aurélien Bompard.
Internal API
------------
@@ -133,6 +135,8 @@ REST
given action.
* Global and list-centric bans can now be managed through the REST API.
Given by Aurélien Bompard.
+ * ``<api>/members/find`` accepts GET query parameters in addition to POST
+ arguments. Given by Aurélien Bompard.
Other
-----
=====================================
src/mailman/interfaces/subscriptions.py
=====================================
--- a/src/mailman/interfaces/subscriptions.py
+++ b/src/mailman/interfaces/subscriptions.py
@@ -110,7 +110,8 @@ class ISubscriptionService(Interface):
list.
:param subscriber: The email address or user id of the user getting
- subscribed.
+ subscribed. This argument may contain asterisks, which will be
+ interpreted as wildcards in the search pattern.
:type subscriber: string or int
:param list_id: The list id of the mailing list to search for the
subscriber's memberships on.
=====================================
src/mailman/model/docs/subscriptions.rst
=====================================
--- a/src/mailman/model/docs/subscriptions.rst
+++ b/src/mailman/model/docs/subscriptions.rst
@@ -105,6 +105,22 @@ There may be no matching memberships.
>>> list(service.find_members('[email protected]'))
[]
+The address may contain asterisks, which will be interpreted as a wildcard in
+the search pattern.
+
+ >>> for member in service.find_members('*person*'):
+ ... print(member)
+ <Member: Anne Person <[email protected]>
+ on [email protected] as MemberRole.member>
+ <Member: Anne Person <[email protected]>
+ on [email protected] as MemberRole.owner>
+ <Member: Bart Person <[email protected]>
+ on [email protected] as MemberRole.moderator>
+ <Member: Bart Person <[email protected]>
+ on [email protected] as MemberRole.owner>
+ <Member: Cris Person <[email protected]>
+ on [email protected] as MemberRole.member>
+
Memberships can also be searched for by user id.
>>> for member in service.find_members(anne_1.user.user_id):
=====================================
src/mailman/model/subscriptions.py
=====================================
--- a/src/mailman/model/subscriptions.py
+++ b/src/mailman/model/subscriptions.py
@@ -94,10 +94,18 @@ class SubscriptionService:
if subscriber is not None:
if isinstance(subscriber, str):
# subscriber is an email address.
- q_address = q_address.filter(
- Address.email == subscriber.lower())
- q_user = q_user.join(User.addresses).filter(
- Address.email == subscriber.lower())
+ subscriber = subscriber.lower()
+ if '*' in subscriber:
+ subscriber = subscriber.replace('*', '%')
+ q_address = q_address.filter(
+ Address.email.like(subscriber))
+ q_user = q_user.join(User.addresses).filter(
+ Address.email.like(subscriber))
+ else:
+ q_address = q_address.filter(
+ Address.email == subscriber)
+ q_user = q_user.join(User.addresses).filter(
+ Address.email == subscriber)
else:
# subscriber is a user id.
q_address = q_address.join(Address.user).filter(
=====================================
src/mailman/rest/docs/membership.rst
=====================================
--- a/src/mailman/rest/docs/membership.rst
+++ b/src/mailman/rest/docs/membership.rst
@@ -626,6 +626,28 @@ Finally, we can search for a specific member given all
three criteria.
start: 0
total_size: 1
+Search can also be performed using HTTP GET queries.
+
+ >>> dump_json('http://localhost:9001/3.0/members/find'
+ ... '[email protected]'
+ ... '&list_id=bee.example.com'
+ ... '&role=member'
+ ... )
+ entry 0:
+ address: http://localhost:9001/3.0/addresses/[email protected]
+ delivery_mode: regular
+ email: [email protected]
+ http_etag: ...
+ list_id: bee.example.com
+ member_id: 2
+ moderation_action: defer
+ role: member
+ self_link: http://localhost:9001/3.0/members/2
+ user: http://localhost:9001/3.0/users/2
+ http_etag: ...
+ start: 0
+ total_size: 1
+
Joining a mailing list
======================
=====================================
src/mailman/rest/members.py
=====================================
--- a/src/mailman/rest/members.py
+++ b/src/mailman/rest/members.py
@@ -356,19 +356,32 @@ class _FoundMembers(MemberCollection):
class FindMembers(_MemberBase):
"""/members/find"""
+ def on_get(self, request, response):
+ return self._find(request, response)
+
def on_post(self, request, response):
+ return self._find(request, response)
+
+ def _find(self, request, response):
"""Find a member"""
service = getUtility(ISubscriptionService)
validator = Validator(
list_id=str,
subscriber=str,
role=enum_validator(MemberRole),
- _optional=('list_id', 'subscriber', 'role'))
+ # Allow pagination.
+ page=int,
+ count=int,
+ _optional=('list_id', 'subscriber', 'role', 'page', 'count'))
try:
data = validator(request)
except ValueError as error:
bad_request(response, str(error))
else:
+ # Remove any optional pagination query elements; they will be
+ # handled later.
+ data.pop('page', None)
+ data.pop('count', None)
members = service.find_members(**data)
resource = _FoundMembers(members, self.api)
okay(response, etag(resource._make_collection(request)))
View it on GitLab:
https://gitlab.com/mailman/mailman/compare/95446742669349777ee4101237a76395f1dfaa87...a4ebbd164bdba4a7ede651dfcf802c300e8e9743
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe:
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org