コード例 #1
0
ファイル: app.py プロジェクト: afrims/afrims
 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()
コード例 #2
0
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)
コード例 #3
0
ファイル: app.py プロジェクト: AndreLesa/mwana
 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
コード例 #4
0
    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()
コード例 #5
0
ファイル: views.py プロジェクト: dimagi/WBNigeria
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
コード例 #6
0
ファイル: app.py プロジェクト: peterayeni/rapidsms-clickatell
 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()
コード例 #7
0
ファイル: mocking.py プロジェクト: AndreLesa/mwana
 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)
コード例 #8
0
 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()
コード例 #9
0
ファイル: mocking.py プロジェクト: makandok/mwana
 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)
コード例 #10
0
ファイル: utils.py プロジェクト: copelco/souktel-alert
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()
コード例 #11
0
    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 = []
コード例 #12
0
ファイル: help.py プロジェクト: makandok/mwana
    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)
コード例 #13
0
ファイル: base.py プロジェクト: makandok/mwana
    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
コード例 #14
0
    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')
コード例 #15
0
ファイル: tasks.py プロジェクト: kaofelix/mwana
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
コード例 #16
0
def ussd_msg_response(msg, template, **kwargs):
    response = OutgoingMessage(
        get_ussd_connection(msg.connection),
        template,
        **kwargs
    )
    msg.responses.append(response)
    return msg
コード例 #17
0
ファイル: base.py プロジェクト: cheekybastard/rapidsms
 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)
コード例 #18
0
    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
コード例 #19
0
 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
コード例 #20
0
    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
コード例 #21
0
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)
コード例 #22
0
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)
コード例 #23
0
ファイル: tests.py プロジェクト: phpnoida/testingyar
 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)
コード例 #24
0
ファイル: tests.py プロジェクト: leroyg/rapidsms-twilio
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)
コード例 #25
0
 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'])
コード例 #26
0
ファイル: test_outgoing.py プロジェクト: KqSMea8/gueslang
 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])
コード例 #27
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')
コード例 #28
0
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
コード例 #29
0
 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)
コード例 #30
0
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))
コード例 #31
0
    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',)
コード例 #32
0
ファイル: demo.py プロジェクト: dimagi/aremind-rss
    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)
コード例 #33
0
    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
コード例 #34
0
    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)
コード例 #35
0
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)
    )
コード例 #36
0
ファイル: mocking.py プロジェクト: makandok/mwana
    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
コード例 #37
0
def send_message_safe(contact, message):
    if contact.default_connection:
        OutgoingMessage(contact.default_connection, message).send()
コード例 #38
0
ファイル: app.py プロジェクト: unicefuganda/edtrac
 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()
コード例 #39
0
ファイル: views.py プロジェクト: cwezi/rapidsms-httprouter
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))
コード例 #40
0
 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()