Esempio n. 1
0
def delete_twilio_feedback(sidd):
    """Wipes the message with the specified sid(s) on Twilio
    Will display response codes.

    Args:
        sidd(str): optional argument. Include a sid or a list of SMS sids to delete from the twilio DB
    
    Returns:
        res(int): 1 on success. 0 if the feedback could not be deleted
    
    Raises:
        ValueError: sms could not be found in database
    """
    if (sidd):     #Assumption is that all feedback in db will match twilio
        if type(sidd) is list:
            try:
                smss = Sms.delete().where(Sms.sid in sidd).execute()
            except:
                raise ValueError
            for sid in sidd:
                url = "https://{}:{}@api.twilio.com/2010-04-01/Accounts/".format(account_sid,auth_token) + account_sid + '/Messages/' + sid
                try:
                    response = request.delete(url)
                except:
                    print("max retries Error")
                finally:
                    if response.status_code == 204:
                        return 1
                    if response.status_code == 404:
                        print(sid + " " + response.reason)
                        return 0
                    else:
                        print(response.reason)
                        return 0
        elif type(sidd) is str:
            sid = sidd
            try:
                sms = Sms.delete().where(Sms.sid==sid).execute()
            except:
                raise ValueError
            url = "https://{}:{}@api.twilio.com/2010-04-01/Accounts/".format(account_sid,auth_token) + account_sid + '/Messages/' + sid
            try:
                response = request.delete(url)
            except:
                print("max retries Error")
            finally:
                if response.status_code == 204:
                    return 1
                if response.status_code == 404:
                    print(sid + " " + response.reason)
                    return 0
                else:
                    print(response.reason)
                    return 0
        else:
            return 0
    else:
        return 0
    return 0
Esempio n. 2
0
def delete_feedback():
    """Calls the delete_feedback function, returns a message confirming # of feedback entries deleted

    Returns:
        res(str): Confirmation string
    """
    query = Sms.delete()  # deletes all SMS objects
    res = query.execute()
    return "{} amount of sms entries deleted".format(res)
Esempio n. 3
0
    def test_update_db(self):
        """Tests to make sure that Sms objects that are stored in the database are storing correctly.
        Tests the functionality of the Sms feedback use case: storing and accessing feedback

        **Passes when**: The system can process Sms data that is sent and update the database. 
        Can query with a date range while rejecting invalid dates. Can correctly read sms data

        **Fails when**: System has errors in processing sms. Cannot read information from the Sms object
        The sms database is not empty when deleted and invalid date ranges are specified

        """
        #TODO: if twilio connection not maintained
        self.assertEqual(
            feedback_controller.update_db(datetime(2016, 3, 21),
                                          update_from="test"), 1)
        self.assertEqual(
            feedback_controller.update_db(datetime(2027, 3, 21),
                                          update_from="test"), 0)
        query = Sms.delete()
        res = query.execute()
        self.assertEqual(len(Sms.select()), 0)
        feedback_controller.update_db(update_from="test")
        self.assertTrue(len(Sms.select()) > 0)
        smss = Sms.select().where(Sms.sid == 1)
        for sms in smss:
            self.assertEqual(sms.phone_num, "+12345678905")
        query = Sms.delete()
        res = query.execute()
        self.assertEqual(len(Sms.select()), 0)
Esempio n. 4
0
def delete_twilio_feedback():
    """Wipe all message history on twilio since a specified time. Only needs to be called once to clear data.

    Returns:
        res(str): Confirmation string
    """
    smss = Sms.select().where(Sms.submission_time >= datetime(
        2017, 4, 25, 2, 35, 00))  #2017-04-25 02:49:49
    sidd = []
    for sms in smss:
        sidd.append(sms.sid)
    #print(sidd)
    feedback_controller.delete_twilio_feedback(sidd)
    return "Twilio Feedback deleted"
