<commit_before>from functools import wraps
from django.utils import timezone
from rest_framework import decorators, exceptions, response, status

from nodeconductor.structure import views as structure_views

from . import models, serializers, filters
from .backend import OracleBackendError
from .log import event_logger

States = models.Deployment.States

def safe_operation(valid_state=None):
    def decorator(view_fn):
        @wraps(view_fn)
        def wrapped(self, request, *args, **kwargs):
            try:
                resource = self.get_object()
                structure_views.check_operation(request.user, resource, view_fn.__name__, valid_state)
                return view_fn(self, request, resource, *args, **kwargs)
            except OracleBackendError as e:
                resource.error_message = unicode(e)
                resource.set_erred()
                resource.save(update_fields=['state', 'error_message'])
                raise exceptions.APIException(e)
        return wrapped
    return decorator

class OracleServiceViewSet(structure_views.BaseServiceViewSet):
    queryset = models.OracleService.objects.all()
    serializer_class = serializers.ServiceSerializer

class OracleServiceProjectLinkViewSet(structure_views.BaseServiceProjectLinkViewSet):
    queryset = models.OracleServiceProjectLink.objects.all()
    serializer_class = serializers.ServiceProjectLinkSerializer

class FlavorViewSet(structure_views.BaseServicePropertyViewSet):
    queryset = models.Flavor.objects.order_by('cores', 'ram', 'disk')
    serializer_class = serializers.FlavorSerializer
    lookup_field = 'uuid'

class DeploymentViewSet(structure_views.BaseResourceViewSet):
    queryset = models.Deployment.objects.all()
    serializer_class = serializers.DeploymentSerializer
    filter_class = filters.DeploymentFilter

    def get_serializer_class(self):
        if self.action == 'resize':
            return serializers.DeploymentResizeSerializer
        elif self.action == 'support':
            return serializers.SupportSerializer
        return super(DeploymentViewSet, self).get_serializer_class()

    def perform_provision(self, serializer):
        resource = serializer.save()
        backend = resource.get_backend()

        try:
            backend.provision(
                resource, self.request, ssh_key=serializer.validated_data.get('ssh_public_key'))
        except OracleBackendError as e:
            resource.error_message = unicode(e)
            resource.set_erred()
            resource.save(update_fields=['state', 'error_message'])
            raise

        resource.begin_provisioning()
        resource.save(update_fields=['state'])

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=States.PROVISIONING)
    def provision(self, request, resource, uuid=None):
        """ Complete provisioning. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/provision/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "report": "ORACONF=TST12DB\n\nDBTYPE=single\nDBNAME='TST12DB'"
                }
        """
        report = request.data.get('report')
        if report:
            resource.report = report
            resource.start_time = timezone.now()
            resource.set_online()
            resource.save(update_fields=['report', 'start_time', 'state'])
            event_logger.oracle_deployment.info(
                'Oracle deployment {deployment_name} report has been updated.',
                event_type='oracle_deployment_report_updated',
                event_context={
                    'deployment': resource,
                }
            )
            return response.Response({'detail': "Provision complete"})
        else:
            return response.Response({'detail': "Empty report"}, status=status.HTTP_400_BAD_REQUEST)

    @decorators.detail_route(methods=['post'])
    @safe_operation()
    def update_report(self, request, resource, uuid=None):
        """ Update provisioning report. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/update_report/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "report": "ORACONF=TST12DB\n\nDBTYPE=single\nDBNAME='PRD12DB'"
                }
        """
        if not self.request.user.is_staff:
            raise exceptions.PermissionDenied

        report = request.data.get('report')
        if report:
            resource.report = report
            resource.save(update_fields=['report'])
            event_logger.oracle_deployment.info(
                'Oracle deployment {deployment_name} report has been updated.',
                event_type='oracle_deployment_report_updated',
                event_context={
                    'deployment': resource,
                }
            )
            return response.Response({'detail': "Report has been updated"})
        else:
            return response.Response({'detail': "Empty report"}, status=status.HTTP_400_BAD_REQUEST)

    @decorators.detail_route(methods=['post'])
    @safe_operation()
    def support(self, request, resource, uuid=None):
        """ File custom support request.

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/support/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "message": "Could you make that DB running faster?\n\nThanks."
                }
        """

        serializer = self.get_serializer(resource, data=request.data)
        serializer.is_valid(raise_exception=True)
        backend = resource.get_backend()
        ticket = backend.support_request(resource, self.request, serializer.validated_data['message'])

        # XXX: Switch this and below to a more standard resource_stop_scheduled / resource_stop_succeeded for ECC release
        event_logger.oracle_deployment.info(
            'Support for Oracle deployment {deployment_name} has been requested ({jira_issue_key}).',
            event_type='oracle_deployment_support_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Support request accepted", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.ONLINE, States.RESIZING))
    def resize(self, request, resource, uuid=None):
        """ Request for DB Instance resize. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/resize/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "flavor": "http://example.com/api/oracle-flavors/ef86802458684056b18576a91daf7690/"
                }

            To confirm resize completion, issue an empty POST request to the same endpoint.
        """

        if resource.state == States.RESIZING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            resource.set_resized()
            resource.save(update_fields=['state'])
            event_logger.oracle_deployment.info(
                'Resize request for Oracle deployment {deployment_name} has been fulfilled.',
                event_type='oracle_deployment_resize_succeeded',
                event_context={
                    'deployment': resource,
                }
            )

            return response.Response({'detail': "Resizing complete"})

        serializer = self.get_serializer(resource, data=request.data)
        serializer.is_valid(raise_exception=True)

        resource.state = States.RESIZING_SCHEDULED
        resource.flavor = serializer.validated_data.get('flavor')
        resource.save(update_fields=['flavor', 'state'])

        backend = resource.get_backend()
        ticket = backend.resize(resource, self.request)

        resource.begin_resizing()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Resize request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_resize_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Resizing scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @safe_operation(valid_state=(States.OFFLINE, States.DELETING))
    def destroy(self, request, resource, uuid=None):
        """ Request for DB Instance deletion or confirm deletion success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.DELETING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            self.perform_destroy(resource)
            return response.Response({'detail': "Deployment deleted"})

        resource.schedule_deletion()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.destroy(resource, self.request)

        resource.begin_deleting()
        resource.save(update_fields=['state'])

        return response.Response(
            {'detail': "Deletion scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.OFFLINE, States.STARTING))
    def start(self, request, resource, uuid=None):
        """ Request for DB Instance starting or confirm starting success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.STARTING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            else:
                resource.set_online()
                resource.save(update_fields=['state'])
                event_logger.oracle_deployment.info(
                    'Start request for Oracle deployment {deployment_name} has been fulfilled.',
                    event_type='oracle_deployment_start_succeeded',
                    event_context={
                        'deployment': resource,
                    }
                )
                return response.Response({'detail': "Deployment started"})

        resource.schedule_starting()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.start(resource, self.request)

        resource.begin_starting()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Start request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_start_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Starting scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.ONLINE, States.STOPPING))
    def stop(self, request, resource, uuid=None):
        """ Request for DB Instance stopping or confirm stopping success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.STOPPING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            else:
                resource.set_offline()
                resource.save(update_fields=['state'])
                event_logger.oracle_deployment.info(
                    'Stop request for Oracle deployment {deployment_name} has been fulfilled.',
                    event_type='oracle_deployment_stop_succeeded',
                    event_context={
                        'deployment': resource,
                    }
                )

                return response.Response({'detail': "Deployment stopped"})

        resource.schedule_stopping()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.stop(resource, self.request)

        resource.begin_stopping()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Stop request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_stop_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Stopping scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.ONLINE, States.RESTARTING))
    def restart(self, request, resource, uuid=None):
        """ Request for DB Instance restarting or confirm restarting success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.RESTARTING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            else:
                resource.set_online()
                resource.save(update_fields=['state'])
                event_logger.oracle_deployment.info(
                    'Restart request for Oracle deployment {deployment_name} has been fulfilled.',
                    event_type='oracle_deployment_restart_succeeded',
                    event_context={
                        'deployment': resource,
                    }
                )

                return response.Response({'detail': "Deployment restarted"})

        resource.schedule_restarting()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.restart(resource, self.request)

        resource.begin_restarting()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Restart request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_restart_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Restarting scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)
<commit_msg>A hotfix for the creation event message<commit_after>from functools import wraps
from django.utils import timezone
from rest_framework import decorators, exceptions, response, status

from nodeconductor.core import exceptions as core_exceptions
from nodeconductor.core import models as core_models
from nodeconductor.structure import ServiceBackendError
from nodeconductor.structure import views as structure_views

from . import models, serializers, filters
from .backend import OracleBackendError
from .log import event_logger

States = models.Deployment.States

