def test_send(self): self.router.start() msg = Message(self.connection, "this is a test") self.assertTrue(msg.send(), "message was sent") waiting = self.backend.next_message() self.assertEquals(msg, waiting, "the backend got the message") self.router.stop()
def test_send (self): self.router.start() msg = Message(self.connection, "this is a test") self.assertTrue(msg.send(), "message was sent") waiting = self.backend.next_message() self.assertEquals(msg, waiting, "the backend got the message") self.router.stop()
def test_respond (self): msg = Message(self.connection, "this is a test") msg.respond("how did it go?") msg.respond("okay?") self.assertEquals(len(msg.responses), 2, "message queues responses") self.assertEquals(msg.responses[0].text, "how did it go?", "it went well") self.assertEquals(msg.responses[1].text, "okay?", "sure enough")
def test__init__(self): msg = Message(self.connection, "this is a test") self.assertEquals(msg.connection, self.connection, "connection is right (connection)") msg = Message(None, "this is a test", self.person) self.assertEquals(msg.connection, self.connection, "connection is right (person)") self.assertEquals(msg.text, "this is a test", "text is right") self.assertEquals(msg.responses, [], "responses is empty") self.assertRaises(Exception, Message)
def responder_loop(self, seconds=10): self.info("Starting responder...") while True: # look for any new handled messages # in the database, and send the responses for msg_in_waiting in MessageInWaiting.objects.filter(status="H"): self.info("Responding to %s.", msg_in_waiting) for response in msg_in_waiting.responses.all(): self.info("Response: %s.", response) # only send confirmed or added responses if response.type != "O": db_connection = msg_in_waiting.get_connection() if db_connection is not None: db_backend = db_connection.backend # we need to get the real backend from the router # to properly send it real_backend = self.router.get_backend(db_backend.slug) if real_backend: connection = Connection(real_backend, db_connection.identity) response_msg = Message(connection, response.text) self.router.outgoing(response_msg) else: # TODO: should we fail harder here? This will permanently # disable responses to this message which is bad. self.error("Can't find backend %s. Messages will not be sent") # mark the original message as responded to msg_in_waiting.status="R" msg_in_waiting.save() # wait until it's time to check again time.sleep(seconds)
def to_group(self, message, grp, rest): ident = self.__identify(message, "posting") grp = self.__group(grp) # check that the caller is a member of # the group to which we are broadcasting if not message.connection.identity in self.groups[grp]: err = "You are not a member of the %s group" % (grp) message.respond(err) self.handled = True # keep a log of broadcasts self.info("Sending to group: %s" % grp) # iterate every member of the group we are broadcasting # to, and queue up the same message to each of them msg = "[%s] %s: %s" % (grp, ident, rest) for dest in self.groups[grp]: if dest != message.connection.identity: Message(dest, msg).send() # notify the caller that his/her message was sent people = len(self.groups[grp]) - 1 msg = "Your message was sent to the %s group (%d people)" % (grp, people) message.respond(msg) self.handled = True
def __callback(self, source, message_text): # drop the "sms://" protocol from the source phone_number = re.compile("[a-z]+://").sub("", source) # create connection and message objects, and # pass it off to the router c = Connection(self, phone_number) m = Message(c, message_text) self.router.send(m)
def test_respond(self): msg = Message(self.connection, "this is a test") msg.respond("how did it go?") msg.respond("okay?") self.assertEquals(len(msg.responses), 2, "message queues responses") self.assertEquals(msg.responses[0].text, "how did it go?", "it went well") self.assertEquals(msg.responses[1].text, "okay?", "sure enough")
def run(self): while self._running: # check for new messages msg = self.modem.next_message(True) if msg is not None: # self.error("index: %s" % msg.index) # self._log( self.modem, "index: %s" % msg.index, "info") # we got an sms! create RapidSMS Connection and # Message objects, and hand it off to the router c = Connection(self, msg.sender) # Try to use message sent date as timestamp # SOMETIMES this doesn't come over, in which # case use the current time try: date = utils.to_naive_utc_dt(msg.sent) except: date = datetime.utcnow() m = Message(connection=c, text=msg.text, date=date) self.router.send(m) # remove the message #if msg.index: # self.modem.command("AT+CMGD=%s" % msg.index) self.modem.command('AT+CMGD="ALL",2') # process all outbound messages while True: try: self.__send_sms(self._queue.get_nowait()) except Queue.Empty: # break out of while break # poll for new messages # every POLL_INTERVAL seconds time.sleep(POLL_INTERVAL) self.modem.command("AT+CPMS?")
def _initiate_tree_sequence(self, user, initiator=None): user_conn = user.connection() if user_conn: db_backend = user_conn.backend # we need to get the real backend from the router # to properly send it real_backend = self.router.get_backend(db_backend.slug) if real_backend: connection = Connection(real_backend, user_conn.identity) text = self._get_tree_sequence(user) if not text: return _(strings["unknown_survey_location"], get_language_code( user.connection)) % ({ "location": user.location, "alias": user.study_id }) else: # first ask the tree app to end any sessions it has open if self.tree_app: self.tree_app.end_sessions(user_conn) if initiator: # if this was initiated by someone else # create an entry for this so they can be # notified upon completion, and also so # we can ignore the data TestSession.objects.create(initiator=initiator, tester=user, status="A") start_msg = Message(connection, text) self.router.incoming(start_msg) return else: error = "Can't find backend %s. Messages will not be sent" % connection.backend.slug self.error(error) return error else: error = "Can't find connection %s. Messages will not be sent" % user_conn self.error(error) return error
def _send_question(self, session, msg=None): '''Sends the next question in the session, if there is one''' state = session.state if state and state.question: response = _(state.question.text, get_language_code(session.connection)) self.info("Sending: %s" % response) if msg: msg.respond(response) else: # we need to get the real backend from the router # to properly send it real_backend = self.router.get_backend( session.connection.backend.slug) if real_backend: connection = Connection(real_backend, session.connection.identity) outgoing_msg = Message(connection, response) self.router.outgoing(outgoing_msg) else: # todo: do we want to fail more loudly than this? error = "Can't find backend %s. Messages will not be sent" % connection.backend.slug self.error(error)
def test_flush_responses (self): msg = Message(self.connection, "this is a test") self.router.start() msg.respond("how did it go?") msg.flush_responses() waiting = self.backend.next_message() self.assertEquals(waiting.text, "how did it go?", "the backend got the message (1)") msg.respond("again?") msg.respond("and again?") msg.flush_responses() waiting = self.backend.next_message() self.assertEquals(waiting.text, "again?", "the backend got the message (2)") waiting = self.backend.next_message() self.assertEquals(waiting.text, "and again?", "the backend got the message (3)") self.router.stop()
def test__unicode__(self): msg = Message(self.connection, "this is a test") self.assertEquals(unicode(msg), "this is a test", "unicode is right")
def test_peer(self): msg = Message(self.connection, "this is a test") self.assertEquals(msg.peer, "12345", "peer identifier is right")
def message(self, identity, text, date=None): c = Connection(self, identity) return Message(connection=c, text=text, date=date)
def _handle_session(self, session, is_ending, klass): self.debug("%s session: %s" % (klass, session)) # get the reporter object reporter = session.connection.reporter iavi_reporter = IaviReporter.objects.get(pk=reporter.pk) if not is_ending: # check if the reporter has an active test session # and if so, link it. Otherwise treat it normally try: test_session = TestSession.objects.get(tester=iavi_reporter, status="A") test_session.tree_session = session test_session.save() except TestSession.DoesNotExist: # not an error, just means this wasn't a test # create a new report for this klass.objects.create(reporter=iavi_reporter, started=session.start_date, session=session, status="A") else: # if we have a test session mark the status and save try: test_session = TestSession.objects.get(tree_session=session) if session.canceled: test_session.status = "F" response = _(strings["test_fail"], get_language_code(test_session.initiator)) % ( { "alias": iavi_reporter.study_id }) else: test_session.status = "P" response = _(strings["test_pass"], get_language_code(test_session.initiator)) % ( { "alias": iavi_reporter.study_id }) test_session.save() # also have to initiate a callback to the # original person who initiated the test db_backend = test_session.initiator.backend real_backend = self.router.get_backend(db_backend.slug) if real_backend: real_connection = Connection( real_backend, test_session.initiator.identity) response_msg = Message(real_connection, response) self.router.outgoing(response_msg) else: error = "Can't find backend %s. Messages will not be sent" % connection.backend.slug self.error(error) except TestSession.DoesNotExist: # not a big deal. it wasn't a test. # if we have a report # update the data and save try: report = klass.objects.get(session=session) for entry in session.entry_set.all(): answer = entry.transition.answer column = self._get_column( entry.transition.current_state) if column: clean_answer = self._get_clean_answer( answer, entry.text) setattr(report, column, clean_answer) report.completed = datetime.now() if session.canceled: report.status = "C" else: report.status = "F" report.save() except klass.DoesNotExist: # oops, not sure how this could happen, but we don't # want to puke self.error("No report found for session %s" % session)
def test_flush_responses(self): msg = Message(self.connection, "this is a test") self.router.start() msg.respond("how did it go?") msg.flush_responses() waiting = self.backend.next_message() self.assertEquals(waiting.text, "how did it go?", "the backend got the message (1)") msg.respond("again?") msg.respond("and again?") msg.flush_responses() waiting = self.backend.next_message() self.assertEquals(waiting.text, "again?", "the backend got the message (2)") waiting = self.backend.next_message() self.assertEquals(waiting.text, "and again?", "the backend got the message (3)") self.router.stop()
def setUp(self): self.sent = [] p = Person() self.short_msg = Message(p, text="This is shorter than 160 characters.") self.long_msg = Message(p, text="This is longer than 160 characters. 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901160 ENDS HEREBeginning of second text message.")
def do_GET(self): # if the path is just "/" then start a new session # and redirect to that session's URL if self.path == "/": session_id = random.randint(100000, 999999) self.send_response(301) self.send_header("Location", "/%d/" % session_id) self.end_headers() return # if the path is of the form /integer/blah # send a new message from integer with content blah send_regex = re.compile(r"^/(.*?)/(.*)") match = send_regex.match(self.path) if match: # parse the url parsed = urlparse(self.path) # use our default backend by default backend = self.server.backend # whether we are incoming or outgoing, be default we are incoming incoming = True # if there is a query string if parsed.query: # see if there is a different backend specified query_string = parse_qs(parsed.query) # if so, try to look it up if 'backend' in query_string: backend = self.server.backend._router.get_backend( query_string['backend'][0]) if not backend: self.send_response(404) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write("No backend with slug: %s found." % query_string['backend'][0]) return # is this actually an outgoing message? if 'direction' in query_string: if query_string['direction'][0].lower() == 'out': incoming = False # parse the groups out match = send_regex.match(parsed.path) # send the message session_id = urllib.unquote(str(match.group(1))) text = urllib.unquote(_str(match.group(2))) if text == "json_resp": self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() if HttpHandler.msg_store.has_key(session_id) and len( HttpHandler.msg_store[session_id]): resp = _str( "{'phone':'%s', 'message':'%s'}" % (session_id, HttpHandler.msg_store[session_id].pop(0).replace( "'", r"\'"))) self.wfile.write(resp) return # get time received = datetime.utcnow() # leave Naive! # received.replace(tzinfo=pytz.utc) c = Connection(backend, session_id) msg = Message(connection=c, text=text, date=received) # inny or outy? if incoming: backend.route(msg) else: backend._router.outgoing(msg) # respond with the number and text self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write( _str("{'phone':'%s', 'message':'%s'}" % (session_id, urllib.unquote(text).replace("'", r"\'")))) return return