コード例 #1
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def _contact_from_args(first_name, last_name, email, text, voice):
    messages = []
    info = {'first_name': first_name, 'last_name': last_name, 'methods': [], "type": "p", "notes": ""}

    def _add_phone_number(number, type_):
        phone, messages = validate_and_standardize_phone(number)
        if phone:
            info['methods'].append({'type': type_, 'value': phone})
        else:
            messages.extend(messages)
            info['methods'].append({'type': type_, 'value': ''})

    if email and valid_email(email):
        info['methods'].append({'type': 'e', 'value': email})
    else:
        messages.append("Invalid email address %s" % (email,))
        error = "Invalid email address %s" % (email)
        create_error_log(error, 'ERR')
        info['methods'].append({'type': 'e', 'value': ''})

    if voice:
        _add_phone_number(voice, 'p')
    if text:
        _add_phone_number(text, 't')

    return info, messages
コード例 #2
0
ファイル: message.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def broadcast_call(number, text_message, play_audio):
    """Send a message to a given phone number."""
    from twilio.rest import TwilioRestClient
    import settings
    import urllib
    import re

    logging.debug("Call notice to %s via twilio.", number)

    client = TwilioRestClient(settings.TWILIO_ACCOUNT, settings.TWILIO_TOKEN)

    try:
        message = re.sub("<[^<]+?>", "", text_message)
        params = {"textMessage": message.encode("utf-8")}
        broadcast_url = (
            "http://5.sos-beacon-dev.appspot.com/broadcast/record?"
            + urllib.urlencode(params)
            + "&playUrl="
            + play_audio
        )
        client.calls.create(to=number, from_=settings.TWILIO_FROM, url=broadcast_url, if_machine="Continue")
    except:
        logging.info("call error")
        error = "Can not make a call to phone number: %s" % number
        create_error_log(error, "ERR")
コード例 #3
0
ファイル: message.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def broadcast_call(number, text_message, play_audio):
    """Send a message to a given phone number."""
    from twilio.rest import TwilioRestClient
    import settings
    import urllib
    import re

    logging.debug('Call notice to %s via twilio.', number)

    client = TwilioRestClient(settings.TWILIO_ACCOUNT, settings.TWILIO_TOKEN)

    try:
        message = re.sub('<[^<]+?>', '', text_message)
        params = {'textMessage': message.encode('utf-8')}
        broadcast_url = "http://5.sos-beacon-dev.appspot.com/broadcast/record?" + urllib.urlencode(
            params) + "&playUrl=" + play_audio
        client.calls.create(
            to=number,
            from_=settings.TWILIO_FROM,
            url=broadcast_url,
            if_machine='Continue',
        )
    except:
        logging.info("call error")
        error = 'Can not make a call to phone number: %s' % number
        create_error_log(error, 'ERR')
コード例 #4
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def import_student(school_urlsafe,
                   is_direct,
                   student_array,
                   group_lookup=None):
    messages = []

    if group_lookup is None:
        group_lookup = {}

    #expected CSV format
    #Group, Student name, contact name parent 1, contact email,
    #voice phone, text phone, space, contact name parent 2
    #contact email, voice phone, text phone
    group_name = unicode(student_array[0], 'utf8').strip()
    if not group_name:
        #TODO: add bad message
        logging.error("Invalid group name %s", group_name)
        error = "Invalid group name %s", group_name
        create_error_log(error, 'ERR')
        return None, None, messages

    group_key, group_future = _get_group(group_name, group_lookup,
                                         school_urlsafe)

    #TODO: look for existing student by name?
    student_first_name = unicode(student_array[1], 'utf8')
    student_last_name = unicode(student_array[2], 'utf8')
    if not student_first_name:
        #TODO: add bad message
        logging.error("Invalid student name %s", student_first_name)
        error = "Invalid student name %s", student_first_name
        create_error_log(error, 'ERR')
        return None, None, messages

        #Ideally they have an ID in the sheet to import in
    #    student = Student(identifier=uuid.uuid4().hex[:6], name=student_name, is_direct=is_direct)
    student = Student(first_name=student_first_name,
                      last_name=student_last_name,
                      last_name_=student_last_name.lower(),
                      is_direct=is_direct)

    if is_direct:
        student.contacts = _build_direct_contacts(student_array)
    else:
        student.contacts = _build_student_contacts(student_array)

    if group_future:
        group_key = group_future.get_result()

    if group_name.lower() not in group_lookup:
        group_lookup[group_name.lower()] = group_key

    if group_key not in student.groups:
        school_key = ndb.Key(urlsafe=school_urlsafe)
        student.groups.append(group_key)
        student.school = school_key

    logging.info("Saving student %s", student)
    future = student.put_async()
    return student, future, messages
コード例 #5
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def _contact_from_args(first_name, last_name, email, text, voice):
    messages = []
    info = {
        'first_name': first_name,
        'last_name': last_name,
        'methods': [],
        "type": "p",
        "notes": ""
    }

    def _add_phone_number(number, type_):
        phone, messages = validate_and_standardize_phone(number)
        if phone:
            info['methods'].append({'type': type_, 'value': phone})
        else:
            messages.extend(messages)
            info['methods'].append({'type': type_, 'value': ''})

    if email and valid_email(email):
        info['methods'].append({'type': 'e', 'value': email})
    else:
        messages.append("Invalid email address %s" % (email, ))
        error = "Invalid email address %s" % (email)
        create_error_log(error, 'ERR')
        info['methods'].append({'type': 'e', 'value': ''})

    if voice:
        _add_phone_number(voice, 'p')
    if text:
        _add_phone_number(text, 't')

    return info, messages