Esempio n. 5
0
def update_db(*date_from, **kwargs):
    """Updates the sms in the database starting from the date_from specified (at time midnight)
    no param = updates the sms feedback in database with all message entries
    analyze feedback when sms is sent

    Args:
        date_from (Date): a specified date, where we update db with sms sent after this date
        update_from (str): an optional argument. This should be "test" if messages are not coming from
        twilio, but from the test_fb_data file

    Returns:
        res(int): 1 on success. 0 on error

    Throws:
        SystemError: When the Twilio Client cannot be started. Possibly invalid account_sid or
        auth_token
    """

    if (kwargs):
        if(kwargs["update_from"]):
            if(kwargs['update_from'] == "test"):
                if date_from == ():
                    messages = test_sms_data(5, datetime(2016, 3, 25))
                else:
                    date_from = date_from[0]
                    if (date_from > datetime.now()):
                        return 0
                    else:
                        messages = test_sms_data(5, date_from)
                messages = test_sms_data(5, datetime(2016, 3, 25))
            elif(kwargs['update_from'] == "autogen"):
                if date_from == ():
                    messages = auto_generate_sms_data()
                else:
                    date_from = date_from[0]
                    if (date_from > datetime.now()):
                        return 0
                    else:
                        messages = auto_generate_sms_data(date_from=date_from)
            else:
                return 0
        else:
            return 0
    else:
        try:
            client = Client(account_sid,auth_token)
            messages = client.messages.list(to=restaurant_phone_number)
            process_incoming_sms()
            if date_from == ():
                messages = client.messages.list(to=restaurant_phone_number) # this may have a long random string first
            else:
                date_from = date_from[0]
                if (date_from > datetime.now()):
                    #raise ValueError
                    return 0
                messages = client.messages.list(date_sent=date_from,to=restaurant_phone_number)
        except:
            if date_from==():
                messages = auto_generate_sms_data()
            else:
                date_from = date_from[0]
                if (date_from > datetime.now()):
                    return 0
                else:
                    messages = auto_generate_sms_data(date_from=date_from)
            #raise SystemError
    for message in messages:
        try:
            sms = Sms.get(message.sid == Sms.sid)
            if (sms.invalid_field == True):
                #pass
                print('deleting ' + sms.body)
                delete_twilio_feedback(sms.sid)
            else:
                pass
        except:
            try:
                if message.date_sent != None:
                    date_tmp = message.date_sent - timedelta(hours=4)
                    sms_str = date_tmp.strftime("%Y-%m-%d %H:%M:%S")
                    date_tmp= datetime.strptime(sms_str, "%Y-%m-%d %H:%M:%S")
                else:
                    date_tmp = None
                sms_tmp = Sms(sid=message.sid,
                    submission_time=date_tmp,
                    body=message.body,
                    phone_num=message.from_,
                    )
                res2 = feedback_analysis(sms_tmp.body)
                sms_tmp.pos_flag = res2[0]
                sms_tmp.neg_flag = res2[1]
                sms_tmp.exception_flag = res2[2]
                sms_tmp.food_flag = res2[3]
                sms_tmp.service_flag = res2[4]
                sms_tmp.invalid_field = False
                try:
                    err = sms_tmp.save()
                except IntegrityError:
                    pass
            except IntegrityError:
                err = 0
                #print("Duplicate Sms Entry " + sms_tmp.body)
    return 1
