# Path: ob2/util/time.py
# def now_str():
#     """Gets the current datetime in a serializable format (for database)."""
#     return format_time(now())
# 
# Path: ob2/util/assignments.py
# def get_assignment_name_set():
#     global _assignment_name_set
#     if _assignment_name_set is None:
#         _assignment_name_set = {assignment.name for assignment in config.assignments}
#     return _assignment_name_set
# 
# Path: ob2/util/build_constants.py
# QUEUED = -2
# 
# Path: ob2/util/config_data.py
# def get_repo_type(repo_name):
#     """
#     Returns either "group" or "personal", depending on what repo_name appears to be. If repo is
#     unidentifiable, return None.
# 
#     """
#     if re.match(r'^group\d+$', repo_name):
#         repo_type = "group"
#     elif re.match(r'^[a-z]{2,3}$', repo_name):
#         repo_type = "personal"
#     else:
#         repo_type = None
# 
#     # This is a useful hook to change how repos are classified, based on their name. The default is
#     # pretty good, but you may have extra repos that don't exactly follow this naming scheme.
#     #
#     # Arguments:
#     #   repo_type -- The original guess for the repo_type (see code above)
#     #   repo_name -- The name of the repo (e.g. "aa" or "group1")
#     #
#     # Returns:
#     #   Either "group" or "personal"
#     repo_type = apply_filters("get-repo-type", repo_type, repo_name)
# 
#     return repo_type
# 
# Path: ob2/util/group_constants.py
# ACCEPTED = 1


from collections import Counter
from ob2.util.time import now_str
from ob2.util.assignments import get_assignment_name_set
from ob2.util.build_constants import QUEUED
from ob2.util.config_data import get_repo_type
from ob2.util.group_constants import ACCEPTED
        pass


def create_build(c, job_name, source, commit, message):
    build_number = get_next_autoincrementing_value(c, "dockergrader_last_build_number")
    build_name = "%s-build-%d" % (job_name, build_number)
    c.execute('''INSERT INTO builds (build_name, source, `commit`, message, job, status, score,
                 started, updated, log) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
              [build_name, source, commit, message, job_name, QUEUED, 0.0, now_str(),
               now_str(), None])
    return build_name


def assign_grade_batch(c, users, assignment, score, slipunits, transaction_name, description,
                       source, manual=False, dont_lower=False):
    """
    Assigns a new grade to one or more students. Also supports assigning slip units. You can use
    the special value `None` for score and/or slipunits to use the current value. If the dont_lower
    flag is True, then anybody in `users` who currently has a higher grade will be removed from
    the operation (and slip days will not be adjusted either).

    Returns a list of user ids whose grades were affected (will always be a subset of users).

    """
    if assignment not in get_assignment_name_set():
        raise ValueError("Assignment %s is not known" % assignment)
    if not users:
        return []
    if score is None and slipunits is None:
        return []

# Path: ob2/util/time.py
# def now_str():
#     """Gets the current datetime in a serializable format (for database)."""
#     return format_time(now())
# 
# Path: ob2/util/assignments.py
# def get_assignment_name_set():
#     global _assignment_name_set
#     if _assignment_name_set is None:
#         _assignment_name_set = {assignment.name for assignment in config.assignments}
#     return _assignment_name_set
# 
# Path: ob2/util/build_constants.py
# QUEUED = -2
# 
# Path: ob2/util/config_data.py
# def get_repo_type(repo_name):
#     """
#     Returns either "group" or "personal", depending on what repo_name appears to be. If repo is
#     unidentifiable, return None.
# 
#     """
#     if re.match(r'^group\d+$', repo_name):
#         repo_type = "group"
#     elif re.match(r'^[a-z]{2,3}$', repo_name):
#         repo_type = "personal"
#     else:
#         repo_type = None
# 
#     # This is a useful hook to change how repos are classified, based on their name. The default is
#     # pretty good, but you may have extra repos that don't exactly follow this naming scheme.
#     #
#     # Arguments:
#     #   repo_type -- The original guess for the repo_type (see code above)
#     #   repo_name -- The name of the repo (e.g. "aa" or "group1")
#     #
#     # Returns:
#     #   Either "group" or "personal"
#     repo_type = apply_filters("get-repo-type", repo_type, repo_name)
# 
#     return repo_type
# 
# Path: ob2/util/group_constants.py
# ACCEPTED = 1


# Path: ob2/database/helpers.py
from collections import Counter
from ob2.util.time import now_str
from ob2.util.assignments import get_assignment_name_set
from ob2.util.build_constants import QUEUED
from ob2.util.config_data import get_repo_type
from ob2.util.group_constants import ACCEPTED

        pass


def create_build(c, job_name, source, commit, message):
    build_number = get_next_autoincrementing_value(c, "dockergrader_last_build_number")
    build_name = "%s-build-%d" % (job_name, build_number)
    c.execute('''INSERT INTO builds (build_name, source, `commit`, message, job, status, score,
                 started, updated, log) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
              [build_name, source, commit, message, job_name, QUEUED, 0.0, now_str(),
               now_str(), None])
    return build_name


def assign_grade_batch(c, users, assignment, score, slipunits, transaction_name, description,
                       source, manual=False, dont_lower=False):
    """
    Assigns a new grade to one or more students. Also supports assigning slip units. You can use
    the special value `None` for score and/or slipunits to use the current value. If the dont_lower
    flag is True, then anybody in `users` who currently has a higher grade will be removed from
    the operation (and slip days will not be adjusted either).

    Returns a list of user ids whose grades were affected (will always be a subset of users).

    """
    if assignment not in get_assignment_name_set():
        raise ValueError("Assignment %s is not known" % assignment)
    if not users:
        return []
    if score is None and slipunits is None:
        return []

    timestamp = now_str()