コード例 #6
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def _get_group(group_name, group_lookup, school_urlsafe):
    """Return a group for the group name passed in. Checks the group cache
    first if not there then queries by the lower case name. If not there then
    creates a new group.
    """
    #check for existing group by name
    if group_name.lower() in group_lookup:
        logging.debug("group found in cache")
        error = "group found in cache"
        create_error_log(error, 'ERR')
        return group_lookup[group_name.lower()], None

    from .group import Group
    school_key = ndb.Key(urlsafe=school_urlsafe)
    group = Group.query(Group.name_ == group_name,
                        Group.school == school_key,
                        namespace='_x_').get()

    if group:
        logging.debug("group found in datastore")
        error = "group found in datastore"
        create_error_log(error, 'ERR')
        group_lookup[group_name.lower()] = group.key
        return group.key, None

    logging.debug("No group found for %s, creating a new one", group_name)
    group = Group(name=group_name)
    school_key = ndb.Key(urlsafe=school_urlsafe)
    group.school = school_key
    future = group.put_async()
    return group.key, future
コード例 #7
0
    def email_broadcast_message(self, user_key, title, query_messages):

        body = """
            <table style='border:1px solid #607298;width:540px;max-width:600px'>
                <thead>
                    <tr>
                        <th colspan="2" style="background:#607298;color:#fff;min-height:30px;line-height:30px;text-align:center;font-size:20px">%s</th>
                    </tr>
                </thead>
                <tbody>
        """ % (title)

        try:
            for query_message in query_messages:
                sms_content = query_message.message['sms']
                email_content = query_message.message['email']
                create_at = query_message.added.strftime('%Y-%m-%d %H:%M')
                body += self.format_email_message(user_key.name,
                                                  user_key.phone,
                                                  user_key.email, create_at,
                                                  sms_content, email_content)
        except:
            error = "Can not query message."
            create_error_log(error, 'ERR')

        body += """</tbody></table><br><br><br>"""
        return body
コード例 #8
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def _get_group(group_name, group_lookup, school_urlsafe):
    """Return a group for the group name passed in. Checks the group cache
    first if not there then queries by the lower case name. If not there then
    creates a new group.
    """
    #check for existing group by name
    if group_name.lower() in group_lookup:
        logging.debug("group found in cache")
        error = "group found in cache"
        create_error_log(error, 'ERR')
        return group_lookup[group_name.lower()], None

    from .group import Group
    school_key = ndb.Key(urlsafe = school_urlsafe)
    group = Group.query(Group.name_ == group_name, Group.school == school_key, namespace = '_x_').get()

    if group:
        logging.debug("group found in datastore")
        error = "group found in datastore"
        create_error_log(error, 'ERR')
        group_lookup[group_name.lower()] = group.key
        return group.key, None

    logging.debug("No group found for %s, creating a new one", group_name)
    group = Group(name=group_name)
    school_key = ndb.Key(urlsafe = school_urlsafe)
    group.school = school_key
    future = group.put_async()
    return group.key, future
コード例 #9
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def import_student(school_urlsafe, is_direct, student_array, group_lookup=None):
    messages = []

    if group_lookup is None:
        group_lookup = {}

    #expected CSV format
    #Group, Student name, contact name parent 1, contact email,
    #voice phone, text phone, space, contact name parent 2
    #contact email, voice phone, text phone
    group_name = unicode(student_array[0], 'utf8').strip()
    if not group_name:
        #TODO: add bad message
        logging.error("Invalid group name %s", group_name)
        error = "Invalid group name %s", group_name
        create_error_log(error, 'ERR')
        return None, None, messages

    group_key, group_future = _get_group(group_name, group_lookup, school_urlsafe)

    #TODO: look for existing student by name?
    student_first_name = unicode(student_array[1], 'utf8')
    student_last_name = unicode(student_array[2], 'utf8')
    if not student_first_name:
        #TODO: add bad message
        logging.error("Invalid student name %s", student_first_name)
        error = "Invalid student name %s", student_first_name
        create_error_log(error, 'ERR')
        return None, None, messages

        #Ideally they have an ID in the sheet to import in
    #    student = Student(identifier=uuid.uuid4().hex[:6], name=student_name, is_direct=is_direct)
    student = Student(first_name=student_first_name, last_name=student_last_name, last_name_=student_last_name.lower(), is_direct=is_direct)

    if is_direct:
        student.contacts = _build_direct_contacts(student_array)
    else:
        student.contacts = _build_student_contacts(student_array)

    if group_future:
        group_key = group_future.get_result()

    if group_name.lower() not in group_lookup:
        group_lookup[group_name.lower()] = group_key

    if group_key not in student.groups:
        school_key = ndb.Key(urlsafe = school_urlsafe)
        student.groups.append(group_key)
        student.school = school_key

    logging.info("Saving student %s", student)
    future = student.put_async()
    return student, future, messages
コード例 #10
0
    def post(self):
        event_urlsafe = self.request.get('event')
        event_key = ndb.Key(urlsafe=event_urlsafe)
        event = event_key.get()

        if not event:
            logging.error('Event %s not found!', event_key)
            error = 'Event %s not found!' % event_key
            create_error_log(error, 'ERR')
            return

        is_direct = self.request.get('is_direct')
        robocall_start(event_urlsafe, is_direct)
