<commit_before>"""Serializers for the tracking app."""
from datetime import date, timedelta

from django.contrib.auth import get_user_model
from django.db.models import BooleanField, Case, Q, When
from django.utils.duration import duration_string
from django.utils.translation import gettext_lazy as _
from rest_framework_json_api import relations, serializers
from rest_framework_json_api.relations import ResourceRelatedField
from rest_framework_json_api.serializers import (
    ModelSerializer,
    Serializer,
    SerializerMethodField,
    ValidationError,
)

from timed.employment.models import AbsenceType, Employment, PublicHoliday
from timed.employment.relations import CurrentUserResourceRelatedField
from timed.projects.models import Customer, Project, Task
from timed.serializers import TotalTimeRootMetaMixin
from timed.tracking import models

class ActivitySerializer(ModelSerializer):
    """Activity serializer."""

    user = CurrentUserResourceRelatedField()

    included_serializers = {
        "task": "timed.projects.serializers.TaskSerializer",
        "user": "timed.employment.serializers.UserSerializer",
    }

    def validate(self, data):
        """Validate the activity block.

        Ensure that a user can only have one activity
        which doesn't end before it started.
        """
        instance = self.instance
        from_time = data.get("from_time", instance and instance.from_time)
        to_time = data.get("to_time", instance and instance.to_time)
        user = instance and instance.user or data["user"]

        def validate_running_activity():
            if activity.filter(to_time__isnull=True).exists():
                raise ValidationError(_("A user can only have one active activity"))

        # validate that there is only one active activity
        activity = models.Activity.objects.filter(user=user)
        # if the request creates a new activity
        if instance is None and to_time is None:
            validate_running_activity()
        # if the request mutates an existsting activity
        if instance and instance.to_time and to_time is None:
            validate_running_activity()

        # validate that to is not before from
        if to_time is not None and to_time < from_time:
            raise ValidationError(_("An activity block may not end before it starts."))

        return data

    class Meta:
        """Meta information for the activity serializer."""

        model = models.Activity
        fields = "__all__"

class AttendanceSerializer(ModelSerializer):
    """Attendance serializer."""

    user = CurrentUserResourceRelatedField()

    included_serializers = {"user": "timed.employment.serializers.UserSerializer"}

    class Meta:
        """Meta information for the attendance serializer."""

        model = models.Attendance
        fields = ["date", "from_time", "to_time", "user"]

class ReportSerializer(TotalTimeRootMetaMixin, ModelSerializer):
    """Report serializer."""

    task = ResourceRelatedField(queryset=Task.objects.all())
    activity = ResourceRelatedField(
        queryset=models.Activity.objects.all(), allow_null=True, required=False
    )
    user = CurrentUserResourceRelatedField()
    verified_by = ResourceRelatedField(
        queryset=get_user_model().objects, required=False, allow_null=True
    )

    included_serializers = {
        "task": "timed.projects.serializers.TaskSerializer",
        "user": "timed.employment.serializers.UserSerializer",
        "verified_by": "timed.employment.serializers.UserSerializer",
    }

    def _validate_owner_only(self, value, field):
        if self.instance is not None:
            user = self.context["request"].user
            owner = self.instance.user
            if getattr(self.instance, field) != value and user != owner:
                raise ValidationError(_(f"Only owner may change {field}"))

        return value

    def validate_date(self, value):
        """Only owner is allowed to change date."""
        return self._validate_owner_only(value, "date")

    def validate_duration(self, value):
        """Only owner is allowed to change duration."""
        return self._validate_owner_only(value, "duration")

    def validate(self, data):
        """
        Validate that verified by is only set by reviewer or superuser.

        Additionally make sure a report is cannot be verified_by if is still
        needs review.

        External employees with manager or reviewer role may not create reports.
        """

        user = self.context["request"].user
        current_verified_by = self.instance and self.instance.verified_by
        new_verified_by = data.get("verified_by")
        task = data.get("task") or self.instance.task
        review = data.get("review")
        billed = data.get("billed")
        is_reviewer = (
            user.is_superuser
            or Task.objects.filter(
                Q(
                    task_assignees__user=user,
                    task_assignees__is_reviewer=True,
                    task_assignees__task=task,
                )
                | Q(
                    project__project_assignees__user=user,
                    project__project_assignees__is_reviewer=True,
                    project__project_assignees__project=task.project,
                )
                | Q(
                    project__customer__customer_assignees__user=user,
                    project__customer__customer_assignees__is_reviewer=True,
                    project__customer__customer_assignees__customer=task.project.customer,
                )
            ).exists()
        )

        if new_verified_by != current_verified_by:
            if not is_reviewer:
                raise ValidationError(_("Only reviewer may verify reports."))

            if new_verified_by is not None and new_verified_by != user:
                raise ValidationError(_("You may only verifiy with your own user"))

            if new_verified_by and review:  # pragma: no cover
                raise ValidationError(
                    _("Report can't both be set as `review` and `verified`.")
                )

        if not user.is_accountant and billed:
            raise ValidationError(_("Only accountants may bill reports."))

        # update billed flag on created reports
        if not self.instance or billed is None:
            data["billed"] = task.project.billed

        # update billed flag on reports that are being moved to a different project
        # according to the billed flag of the project the report was moved to
        if self.instance and data.get("task"):
            if self.instance.task.id != data.get("task").id:
                data["billed"] = data.get("task").project.billed

        current_employment = Employment.objects.get_at(user=user, date=date.today())

        if (
            self.context["request"].method == "POST"
            and current_employment.is_external
            and Task.objects.filter(
                Q(
                    task_assignees__user=user,
                    task_assignees__is_reviewer=True,
                )
                | Q(
                    project__project_assignees__user=user,
                    project__project_assignees__is_reviewer=True,
                )
                | Q(
                    project__customer__customer_assignees__user=user,
                    project__customer__customer_assignees__is_reviewer=True,
                )
                | Q(
                    task_assignees__user=user,
                    task_assignees__is_manager=True,
                )
                | Q(
                    project__project_assignees__user=user,
                    project__project_assignees__is_manager=True,
                )
                | Q(
                    project__customer__customer_assignees__user=user,
                    project__customer__customer_assignees__is_manager=True,
                )
            ).exists()
        ):
            raise ValidationError(
                "User is not a resource on the corresponding task, project or customer"
            )
        return data

    class Meta:
        model = models.Report
        fields = [
            "comment",
            "date",
            "duration",
            "review",
            "not_billable",
            "billed",
            "task",
            "activity",
            "user",
            "verified_by",
        ]

class ReportBulkSerializer(Serializer):
    """Serializer used for bulk updates of reports."""

    task = ResourceRelatedField(
        queryset=Task.objects.all(), allow_null=True, required=False
    )
    comment = serializers.CharField(allow_null=True, required=False)
    review = serializers.BooleanField(required=False, allow_null=True)
    not_billable = serializers.BooleanField(required=False, allow_null=True)
    billed = serializers.BooleanField(required=False, allow_null=True)
    verified = serializers.BooleanField(required=False, allow_null=True)

    class Meta:
        resource_name = "report-bulks"

class ReportIntersectionSerializer(Serializer):
    """
    Serializer of report intersections.

    Serializes a representation of all fields which are the same
    in given Report objects. If values of one field are not the same
    in all objects it will be represented as None.

    Serializer expect instance to have a queryset value.
    """

    customer = relations.SerializerMethodResourceRelatedField(
        source="get_customer", model=Customer, read_only=True
    )
    project = relations.SerializerMethodResourceRelatedField(
        source="get_project", model=Project, read_only=True
    )
    task = relations.SerializerMethodResourceRelatedField(
        source="get_task", model=Task, read_only=True
    )
    comment = SerializerMethodField()
    review = SerializerMethodField()
    not_billable = SerializerMethodField()
    billed = SerializerMethodField()
    verified = SerializerMethodField()

    def _intersection(self, instance, field, model=None):
        """Get intersection of given field.

        :return: Returns value of field if objects have same value;
                 otherwise None
        """
        value = None
        queryset = instance["queryset"]
        values = queryset.values(field).distinct()
        if values.count() == 1:
            value = values.first()[field]
            if model:
                value = model.objects.get(pk=value)

        return value

    def get_customer(self, instance):
        return self._intersection(instance, "task__project__customer", Customer)

    def get_project(self, instance):
        return self._intersection(instance, "task__project", Project)

    def get_task(self, instance):
        return self._intersection(instance, "task", Task)

    def get_comment(self, instance):
        return self._intersection(instance, "comment")

    def get_review(self, instance):
        return self._intersection(instance, "review")

    def get_not_billable(self, instance):
        return self._intersection(instance, "not_billable")

    def get_billed(self, instance):
        return self._intersection(instance, "billed")

    def get_verified(self, instance):
        queryset = instance["queryset"]
        queryset = queryset.annotate(
            verified=Case(
                When(verified_by_id__isnull=True, then=False),
                default=True,
                output_field=BooleanField(),
            )
        )
        instance["queryset"] = queryset
        return self._intersection(instance, "verified")

    def get_root_meta(self, resource, many):
        """Add number of results to meta."""
        queryset = self.instance["queryset"]
        return {"count": queryset.count()}

    included_serializers = {
        "customer": "timed.projects.serializers.CustomerSerializer",
        "project": "timed.projects.serializers.ProjectSerializer",
        "task": "timed.projects.serializers.TaskSerializer",
    }

    class Meta:
        resource_name = "report-intersections"

