# Path: ob2/util/build_constants.py
# QUEUED = -2
# 
# IN_PROGRESS = -1
# 
# SUCCESS = 0
# 
# FAILED = 1
# 
# def build_status_to_string(status, default='Unknown'):
#     return {QUEUED:      "Waiting in queue",
#             IN_PROGRESS: "In progress",
#             SUCCESS:     "Completed",
#             FAILED:      "Failed to complete"}.get(status, default)
# 
# Path: ob2/util/encoding.py
# def wrangle_to_unicode(text):
#     """
#     Converts some object to unicode text. Use the same decoding heuristic that's most commonly used
#     in other places.
# 
#     """
#     try:
#         text = str(text).decode("utf-8")
#     except UnicodeDecodeError:
#         text = str(text).decode("latin-1")
#     return text
# 
# Path: ob2/util/group_constants.py
# INVITED = 0
# 
# ACCEPTED = 1
# 
# REJECTED = 2
# 
# def invitation_status_to_string(status, default='Unknown'):
#     return {INVITED:  "invited",
#             ACCEPTED: "accepted",
#             REJECTED: "rejected"}.get(status, default)
# 
# Path: ob2/util/hooks.py
# def apply_filters(name, value, *args):
#     """
#     Applies all filters registered under NAME to VALUE.
# 
#     """
#     for _, hook in _HOOKS_FILTERS[name]:
#         value = hook(value, *args)
#     return value
# 
# def show_partial(name, *args):
#     """
#     Returns all partials registered under NAME.
#     This function should be used in templates (see jinja_show_partial).
# 
#     """
#     return "".join(map(str, [hook(*args) for _, hook in _HOOKS_PARTIALS[name]]))
# 
# Path: ob2/util/security.py
# def generate_csrf_token():
#     if "_csrf_token" not in session:
#         session["_csrf_token"] = generate_shitty_random_string()
#     return session["_csrf_token"]
# 
# Path: ob2/util/time.py
# def now_compare(start_date, end_date=None):
#     """
#     Given (start_date, end_date), return -1 if now() is before start_date
#                                   return  1 if now() is after end_date
#                                   return  0 if now() is between start_date and end_date inclusive.
# 
#     If end_date is ommitted, it takes the same value as start_date.
# 
#     """
#     if isinstance(start_date, basestring):
#         start_date = parse_time(start_date)
#     if end_date is None:
#         end_date = start_date
#     if isinstance(end_date, basestring):
#         end_date = parse_time(end_date)
#     current_date = now()
#     if current_date < start_date:
#         return -1
#     elif current_date <= end_date:
#         return 0
#     else:
#         return 1
# 
# def parse_to_relative(target, past_relative_cutoff=86400, future_relative_cutoff=-86400):
#     """
#     Expresses TARGET as it is relative to now(). If the target is more than Y seconds in the past
#     or more than Z seconds in the future, then express TARGET in an absolute way.
# 
#     """
#     if isinstance(target, basestring):
#         target = parse_time(target)
#     delta = now() - target
#     total_seconds = delta.total_seconds()
#     # Example: Jul 9 8:00PM
#     extended_date_format = "%b %-d %-I:%M%p"
#     if total_seconds < -6 * 30.5 * 86400 or total_seconds > 6 * 30.5 * 86400:
#         extended_date_format += " %Y"
#     if total_seconds > past_relative_cutoff or total_seconds < -abs(future_relative_cutoff):
#         return target.strftime(extended_date_format)
#     return delta_to_relative(total_seconds)


from ansi2html import Ansi2HTMLConverter
from binascii import b2a_base64
from markupsafe import Markup
from ob2.util.build_constants import (
    QUEUED,
    IN_PROGRESS,
    SUCCESS,
    FAILED,
    build_status_to_string,
)
from ob2.util.encoding import wrangle_to_unicode
from ob2.util.group_constants import (
    INVITED,
    ACCEPTED,
    REJECTED,
    invitation_status_to_string,
)
from ob2.util.hooks import apply_filters, show_partial
from ob2.util.security import generate_csrf_token
from ob2.util.time import now_compare, parse_to_relative
import ob2.config as config
        return ("grey", "Manual Grading")
    status = now_compare(begin, end)
    if status == 0:
        return ("green", "Enabled")
    elif status == -1:
        return ("purple", "Not yet enabled")
    else:
        return ("grey", "Disabled")


def participation_color(amount):
    if amount == 0.0:
        return "grey"
    elif amount < 0.4:
        return "red"
    elif amount < 0.75:
        return "amber"
    else:
        return "green"


def ansi_to_html(ansi_text):
    return Ansi2HTMLConverter(inline=True).convert(wrangle_to_unicode(ansi_text), full=False)


def jinja_show_partial(name, *args, **kwargs):
    return Markup(show_partial(name, *args, **kwargs))


