Пример #1
0
def broadcast_to_student(student_key, event_key, message_key, batch_id=""):
    """Send broadcast to each of the student's contacts."""
    from sosbeacon.event.student_marker import create_or_update_marker
    from sosbeacon.student import Student  # Needed to load the entity.
    from sosbeacon.utils import insert_tasks

    student = student_key.get()

    if not student:
        # TODO: ?
        logging.info("Tried to broadcast %s to missing student %s.", message_key.urlsafe(), student_key.urlsafe())
        return

    tasks = []

    # contacts = {}
    for contact in student.contacts:
        # TODO: Optimize task building with memcache markers to
        # avoid building tasks that already exist.

        task = get_contact_broadcast_task(event_key, message_key, student_key, contact, batch_id)

        if not task:
            continue

        tasks.append(task)

        # TODO: WTF is this?
        # contacts[contact['t']] = contact

    if tasks:
        insert_tasks(tasks, CONTACT_TX_QUEUE)

    create_or_update_marker(event_key, student, message_key)
Пример #2
0
def broadcast_to_contact(event_key, message_key, student_key, contact, batch_id=""):
    """Insert tasks to send message to each contact method, and create a
    contact marker.
    """
    from sosbeacon.event.contact_marker import create_or_update_marker
    from sosbeacon.utils import insert_tasks

    SEARCH_TYPES = ["e", "t"]

    # Find methods we want to query by.
    methods = set()
    for method in contact.get("methods", ()):
        method_type = method.get("type")
        value = method.get("value")

        if method_type == "t" and not value:
            SEARCH_TYPES.append("p")

        if not value or method_type not in SEARCH_TYPES:
            continue

        methods.add(value)

    if not methods:
        return

    short_id = create_or_update_marker(event_key, student_key, message_key, contact, methods)

    method_tasks = []
    for method in methods:
        method_tasks.append(get_method_broadcast_task(event_key, message_key, short_id, method, batch_id))

    insert_tasks(method_tasks, METHOD_TX_QUEUE)
Пример #3
0
def broadcast_to_groups(group_keys, event_key, message_key, batch_id):
    """Scan over the given set of groups, sending the broadcast to everyone
    in those groups.
    """
    from sosbeacon.group import ADMIN_GROUPS_ID
    from sosbeacon.group import Group
    from sosbeacon.utils import insert_tasks

    # This is done to dedupe the group list, for better resilience.
    group_keys = list(set(group_keys))

    if len(group_keys) == 1 and group_keys[0].id() == ADMIN_GROUPS_ID:
        group_keys = Group.query().order(Group.key).iter(keys_only=True)

    tasks = []
    for group_key in group_keys:
        # TODO: Batch tasks or start
        tasks.append(get_group_broadcast_task(group_key, event_key, message_key, batch_id))

        if len(tasks) > 10:
            insert_tasks(tasks, GROUP_TX_QUEUE)
            tasks = []

    if tasks:
        insert_tasks(tasks, GROUP_TX_QUEUE)
Пример #4
0
def broadcast_to_groups(group_keys, event_key, message_key, batch_id):
    """Scan over the given set of groups, sending the broadcast to everyone
    in those groups.
    """
    from sosbeacon.group import ADMIN_GROUPS_ID
    from sosbeacon.group import Group
    from sosbeacon.utils import insert_tasks

    # This is done to dedupe the group list, for better resilience.
    group_keys = list(set(group_keys))

    if len(group_keys) == 1 and group_keys[0].id() == ADMIN_GROUPS_ID:
        group_keys = Group.query().order(Group.key).iter(keys_only=True)

    tasks = []
    for group_key in group_keys:
        # TODO: Batch tasks or start
        tasks.append(
            get_group_broadcast_task(group_key, event_key, message_key,
                                     batch_id))

        if len(tasks) > 10:
            insert_tasks(tasks, GROUP_TX_QUEUE)
            tasks = []

    if tasks:
        insert_tasks(tasks, GROUP_TX_QUEUE)
