Skip to content

Commit 8a5ef1e

Browse files
committed
Hologram Python SDK v0.6.1 release
1 parent 7fe0b78 commit 8a5ef1e

23 files changed

+125
-158
lines changed

ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2017-09-29 Hologram <[email protected]>
2+
* Fixed bug where empty result list might cause an index error
3+
4+
2017-09-28 Hologram <[email protected]>
5+
* Logging is now turned off by default for CLI subcommands.
6+
* Added -v and -vv options for INFO and DEBUG log levels respectively.
7+
18
2017-09-22 Hologram <[email protected]>
29
* Added program install verification steps to install script.
310

Hologram/Authentication/CSRPSKAuthentication.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
# LICENSE: Distributed under the terms of the MIT License
1010
#
1111
import json
12-
import sys
1312
from Exceptions.HologramError import AuthenticationError
1413
from HologramAuthentication import HologramAuthentication
1514

@@ -24,11 +23,7 @@ def __init__(self, credentials):
2423
def buildPayloadString(self, messages, topics=None, modem_type=None,
2524
modem_id=None, version=None):
2625

27-
try:
28-
self.enforceValidDeviceKey()
29-
except AuthenticationError as e:
30-
self.logger.error(repr(e))
31-
sys.exit(1)
26+
self.enforceValidDeviceKey()
3227

