Example #1
0
 def test_check_id_error (self):
     """
         If the Id is valid and pepito is the owner of the message and there is an error.
     """
     customer = Customer.get_customer ('pepito', 'password')
     (status, status_msg) = SMSHistory.check_id (customer, 'testMessage2')[0]
     self.assertEqual ((status, status_msg), (True, 'A critical error'))
Example #2
0
 def test_check_id_not_error (self):
     """
         If the Id is valid, pepito is the owner of the message and there isn't an error
     """
     customer = Customer.get_customer ('pepito', 'password')
     (status, status_msg) = SMSHistory.check_id (customer, 'testMessage1')[0]
     self.assertEqual ((status, status_msg), (False, ''))
Example #3
0
 def test_check_id_invalid_id (self):
     """
         If the Id is invalid
     """
     customer = Customer.get_customer ('pepito', 'password')
     (status, status_msg) = SMSHistory.check_id (customer, '{--Invalid_ID--}')[0]
     self.assertEqual ((status, status_msg), (True, 'badid'))
Example #4
0
 def test_check_id_not_owner (self):
     """
         If the Id is valid but pepito is not the owner of the message.
     """
     #customer = Customer.objects.get (user__username='******')
     customer = Customer.objects.get(username='******')
     (status, status_msg) = SMSHistory.check_id (customer, 'testMessage1')[0]
     self.assertEqual ((status, status_msg), (True, 'badid'))
Example #5
0
def get_status(username, password, id):
    """
        Return msg status given by his id
    """
    customer = Customer.get_customer (username, password)
    if customer < 0:
        return [str(FAIL_STATUS), "Customer error, please check your customer id and password"]
    l = SMSHistory.check_id (customer, id)
    if l:
        return [str(l[0]), str(l[1])]
    return [str(NONE_STATUS), "Msg %s not found on system, try it later" % id]
Example #6
0
    def run(self):
        """
            Send sms method. It sends SMS over a given connector (by SMS's account)
        """
        log.info("starting thread in AccountThread")
        n = 0
        while self.parent.running:
            log.info("Waiting for tasks")
            try:
                sq = self.parent.work.get(True, 10)
                n += 1
            except Queue.Empty:
                log.info("No more tasks, empty queue")
                break

            log.info("id %s: start sending %d" % (sq.get_id(), n)) 
            try:
                # KIND OF MESSAGE: SMS | MMS
                credit = SMS_CREDIT
                if sq.message.body.mms:
                    credit = MMS_CREDIT

                local_status = NONE_STATUS
                server_status = NONE_STATUS
                status_info = ''
                batch_id = ''
                today = datetime.datetime.now()
                available_credit = self.account.get_available_credit()
                if not available_credit:
                    # Run out of credit, delay sending process
                    sq.nextProcDate = today + datetime.timedelta(0,settings.DEFAULT_DEACTIVATION_TIME)
                    sq.save()
                    status_info = "Run out of credit, delayed %d day(s)" % NEXT_SEND
                    local_status = PROCESSING_STATUS
                else:
                    if sq.message.activationDate > today:
                        # This message is not active yet
                        sq.nextProcDate = sq.message.activationDate
                        sq.save()
                        status_info = "Sending delayed until activation date"
                        local_status = PROCESSING_STATUS
                    else:
                        # Active message
                        if sq.message.deactivationDate and today > sq.message.deactivationDate:
                            # Expired
                            status_info = "Sending date expired"
                            local_status = FAIL_STATUS
                        else:
                            # Not deactivation date or not sent, we create an instance
                            # of backend (connector) related to this message.
                            GenericConnector = backends[self.account.access.backend]
                            connector = GenericConnector(self.account.args())
                            log.debug("Account connector = %s (%d) is %s", self.account, self.account.id, connector)

                            # Send message
                            server_status, status_info, batch_id = self._send_message(connector, credit, sq)
                            if server_status != NONE_STATUS:
                                local_status = SENT_STATUS
                            else:
                                local_status = PROCESSING_STATUS
                                sq.nextProcDate = today + datetime.timedelta(0,settings.DEFAULT_RETRY_TIME_CONNECTOR_TEMP_FAIL)
                                log.warn("Cannot send the message over his defined connector, it will be retried in a few minutes.") 
                                sq.save()

                log.debug("Status of message %d = (local = %d, server = %d)" % (sq.message.id, local_status, server_status))
                self._update_credit(sq, local_status)
                # Status message updated
                if not sq.message.firstSentDate:
                    sq.message.firstSentDate = datetime.datetime.now()
                sq.message.lastSentDate = datetime.datetime.now()
                sq.message.save()

            except Exception, e:
                #
                # !!PANIC MODE!!
                #
                # Unhandled error. Activate a panic mode. It will mark the local error message 
                # and will be removed from the queue. For this to work the code below should return no exception. 
                # If you enter this code strange things can happen, for example, may have failed to 
                # update the credit and yet having sent the message to the operator. To try to prevent 
                # something worse going to delete the problem message. Also possible that the error is 
                # software that will be marked with all error messages.
                log.error('Fatal error in sending on AccountThread: %s' % e)
                # Forzamos el borrado del mensaje problemático
                local_status = FAIL_STATUS
                if not status_info:
                    status_info = "A falta error has happened when daemon tried to send %s over this AccountThread" % sq
                g = GalotecniaSupport()
                g.process_exception('Sending process over singularms daemon', e)
                get_traceback(e)
            
            # MessageID_smsqueueID saved before object will be deleted
            id = sq.get_id()

            # Delete smsqueue (if it doesn't have to be fowarded again)
            if local_status != PROCESSING_STATUS:
                log.info("Deleting SMSQueue object id: %d" % sq.id)
                sq.delete()
            
            # Temporal SMSHistory data
            message = sq.message
            mobile = sq.mobile
            priority = sq.priority

            # SMSHistory object creation. Write errors, sent time, sq.id and local_id about it
            sh = SMSHistory(message = message, mobile = mobile, priority = priority, 
                sentDate = datetime.datetime.now(), local_id = id, remote_id = batch_id, 
                local_status = local_status, status_info = status_info[:255], server_status = server_status)
            sh.save()

            # Task done. If this thread die before now, when parent thread calls join() method it will
            # be blocked
            self.parent.work.task_done()          

            # Main loop can continue
            log.debug("id %s: end sending" % id)