class AbsenceSerializer(ModelSerializer):
    """Absence serializer."""

    duration = SerializerMethodField(source="get_duration")
    type = ResourceRelatedField(queryset=AbsenceType.objects.all())
    user = CurrentUserResourceRelatedField()

    included_serializers = {
        "user": "timed.employment.serializers.UserSerializer",
        "type": "timed.employment.serializers.AbsenceTypeSerializer",
    }

    def get_duration(self, instance):
        try:
            employment = Employment.objects.get_at(instance.user, instance.date)
        except Employment.DoesNotExist:
            # absence is invalid if no employment exists on absence date
            return duration_string(timedelta())

        return duration_string(instance.calculate_duration(employment))

    def validate_date(self, value):
        """Only owner is allowed to change date."""
        if self.instance is not None:
            user = self.context["request"].user
            owner = self.instance.user
            if self.instance.date != value and user != owner:
                raise ValidationError(_("Only owner may change date"))

        return value

    def validate_type(self, value):
        """Only owner is allowed to change type."""
        if self.instance is not None:
            user = self.context["request"].user
            owner = self.instance.user
            if self.instance.date != value and user != owner:
                raise ValidationError(_("Only owner may change absence type"))

        return value

    def validate(self, data):
        """Validate the absence data.

        An absence should not be created on a public holiday or a weekend.

        :returns: The validated data
        :rtype:   dict
        """
        instance = self.instance
        user = data.get("user", instance and instance.user)
        try:
            location = Employment.objects.get_at(user, data.get("date")).location
        except Employment.DoesNotExist:  # pragma: no cover
            raise ValidationError(
                _("You can't create an absence on an unemployed day.")
            )

        if PublicHoliday.objects.filter(
            location_id=location.id, date=data.get("date")
        ).exists():
            raise ValidationError(_("You can't create an absence on a public holiday"))

        workdays = [int(day) for day in location.workdays]
        if data.get("date").isoweekday() not in workdays:
            raise ValidationError(_("You can't create an absence on a weekend"))

        return data

    class Meta:
        """Meta information for the absence serializer."""

        model = models.Absence
        fields = ["comment", "date", "duration", "type", "user"]
<commit_msg>feat: include user in report-intersection<commit_after>"""Serializers for the tracking app."""
from datetime import date, timedelta

from django.contrib.auth import get_user_model
from django.db.models import BooleanField, Case, Q, When
from django.utils.duration import duration_string
from django.utils.translation import gettext_lazy as _
from rest_framework_json_api import relations, serializers
from rest_framework_json_api.relations import ResourceRelatedField
from rest_framework_json_api.serializers import (
    ModelSerializer,
    Serializer,
    SerializerMethodField,
    ValidationError,
)

from timed.employment.models import AbsenceType, Employment, PublicHoliday, User
from timed.employment.relations import CurrentUserResourceRelatedField
from timed.projects.models import Customer, Project, Task
from timed.serializers import TotalTimeRootMetaMixin
from timed.tracking import models

class ActivitySerializer(ModelSerializer):
    """Activity serializer."""

    user = CurrentUserResourceRelatedField()

    included_serializers = {
        "task": "timed.projects.serializers.TaskSerializer",
        "user": "timed.employment.serializers.UserSerializer",
    }

    def validate(self, data):
        """Validate the activity block.

        Ensure that a user can only have one activity
        which doesn't end before it started.
        """
        instance = self.instance
        from_time = data.get("from_time", instance and instance.from_time)
        to_time = data.get("to_time", instance and instance.to_time)
        user = instance and instance.user or data["user"]

        def validate_running_activity():
            if activity.filter(to_time__isnull=True).exists():
                raise ValidationError(_("A user can only have one active activity"))

        # validate that there is only one active activity
        activity = models.Activity.objects.filter(user=user)
        # if the request creates a new activity
        if instance is None and to_time is None:
            validate_running_activity()
        # if the request mutates an existsting activity
        if instance and instance.to_time and to_time is None:
            validate_running_activity()

        # validate that to is not before from
        if to_time is not None and to_time < from_time:
            raise ValidationError(_("An activity block may not end before it starts."))

        return data

    class Meta:
        """Meta information for the activity serializer."""

        model = models.Activity
        fields = "__all__"

class AttendanceSerializer(ModelSerializer):
    """Attendance serializer."""

    user = CurrentUserResourceRelatedField()

    included_serializers = {"user": "timed.employment.serializers.UserSerializer"}

    class Meta:
        """Meta information for the attendance serializer."""

        model = models.Attendance
        fields = ["date", "from_time", "to_time", "user"]

class ReportSerializer(TotalTimeRootMetaMixin, ModelSerializer):
    """Report serializer."""

    task = ResourceRelatedField(queryset=Task.objects.all())
    activity = ResourceRelatedField(
        queryset=models.Activity.objects.all(), allow_null=True, required=False
    )
    user = CurrentUserResourceRelatedField()
    verified_by = ResourceRelatedField(
        queryset=get_user_model().objects, required=False, allow_null=True
    )

    included_serializers = {
        "task": "timed.projects.serializers.TaskSerializer",
        "user": "timed.employment.serializers.UserSerializer",
        "verified_by": "timed.employment.serializers.UserSerializer",
    }

    def _validate_owner_only(self, value, field):
        if self.instance is not None:
            user = self.context["request"].user
            owner = self.instance.user
            if getattr(self.instance, field) != value and user != owner:
                raise ValidationError(_(f"Only owner may change {field}"))

        return value

    def validate_date(self, value):
        """Only owner is allowed to change date."""
        return self._validate_owner_only(value, "date")

    def validate_duration(self, value):
        """Only owner is allowed to change duration."""
        return self._validate_owner_only(value, "duration")

    def validate(self, data):
        """
        Validate that verified by is only set by reviewer or superuser.

        Additionally make sure a report is cannot be verified_by if is still
        needs review.

        External employees with manager or reviewer role may not create reports.
        """

        user = self.context["request"].user
        current_verified_by = self.instance and self.instance.verified_by
        new_verified_by = data.get("verified_by")
        task = data.get("task") or self.instance.task
        review = data.get("review")
        billed = data.get("billed")
        is_reviewer = (
            user.is_superuser
            or Task.objects.filter(
                Q(
                    task_assignees__user=user,
                    task_assignees__is_reviewer=True,
                    task_assignees__task=task,
                )
                | Q(
                    project__project_assignees__user=user,
                    project__project_assignees__is_reviewer=True,
                    project__project_assignees__project=task.project,
                )
                | Q(
                    project__customer__customer_assignees__user=user,
                    project__customer__customer_assignees__is_reviewer=True,
                    project__customer__customer_assignees__customer=task.project.customer,
                )
            ).exists()
        )

        if new_verified_by != current_verified_by:
            if not is_reviewer:
                raise ValidationError(_("Only reviewer may verify reports."))

            if new_verified_by is not None and new_verified_by != user:
                raise ValidationError(_("You may only verifiy with your own user"))

            if new_verified_by and review:  # pragma: no cover
                raise ValidationError(
                    _("Report can't both be set as `review` and `verified`.")
                )

        if not user.is_accountant and billed:
            raise ValidationError(_("Only accountants may bill reports."))

        # update billed flag on created reports
        if not self.instance or billed is None:
            data["billed"] = task.project.billed

        # update billed flag on reports that are being moved to a different project
        # according to the billed flag of the project the report was moved to
        if self.instance and data.get("task"):
            if self.instance.task.id != data.get("task").id:
                data["billed"] = data.get("task").project.billed

        current_employment = Employment.objects.get_at(user=user, date=date.today())

        if (
            self.context["request"].method == "POST"
            and current_employment.is_external
            and Task.objects.filter(
                Q(
                    task_assignees__user=user,
                    task_assignees__is_reviewer=True,
                )
                | Q(
                    project__project_assignees__user=user,
                    project__project_assignees__is_reviewer=True,
                )
                | Q(
                    project__customer__customer_assignees__user=user,
                    project__customer__customer_assignees__is_reviewer=True,
                )
                | Q(
                    task_assignees__user=user,
                    task_assignees__is_manager=True,
                )
                | Q(
                    project__project_assignees__user=user,
                    project__project_assignees__is_manager=True,
                )
                | Q(
                    project__customer__customer_assignees__user=user,
                    project__customer__customer_assignees__is_manager=True,
                )
            ).exists()
        ):
            raise ValidationError(
                "User is not a resource on the corresponding task, project or customer"
            )
        return data

    class Meta:
        model = models.Report
        fields = [
            "comment",
            "date",
            "duration",
            "review",
            "not_billable",
            "billed",
            "task",
            "activity",
            "user",
            "verified_by",
        ]

class ReportBulkSerializer(Serializer):
    """Serializer used for bulk updates of reports."""

    task = ResourceRelatedField(
        queryset=Task.objects.all(), allow_null=True, required=False
    )
    comment = serializers.CharField(allow_null=True, required=False)
    review = serializers.BooleanField(required=False, allow_null=True)
    not_billable = serializers.BooleanField(required=False, allow_null=True)
    billed = serializers.BooleanField(required=False, allow_null=True)
    verified = serializers.BooleanField(required=False, allow_null=True)

    class Meta:
        resource_name = "report-bulks"

