diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..815554c74f1daf7291db3bbda4d6f557d5d8c693 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: python + +python: + - "2.6" + - "2.7" + +install: make + +script: make test diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..dd37a921b8c11e8a29e5c4460d02947c3cf08e43 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +all: install_requirements develop todo + +develop: + python setup.py develop + +install_requirements: + pip install -r requirements.txt --use-mirrors + +install: + python setup.py install + +uninstall: + pip uninstall -y aprs + +todo: + grep \#\ TODO Makefile + +clean: + rm -rf *.egg* build dist *.py[oc] */*.py[co] cover doctest_pypi.cfg \ + nosetests.xml pylint.log *.egg output.xml flake8.log tests.log \ + test-result.xml htmlcov fab.log + +publish: + python setup.py register sdist upload + +nosetests: + python setup.py nosetests + +pep8: + flake8 + +flake8: + flake8 --exit-zero --max-complexity 12 aprs/*.py tests/*.py *.py | \ + awk -F\: '{printf "%s:%s: [E]%s\n", $$1, $$2, $$3}' | tee flake8.log + +clonedigger: + clonedigger --cpd-output . + +lint: + pylint -f parseable -i y -r y aprs/*.py tests/*.py *.py | \ + tee pylint.log + +test: install_requirements lint clonedigger flake8 nosetests diff --git a/aprs/__init__.py b/aprs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9897db3e8fc0d70b4fdd8876153ba6222af8c6bd --- /dev/null +++ b/aprs/__init__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +__author__ = 'Greg Albrecht <gba@gregalbrecht.com>' +__copyright__ = 'Copyright 2013 Greg Albrecht' +__license__ = 'Creative Commons Attribution 3.0 Unported License' + + +from .aprs import APRS diff --git a/aprs/aprs.py b/aprs/aprs.py new file mode 100755 index 0000000000000000000000000000000000000000..8ffefc6436e9101509285669e76ca2e4b889585c --- /dev/null +++ b/aprs/aprs.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + + +import logging +import logging.handlers + +import requests + + +class APRS(object): + + logger = logging.getLogger('aprs') + logger.addHandler(logging.StreamHandler()) + + def __init__(self, user, password=-1, input_url=None): + self._url = input_url or 'http://srvr.aprs-is.net:8080' + self._auth = "user %s pass %s" % (user, password) + + def send(self, message): + headers = { + 'content-type': 'application/octet-stream', + 'accept': 'text/plain' + } + + content = "\n".join([self._auth, message]) + + result = requests.post(self._url, data=content, headers=headers) + + return result.status_code == 204 diff --git a/setup.py b/setup.py index 2d8ebb63d400a7c4f095108745366f8ed971cc3d..19617844cade9b8e3e5d75d93858a9fe3a9781b7 100644 --- a/setup.py +++ b/setup.py @@ -16,5 +16,8 @@ setuptools.setup( author_email='gba@gregalbrecht.com', license='Creative Commons Attribution 3.0 Unported License', url='https://github.com/ampledata/aprs', - setup_requires=['nose>=1.0'] + setup_requires=['nose'], + tests_require=['nose', 'httpretty'], + install_requires=['requests'] + ) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/context.py b/tests/context.py new file mode 100644 index 0000000000000000000000000000000000000000..922205b5f6c18632f645ca3198a2cf5802c14f04 --- /dev/null +++ b/tests/context.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +"""Test context. + +Based on http://kennethreitz.com/repository-structure-and-python.html +""" + +__author__ = 'Greg Albrecht <gba@gregalbrecht.com>' +__copyright__ = 'Copyright 2013 Greg Albrecht' +__license__ = 'Creative Commons Attribution 3.0 Unported License' + + +import os +import sys + + +sys.path.insert(0, os.path.abspath('..')) + + +import aprs diff --git a/tests/test_aprs.py b/tests/test_aprs.py new file mode 100644 index 0000000000000000000000000000000000000000..181dcc6d2d4dfc0c099d8356d328962c2459ff51 --- /dev/null +++ b/tests/test_aprs.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python + + +import random +import unittest +import logging +import logging.handlers + +import httpretty + +from .context import aprs + + +ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +NUMBERS = '0123456789' +ALPHANUM = ''.join([ALPHABET, NUMBERS]) + + +class APRSTest(unittest.TestCase): + """Tests for Python APRS Bindings.""" + + logger = logging.getLogger('aprs.tests') + logger.addHandler(logging.StreamHandler()) + + def random(self, length=8, alphabet=ALPHANUM): + return ''.join(random.choice(alphabet) for _ in xrange(length)) + + def setUp(self): + self.fake_server = ''.join([ + 'http://localhost:', + self.random(4, '123456789'), + '/' + ]) + + self.fake_callsign = ''.join([ + self.random(1, 'KWN'), + self.random(1, NUMBERS), + self.random(3, ALPHABET), + '-', + self.random(1, '123456789') + ]) + + self.real_server = 'http://localhost:14580' + self.real_callsign = '-'.join(['W2GMD', self.random(1, '123456789')]) + + self.logger.debug("fake_server=%s fake_callsign=%s" + % (self.fake_server, self.fake_callsign)) + + @httpretty.httprettified + def test_fake_good_auth(self): + httpretty.HTTPretty.register_uri( + httpretty.HTTPretty.POST, + self.fake_server, + status=204 + ) + + aprs_conn = aprs.APRS( + user=self.fake_callsign, + input_url=self.fake_server + ) + + msg = '>'.join([ + self.fake_callsign, + 'APRS,TCPIP*:=3745.00N/12227.00W-Simulated Location' + ]) + self.logger.debug(locals()) + + result = aprs_conn.send(msg) + + self.assertTrue(result) + + @httpretty.httprettified + def test_fake_bad_auth(self): + httpretty.HTTPretty.register_uri( + httpretty.HTTPretty.POST, + self.fake_server, + status=401 + ) + + aprs_conn = aprs.APRS( + user=self.fake_callsign, + input_url=self.fake_server + ) + + msg = '>'.join([ + self.fake_callsign, + 'APRS,TCPIP*:=3745.00N/12227.00W-Simulated Location' + ]) + self.logger.debug(locals()) + + result = aprs_conn.send(msg) + + self.assertFalse(result) + + def test_more(self): + aprs_conn = aprs.APRS( + user=self.real_callsign, + input_url=self.real_server + ) + + msg = '>'.join([ + self.real_callsign, + 'APRS,TCPIP*:=3745.00N/12227.00W-Simulated Location' + ]) + self.logger.debug(locals()) + + result = aprs_conn.send(msg) + + self.assertFalse(result)