aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2019-10-01 14:44:02 +0200
committerMatěj Cepl <mcepl@cepl.eu>2019-10-01 14:44:02 +0200
commitd6b4d3860c4b36d35b9a8a96dcdf49093a139650 (patch)
tree980bea91eda072344f47c29f7311ac9922c14497
parentc60e11ceba4fc9ac017e8b1c6a2f1eab810f2dc7 (diff)
downloadpyg-d6b4d3860c4b36d35b9a8a96dcdf49093a139650.tar.gz
A ways better.
Tentatively fixes #7
-rw-r--r--mail2news.py40
-rw-r--r--news2mail.py44
-rw-r--r--setup.py1
-rwxr-xr-xtest/test_pyg.py19
4 files changed, 61 insertions, 43 deletions
diff --git a/mail2news.py b/mail2news.py
index 386305b..dd4758c 100644
--- a/mail2news.py
+++ b/mail2news.py
@@ -15,7 +15,8 @@ Gets news email and sends it via SMTP.
class mail2news is hopefully conform to rfc850.
"""
-from StringIO import StringIO
+import argparse
+from io import StringIO
from collections import OrderedDict
import email
import logging
@@ -54,7 +55,11 @@ class mail2news(object):
self.hostname = gethostbyaddr(gethostname())[0]
self.heads_dict, self.smtpheads, self.nntpheads = {}, {}, {}
- self.message = self.__readfile(options)
+ if options.input == '':
+ self.message = self.__readfile(options, sys.stdin)
+ else:
+ with open(options.input, 'r') as inp_stream:
+ self.message = self.__readfile(options, inp_stream)
self.message['X-Gateway'] = 'pyg {0} {1}'.format(VERSION, DESC)
@@ -64,8 +69,8 @@ class mail2news(object):
if value:
msg[header] = value.strip()
- def __readfile(self, opt):
- message = email.message_from_file(sys.stdin)
+ def __readfile(self, opt, input_stream):
+ message = email.message_from_file(input_stream)
if (len(message) == 0) \
and message.get_payload().startswith('/'):
@@ -185,10 +190,10 @@ class mail2news(object):
server.quit()
-def parse_cmdline():
+def parse_cmdline(args):
parser = argparse.ArgumentParser(
description='%s version %s - Copyright 2000 Cosimo Alfarano\n%s' %
- ('pyg', mail2news.VERSION, mail2news.DESC))
+ ('pyg', VERSION, DESC))
parser.add_argument('-s', '--newsserver', default='')
parser.add_argument('-a', '--approver', default='',
@@ -201,7 +206,8 @@ def parse_cmdline():
parser.add_argument('-p', '--password', default='',
help='NNTP server password (for authentication)')
parser.add_argument('-P', '--port', default='')
- parser.add_argument('-e', '--envellope', default='')
+ parser.add_argument('-e', '--envelope', default='')
+ parser.add_argument('-i', '--input', default='')
parser.add_argument('-l', '--logfile')
parser.add_argument('-T', '--test', action='store_true',
@@ -210,7 +216,7 @@ def parse_cmdline():
help='verbose output ' +
'(usefull with -T option for debugging)')
- args = parser.parse_args()
+ args = parser.parse_args(args)
if not args.newsgroup:
raise argparse.ArgumentError('Error: Missing Newsgroups\n')
@@ -218,21 +224,22 @@ def parse_cmdline():
return args
-def main():
+def main(args=sys.argv[1:]):
"""main is structured in 4 phases:
1) check and set pyg's internal variables
2) check whitelist for users' permission
3) format rfc 822 headers from input article
4) open smtp connection and send e-mail
"""
+ out = ''
try:
"""phase 1:
check and set pyg's internal variables
"""
- opt = parse_cmdline()
+ opt = parse_cmdline(args)
- m2n = mail2news.mail2news(opt)
+ m2n = mail2news(opt)
owner = None
"""phase 3:
@@ -244,7 +251,7 @@ def main():
m2n.sortheads() # sort remaining heads :)
if opt.verbose:
- print(m2n.message.as_string())
+ out += m2n.message.as_string() + '\n'
logging.debug('m2n.payload = len %d', len(m2n.message.get_payload()))
if len(m2n.message.get_payload()) > 0:
@@ -253,7 +260,12 @@ def main():
try:
resp = m2n.sendemail()
except nntplib.NNTPError as ex:
- print(ex)
+ logging.exception(ex)
except KeyboardInterrupt:
- print('Keyboard Interrupt')
+ logging.error('Keyboard Interrupt')
sys.exit(0)
+
+ if opt.input == '':
+ print(out)
+ else:
+ return out
diff --git a/news2mail.py b/news2mail.py
index eecd701..a21e1ed 100644
--- a/news2mail.py
+++ b/news2mail.py
@@ -23,23 +23,27 @@ normal (what pygs does) operations flow is:
Date:, normal headers ending with X-* and Resent-* headers.
"""
-from collections import OrderedDict
+import argparse
+import os
+import os.path
+import collections
import email
from mail2news import VERSION, DESC
import smtplib
-from socket import gethostbyaddr, gethostname
+import socket
import sys
import time
+import whitelist
# logging.basicConfig(level=logging.DEBUG)
class news2mail(object):
"""news to mail gateway class"""
- def __init__(self, verbose=False):
+ def __init__(self, options):
self.wlfile = None
self.logfile = None
- self.verbose = verbose
+ self.verbose = options.verbose
self.sender = ''
self.rcpt = ''
@@ -47,11 +51,16 @@ class news2mail(object):
self.smtpserver = 'localhost'
- self.hostname = gethostbyaddr(gethostname())[0]
+ self.hostname = socket.gethostbyaddr(socket.gethostname())[0]
self.heads_dict = {}
self.article, self.headers, self.body = [], [], []
- self.message = self.__addheads(email.message_from_file(sys.stdin))
+
+ if options.input == '':
+ self.message = self.__addheads(email.message_from_file(sys.stdin))
+ else:
+ with open(options.input, 'r') as inp_stream:
+ self.message = self.__addheads(email.message_from_file(inp_stream))
def __addheads(self, msg):
"""add new header like X-Gateway: Received:
@@ -132,7 +141,7 @@ class news2mail(object):
# put at top
header_set = ('Received', 'From', 'To', 'Subject', 'Date')
- heads_dict = OrderedDict(self.message)
+ heads_dict = collections.OrderedDict(self.message)
for hdr in self.message.keys():
del self.message[hdr]
@@ -169,7 +178,7 @@ class news2mail(object):
s.quit()
-def parse_cmdline():
+def parse_cmdline(args):
"""
set a dictionary with smtp new header in gw parameter (gw.smtpheads)
return (test,verbose) boolean tuple
@@ -183,6 +192,7 @@ def parse_cmdline():
parser.add_argument('-e', '--envelope', default='')
parser.add_argument('-t', '--to', dest='rcpt', required=True)
parser.add_argument('-w', '--wlfile')
+ parser.add_argument('-i', '--input', default='')
parser.add_argument('-l', '--logfile')
parser.add_argument('-T', '--test',
@@ -191,7 +201,7 @@ def parse_cmdline():
parser.add_argument('-v', '--verbose', help='verbose output',
action='store_true')
- opts = parser.parse_args()
+ opts = parser.parse_args(args)
# By rfc822 [Resent-]Sender: should be ever set, unless == From:
# (not this case). Should be a human, while [Resent-]From: may be a program.
@@ -204,7 +214,7 @@ def parse_cmdline():
return opts
-def main():
+def main(args=sys.argv[1:]):
"""main is structured in 4 phases:
1) check and set pyg's internal variables
2) check whitelist for users' permission
@@ -215,12 +225,13 @@ def main():
"""phase 1:
check and set pyg's internal variables
"""
+ out = ''
# it returns only test, other parms are set directly in the actual
# parameter
- args = parse_cmdline()
+ args = parse_cmdline(args)
- n2m = news2mail.news2mail(verbose=args.verbose)
+ n2m = news2mail(args)
owner = None
# check if n2m has some file prefercences set on commandline
@@ -244,7 +255,7 @@ def main():
owner = wl.checkfrom(n2m.message['From'])
if owner is None:
if sys.stdin.isatty() == 1 or args.test:
- print ('"%s" is not in whitelist!' % (n2m.message['From'][:-1]))
+ out += str('"%s" is not in whitelist!' % (n2m.message['From'][:-1])) + '\n'
else:
wl.logmsg(n2m.nntpheads, wl.DENY)
@@ -258,7 +269,7 @@ def main():
# prints formatted email message only (without send) if user wants
if args.verbose:
- print(n2m.message.as_string())
+ out += n2m.message.as_string() + '\n'
if owner is None:
sys.exit(1)
@@ -270,3 +281,8 @@ def main():
wl.logmsg(n2m.heads_dict, wl.ACCEPT, owner)
if not args.test:
n2m.sendarticle()
+
+ if args.input == '':
+ print(out)
+ else:
+ return out
diff --git a/setup.py b/setup.py
index 67e2574..53a6151 100644
--- a/setup.py
+++ b/setup.py
@@ -21,7 +21,6 @@ setup(name='pygn',
py_modules=['mail2news', 'news2mail', 'setup',
'whitelist', 'wlp', 'wlp_parser'],
test_suite="test",
- scripts=['pygm2n', 'pygn2m'],
entry_points={
"console_scripts": [
"pygm2n = mail2news:main",
diff --git a/test/test_pyg.py b/test/test_pyg.py
index e6b8fca..4076fc3 100755
--- a/test/test_pyg.py
+++ b/test/test_pyg.py
@@ -6,6 +6,7 @@ import subprocess
import unittest
import mail2news
+import news2mail
class TestM2N(unittest.TestCase):
@@ -27,12 +28,7 @@ one line test
""" % (mail2news.VERSION, mail2news.DESC)
def test_m2n(self):
- with open('examples/mail') as in_mail:
- pid = subprocess.Popen(['python', 'pygm2n', '-Tv', '-n', 'pyg.test'],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- universal_newlines=True)
- out, _ = pid.communicate(in_mail.read())
+ out = mail2news.main(['-T', '-v', '-i', 'examples/mail', '-n', 'pyg.test'])
self.assertEqual(out, self.expected_output)
@@ -59,22 +55,17 @@ Resent-Sender: sender@example.com
def test_n2m(self):
with open('examples/articletest.accepted') as in_mail:
- pid = subprocess.Popen(['python', 'pygn2m', '-Tvt', 'test@example.com',
- '-s', 'sender@example.com',
- '-w', 'examples/whitelist.example'],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- universal_newlines=True)
in_message = in_mail.read().replace('pyg@pyg.server.tld',
'kame@inwind.it')
- out, err = pid.communicate(in_message)
+ out = news2mail.main(['-T', '-v', '-t', 'test@example.com',
+ '-s', 'sender@example.com',
+ '-w', 'examples/whitelist.example'])
out = re.sub(r'^Message-Id:.*$', '', out)
# Not sure how to compare two email mesages (with different
# times, etc.) so for now just to make sure the script doesn’t
# blow up and gives some output
# otherwise it would be
# self.assertEqual(out, expected_output)
- self.assertEqual(pid.returncode, 0)
self.assertGreater(len(out), 0)