コード例 #11
0
ファイル: message.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def broadcast_email(address, message, url, user, school):
    """Send an email to a given email address."""

    logging.info("Sending notice to %s via mail api.", address)

    #    if message.message['title']:
    #        subject = message.message['title']
    #    else:
    if message.message_type == "em":
        subject = "Emergency Alert from %s (%s)" % (
            user.get().first_name + " " + user.get().last_name,
            school.get().name,
        )
    else:
        subject = "School Notice message from %s (%s)" % (
            user.get().first_name + " " + user.get().last_name,
            school.get().name,
        )

    if message.message["email"]:
        body = "%s (%s) sent a Event Broadcast. Detail here: <a href='%s'>%s</a>. \nMessage: %s" % (
            user.get().first_name + " " + user.get().last_name,
            school.get().name,
            url,
            url,
            message.message["email"],
        )
    else:
        body = "%s (%s) sent a Event Broadcast. Detail here: %s. \nMessage: %s" % (
            user.get().first_name + " " + user.get().last_name,
            school.get().name,
            url,
            message.message["sms"],
        )

    # TODO: it might make sense to group emails as we can add more than one to
    # address per email sent
    import sendgrid
    import settings

    s = sendgrid.Sendgrid(settings.SENDGRID_ACCOUNT, settings.SENDGRID_PASSWORD, secure=True)

    try:
        message = sendgrid.Message(user.get().email, subject, body, body)
        message.add_to(address)
        s.web.send(message)

    except:
        error = "The 'To' email %s is not a valid email" % address
        create_error_log(error, "ERR")
コード例 #12
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def validate_and_standardize_phone(number):
    import string
    messages = []

    logging.info(number)
    try:
        stuff = string.maketrans('', '')
        non_digits = stuff.translate(None, string.digits)
        number = number.translate(None, non_digits)
        logging.info(number)
    except Exception, e:
        logging.exception("Invalid phone number %s", number)
        messages.append("Invalid phone number %s, %s", number, e.message)
        error = "Invalid phone number %s", number
        create_error_log(error, 'ERR')
        return None, messages
コード例 #13
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def validate_and_standardize_phone(number):
    import string
    messages = []

    logging.info(number)
    try:
        stuff = string.maketrans('', '')
        non_digits = stuff.translate(None, string.digits)
        number = number.translate(None, non_digits)
        logging.info(number)
    except Exception, e:
        logging.exception("Invalid phone number %s", number)
        messages.append("Invalid phone number %s, %s", number, e.message)
        error = "Invalid phone number %s", number
        create_error_log(error, 'ERR')
        return None, messages
コード例 #14
0
ファイル: message.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def broadcast_sms(number, message, url, user_name, school_name):
    """Send a message to a given phone number."""
    from twilio.rest import TwilioRestClient
    import settings

    logging.debug("Sending notice to %s via twilio.", number)
    logging.info("Sending notice to %s via twilio.", number)

    body = message.message["sms"]
    body = "Broadcast from %s (School %s). Link %s. Message: %s" % (user_name, school_name, url, body)

    client = TwilioRestClient(settings.TWILIO_ACCOUNT, settings.TWILIO_TOKEN)

    try:
        client.sms.messages.create(to="+%s" % (number), from_=settings.TWILIO_FROM, body=body)
    except:
        error = "The 'To' number %s is not a valid phone number" % number
        create_error_log(error, "ERR")
コード例 #15
0
ファイル: message.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def broadcast_email(address, message, url, user, school):
    """Send an email to a given email address."""

    logging.info('Sending notice to %s via mail api.', address)

    #    if message.message['title']:
    #        subject = message.message['title']
    #    else:
    if message.message_type == 'em':
        subject = "Emergency Alert from %s (%s)" % (user.get().first_name +
                                                    " " + user.get().last_name,
                                                    school.get().name)
    else:
        subject = "School Notice message from %s (%s)" % (
            user.get().first_name + " " + user.get().last_name,
            school.get().name)

    if message.message['email']:
        body = "%s (%s) sent a Event Broadcast. Detail here: <a href='%s'>%s</a>. \nMessage: %s" %\
               (user.get().first_name + " " + user.get().last_name, school.get().name, url, url,message.message['email'])
    else:
        body = "%s (%s) sent a Event Broadcast. Detail here: %s. \nMessage: %s" %\
               (user.get().first_name + " " + user.get().last_name, school.get().name, url, message.message['sms'])

    #TODO: it might make sense to group emails as we can add more than one to
    # address per email sent
    import sendgrid
    import settings

    s = sendgrid.Sendgrid(settings.SENDGRID_ACCOUNT,
                          settings.SENDGRID_PASSWORD,
                          secure=True)

    try:
        message = sendgrid.Message(user.get().email, subject, body, body)
        message.add_to(address)
        s.web.send(message)

    except:
        error = "The 'To' email %s is not a valid email" % address
        create_error_log(error, 'ERR')
コード例 #16
0
ファイル: message.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def broadcast_sms(number, message, url, user_name, school_name):
    """Send a message to a given phone number."""
    from twilio.rest import TwilioRestClient
    import settings

    logging.debug('Sending notice to %s via twilio.', number)
    logging.info('Sending notice to %s via twilio.', number)

    body = message.message['sms']
    body = "Broadcast from %s (School %s). Link %s. Message: %s" % (
        user_name, school_name, url, body)

    client = TwilioRestClient(settings.TWILIO_ACCOUNT, settings.TWILIO_TOKEN)

    try:
        client.sms.messages.create(to="+%s" % (number),
                                   from_=settings.TWILIO_FROM,
                                   body=body)
    except:
        error = "The 'To' number %s is not a valid phone number" % number
        create_error_log(error, 'ERR')
コード例 #17
0
    def responder_messages(self, user_key, title, list_comment):
        """List comment messages of current event"""
        body = """
            <table style='border:1px solid #607298;width:540px;max-width:600px'>
                <thead>
                    <tr>
                        <th colspan="2" style="background:#607298;color:#fff;min-height:30px;line-height:30px;text-align:center;font-size:20px">%s</th>
                    </tr>
                </thead>
                <tbody>
        """ % (title)

        try:
            for comment in list_comment:
                message = comment.message['body']
                create_at   = comment.added.strftime('%Y-%m-%d %H:%M')
                body       += self.format_email_comment_message(comment.user_name, create_at, message)
        except:
            error = "Can not query comment message."
            create_error_log(error, 'ERR')

        body += """</tbody></table><br><br><br>"""
        return body
