<commit_before>from datetime import date, time, timedelta, datetime
from django.conf import settings
from script.models import Script, ScriptProgress
from rapidsms.models import Connection
from django.contrib.auth.models import Group

roster = getattr(settings, 'POLL_DATES', {})
groups = getattr(settings, 'GROUPS', {})

def upcoming(dates, get_day=date.today):
    """
    Returns the next date, or None.
    """
    return _first(lambda d: d > get_day(), dates)

def current_period(dates, get_day=date.today):
    """
    Returns a tuple of the current period, with a non-inclusive end date.

    Either element in the tuple may be None, for open intervals.
    """
    start = _first(lambda d: d <= get_day(), dates)
    end = _first(lambda d: d > get_day(), dates)
    return (start, end - timedelta(days=1) if end else None)

def next_scheduled(poll_id, roster=roster, get_day=date.today):
    """
    Returns the datetime the specified poll should next run on.
    """
    dates = roster.get(poll_id) or []
    date = upcoming(dates, get_day = get_day)
    return at(date, 10) if date else None

def schedule(connection, script, get_day=date.today, roster=roster):
    """
    Schedules the script for the current connection according to roster.
    """
    time = next_scheduled(script.slug, roster=roster, get_day=get_day)
    schedule_at(connection, script, time)

def schedule_script(script, get_day = date.today, groups=groups, roster = roster):
    """
    Schedules the script for each connection belonging to a subscribed group.
    """
    names = [name for name in groups.keys() if script.slug in groups.get(name)]
    connections = Connection.objects.filter(contact__groups__name__in = names)

    for connection in connections:
        schedule(connection, script, get_day=get_day, roster=roster)

    # Teachers are also in a virtual group named the same as their grade.
    if 'p6' in names or 'p3' in names:
        for connection in Connection.objects.filter(contact__groups__name = 'Teachers'):
            schedule(connection, script, get_day=get_day, roster=roster)<commit_msg>Unify schedule_script() and schedule_script_now() to give bugs less code paths to hide in.<commit_after>from datetime import date, time, timedelta, datetime
from django.conf import settings
from script.models import Script, ScriptProgress
from rapidsms.models import Connection
from django.contrib.auth.models import Group

roster = getattr(settings, 'POLL_DATES', {})
groups = getattr(settings, 'GROUPS', {})

def upcoming(dates, get_day=date.today):
    """
    Returns the next date, or None.
    """
    return _first(lambda d: d > get_day(), dates)

def current_period(dates, get_day=date.today):
    """
    Returns a tuple of the current period, with a non-inclusive end date.

    Either element in the tuple may be None, for open intervals.
    """
    start = _first(lambda d: d <= get_day(), dates)
    end = _first(lambda d: d > get_day(), dates)
    return (start, end - timedelta(days=1) if end else None)

def next_scheduled(poll_id, roster=roster, get_day=date.today):
    """
    Returns the datetime the specified poll should next run on.
    """
    dates = roster.get(poll_id) or []
    date = upcoming(dates, get_day = get_day)
    return at(date, 10) if date else None

def schedule(connection, script, get_day=date.today, roster=roster):
    """
    Schedules the script for the current connection according to roster.
    """
    time = next_scheduled(script.slug, roster=roster, get_day=get_day)
    schedule_at(connection, script, time)

def schedule_script(script, get_day=date.today, groups=groups, roster=roster):
    """
    Schedules the script for each connection belonging to a subscribed group.
    """
    time = next_scheduled(script.slug, roster=roster, get_day=get_day)
    schedule_script_at(script, time, groups=groups)
{'fraction_non_alphanumeric': 0.10305541170378042, 'fraction_numerical': 0.0020714655618850335, 'mean_word_length': 4.036505867014341, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1424080', 'n_tokens_mistral': 1181, 'n_tokens_neox': 1145, 'n_words': 385}