From 60fa3ffcd424738ef536466f5881b936f85d4d7f Mon Sep 17 00:00:00 2001 From: "Walter A. Boring IV" Date: Wed, 21 Nov 2018 12:41:49 -0800 Subject: [PATCH 1/5] Cleaned up trailing whitespace --- fuzzyclock.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/fuzzyclock.py b/fuzzyclock.py index 85f8f1e..aae0e2c 100644 --- a/fuzzyclock.py +++ b/fuzzyclock.py @@ -23,38 +23,38 @@ def fuzzy(hour, minute, degree=1): Supports two degrees of fuzziness. Set with degree = 1 or degree = 2 When degree = 1, time is in quantum of 5 minutes. When degree = 2, time is in quantum of 15 minutes.''' - + if degree<=0 or degree>2: print 'Please use a degree of 1 or 2. Using fuzziness degree=1' - degree = 1 - + degree = 1 + begin = 'It\'s ' - + f0 = 'almost ' f1 = 'exactly ' f2 = 'around ' - + b0 = ' past ' b1 = ' to ' - + hourList = ('One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve') - + s1 = s2 = s3 = s4 = '' base = 5 - + if degree == 1: base = 5 val = ('Five', 'Ten', 'Quarter', 'Twenty', 'Twenty-Five', 'Half') elif degree == 2: base = 15 val = ('Quarter', 'Half') - + dmin = minute % base # to find whether we have to use 'almost', 'exactly' or 'around' if minute > 30: pos = int((60 - minute) / base) #position in the tuple 'val' else: pos = int(minute / base) - + if dmin == 0: s1 = f1 pos = pos - 1 @@ -66,9 +66,9 @@ def fuzzy(hour, minute, degree=1): s1 = f0 if minute > 30: pos = pos -1 - + s2 = val[pos] - + if minute <= base/2: # Case like "It's around/exactly Ten" s2 = s3 = '' s4 = hourList[hour - 12 - 1] @@ -82,7 +82,7 @@ def fuzzy(hour, minute, degree=1): else: s3 = b0 # past s4 = hourList[hour - 12 - 1] - + return begin + s1 + s2 + s3 + s4 def main(): @@ -90,13 +90,13 @@ def main(): stm = time.localtime() h = stm.tm_hour m = stm.tm_min - + if len(sys.argv)>=2: try: deg = int(sys.argv[1]) except: print 'Please use a degree of 1 or 2. Using fuzziness degree=1' - + if len(sys.argv)>=3: tm = sys.argv[2].split(':') try: From 8b61116fceef117a5d2faa86bde5e8244878f88d Mon Sep 17 00:00:00 2001 From: "Walter A. Boring IV" Date: Wed, 21 Nov 2018 12:55:14 -0800 Subject: [PATCH 2/5] Added argparse for cli options This patch adds the argparser to collect the user/callsign from the command line, so it doesn't have to be hard coded. It can be passed on the command line or set in an environment var python aprsd.py --user KCAMEL1 or export APRS_USER=KCAMEL1 python aprsd.py --- .gitignore | 1 + aprsd.py | 29 +++++++++++++++++++++++++++-- utils.py | 16 ++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 utils.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/aprsd.py b/aprsd.py index f3558ec..348d4d2 100644 --- a/aprsd.py +++ b/aprsd.py @@ -19,7 +19,8 @@ # License GPLv2 # -from fuzzyclock import fuzzy +# python included libs +import argparse import json import urllib import sys @@ -33,12 +34,18 @@ from email.mime.text import MIMEText import subprocess import datetime import calendar -from imapclient import IMAPClient, SEEN import email import threading import signal import pprint +# external lib imports +from imapclient import IMAPClient, SEEN + +# local imports here +from fuzzyclock import fuzzy +import utils + # localization, please edit: HOST = "noam.aprs2.net" # north america tier2 servers round robin USER = "KM6XXX-9" # callsign of this aprs client with SSID @@ -54,6 +61,24 @@ shortcuts = { email_sent_dict = {} # message_number:time combos so we don't resend the same email in five mins {int:int} ack_dict = {} # message_nubmer:ack combos so we stop sending a message after an ack from radio {int:int} message_number = 0 # current aprs radio message number, increments for each message we send over rf {int} + +# command line args +parser = argparse.ArgumentParser() +parser.add_argument("--user", + metavar="", + default=utils.env("APRS_USER"), + help="The callsign of this ARPS client with SSID" + " Default=env[APRS_USER]") + +args = parser.parse_args() +if not args.user: + print("Missing the aprs user") + parser.print_help() + parser.exit() +else: + USER = args.user + + try: tn = telnetlib.Telnet(HOST, 14580) except Exception, e: diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..c51b982 --- /dev/null +++ b/utils.py @@ -0,0 +1,16 @@ +"""Utilities and helper functions.""" + +import os +import pprint +import sys + + +def env(*vars, **kwargs): + """This returns the first environment variable set. + if none are non-empty, defaults to '' or keyword arg default + """ + for v in vars: + value = os.environ.get(v, None) + if value: + return value + return kwargs.get('default', '') From ca888685c56757657edf499bea57cfe9b36a5217 Mon Sep 17 00:00:00 2001 From: "Walter A. Boring IV" Date: Wed, 21 Nov 2018 13:03:28 -0800 Subject: [PATCH 3/5] Added password, callsign and host This patch adds the cli options for setting the host, password and the base callsign --- aprsd.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/aprsd.py b/aprsd.py index 348d4d2..a77d6ca 100644 --- a/aprsd.py +++ b/aprsd.py @@ -70,14 +70,42 @@ parser.add_argument("--user", help="The callsign of this ARPS client with SSID" " Default=env[APRS_USER]") +parser.add_argument("--host", + metavar="", + default=utils.env("APRS_HOST"), + help="The aprs host to use Default=env[APRS_HOST]") +parser.add_argument("--password", + metavar="", + default=utils.env("APRS_PASSWORD"), + help="The aprs password Default=env[APRS_PASSWORD]") +parser.add_argument("--callsign", + metavar="", + default=utils.env("APRS_CALLSIGN"), + help="The callsign of radio in the field to which we send " + "email Default=env[APRS_CALLSIGN]") + args = parser.parse_args() if not args.user: - print("Missing the aprs user") + print("Missing the aprs user (env[APRS_USER])") parser.print_help() parser.exit() else: USER = args.user +if not args.password: + print("Missing the aprs password (env[APRS_PASSWORD])") + parser.print_help() + parser.exit() +else: + PASS = args.password + +if not args.callsign: + print("Missing the aprs callsign (env[APRS_CALLSIGN])") + parser.print_help() + parser.exit() +else: + BASECALLSIGN = args.callsign + try: tn = telnetlib.Telnet(HOST, 14580) From a2b5908b1670251bb4a4250db8bbf8d75da646fd Mon Sep 17 00:00:00 2001 From: "Walter A. Boring IV" Date: Wed, 21 Nov 2018 13:38:45 -0800 Subject: [PATCH 4/5] First stab at migrating this to a pytpi repo This patch does some refactoring of the code and the directory structure to conform to the needs of a pypi project. The python code now lives in the aprsd directory so it acts like a real python package that can be installed/included/used. The aprsd.py is now aprds/main.py This patch also adds support for using pbr, which enables a consistent bin install that you can then call as 'aprsd' from the command line. To use this as a developer you should create a virtualenv virtualenv .venv source .venv/bin/activate pip install -e . now you can edit the aprds/main.py and then test it by immediately running aprsd from the command line. The -e option for pip allows you to install the package as an editable package in the .venv, so you can hack on it and not need to re-install every time you make a change. --- .gitignore | 56 +++++++++++++++++++++++++++- MANIFEST.in | 6 +++ aprsd/__init__.py | 19 ++++++++++ fuzzyclock.py => aprsd/fuzzyclock.py | 0 aprsd.py => aprsd/main.py | 0 utils.py => aprsd/utils.py | 0 requirements.txt | 2 + setup.cfg | 31 +++++++++++++++ setup.py | 29 ++++++++++++++ 9 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 MANIFEST.in create mode 100644 aprsd/__init__.py rename fuzzyclock.py => aprsd/fuzzyclock.py (100%) rename aprsd.py => aprsd/main.py (100%) rename utils.py => aprsd/utils.py (100%) create mode 100644 requirements.txt create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 0d20b64..7707d82 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,55 @@ -*.pyc +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +.eggs +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml +.testrepository +.venv + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Complexity +output/*.html +output/*/index.html + +# Sphinx +doc/build + +# pbr generates these +AUTHORS +ChangeLog + +# Editors +*~ +.*.swp +.*sw? +.ropeproject diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..c978a52 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,6 @@ +include AUTHORS +include ChangeLog +exclude .gitignore +exclude .gitreview + +global-exclude *.pyc diff --git a/aprsd/__init__.py b/aprsd/__init__.py new file mode 100644 index 0000000..ecc74b1 --- /dev/null +++ b/aprsd/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import pbr.version + + +__version__ = pbr.version.VersionInfo( + 'aprsd').version_string() diff --git a/fuzzyclock.py b/aprsd/fuzzyclock.py similarity index 100% rename from fuzzyclock.py rename to aprsd/fuzzyclock.py diff --git a/aprsd.py b/aprsd/main.py similarity index 100% rename from aprsd.py rename to aprsd/main.py diff --git a/utils.py b/aprsd/utils.py similarity index 100% rename from utils.py rename to aprsd/utils.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..bd92dae --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pbr +imapclient diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..aa29c81 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,31 @@ +[metadata] +name = aprsd +summary = Amateur radio APRS daemon which listens for messages and responds +description-file = + README.md +author = Craig Lamparter +author-email = something@somewhere.com +classifier = + Topic :: Communications :: Ham Radio + Operating System :: POSIX :: Linux + Programming Language :: Python + +[global] +setup-hooks = + pbr.hooks.setup_hook + +[files] +packages = + aprsd + +[entry_points] +console_scripts = + aprsd = aprsd.main:main + +[build_sphinx] +source-dir = doc/source +build-dir = doc/build +all_files = 1 + +[upload_sphinx] +upload-dir = doc/build/html diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..056c16c --- /dev/null +++ b/setup.py @@ -0,0 +1,29 @@ +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT +import setuptools + +# In python < 2.7.4, a lazy loading of package `pbr` will break +# setuptools if some other modules registered functions in `atexit`. +# solution from: http://bugs.python.org/issue15881#msg170215 +try: + import multiprocessing # noqa +except ImportError: + pass + +setuptools.setup( + setup_requires=['pbr'], + pbr=True) From ecd797d91e56a3444e79a9e67d552c602fffa772 Mon Sep 17 00:00:00 2001 From: "Walter A. Boring IV" Date: Wed, 21 Nov 2018 13:38:45 -0800 Subject: [PATCH 5/5] First stab at migrating this to a pytpi repo This patch does some refactoring of the code and the directory structure to conform to the needs of a pypi project. The python code now lives in the aprsd directory so it acts like a real python package that can be installed/included/used. The aprsd.py is now aprds/main.py This patch also adds support for using pbr, which enables a consistent bin install that you can then call as 'aprsd' from the command line. To use this as a developer you should create a virtualenv virtualenv .venv source .venv/bin/activate pip install -e . now you can edit the aprds/main.py and then test it by immediately running aprsd from the command line. The -e option for pip allows you to install the package as an editable package in the .venv, so you can hack on it and not need to re-install every time you make a change. --- .gitignore | 56 +++++++++++++++++++++++++++- MANIFEST.in | 6 +++ aprsd/__init__.py | 19 ++++++++++ fuzzyclock.py => aprsd/fuzzyclock.py | 0 aprsd.py => aprsd/main.py | 0 utils.py => aprsd/utils.py | 0 requirements.txt | 2 + setup.cfg | 31 +++++++++++++++ setup.py | 29 ++++++++++++++ 9 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 MANIFEST.in create mode 100644 aprsd/__init__.py rename fuzzyclock.py => aprsd/fuzzyclock.py (100%) rename aprsd.py => aprsd/main.py (100%) rename utils.py => aprsd/utils.py (100%) create mode 100644 requirements.txt create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 0d20b64..7707d82 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,55 @@ -*.pyc +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +.eggs +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml +.testrepository +.venv + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Complexity +output/*.html +output/*/index.html + +# Sphinx +doc/build + +# pbr generates these +AUTHORS +ChangeLog + +# Editors +*~ +.*.swp +.*sw? +.ropeproject diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..c978a52 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,6 @@ +include AUTHORS +include ChangeLog +exclude .gitignore +exclude .gitreview + +global-exclude *.pyc diff --git a/aprsd/__init__.py b/aprsd/__init__.py new file mode 100644 index 0000000..ecc74b1 --- /dev/null +++ b/aprsd/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import pbr.version + + +__version__ = pbr.version.VersionInfo( + 'aprsd').version_string() diff --git a/fuzzyclock.py b/aprsd/fuzzyclock.py similarity index 100% rename from fuzzyclock.py rename to aprsd/fuzzyclock.py diff --git a/aprsd.py b/aprsd/main.py similarity index 100% rename from aprsd.py rename to aprsd/main.py diff --git a/utils.py b/aprsd/utils.py similarity index 100% rename from utils.py rename to aprsd/utils.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..bd92dae --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pbr +imapclient diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..aa29c81 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,31 @@ +[metadata] +name = aprsd +summary = Amateur radio APRS daemon which listens for messages and responds +description-file = + README.md +author = Craig Lamparter +author-email = something@somewhere.com +classifier = + Topic :: Communications :: Ham Radio + Operating System :: POSIX :: Linux + Programming Language :: Python + +[global] +setup-hooks = + pbr.hooks.setup_hook + +[files] +packages = + aprsd + +[entry_points] +console_scripts = + aprsd = aprsd.main:main + +[build_sphinx] +source-dir = doc/source +build-dir = doc/build +all_files = 1 + +[upload_sphinx] +upload-dir = doc/build/html diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..056c16c --- /dev/null +++ b/setup.py @@ -0,0 +1,29 @@ +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT +import setuptools + +# In python < 2.7.4, a lazy loading of package `pbr` will break +# setuptools if some other modules registered functions in `atexit`. +# solution from: http://bugs.python.org/issue15881#msg170215 +try: + import multiprocessing # noqa +except ImportError: + pass + +setuptools.setup( + setup_requires=['pbr'], + pbr=True)