3328
super(CSRPSKAuthentication, self).buildPayloadString(messages,
3429
topics=topics,
@@ -40,11 +35,7 @@ def buildPayloadString(self, messages, topics=None, modem_type=None,
4035

4136
def buildSMSPayloadString(self, destination_number, message):
4237

43-
try:
44-
self.enforceValidDeviceKey()
45-
except AuthenticationError as e:
46-
self.logger.error(repr(e))
47-
sys.exit(1)
38+
self.enforceValidDeviceKey()
4839

4940
send_data = 'S' + self.credentials['devicekey']
5041
send_data += destination_number + ' ' + message

Hologram/Cloud.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@
99

1010
import logging
1111
from logging import NullHandler
12-
import sys
1312
import Event
1413
from Network import NetworkManager
1514
from Authentication import *
1615

17-
__version__ = '0.6.0'
16+
__version__ = '0.6.1'
1817

1918
class Cloud(object):
2019

@@ -113,8 +112,7 @@ def send_port(self, send_port):
113112
try:
114113
self._send_port = int(send_port)
115114
except ValueError as e:
116-
self.logger.error('Invalid port parameter. Unable to convert port to a valid integer')
117-
sys.exit(1)
115+
raise ValueError('Invalid port parameter. Unable to convert port to a valid integer')
118116

119117
@property
120118
def receive_host(self):

Hologram/CustomCloud.py

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,9 @@ def __init__(self, credentials, send_host='', send_port=0,
3434
receive_port=receive_port,
3535
network=network)
3636

37-
try:
38-
# Enforce that the send and receive configs are set before using the class.
39-
if enable_inbound and (receive_host == '' or receive_port == 0):
40-
raise HologramError('Must set receive host and port for inbound connection')
41-
42-
except HologramError as e:
43-
self.logger.error(repr(e))
44-
sys.exit(1)
37+
# Enforce that the send and receive configs are set before using the class.
38+
if enable_inbound and (receive_host == '' or receive_port == 0):
39+
raise HologramError('Must set receive host and port for inbound connection')
4540

4641
self._periodic_msg_lock = threading.Lock()
4742
self._periodic_msg = None
@@ -81,14 +76,15 @@ def sendMessage(self, message, timeout=SEND_TIMEOUT):
8176

8277
self.event.broadcast('message.sent')
8378
return resultbuf
84-
85-
except HologramError as e:
86-
self.logger.error(repr(e))
87-
sys.exit(1)
8879
except (IOError):
80+
self.__enforce_network_disconnected()
8981
self.logger.error('An error occurred while attempting to send the message to the cloud')
9082
self.logger.error('Please try again.')
9183
return ''
84+
except Exception as e:
85+
self.__enforce_network_disconnected()
86+
raise
87+
9288

9389
def open_send_socket(self, timeout=SEND_TIMEOUT):
9490

@@ -104,10 +100,6 @@ def open_send_socket(self, timeout=SEND_TIMEOUT):
104100
self.sock.settimeout(timeout)
105101
self.sock.connect((self.send_host, self.send_port))
106102
self._is_send_socket_open = True
107-
108-
except HologramError as e:
109-
self.logger.error(repr(e))
110-
sys.exit(1)
111103
except (IOError):
112104
self.logger.error('An error occurred while attempting to send the message to the cloud')
113105
self.logger.error('Please try again.')
@@ -123,10 +115,6 @@ def close_send_socket(self):
123115
self.sock.close()
124116
self._is_send_socket_open = False
125117
self.logger.info('Socket closed.')
126-
127-
except HologramError as e:
128-
self.logger.error(repr(e))
129-
sys.exit(1)
130118
except (IOError):
131119
self.logger.error('An error occurred while attempting to send the message to the cloud')
132120
self.logger.error('Please try again.')
@@ -152,22 +140,19 @@ def sendPeriodicMessage(self, interval, message, topics=None, timeout=5):
152140

153141
try:
154142
self._enforce_minimum_periodic_interval(interval)
155-
except HologramError as e:
156-
self.logger.error(repr(e))
157-
sys.exit(1)
158143

159-
self._periodic_msg_lock.acquire()
144+
self._periodic_msg_lock.acquire()
160145

161-
try:
162146
if self._periodic_msg_enabled == True:
163147
raise HologramError('Cannot have more than 1 periodic message job at once')
164-
except HologramError as e:
165-
self.logger.error(repr(e))
166-
sys.exit(1)
167148

168-
self._periodic_msg_enabled = True
149+
self._periodic_msg_enabled = True
169150

170-
self._periodic_msg_lock.release()
151+
self._periodic_msg_lock.release()
152+
153+
except Exception as e:
154+
self.__enforce_network_disconnected()
155+
raise
171156

172157
self._periodic_msg = threading.Thread(target=self._periodic_job_thread,
173158
args=[interval, self.sendMessage,
@@ -211,11 +196,7 @@ def initializeReceiveSocket(self):
211196

212197
def openReceiveSocket(self):
213198

214-
try:
215-
self.__enforce_receive_host_and_port()
216-
except HologramError as e:
217-
self.logger.error(repr(e))
218-
sys.exit(1)
199+
self.__enforce_receive_host_and_port()
219200

220201
self._receive_cv.acquire()
221202
self._receive_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -258,7 +239,7 @@ def open_receive_socket_helper(self):
258239
self._receive_cv.release()
259240

260241
# Spin a new thread for accepting incoming operations
261-
self._accept_thread = threading.Thread(target = self.acceptIncomingConnection)
242+
self._accept_thread = threading.Thread(target=self.acceptIncomingConnection)
262243
self._accept_thread.daemon = True
263244
self._accept_thread.start()
264245

@@ -297,7 +278,7 @@ def acceptIncomingConnection(self):
297278
try:
298279
self._receive_socket.setblocking(0)
299280
(clientsocket, address) = self._receive_socket.accept()
300-
self.logger.info('Connected to ' + str(address))
281+
self.logger.info('Connected to %s', address)
301282
# Spin a new thread to handle the current incoming operation.
302283
threading.Thread(target = self.__incoming_connection_thread,
303284
args = [clientsocket]).start()
@@ -324,13 +305,13 @@ def __incoming_connection_thread(self, clientsocket):
324305
break
325306
recv += result
326307

327-
self.logger.info('Received message: ' + str(recv))
308+
self.logger.info('Received message: %s', recv)
328309

329310
self._receive_buffer_lock.acquire()
330311

331312
# Append received message into receive buffer
332313
self._receive_buffer.append(recv)
333-
self.logger.debug('Receive buffer: ' + str(self._receive_buffer))
314+
self.logger.debug('Receive buffer: %s', self._receive_buffer)
334315

335316
self._receive_buffer_lock.release()
336317

@@ -364,3 +345,7 @@ def __enforce_receive_host_and_port(self):
364345
def _enforce_minimum_periodic_interval(self, interval):
365346
if interval < MIN_PERIODIC_INTERVAL:
366347
raise HologramError('Interval cannot be less than %d seconds.' % MIN_PERIODIC_INTERVAL)
348+
349+
def __enforce_network_disconnected(self):
350+
if self.network_type == 'Cellular':
351+
self.network.disconnect()

Hologram/HologramCloud.py

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class HologramCloud(CustomCloud):
5858
}
5959

6060
def __init__(self, credentials, enable_inbound=False, network='',
61-
authentication_type='csrpsk'):
61+
authentication_type='totp'):
6262
super(HologramCloud, self).__init__(credentials,
6363
send_host=HOLOGRAM_HOST_SEND,
6464
send_port=HOLOGRAM_PORT_SEND,
@@ -72,16 +72,12 @@ def __init__(self, credentials, enable_inbound=False, network='',
7272
# EFFECTS: Authentication Configuration
7373
def setAuthenticationType(self, credentials, authentication_type='csrpsk'):
7474

75-
try:
76-
if authentication_type not in HologramCloud._authentication_handlers:
77-
raise HologramError('Invalid authentication type: %s' % authentication_type)
75+
if authentication_type not in HologramCloud._authentication_handlers:
76+
raise HologramError('Invalid authentication type: %s' % authentication_type)
7877

79-
self.authenticationType = authentication_type
78+
self.authenticationType = authentication_type
8079

81-
self.authentication = HologramCloud._authentication_handlers[self.authenticationType](credentials)
82-
except HologramError as e:
83-
self.logger.error(repr(e))
84-
sys.exit(1)
80+
self.authentication = HologramCloud._authentication_handlers[self.authenticationType](credentials)
8581

8682
# EFFECTS: Sends the message to the cloud.
8783
def sendMessage(self, message, topics = None, timeout = 5):
@@ -126,12 +122,8 @@ def sendMessage(self, message, topics = None, timeout = 5):
126122

127123
def sendSMS(self, destination_number, message):
128124

129-
try:
130-
self.__enforce_valid_destination_number(destination_number)
131-
self.__enforce_max_sms_length(message)
132-
except HologramError as e:
133-
self.logger.error(repr(e))
134-
sys.exit(1)
125+
self.__enforce_valid_destination_number(destination_number)
126+
self.__enforce_max_sms_length(message)
135127

136128
output = self.authentication.buildSMSPayloadString(destination_number,
137129
message)
@@ -148,26 +140,21 @@ def sendSMS(self, destination_number, message):
148140
# EFFECTS: Request for nonce.
149141
def request_nonce(self):
150142

151-
try:
152-
self.open_send_socket()
153-
154-
# build nonce request payload string
155-
request = self.authentication.buildNonceRequestPayloadString()
143+
self.open_send_socket()
156144

157-
self.logger.debug("Sending nonce request with body of length %d", len(request))
158-
self.logger.debug('Send: %s', request)
145+
# build nonce request payload string
146+
request = self.authentication.buildNonceRequestPayloadString()
159147

160-
self.sock.send(request)
161-
self.logger.debug('Nonce request sent.')
148+
self.logger.debug("Sending nonce request with body of length %d", len(request))
149+
self.logger.debug('Send: %s', request)
162150

163-
resultbuf = binascii.b2a_hex(self.receive_send_socket(max_receive_bytes=32))
151+
self.sock.send(request)
152+
self.logger.debug('Nonce request sent.')
164153

165-
if resultbuf is None:
166-
raise HologramError('Internal nonce error')
154+
resultbuf = binascii.b2a_hex(self.receive_send_socket(max_receive_bytes=32))
167155

168-
except HologramError as e:
169-
self.logger.error(repr(e))
170-
sys.exit(1)
156+
if resultbuf is None:
157+
raise HologramError('Internal nonce error')
171158

172159
return resultbuf
173160

@@ -206,6 +193,9 @@ def __parse_hologram_compact_result(self, result):
206193
self.logger.error('Server replied with invalid JSON [%s]', result)
207194
resultList = [ERR_UNKNOWN]
208195

196+
if len(resultList) == 0:
197+
resultList = [ERR_UNKNOWN]
198+
209199
return resultList
210200

211201
def __enforce_max_sms_length(self, message):

Hologram/Network/Cellular.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from Modem import MS2131
1717
from Network import Network
1818
import subprocess
19-
import sys
2019
import usb.core
2120

2221
# Cellular return codes.
@@ -141,15 +140,10 @@ def modem(self):
141140

142141
@modem.setter
143142
def modem(self, modem):
144-
try:
145-
if modem not in self._modemHandlers:
146-
raise NetworkError('Invalid modem type: %s' % modem)
147-
else:
148-
self._modem = self._modemHandlers[modem](event=self.event)
149-
# not sure about the exception handling in here. seems like we should let it bubble up
150-
except NetworkError as e:
151-
self.logger.error(repr(e))
152-
sys.exit(1)
143+
if modem not in self._modemHandlers:
144+
raise NetworkError('Invalid modem type: %s' % modem)
145+
else:
146+
self._modem = self._modemHandlers[modem](event=self.event)
153147

154148
@property
155149
def localIPAddress(self):

Hologram/Network/Modem/ModemMode/PPP.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#
1010
import psutil
1111
import subprocess
12-
import sys
1312
import time
1413
from pppd import PPPConnection
1514
from IPPP import IPPP
@@ -40,11 +39,7 @@ def isConnected(self):
4039
# reroute packets to ppp0 interface.
4140
def connect(self, timeout=DEFAULT_PPP_TIMEOUT):
4241

43-
try:
44-
self.__enforce_no_existing_ppp_session()
45-
except PPPError as e:
46-
self.logger.error(repr(e))
47-
sys.exit(1)
42+
self.__enforce_no_existing_ppp_session()
4843

4944
result = self._ppp.connect(timeout=timeout)
5045

Hologram/Network/Modem/ModemMode/pppd.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import os
1414
import re
1515
import signal
16-
import sys
1716
import time
1817
import threading
1918
from subprocess import Popen, PIPE, STDOUT
@@ -106,14 +105,10 @@ def connectThreadedFunc(self, result):
106105
result[0] = True
107106
return
108107

109-
try:
110-
if 'Modem hangup' in self.output:
111-
raise PPPError('Modem hangup - possibly due to an unregistered SIM')
112-
elif self.proc.poll():
113-
raise PPPConnectionError(self.proc.returncode, self.output)
114-
except (PPPError, PPPConnectionError) as e:
115-
self.logger.error(repr(e))
116-
sys.exit(1)
108+
if 'Modem hangup' in self.output:
109+
raise PPPError('Modem hangup - possibly due to an unregistered SIM')
110+
elif self.proc.poll():
111+
raise PPPConnectionError(self.proc.returncode, self.output)
117112

118113
# EFFECTS: Disconnects from the network.
119114
# Returns true if successful, false otherwise.

0 commit comments

Comments
 (0)