From aed42557a7e8a17561c225426f66db1187006d9c Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Fri, 3 May 2013 17:05:53 -0300 Subject: Add setup script and init.d script Also, some pep8 fixes --- .gitignore | 6 ++++ MANIFEST.in | 1 + mx.tac | 3 +- pkg/__init__.py | 0 pkg/leap_mx | 50 ++++++++++++++++++++++++++++++ pkg/mx-requirements.pip | 4 --- pkg/requirements.pip | 12 ++++++++ pkg/utils/__init__.py | 0 pkg/utils/reqs.py | 72 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 60 ++++++++++++++++++++++++++++++++++++ src/leap/__init__.py | 28 ++++------------- src/leap/mx/__init__.py | 2 -- src/leap/mx/alias_resolver.py | 3 +- src/leap/mx/couchdbhelper.py | 2 ++ src/leap/mx/mail_receiver.py | 16 +++++++--- 15 files changed, 224 insertions(+), 35 deletions(-) create mode 100644 MANIFEST.in create mode 100644 pkg/__init__.py create mode 100644 pkg/leap_mx delete mode 100644 pkg/mx-requirements.pip create mode 100644 pkg/requirements.pip create mode 100644 pkg/utils/__init__.py create mode 100644 pkg/utils/reqs.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 0519df8..4c572d1 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ develop-eggs .installed.cfg lib lib64 +MANIFEST +PKG-INFO # Installer logs pip-log.txt @@ -37,6 +39,10 @@ nosetests.xml # Don't upload private things *.private +# and vim's +*.swp +*.swo + # Ignore emacs temporary files *~ \#*\# diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..07f43b8 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +data/* \ No newline at end of file diff --git a/mx.tac b/mx.tac index 30ede8f..cdebba7 100755 --- a/mx.tac +++ b/mx.tac @@ -1,6 +1,5 @@ -#!/usr/bin/env python # -*- encoding: utf-8 -*- -# start_mx.py +# mx.tac # Copyright (C) 2013 LEAP # # This program is free software: you can redistribute it and/or modify diff --git a/pkg/__init__.py b/pkg/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pkg/leap_mx b/pkg/leap_mx new file mode 100644 index 0000000..d2c4bc3 --- /dev/null +++ b/pkg/leap_mx @@ -0,0 +1,50 @@ +#!/bin/sh + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +pidfile=/var/run/leap_mx.pid \ +rundir=/var/lib/leap_mx/ \ +file=/etc/leap/mx \ +logfile=/var/log/leap_mx.log + +[ -r /etc/default/leap_mx ] && . /etc/default/leap_mx + +test -x /usr/bin/twistd || exit 0 +test -r $file || exit 0 +test -r /etc/leap/ || exit 0 + + +case "$1" in + start) + echo -n "Starting leap_mx: twistd" + start-stop-daemon --start --quiet --exec /usr/bin/twistd -- \ + --pidfile=$pidfile \ + --rundir=$rundir \ + --python=$file \ + --logfile=$logfile + echo "." + ;; + + stop) + echo -n "Stopping leap_mx: twistd" + start-stop-daemon --stop --quiet \ + --pidfile $pidfile + echo "." + ;; + + restart) + $0 stop + $0 start + ;; + + force-reload) + $0 restart + ;; + + *) + echo "Usage: /etc/init.d/leap_mx {start|stop|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/pkg/mx-requirements.pip b/pkg/mx-requirements.pip deleted file mode 100644 index a05ac98..0000000 --- a/pkg/mx-requirements.pip +++ /dev/null @@ -1,4 +0,0 @@ -Twisted -paisley>=0.3.1 -## xxx change me to whatever you name the package in pypi -python-gnupg>=0.3.0 diff --git a/pkg/requirements.pip b/pkg/requirements.pip new file mode 100644 index 0000000..dc39dca --- /dev/null +++ b/pkg/requirements.pip @@ -0,0 +1,12 @@ +Twisted>=12.0.2 +paisley>=0.3.1 +## XXX change me to whatever you name the package in pypi +python-gnupg>=0.3.0 +leap.common>=0.0.2-dev + +############### +# Development # +############### + +#leap.soledad # make this a dep as soon as it is installable from pypi !! +-e git://github.com/andrejb/soledad.git@develop#egg=leap.soledad diff --git a/pkg/utils/__init__.py b/pkg/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pkg/utils/reqs.py b/pkg/utils/reqs.py new file mode 100644 index 0000000..5e2324f --- /dev/null +++ b/pkg/utils/reqs.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# reqs.py +# Copyright (C) 2013 LEAP +# +# This program 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. +# +# This program 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 this program. If not, see . +""" +Utils to help in the setup process +""" +import os +import re +import sys + + +def get_reqs_from_files(reqfiles): + """ + Returns the contents of the top requirement file listed as a + string list with the lines + + @param reqfiles: requirement files to parse + @type reqfiles: list of str + """ + for reqfile in reqfiles: + if os.path.isfile(reqfile): + return open(reqfile, 'r').read().split('\n') + + +def parse_requirements(reqfiles=['requirements.txt', + 'requirements.pip', + 'pkg/requirements.pip']): + """ + Parses the requirement files provided. + + @param reqfiles: requirement files to parse + @type reqfiles: list of str + """ + + requirements = [] + for line in get_reqs_from_files(reqfiles): + # -e git://foo.bar/baz/master#egg=foobar + if re.match(r'\s*-e\s+', line): + pass + # do not try to do anything with externals on vcs + #requirements.append(re.sub(r'\s*-e\s+.*#egg=(.*)$', r'\1', + #line)) + # http://foo.bar/baz/foobar/zipball/master#egg=foobar + elif re.match(r'\s*https?:', line): + requirements.append(re.sub(r'\s*https?:.*#egg=(.*)$', r'\1', + line)) + # -f lines are for index locations, and don't get used here + elif re.match(r'\s*-f\s+', line): + pass + + # argparse is part of the standard library starting with 2.7 + # adding it to the requirements list screws distro installs + elif line == 'argparse' and sys.version_info >= (2, 7): + pass + else: + if line != '': + requirements.append(line) + + return requirements diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c511a10 --- /dev/null +++ b/setup.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# setup.py +# Copyright (C) 2013 LEAP +# +# This program 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. +# +# This program 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 this program. If not, see . +""" +setup file for leap.mx +""" +from setuptools import setup, find_packages + +from pkg.utils.reqs import parse_requirements + +trove_classifiers = [ + 'Development Status :: 3 - Alpha', + 'Environment :: No Input/Output (Daemon)', + 'Framework :: Twisted', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU Affero General Public License v3' + 'or later (AGPLv3+)', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Topic :: Communications :: Email', + 'Topic :: Security :: Cryptography', +] + +setup( + name='leap.mx', + version="0.2.0", + url="http://github.com/leapcode/leap_mx", + license='AGPLv3+', + author='The LEAP Encryption Access Project', + author_email='info@leap.se', + description=("An asynchronous, transparently-encrypting remailer " + "for the LEAP platform"), + long_description=( + "An asynchronous, transparently-encrypting remailer " + "using BigCouch/CouchDB and PGP/GnuPG, written in Twisted Python." + ), + namespace_packages=["leap"], + package_dir={'': 'src'}, + packages=find_packages('src'), + #test_suite='leap.mx.tests', + install_requires=parse_requirements(), + classifiers=trove_classifiers, + data_files = [("/etc/leap/", ["mx.tac"]), + ("/etc/init.d/", ["pkg/leap_mx"])] +) diff --git a/src/leap/__init__.py b/src/leap/__init__.py index ff2d8a1..f48ad10 100644 --- a/src/leap/__init__.py +++ b/src/leap/__init__.py @@ -1,22 +1,6 @@ -# -*- encoding: utf-8 -*- -# __init__.py -# Copyright (C) 2013 LEAP -# -# This program 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. -# -# This program 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 this program. If not, see . - -""" -Module intialization file for leap. -""" - -__all__ = ['mx'] +# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/src/leap/mx/__init__.py b/src/leap/mx/__init__.py index df784db..2c4f106 100644 --- a/src/leap/mx/__init__.py +++ b/src/leap/mx/__init__.py @@ -14,9 +14,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - """ Module intialization file for leap.mx . """ - __all__ = ['alias_resolver', 'couchdbhelper'] diff --git a/src/leap/mx/alias_resolver.py b/src/leap/mx/alias_resolver.py index 68c6212..2074ee5 100644 --- a/src/leap/mx/alias_resolver.py +++ b/src/leap/mx/alias_resolver.py @@ -36,7 +36,8 @@ except ImportError: class AliasResolverFactory(postfix.PostfixTCPMapDeferringDictServerFactory): def __init__(self, couchdb, *args, **kwargs): - postfix.PostfixTCPMapDeferringDictServerFactory.__init__(self, *args, **kwargs) + postfix.PostfixTCPMapDeferringDictServerFactory.__init__( + self, *args, **kwargs) self._cdb = couchdb def _to_str(self, result): diff --git a/src/leap/mx/couchdbhelper.py b/src/leap/mx/couchdbhelper.py index 7c4c8ce..02ef088 100644 --- a/src/leap/mx/couchdbhelper.py +++ b/src/leap/mx/couchdbhelper.py @@ -157,6 +157,7 @@ if __name__ == "__main__": password="") d = cdb.queryByLoginOrAlias("test1") + @d.addCallback def right(result): print "Should be an actual uuid:", result @@ -164,6 +165,7 @@ if __name__ == "__main__": print cdb.getPubKey(result) d2 = cdb.queryByLoginOrAlias("asdjaoisdjoiqwjeoi") + @d2.addCallback def wrong(result): print "Should be None:", result diff --git a/src/leap/mx/mail_receiver.py b/src/leap/mx/mail_receiver.py index 49d4455..2c04863 100644 --- a/src/leap/mx/mail_receiver.py +++ b/src/leap/mx/mail_receiver.py @@ -72,7 +72,9 @@ class MailReceiver(Service): for directory, recursive in self._directories: log.msg("Watching %s --- Recursive: %s" % (directory, recursive)) - wm.watch(filepath.FilePath(directory), mask, callbacks=[self._process_incoming_email], recursive=recursive) + wm.watch(filepath.FilePath(directory), mask, + callbacks=[self._process_incoming_email], + recursive=recursive) def _get_pubkey(self, uuid): """ @@ -127,7 +129,8 @@ class MailReceiver(Service): doc.content = { "_enc_scheme": EncryptionSchemes.PUBKEY, - "_enc_json": openpgp.encrypt_asym(json.dumps(data), openpgp_key) + "_enc_json": openpgp.encrypt_asym(json.dumps(data), + openpgp_key) } return uuid, doc @@ -198,6 +201,9 @@ class MailReceiver(Service): owner = mail["To"] if owner is None: # default to Delivered-To owner = mail["Delivered-To"] + if owner is None: + log.err("Malformed mail, neither To: nor " + "Delivered-To: field") owner = owner.split("@")[0] owner = owner.split("+")[0] log.msg("Mail owner: %s" % (owner,)) @@ -205,8 +211,10 @@ class MailReceiver(Service): log.msg("%s received a new mail" % (owner,)) d = self._users_cdb.queryByLoginOrAlias(owner) d.addCallbacks(self._get_pubkey, log.err) - d.addCallbacks(self._encrypt_message, log.err, (owner, mail_data)) + d.addCallbacks(self._encrypt_message, log.err, + (owner, mail_data)) d.addCallbacks(self._export_message, log.err) - d.addCallbacks(self._conditional_remove, log.err, (filepath,)) + d.addCallbacks(self._conditional_remove, log.err, + (filepath,)) d.addErrback(log.err) -- cgit v1.2.3