<commit_before># *-* coding: utf-8 -*-

import re
import logging

from math import pow

from django import template
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _

from ...base.utils.dateutils import now, naturaldelta as onef_naturaldelta

from ..models.nonrel import Read

LOGGER = logging.getLogger(__name__)

register = template.Library()

# http://www.christianfaur.com/color/
# http://www.christianfaur.com/color/Site/Picking%20Colors.html
#
# And then: http://stackoverflow.com/q/3116260/654755
# http://ux.stackexchange.com/q/8297
letters_colors = {
    u'a': ((0, 0, 180), u'rgba(0, 0, 180, 1)', u'blue'),
    u'b': ((175, 13, 102), u'rgba(175, 13, 102, 1)', u'red-violet'),
    u'c': ((146, 248, 70), u'rgba(146, 248, 70, 1)', u'green-yellow'),
    u'd': ((255, 200, 47), u'rgba(255, 200, 47, 1)', u'yellow-orange'),
    u'e': ((255, 118, 0), u'rgba(255, 118, 0, 1)', u'orange'),
    u'f': ((185, 185, 185), u'rgba(185, 185, 185, 1)', u'light-gray'),
    u'g': ((235, 235, 222), u'rgba(235, 235, 222, 1)', u'off-white'),
    u'h': ((100, 100, 100), u'rgba(100, 100, 100, 1)', u'gray'),
    u'i': ((255, 255, 0), u'rgba(255, 255, 0, 1)', u'yellow'),
    u'j': ((55, 19, 112), u'rgba(55, 19, 112, 1)', u'dark-purple'),
    u'k': ((255, 255, 150), u'rgba(255, 255, 150, 1)', u'light-yellow'),
    u'l': ((202, 62, 94), u'rgba(202, 62, 94, 1)', u'dark-pink'),
    u'm': ((205, 145, 63), u'rgba(205, 145, 63, 1)', u'dark-orange'),
    u'n': ((12, 75, 100), u'rgba(12, 75, 100, 1)', u'teal'),
    u'o': ((255, 0, 0), u'rgba(255, 0, 0, 1)', u'red'),
    u'p': ((175, 155, 50), u'rgba(175, 155, 50, 1)', u'dark-yellow'),
    u'q': ((0, 0, 0), u'rgba(0, 0, 0, 1)', u'black'),
    u'r': ((37, 70, 25), u'rgba(37, 70, 25, 1)', u'dark-green'),
    u's': ((121, 33, 135), u'rgba(121, 33, 135, 1)', u'purple'),
    u't': ((83, 140, 208), u'rgba(83, 140, 208, 1)', u'light-blue'),
    u'u': ((0, 154, 37), u'rgba(0, 154, 37, 1)', u'green'),
    u'v': ((178, 220, 205), u'rgba(178, 220, 205, 1)', u'cyan'),
    u'w': ((255, 152, 213), u'rgba(255, 152, 213, 1)', u'pink'),
    u'x': ((0, 0, 74), u'rgba(0, 0, 74, 1)', u'dark blue'),
    u'y': ((175, 200, 74), u'rgba(175, 200, 74, 1)', u'olive-green'),
    u'z': ((63, 25, 12), u'rgba(63, 25, 12, 1)', u'red-brown'),
}

html_letters_re = re.compile(ur'[^\w]', re.UNICODE | re.IGNORECASE)

@register.filter
def naturaldelta(the_datetime):

    return onef_naturaldelta(now() - the_datetime)

@register.simple_tag
def feature_not_ready():

    return mark_safe(u' title="{0}" data-toggle="tooltip" '.format(
                     _(u'Feature coming soon. More information on the '
                       u'1flow blog http://blog.1flow.io/ or Twitter '
                       u'@1flow_io.')))

@register.simple_tag
def read_status_css(read):

    css = []

    for attr in Read.get_status_attributes():
        css.append(attr if getattr(read, attr) else (u'not_'+attr))

    return u' '.join(css)

@register.simple_tag
def reading_list_with_count(view_name, translation, css_classes=None):

    return mark_safe((
        u'{2}'
        u''
    ).format(
        reverse(view_name), css_classes or u'nowrap', translation))

@register.simple_tag
def feed_reading_list_with_count(view_name, subscription, attrname,
                                 translation, css_classes=None):

    # u'{3}'
    # u''

    count = getattr(subscription, attrname + '_articles_count')

    if count:
        return mark_safe((
            # last space at end of second line is needed.
            u'{3}'
            u' ({4}) '
        ).format(
            reverse(view_name, kwargs={'feed': subscription.id}),
            view_name, css_classes or u'nowrap', translation, count))

    return u''

@register.simple_tag
def read_action_toggle_url(read):

    any_key = Read.get_status_attributes()[0]
    url_base = reverse('toggle', kwargs={'klass': 'Read',
                       'oid': read.id, 'key': any_key}).replace(
                        any_key, u'@@KEY@@')

    return u'data-url-action-toggle={0}'.format(url_base)

@register.inclusion_tag('snippets/read/read-action.html')
def read_action(read, action_name, with_text=True, popover_direction=None):

    action_value = getattr(read, action_name)

    return {
        'with_text': with_text,
        'popover_direction' : popover_direction or 'top',
        'action_name': action_name,
        'action_data' : Read.status_data.get(action_name),
        'popover_class': '' if with_text else 'popover-tooltip',
        'do_start_hidden' : 'hide' if action_value else '',
        'undo_start_hidden' : '' if action_value else 'hide',
        'js_func': "toggle_status('{0}', '{1}')".format(
                   read.id, action_name)

    }

@register.inclusion_tag('snippets/read/read-action-status.html')
def read_action_status(read, action_name, with_text=False):

    return {
        'with_text': with_text,
        'action_name': action_name,
        'action_data' : Read.status_data.get(action_name),
        'status_hidden' : '' if getattr(read, action_name) else 'hide',
    }

@register.simple_tag
def html_first_letters(name, number=1):

    try:
        # Try to get the capitalized letters to make a nice name.
        capitalized = ''.join(c for c in name if c.isupper() or c.isdigit())

    except:
        # If that fails, just start with the full name.
        cleaned = html_letters_re.sub(u'', name)

    else:
        caplen = len(capitalized)

        # If it succeeded, make sure we have enough letters
        if caplen > 0:

            # If we don't have enough letters, take
            # what's left after the last capital.
            if caplen < number:
                capitalized += name[name.index(capitalized[-1]) + 1:]

            cleaned = html_letters_re.sub(u'', capitalized)

        else:
            cleaned = html_letters_re.sub(u'', name)

    if len(cleaned) == 0:
        number = 3
        cleaned   = u';-)'

    if number > len(cleaned):
        number = 1

    try:
        return cleaned[:number].title()

    except:
        # OMG… Unicode characters everywhere…
        return cleaned[:number]

@register.simple_tag
def html_background_color_for_name(name, opacity=1):

    name = html_letters_re.sub(u'', name)

    try:
        letter = name[0].lower()

    except:
        # OMG… Unicode characters everywhere…
        letter = u'a'

    try:
        return letters_colors[letter][1].replace(u', 1)',
                                                 u', {0})'.format(opacity))

    except:
        # Still, some unicode characters can
        # lower() but are not in the table.
        return letters_colors[u'a'][1].replace(u', 1)',
                                               u', {0})'.format(opacity))

@register.simple_tag
def html_foreground_color_for_name(name):
    """ TODO: pre-compute these values for our colors. """

    name = html_letters_re.sub(u'', name)

    try:
        letter = name[0].lower()

    except:
        # OMG… Unicode characters everywhere…
        letter = u'a'

    try:
        R, G, B = letters_colors[letter][0]

    except:
        # Still, some unicode characters can
        # lower() but are not in the table.
        R, G, B = letters_colors[u'a'][0]

    Y = (0.2126 * pow(R / 255, 2.2)
         + 0.7151 * pow(G / 255, 2.2)
         + 0.0721 * pow(B / 255, 2.2))

    return u'white' if Y <= 0.18 else u'black'
<commit_msg>Make 'F' & 'G' colors more visible in our color scheme.<commit_after># *-* coding: utf-8 -*-

import re
import logging

from math import pow

from django import template
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _

from ...base.utils.dateutils import now, naturaldelta as onef_naturaldelta

from ..models.nonrel import Read

LOGGER = logging.getLogger(__name__)

register = template.Library()