コード例 #18
0
    def post(self):
        from sosbeacon.event.event import EVENT_STATUS_CLOSED

        event_urlsafe = self.request.get('event')
        user_urlsafe = self.request.get('user')
        message_urlsafe = self.request.get('message')
        method = self.request.get('method')

        if not event_urlsafe:
            logging.error('No event key given.')
            return

        # TODO: Use event id rather than key here for namespacing purposes?
        event_key = ndb.Key(urlsafe=event_urlsafe)
        event = event_key.get()

        if not event:
            logging.error('Event %s not found!', event_key)
            error = 'Event %s not found!' % event_key
            create_error_log(error, 'ERR')
            return

        if event.status == EVENT_STATUS_CLOSED:
            logging.error('Event %s closed!', event_key)
            error = 'Event %s not found!' % event_key
            create_error_log(error, 'ERR')
            return

        user_key = ndb.Key(urlsafe = user_urlsafe)
        user = user_key.get()

        if not user:
            logging.error('User %s not found!', user_key)
            error = 'User %s not found!' % user_key
            create_error_log(error, 'ERR')
            return

        message_key = ndb.Key(urlsafe = message_urlsafe)
        message = message_key.get()

        if not message:
            logging.error('Message %s not found!', message_key)
            error = 'Message %s not found!' % message_key
            create_error_log(error, 'ERR')
            return

        broadcast_to_method(event_key, message_key, user_key.id(), method)
コード例 #19
0
    def email_broadcast_message(self, user_key, title, query_messages):

        body = """
            <table style='border:1px solid #607298;width:540px;max-width:600px'>
                <thead>
                    <tr>
                        <th colspan="2" style="background:#607298;color:#fff;min-height:30px;line-height:30px;text-align:center;font-size:20px">%s</th>
                    </tr>
                </thead>
                <tbody>
        """ % (title)

        try:
            for query_message in query_messages:
                sms_content = query_message.message['sms']
                email_content = query_message.message['email']
                create_at   = query_message.added.strftime('%Y-%m-%d %H:%M')
                body       += self.format_email_message(user_key.name, user_key.phone, user_key.email, create_at, sms_content, email_content)
        except:
            error = "Can not query message."
            create_error_log(error, 'ERR')

        body += """</tbody></table><br><br><br>"""
        return body
コード例 #20
0
    def responder_messages(self, user_key, title, list_comment):
        """List comment messages of current event"""
        body = """
            <table style='border:1px solid #607298;width:540px;max-width:600px'>
                <thead>
                    <tr>
                        <th colspan="2" style="background:#607298;color:#fff;min-height:30px;line-height:30px;text-align:center;font-size:20px">%s</th>
                    </tr>
                </thead>
                <tbody>
        """ % (title)

        try:
            for comment in list_comment:
                message = comment.message['body']
                create_at = comment.added.strftime('%Y-%m-%d %H:%M')
                body += self.format_email_comment_message(
                    comment.user_name, create_at, message)
        except:
            error = "Can not query comment message."
            create_error_log(error, 'ERR')

        body += """</tbody></table><br><br><br>"""
        return body