Пример #5
0
def robocall_start(event_key, is_direct, user_urlsafe, tz):

    event_urlsafe = ndb.Key(urlsafe=event_key)
    event = event_urlsafe.get()

    if not event:
        logging.error('Event %s not found!', event_urlsafe)
        return

    if event.status == EVENT_STATUS_CLOSED:
        logging.error('Event %s closed!', event_urlsafe)
        return

    query = StudentMarker.query(StudentMarker.event == event_urlsafe,
                                StudentMarker.acknowledged == False,
                                StudentMarker.is_direct == is_direct)

    student_markers = query.fetch()

    list_broadcast = Message.query(
        Message.event == event_urlsafe,
        Message.message_type.IN(['b', 'eo', 'em',
                                 'ec'])).order(Message.timestamp).fetch()

    last_broadcast = list_broadcast[0]

    tasks = []
    phones = []

    #    if voice phone is empty, text phone will replace voice phone to make a call
    for student_marker in student_markers:
        for contact in student_marker.contacts:
            if contact['methods'][2]['value']:
                phones.append(contact['methods'][2]['value'])
            else:
                phones.append(contact['methods'][1]['value'])

    phones = list(set(phones))

    if not phones:
        return

    for phone in phones:
        tasks.append(
            get_robocall_task(event_urlsafe, phone, last_broadcast.key, tz))

        if len(tasks) > 10:
            insert_tasks(tasks, ROBOCALL_QUEUE_NAME)
            tasks = []

    if tasks:
        tasks.append(
            get_sent_email_task(event_urlsafe, user_urlsafe,
                                last_broadcast.key, phones))
        insert_tasks(tasks, ROBOCALL_QUEUE_NAME)
Пример #6
0
def create_marker_user(event_key, message_key, user_key):
    """Scan over the given set of groups, sending the broadcast to everyone
    in those groups.
    """
    from sosbeacon.utils import insert_tasks
    from sosbeacon.event.contact_marker import ContactMarker
    from sosbeacon.event.contact_marker import get_marker_for_methods
    from sosbeacon.student import Student
    from sosbeacon.student import DEFAULT_STUDENT_ID

    methods = set()
    if message_key.get().message_type == 'eo':
        methods.add(user_key.get().email)
    else:
        methods.add(user_key.get().phone)
        methods.add(user_key.get().email)

    marker = get_marker_for_methods(event_key, methods)

    student_key = ndb.Key(Student,
                          "%s-%s" % (DEFAULT_STUDENT_ID, user_key.id()),
                          namespace='_x_')

    if not marker:
        # TODO: What needs set?
        short_id = str(ContactMarker.allocate_ids(size=1, parent=event_key)[0])
        key_id = "%s:%s" % (event_key.id(), user_key.id())
        marker = ContactMarker(
            id=key_id,
            event=event_key,
            first_name=user_key.get().first_name,
            last_name=user_key.get().last_name,
            students={str(student_key.id()): []},
            short_id=short_id,
            methods=[user_key.get().email,
                     user_key.get().phone],
            count_comment=0,
            count_visit=0,
            is_user=True)
        marker.acknowledged = True
        marker.put()

    tasks = []
    for method in methods:
        # TODO: Batch tasks or start
        tasks.append(
            get_broadcast_method_to_user_task(event_key, message_key, user_key,
                                              method))

        if len(tasks) > 10:
            insert_tasks(tasks, USER_TX_QUEUE)
            tasks = []

    if tasks:
        insert_tasks(tasks, USER_TX_QUEUE)
Пример #7
0
def robocall_start(event_key, is_direct, user_urlsafe, tz):

    event_urlsafe = ndb.Key(urlsafe=event_key)
    event = event_urlsafe.get()

    if not event:
        logging.error('Event %s not found!', event_urlsafe)
        return

    if event.status == EVENT_STATUS_CLOSED:
        logging.error('Event %s closed!', event_urlsafe)
        return

    query = StudentMarker.query(StudentMarker.event == event_urlsafe,
                                StudentMarker.acknowledged == False,
                                StudentMarker.is_direct == is_direct)

    student_markers = query.fetch()

    list_broadcast = Message.query(Message.event == event_urlsafe,
                                   Message.message_type.IN(['b', 'eo', 'em', 'ec'])).order(Message.timestamp).fetch()

    last_broadcast = list_broadcast[0]

    tasks = []
    phones = []

#    if voice phone is empty, text phone will replace voice phone to make a call
    for student_marker in student_markers:
        for contact in student_marker.contacts:
            if contact['methods'][2]['value']:
                phones.append(contact['methods'][2]['value'])
            else:
                phones.append(contact['methods'][1]['value'])

    phones = list(set(phones))

    if not phones:
        return

    for phone in phones:
        tasks.append(
            get_robocall_task(event_urlsafe, phone, last_broadcast.key, tz)
        )

        if len(tasks) > 10:
            insert_tasks(tasks, ROBOCALL_QUEUE_NAME)
            tasks = []

    if tasks:
        tasks.append(get_sent_email_task(event_urlsafe, user_urlsafe, last_broadcast.key, phones))
        insert_tasks(tasks, ROBOCALL_QUEUE_NAME)