# http://www.christianfaur.com/color/
# http://www.christianfaur.com/color/Site/Picking%20Colors.html
#
# And then: http://stackoverflow.com/q/3116260/654755
# http://ux.stackexchange.com/q/8297
letters_colors = {
    u'a': ((0, 0, 180), u'rgba(0, 0, 180, 1)', u'blue'),
    u'b': ((175, 13, 102), u'rgba(175, 13, 102, 1)', u'red-violet'),
    u'c': ((146, 248, 70), u'rgba(146, 248, 70, 1)', u'green-yellow'),
    u'd': ((255, 200, 47), u'rgba(255, 200, 47, 1)', u'yellow-orange'),
    u'e': ((255, 118, 0), u'rgba(255, 118, 0, 1)', u'orange'),

    # Original f & g, not used because grey means "disabled"
    # and G is not visible enough when opacity < 1.
    #
    #    u'f': ((185, 185, 185), u'rgba(185, 185, 185, 1)', u'light-gray'),
    #    u'g': ((235, 235, 222), u'rgba(235, 235, 222, 1)', u'off-white'),
    #
    # Instead, we use w & y colors, which are the most near on the graph.

    u'f': ((255, 152, 213), u'rgba(255, 152, 213, 1)', u'pink'),
    u'g': ((175, 200, 74), u'rgba(175, 200, 74, 1)', u'olive-green'),
    u'h': ((100, 100, 100), u'rgba(100, 100, 100, 1)', u'gray'),
    u'i': ((255, 255, 0), u'rgba(255, 255, 0, 1)', u'yellow'),
    u'j': ((55, 19, 112), u'rgba(55, 19, 112, 1)', u'dark-purple'),
    u'k': ((255, 255, 150), u'rgba(255, 255, 150, 1)', u'light-yellow'),
    u'l': ((202, 62, 94), u'rgba(202, 62, 94, 1)', u'dark-pink'),
    u'm': ((205, 145, 63), u'rgba(205, 145, 63, 1)', u'dark-orange'),
    u'n': ((12, 75, 100), u'rgba(12, 75, 100, 1)', u'teal'),
    u'o': ((255, 0, 0), u'rgba(255, 0, 0, 1)', u'red'),
    u'p': ((175, 155, 50), u'rgba(175, 155, 50, 1)', u'dark-yellow'),
    u'q': ((0, 0, 0), u'rgba(0, 0, 0, 1)', u'black'),
    u'r': ((37, 70, 25), u'rgba(37, 70, 25, 1)', u'dark-green'),
    u's': ((121, 33, 135), u'rgba(121, 33, 135, 1)', u'purple'),
    u't': ((83, 140, 208), u'rgba(83, 140, 208, 1)', u'light-blue'),
    u'u': ((0, 154, 37), u'rgba(0, 154, 37, 1)', u'green'),
    u'v': ((178, 220, 205), u'rgba(178, 220, 205, 1)', u'cyan'),
    u'w': ((255, 152, 213), u'rgba(255, 152, 213, 1)', u'pink'),
    u'x': ((0, 0, 74), u'rgba(0, 0, 74, 1)', u'dark blue'),
    u'y': ((175, 200, 74), u'rgba(175, 200, 74, 1)', u'olive-green'),
    u'z': ((63, 25, 12), u'rgba(63, 25, 12, 1)', u'red-brown'),
}

html_letters_re = re.compile(ur'[^\w]', re.UNICODE | re.IGNORECASE)

@register.filter
def naturaldelta(the_datetime):

    return onef_naturaldelta(now() - the_datetime)

@register.simple_tag
def feature_not_ready():

    return mark_safe(u' title="{0}" data-toggle="tooltip" '.format(
                     _(u'Feature coming soon. More information on the '
                       u'1flow blog http://blog.1flow.io/ or Twitter '
                       u'@1flow_io.')))

@register.simple_tag
def read_status_css(read):

    css = []

    for attr in Read.get_status_attributes():
        css.append(attr if getattr(read, attr) else (u'not_'+attr))

    return u' '.join(css)

@register.simple_tag
def reading_list_with_count(view_name, translation, css_classes=None):

    return mark_safe((
        u'{2}'
        u''
    ).format(
        reverse(view_name), css_classes or u'nowrap', translation))

@register.simple_tag
def feed_reading_list_with_count(view_name, subscription, attrname,
                                 translation, css_classes=None):

    # u'{3}'
    # u''

    count = getattr(subscription, attrname + '_articles_count')

    if count:
        return mark_safe((
            # last space at end of second line is needed.
            u'{3}'
            u' ({4}) '
        ).format(
            reverse(view_name, kwargs={'feed': subscription.id}),
            view_name, css_classes or u'nowrap', translation, count))

    return u''

@register.simple_tag
def read_action_toggle_url(read):

    any_key = Read.get_status_attributes()[0]
    url_base = reverse('toggle', kwargs={'klass': 'Read',
                       'oid': read.id, 'key': any_key}).replace(
                        any_key, u'@@KEY@@')

    return u'data-url-action-toggle={0}'.format(url_base)

@register.inclusion_tag('snippets/read/read-action.html')
def read_action(read, action_name, with_text=True, popover_direction=None):

    action_value = getattr(read, action_name)

    return {
        'with_text': with_text,
        'popover_direction' : popover_direction or 'top',
        'action_name': action_name,
        'action_data' : Read.status_data.get(action_name),
        'popover_class': '' if with_text else 'popover-tooltip',
        'do_start_hidden' : 'hide' if action_value else '',
        'undo_start_hidden' : '' if action_value else 'hide',
        'js_func': "toggle_status('{0}', '{1}')".format(
                   read.id, action_name)

    }

@register.inclusion_tag('snippets/read/read-action-status.html')
def read_action_status(read, action_name, with_text=False):

    return {
        'with_text': with_text,
        'action_name': action_name,
        'action_data' : Read.status_data.get(action_name),
        'status_hidden' : '' if getattr(read, action_name) else 'hide',
    }

@register.simple_tag
def html_first_letters(name, number=1):

    try:
        # Try to get the capitalized letters to make a nice name.
        capitalized = ''.join(c for c in name if c.isupper() or c.isdigit())

    except:
        # If that fails, just start with the full name.
        cleaned = html_letters_re.sub(u'', name)

    else:
        caplen = len(capitalized)

        # If it succeeded, make sure we have enough letters
        if caplen > 0:

            # If we don't have enough letters, take
            # what's left after the last capital.
            if caplen < number:
                capitalized += name[name.index(capitalized[-1]) + 1:]

            cleaned = html_letters_re.sub(u'', capitalized)

        else:
            cleaned = html_letters_re.sub(u'', name)

    if len(cleaned) == 0:
        number = 3
        cleaned   = u';-)'

    if number > len(cleaned):
        number = 1

    try:
        return cleaned[:number].title()

    except:
        # OMG… Unicode characters everywhere…
        return cleaned[:number]

@register.simple_tag
def html_background_color_for_name(name, opacity=1):

    name = html_letters_re.sub(u'', name)

    try:
        letter = name[0].lower()

    except:
        # OMG… Unicode characters everywhere…
        letter = u'a'

    try:
        return letters_colors[letter][1].replace(u', 1)',
                                                 u', {0})'.format(opacity))

    except:
        # Still, some unicode characters can
        # lower() but are not in the table.
        return letters_colors[u'a'][1].replace(u', 1)',
                                               u', {0})'.format(opacity))

@register.simple_tag
def html_foreground_color_for_name(name):
    """ TODO: pre-compute these values for our colors. """

    name = html_letters_re.sub(u'', name)

    try:
        letter = name[0].lower()

    except:
        # OMG… Unicode characters everywhere…
        letter = u'a'

    try:
        R, G, B = letters_colors[letter][0]

    except:
        # Still, some unicode characters can
        # lower() but are not in the table.
        R, G, B = letters_colors[u'a'][0]

    Y = (0.2126 * pow(R / 255, 2.2)
         + 0.7151 * pow(G / 255, 2.2)
         + 0.0721 * pow(B / 255, 2.2))

    return u'white' if Y <= 0.18 else u'black'
<|endoftext|>


<commit_before>import re
from os import walk
from functools import partial
from collections import namedtuple

from django.template.loaders.filesystem import Loader as FSLoader
from django.conf import settings

fs_loader = FSLoader()

FILENAME_RE = re.compile("""['\\"](?P<fname>[^'"]+)""")
EXTEND_RE = re.compile('\{\%\s*extends.+\%\}')
INCLUDE_RE = re.compile('\{\%\s*include.+\%\}')

INCLUDE_TAG = 'include'
EXTEND_TAG = 'extends'

PATTERNS = {
    INCLUDE_TAG: INCLUDE_RE,
    EXTEND_TAG: EXTEND_RE,
}

TemplateLine = namedtuple('TemplateLine', 'source target line_number tag_type')

def filter_line(patterns, line):
    for tag, pattern in patterns.items():
        if bool(pattern.search(line)):
            return tag, line
    return None, None

def path_walker(path):
    for base, _, filenames in walk(path):
        for filename in filenames:
            yield '/'.join((base, filename))

def line_reader(filename):
    try:
        with open(filename) as f:
            for line in f:
                yield line.strip()
    except IOError:
        yield ''

def filter_lines_in_path_by_patterns(path, patterns):
    filter_line_by_patterns = partial(filter_line, patterns)
    for filename in path_walker(path):
        for line_number, line in enumerate(line_reader(filename)):
            tag, line = filter_line_by_patterns(line)
            if line is not None:
                yield filename, line_number, tag, line

def find_targets(line):
    # TODO: Just uses FSLoader for now. Should also use app directories at least
    target_search = FILENAME_RE.search(line)
    if target_search is None:
        return ()
    else:
        try:
            target_value = target_search.groups()[0]
        except IndexError:
            return ()
        else:
            return fs_loader.get_template_sources(target_value)

def stream_template_assocs(template_dirs, patterns):
    for path in template_dirs:
        filtered_lines = filter_lines_in_path_by_patterns(path, patterns)
        for source, line_number, tag_type, line in filtered_lines:
            for target in find_targets(line):
                yield TemplateLine(source=source, target=target,
                    tag_type=tag_type, line_number=line_number)

"""
Top level generator that other modules should import and use directly
"""
get_template_line_stream = partial(
    stream_template_assocs, settings.TEMPLATE_DIRS, PATTERNS)

if __name__ == '__main__':
    for data in get_template_line_stream():
        print data
<commit_msg>First pass - Adds app dir loader in line_stream<commit_after>import re
from os import walk
from os.path import exists as path_exists
from functools import partial
from collections import namedtuple

