def setUp(self): self.stream = StringIO() handler = Debugging(self.stream) controller = Controller(handler) controller.start() self.addCleanup(controller.stop) self.address = (controller.hostname, controller.port)
def setUp(self): # There are two controllers and two SMTPd's running here. The # "upstream" one listens on port 9025 and is connected to a "data # handler" which captures the messages it receives. The second -and # the one under test here- listens on port 9024 and proxies to the one # on port 9025. Because we need to set the decode_data flag # differently for each different test, the controller of the proxy is # created in the individual tests, not in the setup. self.upstream = DataHandler() upstream_controller = Controller(self.upstream, port=9025) upstream_controller.start() self.addCleanup(upstream_controller.stop) self.proxy = Proxy(upstream_controller.hostname, 9025) self.source = """\ From: Anne Person <*****@*****.**> To: Bart Person <*****@*****.**> Subject: A test Testing """ # The upstream SMTPd will always receive the content as bytes # delimited with CRLF. self.expected = CRLF.join([ 'From: Anne Person <*****@*****.**>', 'To: Bart Person <*****@*****.**>', 'Subject: A test', 'X-Peer: ::1', '', 'Testing']).encode('ascii')
def test_mail_with_compatible_smtputf8(self): handler = ReceivingHandler() controller = Controller(handler) controller.start() self.addCleanup(controller.stop) recipient = 'bart\[email protected]' sender = 'anne\[email protected]' with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') client.send(bytes( 'MAIL FROM: <' + sender + '> SMTPUTF8\r\n', encoding='utf-8')) code, response = client.getreply() self.assertEqual(code, 250) self.assertEqual(response, b'OK') client.send(bytes( 'RCPT TO: <' + recipient + '>\r\n', encoding='utf-8')) code, response = client.getreply() self.assertEqual(code, 250) self.assertEqual(response, b'OK') code, response = client.data('') self.assertEqual(code, 250) self.assertEqual(response, b'OK') self.assertEqual(handler.box[0].rcpt_tos[0], recipient) self.assertEqual(handler.box[0].mail_from, sender)
def test_real_mail_aiosmtpd(self): """ Test sending messages with a real-world SMTPD server """ if aiosmtpd is None: self.skipTest('aiosmtpd not available') # Start an smtp server mail_handler = StashingHandler() controller = Controller(mail_handler, loop=None, hostname='localhost', port=self.smtpd_port) controller.start() # Give it time to settle sleep(0.5) # Initialize a Postman postman = Postman('*****@*****.**', NoLoginSMTP('localhost', self.smtpd_port, None, None)) # Send messages with postman.connect() as c: # Send plaintext message msg = Message(['*****@*****.**'], 'Subject', 'HTML message') c.sendmail(msg) # Send unicode message msg = Message(['*****@*****.**'], u'Håkon', u'Håkon') c.sendmail(msg) # Done controller.stop() # Test self.assertEqual(len(mail_handler.mail), 2)
def test_socket_error(self): # Testing starting a server with a port already in use s1 = Controller(Sink(), port=8025) s2 = Controller(Sink(), port=8025) self.addCleanup(s1.stop) self.addCleanup(s2.stop) s1.start() self.assertRaises(socket.error, s2.start)
def test_helo_hook(self): controller = Controller(HELOHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.helo('me') self.assertEqual(code, 250) self.assertEqual(response, b'geddy.example.com')
def test_smtp_utf8(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.ehlo('example.com') self.assertEqual(code, 250) self.assertIn(b'SMTPUTF8', response.splitlines())
def test_server_attribute(self): controller = Controller(Sink()) self.assertIsNone(controller.server) try: controller.start() self.assertIsNotNone(controller.server) finally: controller.stop() self.assertIsNone(controller.server)
def test_default_greeting(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP() as client: code, msg = client.connect(controller.hostname, controller.port) self.assertEqual(code, 220) # The hostname prefix is unpredictable. self.assertEqual(msg[-len(GREETING):], bytes(GREETING, 'utf-8'))
def setUp(self): self.tempdir = TemporaryDirectory() self.addCleanup(self.tempdir.cleanup) self.maildir_path = os.path.join(self.tempdir.name, 'maildir') self.handler = handler = Mailbox(self.maildir_path) controller = Controller(handler) controller.start() self.addCleanup(controller.stop) self.address = (controller.hostname, controller.port)
def test_ehlo_hook(self): controller = Controller(EHLOHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.ehlo('me') self.assertEqual(code, 250) lines = response.decode('utf-8').splitlines() self.assertEqual(lines[-1], 'alex.example.com')
def test_mail_hook(self): controller = Controller(MAILHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.helo('me') code, response = client.mail('*****@*****.**') self.assertEqual(code, 250) self.assertEqual(response, b'Yeah, sure')
def test_mail_with_unrequited_smtputf8(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') code, response = client.docmd('MAIL FROM: <*****@*****.**>') self.assertEqual(code, 250) self.assertEqual(response, b'OK')
def test_mail_with_incompatible_smtputf8(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') code, response = client.docmd( 'MAIL FROM: <*****@*****.**> SMTPUTF8=YES') self.assertEqual(code, 501) self.assertEqual(response, b'Error: SMTPUTF8 takes no arguments')
def test_mail_invalid_body(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') code, response = client.docmd( 'MAIL FROM: <*****@*****.**> BODY 9BIT') self.assertEqual(code, 501) self.assertEqual(response, b'Error: BODY can only be one of 7BIT, 8BITMIME')
def test_deliver_bytes(self): with ExitStack() as resources: controller = Controller(self.proxy, port=9024) controller.start() resources.callback(controller.stop) client = resources.enter_context( SMTP(*(controller.hostname, controller.port))) client.sendmail( '*****@*****.**', ['*****@*****.**'], self.source) client.quit() self.assertEqual(self.upstream.content, self.expected) self.assertEqual(self.upstream.original_content, self.expected)
class CapturingAiosmtpdServer: """An async SMTP server / context manager for testing RPC effects.""" def __init__(self): self.messages = [] self.handler = CapturingAiosmtpdHandler(context=self) self.controller = Controller( handler=self.handler, hostname="localhost", port=10025) def __enter__(self): self.controller.start() return self def __exit__(self, *exc): self.controller.stop()
def test_no_hooks(self): controller = Controller(NoHooksHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.helo('me') client.mail('*****@*****.**') client.rcpt(['*****@*****.**']) code, response = client.data("""\ From: [email protected] To: [email protected] Subject: Test """) self.assertEqual(code, 250)
def test_rcpt_hook(self): controller = Controller(RCPTHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: with self.assertRaises(SMTPRecipientsRefused) as cm: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: [email protected] To: [email protected] Subject: Test """) self.assertEqual(cm.exception.recipients, { '*****@*****.**': (550, b'Rejected'), })
def test_data_hook(self): controller = Controller(DATAHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: with self.assertRaises(SMTPDataError) as cm: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: [email protected] To: [email protected] Subject: Test Yikes """) self.assertEqual(cm.exception.smtp_code, 599) self.assertEqual(cm.exception.smtp_error, b'Not today')
def test_process_message_error(self): controller = Controller(ErroringHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.ehlo('example.com') self.assertEqual(code, 250) with self.assertRaises(SMTPDataError) as cm: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: [email protected] To: [email protected] Subject: A test Testing """) self.assertEqual(cm.exception.smtp_code, 499) self.assertEqual(cm.exception.smtp_error, b'Could not accept the message')
def test_message(self): # In this test, the message content comes in as a bytes. handler = DataHandler() controller = Controller(handler) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: Anne Person <*****@*****.**> To: Bart Person <*****@*****.**> Subject: A test Message-ID: <ant> Testing """) # The content is not converted, so it's bytes. self.assertEqual(handler.content, handler.original_content) self.assertIsInstance(handler.content, bytes) self.assertIsInstance(handler.original_content, bytes)
def test_message(self): # In this test, the message data comes in as bytes. controller = Controller(self.handler) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: Anne Person <*****@*****.**> To: Bart Person <*****@*****.**> Subject: A test Message-ID: <ant> Testing """) self.assertEqual(self.handled_message['subject'], 'A test') self.assertEqual(self.handled_message['message-id'], '<ant>') self.assertIsNotNone(self.handled_message['X-Peer']) self.assertEqual( self.handled_message['X-MailFrom'], '*****@*****.**') self.assertEqual(self.handled_message['X-RcptTo'], '*****@*****.**')
def __init__(self): self.messages = [] self.handler = CapturingAiosmtpdHandler(context=self) self.controller = Controller( handler=self.handler, hostname="localhost", port=10025)
def setUp(self): controller = Controller(Sink) controller.start() self.addCleanup(controller.stop) self.address = (controller.hostname, controller.port)
async def smtpd_main(self, hostname, port): cont = Controller(self, hostname=hostname, port=port) cont.start()
def __init__(self, port=settings.SMTP_INBOUND_PORT) -> None: self.controller = Controller(self, hostname="0.0.0.0", port=port) super().__init__()
database.update_state(database.open_db(), 23, job_id) print('waiting for payment') hashtx, _ = ensicoin.wait_for_pubkey(pk1) print('hashtx: ', hashtx) ensicoin.send_to(10, hashtx, 0, sk1, 42, pk2, [job_id, "'" + json.dumps(split.generate_id_tuple(cut_segments)) + "'"], job_id) print('payment sent') database.update_state(database.open_db(), 24, job_id) return '250 Message accepted for delivery' if __name__ == "__main__": controller = Controller(Handler(), hostname="0.0.0.0") controller.start() while True: time.sleep(1)
data = json.dumps({ "subject": message["subject"], "from": message["from"], "message": message_content, "attachments": attachments }) self.mqtt.publish("printer/print", data) return '250 Message accepted for delivery' if __name__ == "__main__": client = mqtt.Client() client.on_connect = on_connect client.connect(os.getenv("MQTT_SERVER", "172.30.2.3"), 1883, 60) controller = Controller(TelegraphHandler(client), hostname='0.0.0.0', port=25) controller.start() print("SMTP server started", flush=True) while True: try: client.loop() except (KeyboardInterrupt, SystemExit): print("Bye!", flush=True) break controller.stop()
async def amain(handler): cont = Controller(handler, hostname="localhost", port=10025) cont.start() return cont
break else: _logger.debug('no match found') return '500 Could not process your message' headers = {'User-Agent': 'EmailPing from ' + mail_from} url = f'{self.ping_url}{match.group(1)}' _logger.info('Calling Ping url: %s for address: %s', url, mail_from) requests.get(url, headers=headers) return '250 OK' async def health_check(): ping_url = os.getenv('PING_URL', 'https://healthcheck.io/ping/') ping_id = os.getenv('PING_ID', '101fcaa8-32c5-4281-936f-330412b7afa4') ping_timeout = int(os.getenv('PING_TIMEOUT', '60')) _logger.info('Reporting own health to: %s', f'{ping_url}{ping_id}') while True: requests.get(f'{ping_url}{ping_id}') await asyncio.sleep(ping_timeout) if __name__ == '__main__': handler = CustomHandler() controller = Controller(handler, hostname='0.0.0.0', port=10025) # Run the event loop in a separate thread. controller.start() # Wait for the user to press Return. loop = asyncio.get_event_loop() loop.create_task(health_check()) loop.run_forever()
async def start(self): from aiosmtpd.controller import Controller _LOGGER.info("Setting up mailserver " + self._server + ":" + str(self._port)) controller = Controller(self, hostname=self._server, port=self._port) controller.start()
class MailQueueServer(object): def __init__(self, queue_host, queue_port, mail_host, mail_port): # message queue variables self._queue_host = queue_host self._queue_port = queue_port self.context = None self.publisher = None # mail server variables self._mail_host = mail_host self._mail_port = mail_port self.handler = None self.controller = None # store emails for debugging self._store_emails = False self.queue = None @property def store_emails(self): return self._store_emails @store_emails.setter def store_emails(self, value): if type(value) is not bool: raise Exception("bad value: should be bool") self._store_emails = value def start(self): # Prepare our message queue context and publisher self.context = zmq.asyncio.Context() self.publisher = self.context.socket(zmq.PUB) self.publisher.bind("tcp://{0}:{1}".format(self._queue_host, self._queue_port)) # setup the debug queue if self.store_emails is True and self.queue is None: self.queue = asyncio.Queue() # Prepare the mail server handler and controller self.handler = ZeroMQHandler(self.publisher, self.queue) self.controller = Controller(self.handler, hostname=self._mail_host, port=self._mail_port) self.controller.start() def stop(self): # stop/reset the mail server self.controller.stop() self.controller = None self.handler = None # tear down the debug queue self.queue = None # tear down the message queue self.publisher.close() self.publisher = None self.context.term() self.context = None def __enter__(self): logging.debug('Entering context') self.start() return self def __exit__(self, exc_type, exc_value, traceback): logging.debug('Exiting context') self.stop()
class MailerTest(AsyncTestCase): async def setUpAsync(self) -> None: await super().setUpAsync() self.smtp_handler = DummySMTPHandler() self.smtp = Controller(self.smtp_handler) self.smtp.start() config = TEST_CONFIG.copy() config.update({ "email": { "host": self.smtp.hostname, "port": self.smtp.port, "address": "*****@*****.**", } }) self.mailer_config = Config.from_dict(config) self.mailer = Mailer(config=self.mailer_config) self.mailer_task = asyncio.create_task(self.mailer.run()) self.user_service = UserService(db_pool=self.db_pool, config=self.mailer_config) async def tearDownAsync(self) -> None: await super().tearDownAsync() self.mailer_task.cancel() self.smtp.stop() async def test_registration_mail_delivery(self): user_email = "*****@*****.**" await self.user_service.register_user("user1", user_email, "password") await asyncio.sleep(0.5) mail: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait() self.assertIsNotNone(mail) self.assertIn(user_email, mail.rcpt_tos) self.assertIn("[Test Abrechnung] Confirm user account", mail.content.decode("utf-8")) async def test_email_change_mail_delivery(self): user_email = "*****@*****.**" new_email = "*****@*****.**" user_id, password = await self._create_test_user(username="******", email=user_email) await self.user_service.request_email_change(user_id=user_id, password=password, email=new_email) await asyncio.sleep(0.5) mail1: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait() self.assertIsNotNone(mail1) mail2: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait() self.assertIsNotNone(mail2) self.assertTrue(user_email in mail1.rcpt_tos or mail2.rcpt_tos) self.assertTrue(new_email in mail1.rcpt_tos or mail2.rcpt_tos) self.assertIn("[Test Abrechnung] Change email", mail1.content.decode("utf-8")) self.assertIn("[Test Abrechnung] Change email", mail2.content.decode("utf-8")) async def test_password_reset_mail_delivery(self): user_email = "*****@*****.**" await self._create_test_user(username="******", email=user_email) await self.user_service.request_password_recovery(email=user_email) await asyncio.sleep(0.5) mail: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait() self.assertIsNotNone(mail) self.assertIn(user_email, mail.rcpt_tos) self.assertIn("[Test Abrechnung] Reset password", mail.content.decode("utf-8"))
async def amain(loop): cont = Controller(Sink(), hostname='', port=8025) cont.start()
from smtpx import CrazySrvHandler from web import web_start from aiosmtpd.controller import Controller from aiosmtpd.smtp import SMTP import configparser if __name__ == "__main__": cf = configparser.ConfigParser() cf.read("cfg.ini") smtpd_host = cf.get("smtpd", "host") smtpd_port = cf.getint("smtpd", "port") rest_host = smtpd_host rest_port = cf.getint("rest", "port") handler = CrazySrvHandler() controller = Controller(handler, hostname=smtpd_host, port=smtpd_port) controller.factory = lambda: SMTP(handler, enable_SMTPUTF8=True) try: controller.start() web_start(rest_host, rest_port) except KeyboardInterrupt: print("Shutting down") finally: controller.stop()
def test_socket_error_default(self): contr1 = Controller(Sink()) contr2 = Controller(Sink()) expectedre = r"error while attempting to bind on address" try: with pytest.raises(socket.error, match=expectedre): contr1.start() contr2.start() finally: contr2.stop() contr1.stop()
def threaded_smtpd_server(request, hostname, port, smtpd_handler): controller = Controller(smtpd_handler, hostname=hostname, port=port) controller.start() request.addfinalizer(controller.stop) return controller.server
async def startService(loop): controller = Controller(smtpHandler(), hostname='127.0.0.1', port=25) controller.start()
def test_stop_noassert(self): controller = Controller(Sink()) controller.stop(no_assert=True)
def test_stop_assert(self): controller = Controller(Sink()) with pytest.raises(AssertionError, match="SMTP daemon not running"): controller.stop(no_assert=False)
config = configparser.ConfigParser() config.read(config_path) use_auth = config.getboolean('remote', 'smtp_auth', fallback=False) if use_auth: auth = { 'user': config.get('remote', 'smtp_auth_user'), 'password': config.get('remote', 'smtp_auth_password') } else: auth = None controller = Controller( MailProxyHandler( host=config.get('remote', 'host', fallback='0.0.0.0'), port=config.getint('remote', 'port', fallback=25), auth=auth, #use_ssl=config.getboolean('remote', 'use_ssl',fallback=False), starttls=config.getboolean('remote', 'starttls', fallback=False), local_hostname=config.get('remote', 'local_hostname', fallback='mail.foo.com'), debug_level=config.getint('remote', 'debug_level', fallback=0)), hostname=config.get('local', 'host', fallback='email-smtp.us-west-2.amazonaws.com'), port=config.getint('local', 'port', fallback=587)) controller.start() while controller.loop.is_running(): sleep(0.2)
import asyncio from aiosmtpd.controller import Controller class CustomHandler: async def handle_DATA(self, server, session, envelope): peer = session.peer mail_from = envelope.mail_from rcpt_tos = envelope.rcpt_tos data = envelope.content # type: bytes print('peer:', peer) print('mail_from:', mail_from) print('rcpt_tos:', rcpt_tos) print('data:', data) # Process message data... # if error_occurred: # return '500 Could not process your message' return '250 OK' if __name__ == '__main__': handler = CustomHandler() controller = Controller(handler, hostname='127.0.0.1', port=10025) print('SMTP server:', controller.hostname, controller.port) # Run the event loop in a separate thread. controller.start() # Wait for the user to press Return. input('SMTP server running. Press Return to stop server and exit.') controller.stop()
class SmtpServer: def __init__(self, port=settings.SMTP_INBOUND_PORT) -> None: self.controller = Controller(self, hostname="0.0.0.0", port=port) super().__init__() def parse_message_id(self, raw_message_id): parts = raw_message_id.split("@") if len(parts) > 1: try: return UUID(parts[0].replace("<", "")) except: return None return None def get_ticket(self, message): if "Message-ID" not in message: return None, None message_id = self.parse_message_id(message["Message-ID"]) if not message_id: return None, None return Ticket.objects.filter( Q(reply_message_id=message_id) | Q(comment_message_id=message_id)).first(), message_id @sync_to_async def handle_RCPT(self, server, session, envelope, address, rcpt_options): if not Inbox.objects.filter(email=address).exists(): return '550 not relaying to that domain' envelope.rcpt_tos.append(address) return '250 OK' @sync_to_async def handle_DATA(self, server, session, envelope): mail_from = envelope.mail_from message = BytesParser(policy=policy.default).parsebytes( envelope.content) body = message.get_body(preferencelist=('plain', )) if body: content = body.get_content() reply = EmailReplyParser.parse_reply(content) author, _ = User.objects.get_or_create(email=mail_from) ticket, message_id = self.get_ticket(message) if ticket: if not ticket.inbox.enable_reply_by_email: return '450 Reply by email is disabled for the inbox' Comment.objects.create( ticket=ticket, author=author, is_reply=ticket.reply_message_id == message_id, content=reply) UserInbox.objects.get_or_create(user=author, inbox=ticket.inbox) else: inbox = Inbox.objects.get(email__in=envelope.rcpt_tos, ) if not inbox.enable_create_new_ticket_by_email: return '450 Creation of ticket by email is disabled for the inbox' Ticket.objects.create(author=author, inbox=inbox, title=message["Subject"], content=reply) UserInbox.objects.get_or_create(user=author, inbox=inbox) return '250 OK' def start(self): try: self.controller.stop() except: pass try: self.controller.start() print("SMTP server started on port {}".format( settings.SMTP_INBOUND_PORT)) except: pass def stop(self): self.controller.stop()
async def main(): controller = Controller(MessageHandler(), port=25) controller.start()
def __init__(self, port): handler = InMemorySMTPServer.ReceivingHandler(self) InMemorySMTPServerBase.__init__(self, port) Controller.__init__(self, handler, hostname='127.0.0.1', port=port, enable_SMTPUTF8=False) self.start()
else: smtp = SMTP(POSTFIX_SERVER, 25) msg = Parser(policy=SMTPUTF8).parsestr(message_data) for rcpt_to in envelope.rcpt_tos: # Reply case # recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix if rcpt_to.startswith("reply+") or rcpt_to.startswith("ra+"): LOG.debug("Reply phase") app = new_app() with app.app_context(): return handle_reply(envelope, smtp, msg, rcpt_to) else: # Forward case LOG.debug("Forward phase") app = new_app() with app.app_context(): return handle_forward(envelope, smtp, msg, rcpt_to) if __name__ == "__main__": controller = Controller(MailHandler(), hostname="0.0.0.0", port=20381) controller.start() LOG.d("Start mail controller %s %s", controller.hostname, controller.port) while True: time.sleep(2)
def __init__(self): self.messages = [] self.handler = CapturingAiosmtpdHandler(context=self) self.controller = Controller(handler=self.handler, hostname="localhost", port=10025)
def test_hostname_none(self): cont = Controller(Sink()) try: cont.start() finally: cont.stop()
async def amain(loop): handler = FixerHandler() controller = Controller(handler, hostname="0.0.0.0", port=8025) controller.start()
application = tornado.web.Application( [ # Health Checks (r'/healthcheck', HealthCheckHandler), ], debug=(os.environ.get('DEBUG_MODE') == 'devel'), **APP_SETTINGS) #=============================================================================== #=============================================================================== if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('--port', help='Server Port') parser.add_argument('--smtpport', help='SMTP Port') args = parser.parse_args() # Begin SMTP server smtp_server = Controller(SMTPHandler(), hostname='0.0.0.0', port=int(args.smtpport)) smtp_server.start() # Begin Web server http_server = tornado.httpserver.HTTPServer(application) http_server.listen(int(args.port)) IOLoop.instance().start() #=============================================================================== #===============================================================================
def init_db(self): print(f"use db {self.db}") conn = sqlite3.connect(self.db) cur = conn.cursor() sql = f""" create table if not exists {self.table_name}( id INTEGER PRIMARY KEY autoincrement, email_from VARCHAR(255), email_to VARCHAR(255), email_title VARCHAR(512), dt TEXT, email_raw TEXT, has_attach INTEGER not null ) """ cur.execute(sql) conn.commit() cur.close() conn.close() if __name__=='__main__': try: controller = Controller(DataHandler("~/mailbox", 'fake_mail.db', "fake_mail"), hostname='0.0.0.0', port=25) controller.start() start_web("0.0.0.0", "9080") except KeyboardInterrupt: print("smtpd quit!")
'body': message.body, 'data': content, 'timestamp': datetime.utcnow().isoformat() }, open_file) return '250 OK' except Exception: return '500 Could not process your message' if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('host', type=str) parser.add_argument('port', type=int) args = parser.parse_args() handler = Handler() controller = Controller(handler, hostname=args.host, port=args.port) # noinspection PyBroadException try: controller.start() pid = str(os.getpid()) pidfile = "/run/postoffice/postoffice.pid" open(pidfile, 'w').write(pid) print("Running smtpd server on {}:{}\n".format(args.host, args.port)) while True: time.sleep(3) except Exception as exc: print(exc, file=sys.stderr) controller.stop() finally: os.unlink(pidfile)
async def amain(loop): cont = Controller(Sink(), hostname='::0', port=8025) cont.start()
config_path = os.path.join(sys.path[0], 'config.ini') if not os.path.exists(config_path): raise Exception("Config file not found: {}".format(config_path)) config = configparser.ConfigParser() config.read(config_path) use_auth = config.getboolean('remote', 'smtp_auth', fallback=False) if use_auth: auth = { 'user': config.get('remote', 'smtp_auth_user'), 'password': config.get('remote', 'smtp_auth_password') } else: auth = None controller = Controller(MailProxyHandler( host=config.get('remote', 'host'), port=config.getint('remote', 'port', fallback=25), auth=auth, use_ssl=config.getboolean('remote', 'use_ssl', fallback=False), starttls=config.getboolean('remote', 'starttls', fallback=False), ), hostname=config.get('local', 'host', fallback='127.0.0.1'), port=config.getint('local', 'port', fallback=25)) controller.start() while controller.loop.is_running(): sleep(0.2)