def subscribe(list_address, user): client = Client('%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) rest_list = client.get_list(list_address) try: member = rest_list.get_member(user.email) except ValueError: # not subscribed yet, subscribe the user without email delivery member = rest_list.subscribe( user.email, "%s %s" % (user.first_name, user.last_name)) member.preferences["delivery_status"] = "by_user" member.preferences.save()
def subscribe(list_address, user): client = Client('%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) rest_list = client.get_list(list_address) try: member = rest_list.get_member(user.email) except ValueError: # not subscribed yet, subscribe the user without email delivery member = rest_list.subscribe(user.email, "%s %s" % (user.first_name, user.last_name)) member.preferences["delivery_status"] = "by_user" member.preferences.save()
def list_properties(request): """Get JSON encoded list properties""" store = get_store(request) lists = store.get_lists() client = Client('%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) props = {} for ml in lists: try: mm_list = client.get_list(ml.name) except urllib2.HTTPError: continue props[ml.name] = { "display_name": mm_list.display_name, "description": mm_list.settings["description"], } # Update KittyStore if necessary if ml.display_name != mm_list.display_name: ml.display_name = mm_list.display_name return HttpResponse(json.dumps(props), mimetype='application/javascript')
def list_properties(request): """Get JSON encoded list properties""" store = get_store(request) lists = store.get_lists() client = Client('%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) props = {} for ml in lists: try: mm_list = client.get_list(ml.name) except urllib2.HTTPError: continue props[ml.name] = { "display_name": mm_list.display_name, "description": mm_list.settings["description"], } # Update KittyStore if necessary if ml.display_name != mm_list.display_name: ml.display_name = mm_list.display_name return HttpResponse(json.dumps(props), mimetype='application/javascript')
parser.add_argument('--rest-user', dest='core_user', default=CORE_USER) parser.add_argument('--rest-password', dest='core_password', default=CORE_PASS) args = parser.parse_args() # client = Client(CORE_URI, CORE_USER, CORE_PASS) client = Client(args.core_uri, args.core_user, args.core_password) ml_fqdn = args.list_fqdn member_list = args.members member_file = None if args.list: if args.list == '-': member_file = sys.stdin else: member_file = open(args.list, 'r') for m in member_file: member_list.append(m.strip()) if args.list and args.list != '-': member_file.close() results = {} ml = client.get_list(ml_fqdn) for member_email in member_list: member = ml.get_member(member_email) results[member_email] = dict(member.preferences) print json.dumps(results, indent=2)
# create the list if it does not exist # update the lists with the information from the .ini file for list in cp_lists.sections(): listname = helpers.cleanStr(cp_lists[list]['name']) log.info('processing ' + listname) # create the list if it does not exist if not listname in str(mm_lists): l = mm_domain.create_list(listname) log.info('new list created: ' + listname) # read the list fqdn = helpers.cleanStr(listname+'@'+cp_config['mm_settings']['domain']) lst = client.get_list(fqdn) # get the settings from ini file and update the list configuration settings = lst.settings settings['display_name'] = cp_lists[list]['display_name'] settings['subject_prefix'] = cp_lists[list]['subject_prefix'] settings['description'] = cp_lists[list]['description'] settings['info'] = cp_lists[list]['info'] settings['advertised'] = cp_lists[list]['advertised'] settings['archive_policy'] = cp_lists[list]['archive_policy'] settings['default_member_action'] = cp_lists[list]['default_member_action'] # make sure the list is open, to accept members without sending an email settings['subscription_policy'] = 'open' # don't send a welcome message settings['send_welcome_message'] = 'false'
class MailMan(object): ''' Use official mailman 3.0 api client ''' client = None connected = False lists = [] def __init__(self): # Create settings & check connection try: self.client = Client(settings.MAILMAN_URL, settings.MAILMAN_USER, settings.MAILMAN_PASS) logger.debug('Connected to mailman %(mailman_version)s' % self.client.system) except: logger.error('Connection to mailman failed on %s' % settings.MAILMAN_URL) return None self.connected = True def get_list(self, list_name): ''' Retrieve a list using only its name ''' if not self.connected: raise Exception('No mailman connection') list_name += '@%s' % settings.MAILMAN_DOMAIN ml = self.client.get_list(list_name) if not ml: raise Exception('Mailing list %s not found' % list_name) return ml def subscribe(self, list_name, email, full_name): ''' Subscribe a member to a mailing list With full approval directly ''' if not self.connected: raise Exception('No mailman connection') ml = self.get_list(list_name) return ml.subscribe(email, full_name, pre_verified=True, pre_confirmed=True, pre_approved=True) def unsubscribe(self, list_name, email): ''' Unsubscribe a member from a mailing list ''' if not self.connected: raise Exception('No mailman connection') ml = self.get_list(list_name) return ml.unsubscribe(email) def create_list(self, list_name, full_name, extra_settings=None): ''' Create a new mailing list properly configured ''' # Retrieve domain domain = self.client.get_domain(settings.MAILMAN_DOMAIN) if not domain: raise Exception('No mailman domain %s' % settings.MAILMAN_DOMAIN) # Get or create list on domain try: ml = domain.create_list(list_name) except: ml = self.get_list(list_name) # Configure mailing mls = ml.settings mls['default_member_action'] = 'accept' mls['default_nonmember_action'] = 'accept' mls['send_welcome_message'] = False mls['advertised'] = False mls['display_name'] = full_name mls['subject_prefix'] = '[%s] ' % full_name mls['reply_to_address'] = ml.fqdn_listname # Override if extra_settings: # No update on mls for k, v in extra_settings.items(): mls[k] = v mls.save() return ml def delete_list(self, list_name): ''' Delete a mailing list ''' if not self.connected: raise Exception('No mailman connection') ml = self.get_list(list_name) return ml.delete()
else: log.info('sparql list contains ' + str(len(cpresult[1])) + ' entries') for icos_station in cpresult[1]: station = dict(zip(cpresult[0], icos_station)) listname = station['stationId'].lower( ) + '@' + cp_config['mm_settings']['domain'] listname = helpers.cleanStr(listname) log.debug('processing station list: ' + listname) if listname in str(mm_lists): log.info('delete station list: ' + listname) # make sure there are not whitespace, maybe we need a good regex lst = client.get_list(listname) lst.delete() # reread the lists from the server mm_lists = mm_domain.get_lists() else: log.debug(listname + ' not found') for list in cp_lists.sections(): listname = cp_lists[list]['name'] + '@' + cp_config['mm_settings']['domain'] listname = helpers.cleanStr(listname) log.debug('processing umbrella list: ' + listname) if listname in str(mm_lists): log.info('delete umbrella: ' + listname) lst = client.get_list(helpers.cleanStr(listname))
class MailMan(object): ''' Use official mailman 3.0 api client ''' client = None connected = False lists = [] def __init__(self): # Create settings & check connection try: self.client = Client(settings.MAILMAN_URL, settings.MAILMAN_USER, settings.MAILMAN_PASS) logger.debug('Connected to mailman %(mailman_version)s' % self.client.system) except: logger.error('Connection to mailman failed on %s' % settings.MAILMAN_URL) return None self.connected = True def get_list(self, list_name): ''' Retrieve a list using only its name ''' if not self.connected: raise Exception('No mailman connection') list_name += '@%s' % settings.MAILMAN_DOMAIN ml = self.client.get_list(list_name) if not ml: raise Exception('Mailing list %s not found' % list_name) return ml def subscribe(self, list_name, email, full_name): ''' Subscribe a member to a mailing list With full approval directly ''' if not self.connected: raise Exception('No mailman connection') ml = self.get_list(list_name) return ml.subscribe(email, full_name, pre_verified=True, pre_confirmed=True, pre_approved=True) def unsubscribe(self, list_name, email): ''' Unsubscribe a member from a mailing list ''' if not self.connected: raise Exception('No mailman connection') ml = self.get_list(list_name) return ml.unsubscribe(email) def create_list(self, list_name, full_name, extra_settings=None): ''' Create a new mailing list properly configured ''' # Retrieve domain domain = self.client.get_domain(settings.MAILMAN_DOMAIN) if not domain: raise Exception('No mailman domain %s' % settings.MAILMAN_DOMAIN) # Get or create list on domain try: ml = domain.create_list(list_name) except: ml = self.get_list(list_name) # Configure mailing mls = ml.settings mls['default_member_action'] = 'accept' mls['default_nonmember_action'] = 'accept' mls['send_welcome_message'] = False mls['advertised'] = False mls['display_name'] = full_name mls['subject_prefix'] = '[%s] ' % full_name mls['reply_to_address'] = ml.fqdn_listname # Override if extra_settings: # No update on mls for k,v in extra_settings.items(): mls[k] = v mls.save() return ml def delete_list(self, list_name): ''' Delete a mailing list ''' if not self.connected: raise Exception('No mailman connection') ml = self.get_list(list_name) return ml.delete()
if member not in [m.email for m in ml.members]: ml.accept_request(request['token']) else: ml.discard_request(request['token']) done = True return done for mailing, actions in six.iteritems(lists): for action, members in six.iteritems(actions): if not members: continue addr = '{0}@{1}'.format(mailing, domain) print("mailing: {0}".format(addr)) try: ml = client.get_list(addr) except (HTTPError, ) as exc: if exc.code != 404: raise ml = dom.create_list(mailing) for member in members: if action == 'add': print(" + {0}".format(member)) accepted = accept_request(ml, member) if accepted: continue elif member in [m.email for m in ml.members]: print(" already in!") continue else: ml.subscribe(member)
class maillist(object): def __init__(self, **args): self.client = Client(args['rest_url'], args['rest_username'], args['rest_password']) self.domain = self.client.get_domain(args['domain']) self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) def get_lists(self): mailists = [] for list in self.domain.lists: mailists.append(list.fqdn_listname) return mailists def create_list(self, **args): list = args['list'] name = list.split('@')[0] self.logger.debug(list) self.logger.debug(name) self.domain.create_list(name) self.set_settings(list) def set_settings(self, list_fqdn): list = self.client.get_list(list_fqdn) for key, value in self.default_settings().items(): list.settings[key] = value list.settings.save() def get_list_members(self, list_fqdn): members = [] list = self.client.get_list(list_fqdn) for member in list.members: members.append(member.address.email.lower()) return members def sync_members(self, list_fqdn, wannabe_members): members = self.get_list_members(list_fqdn) list = self.client.get_list(list_fqdn) todo_add = set(wannabe_members) - set(members) if len(todo_add) > 0: self.logger.info('Will add users to {}'.format(list_fqdn)) self.logger.info(str(todo_add)) todo_remove = set(members) - set(wannabe_members) if len(todo_remove) > 0: self.logger.info('Will remove users from {}'.format(list_fqdn)) self.logger.info(str(todo_remove)) for user in todo_remove: list.unsubscribe(user, pre_approved=True) for user in todo_add: list.subscribe(user, pre_verified=True, pre_confirmed=True, pre_approved=True) return True def default_settings(self): return { "acceptable_aliases": [], "accept_these_nonmembers": [], "admin_immed_notify": True, "admin_notify_mchanges": False, "administrivia": False, "advertised": False, "allow_list_posts": True, "anonymous_list": False, "archive_policy": "private", "archive_rendering_mode": "text", "autorespond_owner": "none", "autorespond_postings": "none", "autorespond_requests": "none", "autoresponse_grace_period": "90d", "autoresponse_owner_text": "", "autoresponse_postings_text": "", "autoresponse_request_text": "", "bounce_info_stale_after": "7d", "bounce_notify_owner_on_disable": True, "bounce_notify_owner_on_removal": True, "bounce_score_threshold": 5, "bounce_you_are_disabled_warnings": 3, "bounce_you_are_disabled_warnings_interval": "7d", "collapse_alternatives": True, "convert_html_to_plaintext": False, "default_member_action": "defer", "default_nonmember_action": "hold", "description": "Wannabe list", "digest_send_periodic": False, "digest_size_threshold": 30.0, "digest_volume_frequency": "monthly", "digests_enabled": False, "discard_these_nonmembers": [], "dmarc_mitigate_action": "munge_from", "dmarc_mitigate_unconditionally": True, "dmarc_moderation_notice": "", "dmarc_wrapped_message_text": "", "emergency": False, "filter_action": "discard", "filter_content": False, "filter_extensions": [], "filter_types": [], "first_strip_reply_to": False, "forward_unrecognized_bounces_to": "administrators", "gateway_to_mail": False, "gateway_to_news": False, "hold_these_nonmembers": [], "include_rfc2369_headers": True, "info": "", "linked_newsgroup": "", "max_message_size": 128, "max_num_recipients": 12, "max_days_to_hold": 0, "member_roster_visibility": "moderators", "moderator_password": None, "newsgroup_moderation": "none", "nntp_prefix_subject_too": True, "pass_types": [], "pass_extensions": [], "personalize": "none", "posting_pipeline": "default-posting-pipeline", "preferred_language": "no", "process_bounces": True, "reject_these_nonmembers": [], "reply_goes_to_list": "no_munging", "reply_to_address": "", "require_explicit_destination": False, "respond_to_post_requests": True, "send_welcome_message": False, "subscription_policy": "moderate", "unsubscription_policy": "moderate", "usenet_watermark": None, }