def safe_operation(valid_state=None):
    def decorator(view_fn):
        @wraps(view_fn)
        def wrapped(self, request, *args, **kwargs):
            try:
                resource = self.get_object()
                structure_views.check_operation(request.user, resource, view_fn.__name__, valid_state)
                return view_fn(self, request, resource, *args, **kwargs)
            except OracleBackendError as e:
                resource.error_message = unicode(e)
                resource.set_erred()
                resource.save(update_fields=['state', 'error_message'])
                raise exceptions.APIException(e)
        return wrapped
    return decorator

class OracleServiceViewSet(structure_views.BaseServiceViewSet):
    queryset = models.OracleService.objects.all()
    serializer_class = serializers.ServiceSerializer

class OracleServiceProjectLinkViewSet(structure_views.BaseServiceProjectLinkViewSet):
    queryset = models.OracleServiceProjectLink.objects.all()
    serializer_class = serializers.ServiceProjectLinkSerializer

class FlavorViewSet(structure_views.BaseServicePropertyViewSet):
    queryset = models.Flavor.objects.order_by('cores', 'ram', 'disk')
    serializer_class = serializers.FlavorSerializer
    lookup_field = 'uuid'

class DeploymentViewSet(structure_views.BaseResourceViewSet):
    queryset = models.Deployment.objects.all()
    serializer_class = serializers.DeploymentSerializer
    filter_class = filters.DeploymentFilter

    def get_serializer_class(self):
        if self.action == 'resize':
            return serializers.DeploymentResizeSerializer
        elif self.action == 'support':
            return serializers.SupportSerializer
        return super(DeploymentViewSet, self).get_serializer_class()

    # XXX: overloaded base class method to skip emitting too generic event message
    def perform_create(self, serializer):
        service_project_link = serializer.validated_data['service_project_link']

        if service_project_link.service.settings.state == core_models.SynchronizationStates.ERRED:
            raise core_exceptions.IncorrectStateException(
                detail='Cannot create resource if its service is in erred state.')

        try:
            self.perform_provision(serializer)
        except ServiceBackendError as e:
            raise exceptions.APIException(e)

    def perform_provision(self, serializer):
        resource = serializer.save()
        backend = resource.get_backend()

        try:
            ticket = backend.provision(
                resource, self.request, ssh_key=serializer.validated_data.get('ssh_public_key'))
            event_logger.resource.info(
                '{resource_full_name} creation has been scheduled ({jira_issue_key}).',
                event_type='resource_creation_scheduled',
                event_context={
                    'resource': serializer.instance,
                    'jira_issue_key': ticket.key,
                })

        except OracleBackendError as e:
            resource.error_message = unicode(e)
            resource.set_erred()
            resource.save(update_fields=['state', 'error_message'])
            raise

        resource.begin_provisioning()
        resource.save(update_fields=['state'])

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=States.PROVISIONING)
    def provision(self, request, resource, uuid=None):
        """ Complete provisioning. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/provision/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "report": "ORACONF=TST12DB\n\nDBTYPE=single\nDBNAME='TST12DB'"
                }
        """
        report = request.data.get('report')
        if report:
            resource.report = report
            resource.start_time = timezone.now()
            resource.set_online()
            resource.save(update_fields=['report', 'start_time', 'state'])
            event_logger.oracle_deployment.info(
                'Oracle deployment {deployment_name} report has been updated.',
                event_type='oracle_deployment_report_updated',
                event_context={
                    'deployment': resource,
                }
            )
            return response.Response({'detail': "Provision complete"})
        else:
            return response.Response({'detail': "Empty report"}, status=status.HTTP_400_BAD_REQUEST)

    @decorators.detail_route(methods=['post'])
    @safe_operation()
    def update_report(self, request, resource, uuid=None):
        """ Update provisioning report. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/update_report/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "report": "ORACONF=TST12DB\n\nDBTYPE=single\nDBNAME='PRD12DB'"
                }
        """
        if not self.request.user.is_staff:
            raise exceptions.PermissionDenied

        report = request.data.get('report')
        if report:
            resource.report = report
            resource.save(update_fields=['report'])
            event_logger.oracle_deployment.info(
                'Oracle deployment {deployment_name} report has been updated.',
                event_type='oracle_deployment_report_updated',
                event_context={
                    'deployment': resource,
                }
            )
            return response.Response({'detail': "Report has been updated"})
        else:
            return response.Response({'detail': "Empty report"}, status=status.HTTP_400_BAD_REQUEST)

    @decorators.detail_route(methods=['post'])
    @safe_operation()
    def support(self, request, resource, uuid=None):
        """ File custom support request.

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/support/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "message": "Could you make that DB running faster?\n\nThanks."
                }
        """

        serializer = self.get_serializer(resource, data=request.data)
        serializer.is_valid(raise_exception=True)
        backend = resource.get_backend()
        ticket = backend.support_request(resource, self.request, serializer.validated_data['message'])

        # XXX: Switch this and below to a more standard resource_stop_scheduled / resource_stop_succeeded for ECC release
        event_logger.oracle_deployment.info(
            'Support for Oracle deployment {deployment_name} has been requested ({jira_issue_key}).',
            event_type='oracle_deployment_support_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Support request accepted", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.ONLINE, States.RESIZING))
    def resize(self, request, resource, uuid=None):
        """ Request for DB Instance resize. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/resize/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token c84d653b9ec92c6cbac41c706593e66f567a7fa4
                Host: example.com

                {
                    "flavor": "http://example.com/api/oracle-flavors/ef86802458684056b18576a91daf7690/"
                }

            To confirm resize completion, issue an empty POST request to the same endpoint.
        """

        if resource.state == States.RESIZING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            resource.set_resized()
            resource.save(update_fields=['state'])
            event_logger.oracle_deployment.info(
                'Resize request for Oracle deployment {deployment_name} has been fulfilled.',
                event_type='oracle_deployment_resize_succeeded',
                event_context={
                    'deployment': resource,
                }
            )

            return response.Response({'detail': "Resizing complete"})

        serializer = self.get_serializer(resource, data=request.data)
        serializer.is_valid(raise_exception=True)

        resource.state = States.RESIZING_SCHEDULED
        resource.flavor = serializer.validated_data.get('flavor')
        resource.save(update_fields=['flavor', 'state'])

        backend = resource.get_backend()
        ticket = backend.resize(resource, self.request)

        resource.begin_resizing()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Resize request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_resize_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Resizing scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @safe_operation(valid_state=(States.OFFLINE, States.DELETING))
    def destroy(self, request, resource, uuid=None):
        """ Request for DB Instance deletion or confirm deletion success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.DELETING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            self.perform_destroy(resource)
            return response.Response({'detail': "Deployment deleted"})

        resource.schedule_deletion()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.destroy(resource, self.request)

        resource.begin_deleting()
        resource.save(update_fields=['state'])

        return response.Response(
            {'detail': "Deletion scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.OFFLINE, States.STARTING))
    def start(self, request, resource, uuid=None):
        """ Request for DB Instance starting or confirm starting success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.STARTING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            else:
                resource.set_online()
                resource.save(update_fields=['state'])
                event_logger.oracle_deployment.info(
                    'Start request for Oracle deployment {deployment_name} has been fulfilled.',
                    event_type='oracle_deployment_start_succeeded',
                    event_context={
                        'deployment': resource,
                    }
                )
                return response.Response({'detail': "Deployment started"})

        resource.schedule_starting()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.start(resource, self.request)

        resource.begin_starting()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Start request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_start_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Starting scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.ONLINE, States.STOPPING))
    def stop(self, request, resource, uuid=None):
        """ Request for DB Instance stopping or confirm stopping success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.STOPPING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            else:
                resource.set_offline()
                resource.save(update_fields=['state'])
                event_logger.oracle_deployment.info(
                    'Stop request for Oracle deployment {deployment_name} has been fulfilled.',
                    event_type='oracle_deployment_stop_succeeded',
                    event_context={
                        'deployment': resource,
                    }
                )

                return response.Response({'detail': "Deployment stopped"})

        resource.schedule_stopping()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.stop(resource, self.request)

        resource.begin_stopping()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Stop request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_stop_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Stopping scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)

    @decorators.detail_route(methods=['post'])
    @safe_operation(valid_state=(States.ONLINE, States.RESTARTING))
    def restart(self, request, resource, uuid=None):
        """ Request for DB Instance restarting or confirm restarting success.
            A proper action will be taken depending on the current deployment state.
        """

        if resource.state == States.RESTARTING:
            if not self.request.user.is_staff:
                raise exceptions.PermissionDenied
            else:
                resource.set_online()
                resource.save(update_fields=['state'])
                event_logger.oracle_deployment.info(
                    'Restart request for Oracle deployment {deployment_name} has been fulfilled.',
                    event_type='oracle_deployment_restart_succeeded',
                    event_context={
                        'deployment': resource,
                    }
                )

                return response.Response({'detail': "Deployment restarted"})

        resource.schedule_restarting()
        resource.save(update_fields=['state'])

        backend = resource.get_backend()
        ticket = backend.restart(resource, self.request)

        resource.begin_restarting()
        resource.save(update_fields=['state'])
        event_logger.oracle_deployment.info(
            'Restart request for Oracle deployment {deployment_name} has been submitted ({jira_issue_key}).',
            event_type='oracle_deployment_restart_requested',
            event_context={
                'deployment': resource,
                'jira_issue_key': ticket.key,
            }
        )

        return response.Response(
            {'detail': "Restarting scheduled", 'jira_issue_uuid': ticket.uuid.hex, 'jira_issue_key': ticket.key},
            status=status.HTTP_202_ACCEPTED)
<|endoftext|>


<commit_before>import requests
import random
import time
import userdata as DG

postUrl = "http://192.168.99.100:1000"

def sendUser(profile):
    r = requests.post(postUrl+'/user/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Send User')

def sendPost(profile):
    r = requests.post(postUrl+'/schedule/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Send Post')
    return r.json()

def sendMsg(profile):
    r = requests.post(postUrl+'/message/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Send Msg')
    return r.json()

def getMsg(id):
    r = requests.get(postUrl+'/message/'+id)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Get Msg')
    return r.json()

def getUser(id):
    r = requests.get(postUrl+'/user/'+id)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Get User')
    return r.json()

def getPost(id):
    r = requests.get(postUrl+'/schedule/'+id)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Get Post')
    return r.json()

def sendMsgPut(profile):
    r = requests.put(postUrl+'/message/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Deal Msg')
    return r.json()

# create some users and store all the fbids

fbids = {}

userNum = 10
for i in range(userNum):
    userData = DG.generateUser()
    sendUser(userData)
    fbids[userData['_id']] = {}
    fbids[userData['_id']]["posts"] = []
    fbids[userData['_id']]["invite_msg"] = []
    fbids[userData['_id']]["join_msg"] = []

# use a id from the fbids to create a post and store all the pids from return reponse

pids = {}
postNum = 10
for i in range(postNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    post = DG.generatePost(uid)
    # send schedule profile request and get the id
    r = sendPost(post)
    time.sleep(1)
    pids[r["_id"]] = {}
    pids[r['_id']]["members"] = []
    # update fbdis._id.posts
    fbids[uid]["posts"].append(r["_id"])

# TODO: check correctness

# use a uid generate some invite messages

msgNum = 10
for i in range(msgNum):
    sid = (fbids.keys())[int(random.random()*userNum)]
    rid = (fbids.keys())[int(random.random()*userNum)]
    # post must be in sender's posts list
    userPostLen = len(fbids[sid]["posts"])
    if userPostLen > 0:
        pid = fbids[sid]["posts"][int(random.random()*userPostLen)]
        # generate msg
        msg = DG.generateMsg(sid,rid,pid,"invite")
        # send msg request
        r = sendMsg(msg)
        # store msgid
        fbids[rid]["invite_msg"].append(r["_id"])

# use a uid generate some join messages
for i in range(msgNum):
    sid = (fbids.keys())[int(random.random()*userNum)]
    rid = (fbids.keys())[int(random.random()*userNum)]
    # join : post must be in receiver's posts list
    userPostLen = len(fbids[rid]["posts"])
    if userPostLen > 0:
        pid = fbids[rid]["posts"][int(random.random()*userPostLen)]
        # generate msg
        msg = DG.generateMsg(sid,rid,pid,"join")
        # send msg request
        r = sendMsg(msg)
        # store msgid
        fbids[rid]["join_msg"].append(r["_id"])

# accept and decline some messages

# accept
# invite
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    inviteMsgLen = len(fbids[uid]["invite_msg"])
    if inviteMsgLen > 0:
        mid = fbids[uid]["invite_msg"][int(random.random()*inviteMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"accept"})
        # remove from unprocessed
        fbids[uid]["invite_msg"].remove(mid)
        fbids[uid]["posts"].append(msg["post_id"])
        pids[msg["post_id"]]["members"].append(uid)

# join
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    joinMsgLen = len(fbids[uid]["join_msg"])
    if joinMsgLen > 0:
        mid = fbids[uid]["join_msg"][int(random.random()*joinMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"accept"})
        fbids[uid]["join_msg"].remove(mid)
        fbids[msg["sender_id"]]["posts"].append(msg["post_id"])
        pids[msg["post_id"]]["members"].append(msg["sender_id"])

# decline
# invite
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    inviteMsgLen = len(fbids[uid]["invite_msg"])
    if inviteMsgLen > 0:
        mid = fbids[uid]["invite_msg"][int(random.random()*inviteMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"decline"})
        # remove from unprocessed
        fbids[uid]["invite_msg"].remove(mid)

# join
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    joinMsgLen = len(fbids[uid]["join_msg"])
    if joinMsgLen > 0:
        mid = fbids[uid]["join_msg"][int(random.random()*joinMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"decline"})
        fbids[uid]["join_msg"].remove(mid)

for i in fbids:
    profile = getUser(i)
    if (set(fbids[i]["posts"]) != set(profile["schedule_list"])):
        print i

print "##########"

for i in pids:
    post = getPost(i)
    if (set(post["member"]) != set(pids[i]["members"])):
        print i
<commit_msg>output the error details in datagenerator<commit_after>import requests
import random
import time
import userdata as DG

postUrl = "http://192.168.99.100:1000"

def sendUser(profile):
    r = requests.post(postUrl+'/user/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Send User')

def sendPost(profile):
    r = requests.post(postUrl+'/schedule/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Send Post')
    return r.json()

def sendMsg(profile):
    r = requests.post(postUrl+'/message/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Send Msg')
    return r.json()

def getMsg(id):
    r = requests.get(postUrl+'/message/'+id)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Get Msg')
    return r.json()

def getUser(id):
    r = requests.get(postUrl+'/user/'+id)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Get User')
    return r.json()

def getPost(id):
    r = requests.get(postUrl+'/schedule/'+id)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Get Post')
    return r.json()

def sendMsgPut(profile):
    r = requests.put(postUrl+'/message/', data = profile)
    if ("status" in r.json() and r.json()["status"] != 1) :
        raise Exception('Fail', 'Deal Msg')
    return r.json()

# create some users and store all the fbids

fbids = {}

userNum = 30
for i in range(userNum):
    userData = DG.generateUser()
    sendUser(userData)
    fbids[userData['_id']] = {}
    fbids[userData['_id']]["posts"] = []
    fbids[userData['_id']]["invite_msg"] = []
    fbids[userData['_id']]["join_msg"] = []

# use a id from the fbids to create a post and store all the pids from return reponse

pids = {}
postNum = 30
for i in range(postNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    post = DG.generatePost(uid)
    # send schedule profile request and get the id
    r = sendPost(post)
    pids[r["_id"]] = {}
    pids[r['_id']]["members"] = []
    # update fbdis._id.posts
    fbids[uid]["posts"].append(r["_id"])

# TODO: check correctness

# use a uid generate some invite messages

msgNum = 30
for i in range(msgNum):
    sid = (fbids.keys())[int(random.random()*userNum)]
    rid = (fbids.keys())[int(random.random()*userNum)]
    # post must be in sender's posts list
    userPostLen = len(fbids[sid]["posts"])
    if userPostLen > 0:
        pid = fbids[sid]["posts"][int(random.random()*userPostLen)]
        # generate msg
        msg = DG.generateMsg(sid,rid,pid,"invite")
        # send msg request
        r = sendMsg(msg)
        # store msgid
        fbids[rid]["invite_msg"].append(r["_id"])

# use a uid generate some join messages
for i in range(msgNum):
    sid = (fbids.keys())[int(random.random()*userNum)]
    rid = (fbids.keys())[int(random.random()*userNum)]
    # join : post must be in receiver's posts list
    userPostLen = len(fbids[rid]["posts"])
    if userPostLen > 0:
        pid = fbids[rid]["posts"][int(random.random()*userPostLen)]
        # generate msg
        msg = DG.generateMsg(sid,rid,pid,"join")
        # send msg request
        r = sendMsg(msg)
        # store msgid
        fbids[rid]["join_msg"].append(r["_id"])

# accept and decline some messages

# accept
# invite
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    inviteMsgLen = len(fbids[uid]["invite_msg"])
    if inviteMsgLen > 0:
        mid = fbids[uid]["invite_msg"][int(random.random()*inviteMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"accept"})
        # remove from unprocessed
        fbids[uid]["invite_msg"].remove(mid)
        fbids[uid]["posts"].append(msg["post_id"])
        pids[msg["post_id"]]["members"].append(uid)

# join
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    joinMsgLen = len(fbids[uid]["join_msg"])
    if joinMsgLen > 0:
        mid = fbids[uid]["join_msg"][int(random.random()*joinMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"accept"})
        fbids[uid]["join_msg"].remove(mid)
        fbids[msg["sender_id"]]["posts"].append(msg["post_id"])
        pids[msg["post_id"]]["members"].append(msg["sender_id"])

# decline
# invite
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    inviteMsgLen = len(fbids[uid]["invite_msg"])
    if inviteMsgLen > 0:
        mid = fbids[uid]["invite_msg"][int(random.random()*inviteMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"decline"})
        # remove from unprocessed
        fbids[uid]["invite_msg"].remove(mid)

# join
for i in range(userNum):
    uid = (fbids.keys())[int(random.random()*userNum)]
    joinMsgLen = len(fbids[uid]["join_msg"])
    if joinMsgLen > 0:
        mid = fbids[uid]["join_msg"][int(random.random()*joinMsgLen)]
        msg = getMsg(mid)
        sendMsgPut({"sender_id":uid, "_id":mid, 'type':"decline"})
        fbids[uid]["join_msg"].remove(mid)

for i in fbids:
    profile = getUser(i)
    if (set(fbids[i]["posts"]) != set(profile["schedule_list"])):
        print i
        print fbids[i]["posts"]
        print profile["schedule_list"]

print "##########"

for i in pids:
    post = getPost(i)
    if (set(post["member"]) != set(pids[i]["members"])):
        print i
<|endoftext|>


<commit_before>from django.http import JsonResponse
from django.shortcuts import render
from django.db.models import Q
from django.views.decorators.csrf import ensure_csrf_cookie
from logging import getLogger

from bookmarks.models import Bookmark

logger = getLogger(__name__)

@ensure_csrf_cookie
def bookmarks(request):
    if request.method == 'GET':
        search = request.GET.get('search')
        if search:
            bookmarks = Bookmark.objects.filter(Q(title__contains=search) | Q(url__contains=search))
        else:
            bookmarks = Bookmark.objects.all()
        offset = int(request.GET.get('offset') or '0')
        limit = int(request.GET.get('limit') or len(bookmarks) - offset)
        rows = [{
            'id': b.id,
            'url': b.url,
            'title': b.title,
            'bookmarked_at': b.bookmarked_at
        } for b in bookmarks[offset:offset + limit]]
        data = {
            'total': len(bookmarks),
            'rows': rows
        }
        return JsonResponse(data)
    elif request.method == 'POST':
        url = request.POST['url']
        title = request.POST['title']
        bookmark = Bookmark()
        bookmark.url = url
        bookmark.title = title
        bookmark.save()
        logger.debug('create bookmark for url={0}, title={1}'.format(url, title))
        data = {}
        return JsonResponse(data, status=201)
    else:
        return JsonResponse({}, status=405)

@ensure_csrf_cookie
def bookmark(request, bookmark_id):
    if request.method == 'DELETE':
        try:
            bookmark = Bookmark.objects.get(pk=bookmark_id)
            bookmark.delete()
            return JsonResponse({}, status=204)
        except:
            data = {
                'errors': [{
                    'title': 'ブックマークを削除できませんでした'
                }]
            }
            return JsonResponse(data, status=500)
    else:
        return JsonResponse({}, status=405)

<commit_msg>Implement sort<commit_after>from django.http import JsonResponse
from django.shortcuts import render
from django.db.models import Q
from django.views.decorators.csrf import ensure_csrf_cookie
from logging import getLogger

from bookmarks.models import Bookmark

logger = getLogger(__name__)

@ensure_csrf_cookie
def bookmarks(request):
    if request.method == 'GET':
        return _get_bookmarks(request)
    elif request.method == 'POST':
        return _post_bookmarks(request)
    else:
        return JsonResponse({}, status=405)

def _get_bookmarks(request):
    search = request.GET.get('search')
    if search:
        bookmarks = Bookmark.objects.filter(Q(title__contains=search) | Q(url__contains=search))
    else:
        bookmarks = Bookmark.objects.all()
    sort = request.GET.get('sort')
    if sort and sort in ('id', 'url', 'title', 'bookmarked_at'):
        if request.GET.get('order') == 'desc':
            order = '-{0}'.format(sort)
        else:
            order = sort
        bookmarks = bookmarks.order_by(order)

    offset = int(request.GET.get('offset') or '0')
    limit = int(request.GET.get('limit') or len(bookmarks) - offset)
    rows = [{
        'id': b.id,
        'url': b.url,
        'title': b.title,
        'bookmarked_at': b.bookmarked_at
    } for b in bookmarks[offset:offset + limit]]
    data = {
        'total': len(bookmarks),
        'rows': rows
    }
    return JsonResponse(data)

def _post_bookmarks(request):
    url = request.POST['url']
    title = request.POST['title']
    bookmark = Bookmark()
    bookmark.url = url
    bookmark.title = title
    bookmark.save()
    data = {}
    return JsonResponse(data, status=201)

@ensure_csrf_cookie
def bookmark(request, bookmark_id):
    if request.method == 'DELETE':
        return _delete_bookmark(request, bookmark_id)
    else:
        return JsonResponse({}, status=405)

def _delete_bookmark(request, bookmark_id):
    try:
        bookmark = Bookmark.objects.get(pk=bookmark_id)
        bookmark.delete()
        return JsonResponse({}, status=204)
    except:
        data = {
            'errors': [{
                'title': 'ブックマークを削除できませんでした'
            }]
        }
        return JsonResponse(data, status=500)
<|endoftext|>


<commit_before>from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django_xhtml2pdf.utils import generate_pdf
from .forms import ClientForm
from .forms import ContactForm
from .forms import EstimateForm
from .forms import InvoiceForm
from .forms import ProjectForm
from .forms import TaskForm
from .forms import TimeForm
from .models import Client
from .models import Contact
from .models import Estimate
from .models import Invoice
from .models import Project
from .models import Task
from .models import Time

# Create your views here.

@staff_member_required
def client(request, pk=None):
    context = {}
    client = get_object_or_404(Client, pk=pk)
    projects = Project.objects.filter(client=client)
    context['client'] = client
    context['projects'] = projects
    return render(request, 'client.html', context)

@staff_member_required
def client_edit(request, pk=None):
    context = {}

    if pk is None:
        form = ClientForm()
    else:
        client = get_object_or_404(Client, pk=pk)
        form = ClientForm(instance=client)

    if request.method == 'POST':

        if pk is None:
            form = ClientForm(request.POST)
        else:
            form = ClientForm(request.POST, instance=client)

        if form.is_valid():
            client = form.save()
            return HttpResponseRedirect(reverse('client_index'))

    context['form'] = form
    return render(request, 'client_edit.html', context)

@staff_member_required
def client_index(request):
    context = {}
    show_all = request.GET.get('show-all', False)
    if show_all:
        clients = Client.objects.all()
    else:
        clients = Client.objects.filter(active=True)
    context['clients'] = clients
    return render(request, 'client_index.html', context)

@staff_member_required
def contact(request, pk=None):
    context = {}
    contact = get_object_or_404(Contact, pk=pk)
    context['contact'] = contact
    return render(request, 'contact.html', context)

@staff_member_required
def contact_edit(request, pk=None):
    context = {}
    contact = None

    if pk is None:
        form = ContactForm()
    else:
        contact = get_object_or_404(Contact, pk=pk)
        form = ContactForm(instance=contact)

    if request.method == 'POST':

        if pk is None:
            form = ContactForm(request.POST)
        else:
            form = ContactForm(request.POST, instance=contact)

        if form.is_valid():
            contact = form.save()
            return HttpResponseRedirect(reverse('contact_index'))

    context['contact'] = contact
    context['form'] = form
    return render(request, 'contact_edit.html', context)

@staff_member_required
def contact_index(request):
    context = {}
    show_all = request.GET.get('show-all', False)
    if show_all:
        contacts = Contact.objects.all()
    else:
        contacts = Contact.objects.filter(active=True)
    context['contacts'] = contacts
    return render(request, 'contact_index.html', context)

@staff_member_required
def estimate(request, pk=None):
    context = {}
    estimate = get_object_or_404(Estimate, pk=pk)
    context['estimate'] = estimate
    return render(request, 'estimate.html', context)

@staff_member_required
def estimate_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = EstimateForm()
        else:
            client = get_object_or_404(Client, pk=client)
            estimate = Estimate(client=client)
            form = EstimateForm(instance=estimate)
    else:
        estimate = get_object_or_404(Estimate, pk=pk)
        form = EstimateForm(instance=estimate)

    if request.method == 'POST':

        if pk is None:
            form = EstimateForm(request.POST)
        else:
            estimate = get_object_or_404(Estimate, pk=pk)
            form = EstimateForm(request.POST, instance=estimate)

        if form.is_valid():
            estimate = form.save()
            return HttpResponseRedirect(reverse('estimate_index'))

    context['form'] = form
    return render(request, 'estimate_edit.html', context)

@staff_member_required
def estimate_index(request):
    context = {}
    estimates = Estimate.objects.all()
    context['estimates'] = estimates
    return render(request, 'estimate_index.html', context)

@staff_member_required
def estimate_pdf(request, pk=None):
    estimate = get_object_or_404(Estimate, pk=pk)
    context = {}
    context['estimate'] = estimate
    response = HttpResponse(content_type='application/pdf')
    return generate_pdf('estimate.html', context=context, file_object=response)

def home(request):
    context = {}
    clients = Client.objects.all()
    context['request'] = request
    context['clients'] = clients
    return render(request, 'home.html', context)

@staff_member_required
def invoice(request, pk=None):
    client = None
    context = {}
    invoice = get_object_or_404(Invoice, pk=pk)
    project = Project.objects.filter(invoice=invoice)
    clients = Client.objects.filter(project=project)
    if len(clients) > 0:
        client = clients[0]
    tasks = Task.objects.all()
    context['client'] = client
    context['invoice'] = invoice
    context['project'] = project
    context['tasks'] = tasks
    return render(request, 'invoice.html', context)

@staff_member_required
def invoice_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = InvoiceForm()
        else:
            client = get_object_or_404(Client, pk=client)
            invoice = Invoice(client=client)
            form = InvoiceForm(instance=invoice)
    else:
        invoice = get_object_or_404(Invoice, pk=pk)
        form = InvoiceForm(instance=invoice)

    if request.method == 'POST':

        if pk is None:
            form = InvoiceForm(request.POST)
        else:
            invoice = get_object_or_404(Invoice, pk=pk)
            form = InvoiceForm(request.POST, instance=invoice)

        if form.is_valid():
            invoice = form.save()
            return HttpResponseRedirect(reverse('invoice_index'))

    context['form'] = form
    return render(request, 'invoice_edit.html', context)

@staff_member_required
def invoice_index(request):
    client = None
    context = {}
    invoices = []
    for invoice in Invoice.objects.all():
        clients = Client.objects.filter(project=invoice.project)
        if len(clients) > 0:
            client = clients[0]
        invoices.append([invoice, client])
    context['invoices'] = invoices

    return render(request, 'invoice_index.html', context)

@staff_member_required
def invoice_pdf(request, pk=None):
    invoice = get_object_or_404(Invoice, pk=pk)
    context = {}
    context['invoice'] = invoice
    response = HttpResponse(content_type='application/pdf')
    return generate_pdf('invoice.html', context=context, file_object=response)

@staff_member_required
def project(request, pk=None):
    context = {}
    project = get_object_or_404(Project, pk=pk)
    times = Time.objects.filter(project=project)
    context['project'] = project
    context['times'] = times
    return render(request, 'project.html', context)

@staff_member_required
def project_edit(request, pk=None):
    context = {}

    client = request.GET.get('client', None)

    if pk is None:
        if client is None:
            form = ProjectForm()
        else:
            client = get_object_or_404(Client, pk=client)
            project = Project(client=client)
            form = ProjectForm(instance=project)
    else:
        project = get_object_or_404(Project, pk=pk)
        form = ProjectForm(instance=project)

    if request.method == 'POST':

        if pk is None:
            form = ProjectForm(request.POST)
        else:
            project = get_object_or_404(Project, pk=pk)
            form = ProjectForm(request.POST, instance=project)

        if form.is_valid():
            project = form.save()
            return HttpResponseRedirect(reverse('project_index'))

    context['form'] = form
    return render(request, 'project_edit.html', context)

@staff_member_required
def project_index(request, pk=None):
    context = {}
    projects = Project.objects.all()
    context['projects'] = projects
    return render(request, 'project_index.html', context)

@staff_member_required
def task(request, pk=None):
    context = {}
    task = get_object_or_404(Task, pk=pk)
    context['task'] = task
    return render(request, 'task.html', context)

@staff_member_required
def task_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TaskForm()
        else:
            project = get_object_or_404(Project, pk=project)
            task = Task(project=project)
            form = TaskForm(instance=task)
    else:
        task = get_object_or_404(Task, pk=pk)
        form = TaskForm(instance=task)

    if request.method == 'POST':

        if pk is None:
            form = TaskForm(request.POST)
        else:
            task = get_object_or_404(Task, pk=pk)
            form = TaskForm(request.POST, instance=task)

        if form.is_valid():
            task = form.save()
            return HttpResponseRedirect(reverse('task_index'))

    context['form'] = form
    return render(request, 'task_edit.html', context)

@staff_member_required
def task_index(request):
    context = {}
    tasks = Task.objects.all()
    context['tasks'] = tasks
    return render(request, 'task_index.html', context)

@login_required
def time(request, pk=None):
    context = {}
    entry = get_object_or_404(Time, pk=pk)
    context['entry'] = entry
    return render(request, 'time.html', context)

@login_required
def time_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TimeForm()
        else:
            project = get_object_or_404(Project, pk=project)
            time = Time(project=project)
            form = TimeForm(instance=time)
    else:
        time = get_object_or_404(Time, pk=pk)
        form = TimeForm(instance=time)

    if request.method == 'POST':

        if pk is None:
            form = TimeForm(request.POST)
        else:
            time = get_object_or_404(Time, pk=pk)
            form = TimeForm(request.POST, instance=time)

        if form.is_valid():
            time = form.save()
            return HttpResponseRedirect(reverse('entry_index'))

    context['form'] = form
    return render(request, 'time_edit.html', context)

@login_required
def time_index(request):
    context = {}
    entries = Time.objects.all()
    context['entries'] = entries
    return render(request, 'time_index.html', context)

@login_required
def user(request, pk=None):
    context = {}
    user = get_object_or_404(User, pk=pk)
    context['request'] = request
    context['user'] = user
    return render(request, 'user.html', context)

@staff_member_required
def user_index(request):
    context = {}
    users = User.objects.all()
    context['users'] = users
    return render(request, 'user_index.html', context)
<commit_msg>Update<commit_after>from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django_xhtml2pdf.utils import generate_pdf
from .forms import ClientForm
from .forms import ContactForm
from .forms import EstimateForm
from .forms import InvoiceForm
from .forms import ProjectForm
from .forms import TaskForm
from .forms import TimeForm
from .models import Client
from .models import Contact
from .models import Estimate
from .models import Invoice
from .models import Project
from .models import Task
from .models import Time

# Create your views here.

@staff_member_required
def client(request, pk=None):
    context = {}
    client = get_object_or_404(Client, pk=pk)
    projects = Project.objects.filter(client=client)
    context['client'] = client
    context['projects'] = projects
    return render(request, 'client.html', context)

@staff_member_required
def client_edit(request, pk=None):
    context = {}

    if pk is None:
        form = ClientForm()
    else:
        client = get_object_or_404(Client, pk=pk)
        form = ClientForm(instance=client)

    if request.method == 'POST':

        if pk is None:
            form = ClientForm(request.POST)
        else:
            form = ClientForm(request.POST, instance=client)

        if form.is_valid():
            client = form.save()
            return HttpResponseRedirect(reverse('client_index'))

    context['form'] = form
    return render(request, 'client_edit.html', context)

@staff_member_required
def client_index(request):
    context = {}
    show_all = request.GET.get('show-all', False)
    if show_all:
        clients = Client.objects.all()
    else:
        clients = Client.objects.filter(active=True)
    context['clients'] = clients
    return render(request, 'client_index.html', context)

@staff_member_required
def contact(request, pk=None):
    context = {}
    contact = get_object_or_404(Contact, pk=pk)
    context['contact'] = contact
    return render(request, 'contact.html', context)

@staff_member_required
def contact_edit(request, pk=None):
    context = {}
    contact = None

    if pk is None:
        form = ContactForm()
    else:
        contact = get_object_or_404(Contact, pk=pk)
        form = ContactForm(instance=contact)

    if request.method == 'POST':

        if pk is None:
            form = ContactForm(request.POST)
        else:
            form = ContactForm(request.POST, instance=contact)

        if form.is_valid():
            contact = form.save()
            return HttpResponseRedirect(reverse('contact_index'))

    context['contact'] = contact
    context['form'] = form
    return render(request, 'contact_edit.html', context)

@staff_member_required
def contact_index(request):
    context = {}
    show_all = request.GET.get('show-all', False)
    if show_all:
        contacts = Contact.objects.all()
    else:
        contacts = Contact.objects.filter(active=True)
    context['contacts'] = contacts
    return render(request, 'contact_index.html', context)

@staff_member_required
def estimate(request, pk=None):
    context = {}
    estimate = get_object_or_404(Estimate, pk=pk)
    context['estimate'] = estimate
    return render(request, 'estimate.html', context)

@staff_member_required
def estimate_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = EstimateForm()
        else:
            client = get_object_or_404(Client, pk=client)
            estimate = Estimate(client=client)
            form = EstimateForm(instance=estimate)
    else:
        estimate = get_object_or_404(Estimate, pk=pk)
        form = EstimateForm(instance=estimate)

    if request.method == 'POST':

        if pk is None:
            form = EstimateForm(request.POST)
        else:
            estimate = get_object_or_404(Estimate, pk=pk)
            form = EstimateForm(request.POST, instance=estimate)

        if form.is_valid():
            estimate = form.save()
            return HttpResponseRedirect(reverse('estimate_index'))

    context['form'] = form
    return render(request, 'estimate_edit.html', context)

@staff_member_required
def estimate_index(request):
    context = {}
    estimates = Estimate.objects.all()
    context['estimates'] = estimates
    return render(request, 'estimate_index.html', context)

@staff_member_required
def estimate_pdf(request, pk=None):
    estimate = get_object_or_404(Estimate, pk=pk)
    context = {}
    context['estimate'] = estimate
    response = HttpResponse(content_type='application/pdf')
    return generate_pdf('estimate.html', context=context, file_object=response)

def home(request):
    context = {}
    clients = Client.objects.all()
    context['request'] = request
    context['clients'] = clients
    return render(request, 'home.html', context)

@staff_member_required
def invoice(request, pk=None):
    client = None
    context = {}
    invoice = get_object_or_404(Invoice, pk=pk)
    project = Project.objects.filter(invoice=invoice)
    clients = Client.objects.filter(project=project)
    if len(clients) > 0:
        client = clients[0]
    tasks = Task.objects.all()
    context['client'] = client
    context['invoice'] = invoice
    context['project'] = project
    context['tasks'] = tasks
    return render(request, 'invoice.html', context)

@staff_member_required
def invoice_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = InvoiceForm()
        else:
            client = get_object_or_404(Client, pk=client)
            invoice = Invoice(client=client)
            form = InvoiceForm(instance=invoice)
    else:
        invoice = get_object_or_404(Invoice, pk=pk)
        form = InvoiceForm(instance=invoice)

    if request.method == 'POST':

        if pk is None:
            form = InvoiceForm(request.POST)
        else:
            invoice = get_object_or_404(Invoice, pk=pk)
            form = InvoiceForm(request.POST, instance=invoice)

        if form.is_valid():
            invoice = form.save()
            return HttpResponseRedirect(reverse('invoice_index'))

    context['form'] = form
    return render(request, 'invoice_edit.html', context)

@staff_member_required
def invoice_index(request):
    client = None
    context = {}
    invoices = []
    for invoice in Invoice.objects.all():
        clients = Client.objects.filter(project=invoice.project)
        if len(clients) > 0:
            client = clients[0]
        invoices.append([invoice, client])
    context['invoices'] = invoices

    return render(request, 'invoice_index.html', context)

@staff_member_required
def invoice_pdf(request, pk=None):
    invoice = get_object_or_404(Invoice, pk=pk)
    context = {}
    context['invoice'] = invoice
    response = HttpResponse(content_type='application/pdf')
    return generate_pdf('invoice.html', context=context, file_object=response)

@staff_member_required
def project(request, pk=None):
    context = {}
    project = get_object_or_404(Project, pk=pk)
    times = Time.objects.filter(project=project)
    context['project'] = project
    context['times'] = times
    return render(request, 'project.html', context)

@staff_member_required
def project_edit(request, pk=None):
    context = {}

    client = request.GET.get('client', None)

    if pk is None:
        if client is None:
            form = ProjectForm()
        else:
            client = get_object_or_404(Client, pk=client)
            project = Project(client=client)
            form = ProjectForm(instance=project)
    else:
        project = get_object_or_404(Project, pk=pk)
        form = ProjectForm(instance=project)

    if request.method == 'POST':

        if pk is None:
            form = ProjectForm(request.POST)
        else:
            project = get_object_or_404(Project, pk=pk)
            form = ProjectForm(request.POST, instance=project)

        if form.is_valid():
            project = form.save()
            return HttpResponseRedirect(reverse('project_index'))

    context['form'] = form
    return render(request, 'project_edit.html', context)

@staff_member_required
def project_index(request, pk=None):
    context = {}
    projects = Project.objects.all()
    context['projects'] = projects
    return render(request, 'project_index.html', context)

@staff_member_required
def task(request, pk=None):
    context = {}
    task = get_object_or_404(Task, pk=pk)
    context['task'] = task
    return render(request, 'task.html', context)

@staff_member_required
def task_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TaskForm()
        else:
            project = get_object_or_404(Project, pk=project)
            task = Task(project=project)
            form = TaskForm(instance=task)
    else:
        task = get_object_or_404(Task, pk=pk)
        form = TaskForm(instance=task)

    if request.method == 'POST':

        if pk is None:
            form = TaskForm(request.POST)
        else:
            task = get_object_or_404(Task, pk=pk)
            form = TaskForm(request.POST, instance=task)

        if form.is_valid():
            task = form.save()
            return HttpResponseRedirect(reverse('task_index'))

    context['form'] = form
    return render(request, 'task_edit.html', context)

@staff_member_required
def task_index(request):
    context = {}
    tasks = Task.objects.all()
    context['tasks'] = tasks
    return render(request, 'task_index.html', context)

@login_required
def time(request, pk=None):
    context = {}
    entry = get_object_or_404(Time, pk=pk)
    context['entry'] = entry
    return render(request, 'time.html', context)

@login_required
def time_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TimeForm()
        else:
            project = get_object_or_404(Project, pk=project)
            time = Time(project=project)
            form = TimeForm(instance=time)
    else:
        time = get_object_or_404(Time, pk=pk)
        form = TimeForm(instance=time)

    if request.method == 'POST':

        if pk is None:
            form = TimeForm(request.POST)
        else:
            time = get_object_or_404(Time, pk=pk)
            form = TimeForm(request.POST, instance=time)

        if form.is_valid():
            time = form.save()
            return HttpResponseRedirect(reverse('entry_index'))

    context['form'] = form
    return render(request, 'time_edit.html', context)

@login_required
def time_index(request):
    context = {}
    entries = Time.objects.all()
    context['entries'] = entries
    return render(request, 'time_index.html', context)

@login_required
def user(request, pk=None):
    context = {}
    user = get_object_or_404(User, pk=pk)
    context['request'] = request
    context['user'] = user

    if request.user.pk == int(pk):
        return render(request, 'user.html', context)
    else:
        return HttpResponseRedirect(reverse('home'))

@staff_member_required
def user_index(request):
    context = {}
    users = User.objects.all()
    context['users'] = users
    return render(request, 'user_index.html', context)
<|endoftext|>


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

import numpy as np
import math
import numbers
from lazy import *
import abc

class TimeSeriesInterface(abc.ABC):

    @abc.abstractmethod
    def __iter__(self):
       '''Iterate over data in TimeSeries'''

    @abc.abstractmethod
    def iteritems(self):
        '''Iterate over (time, data)'''

    @abc.abstractmethod
    def itertimes(self):
        '''Iterate over times'''

class SizedContainerTimeSeriesInterface(TimeSeriesInterface):

    def __init__(self, time_points, data_points):

        # Raise an exception if any parameter is not a sequence
        params = {'time_points': time_points,
                  'data_points': data_points}
        for p in params:
            try:
                iter(params[p])
            except:
                raise TypeError('`%s` must be a sequence.' % p)

        # Raise an exception if `time_points` and `data_points` are not the same length
        if len(list(time_points)) != len(list(data_points)):
            raise ValueError('`time_points` and `data_points` must have the same length.')

    def __getitem__(self, key):
        return self._data[key]

    def __setitem__(self, key, value):
        self._data[key] = value

    def __repr__(self):
        return str(self)

    def __str__(self):
        format_str = '{}([{}])'
        row_str = '[{}\t{}]'
        add_str = ''

        for pts in self.iteritems():
            add_str += row_str.format(pts[0], pts[1])
        class_name = type(self).__name__
        return format_str.format(class_name, add_str)

    def interpolate(self, pts):
        inter_pts = []
        ts = list(pts)
        for pt in ts:
            # Get the two time points bounding `pts`
            times = sorted(enumerate(self._times), key = lambda x: abs(x[1] - pt))[:2]
            vals = [self._data[times[0][0]], self._data[times[1][0]]]
            x = vals[0] + (pt - times[0][1]) * (vals[1] - vals[0]) / (times[1][1] - times[0][1])
            inter_pts.append(x)
        return TimeSeries(ts, inter_pts)

    def __abs__(self):
        return math.sqrt(sum(x**2 for x in self))

    def __bool__(self):
        return bool(abs(self))

    def _check_time_values(function):
        def _check_time_values_helper(self , rhs):
            print(rhs)
            try:
<<<<<<< HEAD
                if isinstance(rhs, numbers.Real):
                    return function(self, rhs)
                elif len(self) != len(rhs) or not all(t1 == t2 for t1, t2 in zip(self.itertimes(), rhs.itertimes())):
                    raise ValueError('Both time series must have the same time points.')
                return function(self, rhs)
=======
                if len(self._times)!=len(rhs._times) or not all(t1 == t2 for t1, t2 in zip(self._times, rhs._times)):
                    raise ValueError(str(self)+' and '+str(rhs)+' must have the same points')
                return function(self,rhs)
>>>>>>> ce48486ded2ac12e986338efdf4067fd7d265e1a
            except AttributeError:
                raise NotImplemented
        return _check_time_values_helper

    def __neg__(self):
        # TODO: Create instance of calling class instead of TimeSeries
        return TimeSeries(list(self.itertimes()), [-x for x in iter(self)])

    def __pos__(self):
        # TODO: Create instance of calling class instead of TimeSeries
        return TimeSeries(list(self.itertimes()), list(iter(self)))

    @_check_time_values
    def __eq__(self, other):
        if isinstance(other, numbers.Real):
            return (all(x == numbers.Real for x in iter(self)))
        else:
            return (all(x == y for x, y in zip(iter(self), iter(other))))

    @_check_time_values
    def __add__(self, other):
        if isinstance(other, numbers.Real):
            return TimeSeries(list(self.itertimes()), [x + other for x in iter(self)])
        else:
            return TimeSeries(list(self.itertimes()), [x + y for x, y in zip(iter(self), iter(other))])

    @_check_time_values
    def __sub__(self, other):
        if isinstance(other, numbers.Real):
            return TimeSeries(list(self.itertimes()), [x - other for x in iter(self)])
        else:
            return TimeSeries(list(self.itertimes()), [x - y for x, y in zip(iter(self), iter(other))])

    @_check_time_values
    def __mul__(self, other):
        if isinstance(other, numbers.Real):
            return TimeSeries(list(self.itertimes()), [x * other for x in iter(self)])
        else:
            return TimeSeries(list(self.itertimes()), [x * y for x, y in zip(iter(self), iter(other))])

    def iteritems(self):
        return iter(zip(self.itertimes(), iter(self)))

    @property
    def lazy(self):
        return LazyOperation(lambda x: x, self)

class TimeSeries(SizedContainerTimeSeriesInterface):
    def __init__(self, time_points, data_points):

        super().__init__(time_points, data_points)
        self._times = list(time_points)
        self._data = list(data_points)

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

    def __iter__(self):
        return iter(self._data)

    def itertimes(self):
        return iter(self._times)

class ArrayTimeSeries(TimeSeries):

    def __init__(self, time_points, data_points):

        super().__init__(time_points, data_points)

        self._length = len(time_points)
        self._times = np.empty(self._length * 2)
        self._data = np.empty(self._length * 2)
        self._times[:self._length] = time_points
        self._data[:self._length] = data_points

    def __len__(self):
        return self._length

    def __getitem__(self, key):
        if key >= self._length:
            raise IndexError('ArrayTimeSeries index out of range.')
        return self._data[key]

    def __setitem__(self, key, value):
        if key >= self._length:
            raise IndexError('ArrayTimeSeries index out of range.')
        self._data[key] = value

    def __iter__(self):
        return iter(self._data[:self._length])

    def itertimes(self):
        '''Returns an iterator over the time indices for the ArrayTimeSeries.'''
        return iter(self._times[:self._length])

    def iteritems(self):
        '''Returns an iterator over the tuples (time, value) for each item in the ArrayTimeSeries.'''
        return iter(zip(self._times[:self._length], self._data[:self._length]))

class StreamTimeSeriesInterface(TimeSeriesInterface):
    '''Creates an interface for a Timeseries with no internal storage that
    yields data based on a generator '''

    @abc.abstractmethod
    def produce(self)->list:
        "intersection with another set"

class SimulatedTimeSeries(StreamTimeSeriesInterface):

    def __init__(self, generator):
        self._gen = generator

    def __iter__(self):
        return self

    def __next__(self):
        return self.produce()

    def iteritems(self):
        return self.produce()[1]

    def itertimes(self):
        return self.produce()[0]

    def __repr__(self):
        format_str = '{}([{}])'

        class_name = type(self).__name__
        return format_str.format(class_name, str(self._gen))

    def produce(self, chunk=1):
        for i in range(chunk):
            value = next(self._gen)
            if type(value) == tuple:
                return value
            else:
                return (datetime.datetime.now(), value)
<commit_msg>Fixed merge build bug<commit_after>#!/usr/bin/env python3

import numpy as np
import math
import numbers
from lazy import *
import abc

class TimeSeriesInterface(abc.ABC):

    @abc.abstractmethod
    def __iter__(self):
       '''Iterate over data in TimeSeries'''

    @abc.abstractmethod
    def iteritems(self):
        '''Iterate over (time, data)'''

    @abc.abstractmethod
    def itertimes(self):
        '''Iterate over times'''

class SizedContainerTimeSeriesInterface(TimeSeriesInterface):

    def __init__(self, time_points, data_points):

        # Raise an exception if any parameter is not a sequence
        params = {'time_points': time_points,
                  'data_points': data_points}
        for p in params:
            try:
                iter(params[p])
            except:
                raise TypeError('`%s` must be a sequence.' % p)

        # Raise an exception if `time_points` and `data_points` are not the same length
        if len(list(time_points)) != len(list(data_points)):
            raise ValueError('`time_points` and `data_points` must have the same length.')

    def __getitem__(self, key):
        return self._data[key]

    def __setitem__(self, key, value):
        self._data[key] = value

    def __repr__(self):
        return str(self)

    def __str__(self):
        format_str = '{}([{}])'
        row_str = '[{}\t{}]'
        add_str = ''

        for pts in self.iteritems():
            add_str += row_str.format(pts[0], pts[1])
        class_name = type(self).__name__
        return format_str.format(class_name, add_str)

    def interpolate(self, pts):
        inter_pts = []
        ts = list(pts)
        for pt in ts:
            # Get the two time points bounding `pts`
            times = sorted(enumerate(self._times), key = lambda x: abs(x[1] - pt))[:2]
            vals = [self._data[times[0][0]], self._data[times[1][0]]]
            x = vals[0] + (pt - times[0][1]) * (vals[1] - vals[0]) / (times[1][1] - times[0][1])
            inter_pts.append(x)
        return TimeSeries(ts, inter_pts)

    def __abs__(self):
        return math.sqrt(sum(x**2 for x in self))

    def __bool__(self):
        return bool(abs(self))

    def _check_time_values(function):
        def _check_time_values_helper(self , rhs):
            print(rhs)
            try:
                if isinstance(rhs, numbers.Real):
                    return function(self, rhs)
                elif len(self) != len(rhs) or not all(t1 == t2 for t1, t2 in zip(self.itertimes(), rhs.itertimes())):
                    raise ValueError('Both time series must have the same time points.')
                return function(self, rhs)
            except AttributeError:
                raise NotImplemented
        return _check_time_values_helper

    def __neg__(self):
        # TODO: Create instance of calling class instead of TimeSeries
        return TimeSeries(list(self.itertimes()), [-x for x in iter(self)])

    def __pos__(self):
        # TODO: Create instance of calling class instead of TimeSeries
        return TimeSeries(list(self.itertimes()), list(iter(self)))

    @_check_time_values
    def __eq__(self, other):
        if isinstance(other, numbers.Real):
            return (all(x == numbers.Real for x in iter(self)))
        else:
            return (all(x == y for x, y in zip(iter(self), iter(other))))

    @_check_time_values
    def __add__(self, other):
        if isinstance(other, numbers.Real):
            return TimeSeries(list(self.itertimes()), [x + other for x in iter(self)])
        else:
            return TimeSeries(list(self.itertimes()), [x + y for x, y in zip(iter(self), iter(other))])

    @_check_time_values
    def __sub__(self, other):
        if isinstance(other, numbers.Real):
            return TimeSeries(list(self.itertimes()), [x - other for x in iter(self)])
        else:
            return TimeSeries(list(self.itertimes()), [x - y for x, y in zip(iter(self), iter(other))])

    @_check_time_values
    def __mul__(self, other):
        if isinstance(other, numbers.Real):
            return TimeSeries(list(self.itertimes()), [x * other for x in iter(self)])
        else:
            return TimeSeries(list(self.itertimes()), [x * y for x, y in zip(iter(self), iter(other))])

    def iteritems(self):
        return iter(zip(self.itertimes(), iter(self)))

    @property
    def lazy(self):
        return LazyOperation(lambda x: x, self)

class TimeSeries(SizedContainerTimeSeriesInterface):
    def __init__(self, time_points, data_points):

        super().__init__(time_points, data_points)
        self._times = list(time_points)
        self._data = list(data_points)

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

    def __iter__(self):
        return iter(self._data)

    def itertimes(self):
        return iter(self._times)

class ArrayTimeSeries(TimeSeries):

    def __init__(self, time_points, data_points):

        super().__init__(time_points, data_points)

        self._length = len(time_points)
        self._times = np.empty(self._length * 2)
        self._data = np.empty(self._length * 2)
        self._times[:self._length] = time_points
        self._data[:self._length] = data_points

    def __len__(self):
        return self._length

    def __getitem__(self, key):
        if key >= self._length:
            raise IndexError('ArrayTimeSeries index out of range.')
        return self._data[key]

    def __setitem__(self, key, value):
        if key >= self._length:
            raise IndexError('ArrayTimeSeries index out of range.')
        self._data[key] = value

    def __iter__(self):
        return iter(self._data[:self._length])

    def itertimes(self):
        '''Returns an iterator over the time indices for the ArrayTimeSeries.'''
        return iter(self._times[:self._length])

    def iteritems(self):
        '''Returns an iterator over the tuples (time, value) for each item in the ArrayTimeSeries.'''
        return iter(zip(self._times[:self._length], self._data[:self._length]))

class StreamTimeSeriesInterface(TimeSeriesInterface):
    '''Creates an interface for a Timeseries with no internal storage that
    yields data based on a generator '''

    @abc.abstractmethod
    def produce(self)->list:
        "intersection with another set"

class SimulatedTimeSeries(StreamTimeSeriesInterface):

    def __init__(self, generator):
        self._gen = generator

    def __iter__(self):
        return self

    def __next__(self):
        return self.produce()

    def iteritems(self):
        return self.produce()[1]

    def itertimes(self):
        return self.produce()[0]

    def __repr__(self):
        format_str = '{}([{}])'

        class_name = type(self).__name__
        return format_str.format(class_name, str(self._gen))

    def produce(self, chunk=1):
        for i in range(chunk):
            value = next(self._gen)
            if type(value) == tuple:
                return value
            else:
                return (datetime.datetime.now(), value)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# This file is part of the pyMor project (http://www.pymor.org).
# Copyright Holders: Felix Albrecht, Rene Milk, Stephan Rave
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from __future__ import absolute_import, division, print_function

import numpy as np

from pymor.algorithms.timestepping import TimeStepperInterface
from pymor.la.interfaces import VectorArrayInterface
from pymor.tools import selfless_arguments
from pymor.operators import OperatorInterface, LinearOperatorInterface, ConstantOperator
from pymor.discretizations.interfaces import DiscretizationInterface

class InstationaryNonlinearDiscretization(DiscretizationInterface):

    def __init__(self, operator, rhs, initial_data, T, time_stepper=None, products=None, parameter_space=None,
                 estimator=None, visualizer=None, caching='disk', name=None):
        assert isinstance(operator, OperatorInterface)
        assert isinstance(rhs, LinearOperatorInterface)
        assert isinstance(initial_data, (VectorArrayInterface, OperatorInterface))
        assert not isinstance(initial_data, OperatorInterface) or initial_data.dim_source == 0
        if isinstance(initial_data, VectorArrayInterface):
            initial_data = ConstantOperator(initial_data, name='initial_data')
        assert isinstance(time_stepper, TimeStepperInterface)
        assert operator.dim_source == operator.dim_range == rhs.dim_source == initial_data.dim_range
        assert rhs.dim_range == 1

        operators = {'operator': operator, 'rhs': rhs, 'initial_data': initial_data}
        super(InstationaryNonlinearDiscretization, self).__init__(operators=operators, products=products,
                                                                  estimator=estimator, visualizer=visualizer,
                                                                  caching=caching, name=name)
        self.operator = operator
        self.rhs = rhs
        self.initial_data = initial_data
        self.T = T
        self.time_stepper = time_stepper
        self.solution_dim = operator.dim_range
        self.build_parameter_type(inherits=(operator, rhs, initial_data), provides={'_t': 0})
        self.parameter_space = parameter_space

        if hasattr(time_stepper, 'nt'):
            self.with_arguments.add('time_stepper_nt')
        self.lock()

    with_arguments = set(selfless_arguments(__init__)).union(['operators'])

    def with_(self, **kwargs):
        assert set(kwargs.keys()) <= self.with_arguments
        assert 'operators' not in kwargs or not ('rhs' in kwargs or 'operator' in kwargs or 'initial_data' in kwargs)
        assert 'operators' not in kwargs or set(kwargs['operators'].keys()) <= set(('operator', 'rhs', 'initial_data'))
        assert 'time_stepper_nt' not in kwargs or 'time_stepper' not in kwargs

        if 'time_stepper_nt' in kwargs:
            kwargs['time_stepper'] = self.time_stepper.with_(nt=kwargs.pop('time_stepper_nt'))

        if 'operators' in kwargs:
            kwargs.update(kwargs.pop('operators'))

        return self._with_via_init(kwargs)

    def _solve(self, mu=None):
        mu = self.parse_parameter(mu)

        # explicitly checking if logging is disabled saves the expensive str(mu) call
        if not self.logging_disabled:
            self.logger.info('Solving {} for {} ...'.format(self.name, mu))

        mu['_t'] = 0
        U0 = self.initial_data.apply(0, mu=mu)
        return self.time_stepper.solve(operator=self.operator, rhs=self.rhs, initial_data=U0, initial_time=0,
                                       end_time=self.T, mu=mu)
<commit_msg>[discretizations.nonlinear] bugfix<commit_after># -*- coding: utf-8 -*-
# This file is part of the pyMor project (http://www.pymor.org).
# Copyright Holders: Felix Albrecht, Rene Milk, Stephan Rave
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from __future__ import absolute_import, division, print_function

import numpy as np

from pymor.algorithms.timestepping import TimeStepperInterface
from pymor.la.interfaces import VectorArrayInterface
from pymor.tools import selfless_arguments
from pymor.operators import OperatorInterface, LinearOperatorInterface, ConstantOperator
from pymor.discretizations.interfaces import DiscretizationInterface

class InstationaryNonlinearDiscretization(DiscretizationInterface):

    def __init__(self, operator, rhs, initial_data, T, time_stepper=None, products=None, parameter_space=None,
                 estimator=None, visualizer=None, caching='disk', name=None):
        assert isinstance(operator, OperatorInterface)
        assert isinstance(rhs, LinearOperatorInterface)
        assert isinstance(initial_data, (VectorArrayInterface, OperatorInterface))
        assert not isinstance(initial_data, OperatorInterface) or initial_data.dim_source == 0
        if isinstance(initial_data, VectorArrayInterface):
            initial_data = ConstantOperator(initial_data, name='initial_data')
        assert isinstance(time_stepper, TimeStepperInterface)
        assert operator.dim_source == operator.dim_range == rhs.dim_source == initial_data.dim_range
        assert rhs.dim_range == 1

        operators = {'operator': operator, 'rhs': rhs, 'initial_data': initial_data}
        super(InstationaryNonlinearDiscretization, self).__init__(operators=operators, products=products,
                                                                  estimator=estimator, visualizer=visualizer,
                                                                  caching=caching, name=name)
        self.operator = operator
        self.rhs = rhs
        self.initial_data = initial_data
        self.T = T
        self.time_stepper = time_stepper
        self.solution_dim = operator.dim_range
        self.build_parameter_type(inherits=(operator, rhs, initial_data), provides={'_t': 0})
        self.parameter_space = parameter_space

        if hasattr(time_stepper, 'nt'):
            self.with_arguments.add('time_stepper_nt')
        self.lock()

    with_arguments = set(selfless_arguments(__init__)).union(['operators'])

    def with_(self, **kwargs):
        assert set(kwargs.keys()) <= self.with_arguments
        assert 'operators' not in kwargs or not ('rhs' in kwargs or 'operator' in kwargs or 'initial_data' in kwargs)
        assert 'operators' not in kwargs or set(kwargs['operators'].keys()) <= set(('operator', 'rhs', 'initial_data'))
        assert 'time_stepper_nt' not in kwargs or 'time_stepper' not in kwargs

        if 'time_stepper_nt' in kwargs:
            kwargs['time_stepper'] = self.time_stepper.with_(nt=kwargs.pop('time_stepper_nt'))

        if 'operators' in kwargs:
            kwargs.update(kwargs.pop('operators'))

        return self._with_via_init(kwargs)

    def _solve(self, mu=None):
        mu = self.parse_parameter(mu).copy()

        # explicitly checking if logging is disabled saves the expensive str(mu) call
        if not self.logging_disabled:
            self.logger.info('Solving {} for {} ...'.format(self.name, mu))

        mu['_t'] = 0
        U0 = self.initial_data.apply(0, mu=mu)
        return self.time_stepper.solve(operator=self.operator, rhs=self.rhs, initial_data=U0, initial_time=0,
                                       end_time=self.T, mu=mu)
<|endoftext|>