class ReportIntersectionSerializer(Serializer):
    """
    Serializer of report intersections.

    Serializes a representation of all fields which are the same
    in given Report objects. If values of one field are not the same
    in all objects it will be represented as None.

    Serializer expect instance to have a queryset value.
    """

    customer = relations.SerializerMethodResourceRelatedField(
        source="get_customer", model=Customer, read_only=True
    )
    project = relations.SerializerMethodResourceRelatedField(
        source="get_project", model=Project, read_only=True
    )
    task = relations.SerializerMethodResourceRelatedField(
        source="get_task", model=Task, read_only=True
    )
    user = relations.SerializerMethodResourceRelatedField(
        source="get_user", model=User, read_only=True
    )
    comment = SerializerMethodField()
    review = SerializerMethodField()
    not_billable = SerializerMethodField()
    billed = SerializerMethodField()
    verified = SerializerMethodField()

    def _intersection(self, instance, field, model=None):
        """Get intersection of given field.

        :return: Returns value of field if objects have same value;
                 otherwise None
        """
        value = None
        queryset = instance["queryset"]
        values = queryset.values(field).distinct()
        if values.count() == 1:
            value = values.first()[field]
            if model:
                value = model.objects.get(pk=value)

        return value

    def get_customer(self, instance):
        return self._intersection(instance, "task__project__customer", Customer)

    def get_project(self, instance):
        return self._intersection(instance, "task__project", Project)

    def get_task(self, instance):
        return self._intersection(instance, "task", Task)

    def get_user(self, instance):
        return self._intersection(instance, "user", User)

    def get_comment(self, instance):
        return self._intersection(instance, "comment")

    def get_review(self, instance):
        return self._intersection(instance, "review")

    def get_not_billable(self, instance):
        return self._intersection(instance, "not_billable")

    def get_billed(self, instance):
        return self._intersection(instance, "billed")

    def get_verified(self, instance):
        queryset = instance["queryset"]
        queryset = queryset.annotate(
            verified=Case(
                When(verified_by_id__isnull=True, then=False),
                default=True,
                output_field=BooleanField(),
            )
        )
        instance["queryset"] = queryset
        return self._intersection(instance, "verified")

    def get_root_meta(self, resource, many):
        """Add number of results to meta."""
        queryset = self.instance["queryset"]
        return {"count": queryset.count()}

    included_serializers = {
        "customer": "timed.projects.serializers.CustomerSerializer",
        "project": "timed.projects.serializers.ProjectSerializer",
        "task": "timed.projects.serializers.TaskSerializer",
        "user": "timed.employment.serializers.UserSerializer",
    }

    class Meta:
        resource_name = "report-intersections"

class AbsenceSerializer(ModelSerializer):
    """Absence serializer."""

    duration = SerializerMethodField(source="get_duration")
    type = ResourceRelatedField(queryset=AbsenceType.objects.all())
    user = CurrentUserResourceRelatedField()

    included_serializers = {
        "user": "timed.employment.serializers.UserSerializer",
        "type": "timed.employment.serializers.AbsenceTypeSerializer",
    }

    def get_duration(self, instance):
        try:
            employment = Employment.objects.get_at(instance.user, instance.date)
        except Employment.DoesNotExist:
            # absence is invalid if no employment exists on absence date
            return duration_string(timedelta())

        return duration_string(instance.calculate_duration(employment))

    def validate_date(self, value):
        """Only owner is allowed to change date."""
        if self.instance is not None:
            user = self.context["request"].user
            owner = self.instance.user
            if self.instance.date != value and user != owner:
                raise ValidationError(_("Only owner may change date"))

        return value

    def validate_type(self, value):
        """Only owner is allowed to change type."""
        if self.instance is not None:
            user = self.context["request"].user
            owner = self.instance.user
            if self.instance.date != value and user != owner:
                raise ValidationError(_("Only owner may change absence type"))

        return value

    def validate(self, data):
        """Validate the absence data.

        An absence should not be created on a public holiday or a weekend.

        :returns: The validated data
        :rtype:   dict
        """
        instance = self.instance
        user = data.get("user", instance and instance.user)
        try:
            location = Employment.objects.get_at(user, data.get("date")).location
        except Employment.DoesNotExist:  # pragma: no cover
            raise ValidationError(
                _("You can't create an absence on an unemployed day.")
            )

        if PublicHoliday.objects.filter(
            location_id=location.id, date=data.get("date")
        ).exists():
            raise ValidationError(_("You can't create an absence on a public holiday"))

        workdays = [int(day) for day in location.workdays]
        if data.get("date").isoweekday() not in workdays:
            raise ValidationError(_("You can't create an absence on a weekend"))

        return data

    class Meta:
        """Meta information for the absence serializer."""

        model = models.Absence
        fields = ["comment", "date", "duration", "type", "user"]
<|endoftext|>


<commit_before>from Timeseries import TimeSeries
import numpy as np

class ArrayTimeSeries(TimeSeries):
    """
    It is a new class ArrayTimeSeries which inherits from TimeSeries
    class and uses numpy.array to store the data internally.

    Parameters
    ----------
    values : a sequence
    data used to populate time series instance.
    times  : a sequence (optional)
    time associated with each observation in `values`.

    >>> threes=range(0,1000,3)
    >>> ap=ArrayTimeSeries(threes)
    >>> ap[0]=999
    >>> ap[0]
    array([  0, 999])
    >>> ap
    ArrayTimeSeries(Length: 334, Times: range(0, 334), Values: array([[  0, ...  [333, 999]]))
    >>> print(ap)
    ArrayTimeSeries with 334 elements (Times: range(0, 334), Values: array([[  0, ...  [333, 999]]))

    Now test non-uniform time series
    >>> a = ArrayTimeSeries(values=[0,5,10,8,7], times=[1,2.5,3,3.5,4])
    >>> a
    ArrayTimeSeries(Length: 5, Times: [1, 2.5, 3, ...], Values: array([[  1. ... 4. ,   7. ]]))
    >>> print(a)
    ArrayTimeSeries with 5 elements (Times: [1, 2.5, 3, ...], Values: array([[  1. ... 4. ,   7. ]]))

    """
    def __init__(self,values,times=None):
        TimeSeries.__init__(self,values,times)
        self._values=np.column_stack((self._times, values))

    def __getitem__(self,time):
        try:
            return self._values[self._times.index(time),]
        except IndexError:
            raise("Index out of bounds")

    def __setitem__(self,time,value):
        try:
            self._values[self._times.index(time),1] = value
        except IndexError:
            raise("Index out of bounds")

    def __len__(self):
        return len(self._values)

    def itertimes(self):
        super().itertimes()

    def iteritems(self):
        for i,j in self._values:
            yield i,j
<commit_msg>Change itertimes return from None to generator<commit_after>from Timeseries import TimeSeries
import numpy as np

class ArrayTimeSeries(TimeSeries):
    """
    It is a new class ArrayTimeSeries which inherits from TimeSeries
    class and uses numpy.array to store the data internally.

    Parameters
    ----------
    values : a sequence
    data used to populate time series instance.
    times  : a sequence (optional)
    time associated with each observation in `values`.

    >>> threes=range(0,1000,3)
    >>> ap=ArrayTimeSeries(threes)
    >>> ap[0]=999
    >>> ap[0]
    array([  0, 999])
    >>> ap
    ArrayTimeSeries(Length: 334, Times: range(0, 334), Values: array([[  0, ...  [333, 999]]))
    >>> print(ap)
    ArrayTimeSeries with 334 elements (Times: range(0, 334), Values: array([[  0, ...  [333, 999]]))

    Now test non-uniform time series
    >>> a = ArrayTimeSeries(values=[0,5,10,8,7], times=[1,2.5,3,3.5,4])
    >>> a
    ArrayTimeSeries(Length: 5, Times: [1, 2.5, 3, ...], Values: array([[  1. ... 4. ,   7. ]]))
    >>> print(a)
    ArrayTimeSeries with 5 elements (Times: [1, 2.5, 3, ...], Values: array([[  1. ... 4. ,   7. ]]))

    """
    def __init__(self,values,times=None):
        TimeSeries.__init__(self,values,times)
        self._values=np.column_stack((self._times, values))

    def __getitem__(self,time):
        try:
            return self._values[self._times.index(time),]
        except IndexError:
            raise("Index out of bounds")

    def __setitem__(self,time,value):
        try:
            self._values[self._times.index(time),1] = value
        except IndexError:
            raise("Index out of bounds")

    def __len__(self):
        return len(self._values)

    def itertimes(self):
        return super().itertimes()

    def iteritems(self):
        for i,j in self._values:
            yield i,j
<|endoftext|>


<commit_before>from Timeseries import TimeSeries
import numpy as np

class ArrayTimeSeries(TimeSeries):
    """
    It is a new class ArrayTimeSeries which inherits from TimeSeries
    class and uses numpy arrays to store the data internally.

    Parameters
    ----------
    values : a sequence- data used to populate time series instance.
    times  : a sequence- time associated with each observation in `values`.

    >>> threes=range(0,1000,3)
    >>> times = range(0,1000,1)
    >>> ap=ArrayTimeSeries(times,threes)
    >>> ap[0] = 999
    >>> ap[0]
    999
    >>> repr(ap)
    'ArrayTimeSeries(Length: 334, Times: array([  0,  ...97, 998, 999]), Values: array([999,  ...93, 996, 999]))'
    >>> print(ap)
    ArrayTimeSeries with 334 elements (Times: array([  0,  ...97, 998, 999]), Values: array([999,  ...93, 996, 999]))
    >>> len(ap)
    334
    >>> ap = ap=ArrayTimeSeries([0,1,2,3],[5,6,7,8])
    >>> list(iter(ap))
    [5, 6, 7, 8]
    >>> list(ap.itertimes())
    [0, 1, 2, 3]
    >>> list(ap.iteritems())
    [(0, 5), (1, 6), (2, 7), (3, 8)]

    #Now test non-uniform time series
    >>> a = ArrayTimeSeries(times=[1,2.5,3,3.5,4],values=[0,5,10,8,7], )
    >>> a
    ArrayTimeSeries(Length: 5, Times: array([ 1. , ...,  3.5,  4. ]), Values: array([ 0,  5, 10,  8,  7]))
    >>> print(a)
    ArrayTimeSeries with 5 elements (Times: array([ 1. , ...,  3.5,  4. ]), Values: array([ 0,  5, 10,  8,  7]))

    """
    def __init__(self,times,values):
        TimeSeries.__init__(self,values,times)
        self._times = np.array(times)
        self._values = np.array(values)

    def __getitem__(self,index):
        try:
            return self._values[index]
        except IndexError:
            raise IndexError("Index out of bounds")

    def __setitem__(self,index,value):
        try:
            self._values[index] = value
        except IndexError:
            raise IndexError("Index out of bounds")

    def __len__(self):
        return super().__len__()

    def __iter__(self):
        return super().__iter__()

    def itertimes(self):
        return super().itertimes()

    def iteritems(self):
        return super().iteritems()

