Author: adc Date: Mon Jun 30 17:35:36 2014 New Revision: 1606846 URL: http://svn.apache.org/r1606846 Log: moderator command now "talks" to hermes
Or will talk to hermes once the WSGI api is set up. Added: labs/panopticon/pan-utils/src/asf/data/lists.py labs/panopticon/pan-utils/tests/test_lists.py Modified: labs/panopticon/pan-commands/bin/moderator labs/panopticon/pan-utils/src/asf/utils/test.py Modified: labs/panopticon/pan-commands/bin/moderator URL: http://svn.apache.org/viewvc/labs/panopticon/pan-commands/bin/moderator?rev=1606846&r1=1606845&r2=1606846&view=diff ============================================================================== --- labs/panopticon/pan-commands/bin/moderator (original) +++ labs/panopticon/pan-commands/bin/moderator Mon Jun 30 17:35:36 2014 @@ -20,21 +20,21 @@ """ Mailing list moderator tool used to manage mailing lists from the command line. """ -import argparse -import sys +import restkit from asf.cli import entrypoint -from asf.data.aliases import get_mail_aliases -from asf.utils.committers import get_committer +from asf.data import aliases +from asf.data import lists +from asf.utils import committers from asf.utils.emails import email_from_alias, is_apache_email_address, username_from_apache_email def cmd_lookup(args): - mail_aliases = get_mail_aliases(args.username, args.password) + mail_aliases = aliases.get_mail_aliases(args.username, args.password) email_alias = args.email_alias asf_email = email_alias if is_apache_email_address(email_alias) else email_from_alias(email_alias, mail_aliases) if asf_email: - committer = get_committer(username_from_apache_email(asf_email), args.username, args.password) + committer = committers.get_committer(username_from_apache_email(asf_email), args.username, args.password) if committer: print committer.fullname, '-', committer.username if committer.member: @@ -60,22 +60,46 @@ def cmd_lookup(args): def cmd_add(args): - print 'Email list additions is not supported yet' + try: + if args.moderator: + lists.add_ezmlm_moderator(args.mailing_list, args.email_address, args.username, args.password) + else: + lists.add_ezmlm_subscriber(args.mailing_list, args.email_address, args.username, args.password) + + print 'Added %s to %s' % ('moderator %s' % args.email_address if args.moderator else args.email_address, args.mailing_list) + except restkit.ResourceNotFound: + print 'Mailing list %s not found' % args.mailing_list def cmd_remove(args): - print 'Email list removals is not supported yet' + try: + if args.moderator: + lists.remove_ezmlm_moderator(args.mailing_list, args.email_address, args.username, args.password) + else: + lists.remove_ezmlm_subscriber(args.mailing_list, args.email_address, args.username, args.password) + + print 'Removed %s to %s' % ('moderator %s' % args.email_address if args.moderator else args.email_address, args.mailing_list) + except restkit.ResourceNotFound: + print 'Mailing list %s not found' % args.mailing_list def cmd_list(args): - print 'd...@mock.apache.org' - print 'u...@mock.apache.org' - print 'com...@mock.apache.org' + for address, groups in lists.get_ezmlm_lists().iteritems(): + for group in groups: + print group + '@' + address def cmd_members(args): - print 'john....@gmail.com' - print 'jane....@gmail.com*' + try: + if args.moderator: + members = lists.get_ezmlm_moderators(args.mailing_list, args.username, args.password) + else: + members = lists.get_ezmlm_subscribers(args.mailing_list, args.username, args.password) + + for member in members: + print member + except restkit.ResourceNotFound: + print 'Mailing list %s not found' % args.mailing_list @entrypoint @@ -93,11 +117,13 @@ def main(cli): add_parser = subparsers.add_parser('add', description='Add an email address to a mailing list') add_parser.add_argument('mailing_list', help='The mailing list that the email address is attempting to join') add_parser.add_argument('email_address', help='The email address to add') + add_parser.add_argument('-m', '--moderator', default=False, action='store_true', help='Email address is for moderator') add_parser.set_defaults(func=cmd_add) remove_parser = subparsers.add_parser('remove', description='Remove an email address to a mailing list') remove_parser.add_argument('mailing_list', help='The mailing list that the email address is being removed from') remove_parser.add_argument('email_address', help='The email address to remove') + remove_parser.add_argument('-m', '--moderator', default=False, action='store_true', help='Email address is for moderator') remove_parser.set_defaults(func=cmd_remove) list_parser = subparsers.add_parser('list', description='List the ASF mailing lists') @@ -105,6 +131,7 @@ def main(cli): list_parser = subparsers.add_parser('members', description='List the members of a mailing list') list_parser.add_argument('mailing_list', help='The mailing list whose membership is to be listed') + list_parser.add_argument('-m', '--moderator', default=False, action='store_true', help='List moderators of mailing list') list_parser.set_defaults(func=cmd_members) with cli.run(): Added: labs/panopticon/pan-utils/src/asf/data/lists.py URL: http://svn.apache.org/viewvc/labs/panopticon/pan-utils/src/asf/data/lists.py?rev=1606846&view=auto ============================================================================== --- labs/panopticon/pan-utils/src/asf/data/lists.py (added) +++ labs/panopticon/pan-utils/src/asf/data/lists.py Mon Jun 30 17:35:36 2014 @@ -0,0 +1,103 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +import json +import urlparse + +from restkit import Resource + + +EZMLM_URL = 'http://hermes.apache.org/ezmlm/' + + +def get_ezmlm_lists(): + """ Obtain a dictionary of ASF addresses and their lists + :return: a dictionary of ASF addresses and their lists + """ + ezmlm_lists_url = urlparse.urljoin(EZMLM_URL, 'v1/public/lists') + return json.load(Resource(ezmlm_lists_url).get().body_stream()) + + +def get_ezmlm_subscribers(mailing_list, username, password): + """ Obtain the list of subscriber emails belonging to a particular mailing list + :param mailing_list: the mailing list that the subscribers belong to + :param username: the username to use to obtain the list of mailing list subscribers + :param password: the password for the username + :return: the list of subscriber emails + """ + ezmlm_lists_url = urlparse.urljoin(EZMLM_URL, 'v1/asf/lists/%s/subscribers' % mailing_list) + return json.load(Resource(ezmlm_lists_url).get().body_stream())['subscribers'] + + +def get_ezmlm_moderators(mailing_list, username, password): + """ Obtain the list of moderator emails belonging to a particular mailing list + :param mailing_list: the mailing list that the moderators belong to + :param username: the username to use to obtain the list of mailing list moderators + :param password: the password for the username + :return: the list of moderator emails + """ + ezmlm_lists_url = urlparse.urljoin(EZMLM_URL, 'v1/asf/lists/%s/moderators' % mailing_list) + return json.load(Resource(ezmlm_lists_url).get().body_stream())['moderators'] + + +def add_ezmlm_subscriber(mailing_list, address, username, password): + """ Add a subscriber email address to a particular mailing list + :param mailing_list: the mailing list that the subscribers belong to + :param address: the email address to add to the mailing list + :param username: the username to use to manage the list of mailing list subscribers + :param password: the password for the username + :return: the list of subscriber emails + """ + ezmlm_lists_url = urlparse.urljoin(EZMLM_URL, 'v1/asf/lists/%s/subscribers/%s' % (mailing_list, address)) + return json.load(Resource(ezmlm_lists_url).put().body_stream())['added'] + + +def add_ezmlm_moderator(mailing_list, address, username, password): + """ Add a moderator email address to a particular mailing list + :param mailing_list: the mailing list that the moderators belong to + :param address: the email address to add to the mailing list moderators + :param username: the username to use to manage the list of mailing list moderators + :param password: the password for the username + :return: the list of moderator emails + """ + ezmlm_lists_url = urlparse.urljoin(EZMLM_URL, 'v1/asf/lists/%s/moderators/%s' % (mailing_list, address)) + return json.load(Resource(ezmlm_lists_url).put().body_stream())['added'] + + +def remove_ezmlm_subscriber(mailing_list, address, username, password): + """ Remove a subscriber email address to a particular mailing list + :param mailing_list: the mailing list that the subscribers belong to + :param address: the email address to remove from the mailing list + :param username: the username to use to manage the list of mailing list subscribers + :param password: the password for the username + :return: the list of subscriber emails + """ + ezmlm_lists_url = urlparse.urljoin(EZMLM_URL, 'v1/asf/lists/%s/subscribers/%s' % (mailing_list, address)) + return json.load(Resource(ezmlm_lists_url).delete().body_stream())['removed'] + + +def remove_ezmlm_moderator(mailing_list, address, username, password): + """ Remove a moderator email address to a particular mailing list + :param mailing_list: the mailing list that the moderators belong to + :param address: the email address to remove from the mailing list moderators + :param username: the username to use to manage the list of mailing list moderators + :param password: the password for the username + :return: the list of moderator emails + """ + ezmlm_lists_url = urlparse.urljoin(EZMLM_URL, 'v1/asf/lists/%s/moderators/%s' % (mailing_list, address)) + return json.load(Resource(ezmlm_lists_url).delete().body_stream())['removed'] Modified: labs/panopticon/pan-utils/src/asf/utils/test.py URL: http://svn.apache.org/viewvc/labs/panopticon/pan-utils/src/asf/utils/test.py?rev=1606846&r1=1606845&r2=1606846&view=diff ============================================================================== --- labs/panopticon/pan-utils/src/asf/utils/test.py (original) +++ labs/panopticon/pan-utils/src/asf/utils/test.py Mon Jun 30 17:35:36 2014 @@ -17,10 +17,11 @@ # under the License. # import ConfigParser -import gnupg +import gnupg import pytest -from asf.data import ldap + +from asf.data import ldap, lists from asf.utils.auth import get_stored_credentials from asf.utils.file import temp_directory @@ -60,3 +61,15 @@ def test_gpg(): ensure_gpg = pytest.mark.skipif(test_gpg(), reason="Need to ensure that gpg is available") + + +def test_hermes(): + try: + lists.get_ezmlm_lists() + return False + except Exception: + return True + + +ensure_hermes = pytest.mark.skipif(test_hermes(), + reason="Hermes is not up") Added: labs/panopticon/pan-utils/tests/test_lists.py URL: http://svn.apache.org/viewvc/labs/panopticon/pan-utils/tests/test_lists.py?rev=1606846&view=auto ============================================================================== --- labs/panopticon/pan-utils/tests/test_lists.py (added) +++ labs/panopticon/pan-utils/tests/test_lists.py Mon Jun 30 17:35:36 2014 @@ -0,0 +1,63 @@ +import pytest +import restkit + +from asf.data import lists +from asf.utils import test + + +@test.ensure_hermes +def test_get_ezmlm_lists(): + print lists.get_ezmlm_lists() + + +@test.ensure_hermes +@test.ensure_credentials_stored +def test_get_ezmlm_subscribers(username, password): + print lists.get_ezmlm_subscribers('d...@mrql.apache.org', username, password) + + +@test.ensure_hermes +@test.ensure_credentials_stored +def test_get_ezmlm_subscribers_errors(username, password): + with pytest.raises(restkit.ResourceNotFound): + lists.get_ezmlm_subscribers('z...@mrql.apache.org', username, password) + with pytest.raises(restkit.ResourceNotFound): + lists.get_ezmlm_subscribers('d...@zmrql.apache.org', username, password) + with pytest.raises(restkit.RequestFailed): + lists.get_ezmlm_subscribers('dev.mrql.apache.org', username, password) + + +@test.ensure_hermes +def test_get_ezmlm_subscribers_unauthorized(): + with pytest.raises(restkit.Unauthorized): + lists.get_ezmlm_subscribers('dev.mrql.apache.org', 'BAD_USER', 'BAD_PASSWORD') + + +@test.ensure_hermes +@test.ensure_credentials_stored +def test_get_ezmlm_moderators(username, password): + print lists.get_ezmlm_moderators('d...@mrql.apache.org', username, password) + + +@test.ensure_hermes +@test.ensure_credentials_stored +def test_add_ezmlm_subscribers(username, password): + print lists.add_ezmlm_subscriber('d...@mrql.apache.org', 'a...@apache.org', username, password) + + +@test.ensure_hermes +@test.ensure_credentials_stored +def test_add_ezmlm_moderators(username, password): + print lists.add_ezmlm_moderator('d...@mrql.apache.org', 'a...@apache.org', username, password) + + +@test.ensure_hermes +@test.ensure_credentials_stored +def test_remove_ezmlm_subscribers(username, password): + print lists.remove_ezmlm_subscriber('d...@mrql.apache.org', 'a...@apache.org', username, password) + + +@test.ensure_hermes +@test.ensure_credentials_stored +def test_remove_ezmlm_moderators(username, password): + print lists.remove_ezmlm_moderator('d...@mrql.apache.org', 'a...@apache.org', username, password) --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@labs.apache.org For additional commands, e-mail: commits-h...@labs.apache.org