def gen_dot(): d = Dot() nodes = dict() login = read_ssv_file("vpopmail.login") db = MySQLdb.connect(host="localhost", user=login[0], passwd=login[2], db=login[1]) c = db.cursor() c.execute("SELECT alias, valias_line FROM valias WHERE domain=%s", (MAILDOMAIN,)) for alias, target in c.fetchall(): assert target[0] == "&" target = target[1:] alias += "@" + MAILDOMAIN if not alias in nodes: nodes[alias] = Node(alias) d.add_node(nodes[alias]) if not target in nodes: nodes[target] = Node(target) d.add_node(nodes[target]) d.add_edge(Edge(nodes[alias], nodes[target])) for list in Utils.list_names(): if list == "plukdenacht2008": continue source = list + "@" + LISTDOMAIN if not source in nodes: nodes[source] = Node(source) d.add_node(nodes[source]) m = MailList.MailList(list, lock=False) for member in m.members: if not member in nodes: nodes[member] = Node(member) d.add_node(nodes[member]) d.add_edge(Edge(nodes[source], nodes[member])) d.write("the.dot")
def lists_of_member(safeuser): hostname = mm_cfg.DEFAULT_URL_HOST onlists = [] for listname in Utils.list_names(): # The current list will always handle things in the mainline if listname == Utils.list_names(): continue glist = MailList.MailList(listname, lock=0) if glist.host_name <> hostname: continue if not glist.isMember(safeuser): continue onlists.append(glist) return onlists
def gen_dot(): d = Dot() nodes = dict() login = read_ssv_file('vpopmail.login') db = MySQLdb.connect(host='localhost', user=login[0], passwd=login[2], db=login[1]) c = db.cursor() c.execute("SELECT alias, valias_line FROM valias WHERE domain=%s", (MAILDOMAIN, )) for alias, target in c.fetchall(): assert target[0] == '&' target = target[1:] alias += "@" + MAILDOMAIN if not alias in nodes: nodes[alias] = Node(alias) d.add_node(nodes[alias]) if not target in nodes: nodes[target] = Node(target) d.add_node(nodes[target]) d.add_edge(Edge(nodes[alias], nodes[target])) for list in Utils.list_names(): if list == 'plukdenacht2008': continue source = list + "@" + LISTDOMAIN if not source in nodes: nodes[source] = Node(source) d.add_node(nodes[source]) m = MailList.MailList(list, lock=False) for member in m.members: if not member in nodes: nodes[member] = Node(member) d.add_node(nodes[member]) d.add_edge(Edge(nodes[source], nodes[member])) d.write('the.dot')
def process(res, args): mlist = res.mlist if args: res.results.append(_('Usage:')) res.results.append(gethelp(mlist)) return STOP hostname = mlist.host_name res.results.append(_('Public mailing lists at %(hostname)s:')) lists = Utils.list_names() lists.sort() i = 1 for listname in lists: if listname == mlist.internal_name(): xlist = mlist else: xlist = MailList(listname, lock=0) # We can mention this list if you already know about it if not xlist.advertised and xlist is not mlist: continue # Skip the list if it isn't in the same virtual domain. BAW: should a # message to the site list include everything regardless of domain? if mm_cfg.VIRTUAL_HOST_OVERVIEW and \ xlist.host_name <> mlist.host_name: continue realname = xlist.real_name description = xlist.description or _('n/a') requestaddr = xlist.GetRequestEmail() if i > 1: res.results.append('') res.results.append(_('%(i)3d. List name: %(realname)s')) res.results.append(_(' Description: %(description)s')) res.results.append(_(' Requests to: %(requestaddr)s')) i += 1
def list_lists(): """Lists existing mailing lists on the server. **Method**: GET **URI**: / Returns a list of the mailing lists that exist on this server.""" all_lists = Utils.list_names() lists = [] include_description = request.query.get('description') include_private = request.query.get('private') address = request.query.get('address') for listname in all_lists: mlist = get_mailinglist(listname, lock=False) members = mlist.getMembers() if not address or address in members: list_values = [listname] if include_description: list_values.append(mlist.description.decode('latin1')) if include_private: list_values.append(bool(mlist.archive_private)) if len(list_values) == 1: lists.append(list_values[0]) else: lists.append(list_values) return jsonify(lists)
def get_lists(userdesc, perms, vhost, email=None): """ List available lists for the given vhost """ if email is None: udesc = userdesc else: udesc = UserDesc(email.lower(), email.lower(), None, 0) prefix = vhost.lower()+VHOST_SEP names = Utils.list_names() names.sort() result = [] for name in names: if not name.startswith(prefix): continue try: mlist = MailList.MailList(name, lock=0) except: continue try: details = get_list_info(udesc, perms, mlist, (email is None and vhost == PLATAL_DOMAIN)) if details is not None: result.append(details[0]) except Exception, e: sys.stderr.write('Can\'t get list %s: %s\n' % (name, str(e))) continue
def kill(userdesc, perms, vhost, forlife, promo, del_from_promo): """ Remove a user from all the lists. Args: forlife: the user's forlife email promo: the user's promo, if any (format: X2006) del_from_promo: bool, whether to delete from the promo lists as well. """ exclude = [] if promo and promo[0] == 'X' and not del_from_promo: exclude.append(PLATAL_DOMAIN + VHOST_SEP + 'promo' + promo[1:]) for list in Utils.list_names(): if list in exclude: continue try: mlist = MailList.MailList(list, lock=0) except: continue try: mlist.Lock() mlist.ApprovedDeleteMember(forlife, None, 0, 0) mlist.Save() mlist.Unlock() except: mlist.Unlock() return 1
def list_lists(): """Lists existing mailing lists on the server. **Method**: GET **URI**: /v2/ Returns a list of dictionaries the mailing lists and its public attributes that exist on this server.""" all_lists = Utils.list_names() lists = [] address = request.query.get('address') for listname in all_lists: if listname == Defaults.MAILMAN_SITE_LIST: continue mlist = get_mailinglist(listname, lock=False) members = mlist.getMembers() if not address or address in members: list_values = { 'listname': listname, 'archive_private': mlist.archive_private, 'real_name': mlist.real_name, 'description': mlist.description, } lists.append(list_values) return jsonify(lists)
def process(res, args): mlist = res.mlist if args: res.results.append(_('Usage:')) res.results.append(gethelp(mlist)) return STOP hostname = mlist.host_name res.results.append(_('Public mailing lists at %(hostname)s:')) lists = Utils.list_names() lists.sort() i = 1 for listname in lists: if listname == mlist.internal_name(): xlist = mlist else: xlist = MailList(listname, lock=0) # We can mention this list if you already know about it if not xlist.advertised and xlist is not mlist: continue # Skip the list if it isn't in the same virtual domain. BAW: should a # message to the site list include everything regardless of domain? if mm_cfg.VIRTUAL_HOST_OVERVIEW and \ xlist.host_name != mlist.host_name: continue realname = xlist.real_name description = xlist.description or _('n/a') requestaddr = xlist.GetRequestEmail() if i > 1: res.results.append('') res.results.append(_('%(i)3d. List name: %(realname)s')) res.results.append(_(' Description: %(description)s')) res.results.append(_(' Requests to: %(requestaddr)s')) i += 1
def get_lists(): names = Utils.list_names() names.sort() committees = OfficerPosition.objects.all() committee_lists = {} for committee in committees: if committee.mailing_list: committee_lists[committee.mailing_list] = committee mlists = [] for name in names: try: mlist = MailList.MailList(name, lock=False) except IOError: continue mlist_item = { 'name': mlist.internal_name(), 'url': mlist.GetScriptURL('listinfo', absolute=1), 'adminurl': mlist.GetScriptURL('admin', absolute=1), 'description': mlist.description, 'public': True if mlist.advertised else False, } if mlist.internal_name() in committee_lists: mlist_item['position'] = committee_lists[mlist.internal_name()] mlists.append(mlist_item) return mlists
def list_lists(): """Lists existing mailing lists on the server. **Method**: GET **URI**: / Returns a list of the mailing lists that exist on this server.""" all_lists = Utils.list_names() lists = [] include_description = request.query.get('description') address = request.query.get('address') for listname in all_lists: mlist = get_mailinglist(listname, lock=False) members = mlist.getMembers() if not address or address in members: if include_description: lists.append((listname, mlist.description.decode('latin1'))) else: lists.append(listname) return jsonify(lists)
def getLists(): names = Utils.list_names() names.sort() mailinglists = [] for n in names: mailinglists.append(UCPMailingList(n)) return mailinglists
def create_list(cls, list_name, list_admin='*****@*****.**', list_pass='******', subscribe_policy=0): if list_name in Utils.list_names(): return m = MailList.MailList() m.Create(list_name, list_admin, list_pass) m.subscribe_policy = subscribe_policy m.Save() m.Unlock()
def _oneloop(self): # Refresh this each time through the list. BAW: could be too # expensive. listnames = Utils.list_names() # Cruise through all the files currently in the new/ directory try: files = os.listdir(self._dir) except OSError, e: if e.errno <> errno.ENOENT: raise # Nothing's been delivered yet return 0
def get_all_lists(userdesc, perms, vhost): """ Get all the list for the given vhost @root """ prefix = vhost.lower()+VHOST_SEP names = Utils.list_names() names.sort() result = [] for name in names: if not name.startswith(prefix): continue result.append(name.replace(prefix, '')) return result
def lists_of_member(mlist, user): hostname = mlist.host_name onlists = [] for listname in Utils.list_names(): # The current list will always handle things in the mainline if listname == mlist.internal_name(): continue glist = MailList.MailList(listname, lock=0) if glist.host_name <> hostname: continue if not glist.isMember(user): continue onlists.append(glist) return onlists
def lists_of_member(mlist, user): hostname = mlist.host_name onlists = [] for listname in Utils.list_names(): # The current list will always handle things in the mainline if listname == mlist.internal_name(): continue glist = MailList.MailList(listname, lock=0) if glist.host_name != hostname: continue if not glist.isMember(user): continue onlists.append(glist) return onlists
def all_mls (self): """A dictionary of listname to corresponding MailList objects. The lists are not locked. This is an important thing to keep in mind. This is potentially time consuming to create for every call. We may revisit this as a potential performance improvement. FIXME""" if self._all_mls: return self._all_mls self._all_mls = {} for name in Utils.list_names(): self._all_mls[name] = MailList.MailList(name, lock=0) return self._all_mls
def import_lists(prefix): ''' Imports lists named with the given prefix from mailman into the compsoc website. Caveat: they have to be subscribed using the same email address they use for the compsoc website. ''' for list_name in Utils.list_names(): if list_name.startswith(prefix): list,new = MailingList.objects.get_or_create(list=list_name) mailman_list = MailList.MailList(list_name, lock=False) members = mailman_list.getMemberCPAddresses(mailman_list.getRegularMemberKeys()+mailman_list.getDigestMemberKeys()) for member in members: try: list.users.add(User.objects.get(email=member)) except User.DoesNotExist: pass
def list_attr(listname): """Returns basic attributes of specific list. **Method**: GET **URI**: /v3/<listname> Returns a dictionary containing the basic attributes for a specific mailing list that exist on this server.""" all_lists = Utils.list_names() lists = [] try: mlist = get_mailinglist(listname) except Errors.MMUnknownListError, e: return jsonify(ERRORS_CODE[e.__class__.__name__])
def list_lists(): all_lists = Utils.list_names() lists = [] include_description = request.query.get('description') address = request.query.get('address') for listname in all_lists: mlist = get_mailinglist(listname, lock=False) members = mlist.getMembers() if not address or address in members: if include_description: lists.append((listname, mlist.description.decode('latin1'))) else: lists.append(listname) return jsonify(lists)
def list_lists(): """ List all lists ?address: an email address if provided will only return lists with the member on it """ all_lists = Utils.list_names() address = request.args.get('address') if not address: return jsonify({'lists': all_lists}) lists = [] for list_name in all_lists: m_list = get_mailing_list(list_name, lock=False) members = m_list.getMembers() if address in members: lists.append(list_name) return jsonify({'lists': lists})
def change_user_email(userdesc, perms, vhost, from_email, to_email): """ Change the email of a user @root """ from_email = from_email.lower() to_email = to_email.lower() for list in Utils.list_names(): try: mlist = MailList.MailList(list, lock=0) except: continue try: mlist.Lock() mlist.ApprovedChangeMemberAddress(from_email, to_email, 0) mlist.Save() mlist.Unlock() except: mlist.Unlock() return 1
def import_lists(prefix): ''' Imports lists named with the given prefix from mailman into the compsoc website. Caveat: they have to be subscribed using the same email address they use for the compsoc website. ''' for list_name in Utils.list_names(): if list_name.startswith(prefix): list, new = MailingList.objects.get_or_create(list=list_name) mailman_list = MailList.MailList(list_name, lock=False) members = mailman_list.getMemberCPAddresses( mailman_list.getRegularMemberKeys() + mailman_list.getDigestMemberKeys()) for member in members: try: list.users.add(User.objects.get(email=member)) except User.DoesNotExist: pass
def _get_subscriptions(self): """Get the latest subscription information.""" # First, calculate the names of the active mailing lists. lists = sorted(list_name for list_name in Utils.list_names() if list_name != mm_cfg.MAILMAN_SITE_LIST) # Batch the subscription requests in order to reduce the possibility # of timeouts in the XMLRPC server. Note that we cannot eliminate # timeouts, which will cause an entire batch to fail. To reduce the # possibility that the same batch of teams will always fail, we # shuffle the list of team names so the batches will always be # different. shuffle(lists) while lists: if self._shortcircuit(): # Stop was called during a long network call. return batch = lists[:mm_cfg.XMLRPC_SUBSCRIPTION_BATCH_SIZE] lists = lists[mm_cfg.XMLRPC_SUBSCRIPTION_BATCH_SIZE:] ## syslog('xmlrpc', 'batch: %s', batch) ## syslog('xmlrpc', 'lists: %s', lists) # Get the information for this batch of mailing lists. try: info = self._proxy.getMembershipInformation(batch) except (xmlrpclib.ProtocolError, socket.error) as error: log_exception('Cannot talk to Launchpad: %s', error) syslog('xmlrpc', 'batch: %s', batch) continue except xmlrpclib.Fault as error: log_exception('Launchpad exception: %s', error) syslog('xmlrpc', 'batch: %s', batch) continue for list_name in info: subscription_info = info[list_name] # The subscription info for a mailing list can be None, # meaning that there are no subscribers or allowed posters. # The latter can only happen if there are no active team # members, and that can only happen when the owner has been # specifically deactivate for some reason. This is not an # error condition. if subscription_info is not None: self._update_list_subscriptions(list_name, subscription_info)
def import_mailman_listinfo(verbosity=0): def note(msg): if verbosity > 1: sys.stdout.write(msg) sys.stdout.write('\n') if not have_mailman: note("Could not import mailman modules -- skipping import of mailman list info") return names = list(Utils.list_names()) names.sort() for name in names: mlist = MailList.MailList(name, lock=False) note("List: %s" % mlist.internal_name()) if mlist.advertised: description = mlist.description.decode('latin1')[:256] mmlist, created = List.objects.get_or_create(name=mlist.real_name, description=description, advertised=mlist.advertised) # The following calls return lowercased addresses members = mlist.getRegularMemberKeys() + mlist.getDigestMemberKeys() members = [ m for m in members if mlist.getDeliveryStatus(m) == MemberAdaptor.ENABLED ] known = Subscribed.objects.filter(lists__name=name).values_list('email', flat=True) for addr in known: if not addr in members: note(" Removing subscription: %s" % (addr)) old = Subscribed.objects.get(email=addr) old.lists.remove(mmlist) if old.lists.count() == 0: note(" Removing address with no subscriptions: %s" % (addr)) old.delete() for addr in members: if len(addr) > 64: sys.stderr.write(" ** Email address subscribed to '%s' too long for table: <%s>\n" % (name, addr)) continue if not addr in known: note(" Adding subscription: %s" % (addr)) try: new, created = Subscribed.objects.get_or_create(email=addr) except MultipleObjectsReturned as e: sys.stderr.write(" ** Error handling %s in %s: %s\n" % (addr, name, e)) continue new.lists.add(mmlist)
def main(): parser, opts, args = parseargs() if opts.outputfile in (None, '-'): # This will fail if there are characters in the output incompatible # with stdout. fp = sys.stdout else: fp = codecs.open(opts.outputfile, 'w', 'utf-8') try: dumper = XMLDumper(fp) if opts.listnames: listnames = opts.listnames else: listnames = Utils.list_names() dumper.dump(listnames, SCHEMES[opts.password_scheme.lower()]) dumper.close() finally: if fp is not sys.stdout: fp.close()
def kill(userdesc, perms, vhost, alias, del_from_promo): """ Remove a user from all the lists. """ exclude = [] if not del_from_promo: exclude.append(PLATAL_DOMAIN + VHOST_SEP + 'promo' + alias[-4:]) for list in Utils.list_names(): if list in exclude: continue try: mlist = MailList.MailList(list, lock=0) except: continue try: mlist.Lock() mlist.ApprovedDeleteMember(alias + '@' + PLATAL_DOMAIN, None, 0, 0) mlist.Save() mlist.Unlock() except: mlist.Unlock() return 1
def _get_subscriptions(self): """Get the latest subscription information.""" # First, calculate the names of the active mailing lists. lists = sorted(list_name for list_name in Utils.list_names() if list_name != mm_cfg.MAILMAN_SITE_LIST) # Batch the subscription requests in order to reduce the possibility # of timeouts in the XMLRPC server. Note that we cannot eliminate # timeouts, which will cause an entire batch to fail. To reduce the # possibility that the same batch of teams will always fail, we # shuffle the list of team names so the batches will always be # different. shuffle(lists) while lists: if self._shortcircuit(): # Stop was called during a long network call. return batch = lists[: mm_cfg.XMLRPC_SUBSCRIPTION_BATCH_SIZE] lists = lists[mm_cfg.XMLRPC_SUBSCRIPTION_BATCH_SIZE :] ## syslog('xmlrpc', 'batch: %s', batch) ## syslog('xmlrpc', 'lists: %s', lists) # Get the information for this batch of mailing lists. try: info = self._proxy.getMembershipInformation(batch) except (xmlrpclib.ProtocolError, socket.error) as error: log_exception("Cannot talk to Launchpad: %s", error) syslog("xmlrpc", "batch: %s", batch) continue except xmlrpclib.Fault as error: log_exception("Launchpad exception: %s", error) syslog("xmlrpc", "batch: %s", batch) continue for list_name in info: subscription_info = info[list_name] # The subscription info for a mailing list can be None, # meaning that there are no subscribers or allowed posters. # The latter can only happen if there are no active team # members, and that can only happen when the owner has been # specifically deactivate for some reason. This is not an # error condition. if subscription_info is not None: self._update_list_subscriptions(list_name, subscription_info)
def list_lists_with_members(): domain_name = request.args.get('domain__name') source_regex = request.args.get('source__iregex') dest_regex = request.args.get('destination__iregex') lists_w_members = [] for list_name in Utils.list_names(): if list_name == 'mailman': continue mlist = get_mailing_list(list_name, lock=False) source = mlist.GetListEmail() # Correct domain if domain_name and not source.split()[-1].endswith(domain_name): continue # Matching source if source_regex and not matches_regex(source_regex, source): continue destinations = mlist.getMembers() # Matching at least one destination if dest_regex and not matches_regex(dest_regex, "\n".join(destinations)): continue lists_w_members.append({ 'destinations': destinations, 'name': source, 'type': 'mailman', 'admin_url': 'https://lists.neuf.no/admin/{}/'.format(list_name), 'admin_type': 'selfservice', 'num': len(destinations) }) return jsonify({ 'lists': lists_w_members, 'num': len(lists_w_members) })
def get_all_user_lists(userdesc, perms, vhost, email): """ Get all the lists for the given user @root """ names = Utils.list_names() names.sort() result = [] for name in names: try: mlist = MailList.MailList(name, lock=0) ismember = email in mlist.getRegularMemberKeys() isowner = email in mlist.owner if not ismember and not isowner: continue host = mlist.internal_name().split(VHOST_SEP)[0].lower() result.append({ 'list': mlist.real_name, 'addr': mlist.real_name.lower() + '@' + host, 'host': host, 'own' : isowner, 'sub' : ismember }) except Exception, e: continue
def setUp(self): super(TestAPIv1, self).setUp() self.list_names = Utils.list_names()
def fixHostnames(self): """Fix up the host names in Mailman and the LP database.""" # These can't be done at module global scope. from Mailman import Utils from Mailman import mm_cfg from Mailman.MailList import MailList # Grab a couple of useful components. email_address_set = getUtility(IEmailAddressSet) mailing_list_set = getUtility(IMailingListSet) # Clean things up per mailing list. for list_name in Utils.list_names(): # Skip the site list. if list_name == mm_cfg.MAILMAN_SITE_LIST: continue # The first thing to clean up is the mailing list pickles. There # are things like host names in some attributes that need to be # converted. The following opens a locked list. mailing_list = MailList(list_name) try: mailing_list.host_name = mm_cfg.DEFAULT_EMAIL_HOST mailing_list.web_page_url = ( mm_cfg.DEFAULT_URL_PATTERN % mm_cfg.DEFAULT_URL_HOST) mailing_list.Save() finally: mailing_list.Unlock() # Patch up the email address for the list in the Launchpad # database. lp_mailing_list = mailing_list_set.get(list_name) if lp_mailing_list is None: # We found a mailing list in Mailman that does not exist in # the Launchpad database. This can happen if we rsync'd the # Mailman directories after the lists were created, but we # copied the LP database /before/ the lists were created. # If we don't delete the Mailman lists, we won't be able to # create the mailing lists on staging. self.logger.error('No LP mailing list for: %s', list_name) self.deleteMailmanList(list_name) continue # Clean up the team email addresses corresponding to their mailing # lists. Note that teams can have two email addresses if they # have a different contact address. team = getUtility(IPersonSet).getByName(list_name) mlist_addresses = email_address_set.getByPerson(team) if mlist_addresses.count() == 0: self.logger.error('No LP email address for: %s', list_name) else: # Teams can have both a mailing list and a contact address. old_address = '%s@%s' % (list_name, self.options.hostname) for email_address in mlist_addresses: if email_address.email == old_address: new_address = lp_mailing_list.address removeSecurityProxy(email_address).email = new_address self.logger.info('%s -> %s', old_address, new_address) break else: self.logger.error('No change to LP email address for: %s', list_name)
# This Checkmk-Agent plugin gathers information about mailinglists hosted # by the local mailman instance. # Needed if you have located your mailman python modules not in default # python module paths import sys sys.path.append("/usr/local/mailman") sys.path.append("/usr/lib/mailman") # Set to True to filter out all "hidden" mailinglists only_advertised = True from Mailman import Utils, MailList # type: ignore[import] # pylint: disable=import-error # 1. list memberships sys.stdout.write('<<<mailman_lists>>>\n') total_members = set([]) for name in sorted(Utils.list_names()): mlist = MailList.MailList(name, lock=0) if only_advertised and not mlist.advertised: continue rmembers = mlist.getRegularMemberKeys() dmembers = mlist.getDigestMemberKeys() members = rmembers + dmembers total_members.update(members) sys.stdout.write('%s %d\n' % (name, len(members))) sys.stdout.write('TOTAL %d\n' % len(total_members))
def FormatListinfoOverview(error=None): "Present a general welcome and itemize the (public) lists for this host." # XXX We need a portable way to determine the host by which we are being # visited! An absolute URL would do... http_host = os.environ.get('HTTP_HOST', os.environ.get('SERVER_NAME')) port = os.environ.get('SERVER_PORT') # strip off the port if there is one if port and http_host[-len(port)-1:] == ':'+port: http_host = http_host[:-len(port)-1] if mm_cfg.VIRTUAL_HOST_OVERVIEW and http_host: host_name = http_host else: host_name = mm_cfg.DEFAULT_HOST_NAME doc = Document() legend = "%s Mailing Lists" % host_name doc.SetTitle(legend) table = Table(border=0, width="100%") table.AddRow([Center(Header(2, legend))]) table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2, bgcolor="#99ccff") advertised = [] names = Utils.list_names() names.sort() for n in names: mlist = MailList.MailList(n, lock=0) if mlist.advertised: if mm_cfg.VIRTUAL_HOST_OVERVIEW and \ http_host and \ string.find(http_host, mlist.web_page_url) == -1 and \ string.find(mlist.web_page_url, http_host) == -1: # List is for different identity of this host - skip it. continue else: advertised.append(mlist) if error: greeting = FontAttr(error, color="ff5060", size="+1") else: greeting = FontAttr('Welcome!', size='+2') if not advertised: welcome_items = (greeting, "<p>" " There currently are no publicly-advertised ", Link(mm_cfg.MAILMAN_URL, "mailman"), " mailing lists on %s." % host_name, ) else: welcome_items = ( greeting, '''<p>Below is a listing of all the public mailing lists on %(hostname)s. Click on a list name to get more information about the list, or to subscribe, unsubscribe, and change the preferences on your subscription.''' % {'hostname': host_name}, ) welcome_items = (welcome_items + (" To visit the info page for an unadvertised list," " open a URL similar to this one, but with a '/' and" + (" the %slist name appended." % ((error and "right ") or "")) + '<p> List administrators, you can visit ', Link(Utils.ScriptURL('admin'), 'the list admin overview page'), " to find the management interface for your list." "<p>(Send questions or comments to ", Link("mailto:%s" % mm_cfg.MAILMAN_OWNER, mm_cfg.MAILMAN_OWNER), ".)<p>")) table.AddRow([apply(Container, welcome_items)]) table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2) if advertised: table.AddRow([' ', ' ']) table.AddRow([Bold(FontAttr('List', size='+2')), Bold(FontAttr('Description', size='+2')) ]) for mlist in advertised: table.AddRow( [Link(mlist.GetScriptURL('listinfo'), Bold(mlist.real_name)), mlist.description or Italic('[no description available]')]) doc.AddItem(table) doc.AddItem('<hr>') doc.AddItem(MailmanLogo()) print doc.Format(bgcolor="#ffffff")
def get_listnames(only_public=False, **kwargs): names = Utils.list_names() names.sort() if only_public: names = [name for name in names if get_list(name, lock=False).subscribe_policy == 1] return names
def FormatAdminOverview(error=None): "Present a general welcome and itemize the (public) lists." doc = Document() legend = "%s mailing lists - Admin Links" % mm_cfg.DEFAULT_HOST_NAME doc.SetTitle(legend) table = Table(border=0, width="100%") table.AddRow([Center(Header(2, legend))]) table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2, bgcolor="#99ccff") advertised = [] names = Utils.list_names() names.sort() for n in names: l = MailList.MailList(n, lock=0) if l.advertised: advertised.append(l) if error: greeting = FontAttr(error, color="ff5060", size="+1") else: greeting = "Welcome!" if not advertised: welcome_items = (greeting, "<p>" " There currently are no publicly-advertised ", Link(mm_cfg.MAILMAN_URL, "mailman"), " mailing lists on %s." % mm_cfg.DEFAULT_HOST_NAME, ) else: welcome_items = ( greeting, "<p>" " Below is the collection of publicly-advertised ", Link(mm_cfg.MAILMAN_URL, "mailman"), " mailing lists on %s." % mm_cfg.DEFAULT_HOST_NAME, (' Click on a list name to visit the configuration pages' ' for that list.' ) ) welcome_items = (welcome_items + (" To visit the administrators configuration page for" " an unadvertised list, open a URL similar to this" + (" one, but with a '/' and the %slist name appended.<p>" % ((error and "right ") or "")) + " General list information can be found at ", Link(Utils.ScriptURL('listinfo'), 'the mailing list overview page'), "." "<p>(Send questions and comments to ", Link("mailto:%s" % mm_cfg.MAILMAN_OWNER, mm_cfg.MAILMAN_OWNER), ".)<p>" ) ) table.AddRow([apply(Container, welcome_items)]) table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2) if advertised: table.AddRow([' ', ' ']) table.AddRow([Bold("List"), Bold("Description")]) for l in advertised: table.AddRow( [Link(l.GetScriptURL('admin'), Bold(l.real_name)), l.description or Italic('[no description available]'), ]) doc.AddItem(table) doc.AddItem('<hr>') doc.AddItem(MailmanLogo()) print doc.Format(bgcolor="#ffffff")
def _oneloop(self): # Refresh this each time through the list. BAW: could be too # expensive. listnames = Utils.list_names() # Cruise through all the files currently in the new/ directory try: files = os.listdir(self._dir) except OSError as e: if e.errno != errno.ENOENT: raise # Nothing's been delivered yet return 0 for file in files: srcname = os.path.join(self._dir, file) dstname = os.path.join(self._cur, file + ':1,P') xdstname = os.path.join(self._cur, file + ':1,X') try: os.rename(srcname, dstname) except OSError as e: if e.errno == errno.ENOENT: # Some other MaildirRunner beat us to it continue syslog('error', 'Could not rename maildir file: %s', srcname) raise # Now open, read, parse, and enqueue this message try: fp = open(dstname) try: msg = self._parser.parse(fp) finally: fp.close() # Now we need to figure out which queue of which list this # message was destined for. See verp_bounce() in # BounceRunner.py for why we do things this way. vals = [] for header in ('delivered-to', 'envelope-to', 'apparently-to'): vals.extend(msg.get_all(header, [])) for field in vals: to = parseaddr(field)[1] if not to: continue mo = lre.match(to) if not mo: # This isn't an address we care about continue listname, subq = mo.group('listname', 'subq') if listname in listnames: break else: # As far as we can tell, this message isn't destined for # any list on the system. What to do? syslog('error', 'Message apparently not for any list: %s', xdstname) os.rename(dstname, xdstname) continue # BAW: blech, hardcoded msgdata = {'listname': listname} # -admin is deprecated if subq in ('bounces', 'admin'): queue = get_switchboard(mm_cfg.BOUNCEQUEUE_DIR) elif subq == 'confirm': msgdata['toconfirm'] = 1 queue = get_switchboard(mm_cfg.CMDQUEUE_DIR) elif subq in ('join', 'subscribe'): msgdata['tojoin'] = 1 queue = get_switchboard(mm_cfg.CMDQUEUE_DIR) elif subq in ('leave', 'unsubscribe'): msgdata['toleave'] = 1 queue = get_switchboard(mm_cfg.CMDQUEUE_DIR) elif subq == 'owner': msgdata.update({ 'toowner': 1, 'envsender': Utils.get_site_email(extra='bounces'), 'pipeline': mm_cfg.OWNER_PIPELINE, }) queue = get_switchboard(mm_cfg.INQUEUE_DIR) elif subq is None: msgdata['tolist'] = 1 queue = get_switchboard(mm_cfg.INQUEUE_DIR) elif subq == 'request': msgdata['torequest'] = 1 queue = get_switchboard(mm_cfg.CMDQUEUE_DIR) else: syslog('error', 'Unknown sub-queue: %s', subq) os.rename(dstname, xdstname) continue queue.enqueue(msg, msgdata) os.unlink(dstname) except Exception as e: os.rename(dstname, xdstname) syslog('error', str(e))
from Mailman.ListAdmin import readMessage from email.Iterators import typed_subpart_iterator uid = getpwnam(mm_cfg.MAILMAN_USER)[2] gid = getgrnam(mm_cfg.MAILMAN_GROUP)[2] if not os.getuid(): os.setregid(gid,gid) os.setreuid(uid,uid) if ( os.getuid() is not uid ) or ( os.getgid() is not gid): sys.exit(0) for listname in Utils.list_names(): try: mlist = MailList.MailList(listname,lock=0) except: print 'ERROR for '+listname continue try: mlist.Lock() ############################################ # do treatement here ############################################ mlist.Save() mlist.Unlock() print 'OK for '+listname
from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler import paths from Mailman import MailList from Mailman import Utils from Mailman import Message from Mailman import Errors from Mailman import mm_cfg from Mailman import i18n from Mailman.UserDesc import UserDesc from Mailman.ListAdmin import readMessage from email.Iterators import typed_subpart_iterator names = Utils.list_names() for listname in names: try: mlist = MailList.MailList(listname,lock=0) except: print 'ERROR '+listname continue try: print 'BEGIN '+listname mlist.Lock() mlist.header_filter_rules = [] mlist.header_filter_rules.append(('X-Spam-Flag: Yes, tests=bogofilter', mm_cfg.HOLD, False)) print ' set new bogofilter policy' mlist.Save() mlist.Unlock() print 'END'
def listinfo_overview(msg=''): # Present the general listinfo overview hostname = Utils.get_domain() # Set up the document and assign it the correct language. The only one we # know about at the moment is the server's default. doc = Document() doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) legend = _("%(hostname)s Mailing Lists") doc.SetTitle(legend) table = Table(border=0, width="100%") table.AddRow([Center(Header(2, legend))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR) # Skip any mailing lists that isn't advertised. advertised = [] listnames = Utils.list_names() listnames.sort() for name in listnames: mlist = MailList.MailList(name, lock=0) if mlist.advertised: if mm_cfg.VIRTUAL_HOST_OVERVIEW and ( mlist.web_page_url.find('/%s/' % hostname) == -1 and mlist.web_page_url.find('/%s:' % hostname) == -1): # List is for different identity of this host - skip it. continue else: advertised.append( (mlist.GetScriptURL('listinfo'), mlist.real_name, Utils.websafe(mlist.description))) if msg: greeting = FontAttr(msg, color="ff5060", size="+1") else: greeting = FontAttr(_('Welcome!'), size='+2') welcome = [greeting] mailmanlink = Link(mm_cfg.MAILMAN_URL, _('Mailman')).Format() if not advertised: welcome.extend( _('''<p>There currently are no publicly-advertised %(mailmanlink)s mailing lists on %(hostname)s.''')) else: welcome.append( _('''<p>Below is a listing of all the public mailing lists on %(hostname)s. Click on a list name to get more information about the list, or to subscribe, unsubscribe, and change the preferences on your subscription.''')) # set up some local variables adj = msg and _('right') or '' siteowner = Utils.get_site_email() welcome.extend( (_(''' To visit the general information page for an unadvertised list, open a URL similar to this one, but with a '/' and the %(adj)s list name appended. <p>List administrators, you can visit '''), Link(Utils.ScriptURL('admin'), _('the list admin overview page')), _(''' to find the management interface for your list. <p>If you are having trouble using the lists, please contact '''), Link('mailto:' + siteowner, siteowner), '.<p>')) table.AddRow([apply(Container, welcome)]) table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2) if advertised: table.AddRow([' ', ' ']) table.AddRow([ Bold(FontAttr(_('List'), size='+2')), Bold(FontAttr(_('Description'), size='+2')) ]) highlight = 1 for url, real_name, description in advertised: table.AddRow([ Link(url, Bold(real_name)), description or Italic(_('[no description available]')) ]) if highlight and mm_cfg.WEB_HIGHLIGHT_COLOR: table.AddRowInfo(table.GetCurrentRowIndex(), bgcolor=mm_cfg.WEB_HIGHLIGHT_COLOR) highlight = not highlight doc.AddItem(table) doc.AddItem('<hr>') doc.AddItem(MailmanLogo()) print doc.Format()
def listinfo_overview(msg=''): # Present the general listinfo overview hostname = Utils.get_domain() # Set up the document and assign it the correct language. The only one we # know about at the moment is the server's default. doc = Document() doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) legend = _("%(hostname)s Mailing Lists") doc.SetTitle(legend) table = Table(border=0, width="100%") table.AddRow([Center(Header(2, legend))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR) # Skip any mailing lists that isn't advertised. advertised = [] listnames = Utils.list_names() listnames.sort() for name in listnames: mlist = MailList.MailList(name, lock=0) if mlist.advertised: if mm_cfg.VIRTUAL_HOST_OVERVIEW and \ mlist.web_page_url.find(hostname) == -1: # List is for different identity of this host - skip it. continue else: advertised.append((mlist.GetScriptURL('listinfo'), mlist.real_name, mlist.description)) if msg: greeting = FontAttr(msg, color="ff5060", size="+1") else: greeting = FontAttr(_('Welcome!'), size='+2') welcome = [greeting] mailmanlink = Link(mm_cfg.MAILMAN_URL, _('Mailman')).Format() if not advertised: welcome.extend( _('''<p>There currently are no publicly-advertised %(mailmanlink)s mailing lists on %(hostname)s.''')) else: welcome.append( _('''<p>Below is a listing of all the public mailing lists on %(hostname)s. Click on a list name to get more information about the list, or to subscribe, unsubscribe, and change the preferences on your subscription.''')) # set up some local variables adj = msg and _('right') or '' siteowner = Utils.get_site_email() welcome.extend( (_(''' To visit the general information page for an unadvertised list, open a URL similar to this one, but with a '/' and the %(adj)s list name appended. <p>List administrators, you can visit '''), Link(Utils.ScriptURL('admin'), _('the list admin overview page')), _(''' to find the management interface for your list. <p>If you are having trouble using the lists, please contact '''), Link('mailto:' + siteowner, siteowner), '.<p>')) welcome.extend( (_('''Users who are subscribed to one of the Mailing List can use OpenID to login with common credentials, to access all their subscribed List. <p> To register OpenID '''), Link(Utils.ScriptURL('openidreg'), _('Click Here')), _(''' to use OpenID for Systers'''), '.<p>')) table.AddRow([apply(Container, welcome)]) table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2) if advertised: table.AddRow([' ', ' ']) table.AddRow([Bold(FontAttr(_('List'), size='+2')), Bold(FontAttr(_('Description'), size='+2')) ]) highlight = 1 for url, real_name, description in advertised: table.AddRow( [Link(url, Bold(real_name)), description or Italic(_('[no description available]'))]) if highlight and mm_cfg.WEB_HIGHLIGHT_COLOR: table.AddRowInfo(table.GetCurrentRowIndex(), bgcolor=mm_cfg.WEB_HIGHLIGHT_COLOR) highlight = not highlight doc.AddItem(table) doc.AddItem('<hr>') doc.AddItem(MailmanLogo()) print doc.Format()
from Mailman import i18n from Mailman.UserDesc import UserDesc from Mailman.ListAdmin import readMessage from email.Iterators import typed_subpart_iterator uid = getpwnam(mm_cfg.MAILMAN_USER)[2] gid = getgrnam(mm_cfg.MAILMAN_GROUP)[2] if not os.getuid(): os.setregid(gid, gid) os.setreuid(uid, uid) if (os.getuid() is not uid) or (os.getgid() is not gid): sys.exit(0) for listname in Utils.list_names(): try: mlist = MailList.MailList(listname, lock=0) except: print 'ERROR for ' + listname continue try: mlist.Lock() ############################################ # do treatement here ############################################ mlist.Save() mlist.Unlock() print 'OK for ' + listname
from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler import paths from Mailman import MailList from Mailman import Utils from Mailman import Message from Mailman import Errors from Mailman import mm_cfg from Mailman import i18n from Mailman.UserDesc import UserDesc from Mailman.ListAdmin import readMessage from email.Iterators import typed_subpart_iterator names = Utils.list_names() for listname in names: try: mlist = MailList.MailList(listname, lock=0) except: print 'ERROR ' + listname continue try: print 'BEGIN ' + listname mlist.Lock() mlist.header_filter_rules = [] mlist.header_filter_rules.append( ('X-Spam-Flag: Yes, tests=bogofilter', mm_cfg.HOLD, False)) print ' set new bogofilter policy' mlist.Save() mlist.Unlock()