#threes=range(0,1000,3)
#times = range(0,1000,1)
#ap=ArrayTimeSeries(times,threes)
#ap[0] = 999
#ap[0]
##999
#print("HERE",repr(ap))
##ArrayTimeSeries(Length: 334, Times: array([  0,  ...97, 998, 999]), Values: array([999,  ...93, 996, 999]))
#print(ap)<commit_msg>Edited docstring description for class<commit_after>from Timeseries import TimeSeries
import numpy as np

class ArrayTimeSeries(TimeSeries):
    """
    Inherits from TimeSeries; uses numpy arrays to store time and values data internally.

    Parameters
    ----------
    values : a sequence- data used to populate time series instance.
    times  : a sequence- time associated with each observation in `values`.

    >>> threes=range(0,1000,3)
    >>> times = range(0,1000,1)
    >>> ap=ArrayTimeSeries(times,threes)
    >>> ap[0] = 999
    >>> ap[0]
    999
    >>> repr(ap)
    'ArrayTimeSeries(Length: 334, Times: array([  0,  ...97, 998, 999]), Values: array([999,  ...93, 996, 999]))'
    >>> print(ap)
    ArrayTimeSeries with 334 elements (Times: array([  0,  ...97, 998, 999]), Values: array([999,  ...93, 996, 999]))
    >>> len(ap)
    334
    >>> ap = ap=ArrayTimeSeries([0,1,2,3],[5,6,7,8])
    >>> list(iter(ap))
    [5, 6, 7, 8]
    >>> list(ap.itertimes())
    [0, 1, 2, 3]
    >>> list(ap.iteritems())
    [(0, 5), (1, 6), (2, 7), (3, 8)]

    #Now test non-uniform time series
    >>> a = ArrayTimeSeries(times=[1,2.5,3,3.5,4],values=[0,5,10,8,7], )
    >>> a
    ArrayTimeSeries(Length: 5, Times: array([ 1. , ...,  3.5,  4. ]), Values: array([ 0,  5, 10,  8,  7]))
    >>> print(a)
    ArrayTimeSeries with 5 elements (Times: array([ 1. , ...,  3.5,  4. ]), Values: array([ 0,  5, 10,  8,  7]))

    """
    def __init__(self,times,values):
        TimeSeries.__init__(self,values,times)
        self._times = np.array(times)
        self._values = np.array(values)

    def __getitem__(self,index):
        try:
            return self._values[index]
        except IndexError:
            raise IndexError("Index out of bounds")

    def __setitem__(self,index,value):
        try:
            self._values[index] = value
        except IndexError:
            raise IndexError("Index out of bounds")

    def __len__(self):
        return super().__len__()

    def __iter__(self):
        return super().__iter__()

    def itertimes(self):
        return super().itertimes()

    def iteritems(self):
        return super().iteritems()

#threes=range(0,1000,3)
#times = range(0,1000,1)
#ap=ArrayTimeSeries(times,threes)
#ap[0] = 999
#ap[0]
##999
#print("HERE",repr(ap))
##ArrayTimeSeries(Length: 334, Times: array([  0,  ...97, 998, 999]), Values: array([999,  ...93, 996, 999]))
#print(ap)
<|endoftext|>


<commit_before>""" Unit tests for grid_utils module. """

from datetime import datetime
import numpy as np

from tint import grid_utils
from tint.testing.sample_files import SAMPLE_GRID_FILE
import pyart

grid = pyart.io.read_grid(SAMPLE_GRID_FILE)

def test_parse_grid_datetime():
    dt = grid_utils.parse_grid_datetime(grid)
    assert(dt == datetime(2015, 7, 10, 18, 34, 6))

def test_get_grid_size():
    grid_size = grid_utils.get_grid_size(grid)
    assert(np.all(grid_size == np.array([500., 500., 500.])))
<commit_msg>TST: Assert style fix<commit_after>""" Unit tests for grid_utils module. """

from datetime import datetime
import numpy as np

from tint import grid_utils
from tint.testing.sample_files import SAMPLE_GRID_FILE
import pyart

grid = pyart.io.read_grid(SAMPLE_GRID_FILE)

def test_parse_grid_datetime():
    dt = grid_utils.parse_grid_datetime(grid)
    assert(dt == datetime(2015, 7, 10, 18, 34, 6))

def test_get_grid_size():
    grid_size = grid_utils.get_grid_size(grid)
    assert np.all(grid_size == np.array([500., 500., 500.]))
<|endoftext|>


<commit_before>import lib.rome.driver.database_driver
import riak
from riak.datatypes import Counter
from multiprocessing import Pool
import json