Пример #8
0
def create_marker_user(event_key, message_key, user_key):
    """Scan over the given set of groups, sending the broadcast to everyone
    in those groups.
    """
    from sosbeacon.utils import insert_tasks
    from sosbeacon.event.contact_marker import ContactMarker
    from sosbeacon.event.contact_marker import get_marker_for_methods
    from sosbeacon.student import Student
    from sosbeacon.student import DEFAULT_STUDENT_ID

    methods = set()
    if message_key.get().message_type == "eo":
        methods.add(user_key.get().email)
    else:
        methods.add(user_key.get().phone)
        methods.add(user_key.get().email)

    marker = get_marker_for_methods(event_key, methods)

    student_key = ndb.Key(Student, "%s-%s" % (DEFAULT_STUDENT_ID, user_key.id()), namespace="_x_")

    if not marker:
        # TODO: What needs set?
        short_id = str(ContactMarker.allocate_ids(size=1, parent=event_key)[0])
        key_id = "%s:%s" % (event_key.id(), user_key.id())
        marker = ContactMarker(
            id=key_id,
            event=event_key,
            first_name=user_key.get().first_name,
            last_name=user_key.get().last_name,
            students={str(student_key.id()): []},
            short_id=short_id,
            methods=[user_key.get().email, user_key.get().phone],
            count_comment=0,
            count_visit=0,
            is_user=True,
        )
        marker.acknowledged = True
        marker.put()

    tasks = []
    for method in methods:
        # TODO: Batch tasks or start
        tasks.append(get_broadcast_method_to_user_task(event_key, message_key, user_key, method))

        if len(tasks) > 10:
            insert_tasks(tasks, USER_TX_QUEUE)
            tasks = []

    if tasks:
        insert_tasks(tasks, USER_TX_QUEUE)
Пример #9
0
    def test_insert_batch(self, queue_mock):
        """Ensure taskqueue.Queue.add is called exactly once."""
        from sosbeacon.utils import insert_tasks

        tasks = []
        for i in xrange(1, 10):
            tasks.append(object())
        added = insert_tasks(tasks, 'default')
        self.assertEqual(added, 9)
Пример #10
0
    def test_insert_batch(self, queue_mock):
        """Ensure taskqueue.Queue.add is called exactly once."""
        from sosbeacon.utils import insert_tasks

        tasks = []
        for i in xrange(1, 10):
            tasks.append(object())
        added = insert_tasks(tasks, 'default')
        self.assertEqual(added, 9)
Пример #11
0
def broadcast_to_contact(event_key,
                         message_key,
                         student_key,
                         contact,
                         batch_id=''):
    """Insert tasks to send message to each contact method, and create a
    contact marker.
    """
    from sosbeacon.event.contact_marker import create_or_update_marker
    from sosbeacon.utils import insert_tasks

    SEARCH_TYPES = ['e', 't']

    # Find methods we want to query by.
    methods = set()
    for method in contact.get('methods', ()):
        method_type = method.get('type')
        value = method.get('value')

        if method_type == 't' and not value:
            SEARCH_TYPES.append('p')

        if not value or method_type not in SEARCH_TYPES:
            continue

        methods.add(value)

    if not methods:
        return

    short_id = create_or_update_marker(event_key, student_key, message_key,
                                       contact, methods)

    method_tasks = []
    for method in methods:
        method_tasks.append(
            get_method_broadcast_task(event_key, message_key, short_id, method,
                                      batch_id))

    insert_tasks(method_tasks, METHOD_TX_QUEUE)
Пример #12
0
def broadcast_to_group(group_key, event_key, message_key, batch_id="", iteration=0, cursor=None):
    """Scan over people in the group, starting from cursor if provided,
    sending the broadcast to every contact.
    """
    from sosbeacon.group import get_student_keys
    from sosbeacon.utils import insert_tasks

    students, cursor, more = get_student_keys(group_key, cursor)

    if more:
        continuation = get_group_broadcast_task(group_key, event_key, message_key, batch_id, iteration + 1, cursor)

        insert_tasks((continuation,), GROUP_TX_QUEUE)

    tasks = []
    for student_key in students:
        task = get_student_broadcast_task(student_key, event_key, message_key, batch_id)
        if not task:
            continue

        tasks.append(task)

        if len(tasks) > 10:
            insert_tasks(tasks, STUDENT_TX_QUEUE)
            tasks = []

    if tasks:
        insert_tasks(tasks, STUDENT_TX_QUEUE)
