diff --git a/README.md b/README.md index b02bab9..d3ea516 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ System requirements: Computer: Intel 32-bit, with hardware serial port. (USB to serial converters will usually not work at 45.45 baud.) Operating system Windows 7/Linux. - Python system: 2.6 or 2.7 (No 3.x yet.) - Required packages: win32api + Python system: 2.7 or 3.x + Required packages: bs4 pyserial feedparser Baudot teletype: Model 15, 19 or 28 in proper working condition. @@ -57,7 +57,15 @@ System requirements: the appropriate times. For information on interfacing a current-loop Teletype to a PC, - see http://www.aetherltd.com" + see http://www.aetherltd.com". + + For sending SMS messages: + An account with Twilio. + + For receiving SMS messages: + A server which supports our message API. + + System configuration issues: diff --git a/messager/baudotrss.py b/messager/baudotrss.py index 0b804c1..c340559 100644 --- a/messager/baudotrss.py +++ b/messager/baudotrss.py @@ -29,11 +29,6 @@ import baudottty -# -# Suppress deprecation warnings. We know feedparser and BeautifulSoup need updates. -# -####warnings.filterwarnings(action='ignore', category=DeprecationWarning, module='BeautifulSoup') -####warnings.filterwarnings(action='ignore', category=DeprecationWarning, module='feedparser') # # get_script_dir # @@ -49,7 +44,6 @@ def get_script_dir(follow_symlinks=True): path = os.path.realpath(path) return os.path.dirname(path) -####print(get_script_dir()) # # opentty -- create and open the TTY device diff --git a/messager/twiliofeed.py b/messager/twiliofeed.py index facfe54..78740ad 100644 --- a/messager/twiliofeed.py +++ b/messager/twiliofeed.py @@ -33,7 +33,6 @@ # # Constants # -SERVERPOLLURL = "http://www.aetherltd.com/cgi/ttypoll.cgi?" # URL for polling TWILIOBASE = "https://api.twilio.com/2010-04-01/" # Twilio base URL def expandplaceabbrev(fields, fieldname, placetable) : @@ -70,7 +69,7 @@ def maketimelocal(dt) : return(dt + delta) # apply time delta -def doservercmd(logger, accountsid, ourphoneno, cmd, v1=None, v2=None) : +def doservercmd(logger, serverpollurl, accountsid, ourphoneno, cmd, v1=None, v2=None) : """ Send command to server at Aetheric (not Twilio), get XML reply """ @@ -79,7 +78,7 @@ def doservercmd(logger, accountsid, ourphoneno, cmd, v1=None, v2=None) : fields["v1"] = v1 if v2: fields["v2"] = v2 - url = SERVERPOLLURL + urllib.parse.urlencode(fields) # construct cmd URL + url = serverpollurl + urllib.parse.urlencode(fields) # construct cmd URL logger.debug("SMS server cmd: " + url) fd = urllib.request.urlopen(url) # open url result = fd.read() # read contents @@ -104,14 +103,17 @@ class Twiliofeed(feedmanager.Feed) : # # Called from outside the thread # - def __init__(self, accountsid, authtoken, ourphoneno, logger) : + def __init__(self, serverpollurl, accountsid, authtoken, ourphoneno, hdrtitle, logger) : feedmanager.Feed.__init__(self, "SMS", logger) self.lock = threading.Lock() # lock object. One login at a time. + self.serverpollurl = serverpollurl # our site to poll for incoming SMS self.accountsid = accountsid # accounts ID - for all requests self.authtoken = authtoken # auth token self.ourphoneno = ourphoneno # our phone number + if hdrtitle is None : # if no header title + hdrtitle = "SMS message" # default title for feed + self.hdrtitle = hdrtitle # title of this SMS source self.errmsg = None # no pending error message - self.hdrtitle = "Aetheric Message" self.url = self.hdrtitle self.msgfrom = None # phone number of last message returned to user self.logger = logger # debug og to here @@ -246,7 +248,7 @@ def fetchitems(self) : # fetch more items from feed while True : # until all available read self.logger.debug("Polling SMS server starting after serial #%s" % (self.lastserial,)) - replyxml = doservercmd(self.logger, self.accountsid, self.ourphoneno, "getnext", self.lastserial + 1, None) # get next msg + replyxml = doservercmd(self.logger, self.serverpollurl, self.accountsid, self.ourphoneno, "getnext", self.lastserial + 1, None) # get next msg newserial = self.handlereply(replyxml) # handle message self.logger.debug("Poll complete.") if newserial and newserial > self.lastserial: # if got message @@ -374,7 +376,7 @@ def markitemsdone(self) : # mark any printed items as while True: # until Queue.empty or network error item = self.donequeue.get_nowait() # get input if any serial = item.serial # serial number of done item - reply = doservercmd(self.logger, self.accountsid, self.ourphoneno, + reply = doservercmd(self.logger, self.serverpollurl, self.accountsid, self.ourphoneno, "printed", serial, serial) except queue.Empty: # if empty return(True) # success @@ -385,7 +387,7 @@ def markitemsdone(self) : # mark any printed items as return(False) # -# Unit test +# Unit test ***NEEDS WORK*** Obsolete # def test(accountsid) : import logging @@ -394,7 +396,7 @@ def test(accountsid) : logger = logging.getLogger('Messager') # main logger logger.setLevel(logging.DEBUG) # very verbose - feed = Twiliofeed(accountsid, logger) + feed = Twiliofeed(accountsid, logger) # ***NEEDS WORK*** feed.start() for i in xrange(300) : msg = feed.getitem() diff --git a/messager/userinterface.py b/messager/userinterface.py index d4c49f9..8c0e82c 100644 --- a/messager/userinterface.py +++ b/messager/userinterface.py @@ -273,9 +273,11 @@ def __init__(self, tty, newsfeeds, config, logger) : # SMS feed initialization if config.has_section("twilio") : # if Twilio mode self.smsmsgfeed = twiliofeed.Twiliofeed( + config.get("twilio", "serverpollurl"), config.get("twilio", "accountsid"), config.get("twilio", "authtoken"), config.get("twilio", "phone"), + config.get("twilio", "title"), self.logger) if config.has_section("format") : # format config self.cutmarks = config.getboolean("format","cutmarks") @@ -530,10 +532,9 @@ def runui(self, initialcmd = None) : self.abortthreads() # abort all threads raise except (KeyboardInterrupt) as message : # if shutdown - self.logger.error("Shutting down: " + str(message)) - self.abortthreads() # abort all threads - raise - except (RuntimeError) as message : # if trouble + self.logger.error("Control-C - Shutting down and exiting.") + sys.exit() # exit normally + except (RuntimeError) as message : # if trouble self.logger.exception("Unrecoverable error, aborting: " + str(message)) self.abortthreads() # abort all threads raise # re-raise exception with other thread exited.