class RiakDriver(lib.rome.driver.database_driver.DatabaseDriverInterface):

    def __init__(self):
        self.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')

    def add_key(self, tablename, key):
        """"""
        pass

    def remove_key(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.delete("%s" % (key))

    def next_key(self, tablename):
        """"""
        bucket = self.riak_client.bucket_type('counters').bucket(tablename)
        counter = Counter(bucket, "next_key")
        counter.increment()
        counter.store()
        counter.reload()
        return counter.value

    def keys(self, tablename):
        """"""
        """Check if the current table contains keys."""
        bucket = self.riak_client.bucket(tablename)
        return bucket.get_keys()

    def put(self, tablename, key, value):
        """"""
        bucket = self.riak_client.bucket(tablename)
        fetched = bucket.new("%s" % (key), data=value)
        fetched.store()
        return fetched

    def get(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.get("%s" % (key)).data

    def getall(self, tablename):
        """"""
        keys = map(lambda x:str(x), self.keys(tablename))
        bucket = self.riak_client.bucket(tablename)
        result = map(lambda x:x.data, bucket.multiget(keys))
        return result

class MapReduceRiakDriver(lib.rome.driver.database_driver.DatabaseDriverInterface):

    def __init__(self):
        self.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')

    def add_key(self, tablename, key):
        """"""
        pass

    def remove_key(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.delete("%s-%s" % (tablename, key))

    def next_key(self, tablename):
        """"""
        bucket = self.riak_client.bucket_type('counters').bucket(tablename)
        counter = Counter(bucket, "next_key")
        counter.increment()
        counter.store()
        counter.reload()
        return counter.value

    def keys(self, tablename):
        """"""
        """Check if the current table contains keys."""
        mapReduce = riak.RiakMapReduce(self.riak_client)
        mapReduce.add_key_filter("starts_with", "%s-" % (tablename))
        mapReduce.map("function (v, keydata) { return [v.key]; }")
        results = mapReduce.run()
        return results

    def put(self, tablename, key, value):
        """"""
        bucket = self.riak_client.bucket(tablename)
        fetched = bucket.new("%s-%s" % (tablename, key), data=value)
        fetched.store()
        return fetched

    def get(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.get("%s-%s" % (tablename, key)).data

    def getall(self, tablename):
        """"""
        keys = map(lambda x:str(x), self.keys(tablename))
        if len(keys) > 0:
            mapReduce = riak.RiakMapReduce(self.riak_client)
            mapReduce.add(tablename, keys)
            mapReduce.map("function(v) {return [v.values[0].data]}")
            result = map(lambda x: json.loads(x), mapReduce.run())
        else:
            result = []
        return result<commit_msg>try a faster listing of keys in a buckets; (2)<commit_after>import lib.rome.driver.database_driver
import riak
from riak.datatypes import Counter
from multiprocessing import Pool
import json

class RiakDriver(lib.rome.driver.database_driver.DatabaseDriverInterface):

    def __init__(self):
        self.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')

    def add_key(self, tablename, key):
        """"""
        pass

    def remove_key(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.delete("%s" % (key))

    def next_key(self, tablename):
        """"""
        bucket = self.riak_client.bucket_type('counters').bucket(tablename)
        counter = Counter(bucket, "next_key")
        counter.increment()
        counter.store()
        counter.reload()
        return counter.value

    def keys(self, tablename):
        """"""
        """Check if the current table contains keys."""
        bucket = self.riak_client.bucket(tablename)
        return bucket.get_keys()

    def put(self, tablename, key, value):
        """"""
        bucket = self.riak_client.bucket(tablename)
        fetched = bucket.new("%s" % (key), data=value)
        fetched.store()
        return fetched

    def get(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.get("%s" % (key)).data

    def getall(self, tablename):
        """"""
        keys = map(lambda x:str(x), self.keys(tablename))
        bucket = self.riak_client.bucket(tablename)
        result = map(lambda x:x.data, bucket.multiget(keys))
        return result

class MapReduceRiakDriver(lib.rome.driver.database_driver.DatabaseDriverInterface):

    def __init__(self):
        self.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')

    def add_key(self, tablename, key):
        """"""
        pass

    def remove_key(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.delete("%s-%s" % (tablename, key))

    def next_key(self, tablename):
        """"""
        bucket = self.riak_client.bucket_type('counters').bucket(tablename)
        counter = Counter(bucket, "next_key")
        counter.increment()
        counter.store()
        counter.reload()
        return counter.value

    def keys(self, tablename):
        """"""
        """Check if the current table contains keys."""
        mapReduce = riak.RiakMapReduce(self.riak_client)
        mapReduce.add(tablename)
        mapReduce.add_key_filter("starts_with", "%s-" % (tablename))
        mapReduce.map("function (v, keydata) { return [v.key]; }")
        results = mapReduce.run()
        return results if results is not None else []

    def put(self, tablename, key, value):
        """"""
        bucket = self.riak_client.bucket(tablename)
        fetched = bucket.new("%s-%s" % (tablename, key), data=value)
        fetched.store()
        return fetched

    def get(self, tablename, key):
        """"""
        bucket = self.riak_client.bucket(tablename)
        return bucket.get("%s-%s" % (tablename, key)).data

    def getall(self, tablename):
        """"""
        keys = map(lambda x:str(x), self.keys(tablename))
        if len(keys) > 0:
            mapReduce = riak.RiakMapReduce(self.riak_client)
            mapReduce.add(tablename, keys)
            mapReduce.map("function(v) {return [v.values[0].data]}")
            result = map(lambda x: json.loads(x), mapReduce.run())
        else:
            result = []
        return result<|endoftext|>


<commit_before>from sparkperf.cluster import Cluster
import json
import re
import os
import sys
import time
import urllib2

class MesosCluster(Cluster):
    """
    Functionality for interacting with a already running Mesos Spark cluster.
    All the behavior for starting and stopping the cluster is not supported.
    """

    def __init__(self, spark_home, mesos_master, spark_conf_dir = None, commit_sha="unknown"):
        self.spark_home = spark_home
        self.mesos_master = mesos_master
        self.spark_conf_dir = spark_conf_dir
        self.commit_sha = commit_sha

        state_url = "http://" + os.path.join(mesos_master.strip("mesos://"), "state.json")
        resp = urllib2.urlopen(state_url)
        if resp.getcode() != 200:
            raise "Bad status code returned fetching state.json from mesos master"

        state = json.loads(resp.read())
        self.slaves = list(map((lambda slave: slave["hostname"]), state["slaves"]))

    def sync_spark(self):
        None

    def stop(self):
        None

    def start(self):
        None

    def ensure_spark_stopped_on_slaves(self):
        None

<commit_msg>Remove unused imports in mesos cluster<commit_after>from sparkperf.cluster import Cluster
import json
import os
import urllib2

class MesosCluster(Cluster):
    """
    Functionality for interacting with a already running Mesos Spark cluster.
    All the behavior for starting and stopping the cluster is not supported.
    """

    def __init__(self, spark_home, mesos_master, spark_conf_dir = None, commit_sha="unknown"):
        self.spark_home = spark_home
        self.mesos_master = mesos_master
        self.spark_conf_dir = spark_conf_dir
        self.commit_sha = commit_sha

        state_url = "http://" + os.path.join(mesos_master.strip("mesos://"), "state.json")
        resp = urllib2.urlopen(state_url)
        if resp.getcode() != 200:
            raise "Bad status code returned fetching state.json from mesos master"

        state = json.loads(resp.read())
        self.slaves = list(map((lambda slave: slave["hostname"]), state["slaves"]))

    def sync_spark(self):
        None

    def stop(self):
        None

    def start(self):
        None

    def ensure_spark_stopped_on_slaves(self):
        None

<|endoftext|>


<commit_before>import sys
import traceback

DEFAULT_PROMPT = "$ "

class CommandLineInterface(object):
    """
    Basic read-eval-print loop.

    :param prompt: (optional) the string which is printed before reading each
                   command from the terminal. Defaults to "$ ".
    """
    def __init__(self, prompt=None):
        self._prompt = prompt or DEFAULT_PROMPT

    @property
    def prompt(self):
        """
        The string which is printed before reading each command from the
        terminal.
        """
        return self._prompt

    def read(self):
        """Prompt the user and read the user input. Returns a string."""
        try:
            return raw_input(self.prompt)
        except EOFError:
            raise SystemExit()

    def eval(self, text):
        """Interpret and respond to user input. Optionally returns a string to
        print to standard out.

        :param text: the user's input
        """
        raise NotImplementedError()

    def output(self, msg):
        """Output a message.

        :param msg: a string to print to standard out
        """
        sys.stdout.write(msg)

    def error(self, msg):
        """Output an error.

        :param msg: a string to print to standard error
        """
        sys.stderr.write(msg)

    def interact(self, banner=None):
        """Interact with the user.

        :param banner: (optional) the banner to print before the first
                       interaction. Defaults to ``None``.
        """
        if banner:
            print(banner)
        while True:
            try:
                response = self.eval(self.read())
                if response is not None:
                    self.output(response)
            except SystemExit:
                break
            except:
                self.error(traceback.format_exc())
<commit_msg>fixes #3<commit_after>import sys
import traceback

DEFAULT_PROMPT = "$ "

class CommandLineInterface(object):
    """
    Basic read-eval-print loop.

    :param prompt: (optional) the string which is printed before reading each
                   command from the terminal. Defaults to "$ ".
    """
    def __init__(self, prompt=None):
        self._prompt = prompt or DEFAULT_PROMPT

    @property
    def prompt(self):
        """
        The string which is printed before reading each command from the
        terminal.
        """
        return self._prompt

    def read(self):
        """Prompt the user and read the user input. Returns a string."""
        try:
            line = raw_input(self.prompt)
            while line.endswith("\\"):
                line = line[:-1] + raw_input("> ")
            return line
        except EOFError:
            raise SystemExit()

    def eval(self, text):
        """Interpret and respond to user input. Optionally returns a string to
        print to standard out.

        :param text: the user's input
        """
        raise NotImplementedError()

    def output(self, msg):
        """Output a message.

        :param msg: a string to print to standard out
        """
        sys.stdout.write(msg)

    def error(self, msg):
        """Output an error.

        :param msg: a string to print to standard error
        """
        sys.stderr.write(msg)

    def interact(self, banner=None):
        """Interact with the user.

        :param banner: (optional) the banner to print before the first
                       interaction. Defaults to ``None``.
        """
        if banner:
            print(banner)
        while True:
            try:
                response = self.eval(self.read())
                if response is not None:
                    self.output(response)
            except SystemExit:
                break
            except:
                self.error(traceback.format_exc())
<|endoftext|>


<commit_before>"""
Module that provides classes for tree creation and handling.

Trees are powerful structures to sort a huge amount of data and to speed up
performing query requests on them significantly.
"""

from collections import Iterable

import numpy as np

__all__ = [
    "IntervalTree"
]

class IntervalTreeNode:
    """Helper class for IntervalTree.

    """
    def __init__(self, center_point, center, left, right):
        self.center_point = center_point
        self.center = np.asarray(center)
        self.left = left
        self.right = right

class IntervalTree:
    """Tree to implement fast 1-dimensional interval searches.

    Based on the description in Wikipedia
    (https://en.wikipedia.org/wiki/Interval_tree#Centered_interval_tree)
    and the GitHub repository by tylerkahn
    (https://github.com/tylerkahn/intervaltree-python).

    Examples:
        Check 1000 intervals on 1000 other intervals:

        >>> intervals = np.asarray([np.arange(1000)-0.5, np.arange(1000)+0.5]).T
        >>> tree = IntervalTree(intervals)
        >>> query_intervals = [[i-1, i+1] for i in range(1000)]
        >>> results = tree.query(query_intervals)

    """
    def __init__(self, intervals):
        """Creates an IntervalTree object.

        Args:
            intervals: A numpy array containing the intervals (list of two
                numbers).
        """
        # Check the intervals whether they are valid:

        self.left = np.min(intervals)
        self.right = np.max(intervals)

        # We want to return the indices of the intervals instead of their
        # actual bounds. But the original indices will be lost due resorting.
        # Hence, we add the original indices to the intervals themselves.
        indices = np.arange(intervals.shape[0]).reshape(intervals.shape[0], 1)
        indexed_intervals = np.hstack([intervals, indices])
        self.root = self._build_tree(np.sort(indexed_intervals, axis=0))

    def __contains__(self, item):
        if isinstance(item, (tuple, list)):
            return bool(self._query(item, self.root, check_extreme=True))
        else:
            return bool(self._query_point(item, self.root, check_extreme=True))

    def _build_tree(self, intervals):
        if not intervals.any():
            return None

        center_point = self._get_center(intervals)

        # Sort the intervals into bins
        center = intervals[(intervals[:, 0] <= center_point)
                           & (intervals[:, 1] >= center_point)]
        left = intervals[intervals[:, 1] < center_point]
        right = intervals[intervals[:, 0] > center_point]

        return IntervalTreeNode(
            center_point, center,
            self._build_tree(left), self._build_tree(right))

    @staticmethod
    def _get_center(intervals):
        return intervals[int(intervals.shape[0]/2), 0]

    @staticmethod
    def interval_overlaps(interval1, interval2):
        """Checks whether two interval overlap each other.

        Args:
            interval1: A tuple of two numbers: the lower and higher bound of the
                first interval.
            interval2: A tuple of two numbers: the lower and higher bound of the
                second interval.

        Returns:
            True if the interval overlap.
        """
        return interval1[0] <= interval2[0] <= interval1[1] or \
            interval1[0] <= interval2[1] <= interval1[1] or \
            (interval2[0] <= interval1[0] and interval2[1] >= interval1[1])

    @staticmethod
    def interval_contains(interval, point):
        """Checks whether a point lies in a interval.

        Args:
            interval: A tuple of two numbers: the lower and higher bound of the
                first interval.
            point: The point (just a number)

        Returns:
            True if point lies in the interval.
        """
        return interval[0] <= point <= interval[1]

    def query(self, intervals):
        """Find all overlaps between this tree and a list of intervals.

        Args:
            intervals: A list of intervals. Each interval is a tuple/list of
                two elements: its lower and higher boundary.

        Returns:
            List of lists which contain the overlapping intervals of this tree
            for each element in `intervals`.
        """
        return [self._query(interval, self.root, check_extreme=True)
                for interval in intervals]

    def _query(self, query_interval, node, check_extreme=False):
        # Check this special case: the bounds of the query interval lie outside
        # of the bounds of this tree:
        if (check_extreme
                and IntervalTree.interval_contains(query_interval, self.left)
                and IntervalTree.interval_contains(query_interval, self.right)):
            return [] # TODO: Return all intervals

        # Let's start with the centered intervals
        intervals = [int(interval[2]) for interval in node.center
                     if IntervalTree.interval_overlaps(interval, query_interval)]

        if query_interval[0] <= node.center_point and node.left is not None:
            intervals.extend(self._query(query_interval, node.left))

        if query_interval[1] >= node.center_point and node.right is not None:
            intervals.extend(self._query(query_interval, node.right))

        return intervals

    def query_points(self, points):
        """Find all intervals of this tree which contain one of those points.

        Args:
            points: A list of points.

        Returns:
            List of lists which contain the enclosing intervals of this tree
            for each element in `points`.
        """
        return [self._query_point(point, self.root, check_extreme=True)
                for point in points]

    def _query_point(self, point, node, check_extreme=False):
        # Check this special case: the query point lies outside of the bounds of
        # this tree:
        if check_extreme \
                and not IntervalTree.interval_contains((self.left, self.right), point):
            return []

        # Let's start with the centered intervals
        intervals = [int(interval[2])
                     for interval in node.center
                     if IntervalTree.interval_contains(interval, point)]

        if point < node.center_point and node.left is not None:
            intervals.extend(self._query_point(point, node))

        if point > node.center_point and node.right is not None:
            intervals.extend(self._query_point(point, node))

        return intervals
<commit_msg>Fix typos<commit_after>"""
Module that provides classes for tree creation and handling.

Trees are powerful structures to sort a huge amount of data and to speed up
performing query requests on them significantly.
"""

from collections import Iterable

import numpy as np

__all__ = [
    "IntervalTree"
]

class IntervalTreeNode:
    """Helper class for IntervalTree.

    """
    def __init__(self, center_point, center, left, right):
        self.center_point = center_point
        self.center = np.asarray(center)
        self.left = left
        self.right = right

class IntervalTree:
    """Tree to implement fast 1-dimensional interval searches.

    Based on the description in Wikipedia
    (https://en.wikipedia.org/wiki/Interval_tree#Centered_interval_tree)
    and the GitHub repository by tylerkahn
    (https://github.com/tylerkahn/intervaltree-python).

    Examples:
        Check 1000 intervals on 1000 other intervals:

    .. code-block:: python

        import numpy as np
        from typhon.trees import IntervalTree

        intervals = np.asarray([np.arange(1000)-0.5, np.arange(1000)+0.5]).T
        tree = IntervalTree(intervals)
        query_intervals = [[i-1, i+1] for i in range(1000)]
        results = tree.query(query_intervals)

    """
    def __init__(self, intervals):
        """Creates an IntervalTree object.

        Args:
            intervals: A numpy array containing the intervals (list of two
                numbers).
        """
        # Check the intervals whether they are valid:
        self.left = np.min(intervals)
        self.right = np.max(intervals)

        # We want to return the indices of the intervals instead of their
        # actual bounds. But the original indices will be lost due resorting.
        # Hence, we add the original indices to the intervals themselves.
        indices = np.arange(intervals.shape[0]).reshape(intervals.shape[0], 1)
        indexed_intervals = np.hstack([intervals, indices])
        self.root = self._build_tree(np.sort(indexed_intervals, axis=0))

    def __contains__(self, item):
        if isinstance(item, (tuple, list)):
            return bool(self._query(item, self.root, check_extreme=True))
        else:
            return bool(self._query_point(item, self.root, check_extreme=True))

    def _build_tree(self, intervals):
        if not intervals.any():
            return None

        center_point = self._get_center(intervals)

        # Sort the intervals into bins
        center = intervals[(intervals[:, 0] <= center_point)
                           & (intervals[:, 1] >= center_point)]
        left = intervals[intervals[:, 1] < center_point]
        right = intervals[intervals[:, 0] > center_point]

        return IntervalTreeNode(
            center_point, center,
            self._build_tree(left), self._build_tree(right))

    @staticmethod
    def _get_center(intervals):
        return intervals[int(intervals.shape[0]/2), 0]

    @staticmethod
    def interval_overlaps(interval1, interval2):
        """Checks whether two intervals overlap each other.

        Args:
            interval1: A tuple of two numbers: the lower and higher bound of
                the first interval.
            interval2: A tuple of two numbers: the lower and higher bound of
                the second interval.

        Returns:
            True if the intervals overlap.
        """
        return interval1[0] <= interval2[0] <= interval1[1] or \
            interval1[0] <= interval2[1] <= interval1[1] or \
            (interval2[0] <= interval1[0] and interval2[1] >= interval1[1])

    @staticmethod
    def interval_contains(interval, point):
        """Checks whether a point lies in a interval.

        Args:
            interval: A tuple of two numbers: the lower and higher bound of the
                first interval.
            point: The point (just a number)

        Returns:
            True if point lies in the interval.
        """
        return interval[0] <= point <= interval[1]

    def query(self, intervals):
        """Find all overlaps between this tree and a list of intervals.

        Args:
            intervals: A list of intervals. Each interval is a tuple/list of
                two elements: its lower and higher boundary.

        Returns:
            List of lists which contain the overlapping intervals of this tree
            for each element in `intervals`.
        """
        return [self._query(interval, self.root, check_extreme=True)
                for interval in intervals]

    def _query(self, query_interval, node, check_extreme=False):
        # Check this special case: the bounds of the query interval lie outside
        # of the bounds of this tree:
        if (check_extreme
                and IntervalTree.interval_contains(query_interval, self.left)
                and IntervalTree.interval_contains(query_interval, self.right)):
            return []  # TODO: Return all intervals

        # Let's start with the centered intervals
        intervals = [int(interval[2]) for interval in node.center
                     if IntervalTree.interval_overlaps(interval, query_interval)]

        if query_interval[0] <= node.center_point and node.left is not None:
            intervals.extend(self._query(query_interval, node.left))

        if query_interval[1] >= node.center_point and node.right is not None:
            intervals.extend(self._query(query_interval, node.right))

        return intervals

    def query_points(self, points):
        """Find all intervals of this tree which contain one of those points.

        Args:
            points: A list of points.

        Returns:
            List of lists which contain the enclosing intervals of this tree
            for each element in `points`.
        """
        return [self._query_point(point, self.root, check_extreme=True)
                for point in points]

    def _query_point(self, point, node, check_extreme=False):
        # Check this special case: the query point lies outside of the bounds
        # of this tree:
        if check_extreme \
                and not IntervalTree.interval_contains((self.left, self.right), point):
            return []

        # Let's start with the centered intervals
        intervals = [int(interval[2])
                     for interval in node.center
                     if IntervalTree.interval_contains(interval, point)]

        if point < node.center_point and node.left is not None:
            intervals.extend(self._query_point(point, node))

        if point > node.center_point and node.right is not None:
            intervals.extend(self._query_point(point, node))

        return intervals
<|endoftext|>


<commit_before>from uber.common import *

verbose = dry_run = False

class Style:
    def __getattr__(self, name):
        return lambda text: text

with open(join(MODULE_ROOT, 'models.py')) as f:
    text = f.read()

classes = sorted(all_models(), key=lambda c: text.index('class {}('.format(c.__name__)))

def drop_and_create():
    with closing(connection.cursor()) as cursor:
        for model in reversed(classes):
            sql = 'DROP TABLE IF EXISTS "{}";'.format(model.__name__)
            if verbose:
                print(sql)
            if not dry_run:
                cursor.execute(sql)

        for model in classes:
            sql = connection.creation.sql_create_model(model, Style(), classes)[0][0]
            if verbose:
                print(sql)
            if not dry_run:
                cursor.execute(sql)

def insert_admin():
    attendee = Attendee.objects.create(
        placeholder = True,
        first_name  = 'Test',
        last_name   = 'Developer',
        email       = 'magfest@example.com',
        badge_type  = STAFF_BADGE,
        ribbon      = DEPT_HEAD_RIBBON
    )
    AdminAccount.objects.create(
        attendee = attendee,
        access   = ','.join(str(level) for level, name in ACCESS_OPTS),
        hashed   = bcrypt.hashpw('magfest', bcrypt.gensalt())
    )

if __name__ == '__main__':
    verbose = '--quiet' not in sys.argv
    dry_run = '--dry-run' in sys.argv
    if any(not arg.startswith('-') for arg in sys.argv[1:]):
        classes = [c for c in classes if c.__name__ in sys.argv[1:]]

    drop_and_create()
    if not dry_run:
        insert_admin()
<commit_msg>init_db will by default not erase existing database unless you do --force-init<commit_after>from uber.common import *

verbose = dry_run = False

class Style:
    def __getattr__(self, name):
        return lambda text: text

with open(join(MODULE_ROOT, 'models.py')) as f:
    text = f.read()

classes = sorted(all_models(), key=lambda c: text.index('class {}('.format(c.__name__)))

def does_attendee_table_already_exist(cursor):
    cursor.execute("select exists(select * from information_schema.tables where table_name='Attendee')", ('mytable',))
    return cursor.fetchone()[0]

def drop_and_create(cursor):
    for model in reversed(classes):
        sql = 'DROP TABLE IF EXISTS "{}";'.format(model.__name__)
        if verbose:
            print(sql)
        if not dry_run:
            cursor.execute(sql)

    for model in classes:
        sql = connection.creation.sql_create_model(model, Style(), classes)[0][0]
        if verbose:
            print(sql)
        if not dry_run:
            cursor.execute(sql)

def insert_admin():
    attendee = Attendee.objects.create(
        placeholder = True,
        first_name  = 'Test',
        last_name   = 'Developer',
        email       = 'magfest@example.com',
        badge_type  = STAFF_BADGE,
        ribbon      = DEPT_HEAD_RIBBON
    )
    AdminAccount.objects.create(
        attendee = attendee,
        access   = ','.join(str(level) for level, name in ACCESS_OPTS),
        hashed   = bcrypt.hashpw('magfest', bcrypt.gensalt())
    )

def init_db():
    with closing(connection.cursor()) as cursor:
        if (does_attendee_table_already_exist(cursor)):
            if not force_init:
                print("ERROR: data already exists in this database, not going to init.\n"
                      "Use --force-init to override. WARNING: YOU WILL LOSE ALL DATA")
                return
            else:
                print("WARNING: --force-init specified, deleting everything the database.")

        drop_and_create(cursor)

    if not dry_run:
        insert_admin()

if __name__ == '__main__':
    verbose = '--quiet' not in sys.argv
    dry_run = '--dry-run' in sys.argv
    force_init = '--force-init' in sys.argv

    if any(not arg.startswith('-') for arg in sys.argv[1:]):
        classes = [c for c in classes if c.__name__ in sys.argv[1:]]

    init_db()<|endoftext|>


<commit_before>#################################################################################
#
# The MIT License (MIT)
#
# Copyright (c) 2015 Dmitry Sovetov
#
# https://github.com/dmsovetov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#################################################################################

import os
import sys
import cmake
import command_line

class PlatformConfigurationCommand(cmake.Command):
    """A base class for all platform configuration commands"""

    def __init__(self, platform, parser, generators, rendering_backend, toolchain=None):
        """Constructs a platform configuration command"""

        # Load home directory from environment
        if 'DREEMCHEST_HOME' not in os.environ.keys():
            raise Exception('DREEMCHEST_HOME environment variable was not set')

        prefix_path = os.path.join(os.environ['DREEMCHEST_HOME'], 'Build', 'Dependencies', platform)

        cmake.Command.__init__(self, parser, generators, prefix_path=prefix_path)

        command_line.add_component(parser, 'pch', description='generate a build system that uses precompiled headers.', default=False)
        command_line.add_component(parser, 'composer', description='do not build the Composer tool.', default=False)
        command_line.add_component(parser, 'relight', description='do not build the Relight lightmapping library.', default=False)
        command_line.add_component(parser, 'tests', description='do not build unit tests.', default=False)
        command_line.add_component(parser, 'examples', description='do not build examples.')
        command_line.add_component(parser, 'sound', description='build with no sound support.')
        command_line.add_component(parser, 'renderer', description='build with no rendering support.', options=rendering_backend)

        # Add third party libraries options
        self._libraries = ['TIFF', 'jsoncpp', 'Zlib', 'Box2D', 'GTest', 'PNG', 'Lua', 'Ogg', 'Vorbis', 'OpenAL', 'cURL']

        for lib in self._libraries:
            command_line.add_library(parser, lib)

        self._toolchain = toolchain

        parser.set_defaults(function=self.configure)

    def configure(self, options):
        """Performs basic build system configuration"""
        pass

    def _prepare(self, options):
        """Generates a command line arguments from an input options"""

        # Generate platform independent CMake arguments from passed options
        parameters = dict(
            DC_USE_PCH=cmake.disable_option(options.no_pch),
            DC_COMPOSER_ENABLED=cmake.disable_option(options.no_composer or options.no_qt),
            DC_OPENGL_ENABLED=cmake.disable_option(options.no_renderer),
            DC_SOUND_ENABLED=cmake.disable_option(options.no_sound),
            DC_WITH_RELIGHT=cmake.disable_option(options.no_relight),
            DC_BUILD_TESTS=cmake.disable_option(options.no_tests),
            DC_BUILD_EXAMPLES=cmake.disable_option(options.no_examples),
            CMAKE_CXX_STANDARD=options.cpp,
            DC_QT_SUPPORT=('disabled' if not hasattr(options, 'no_qt') or options.no_qt else options.qt).capitalize(),
            CMAKE_PREFIX_PATH=os.path.abspath(options.prefix_path),
        )

        # Set the CMAKE_TOOLCHAIN_FILE variable
        if self._toolchain:
            parameters['CMAKE_TOOLCHAIN_FILE'] = self._toolchain

        # Generate CMake arguments from added libraries
        for lib in self._libraries:
            cmake.library_option(parameters, lib, options)

        if hasattr(options, 'identifier'):
            parameters['MACOSX_BUNDLE_GUI_IDENTIFIER'] = options.identifier

        if hasattr(options, 'codesign'):
            parameters['IOS_CODESIGN_IDENTITY'] = '"%s"' % ' '.join(options.codesign)

        if hasattr(options, 'api'):
            parameters['ANDROID_NATIVE_API_LEVEL'] = 'android-%s' % options.api

        return parameters

class DesktopConfigureCommand(PlatformConfigurationCommand):
    """Performs desktop OS build system configuration"""

    def __init__(self, platform, parser, generators, rendering_backend):
        """Constructs desktop configuration command"""

        PlatformConfigurationCommand.__init__(self, platform, parser, generators, rendering_backend)

        # Add Qt library option
        command_line.add_system_library(parser, 'Qt', versions=['auto', 'qt4', 'qt5'])

        # Add third party libraries
        self._libraries.append('FBX')
        command_line.add_library(parser, 'FBX', is_bundled=False)

class WindowsConfigureCommand(DesktopConfigureCommand):
    """Performs Windows build system configuration"""

    def __init__(self, parser):
        """Constructs Windows configuration command"""

        DesktopConfigureCommand.__init__(self, 'Windows', parser, ['Visual Studio 12'], ['opengl', 'direct3d9', 'direct3d12'])

    def configure(self, options):
        """Performs basic build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        cmake.generate('Visual Studio 12', options.source, options.output, cmake_parameters)

class MacOSConfigureCommand(DesktopConfigureCommand):
    """Performs MacOS build system configuration"""

    def __init__(self, parser):
        """Constructs MacOS configuration command"""

        DesktopConfigureCommand.__init__(self, 'macOS', parser, ['Xcode'], ['opengl'])

    def configure(self, options):
        """Performs MacOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        cmake.generate('Xcode', options.source, options.output, cmake_parameters)

class IOSConfigureCommand(PlatformConfigurationCommand):
    """Performs iOS build system configuration"""

    def __init__(self, parser):
        """Constructs iOS configuration command"""

        # Load home directory from environment
        if 'DREEMCHEST_HOME' not in os.environ.keys():
            raise Exception('DREEMCHEST_HOME environment variable was not set')

        toolchain = os.path.join(os.environ['DREEMCHEST_HOME'], 'CMake', 'Toolchains', 'iOS.cmake')

        PlatformConfigurationCommand.__init__(self, 'iOS', parser, ['Xcode'], ['opengl'], toolchain=toolchain)

        parser.add_argument('--identifier', help='a bundle identifier to be used.')
        parser.add_argument('--codesign', nargs='+', help='code sign identity name')

    def configure(self, options):
        """Performs iOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        cmake.generate('Xcode', options.source, options.output, cmake_parameters)

class AndroidConfigureCommand(PlatformConfigurationCommand):
    def __init__(self, parser):
        """Constructs Android configuration command"""

        # Load home directory from environment
        if 'DREEMCHEST_HOME' not in os.environ.keys():
            raise Exception('DREEMCHEST_HOME environment variable was not set')

        toolchain = os.path.join(os.environ['DREEMCHEST_HOME'], 'CMake', 'Toolchains', 'Android.cmake')

        PlatformConfigurationCommand.__init__(self, 'Android', parser, ['Unix Makefiles'], ['opengl'], toolchain=toolchain)

        parser.add_argument('--api', help='Android API level')

    def configure(self, options):
        """Performs iOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        cmake.generate('Unix Makefiles', options.source, options.output, cmake_parameters)

class EmscriptenConfigureCommand(PlatformConfigurationCommand):
    def __init__(self, parser):
        """Constructs Emscripten configuration command"""

        # Load home directory from environment
        #if 'EMSCRIPTEN' not in os.environ.keys():
        #    raise Exception('EMSCRIPTEN environment variable was not set')

        #toolchain = os.path.join(os.environ['EMSCRIPTEN'], 'cmake', 'Modules', 'Platform', 'Emscripten.cmake')
        toolchain = '~'

        PlatformConfigurationCommand.__init__(self, 'Emscripten', parser, ['Unix Makefiles'], ['opengl'], toolchain=toolchain)

    def configure(self, options):
        """Performs iOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        cmake.generate('Unix Makefiles', options.source, options.output, cmake_parameters)

class Command(command_line.Tool):
    """A command line tool to configure a build system for a specified target system"""

    def __init__(self, parser):
        """Constructs a configure command line tool"""

        command_line.Tool.__init__(self, parser, 'available platforms')

        self._add_command('android', AndroidConfigureCommand)
        self._add_command('emscripten', EmscriptenConfigureCommand)
        if os.name == 'nt':
            self._add_command('windows', WindowsConfigureCommand)
        if sys.platform == 'darwin':
            self._add_command('macos', MacOSConfigureCommand)
            self._add_command('ios', IOSConfigureCommand)
<commit_msg>Finished: DR-5 / Configuration command<commit_after>#################################################################################
#
# The MIT License (MIT)
#
# Copyright (c) 2015 Dmitry Sovetov
#
# https://github.com/dmsovetov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#################################################################################

import os
import sys
import cmake
import command_line
import env

class PlatformConfigurationCommand(cmake.Command):
    """A base class for all platform configuration commands"""

    def __init__(self, platform, parser, generators, rendering_backend, toolchain=None):
        """Constructs a platform configuration command"""

        # Load active environment
        self._env = env.load()

        cmake.Command.__init__(self, parser, generators, prefix_path=os.path.join(self.env.dependencies, platform))

        command_line.add_component(parser, 'pch', description='generate a build system that uses precompiled headers.', default=False)
        command_line.add_component(parser, 'composer', description='do not build the Composer tool.', default=False)
        command_line.add_component(parser, 'relight', description='do not build the Relight lightmapping library.', default=False)
        command_line.add_component(parser, 'tests', description='do not build unit tests.', default=False)
        command_line.add_component(parser, 'examples', description='do not build examples.')
        command_line.add_component(parser, 'sound', description='build with no sound support.')
        command_line.add_component(parser, 'renderer', description='build with no rendering support.', options=rendering_backend)

        # Add third party libraries options
        self._libraries = ['TIFF', 'jsoncpp', 'Zlib', 'Box2D', 'GTest', 'PNG', 'Lua', 'Ogg', 'Vorbis', 'OpenAL', 'cURL']

        for lib in self._libraries:
            command_line.add_library(parser, lib)

        self._toolchain = toolchain

        parser.set_defaults(function=self.configure)

    @property
    def env(self):
        """Returns a loaded environment configuration"""
        return self._env

    def configure(self, options):
        """Performs basic build system configuration"""
        pass

    def _prepare(self, options):
        """Generates a command line arguments from an input options"""

        # Generate platform independent CMake arguments from passed options
        parameters = dict(
            DC_USE_PCH=cmake.disable_option(options.no_pch),
            DC_COMPOSER_ENABLED=cmake.disable_option(options.no_composer or options.no_qt),
            DC_OPENGL_ENABLED=cmake.disable_option(options.no_renderer),
            DC_SOUND_ENABLED=cmake.disable_option(options.no_sound),
            DC_WITH_RELIGHT=cmake.disable_option(options.no_relight),
            DC_BUILD_TESTS=cmake.disable_option(options.no_tests),
            DC_BUILD_EXAMPLES=cmake.disable_option(options.no_examples),
            CMAKE_CXX_STANDARD=options.cpp,
            DC_QT_SUPPORT=('disabled' if not hasattr(options, 'no_qt') or options.no_qt else options.qt).capitalize(),
            CMAKE_PREFIX_PATH=os.path.abspath(options.prefix_path),
        )

        # Set the CMAKE_TOOLCHAIN_FILE variable
        if self._toolchain:
            parameters['CMAKE_TOOLCHAIN_FILE'] = self._toolchain

        # Generate CMake arguments from added libraries
        for lib in self._libraries:
            cmake.library_option(parameters, lib, options)

        if hasattr(options, 'identifier'):
            parameters['MACOSX_BUNDLE_GUI_IDENTIFIER'] = options.identifier

        if hasattr(options, 'codesign'):
            parameters['IOS_CODESIGN_IDENTITY'] = '"%s"' % ' '.join(options.codesign)

        if hasattr(options, 'api'):
            parameters['ANDROID_NATIVE_API_LEVEL'] = 'android-%s' % options.api

        return parameters

class DesktopConfigureCommand(PlatformConfigurationCommand):
    """Performs desktop OS build system configuration"""

    def __init__(self, platform, parser, generators, rendering_backend):
        """Constructs desktop configuration command"""

        PlatformConfigurationCommand.__init__(self, platform, parser, generators, rendering_backend)

        # Add Qt library option
        command_line.add_system_library(parser, 'Qt', versions=['auto', 'qt4', 'qt5'])

        # Add third party libraries
        self._libraries.append('FBX')
        command_line.add_library(parser, 'FBX', is_bundled=False)

class WindowsConfigureCommand(DesktopConfigureCommand):
    """Performs Windows build system configuration"""

    def __init__(self, parser):
        """Constructs Windows configuration command"""

        DesktopConfigureCommand.__init__(self, 'Windows', parser, ['Visual Studio 12'], ['opengl', 'direct3d9', 'direct3d12'])

    def configure(self, options):
        """Performs basic build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        install_path = os.path.join(self.env.prebuilt, 'Windows')
        prefix_path = os.path.join(self.env.dependencies, 'Windows')
        cm = cmake.CMake(self.env.cmake, prefix_path=prefix_path, install_prefix=install_path)
        cm.configure('Visual Studio 12', options.source, options.output, cmake_parameters)

class MacOSConfigureCommand(DesktopConfigureCommand):
    """Performs MacOS build system configuration"""

    def __init__(self, parser):
        """Constructs MacOS configuration command"""

        DesktopConfigureCommand.__init__(self, 'macOS', parser, ['Xcode'], ['opengl'])

    def configure(self, options):
        """Performs MacOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        install_path = os.path.join(self.env.prebuilt, 'macOS')
        prefix_path = os.path.join(self.env.dependencies, 'macOS')
        cm = cmake.CMake(self.env.cmake, prefix_path=prefix_path, install_prefix=install_path)
        cm.configure('Xcode', options.source, options.output, cmake_parameters)

class IOSConfigureCommand(PlatformConfigurationCommand):
    """Performs iOS build system configuration"""

    def __init__(self, parser):
        """Constructs iOS configuration command"""

        PlatformConfigurationCommand.__init__(self,
                                              'iOS',
                                              parser,
                                              ['Xcode'], ['opengl'],
                                              toolchain=env.load().ios_toolchain)

        parser.add_argument('--identifier', help='a bundle identifier to be used.')
        parser.add_argument('--codesign', nargs='+', help='code sign identity name')

    def configure(self, options):
        """Performs iOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)

        # Invoke a CMake command to generate a build system
        install_path = os.path.join(self.env.prebuilt, 'iOS')
        prefix_path = os.path.join(self.env.dependencies, 'iOS')
        cm = cmake.CMake(self.env.cmake, prefix_path=prefix_path, install_prefix=install_path)
        cm.configure('Xcode', options.source, options.output, cmake_parameters)

class AndroidConfigureCommand(PlatformConfigurationCommand):
    def __init__(self, parser):
        """Constructs Android configuration command"""

        PlatformConfigurationCommand.__init__(self,
                                              'Android',
                                              parser,
                                              ['Unix Makefiles'],
                                              ['opengl'],
                                              toolchain=env.load().android_toolchain)

    def configure(self, options):
        """Performs iOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)
        cmake_parameters['ANDROID_NATIVE_API_LEVEL'] = 'android-24'
        cmake_parameters['ANDROID_NDK'] = self.env.android_ndk

        # Invoke a CMake command to generate a build system
        install_path = os.path.join(self.env.prebuilt, 'Android')
        prefix_path = os.path.join(self.env.dependencies, 'Android')
        cm = cmake.CMake(self.env.cmake, prefix_path=prefix_path, install_prefix=install_path)
        cm.configure('Unix Makefiles', options.source, options.output, cmake_parameters)

class EmscriptenConfigureCommand(PlatformConfigurationCommand):
    def __init__(self, parser):
        """Constructs Emscripten configuration command"""

        PlatformConfigurationCommand.__init__(self,
                                              'Emscripten',
                                              parser,
                                              ['Unix Makefiles'],
                                              ['opengl'],
                                              toolchain=env.load().emscripten_toolchain)

    def configure(self, options):
        """Performs iOS build system configuration"""

        # Perform basic build configuration
        cmake_parameters = self._prepare(options)
        cmake_parameters['EMSCRIPTEN_ROOT_PATH'] = self.env.emscripten

        # Invoke a CMake command to generate a build system
        install_path = os.path.join(self.env.prebuilt, 'Emscripten')
        prefix_path = os.path.join(self.env.dependencies, 'Emscripten')
        cm = cmake.CMake(self.env.cmake, prefix_path=prefix_path, install_prefix=install_path)
        cm.configure('Unix Makefiles', options.source, options.output, cmake_parameters)

class Command(command_line.Tool):
    """A command line tool to configure a build system for a specified target system"""

    def __init__(self, parser):
        """Constructs a configure command line tool"""

        command_line.Tool.__init__(self, parser, 'available platforms')

        self._add_command('android', AndroidConfigureCommand)
        self._add_command('emscripten', EmscriptenConfigureCommand)
        if os.name == 'nt':
            self._add_command('windows', WindowsConfigureCommand)
        if sys.platform == 'darwin':
            self._add_command('macos', MacOSConfigureCommand)
            self._add_command('ios', IOSConfigureCommand)
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# NetProfile: XOP module - Models
# Copyright © 2014-2017 Nikita Andriyanov
#
# This file is part of NetProfile.
# NetProfile is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public
# License as published by the Free Software Foundation, either
# version 3 of the License, or (at your option) any later
# version.
#
# NetProfile is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General
# Public License along with NetProfile. If not, see
# <http://www.gnu.org/licenses/>.

from exceptions import RuntimeError

class ExternalOperationError(RuntimeError):
    def __init__(self, error, xop=None):
        self.error = error
        self.xop = xop<commit_msg>Fix some errors<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# NetProfile: XOP module - Exceptions
# Copyright © 2014-2017 Nikita Andriyanov
#
# This file is part of NetProfile.
# NetProfile is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public
# License as published by the Free Software Foundation, either
# version 3 of the License, or (at your option) any later
# version.
#
# NetProfile is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General
# Public License along with NetProfile. If not, see
# <http://www.gnu.org/licenses/>.

from __future__ import (unicode_literals, print_function,
                        absolute_import, division)

class ExternalOperationError(RuntimeError):
    def __init__(self, error, xop=None):
        self.error = error
        self.xop = xop<|endoftext|>