<commit_before>import typing as tp
import numpy as np
import random
Location = tp.Tuple[int, int]

class World():
    def __init__(self, world_size):
        self.world_size = world_size
        self.world = np.zeros((world_size, world_size), dtype=int)
        self.peak_resource = 255
        self.bin_size = self.peak_resource / 4

    def generate_resources(self, loc: Location):
        """
        Generates a new pyramid of resources centered a the loc
        """
        for dx in range(-8, 8):
            for dy in range(-8, 8):
                self.set((loc[0] + dx, loc[1] + dy),
                         self.resource_quota(dx, dy))

    def resource_quota(self, dx: int, dy: int):
        """
        Computes the amount of resources to add in the location based on the
        manhattan distance from the peak. The value peaks at 255 when dx=0 dy=0
        and falls linearly up to a distance of 8

        Args:
            dx: displacement on the x-axis
            dy: displacement on the y-axis

        Returns:
            the amount of resource to add in the location,
        """
        distance = abs(dx) + abs(dy)
        if distance < 8:
            return 255 * (1 - distance / 8)
        else:
            return 0.

    def sense(self, loc: Location):
        """
        Turns the amount of resources available in a location into 4 possible
        values (2 bits of indormation)

        Args:
            loc: location from which to extract the 2 bits of information
        Return:
            the two bits as an integer value
        """
        resources = self.get(loc)
        if(resources >= self.peak_resource):
            return 3
        else:
            return int(resources / self.bin_size)

    def get_sensory_state(self, loc: Location):
        """
        Builds the 10bit sensory state assembling the 2 bits of the current
        with the 8 bits coming from the 4 neighbours.
        Do so each value is shifted by 2 bits and then all the values are
        summed together to compute the final sensory state

        Args:
            loc: current location of the Agent
        Returns:
            sensory state
        """
        partial_state = []
        partial_state.append(self.sense(loc))
        partial_state.append(self.sense((loc[0] + 1, loc[1])) << 2)
        partial_state.append(self.sense((loc[0] - 1, loc[1])) << 4)
        partial_state.append(self.sense((loc[0], loc[1] - 1)) << 6)
        partial_state.append(self.sense((loc[0], loc[1] + 1)) << 8)
        return sum(partial_state)

    def get(self, loc: Location):
        """
        Gets the value at the specified position
        Args:
            loc: a tuple (x,y) that can be outside the limits of the world_size
        Returns:
            the resource at the corresponding location on the torus
        """
        return self.world[loc[0] % self.world_size][loc[1] % self.world_size]

    def set(self, loc: Location, increment: float):
        """
        Sets the resource at the specified position to value
        Args:
            loc: a tuple (x,y) that can be outside the limits of the world_size
            increment: amount to add in the specified position
        """
        curr_value = self.get(loc)
        new_value = min(curr_value + increment, 255)
        self.world[loc[0] % self.world_size][loc[1] %
                                             self.world_size] = new_value

    def probe(self, loc):
        resource_available = self.get(loc)
        resource_to_collect = min(resource_available, 100)
        self.set(loc, - resource_to_collect)
        return resource_to_collect

    def print_world(self):
        for row in self.world:
            print(''.join(map(lambda x: str(int(x)).ljust(4), row)))

    def random_location(self):
        return (random.choice(range(0, self.world_size)), random.choice(range(0, self.world_size)))

    def residual_resource(self):
        return self.world.sum()
<commit_msg>Turn the resources in the world to float to avoid rounding<commit_after>import typing as tp
import numpy as np
import random
Location = tp.Tuple[int, int]

class World():
    def __init__(self, world_size):
        self.world_size = world_size
        self.world = np.zeros((world_size, world_size), dtype=float)
        self.peak_resource = 255
        self.bin_size = self.peak_resource / 4

    def generate_resources(self, loc: Location):
        """
        Generates a new pyramid of resources centered a the loc
        """
        for dx in range(-8, 8):
            for dy in range(-8, 8):
                self.set((loc[0] + dx, loc[1] + dy),
                         self.resource_quota(dx, dy))

    def resource_quota(self, dx: int, dy: int):
        """
        Computes the amount of resources to add in the location based on the
        manhattan distance from the peak. The value peaks at 255 when dx=0 dy=0
        and falls linearly up to a distance of 8

        Args:
            dx: displacement on the x-axis
            dy: displacement on the y-axis

        Returns:
            the amount of resource to add in the location,
        """
        distance = abs(dx) + abs(dy)
        if distance < 8:
            return 255 * (1 - distance / 8)
        else:
            return 0.

    def sense(self, loc: Location):
        """
        Turns the amount of resources available in a location into 4 possible
        values (2 bits of indormation)

        Args:
            loc: location from which to extract the 2 bits of information
        Return:
            the two bits as an integer value
        """
        resources = self.get(loc)
        if(resources >= self.peak_resource):
            return 3
        else:
            return int(resources / self.bin_size)

    def get_sensory_state(self, loc: Location):
        """
        Builds the 10bit sensory state assembling the 2 bits of the current
        with the 8 bits coming from the 4 neighbours.
        Do so each value is shifted by 2 bits and then all the values are
        summed together to compute the final sensory state

        Args:
            loc: current location of the Agent
        Returns:
            sensory state
        """
        partial_state = []
        partial_state.append(self.sense(loc))
        partial_state.append(self.sense((loc[0] + 1, loc[1])) << 2)
        partial_state.append(self.sense((loc[0] - 1, loc[1])) << 4)
        partial_state.append(self.sense((loc[0], loc[1] - 1)) << 6)
        partial_state.append(self.sense((loc[0], loc[1] + 1)) << 8)
        return sum(partial_state)

    def get(self, loc: Location):
        """
        Gets the value at the specified position
        Args:
            loc: a tuple (x,y) that can be outside the limits of the world_size
        Returns:
            the resource at the corresponding location on the torus
        """
        return self.world[loc[0] % self.world_size][loc[1] % self.world_size]

    def set(self, loc: Location, increment: float):
        """
        Sets the resource at the specified position to value
        Args:
            loc: a tuple (x,y) that can be outside the limits of the world_size
            increment: amount to add in the specified position
        """
        curr_value = self.get(loc)
        new_value = min(curr_value + increment, 255)
        self.world[loc[0] % self.world_size][loc[1] %
                                             self.world_size] = new_value

    def probe(self, loc):
        resource_available = self.get(loc)
        resource_to_collect = min(resource_available, 100)
        self.set(loc, - resource_to_collect)
        return resource_to_collect

    def print_world(self):
        for row in self.world:
            print(''.join(map(lambda x: str(int(x)).ljust(4), row)))

    def random_location(self):
        return (random.choice(range(0, self.world_size)), random.choice(range(0, self.world_size)))

    def residual_resource(self):
        return self.world.sum()
<|endoftext|>


<commit_before>import os
from math import cos, pi

import asciitable
import pyfits
from astropysics import obstools, coords

from feder import feder
from keyword_names import *

#from coatpy import Sesame

def parse_dateobs(dateobs):
    date, time = dateobs.split('T')
    date = date.split('-')
    date = map(int, date)
    time = map(int, time.split(':'))
    date.extend(time)
    return date

def sexagesimal_string(dms, precision=2, sign=False):
    """Convert degrees, minutes, seconds into a string

    dms should be a list or tuple of (degrees or hours, minutes, seconds)
    precision is the number of digits to be kept to the right of the
    decimal in the seconds (default is 2)
    sign should be True if a leading sign should be displayed for
    positive values.
    """
    if sign:
        degree_format = '{0[0]:+03}'
    else:
        degree_format = '{0[0]:02}'

    seconds_width = str(precision + 3)
    format_string = degree_format+':{0[1]:02}:{0[2]:0'+seconds_width+'.'+str(precision)+'f}'
    return format_string.format(dms)

def deg2dms(dd):
    """Convert decimal degrees to degrees, minutes, seconds.

    Poached from stackoverflow.
    """
    mnt,sec = divmod(dd*3600,60)
    deg,mnt = divmod(mnt,60)
    return int(deg),int(mnt),sec

def add_time_info(header):
    dateobs = parse_dateobs(header['date-obs'])
    JD.value = round(obstools.calendar_to_jd(dateobs), 6)
    MJD.value = round(obstools.calendar_to_jd(dateobs, mjd=True), 6)

    # setting currentobsjd makes calls following it use that time
    # for calculations

    feder.currentobsjd = JD.value
    LST.value = feder.localSiderialTime()
    LST.value = sexagesimal_string(deg2dms(LST.value))

    for keyword in all_files:
        keyword.add_to_header(header)

def add_object_pos_airmass(header):
    """Add object information, such as RA/Dec and airmass.

    Has side effect of setting feder site JD to JD-OBS, which means it
    also assume JD.value has been set.
    """
    if JD.value is not None:
        feder.currentobsjd == JD.value
    else:
        raise ValueError('Need to set JD.value before calling.')

    try:
        RA.set_value_from_header(header)
    except ValueError:
        raise ValueError("No RA is present.")
        return

    Dec.set_value_from_header(header)
    RA.value = RA.value.replace(' ',':')
    Dec.value = Dec.value.replace(' ',':')
    object_coords = coords.EquatorialCoordinatesEquinox((RA.value, Dec.value))
    alt_az = feder.apparentCoordinates(object_coords, refraction=False)
    altitude.value = round(alt_az.alt.d, 5)
    azimuth.value = round(alt_az.az.d, 5)
    airmass.value = round(1/cos(pi/2 - alt_az.alt.r),3)
    hour_angle.value = sexagesimal_string(
        coords.EquatorialCoordinatesEquinox((feder.localSiderialTime()-
                                            object_coords.ra.hours,
                                             0)).ra.hms)
    for keyword in light_files:
        if keyword.value is not None:
            keyword.add_to_header(header)