JINJA_EXPORTS = {

# Path: ob2/util/build_constants.py
# QUEUED = -2
# 
# IN_PROGRESS = -1
# 
# SUCCESS = 0
# 
# FAILED = 1
# 
# def build_status_to_string(status, default='Unknown'):
#     return {QUEUED:      "Waiting in queue",
#             IN_PROGRESS: "In progress",
#             SUCCESS:     "Completed",
#             FAILED:      "Failed to complete"}.get(status, default)
# 
# Path: ob2/util/encoding.py
# def wrangle_to_unicode(text):
#     """
#     Converts some object to unicode text. Use the same decoding heuristic that's most commonly used
#     in other places.
# 
#     """
#     try:
#         text = str(text).decode("utf-8")
#     except UnicodeDecodeError:
#         text = str(text).decode("latin-1")
#     return text
# 
# Path: ob2/util/group_constants.py
# INVITED = 0
# 
# ACCEPTED = 1
# 
# REJECTED = 2
# 
# def invitation_status_to_string(status, default='Unknown'):
#     return {INVITED:  "invited",
#             ACCEPTED: "accepted",
#             REJECTED: "rejected"}.get(status, default)
# 
# Path: ob2/util/hooks.py
# def apply_filters(name, value, *args):
#     """
#     Applies all filters registered under NAME to VALUE.
# 
#     """
#     for _, hook in _HOOKS_FILTERS[name]:
#         value = hook(value, *args)
#     return value
# 
# def show_partial(name, *args):
#     """
#     Returns all partials registered under NAME.
#     This function should be used in templates (see jinja_show_partial).
# 
#     """
#     return "".join(map(str, [hook(*args) for _, hook in _HOOKS_PARTIALS[name]]))
# 
# Path: ob2/util/security.py
# def generate_csrf_token():
#     if "_csrf_token" not in session:
#         session["_csrf_token"] = generate_shitty_random_string()
#     return session["_csrf_token"]
# 
# Path: ob2/util/time.py
# def now_compare(start_date, end_date=None):
#     """
#     Given (start_date, end_date), return -1 if now() is before start_date
#                                   return  1 if now() is after end_date
#                                   return  0 if now() is between start_date and end_date inclusive.
# 
#     If end_date is ommitted, it takes the same value as start_date.
# 
#     """
#     if isinstance(start_date, basestring):
#         start_date = parse_time(start_date)
#     if end_date is None:
#         end_date = start_date
#     if isinstance(end_date, basestring):
#         end_date = parse_time(end_date)
#     current_date = now()
#     if current_date < start_date:
#         return -1
#     elif current_date <= end_date:
#         return 0
#     else:
#         return 1
# 
# def parse_to_relative(target, past_relative_cutoff=86400, future_relative_cutoff=-86400):
#     """
#     Expresses TARGET as it is relative to now(). If the target is more than Y seconds in the past
#     or more than Z seconds in the future, then express TARGET in an absolute way.
# 
#     """
#     if isinstance(target, basestring):
#         target = parse_time(target)
#     delta = now() - target
#     total_seconds = delta.total_seconds()
#     # Example: Jul 9 8:00PM
#     extended_date_format = "%b %-d %-I:%M%p"
#     if total_seconds < -6 * 30.5 * 86400 or total_seconds > 6 * 30.5 * 86400:
#         extended_date_format += " %Y"
#     if total_seconds > past_relative_cutoff or total_seconds < -abs(future_relative_cutoff):
#         return target.strftime(extended_date_format)
#     return delta_to_relative(total_seconds)


# Path: ob2/util/templating.py
from ansi2html import Ansi2HTMLConverter
from binascii import b2a_base64
from markupsafe import Markup
from ob2.util.build_constants import (
    QUEUED,
    IN_PROGRESS,
    SUCCESS,
    FAILED,
    build_status_to_string,
)
from ob2.util.encoding import wrangle_to_unicode
from ob2.util.group_constants import (
    INVITED,
    ACCEPTED,
    REJECTED,
    invitation_status_to_string,
)
from ob2.util.hooks import apply_filters, show_partial
from ob2.util.security import generate_csrf_token
from ob2.util.time import now_compare, parse_to_relative
import ob2.config as config

        return ("grey", "Manual Grading")
    status = now_compare(begin, end)
    if status == 0:
        return ("green", "Enabled")
    elif status == -1:
        return ("purple", "Not yet enabled")
    else:
        return ("grey", "Disabled")


def participation_color(amount):
    if amount == 0.0:
        return "grey"
    elif amount < 0.4:
        return "red"
    elif amount < 0.75:
        return "amber"
    else:
        return "green"


def ansi_to_html(ansi_text):
    return Ansi2HTMLConverter(inline=True).convert(wrangle_to_unicode(ansi_text), full=False)


def jinja_show_partial(name, *args, **kwargs):
    return Markup(show_partial(name, *args, **kwargs))


JINJA_EXPORTS = {

    "FAILED": FAILED,