Esempio n. 6
0
def process_incoming_sms(*one):
    """Updates SMS table in database with the incoming SMS. Checks for the unique key to invalidate
    SMS or keep it. 
    
    Only for processing SMS in real time.

    - Precondition: A Twilio POST request is received.

    TODO: Fix error with twilio, where the most recent message does not have a submission timep

    Args:
        *one(int): optional argument

    Returns:
        res(int): 1 on success. 0 on error

    Throws:
        SystemError: When the Twilio Client cannot be started. Possibly invalid account_sid or
        auth_token
    """
    tabss = Tabs.select()
    valid_keys = []
    for tab in tabss:
        key = tab.fb_key
        if key == "~~~~~~~~~~":
            continue
        else:
            valid_keys.append(key)
    try:
        client = Client(account_sid,auth_token)
        messages = client.messages.list(to=restaurant_phone_number)
    except:
        raise SystemError

    if (one):
        messages = client.messages.list(to=restaurant_phone_number)
        message = messages[0] # get the first message
        message_key = []
        for key in valid_keys:
            if key in message.body[:len(key)]:
                new_body = message.body.replace(key,'')
                #remoev key
                tab = Tabs.update(fb_key="~~~~~~~~~~").where(Tabs.fb_key == key)
                message_key.append(key)

        if (message_key):
            #i can use the date time as now because feedback comes in immediately here
            sms_tmp = Sms(
                sid=message.sid,
                submission_time=datetime.now(),
                body=new_body,
                phone_num=message.from_)
            res2 = feedback_analysis(sms_tmp.body)
            sms_tmp.pos_flag = res2[0]
            sms_tmp.neg_flag = res2[1]
            sms_tmp.exception_flag = res2[2]
            sms_tmp.food_flag = res2[3]
            sms_tmp.service_flag = res2[4]
            sms_tmp.invalid_field = False
            try:
                err = sms_tmp.save()
            except IntegrityError:
                pass
        else:                
            try:
                i = message.body.index(' ')
            except ValueError:
                i = 7
                pass
            if (one):
                non_accept = "Your unique key {" + message.body[:i] + "} is not valid"
                client.messages.create(
                    to=message.from_,
                    from_=restaurant_phone_number,
                    body=non_accept,)
            
            sms_tmp = Sms(
                sid=message.sid,
                submission_time=datetime.now(),
                body=message.body,
                phone_num=message.from_)
            sms_tmp.invalid_field = True
            try:
                err = sms_tmp.save()
            except IntegrityError:
                pass
            #delete_twilio_feedback(message.sid)
    else:
        messages = client.messages.list(to=restaurant_phone_number, date_sent=datetime.today())
        for message in messages:
            message_key = []
            for key in valid_keys:
                if key in message.body[:len(key)]:
                    new_body = message.body.replace(key,'')
                    tab = Tabs.select().where(Tabs.fb_key == key)
                    tab.fb_key = "~~~~~~~~~~"
                    message_key.append(key)

            if (message_key):
                #i can use the date time as now because feedback comes in immediately here
                sms_tmp = Sms(
                    sid=message.sid,
                    submission_time=datetime.now(),
                    body=new_body,
                    phone_num=message.from_
                    )
                res2 = feedback_analysis(sms_tmp.body)
                sms_tmp.pos_flag = res2[0]
                sms_tmp.neg_flag = res2[1]
                sms_tmp.exception_flag = res2[2]
                sms_tmp.food_flag = res2[3]
                sms_tmp.service_flag = res2[4]
                sms_tmp.invalid_field = False
                try:
                    err = sms_tmp.save()
                except IntegrityError:
                    pass
            else:                
                try:
                    i = message.body.index(' ')
                except ValueError:
                    i = 7
                    pass
                if (one):
                    non_accept = "Your unique key {" + message.body[:i] + "} is not valid"
                    client.messages.create(
                        to=message.from_,
                        from_=restaurant_phone_number,
                        body=non_accept,)
                
                sms_tmp = Sms(
                    sid=message.sid,
                    submission_time=datetime.now(),
                    body=message.body,
                    phone_num=message.from_,
                    invalid_field=True
                    )
                try:
                    err = sms_tmp.save()
                except IntegrityError:
                    pass
                #delete_twilio_feedback(message.sid)
    return 1
