<commit_before>#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4


import datetime 
import rapidsms
from reporters.models import *
from models import *


class App (rapidsms.app.App):
    """When an incoming message is received, this application is notified
       last, to grab and log the message as a "free-text" message, to be
       displayed in the WebUI with no automatic response from RapidSMS.

       Also, this app receives outgoing messages from the WebUI (via the
       AJAX app), and relays them to the router."""

    PRIORITY = "lowest"


    def handle(self, msg):
        if not msg.responses:

            # log the message, along with the identity
            # information provided by reporters.app/parse
            msg = IncomingMessage.objects.create(
                received=datetime.datetime.now(),
                text=msg.text,
                **msg.persistance_dict)

            self.info("Message %d captured" % (msg.pk))

            # short-circuit, since this message is dealt
            # with now (even if it shouldn't have been)
            return True


    # NOTE: outgoing messages are not logged here via the "outoging"
    # hook, since we're not interested in ALL outgoing messages; only
    # those that were sent from within the messaging UI (below)


    def ajax_POST_send_message(self, params, form):
        rep = Reporter.objects.get(pk=form["uid"])

        # if this message contains the same text as the _previous_ message sent,
        # and is within 6 hours, we'll recycle it (since it has-many recipients)
        try:
            time_limit = datetime.datetime.now() - datetime.timedelta(hours=6)
            msg = OutgoingMessage.objects.filter(
                sent__gt=time_limit,
                text=form["text"])[0]

        # no match, so create a new outgoing message for
        # this recipient (it might be the first of many)
        except IndexError:
            msg = OutgoingMessage.objects.create(
                sent=datetime.datetime.now(),
                text=form["text"])

        # attach this recipient to
        # the (old or new) message
        msg.recipients.create(
            reporter=rep)

        # abort if we don't know where to send the message to
        # (if the device the reporter registed with has been
        # taken by someone else, or was created in the WebUI)
        pconn = rep.connection()
        if pconn is None:
            raise Exception("%s is unreachable (no connection)" % rep)

        # abort if we can't find a valid backend. PersistantBackend
        # objects SHOULD refer to a valid RapidSMS backend (via their
        # slug), but sometimes backends are removed or renamed.
        be = self.router.get_backend(pconn.backend.slug)
        if be is None:
            raise Exception(
                "No such backend: %s" %
                pconn.backend.title)
        
        # attempt to send the message
        # TODO: what could go wrong here?
        return be.message(pconn.identity, form["text"]).send()<commit_msg>Adding a view in the messaging app that supports the sending of messages by connection and not reporter.  This allows other pieces of code to use the ajax app to call it by connection, but is not exposed through the UI.<commit_after>#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4


from datetime import datetime, timedelta
import rapidsms
from reporters.models import *
from models import *


class App (rapidsms.app.App):
    """When an incoming message is received, this application is notified
       last, to grab and log the message as a "free-text" message, to be
       displayed in the WebUI with no automatic response from RapidSMS.

       Also, this app receives outgoing messages from the WebUI (via the
       AJAX app), and relays them to the router."""

    PRIORITY = "lowest"


    def handle(self, msg):
        if not msg.responses:

            # log the message, along with the identity
            # information provided by reporters.app/parse
            msg = IncomingMessage.objects.create(
                received=datetime.now(),
                text=msg.text,
                **msg.persistance_dict)

            self.info("Message %d captured" % (msg.pk))

            # short-circuit, since this message is dealt
            # with now (even if it shouldn't have been)
            return True


    # NOTE: outgoing messages are not logged here via the "outoging"
    # hook, since we're not interested in ALL outgoing messages; only
    # those that were sent from within the messaging UI (below)


    def ajax_POST_send_message(self, params, form):
        rep = Reporter.objects.get(pk=form["uid"])

        # if this message contains the same text as the _previous_ message sent,
        # and is within 6 hours, we'll recycle it (since it has-many recipients)
        try:
            time_limit = datetime.now() - timedelta(hours=6)
            msg = OutgoingMessage.objects.filter(
                sent__gt=time_limit,
                text=form["text"])[0]

        # no match, so create a new outgoing message for
        # this recipient (it might be the first of many)
        except IndexError:
            msg = OutgoingMessage.objects.create(
                sent=datetime.now(),
                text=form["text"])

        # attach this recipient to
        # the (old or new) message
        msg.recipients.create(
            reporter=rep)

        # abort if we don't know where to send the message to
        # (if the device the reporter registed with has been
        # taken by someone else, or was created in the WebUI)
        pconn = rep.connection()
        if pconn is None:
            raise Exception("%s is unreachable (no connection)" % rep)

        return self._send_message(pconn, form["text"])
        
    def ajax_POST_send_message_to_connection(self, params, form):
        '''Sends a message using a connection id, instead of
           a reporter id.'''
        # todo: this method doesn't deal with logging.  should it?
        # possibly not, since there is no UI for this on the messaging
        # tab.  This is just a convenience for other apps.  
        connection = PersistantConnection.objects.get(pk=form["connection_id"])
        return self._send_message(connection, form["text"])
        
    
    def _send_message(self, connection, message_body):    
        '''Attempts to send a message througha given connection'''
        # abort if we can't find a valid backend. PersistantBackend
        # objects SHOULD refer to a valid RapidSMS backend (via their
        # slug), but sometimes backends are removed or renamed.
        be = self.router.get_backend(connection.backend.slug)
        if be is None:
            raise Exception(
                "No such backend: %s" %
                connection.backend.title)
        
        # attempt to send the message
        # TODO: what could go wrong here?
        return be.message(connection.identity, message_body).send()
{'fraction_non_alphanumeric': 0.07613344739093242, 'fraction_numerical': 0.001710863986313088, 'mean_word_length': 2.2031963470319633, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3778047', 'n_tokens_mistral': 1891, 'n_tokens_neox': 1781, 'n_words': 742}