from django.template.loaders.filesystem import Loader as FSLoader
from django.template.loaders.app_directories import Loader as AppLoader
from django.template.loaders.app_directories import app_template_dirs
from django.conf import settings

def get_template_loaders_dirs():
    loader_configs = settings.TEMPLATE_LOADERS
    dirs = ()
    loaders = []
    if 'django.template.loaders.filesystem.Loader' in loader_configs:
        dirs += settings.TEMPLATE_DIRS
        loaders.append(FSLoader())
    if 'django.template.loaders.app_directories.Loader' in loader_configs:
        dirs += app_template_dirs
        loaders.append(AppLoader())
    return loaders, dirs

TLOADERS, TDIRS = get_template_loaders_dirs()

FILENAME_RE = re.compile("""['\\"](?P<fname>[^'"]+)""")
EXTEND_RE = re.compile('\{\%\s*extends.+\%\}')
INCLUDE_RE = re.compile('\{\%\s*include.+\%\}')

INCLUDE_TAG = 'include'
EXTEND_TAG = 'extends'

PATTERNS = {
    INCLUDE_TAG: INCLUDE_RE,
    EXTEND_TAG: EXTEND_RE,
}

TemplateLine = namedtuple('TemplateLine', 'source target line_number tag_type')

def filter_line(patterns, line):
    for tag, pattern in patterns.items():
        if bool(pattern.search(line)):
            return tag, line
    return None, None

def path_walker(path):
    for base, _, filenames in walk(path):
        for filename in filenames:
            yield '/'.join((base, filename))

def line_reader(filename):
    try:
        with open(filename) as f:
            for line in f:
                yield line.strip()
    except IOError:
        yield ''

def filter_lines_in_path_by_patterns(path, patterns):
    filter_line_by_patterns = partial(filter_line, patterns)
    for filename in path_walker(path):
        for line_number, line in enumerate(line_reader(filename)):
            tag, line = filter_line_by_patterns(line)
            if line is not None:
                yield filename, line_number, tag, line

def find_targets(line):
    # TODO: Just uses FSLoader for now. Should also use app directories at least
    target_search = FILENAME_RE.search(line)
    if target_search is None:
        return None
    else:
        try:
            target_value = target_search.groups()[0]
        except IndexError:
            return None
        for loader in TLOADERS:
            fns = loader.get_template_sources(target_value)
            for fn in fns:
                if path_exists(fn):
                    return fn

def stream_template_assocs(template_dirs, patterns):
    for path in template_dirs:
        filtered_lines = filter_lines_in_path_by_patterns(path, patterns)
        for source, line_number, tag_type, line in filtered_lines:
            target = find_targets(line)
            if target is not None:
                yield TemplateLine(source=source, target=target,
                    tag_type=tag_type, line_number=line_number)

"""
Top level generator that other modules should import and use directly
"""
get_template_line_stream = partial(
    stream_template_assocs, TDIRS, PATTERNS)

if __name__ == '__main__':
    for data in get_template_line_stream():
        print data
<|endoftext|>


<commit_before># Python Version: 3.x
name = 'online-judge-tools'
__author__  = 'Kimiyuki Onaka'
__email__ = 'kimiyuki95@gmail.com'
__license__ = 'MIT License'
__url__ = 'https://github.com/kmyk/online-judge-tools'
__version_info__ = ( 0, 1, 39, 'final', 0 )
__version__ = '.'.join(map(str, __version_info__[: 3]))
<commit_msg>RELEASE: 0.1.40<commit_after># Python Version: 3.x
name = 'online-judge-tools'
__author__  = 'Kimiyuki Onaka'
__email__ = 'kimiyuki95@gmail.com'
__license__ = 'MIT License'
__url__ = 'https://github.com/kmyk/online-judge-tools'
__version_info__ = ( 0, 1, 40, 'final', 0 )
__version__ = '.'.join(map(str, __version_info__[: 3]))
<|endoftext|>


<commit_before>import logging
import os
import re

import bleach
import markdown as markdown_library

from django import template
from django.conf import settings
from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.urlresolvers import reverse, NoReverseMatch
from django.template.loader_tags import do_include
from django.utils.safestring import mark_safe

from common.utils import full_url as full_url_method
from private_sharing.models import app_label_to_verbose_name_including_dynamic

logger = logging.getLogger(__name__)

register = template.Library()

@register.filter
def source_to_name(source):
    """
    Given 'go_viral', return 'GoViral'
    """
    try:
        return app_label_to_verbose_name_including_dynamic(source)
    except:  # pylint: disable=bare-except
        return source

@register.filter
def lookup(dictionary, key):
    """
    Get a dictionary value by key within a template.
    """
    return dictionary.get(key)

class TryIncludeNode(template.Node):
    """
    A Node that instantiates an IncludeNode but wraps its render() in a
    try/except in case the template doesn't exist.
    """
    def __init__(self, parser, token):
        self.include_node = do_include(parser, token)

    def render(self, context):
        try:
            return self.include_node.render(context)
        except template.TemplateDoesNotExist:
            return ''

@register.tag
def try_include(parser, token):
    """
    Include the specified template but only if it exists.
    """
    return TryIncludeNode(parser, token)

