def send_notifications(self): """ send queued for delivery messages """ notifications = reminders.SentNotification.objects.filter( status="queued", date_to_send__lt=datetime.datetime.now() ) count = notifications.count() if count > 0: self.info("found {0} notification(s) to send".format(count)) for notification in notifications: connection = notification.recipient.default_connection if not connection: self.debug("no connection found for recipient {0}, unable " "to send".format(notification.recipient)) continue msg = OutgoingMessage(connection=connection, template=notification.message) success = True try: msg.send() except Exception, e: self.exception(e) success = False if success and (msg.sent or msg.sent is None): self.debug("notification sent successfully") notification.status = "sent" notification.date_sent = datetime.datetime.now() else: self.debug("notification failed to send") notification.status = "error" notification.save()
def demo(req, poll_id): poll = get_object_or_404(Poll, pk=poll_id) (b1, created) = Backend.objects.get_or_create(name='dmark') # Terra (c1, created) = \ Connection.objects.get_or_create(identity='256785137868', defaults={'backend': b1}) # Sharad (b2, created) = Backend.objects.get_or_create(name='utl') (c2, created) = \ Connection.objects.get_or_create(identity='256717171100', defaults={'backend': b2}) router = get_router() outgoing = OutgoingMessage(c1, "dear Bulambuli representative: uReport, Uganda's community-level monitoring system, shows that 75% of young reporters in your district found that their local water point IS NOT functioning." ) router.handle_outgoing(outgoing) outgoing = OutgoingMessage(c2, "dear Amuru representative: uReport, Uganda's community-level monitoring system, shows that 46.7% of young reporters in your district found that their local water point IS NOT functioning." ) router.handle_outgoing(outgoing) return HttpResponse(status=200)
def default(self, message): # In the default phase, after everyone has had a chance to deal # with this message, check if it might be a response to a previous # blast, and if so pass along to the original sender if message.contact: window = datetime.utcnow() - timedelta(hours=self.BLAST_RESPONSE_WINDOW_HOURS) broadcasts = BroadcastMessage.objects.filter\ (date__gte=window, recipients=message.contact) if broadcasts.count() > 0: latest_broadcast = broadcasts.order_by("-date")[0] if not latest_broadcast.contact.default_connection: self.info("Can't send to %s as they have no connections" % \ latest_broadcast.contact) message.respond(NO_CONTACT, sender=message.contact.name, recipient=latest_broadcast.contact) else: response = OutgoingMessage(latest_broadcast.contact.default_connection, "%(text)s [from %(user)s]", **{"text": message.text, "user": message.contact.name}) response.send() logger_msg = getattr(response, "logger_msg", None) if not logger_msg: self.error("No logger message found for %s. Do you have the message log app running?" %\ message) BroadcastResponse.objects.create(broadcast=latest_broadcast, contact=message.contact, text=message.text, logger_message=logger_msg) return True
def _send_message(self, contact, text): """Send message through connection associated with this contact""" if not contact.default_connection: return False message = OutgoingMessage(contact.default_connection,text) return message.send()
def reimburse(): ''' Start reimbursement process, entailing interaction with special numbers ''' counter = 0 network_name_map = dict([(v, k) for k, v in NAME_NETWORK_MAP.items()]) reimbursements = ReimbursementRecord.objects.exclude( status__in=(ReimbursementRecord.COMPLETED, ReimbursementRecord.ERROR) ) #import pdb;pdb.set_trace() for network, _ in Subscriber.NETWORKS: print 'network: %s'%network if reimbursements.filter( status__in=( ReimbursementRecord.IN_PROGRESS, ReimbursementRecord.QUEUED), subscriber__network=network): continue else: #there is no reimbursement in progress for "network" subscribers = Subscriber.objects.filter(balance__gt=0, network=network) min_time = settings.REIMBURSEMENT_MIN_TIME qualified = qualify(subscribers, min_time) if qualified: subscriber = qualified[0] else: continue network_name = network_name_map.get(network) _amount = max(subscriber.balance, settings.MINIMUM_TRANSFERS.get(network_name)) backend_name = subscriber.get_backend() backend, _ = Backend.objects.get_or_create(name=backend_name) text = subscriber.first_message % { 'number': '0%s'%subscriber.number[-10:], 'amount': _amount, 'pin': settings.NETWORK_PINS.get(network_name) } logging.info('message to send is %s'%text) to_number = REIMBURSEMENT_NUMBERS.get(network_name) if len(to_number) < 11:#If it is a short-code, prefix with 's' to_number = 's%s'%to_number connection, _ = Connection.objects.get_or_create( backend=backend, identity=to_number) msg = OutgoingMessage(connection=connection, template=text) try: msg.send() except: router = Router() #router.start() router.outgoing(msg) ReimbursementRecord.objects.create( subscriber=subscriber, amount=_amount, status=ReimbursementRecord.IN_PROGRESS) counter += 1 return counter
def ajax_POST_test(self, get, post): form = MessageForm(post) if form.is_valid(): contact = form.cleaned_data["contact"] message = form.cleaned_data["message"] phone = form.cleaned_data["phone"] backend = Backend.objects.get(name="clickatell") connection, _ = Connection.objects.get_or_create(contact=contact, identity=phone, backend=backend) message = OutgoingMessage(connection, message) return message.send()
def fake_pending_results(self, clinic): """Notifies clinic staff that results are ready via sms, except this is fake!""" contacts = Contact.active.filter(types=const.get_clinic_worker_type()).location(clinic) results = get_fake_results(3, clinic) for contact in contacts: msg = OutgoingMessage(connection=contact.default_connection, template=RESULTS_READY, name=contact.name, count=len(results)) msg.send() self._mark_results_pending(results, msg.connection)
def ajax_POST_test(self, get, post): form = MessageForm(post) if form.is_valid(): contact = form.cleaned_data['contact'] message = form.cleaned_data['message'] phone = form.cleaned_data['phone'] backend = Backend.objects.get(name='clickatell') connection, _ = Connection.objects.get_or_create(contact=contact, identity=phone, backend=backend) message = OutgoingMessage(connection, message) return message.send()
def fake_pending_results(self, clinic): """Notifies clinic staff that results are ready via sms, except this is fake!""" contacts = Contact.active.filter( types=const.get_clinic_worker_type()).location(clinic) results = get_fake_results(3, clinic) for contact in contacts: msg = OutgoingMessage(connection=contact.default_connection, template=RESULTS_READY, name=contact.name, count=len(results)) msg.send() self._mark_results_pending(results, msg.connection)
def process_queue(router): logger.debug('processing queue') # queued messages messages = OutgoingLog.objects.filter(status=OutgoingLog.QUEUED)[:10] for message in messages: logger.debug('Processing message: %s', message) conn, _ = Connection.objects.get_or_create(identity=message.identity, backend=message.backend) msg = OutgoingMessage(conn, message.text) msg.send() message.status = str(OutgoingLog.DELIVERED) message.save()
def testAppCancel(self): router = get_router() class CancelApp(AppBase): # cancel outgoing phases by returning True def outgoing(self, msg): return False @property def name(self): return "ReplyApp" try: router.apps.append(CancelApp(router)) msg = OutgoingMessage(self.connection, "test") db_msg = router.handle_outgoing(msg) # assert a db message was created, but also cancelled self.assertTrue(db_msg.pk) self.assertEqual(db_msg.text, "test") self.assertEqual(db_msg.direction, "O") self.assertEqual(db_msg.connection, self.connection) self.assertEqual(db_msg.status, 'C') finally: router.apps = []
def handle(self, text): # create the "ticket" in the db HelpRequest.objects.create(requested_by=self.msg.connection, additional_text=text) params = {"phone": self.msg.connection.identity} resp_template = ANONYMOUS_FORWARD if self.msg.connection.contact: params["name"] = self.msg.connection.contact.name if self.msg.connection.contact.location: params["location"] = self.msg.connection.contact.location resp_template = CON_LOC_FORWARD else: resp_template = CONTACT_FORWARD if text: resp_template = resp_template + " " + ADDITIONAL_INFO params["message"] = text for help_admin in Contact.active.filter(is_help_admin=True): OutgoingMessage(help_admin.default_connection, resp_template, **params).send() person_arg = " " + self.msg.connection.contact.name if self.msg.connection.contact else "" self.respond(RESPONSE, person=person_arg)
def broadcast(self, text, contacts): message_body = "%(text)s [from %(user)s to %(group)s]" for contact in contacts: if contact.default_connection is None: self.info("Can't send to %s as they have no connections" % contact) else: OutgoingMessage( contact.default_connection, message_body, **{ "text": text, "user": self.msg.contact.name, "group": self.group_name }).send() logger_msg = getattr(self.msg, "logger_msg", None) if not logger_msg: self.error("No logger message found for %s. Do you have the message log app running?" %\ self.msg) bmsg = BroadcastMessage.objects.create(logger_message=logger_msg, contact=self.msg.contact, text=text, group=self.group_name) bmsg.recipients = contacts bmsg.save() return True
def testRouter(self): router = get_router() msg = OutgoingMessage(self.connection, "test") db_msg = router.handle_outgoing(msg) # assert a db message was created self.assertTrue(db_msg.pk) self.assertEqual(db_msg.text, "test") self.assertEqual(db_msg.direction, "O") self.assertEqual(db_msg.connection, self.connection) self.assertEqual(db_msg.status, 'Q') # check our queue msgs = Message.objects.filter(status='Q') self.assertEqual(1, len(msgs)) # now mark the message as delivered router.mark_delivered(db_msg.pk) # load it back up db_msg = Message.objects.get(id=db_msg.pk) # assert it looks ok now self.assertEqual(db_msg.text, "test") self.assertEqual(db_msg.direction, 'O') self.assertEqual(db_msg.connection, self.connection) self.assertEqual(db_msg.status, 'D')
def send_appointment_reminder(patient, default_conn=None, pronouns=None): if pronouns is None: pronouns = {} logger.info('Sending appointment reminder for %s' % patient) if patient.location: logger.debug('using patient location (%s) to find CBAs' % patient.location) # if the cba was registered, we'll have a location on # the patient and can use that information to find the CBAs to whom # we should send the appointment reminders # TODO: also check child locations? connections = list(Connection.objects.filter( contact__types__slug=const.CBA_SLUG, contact__location=patient.location, contact__is_active=True)) logger.debug('found %d CBAs to deliver reminders to' % len(connections)) elif default_conn: logger.debug('no patient location; using default_conn') # if the CBA was not registered, just send the notification to the # CBA who logged the event connections = [default_conn] else: logger.debug('no patient location or default_conn; not sending any ' 'reminders') for connection in connections: if connection.contact: cba_name = ' %s' % connection.contact.name else: cba_name = '' if patient.location: if patient.location.type == const.get_zone_type() and\ patient.location.parent: clinic_name = patient.location.parent.name else: clinic_name = patient.location.name else: clinic_name = 'the clinic' msg = OutgoingMessage(connection, _("Hello%(cba)s. %(patient)s is due " "for their next clinic appointment. Please " "deliver a reminder to this person and ensure " "they visit %(clinic)s within 3 days."), cba=cba_name, patient=patient.name, clinic=clinic_name) msg.send() return connections
def ussd_msg_response(msg, template, **kwargs): response = OutgoingMessage( get_ussd_connection(msg.connection), template, **kwargs ) msg.responses.append(response) return msg
def create_outgoing_message(self, data={}): defaults = { 'template': self.random_string(10), } defaults.update(data) if 'connection' not in defaults: defaults['connection'] = self.create_connection() return OutgoingMessage(**defaults)
def process_outgoing_phases(self, outgoing): """ Passes the passed in message through the outgoing phase for all our configured SMS apps. Apps have the opportunity to cancel messages in this phase by returning False when called with the message. In that case this method will also return False """ # create a RapidSMS outgoing message try: outgoing.connection[0] connections = [outgoing.connection] except TypeError: connections = outgoing.connection msg = OutgoingMessage(connections, outgoing.text.replace('%','%%')) msg.db_message = outgoing send_msg = True for phase in self.outgoing_phases: logger.debug("Out %s phase" % phase) # call outgoing phases in the opposite order of the incoming # phases, so the first app called with an incoming message # is the last app called with an outgoing message for app in reversed(self.apps): logger.debug("Out %s app" % app) try: func = getattr(app, phase) keep_sending = func(msg) # we have to do things this way because by default apps return # None from outgoing() if keep_sending is False: send_msg = False except Exception, err: app.exception() # during any outgoing phase, an app can return True to # abort ALL further processing of this message if not send_msg: outgoing.status = 'C' outgoing.save() logger.warning("Message cancelled") send_msg = False break
def handle(self, **options): try: connection = Connection.objects.get(identity=settings.PING_NUMBER) text = datetime.datetime.now().strftime('Worked at %H:%M %Y-%m-%d') get_router().handle_outgoing(OutgoingMessage(connection, text)) except: print "exception" pass
def process_outgoing_phases(self, outgoing): """ Passes the passed in message through the outgoing phase for all our configured SMS apps. Apps have the opportunity to cancel messages in this phase by returning False when called with the message. In that case this method will also return False """ # create a RapidSMS outgoing message msg = OutgoingMessage(outgoing.connection, outgoing.text.replace('%', '%%')) msg.db_message = outgoing send_msg = True for phase in self.outgoing_phases: self.debug("Out %s phase" % phase) # call outgoing phases in the opposite order of the incoming # phases, so the first app called with an incoming message # is the last app called with an outgoing message for app in reversed(self.apps): self.debug("Out %s app" % app) try: func = getattr(app, phase) keep_sending = func(msg) # we have to do things this way because by default apps return # None from outgoing() if keep_sending is False: send_msg = False except Exception, err: app.exception() # during any outgoing phase, an app can return True to # abort ALL further processing of this message if not send_msg: outgoing.status = 'C' outgoing_db_lock.acquire() outgoing.save() outgoing_db_lock.release() self.warning("Message cancelled") send_msg = False break
def test_long_ascii_message(): """ ASCII messages over 160 characters should have a split parameter """ backend = MachBackend(name="mach", router=None, **basic_conf) bk = Backend.objects.create(name='long-ascii') connection = Connection.objects.create(identity='1112229999', backend=bk) text = get_random_string(200) message = OutgoingMessage(connection, text) data = backend.prepare_message(message) assert_equals(data['split'], 2)
def test_long_unicode_message(): """ Unicode messages over 70 characters should have a split parameter """ backend = MachBackend(name="mach", router=None, **basic_conf) bk = Backend.objects.create(name='long-unicode') connection = Connection.objects.create(identity='1112229999', backend=bk) text = get_random_string(200, choices=UNICODE_CHARS) message = OutgoingMessage(connection, text) data = backend.prepare_message(message) assert_equals(data['split'], 3)
def test_message_id(self): """All message objects should have IDs.""" connections = [self.create_connection()] msg = MessageBase(text="test", connections=connections) self.assertIsNotNone(msg.id) msg = IncomingMessage(text="test", connections=connections) self.assertIsNotNone(msg.id) msg = OutgoingMessage(text="test", connections=connections) self.assertIsNotNone(msg.id)
def test_outgoing_unicode_characters(): basic_conf['config']['encoding'] = 'UTF-8' backend = TwilioBackend(name="twilio", router=None, **basic_conf) bk = Backend.objects.create(name='test') connection = Connection.objects.create(identity='1112229999', backend=bk) text = random_unicode_string(20) message = OutgoingMessage(connection, text) data = backend.prepare_message(message) assert_equals(data['Body'].decode('UTF-8'), text)
def test_outgoing_message(self): conf = {'user': '******', 'password': '******', 'api_id': '1234'} clickatell = ClickatellBackend(name="clickatell", router=self.router, **conf) message = OutgoingMessage([self.connection], 'abc') msg, data = clickatell._prepare_message(message) keys = ('user', 'password', 'api_id', 'to', 'text') for key in keys: self.assertTrue(key in data) self.assertEqual('abc', data['text'])
def test_outgoing(self): """ Router.outgoing should call backend.send() method and set message.sent flag respectively """ msg = OutgoingMessage(self.connection, 'hello!') self.router.outgoing(msg) self.assertTrue(msg.sent) self.assertEqual(msg, self.outbox[0])
def test_outgoing_unicode_characters(): """ Outgoing unicode characters need to be UCS/UTF-16 encoded """ backend = MachBackend(name="mach", router=None, **basic_conf) bk = Backend.objects.create(name='test') connection = Connection.objects.create(identity='1112229999', backend=bk) text = random_unicode_string(20) message = OutgoingMessage(connection, text) data = backend.prepare_message(message) assert_equals(data['msg'].decode(MachBackend.encoding), text) assert_true(data['encoding'], 'ucs')
def queue_messages_task(): """ Queue batched messages TODO: Ensure that batches that were queued before are taken care of first """ from .models import Message, MessageBatch from rapidsms.messages.outgoing import OutgoingMessage batches = MessageBatch.objects.filter(status='Q') for batch in batches: try: messages = Message.objects.filter(batch=batch, status='P', direction='O')[0:settings.CHUNK_SIZE] # create a RapidSMS outgoing message for outgoing in messages: msg = OutgoingMessage(outgoing.connection, outgoing.text.replace('%','%%')) msg.db_message = outgoing if msg: outgoing.status = 'Q' outgoing.save() except IndexError: pass
def create_outgoing_message(self, data={}, backend=None): """Create and return RapidSMS OutgoingMessage object.""" defaults = { 'text': self.random_string(10), } defaults.update(data) if 'connections' not in defaults: conn_kwargs = {} if backend: conn_kwargs = {'data': {'backend': backend}} defaults['connections'] = [self.create_connection(**conn_kwargs)] return OutgoingMessage(**defaults)
def view_message_history(request, connection_id): """ This view lists all (sms message) correspondence between RapidSMS and a User """ direction_choices = DIRECTION_CHOICES status_choices = STATUS_CHOICES reply_form = ReplyForm() connection = get_object_or_404(Connection, pk=connection_id) if connection.contact: messages = Message.objects.filter( connection__contact=connection.contact) else: messages = Message.objects.filter(connection=connection) messages = messages.order_by('-date') total_incoming = messages.filter(direction="I").count() total_outgoing = messages.filter(direction="O").count() latest_message = None if total_incoming: latest_message = messages.filter(direction="I").latest('date') if request.method == 'POST': reply_form = ReplyForm(request.POST) if reply_form.is_valid(): if Connection.objects.filter( identity=reply_form.cleaned_data['recipient']).count(): text = reply_form.cleaned_data.get('message') conn = Connection.objects.filter( identity=reply_form.cleaned_data['recipient'])[0] in_response_to = reply_form.cleaned_data['in_response_to'] outgoing = OutgoingMessage(conn, text) get_router().handle_outgoing(outgoing, in_response_to) return redirect("/contact/%d/message_history/" % connection.pk) else: reply_form.errors.setdefault('short_description', ErrorList()) reply_form.errors['recipient'].append( "This number isn't in the system") return render_to_response("contact/message_history.html", { "messages": messages, "stats_latest_message": latest_message, "stats_total_incoming": total_incoming, "stats_total_outgoing": total_outgoing, "connection": connection, "direction_choices": direction_choices, "status_choices": status_choices, "replyForm": reply_form }, context_instance=RequestContext(request))
def perform(self, request, results): if results is None or len(results) == 0: return ('A message must have one or more recipients!', 'error') if request.user and request.user.has_perm('contact.can_message'): router = get_router() text = self.cleaned_data['text'] for msg in results: outgoing = OutgoingMessage(msg.connection, text) router.handle_outgoing(outgoing, msg) return ('%d messages sent successfully' % results.count(), 'success',) else: return ("You don't have permission to send messages!", 'error',)
def fire_ze_missiles(self): contacts_with_feeds = Contact.objects.filter(feed__isnull=False) #assumes contacts are correctly set up with an identity etc. for contact in contacts_with_feeds: if contact.default_connection is None: logging.warn("Can't send to %s as they have no connections" % contact) continue story_txt = '%s::%s' % ( contact.feed.get_latest_story().story_title, contact.feed.get_latest_story().story_contents) print 'Contact default backend=%s' % contact.default_connection OutgoingMessage(contact.default_connection, story_txt).send() self.respond(SUCCESS_MSG)
def default(self, message): # In the default phase, after everyone has had a chance to deal # with this message, check if it might be a response to a previous # blast, and if so pass along to the original sender if message.contact: window = datetime.utcnow() - timedelta( hours=self.BLAST_RESPONSE_WINDOW_HOURS) broadcasts = BroadcastMessage.objects.filter\ (date__gte=window, recipients=message.contact) if broadcasts.count() > 0: latest_broadcast = broadcasts.order_by("-date")[0] if not latest_broadcast.contact.default_connection: self.info("Can't send to %s as they have no connections" % \ latest_broadcast.contact) message.respond(NO_CONTACT, sender=message.contact.name, recipient=latest_broadcast.contact) else: response = OutgoingMessage( latest_broadcast.contact.default_connection, "%(text)s [from %(user)s]", **{ "text": message.text, "user": message.contact.name }) response.send() logger_msg = getattr(response, "logger_msg", None) if not logger_msg: self.error("No logger message found for %s. Do you have the message log app running?" %\ message) BroadcastResponse.objects.create( broadcast=latest_broadcast, contact=message.contact, text=message.text, logger_message=logger_msg) return True
def create_outgoing_message(self, data={}, backend=None): """Create and return RapidSMS OutgoingMessage object. A random ``template`` will be created if not specified in ``data`` attribute. :param data: Optional dictionary of field name/value pairs to pass to ``OutgoingMessage.__init__``.""" defaults = { 'text': self.random_string(10), } defaults.update(data) if 'connections' not in defaults: conn_kwargs = {} if backend: conn_kwargs = {'data': {'backend': backend}} defaults['connections'] = [self.create_connection(**conn_kwargs)] return OutgoingMessage(**defaults)
def console(request): """ Our web console, lets you see recent messages as well as send out new ones for processing. """ form = SendForm() reply_form = ReplyForm() search_form = SearchForm() queryset = Message.objects.all() if request.method == 'POST': if request.REQUEST['action'] == 'test': form = SendForm(request.POST) if form.is_valid(): backend = "console" message = get_router().handle_incoming(backend, form.cleaned_data['sender'], form.cleaned_data['text']) reply_form = ReplyForm() elif request.REQUEST['action'] == 'reply': reply_form = ReplyForm(request.POST) if reply_form.is_valid(): text = reply_form.cleaned_data['message'] try: conn = Connection.objects.filter(identity=reply_form.cleaned_data['recipient'])[0] except (Connection.DoesNotExist,IndexError): backend, created = Backend.objects.get_or_create(name="test") conn, created = Connection.objects.get_or_create(backend=backend, identity=reply_form.cleaned_data['recipient']) outgoing = OutgoingMessage(conn, text) get_router().handle_outgoing(outgoing) if request.REQUEST.get('action', None) == 'search': # split on spaces search_form = SearchForm(request.REQUEST) if search_form.is_valid(): terms = search_form.cleaned_data['search'].split() if terms: term = terms[0] query = (Q(text__icontains=term) | Q(in_response_to__text__icontains=term) | Q(connection__identity__icontains=term)) for term in terms[1:]: query &= (Q(text__icontains=term) | Q(in_response_to__text__icontains=term) | Q(connection__identity__icontains=term)) queryset = queryset.filter(query) paginator = Paginator(queryset.order_by('-id'), 20) page = request.REQUEST.get('page') try: messages = paginator.page(page) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. messages = paginator.page(paginator.num_pages) except: # None or not an integer, default to first page messages = paginator.page(1) return render_to_response( "router/index.html", { "messages_table": MessageTable(queryset, request=request), "form": form, "reply_form": reply_form, "search_form": search_form, "sms_messages": messages }, context_instance=RequestContext(request) )
def handle(self, message): if message.text.strip().upper().startswith("DEMO"): rest = message.text.strip()[4:].strip() clinic = None if rest: # optionally allow the tester to pass in a clinic code try: clinic = Location.objects.get(slug__iexact=rest) except Location.DoesNotExist: # maybe they just passed along some extra text pass if not clinic and message.connection.contact \ and message.connection.contact.location: # They were already registered for a particular clinic # so assume they want to use that one. clinic = message.connection.contact.location if not clinic: message.respond(DEMO_FAIL) else: # Fake like we need to prompt their clinic for results, as a means # to conduct user testing. The mocker does not touch the database self.info("Initiating a demo sequence to clinic: %s" % clinic) self.fake_pending_results(clinic) return True elif message.connection in self.waiting_for_pin \ and message.connection.contact: pin = message.text.strip() if pin.upper() == message.connection.contact.pin.upper(): results = self.waiting_for_pin[message.connection] responses = build_results_messages(results) for resp in responses: message.respond(resp) message.respond(INSTRUCTIONS, name=message.connection.contact.name) self.waiting_for_pin.pop(message.connection) # remove pending contacts for this clinic and notify them it # was taken care of clinic_connections = [contact.default_connection for contact in \ Contact.active.filter\ (location=message.connection.contact.location)] for conn in clinic_connections: if conn in self.waiting_for_pin: self.waiting_for_pin.pop(conn) OutgoingMessage( conn, RESULTS_PROCESSED, name=message.connection.contact.name).send() self.last_collectors[message.connection.contact. location] = message.connection.contact return True else: # pass a secret message to default phase, see app.py self.debug("caught a potential bad pin: %s for %s" % \ (message.text, message.connection)) message.possible_bad_mock_pin = True
def send_message_safe(contact, message): if contact.default_connection: OutgoingMessage(contact.default_connection, message).send()
def _send_message(self, connection, message_body): '''Attempts to send a message through a given connection''' # attempt to send the message # TODO: what could go wrong here? msg = OutgoingMessage(connection, message_body) return msg.send()
def console(request): """ Our web console, lets you see recent messages as well as send out new ones for processing. """ form = SendForm() reply_form = ReplyForm() search_form = SearchForm() queryset = Message.objects.all() if request.method == 'POST': if request.POST['action'] == 'test': form = SendForm(request.POST) if form.is_valid(): backend = "console" message = get_router().handle_incoming( backend, form.cleaned_data['sender'], form.cleaned_data['text']) reply_form = ReplyForm() elif request.POST['action'] == 'reply': reply_form = ReplyForm(request.POST) if reply_form.is_valid(): if Connection.objects.filter( identity=reply_form.cleaned_data['recipient']).count(): text = reply_form.cleaned_data['message'] conn = Connection.objects.filter( identity=reply_form.cleaned_data['recipient'])[0] outgoing = OutgoingMessage(conn, text) get_router().handle_outgoing(outgoing) else: reply_form.errors.setdefault('short_description', ErrorList()) reply_form.errors['recipient'].append( "This number isn't in the system") elif request.POST['action'] == 'search': # split on spaces search_form = SearchForm(request.POST) if search_form.is_valid(): terms = search_form.cleaned_data['search'].split() if terms: term = terms[0] query = (Q(text__icontains=term) | Q(in_response_to__text__icontains=term) | Q(connection__identity__icontains=term)) for term in terms[1:]: query &= (Q(text__icontains=term) | Q(in_response_to__text__icontains=term) | Q(connection__identity__icontains=term)) queryset = queryset.filter(query) paginator = Paginator(queryset.order_by('-id'), 20) page = request.GET.get('page') try: messages = paginator.page(page) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. messages = paginator.page(paginator.num_pages) except: # None or not an integer, default to first page messages = paginator.page(1) return render_to_response( "router/index.html", { "messages_table": MessageTable(queryset, request=request), "form": form, "reply_form": reply_form, "search_form": search_form, "messages": messages }, context_instance=RequestContext(request))