import logging from cms.plugin_base import CMSPluginBase from cms.plugin_pool import plugin_pool from django import forms from django.conf import settings from django.contrib import messages from django.core.exceptions import ValidationError from django.shortcuts import redirect from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from .cms_models import ( DCLBannerItemPluginModel, DCLBannerListPluginModel, DCLContactPluginModel, DCLFooterPluginModel, DCLLinkPluginModel, DCLNavbarDropdownPluginModel, DCLSectionIconPluginModel, DCLSectionImagePluginModel, DCLSectionPluginModel, DCLNavbarPluginModel, DCLSectionPromoPluginModel, DCLCalculatorPluginModel ) from .models import VMTemplate, VMPricing from datacenterlight.utils import clear_all_session_vars from opennebula_api.serializers import VMTemplateSerializer logger = logging.getLogger(__name__) @plugin_pool.register_plugin class DCLSectionPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Section Plugin" model = DCLSectionPluginModel render_template = "datacenterlight/cms/section.html" cache = False allow_children = True child_classes = [ 'DCLSectionIconPlugin', 'DCLSectionImagePlugin', 'DCLSectionPromoPlugin', 'UngleichHTMLPlugin', 'DCLCalculatorPlugin' ] def render(self, context, instance, placeholder): context = super(DCLSectionPlugin, self).render( context, instance, placeholder ) context['children_to_side'] = [] context['children_to_content'] = [] context['children_calculator'] = [] if instance.child_plugin_instances is not None: right_children = [ 'DCLSectionImagePluginModel', 'DCLSectionIconPluginModel', ] for child in instance.child_plugin_instances: if child.__class__.__name__ in right_children: context['children_to_side'].append(child) elif child.plugin_type == 'DCLCalculatorPlugin': context['children_calculator'].append(child) else: context['children_to_content'].append(child) return context @plugin_pool.register_plugin class DCLSectionIconPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Section Icon Plugin" model = DCLSectionIconPluginModel render_template = "datacenterlight/cms/section_icon.html" cache = False require_parent = True @plugin_pool.register_plugin class DCLSectionImagePlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Section Image Plugin" model = DCLSectionImagePluginModel render_template = "datacenterlight/cms/section_image.html" cache = False require_parent = True @plugin_pool.register_plugin class DCLSectionPromoPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Section Promo Plugin" model = DCLSectionPromoPluginModel render_template = "datacenterlight/cms/section_promo.html" cache = False @plugin_pool.register_plugin class DCLCalculatorPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Calculator Plugin" model = DCLCalculatorPluginModel render_template = "datacenterlight/cms/calculator.html" cache = False require_parent = True def render(self, context, instance, placeholder): clear_all_session_vars(context['request']) if instance and hasattr(instance, 'template'): self.render_template = instance.template request = context['request'] if request.method == "POST" and "order_form" in request.POST.keys(): cores = request.POST.get('cpu') cores_field = forms.IntegerField(validators=[self.validate_cores]) memory = request.POST.get('ram') memory_field = forms.FloatField(validators=[self.validate_memory]) storage = request.POST.get('storage') storage_field = forms.IntegerField( validators=[self.validate_storage]) template_id = int(request.POST.get('config')) pricing_name = request.POST.get('pricing_name') vm_pricing = VMPricing.get_vm_pricing_by_name(pricing_name) template = VMTemplate.objects.filter( opennebula_vm_template_id=template_id).first() template_data = VMTemplateSerializer(template).data if vm_pricing is None: vm_pricing_name_msg = _( "Incorrect pricing name. Please contact support" "{support_email}".format( support_email=settings.DCL_SUPPORT_FROM_ADDRESS ) ) messages.add_message( request, messages.ERROR, vm_pricing_name_msg, extra_tags='pricing' ) return redirect(self) else: vm_pricing_name = vm_pricing.name try: cores = cores_field.clean(cores) except ValidationError as err: msg = '{} : {}.'.format(cores, str(err)) messages.add_message(request, messages.ERROR, msg, extra_tags='cores') return redirect(self) try: memory = memory_field.clean(memory) except ValidationError as err: msg = '{} : {}.'.format(memory, str(err)) messages.add_message(request, messages.ERROR, msg, extra_tags='memory') return redirect(self) try: storage = storage_field.clean(storage) except ValidationError as err: msg = '{} : {}.'.format(storage, str(err)) messages.add_message(request, messages.ERROR, msg, extra_tags='storage') return redirect(self) price, vat, vat_percent, discount = get_vm_price_with_vat( cpu=cores, memory=memory, ssd_size=storage, pricing_name=vm_pricing_name ) specs = { 'cpu': cores, 'memory': memory, 'disk_size': storage, 'discount': discount, 'price': price, 'vat': vat, 'vat_percent': vat_percent, 'total_price': round(price + vat - discount['amount'], 2), 'pricing_name': vm_pricing_name } request.session['specs'] = specs request.session['template'] = template_data return redirect(reverse('datacenterlight:payment')) else: context = super(DCLCalculatorPlugin, self).render( context, instance, placeholder ) ids = instance.vm_templates_to_show if ids: context['templates'] = VMTemplate.objects.filter( vm_type=instance.vm_type ).filter(opennebula_vm_template_id__in=ids).order_by('name') else: context['templates'] = VMTemplate.objects.filter( vm_type=instance.vm_type ).order_by('name') context['instance'] = instance context['min_ram'] = 0.5 if instance.enable_512mb_ram else 1 return context def validate_cores(self, value): if (value > 48) or (value < 1): raise ValidationError(_('Invalid number of cores')) def validate_memory(self, value): if 'pid' in request.POST: try: plugin = DCLCalculatorPluginModel.objects.get( id=request.POST['pid'] ) except DCLCalculatorPluginModel.DoesNotExist as dne: logger.error( str(dne) + " plugin_id: " + request.POST['pid'] ) raise ValidationError(_('Invalid calculator properties')) if plugin.enable_512mb_ram: if value % 1 == 0 or value == 0.5: logger.debug( "Given ram {value} is either 0.5 or a" " whole number".format(value=value) ) if (value > 200) or (value < 0.5): raise ValidationError(_('Invalid RAM size')) else: raise ValidationError(_('Invalid RAM size')) elif (value > 200) or (value < 1) or (value % 1 != 0): raise ValidationError(_('Invalid RAM size')) else: raise ValidationError(_('Invalid RAM size')) def validate_storage(self, value): if (value > 2000) or (value < 10): raise ValidationError(_('Invalid storage size')) @plugin_pool.register_plugin class DCLBannerListPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Banner List Plugin" model = DCLBannerListPluginModel render_template = "datacenterlight/cms/banner_list.html" cache = False allow_children = True child_classes = ['DCLBannerItemPlugin'] @plugin_pool.register_plugin class DCLBannerItemPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Banner Item Plugin" model = DCLBannerItemPluginModel render_template = "datacenterlight/cms/banner_item.html" cache = False require_parent = True parent_classes = ['DCLBannerListPlugin'] @plugin_pool.register_plugin class DCLNavbarPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Navbar Plugin" model = DCLNavbarPluginModel render_template = "datacenterlight/cms/navbar.html" cache = False allow_children = True child_classes = ['DCLLinkPlugin', 'DCLNavbarDropdownPlugin'] @plugin_pool.register_plugin class DCLNavbarDropdownPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Navbar Dropdown Plugin" model = DCLNavbarDropdownPluginModel render_template = "datacenterlight/cms/navbar_dropdown.html" cache = False allow_children = True child_classes = ['DCLLinkPlugin'] require_parent = True parent_classes = ['DCLNavbarPlugin'] @plugin_pool.register_plugin class DCLLinkPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Link Plugin" model = DCLLinkPluginModel render_template = "datacenterlight/cms/link.html" cache = False require_parent = True @plugin_pool.register_plugin class DCLContactPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Contact Plugin" model = DCLContactPluginModel render_template = "datacenterlight/cms/contact.html" cache = False @plugin_pool.register_plugin class DCLFooterPlugin(CMSPluginBase): module = "Datacenterlight" name = "DCL Footer Plugin" model = DCLFooterPluginModel render_template = "datacenterlight/cms/footer.html" cache = False allow_children = True child_classes = ['DCLLinkPlugin']