<commit_before># Copyright 2013 Rackspace Hosting
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import binascii
import logging

from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _

from horizon import exceptions
from horizon import forms
from horizon.utils import memoized
from horizon import workflows
from openstack_dashboard import api as dash_api
from openstack_dashboard.dashboards.project.instances \
    import utils as instance_utils
from openstack_dashboard.dashboards.project.instances.workflows \
    import create_instance as dash_create_instance


from stashboard import api

LOG = logging.getLogger(__name__)


def parse_datastore_and_version_text(datastore_and_version):
    if datastore_and_version:
        datastore, datastore_version = datastore_and_version.split('-', 1)
        return datastore.strip(), datastore_version.strip()
    return None, None


class SetInstanceDetailsAction(workflows.Action):
    availability_zone = forms.ChoiceField(
        label=_("Availability Zone"),
        required=False)
    name = forms.CharField(max_length=80, label=_("Instance Name"))
    volume = forms.IntegerField(label=_("Volume Size"),
                                min_value=0,
                                initial=1,
                                help_text=_("Size of the volume in GB."))
    volume_type = forms.ChoiceField(
        label=_("Volume Type"),
        required=False,
        help_text=_("Applicable only if the volume size is specified."))
    datastore = forms.ChoiceField(
        label=_("Datastore"),
        help_text=_("Type and version of datastore."),
        widget=forms.Select(attrs={
            'class': 'switchable',
            'data-slug': 'datastore'
        }))

    def __init__(self, request, *args, **kwargs):
        super(SetInstanceDetailsAction, self).__init__(request,
                                                       *args,
                                                       **kwargs)
        # Add this field to the end after the dynamic fields
        self.fields['locality'] = forms.ChoiceField(
            label=_("Locality"),
            choices=[("", "None"),
                     ("affinity", "affinity"),
                     ("anti-affinity", "anti-affinity")],
            required=False,
            help_text=_("Specify whether future replicated instances will "
                        "be created on the same hypervisor (affinity) or on "
                        "different hypervisors (anti-affinity). "
                        "This value is ignored if the instance to be "
                        "launched is a replica.")
        )

    class Meta(object):
        name = _("Details")
        help_text_template = "project/databases/_launch_details_help.html"

    def clean(self):
        datastore_and_version = self.data.get("datastore", None)
        if not datastore_and_version:
            msg = _("You must select a datastore type and version.")
            self._errors["datastore"] = self.error_class([msg])
        else:
            datastore, datastore_version = parse_datastore_and_version_text(
                binascii.unhexlify(datastore_and_version))
            field_name = self._build_flavor_field_name(datastore,
                                                       datastore_version)
            flavor = self.data.get(field_name, None)
            if not flavor:
                msg = _("You must select a flavor.")
                self._errors[field_name] = self.error_class([msg])

        if not self.data.get("locality", None):
            self.cleaned_data["locality"] = None

        return self.cleaned_data

    def handle(self, request, context):
        datastore_and_version = context["datastore"]
        if datastore_and_version:
            datastore, datastore_version = parse_datastore_and_version_text(
                binascii.unhexlify(context["datastore"]))
            field_name = self._build_flavor_field_name(datastore,
                                                       datastore_version)
            flavor = self.data[field_name]
            if flavor:
                context["flavor"] = flavor
                return context
        return None

    @memoized.memoized_method
    def availability_zones(self, request):
        try:
            return dash_api.nova.availability_zone_list(request)
        except Exception:
            LOG.exception("Exception while obtaining availablity zones")
            self._availability_zones = []

    def populate_availability_zone_choices(self, request, context):
        try:
            zones = self.availability_zones(request)
        except Exception:
            zones = []
            redirect = reverse('horizon:project:databases:index')
            exceptions.handle(request,
                              _('Unable to retrieve availability zones.'),
                              redirect=redirect)

        zone_list = [(zone.zoneName, zone.zoneName)
                     for zone in zones if zone.zoneState['available']]
        zone_list.sort()
        if not zone_list:
            zone_list.insert(0, ("", _("No availability zones found")))
        elif len(zone_list) > 1:
            zone_list.insert(0, ("", _("Any Availability Zone")))
        return zone_list

    @memoized.memoized_method
    def datastore_flavors(self, request, datastore_name, datastore_version):
        try:
            return api.trove.datastore_flavors(
                request, datastore_name, datastore_version)
        except Exception:
            LOG.exception("Exception while obtaining flavors list")
            redirect = reverse("horizon:project:databases:index")
            exceptions.handle(request,
                              _('Unable to obtain flavors.'),
                              redirect=redirect)

    @memoized.memoized_method
    def populate_volume_type_choices(self, request, context):
        try:
            volume_types = dash_api.cinder.volume_type_list(request)
            return ([("no_type", _("No volume type"))] +
                    [(type.name, type.name)
                     for type in volume_types])
        except Exception:
            LOG.exception("Exception while obtaining volume types list")
            self._volume_types = []

    @memoized.memoized_method
    def datastores(self, request):
        try:
            return api.trove.datastore_list(request)
        except Exception:
            LOG.exception("Exception while obtaining datastores list")
            self._datastores = []

    @memoized.memoized_method
    def datastore_versions(self, request, datastore):
        try:
            return api.trove.datastore_version_list(request, datastore)
        except Exception:
            LOG.exception("Exception while obtaining datastore version list")
            self._datastore_versions = []

    def populate_datastore_choices(self, request, context):
        choices = ()
        datastores = self.datastores(request)
        if datastores is not None:
            for ds in datastores:
                versions = self.datastore_versions(request, ds.name)
                if versions:
                    # only add to choices if datastore has at least one version
                    version_choices = ()
                    for v in versions:
                        if hasattr(v, 'active') and not v.active:
                            continue
                        selection_text = self._build_datastore_display_text(
                            ds.name, v.name)
                        widget_text = self._build_widget_field_name(
                            ds.name, v.name)
                        version_choices = (version_choices +
                                           ((widget_text, selection_text),))
                        self._add_datastore_flavor_field(request,
                                                         ds.name,
                                                         v.name)
                    choices = choices + version_choices
        return choices

    def _add_datastore_flavor_field(self,
                                    request,
                                    datastore,<commit_msg>Removing datastore flavors lookup<commit_after># Copyright 2013 Rackspace Hosting
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import binascii
import logging

from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _

from horizon import exceptions
from horizon import forms
from horizon.utils import memoized
from horizon import workflows
from openstack_dashboard import api as dash_api
from openstack_dashboard.dashboards.project.instances \
    import utils as instance_utils
from openstack_dashboard.dashboards.project.instances.workflows \
    import create_instance as dash_create_instance


from stashboard import api

LOG = logging.getLogger(__name__)


def parse_datastore_and_version_text(datastore_and_version):
    if datastore_and_version:
        datastore, datastore_version = datastore_and_version.split('-', 1)
        return datastore.strip(), datastore_version.strip()
    return None, None


class SetInstanceDetailsAction(workflows.Action):
    availability_zone = forms.ChoiceField(
        label=_("Availability Zone"),
        required=False)
    name = forms.CharField(max_length=80, label=_("Instance Name"))
    volume = forms.IntegerField(label=_("Volume Size"),
                                min_value=0,
                                initial=1,
                                help_text=_("Size of the volume in GB."))
    volume_type = forms.ChoiceField(
        label=_("Volume Type"),
        required=False,
        help_text=_("Applicable only if the volume size is specified."))
    datastore = forms.ChoiceField(
        label=_("Datastore"),
        help_text=_("Type and version of datastore."),
        widget=forms.Select(attrs={
            'class': 'switchable',
            'data-slug': 'datastore'
        }))

    def __init__(self, request, *args, **kwargs):
        super(SetInstanceDetailsAction, self).__init__(request,
                                                       *args,
                                                       **kwargs)
        # Add this field to the end after the dynamic fields
        self.fields['locality'] = forms.ChoiceField(
            label=_("Locality"),
            choices=[("", "None"),
                     ("affinity", "affinity"),
                     ("anti-affinity", "anti-affinity")],
            required=False,
            help_text=_("Specify whether future replicated instances will "
                        "be created on the same hypervisor (affinity) or on "
                        "different hypervisors (anti-affinity). "
                        "This value is ignored if the instance to be "
                        "launched is a replica.")
        )

    class Meta(object):
        name = _("Details")
        help_text_template = "project/databases/_launch_details_help.html"

    def clean(self):
        datastore_and_version = self.data.get("datastore", None)
        if not datastore_and_version:
            msg = _("You must select a datastore type and version.")
            self._errors["datastore"] = self.error_class([msg])
        else:
            datastore, datastore_version = parse_datastore_and_version_text(
                binascii.unhexlify(datastore_and_version))
            field_name = self._build_flavor_field_name(datastore,
                                                       datastore_version)
            flavor = self.data.get(field_name, None)
            if not flavor:
                msg = _("You must select a flavor.")
                self._errors[field_name] = self.error_class([msg])

        if not self.data.get("locality", None):
            self.cleaned_data["locality"] = None

        return self.cleaned_data

    def handle(self, request, context):
        datastore_and_version = context["datastore"]
        if datastore_and_version:
            datastore, datastore_version = parse_datastore_and_version_text(
                binascii.unhexlify(context["datastore"]))
            field_name = self._build_flavor_field_name(datastore,
                                                       datastore_version)
            flavor = self.data[field_name]
            if flavor:
                context["flavor"] = flavor
                return context
        return None

    @memoized.memoized_method
    def availability_zones(self, request):
        try:
            return dash_api.nova.availability_zone_list(request)
        except Exception:
            LOG.exception("Exception while obtaining availablity zones")
            self._availability_zones = []

    def populate_availability_zone_choices(self, request, context):
        try:
            zones = self.availability_zones(request)
        except Exception:
            zones = []
            redirect = reverse('horizon:project:databases:index')
            exceptions.handle(request,
                              _('Unable to retrieve availability zones.'),
                              redirect=redirect)

        zone_list = [(zone.zoneName, zone.zoneName)
                     for zone in zones if zone.zoneState['available']]
        zone_list.sort()
        if not zone_list:
            zone_list.insert(0, ("", _("No availability zones found")))
        elif len(zone_list) > 1:
            zone_list.insert(0, ("", _("Any Availability Zone")))
        return zone_list

    @memoized.memoized_method
    def datastore_flavors(self, request, datastore_name, datastore_version):
        try:
            return api.trove.datastore_flavors(
                request, datastore_name, datastore_version)
        except Exception:
            LOG.exception("Exception while obtaining flavors list")
            redirect = reverse("horizon:project:databases:index")
            exceptions.handle(request,
                              _('Unable to obtain flavors.'),
                              redirect=redirect)

    @memoized.memoized_method
    def populate_volume_type_choices(self, request, context):
        try:
            volume_types = dash_api.cinder.volume_type_list(request)
            return ([("no_type", _("No volume type"))] +
                    [(type.name, type.name)
                     for type in volume_types])
        except Exception:
            LOG.exception("Exception while obtaining volume types list")
            self._volume_types = []

    @memoized.memoized_method
    def datastores(self, request):
        try:
            return api.trove.datastore_list(request)
        except Exception:
            LOG.exception("Exception while obtaining datastores list")
            self._datastores = []

    @memoized.memoized_method
    def datastore_versions(self, request, datastore):
        try:
            return api.trove.datastore_version_list(request, datastore)
        except Exception:
            LOG.exception("Exception while obtaining datastore version list")
            self._datastore_versions = []

    def populate_datastore_choices(self, request, context):
        choices = ()
        datastores = self.datastores(request)
        if datastores is not None:
            for ds in datastores:
                versions = self.datastore_versions(request, ds.name)
                if versions:
                    # only add to choices if datastore has at least one version
                    version_choices = ()
                    for v in versions:
                        if hasattr(v, 'active') and not v.active:
                            continue
                        selection_text = self._build_datastore_display_text(
                            ds.name, v.name)
                        widget_text = self._build_widget_field_name(
                            ds.name, v.name)
                        version_choices = (version_choices +
                                           ((widget_text, selection_text),))
                        # self._add_datastore_flavor_field(request,
                        #                                  ds.name,
                        #                                  v.name)
                    choices = choices + version_choices
        return choices

    def _add_datastore_flavor_field(self,
                                    request,
                                    datastore,
{'fraction_non_alphanumeric': 0.07896524397147062, 'fraction_numerical': 0.001811389109022982, 'mean_word_length': 1.871282301316431, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1214976', 'n_tokens_mistral': 4547, 'n_tokens_neox': 4415, 'n_words': 1120}