Пример #13
0
    def test_splits_on_taskexists(self, queue_add_mock):
        """Ensure task batches are split and insertion is retried on
        TaskAlreadyExistsError.
        """
        from google.appengine.api import taskqueue
        from sosbeacon.utils import insert_tasks

        queue_add_mock.side_effect = taskqueue.TaskAlreadyExistsError

        tasks = [i for i in xrange(0, 10)]
        added = insert_tasks(tasks, 'default')

        self.assertEqual(added, 0)
        self.assertEqual(queue_add_mock.call_count, 19)
Пример #14
0
    def test_splits_on_taskexists(self, queue_add_mock):
        """Ensure task batches are split and insertion is retried on
        TaskAlreadyExistsError.
        """
        from google.appengine.api import taskqueue
        from sosbeacon.utils import insert_tasks

        queue_add_mock.side_effect = taskqueue.TaskAlreadyExistsError

        tasks = [i for i in xrange(0, 10)]
        added = insert_tasks(tasks, 'default')

        self.assertEqual(added, 0)
        self.assertEqual(queue_add_mock.call_count, 19)
Пример #15
0
def broadcast_to_student(student_key, event_key, message_key, batch_id=''):
    """Send broadcast to each of the student's contacts."""
    from sosbeacon.event.student_marker import create_or_update_marker
    from sosbeacon.student import Student  # Needed to load the entity.
    from sosbeacon.utils import insert_tasks

    student = student_key.get()

    if not student:
        # TODO: ?
        logging.info('Tried to broadcast %s to missing student %s.',
                     message_key.urlsafe(), student_key.urlsafe())
        return

    tasks = []

    #contacts = {}
    for contact in student.contacts:
        # TODO: Optimize task building with memcache markers to
        # avoid building tasks that already exist.

        task = get_contact_broadcast_task(event_key, message_key, student_key,
                                          contact, batch_id)

        if not task:
            continue

        tasks.append(task)

        # TODO: WTF is this?
        #contacts[contact['t']] = contact

    if tasks:
        insert_tasks(tasks, CONTACT_TX_QUEUE)

    create_or_update_marker(event_key, student, message_key)
Пример #16
0
    def test_splits_once(self, queue_add_mock):
        """Ensure task batches are split and insertion is retried on
        TaskAlreadyExistsError.
        """
        from google.appengine.api import taskqueue
        from sosbeacon.utils import insert_tasks

        def side_effect(*args):
            if 2 in args[0]:
                raise taskqueue.TombstonedTaskError('uh oh')

        queue_add_mock.side_effect = side_effect

        tasks = [i for i in xrange(0, 9)]
        added = insert_tasks(tasks, 'default')

        self.assertEqual(added, 8)
        self.assertEqual(queue_add_mock.call_count, 7)
Пример #17
0
    def test_splits_once(self, queue_add_mock):
        """Ensure task batches are split and insertion is retried on
        TaskAlreadyExistsError.
        """
        from google.appengine.api import taskqueue
        from sosbeacon.utils import insert_tasks

        def side_effect(*args):
            if 2 in args[0]:
                raise taskqueue.TombstonedTaskError('uh oh')

        queue_add_mock.side_effect = side_effect

        tasks = [i for i in xrange(0, 9)]
        added = insert_tasks(tasks, 'default')

        self.assertEqual(added, 8)
        self.assertEqual(queue_add_mock.call_count, 7)
Пример #18
0
def broadcast_to_group(group_key,
                       event_key,
                       message_key,
                       batch_id='',
                       iteration=0,
                       cursor=None):
    """Scan over people in the group, starting from cursor if provided,
    sending the broadcast to every contact.
    """
    from sosbeacon.group import get_student_keys
    from sosbeacon.utils import insert_tasks

    students, cursor, more = get_student_keys(group_key, cursor)

    if more:
        continuation = get_group_broadcast_task(group_key, event_key,
                                                message_key, batch_id,
                                                iteration + 1, cursor)

        insert_tasks((continuation, ), GROUP_TX_QUEUE)

    tasks = []
    for student_key in students:
        task = get_student_broadcast_task(student_key, event_key, message_key,
                                          batch_id)
        if not task:
            continue

        tasks.append(task)

        if len(tasks) > 10:
            insert_tasks(tasks, STUDENT_TX_QUEUE)
            tasks = []

    if tasks:
        insert_tasks(tasks, STUDENT_TX_QUEUE)