Esempio n. 7
0
def feedback_table(role):
    """
    By default displays a webpage for user to make feedback DB query.
    Display a table of feedback sent in during a specified date-time range.
    Also, depending on whether category flags are specified, this page will only display that category
    table: table of feedback to display
    form: form that specifies the query instructions.

    Args:
        role(str): correct role of user in this context acquired from the require_role wrapper
    
    Returns:
        template: The template to display with the appropriate parameters
    """
    #get all of the feedback objects and insert it into table
    form = DateSpecifyForm()
    if (request.method == 'POST'):
        pos_col, neg_col, except_col, food_col, service_col = (
            -1, -1, -1, -1, -1)  # -1 is a don't care term
        dtf = datetime.strptime(request.form['datetimefrom'],
                                "%m/%d/%Y %I:%M %p")
        dtt = datetime.strptime(request.form['datetimeto'],
                                "%m/%d/%Y %I:%M %p") + timedelta(minutes=2)
        query_expr = ((Sms.submission_time > dtf) &
                      (Sms.submission_time <= dtt) &
                      (Sms.invalid_field == False))
        if (request.form.get('dropdown') == 'Good'):
            #print('Form Good')
            pos_col, neg_col = (1, 0)
            query_expr = ((query_expr) & (Sms.pos_flag == pos_col) &
                          (Sms.neg_flag == neg_col))
        elif (request.form.get('dropdown') == 'Bad'):
            pos_col, neg_col = (0, 1)
            query_expr = ((query_expr) & (Sms.pos_flag == pos_col) &
                          (Sms.neg_flag == neg_col))
        elif (request.form.get('dropdown') == 'Mixed'):
            pos_col, neg_col = (1, 1)
            query_expr = ((query_expr) & (Sms.pos_flag == pos_col) &
                          (Sms.neg_flag == neg_col))
        elif (request.form.get('dropdown') == 'Food'):
            food_col = 1
            query_expr = ((query_expr) & (Sms.food_flag == food_col))
        elif (request.form.get('dropdown') == 'Service'):
            service_col = 1
            query_expr = ((query_expr) & (Sms.service_flag == service_col))
        elif (request.form.get('dropdown') == 'Exception'):
            except_col = 1
            query_expr = ((query_expr) & (Sms.exception_flag == except_col))
        else:
            pos_col, neg_col, except_col, food_col, service_col = (-1, -1, -1,
                                                                   -1, -1)
        feedback_controller.update_db()
        smss = Sms.select().where(query_expr).order_by(-Sms.submission_time)
        res = []
        all_string_bodies = ""
        for sms in smss:
            #print('pos:{} neg:{} except:{} food:{} service:{}'.format(sms.pos_flag,sms.neg_flag, sms.exception_flag, sms.food_flag, sms.service_flag))
            if (type(sms.submission_time) is str):
                sms_dt = datetime.strptime(
                    sms.submission_time[:-6], "%Y-%m-%d %H:%M:%S"
                )  #removes the +HH:MM offset in datetime
            else:
                sms_dt = sms.submission_time
            sms_str = sms_dt.strftime("%Y-%m-%d %H:%M:%S")
            res.append(dict(time=sms_str, body=sms.body))
            all_string_bodies = all_string_bodies + sms.body + ","
        if (request.form.get('wordcloud')):
            wc = True
            [wordSet, freqs, maxfreq
             ] = feedback_controller.word_freq_counter(all_string_bodies)
            #word cloud output format
            word_freq = []
            n = 0
            for n in range(len(wordSet)):
                word_freq.append(dict(text=wordSet[n], weight=freqs[n]))
        else:
            wc = False
            word_freq = []
            maxfreq = 0  # fix wc error
        table = ItemTable(res)
    else:
        res = []
        table = ItemTable(res)
    if not (res == []):
        return render_template('feedbackM/index.html',
                               logged_in=True,
                               table=table,
                               form=form,
                               word_freq=json.dumps(word_freq),
                               max_freq=maxfreq,
                               role=role,
                               wordcloud=wc)
    else:
        return render_template(
            'feedbackM/index.html',
            logged_in=True,
            form=form,
            role=role,
            wordcloud=False
        )  # allow table to stay until it is cleared manually.