diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..f439bbd5 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,6 @@ +include README.rst +include LICENSE +include testall.py +recursive-include docs Makefile *.bat *.py *.rst *.css *.ttf *.png +recursive-include examples *.py +recursive-include tests *.py diff --git a/README.rst b/README.rst index a8b69ac9..632c5758 100644 --- a/README.rst +++ b/README.rst @@ -34,7 +34,8 @@ SleekXMPP's design goals and philosphy are: Get the Code ------------ -.. code-block:: sh + +Get the latest stable version from PyPI:: pip install sleekxmpp @@ -54,6 +55,15 @@ The latest source code for SleekXMPP may be found on `Github **Develop Releases** - `Latest Develop Version `_ +Installing DNSPython +--------------------- +If you are using Python3 and wish to use dnspython, you will have to checkout and +install the ``python3`` branch:: + + git clone http://github.com/rthalley/dnspython + cd dnspython + git checkout python3 + python3 setup.py install Discussion ---------- @@ -68,7 +78,6 @@ help with SleekXMPP. Documentation and Testing ------------------------- - Documentation can be found both inline in the code, and as a Sphinx project in ``/docs``. To generate the Sphinx documentation, follow the commands below. The HTML output will be in ``docs/_build/html``:: @@ -84,7 +93,6 @@ To run the test suite for SleekXMPP:: The SleekXMPP Boilerplate ------------------------- - Projects using SleekXMPP tend to follow a basic pattern for setting up client/component connections and configuration. Here is the gist of the boilerplate needed for a SleekXMPP based project. See the documetation or examples directory for more detailed archetypes for @@ -136,8 +144,10 @@ SleekXMPP projects:: xmpp.register_plugin('xep_0199') # XMPP Ping # If you are working with an OpenFire server, you will need - # to useuterborg Larsson version: - # xmppissl_version = ssl.PROTOCOL_SSLv3 + # to use a different SSL version: + # + # import ssl + # xmpp.ssl_version = ssl.PROTOCOL_SSLv3 if xmpp.connect(): xmpp.process(block=True) diff --git a/docs/api/clientxmpp.rst b/docs/api/clientxmpp.rst index 1c5055a9..8f87664e 100644 --- a/docs/api/clientxmpp.rst +++ b/docs/api/clientxmpp.rst @@ -4,8 +4,6 @@ clientxmpp .. module:: sleekxmpp.clientxmpp -.. autodata:: SRV_SUPPORT - .. autoclass:: ClientXMPP .. automethod:: connect diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 877991a8..47f6a1ba --- a/setup.py +++ b/setup.py @@ -4,16 +4,15 @@ # Copyright (C) 2007-2011 Nathanael C. Fritz # All Rights Reserved # -# This software is licensed as described in the README file, -# which you should have received as part of this distribution. -# +# This software is licensed as described in the README.rst and LICENSE +# file, which you should have received as part of this distribution. -# from ez_setup import use_setuptools -from distutils.core import setup import sys +from distutils.core import setup, Command +# from ez_setup import use_setuptools -import sleekxmpp - +from testall import TestCommand +from sleekxmpp.version import __version__ # if 'cygwin' in sys.platform.lower(): # min_version = '0.6c6' # else: @@ -27,10 +26,10 @@ import sleekxmpp # # from setuptools import setup, find_packages, Extension, Feature -VERSION = sleekxmpp.__version__ +VERSION = __version__ DESCRIPTION = 'SleekXMPP is an elegant Python library for XMPP (aka Jabber, Google Talk, etc).' with open('README.rst') as readme: - LONG_DESCRIPTION = '\n'.join(readme) + LONG_DESCRIPTION = ''.join(readme) CLASSIFIERS = [ 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', @@ -93,5 +92,7 @@ setup( license = 'MIT', platforms = [ 'any' ], packages = packages, - requires = [ 'tlslite', 'pythondns' ], + requires = [ 'dnspython' ], + classifiers = CLASSIFIERS, + cmdclass = {'test': TestCommand} ) diff --git a/sleekxmpp/__init__.py b/sleekxmpp/__init__.py index d2c014d3..a1f1c0f1 100644 --- a/sleekxmpp/__init__.py +++ b/sleekxmpp/__init__.py @@ -15,5 +15,4 @@ from sleekxmpp.xmlstream import XMLStream, RestartStream from sleekxmpp.xmlstream.matcher import * from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET -__version__ = '1.0rc1' -__version_info__ = (1, 0, 0, 'rc1', 0) +from sleekxmpp.version import __version__, __version_info__ diff --git a/sleekxmpp/version.py b/sleekxmpp/version.py new file mode 100644 index 00000000..33c7583e --- /dev/null +++ b/sleekxmpp/version.py @@ -0,0 +1,13 @@ +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2010 Nathanael C. Fritz + This file is part of SleekXMPP. + + See the file LICENSE for copying permission. +""" + +# We don't want to have to import the entire library +# just to get the version info for setup.py + +__version__ = '1.0rc2' +__version_info__ = (1, 0, 0, 'rc2', 0) diff --git a/testall.py b/testall.py old mode 100644 new mode 100755 index 2f980654..65c4a85f --- a/testall.py +++ b/testall.py @@ -1,70 +1,63 @@ #!/usr/bin/env python -import unittest -import logging -import sys + import os +import sys +import logging +import unittest +import distutils.core -class testoverall(unittest.TestCase): +from glob import glob +from os.path import splitext, basename, join as pjoin, walk - def testModules(self): - """Testing all modules by compiling them""" - import compileall - import re - if sys.version_info < (3,0): - self.failUnless(compileall.compile_dir('.' + os.sep + 'sleekxmpp', rx=re.compile('/[.]svn'), quiet=True)) - else: - self.failUnless(compileall.compile_dir('.' + os.sep + 'sleekxmpp', rx=re.compile('/[.]svn|.*26.*'), quiet=True)) - def testTabNanny(self): - """Invoking the tabnanny""" - import tabnanny - self.failIf(tabnanny.check("." + os.sep + 'sleekxmpp')) - #raise "Help!" +def run_tests(): + """ + Find and run all tests in the tests/ directory. + + Excludes live tests (tests/live_*). + """ + testfiles = ['tests.test_overall'] + exclude = ['__init__.py', 'test_overall.py'] + for t in glob(pjoin('.', 'tests', '*.py')): + if True not in [t.endswith(ex) for ex in exclude]: + if basename(t).startswith('test_'): + testfiles.append('tests.%s' % splitext(basename(t))[0]) + + suites = [] + for file in testfiles: + __import__(file) + suites.append(sys.modules[file].suite) + + tests = unittest.TestSuite(suites) + runner = unittest.TextTestRunner(verbosity=2) + + # Disable logging output + logging.basicConfig(level=100) + logging.disable(100) + + result = runner.run(tests) + return result + + +# Add a 'test' command for setup.py + +class TestCommand(distutils.core.Command): + + user_options = [ ] + + def initialize_options(self): + self._dir = os.getcwd() + + def finalize_options(self): + pass + + def run(self): + run_tests() - def disabled_testMethodLength(self): - """Testing for excessive method lengths""" - import re - dirs = os.walk(sys.path[0] + os.sep + 'sleekxmpp') - offenders = [] - for d in dirs: - if not '.svn' in d[0]: - for filename in d[2]: - if filename.endswith('.py') and d[0].find("template%stemplates" % os.sep) == -1: - with open("%s%s%s" % (d[0],os.sep,filename), "r") as fp: - cur = None - methodline = lineno = methodlen = methodindent = 0 - for line in fp: - indentlevel = re.compile("^[\t ]*").search(line).end() - line = line.expandtabs() - lineno += 1 - if line.strip().startswith("def ") or line.strip().startswith("except") or (line.strip() and methodindent > indentlevel) or (line.strip() and methodindent == indentlevel): #new method found or old one ended - if cur: #existing method needs final evaluation - if methodlen > 50 and not cur.strip().startswith("def setupUi"): - offenders.append("Method '%s' on line %s of %s/%s is longer than 50 lines (%s)" % (cur.strip(),methodline,d[0][len(rootp):],filename,methodlen)) - methodlen = 0 - cur = line - methodindent = indentlevel - methodline = lineno - if line and cur and not line.strip().startswith("#") and not (cur.strip().startswith("try:") and methodindent == 0): #if we weren't all whitespace and weren't a comment - methodlen += 1 - self.failIf(offenders,"\n".join(offenders)) - if __name__ == '__main__': - logging.basicConfig(level=100) - logging.disable(100) - #this doesn't need to be very clean - alltests = [unittest.TestLoader().loadTestsFromTestCase(testoverall)] - rootp = sys.path[0] + os.sep + 'tests' - dirs = os.walk(rootp) - for d in dirs: - if not '.svn' in d[0]: - for filename in d[2]: - if filename.startswith('test_') and filename.endswith('.py'): - modname = ('tests' + "." + filename)[:-3].replace(os.sep,'.') - __import__(modname) - #sys.modules[modname].config = moduleconfig - alltests.append(sys.modules[modname].suite) - alltests_suite = unittest.TestSuite(alltests) - result = unittest.TextTestRunner(verbosity=2).run(alltests_suite) - print("""""" % (result.testsRun, len(result.errors), len(result.failures), result.wasSuccessful())) + result = run_tests() + print("" % ( + "xmlns='http//andyet.net/protocol/tests'", + result.testsRun, len(result.errors), + len(result.failures), result.wasSuccessful())) diff --git a/tests/test_overall.py b/tests/test_overall.py new file mode 100644 index 00000000..4821f11d --- /dev/null +++ b/tests/test_overall.py @@ -0,0 +1,29 @@ +import os +import re +import sys +import unittest +import tabnanny +import compileall + +class TestOverall(unittest.TestCase): + + """ + Test overall package health by compiling and checking + code style. + """ + + def testModules(self): + """Testing all modules by compiling them""" + src = '..%ssleekxmpp' % os.sep + if sys.version_info < (3, 0): + rx = re.compile('/[.]svn') + else: + rx = re.compile('/[.]svn|.*26.*') + self.failUnless(compileall.compile_dir(src, rx=rx, quiet=True)) + + def testTabNanny(self): + """Testing that indentation is consistent""" + self.failIf(tabnanny.check('..%ssleekxmpp' % os.sep)) + + +suite = unittest.TestLoader().loadTestsFromTestCase(TestOverall)