From 0911ec5330e460f79daca557bb03114276def026 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Fri, 25 Jan 2013 00:56:12 +0000 Subject: Clean up directory structure to be better aligned with other leap python project, add __init__.py to modules directories, and add query callback function to couchdb in alias_resolver.py for check_recipient feature. --- leap/__init__.py | 9 --- leap/mx/alias_resolver.py | 172 ---------------------------------------------- leap/util/net.py | 126 --------------------------------- leap/util/version.py | 69 ------------------- 4 files changed, 376 deletions(-) delete mode 100644 leap/__init__.py delete mode 100644 leap/mx/alias_resolver.py delete mode 100644 leap/util/net.py delete mode 100644 leap/util/version.py (limited to 'leap') diff --git a/leap/__init__.py b/leap/__init__.py deleted file mode 100644 index 370676e..0000000 --- a/leap/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- encoding: utf-8 -*- - -from . import mx -from . import util -from . import tests - -__author__ = util.version.authors -__version__ = util.version.getVersion() -__all__ = ['mx', 'util', 'tests'] diff --git a/leap/mx/alias_resolver.py b/leap/mx/alias_resolver.py deleted file mode 100644 index 5010f63..0000000 --- a/leap/mx/alias_resolver.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -''' -alias_resolver.py -================= -Classes for resolving postfix aliases. - -@authors: Isis Agora Lovecruft -@version: 0.0.1-beta -@license: see included LICENSE file -@copyright: copyright 2013 Isis Agora Lovecruft -''' - -import os - -try: - from paisley import client -except ImportError: - print "This software requires paisley. Please see the README file" - print "for instructions on getting required dependencies." - -try: - from twisted.internet import address, defer, reactor - from twisted.mail import maildir, alias - from twisted.protocols import postfix -except ImportError: - print "This software requires paisley. Please see the README file" - print "for instructions on getting required dependencies." - -from leap.mx import net, log ## xxx implement log - - -class ConnectedCouchDB(client.CouchDB): - """ - Connect to a CouchDB instance. - - ## xxx will we need to open CouchDB documents and views? - """ - def __init__(self, host, port, dbName=None, - username=None, password=None, *args, **kwargs): - """ - Connect to a CouchDB instance. - - @param host: A hostname string for the CouchDB server. - @param port: The port of the CouchDB server, as an integer. - @param dbName: (optional) The default database to connect to. - @param username: (optional) The username for authorization. - @param password: (optional) The password for authorization. - @returns: A :class:`twisted.internet.defer.Deferred` representing the - the client connection to the CouchDB instance. - """ - super(client.CouchDB, self).__init__(host, port, - dbName=dbName, - username=username, - password=password, - *args, **kwargs) - - def query(self, uri): - """ - Query a CouchDB instance that we are connected to. - """ - try: - self.checkURI(uri) ## xxx write checkURI() - ## xxx we might be able to use self._parseURI() - except SchemeNotSupported, sns: ## xxx where in paisley is this? - log.exception(sns) ## xxx need log.exception() - - d = self.get(uri) - @d.addCallback - def parse_answer(answer): - return answer - - return answer - - @defer.inlineCallbacks - def listUsersAndEmails(self, limit=1000, reverse=False): - """ - List all users and email addresses, up to the given limit. - """ - query = "/users/_design/User/_view/by_email_or_alias/?reduce=false" - answer = yield self.query(query, limit=limit, reverse=reverse) - - if answer: - parsed = yield self.parseResult(answer) - if parsed: - log.msg("%s" % parsed) - else: - log.msg("No answer from database, perhaps there are no users.") - else: - log.msg("Problem querying CouchDB instance...") - log.debug("Host: %s" % host) - log.debug("Port: %d" % port) - -class PostfixAliasResolver(postfix.PostfixTCPMapServer): - """ - Resolve postfix aliases, similarly to using "$ postmap -q ". - - This class starts a simple LineReceiver server which listens for a string - specifying an alias to look up, :param:`key`, and which will be used to - query the local Postfix server. You can test it with: - - $ ./alias_resolver.py & - $ /usr/bin/postmap -q tcp:localhost:4242 - - """ - def __init__(self, *args, **kwargs): - """ - Create a local LineReceiver server which listens for Postfix aliases - to resolve. - """ - super(postfix.PostfixTCPMapServer, self).__init__(*args, **kwargs) - - -class PostfixAliasResolverFactory(postfix.PostfixTCPMapDeferringDictServerFactory): - """ - A Factory for creating PostfixAliasResolver servers, which handles inputs - and outputs, and keeps an in-memory mapping of Postfix aliases in the form - of a dict. - - xxx fill me in - - """ - protocol = PostfixAliasResolver - - def __init__(self, addr='127.0.0.1', port=4242, timeout=120, data=None): - """ - Create a Factory which returns :class:`PostfixAliasResolver` servers. - - @param addr: - (optional) A string giving the IP address of the Postfix server. - Default: '127.0.0.1' - @param port: - (optional) An integer that specifies the port number of the - Postfix server. Default: 4242 - @param timeout: - (optional) An integer specifying the number of seconds to wait - until we should time out. Default: 120 - @param data: - (optional) A dict to use to initialise or update the alias - mapping. - """ - super(postfix.PostfixTCPMapDeferringDictServerFactory, - self).__init__(data=data) - self.timeout = timeout - ## xxx get config value, should be something like verbose = no - self.noisy = False - - try: - assert isinstance(port, int), "Port number must be an integer" - assert isinstance(timeout, int), "Timeout must be an integer" - except AssertionError, ae: - raise SystemExit(ae.message) - - if net.checkIPaddress(addr): - self.addr = address._IPAddress('TCP', addr, int(port)) - else: - log.debug("Using default address for Postfix: 127.0.0.1:%s" % port) - self.addr = address._IPAddress('TCP', '127.0.0.1', int(port)) - - def buildProtocol(self): - """ - Create an instance of the :class:`PostfixAliasResolver` server. - """ - proto = self.protocol() - proto.timeout = self.timeout - proto.factory = self - return proto - - -if __name__ == "__main__": - - print "To test alias_resolver.py, please use /test/test_alias_resolver.py" diff --git a/leap/util/net.py b/leap/util/net.py deleted file mode 100644 index a4104d0..0000000 --- a/leap/util/net.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -''' -net.py -------- -Utilities for networking. - -@authors: Isis Agora Lovecruft, 0x2cdb8b35 -@license: see included LICENSE file -@copyright: 2013 Isis Agora Lovecruft -''' - -import ipaddr -import sys -import socket - -from random import randint - -from leap.mx.utils import log - - -PLATFORMS = {'LINUX': sys.platform.startswith("linux"), - 'OPENBSD': sys.platform.startswith("openbsd"), - 'FREEBSD': sys.platform.startswith("freebsd"), - 'NETBSD': sys.platform.startswith("netbsd"), - 'DARWIN': sys.platform.startswith("darwin"), - 'SOLARIS': sys.platform.startswith("sunos"), - 'WINDOWS': sys.platform.startswith("win32")} - - -class UnsupportedPlatform(Exception): - """Support for this platform is not currently available.""" - -class IfaceError(Exception): - """Could not find default network interface.""" - -class PermissionsError(SystemExit): - """This test requires admin or root privileges to run. Exiting...""" - - -def checkIPaddress(addr): - """ - Check that a given string is a valid IPv4 or IPv6 address. - - @param addr: Any string defining an IP address, i.e. '1.2.3.4' or '::1'. - @returns: True if :param:`addr` defines a valid IPAddress, else False. - """ - import ipaddr - - try: - check = ipaddr.IPAddress(addr) - except ValueError, ve: - log.warn(ve.message) - return False - else: - return True - -def getClientPlatform(platform_name=None): - for name, test in PLATFORMS.items(): - if not platform_name or platform_name.upper() == name: - if test: - return name, test - -def getPosixIfaces(): - from twisted.internet.test import _posixifaces - log.msg("Attempting to discover network interfaces...") - ifaces = _posixifaces._interfaces() - return ifaces - -def getWindowsIfaces(): - from twisted.internet.test import _win32ifaces - log.msg("Attempting to discover network interfaces...") - ifaces = _win32ifaces._interfaces() - return ifaces - -def getIfaces(platform_name=None): - client, test = getClientPlatform(platform_name) - if client: - if client == ('LINUX' or 'DARWIN') or client[-3:] == 'BSD': - return getPosixIfaces() - elif client == 'WINDOWS': - return getWindowsIfaces() - ## XXX fixme figure out how to get iface for Solaris - else: - raise UnsupportedPlatform - else: - raise UnsupportedPlatform - -def getRandomUnusedPort(addr=None): - free = False - while not free: - port = randint(1024, 65535) - s = socket.socket() - try: - s.bind((addr, port)) - free = True - except: - pass - s.close() - return port - -def getNonLoopbackIfaces(platform_name=None): - try: - ifaces = getIfaces(platform_name) - except UnsupportedPlatform, up: - log.err(up) - - if not ifaces: - log.msg("Unable to discover network interfaces...") - return None - else: - found = [{i[0]: i[2]} for i in ifaces if i[0] != 'lo'] - log.debug("Found non-loopback interfaces: %s" % found) - for iface in ifaces: - try: - interface = checkInterfaces(found) - except IfaceError, ie: - log.err(ie) - return None - else: - return interfaces - - -def getLocalAddress(): - default_iface = getDefaultIface() - return default_iface.ipaddr diff --git a/leap/util/version.py b/leap/util/version.py deleted file mode 100644 index ecf8a22..0000000 --- a/leap/util/version.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -''' -version.py ----------- -Version information for leap_mx. - -@authors: Isis Agora Lovecruft, 0x2cdb8b35 -@licence: see included LICENSE file -@copyright: 2013 Isis Agora Lovecruft -''' - -import os - -from twisted.python import versions - -name = 'leap_mx' -version = versions.Version(name, 0, 0, 1, None) -authors = [('Isis Agora Lovecruft', '', '0x2cdb8b35'),] -git_url = 'https://github.com/isislovecruft/leap_mx/' -website = 'https://leap.se' - -def getVersion(): - version.authors = authors - version.git_url = git_url - version.website = website - return version - -def getRepoDir(): - here = os.getcwd() - base = here.rsplit(name, 1)[0] - repo = os.path.join(base, name) - return repo - -def __make_text__(extra_text=None): - splitter = "-" * len(version.__str__()) - header = ["\n%s\n" % version.__str__(), "%s\n" % splitter] - footer = ["Website: \t%s\n" % website, "Github: \t%s\n" % git_url, "\n"] - contacts = ["\t%s, %s %s\n" % (a[0], a[1], a[2]) for a in authors] - contacts.insert(0, "Authors: ") - - with_contacts = header + contacts - - if extra_text is not None: - if isinstance(extra_text, iter): - with_contacts.extend((e for e in extra_text)) - elif isinstance(extra_text, str): - with_contacts.append(extra_text) - else: - print "Couldn't add extra text..." - - text = with_contacts + footer - return text - -def __update_version__(): - repo = getRepoDir() - version_file = os.path.join(repo, 'VERSION') - version_text = __make_text__() - - with open(version_file, 'w+') as fh: - fh.writelines((line for line in version_text)) - fh.flush() - fh.truncate() - - -if __name__ == "__main__": - print "Generating new VERSION file..." - __update_version__() - print "Done." -- cgit v1.2.3