def patch_headers(dir='.',manifest='Manifest.txt'):
    try:
        image_info_file = open(os.path.join(dir, manifest))
    except IOError:
        raise

    image_info = asciitable.read(image_info_file)
    image_info_file.close()
    current_dir = os.getcwd()
    os.chdir(dir)

    files = image_info['file name']

    latitude.value = sexagesimal_string(feder.latitude.dms)
    longitude.value = sexagesimal_string(feder.longitude.dms)
    obs_altitude.value = feder.altitude

    for image in files:
        hdulist = pyfits.open(image)
        header = hdulist[0].header
        int16 = (header['bitpix'] == 16)
        hdulist.verify('fix')
        add_time_info(header)
        if header['imagetyp'] == 'LIGHT':
            try:
                add_object_pos_airmass(header)
            except ValueError:
                print 'Skipping file %s' % image
                continue

        hdulist.writeto(image+'new')

    os.chdir(current_dir)

<commit_msg>Added minimal history to fits files, ability to overwrite existing files.<commit_after>import os
from math import cos, pi
from datetime import datetime

import asciitable
import pyfits
from astropysics import obstools, coords

from feder import feder
from keyword_names import *

#from coatpy import Sesame

def parse_dateobs(dateobs):
    date, time = dateobs.split('T')
    date = date.split('-')
    date = map(int, date)
    time = map(int, time.split(':'))
    date.extend(time)
    return date

def sexagesimal_string(dms, precision=2, sign=False):
    """Convert degrees, minutes, seconds into a string

    dms should be a list or tuple of (degrees or hours, minutes, seconds)
    precision is the number of digits to be kept to the right of the
    decimal in the seconds (default is 2)
    sign should be True if a leading sign should be displayed for
    positive values.
    """
    if sign:
        degree_format = '{0[0]:+03}'
    else:
        degree_format = '{0[0]:02}'

    seconds_width = str(precision + 3)
    format_string = degree_format+':{0[1]:02}:{0[2]:0'+seconds_width+'.'+str(precision)+'f}'
    return format_string.format(dms)

def deg2dms(dd):
    """Convert decimal degrees to degrees, minutes, seconds.

    Poached from stackoverflow.
    """
    mnt,sec = divmod(dd*3600,60)
    deg,mnt = divmod(mnt,60)
    return int(deg),int(mnt),sec

def add_time_info(header):
    dateobs = parse_dateobs(header['date-obs'])
    JD.value = round(obstools.calendar_to_jd(dateobs), 6)
    MJD.value = round(obstools.calendar_to_jd(dateobs, mjd=True), 6)

    # setting currentobsjd makes calls following it use that time
    # for calculations

    feder.currentobsjd = JD.value
    LST.value = feder.localSiderialTime()
    LST.value = sexagesimal_string(deg2dms(LST.value))

    for keyword in keywords_for_all_files:
        keyword.add_to_header(header, history=False)

def add_object_pos_airmass(header):
    """Add object information, such as RA/Dec and airmass.

    Has side effect of setting feder site JD to JD-OBS, which means it
    also assume JD.value has been set.
    """
    if JD.value is not None:
        feder.currentobsjd == JD.value
    else:
        raise ValueError('Need to set JD.value before calling.')

    try:
        RA.set_value_from_header(header)
    except ValueError:
        raise ValueError("No RA is present.")
        return

    Dec.set_value_from_header(header)
    RA.value = RA.value.replace(' ',':')
    Dec.value = Dec.value.replace(' ',':')
    object_coords = coords.EquatorialCoordinatesEquinox((RA.value, Dec.value))
    alt_az = feder.apparentCoordinates(object_coords, refraction=False)
    altitude.value = round(alt_az.alt.d, 5)
    azimuth.value = round(alt_az.az.d, 5)
    airmass.value = round(1/cos(pi/2 - alt_az.alt.r),3)
    hour_angle.value = sexagesimal_string(
        coords.EquatorialCoordinatesEquinox((feder.localSiderialTime()-
                                            object_coords.ra.hours,
                                             0)).ra.hms)
    for keyword in keywords_for_light_files:
        if keyword.value is not None:
            keyword.add_to_header(header, history=False)

def keyword_names_as_string(list_of_keywords):
    return ' '.join([' '.join(keyword.names) for keyword in list_of_keywords])

def patch_headers(dir='.',manifest='Manifest.txt', new_file_ext='new',
                  overwrite=False):
    try:
        image_info_file = open(os.path.join(dir, manifest))
    except IOError:
        raise

    image_info = asciitable.read(image_info_file)
    image_info_file.close()
    current_dir = os.getcwd()
    os.chdir(dir)

    files = image_info['file name']

    latitude.value = sexagesimal_string(feder.latitude.dms)
    longitude.value = sexagesimal_string(feder.longitude.dms)
    obs_altitude.value = feder.altitude

    for image in files:
        hdulist = pyfits.open(image)
        header = hdulist[0].header
        int16 = (header['bitpix'] == 16)
        hdulist.verify('fix')
        header.add_history('patch_headers.py modified this file on %s'
                           % datetime.now())
        add_time_info(header)
        header.add_history('patch_headers.py updated keywords %s' %
                            keyword_names_as_string(keywords_for_all_files))
        if header['imagetyp'] == 'LIGHT':
            try:
                add_object_pos_airmass(header)
            except ValueError:
                print 'Skipping file %s' % image
                continue
        header.add_history('patch_headers.py updated keywords %s' %
                           keyword_names_as_string(keywords_for_light_files))
        if overwrite:
            new_image = image
        else:
            root, ext = os.path.splitext(image)
            new_image = root + new_file_ext + ext

        if int16:
            hdulist[0].scale('int16')
        hdulist.writeto(new_image, clobber=overwrite)

    os.chdir(current_dir)

<|endoftext|>


<commit_before>"""
Helper functions for creating Form classes from Django models
and database field objects.
"""

from django.utils.translation import gettext

from util import ValidationError
from forms import BaseForm, SortedDictFromList
from fields import Field, ChoiceField
from widgets import Select, SelectMultiple, MultipleHiddenInput

__all__ = (
    'save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields',
    'ModelChoiceField', 'ModelMultipleChoiceField'
)

def save_instance(form, instance, fields=None, fail_message='saved', commit=True):
    """
    Saves bound Form ``form``'s cleaned_data into model instance ``instance``.

    Assumes ``form`` has a field for every non-AutoField database field in
    ``instance``. If commit=True, then the changes to ``instance`` will be
    saved to the database. Returns ``instance``.
    """
    from django.db import models
    opts = instance.__class__._meta
    if form.errors:
        raise ValueError("The %s could not be %s because the data didn't validate." % (opts.object_name, fail_message))
    cleaned_data = form.cleaned_data
    for f in opts.fields:
        if not f.editable or isinstance(f, models.AutoField) or not f.name in cleaned_data:
            continue
        if fields and f.name not in fields:
            continue
        setattr(instance, f.name, cleaned_data[f.name])
    if commit:
        instance.save()
        for f in opts.many_to_many:
            if fields and f.name not in fields:
                continue
            if f.name in cleaned_data:
                setattr(instance, f.attname, cleaned_data[f.name])
    # GOTCHA: If many-to-many data is given and commit=False, the many-to-many
    # data will be lost. This happens because a many-to-many options cannot be
    # set on an object until after it's saved. Maybe we should raise an
    # exception in that case.
    return instance

def make_model_save(model, fields, fail_message):
    "Returns the save() method for a Form."
    def save(self, commit=True):
        return save_instance(self, model(), fields, fail_message, commit)
    return save

def make_instance_save(instance, fields, fail_message):
    "Returns the save() method for a Form."
    def save(self, commit=True):
        return save_instance(self, instance, fields, fail_message, commit)
    return save

def form_for_model(model, form=BaseForm, fields=None, formfield_callback=lambda f: f.formfield()):
    """
    Returns a Form class for the given Django model class.

    Provide ``form`` if you want to use a custom BaseForm subclass.

    Provide ``formfield_callback`` if you want to define different logic for
    determining the formfield for a given database field. It's a callable that
    takes a database Field instance and returns a form Field instance.
    """
    opts = model._meta
    field_list = []
    for f in opts.fields + opts.many_to_many:
        if not f.editable:
            continue
        if fields and not f.name in fields:
            continue
        formfield = formfield_callback(f)
        if formfield:
            field_list.append((f.name, formfield))
    base_fields = SortedDictFromList(field_list)
    return type(opts.object_name + 'Form', (form,),
        {'base_fields': base_fields, '_model': model, 'save': make_model_save(model, fields, 'created')})

def form_for_instance(instance, form=BaseForm, fields=None, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)):
    """
    Returns a Form class for the given Django model instance.

    Provide ``form`` if you want to use a custom BaseForm subclass.

    Provide ``formfield_callback`` if you want to define different logic for
    determining the formfield for a given database field. It's a callable that
    takes a database Field instance, plus **kwargs, and returns a form Field
    instance with the given kwargs (i.e. 'initial').
    """
    model = instance.__class__
    opts = model._meta
    field_list = []
    for f in opts.fields + opts.many_to_many:
        if not f.editable:
            continue
        if fields and not f.name in fields:
            continue
        current_value = f.value_from_object(instance)
        formfield = formfield_callback(f, initial=current_value)
        if formfield:
            field_list.append((f.name, formfield))
    base_fields = SortedDictFromList(field_list)
    return type(opts.object_name + 'InstanceForm', (form,),
        {'base_fields': base_fields, '_model': model, 'save': make_instance_save(instance, fields, 'changed')})

def form_for_fields(field_list):
    "Returns a Form class for the given list of Django database field instances."
    fields = SortedDictFromList([(f.name, f.formfield()) for f in field_list if f.editable])
    return type('FormForFields', (BaseForm,), {'base_fields': fields})

class QuerySetIterator(object):
    def __init__(self, queryset, empty_label, cache_choices):
        self.queryset, self.empty_label, self.cache_choices = queryset, empty_label, cache_choices

    def __iter__(self):
        if self.empty_label is not None:
            yield (u"", self.empty_label)
        for obj in self.queryset:
            yield (obj._get_pk_val(), str(obj))
        # Clear the QuerySet cache if required.
        if not self.cache_choices:
            self.queryset._result_cache = None