コード例 #21
0
def robocall_phone(event_urlsafe, phone_markers, message_urlsafe, timezone):
    from .message import broadcast_call
    from webapp2_extras import sessions

    if not event_urlsafe:
        logging.error('No event key given.')
        return

    # TODO: Use event id rather than key here for namespacing purposes?
    event_key = ndb.Key(urlsafe=event_urlsafe)
    event = event_key.get()
    message_key = ndb.Key(urlsafe=message_urlsafe)
    message = message_key.get()

    if not event:
        logging.error('Event %s not found!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if event.status == EVENT_STATUS_CLOSED:
        logging.error('Event %s closed!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if not phone_markers:
        logging.error('No phone marker given.')
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    time = message.added.strftime("%B %d, %Y at %I:%M %p")
    convert_time = convertTimeZone(timezone, time)

    logging.info(timezone)
    #    number = message.user.get().phone
    #    number = " ".join(number[i:i+1] for i in range(0, len(number), 1))
    #    text_message = message.user.get().name + " at " + string_date +". Message " + message.message['email']
    text_message = "from " + event.school.get(
    ).name + " by " + message.user.get().first_name + " " + message.user.get(
    ).last_name + " on " + convert_time + ". Message " + message.message[
        'email']
    broadcast_call(phone_markers, text_message, message.link_audio)
コード例 #22
0
def robocall_phone(event_urlsafe, phone_markers, message_urlsafe, timezone):
    from .message import broadcast_call
    from webapp2_extras import sessions

    if not event_urlsafe:
        logging.error('No event key given.')
        return

    # TODO: Use event id rather than key here for namespacing purposes?
    event_key = ndb.Key(urlsafe=event_urlsafe)
    event = event_key.get()
    message_key = ndb.Key(urlsafe=message_urlsafe)
    message = message_key.get()

    if not event:
        logging.error('Event %s not found!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if event.status == EVENT_STATUS_CLOSED:
        logging.error('Event %s closed!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if not phone_markers:
        logging.error('No phone marker given.')
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return


    time = message.added.strftime("%B %d, %Y at %I:%M %p")
    convert_time = convertTimeZone(timezone, time)

    logging.info(timezone)
#    number = message.user.get().phone
#    number = " ".join(number[i:i+1] for i in range(0, len(number), 1))
#    text_message = message.user.get().name + " at " + string_date +". Message " + message.message['email']
    text_message = "from " + event.school.get().name + " by " + message.user.get().first_name + " " + message.user.get().last_name + " on " + convert_time + ". Message " + message.message['email']
    broadcast_call(phone_markers, text_message, message.link_audio)
コード例 #23
0
    def post(self):
        from sosbeacon.event.message import send_email_robocall_to_user
        from sosbeacon.event.event import EVENT_STATUS_CLOSED

        event_urlsafe = self.request.get('event')
        message_urlsafe = self.request.get('message')

        if not event_urlsafe:
            logging.error('No event key given.')
            return

        # TODO: Use event id rather than key here for namespacing purposes?
        event_key = ndb.Key(urlsafe=event_urlsafe)
        event = event_key.get()

        if not event:
            logging.error('Event %s not found!', event_key)
            error = 'Event %s not found!' % event_key
            create_error_log(error, 'ERR')
            return

        if event.status == EVENT_STATUS_CLOSED:
            logging.error('Event %s closed!', event_key)
            error = 'Event %s not found!' % event_key
            create_error_log(error, 'ERR')
            return

        message_key = ndb.Key(urlsafe = message_urlsafe)
        message = message_key.get()

        if not message:
            logging.error('Message %s not found!', message_key)
            error = 'Message %s not found!' % message_key
            create_error_log(error, 'ERR')
            return

        send_email_robocall_to_user(message_key, event_key)
コード例 #24
0
def send_email_robocall_to_user(event_urlsafe, user_urlsafe, message_urlsafe, phones):
    from sosbeacon.event.contact_marker import ContactMarker
    import sendgrid
    import settings

    if not event_urlsafe:
        logging.error('No event key given.')
        return

    # TODO: Use event id rather than key here for namespacing purposes?
    event_key = ndb.Key(urlsafe=event_urlsafe)
    event = event_key.get()
    user_key = ndb.Key(urlsafe = user_urlsafe)
    user = user_key.get()
    message_key = ndb.Key(urlsafe = message_urlsafe)
    message = message_key.get()

    if not event:
        logging.error('Event %s not found!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if event.status == EVENT_STATUS_CLOSED:
        logging.error('Event %s closed!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if not user:
        logging.error('User %s not found!', user_key)
        error = 'User %s not found!' % user_key
        create_error_log(error, 'ERR')
        return

    if not message:
        logging.error('Message %s not found!', message_key)
        error = 'Message %s not found!' % message_key
        create_error_log(error, 'ERR')
        return

    logging.info('Sending notice to %s via mail api.', user.email)

#    contact_markers = ContactMarker.query(ContactMarker.event == event_key,
#                                          ContactMarker.acknowledged == False)

    string_date = "%s %s, %s at %s:%s %s (GMT)" % (event.added.strftime("%B"), event.added.strftime("%d"),
                                                   event.added.strftime("%Y"),event.added.strftime("%I"),
                                                   event.added.strftime("%M"), event.added.strftime("%p"))

    subject = "School Beacon ROBOCALL service for alert %s was requested by you" % event_key.id()
    body = "School Beacon ROBOCALL service for alert <span style='color: red'>%s</span> was requested by you" % event_key.id()
    body = body + " on " + "<br><span style='color:red'>" + string_date + "</span>.<br><br>" + " The following numbers were called: <br>"

#    for contact_marker in contact_markers:
#        logging.info(contact_marker)
#        logging.info(contact_marker.methods)
#        for method in contact_marker.methods:
#            logging.info(method)
#            if '@' not in method:
#                body += str(method) + '<br>'
    for phone in phones:
        body += str(phone) + '<br>'

    body += "<br><br>The following text was delivered:<br> <span style='color:red'>%s</span>" % message.message['email']

    s = sendgrid.Sendgrid(settings.SENDGRID_ACCOUNT,
        settings.SENDGRID_PASSWORD,
        secure=True)

    email = sendgrid.Message(
        user.email,
        subject,
        body,
        body)
    email.add_to(user.email)
    s.web.send(email)
コード例 #25
0
    def get(self, event_id, number, *args, **kwargs):
        import sendgrid
        import settings
        from datetime import datetime
        from sosbeacon.event.message import Message
        from sosbeacon.event.student_marker import StudentMarker

        session_store = sessions.get_store()
        session = session_store.get_session()
        user_urlsafe = session.get('u')

        user_key = ndb.Key(urlsafe = user_urlsafe).get()
        event_key = ndb.Key(urlsafe = event_id)
        query_messages = Message.query(Message.event == event_key).fetch()

        body = ""

        for i in number:
        #           list comment message
            if i == "1":
                list_comment = Message.query(Message.event == event_key,
                    Message.message_type == 'c')
                title       = "Responder messages"
                body += str(self.responder_messages(user_key, title, list_comment))

            #           list student marker Responders
            if i == "2":
                query_response = StudentMarker.query(StudentMarker.event == event_key,
                    StudentMarker.is_direct == True,
                    StudentMarker.acknowledged == True)
                student_markers = query_response.fetch()
                title = "Responder List"
                body += str(self.email_student_marker(student_markers, title))

            #           list student marker Non Responders
            if i == "3":
                query_response = StudentMarker.query(StudentMarker.event == event_key,
                    StudentMarker.acknowledged == False, StudentMarker.is_direct == True)
                student_markers = query_response.fetch()
                title = "No Responder List"
                body += str(self.email_student_marker(student_markers, title))

            #           list message email
            if i == "4":
                title = "Alert Messages"
                body += str(self.email_broadcast_message(user_key, title, query_messages))

        today       = datetime.today()
        today       = today.strftime('%Y-%m-%d %H:%M')
        subject     = "Download data sent from SOSbeacon Message Center %s" % today
        email       = user_key.email

        s = sendgrid.Sendgrid(settings.SENDGRID_ACCOUNT,
            settings.SENDGRID_PASSWORD,
            secure=True)

        message = sendgrid.Message(
            settings.SENDGRID_SENDER,
            subject,
            body, body)

        message.add_to(str(email))
        try:
            s.web.send(message)
        except:
            error = "Can not download email."
            create_error_log(error, 'ERR')
コード例 #26
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
    except Exception, e:
        logging.exception("Invalid phone number %s", number)
        messages.append("Invalid phone number %s, %s", number, e.message)
        error = "Invalid phone number %s", number
        create_error_log(error, 'ERR')
        return None, messages

    logging.info(number)
    if not number.startswith('1'):
        number = '1' + number

    if not len(number) == 11:
        logging.error("Invalid phone number %s", number)
        messages.append("Invalide number %s, not 11 characters" % (number,))
        error = "Invalid phone number %s", number
        create_error_log(error, 'ERR')
        return None, messages

    number = "%s (%s) %s-%s" % (
        number[0], number[1:4], number[4:7], number[7:11])

    return number, messages


def _get_group(group_name, group_lookup, school_urlsafe):
    """Return a group for the group name passed in. Checks the group cache
    first if not there then queries by the lower case name. If not there then
    creates a new group.
    """
    #check for existing group by name
    if group_name.lower() in group_lookup:
コード例 #27
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def import_students(file_, school_urlsafe, is_direct):
    import csv
    import StringIO
    from collections import namedtuple

    results = {'success': [], 'failures': []}
    ResultItemDirect = namedtuple('ResultItemDirect', [
        'first_name', 'last_name', 'group', 'email', 'text_phone',
        'voice_phone', 'messages'
    ])
    ResultItemStudent = namedtuple('ResultItemStudent', [
        'first_name', 'last_name', 'group', 'parent_first_name_1',
        'parent_last_name_1', 'parent_email_1', 'parent_text_phone_1',
        'parent_voice_phone_1', 'parent_first_name_2', 'parent_last_name_2',
        'parent_email_2', 'parent_text_phone_2', 'parent_voice_phone_2',
        'messages'
    ])

    students = csv.reader(StringIO.StringIO(file_), delimiter=',')
    #TODO: check size and move to tasks

    #expected CSV format
    #Group, Student name, contact name parent 1, contact email,
    #voice phone, text phone, space, contact name parent 2
    #contact email, voice phone, text phone
    groups = {}
    futures = []
    for student_array in students:
        if student_array[0] and student_array[0].lower() == 'group':
            #assume it has a header
            continue

        first_name = unicode(student_array[1], 'utf8').strip()
        last_name = unicode(student_array[2], 'utf8').strip()
        group = unicode(student_array[0], 'utf8').strip()

        if is_direct:
            email = unicode(student_array[3], 'utf8').strip()
            text_phone = unicode(student_array[4], 'utf8').strip()
            voice_phone = unicode(student_array[5], 'utf8').strip()
            try:
                student, future, messages = import_student(
                    school_urlsafe, is_direct, student_array, groups)
                result = ResultItemDirect(first_name=first_name,
                                          last_name=last_name,
                                          group=group,
                                          email=email,
                                          text_phone=text_phone,
                                          voice_phone=voice_phone,
                                          messages=messages)
                results['success'].append(result)
            except Exception, e:
                logging.exception("Unable to import direct contact")
                result = ResultItemDirect(first_name=first_name,
                                          last_name=last_name,
                                          group=group,
                                          email=email,
                                          text_phone=text_phone,
                                          voice_phone=voice_phone,
                                          messages=[e.message])
                results['failures'].append(result)
                error = "Unable to import direct contact"
                create_error_log(error, 'ERR')

#            if not student and future:
#                futures.append(future)

        else:
            parent_first_name_1 = unicode(student_array[3], 'utf8').strip()
            parent_last_name_1 = unicode(student_array[4], 'utf8').strip()
            parent_email_1 = unicode(student_array[5], 'utf8').strip()
            parent_text_phone_1 = unicode(student_array[5], 'utf8').strip()
            parent_voice_phone_1 = unicode(student_array[6], 'utf8').strip()

            if len(student_array) > 7:
                parent_first_name_2 = unicode(student_array[7], 'utf8').strip()
                parent_last_name_2 = unicode(student_array[8], 'utf8').strip()
                parent_email_2 = unicode(student_array[9], 'utf8').strip()
                parent_text_phone_2 = unicode(student_array[10],
                                              'utf8').strip()
                parent_voice_phone_2 = unicode(student_array[11],
                                               'utf8').strip()
            else:
                parent_first_name_2 = parent_last_name_2 = parent_text_phone_2 = parent_voice_phone_2 = ''

            try:
                student, future, messages = import_student(
                    school_urlsafe, is_direct, student_array, groups)
                result = ResultItemStudent(
                    first_name=first_name,
                    last_name=last_name,
                    group=group,
                    parent_first_name_1=parent_first_name_1,
                    parent_last_name_1=parent_last_name_1,
                    parent_email_1=parent_email_1,
                    parent_text_phone_1=parent_text_phone_1,
                    parent_voice_phone_1=parent_voice_phone_1,
                    parent_first_name_2=parent_first_name_2,
                    parent_last_name_2=parent_last_name_2,
                    parent_email_2=parent_email_2,
                    parent_text_phone_2=parent_text_phone_2,
                    parent_voice_phone_2=parent_voice_phone_2,
                    messages='')

                results['success'].append(result)
            except Exception, e:
                logging.exception("Unable to import direct contact")
                result = ResultItemStudent(
                    first_name=first_name,
                    last_name=last_name,
                    group=group,
                    parent_first_name_1=parent_first_name_1,
                    parent_last_name_1=parent_last_name_1,
                    parent_email_1=parent_email_1,
                    parent_text_phone_1=parent_text_phone_1,
                    parent_voice_phone_1=parent_voice_phone_1,
                    parent_first_name_2=parent_first_name_2,
                    parent_last_name_2=parent_last_name_2,
                    parent_email_2=parent_email_2,
                    parent_text_phone_2=parent_text_phone_2,
                    parent_voice_phone_2=parent_voice_phone_2,
                    messages=[e.message])

                results['failures'].append(result)
                error = "Unable to import direct contact"
                create_error_log(error, 'ERR')
コード例 #28
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
    except Exception, e:
        logging.exception("Invalid phone number %s", number)
        messages.append("Invalid phone number %s, %s", number, e.message)
        error = "Invalid phone number %s", number
        create_error_log(error, 'ERR')
        return None, messages

    logging.info(number)
    if not number.startswith('1'):
        number = '1' + number

    if not len(number) == 11:
        logging.error("Invalid phone number %s", number)
        messages.append("Invalide number %s, not 11 characters" % (number, ))
        error = "Invalid phone number %s", number
        create_error_log(error, 'ERR')
        return None, messages

    number = "%s (%s) %s-%s" % (number[0], number[1:4], number[4:7],
                                number[7:11])

    return number, messages


def _get_group(group_name, group_lookup, school_urlsafe):
    """Return a group for the group name passed in. Checks the group cache
    first if not there then queries by the lower case name. If not there then
    creates a new group.
    """
    #check for existing group by name
    if group_name.lower() in group_lookup:
コード例 #29
0
ファイル: student.py プロジェクト: SOSbeacon/SchoolBeacon-GAE
def import_students(file_, school_urlsafe, is_direct):
    import csv
    import StringIO
    from collections import namedtuple

    results = {'success': [], 'failures': []}
    ResultItemDirect = namedtuple('ResultItemDirect', ['first_name', 'last_name', 'group', 'email', 'text_phone', 'voice_phone','messages'])
    ResultItemStudent = namedtuple('ResultItemStudent', ['first_name', 'last_name','group', 'parent_first_name_1', 'parent_last_name_1','parent_email_1', 'parent_text_phone_1', 'parent_voice_phone_1',
                                                         'parent_first_name_2', 'parent_last_name_2','parent_email_2', 'parent_text_phone_2', 'parent_voice_phone_2','messages'])

    students = csv.reader(StringIO.StringIO(file_), delimiter=',')
    #TODO: check size and move to tasks

    #expected CSV format
    #Group, Student name, contact name parent 1, contact email,
    #voice phone, text phone, space, contact name parent 2
    #contact email, voice phone, text phone
    groups = {}
    futures = []
    for student_array in students:
        if student_array[0] and student_array[0].lower() == 'group':
            #assume it has a header
            continue

        first_name = unicode(student_array[1], 'utf8').strip()
        last_name = unicode(student_array[2], 'utf8').strip()
        group = unicode(student_array[0], 'utf8').strip()

        if is_direct:
            email = unicode(student_array[3], 'utf8').strip()
            text_phone = unicode(student_array[4], 'utf8').strip()
            voice_phone = unicode(student_array[5], 'utf8').strip()
            try:
                student, future, messages = import_student(school_urlsafe, is_direct, student_array, groups)
                result = ResultItemDirect(first_name=first_name, last_name=last_name, group=group, email=email, text_phone=text_phone, voice_phone=voice_phone, messages=messages)
                results['success'].append(result)
            except Exception, e:
                logging.exception("Unable to import direct contact")
                result = ResultItemDirect(first_name=first_name, last_name=last_name, group=group, email=email, text_phone=text_phone, voice_phone=voice_phone, messages=[e.message])
                results['failures'].append(result)
                error = "Unable to import direct contact"
                create_error_log(error, 'ERR')

#            if not student and future:
#                futures.append(future)

        else:
            parent_first_name_1 = unicode(student_array[3], 'utf8').strip()
            parent_last_name_1 = unicode(student_array[4], 'utf8').strip()
            parent_email_1 = unicode(student_array[5], 'utf8').strip()
            parent_text_phone_1 = unicode(student_array[5], 'utf8').strip()
            parent_voice_phone_1 = unicode(student_array[6], 'utf8').strip()


            if len(student_array) > 7:
                parent_first_name_2 = unicode(student_array[7], 'utf8').strip()
                parent_last_name_2 = unicode(student_array[8], 'utf8').strip()
                parent_email_2 = unicode(student_array[9], 'utf8').strip()
                parent_text_phone_2 = unicode(student_array[10], 'utf8').strip()
                parent_voice_phone_2 = unicode(student_array[11], 'utf8').strip()
            else:
                parent_first_name_2 = parent_last_name_2 = parent_text_phone_2 = parent_voice_phone_2 = ''

            try:
                student, future, messages = import_student(school_urlsafe, is_direct, student_array, groups)
                result = ResultItemStudent(first_name=first_name, last_name=last_name,
                    group=group,
                    parent_first_name_1 = parent_first_name_1,
                    parent_last_name_1 = parent_last_name_1,
                    parent_email_1 = parent_email_1,
                    parent_text_phone_1 = parent_text_phone_1,
                    parent_voice_phone_1 = parent_voice_phone_1,
                    parent_first_name_2 = parent_first_name_2,
                    parent_last_name_2 = parent_last_name_2,
                    parent_email_2 = parent_email_2,
                    parent_text_phone_2 = parent_text_phone_2,
                    parent_voice_phone_2 = parent_voice_phone_2, messages='')

                results['success'].append(result)
            except Exception, e:
                logging.exception("Unable to import direct contact")
                result = ResultItemStudent(first_name=first_name, last_name=last_name,
                    group=group,
                    parent_first_name_1 = parent_first_name_1,
                    parent_last_name_1 = parent_last_name_1,
                    parent_email_1 = parent_email_1,
                    parent_text_phone_1 = parent_text_phone_1,
                    parent_voice_phone_1 = parent_voice_phone_1,
                    parent_first_name_2 = parent_first_name_2,
                    parent_last_name_2 = parent_last_name_2,
                    parent_email_2 = parent_email_2,
                    parent_text_phone_2 = parent_text_phone_2,
                    parent_voice_phone_2 = parent_voice_phone_2, messages=[e.message])

                results['failures'].append(result)
                error = "Unable to import direct contact"
                create_error_log(error, 'ERR')
コード例 #30
0
    def get(self, event_id, number, *args, **kwargs):
        import sendgrid
        import settings
        from datetime import datetime
        from sosbeacon.event.message import Message
        from sosbeacon.event.student_marker import StudentMarker

        session_store = sessions.get_store()
        session = session_store.get_session()
        user_urlsafe = session.get('u')

        user_key = ndb.Key(urlsafe=user_urlsafe).get()
        event_key = ndb.Key(urlsafe=event_id)
        query_messages = Message.query(Message.event == event_key).fetch()

        body = ""

        for i in number:
            #           list comment message
            if i == "1":
                list_comment = Message.query(Message.event == event_key,
                                             Message.message_type == 'c')
                title = "Responder messages"
                body += str(
                    self.responder_messages(user_key, title, list_comment))

            #           list student marker Responders
            if i == "2":
                query_response = StudentMarker.query(
                    StudentMarker.event == event_key,
                    StudentMarker.is_direct == True,
                    StudentMarker.acknowledged == True)
                student_markers = query_response.fetch()
                title = "Responder List"
                body += str(self.email_student_marker(student_markers, title))

            #           list student marker Non Responders
            if i == "3":
                query_response = StudentMarker.query(
                    StudentMarker.event == event_key,
                    StudentMarker.acknowledged == False,
                    StudentMarker.is_direct == True)
                student_markers = query_response.fetch()
                title = "No Responder List"
                body += str(self.email_student_marker(student_markers, title))

            #           list message email
            if i == "4":
                title = "Alert Messages"
                body += str(
                    self.email_broadcast_message(user_key, title,
                                                 query_messages))

        today = datetime.today()
        today = today.strftime('%Y-%m-%d %H:%M')
        subject = "Download data sent from SOSbeacon Message Center %s" % today
        email = user_key.email

        s = sendgrid.Sendgrid(settings.SENDGRID_ACCOUNT,
                              settings.SENDGRID_PASSWORD,
                              secure=True)

        message = sendgrid.Message(settings.SENDGRID_SENDER, subject, body,
                                   body)

        message.add_to(str(email))
        try:
            s.web.send(message)
        except:
            error = "Can not download email."
            create_error_log(error, 'ERR')
コード例 #31
0
def send_email_robocall_to_user(event_urlsafe, user_urlsafe, message_urlsafe,
                                phones):
    from sosbeacon.event.contact_marker import ContactMarker
    import sendgrid
    import settings

    if not event_urlsafe:
        logging.error('No event key given.')
        return

    # TODO: Use event id rather than key here for namespacing purposes?
    event_key = ndb.Key(urlsafe=event_urlsafe)
    event = event_key.get()
    user_key = ndb.Key(urlsafe=user_urlsafe)
    user = user_key.get()
    message_key = ndb.Key(urlsafe=message_urlsafe)
    message = message_key.get()

    if not event:
        logging.error('Event %s not found!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if event.status == EVENT_STATUS_CLOSED:
        logging.error('Event %s closed!', event_key)
        error = 'Event %s not found!' % event_key
        create_error_log(error, 'ERR')
        return

    if not user:
        logging.error('User %s not found!', user_key)
        error = 'User %s not found!' % user_key
        create_error_log(error, 'ERR')
        return

    if not message:
        logging.error('Message %s not found!', message_key)
        error = 'Message %s not found!' % message_key
        create_error_log(error, 'ERR')
        return

    logging.info('Sending notice to %s via mail api.', user.email)

    #    contact_markers = ContactMarker.query(ContactMarker.event == event_key,
    #                                          ContactMarker.acknowledged == False)

    string_date = "%s %s, %s at %s:%s %s (GMT)" % (
        event.added.strftime("%B"), event.added.strftime("%d"),
        event.added.strftime("%Y"), event.added.strftime("%I"),
        event.added.strftime("%M"), event.added.strftime("%p"))

    subject = "School Beacon ROBOCALL service for alert %s was requested by you" % event_key.id(
    )
    body = "School Beacon ROBOCALL service for alert <span style='color: red'>%s</span> was requested by you" % event_key.id(
    )
    body = body + " on " + "<br><span style='color:red'>" + string_date + "</span>.<br><br>" + " The following numbers were called: <br>"

    #    for contact_marker in contact_markers:
    #        logging.info(contact_marker)
    #        logging.info(contact_marker.methods)
    #        for method in contact_marker.methods:
    #            logging.info(method)
    #            if '@' not in method:
    #                body += str(method) + '<br>'
    for phone in phones:
        body += str(phone) + '<br>'

    body += "<br><br>The following text was delivered:<br> <span style='color:red'>%s</span>" % message.message[
        'email']

    s = sendgrid.Sendgrid(settings.SENDGRID_ACCOUNT,
                          settings.SENDGRID_PASSWORD,
                          secure=True)

    email = sendgrid.Message(user.email, subject, body, body)
    email.add_to(user.email)
    s.web.send(email)