@register.filter
def markdown(value):
    """
    Translate markdown to a safe subset of HTML.
    """
    cleaned = bleach.clean(markdown_library.markdown(value),
                           tags=bleach.ALLOWED_TAGS +
                           ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'])

    linkified = bleach.linkify(cleaned)

    return mark_safe(linkified)

@register.simple_tag(takes_context=True)
def next_page(context):
    """
    Get the next page for signup or login.

    The query string takes priority over the template variable and the default
    is an empty string.
    """
    if 'next' in context.request.GET:
        return context.request.GET['next']

    if 'next' in context.request.POST:
        return context.request.POST['next']

    if 'next' in context:
        return context['next']

    return ''

def slugify_url(url):
    """
    Turn '/study/connect_me/' into 'study-connect-me'.
    """
    return (url
            .lower()
            .strip('/')
            .replace(':', '-')
            .replace('/', '-')
            .replace('_', '-'))

def script_if_exists(slug):
    """
    Return a script tag if the given slug path exists.
    """
    # don't try to add scripts with unicode characters
    try:
        slug.decode('ascii')
    except UnicodeDecodeError:
        return

    fs_path = os.path.join(settings.BASE_DIR,
                           'build/js/{}.js'.format(slug))

    if os.path.exists(fs_path):
        return ''.format(
            settings.STATIC_URL, slug)

@register.simple_tag(takes_context=True)
def page_bundle(context):
    """
    Get the bundle path for a given page, first trying the view name and then
    the URL slug.
    """
    # for example, /study/connect/abc/ has a view_name of studies:connect
    try:
        name = slugify_url(context.request.resolver_match.view_name)
    except AttributeError:
        name = '404'

    script = script_if_exists(name)

    if script:
        return mark_safe(script)

    path = slugify_url(context.request.path)
    script = script_if_exists(path)

    if script:
        return mark_safe(script)

    if settings.DEBUG:
        return mark_safe(''
                         .format(name, path))

    return ''

@register.simple_tag(takes_context=True)
def page_body_id(context):
    """
    Get the CSS class for a given page.
    """
    path = slugify_url(context.request.path)

    if not path:
        path = 'home'

    return 'page-{}'.format(path)

@register.simple_tag(takes_context=True)
def page_body_class(context):
    """
    Get the CSS class for a given resolved URL.
    """
    try:
        return 'url-{}'.format(context.request.resolver_match.url_name)
    except AttributeError:
        return '404'

@register.simple_tag(takes_context=True)
def active(context, pattern_or_urlname):
    """
    Return 'active' if the given URL or pattern is active.
    """
    try:
        pattern = '^' + reverse(pattern_or_urlname)
    except NoReverseMatch:
        pattern = pattern_or_urlname

    path = context.request.path

    if re.search(pattern, path):
        return 'active'

    return ''

@register.simple_tag()
def badge(badge_object):
    """
    Return HTML for a badge.
    """
    if not (badge_object['url'].startswith('/') or
            badge_object['url'].startswith('http')):
        badge_object['static_url'] = static(badge_object['url'])
    else:
        badge_object['static_url'] = badge_object['url']

    if badge_object['url'] == 'direct-sharing/images/badge.png':
        return mark_safe(
            """

{name}

""".format(**badge_object))

    return mark_safe(
        ''
        .format(**badge_object))

@register.filter
def join_and(value):
    """
    Given a list of strings, format them with commas and spaces, but
    with 'and' at the end.

    >>> join_and(['apples', 'oranges', 'pears'])
    "apples, oranges, and pears"
    """
    # convert numbers to strings
    value = [str(item) for item in value]

    if len(value) == 1:
        return value[0]

    if len(value) == 2:
        return '{} and {}'.format(value[0], value[1])

    # join all but the last element
    all_but_last = ', '.join(value[:-1])
    return '{}, and {}'.format(all_but_last, value[-1])

@register.filter
def full_url(value):
    return full_url_method(value)

@register.filter
def add_string(a, b):
    """
    Like `add` but coerces to strings instead of integers.
    """
    return str(a) + str(b)
<commit_msg>🔧 catch both classes of Unicode exception<commit_after>import logging
import os
import re

import bleach
import markdown as markdown_library

from django import template
from django.conf import settings
from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.urlresolvers import reverse, NoReverseMatch
from django.template.loader_tags import do_include
from django.utils.safestring import mark_safe

from common.utils import full_url as full_url_method
from private_sharing.models import app_label_to_verbose_name_including_dynamic

logger = logging.getLogger(__name__)

register = template.Library()

@register.filter
def source_to_name(source):
    """
    Given 'go_viral', return 'GoViral'
    """
    try:
        return app_label_to_verbose_name_including_dynamic(source)
    except:  # pylint: disable=bare-except
        return source

@register.filter
def lookup(dictionary, key):
    """
    Get a dictionary value by key within a template.
    """
    return dictionary.get(key)

class TryIncludeNode(template.Node):
    """
    A Node that instantiates an IncludeNode but wraps its render() in a
    try/except in case the template doesn't exist.
    """
    def __init__(self, parser, token):
        self.include_node = do_include(parser, token)

    def render(self, context):
        try:
            return self.include_node.render(context)
        except template.TemplateDoesNotExist:
            return ''

@register.tag
def try_include(parser, token):
    """
    Include the specified template but only if it exists.
    """
    return TryIncludeNode(parser, token)

@register.filter
def markdown(value):
    """
    Translate markdown to a safe subset of HTML.
    """
    cleaned = bleach.clean(markdown_library.markdown(value),
                           tags=bleach.ALLOWED_TAGS +
                           ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'])

    linkified = bleach.linkify(cleaned)

    return mark_safe(linkified)

@register.simple_tag(takes_context=True)
def next_page(context):
    """
    Get the next page for signup or login.

    The query string takes priority over the template variable and the default
    is an empty string.
    """
    if 'next' in context.request.GET:
        return context.request.GET['next']

    if 'next' in context.request.POST:
        return context.request.POST['next']

    if 'next' in context:
        return context['next']

    return ''

def slugify_url(url):
    """
    Turn '/study/connect_me/' into 'study-connect-me'.
    """
    return (url
            .lower()
            .strip('/')
            .replace(':', '-')
            .replace('/', '-')
            .replace('_', '-'))

def script_if_exists(slug):
    """
    Return a script tag if the given slug path exists.
    """
    # don't try to add scripts with unicode characters
    try:
        slug.decode('ascii')
    except (UnicodeDecodeError, UnicodeEncodeError):
        return

    fs_path = os.path.join(settings.BASE_DIR,
                           'build/js/{}.js'.format(slug))

    if os.path.exists(fs_path):
        return ''.format(
            settings.STATIC_URL, slug)

@register.simple_tag(takes_context=True)
def page_bundle(context):
    """
    Get the bundle path for a given page, first trying the view name and then
    the URL slug.
    """
    # for example, /study/connect/abc/ has a view_name of studies:connect
    try:
        name = slugify_url(context.request.resolver_match.view_name)
    except AttributeError:
        name = '404'

    script = script_if_exists(name)

    if script:
        return mark_safe(script)

    path = slugify_url(context.request.path)
    script = script_if_exists(path)

    if script:
        return mark_safe(script)

    if settings.DEBUG:
        return mark_safe(''
                         .format(name, path))

    return ''

@register.simple_tag(takes_context=True)
def page_body_id(context):
    """
    Get the CSS class for a given page.
    """
    path = slugify_url(context.request.path)

    if not path:
        path = 'home'

    return 'page-{}'.format(path)

@register.simple_tag(takes_context=True)
def page_body_class(context):
    """
    Get the CSS class for a given resolved URL.
    """
    try:
        return 'url-{}'.format(context.request.resolver_match.url_name)
    except AttributeError:
        return '404'

@register.simple_tag(takes_context=True)
def active(context, pattern_or_urlname):
    """
    Return 'active' if the given URL or pattern is active.
    """
    try:
        pattern = '^' + reverse(pattern_or_urlname)
    except NoReverseMatch:
        pattern = pattern_or_urlname

    path = context.request.path

    if re.search(pattern, path):
        return 'active'

    return ''

@register.simple_tag()
def badge(badge_object):
    """
    Return HTML for a badge.
    """
    if not (badge_object['url'].startswith('/') or
            badge_object['url'].startswith('http')):
        badge_object['static_url'] = static(badge_object['url'])
    else:
        badge_object['static_url'] = badge_object['url']

    if badge_object['url'] == 'direct-sharing/images/badge.png':
        return mark_safe(
            """

{name}

""".format(**badge_object))

    return mark_safe(
        ''
        .format(**badge_object))

@register.filter
def join_and(value):
    """
    Given a list of strings, format them with commas and spaces, but
    with 'and' at the end.

    >>> join_and(['apples', 'oranges', 'pears'])
    "apples, oranges, and pears"
    """
    # convert numbers to strings
    value = [str(item) for item in value]

    if len(value) == 1:
        return value[0]

    if len(value) == 2:
        return '{} and {}'.format(value[0], value[1])

    # join all but the last element
    all_but_last = ', '.join(value[:-1])
    return '{}, and {}'.format(all_but_last, value[-1])

@register.filter
def full_url(value):
    return full_url_method(value)

@register.filter
def add_string(a, b):
    """
    Like `add` but coerces to strings instead of integers.
    """
    return str(a) + str(b)
<|endoftext|>


<commit_before>import uuid

from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _

from persons.models import Person
from competences.models import Competence
from modules.models import Module
from disciplines.models import Discipline

class LearningPlan(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    uni_displayableTitle = models.CharField(_("Версия"), max_length=32, blank=True, null=True)
    uni_number = models.CharField(_("Номер УП"), max_length=32, blank=True, null=True)
    uni_active = models.CharField(_("Текущая версия"), max_length=32, blank=True, null=True)
    uni_title = models.CharField(_("Название"), max_length=32, blank=True, null=True)
    uni_stage = models.BooleanField(_("План утверждён"), default=True)
    uni_loadTimeType = models.CharField(_("Единица измерения нагрузки"), max_length=32, blank=True, null=True)
    uni_html = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.uni_number

    class Meta:
        verbose_name = 'учебный план'
        verbose_name_plural = 'учебные планы'

class Program(ObjectBaseClass):

    LEVELS = (
        ("b", _("бакалавриат")),
        ("m", _("магистратура")),
        ("s", _("специалитет")),
    )

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    level = models.CharField(_("Уровень программы"), max_length=1, choices=LEVELS, default="b")
    title = models.CharField(_('Наименование образовательной программы'), blank=False, max_length=256, default=_(''))
    training_direction = models.CharField(_("Направление подготовки"), blank=False, max_length=256, default=_(''))
    competences = models.ManyToManyField(Competence, blank=True)
    chief = models.ForeignKey(Person, verbose_name=_('Руководитель образовательной программы'), blank=True, null=True)
    learning_plans = models.ManyToManyField("LearningPlan", blank=True)

    class Meta:
        verbose_name = 'программа'
        verbose_name_plural = 'программы'

    def __str__(self):
        return self.title

    def get_choice_groups(self):
        return [choice_group.id for choice_group in ChoiceGroup.objects.filter(program__id=self.id)]

    def get_modules(self):
        return

class TrainingTarget(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование образовательной цели'), blank=False, max_length=256, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Порядковый номер цели"))

    class Meta:
        verbose_name = 'образовательная цель'
        verbose_name_plural = 'образовательные цели'

    def __str__(self):
        return self.title

class ProgramCompetence(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование компетенции'), blank=False, max_length=2048, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Номер компетенции"))

    class Meta:
        verbose_name = 'компетенция программы'
        verbose_name_plural = 'компетенции программы'

    def __str__(self):
        return self.title

class ProgramModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    module = models.ForeignKey("modules.Module")
    choice_group = models.ForeignKey("ChoiceGroup", blank=True, null=True)
    competence = models.ForeignKey(ProgramCompetence, blank=True, null=True)
    semester = models.PositiveIntegerField(blank=True, null=True)

    class Meta:
        verbose_name = 'модуль программы'
        verbose_name_plural = 'модули программы'

    def get_competence_display(self):
        return str(self.competence)

    def get_weight(self):
        try:
            weight = max([int(ds["period"]) for ds in
                          Discipline.objects.filter(pk__in=self.module.get_all_discipline_ids()).values(
                              "period")]) + self.semester
        except:
            weight = self.semester

        try:
            return int(weight) * 100
        except:
            return 100

    def get_target_positions(self):

        training_targets = TrainingTarget.objects.filter(program=self.program, ).order_by('number')
        target_modules = TargetModules.objects.filter(target__in=training_targets, program_module=self)
        print(target_modules)
        targets_positions = []
        # for tr_target in TrainingTarget.objects.filter(program=self.program, ).order_by('number'):
        #     tms = TargetModules.objects.filter(target=tr_target, status="p", archived=False).values_list("choice_group", flat=True)
        #     print(tms)
        #
        #     for target_module in tms:
        #         print(target_module)
        #         if target_module:
        #             if target_module is False:
        #                 targets_positions.append(1)
        #             elif target_module is True:
        #                 targets_positions.append(2)
        #         else:
        #             targets_positions.append(0)
        #
        # # except:
        # #     pass
        return targets_positions

class TargetModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    target = models.ForeignKey("TrainingTarget")
    program_module = models.ForeignKey("ProgramModules")
    choice_group = models.BooleanField(default=False)

    class Meta:
        verbose_name = 'модуль цели'
        verbose_name_plural = 'модули цели'

class ChoiceGroup(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    title = models.CharField(_('Наименование группы выбора'), blank=False, max_length=2048, default=_(''))
    labor = models.IntegerField(_("Трудоёмкость группы"), default=3)
    choice_group_type = models.ForeignKey("ChoiceGroupType")
    number = models.IntegerField(_("Номер группы выбора"))

    class Meta:
        verbose_name = 'группа выбора'
        verbose_name_plural = 'группы выбора'

    def __str__(self):
        return self.title

    def get_choice_group_type_display(self):
        return self.choice_group_type.title

    def get_program_modules(self):
        return [program_module.id for program_module in ProgramModules.objects.filter(program=self.program, choice_group=self, status="p", archived=False)]

class ChoiceGroupType(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование типы группы выбора'), blank=False, max_length=2048, default=_(''))

    class Meta:
        verbose_name = 'тип группы выбора'
        verbose_name_plural = 'типы группы выбора'

    def __str__(self):
        return self.title
<commit_msg>targets optimize#24<commit_after>import uuid

from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _

from persons.models import Person
from competences.models import Competence
from modules.models import Module
from disciplines.models import Discipline

class LearningPlan(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    uni_displayableTitle = models.CharField(_("Версия"), max_length=32, blank=True, null=True)
    uni_number = models.CharField(_("Номер УП"), max_length=32, blank=True, null=True)
    uni_active = models.CharField(_("Текущая версия"), max_length=32, blank=True, null=True)
    uni_title = models.CharField(_("Название"), max_length=32, blank=True, null=True)
    uni_stage = models.BooleanField(_("План утверждён"), default=True)
    uni_loadTimeType = models.CharField(_("Единица измерения нагрузки"), max_length=32, blank=True, null=True)
    uni_html = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.uni_number

    class Meta:
        verbose_name = 'учебный план'
        verbose_name_plural = 'учебные планы'

class Program(ObjectBaseClass):

    LEVELS = (
        ("b", _("бакалавриат")),
        ("m", _("магистратура")),
        ("s", _("специалитет")),
    )

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    level = models.CharField(_("Уровень программы"), max_length=1, choices=LEVELS, default="b")
    title = models.CharField(_('Наименование образовательной программы'), blank=False, max_length=256, default=_(''))
    training_direction = models.CharField(_("Направление подготовки"), blank=False, max_length=256, default=_(''))
    competences = models.ManyToManyField(Competence, blank=True)
    chief = models.ForeignKey(Person, verbose_name=_('Руководитель образовательной программы'), blank=True, null=True)
    learning_plans = models.ManyToManyField("LearningPlan", blank=True)

    class Meta:
        verbose_name = 'программа'
        verbose_name_plural = 'программы'

    def __str__(self):
        return self.title

    def get_choice_groups(self):
        return [choice_group.id for choice_group in ChoiceGroup.objects.filter(program__id=self.id)]

    def get_modules(self):
        return

class TrainingTarget(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование образовательной цели'), blank=False, max_length=256, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Порядковый номер цели"))

    class Meta:
        verbose_name = 'образовательная цель'
        verbose_name_plural = 'образовательные цели'

    def __str__(self):
        return self.title

class ProgramCompetence(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование компетенции'), blank=False, max_length=2048, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Номер компетенции"))

    class Meta:
        verbose_name = 'компетенция программы'
        verbose_name_plural = 'компетенции программы'

    def __str__(self):
        return self.title

class ProgramModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    module = models.ForeignKey("modules.Module")
    choice_group = models.ForeignKey("ChoiceGroup", blank=True, null=True)
    competence = models.ForeignKey(ProgramCompetence, blank=True, null=True)
    semester = models.PositiveIntegerField(blank=True, null=True)

    class Meta:
        verbose_name = 'модуль программы'
        verbose_name_plural = 'модули программы'

    def get_competence_display(self):
        return str(self.competence)

    def get_weight(self):
        try:
            weight = max([int(ds["period"]) for ds in
                          Discipline.objects.filter(pk__in=self.module.get_all_discipline_ids()).values(
                              "period")]) + self.semester
        except:
            weight = self.semester

        try:
            return int(weight) * 100
        except:
            return 100

    def get_target_positions(self):

        training_targets = TrainingTarget.objects.filter(program=self.program, ).order_by('number')
        target_modules = TargetModules.objects.filter(target__in=training_targets, program_module=self).values_list("choice_group", flat=True)
        print(target_modules)
        targets_positions = []
        # for tr_target in TrainingTarget.objects.filter(program=self.program, ).order_by('number'):
        #     tms = TargetModules.objects.filter(target=tr_target, status="p", archived=False).values_list("choice_group", flat=True)
        #     print(tms)
        #
        #     for target_module in tms:
        #         print(target_module)
        #         if target_module:
        #             if target_module is False:
        #                 targets_positions.append(1)
        #             elif target_module is True:
        #                 targets_positions.append(2)
        #         else:
        #             targets_positions.append(0)
        #
        # # except:
        # #     pass
        return targets_positions

class TargetModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    target = models.ForeignKey("TrainingTarget")
    program_module = models.ForeignKey("ProgramModules")
    choice_group = models.BooleanField(default=False)

    class Meta:
        verbose_name = 'модуль цели'
        verbose_name_plural = 'модули цели'

class ChoiceGroup(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    title = models.CharField(_('Наименование группы выбора'), blank=False, max_length=2048, default=_(''))
    labor = models.IntegerField(_("Трудоёмкость группы"), default=3)
    choice_group_type = models.ForeignKey("ChoiceGroupType")
    number = models.IntegerField(_("Номер группы выбора"))

    class Meta:
        verbose_name = 'группа выбора'
        verbose_name_plural = 'группы выбора'

    def __str__(self):
        return self.title

    def get_choice_group_type_display(self):
        return self.choice_group_type.title

    def get_program_modules(self):
        return [program_module.id for program_module in ProgramModules.objects.filter(program=self.program, choice_group=self, status="p", archived=False)]

class ChoiceGroupType(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование типы группы выбора'), blank=False, max_length=2048, default=_(''))

    class Meta:
        verbose_name = 'тип группы выбора'
        verbose_name_plural = 'типы группы выбора'

    def __str__(self):
        return self.title
<|endoftext|>


<commit_before>import uuid
from os import urandom
import hashlib
from jsonfield import JSONField

from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from django.conf import settings

from persons.models import Person
from competences.models import Competence
from modules.models import Module
from disciplines.models import Discipline

class LearningPlan(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    uni_displayableTitle = models.CharField(_("Версия"), max_length=32, blank=True, null=True)
    uni_number = models.CharField(_("Номер УП"), max_length=32, blank=True, null=True)
    uni_active = models.CharField(_("Текущая версия"), max_length=32, blank=True, null=True)
    uni_title = models.CharField(_("Название"), max_length=32, blank=True, null=True)
    uni_stage = models.BooleanField(_("План утверждён"), default=True)
    uni_loadTimeType = models.CharField(_("Единица измерения нагрузки"), max_length=32, blank=True, null=True)
    uni_html = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.uni_number

    class Meta:
        verbose_name = 'учебный план'
        verbose_name_plural = 'учебные планы'

class Program(ObjectBaseClass):

    LEVELS = (
        ("b", _("бакалавриат")),
        ("m", _("магистратура")),
        ("s", _("специалитет")),
    )

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    level = models.CharField(_("Уровень программы"), max_length=1, choices=LEVELS, default="b")
    title = models.CharField(_('Наименование образовательной программы'), blank=False, max_length=256, default=_(''))
    training_direction = models.CharField(_("Направление подготовки"), blank=False, max_length=256, default=_(''))
    competences = models.ManyToManyField(Competence, blank=True)
    chief = models.ForeignKey(Person, verbose_name=_('Руководитель образовательной программы'), blank=True, null=True)
    learning_plans = models.ManyToManyField("LearningPlan", blank=True)

    class Meta:
        verbose_name = 'программа'
        verbose_name_plural = 'программы'

    def __str__(self):
        return self.title

    def get_choice_groups(self):
        return [choice_group.id for choice_group in ChoiceGroup.objects.filter(program__id=self.id)]

    def get_modules(self):
        return

    def get_all_disciplines(self):
        pms = ProgramModules.objects.filter(program=self, status="p", archived=False).values_list("module__id", flat=True)
        return Discipline.objects.filter(module__id__in=pms, status="p", archived=False)

    def get_competences_diagram(self):
        response = {}
        for target in TrainingTarget.objects.filter(program=self, status="p", archived=False).order_by("number"):
            response[target.title] = []
            for competence in ProgramCompetence.objects.filter(program=self):
                labors = [pm.module.get_labor() for pm in
                          ProgramModules.objects.filter(program=self, competence=competence, status="p", archived=False,
                                                        module__id__in=target.get_mandatory_modules_id())]
                response[target.title].append(
                    ([competence.title, competence.color, sum([0 if not labor else labor for labor in labors])]))

        return response

class TrainingTarget(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование образовательной цели'), blank=False, max_length=256, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Порядковый номер цели"))

    class Meta:
        verbose_name = 'образовательная цель'
        verbose_name_plural = 'образовательные цели'

    def __str__(self):
        return self.title

    def get_modules_id(self):
        return TargetModules.objects.filter(target=self, archived=False, status="p").values_list(
            'program_module__module__id', flat=True)

    def get_mandatory_modules_id(self):
        return TargetModules.objects.filter(target=self, archived=False, status="p", choice_group=False).values_list(
            'program_module__module__id', flat=True)

    def get_choice_modules_id(self):
        return TargetModules.objects.filter(target=self, archived=False, status="p", choice_group=True).values_list(
            'program_module__module__id', flat=True)

class ProgramCompetence(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование компетенции'), blank=False, max_length=2048, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Номер компетенции"))
    color = models.CharField(_("Цвет"), max_length=32, blank=True, null=True, default="green")

    class Meta:
        verbose_name = 'компетенция программы'
        verbose_name_plural = 'компетенции программы'

    def __str__(self):
        return self.title

    def get_labor(self):
        response = [pm.module.get_labor() for pm in
                    ProgramModules.objects.filter(program=self.program, competence=self, status="p", archived=False)]
        return sum([0 if not labor else labor for labor in response])

class ProgramModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    module = models.ForeignKey("modules.Module")
    choice_group = models.ForeignKey("ChoiceGroup", blank=True, null=True)
    competence = models.ForeignKey(ProgramCompetence, blank=True, null=True)
    semester = models.PositiveIntegerField(blank=True, null=True)

    class Meta:
        verbose_name = 'модуль программы'
        verbose_name_plural = 'модули программы'

    def get_competence_display(self):
        return str(self.competence)

    def get_weight(self):
        try:
            weight = max([int(ds["period"]) for ds in
                          Discipline.objects.filter(pk__in=self.module.get_all_discipline_ids()).values(
                              "period")]) + self.semester
        except:
            weight = self.semester

        try:
            return int(weight) * 100
        except:
            return 100

    def get_target_positions(self):
        targets_positions = []
        try:
            tr_targets = TrainingTarget.objects.filter(program=self.program).order_by('number')
            for tt in tr_targets:
                tms = TargetModules.objects.filter(program_module=self, target=tt, status="p",
                                                   archived=False)
                if not tms:
                    status = 0
                for target_module in tms:
                    if target_module.choice_group is False:
                        status = 1
                    elif target_module.choice_group is True:
                        status = 2
                targets_positions.append(status)

        except:
            pass
        return targets_positions

class Changed(models.Model):
    _changed = models.BooleanField(default=True)
    program = models.ForeignKey("Program", null=True)
    view = models.CharField(max_length=16, blank=True, null=True)

    def state(self):
        return self._changed

    def activate(self):
        self._changed = True
        self.save()

    def deactivate(self):
        self._changed = False
        self.save()

class TargetModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    target = models.ForeignKey("TrainingTarget")
    program_module = models.ForeignKey("ProgramModules")
    choice_group = models.BooleanField(default=False)

    class Meta:
        verbose_name = 'модуль цели'
        verbose_name_plural = 'модули цели'

class ChoiceGroup(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    title = models.CharField(_('Наименование группы выбора'), blank=False, max_length=2048, default=_(''))
    labor = models.IntegerField(_("Трудоёмкость группы"), default=3)
    choice_group_type = models.ForeignKey("ChoiceGroupType")
    number = models.IntegerField(_("Номер группы выбора"))

    class Meta:
        verbose_name = 'группа выбора'
        verbose_name_plural = 'группы выбора'

    def __str__(self):
        return self.title

    def get_choice_group_type_display(self):
        return self.choice_group_type.title

    def get_program_modules(self):
        return [program_module.id for program_module in
                ProgramModules.objects.filter(program=self.program, choice_group=self, status="p", archived=False)]

class ChoiceGroupType(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование типы группы выбора'), blank=False, max_length=2048, default=_(''))

    class Meta:
        verbose_name = 'тип группы выбора'
        verbose_name_plural = 'типы группы выбора'

    def __str__(self):
        return self.title

def student_program_key():
    pass  # o_O

class StudentProgram(ObjectBaseClass):
    # id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    link = models.CharField(primary_key=True, unique=True, null=False, max_length=16, default=student_program_key)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True)
    program = models.ForeignKey("Program")
    json = JSONField(verbose_name=_("JSON"), null=True, blank=True)

    class Meta:
        verbose_name = 'сохранение'
        verbose_name_plural = 'сохранения'

    def __str__(self):
        return self.title

def student_program_key():
    while True:  # lol hack
        key = hashlib.md5(urandom(128)).hexdigest()[6:]
        if StudentProgram.objects.filter(link=key).count() == 0:
            break
    return key

<commit_msg>StudentProgram#5<commit_after>import uuid
from os import urandom
import hashlib
from jsonfield import JSONField

from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from django.conf import settings

from persons.models import Person
from competences.models import Competence
from modules.models import Module
from disciplines.models import Discipline

class LearningPlan(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    uni_displayableTitle = models.CharField(_("Версия"), max_length=32, blank=True, null=True)
    uni_number = models.CharField(_("Номер УП"), max_length=32, blank=True, null=True)
    uni_active = models.CharField(_("Текущая версия"), max_length=32, blank=True, null=True)
    uni_title = models.CharField(_("Название"), max_length=32, blank=True, null=True)
    uni_stage = models.BooleanField(_("План утверждён"), default=True)
    uni_loadTimeType = models.CharField(_("Единица измерения нагрузки"), max_length=32, blank=True, null=True)
    uni_html = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.uni_number

    class Meta:
        verbose_name = 'учебный план'
        verbose_name_plural = 'учебные планы'

class Program(ObjectBaseClass):

    LEVELS = (
        ("b", _("бакалавриат")),
        ("m", _("магистратура")),
        ("s", _("специалитет")),
    )

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    level = models.CharField(_("Уровень программы"), max_length=1, choices=LEVELS, default="b")
    title = models.CharField(_('Наименование образовательной программы'), blank=False, max_length=256, default=_(''))
    training_direction = models.CharField(_("Направление подготовки"), blank=False, max_length=256, default=_(''))
    competences = models.ManyToManyField(Competence, blank=True)
    chief = models.ForeignKey(Person, verbose_name=_('Руководитель образовательной программы'), blank=True, null=True)
    learning_plans = models.ManyToManyField("LearningPlan", blank=True)

    class Meta:
        verbose_name = 'программа'
        verbose_name_plural = 'программы'

    def __str__(self):
        return self.title

    def get_choice_groups(self):
        return [choice_group.id for choice_group in ChoiceGroup.objects.filter(program__id=self.id)]

    def get_modules(self):
        return

    def get_all_disciplines(self):
        pms = ProgramModules.objects.filter(program=self, status="p", archived=False).values_list("module__id", flat=True)
        return Discipline.objects.filter(module__id__in=pms, status="p", archived=False)

    def get_competences_diagram(self):
        response = {}
        for target in TrainingTarget.objects.filter(program=self, status="p", archived=False).order_by("number"):
            response[target.title] = []
            for competence in ProgramCompetence.objects.filter(program=self):
                labors = [pm.module.get_labor() for pm in
                          ProgramModules.objects.filter(program=self, competence=competence, status="p", archived=False,
                                                        module__id__in=target.get_mandatory_modules_id())]
                response[target.title].append(
                    ([competence.title, competence.color, sum([0 if not labor else labor for labor in labors])]))

        return response

class TrainingTarget(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование образовательной цели'), blank=False, max_length=256, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Порядковый номер цели"))

    class Meta:
        verbose_name = 'образовательная цель'
        verbose_name_plural = 'образовательные цели'

    def __str__(self):
        return self.title

    def get_modules_id(self):
        return TargetModules.objects.filter(target=self, archived=False, status="p").values_list(
            'program_module__module__id', flat=True)

    def get_mandatory_modules_id(self):
        return TargetModules.objects.filter(target=self, archived=False, status="p", choice_group=False).values_list(
            'program_module__module__id', flat=True)

    def get_choice_modules_id(self):
        return TargetModules.objects.filter(target=self, archived=False, status="p", choice_group=True).values_list(
            'program_module__module__id', flat=True)

class ProgramCompetence(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование компетенции'), blank=False, max_length=2048, default=_(''))
    program = models.ForeignKey("Program", blank=True, null=True)
    number = models.IntegerField(_("Номер компетенции"))
    color = models.CharField(_("Цвет"), max_length=32, blank=True, null=True, default="green")

    class Meta:
        verbose_name = 'компетенция программы'
        verbose_name_plural = 'компетенции программы'

    def __str__(self):
        return self.title

    def get_labor(self):
        response = [pm.module.get_labor() for pm in
                    ProgramModules.objects.filter(program=self.program, competence=self, status="p", archived=False)]
        return sum([0 if not labor else labor for labor in response])

class ProgramModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    module = models.ForeignKey("modules.Module")
    choice_group = models.ForeignKey("ChoiceGroup", blank=True, null=True)
    competence = models.ForeignKey(ProgramCompetence, blank=True, null=True)
    semester = models.PositiveIntegerField(blank=True, null=True)

    class Meta:
        verbose_name = 'модуль программы'
        verbose_name_plural = 'модули программы'

    def get_competence_display(self):
        return str(self.competence)

    def get_weight(self):
        try:
            weight = max([int(ds["period"]) for ds in
                          Discipline.objects.filter(pk__in=self.module.get_all_discipline_ids()).values(
                              "period")]) + self.semester
        except:
            weight = self.semester

        try:
            return int(weight) * 100
        except:
            return 100

    def get_target_positions(self):
        targets_positions = []
        try:
            tr_targets = TrainingTarget.objects.filter(program=self.program).order_by('number')
            for tt in tr_targets:
                tms = TargetModules.objects.filter(program_module=self, target=tt, status="p",
                                                   archived=False)
                if not tms:
                    status = 0
                for target_module in tms:
                    if target_module.choice_group is False:
                        status = 1
                    elif target_module.choice_group is True:
                        status = 2
                targets_positions.append(status)

        except:
            pass
        return targets_positions

class Changed(models.Model):
    _changed = models.BooleanField(default=True)
    program = models.ForeignKey("Program", null=True)
    view = models.CharField(max_length=16, blank=True, null=True)

    def state(self):
        return self._changed

    def activate(self):
        self._changed = True
        self.save()

    def deactivate(self):
        self._changed = False
        self.save()

class TargetModules(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    target = models.ForeignKey("TrainingTarget")
    program_module = models.ForeignKey("ProgramModules")
    choice_group = models.BooleanField(default=False)

    class Meta:
        verbose_name = 'модуль цели'
        verbose_name_plural = 'модули цели'

class ChoiceGroup(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    program = models.ForeignKey("Program")
    title = models.CharField(_('Наименование группы выбора'), blank=False, max_length=2048, default=_(''))
    labor = models.IntegerField(_("Трудоёмкость группы"), default=3)
    choice_group_type = models.ForeignKey("ChoiceGroupType")
    number = models.IntegerField(_("Номер группы выбора"))

    class Meta:
        verbose_name = 'группа выбора'
        verbose_name_plural = 'группы выбора'

    def __str__(self):
        return self.title

    def get_choice_group_type_display(self):
        return self.choice_group_type.title

    def get_program_modules(self):
        return [program_module.id for program_module in
                ProgramModules.objects.filter(program=self.program, choice_group=self, status="p", archived=False)]

class ChoiceGroupType(ObjectBaseClass):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование типы группы выбора'), blank=False, max_length=2048, default=_(''))

    class Meta:
        verbose_name = 'тип группы выбора'
        verbose_name_plural = 'типы группы выбора'

    def __str__(self):
        return self.title

def student_program_key():
    key = hashlib.md5(urandom(128)).hexdigest()[6:]
    return key

class StudentProgram(ObjectBaseClass):
    # id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    link = models.CharField(primary_key=True, unique=True, null=False, max_length=16, default=student_program_key)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True)
    program = models.ForeignKey("Program")
    json = JSONField(verbose_name=_("JSON"), null=True, blank=True)

    class Meta:
        verbose_name = 'сохранение'
        verbose_name_plural = 'сохранения'

    def __str__(self):
        return self.title

<|endoftext|>


<commit_before>from rest_framework import serializers
from openbudget.apps.international.utilities import translated_fields
from openbudget.apps.sheets import models

class TemplateMin(serializers.HyperlinkedModelSerializer):
    """A minimal serializer for nested template objects."""

    class Meta:
        model = models.Template
        fields = ['id', 'url']

class TemplateBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of templates."""

    period = serializers.Field(source='period')

    class Meta:
        model = models.Template
        fields = ['id', 'url', 'name', 'description', 'divisions', 'period',
                  'created_on', 'last_modified'] + translated_fields(model)

class TemplateNodeMin(serializers.HyperlinkedModelSerializer):
    """A more efficient serialized representation of template nodes."""

    class Meta:
        model = models.TemplateNode
        fields = ['id', 'url']

class TemplateNodeBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of template nodes."""

    parent = TemplateNodeMin()
    backwards = TemplateNodeMin(many=True)

    class Meta:
        model = models.TemplateNode
        fields = ['id', 'url', 'code', 'name', 'description', 'direction',
                  'templates', 'path', 'parent', 'created_on',
                  'last_modified', 'backwards'] + translated_fields(model)

class TemplateDetail(TemplateBase):
    """A detailed, related representation of templates."""

    nodes = TemplateNodeBase()

    class Meta(TemplateBase.Meta):
        fields = TemplateBase.Meta.fields + ['nodes']

class SheetBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of sheets."""

    period = serializers.Field(source='period')
    # preventing circular import
    from openbudget.apps.entities.serializers import EntityMin
    entity = EntityMin()
    template = TemplateMin()

    class Meta:
        model = models.Sheet
        fields = ['id', 'url', 'template', 'entity', 'description', 'period',
                  'created_on', 'last_modified'] + translated_fields(model)

class SheetItemBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of sheet items."""

    #node = TemplateNodeMin()
    node = serializers.Field('node.id')
    code = serializers.Field('node.code')
    name = serializers.Field('node.name')
    name_en = serializers.Field('node.name_en')
    name_ar = serializers.Field('node.name_ar')
    name_ru = serializers.Field('node.name_ru')
    path = serializers.Field('node.path')
    direction = serializers.Field('node.direction')

    class Meta:
        model = models.SheetItem
        fields = ['id', 'url', 'code', 'name', 'path', 'direction', 'budget',
                  'actual', 'description', 'node', 'discussion'] + \
                 translated_fields(models.TemplateNode)

class SheetDetail(SheetBase):
    """A detailed, related representation of sheets."""

    #entity = EntityBase()
    #total = serializers.DecimalField(source='total')
    items = SheetItemBase()

    class Meta(SheetBase.Meta):
        fields = SheetBase.Meta.fields

class SheetItemDetail(SheetItemBase):
    """A detailed, related representation of sheet items."""

    class Meta(SheetItemBase.Meta):
        fields = SheetItemBase.Meta.fields + ['discussion']

class SheetTimeline(serializers.ModelSerializer):

    period = serializers.SerializerMethodField('get_period')

    class Meta:
        model = models.SheetItem
        fields = ['id', 'budget', 'actual', 'description', 'period'] + translated_fields(model)

    def get_period(self, obj):
        return obj.sheet.period
<commit_msg>Updated API SheetItem serializers to match UI SheetItem seralizers<commit_after>from rest_framework import serializers
from openbudget.apps.international.utilities import translated_fields
from openbudget.apps.sheets import models

class TemplateMin(serializers.HyperlinkedModelSerializer):
    """A minimal serializer for nested template objects."""

    class Meta:
        model = models.Template
        fields = ['id', 'url']

class TemplateBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of templates."""

    period = serializers.Field(source='period')

    class Meta:
        model = models.Template
        fields = ['id', 'url', 'name', 'description', 'divisions', 'period',
                  'created_on', 'last_modified'] + translated_fields(model)

class TemplateNodeMin(serializers.HyperlinkedModelSerializer):
    """A more efficient serialized representation of template nodes."""

    class Meta:
        model = models.TemplateNode
        fields = ['id', 'url']

class TemplateNodeBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of template nodes."""

    parent = TemplateNodeMin()
    backwards = TemplateNodeMin(many=True)

    class Meta:
        model = models.TemplateNode
        fields = ['id', 'url', 'code', 'name', 'description', 'direction',
                  'templates', 'path', 'parent', 'created_on',
                  'last_modified', 'backwards'] + translated_fields(model)

class TemplateDetail(TemplateBase):
    """A detailed, related representation of templates."""

    nodes = TemplateNodeBase()

    class Meta(TemplateBase.Meta):
        fields = TemplateBase.Meta.fields + ['nodes']

class SheetBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of sheets."""

    period = serializers.Field(source='period')
    # preventing circular import
    from openbudget.apps.entities.serializers import EntityMin
    entity = EntityMin()
    template = TemplateMin()

    class Meta:
        model = models.Sheet
        fields = ['id', 'url', 'template', 'entity', 'description', 'period',
                  'created_on', 'last_modified'] + translated_fields(model)

class SheetItemMinSerializer(serializers.HyperlinkedModelSerializer):
    """A minimal serialized representation of sheet items."""

    node = serializers.Field('node.id')
    code = serializers.Field('node.code')
    name = serializers.Field('node.name')
    name_en = serializers.Field('node.name_en')
    name_ar = serializers.Field('node.name_ar')
    name_ru = serializers.Field('node.name_ru')
    path = serializers.Field('node.path')
    direction = serializers.Field('node.direction')

    class Meta:
        model = models.SheetItem
        fields = ['id', 'url', 'code', 'name', 'path', 'direction', 'budget',
                  'actual', 'description', 'node']\
                 + translated_fields(models.TemplateNode)

class SheetItemBase(serializers.HyperlinkedModelSerializer):
    """The default serialized representation of sheet items."""

    #node = TemplateNodeMin()
    node = serializers.Field('node.id')
    code = serializers.Field('node.code')
    parent = SheetItemMinSerializer()
    children = SheetItemMinSerializer(many=True)
    ancestors = SheetItemMinSerializer(many=True)
    # descendants = SheetItemMinSerializer(many=True)
    name = serializers.Field('node.name')
    name_en = serializers.Field('node.name_en')
    name_ar = serializers.Field('node.name_ar')
    name_ru = serializers.Field('node.name_ru')
    path = serializers.Field('node.path')
    direction = serializers.Field('node.direction')

    class Meta:
        model = models.SheetItem
        fields = ['id', 'url', 'code', 'name', 'path', 'direction', 'budget',
                  'actual', 'description', 'node', 'discussion', 'parent', 'children', 'ancestors'] + \
                 translated_fields(models.TemplateNode)

class SheetDetail(SheetBase):
    """A detailed, related representation of sheets."""

    #entity = EntityBase()
    #total = serializers.DecimalField(source='total')
    items = SheetItemBase()

    class Meta(SheetBase.Meta):
        fields = SheetBase.Meta.fields

class SheetItemDetail(SheetItemBase):
    """A detailed, related representation of sheet items."""

    class Meta(SheetItemBase.Meta):
        fields = SheetItemBase.Meta.fields + ['discussion']

class SheetTimeline(serializers.ModelSerializer):

    period = serializers.SerializerMethodField('get_period')

    class Meta:
        model = models.SheetItem
        fields = ['id', 'budget', 'actual', 'description', 'period'] + translated_fields(model)

    def get_period(self, obj):
        return obj.sheet.period
<|endoftext|>


<commit_before>#!/usr/bin/env python

#======================================================================
# MODULE DOCSTRING
#======================================================================

"""
Test that the examples in the repo run without errors.
"""

#======================================================================
# GLOBAL IMPORTS
#======================================================================

import glob
import os
import re
import subprocess
import textwrap

import pytest

from openforcefield.utils import temporary_directory
from openforcefield.utils import RDKIT_AVAILABLE

#======================================================================
# TEST UTILITIES
#======================================================================

ROOT_DIR_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..')

def run_script_file(file_path):
    """Run through the shell a python script."""
    cmd = ['python', file_path]
    try:
        subprocess.check_call(cmd)
    except subprocess.CalledProcessError:
        raise Exception('Example {file_path} failed'.format(file_path=file_path))

def run_script_str(script_str):
    """Execute a Python string through the shell in a temporary directory.

    With respect to eval, this has the advantage of catching all import errors.

    """
    with temporary_directory() as tmp_dir:
        temp_file_path = os.path.join(tmp_dir, 'temp.py')
        # Create temporary python script.
        with open(temp_file_path, 'w') as f:
            f.write(script_str)
        # Run the Python script.
        try:
            run_script_file(temp_file_path)
        except:
            script_str = textwrap.indent(script_str, '    ')
            raise Exception(f'The following script failed:\n{script_str}')

def find_examples():
    """Find all examples in the examples folder.

    Returns
    -------
    example_file_paths : List[str]
        List of python script to execute.
    """
    slow_examples = {
        os.path.join('SMIRNOFF_comparison', 'compare_set_energies.py')
    }
    examples_dir_path = os.path.join(ROOT_DIR_PATH, 'examples')

    requires_rdkit = {
        os.path.join('conformer_energies', 'conformer_energies.py')
    }

    example_file_paths = []
    for example_file_path in glob.glob(os.path.join(examples_dir_path, '*', '*.py')):
        example_file_path = os.path.relpath(example_file_path)
        example_file_paths.append(example_file_path)
        if not RDKIT_AVAILABLE:
            for rdkit_example in requires_rdkit:
                if rdkit_example in example_file_path:
                    example_file_paths.remove(example_file_path)
        # Check if this is a slow test.
        for slow_example in slow_examples:
            if slow_example in example_file_path:
                # This is a slow example.
                example_file_path = pytest.param(example_file_path, marks=pytest.mark.slow)
    return example_file_paths

def find_readme_examples():
    """Yield the Python scripts in the main README.md file.

    Returns
    -------
    readme_examples : List[str]
        The list of Python scripts included in the README.md files.
    """
    readme_file_path = os.path.join(ROOT_DIR_PATH, 'README.md')
    with open(readme_file_path, 'r') as f:
        readme_content = f.read()
    return re.findall('```python(.*?)```', readme_content, flags=re.DOTALL)

def find_readme_links():
    """Yield all the links in the main README.md file.

    Returns
    -------
    readme_examples : List[str]
        The list of links included in the README.md file.
    """
    readme_file_path = os.path.join(ROOT_DIR_PATH, 'README.md')
    with open(readme_file_path, 'r') as f:
        readme_content = f.read()
    return re.findall('http[s]?://(?:[0-9a-zA-Z]|[-/.%:_])+', readme_content)

#======================================================================
# TESTS
#======================================================================

@pytest.mark.parametrize('readme_example_str', find_readme_examples())
def test_readme_examples(readme_example_str):
    """Test the example"""
    run_script_str(readme_example_str)

@pytest.mark.parametrize('readme_link', find_readme_links())
def test_readme_links(readme_link):
    """Test the example"""
    from urllib.request import Request, urlopen
    # Some websites do not accept requests that don't specify the
    # client and the type of accepted documents so we add fake info
    # to avoid the response being an error.
    headers = {'User-Agent':'Mozilla/5.0',
               'Accept': 'application/xhtml+xml,text/html,application/xml;q=0.9,*/*;q=0.8',}
    request = Request(readme_link, headers=headers)

    # Some DOI-based links are now behind DDoS protections, so skip them
    if 'doi.org' in readme_link:
        pytest.skip("DOI links are behind DDoS protection and do not resolve")

    # Try to connect 3 times, keeping track of exceptions so useful feedback can be provided.
    success = False
    exception= None
    for retry in range(3):
        try:
            urlopen(request)
            success = True
            break
        except Exception as e:
            exception = e
    if not(success):
        raise exception

@pytest.mark.parametrize('example_file_path', find_examples())
def test_examples(example_file_path):
    """Test that the example run without errors."""
    run_script_file(example_file_path)

<commit_msg>Pass file to conformer energy script<commit_after>#!/usr/bin/env python

#======================================================================
# MODULE DOCSTRING
#======================================================================

"""
Test that the examples in the repo run without errors.
"""

#======================================================================
# GLOBAL IMPORTS
#======================================================================

import glob
import os
import re
import subprocess
import textwrap

import pytest

from openforcefield.utils import (RDKIT_AVAILABLE, get_data_file_path,
                                  temporary_directory)

#======================================================================
# TEST UTILITIES
#======================================================================

ROOT_DIR_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..')

def run_script_file(file_path):
    """Run through the shell a python script."""
    cmd = ['python', file_path]
    if 'conformer_energies.py' in file_path:
        cmd.append('--filename')
        mol_file = get_data_file_path('molecules/ruxolitinib_conformers.sdf')
        cmd.append(mol_file)
    try:
        subprocess.check_call(cmd)
    except subprocess.CalledProcessError:
        raise Exception('Example {file_path} failed'.format(file_path=file_path))

def run_script_str(script_str):
    """Execute a Python string through the shell in a temporary directory.

    With respect to eval, this has the advantage of catching all import errors.

    """
    with temporary_directory() as tmp_dir:
        temp_file_path = os.path.join(tmp_dir, 'temp.py')
        # Create temporary python script.
        with open(temp_file_path, 'w') as f:
            f.write(script_str)
        # Run the Python script.
        try:
            run_script_file(temp_file_path)
        except:
            script_str = textwrap.indent(script_str, '    ')
            raise Exception(f'The following script failed:\n{script_str}')

def find_examples():
    """Find all examples in the examples folder.

    Returns
    -------
    example_file_paths : List[str]
        List of python script to execute.
    """
    slow_examples = {
        os.path.join('SMIRNOFF_comparison', 'compare_set_energies.py')
    }
    examples_dir_path = os.path.join(ROOT_DIR_PATH, 'examples')

    requires_rdkit = {
        os.path.join('conformer_energies', 'conformer_energies.py')
    }

    example_file_paths = []
    for example_file_path in glob.glob(os.path.join(examples_dir_path, '*', '*.py')):
        example_file_path = os.path.relpath(example_file_path)
        example_file_paths.append(example_file_path)
        if not RDKIT_AVAILABLE:
            for rdkit_example in requires_rdkit:
                if rdkit_example in example_file_path:
                    example_file_paths.remove(example_file_path)
        # Check if this is a slow test.
        for slow_example in slow_examples:
            if slow_example in example_file_path:
                # This is a slow example.
                example_file_path = pytest.param(example_file_path, marks=pytest.mark.slow)
    return example_file_paths

def find_readme_examples():
    """Yield the Python scripts in the main README.md file.

    Returns
    -------
    readme_examples : List[str]
        The list of Python scripts included in the README.md files.
    """
    readme_file_path = os.path.join(ROOT_DIR_PATH, 'README.md')
    with open(readme_file_path, 'r') as f:
        readme_content = f.read()
    return re.findall('```python(.*?)```', readme_content, flags=re.DOTALL)

def find_readme_links():
    """Yield all the links in the main README.md file.

    Returns
    -------
    readme_examples : List[str]
        The list of links included in the README.md file.
    """
    readme_file_path = os.path.join(ROOT_DIR_PATH, 'README.md')
    with open(readme_file_path, 'r') as f:
        readme_content = f.read()
    return re.findall('http[s]?://(?:[0-9a-zA-Z]|[-/.%:_])+', readme_content)

#======================================================================
# TESTS
#======================================================================

@pytest.mark.parametrize('readme_example_str', find_readme_examples())
def test_readme_examples(readme_example_str):
    """Test the example"""
    run_script_str(readme_example_str)

@pytest.mark.parametrize('readme_link', find_readme_links())
def test_readme_links(readme_link):
    """Test the example"""
    from urllib.request import Request, urlopen
    # Some websites do not accept requests that don't specify the
    # client and the type of accepted documents so we add fake info
    # to avoid the response being an error.
    headers = {'User-Agent':'Mozilla/5.0',
               'Accept': 'application/xhtml+xml,text/html,application/xml;q=0.9,*/*;q=0.8',}
    request = Request(readme_link, headers=headers)

    # Some DOI-based links are now behind DDoS protections, so skip them
    if 'doi.org' in readme_link:
        pytest.skip("DOI links are behind DDoS protection and do not resolve")

    # Try to connect 3 times, keeping track of exceptions so useful feedback can be provided.
    success = False
    exception= None
    for retry in range(3):
        try:
            urlopen(request)
            success = True
            break
        except Exception as e:
            exception = e
    if not(success):
        raise exception

@pytest.mark.parametrize('example_file_path', find_examples())
def test_examples(example_file_path):
    """Test that the example run without errors."""
    run_script_file(example_file_path)

<|endoftext|>