class ModelChoiceField(ChoiceField):
    "A ChoiceField whose choices are a model QuerySet."
    # This class is a subclass of ChoiceField for purity, but it doesn't
    # actually use any of ChoiceField's implementation.
    def __init__(self, queryset, empty_label=u"---------", cache_choices=False,
            required=True, widget=Select, label=None, initial=None, help_text=None):
        self.queryset = queryset
        self.empty_label = empty_label
        self.cache_choices = cache_choices
        # Call Field instead of ChoiceField __init__() because we don't need
        # ChoiceField.__init__().
        Field.__init__(self, required, widget, label, initial, help_text)
        self.widget.choices = self.choices

    def _get_choices(self):
        # If self._choices is set, then somebody must have manually set
        # the property self.choices. In this case, just return self._choices.
        if hasattr(self, '_choices'):
            return self._choices
        # Otherwise, execute the QuerySet in self.queryset to determine the
        # choices dynamically. Return a fresh QuerySetIterator that has not
        # been consumed. Note that we're instantiating a new QuerySetIterator
        # *each* time _get_choices() is called (and, thus, each time
        # self.choices is accessed) so that we can ensure the QuerySet has not
        # been consumed.
        return QuerySetIterator(self.queryset, self.empty_label, self.cache_choices)

    def _set_choices(self, value):
        # This method is copied from ChoiceField._set_choices(). It's necessary
        # because property() doesn't allow a subclass to overwrite only
        # _get_choices without implementing _set_choices.
        self._choices = self.widget.choices = list(value)

    choices = property(_get_choices, _set_choices)

    def clean(self, value):
        Field.clean(self, value)
        if value in ('', None):
            return None
        try:
            value = self.queryset.model._default_manager.get(pk=value)
        except self.queryset.model.DoesNotExist:
            raise ValidationError(gettext(u'Select a valid choice. That choice is not one of the available choices.'))
        return value

class ModelMultipleChoiceField(ModelChoiceField):
    "A MultipleChoiceField whose choices are a model QuerySet."
    hidden_widget = MultipleHiddenInput
    def __init__(self, queryset, cache_choices=False, required=True,
            widget=SelectMultiple, label=None, initial=None, help_text=None):
        super(ModelMultipleChoiceField, self).__init__(queryset, None, cache_choices,
            required, widget, label, initial, help_text)

    def clean(self, value):
        if self.required and not value:
            raise ValidationError(gettext(u'This field is required.'))
        elif not self.required and not value:
            return []
        if not isinstance(value, (list, tuple)):
            raise ValidationError(gettext(u'Enter a list of values.'))
        final_values = []
        for val in value:
            try:
                obj = self.queryset.model._default_manager.get(pk=val)
            except self.queryset.model.DoesNotExist:
                raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % val)
            else:
                final_values.append(obj)
        return final_values
