コード例 #1
0
class CDWApi(object):
    def __init__(self, app=None):
        self.init_app(app)

    def init_app(self, app):
        if app is None: return

        blueprint = Blueprint('cdwapi', __name__)

        config = default_config.copy()
        config.update(app.config.get('CDWAPI', {}))

        self.config = config
        self.sms = MongoengineService(SMSRegistrationMessage)
        self.switchboard_number = app.config['CDW']['twilio'][
            'switchboard_number']
        app.twilio = TwilioService()

        app.cdwapi = self

        from cdwapi.views import load_views
        load_views(blueprint)

        app.register_blueprint(blueprint, url_prefix=config['url_prefix'])

    def save_incoming_sms(self, kiosk_number, phone, message):
        msg = SMSRegistrationMessage(kioskNumber=kiosk_number,
                                     phoneNumber=phone,
                                     message=message,
                                     profane=has_bad_words(message))
        self.sms.save(msg)
        return msg

    def get_recent_sms_messages(self, kiosk_number):
        return [
            x.as_dict()
            for x in self.sms.with_fields(**{
                "kioskNumber": kiosk_number
            }).order_by('-created')[:5]
        ]

    def stop_sms_updates(self, user):
        if not user.phoneNumber or \
           not user.receiveSMSUpdates:
            return False

        user.receiveSMSUpdates = False
        cdw.users.save(user)

        msg = "Message following stopped. To start again, text " \
              "back START, or begin a new debate."

        current_app.twilio.send_message(msg, self.switchboard_number,
                                        [user.phoneNumber])
        return True

    def resume_sms_updates(self, user):
        if not user.phoneNumber or \
           user.receiveSMSUpdates or \
           not user.threadSubscription:
            return False

        user.receiveSMSUpdates = True
        cdw.users.save(user)

        message = "You will now begin to receive SMS updates for the last " \
                  "debate you participated in."

        self.send_sms_message(message, [user.phoneNumber])

    def start_sms_updates(self, user, thread):
        if not user.phoneNumber or \
           user.threadSubscription == thread:
            return False

        switched_msg = "You can follow one debate at a time via SMS. We " \
                       "will switch to the debate you joined" \
                       ". If you want to stay in your previous debate, " \
                       "text back STAY."

        message = "You are now subscribed to the debate you joined. " \
                  "You can reply to messages you receive via SMS " \
                  "to continue the debate. To stop these messages " \
                  "text back STOP."

        all_users = cdw.users.with_fields(
            phoneNumber=user.phoneNumber).order_by('-lastPostDate')

        previous = None

        if len(all_users) == 1:

            if user.threadSubscription != None:
                previous = user.threadSubscription
                message = switched_msg

        else:
            if user.origin == 'web' and \
               user.previousThreadSubscription == None and \
               all_users[1].origin =='kiosk' and \
               all_users[1].threadSubscription != None:

                current_app.logger.info('Setting previous thread subscription '
                                        'for web user based on last kiosk '
                                        'interaction')

                previous = all_users[1].threadSubscription
                message = switched_msg

            if user.origin == 'kiosk' and \
               user.previousThreadSubscription == None and \
               all_users[1].origin =='web' and \
               all_users[1].threadSubscription != None:

                current_app.logger.info('Setting previous thread subscription '
                                        'for kiosk user based on last web '
                                        'interaction')

                previous = all_users[1].threadSubscription
                message = switched_msg

        for u in all_users[1:]:
            u.threadSubscription = None
            u.previousThreadSubscription = None
            cdw.users.save(u)

        user.threadSubscription = thread
        user.previousThreadSubscription = previous
        user.receiveSMSUpdates = True
        cdw.users.save(user)

        current_app.twilio.send_message(message, self.switchboard_number,
                                        [user.phoneNumber])
        return True

    def revert_sms_updates(self, user):
        if not user.phoneNumber or \
           not user.previousThreadSubscription:
            return False

        user.threadSubscription = user.previousThreadSubscription
        user.previousThreadSubscription = None
        cdw.users.save(user)

        msg = "Got it. We've changed your subscription " \
              "to the previous debate."

        current_app.twilio.send_message(msg, self.switchboard_number,
                                        [user.phoneNumber])

        return True

    def send_sms_message(self, message, recipients):
        current_app.twilio.send_message(message, self.switchboard_number,
                                        recipients)

    def notify_sms_subscribers(self, thread, exclude, message):
        subscribers = cdw.users.with_fields(threadSubscription=thread)

        # Just their phone numbers
        subscribers = [ u.phoneNumber \
                        for u in subscribers \
                        if u.phoneNumber not in exclude and u.receiveSMSUpdates ]

        self.send_sms_message(message, subscribers)

    def start_email_updates(self, user, thread):
        if user not in thread.emailSubscribers:
            thread.emailSubscribers.append(user)
            cdw.threads.save(thread)

    def stop_email_updates(self, user, thread):
        thread.emailSubscribers.remove(user)
        cdw.threads.save(thread)

    def stop_all_email_updates(self, user):
        thread_subscriptions = cdw.threads.with_fields(emailSubscribers=user)

        for thread in thread_subscriptions:
            self.stop_email_updates(user, thread)

    def notify_email_subscribers(self, thread, exclude, message):
        subscribers = [u for u in thread.emailSubscribers \
                       if u.email not in exclude]

        from cdw.emailers import send_reply_notification

        for s in subscribers:
            ctx = dict(question_id=str(thread.question.id),
                       thread_id=str(thread.id),
                       user_id=str(s.id),
                       local_request=current_app.config['LOCAL_REQUEST'],
                       message=message)

            attempts = 0
            attempts_allowed = 5

            current_app.logger.debug('Attempting to send email to %s' %
                                     s.email)

            while True:
                try:
                    send_reply_notification(s.email, ctx)
                    break

                except Exception, e:
                    attempts += 1
                    if attempts == attempts_allowed:
                        current_app.logger.error(
                            "Error sending email notification: %s" % e)
                        break
                    else:
                        current_app.logger.warn(
                            "Attempt %s to send email failed. "
                            "Error: %s" % (attempts, e))

                    time.sleep(1)
