diff --git a/mailmanclient/__init__.py b/mailmanclient/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/mailmanclient/__init__.py +++ /dev/null diff --git a/mailmanclient/rest.py b/mailmanclient/rest.py deleted file mode 100644 index dd82ec3..0000000 --- a/mailmanclient/rest.py +++ /dev/null @@ -1,393 +0,0 @@ -# Copyright (C) 2010 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman is free software: you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# GNU Mailman. If not, see . - -"""A client library for the Mailman REST API.""" - - -from __future__ import absolute_import, unicode_literals - -__metaclass__ = type -__all__ = [ - 'MailmanRESTClient', - 'MailmanRESTClientError', - ] - - -import re -import json -import os.path - -from base64 import b64encode -from httplib2 import Http -from operator import itemgetter -from urllib import urlencode -from urllib2 import HTTPError - - -class MailmanRESTClientError(Exception): - """An exception thrown by the Mailman REST API client.""" - - -class MailmanRESTClient(): - """A wrapper for the Mailman REST API.""" - - def __init__(self, host, username, password): - """Check and modify the host name. Also, try to parse a config file to - get the API credentials. - - :param host: the host name of the REST API - :type host: string - :param username: auth user name for the rest api - :type: username: string - :param password: pwd for the rest api - :type: password: string - :return: a MailmanRESTClient object - :rtype: objectFirst line should - """ - self.host = host - self.username = username - self.password = password - # If there is a trailing slash remove it - if self.host[-1] == '/': - self.host = self.host[:-1] - # If there is no protocol, fall back to http:// - if self.host[0:4] != 'http': - self.host = 'http://' + self.host - - def __repr__(self): - return '' % self.host - - def _http_request(self, path, data=None, method=None): - """Send an HTTP request. - - :param path: the path to send the request to - :type path: string - :param data: POST oder PUT data to send - :type data: dict - :param method: the HTTP method; defaults to GET or POST (if - data is not None) - :type method: string - :return: the request content or a status code, depending on the - method and if the request was successful - :rtype: int, list or dict - """ - url = self.host + path - # Include general header information - headers = { - 'User-Agent': 'MailmanRESTClient', - 'Accept': 'text/plain', - } - if data is not None: - data = urlencode(data, doseq=True) - headers['Content-type'] = "application/x-www-form-urlencoded" - if method is None: - if data is None: - method = 'GET' - else: - method = 'POST' - method = method.upper() - basic_auth = '{0}:{1}'.format(self.username, self.password) - headers['Authorization'] = 'Basic ' + b64encode(basic_auth) - response, content = Http().request(url, method, data, headers) - - if method == 'GET': - if response.status // 100 != 2: - raise HTTPError(url, response.status, content, response, None) - else: - return json.loads(content) - else: - return response.status - - def create_domain(self, email_host): - """Create a domain and return a domain object. - - :param email_host: The host domain to create - :type email_host: string - :return: A domain object or a status code (if the create - request failed) - :rtype int or object - """ - data = { - 'email_host': email_host, - } - response = self._http_request('/3.0/domains', data, 'POST') - if response == 201: - return _Domain(self.host, self.username, self.password, email_host) - else: - return response - - def get_domain(self, email_host): - """Return a domain object. - - :param email_host: host domain - :type email_host: string - :rtype object - """ - return _Domain(self.host, self.username, self.password, email_host) - - def get_lists(self): - """Get a list of all mailing list. - - :return: a list of dicts with all mailing lists - :rtype: list - """ - response = self._http_request('/3.0/lists') - if 'entries' not in response: - return [] - else: - # Return a dict with entries sorted by fqdn_listname - return sorted(response['entries'], - key=itemgetter('fqdn_listname')) - - def get_list(self, fqdn_listname): - """Find and return a list object. - - :param fqdn_listname: the mailing list address - :type fqdn_listname: string - :rtype: object - """ - return _List(self.host, self.username, self.password, fqdn_listname) - - def get_members(self): - """Get a list of all list members. - - :return: a list of dicts with the members of all lists - :rtype: list - """ - response = self._http_request('/3.0/members') - if 'entries' not in response: - return [] - else: - return sorted(response['entries'], - key=itemgetter('self_link')) - - def get_member(self, email_address, fqdn_listname): - """Return a member object. - - :param email_adresses: the email address used - :type email_address: string - :param fqdn_listname: the mailing list - :type fqdn_listname: string - :return: a member object - :rtype: _Member - """ - return _Member(self.host, self.username, self.password, email_address, fqdn_listname) - - - def get_user(self, email_address): - """Find and return a user object. - - :param email_address: one of the user's email addresses - :type email: string: - :returns: a user object - :rtype: _User - """ - return _User(self.host, self.username, self.password, email_address) - - -class _Domain(MailmanRESTClient): - """A domain wrapper for the MailmanRESTClient.""" - - def __init__(self, host, username, password, email_host): - """Connect to host and get list information. - - :param host: the host name of the REST API - :type host: string - :param username: auth user name for the rest api - :type: username: string - :param password: pwd for the rest api - :type: password: string - :param email_host: host domain - :type email_host: string - :rtype: object - """ - super(_Domain, self).__init__(host, username, password) - self.info = self._http_request('/3.0/domains/' + email_host) - - def create_list(self, list_name): - """Create a mailing list and return a list object. - - :param list_name: the name of the list to be created - :type list_name: string - :rtype: object - """ - fqdn_listname = list_name + '@' + self.info['email_host'] - data = { - 'fqdn_listname': fqdn_listname - } - response = self._http_request('/3.0/lists', data, 'POST') - return _List(self.host, self.username, self.password, fqdn_listname) - - def delete_list(self, list_name): - fqdn_listname = list_name + '@' + self.info['email_host'] - return self._http_request('/3.0/lists/' + fqdn_listname, None, 'DELETE') - - -class _List(MailmanRESTClient): - """A mailing list wrapper for the MailmanRESTClient.""" - - def __init__(self, host, username, password, fqdn_listname): - """Connect to host and get list information. - - :param host: the host name of the REST API - :type host: string - :param username: auth user name for the rest api - :type: username: string - :param password: pwd for the rest api - :type: password: string - :param fqdn_listname: the mailing list address - :type fqdn_listname: string - :rtype: object - """ - super(_List, self).__init__(host, username, password) - self.info = self._http_request('/3.0/lists/' + fqdn_listname) - self.config = self._http_request('/3.0/lists/%s/config' % fqdn_listname) - - def subscribe(self, address, real_name=None): - """Add an address to a list. - - :param address: email address to add to the list. - :type address: string - :param real_name: the real name of the new member - :type real_name: string - """ - data = { - 'fqdn_listname': self.info['fqdn_listname'], - 'address': address, - 'real_name': real_name - } - return self._http_request('/3.0/members', data, 'POST') - - def unsubscribe(self, address): - """Unsubscribe an address to a list. - - :param address: email address to add to the list. - :type address: string - :param real_name: the real name of the new member - :type real_name: string - """ - return self._http_request('/3.0/lists/' + - self.info['fqdn_listname'] + - '/member/' + - address, - None, - 'DELETE') - - def get_members(self): - """Get a list of all list members. - - :return: a list of dicts with all members - :rtype: list - """ - response = self._http_request('/3.0/lists/' + - self.info['fqdn_listname'] + - '/roster/members') - if 'entries' not in response: - return [] - else: - return sorted(response['entries'], - key=itemgetter('self_link')) - - def get_member(self, email_address): - """Return a member object. - - :param email_adresses: the email address used - :type email_address: string - :param fqdn_listname: the mailing list - :type fqdn_listname: string - :return: a member object - :rtype: _Member - """ - return _Member(self.host, self.username, self.password, email_address, self.info['fqdn_listname']) - - def update_list(self, data): - """Update the settings for a list. - """ - return self._http_request('/3.0/lists/' + self.info['fqdn_listname'], - data, method='PATCH') - - def update_config(self, data): - """Update the list configuration. - - :param data: A dict with the config attributes to be updated. - :type data: dict - :return: the return code of the http request - :rtype: integer - """ - url = '/3.0/lists/%s/config' % self.info['fqdn_listname'] - status = self._http_request(url, data, 'PATCH') - if status == 200: - for key in data: - self.config[key] = data[key] - return status - - def __str__(self): - """A string representation of a list. - """ - return "A list object for the list '%s'." % self.info['fqdn_listname'] - - -class _Member(MailmanRESTClient): - """A user wrapper for the MailmanRESTClient.""" - - def __init__(self, host, username, password, email_address, fqdn_listname): - """Connect to host and get membership information. - - :param host: the host name of the REST API - :type host: string - :param username: auth user name for the rest api - :type: username: string - :param password: pwd for the rest api - :type: password: string - :param email_address: email address - :type email_address: string - :param fqdn_listname: the mailing list - :type fqdn_listname: string - :return: a member object - :rtype: _Member - """ - super(_Member, self).__init__(host, username, password) - # Create an info attribute to receive member info via the API. - # To be filled with actual data as soon as the API supports it. - self.info = {} - # Keep these values out of the info dict so info can be send - # back to the server without additional keys - self.email_address = email_address - self.fqdn_listname = fqdn_listname - self.info = self._http_request('/3.0/lists/%s/member/%s' % (fqdn_listname, email_address)) - - def unsubscribe(self, fqdn_listname): - url = '/3.0/lists/%s/member/%s' % (fqdn_listname, 'jack@example.com') - return self._http_request(url, None, 'DELETE') - - def update(self, data=None): - """Update member settings.""" - - # If data is None, use the info dict - if data is None: - data = self.info - - path = '/3.0/lists/%s/member/%s' % (self.fqdn_listname, - self.email_address) - return self._http_request(path, data, method='PATCH') - - def __str__(self): - """A string representation of a member.""" - - return "A member object for '%s', subscribed to '%s'." \ - % (self.email_address, self.fqdn_listname) - diff --git a/views.py b/views.py index ab48763..7a9dd54 100644 --- a/views.py +++ b/views.py @@ -22,9 +22,10 @@ from django.core.urlresolvers import reverse from django.utils.translation import gettext as _ import re -from mailmanclient.rest import MailmanRESTClient, MailmanRESTClientError +from mailman.client import Client from forms import * from settings import API_USER, API_PASS +import sys #Error handing info def login_required(fn): """ @@ -75,7 +76,7 @@ 'message': message}) return _login_decorator -@login_required +#@login_required def list_new(request, template = 'mailman-django/lists/new.html'): """ Add a new mailing list. @@ -91,7 +92,7 @@ if form.is_valid(): listname = form.cleaned_data['listname'] try: - c = MailmanRESTClient('localhost:8001', API_USER, API_PASS) + c = Client('localhost:8001', API_USER, API_PASS) except Exception, e: return HttpResponse(e) @@ -101,14 +102,14 @@ # creating a new one try: domain = c.create_domain(parts[1]) - except MailmanRESTClientError, e: + except: # I don't think this error can ever appear. -- Anna return HttpResponse(e) try: response = domain.create_list(parts[0]) return render_to_response('mailman-django/lists/created.html', {'fqdn_listname': response.info['fqdn_listname']}) - except MailmanRESTClientError, e: + except: return HttpResponse(e) else: @@ -121,17 +122,17 @@ """Show a table of all mailing lists. """ try: - c = MailmanRESTClient('localhost:8001', API_USER, API_PASS) - except MailmanRESTClientError, e: + c = Client('localhost:8001', API_USER, API_PASS) + except: return render_to_response('mailman-django/errors/generic.html', - {'message': e}) + {'message': "Unexpected error:"+ str(sys.exc_info()[0])}) try: lists = c.get_lists() return render_to_response(template, {'lists': lists}) - except MailmanRESTClientError, e: + except: return render_to_response('mailman-django/errors/generic.html', - {'message': e}) + {'message': "Unexpected error:"+ str(sys.exc_info()[0])}) def list_info(request, fqdn_listname = None, @@ -143,7 +144,7 @@ user to fill in which are evaluated in this function. """ try: - c = MailmanRESTClient('localhost:8001', API_USER, API_PASS) + c = Client('localhost:8001', API_USER, API_PASS) the_list = c.get_list(fqdn_listname) except Exception, e: return HttpResponse(e) @@ -210,7 +211,7 @@ # create a connection to Mailman and get the list try: - c = MailmanRESTClient('localhost:8001', API_USER, API_PASS) + c = Client('localhost:8001', API_USER, API_PASS) the_list = c.get_list(fqdn_listname) except Exception, e: return HttpResponse(e) @@ -222,9 +223,9 @@ try: lists = c.get_lists() return render_to_response(template, {'lists': lists}) - except MailmanRESTClientError, e: + except: return render_to_response('mailman-django/errors/generic.html', - {'message': e}) + {'message': "Unexpected error:"+ str(sys.exc_info()[0])}) @login_required def list_settings(request, fqdn_listname = None, @@ -236,7 +237,7 @@ """ message = "" try: - c = MailmanRESTClient('localhost:8001', API_USER, API_PASS) + c = Client('localhost:8001', API_USER, API_PASS) the_list = c.get_list(fqdn_listname) except Exception, e: return HttpResponse(e) @@ -261,7 +262,7 @@ """ message = "" try: - c = MailmanRESTClient('localhost:8001', API_USER, API_PASS) + c = Client('localhost:8001', API_USER, API_PASS) the_list = c.get_list(fqdn_listname) except Exception, e: return HttpResponse(e) @@ -307,7 +308,7 @@ membership_lists = [] listname = "" try: - c = MailmanRESTClient('localhost:8001', API_USER, API_PASS) + c = Client('localhost:8001', API_USER, API_PASS) user_object = c.get_user(member) # address_choices for the 'address' field must be a list of # tuples of length 2