<commit_msg>Fixed #3972 -- Updated docstring. Patch from SmileyChris.<commit_after>"""
Helper functions for creating Form classes from Django models
and database field objects.
"""

from django.utils.translation import gettext

from util import ValidationError
from forms import BaseForm, SortedDictFromList
from fields import Field, ChoiceField
from widgets import Select, SelectMultiple, MultipleHiddenInput

__all__ = (
    'save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields',
    'ModelChoiceField', 'ModelMultipleChoiceField'
)

def save_instance(form, instance, fields=None, fail_message='saved', commit=True):
    """
    Saves bound Form ``form``'s cleaned_data into model instance ``instance``.

    If commit=True, then the changes to ``instance`` will be saved to the
    database. Returns ``instance``.
    """
    from django.db import models
    opts = instance.__class__._meta
    if form.errors:
        raise ValueError("The %s could not be %s because the data didn't validate." % (opts.object_name, fail_message))
    cleaned_data = form.cleaned_data
    for f in opts.fields:
        if not f.editable or isinstance(f, models.AutoField) or not f.name in cleaned_data:
            continue
        if fields and f.name not in fields:
            continue
        setattr(instance, f.name, cleaned_data[f.name])
    if commit:
        instance.save()
        for f in opts.many_to_many:
            if fields and f.name not in fields:
                continue
            if f.name in cleaned_data:
                setattr(instance, f.attname, cleaned_data[f.name])
    # GOTCHA: If many-to-many data is given and commit=False, the many-to-many
    # data will be lost. This happens because a many-to-many options cannot be
    # set on an object until after it's saved. Maybe we should raise an
    # exception in that case.
    return instance

def make_model_save(model, fields, fail_message):
    "Returns the save() method for a Form."
    def save(self, commit=True):
        return save_instance(self, model(), fields, fail_message, commit)
    return save

def make_instance_save(instance, fields, fail_message):
    "Returns the save() method for a Form."
    def save(self, commit=True):
        return save_instance(self, instance, fields, fail_message, commit)
    return save

def form_for_model(model, form=BaseForm, fields=None, formfield_callback=lambda f: f.formfield()):
    """
    Returns a Form class for the given Django model class.

    Provide ``form`` if you want to use a custom BaseForm subclass.

    Provide ``formfield_callback`` if you want to define different logic for
    determining the formfield for a given database field. It's a callable that
    takes a database Field instance and returns a form Field instance.
    """
    opts = model._meta
    field_list = []
    for f in opts.fields + opts.many_to_many:
        if not f.editable:
            continue
        if fields and not f.name in fields:
            continue
        formfield = formfield_callback(f)
        if formfield:
            field_list.append((f.name, formfield))
    base_fields = SortedDictFromList(field_list)
    return type(opts.object_name + 'Form', (form,),
        {'base_fields': base_fields, '_model': model, 'save': make_model_save(model, fields, 'created')})

def form_for_instance(instance, form=BaseForm, fields=None, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)):
    """
    Returns a Form class for the given Django model instance.

    Provide ``form`` if you want to use a custom BaseForm subclass.

    Provide ``formfield_callback`` if you want to define different logic for
    determining the formfield for a given database field. It's a callable that
    takes a database Field instance, plus **kwargs, and returns a form Field
    instance with the given kwargs (i.e. 'initial').
    """
    model = instance.__class__
    opts = model._meta
    field_list = []
    for f in opts.fields + opts.many_to_many:
        if not f.editable:
            continue
        if fields and not f.name in fields:
            continue
        current_value = f.value_from_object(instance)
        formfield = formfield_callback(f, initial=current_value)
        if formfield:
            field_list.append((f.name, formfield))
    base_fields = SortedDictFromList(field_list)
    return type(opts.object_name + 'InstanceForm', (form,),
        {'base_fields': base_fields, '_model': model, 'save': make_instance_save(instance, fields, 'changed')})

def form_for_fields(field_list):
    "Returns a Form class for the given list of Django database field instances."
    fields = SortedDictFromList([(f.name, f.formfield()) for f in field_list if f.editable])
    return type('FormForFields', (BaseForm,), {'base_fields': fields})

class QuerySetIterator(object):
    def __init__(self, queryset, empty_label, cache_choices):
        self.queryset, self.empty_label, self.cache_choices = queryset, empty_label, cache_choices

    def __iter__(self):
        if self.empty_label is not None:
            yield (u"", self.empty_label)
        for obj in self.queryset:
            yield (obj._get_pk_val(), str(obj))
        # Clear the QuerySet cache if required.
        if not self.cache_choices:
            self.queryset._result_cache = None

class ModelChoiceField(ChoiceField):
    "A ChoiceField whose choices are a model QuerySet."
    # This class is a subclass of ChoiceField for purity, but it doesn't
    # actually use any of ChoiceField's implementation.
    def __init__(self, queryset, empty_label=u"---------", cache_choices=False,
            required=True, widget=Select, label=None, initial=None, help_text=None):
        self.queryset = queryset
        self.empty_label = empty_label
        self.cache_choices = cache_choices
        # Call Field instead of ChoiceField __init__() because we don't need
        # ChoiceField.__init__().
        Field.__init__(self, required, widget, label, initial, help_text)
        self.widget.choices = self.choices

    def _get_choices(self):
        # If self._choices is set, then somebody must have manually set
        # the property self.choices. In this case, just return self._choices.
        if hasattr(self, '_choices'):
            return self._choices
        # Otherwise, execute the QuerySet in self.queryset to determine the
        # choices dynamically. Return a fresh QuerySetIterator that has not
        # been consumed. Note that we're instantiating a new QuerySetIterator
        # *each* time _get_choices() is called (and, thus, each time
        # self.choices is accessed) so that we can ensure the QuerySet has not
        # been consumed.
        return QuerySetIterator(self.queryset, self.empty_label, self.cache_choices)

    def _set_choices(self, value):
        # This method is copied from ChoiceField._set_choices(). It's necessary
        # because property() doesn't allow a subclass to overwrite only
        # _get_choices without implementing _set_choices.
        self._choices = self.widget.choices = list(value)

    choices = property(_get_choices, _set_choices)

    def clean(self, value):
        Field.clean(self, value)
        if value in ('', None):
            return None
        try:
            value = self.queryset.model._default_manager.get(pk=value)
        except self.queryset.model.DoesNotExist:
            raise ValidationError(gettext(u'Select a valid choice. That choice is not one of the available choices.'))
        return value

class ModelMultipleChoiceField(ModelChoiceField):
    "A MultipleChoiceField whose choices are a model QuerySet."
    hidden_widget = MultipleHiddenInput
    def __init__(self, queryset, cache_choices=False, required=True,
            widget=SelectMultiple, label=None, initial=None, help_text=None):
        super(ModelMultipleChoiceField, self).__init__(queryset, None, cache_choices,
            required, widget, label, initial, help_text)

    def clean(self, value):
        if self.required and not value:
            raise ValidationError(gettext(u'This field is required.'))
        elif not self.required and not value:
            return []
        if not isinstance(value, (list, tuple)):
            raise ValidationError(gettext(u'Enter a list of values.'))
        final_values = []
        for val in value:
            try:
                obj = self.queryset.model._default_manager.get(pk=val)
            except self.queryset.model.DoesNotExist:
                raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % val)
            else:
                final_values.append(obj)
        return final_values
<|endoftext|>


<commit_before>from django_evolution.db import evolver

def write_sql(sql):
    "Output a list of SQL statements, unrolling parameters as required"
    for statement in sql:
        if isinstance(statement, tuple):
            print unicode(statement[0] % tuple(evolver.quote_sql_param(s) for s in statement[1]))
        else:
            print unicode(statement)

def execute_sql(cursor, sql):
    """
    Execute a list of SQL statements on the provided cursor, unrolling
    parameters as required
    """
    for statement in sql:
        if isinstance(statement, tuple):
            if not statement[0].startswith('--'):
                cursor.execute(*statement)
        else:
            if not statement.startswith('--'):
                try:
                    cursor.execute(statement)
                except:
                    print statement
                    print sql
                    raise Exception(statement)
<commit_msg>Revert a debugging change that slipped in.<commit_after>from django_evolution.db import evolver

def write_sql(sql):
    "Output a list of SQL statements, unrolling parameters as required"
    for statement in sql:
        if isinstance(statement, tuple):
            print unicode(statement[0] % tuple(evolver.quote_sql_param(s) for s in statement[1]))
        else:
            print unicode(statement)

def execute_sql(cursor, sql):
    """
    Execute a list of SQL statements on the provided cursor, unrolling
    parameters as required
    """
    for statement in sql:
        if isinstance(statement, tuple):
            if not statement[0].startswith('--'):
                cursor.execute(*statement)
        else:
            if not statement.startswith('--'):
                cursor.execute(statement)
<|endoftext|>


<commit_before># PyQuantFi - pathDependent.py
# (c) 2012 Nick Collins

from math import log, exp, sqrt

class Cashflow(object):
    def __init__(self,timeIndex,amount):
        self.timeIndex = timeIndex
        self.amount = amount

class PathDependent(object):
    def __init__(self,lookAtTimes):
        self._lookAtTimes = lookAtTimes

    def getLookAtTimes(self):
        return self._lookAtTimes

    def maxNumberOfCashflows(self):
        return self._maxNumberOfCashflows()

    def possibleCashflowTimes(self):
        return self._possibleCashflowTimes()

    def cashflows(self,spotValues,generatedFlows):
        return self._cashflows(spotValues,generatedFlows)

class ExoticEngine(object):

    def __init__(self,product,paramDiscount):
        self._product = product
        self._r = paramDiscount
        self._cashflows = [0] * self._product.maxNumberOfCashflows()

        self._discounts = [exp(self._r.integral(0,t)) for t in
                          self._product.possibleCashflowTimes()]

    #def getOnePath(self,spotValues):
    #    return self._getOnePath(spotValues)

    def doSimulation(self,numberOfPaths,statsGatherer):
        #spotValues = [0] * len(self._product.getLookAtTimes())
        #n = len(self._product.getLookAtTimes())
        #for i in range(numberOfPaths):
            #self.getOnePath(spotValues)
            #thisValue = self.doOnePath(spotValues)
            #statsGatherer.addOneResult(thisValue)
        for path in self.getPaths(numberOfPaths):
            thisValue = self.doOnePath(path)
            statsGatherer.addOneResult(thisValue)

    def doOnePath(self,spotValues):
        numberFlows = self._product.maxNumberOfCashflows()
        self._product.cashflows(spotValues,self._cashflows)
        value = 0.
        for i in range(numberFlows):
            value += (self._cashflows[i].amount *
                      self._discounts[self._cashflows[i].timeIndex])
        return value

class ExoticBSEngine(ExoticEngine):

    def __init__(self,product,r,d,vol,randomGen,spot):
        self._product = product
        self._r = r
        self._randomGen = randomGen

        self._cashflows = [0] * self._product.maxNumberOfCashflows()
        self._discounts = [exp(self._r.integral(0,t)) for t in
                           self._product.possibleCashflowTimes()]

        times = product.getLookAtTimes()
        self._numberOfTimes = len(times)
        self._randomGen.dim = self._numberOfTimes

        # Since the drift and stDev terms are the same for each path
        # they are pre-calculated.
        var = vol.integralSq(0,times[0])
        self._drifts = [r.integral(0,times[0])
                            - d.integral(0,times[0])
                            - 0.5 * var]
        self._stDevs = [sqrt(var)]

        for i in range(1,self._numberOfTimes):
            thisVar = vol.integralSq(times[i-1],times[i])
            self._drifts.append(r.integral(times[i-1],times[i])
                                - d.integral(times[i-1],times[i])
                                - 0.5 * thisVar)
            self._stDevs.append(sqrt(thisVar))

        self._logSpot = log(spot)

    #def _getOnePath(self,spotValues):
    #    self._variates = self._randomGen.getGaussians()
    #    currentLogSpot = self._logSpot
    #    for i in range(self._numberOfTimes):
    #        currentLogSpot += self._drifts[i]
    #        currentLogSpot += self._stDevs[i] * self._variates[i]
    #        spotValues[i] = exp(currentLogSpot)
    #    return spotValues

    def getPaths(self, n):
        for v in self._randomGen.getGaussians(n):
            currentLogSpot = self._logSpot
            spotValues = []
            for i in range(self._numberOfTimes):
                currentLogSpot += self._drifts[i]
                currentLogSpot += self._stDevs[i] * v[i]
                spotValues.append(exp(currentLogSpot))
            yield spotValues

class PathDependentAsian(PathDependent):

    def __init__(self,lookAtTimes,deliveryTime,payoff):
        self._payoff = payoff
        self._lookAtTimes = lookAtTimes
        self._numberOfTimes = len(lookAtTimes)
        self._deliveryTime = deliveryTime

    def _maxNumberOfCashflows(self):
        return 1

    def _possibleCashflowTimes(self):
        return [self._deliveryTime]

    def _cashflows(self,spotValues,generatedFlows):
        product = 1
        for value in spotValues:
            product *= value
        mean = product ** (1./self._numberOfTimes)
        generatedFlows[0] = Cashflow(0,self._payoff(mean))
<commit_msg>added xrange alias for python3 in pathDependent.py<commit_after># PyQuantFi - pathDependent.py
# (c) 2012 Nick Collins

from math import log, exp, sqrt
from sys import version_info

if version_info[0] == 3:
    xrange = range

class Cashflow(object):
    def __init__(self,timeIndex,amount):
        self.timeIndex = timeIndex
        self.amount = amount

class PathDependent(object):
    def __init__(self,lookAtTimes):
        self._lookAtTimes = lookAtTimes

    def getLookAtTimes(self):
        return self._lookAtTimes

    def maxNumberOfCashflows(self):
        return self._maxNumberOfCashflows()

    def possibleCashflowTimes(self):
        return self._possibleCashflowTimes()

    def cashflows(self,spotValues,generatedFlows):
        return self._cashflows(spotValues,generatedFlows)

class ExoticEngine(object):

    def __init__(self,product,paramDiscount):
        self._product = product
        self._r = paramDiscount
        self._cashflows = [0] * self._product.maxNumberOfCashflows()

        self._discounts = [exp(self._r.integral(0,t)) for t in
                          self._product.possibleCashflowTimes()]

    #def getOnePath(self,spotValues):
    #    return self._getOnePath(spotValues)

    def doSimulation(self,numberOfPaths,statsGatherer):
        #spotValues = [0] * len(self._product.getLookAtTimes())
        #n = len(self._product.getLookAtTimes())
        #for i in range(numberOfPaths):
            #self.getOnePath(spotValues)
            #thisValue = self.doOnePath(spotValues)
            #statsGatherer.addOneResult(thisValue)
        for path in self.getPaths(numberOfPaths):
            thisValue = self.doOnePath(path)
            statsGatherer.addOneResult(thisValue)

    def doOnePath(self,spotValues):
        numberFlows = self._product.maxNumberOfCashflows()
        self._product.cashflows(spotValues,self._cashflows)
        value = 0.
        for i in xrange(numberFlows):
            value += (self._cashflows[i].amount *
                      self._discounts[self._cashflows[i].timeIndex])
        return value

class ExoticBSEngine(ExoticEngine):

    def __init__(self,product,r,d,vol,randomGen,spot):
        self._product = product
        self._r = r
        self._randomGen = randomGen

        self._cashflows = [0] * self._product.maxNumberOfCashflows()
        self._discounts = [exp(self._r.integral(0,t)) for t in
                           self._product.possibleCashflowTimes()]

        times = product.getLookAtTimes()
        self._numberOfTimes = len(times)
        self._randomGen.dim = self._numberOfTimes

        # Since the drift and stDev terms are the same for each path
        # they are pre-calculated.
        var = vol.integralSq(0,times[0])
        self._drifts = [r.integral(0,times[0])
                            - d.integral(0,times[0])
                            - 0.5 * var]
        self._stDevs = [sqrt(var)]

        for i in xrange(1,self._numberOfTimes):
            thisVar = vol.integralSq(times[i-1],times[i])
            self._drifts.append(r.integral(times[i-1],times[i])
                                - d.integral(times[i-1],times[i])
                                - 0.5 * thisVar)
            self._stDevs.append(sqrt(thisVar))

        self._logSpot = log(spot)

    #def _getOnePath(self,spotValues):
    #    self._variates = self._randomGen.getGaussians()
    #    currentLogSpot = self._logSpot
    #    for i in range(self._numberOfTimes):
    #        currentLogSpot += self._drifts[i]
    #        currentLogSpot += self._stDevs[i] * self._variates[i]
    #        spotValues[i] = exp(currentLogSpot)
    #    return spotValues

    def getPaths(self, n):
        for v in self._randomGen.getGaussians(n):
            currentLogSpot = self._logSpot
            spotValues = []
            for i in xrange(self._numberOfTimes):
                currentLogSpot += self._drifts[i]
                currentLogSpot += self._stDevs[i] * v[i]
                spotValues.append(exp(currentLogSpot))
            yield spotValues

class PathDependentAsian(PathDependent):

    def __init__(self,lookAtTimes,deliveryTime,payoff):
        self._payoff = payoff
        self._lookAtTimes = lookAtTimes
        self._numberOfTimes = len(lookAtTimes)
        self._deliveryTime = deliveryTime

    def _maxNumberOfCashflows(self):
        return 1

    def _possibleCashflowTimes(self):
        return [self._deliveryTime]

    def _cashflows(self,spotValues,generatedFlows):
        product = 1
        for value in spotValues:
            product *= value
        mean = product ** (1./self._numberOfTimes)
        generatedFlows[0] = Cashflow(0,self._payoff(mean))
<|endoftext|>


<commit_before>"""
Unit test tasks
"""
import os
import sys
from paver.easy import sh, task, cmdopts, needs, call_task
from pavelib.utils.test import suites
from pavelib.utils.envs import Env
from optparse import make_option
from git import Repo

try:
    from pygments.console import colorize
except ImportError:
    colorize = lambda color, text: text

__test__ = False  # do not collect

@task
def generate_nose_exclude_dir():
    # TODO: Toggle this feature using env. variables
    # TODO: Move this function to utils
    # TODO: Allow to customize with env. variables
    # This hash is for: `named-release/dogwood.rc2`
    COMPARE_BASE = '1ebb78c9fa44f0b96d1500890373f672bff3f569'

    DJANGO_PROJECT_DIRS = (
        'cms/djangoapps/',
        'common/djangoapps/',
        'lms/djangoapps/',
        'openedx/core/djangoapps/',
    )

    LMS_TEST_PART = os.environ['LMS_TEST_PART']  # Break if the variable doesn't exist

    git_repo = Repo('.')

    diff_files = git_repo.git.diff(COMPARE_BASE, '--name-only').split('\n')

    def files_to_apps(django_project_dir, files):
        apps = set()
        for f in files:
            if f.startswith(django_project_dir):
                relative_path = f.replace(django_project_dir, '', 1)
                app_name = os.path.split(relative_path)[0]
                apps.add(app_name)

        return apps

    def list_dirs(parent_dir):
        return set(
            name for name in os.listdir(parent_dir)
            if os.path.isdir(os.path.join(parent_dir, name))
        )

    def get_test_dir(app_dir):
        tests_dir = os.path.join(app_dir, 'tests')
        if os.path.exists(tests_dir):
            return tests_dir

        return app_dir  # Probably the app doesn't have tests

    def split_seq(seq, percent):
        """
        Splits a list into two lists based on specific percent.

        Call it:
           >>> split_seq([1,2,3,4,5,6], 50) == [1,2,3],[4,5,6]
        """

        seq = sorted(seq)  # Make sure the result are always consistent
        index = int(len(seq) * percent/100.0)
        return seq[:index], seq[index:]

    nose_rules = []
    for django_project_dir in DJANGO_PROJECT_DIRS:
        changed_apps = files_to_apps(django_project_dir, diff_files)
        all_apps = list_dirs(django_project_dir)
        unchanged_apps = all_apps - changed_apps  # neat python set operations

        if django_project_dir == 'lms/djangoapps/':
            part_a, part_b = split_seq(changed_apps, 55)
            wanted_changed_apps = part_a if LMS_TEST_PART == 'A' else part_b

            nose_rules.extend([
                '# Included: {}'.format(os.path.join(django_project_dir, app))
                for app in wanted_changed_apps
            ])

            nose_rules.extend([
                get_test_dir(os.path.join(django_project_dir, app))
                for app in changed_apps - set(wanted_changed_apps)
            ])
        else:
            nose_rules.extend([
                '# Included: {}'.format(os.path.join(django_project_dir, app))
                for app in changed_apps
            ])

        nose_rules.extend([
            get_test_dir(os.path.join(django_project_dir, app))
            for app in unchanged_apps
        ])

    with open('nose-exclude-dirs', 'w') as dirs_file:
        dirs_file.write('\n'.join(nose_rules))

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("system=", "s", "System to act on"),
    ("test_id=", "t", "Test id"),
    ("failed", "f", "Run only failed tests"),
    ("fail_fast", "x", "Fail suite on first failed test"),
    ("fasttest", "a", "Run without collectstatic"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
def test_system(options):
    """
    Run tests on our djangoapps for lms and cms
    """
    system = getattr(options, 'system', None)
    test_id = getattr(options, 'test_id', None)

    opts = {
        'failed_only': getattr(options, 'failed', None),
        'fail_fast': getattr(options, 'fail_fast', None),
        'fasttest': getattr(options, 'fasttest', None),
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'skip_clean': getattr(options, 'skip_clean', False),
        'pdb': getattr(options, 'pdb', False),
    }

    if test_id:
        if not system:
            system = test_id.split('/')[0]
        if system in ['common', 'openedx']:
            system = 'lms'
        opts['test_id'] = test_id

    if test_id or system:
        system_tests = [suites.SystemTestSuite(system, **opts)]
    else:
        system_tests = []
        for syst in ('cms', 'lms'):
            system_tests.append(suites.SystemTestSuite(syst, **opts))

    test_suite = suites.PythonTestSuite('python tests', subsuites=system_tests, **opts)
    test_suite.run()

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("lib=", "l", "lib to test"),
    ("test_id=", "t", "Test id"),
    ("failed", "f", "Run only failed tests"),
    ("fail_fast", "x", "Run only failed tests"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
def test_lib(options):
    """
    Run tests for common/lib/ and pavelib/ (paver-tests)
    """
    lib = getattr(options, 'lib', None)
    test_id = getattr(options, 'test_id', lib)

    opts = {
        'failed_only': getattr(options, 'failed', None),
        'fail_fast': getattr(options, 'fail_fast', None),
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'skip_clean': getattr(options, 'skip_clean', False),
        'pdb': getattr(options, 'pdb', False),
    }

    if test_id:
        if '/' in test_id:
            lib = '/'.join(test_id.split('/')[0:3])
        else:
            lib = 'common/lib/' + test_id.split('.')[0]
        opts['test_id'] = test_id
        lib_tests = [suites.LibTestSuite(lib, **opts)]
    else:
        lib_tests = [suites.LibTestSuite(d, **opts) for d in Env.LIB_TEST_DIRS]

    test_suite = suites.PythonTestSuite('python tests', subsuites=lib_tests, **opts)
    test_suite.run()

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("failed", "f", "Run only failed tests"),
    ("fail_fast", "x", "Run only failed tests"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
])
def test_python(options):
    """
    Run all python tests
    """
    opts = {
        'failed_only': getattr(options, 'failed', None),
        'fail_fast': getattr(options, 'fail_fast', None),
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'pdb': getattr(options, 'pdb', False),
    }

    python_suite = suites.PythonTestSuite('Python Tests', **opts)
    python_suite.run()

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("suites", "s", "List of unit test suites to run. (js, lib, cms, lms)"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
])
def test(options):
    """
    Run all tests
    """
    opts = {
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'pdb': getattr(options, 'pdb', False),
    }
    # Subsuites to be added to the main suite
    python_suite = suites.PythonTestSuite('Python Tests', **opts)
    js_suite = suites.JsTestSuite('JS Tests', mode='run', with_coverage=True)

    # Main suite to be run
    all_unittests_suite = suites.TestSuite('All Tests', subsuites=[js_suite, python_suite])
    all_unittests_suite.run()

@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts([
    ("compare_branch=", "b", "Branch to compare against, defaults to origin/master"),
])
def coverage(options):
    """
    Build the html, xml, and diff coverage reports
    """
    report_dir = Env.REPORT_DIR
    rcfile = Env.PYTHON_COVERAGERC

    if not (report_dir / '.coverage').isfile():
        # This may be that the coverage files were generated using -p,
        # try to combine them to the one file that we need.
        sh("coverage combine --rcfile={}".format(rcfile))

    if not os.path.getsize(report_dir / '.coverage') > 50:
        # Check if the .coverage data file is larger than the base file,
        # because coverage combine will always at least make the "empty" data
        # file even when there isn't any data to be combined.
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running "
            "`paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
        return

    # Generate the coverage.py XML report
    sh("coverage xml --rcfile={}".format(rcfile))
    # Generate the coverage.py HTML report
    sh("coverage html --rcfile={}".format(rcfile))
    call_task('diff_coverage', options=dict(options))

@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts([
    ("compare_branch=", "b", "Branch to compare against, defaults to origin/master"),
])
def diff_coverage(options):
    """
    Build the diff coverage reports
    """
    compare_branch = getattr(options, 'compare_branch', 'origin/master')

    # Find all coverage XML files (both Python and JavaScript)
    xml_reports = []

    for filepath in Env.REPORT_DIR.walk():
        if filepath.basename() == 'coverage.xml':
            xml_reports.append(filepath)

    if not xml_reports:
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running "
            "`paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
    else:
        xml_report_str = ' '.join(xml_reports)
        diff_html_path = os.path.join(Env.REPORT_DIR, 'diff_coverage_combined.html')

        # Generate the diff coverage reports (HTML and console)
        sh(
            "diff-cover {xml_report_str} --compare-branch={compare_branch} "
            "--html-report {diff_html_path}".format(
                xml_report_str=xml_report_str,
                compare_branch=compare_branch,
                diff_html_path=diff_html_path,
            )
        )

        print "\n"
<commit_msg>Allow testing all LMS at once<commit_after>"""
Unit test tasks
"""
import os
import sys
from paver.easy import sh, task, cmdopts, needs, call_task
from pavelib.utils.test import suites
from pavelib.utils.envs import Env
from optparse import make_option
from git import Repo

try:
    from pygments.console import colorize
except ImportError:
    colorize = lambda color, text: text

__test__ = False  # do not collect

@task
def generate_nose_exclude_dir():
    # TODO: Toggle this feature using env. variables
    # TODO: Move this function to utils
    # TODO: Allow to customize with env. variables
    # This hash is for: `named-release/dogwood.rc2`
    COMPARE_BASE = '1ebb78c9fa44f0b96d1500890373f672bff3f569'

    DJANGO_PROJECT_DIRS = (
        'cms/djangoapps/',
        'common/djangoapps/',
        'lms/djangoapps/',
        'openedx/core/djangoapps/',
    )

    LMS_TEST_PART = os.environ['LMS_TEST_PART']  # Break if the variable doesn't exist

    git_repo = Repo('.')

    diff_files = git_repo.git.diff(COMPARE_BASE, '--name-only').split('\n')

    def files_to_apps(django_project_dir, files):
        apps = set()
        for f in files:
            if f.startswith(django_project_dir):
                relative_path = f.replace(django_project_dir, '', 1)
                app_name = os.path.split(relative_path)[0]
                apps.add(app_name)

        return apps

    def list_dirs(parent_dir):
        return set(
            name for name in os.listdir(parent_dir)
            if os.path.isdir(os.path.join(parent_dir, name))
        )

    def get_test_dir(app_dir):
        tests_dir = os.path.join(app_dir, 'tests')
        if os.path.exists(tests_dir):
            return tests_dir

        return app_dir  # Probably the app doesn't have tests

    def split_seq(seq, percent):
        """
        Splits a list into two lists based on specific percent.

        Call it:
           >>> split_seq([1,2,3,4,5,6], 50) == [1,2,3],[4,5,6]
        """

        seq = sorted(seq)  # Make sure the result are always consistent
        index = int(len(seq) * percent/100.0)
        return seq[:index], seq[index:]

    nose_rules = []
    for django_project_dir in DJANGO_PROJECT_DIRS:
        changed_apps = files_to_apps(django_project_dir, diff_files)
        all_apps = list_dirs(django_project_dir)
        unchanged_apps = all_apps - changed_apps  # neat python set operations

        if django_project_dir == 'lms/djangoapps/' and LMS_TEST_PART != 'ALL':
            part_a, part_b = split_seq(changed_apps, 55)
            wanted_changed_apps = part_a if LMS_TEST_PART == 'A' else part_b

            nose_rules.extend([
                '# Included: {}'.format(os.path.join(django_project_dir, app))
                for app in wanted_changed_apps
            ])

            nose_rules.extend([
                get_test_dir(os.path.join(django_project_dir, app))
                for app in changed_apps - set(wanted_changed_apps)
            ])
        else:
            nose_rules.extend([
                '# Included: {}'.format(os.path.join(django_project_dir, app))
                for app in changed_apps
            ])

        nose_rules.extend([
            get_test_dir(os.path.join(django_project_dir, app))
            for app in unchanged_apps
        ])

    with open('nose-exclude-dirs', 'w') as dirs_file:
        dirs_file.write('\n'.join(nose_rules))

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("system=", "s", "System to act on"),
    ("test_id=", "t", "Test id"),
    ("failed", "f", "Run only failed tests"),
    ("fail_fast", "x", "Fail suite on first failed test"),
    ("fasttest", "a", "Run without collectstatic"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
def test_system(options):
    """
    Run tests on our djangoapps for lms and cms
    """
    system = getattr(options, 'system', None)
    test_id = getattr(options, 'test_id', None)

    opts = {
        'failed_only': getattr(options, 'failed', None),
        'fail_fast': getattr(options, 'fail_fast', None),
        'fasttest': getattr(options, 'fasttest', None),
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'skip_clean': getattr(options, 'skip_clean', False),
        'pdb': getattr(options, 'pdb', False),
    }

    if test_id:
        if not system:
            system = test_id.split('/')[0]
        if system in ['common', 'openedx']:
            system = 'lms'
        opts['test_id'] = test_id

    if test_id or system:
        system_tests = [suites.SystemTestSuite(system, **opts)]
    else:
        system_tests = []
        for syst in ('cms', 'lms'):
            system_tests.append(suites.SystemTestSuite(syst, **opts))

    test_suite = suites.PythonTestSuite('python tests', subsuites=system_tests, **opts)
    test_suite.run()

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("lib=", "l", "lib to test"),
    ("test_id=", "t", "Test id"),
    ("failed", "f", "Run only failed tests"),
    ("fail_fast", "x", "Run only failed tests"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
def test_lib(options):
    """
    Run tests for common/lib/ and pavelib/ (paver-tests)
    """
    lib = getattr(options, 'lib', None)
    test_id = getattr(options, 'test_id', lib)

    opts = {
        'failed_only': getattr(options, 'failed', None),
        'fail_fast': getattr(options, 'fail_fast', None),
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'skip_clean': getattr(options, 'skip_clean', False),
        'pdb': getattr(options, 'pdb', False),
    }

    if test_id:
        if '/' in test_id:
            lib = '/'.join(test_id.split('/')[0:3])
        else:
            lib = 'common/lib/' + test_id.split('.')[0]
        opts['test_id'] = test_id
        lib_tests = [suites.LibTestSuite(lib, **opts)]
    else:
        lib_tests = [suites.LibTestSuite(d, **opts) for d in Env.LIB_TEST_DIRS]

    test_suite = suites.PythonTestSuite('python tests', subsuites=lib_tests, **opts)
    test_suite.run()

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("failed", "f", "Run only failed tests"),
    ("fail_fast", "x", "Run only failed tests"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
])
def test_python(options):
    """
    Run all python tests
    """
    opts = {
        'failed_only': getattr(options, 'failed', None),
        'fail_fast': getattr(options, 'fail_fast', None),
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'pdb': getattr(options, 'pdb', False),
    }

    python_suite = suites.PythonTestSuite('Python Tests', **opts)
    python_suite.run()

@task
@needs(
    'pavelib.prereqs.install_prereqs',
    'pavelib.utils.test.utils.clean_reports_dir',
    'pavelib.tests.generate_nose_exclude_dir',
)
@cmdopts([
    ("suites", "s", "List of unit test suites to run. (js, lib, cms, lms)"),
    ('extra_args=', 'e', 'adds as extra args to the test command'),
    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
    make_option("--verbose", action="store_const", const=2, dest="verbosity"),
    make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
    make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
])
def test(options):
    """
    Run all tests
    """
    opts = {
        'verbosity': getattr(options, 'verbosity', 1),
        'extra_args': getattr(options, 'extra_args', ''),
        'cov_args': getattr(options, 'cov_args', ''),
        'pdb': getattr(options, 'pdb', False),
    }
    # Subsuites to be added to the main suite
    python_suite = suites.PythonTestSuite('Python Tests', **opts)
    js_suite = suites.JsTestSuite('JS Tests', mode='run', with_coverage=True)

    # Main suite to be run
    all_unittests_suite = suites.TestSuite('All Tests', subsuites=[js_suite, python_suite])
    all_unittests_suite.run()

@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts([
    ("compare_branch=", "b", "Branch to compare against, defaults to origin/master"),
])
def coverage(options):
    """
    Build the html, xml, and diff coverage reports
    """
    report_dir = Env.REPORT_DIR
    rcfile = Env.PYTHON_COVERAGERC

    if not (report_dir / '.coverage').isfile():
        # This may be that the coverage files were generated using -p,
        # try to combine them to the one file that we need.
        sh("coverage combine --rcfile={}".format(rcfile))

    if not os.path.getsize(report_dir / '.coverage') > 50:
        # Check if the .coverage data file is larger than the base file,
        # because coverage combine will always at least make the "empty" data
        # file even when there isn't any data to be combined.
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running "
            "`paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
        return

    # Generate the coverage.py XML report
    sh("coverage xml --rcfile={}".format(rcfile))
    # Generate the coverage.py HTML report
    sh("coverage html --rcfile={}".format(rcfile))
    call_task('diff_coverage', options=dict(options))

@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts([
    ("compare_branch=", "b", "Branch to compare against, defaults to origin/master"),
])
def diff_coverage(options):
    """
    Build the diff coverage reports
    """
    compare_branch = getattr(options, 'compare_branch', 'origin/master')

    # Find all coverage XML files (both Python and JavaScript)
    xml_reports = []

    for filepath in Env.REPORT_DIR.walk():
        if filepath.basename() == 'coverage.xml':
            xml_reports.append(filepath)

    if not xml_reports:
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running "
            "`paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
    else:
        xml_report_str = ' '.join(xml_reports)
        diff_html_path = os.path.join(Env.REPORT_DIR, 'diff_coverage_combined.html')

        # Generate the diff coverage reports (HTML and console)
        sh(
            "diff-cover {xml_report_str} --compare-branch={compare_branch} "
            "--html-report {diff_html_path}".format(
                xml_report_str=xml_report_str,
                compare_branch=compare_branch,
                diff_html_path=diff_html_path,
            )
        )

        print "\n"
<|endoftext|>


<commit_before>__version__ = '0.1.2'
<commit_msg>Release 0.1.3<commit_after>__version__ = '0.1.3'
<|endoftext|>


<commit_before>class OptionsError(Exception):
    pass

class Bunch(dict):
    """A dictionary that provides attribute-style access."""

    def __repr__(self):
        keys = self.keys()
        keys.sort()
        args = ', '.join(['%s=%r' % (key, self[key]) for key in keys])
        return '%s(%s)' % (self.__class__.__name__, args)

    def __getitem__(self, key):
        item = dict.__getitem__(self, key)
        if callable(item):
            return item()
        return item

    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

    __setattr__ = dict.__setitem__

    def __delattr__(self, name):
        try:
            del self[name]
        except KeyError:
            raise AttributeError(name)

class Namespace(Bunch):
    """A Bunch that will search dictionaries contained within to find a value.
    The search order is set via the order() method. See the order method for
    more information about search order.
    """
    def __init__(self, d=None, **kw):
        self._sections = []
        self._ordering = None
        self.update(d, **kw)

    def order(self, *keys, **kw):
        """Set the search order for this namespace. The arguments
        should be the list of keys in the order you wish to search,
        or a dictionary/Bunch that you want to search.
        Keys that are left out will not be searched. If you pass in
        no arguments, then the default ordering will be used. (The default
        is to search the global space first, then in the order in
        which the sections were created.)

        If you pass in a key name that is not a section, that
        key will be silently removed from the list.

        Keyword arguments are:

        add_rest=False
            put the sections you list at the front of the search
            and add the remaining sections to the end
        """
        if not keys:
            self._ordering = None
            return

        order = []
        for item in keys:
            if isinstance(item, dict) or item in self._sections:
                order.append(item)

        if kw.get('add_rest'):
            # this is not efficient. do we care? probably not.
            for item in self._sections:
                if item not in order:
                    order.append(item)
        self._ordering = order

    def clear(self):
        self._ordering = None
        self._sections = []
        super(Namespace, self).clear()

    def setdotted(self, key, value):
        """Sets a namespace key, value pair where the key
        can use dotted notation to set sub-values. For example,
        the key "foo.bar" will set the "bar" value in the "foo"
        Bunch in this Namespace. If foo does not exist, it is created
        as a Bunch. If foo is a value, an OptionsError will be
        raised."""
        segments = key.split(".")
        obj = self
        segment = segments.pop(0)
        while segments:
            if segment not in obj:
                obj[segment] = Bunch()
            obj = obj[segment]
            if not isinstance(obj, dict):
                raise OptionsError("In setting option '%s', %s was already a value"
                                   % (key, segment))
            segment = segments.pop(0)
        obj[segment] = value

    def __setitem__(self, key, value):
        if isinstance(value, dict):
            self._sections.insert(0, key)
        super(Namespace, self).__setitem__(key, value)

    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default

    def __getitem__(self, key):
        order = self._ordering
        if order is None:
            order = self._sections
        try:
            return super(Namespace, self).__getitem__(key)
        except KeyError:
            pass
        for section in order:
            if isinstance(section, dict):
                try:
                    return section[key]
                except KeyError:
                    pass
            else:
                try:
                    return self[section][key]
                except KeyError:
                    pass
        raise KeyError("Key %s not found in namespace" % key)

    def __setattr__(self, key, value):
        if key.startswith("_"):
            object.__setattr__(self, key, value)
        else:
            self[key] = value

    def __delitem__(self, key):
        try:
            index = self._sections.index(key)
            del self._sections[index]
        except ValueError:
            pass
        super(Namespace, self).__delitem__(key)

    def update(self, d=None, **kw):
        """Update the namespace. This is less efficient than the standard
        dict.update but is necessary to keep track of the sections that we'll be
        searching."""
        items = []
        if d:
            # look up keys even though we call items
            # because that's what the dict.update
            # doc says
            if hasattr(d, 'keys'):
                items.extend(list(d.items()))
            else:
                items.extend(list(d))
        items.extend(list(kw.items()))
        for key, value in items:
            self[key] = value

    __call__ = update

    def setdefault(self, key, default):
        if not key in self:
            self[key] = default
            return default
        return self[key]
<commit_msg>Python3-compatible dict.keys() sort()ing (refs #106)<commit_after>class OptionsError(Exception):
    pass

class Bunch(dict):
    """A dictionary that provides attribute-style access."""

    def __repr__(self):
        keys = list(self.keys())
        keys.sort()
        args = ', '.join(['%s=%r' % (key, self[key]) for key in keys])
        return '%s(%s)' % (self.__class__.__name__, args)

    def __getitem__(self, key):
        item = dict.__getitem__(self, key)
        if callable(item):
            return item()
        return item

    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

    __setattr__ = dict.__setitem__

    def __delattr__(self, name):
        try:
            del self[name]
        except KeyError:
            raise AttributeError(name)

class Namespace(Bunch):
    """A Bunch that will search dictionaries contained within to find a value.
    The search order is set via the order() method. See the order method for
    more information about search order.
    """
    def __init__(self, d=None, **kw):
        self._sections = []
        self._ordering = None
        self.update(d, **kw)

    def order(self, *keys, **kw):
        """Set the search order for this namespace. The arguments
        should be the list of keys in the order you wish to search,
        or a dictionary/Bunch that you want to search.
        Keys that are left out will not be searched. If you pass in
        no arguments, then the default ordering will be used. (The default
        is to search the global space first, then in the order in
        which the sections were created.)

        If you pass in a key name that is not a section, that
        key will be silently removed from the list.

        Keyword arguments are:

        add_rest=False
            put the sections you list at the front of the search
            and add the remaining sections to the end
        """
        if not keys:
            self._ordering = None
            return

        order = []
        for item in keys:
            if isinstance(item, dict) or item in self._sections:
                order.append(item)

        if kw.get('add_rest'):
            # this is not efficient. do we care? probably not.
            for item in self._sections:
                if item not in order:
                    order.append(item)
        self._ordering = order

    def clear(self):
        self._ordering = None
        self._sections = []
        super(Namespace, self).clear()

    def setdotted(self, key, value):
        """Sets a namespace key, value pair where the key
        can use dotted notation to set sub-values. For example,
        the key "foo.bar" will set the "bar" value in the "foo"
        Bunch in this Namespace. If foo does not exist, it is created
        as a Bunch. If foo is a value, an OptionsError will be
        raised."""
        segments = key.split(".")
        obj = self
        segment = segments.pop(0)
        while segments:
            if segment not in obj:
                obj[segment] = Bunch()
            obj = obj[segment]
            if not isinstance(obj, dict):
                raise OptionsError("In setting option '%s', %s was already a value"
                                   % (key, segment))
            segment = segments.pop(0)
        obj[segment] = value

    def __setitem__(self, key, value):
        if isinstance(value, dict):
            self._sections.insert(0, key)
        super(Namespace, self).__setitem__(key, value)

    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default

    def __getitem__(self, key):
        order = self._ordering
        if order is None:
            order = self._sections
        try:
            return super(Namespace, self).__getitem__(key)
        except KeyError:
            pass
        for section in order:
            if isinstance(section, dict):
                try:
                    return section[key]
                except KeyError:
                    pass
            else:
                try:
                    return self[section][key]
                except KeyError:
                    pass
        raise KeyError("Key %s not found in namespace" % key)

    def __setattr__(self, key, value):
        if key.startswith("_"):
            object.__setattr__(self, key, value)
        else:
            self[key] = value

    def __delitem__(self, key):
        try:
            index = self._sections.index(key)
            del self._sections[index]
        except ValueError:
            pass
        super(Namespace, self).__delitem__(key)

    def update(self, d=None, **kw):
        """Update the namespace. This is less efficient than the standard
        dict.update but is necessary to keep track of the sections that we'll be
        searching."""
        items = []
        if d:
            # look up keys even though we call items
            # because that's what the dict.update
            # doc says
            if hasattr(d, 'keys'):
                items.extend(list(d.items()))
            else:
                items.extend(list(d))
        items.extend(list(kw.items()))
        for key, value in items:
            self[key] = value

    __call__ = update

    def setdefault(self, key, default):
        if not key in self:
            self[key] = default
            return default
        return self[key]
<|endoftext|>


<commit_before>from django.forms import CheckboxInput, CheckboxSelectMultiple, HiddenInput, RadioSelect, Textarea, TextInput, Select

from .cms_plugins import SPAPluginMixin

class BaseSPARenderer(object):
    """
    Some base data needs to be available for all plugins.
    """
    frontend_component_name = ''
    plugin_class = None

    def render(self, request, plugin, instance=None, editable=False):
        context = {
            'content': {},
            'type': self.frontend_component_name
        }

        if editable:
            # This is the structure of the template `cms/toolbar/plugin.html` that is used to register
            # the frontend editing.
            context['cms'] = [
                'cms-plugin-{}'.format(instance.id),
                {
                    'type': 'plugin',
                    'page_language': instance.language,
                    'placeholder_id': instance.placeholder.id,
                    'plugin_name': str(instance._meta.verbose_name),
                    'plugin_type': self.plugin_class.__class__.__name__,
                    'plugin_id': instance.id,
                    'plugin_language': instance.language,
                    'plugin_parent': instance.parent.id if instance.parent else None,
                    'plugin_order': instance.position,
                    'plugin_restriction': self.plugin_class.get_child_classes(instance.placeholder,
                                                                              instance.page) or [],
                    'plugin_parent_restriction': self.plugin_class.get_parent_classes(instance.placeholder,
                                                                                instance.page) or [],
                    'onClose': False,
                    'addPluginHelpTitle': 'Add plugin to {parent_plugin_name}'.format(
                        parent_plugin_name=instance.get_plugin_name()),
                    'urls': instance.get_action_urls()
                }
            ]

        return context

class MixinPluginRenderer(BaseSPARenderer):
    """
    Renders the plugins which use the SPAPluginMixin.
    """
    def __init__(self, plugin_class: SPAPluginMixin):
        super().__init__()
        self.plugin_class = plugin_class

    @property
    def frontend_component_name(self):
        return self.plugin_class.frontend_component_name

    def render(self, request, plugin, instance=None, editable=False):
        context = super(MixinPluginRenderer, self).render(request, plugin, instance, editable)
        return plugin.render_spa(request=request, context=context, instance=instance)

class SPAFormFieldWidgetRenderer(object):
    def __init__(self, form, field, name):
        self.form = form
        self.field = field
        self.name = name

    def render(self):
        context = {
            'id': self.name,
            'label': str(self.field.label),
            'component': self._get_component_name(),
            'val': self._get_value_for_field()
        }

        messages = self._get_messages_for_field()
        context['messages'] = messages

        state = self._get_state_for_field()
        context['state'] = state

        if hasattr(self.field.widget, 'input_type'):
            context['type'] = self.field.widget.input_type

        if self.field.widget.attrs.get('placeholder'):
            context['placeholder'] = str(self.field.widget.attrs['placeholder'])

        if self.field.widget.attrs.get('spa_attrs'):
            context.update(self.field.widget.attrs['spa_attrs'])

        try:
            widget_context = self.field.widget.render_spa(field=self.field)
        except:
            widget_context = {}

        context.update(widget_context)

        return context

    def _get_component_name(self):
        widget_class = type(self.field.widget)

        if issubclass(widget_class, TextInput):
            return 'cmp-form-field-input'
        elif issubclass(widget_class, CheckboxInput):
            return 'cmp-form-field-bool'
        elif issubclass(widget_class, CheckboxSelectMultiple):
            return 'cmp-form-field-bool'
        elif issubclass(widget_class, RadioSelect):
            return 'cmp-form-field-bool'
        elif issubclass(type(self.field.widget), Textarea):
            return 'cmp-form-field-textarea'
        elif issubclass(type(self.field.widget), Select):
            return 'cmp-form-field-select'
        elif issubclass(type(self.field.widget), HiddenInput):
            return 'cmp-form-field-hidden'
        else:
            return ''

    def _get_value_for_field(self):
        if hasattr(self.form, 'cleaned_data') and self.name in self.form.cleaned_data.keys():
            return str(self.form.cleaned_data[self.name])
        elif self.name in self.form.data.keys():
            return str(self.form.data[self.name])
        elif self.name in self.form.initial.keys():
            return self.form.initial[self.name]
        return ''

    def _get_messages_for_field(self):
        messages = {}

        if self.field.help_text:
            messages['info'] = self.field.help_text

        if self.name in self.form.errors.keys():
            messages['error'] = [str(error.message) for error in self.form.errors[self.name].data]

        return messages

    def _get_state_for_field(self):
        state = {}

        if self.field.required:
            state['required'] = True

        if hasattr(self.field, 'is_disabled') and self.field.is_disabled:
            state['disabled'] = True

        # Add errors
        if self.name in self.form.errors.keys():
            state['error'] = True

        return state
<commit_msg>Add SelectMultiple field as checkbox<commit_after>from django.forms import (CheckboxInput, CheckboxSelectMultiple, HiddenInput, RadioSelect, Textarea, TextInput, Select,
                          SelectMultiple)

from .cms_plugins import SPAPluginMixin

class BaseSPARenderer(object):
    """
    Some base data needs to be available for all plugins.
    """
    frontend_component_name = ''
    plugin_class = None

    def render(self, request, plugin, instance=None, editable=False):
        context = {
            'content': {},
            'type': self.frontend_component_name
        }

        if editable:
            # This is the structure of the template `cms/toolbar/plugin.html` that is used to register
            # the frontend editing.
            context['cms'] = [
                'cms-plugin-{}'.format(instance.id),
                {
                    'type': 'plugin',
                    'page_language': instance.language,
                    'placeholder_id': instance.placeholder.id,
                    'plugin_name': str(instance._meta.verbose_name),
                    'plugin_type': self.plugin_class.__class__.__name__,
                    'plugin_id': instance.id,
                    'plugin_language': instance.language,
                    'plugin_parent': instance.parent.id if instance.parent else None,
                    'plugin_order': instance.position,
                    'plugin_restriction': self.plugin_class.get_child_classes(instance.placeholder,
                                                                              instance.page) or [],
                    'plugin_parent_restriction': self.plugin_class.get_parent_classes(instance.placeholder,
                                                                                instance.page) or [],
                    'onClose': False,
                    'addPluginHelpTitle': 'Add plugin to {parent_plugin_name}'.format(
                        parent_plugin_name=instance.get_plugin_name()),
                    'urls': instance.get_action_urls()
                }
            ]

        return context

class MixinPluginRenderer(BaseSPARenderer):
    """
    Renders the plugins which use the SPAPluginMixin.
    """
    def __init__(self, plugin_class: SPAPluginMixin):
        super().__init__()
        self.plugin_class = plugin_class

    @property
    def frontend_component_name(self):
        return self.plugin_class.frontend_component_name

    def render(self, request, plugin, instance=None, editable=False):
        context = super(MixinPluginRenderer, self).render(request, plugin, instance, editable)
        return plugin.render_spa(request=request, context=context, instance=instance)

class SPAFormFieldWidgetRenderer(object):
    def __init__(self, form, field, name):
        self.form = form
        self.field = field
        self.name = name

    def render(self):
        context = {
            'id': self.name,
            'label': str(self.field.label),
            'component': self._get_component_name(),
            'val': self._get_value_for_field()
        }

        messages = self._get_messages_for_field()
        context['messages'] = messages

        state = self._get_state_for_field()
        context['state'] = state

        if hasattr(self.field.widget, 'input_type'):
            context['type'] = self.field.widget.input_type

        if self.field.widget.attrs.get('placeholder'):
            context['placeholder'] = str(self.field.widget.attrs['placeholder'])

        if self.field.widget.attrs.get('spa_attrs'):
            context.update(self.field.widget.attrs['spa_attrs'])

        try:
            widget_context = self.field.widget.render_spa(field=self.field)
        except:
            widget_context = {}

        context.update(widget_context)

        return context

    def _get_component_name(self):
        widget_class = type(self.field.widget)

        if issubclass(widget_class, TextInput):
            return 'cmp-form-field-input'
        elif issubclass(widget_class, CheckboxInput):
            return 'cmp-form-field-bool'
        elif issubclass(widget_class, CheckboxSelectMultiple):
            return 'cmp-form-field-bool'
        elif issubclass(widget_class, RadioSelect):
            return 'cmp-form-field-bool'
        elif issubclass(type(self.field.widget), SelectMultiple):
            return 'cmp-form-field-checkbox'
        elif issubclass(type(self.field.widget), Textarea):
            return 'cmp-form-field-textarea'
        elif issubclass(type(self.field.widget), Select):
            return 'cmp-form-field-select'
        elif issubclass(type(self.field.widget), HiddenInput):
            return 'cmp-form-field-hidden'
        else:
            return ''

    def _get_value_for_field(self):
        if hasattr(self.form, 'cleaned_data') and self.name in self.form.cleaned_data.keys():
            return str(self.form.cleaned_data[self.name])
        elif self.name in self.form.data.keys():
            return str(self.form.data[self.name])
        elif self.name in self.form.initial.keys():
            return self.form.initial[self.name]
        return ''

    def _get_messages_for_field(self):
        messages = {}

        if self.field.help_text:
            messages['info'] = self.field.help_text

        if self.name in self.form.errors.keys():
            messages['error'] = [str(error.message) for error in self.form.errors[self.name].data]

        return messages

    def _get_state_for_field(self):
        state = {}

        if self.field.required:
            state['required'] = True

        if hasattr(self.field, 'is_disabled') and self.field.is_disabled:
            state['disabled'] = True

        # Add errors
        if self.name in self.form.errors.keys():
            state['error'] = True

        return state
<|endoftext|>


<commit_before>'''
This module is responsible for automatic processing of provider callback
data (asynchronous transaction updates).
'''
from __future__ import unicode_literals

from django.conf.urls import patterns, url
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
try:
    from django.db.transaction import atomic
except ImportError:
    def atomic(func):
        return func

from . import factory, get_payment_model, provider_factory

@csrf_exempt
@atomic
def process_data(request, token, provider=None):
    '''
    Calls process_data of an appropriate provider.

    Raises Http404 if variant does not exist.
    '''
    Payment = get_payment_model()
    payment = get_object_or_404(Payment, token=token)
    if provider:
        provider.payment = payment
    else:
        try:
            provider = factory(payment)
        except ValueError:
            raise Http404('No such payment')
    return provider.process_data(request)

@csrf_exempt
@atomic
def static_callback(request, variant):

    try:
        provider = provider_factory(variant)
    except ValueError:
        raise Http404('No such provider')

    token = provider.get_token_from_request(request)
    if not token:
        raise Http404('Invalid response')
    return process_data(request, token, provider)

urlpatterns = patterns(
    '',
    url(r'^process/(?P<token>[0-9a-z]{8}-[0-9a-z]{4}-'
        '[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})/$', process_data,
        name='process_payment'),
    url(r'^process/(?P<variant>[a-z-]+)/$', static_callback,
        name='static_process_payment'),)
<commit_msg>Remove usage of old function<commit_after>'''
This module is responsible for automatic processing of provider callback
data (asynchronous transaction updates).
'''
from __future__ import unicode_literals

from django.conf.urls import patterns, url
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
try:
    from django.db.transaction import atomic
except ImportError:
    def atomic(func):
        return func

from . import get_payment_model, provider_factory

@csrf_exempt
@atomic
def process_data(request, token, provider=None):
    '''
    Calls process_data of an appropriate provider.

    Raises Http404 if variant does not exist.
    '''
    Payment = get_payment_model()
    payment = get_object_or_404(Payment, token=token)
    if provider:
        provider.payment = payment
    else:
        try:
            provider = provider_factory(payment.variant)
        except ValueError:
            raise Http404('No such payment')
    return provider.process_data(request)

@csrf_exempt
@atomic
def static_callback(request, variant):

    try:
        provider = provider_factory(variant)
    except ValueError:
        raise Http404('No such provider')

    token = provider.get_token_from_request(request)
    if not token:
        raise Http404('Invalid response')
    return process_data(request, token, provider)

urlpatterns = patterns(
    '',
    url(r'^process/(?P<token>[0-9a-z]{8}-[0-9a-z]{4}-'
        '[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})/$', process_data,
        name='process_payment'),
    url(r'^process/(?P<variant>[a-z-]+)/$', static_callback,
        name='static_process_payment'),)
<|endoftext|>


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

import sys, os
root = os.path.dirname(__file__)
paths = (
    os.path.join(root),
    os.path.join(root, "djangopeople", "lib"),
)
for path in paths:
    if not path in sys.path:
        sys.path.insert(0, path)

from django.core.management import execute_manager
try:
    import settings # Assumed to be in the same directory.
except ImportError:
    import sys
    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
    sys.exit(1)

if __name__ == "__main__":
    execute_manager(settings)
<commit_msg>fixed paths in manage.py<commit_after>#!/usr/bin/env python

import sys, os
root = os.path.dirname(__file__)
paths = (
    os.path.join(root, '../lib'),
    os.path.join(root, '..'),
)
for path in paths:
    if not path in sys.path:
        sys.path.insert(0, path)

from django.core.management import execute_manager
try:
    import settings # Assumed to be in the same directory.
except ImportError:
    import sys
    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
    sys.exit(1)

if __name__ == "__main__":
    execute_manager(settings)
<|endoftext|>