Changeset 84
- Timestamp:
- 02/27/08 02:33:10 (9 months ago)
- Location:
- trunk
- Files:
-
- 14 modified
-
setup.py (modified) (1 diff)
-
tests/test_address_list.py (modified) (2 diffs)
-
tests/test_message.py (modified) (2 diffs)
-
turbomail/api.py (modified) (1 diff)
-
turbomail/control.py (modified) (1 diff)
-
turbomail/exceptions.py (modified) (1 diff)
-
turbomail/extensions/notification.py (modified) (1 diff)
-
turbomail/extensions/utf8qp.py (modified) (1 diff)
-
turbomail/managers/demand.py (modified) (1 diff)
-
turbomail/managers/immediate.py (modified) (1 diff)
-
turbomail/message.py (modified) (1 diff)
-
turbomail/providers/debug.py (modified) (1 diff)
-
turbomail/providers/smtp.py (modified) (1 diff)
-
turbomail/util.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/setup.py
r76 r84 62 62 63 63 setup( 64 name="TurboMail",65 version=version,66 67 description=description,68 long_description=long_description,69 author=author,70 author_email=email,71 url=url,72 download_url=download_url,73 license=license,74 75 install_requires = [76 "uuid >= 1.30"77 ],78 79 extras_require = {80 'turbogears': ["TurboMail-Gears >= 0.1"],81 'smime': ["TurboMail-SMIME >= 0.1"]82 },83 84 zip_safe=True,85 packages=find_packages(),86 package_data = find_package_data(where='turbomail', package='turbomail'),87 namespace_packages = [88 'turbomail',89 'turbomail.extensions',90 'turbomail.managers',91 'turbomail.providers',92 'turbomail.lib'93 ],94 classifiers = [95 'Development Status :: 5 - Production/Stable',96 'Framework :: TurboGears',97 'Intended Audience :: Developers',98 'License :: OSI Approved :: MIT License',99 'Operating System :: OS Independent',100 'Programming Language :: Python',101 'Topic :: Communications :: Email',102 'Topic :: Software Development :: Libraries :: Python Modules',103 ],104 test_suite = 'nose.collector',105 entry_points = {106 'turbomail.managers': [107 "demand = turbomail.managers.demand",108 # "polling = turbomail.managers.polling",109 "immediate = turbomail.managers.immediate"110 ],111 'turbomail.providers': [112 "smtp = turbomail.providers.smtp",113 # "sendmail = turbomail.providers.sendmail"114 # "disk = turbomail.providers.disk",115 "debug = turbomail.providers.debug"116 ],117 'turbomail.extensions': [118 "utf8qp = turbomail.extensions.utf8qp",119 # "notification = turbomail.extensions.notification",120 # "smime = turbomail.extensions.smime",121 # "gpg = turbomail.extensions.gpg",122 ]123 }124 )125 64 name="TurboMail", 65 version=version, 66 67 description=description, 68 long_description=long_description, 69 author=author, 70 author_email=email, 71 url=url, 72 download_url=download_url, 73 license=license, 74 75 install_requires = [ 76 "uuid >= 1.30" 77 ], 78 79 extras_require = { 80 'turbogears': ["TurboMail-Gears >= 0.1"], 81 'smime': ["TurboMail-SMIME >= 0.1"] 82 }, 83 84 zip_safe=True, 85 packages=find_packages(), 86 package_data = find_package_data(where='turbomail', package='turbomail'), 87 namespace_packages = [ 88 'turbomail', 89 'turbomail.extensions', 90 'turbomail.managers', 91 'turbomail.providers', 92 'turbomail.lib' 93 ], 94 classifiers = [ 95 'Development Status :: 5 - Production/Stable', 96 'Framework :: TurboGears', 97 'Intended Audience :: Developers', 98 'License :: OSI Approved :: MIT License', 99 'Operating System :: OS Independent', 100 'Programming Language :: Python', 101 'Topic :: Communications :: Email', 102 'Topic :: Software Development :: Libraries :: Python Modules', 103 ], 104 test_suite = 'nose.collector', 105 entry_points = { 106 'turbomail.managers': [ 107 "demand = turbomail.managers.demand", 108 # "polling = turbomail.managers.polling", 109 "immediate = turbomail.managers.immediate" 110 ], 111 'turbomail.providers': [ 112 "smtp = turbomail.providers.smtp", 113 # "sendmail = turbomail.providers.sendmail" 114 # "disk = turbomail.providers.disk", 115 "debug = turbomail.providers.debug" 116 ], 117 'turbomail.extensions': [ 118 "utf8qp = turbomail.extensions.utf8qp", 119 # "notification = turbomail.extensions.notification", 120 # "smime = turbomail.extensions.smime", 121 # "gpg = turbomail.extensions.gpg", 122 ] 123 } 124 ) 125 -
trunk/tests/test_address_list.py
r80 r84 8 8 from turbomail.util import AddressList 9 9 try: 10 from email.mime.text import MIMEText10 from email.mime.text import MIMEText 11 11 except ImportError: 12 # Python < 2.5 has no email.mime module13 from email.MIMEText import MIMEText12 # Python < 2.5 has no email.mime module 13 from email.MIMEText import MIMEText 14 14 15 15 import logging … … 18 18 19 19 class TestAddressList(unittest.TestCase): 20 """Test the AddressList helper class."""21 22 addresses = AddressList.protected('_addresses')23 24 def setUp(self):25 self._addresses = AddressList()26 27 # Helper function to avoid repitition.28 def check(self, addresses, string):29 self.assertEqual(self.addresses, addresses)30 self.assertEqual(str(self.addresses), string)31 32 def test_assignment(self):33 self.assertEqual(self.addresses, [])34 35 # A single address.36 addresses = "user@example.com"37 self.addresses = addresses38 self.check([addresses], addresses)39 40 # A list of addresses.41 addresses = ["user1@example.com", "user2@example.com"]42 self.addresses = addresses43 self.check(addresses, ",\n ".join(addresses))44 45 # A single named address.46 addresses = ("Test User", "user@example.com")47 self.addresses = addresses48 self.check([addresses], "%s <%s>" % addresses)49 50 # A list of named addresses.51 addresses = [("Test User 1", "user1@example.com"), ("Test User 2", "user2@example.com")]52 self.addresses = addresses53 self.check(addresses, ",\n ".join(["%s <%s>" % i for i in addresses]))54 55 # Clean up our changes.56 del self.addresses57 58 def test_validation(self):59 self.addresses.append("user.name+test@example.com.info")60 self.addresses.append("eviluser@example.com\nTo: spammeduser@example.com\nFrom: spammeduser@example.com")61 self.assertEqual(str(self.addresses[-1]), "eviluser@example.com")62 63 self.assertRaises(ValueError, lambda: self.addresses.append("baduser.example.com"))64 self.assertRaises(ValueError, lambda: self.addresses.append("bad@user@example.com"))65 self.assertRaises(ValueError, lambda: self.addresses.append("bad-u+s+er@example.com"))66 self.assertRaises(ValueError, lambda: self.addresses.append("baduser@example"))67 68 del self.addresses20 """Test the AddressList helper class.""" 21 22 addresses = AddressList.protected('_addresses') 23 24 def setUp(self): 25 self._addresses = AddressList() 26 27 # Helper function to avoid repitition. 28 def check(self, addresses, string): 29 self.assertEqual(self.addresses, addresses) 30 self.assertEqual(str(self.addresses), string) 31 32 def test_assignment(self): 33 self.assertEqual(self.addresses, []) 34 35 # A single address. 36 addresses = "user@example.com" 37 self.addresses = addresses 38 self.check([addresses], addresses) 39 40 # A list of addresses. 41 addresses = ["user1@example.com", "user2@example.com"] 42 self.addresses = addresses 43 self.check(addresses, ",\n ".join(addresses)) 44 45 # A single named address. 46 addresses = ("Test User", "user@example.com") 47 self.addresses = addresses 48 self.check([addresses], "%s <%s>" % addresses) 49 50 # A list of named addresses. 51 addresses = [("Test User 1", "user1@example.com"), ("Test User 2", "user2@example.com")] 52 self.addresses = addresses 53 self.check(addresses, ",\n ".join(["%s <%s>" % i for i in addresses])) 54 55 # Clean up our changes. 56 del self.addresses 57 58 def test_validation(self): 59 self.addresses.append("user.name+test@example.com.info") 60 self.addresses.append("eviluser@example.com\nTo: spammeduser@example.com\nFrom: spammeduser@example.com") 61 self.assertEqual(str(self.addresses[-1]), "eviluser@example.com") 62 63 self.assertRaises(ValueError, lambda: self.addresses.append("baduser.example.com")) 64 self.assertRaises(ValueError, lambda: self.addresses.append("bad@user@example.com")) 65 self.assertRaises(ValueError, lambda: self.addresses.append("bad-u+s+er@example.com")) 66 self.assertRaises(ValueError, lambda: self.addresses.append("baduser@example")) 67 68 del self.addresses -
trunk/tests/test_message.py
r80 r84 8 8 from turbomail.message import Message 9 9 try: 10 from email.mime.text import MIMEText10 from email.mime.text import MIMEText 11 11 except ImportError: 12 # Python < 2.5 has no email.mime module13 from email.MIMEText import MIMEText12 # Python < 2.5 has no email.mime module 13 from email.MIMEText import MIMEText 14 14 15 15 import logging … … 18 18 19 19 class TestBasicMessage(unittest.TestCase): 20 """Test the basic output of the Message class."""20 """Test the basic output of the Message class.""" 21 21 22 def setUp(self):23 self.message = Message(24 author=("Author", "author@example.com"),25 to=("Recipient", "recipient@example.com"),26 subject="Test message subject.",27 plain="This is a test message plain text body."28 )29 30 def test_message_properties(self):31 self.assertEqual(self.message.author, [("Author", "author@example.com")])32 self.assertEqual(str(self.message.author), "Author <author@example.com>")33 self.failUnless(isinstance(self.message.mime, MIMEText))34 35 def test_message_string(self):36 self.failUnless("To: Recipient <recipient@example.com>" in str(self.message))37 self.failUnless("From: Author <author@example.com>" in str(self.message))38 self.failUnless("Subject: Test message subject." in str(self.message))39 self.failUnless("\n\nThis is a test message plain text body." in str(self.message))40 41 def test_mime_generation(self):42 mime = self.message.mime43 self.failUnless(self.message.mime is mime)44 self.message.subject = "Test message subject."45 self.failIf(self.message.mime is mime)46 47 def test_recipients_collection(self):48 self.message.cc.append("copied@example.com")49 self.assertEqual(self.message.recipients.addresses, ["recipient@example.com", "copied@example.com"])22 def setUp(self): 23 self.message = Message( 24 author=("Author", "author@example.com"), 25 to=("Recipient", "recipient@example.com"), 26 subject="Test message subject.", 27 plain="This is a test message plain text body." 28 ) 29 30 def test_message_properties(self): 31 self.assertEqual(self.message.author, [("Author", "author@example.com")]) 32 self.assertEqual(str(self.message.author), "Author <author@example.com>") 33 self.failUnless(isinstance(self.message.mime, MIMEText)) 34 35 def test_message_string(self): 36 self.failUnless("To: Recipient <recipient@example.com>" in str(self.message)) 37 self.failUnless("From: Author <author@example.com>" in str(self.message)) 38 self.failUnless("Subject: Test message subject." in str(self.message)) 39 self.failUnless("\n\nThis is a test message plain text body." in str(self.message)) 40 41 def test_mime_generation(self): 42 mime = self.message.mime 43 self.failUnless(self.message.mime is mime) 44 self.message.subject = "Test message subject." 45 self.failIf(self.message.mime is mime) 46 47 def test_recipients_collection(self): 48 self.message.cc.append("copied@example.com") 49 self.assertEqual(self.message.recipients.addresses, ["recipient@example.com", "copied@example.com"]) -
trunk/turbomail/api.py
r71 r84 11 11 12 12 class Extension(object): 13 name = "GenericExtension"14 version = "0.1"15 url = "http://www.python-turbomail.org/wiki/3.0/Extensions"16 17 def __init__(self):18 super(Extension, self).__init__()19 self.ready = False20 21 def start(self):22 self.ready = True23 24 return True25 26 def stop(self):27 if not self.ready: return False28 29 self.ready = False30 31 return True13 name = "GenericExtension" 14 version = "0.1" 15 url = "http://www.python-turbomail.org/wiki/3.0/Extensions" 16 17 def __init__(self): 18 super(Extension, self).__init__() 19 self.ready = False 20 21 def start(self): 22 self.ready = True 23 24 return True 25 26 def stop(self): 27 if not self.ready: return False 28 29 self.ready = False 30 31 return True 32 32 33 33 34 34 class ProviderFactory(Extension): 35 """docstring for ProviderFactory"""36 provider = None37 38 def __init__(self):39 super(ProviderFactory, self).__init__()40 41 def new(self):42 if not self.ready: return None43 return self.provider()35 """docstring for ProviderFactory""" 36 provider = None 37 38 def __init__(self): 39 super(ProviderFactory, self).__init__() 40 41 def new(self): 42 if not self.ready: return None 43 return self.provider() 44 44 45 45 46 46 class Provider(object): 47 """docstring for Provider"""48 def __init__(self):49 super(Provider, self).__init__()47 """docstring for Provider""" 48 def __init__(self): 49 super(Provider, self).__init__() 50 50 51 def deliver(self, message):52 raise NotImplementedError, "Provider plugin must override this method without inheritance."51 def deliver(self, message): 52 raise NotImplementedError, "Provider plugin must override this method without inheritance." 53 53 54 54 55 55 class Manager(Extension): 56 """docstring for Manager"""57 def __init__(self):58 super(Manager, self).__init__()59 60 def deliver(self, message):61 if not self.ready: return False62 return True56 """docstring for Manager""" 57 def __init__(self): 58 super(Manager, self).__init__() 59 60 def deliver(self, message): 61 if not self.ready: return False 62 return True 63 63 -
trunk/turbomail/control.py
r81 r84 34 34 35 35 class ControlClass(object): 36 """Control TurboMail startup and shutdown.37 38 Dynamically discovers the presence of TurboGears, creating appropriate aliases for39 TurboGears extension startup and shutdown."""40 41 def __init__(self):42 self.running = False43 self.extensions = dict()44 self.config = dict()45 self.manager = None46 self.provider = None47 48 def __load_single_entry(self, group, name):49 for entrypoint in pkg_resources.iter_entry_points(group, name):50 return entrypoint.load()51 return None52 53 def start(self):54 if not self.config.get("mail.on", False):55 return56 57 log.info("TurboMail extension starting up.")58 59 def load(t, default):60 extension = self.config.get("mail.%s" % t, default)61 controller = self.__load_single_entry("turbomail.%ss" % t, extension)62 if not controller:63 self.config.update({"mail.on": False})64 log.error("Unable to locate %s %s, TurboMail disabled." % (extension, t))65 self.stop(force=True)66 return67 setattr(self, t, controller)68 if hasattr(getattr(self, t), 'load'):69 setattr(self, t, getattr(self, t).load())70 if hasattr(getattr(self, t), 'start'):71 getattr(self, t).start()72 73 # Load the requested manager and provider.74 load('manager', 'immediate')75 load('provider', 'debug')76 77 # Load and initalize the various extensions.78 extensions = pkg_resources.iter_entry_points("turbomail.extensions")79 for entrypoint in extensions:80 log.debug("Found extension '%s'." % entrypoint.name)81 82 if self.config.get("mail.%s.on" % entrypoint.name, False):83 log.info("Loading extension '%s'." % entrypoint.name)84 85 self.extensions[entrypoint.name] = entrypoint.load()86 87 if hasattr(self.extensions[entrypoint.name], 'interface'):88 self.extensions[entrypoint.name] = self.extensions[entrypoint.name].interface89 90 elif hasattr(self.extensions[entrypoint.name], 'load'):91 self.extensions[entrypoint.name] = self.extensions[entrypoint.name].load()92 93 if hasattr(self.extensions[entrypoint.name], 'start'):94 self.extensions[entrypoint.name].start()95 96 self.running = True97 98 def stop(self, force=False):99 if not self.running and not force: return100 101 log.info("TurboMail extension shutting down.")102 103 # Unload the various extensions.104 extensions = pkg_resources.iter_entry_points("turbomail.extensions")105 for entrypoint in extensions:106 if self.config.get("mail." + entrypoint.name + ".on", False):107 ext = entrypoint.load()108 if hasattr(ext, "stop"): ext.stop()109 110 # Unload the provider and manager.111 if self.provider and hasattr(self.provider, "stop"): self.provider.stop()112 if self.manager and hasattr(self.manager, "stop"): self.manager.stop()113 114 self.provider = None115 self.manager = None116 117 self.running = False118 119 def send(self, message):120 if not self.manager:121 raise MailNotEnabledError36 """Control TurboMail startup and shutdown. 37 38 Dynamically discovers the presence of TurboGears, creating appropriate aliases for 39 TurboGears extension startup and shutdown.""" 40 41 def __init__(self): 42 self.running = False 43 self.extensions = dict() 44 self.config = dict() 45 self.manager = None 46 self.provider = None 47 48 def __load_single_entry(self, group, name): 49 for entrypoint in pkg_resources.iter_entry_points(group, name): 50 return entrypoint.load() 51 return None 52 53 def start(self): 54 if not self.config.get("mail.on", False): 55 return 56 57 log.info("TurboMail extension starting up.") 58 59 def load(t, default): 60 extension = self.config.get("mail.%s" % t, default) 61 controller = self.__load_single_entry("turbomail.%ss" % t, extension) 62 if not controller: 63 self.config.update({"mail.on": False}) 64 log.error("Unable to locate %s %s, TurboMail disabled." % (extension, t)) 65 self.stop(force=True) 66 return 67 setattr(self, t, controller) 68 if hasattr(getattr(self, t), 'load'): 69 setattr(self, t, getattr(self, t).load()) 70 if hasattr(getattr(self, t), 'start'): 71 getattr(self, t).start() 72 73 # Load the requested manager and provider. 74 load('manager', 'immediate') 75 load('provider', 'debug') 76 77 # Load and initalize the various extensions. 78 extensions = pkg_resources.iter_entry_points("turbomail.extensions") 79 for entrypoint in extensions: 80 log.debug("Found extension '%s'." % entrypoint.name) 81 82 if self.config.get("mail.%s.on" % entrypoint.name, False): 83 log.info("Loading extension '%s'." % entrypoint.name) 84 85 self.extensions[entrypoint.name] = entrypoint.load() 86 87 if hasattr(self.extensions[entrypoint.name], 'interface'): 88 self.extensions[entrypoint.name] = self.extensions[entrypoint.name].interface 89 90 elif hasattr(self.extensions[entrypoint.name], 'load'): 91 self.extensions[entrypoint.name] = self.extensions[entrypoint.name].load() 92 93 if hasattr(self.extensions[entrypoint.name], 'start'): 94 self.extensions[entrypoint.name].start() 95 96 self.running = True 97 98 def stop(self, force=False): 99 if not self.running and not force: return 100 101 log.info("TurboMail extension shutting down.") 102 103 # Unload the various extensions. 104 extensions = pkg_resources.iter_entry_points("turbomail.extensions") 105 for entrypoint in extensions: 106 if self.config.get("mail." + entrypoint.name + ".on", False): 107 ext = entrypoint.load() 108 if hasattr(ext, "stop"): ext.stop() 109 110 # Unload the provider and manager. 111 if self.provider and hasattr(self.provider, "stop"): self.provider.stop() 112 if self.manager and hasattr(self.manager, "stop"): self.manager.stop() 113 114 self.provider = None 115 self.manager = None 116 117 self.running = False 118 119 def send(self, message): 120 if not self.manager: 121 raise MailNotEnabledError 122 122