コード例 #2
0
class CDWApi(object):
    def __init__(self, app=None):
        self.init_app(app)
        
    def init_app(self, app):
        if app is None: return
        
        blueprint = Blueprint('cdwapi', __name__)
        
        config = default_config.copy()
        config.update(app.config.get('CDWAPI', {}))
        
        self.config = config
        self.sms = MongoengineService(SMSRegistrationMessage)
        self.switchboard_number = app.config['CDW']['twilio']['switchboard_number']
        app.twilio = TwilioService()
        
        app.cdwapi = self
        
        from cdwapi.views import load_views
        load_views(blueprint)
        
        app.register_blueprint(blueprint, url_prefix=config['url_prefix'])
        
    def save_incoming_sms(self, kiosk_number, phone, message):
        msg = SMSRegistrationMessage(kioskNumber=kiosk_number, phoneNumber=phone, 
                                     message=message, profane=has_bad_words(message))
        self.sms.save(msg)
        return msg
    
    def get_recent_sms_messages(self, kiosk_number):
        return [x.as_dict() for x in self.sms.with_fields(
                    **{"kioskNumber":kiosk_number}).order_by('-created')[:5]]
    
    def stop_sms_updates(self, user):
        if not user.phoneNumber or \
           not user.receiveSMSUpdates: 
            return False
        
        user.receiveSMSUpdates = False;
        cdw.users.save(user)
        
        msg = "Message following stopped. To start again, text " \
              "back START, or begin a new debate."
              
        current_app.twilio.send_message(msg, 
                                        self.switchboard_number, 
                                        [user.phoneNumber])
        return True
    
    def resume_sms_updates(self, user):
        if not user.phoneNumber or \
           user.receiveSMSUpdates or \
           not user.threadSubscription:
            return False
        
        user.receiveSMSUpdates = True
        cdw.users.save(user)
        
        message = "You will now begin to receive SMS updates for the last " \
                  "debate you participated in."
                  
        self.send_sms_message(message, [user.phoneNumber])
    
    def start_sms_updates(self, user, thread):
        if not user.phoneNumber or \
           user.threadSubscription == thread:
            return False
        
        switched_msg = "You can follow one debate at a time via SMS. We " \
                       "will switch to the debate you joined" \
                       ". If you want to stay in your previous debate, " \
                       "text back STAY."
                       
        message = "You are now subscribed to the debate you joined. " \
                  "You can reply to messages you receive via SMS " \
                  "to continue the debate. To stop these messages " \
                  "text back STOP."
        
        all_users = cdw.users.with_fields(
                        phoneNumber=user.phoneNumber).order_by('-lastPostDate')
        
        previous = None
        
        if len(all_users) == 1:
            
            if user.threadSubscription != None:
                previous = user.threadSubscription
                message = switched_msg
                
        else:
            if user.origin == 'web' and \
               user.previousThreadSubscription == None and \
               all_users[1].origin =='kiosk' and \
               all_users[1].threadSubscription != None:
            
                current_app.logger.info('Setting previous thread subscription '
                                        'for web user based on last kiosk '
                                        'interaction')
                
                previous = all_users[1].threadSubscription
                message = switched_msg
                
            if user.origin == 'kiosk' and \
               user.previousThreadSubscription == None and \
               all_users[1].origin =='web' and \
               all_users[1].threadSubscription != None:
            
                current_app.logger.info('Setting previous thread subscription '
                                        'for kiosk user based on last web '
                                        'interaction')
                
                previous = all_users[1].threadSubscription
                message = switched_msg
           
        for u in all_users[1:]:
            u.threadSubscription = None
            u.previousThreadSubscription = None
            cdw.users.save(u)
        
        user.threadSubscription = thread
        user.previousThreadSubscription = previous
        user.receiveSMSUpdates = True;
        cdw.users.save(user)
        
        current_app.twilio.send_message(message, 
                                        self.switchboard_number, 
                                        [user.phoneNumber])
        return True
    
    def revert_sms_updates(self, user):
        if not user.phoneNumber or \
           not user.previousThreadSubscription:
            return False
        
        user.threadSubscription = user.previousThreadSubscription;
        user.previousThreadSubscription = None
        cdw.users.save(user)
        
        msg = "Got it. We've changed your subscription " \
              "to the previous debate."
              
        current_app.twilio.send_message(msg, 
            self.switchboard_number, [user.phoneNumber])
        
        return True
        
    def send_sms_message(self, message, recipients):
        current_app.twilio.send_message(message, 
            self.switchboard_number, recipients)
            
    def notify_sms_subscribers(self, thread, exclude, message):
        subscribers = cdw.users.with_fields(threadSubscription=thread)
        
        # Just their phone numbers
        subscribers = [ u.phoneNumber \
                        for u in subscribers \
                        if u.phoneNumber not in exclude and u.receiveSMSUpdates ]
        
        self.send_sms_message(message, subscribers)
        
    def start_email_updates(self, user, thread):
        if user not in thread.emailSubscribers:
            thread.emailSubscribers.append(user)
            cdw.threads.save(thread)
        
    def stop_email_updates(self, user, thread):
        thread.emailSubscribers.remove(user)
        cdw.threads.save(thread)
        
    def stop_all_email_updates(self, user):
        thread_subscriptions = cdw.threads.with_fields(emailSubscribers=user)
        
        for thread in thread_subscriptions:
            self.stop_email_updates(user, thread)
            
    def notify_email_subscribers(self, thread, exclude, message):
        subscribers = [u for u in thread.emailSubscribers \
                       if u.email not in exclude]
        
        from cdw.emailers import send_reply_notification
        
        for s in subscribers:
            ctx = dict(question_id=str(thread.question.id),
                       thread_id=str(thread.id), 
                       user_id=str(s.id),
                       local_request=current_app.config['LOCAL_REQUEST'],
                       message=message)
            
            attempts = 0;
            attempts_allowed = 5
            
            current_app.logger.debug('Attempting to send email to %s' % s.email)
            
            while True:
                try:
                    send_reply_notification(s.email, ctx)
                    break
                
                except Exception, e:
                    attempts += 1
                    if attempts == attempts_allowed:
                        current_app.logger.error(
                            "Error sending email notification: %s" % e)
                        break;
                    else:
                        current_app.logger.warn(
                            "Attempt %s to send email failed. "
                            "Error: %s" % (attempts, e))
                        
                    time.sleep(1)