Use these functions to produce variable times rather than the built-in datetime.datetime.now() and datetime.date.today(). These are better instrumented for testing purposes. """ import datetime from mailman import public from mailman.testing import layers # Python always sets the locale to 'C' locale unless the user explicitly calls # locale.setlocale(locale.LC_ALL, ''). Since we never do this in Mailman (and # no library better do it either!) this will safely give us expected RFC 5322 # Date headers. public(RFC822_DATE_FMT='%a, %d %b %Y %H:%M:%S %z') # Definition of UTC timezone, taken from # http://docs.python.org/library/datetime.html ZERO = datetime.timedelta(0) @public class UTC(datetime.tzinfo): def utcoffset(self, dt): return ZERO def tzname(self, dt): return 'UTC'
# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>. """General Mailman doc tests.""" from mailman import public from mailman.testing.layers import ConfigLayer public(layer=ConfigLayer)
# 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 <http://www.gnu.org/licenses/>. """Autoresponder.""" from datetime import timedelta from enum import Enum from mailman import public from zope.interface import Attribute, Interface public(ALWAYS_REPLY=timedelta()) @public class Response(Enum): # Your message was held for approval. hold = 1 # Email commands, i.e. -request messages. command = 2 # Messages to the list owner/administrator. owner = 3 # Messages to the list's posting address. postings = 4 @public
# 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 <http://www.gnu.org/licenses/>. """System information.""" import sys from mailman import public, version from mailman.interfaces.system import ISystem from zope.interface import implementer @implementer(ISystem) class System: """See `ISystem`.""" @property def mailman_version(self): """See `ISystem`.""" return version.MAILMAN_VERSION_FULL @property def python_version(self): """See `ISystem`.""" return sys.version public(system=System())
Use these functions to produce variable times rather than the built-in datetime.datetime.now() and datetime.date.today(). These are better instrumented for testing purposes. """ import datetime from mailman import public from mailman.testing import layers # Python always sets the locale to 'C' locale unless the user explicitly calls # locale.setlocale(locale.LC_ALL, ''). Since we never do this in Mailman (and # no library better do it either!) this will safely give us expected RFC 5322 # Date headers. public(RFC822_DATE_FMT='%a, %d %b %Y %H:%M:%S %z') # Definition of UTC timezone, taken from # http://docs.python.org/library/datetime.html ZERO = datetime.timedelta(0) @public class UTC(datetime.tzinfo): def utcoffset(self, dt): return ZERO def tzname(self, dt): return 'UTC' def dst(self, dt):
# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>. """Doctest layer setup.""" from mailman import public from mailman.testing.layers import RESTLayer public(layer=RESTLayer)
# Copyright (C) 2014-2016 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 <http://www.gnu.org/licenses/>. """Alembic configuration initization.""" from alembic.config import Config from mailman import public from mailman.utilities.modules import expand_path public(alembic_cfg=Config(expand_path('python:mailman.config.alembic')))
# 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 <http://www.gnu.org/licenses/>. """Internationalization.""" import mailman.messages from flufl.i18n import PackageStrategy, registry from mailman import public from mailman.interfaces.configuration import ConfigurationUpdatedEvent public(_=None) @public def initialize(application=None): """Initialize the i18n subsystem. :param application: An optional `flufl.i18n.Application` instance to use as the translation context. This primarily exists to support the testing environment. :type application: `flufl.i18n.Application` """ global _ if application is None: strategy = PackageStrategy('mailman', mailman.messages) application = registry.register(strategy)
from mailman import public from mailman.config import config from sqlalchemy.ext.declarative import declarative_base class ModelMeta: """The custom metaclass for all model base classes. This is used in the test suite to quickly reset the database after each test. It works by iterating over all the tables, deleting each. The test suite will then recreate the tables before each test. """ @staticmethod def _reset(db): with closing(config.db.engine.connect()) as connection: transaction = connection.begin() try: # Delete all the tables in reverse foreign key dependency # order. http://tinyurl.com/on8dy6f for table in reversed(Model.metadata.sorted_tables): connection.execute(table.delete()) except: transaction.rollback() raise else: transaction.commit() Model = declarative_base(cls=ModelMeta) public(Model=Model)
# 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 <http://www.gnu.org/licenses/>. """Internationalization.""" import mailman.messages from flufl.i18n import PackageStrategy, registry from mailman import public from mailman.interfaces.configuration import ConfigurationUpdatedEvent public(_=None) @public def initialize(application=None): """Initialize the i18n subsystem. :param application: An optional `flufl.i18n.Application` instance to use as the translation context. This primarily exists to support the testing environment. :type application: `flufl.i18n.Application` """ global _ if application is None: strategy = PackageStrategy('mailman', mailman.messages) application = registry.register(strategy)
assert cls.httpd is None, 'Layer already set up' cls.httpd = HTTPServer(('localhost', 8180), TestableHandler) cls._thread = threading.Thread(target=cls.httpd.serve_forever) cls._thread.daemon = True cls._thread.start() wait_for_webservice('localhost', 8180) @classmethod def tearDown(cls): assert cls.httpd is not None, 'Layer not set up' cls.httpd.shutdown() cls.httpd.server_close() cls._thread.join() public(layer=HTTPLayer) # Response texts. WELCOME_1 = """\ Welcome to the "$list_name" mailing list! To post to this list, send your email to: $fqdn_listname There is a Code of Conduct for this mailing list which you can view at http://www.example.com/code-of-conduct.html """ WELCOME_2 = """\ I'm glad you made it!
import sys import mailman.config.config import mailman.core.logging from mailman import public from mailman.interfaces.database import IDatabaseFactory from mailman.utilities.modules import call_name from pkg_resources import resource_string as resource_bytes from zope.component import getUtility from zope.configuration import xmlconfig # The test infrastructure uses this to prevent the search and loading of any # existing configuration file. Otherwise the existence of say a # ~/.mailman.cfg file can break tests. public(INHIBIT_CONFIG_FILE=object()) def search_for_configuration_file(): """Search the file system for a configuration file to use. This is only called if the -C command line argument was not given. """ config_path = os.getenv('MAILMAN_CONFIG_FILE') # Both None and the empty string are considered "missing". if config_path and os.path.exists(config_path): return os.path.abspath(config_path) # ./mailman.cfg config_path = os.path.abspath('mailman.cfg') if os.path.exists(config_path): return config_path
import mailman.config.config import mailman.core.logging from mailman import public from mailman.interfaces.database import IDatabaseFactory from mailman.utilities.modules import call_name from pkg_resources import resource_string as resource_bytes from zope.component import getUtility from zope.configuration import xmlconfig # The test infrastructure uses this to prevent the search and loading of any # existing configuration file. Otherwise the existence of say a # ~/.mailman.cfg file can break tests. INHIBIT_CONFIG_FILE = object() public(INHIBIT_CONFIG_FILE=INHIBIT_CONFIG_FILE) def search_for_configuration_file(): """Search the file system for a configuration file to use. This is only called if the -C command line argument was not given. """ config_path = os.getenv('MAILMAN_CONFIG_FILE') # Both None and the empty string are considered "missing". if config_path and os.path.exists(config_path): return os.path.abspath(config_path) # ./mailman.cfg config_path = os.path.abspath('mailman.cfg') if os.path.exists(config_path): return config_path
from contextlib import closing from mailman import public from mailman.config import config from sqlalchemy.ext.declarative import declarative_base class ModelMeta: """The custom metaclass for all model base classes. This is used in the test suite to quickly reset the database after each test. It works by iterating over all the tables, deleting each. The test suite will then recreate the tables before each test. """ @staticmethod def _reset(db): with closing(config.db.engine.connect()) as connection: transaction = connection.begin() try: # Delete all the tables in reverse foreign key dependency # order. http://tinyurl.com/on8dy6f for table in reversed(Model.metadata.sorted_tables): # noqa connection.execute(table.delete()) except: transaction.rollback() raise else: transaction.commit() public(Model=declarative_base(cls=ModelMeta))
'list:admin:notice:unsubscribe', 'list:member:digest:masthead', 'list:user:action:subscribe', 'list:user:action:unsubscribe', 'list:user:notice:hold', 'list:user:notice:no-more-today', 'list:user:notice:post', 'list:user:notice:probe', 'list:user:notice:refuse', 'list:user:notice:welcome', } } # These have other names. ALL_TEMPLATES.update({ 'list:member:digest:footer': 'list:member:generic:footer.txt', 'list:member:regular:footer': 'list:member:generic:footer.txt', }) # These are some extra supported templates which don't have a mapping to a # file in the source tree. ALL_TEMPLATES.update({ 'list:member:digest:header': None, 'list:member:regular:header': None, 'list:user:notice:goodbye': None, }) public(ALL_TEMPLATES=ALL_TEMPLATES)
# Copyright (C) 2008-2016 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 <http://www.gnu.org/licenses/>. """Mailman configuration package.""" from mailman import public from mailman.config.config import Configuration public(config=Configuration())
# # 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 <http://www.gnu.org/licenses/>. """Autoresponder.""" from datetime import timedelta from enum import Enum from mailman import public from zope.interface import Attribute, Interface public(ALWAYS_REPLY=timedelta()) @public class Response(Enum): # Your message was held for approval. hold = 1 # Email commands, i.e. -request messages. command = 2 # Messages to the list owner/administrator. owner = 3 # Messages to the list's posting address. postings = 4 @public
"""Various constants and enumerations.""" from mailman import public from mailman.config import config from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.member import DeliveryMode, DeliveryStatus from mailman.interfaces.preferences import IPreferences from zope.component import getUtility from zope.interface import implementer @implementer(IPreferences) class SystemDefaultPreferences: """The default system preferences.""" acknowledge_posts = False hide_address = True receive_list_copy = True receive_own_postings = True delivery_mode = DeliveryMode.regular delivery_status = DeliveryStatus.enabled @property def preferred_language(self): """Return the system preferred language.""" return getUtility(ILanguageManager)[config.mailman.default_language] public(system_preferences=SystemDefaultPreferences())