From 0e72f8a4367c8ada9c81513b1b36b24469ed19dd Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Sun, 20 Aug 2017 03:30:10 +0530 Subject: [PATCH 0001/1032] downtime page --- .../datacenterlight/css/downtime-page.css | 52 +++++++++++++++ .../templates/datacenterlight/downtime.html | 63 +++++++++++++++++++ datacenterlight/urls.py | 11 +++- 3 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 datacenterlight/static/datacenterlight/css/downtime-page.css create mode 100644 datacenterlight/templates/datacenterlight/downtime.html diff --git a/datacenterlight/static/datacenterlight/css/downtime-page.css b/datacenterlight/static/datacenterlight/css/downtime-page.css new file mode 100644 index 00000000..9bbfa5bc --- /dev/null +++ b/datacenterlight/static/datacenterlight/css/downtime-page.css @@ -0,0 +1,52 @@ +body { + font-family: Lato, sans-serif; + font-weight: 300; + font-size: 20px; + line-height: 1; +} + +h1 { + font-weight: 300; + font-size: 52px; + text-align: center; +} + +nav { + padding: 15px; +} + +.downtime-container { + max-width: 1200px; + margin: auto; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.downtime-msg { + text-align: center; + font-size: 30px; +} + +.downtime-contact { + max-width: 300px; + margin: auto; + color: #4a90e2; +} + +h2 { + font-weight: 300; + font-size: 24px; + text-align: center; +} +p { + margin: 15px auto +} +.xl_p { + margin: 15px auto; +} + +a { + color: #4a90e2; + text-decoration: none; +} \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/downtime.html b/datacenterlight/templates/datacenterlight/downtime.html new file mode 100644 index 00000000..dd5954ca --- /dev/null +++ b/datacenterlight/templates/datacenterlight/downtime.html @@ -0,0 +1,63 @@ +{% load staticfiles bootstrap3%} +{% load i18n %} + + + + + + + + + + + + ungleich + + + + + + + + + + + + + + {% include "google_analytics.html" %} + + + + + +
+ + +

{% trans "You caught us while working!" %}

+
+

{% trans "We're doing scheduled maintainence from" %}

+

17:00 21.08.2017 {% trans "to" %} 23:00 21.08.2017 CEST.

+
+

{% trans "If you need immediate assistance, please contact us at" %}

+ +
+ + + diff --git a/datacenterlight/urls.py b/datacenterlight/urls.py index a3aed7a6..a0942695 100644 --- a/datacenterlight/urls.py +++ b/datacenterlight/urls.py @@ -1,17 +1,22 @@ from django.conf.urls import url +from django.views.generic import TemplateView from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView, SuccessView, \ - PaymentOrderView, OrderConfirmationView, WhyDataCenterLightView + PaymentOrderView, OrderConfirmationView, WhyDataCenterLightView urlpatterns = [ url(r'^$', IndexView.as_view(), name='index'), - url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(), name='whydatacenterlight'), + url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(), + name='whydatacenterlight'), url(r'^beta-program/?$', BetaProgramView.as_view(), name='beta'), url(r'^landing/?$', LandingProgramView.as_view(), name='landing'), url(r'^pricing/?$', PricingView.as_view(), name='pricing'), url(r'^payment/?$', PaymentOrderView.as_view(), name='payment'), - url(r'^order-confirmation/?$', OrderConfirmationView.as_view(), name='order_confirmation'), + url(r'^order-confirmation/?$', OrderConfirmationView.as_view(), + name='order_confirmation'), url(r'^order-success/?$', SuccessView.as_view(), name='order_success'), url(r'^beta_access?$', BetaAccessView.as_view(), name='beta_access'), + + url(r'test/?$', TemplateView.as_view(template_name='datacenterlight/downtime.html')), ] From 06c68873aea768ba04419a36aac3ae123fd08713 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Sun, 20 Aug 2017 03:59:24 +0530 Subject: [PATCH 0002/1032] downtime.html modified as a static html page --- .../datacenterlight/css/downtime-page.css | 52 ----------- .../templates/datacenterlight/downtime.html | 86 ++++++++++++++----- 2 files changed, 64 insertions(+), 74 deletions(-) delete mode 100644 datacenterlight/static/datacenterlight/css/downtime-page.css diff --git a/datacenterlight/static/datacenterlight/css/downtime-page.css b/datacenterlight/static/datacenterlight/css/downtime-page.css deleted file mode 100644 index 9bbfa5bc..00000000 --- a/datacenterlight/static/datacenterlight/css/downtime-page.css +++ /dev/null @@ -1,52 +0,0 @@ -body { - font-family: Lato, sans-serif; - font-weight: 300; - font-size: 20px; - line-height: 1; -} - -h1 { - font-weight: 300; - font-size: 52px; - text-align: center; -} - -nav { - padding: 15px; -} - -.downtime-container { - max-width: 1200px; - margin: auto; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.downtime-msg { - text-align: center; - font-size: 30px; -} - -.downtime-contact { - max-width: 300px; - margin: auto; - color: #4a90e2; -} - -h2 { - font-weight: 300; - font-size: 24px; - text-align: center; -} -p { - margin: 15px auto -} -.xl_p { - margin: 15px auto; -} - -a { - color: #4a90e2; - text-decoration: none; -} \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/downtime.html b/datacenterlight/templates/datacenterlight/downtime.html index dd5954ca..17c40d79 100644 --- a/datacenterlight/templates/datacenterlight/downtime.html +++ b/datacenterlight/templates/datacenterlight/downtime.html @@ -1,5 +1,3 @@ -{% load staticfiles bootstrap3%} -{% load i18n %} @@ -13,23 +11,69 @@ ungleich - - + @@ -37,25 +81,23 @@
-

{% trans "You caught us while working!" %}

+

You caught us while working!

-

{% trans "We're doing scheduled maintainence from" %}

-

17:00 21.08.2017 {% trans "to" %} 23:00 21.08.2017 CEST.

+

We're doing scheduled maintenance from

+

17:00 21.08.2017 to 23:00 21.08.2017 CEST.

-

{% trans "If you need immediate assistance, please contact us at" %}

+

If you need immediate assistance, please contact us at

From 6536991209fc25af113a91dfa93988ede3a00952 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 6 Oct 2017 01:17:35 +0530 Subject: [PATCH 0003/1032] list all cards, card_input template --- .../datacenterlight/landing_payment.html | 58 +-------------- hosting/templates/hosting/payment.html | 57 +------------- hosting/templates/hosting/settings.html | 74 +++---------------- hosting/views.py | 19 +++-- 4 files changed, 20 insertions(+), 188 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index fa638d77..1a476797 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -121,63 +121,7 @@ {% else %} -
- -
-
-
- -
-
-
-
- -
-
-
- -
-
-
-
- - -
-
-
-
- {% if not messages and not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After placing your order, you will be taken to the Submit Payment Page." %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' in message.tags or 'make_charge_error' in message.tags %} -
    -
  • {{ message|safe }}

  • -
- {% elif not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After placing your order, you will be taken to the Submit Payment Page." %} -

- {% endif %} - {% endfor %} - - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
- -
- -
-

-
-
+ {% include "hosting/includes/_card_input.html" %} {% endif %} diff --git a/hosting/templates/hosting/payment.html b/hosting/templates/hosting/payment.html index e9d6476f..a10cfbca 100644 --- a/hosting/templates/hosting/payment.html +++ b/hosting/templates/hosting/payment.html @@ -105,62 +105,7 @@ {% else %} -
- -
-
-
- -
-
-
-
- -
-
-
- -
-
-
-
- - -
-
-
-
- {% if not messages and not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' or 'make_charge_error' in message.tags %} -
    -
  • -

    {{ message|safe }}

    -
  • -
- {% endif %} - {% endfor %} - - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
- -
- - -
-

-
-
+ {% include "hosting/includes/_card_input.html" %} {% endif %} diff --git a/hosting/templates/hosting/settings.html b/hosting/templates/hosting/settings.html index 0bafe8e5..5e898b04 100644 --- a/hosting/templates/hosting/settings.html +++ b/hosting/templates/hosting/settings.html @@ -30,12 +30,13 @@

{%trans "Credit Card"%}


- {% if credit_card_data.last4 %} + {% for card in cards_list %}
{% trans "Credit Card" %}
-
{% trans "Last" %} 4: *****{{credit_card_data.last4}}
-
{% trans "Type" %}: {{credit_card_data.cc_brand}}
+
{% trans "Last" %} 4: *****{{card.last4}}
+
{% trans "Type" %}: {{card.cc_brand}}
{% comment %} + {% endcomment %}
@@ -46,75 +47,18 @@
- {% endcomment %}
+ {% endfor %} + {% if credit_card_data.last4 %} {% else %}

{% trans "No Credit Cards Added" %}

{% blocktrans %}We are using Stripe for payment and do not store your information in our database.{% endblocktrans %}

- {% comment %}

{% trans "Add a new Card." %}

-

- {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} -

-
- -
-
- -
-
-
-
- -
-
-
- -
-
-
-
- - -
-
- -
- {% if not messages and not form.non_field_errors %} -

- {% blocktrans %}You are not making any payment here.{% endblocktrans %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' or 'make_charge_error' in message.tags %} -
  • -

    {{ message|safe }}

    -
- {% endif %} - {% endfor %} - - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
-
- -
-
-
- -
-

-
-
+ {% include "hosting/includes/_card_input.html" %} + {% comment %} {% endcomment %} {% endif %}
@@ -123,7 +67,6 @@ - {% comment %} {% if stripe_key %} {% get_current_language as LANGUAGE_CODE %} @@ -138,6 +81,7 @@ {%endif%} + {% comment %} {% if credit_card_data.last4 and credit_card_data.cc_brand %} {%endif%} - -{% if credit_card_data.last4 and credit_card_data.cc_brand %} - -{%endif%} - {%endblock%} From 248283b369c55b3989c421a93921453d33248f42 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 28 Oct 2017 23:44:06 +0200 Subject: [PATCH 0072/1032] Show user's credit cards dynamically in landing payment page --- .../datacenterlight/landing_payment.html | 35 ++++++++++++++----- datacenterlight/views.py | 11 +++++- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index 58246b6a..69c80d35 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -84,11 +84,35 @@
+ {% with card_list_len=cards_list|length %}

{%trans "Credit Card"%}


+ {% if card_list_len > 0 %} + {% blocktrans %}Please select one of the previous cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% else %} {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% endif %}

+
+ {% for card in cards_list %} +
+
+
{% trans "Credit Card" %}
+
{% trans "Last" %} 4: ***** {{card.last4}}
+
{% trans "Type" %}: {{card.brand}}
+
+ +
+ {% endfor %} + {% if card_list_len > 0 %} +
Use another card
+ {% endif %} + {% include "hosting/includes/_card_input.html" %} +
+ {% comment %}
{% if credit_card_data.last4 %}
@@ -125,6 +149,8 @@ {% include "hosting/includes/_card_input.html" %} {% endif %}
+ {% endcomment %} + {% endwith %}
@@ -144,13 +170,4 @@ })(); {%endif%} - -{% if credit_card_data.last4 and credit_card_data.cc_brand %} - -{%endif%} - {%endblock%} diff --git a/datacenterlight/views.py b/datacenterlight/views.py index bd1a7f51..861817e1 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -14,7 +14,7 @@ from django.views.decorators.cache import cache_control from django.views.generic import FormView, CreateView, TemplateView, DetailView from datacenterlight.tasks import create_vm_task -from hosting.models import HostingOrder +from hosting.models import HostingOrder, UserCardDetail from hosting.forms import HostingUserLoginForm from membership.models import CustomUser, StripeCustomer from opennebula_api.serializers import VMTemplateSerializer @@ -347,6 +347,14 @@ class PaymentOrderView(FormView): def get_context_data(self, **kwargs): context = super(PaymentOrderView, self).get_context_data(**kwargs) + user = self.request.user + if hasattr(user, 'stripecustomer'): + stripe_customer = user.stripecustomer + else: + stripe_customer = None + cards_list = UserCardDetail.get_all_cards_list( + stripe_customer=stripe_customer + ) if 'billing_address_data' in self.request.session: billing_address_data = self.request.session['billing_address_data'] else: @@ -380,6 +388,7 @@ class PaymentOrderView(FormView): ) context.update({ + 'cards_list': cards_list, 'stripe_key': settings.STRIPE_API_PUBLIC_KEY, 'site_url': reverse('datacenterlight:index'), 'login_form': HostingUserLoginForm(prefix='login_form'), From 2ffaee2d5b9722a50ed33e5d6a338df77af5232c Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 13:14:29 +0100 Subject: [PATCH 0073/1032] Add clear_items_from_list utility function --- utils/hosting_utils.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index 3c193ad7..9541588d 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -60,3 +60,23 @@ def get_vm_price(cpu, memory, disk_size): :return: The price of the VM """ return (cpu * 5) + (memory * 2) + (disk_size * 0.6) + + +class HostingUtils: + @staticmethod + def clear_items_from_list(from_list, items_list): + """ + A utility function to clear items from a given list. + Useful when deleting items in bulk from session. + e.g.: + HostingUtils.clear_items_from_list( + request.session, + ['token', 'billing_address_data', 'card_id',] + ) + :param from_list: + :param items_list: + :return: + """ + for var in items_list: + if var in from_list: + del from_list[var] From 82ad9ac337a9f9ab83256debecc05160b7379274 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 13:17:26 +0100 Subject: [PATCH 0074/1032] Add selected card handling in landing flow "Order confirmation" page --- datacenterlight/views.py | 172 +++++++++++++++++++++++++++------------ 1 file changed, 122 insertions(+), 50 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 861817e1..baec4ee6 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -21,7 +21,7 @@ from opennebula_api.serializers import VMTemplateSerializer from utils.forms import ( BillingAddressForm, BillingAddressFormSignup ) -from utils.hosting_utils import get_vm_price +from utils.hosting_utils import get_vm_price, HostingUtils from utils.mailer import BaseEmail from utils.stripe_utils import StripeUtils from utils.tasks import send_plain_email_task @@ -401,6 +401,13 @@ class PaymentOrderView(FormView): # user is no longer added to session on the index page if 'specs' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:index')) + HostingUtils.clear_items_from_list( + request.session, + ['token', 'billing_address_data', 'card_id', 'customer', + 'user'] + ) + if 'token' in request.session: + del request.session['token'] return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): @@ -436,8 +443,40 @@ class PaymentOrderView(FormView): 'name': request.user.name } customer = StripeCustomer.get_or_create( - email=this_user.get('email'), - token=token) + email=this_user.get('email'), token=token + ) + if token is '': + # card selected case + card_id = address_form.cleaned_data.get('card') + try: + user_card_detail = UserCardDetail.objects.get( + id=card_id) + if not request.user.has_perm( + 'view_usercarddetail', user_card_detail + ): + raise UserCardDetail.DoesNotExist( + _( + "{user} does not have permission to access the " + "card").format(user=request.user.email) + ) + except UserCardDetail.DoesNotExist as e: + ex = str(e) + logger.error( + "Card Id: {card_id}, Exception: {ex}".format( + card_id=card_id, ex=ex + ) + ) + msg = _("An error occurred. Details: {}".format(ex)) + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='make_charge_error' + ) + return HttpResponseRedirect( + reverse('hosting:payment') + '#payment_error' + ) + request.session['card_id'] = user_card_detail.id + else: + request.session['token'] = token else: user_email = address_form.cleaned_data.get('email') user_name = address_form.cleaned_data.get('name') @@ -472,7 +511,7 @@ class PaymentOrderView(FormView): email=user_email, token=token, customer_name=user_name) - + request.session['token'] = token request.session['billing_address_data'] = address_form.cleaned_data request.session['user'] = this_user # Get or create stripe customer @@ -485,7 +524,6 @@ class PaymentOrderView(FormView): billing_address_form=address_form ) ) - request.session['token'] = token if type(customer) is StripeCustomer: request.session['customer'] = customer.stripe_id else: @@ -508,27 +546,33 @@ class OrderConfirmationView(DetailView): def get(self, request, *args, **kwargs): if 'specs' not in request.session or 'user' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:index')) - if 'token' not in request.session: + if 'token' not in request.session and 'card_id' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:payment')) - stripe_api_cus_id = request.session.get('customer') - stripe_utils = StripeUtils() - card_details = stripe_utils.get_card_details(stripe_api_cus_id, - request.session.get( - 'token')) - if not card_details.get('response_object'): - msg = card_details.get('error') - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='failed_payment') - return HttpResponseRedirect( - reverse('datacenterlight:payment') + '#payment_error') context = { 'site_url': reverse('datacenterlight:index'), - 'cc_last4': card_details.get('response_object').get('last4'), - 'cc_brand': card_details.get('response_object').get('brand'), 'vm': request.session.get('specs'), 'page_header_text': _('Confirm Order'), 'billing_address_data': request.session.get('billing_address_data') } + if 'token' in request.session: + stripe_utils = StripeUtils() + card_details = stripe_utils.get_cards_details_from_token( + request.session.get('token') + ) + card_detail_resp = card_details.get('response_object') + if not card_detail_resp: + msg = card_details.get('error') + messages.add_message(self.request, messages.ERROR, msg, + extra_tags='failed_payment') + return HttpResponseRedirect( + reverse('datacenterlight:payment') + '#payment_error') + context['cc_last4'] = card_detail_resp.get('last4') + context['cc_brand'] = card_detail_resp.get('brand') + else: + card_id = self.request.session.get('card_id') + card_detail = UserCardDetail.objects.get(id=card_id) + context['cc_last4'] = card_detail.last4 + context['cc_brand'] = card_detail.brand return render(request, self.template_name, context) def post(self, request, *args, **kwargs): @@ -538,43 +582,62 @@ class OrderConfirmationView(DetailView): stripe_api_cus_id = request.session.get('customer') vm_template_id = template.get('id', 1) stripe_utils = StripeUtils() - card_details = stripe_utils.get_card_details(stripe_api_cus_id, - request.session.get( - 'token')) - if not card_details.get('response_object'): - msg = card_details.get('error') - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='failed_payment') - response = { - 'status': False, - 'redirect': "{url}#{section}".format( - url=reverse('datacenterlight:payment'), - section='payment_error'), - 'msg_title': str(_('Error.')), - 'msg_body': str( - _('There was a payment related error.' - ' On close of this popup, you will be redirected back to' - ' the payment page.')) + if 'token' in self.request.session: + card_details = stripe_utils.get_cards_details_from_token( + request.session['token'] + ) + if not card_details.get('response_object'): + msg = card_details.get('error') + messages.add_message(self.request, messages.ERROR, msg, + extra_tags='failed_payment') + response = { + 'status': False, + 'redirect': "{url}#{section}".format( + url=reverse('datacenterlight:payment'), + section='payment_error'), + 'msg_title': str(_('Error.')), + 'msg_body': str( + _('There was a payment related error.' + ' On close of this popup, you will be redirected back to' + ' the payment page.')) + } + return HttpResponse(json.dumps(response), + content_type="application/json") + card_details_dict = card_details.get('response_object') + ucd = UserCardDetail.contains( + request.user.stripecustomer, card_details_dict + ) + if not ucd: + stripe_utils.associate_customer_card( + stripe_api_cus_id, request.session['token'], + set_as_default=True + ) + else: + card_id = request.session.get('card_id') + user_card_detail = UserCardDetail.objects.get(id=card_id) + card_details_dict = { + 'last4': user_card_detail.last4, + 'brand': user_card_detail.brand } - return HttpResponse(json.dumps(response), - content_type="application/json") - card_details_dict = card_details.get('response_object') + if not user_card_detail.preferred: + UserCardDetail.set_default_card( + stripe_api_cus_id=stripe_api_cus_id, + stripe_source_id=user_card_detail.card_id + ) cpu = specs.get('cpu') memory = specs.get('memory') disk_size = specs.get('disk_size') amount_to_be_charged = specs.get('price') - plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu, - memory=memory, - disk_size=disk_size) - stripe_plan_id = StripeUtils.get_stripe_plan_id(cpu=cpu, - ram=memory, - ssd=disk_size, - version=1, - app='dcl') + plan_name = StripeUtils.get_stripe_plan_name( + cpu=cpu, memory=memory, disk_size=disk_size + ) + stripe_plan_id = StripeUtils.get_stripe_plan_id( + cpu=cpu, ram=memory, ssd=disk_size, version=1, app='dcl' + ) stripe_plan = stripe_utils.get_or_create_stripe_plan( - amount=amount_to_be_charged, - name=plan_name, - stripe_plan_id=stripe_plan_id) + amount=amount_to_be_charged, name=plan_name, + stripe_plan_id=stripe_plan_id + ) subscription_result = stripe_utils.subscribe_customer_to_plan( stripe_api_cus_id, [{"plan": stripe_plan.get( @@ -644,6 +707,15 @@ class OrderConfirmationView(DetailView): billing_address_data.update({ 'user': custom_user.id }) + if 'token' in request.session: + ucd = UserCardDetail.get_or_create_user_card_detail( + stripe_customer=self.request.user.stripecustomer, + card_details=card_details_dict + ) + UserCardDetail.save_default_card_local( + self.request.user.stripecustomer.stripe_id, + ucd.card_id + ) user = { 'name': custom_user.name, 'email': custom_user.email, From 23e7edf7c28af39b0d8d93517a47538b5cd1911c Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 14:40:15 +0100 Subject: [PATCH 0075/1032] Return True if associate_customer_card runs ok --- utils/stripe_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/stripe_utils.py b/utils/stripe_utils.py index 2742045a..cb9ae6fb 100644 --- a/utils/stripe_utils.py +++ b/utils/stripe_utils.py @@ -86,6 +86,7 @@ class StripeUtils(object): if set_as_default: customer.default_source = card.id customer.save() + return True @handleStripeError def dissociate_customer_card(self, stripe_customer_id, card_id): From bea3477d848a8f87526e44ece06df5c0352ee801 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 14:45:14 +0100 Subject: [PATCH 0076/1032] Handle errors related to payment by redirecting to payment page --- datacenterlight/views.py | 39 ++++++++++++++++++++++++++--- hosting/views.py | 54 +++++++++++++++++++++++++++++++++++----- 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index baec4ee6..d9c0fbc1 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -603,21 +603,46 @@ class OrderConfirmationView(DetailView): } return HttpResponse(json.dumps(response), content_type="application/json") - card_details_dict = card_details.get('response_object') + card_details_response = card_details['response_object'] + card_details_dict = { + 'last4': card_details_response['last4'], + 'brand': card_details_response['brand'], + 'card_id': card_details_response['card_id'] + } ucd = UserCardDetail.contains( request.user.stripecustomer, card_details_dict ) if not ucd: - stripe_utils.associate_customer_card( + acc_result = stripe_utils.associate_customer_card( stripe_api_cus_id, request.session['token'], set_as_default=True ) + if acc_result['response_object'] is None: + response = { + 'status': False, + 'redirect': "{url}#{section}".format( + url=reverse('datacenterlight:payment'), + section='payment_error'), + 'msg_title': str(_('Error.')), + 'msg_body': str( + _('There was a payment related error.' + ' On close of this popup, you will be redirected back to' + ' the payment page.')) + } + logger.error( + "Card association failed. Error {error}".format( + error=acc_result['error'] + ) + ) + return HttpResponse(json.dumps(response), + content_type="application/json") else: card_id = request.session.get('card_id') user_card_detail = UserCardDetail.objects.get(id=card_id) card_details_dict = { 'last4': user_card_detail.last4, - 'brand': user_card_detail.brand + 'brand': user_card_detail.brand, + 'card_id': user_card_detail.card_id } if not user_card_detail.preferred: UserCardDetail.set_default_card( @@ -646,6 +671,14 @@ class OrderConfirmationView(DetailView): # Check if the subscription was approved and is active if (stripe_subscription_obj is None or stripe_subscription_obj.status != 'active'): + if request.user.is_authenticated(): + sac_id = request.user.stripecustomer.stripe_id + else: + sac_id = stripe_api_cus_id + stripe_utils.dissociate_customer_card( + sac_id, + card_details_dict['card_id'] + ) msg = subscription_result.get('error') messages.add_message(self.request, messages.ERROR, msg, extra_tags='failed_payment') diff --git a/hosting/views.py b/hosting/views.py index f61a4b19..6d5c9a78 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -632,6 +632,18 @@ class SettingsView(LoginRequiredMixin, FormView): msg = _('You seem to have already added this card') messages.add_message(request, messages.ERROR, msg) else: + acc_result = stripe_utils.associate_customer_card( + request.user.stripecustomer.stripe_id, token + ) + if acc_result['response_object'] is None: + msg = _( + 'An error occurred while associating the card.' + ' Details: {details}'.format( + details=acc_result['error'] + ) + ) + messages.add_message(request, messages.ERROR, msg) + return self.render_to_response(self.get_context_data()) preferred = False if stripe_customer.usercarddetail_set.count() == 0: preferred = True @@ -645,9 +657,6 @@ class SettingsView(LoginRequiredMixin, FormView): card_id=card['card_id'], preferred=preferred ) - stripe_utils.associate_customer_card( - request.user.stripecustomer.stripe_id, token - ) msg = _( "Successfully associated the card with your account" ) @@ -866,22 +875,48 @@ class OrdersHostingDetailView(LoginRequiredMixin, card_details_response = card_details['response_object'] card_details_dict = { 'last4': card_details_response['last4'], - 'brand': card_details_response['brand'] + 'brand': card_details_response['brand'], + 'card_id': card_details_response['card_id'] } ucd = UserCardDetail.contains( request.user.stripecustomer, card_details_response ) if not ucd: - stripe_utils.associate_customer_card( + acc_result = stripe_utils.associate_customer_card( stripe_api_cus_id, request.session['token'], set_as_default=True ) + if acc_result['response_object'] is None: + msg = _( + 'An error occurred while associating the card.' + ' Details: {details}'.format( + details=acc_result['error'] + ) + ) + messages.add_message(self.request, messages.ERROR, msg, + extra_tags='failed_payment') + response = { + 'status': False, + 'redirect': "{url}#{section}".format( + url=reverse('hosting:payment'), + section='payment_error'), + 'msg_title': str(_('Error.')), + 'msg_body': str( + _('There was a payment related error.' + ' On close of this popup, you will be redirected' + ' back to the payment page.') + ) + } + return HttpResponse( + json.dumps(response), content_type="application/json" + ) else: card_id = request.session.get('card_id') user_card_detail = UserCardDetail.objects.get(id=card_id) card_details_dict = { 'last4': user_card_detail.last4, - 'brand': user_card_detail.brand + 'brand': user_card_detail.brand, + 'card_id': user_card_detail.card_id } if not user_card_detail.preferred: UserCardDetail.set_default_card( @@ -911,6 +946,13 @@ class OrdersHostingDetailView(LoginRequiredMixin, # Check if the subscription was approved and is active if (stripe_subscription_obj is None or stripe_subscription_obj.status != 'active'): + # At this point, we have created a Stripe API card, but and + # associated it with the customer; but the transaction failed + # due to some reason. So, we dissociate this card. + stripe_utils.dissociate_customer_card( + request.user.stripecustomer.stripe_id, + card_details_dict['card_id'] + ) msg = subscription_result.get('error') messages.add_message(self.request, messages.ERROR, msg, extra_tags='failed_payment') From abe8c9efa52b13f4d87eb07392b63c0d3494a4ad Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 15:05:32 +0100 Subject: [PATCH 0077/1032] Add error details to messages datacenterlight landing flow --- datacenterlight/views.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index d9c0fbc1..f58b8276 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -610,7 +610,7 @@ class OrderConfirmationView(DetailView): 'card_id': card_details_response['card_id'] } ucd = UserCardDetail.contains( - request.user.stripecustomer, card_details_dict + request.user.stripecustomer, card_details_response ) if not ucd: acc_result = stripe_utils.associate_customer_card( @@ -618,6 +618,11 @@ class OrderConfirmationView(DetailView): set_as_default=True ) if acc_result['response_object'] is None: + msg = acc_result.get('error') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) response = { 'status': False, 'redirect': "{url}#{section}".format( From 63eb7fc0e2278721932adebe114e3cfe7236313e Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:31:11 +0100 Subject: [PATCH 0078/1032] Rename contains to get_user_card_details --- hosting/models.py | 9 +++++---- hosting/views.py | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hosting/models.py b/hosting/models.py index 9486eae7..7a181fe1 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -312,21 +312,22 @@ class UserCardDetail(AssignPermissionsMixin, models.Model): user_card_detail.save() @staticmethod - def contains(stripe_customer, card_details): + def get_user_card_details(stripe_customer, card_details): """ A utility function to check whether a StripeCustomer is already associated with the card having given details + :param stripe_customer: :param card_details: - :return: + :return: The UserCardDetails object if it exists, False otherwise """ try: - UserCardDetail.objects.get( + ucd = UserCardDetail.objects.get( stripe_customer=stripe_customer, fingerprint=card_details['fingerprint'], exp_month=card_details['exp_month'], exp_year=card_details['exp_year'] ) - return True + return ucd except UserCardDetail.DoesNotExist: return False diff --git a/hosting/views.py b/hosting/views.py index 6d5c9a78..5a9c2e2e 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -628,7 +628,7 @@ class SettingsView(LoginRequiredMixin, FormView): email=request.user.email, token=token ) card = card_details['response_object'] - if UserCardDetail.contains(stripe_customer, card): + if UserCardDetail.get_user_card_details(stripe_customer, card): msg = _('You seem to have already added this card') messages.add_message(request, messages.ERROR, msg) else: @@ -878,7 +878,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, 'brand': card_details_response['brand'], 'card_id': card_details_response['card_id'] } - ucd = UserCardDetail.contains( + ucd = UserCardDetail.get_user_card_details( request.user.stripecustomer, card_details_response ) if not ucd: From af1690b84621322c86fa27a07031d72388da614f Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:36:12 +0100 Subject: [PATCH 0079/1032] Fix: obtaining stripe_customer in landing flow --- datacenterlight/views.py | 82 ++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index f58b8276..1a817310 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -403,8 +403,7 @@ class PaymentOrderView(FormView): return HttpResponseRedirect(reverse('datacenterlight:index')) HostingUtils.clear_items_from_list( request.session, - ['token', 'billing_address_data', 'card_id', 'customer', - 'user'] + ['token', 'card_id', 'customer', 'user'] ) if 'token' in request.session: del request.session['token'] @@ -609,38 +608,49 @@ class OrderConfirmationView(DetailView): 'brand': card_details_response['brand'], 'card_id': card_details_response['card_id'] } - ucd = UserCardDetail.contains( - request.user.stripecustomer, card_details_response - ) - if not ucd: - acc_result = stripe_utils.associate_customer_card( - stripe_api_cus_id, request.session['token'], - set_as_default=True - ) - if acc_result['response_object'] is None: - msg = acc_result.get('error') - messages.add_message( - self.request, messages.ERROR, msg, - extra_tags='failed_payment' + s_cus = None + try: + s_cus = StripeCustomer.objects.get(stripe_id=stripe_api_cus_id) + except StripeCustomer.DoesNotExist: + pass + if s_cus: + ucd = UserCardDetail.get_user_card_details(s_cus, card_details_response) + if not ucd: + acc_result = stripe_utils.associate_customer_card( + stripe_api_cus_id, request.session['token'], + set_as_default=True ) - response = { - 'status': False, - 'redirect': "{url}#{section}".format( - url=reverse('datacenterlight:payment'), - section='payment_error'), - 'msg_title': str(_('Error.')), - 'msg_body': str( - _('There was a payment related error.' - ' On close of this popup, you will be redirected back to' - ' the payment page.')) - } - logger.error( - "Card association failed. Error {error}".format( - error=acc_result['error'] + if acc_result['response_object'] is None: + msg = acc_result.get('error') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) + response = { + 'status': False, + 'redirect': "{url}#{section}".format( + url=reverse('datacenterlight:payment'), + section='payment_error'), + 'msg_title': str(_('Error.')), + 'msg_body': str( + _('There was a payment related error.' + ' On close of this popup, you will be ' + 'redirected back to the payment page.') + ) + } + logger.error( + "Card association failed. Error {error}".format( + error=acc_result['error'] + ) + ) + return HttpResponse(json.dumps(response), + content_type="application/json") + else: + if not ucd.preferred: + UserCardDetail.set_default_card( + stripe_api_cus_id=stripe_api_cus_id, + stripe_source_id=ucd.card_id ) - ) - return HttpResponse(json.dumps(response), - content_type="application/json") else: card_id = request.session.get('card_id') user_card_detail = UserCardDetail.objects.get(id=card_id) @@ -745,13 +755,13 @@ class OrderConfirmationView(DetailView): billing_address_data.update({ 'user': custom_user.id }) - if 'token' in request.session: + if 'token' in request.session and s_cus is not None: ucd = UserCardDetail.get_or_create_user_card_detail( - stripe_customer=self.request.user.stripecustomer, - card_details=card_details_dict + stripe_customer=s_cus, + card_details=card_details_response ) UserCardDetail.save_default_card_local( - self.request.user.stripecustomer.stripe_id, + s_cus.stripe_id, ucd.card_id ) user = { From 618d0004f2456b236d4d427e98631234ea355922 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:41:54 +0100 Subject: [PATCH 0080/1032] Rearrange code --- datacenterlight/views.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 1a817310..36ca81d6 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -451,12 +451,11 @@ class PaymentOrderView(FormView): user_card_detail = UserCardDetail.objects.get( id=card_id) if not request.user.has_perm( - 'view_usercarddetail', user_card_detail + 'view_usercarddetail', user_card_detail ): raise UserCardDetail.DoesNotExist( - _( - "{user} does not have permission to access the " - "card").format(user=request.user.email) + _("{user} does not have permission to access" + " the card").format(user=request.user.email) ) except UserCardDetail.DoesNotExist as e: ex = str(e) @@ -496,9 +495,9 @@ class PaymentOrderView(FormView): ) ) customer = StripeCustomer.create_stripe_api_customer( - email=user_email, - token=token, - customer_name=user_name) + email=user_email, token=token, + customer_name=user_name + ) except CustomUser.DoesNotExist: logger.debug( ("StripeCustomer does not exist for {email}." @@ -597,8 +596,8 @@ class OrderConfirmationView(DetailView): 'msg_title': str(_('Error.')), 'msg_body': str( _('There was a payment related error.' - ' On close of this popup, you will be redirected back to' - ' the payment page.')) + ' On close of this popup, you will be redirected ' + 'back to the payment page.')) } return HttpResponse(json.dumps(response), content_type="application/json") From 3d8f81339b41218e58a2d8f2659d37781188838d Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:49:15 +0100 Subject: [PATCH 0081/1032] Refactor, reorganize some code --- datacenterlight/views.py | 42 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 36ca81d6..51cd18fd 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -560,10 +560,13 @@ class OrderConfirmationView(DetailView): card_detail_resp = card_details.get('response_object') if not card_detail_resp: msg = card_details.get('error') - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='failed_payment') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) return HttpResponseRedirect( - reverse('datacenterlight:payment') + '#payment_error') + reverse('datacenterlight:payment') + '#payment_error' + ) context['cc_last4'] = card_detail_resp.get('last4') context['cc_brand'] = card_detail_resp.get('brand') else: @@ -586,8 +589,10 @@ class OrderConfirmationView(DetailView): ) if not card_details.get('response_object'): msg = card_details.get('error') - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='failed_payment') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) response = { 'status': False, 'redirect': "{url}#{section}".format( @@ -599,8 +604,9 @@ class OrderConfirmationView(DetailView): ' On close of this popup, you will be redirected ' 'back to the payment page.')) } - return HttpResponse(json.dumps(response), - content_type="application/json") + return HttpResponse( + json.dumps(response), content_type="application/json" + ) card_details_response = card_details['response_object'] card_details_dict = { 'last4': card_details_response['last4'], @@ -709,7 +715,6 @@ class OrderConfirmationView(DetailView): } return HttpResponse(json.dumps(response), content_type="application/json") - # Create user if the user is not logged in and if he is not already # registered if not request.user.is_authenticated(): @@ -747,7 +752,6 @@ class OrderConfirmationView(DetailView): # object already exists stripe_customer_id = request.user.stripecustomer.id custom_user = request.user - # Save billing address billing_address_data = request.session.get('billing_address_data') logger.debug('billing_address_data is {}'.format(billing_address_data)) @@ -771,16 +775,16 @@ class OrderConfirmationView(DetailView): 'request_host': request.get_host(), 'language': get_language(), } - - create_vm_task.delay(vm_template_id, user, specs, template, - stripe_customer_id, billing_address_data, - stripe_subscription_obj.id, card_details_dict) - for session_var in ['specs', 'template', 'billing_address', - 'billing_address_data', - 'token', 'customer']: - if session_var in request.session: - del request.session[session_var] - + create_vm_task.delay( + vm_template_id, user, specs, template, stripe_customer_id, + billing_address_data, stripe_subscription_obj.id, + card_details_dict + ) + HostingUtils.clear_items_from_list( + request.session, + ['specs', 'template', 'billing_address', 'billing_address_data', + 'token', 'customer'] + ) response = { 'status': True, 'redirect': reverse( From edac806c118f642b737c7999c02d99643a67b639 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:56:29 +0100 Subject: [PATCH 0082/1032] Some more refactoring --- datacenterlight/views.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 51cd18fd..50148418 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -785,17 +785,18 @@ class OrderConfirmationView(DetailView): ['specs', 'template', 'billing_address', 'billing_address_data', 'token', 'customer'] ) + if request.user.is_authenticated(): + redirect_url = reverse('hosting:virtual_machines') + else: + redirect_url = reverse('datacenterlight:index') response = { 'status': True, - 'redirect': reverse( - 'hosting:virtual_machines') if request.user.is_authenticated() else reverse( - 'datacenterlight:index'), + 'redirect': redirect_url, 'msg_title': str(_('Thank you for the order.')), 'msg_body': str( _('Your VM will be up and running in a few moments.' ' We will send you a confirmation email as soon as' ' it is ready.')) } - return HttpResponse(json.dumps(response), content_type="application/json") From 62f30bf03c37301061b357ab14daa90ea363b648 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 22:03:19 +0100 Subject: [PATCH 0083/1032] Remove some commented and unnecessary code --- .../datacenterlight/landing_payment.html | 38 ------------------- datacenterlight/views.py | 15 -------- hosting/templates/hosting/settings.html | 10 ----- 3 files changed, 63 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index 69c80d35..5ac601ce 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -112,44 +112,6 @@ {% endif %} {% include "hosting/includes/_card_input.html" %} - {% comment %} -
- {% if credit_card_data.last4 %} - -
Credit Card
-
Last 4: *****{{credit_card_data.last4}}
-
Type: {{credit_card_data.cc_brand}}
- - - {% if not messages and not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' or 'make_charge_error' in message.tags %} -
    -
  • -

    {{ message|safe }}

    -
  • -
- {% endif %} - {% endfor %} - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
- -
- {% else %} - {% include "hosting/includes/_card_input.html" %} - {% endif %} -
- {% endcomment %} {% endwith %} diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 50148418..3a8bdac6 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -359,7 +359,6 @@ class PaymentOrderView(FormView): billing_address_data = self.request.session['billing_address_data'] else: billing_address_data = {} - if self.request.user.is_authenticated(): if billing_address_data: billing_address_form = BillingAddressForm( @@ -369,24 +368,10 @@ class PaymentOrderView(FormView): billing_address_form = BillingAddressForm( instance=self.request.user.billing_addresses.first() ) - # Get user last order - last_hosting_order = HostingOrder.objects.filter( - customer__user=self.request.user - ).last() - - # If user has already an hosting order, get the credit card - # data from it - if last_hosting_order: - credit_card_data = last_hosting_order.get_cc_data() - if credit_card_data: - context['credit_card_data'] = credit_card_data - else: - context['credit_card_data'] = None else: billing_address_form = BillingAddressFormSignup( initial=billing_address_data ) - context.update({ 'cards_list': cards_list, 'stripe_key': settings.STRIPE_API_PUBLIC_KEY, diff --git a/hosting/templates/hosting/settings.html b/hosting/templates/hosting/settings.html index 6b5acbee..64057747 100644 --- a/hosting/templates/hosting/settings.html +++ b/hosting/templates/hosting/settings.html @@ -123,14 +123,4 @@ })(); {%endif%} - - {% comment %} - {% if credit_card_data.last4 and credit_card_data.cc_brand %} - - {%endif%} - {% endcomment %} {%endblock%} From 4be27962703cdb2774e1b0d13842ba3df3b22846 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 22:40:21 +0100 Subject: [PATCH 0084/1032] Clean up some unnecessary code --- datacenterlight/views.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 3a8bdac6..fb34f5b4 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -348,10 +348,9 @@ class PaymentOrderView(FormView): def get_context_data(self, **kwargs): context = super(PaymentOrderView, self).get_context_data(**kwargs) user = self.request.user + stripe_customer = None if hasattr(user, 'stripecustomer'): stripe_customer = user.stripecustomer - else: - stripe_customer = None cards_list = UserCardDetail.get_all_cards_list( stripe_customer=stripe_customer ) @@ -390,8 +389,6 @@ class PaymentOrderView(FormView): request.session, ['token', 'card_id', 'customer', 'user'] ) - if 'token' in request.session: - del request.session['token'] return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): From 83dbae74e6a661b649f79d2b691ea8dc73a2e8d2 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 22:54:33 +0100 Subject: [PATCH 0085/1032] Add missing card_id to session variables to be cleared --- datacenterlight/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index fb34f5b4..f9d1dede 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -765,7 +765,7 @@ class OrderConfirmationView(DetailView): HostingUtils.clear_items_from_list( request.session, ['specs', 'template', 'billing_address', 'billing_address_data', - 'token', 'customer'] + 'token', 'customer', 'card_id'] ) if request.user.is_authenticated(): redirect_url = reverse('hosting:virtual_machines') From 16b6ecb38cdc87737c54e9f51e3ffa7eff51014a Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 23:48:33 +0100 Subject: [PATCH 0086/1032] Clear session variables on payment error --- hosting/views.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index 5a9c2e2e..37d6eabb 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -39,7 +39,7 @@ from utils.forms import ( BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm, ResendActivationEmailForm ) -from utils.hosting_utils import get_vm_price +from utils.hosting_utils import get_vm_price, HostingUtils from utils.mailer import BaseEmail from utils.stripe_utils import StripeUtils from utils.views import ( @@ -707,6 +707,10 @@ class PaymentVMView(LoginRequiredMixin, FormView): def get(self, request, *args, **kwargs): if 'next' in request.session: del request.session['next'] + HostingUtils.clear_items_from_list( + request.session, + ['token', 'card_id', 'customer', 'user'] + ) return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): From 24d904288fd0724178af021fcbeec01fadf54947 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 30 Oct 2017 00:26:18 +0100 Subject: [PATCH 0087/1032] Clear token and card form variables explicitly --- datacenterlight/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index f9d1dede..f2af35cd 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -356,6 +356,10 @@ class PaymentOrderView(FormView): ) if 'billing_address_data' in self.request.session: billing_address_data = self.request.session['billing_address_data'] + if 'token' in billing_address_data: + billing_address_data.pop('token') + if 'card' in billing_address_data: + billing_address_data.pop('card') else: billing_address_data = {} if self.request.user.is_authenticated(): From a2a35a9475eb6bafd7d6d70d991416a21caab0f4 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 30 Oct 2017 08:26:35 +0100 Subject: [PATCH 0088/1032] Fix error accessing stripecustomer for user when it doesn't exist --- hosting/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index 37d6eabb..3b259242 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -552,8 +552,11 @@ class SettingsView(LoginRequiredMixin, FormView): def get_context_data(self, **kwargs): context = super(SettingsView, self).get_context_data(**kwargs) user = self.request.user + stripe_customer = None + if hasattr(user, 'stripecustomer'): + stripe_customer = user.stripecustomer cards_list = UserCardDetail.get_all_cards_list( - stripe_customer=user.stripecustomer + stripe_customer=stripe_customer ) context.update({ 'cards_list': cards_list, From 3e08760e044bfed66cb1363a4bfcb8de95b93d52 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 08:58:43 +0100 Subject: [PATCH 0089/1032] Change letter-spacing to 2px for settings-container buttons --- hosting/static/hosting/css/commons.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/static/hosting/css/commons.css b/hosting/static/hosting/css/commons.css index 33381370..32a1338e 100644 --- a/hosting/static/hosting/css/commons.css +++ b/hosting/static/hosting/css/commons.css @@ -363,7 +363,7 @@ } .settings-container .choice-btn { - letter-spacing: 1px; + letter-spacing: 2px; min-width: 127px; } From d8ce0f95c5d92d2c9648051e5cef5f54f03ce04b Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 09:02:07 +0100 Subject: [PATCH 0090/1032] Change letter-spacing to 2px for btn-vm-contact --- hosting/static/hosting/css/virtual-machine.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/static/hosting/css/virtual-machine.css b/hosting/static/hosting/css/virtual-machine.css index 3329d6fe..5f91fe2f 100644 --- a/hosting/static/hosting/css/virtual-machine.css +++ b/hosting/static/hosting/css/virtual-machine.css @@ -413,7 +413,7 @@ border: 2px solid #A3C0E2; padding: 5px 25px; font-size: 12px; - letter-spacing: 1.3px; + letter-spacing: 2px; } .btn-vm-contact:hover, .btn-vm-contact:focus { background: #fff; From f9bd8493330cd809f4c47ea98e7c21ba8b1fb1cd Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 09:05:49 +0100 Subject: [PATCH 0091/1032] Remove redundant "previous" text --- .../templates/datacenterlight/landing_payment.html | 4 ++-- hosting/templates/hosting/payment.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index 5ac601ce..e0bd56a9 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -89,7 +89,7 @@

{% if card_list_len > 0 %} - {% blocktrans %}Please select one of the previous cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% blocktrans %}Please select one of the cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% else %} {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% endif %} @@ -108,7 +108,7 @@ {% endfor %} {% if card_list_len > 0 %} -

Use another card
+
{% trans "Use another card" %}
{% endif %} {% include "hosting/includes/_card_input.html" %} diff --git a/hosting/templates/hosting/payment.html b/hosting/templates/hosting/payment.html index 10fd4674..a321b44c 100644 --- a/hosting/templates/hosting/payment.html +++ b/hosting/templates/hosting/payment.html @@ -72,7 +72,7 @@

{% if card_list_len > 0 %} - {% blocktrans %}Please select one of the previous cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% blocktrans %}Please select one of the cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% else %} {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% endif %} @@ -91,7 +91,7 @@

{% endfor %} {% if card_list_len > 0 %} -
Use another card
+
{% trans "Use another card" %}
{% endif %} {% include "hosting/includes/_card_input.html" %} From c438c0d8cbab7d8518d929cc675fa5d8fc5d1d13 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 09:38:36 +0100 Subject: [PATCH 0092/1032] Add some de translations --- .../locale/de/LC_MESSAGES/django.po | 48 +++++++--- hosting/locale/de/LC_MESSAGES/django.po | 87 +++++++++++++++---- 2 files changed, 108 insertions(+), 27 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 3b8c9ca6..2fe8dba8 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-17 00:32+0530\n" +"POT-Creation-Date: 2017-10-31 08:23+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -345,6 +345,17 @@ msgstr "Monat" msgid "Credit Card" msgstr "Kreditkarte" +msgid "" +"Please select one of the cards that you used before or fill in your credit " +"card information below. We are using Stripe for payment and do not store your information in our " +"database." +msgstr "" +"Bitte wähle Seine der Karten aus, die du zuvor verwendet hast, oder gib " +"deine Kreditkartendaten unten ein. Wir verwenden Stripe als " +"Zahlungdiensleister und speichern deine Daten nicht in unserer Datenbank." + msgid "" "Please fill in your credit card information below. We are using Stripe for payment and do not " @@ -354,12 +365,17 @@ msgstr "" "\"https://stripe.com\" target=\"_blank\">Stripe für die Bezahlung und " "speichern keine Informationen in unserer Datenbank." -msgid "" -"You are not making any payment yet. After submitting your card information, " -"you will be taken to the Confirm Order Page." -msgstr "" -"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, " -"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast." +msgid "Last" +msgstr "Vor" + +msgid "Type" +msgstr "Kartentyp" + +msgid "SELECT" +msgstr "Auswählen" + +msgid "Use another card" +msgstr "Benutze eine andere Kreditkarte" msgid "Processing" msgstr "Weiter" @@ -471,6 +487,13 @@ msgstr "Ungültige RAM-Grösse" msgid "Invalid storage size" msgstr "Ungültige Speicher-Grösse" +#, python-brace-format +msgid "{user} does not have permission to access the card" +msgstr "" + +msgid "An error occurred. Details: {}" +msgstr "" + msgid "Confirm Order" msgstr "Bestellung Bestätigen" @@ -494,15 +517,20 @@ msgstr "" "Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du " "auf sie zugreifen kannst." +#~ msgid "" +#~ "You are not making any payment yet. After submitting your card " +#~ "information, you will be taken to the Confirm Order Page." +#~ msgstr "" +#~ "Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst " +#~ "ausgelöst, nachdem Du die Bestellung auf der nächsten Seite bestätigt " +#~ "hast." + #~ msgid "Card Number" #~ msgstr "Kreditkartennummer" #~ msgid "Expiry Date" #~ msgstr "Ablaufdatum" -#~ msgid "Card Type" -#~ msgstr "Kartentyp" - #~ msgid "Processing..." #~ msgstr "Abarbeitung..." diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 64e4a73e..3614dc49 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-17 00:32+0530\n" +"POT-Creation-Date: 2017-10-31 08:23+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -437,6 +437,17 @@ msgstr "inkl. Mehrwertsteuer" msgid "Billing Address" msgstr "Rechnungsadresse" +msgid "" +"Please select one of the cards that you used before or fill in your credit " +"card information below. We are using Stripe for payment and do not store your information in our " +"database." +msgstr "" +"Bitte wähle Seine der Karten aus, die du zuvor verwendet hast, oder gib " +"deine Kreditkartendaten unten ein. Wir verwenden Stripe als " +"Zahlungdiensleister und speichern deine Daten nicht in unserer Datenbank." + msgid "" "Please fill in your credit card information below. We are using Stripe for payment and do not " @@ -446,12 +457,17 @@ msgstr "" "\"https://stripe.com\" target=\"_blank\">Stripe für die Bezahlung und " "speichern keine Informationen in unserer Datenbank." -msgid "" -"You are not making any payment yet. After submitting your card information, " -"you will be taken to the Confirm Order Page." -msgstr "" -"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, " -"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast." +msgid "Last" +msgstr "Vor" + +msgid "Type" +msgstr "Kartentyp" + +msgid "SELECT" +msgstr "Auswählen" + +msgid "Use another card" +msgstr "Benutze eine andere Kreditkarte" msgid "Processing" msgstr "Weiter" @@ -468,16 +484,19 @@ msgstr "Passwort zurücksetzen" msgid "UPDATE" msgstr "" -msgid "Last" -msgstr "" - -msgid "Type" -msgstr "Kartentyp" - msgid "REMOVE CARD" msgstr "KARTE ENTFERNEN" -msgid "SELECT" +msgid "Remove Card" +msgstr "Karte Entfernen" + +msgid "Do you want to remove this associated card?" +msgstr "" + +msgid "Delete" +msgstr "Löschen" + +msgid "DEFAULT" msgstr "" msgid "No Credit Cards Added" @@ -534,9 +553,6 @@ msgstr "" msgid "Private Key" msgstr "" -msgid "Delete" -msgstr "Löschen" - msgid "Delete SSH Key" msgstr "SSH Key löschen" @@ -668,6 +684,35 @@ msgstr "Dein Passwort konnte nicht zurückgesetzt werden." msgid "The reset password link is no longer valid." msgstr "Der Link zum Zurücksetzen Deines Passwortes ist nicht mehr gültig." +msgid "Card deassociation successful" +msgstr "" + +msgid "You are not permitted to do this operation" +msgstr "" + +msgid "The selected card does not exist" +msgstr "" + +msgid "Billing address updated successfully" +msgstr "" + +msgid "You seem to have already added this card" +msgstr "" + +#, python-brace-format +msgid "An error occurred while associating the card. Details: {details}" +msgstr "Beim Zuordnen der Karte ist ein Fehler aufgetreten. Details: {details}" + +msgid "Successfully associated the card with your account" +msgstr "" + +#, python-brace-format +msgid "{user} does not have permission to access the card" +msgstr "" + +msgid "An error occurred. Details: {}" +msgstr "" + msgid "Invalid credit card" msgstr "Ungültige Kreditkarte" @@ -735,6 +780,14 @@ msgstr "" "Es gab einen Fehler bei der Bearbeitung Deine Anfrage. Bitte versuche es " "noch einmal." +#~ msgid "" +#~ "You are not making any payment yet. After submitting your card " +#~ "information, you will be taken to the Confirm Order Page." +#~ msgstr "" +#~ "Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst " +#~ "ausgelöst, nachdem Du die Bestellung auf der nächsten Seite bestätigt " +#~ "hast." + #~ msgid "Reset your password" #~ msgstr "Passwort zurücksetzen" From 272e14f71253dbf2dcac22a1a8f0e7cf889be301 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 27 Nov 2017 08:43:34 +0100 Subject: [PATCH 0093/1032] Update hosting django.po --- hosting/locale/de/LC_MESSAGES/django.po | 42 +++---------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 6721a75c..6774fa8d 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-31 08:23+0000\n" +"POT-Creation-Date: 2017-11-27 07:43+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -453,9 +453,9 @@ msgid "" "database." msgstr "" "Bitte wähle Seine der Karten aus, die du zuvor verwendet hast, oder gib " -"deine Kreditkartendaten unten ein. Wir verwenden Stripe als " -"Zahlungdiensleister und speichern deine Daten nicht in unserer Datenbank." +"deine Kreditkartendaten unten ein. Wir verwenden Stripe als Zahlungdiensleister und speichern deine " +"Daten nicht in unserer Datenbank." msgid "" "Please fill in your credit card information below. We are using Stripe für die Bezahlung und " "speichern keine Informationen in unserer Datenbank." -msgid "" -"You are not making any payment yet. After submitting your card information, " -"you will be taken to the Confirm Order Page." -msgstr "" -"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, " -"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast." - -msgid "SUBMIT" -msgstr "ABSENDEN" - -msgid "Card Number" -msgstr "Kreditkartennummer" - -msgid "Expiry Date" -msgstr "Ablaufdatum" - -msgid "CVC" -msgstr "" - -msgid "Card Type" -msgstr "Kartentyp" - msgid "Last" msgstr "Vor" @@ -524,12 +502,6 @@ msgstr "Karte Entfernen" msgid "Do you want to remove this associated card?" msgstr "" -msgid "Last" -msgstr "" - -msgid "Type" -msgstr "Kartentyp" - msgid "Delete" msgstr "Löschen" @@ -590,9 +562,6 @@ msgstr "" msgid "Private Key" msgstr "" -msgid "Delete" -msgstr "Löschen" - msgid "Delete SSH Key" msgstr "SSH Key löschen" @@ -894,9 +863,6 @@ msgstr "" #~ msgid "Notifications " #~ msgstr "Benachrichtigungen" -#~ msgid "REMOVE CARD" -#~ msgstr "KARTE ENTFERNEN" - #~ msgid "EDIT CARD" #~ msgstr "BEARBEITEN" From dd54b3052e284edc698f2161216da1e90be71a48 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 25 Dec 2017 15:07:12 +0100 Subject: [PATCH 0094/1032] Reorganize imports --- hosting/views.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index 576b3534..25d89b64 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -12,13 +12,13 @@ from django.contrib.auth.tokens import default_token_generator from django.core.exceptions import ValidationError from django.core.files.base import ContentFile from django.core.urlresolvers import reverse_lazy, reverse - from django.http import Http404, HttpResponseRedirect, HttpResponse from django.shortcuts import redirect, render from django.utils.http import urlsafe_base64_decode from django.utils.safestring import mark_safe from django.utils.translation import get_language, ugettext_lazy as _ from django.utils.translation import ugettext +from django.views.decorators.cache import cache_control from django.views.generic import ( View, CreateView, FormView, ListView, DetailView, DeleteView, TemplateView, UpdateView @@ -29,11 +29,14 @@ from stored_messages.api import mark_read from stored_messages.models import Message from stored_messages.settings import stored_messages_settings +from datacenterlight.models import VMTemplate from datacenterlight.tasks import create_vm_task from membership.models import CustomUser, StripeCustomer from opennebula_api.models import OpenNebulaManager -from opennebula_api.serializers import VirtualMachineSerializer, \ - VirtualMachineTemplateSerializer, VMTemplateSerializer +from opennebula_api.serializers import ( + VirtualMachineSerializer, VirtualMachineTemplateSerializer, + VMTemplateSerializer +) from utils.forms import ( BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm, ResendActivationEmailForm @@ -46,13 +49,14 @@ from utils.views import ( PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin, ResendActivationLinkViewMixin ) -from .forms import HostingUserSignupForm, HostingUserLoginForm, \ - UserHostingKeyForm, generate_ssh_key_name +from .forms import ( + HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm, + generate_ssh_key_name +) from .mixins import ProcessVMSelectionMixin from .models import ( HostingOrder, HostingBill, HostingPlan, UserHostingKey, VMDetail ) -from datacenterlight.models import VMTemplate logger = logging.getLogger(__name__) From b4f03b95531dce6772eac684ed29fb66693b9457 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 25 Dec 2017 15:10:34 +0100 Subject: [PATCH 0095/1032] Add cache_control decorator to all hosting views --- hosting/views.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index 25d89b64..a6922a70 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -65,6 +65,7 @@ CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \ minutes." +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class DashboardView(LoginRequiredMixin, View): template_name = "hosting/dashboard.html" login_url = reverse_lazy('hosting:login') @@ -186,6 +187,7 @@ class HostingPricingView(ProcessVMSelectionMixin, View): return render(request, self.template_name, context) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class IndexView(View): template_name = "hosting/index.html" @@ -210,6 +212,7 @@ class IndexView(View): return render(request, self.template_name, context) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class LoginView(LoginViewMixin): template_name = "hosting/login.html" form_class = HostingUserLoginForm @@ -310,6 +313,7 @@ class SignupValidatedView(SignupValidateView): return context +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class ResendActivationEmailView(ResendActivationLinkViewMixin): template_name = 'hosting/resend_activation_link.html' form_class = ResendActivationEmailForm @@ -318,6 +322,7 @@ class ResendActivationEmailView(ResendActivationLinkViewMixin): email_template_name = 'user_activation' +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class PasswordResetView(PasswordResetViewMixin): site = 'dcl' template_name = 'hosting/reset_password.html' @@ -326,6 +331,7 @@ class PasswordResetView(PasswordResetViewMixin): template_email_path = 'hosting/emails/' +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class PasswordResetConfirmView(PasswordResetConfirmViewMixin): template_name = 'hosting/confirm_reset_password.html' success_url = reverse_lazy('hosting:login') @@ -402,6 +408,7 @@ class MarkAsReadNotificationView(LoginRequiredMixin, UpdateView): return HttpResponseRedirect(reverse('hosting:notifications')) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyDeleteView(LoginRequiredMixin, DeleteView): login_url = reverse_lazy('hosting:login') success_url = reverse_lazy('hosting:ssh_keys') @@ -430,6 +437,7 @@ class SSHKeyDeleteView(LoginRequiredMixin, DeleteView): return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyListView(LoginRequiredMixin, ListView): template_name = "hosting/user_keys.html" login_url = reverse_lazy('hosting:login') @@ -450,6 +458,7 @@ class SSHKeyListView(LoginRequiredMixin, ListView): **response_kwargs) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyChoiceView(LoginRequiredMixin, View): template_name = "hosting/choice_ssh_keys.html" login_url = reverse_lazy('hosting:login') @@ -476,6 +485,7 @@ class SSHKeyChoiceView(LoginRequiredMixin, View): return redirect(reverse_lazy('hosting:ssh_keys'), foo='bar') +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyCreateView(LoginRequiredMixin, FormView): form_class = UserHostingKeyForm model = UserHostingKey @@ -538,6 +548,7 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView): return self.form_invalid(form) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SettingsView(LoginRequiredMixin, FormView): template_name = "hosting/settings.html" login_url = reverse_lazy('hosting:login') @@ -589,6 +600,7 @@ class SettingsView(LoginRequiredMixin, FormView): return self.form_invalid(form) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class PaymentVMView(LoginRequiredMixin, FormView): template_name = 'hosting/payment.html' login_url = reverse_lazy('hosting:login') @@ -667,8 +679,8 @@ class PaymentVMView(LoginRequiredMixin, FormView): return self.form_invalid(form) -class OrdersHostingDetailView(LoginRequiredMixin, - DetailView): +@cache_control(no_cache=True, must_revalidate=True, no_store=True) +class OrdersHostingDetailView(LoginRequiredMixin, DetailView): template_name = "hosting/order_detail.html" context_object_name = "order" login_url = reverse_lazy('hosting:login') @@ -881,6 +893,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, content_type="application/json") +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class OrdersHostingListView(LoginRequiredMixin, ListView): template_name = "hosting/orders.html" login_url = reverse_lazy('hosting:login') @@ -895,6 +908,7 @@ class OrdersHostingListView(LoginRequiredMixin, ListView): return super(OrdersHostingListView, self).get_queryset() +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class OrdersHostingDeleteView(LoginRequiredMixin, DeleteView): login_url = reverse_lazy('hosting:login') success_url = reverse_lazy('hosting:orders') @@ -939,6 +953,7 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): return context +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class CreateVirtualMachinesView(LoginRequiredMixin, View): template_name = "hosting/create_virtual_machine.html" login_url = reverse_lazy('hosting:login') @@ -1011,6 +1026,7 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): return redirect(reverse('hosting:payment')) +@cache_control(no_cache=True, must_revalidate=True, no_store=True) class VirtualMachineView(LoginRequiredMixin, View): template_name = "hosting/virtual_machine_detail.html" login_url = reverse_lazy('hosting:login') From f357c83fc4c7edef344d8f1c9a79ddf1ca00bc69 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 25 Dec 2017 15:53:24 +0100 Subject: [PATCH 0096/1032] Remove cache_control headers from Classes --- hosting/views.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index a6922a70..3a596394 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -65,7 +65,6 @@ CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \ minutes." -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class DashboardView(LoginRequiredMixin, View): template_name = "hosting/dashboard.html" login_url = reverse_lazy('hosting:login') @@ -187,7 +186,6 @@ class HostingPricingView(ProcessVMSelectionMixin, View): return render(request, self.template_name, context) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class IndexView(View): template_name = "hosting/index.html" @@ -212,7 +210,6 @@ class IndexView(View): return render(request, self.template_name, context) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class LoginView(LoginViewMixin): template_name = "hosting/login.html" form_class = HostingUserLoginForm @@ -313,7 +310,6 @@ class SignupValidatedView(SignupValidateView): return context -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class ResendActivationEmailView(ResendActivationLinkViewMixin): template_name = 'hosting/resend_activation_link.html' form_class = ResendActivationEmailForm @@ -322,7 +318,6 @@ class ResendActivationEmailView(ResendActivationLinkViewMixin): email_template_name = 'user_activation' -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class PasswordResetView(PasswordResetViewMixin): site = 'dcl' template_name = 'hosting/reset_password.html' @@ -331,7 +326,6 @@ class PasswordResetView(PasswordResetViewMixin): template_email_path = 'hosting/emails/' -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class PasswordResetConfirmView(PasswordResetConfirmViewMixin): template_name = 'hosting/confirm_reset_password.html' success_url = reverse_lazy('hosting:login') @@ -408,7 +402,6 @@ class MarkAsReadNotificationView(LoginRequiredMixin, UpdateView): return HttpResponseRedirect(reverse('hosting:notifications')) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyDeleteView(LoginRequiredMixin, DeleteView): login_url = reverse_lazy('hosting:login') success_url = reverse_lazy('hosting:ssh_keys') @@ -437,7 +430,6 @@ class SSHKeyDeleteView(LoginRequiredMixin, DeleteView): return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyListView(LoginRequiredMixin, ListView): template_name = "hosting/user_keys.html" login_url = reverse_lazy('hosting:login') @@ -458,7 +450,6 @@ class SSHKeyListView(LoginRequiredMixin, ListView): **response_kwargs) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyChoiceView(LoginRequiredMixin, View): template_name = "hosting/choice_ssh_keys.html" login_url = reverse_lazy('hosting:login') @@ -485,7 +476,6 @@ class SSHKeyChoiceView(LoginRequiredMixin, View): return redirect(reverse_lazy('hosting:ssh_keys'), foo='bar') -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SSHKeyCreateView(LoginRequiredMixin, FormView): form_class = UserHostingKeyForm model = UserHostingKey @@ -548,7 +538,6 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView): return self.form_invalid(form) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class SettingsView(LoginRequiredMixin, FormView): template_name = "hosting/settings.html" login_url = reverse_lazy('hosting:login') @@ -600,7 +589,6 @@ class SettingsView(LoginRequiredMixin, FormView): return self.form_invalid(form) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class PaymentVMView(LoginRequiredMixin, FormView): template_name = 'hosting/payment.html' login_url = reverse_lazy('hosting:login') @@ -679,7 +667,6 @@ class PaymentVMView(LoginRequiredMixin, FormView): return self.form_invalid(form) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class OrdersHostingDetailView(LoginRequiredMixin, DetailView): template_name = "hosting/order_detail.html" context_object_name = "order" @@ -893,7 +880,6 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): content_type="application/json") -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class OrdersHostingListView(LoginRequiredMixin, ListView): template_name = "hosting/orders.html" login_url = reverse_lazy('hosting:login') @@ -908,7 +894,6 @@ class OrdersHostingListView(LoginRequiredMixin, ListView): return super(OrdersHostingListView, self).get_queryset() -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class OrdersHostingDeleteView(LoginRequiredMixin, DeleteView): login_url = reverse_lazy('hosting:login') success_url = reverse_lazy('hosting:orders') @@ -953,7 +938,6 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): return context -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class CreateVirtualMachinesView(LoginRequiredMixin, View): template_name = "hosting/create_virtual_machine.html" login_url = reverse_lazy('hosting:login') @@ -1026,7 +1010,6 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): return redirect(reverse('hosting:payment')) -@cache_control(no_cache=True, must_revalidate=True, no_store=True) class VirtualMachineView(LoginRequiredMixin, View): template_name = "hosting/virtual_machine_detail.html" login_url = reverse_lazy('hosting:login') From d796272c1053f644758bab7eb3a6b0f48bb90734 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 25 Dec 2017 15:54:23 +0100 Subject: [PATCH 0097/1032] Add cache_control headers to get and post methods --- hosting/views.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index 3a596394..879fc3e7 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -73,6 +73,7 @@ class DashboardView(LoginRequiredMixin, View): context = {} return context + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): context = self.get_context_data() return render(request, self.template_name, context) @@ -204,9 +205,9 @@ class IndexView(View): } return context + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): context = self.get_context_data() - return render(request, self.template_name, context) @@ -443,6 +444,7 @@ class SSHKeyListView(LoginRequiredMixin, ListView): self.queryset = UserHostingKey.objects.filter(user=user) return super(SSHKeyListView, self).get_queryset() + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def render_to_response(self, context, **response_kwargs): if not self.queryset: return HttpResponseRedirect(reverse('hosting:choice_ssh_keys')) @@ -454,10 +456,12 @@ class SSHKeyChoiceView(LoginRequiredMixin, View): template_name = "hosting/choice_ssh_keys.html" login_url = reverse_lazy('hosting:login') + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): context = {} return render(request, self.template_name, context) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def post(self, request, *args, **kwargs): name = generate_ssh_key_name() private_key, public_key = UserHostingKey.generate_keys() @@ -527,6 +531,10 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView): manager.manage_public_key([{'value': public_key, 'state': True}]) return HttpResponseRedirect(self.success_url) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + return render(request, self.template_name) + def post(self, request, *args, **kwargs): form = self.get_form() required = 'add_ssh' in self.request.POST @@ -572,6 +580,10 @@ class SettingsView(LoginRequiredMixin, FormView): return context + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + return render(request, self.template_name) + def post(self, request, *args, **kwargs): form = self.get_form() if form.is_valid(): @@ -1045,6 +1057,7 @@ class VirtualMachineView(LoginRequiredMixin, View): final_url = reverse('hosting:virtual_machines') return final_url + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): vm = self.get_object() if vm is None: From 72baa3635bad0f94712f284d9b4abb3a7bb8b3ec Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 08:31:19 +0100 Subject: [PATCH 0098/1032] Add cache_control decorator to LoginViewMixin --- utils/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/views.py b/utils/views.py index 6e54cde6..394a9fc2 100644 --- a/utils/views.py +++ b/utils/views.py @@ -8,6 +8,7 @@ from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode from django.utils.translation import ugettext_lazy as _ from django.views.generic import FormView, CreateView +from django.views.decorators.cache import cache_control from membership.models import CustomUser from .forms import SetPasswordForm @@ -57,6 +58,7 @@ class LoginViewMixin(FormView): return HttpResponseRedirect(self.get_success_url()) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): if self.request.user.is_authenticated(): return HttpResponseRedirect(self.get_success_url()) From 87cdb08f3c94a70e100f41d879490c01e90feac1 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 08:32:55 +0100 Subject: [PATCH 0099/1032] Change success_url in hosting.SignupView from ssh_keys to dashboard --- hosting/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index 879fc3e7..02e30808 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -221,7 +221,7 @@ class SignupView(CreateView): template_name = 'hosting/signup.html' form_class = HostingUserSignupForm model = CustomUser - success_url = reverse_lazy('hosting:ssh_keys') + success_url = reverse_lazy('hosting:dashboard') def get_success_url(self): next_url = self.request.session.get( From bec541c06a4b574d7ccc6b53d44e2f65e3570a18 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 08:33:53 +0100 Subject: [PATCH 0100/1032] Add get method to hosting.SignupView and cache_control --- hosting/views.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hosting/views.py b/hosting/views.py index 02e30808..7d60d7b4 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -239,6 +239,12 @@ class SignupView(CreateView): return HttpResponseRedirect(reverse_lazy('hosting:signup-validate')) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + if self.request.user.is_authenticated(): + return HttpResponseRedirect(self.get_success_url()) + return super(SignupView, self).get(request, *args, **kwargs) + class SignupValidateView(TemplateView): template_name = "hosting/signup_validate.html" From 98e06686f9a556614301a5605de12be4b100a7f7 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 09:03:17 +0100 Subject: [PATCH 0101/1032] Add get method and cache_control to SignupValidatedView --- hosting/views.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hosting/views.py b/hosting/views.py index 7d60d7b4..76be4a67 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -316,6 +316,12 @@ class SignupValidatedView(SignupValidateView): context['section_title'] = section_title return context + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + if self.request.user.is_authenticated(): + return HttpResponseRedirect(reverse_lazy('hosting:dashboard')) + return super(SignupValidatedView, self).get(request, *args, **kwargs) + class ResendActivationEmailView(ResendActivationLinkViewMixin): template_name = 'hosting/resend_activation_link.html' From ab06eeff674ce7b59609957619eadf5a0e22fff7 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 09:04:58 +0100 Subject: [PATCH 0102/1032] Add cache_control to SSHKEyCreateView and SettingsView post methods --- hosting/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hosting/views.py b/hosting/views.py index 76be4a67..0b258536 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -547,6 +547,7 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView): def get(self, request, *args, **kwargs): return render(request, self.template_name) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def post(self, request, *args, **kwargs): form = self.get_form() required = 'add_ssh' in self.request.POST @@ -596,6 +597,7 @@ class SettingsView(LoginRequiredMixin, FormView): def get(self, request, *args, **kwargs): return render(request, self.template_name) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def post(self, request, *args, **kwargs): form = self.get_form() if form.is_valid(): From 14ff876fbf9c984ce54a22ed1d913bb43441b993 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 09:06:46 +0100 Subject: [PATCH 0103/1032] Add cache_control to PaymentVMView and OrdersHostingDetailView --- hosting/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hosting/views.py b/hosting/views.py index 0b258536..26adb834 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -660,11 +660,13 @@ class PaymentVMView(LoginRequiredMixin, FormView): return context + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): if 'next' in request.session: del request.session['next'] return self.render_to_response(self.get_context_data()) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def post(self, request, *args, **kwargs): form = self.get_form() if form.is_valid(): @@ -792,6 +794,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): context['vm'] = self.request.session.get('specs') return context + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): if not self.kwargs.get('pk'): if 'specs' not in self.request.session: @@ -813,6 +816,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): ) return self.render_to_response(context) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def post(self, request): template = request.session.get('template') specs = request.session.get('specs') From 639e4cf414aaddd374e51286f5d2d02533d0f9c7 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 09:09:54 +0100 Subject: [PATCH 0104/1032] Add get method and cache_control to OrdersHostingListView --- hosting/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hosting/views.py b/hosting/views.py index 26adb834..b6d65455 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -923,6 +923,10 @@ class OrdersHostingListView(LoginRequiredMixin, ListView): self.queryset = HostingOrder.objects.filter(customer__user=user) return super(OrdersHostingListView, self).get_queryset() + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + return super(OrdersHostingListView, self).get(request, *args, **kwargs) + class OrdersHostingDeleteView(LoginRequiredMixin, DeleteView): login_url = reverse_lazy('hosting:login') From 1395c04a001033bc0813e4ada4f509dc7e90f85f Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 27 Dec 2017 09:10:41 +0100 Subject: [PATCH 0105/1032] Add cache_control to CreateVirtualMachinesView and VirtualMachineView --- hosting/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hosting/views.py b/hosting/views.py index b6d65455..f43221c6 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -988,10 +988,12 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): if (value > 2000) or (value < 10): raise ValidationError(_('Invalid storage size')) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): context = {'templates': VMTemplate.objects.all()} return render(request, self.template_name, context) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def post(self, request): cores = request.POST.get('cpu') cores_field = forms.IntegerField(validators=[self.validate_cores]) @@ -1114,6 +1116,7 @@ class VirtualMachineView(LoginRequiredMixin, View): return render(request, self.template_name, context) + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def post(self, request, *args, **kwargs): response = {'status': False} admin_email_body = {} From c10dc9f2e294a8cf7343b86f0b8e51d12110d3a1 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 24 Feb 2018 10:12:32 +0100 Subject: [PATCH 0106/1032] Remove some more beta access resources --- .../datacenterlight/beta_access.html | 28 --- .../datacenterlight/beta_success.html | 46 ----- .../emails/base_email_datacenterlight.html | 178 ------------------ 3 files changed, 252 deletions(-) delete mode 100644 datacenterlight/templates/datacenterlight/beta_access.html delete mode 100644 datacenterlight/templates/datacenterlight/beta_success.html delete mode 100644 datacenterlight/templates/datacenterlight/emails/base_email_datacenterlight.html diff --git a/datacenterlight/templates/datacenterlight/beta_access.html b/datacenterlight/templates/datacenterlight/beta_access.html deleted file mode 100644 index d87692fb..00000000 --- a/datacenterlight/templates/datacenterlight/beta_access.html +++ /dev/null @@ -1,28 +0,0 @@ -{% load i18n %} -
- {% csrf_token %} - {{ form.non_field_errors }} -
- {% for message in messages %} - {{ message }} - {% endfor %} -
-
-
- - {{ form.name.errors|striptags}} -
-
- - {{ form.email.errors|striptags}} -
-
- -
- \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/beta_success.html b/datacenterlight/templates/datacenterlight/beta_success.html deleted file mode 100644 index 7ac49457..00000000 --- a/datacenterlight/templates/datacenterlight/beta_success.html +++ /dev/null @@ -1,46 +0,0 @@ -{% load i18n %} - - - - \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/emails/base_email_datacenterlight.html b/datacenterlight/templates/datacenterlight/emails/base_email_datacenterlight.html deleted file mode 100644 index 3f06b069..00000000 --- a/datacenterlight/templates/datacenterlight/emails/base_email_datacenterlight.html +++ /dev/null @@ -1,178 +0,0 @@ -{% load static from staticfiles %} -{% load i18n %} -{% comment %} unused {% endcomment %} - - - - - - - - {{dcl_text}} - - - - - - - - - - - - - -
-
- - - - -
- -
- - - - - -
- logo - -
-
- -
-
-
-
- - - - - - - - - - -
- {% block email_head %} - {% endblock %} -
-

- {% block email_body %} - {% endblock %} -

  -
-
-
-
- - - - -
{% trans 'Your Data Center Light Team' %} -
-
-
- - - From d85e1c671b3078341d03790e4d79ad384386fa3f Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 28 Feb 2018 04:09:19 +0530 Subject: [PATCH 0107/1032] All major DCL plugins added --- datacenterlight/cms_models.py | 104 +++++++ datacenterlight/cms_plugins.py | 95 +++++++ .../0012_dclcalculatorpluginmodel.py | 134 +++++++++ datacenterlight/models.py | 3 + .../datacenterlight/css/header-slider.css | 164 +++++++++++ .../datacenterlight/css/landing-page.css | 177 +++++------- .../static/datacenterlight/js/main.js | 2 +- .../templates/datacenterlight/base.html | 4 +- .../templates/datacenterlight/cms/base.html | 75 +++++ .../datacenterlight/cms/calculator.html | 25 ++ .../datacenterlight/cms/contact.html | 35 +++ .../templates/datacenterlight/cms/footer.html | 15 + .../templates/datacenterlight/cms/link.html | 5 + .../templates/datacenterlight/cms/navbar.html | 64 +++++ .../datacenterlight/cms/navbar_dropdown.html | 10 + .../datacenterlight/cms/section.html | 27 ++ .../datacenterlight/cms/section_icon.html | 3 + .../datacenterlight/cms/section_image.html | 6 + .../datacenterlight/contact_form.html | 6 +- .../includes/_calculator_form.html | 3 - .../datacenterlight/includes/_footer.html | 1 - .../templates/datacenterlight/index.html | 91 +++---- .../datacenterlight/whydatacenterlight.html | 257 +++++++++--------- datacenterlight/views.py | 8 +- dynamicweb/settings/base.py | 42 ++- 25 files changed, 1052 insertions(+), 304 deletions(-) create mode 100644 datacenterlight/cms_models.py create mode 100644 datacenterlight/cms_plugins.py create mode 100644 datacenterlight/migrations/0012_dclcalculatorpluginmodel.py create mode 100644 datacenterlight/static/datacenterlight/css/header-slider.css create mode 100644 datacenterlight/templates/datacenterlight/cms/base.html create mode 100644 datacenterlight/templates/datacenterlight/cms/calculator.html create mode 100644 datacenterlight/templates/datacenterlight/cms/contact.html create mode 100644 datacenterlight/templates/datacenterlight/cms/footer.html create mode 100644 datacenterlight/templates/datacenterlight/cms/link.html create mode 100644 datacenterlight/templates/datacenterlight/cms/navbar.html create mode 100644 datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html create mode 100644 datacenterlight/templates/datacenterlight/cms/section.html create mode 100644 datacenterlight/templates/datacenterlight/cms/section_icon.html create mode 100644 datacenterlight/templates/datacenterlight/cms/section_image.html diff --git a/datacenterlight/cms_models.py b/datacenterlight/cms_models.py new file mode 100644 index 00000000..3db5b969 --- /dev/null +++ b/datacenterlight/cms_models.py @@ -0,0 +1,104 @@ +from djangocms_text_ckeditor.fields import HTMLField +from cms.models.pluginmodel import CMSPlugin +from django.db import models +from django.utils.safestring import mark_safe +from filer.fields.image import FilerImageField + +# Models for CMS Plugins + + +class DCLSectionPluginModel(CMSPlugin): + heading = models.CharField( + blank=True, null=True, max_length=100, + help_text='An optional heading for the Section', + ) + content = HTMLField() + TEXT_DIRECTIONS = ( + ('left', 'Left'), + ('right', 'Right') + ) + text_direction = models.CharField( + choices=TEXT_DIRECTIONS, max_length=10, default=True, + help_text='The alignment of text in the section' + ) + + +class DCLLinkPluginModel(CMSPlugin): + target = models.CharField( + max_length=100, + help_text='Url or #id to navigate to' + ) + text = models.CharField( + max_length=50, + help_text='Text for the menu item' + ) + title = models.CharField( + blank=True, null=True, max_length=100, + help_text=( + 'Optional title text, that will be shown when a user ' + 'hovers over the link' + ) + ) + separator = models.BooleanField( + default=False, + help_text='Select to include a separator after the previous link' + ) + + +class DCLNavbarDropdownPluginModel(CMSPlugin): + target = models.URLField( + blank=True, null=True, max_length=100, + help_text='Optional Url or #id to navigate on click' + ) + text = models.CharField( + max_length=50, + help_text='Text for the dropdown toggle' + ) + + +class DCLContactPluginModel(CMSPlugin): + heading = models.CharField(max_length=100, default="Contact", blank=True) + organization_name = models.CharField( + max_length=100, default="ungleich GmbH", blank=True + ) + email = models.EmailField(max_length=200, default="info@ungleich.ch") + address = models.CharField( + max_length=100, default="In der Au 7, Schwanden 8762", blank=True + ) + country = models.CharField( + max_length=100, default="Switzerland", blank=True + ) + form_header = models.CharField( + max_length=100, default="Send us a message.", blank=True + ) + + +class DCLFooterPluginModel(CMSPlugin): + copyright_label = models.CharField( + max_length=100, default='ungleich GmbH', blank=True, + help_text='Name of the company alongside the copyright year' + ) + + +class DCLSectionIconPluginModel(CMSPlugin): + fontawesome_icon_name = models.CharField( + max_length=30, + help_text=mark_safe( + 'Name of the fontawesome icon to use. ' + 'Refer docs.' + ) + ) + + +class DCLSectionImagePluginModel(CMSPlugin): + image = FilerImageField( + on_delete=models.CASCADE, + help_text=( + 'Image file to be used in section. Add multiple plugins ' + 'to add more than one image' + ) + ) + caption = models.CharField( + max_length=100, null=True, blank=True, + help_text='Optional caption for the image.' + ) diff --git a/datacenterlight/cms_plugins.py b/datacenterlight/cms_plugins.py new file mode 100644 index 00000000..36fcca17 --- /dev/null +++ b/datacenterlight/cms_plugins.py @@ -0,0 +1,95 @@ +from cms.plugin_base import CMSPluginBase +from cms.plugin_pool import plugin_pool +from cms.models.pluginmodel import CMSPlugin + +from .cms_models import ( + DCLSectionPluginModel, DCLLinkPluginModel, + DCLNavbarDropdownPluginModel, DCLContactPluginModel, + DCLFooterPluginModel, DCLSectionIconPluginModel, + DCLSectionImagePluginModel +) + + +@plugin_pool.register_plugin +class DCLCalculatorPlugin(CMSPluginBase): + module = "Datacenterlight" + model = DCLSectionPluginModel + render_template = "datacenterlight/cms/calculator.html" + cache = False + + +@plugin_pool.register_plugin +class DCLSectionPlugin(CMSPluginBase): + module = "Datacenterlight" + model = DCLSectionPluginModel + render_template = "datacenterlight/cms/section.html" + cache = False + allow_children = True + child_classes = ['DCLSectionIconPlugin', 'DCLSectionImagePlugin'] + + +@plugin_pool.register_plugin +class DCLNavbarPlugin(CMSPluginBase): + module = "Datacenterlight" + model = CMSPlugin + render_template = "datacenterlight/cms/navbar.html" + cache = False + allow_children = True + child_classes = ['DCLLinkPlugin', 'DCLNavbarDropdownPlugin'] + + +@plugin_pool.register_plugin +class DCLLinkPlugin(CMSPluginBase): + module = "Datacenterlight" + model = DCLLinkPluginModel + render_template = "datacenterlight/cms/link.html" + cache = False + require_parent = True + + +@plugin_pool.register_plugin +class DCLNavbarDropdownPlugin(CMSPluginBase): + module = "Datacenterlight" + 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 DCLContactPlugin(CMSPluginBase): + module = "Datacenterlight" + model = DCLContactPluginModel + render_template = "datacenterlight/cms/contact.html" + cache = False + + +@plugin_pool.register_plugin +class DCLFooterPlugin(CMSPluginBase): + module = "Datacenterlight" + model = DCLFooterPluginModel + render_template = "datacenterlight/cms/footer.html" + cache = False + allow_children = True + child_classes = ['DCLLinkPlugin'] + + +@plugin_pool.register_plugin +class DCLSectionIconPlugin(CMSPluginBase): + module = "Datacenterlight" + model = DCLSectionIconPluginModel + render_template = "datacenterlight/cms/section_icon.html" + cache = False + require_parent = True + + +@plugin_pool.register_plugin +class DCLSectionImagePlugin(CMSPluginBase): + module = "Datacenterlight" + model = DCLSectionImagePluginModel + render_template = "datacenterlight/cms/section_image.html" + cache = False + require_parent = True diff --git a/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py b/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py new file mode 100644 index 00000000..ee872ee9 --- /dev/null +++ b/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2018-02-27 22:29 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import djangocms_text_ckeditor.fields +import filer.fields.image + + +class Migration(migrations.Migration): + + dependencies = [ + ('cms', '0014_auto_20160404_1908'), + ('datacenterlight', '0011_auto_20180220_1423'), + ('filer', '0005_auto_20171219_1856'), + ] + + operations = [ + migrations.CreateModel( + name='DCLSectionPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, + parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('heading', models.CharField( + blank=True, help_text='An optional heading for the Section', max_length=100, null=True)), + ('content', djangocms_text_ckeditor.fields.HTMLField()), + ('text_direction', models.CharField(choices=[ + ('left', 'Left'), ('right', 'Right')], default=True, help_text='The alignment of text in the section', max_length=10)), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLNavbarDropdownPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, + parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('text', models.CharField( + help_text='Text for the dropdown toggle', max_length=50)), + ('target', models.URLField( + blank=True, help_text='Optional Url or #id to navigate on click', max_length=100, null=True)), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLContactPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, + parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('heading', models.CharField( + blank=True, default='Contact', max_length=100)), + ('organization_name', models.CharField( + blank=True, default='ungleich GmbH', max_length=100)), + ('email', models.EmailField( + default='info@ungleich.ch', max_length=200)), + ('address', models.CharField(blank=True, + default='In der Au 7, Schwanden 8762', max_length=100)), + ('country', models.CharField(blank=True, + default='Switzerland', max_length=100)), + ('form_header', models.CharField(blank=True, + default='Send us a message.', max_length=100)), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLFooterPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, + parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('copyright_label', models.CharField(blank=True, default='ungleich GmbH', + help_text='Name of the company alongside the copyright year', max_length=100)), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLLinkPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, + parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('target', models.CharField( + help_text='Url or #id to navigate to', max_length=100)), + ('text', models.CharField( + help_text='Text for the menu item', max_length=50)), + ('title', models.CharField( + blank=True, help_text='Optional title text, that will be shown when a user hovers over the link', max_length=100, null=True)), + ('separator', models.BooleanField(default=False, + help_text='Select to include a separator after the previous link')), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLSectionIconPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, + parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('fontawesome_icon_name', models.CharField( + help_text='Name of the fontawesome icon to use. Refer docs.', max_length=30)), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLSectionImagePluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, + parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('caption', models.CharField( + blank=True, help_text='Optional caption for the image.', max_length=100, null=True)), + ('image', filer.fields.image.FilerImageField(help_text='Image file to be used in section. Add multiple plugins to add more than one image', + on_delete=django.db.models.deletion.CASCADE, to='filer.Image')), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + ] diff --git a/datacenterlight/models.py b/datacenterlight/models.py index 2fbed5c8..6fcf24a9 100644 --- a/datacenterlight/models.py +++ b/datacenterlight/models.py @@ -29,3 +29,6 @@ class ContactUs(models.Model): email = models.CharField(max_length=250) message = models.TextField() field = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.name diff --git a/datacenterlight/static/datacenterlight/css/header-slider.css b/datacenterlight/static/datacenterlight/css/header-slider.css new file mode 100644 index 00000000..0aeaecd8 --- /dev/null +++ b/datacenterlight/static/datacenterlight/css/header-slider.css @@ -0,0 +1,164 @@ +.header_slider > .carousel .carousel-inner { + min-height: 95vh; + display: flex; +} + +.header_slider > .carousel .carousel-inner > .next, +.header_slider > .carousel .carousel-inner > .prev { + bottom: 0; +} + +.header_slider .carousel-indicators { + width: 100%; + left: 0; + margin-left: 0; +} + +.header_slider .carousel-indicators li { + margin-right: 25px; + width: 16px; + height: 16px; +} + +.header_slider .carousel-indicators li.active { + background-color: #ffffff; +} + +.header_slider .carousel-control { + display: none; +} + +.header_slider .carousel-control .fa { + font-size: 2em; + position: absolute; + top: 50%; + margin-top: -50px; +} + +.header_slider > .carousel .item { + background: rgba(0,0,0,0.5); + flex: 1; +} + +.header_slider > .carousel .item .container { + overflow: auto; + padding: 50px 20px 60px; + height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-end; + /* background: rgba(0,0,0,0.5); */ +} + +.header_slider .intro-cap { + margin: 0; + text-align: right; + line-height: 1.1; + font-size: 23px; + padding-bottom: 10px; + color: #fff; +} + +.header_slider .btn-trans { + align-self: flex-end; + z-index: 2; + position: relative; +} + +@media (min-width: 768px) { + .header_slider .intro-cap { + font-size: 2.5em; + } + .header_slider .carousel-control { + width: 50px; + display: block; + } + .header_slider .carousel-control .fa-angle-left { + left: 25px; + } + .header_slider .carousel-control .fa-angle-right { + right: 25px; + } + .header_slider .carousel-control .fa { + font-size: 4em; + } + .header_slider > .carousel .item .container { + overflow: auto; + padding: 75px 50px; + } + .header_slider .btn-trans { + padding: 8px 15px; + min-width: 175px; + letter-spacing: 1px; + font-size: 1.25em; + } +} + +@media (min-width: 992px) { + .header_slider .intro-cap { + font-size: 3.25em; + } +} + +.header_slider .intro_lead { + color: #fff; + font-size: 1.55em; + text-align: right; + line-height: 1.4; + margin-bottom: 0; + padding-bottom: 10px; +} + +@media (max-width: 768px) { + .header_slider .intro_lead { + font-size: 1.1em; + margin-bottom: 15px; + } + + .header_slider .carousel-indicators li { + margin: 1px 25px; + width: 16px; + height: 16px; + } + .header_slider .carousel-indicators li.active { + margin: 0 25px; + width: 18px; + height: 18px; + } +} + +.bg_img { + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 100%; + background-size: cover; + background-position: center; +} + +.bg_vid { + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 100%; + background-size: cover; + background-position: center; +} + +@media (min-aspect-ratio: 16/9) { + .bg_vid > video { + width: 100%; + height: auto; + } +} + +@media (max-aspect-ratio: 16/9) { + .bg_vid > video { + /* width: auto; */ + height: 100%; + } +} diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index 9c8b4acf..35d9d65d 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -19,17 +19,6 @@ textarea { * blue dark #29427A */ - -.lead { - font-size: 18px; -} - -@media (min-width: 768px) { - .lead-right { - text-align: right; - } -} - .btn { box-shadow: 0 1px 4px rgba(0, 0, 0, .6); } @@ -102,14 +91,32 @@ textarea { color: #fff; } -.navbar-transparent .navbar-nav>li>a { +.navbar-transparent .navbar-nav>li a { color: #fff; } -.navbar-transparent .navbar-nav>li>a:focus, -.navbar-transparent .navbar-nav>li>a:hover { +.navbar-transparent .navbar-nav>li a:focus, +.navbar-transparent .navbar-nav>li a:active, +.navbar-transparent .navbar-nav>li a:hover { color: #fff; background-color: transparent; + text-decoration: none; +} + +.navbar .dcl-link { + display: block; + padding: 15px; + color: #777; +} + +.navbar .dcl-link:focus, +.navbar .dcl-link:active, +.navbar .dcl-link:hover { + text-decoration: none; +} + +.navbar .dropdown-menu .dcl-link { + padding: 1px 10px; } .navbar-transparent .navbar-nav>li>.on-hover-border { @@ -195,8 +202,8 @@ textarea { margin-left: 15px; } -.dropdown-menu>li>a:focus, -.dropdown-menu>li>a:hover { +.dropdown-menu>li a:focus, +.dropdown-menu>li a:hover { background: transparent; text-decoration: underline !important; } @@ -354,11 +361,6 @@ textarea { font-weight: 300 !important; } -.new-lead { - font-weight: 300 !important; - font-size: 21px !important; -} - .split-section .split-text .split-title { position: relative; margin-bottom: 25px; @@ -394,46 +396,49 @@ textarea { text-align: left; } -.split-section.right .split-text { - text-align: right; -} - -.split-section.right .split-text ul { - text-align: left; -} - +.split-section.right .split-text ul, .split-section.left .split-text { text-align: left; } -.split-section.right .split-text .split-title h2 { +.split-section.right .split-text { text-align: right; } -.split-section.left .split-text .split-title h2 { - text-align: left; -} - -.split-section.right .split-text .split-title::before { +.split-section .split-text .split-title::before { content: ""; position: absolute; bottom: 0; background: #29427A; height: 7px; width: 70px; + left: auto; +} + +.split-section.right .split-text .split-title::before { right: 0; } .split-section.left .split-text .split-title::before { - content: ""; - position: absolute; - bottom: 0; - background: #29427A; - height: 7px; - width: 70px; left: 0; } +.section-figure { + display: flex; + flex-wrap: wrap; +} + +.section-figure .cms-plugin { + padding: 10px; + flex-basis: 50%; +} + +@media (max-width: 420px) { + .section-figure .cms-plugin { + flex-basis: 100%; + } +} + .pricing-section { padding: 80px 0 !important; background: -webkit-linear-gradient(top, #f0f4f7, #fff) no-repeat; @@ -461,8 +466,6 @@ textarea { padding: 15px 40px; } -.pricing-section .card .title h3 {} - .pricing-section .card .price { background: #5A74AF; padding: 22px; @@ -792,43 +795,11 @@ tech-sub-sec h2 { /*Pricing page*/ .price-calc-section { - padding: 80px 40px !important; - background: -webkit-linear-gradient(top, #f0f4f7, #fff) no-repeat; - background: linear-gradient(to bottom, #f0f4f7, #fff) no-repeat; display: flex; } -.price-calc-section .text { - width: 50%; -} - -.price-calc-section .text .section-heading { - font-size: 48px; - line-height: 48px; - padding-bottom: 27px; - color: #3a3a3a; - letter-spacing: 1px; - position: relative; - text-align: right; -} - -.price-calc-section .text .description { - font-size: 20px; - text-align: right; -} - -.price-calc-section .text .section-heading::before { - content: ""; - position: absolute; - bottom: 0; - background: #29427A; - height: 7px; - width: 70px; - right: 0; -} - .price-calc-section .card { - width: 50%; + width: 100%; margin: 0 auto; background: #fff; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); @@ -839,21 +810,6 @@ tech-sub-sec h2 { position: relative; } -.price-calc-section .landing { - width: 100% !important; -} - -.no-padding { - padding: 0 !important; -} - -.price-calc-section .card .img-beta { - position: absolute; - top: 5px; - width: 60px; - left: 3px; -} - .price-calc-section .card .title { padding: 15px 40px; } @@ -950,8 +906,6 @@ tech-sub-sec h2 { } - - /*Changed class****.price-calc-section .card .description.input input*/ .price-calc-section .card .description input { @@ -1009,14 +963,17 @@ tech-sub-sec h2 { } @media(max-width:991px) { - .pricing-section .text { - text-align: center; + .pricing-section .split-text { + text-align: center !important; margin-bottom: 40px; } - .pricing-section .text .section-heading::before { - left: 50%; + .pricing-section .split-text .split-title::before { + left: 50% !important; transform: translate(-50%, 0); } + .pricing-section .split-description { + width: 100% !important; + } } @media(max-width:767px) { @@ -1139,7 +1096,7 @@ tech-sub-sec h2 { } .price-calc-section { flex-direction: column; - padding: 60px 10px !important; + /* padding: 60px 10px !important; */ } .price-calc-section .card { width: 90%; @@ -1210,11 +1167,6 @@ tech-sub-sec h2 { display: block; } -.content-section-a { - padding: 50px 0; - background-color: #f8f8f8; -} - .section-heading { margin-bottom: 30px; } @@ -1279,4 +1231,23 @@ footer { border-width: 0 3px 3px 0; /*Rotate the L 45 degrees to turn it into a checkmark*/ transform: rotate(45deg); +} + +footer .dcl-link-separator { + position: relative; + padding-left: 10px; +} + +footer .dcl-link-separator::before { + content: ""; + position: absolute; + display: inline-block; + top: 8px; + bottom: 0; + left: -3px; + right: 0; + width: 4px; + height: 4px; + border-radius: 100%; + background: #777; } \ No newline at end of file diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js index d5deaa21..10412824 100644 --- a/datacenterlight/static/datacenterlight/js/main.js +++ b/datacenterlight/static/datacenterlight/js/main.js @@ -54,7 +54,7 @@ Nav panel classic --------------------------------------------- */ if (window.matchMedia("(min-width: 767px)").matches) { - $('ul.nav li.dropdown').hover(function() { + $('ul.nav .dropdown').hover(function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500); }, function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500); diff --git a/datacenterlight/templates/datacenterlight/base.html b/datacenterlight/templates/datacenterlight/base.html index 15e66fc7..8bdfb65f 100644 --- a/datacenterlight/templates/datacenterlight/base.html +++ b/datacenterlight/templates/datacenterlight/base.html @@ -1,4 +1,4 @@ -{% load staticfiles i18n cms_tags sekizai_tags %} +{% load static i18n cms_tags sekizai_tags %} {% get_current_language as LANGUAGE_CODE %} @@ -22,6 +22,8 @@ {% block css_extra %} {% endblock css_extra %} + {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %} + {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %} diff --git a/datacenterlight/templates/datacenterlight/cms/base.html b/datacenterlight/templates/datacenterlight/cms/base.html new file mode 100644 index 00000000..1a2e7ae8 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/base.html @@ -0,0 +1,75 @@ +{% load static i18n cms_tags menu_tags sekizai_tags %} +{% get_current_language as LANGUAGE_CODE %} + + + + + + + + + + + {% page_attribute page_title %} + + + + + + + + + + + + {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %} + {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %} + + + + + + + + + + + + {% include "google_analytics.html" %} + + + + + {% cms_toolbar %} + + {% placeholder 'datacenterlight_navbar' %} + + {% placeholder 'Datacenterlight Header' or %} +
+
+

{% page_attribute page_title %}

+
+
+ {% endplaceholder %} + + {% placeholder 'datacenterlight_calculator' %} + + {% placeholder 'Datacenterlight Content' %} + + {% placeholder 'datacenterlight_footer'%} + + + + + + + + + + + + + diff --git a/datacenterlight/templates/datacenterlight/cms/calculator.html b/datacenterlight/templates/datacenterlight/cms/calculator.html new file mode 100644 index 00000000..64044a62 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/calculator.html @@ -0,0 +1,25 @@ +
+
+
+
+
+
+

{{ instance.heading }}

+
+
+
+ {{ instance.content }} +
+
+
+
+
+
+
+ {% include "datacenterlight/includes/_calculator_form.html" %} +
+
+
+
+
+
\ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/contact.html b/datacenterlight/templates/datacenterlight/cms/contact.html new file mode 100644 index 00000000..32919668 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/contact.html @@ -0,0 +1,35 @@ +{% load i18n %} + +
+
+
+
+
+
+

{{ instance.contact_text }}

+
+
+
+

{{ instance.organization_name }}

+
+
+

{{ instance.email }}

+

{{ instance.address }}

+

{{ instance.country }}

+
+
+ +
+
+
+ {% include "datacenterlight/contact_form.html" with form_header=instance.form_header %} +
+
+
+
+
+
\ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/footer.html b/datacenterlight/templates/datacenterlight/cms/footer.html new file mode 100644 index 00000000..2d92ff7e --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/footer.html @@ -0,0 +1,15 @@ +{% load i18n cms_tags %} +
+
+
    + {% for plugin in instance.child_plugin_instances %} +
  • + {% render_plugin plugin %} +
  • + {% endfor %} +
+ +
+
\ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/link.html b/datacenterlight/templates/datacenterlight/cms/link.html new file mode 100644 index 00000000..b3f398b2 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/link.html @@ -0,0 +1,5 @@ +{% load cms_tags %} + + + {{ instance.text }} + \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/navbar.html b/datacenterlight/templates/datacenterlight/cms/navbar.html new file mode 100644 index 00000000..30624525 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/navbar.html @@ -0,0 +1,64 @@ +{% load static i18n custom_tags cms_tags %} +{% get_current_language as LANGUAGE_CODE %} + + \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html b/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html new file mode 100644 index 00000000..1dbf5f28 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html @@ -0,0 +1,10 @@ +{% load cms_tags %} + + \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/section.html b/datacenterlight/templates/datacenterlight/cms/section.html new file mode 100644 index 00000000..b1a25004 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/section.html @@ -0,0 +1,27 @@ +{% load cms_tags %} + +
+
+
+
+
+ {% for plugin in instance.child_plugin_instances %} + {% render_plugin plugin %} + {% endfor %} +
+
+
+
+
+

{{ instance.heading }}

+
+
+
+ {{ instance.content }} +
+
+
+
+
+
+
\ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/section_icon.html b/datacenterlight/templates/datacenterlight/cms/section_icon.html new file mode 100644 index 00000000..c0d8feba --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/section_icon.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/cms/section_image.html b/datacenterlight/templates/datacenterlight/cms/section_image.html new file mode 100644 index 00000000..d8bd5e6e --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms/section_image.html @@ -0,0 +1,6 @@ +
+ image + {% if instance.caption %} +
{{ instance.caption }}
+ {% endif %} +
\ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/contact_form.html b/datacenterlight/templates/datacenterlight/contact_form.html index 7b57f227..87848ff2 100644 --- a/datacenterlight/templates/datacenterlight/contact_form.html +++ b/datacenterlight/templates/datacenterlight/contact_form.html @@ -13,7 +13,11 @@
-

{% trans "Get in touch with us!" %}

+ {% if form_header %} +

{{ form_header }}

+ {% else %} +

{% trans "Get in touch with us!" %}

+ {% endif %}
diff --git a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html index d1355245..1892c638 100644 --- a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html +++ b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html @@ -77,9 +77,6 @@ {% endfor %} - diff --git a/datacenterlight/templates/datacenterlight/includes/_footer.html b/datacenterlight/templates/datacenterlight/includes/_footer.html index 933755bf..828a5d19 100644 --- a/datacenterlight/templates/datacenterlight/includes/_footer.html +++ b/datacenterlight/templates/datacenterlight/includes/_footer.html @@ -1,5 +1,4 @@ {% load staticfiles i18n%} -{% get_current_language as LANGUAGE_CODE %}
diff --git a/datacenterlight/templates/datacenterlight/index.html b/datacenterlight/templates/datacenterlight/index.html index 749b94fd..fdd2c198 100755 --- a/datacenterlight/templates/datacenterlight/index.html +++ b/datacenterlight/templates/datacenterlight/index.html @@ -6,41 +6,31 @@
- -
-
- -
-

Data Center Light

-

{% trans "Finally, an affordable VM hosting in Switzerland!" %}

-
- -
-
+
+

Data Center Light

+

{% trans "Finally, an affordable VM hosting in Switzerland!" %}

+
+
-
- -
-
-
+
-
+

{% trans "Highlights" %}

@@ -65,90 +55,79 @@

{% trans "Cuts down the costs for you by using FOSS (Free Open Source Software) exclusively, wherefore we can save money from paying licenses." %}

-
- -
-
-
+

{% trans "Scale out" %}

{% trans "We don't use special hardware. We use commodity hardware: we buy computers that you buy. Just many more and put them in a cozy home for computers called data center." %}

-
-
+
- -
-
+
-
+
-
+

{% trans "Reliable and light" %}

{% trans "Our VMs are located in Switzerland, with reliable power supply and fast internet connection. Our VM costs less thanks to our featherlight infrastructure." %}

-
- -
- -
- +
- -
-
-

{% trans "Simple and affordable: Try our virtual machine with featherlight price." %}

-

{% blocktrans %}Ready in 30 seconds.
Experience the unbeatable speed from Data Center Light.{% endblocktrans %}

+
+
+
+
+

{% trans "Simple and affordable: Try our virtual machine with featherlight price." %}

+
+
+
+

{% blocktrans %}Ready in 30 seconds.
Experience the unbeatable speed from Data Center Light.{% endblocktrans %}

+
+
+
- -
-
+
+
-
{% include "datacenterlight/includes/_calculator_form.html" %} -
-
-
-
@@ -179,10 +158,8 @@
-
-
{% endblock %} diff --git a/datacenterlight/templates/datacenterlight/whydatacenterlight.html b/datacenterlight/templates/datacenterlight/whydatacenterlight.html index 79a7bd2d..bd1b6ceb 100644 --- a/datacenterlight/templates/datacenterlight/whydatacenterlight.html +++ b/datacenterlight/templates/datacenterlight/whydatacenterlight.html @@ -5,147 +5,146 @@
-
-
-
-
-

{% trans "Why Data Center Light?" %}

-
-
+
+
+

{% trans "Why Data Center Light?" %}

+
-
+
-
-
-
-
-
-

{% trans "Tech Stack" %}

-
-
-

{% trans "We are seriously open source." %}

-

{% blocktrans %} Our full software stack is open source – We don't use anything that isn't open source.
Yes, we are that cool. {% endblocktrans %}

-
-
-
-
-
- Devuan - {% trans "Our services run on" %} -
-
- Prometheus - {% trans "Our monitoring" %} -
-
- Ceph - {% trans "Our storage layer" %} -
-
- Django - {% trans "Our web frontend" %} -
-
- Opennebula - {% trans "Our cloud" %} -
-
- Cdist by ungleich - {% trans "Our configuration management system" %} -
-
- Python - {% trans "Our awesome juice" %} -
-
- Tayga - {% trans "Our NAT64 gateway" %} -
- -
-
-
-
- -
-
-
-
-
-
- Opennebula -
-
- Cdist byu ngleich -
-
- Prometheus -
-
-
-
-

{% trans "We believe in giving back to the FOSS community." %}

-

{% blocktrans %}Data Center Light is the child of free and open source software (FOSS) movement.
We grew up with it, live by it, and believe in it.
The more we work on our data center,
the more we contribute back to the FOSS community.{% endblocktrans %}

-
-
-
-
-
- -
-
-
-
-

{% trans "We bring the future to you." %}

-
-
-
- 100% IPv6 -
-
-

{% blocktrans %}Data Center Light uses the most modern technologies out there.
Your VM needs only IPv6. Data Center Light provides
transparent two-way IPv6/IPv4 translation.{% endblocktrans %}

-
-
-
-
- 100% SSD SSD -
-
-

{% blocktrans %} No more spinning metal plates! Data Center Light uses only SSDs. We keep things faster and lighter. {% endblocktrans %}

-
-
-
-
- -
- -
- -
- -
-
-

{% trans "Starting from only 15CHF per month. Try now." %}

-

{% trans "Actions speak louder than words. Let's do it, try our VM now." %}

-
- -
-
-
-
- {% include "datacenterlight/includes/_calculator_form.html" %} +
+
+
+
+
+

{% trans "Tech Stack" %}

+
+
+

{% trans "We are seriously open source." %}

+

{% blocktrans %} Our full software stack is open source – We don't use anything that isn't open source.
Yes, we are that cool. {% endblocktrans %}

+
+
+ Devuan + {% trans "Our services run on" %} +
+
+ Prometheus + {% trans "Our monitoring" %} +
+
+ Ceph + {% trans "Our storage layer" %} +
+
+ Django + {% trans "Our web frontend" %} +
+
+ Opennebula + {% trans "Our cloud" %} +
+
+ Cdist by ungleich + {% trans "Our configuration management system" %} +
+
+ Python + {% trans "Our awesome juice" %} +
+
+ Tayga + {% trans "Our NAT64 gateway" %} +
+
+
+
+
+
+ +
+
+
+
+
+
+ Opennebula +
+
+ Cdist byu ngleich +
+
+ Prometheus +
+
+
+
+
+

{% trans "We believe in giving back to the FOSS community." %}

+

{% blocktrans %}Data Center Light is the child of free and open source software (FOSS) movement.
We grew up with it, live by it, and believe in it.
The more we work on our data center,
the more we contribute back to the FOSS community.{% endblocktrans %}

+
+
+
+
+
+ +
+ +
+
+
+

{% trans "We bring the future to you." %}

+
+
+
+ 100% IPv6 +
+
+

{% blocktrans %}Data Center Light uses the most modern technologies out there.
Your VM needs only IPv6. Data Center Light provides
transparent two-way IPv6/IPv4 translation.{% endblocktrans %}

+
+
+
+
+ 100% SSD SSD +
+
+

{% blocktrans %} No more spinning metal plates! Data Center Light uses only SSDs. We keep things faster and lighter. {% endblocktrans %}

+
+
+
+
+
+ +
+
+
+
+
+
+

{% trans "Starting from only 15CHF per month. Try now." %}

+
+
+
+

{% trans "Actions speak louder than words. Let's do it, try our VM now." %}

+
+
+
+
+
+
+
+ {% include "datacenterlight/includes/_calculator_form.html" %} +
+
-
- {% endblock %} diff --git a/datacenterlight/views.py b/datacenterlight/views.py index d3bdcec6..c67b436a 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -490,9 +490,11 @@ class OrderConfirmationView(DetailView): response = { 'status': True, - 'redirect': reverse( - 'hosting:virtual_machines') if request.user.is_authenticated() else reverse( - 'datacenterlight:index'), + 'redirect': ( + reverse('hosting:virtual_machines') + if request.user.is_authenticated() + else reverse('datacenterlight:index') + ), 'msg_title': str(_('Thank you for the order.')), 'msg_body': str( _('Your VM will be up and running in a few moments.' diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index 5027afef..e3ecf21a 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -227,7 +227,7 @@ CMS_TEMPLATES = ( ('blog_ungleich.html', gettext('Blog')), ('page.html', gettext('Page')), # dcl - ('datacenterlight/cms_page.html', gettext('Data Center Light')), + ('datacenterlight/cms/base.html', gettext('Data Center Light')), ('ungleich_page/glasfaser_cms_page.html', gettext('Glasfaser')), ('ungleich_page/ungleich_cms_page.html', gettext('ungleich')), ) @@ -332,9 +332,41 @@ CMS_PLACEHOLDER_CONF = { }, ] }, + 'datacenterlight_navbar': { + 'name': _('Datacenterlight Navbar'), + 'plugins': ['DCLNavbarPlugin'], + 'default_plugins': [ + { + 'plugin_type': 'DCLNavbarPlugin', + 'values': {}, + }, + ] + }, + 'datacenterlight_footer': { + 'name': _('Datacenterlight Footer'), + 'plugins': ['DCLFooterPlugin'], + 'default_plugins': [ + { + 'plugin_type': 'DCLFooterPlugin', + 'values': {}, + }, + ] + }, + 'datacenterlight_calculator': { + 'name': _('Datacenterlight Calculator'), + 'default_plugins': [ + { + 'plugin_type': 'DCLCalculatorPlugin', + 'values': { + 'heading': 'Heading', + 'content': 'Text' + }, + }, + ] + }, } -CMS_PERMISSION=True +CMS_PERMISSION = True CACHES = { 'default': { @@ -522,14 +554,14 @@ if UNGLEICH_SITE_CONFIGS == "": raise Exception("Please define UNGLEICH_SITE_CONFIGS in your .env") else: try: - configs_dict=json.loads(UNGLEICH_SITE_CONFIGS) + configs_dict = json.loads(UNGLEICH_SITE_CONFIGS) except ValueError as verr: raise Exception("UNGLEICH_SITE_CONFIGS is not a valid JSON: {}".format( str(verr) )) else: MULTISITE_CMS_URLS = { - k:v['MULTISITE_CMS_URL'] for (k,v) in configs_dict.items() + k: v['MULTISITE_CMS_URL'] for (k, v) in configs_dict.items() } MULTISITE_CMS_ALIASES = { @@ -611,7 +643,7 @@ DCL_ERROR_EMAILS_TO_LIST = [] if DCL_ERROR_EMAILS_TO is not None: DCL_ERROR_EMAILS_TO_LIST = [x.strip() for x in DCL_ERROR_EMAILS_TO.split( - ',')] \ + ',')] \ if "," in DCL_ERROR_EMAILS_TO else [DCL_ERROR_EMAILS_TO.strip()] if 'info@ungleich.ch' not in DCL_ERROR_EMAILS_TO_LIST: From 3cd89e244e80bd99a37b1fafac00ffca1643bc70 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 28 Feb 2018 04:22:48 +0530 Subject: [PATCH 0108/1032] minor style fixes --- .../static/datacenterlight/css/landing-page.css | 12 ++++++++---- .../templates/datacenterlight/cms/calculator.html | 2 +- datacenterlight/templates/datacenterlight/index.html | 2 +- .../datacenterlight/whydatacenterlight.html | 2 +- dynamicweb/settings/base.py | 7 +++---- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index 35d9d65d..b970cff4 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -430,12 +430,12 @@ textarea { .section-figure .cms-plugin { padding: 10px; - flex-basis: 50%; + flex-basis: 50%; } @media (max-width: 420px) { .section-figure .cms-plugin { - flex-basis: 100%; + flex-basis: 100%; } } @@ -1249,5 +1249,9 @@ footer .dcl-link-separator::before { width: 4px; height: 4px; border-radius: 100%; - background: #777; -} \ No newline at end of file + background: #777; +} + +.whydcl-header .container { + position: relative; +} diff --git a/datacenterlight/templates/datacenterlight/cms/calculator.html b/datacenterlight/templates/datacenterlight/cms/calculator.html index 64044a62..e4522ffe 100644 --- a/datacenterlight/templates/datacenterlight/cms/calculator.html +++ b/datacenterlight/templates/datacenterlight/cms/calculator.html @@ -15,7 +15,7 @@
-
+
{% include "datacenterlight/includes/_calculator_form.html" %}
diff --git a/datacenterlight/templates/datacenterlight/index.html b/datacenterlight/templates/datacenterlight/index.html index fdd2c198..eaed0162 100755 --- a/datacenterlight/templates/datacenterlight/index.html +++ b/datacenterlight/templates/datacenterlight/index.html @@ -119,7 +119,7 @@
-
+
{% include "datacenterlight/includes/_calculator_form.html" %}
diff --git a/datacenterlight/templates/datacenterlight/whydatacenterlight.html b/datacenterlight/templates/datacenterlight/whydatacenterlight.html index bd1b6ceb..ee882e4f 100644 --- a/datacenterlight/templates/datacenterlight/whydatacenterlight.html +++ b/datacenterlight/templates/datacenterlight/whydatacenterlight.html @@ -138,7 +138,7 @@
-
+
{% include "datacenterlight/includes/_calculator_form.html" %}
diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index e3ecf21a..2c4083af 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -641,10 +641,9 @@ DCL_ERROR_EMAILS_TO = env('DCL_ERROR_EMAILS_TO') DCL_ERROR_EMAILS_TO_LIST = [] if DCL_ERROR_EMAILS_TO is not None: - DCL_ERROR_EMAILS_TO_LIST = [x.strip() for x in - DCL_ERROR_EMAILS_TO.split( - ',')] \ - if "," in DCL_ERROR_EMAILS_TO else [DCL_ERROR_EMAILS_TO.strip()] + DCL_ERROR_EMAILS_TO_LIST = [ + x.strip() for x in DCL_ERROR_EMAILS_TO.split(',') + ] if "," in DCL_ERROR_EMAILS_TO else [DCL_ERROR_EMAILS_TO.strip()] if 'info@ungleich.ch' not in DCL_ERROR_EMAILS_TO_LIST: DCL_ERROR_EMAILS_TO_LIST.append('info@ungleich.ch') From cca555e681a5944957b08934a86a6581e848b795 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 28 Feb 2018 04:27:32 +0530 Subject: [PATCH 0109/1032] navbar dropdown style --- .../templates/datacenterlight/cms/navbar_dropdown.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html b/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html index 1dbf5f28..814e6be1 100644 --- a/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html +++ b/datacenterlight/templates/datacenterlight/cms/navbar_dropdown.html @@ -1,7 +1,7 @@ {% load cms_tags %} {% endplaceholder %} - {% placeholder 'datacenterlight_calculator' %} - - {% placeholder 'Datacenterlight Content' %} + {% placeholder 'datacenterlight_content' %} {% placeholder 'datacenterlight_footer'%} diff --git a/datacenterlight/templates/datacenterlight/cms/calculator.html b/datacenterlight/templates/datacenterlight/cms/calculator.html index e4522ffe..c2580fc7 100644 --- a/datacenterlight/templates/datacenterlight/cms/calculator.html +++ b/datacenterlight/templates/datacenterlight/cms/calculator.html @@ -1,9 +1,9 @@ -
+
-
+
-
+

{{ instance.heading }}

@@ -13,7 +13,7 @@
-
+
{% include "datacenterlight/includes/_calculator_form.html" %} diff --git a/datacenterlight/templates/datacenterlight/cms/section.html b/datacenterlight/templates/datacenterlight/cms/section.html index b1a25004..7743b5b9 100644 --- a/datacenterlight/templates/datacenterlight/cms/section.html +++ b/datacenterlight/templates/datacenterlight/cms/section.html @@ -1,18 +1,20 @@ {% load cms_tags %} -
+
-
- {% for plugin in instance.child_plugin_instances %} - {% render_plugin plugin %} - {% endfor %} -
+ {% block section-feature %} +
+ {% for plugin in instance.child_plugin_instances %} + {% render_plugin plugin %} + {% endfor %} +
+ {% endblock section-feature %}
-
+

{{ instance.heading }}

diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index 2c4083af..05811384 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -352,8 +352,8 @@ CMS_PLACEHOLDER_CONF = { }, ] }, - 'datacenterlight_calculator': { - 'name': _('Datacenterlight Calculator'), + 'datacenterlight_content': { + 'name': _('Datacenterlight Content'), 'default_plugins': [ { 'plugin_type': 'DCLCalculatorPlugin', diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index 24624f10..316b12ca 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -64,13 +64,6 @@ padding: 0 !important; } -.price-calc-section .card .img-beta { - position: absolute; - top: 5px; - width: 60px; - left: 3px; -} - .price-calc-section .card .title { padding: 15px 40px; } From a895f7caa7693195f6bdff7b3af54e48ade78e22 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 2 Mar 2018 02:13:20 +0530 Subject: [PATCH 0116/1032] squashed migrations --- .../0012_dclcalculatorpluginmodel.py | 109 +++++++++--------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py b/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py index 5b9bab61..0f7f3a53 100644 --- a/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py +++ b/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.4 on 2018-02-27 22:29 +# Generated by Django 1.9.4 on 2018-03-01 20:41 from __future__ import unicode_literals from django.db import migrations, models @@ -12,20 +12,21 @@ class Migration(migrations.Migration): dependencies = [ ('cms', '0014_auto_20160404_1908'), - ('datacenterlight', '0011_auto_20180220_1423') + ('datacenterlight', '0011_auto_20180220_1423'), ] operations = [ migrations.CreateModel( name='DCLSectionPluginModel', fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, - parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), - ('heading', models.CharField( - blank=True, help_text='An optional heading for the Section', max_length=100, null=True)), + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('heading', models.CharField(blank=True, help_text='An optional heading for the Section', max_length=100, null=True)), ('content', djangocms_text_ckeditor.fields.HTMLField()), - ('text_direction', models.CharField(choices=[ - ('left', 'Left'), ('right', 'Right')], default=True, help_text='The alignment of text in the section', max_length=10)), + ('text_direction', models.CharField(choices=[('left', 'Left'), ('right', 'Right')], default=True, help_text='The alignment of text in the section', max_length=10)), + ('html_id', models.SlugField(blank=True, help_text='An optional html id for the Section. Required to set as target of a link on page', null=True)), + ('center_on_mobile', models.BooleanField(default=False, help_text='Select to center align content on small screens.')), + ('background_gradient', models.BooleanField(default=False, help_text='Select to add a gradient background to the section.')), + ('plain_heading', models.BooleanField(default=False, help_text='Select to keep the heading style simpler.')), ], options={ 'abstract': False, @@ -35,12 +36,9 @@ class Migration(migrations.Migration): migrations.CreateModel( name='DCLNavbarDropdownPluginModel', fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, - parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), - ('text', models.CharField( - help_text='Text for the dropdown toggle', max_length=50)), - ('target', models.URLField( - blank=True, help_text='Optional Url or #id to navigate on click', max_length=100, null=True)), + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('text', models.CharField(help_text='Text for the dropdown toggle', max_length=50)), + ('target', models.CharField(default='', help_text='Optional Url or #id to navigate on click', max_length=100)), ], options={ 'abstract': False, @@ -50,20 +48,13 @@ class Migration(migrations.Migration): migrations.CreateModel( name='DCLContactPluginModel', fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, - parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), - ('heading', models.CharField( - blank=True, default='Contact', max_length=100)), - ('organization_name', models.CharField( - blank=True, default='ungleich GmbH', max_length=100)), - ('email', models.EmailField( - default='info@ungleich.ch', max_length=200)), - ('address', models.CharField(blank=True, - default='In der Au 7, Schwanden 8762', max_length=100)), - ('country', models.CharField(blank=True, - default='Switzerland', max_length=100)), - ('form_header', models.CharField(blank=True, - default='Send us a message.', max_length=100)), + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('heading', models.CharField(blank=True, default='Contact', max_length=100)), + ('organization_name', models.CharField(blank=True, default='ungleich GmbH', max_length=100)), + ('email', models.EmailField(default='info@ungleich.ch', max_length=200)), + ('address', models.CharField(blank=True, default='In der Au 7, Schwanden 8762', max_length=100)), + ('country', models.CharField(blank=True, default='Switzerland', max_length=100)), + ('form_header', models.CharField(blank=True, default='Send us a message.', max_length=100)), ], options={ 'abstract': False, @@ -73,10 +64,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='DCLFooterPluginModel', fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, - parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), - ('copyright_label', models.CharField(blank=True, default='ungleich GmbH', - help_text='Name of the company alongside the copyright year', max_length=100)), + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('copyright_label', models.CharField(blank=True, default='ungleich GmbH', help_text='Name of the company alongside the copyright year', max_length=100)), ], options={ 'abstract': False, @@ -86,16 +75,11 @@ class Migration(migrations.Migration): migrations.CreateModel( name='DCLLinkPluginModel', fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, - parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), - ('target', models.CharField( - help_text='Url or #id to navigate to', max_length=100)), - ('text', models.CharField( - help_text='Text for the menu item', max_length=50)), - ('title', models.CharField( - blank=True, help_text='Optional title text, that will be shown when a user hovers over the link', max_length=100, null=True)), - ('separator', models.BooleanField(default=False, - help_text='Select to include a separator after the previous link')), + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('target', models.CharField(help_text='Url or #id to navigate to', max_length=100)), + ('text', models.CharField(help_text='Text for the menu item', max_length=50)), + ('title', models.CharField(blank=True, help_text='Optional title text, that will be shown when a user hovers over the link', max_length=100, null=True)), + ('separator', models.BooleanField(default=False, help_text='Select to include a separator after the previous link')), ], options={ 'abstract': False, @@ -105,10 +89,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='DCLSectionIconPluginModel', fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, - parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), - ('fontawesome_icon_name', models.CharField( - help_text='Name of the fontawesome icon to use. Refer docs.', max_length=30)), + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('fontawesome_icon_name', models.CharField(help_text='Name of the fontawesome icon to use. Refer docs.', max_length=30)), ], options={ 'abstract': False, @@ -118,12 +100,35 @@ class Migration(migrations.Migration): migrations.CreateModel( name='DCLSectionImagePluginModel', fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, - parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), - ('caption', models.CharField( - blank=True, help_text='Optional caption for the image.', max_length=100, null=True)), - ('image', filer.fields.image.FilerImageField(help_text='Image file to be used in section. Add multiple plugins to add more than one image', - on_delete=django.db.models.deletion.CASCADE, to='filer.Image')), + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('caption', models.CharField(blank=True, help_text='Optional caption for the image.', max_length=100, null=True)), + ('image', filer.fields.image.FilerImageField(help_text='Image file to be used in section. Add multiple plugins to add more than one image', on_delete=django.db.models.deletion.CASCADE, to='filer.Image')), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLBannerListPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('heading', models.CharField(blank=True, help_text='An optional heading for the Section', max_length=100, null=True)), + ('html_id', models.SlugField(blank=True, help_text='An optional html id for the Section. Required to set as target of a link on page', null=True)), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='DCLBannerItemPluginModel', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('content', djangocms_text_ckeditor.fields.HTMLField()), + ('banner_text', djangocms_text_ckeditor.fields.HTMLField(blank=True, help_text='Optional text to be shown as banner in other half.', max_length=100, null=True)), + ('text_direction', models.CharField(choices=[('left', 'Left'), ('right', 'Right')], default=True, help_text='The alignment of text in the section', max_length=10)), + ('banner_image', filer.fields.image.FilerImageField(blank=True, help_text='Optional image to be used in the banner in other half.', null=True, on_delete=django.db.models.deletion.CASCADE, to='filer.Image')), ], options={ 'abstract': False, From 8d5391782633caabc03d3a70da7b7435d2105f1e Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 3 Mar 2018 11:41:52 +0100 Subject: [PATCH 0117/1032] Update Changelog --- Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog b/Changelog index bdbe2806..28736552 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,5 @@ +Next: + * #3554: [dcl] Remove some more beta access resources (some were left in the earlier release) 1.4.1: 2018-02-23 * #3798: [dg] Redirect user to digital glarus on clicking logo in the email * #3554: [dcl] Remove beta access resources From 883118e0503c630483265f2b4e40fed1123994bd Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Mon, 5 Mar 2018 18:41:13 +0530 Subject: [PATCH 0118/1032] whydcl section style fix, footer style fix --- datacenterlight/cms_models.py | 2 + datacenterlight/cms_plugins.py | 8 ++++ .../static/datacenterlight/css/cms.css | 5 ++- .../datacenterlight/css/landing-page.css | 28 +++++++++--- .../datacenterlight/cms/section.html | 30 ++++++------- .../includes/_calculator_form.html | 2 +- datacenterlight/views.py | 44 +++++++++++-------- 7 files changed, 76 insertions(+), 43 deletions(-) diff --git a/datacenterlight/cms_models.py b/datacenterlight/cms_models.py index 8438e515..a4406c04 100644 --- a/datacenterlight/cms_models.py +++ b/datacenterlight/cms_models.py @@ -47,6 +47,8 @@ class DCLSectionPluginModel(CMSPlugin): extra_classes += ' section-sm-center' if self.background_gradient: extra_classes += ' section-gradient' + if self.plain_heading: + extra_classes += ' split-section-plain' return extra_classes def __str__(self): diff --git a/datacenterlight/cms_plugins.py b/datacenterlight/cms_plugins.py index c3f2fb10..70ecfaa2 100644 --- a/datacenterlight/cms_plugins.py +++ b/datacenterlight/cms_plugins.py @@ -8,6 +8,7 @@ from .cms_models import ( DCLSectionIconPluginModel, DCLSectionImagePluginModel, DCLSectionPluginModel, ) +from .models import VMTemplate @plugin_pool.register_plugin @@ -49,6 +50,13 @@ class DCLCalculatorPlugin(CMSPluginBase): render_template = "datacenterlight/cms/calculator.html" cache = False + def render(self, context, instance, placeholder): + context = super(DCLCalculatorPlugin, self).render( + context, instance, placeholder + ) + context['templates'] = VMTemplate.objects.all() + return context + @plugin_pool.register_plugin class DCLBannerListPlugin(CMSPluginBase): diff --git a/datacenterlight/static/datacenterlight/css/cms.css b/datacenterlight/static/datacenterlight/css/cms.css index 87479a1e..d36a7876 100644 --- a/datacenterlight/static/datacenterlight/css/cms.css +++ b/datacenterlight/static/datacenterlight/css/cms.css @@ -52,7 +52,10 @@ /* only for editing mode */ .section-figure .cms-plugin { - padding: 10px; flex-basis: 50%; flex-grow: 1; +} + +.split-section-plain .section-figure .cms-plugin { + flex-grow: 0; } \ No newline at end of file diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index 66ca4806..90d959a3 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -436,11 +436,29 @@ textarea { } .section-figure .section-image { - padding: 10px; + padding: 25px 15px; flex-basis: 50%; flex-grow: 1; } +.split-section-plain .section-figure .section-image { + flex-grow: 0; +} + +.split-section-plain .section-figure { + justify-content: flex-start; +} + +@media (min-width: 768px) { + .split-section-plain .split-figure { + width: 41.66666667%; + } + + .split-section-plain .split-text { + width: 58.33333333%; + } +} + .section-image img { margin: auto; } @@ -1236,12 +1254,12 @@ footer .dcl-link-separator::before { content: ""; position: absolute; display: inline-block; - top: 8px; + top: 9px; bottom: 0; - left: -3px; + left: -2px; right: 0; - width: 4px; - height: 4px; + width: 2px; + height: 2px; border-radius: 100%; background: #777; } diff --git a/datacenterlight/templates/datacenterlight/cms/section.html b/datacenterlight/templates/datacenterlight/cms/section.html index 7743b5b9..ed399ebc 100644 --- a/datacenterlight/templates/datacenterlight/cms/section.html +++ b/datacenterlight/templates/datacenterlight/cms/section.html @@ -3,24 +3,20 @@
-
- {% block section-feature %} -
- {% for plugin in instance.child_plugin_instances %} - {% render_plugin plugin %} - {% endfor %} -
- {% endblock section-feature %} +
+
+ {% for plugin in instance.child_plugin_instances %} + {% render_plugin plugin %} + {% endfor %} +
-
-
-
-

{{ instance.heading }}

-
-
-
- {{ instance.content }} -
+
+
+

{{ instance.heading }}

+
+
+
+ {{ instance.content }}
diff --git a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html index 1892c638..f38150bb 100644 --- a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html +++ b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html @@ -1,5 +1,5 @@ {% load staticfiles i18n%} -
+ {% csrf_token %}

{% trans "VM hosting" %}

diff --git a/datacenterlight/views.py b/datacenterlight/views.py index c67b436a..faa1d59c 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -112,37 +112,41 @@ class IndexView(CreateView): storage_field = forms.IntegerField(validators=[self.validate_storage]) template_id = int(request.POST.get('config')) template = VMTemplate.objects.filter( - opennebula_vm_template_id=template_id).first() + opennebula_vm_template_id=template_id + ).first() template_data = VMTemplateSerializer(template).data + referer_url = request.META['HTTP_REFERER'] try: cores = cores_field.clean(cores) except ValidationError as err: msg = '{} : {}.'.format(cores, str(err)) - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='cores') - return HttpResponseRedirect( - reverse('datacenterlight:index') + "#order_form") + messages.add_message( + self.request, messages.ERROR, msg, extra_tags='cores' + ) + return HttpResponseRedirect(referer_url + "#order_form") try: memory = memory_field.clean(memory) except ValidationError as err: msg = '{} : {}.'.format(memory, str(err)) - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='memory') - return HttpResponseRedirect( - reverse('datacenterlight:index') + "#order_form") + messages.add_message( + self.request, messages.ERROR, msg, extra_tags='memory' + ) + return HttpResponseRedirect(referer_url + "#order_form") try: storage = storage_field.clean(storage) except ValidationError as err: msg = '{} : {}.'.format(storage, str(err)) - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='storage') - return HttpResponseRedirect( - reverse('datacenterlight:index') + "#order_form") - amount_to_be_charged = get_vm_price(cpu=cores, memory=memory, - disk_size=storage) + messages.add_message( + self.request, messages.ERROR, msg, extra_tags='storage' + ) + return HttpResponseRedirect(referer_url + "#order_form") + + amount_to_be_charged = get_vm_price( + cpu=cores, memory=memory, disk_size=storage + ) specs = { 'cpu': cores, 'memory': memory, @@ -161,8 +165,9 @@ class IndexView(CreateView): def get_context_data(self, **kwargs): context = super(IndexView, self).get_context_data(**kwargs) context.update({ - 'base_url': "{0}://{1}".format(self.request.scheme, - self.request.get_host()), + 'base_url': "{0}://{1}".format( + self.request.scheme, self.request.get_host() + ), 'contact_form': ContactForm }) return context @@ -231,8 +236,9 @@ class PaymentOrderView(FormView): def post(self, request, *args, **kwargs): if 'login_form' in request.POST: - login_form = HostingUserLoginForm(data=request.POST, - prefix='login_form') + login_form = HostingUserLoginForm( + data=request.POST, prefix='login_form' + ) if login_form.is_valid(): email = login_form.cleaned_data.get('email') password = login_form.cleaned_data.get('password') From 4c5912ebc00e6673f903d7a1300a5f02965cb5f6 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Mon, 5 Mar 2018 20:00:31 +0530 Subject: [PATCH 0119/1032] dropdown target fix --- datacenterlight/cms_models.py | 2 +- datacenterlight/migrations/0012_dclcalculatorpluginmodel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datacenterlight/cms_models.py b/datacenterlight/cms_models.py index a4406c04..20e39fde 100644 --- a/datacenterlight/cms_models.py +++ b/datacenterlight/cms_models.py @@ -122,7 +122,7 @@ class DCLLinkPluginModel(CMSPlugin): class DCLNavbarDropdownPluginModel(CMSPlugin): target = models.CharField( - max_length=100, + max_length=100, null=True, blank=True, help_text='Optional Url or #id to navigate on click' ) text = models.CharField( diff --git a/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py b/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py index 0f7f3a53..1aa492af 100644 --- a/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py +++ b/datacenterlight/migrations/0012_dclcalculatorpluginmodel.py @@ -38,7 +38,7 @@ class Migration(migrations.Migration): fields=[ ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), ('text', models.CharField(help_text='Text for the dropdown toggle', max_length=50)), - ('target', models.CharField(default='', help_text='Optional Url or #id to navigate on click', max_length=100)), + ('target', models.CharField(blank=True, help_text='Optional Url or #id to navigate on click', max_length=100, null=True)), ], options={ 'abstract': False, From b73d2529a24bd2a9f41df8b8b499a87fd72d9d38 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Mon, 5 Mar 2018 20:30:33 +0530 Subject: [PATCH 0120/1032] image padding increased --- datacenterlight/static/datacenterlight/css/landing-page.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index 90d959a3..cb84528e 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -436,7 +436,7 @@ textarea { } .section-figure .section-image { - padding: 25px 15px; + padding: 20px 40px 30px; flex-basis: 50%; flex-grow: 1; } From ff635cb7e2649921a6d6af486276488ab6da8f29 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Mon, 5 Mar 2018 20:48:30 +0530 Subject: [PATCH 0121/1032] plain section image padding fix --- datacenterlight/static/datacenterlight/css/landing-page.css | 1 + 1 file changed, 1 insertion(+) diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index cb84528e..c6708c76 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -443,6 +443,7 @@ textarea { .split-section-plain .section-figure .section-image { flex-grow: 0; + padding: 50px 15px 0; } .split-section-plain .section-figure { From 5ba5cb07aad384495e96569e057d231b794c6d8c Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Mon, 5 Mar 2018 20:51:21 +0530 Subject: [PATCH 0122/1032] banner list alignment fix --- datacenterlight/static/datacenterlight/css/landing-page.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index c6708c76..2bd6b8da 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -1211,7 +1211,7 @@ footer { } .flex-row .desc-text, .flex-row .percent-text { - max-width: 430px; + max-width: 380px; } .flex-row-rev .desc-text { max-width: 710px; From fefa5cd5a63d47c582e440d0fbdc146bb2db337f Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Tue, 6 Mar 2018 00:48:31 +0530 Subject: [PATCH 0123/1032] image caption alignment --- datacenterlight/static/datacenterlight/css/landing-page.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index 2bd6b8da..9c8379ea 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -439,6 +439,9 @@ textarea { padding: 20px 40px 30px; flex-basis: 50%; flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: space-between; } .split-section-plain .section-figure .section-image { From 69de26fa229762685ae3dae28ad47f3a1498afe7 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Tue, 6 Mar 2018 00:53:53 +0530 Subject: [PATCH 0124/1032] mobile image size fix --- datacenterlight/static/datacenterlight/css/landing-page.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index 9c8379ea..1bb9308d 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -444,6 +444,12 @@ textarea { justify-content: space-between; } +@media (max-width: 767px) { + .section-figure .section-image { + flex-basis: 100%; + } +} + .split-section-plain .section-figure .section-image { flex-grow: 0; padding: 50px 15px 0; From 77843dd2cb42940bf66f61737cfa97571b205f12 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Tue, 6 Mar 2018 03:23:14 +0530 Subject: [PATCH 0125/1032] header font-weight fix, unused code removed --- .../static/datacenterlight/css/cms.css | 60 ++----------- .../datacenterlight/css/header-slider.css | 7 ++ .../datacenterlight/css/landing-page.css | 88 ++++++++----------- .../templates/datacenterlight/cms/base.html | 6 +- .../templates/datacenterlight/cms_page.html | 4 +- .../datacenterlight/whydatacenterlight.html | 10 +-- .../templates/hosting/calculator_form.html | 9 -- 7 files changed, 61 insertions(+), 123 deletions(-) diff --git a/datacenterlight/static/datacenterlight/css/cms.css b/datacenterlight/static/datacenterlight/css/cms.css index d36a7876..46abf8d8 100644 --- a/datacenterlight/static/datacenterlight/css/cms.css +++ b/datacenterlight/static/datacenterlight/css/cms.css @@ -1,56 +1,4 @@ -.dcl-cms_page-full-width { - color: #fff; - text-align: center; - background-image: -ms-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -moz-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -o-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -webkit-gradient(linear, right top, left top, color-stop(50, #29427A), color-stop(100, #4F6699)); - background-image: -webkit-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: linear-gradient(to left, #29427A 50%, #4F6699 100%); -} - -.dcl-cms_page-header { - padding: 150px 0 150px 0; - text-align: center; - color: #f8f8f8; - background: url(../img/pattern.jpg) no-repeat center center; - background-size: cover; - position: relative; - background-attachment: fixed; -} - -.dcl-cms_page-header::before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background: rgba(90, 116, 175, 0.85); -} - -.dcl-cms_page-header .container { - position: relative; -} - -#dcl-cms_page-text { - background: #fff; -} - -#dcl-cms_page-text h3 { - font-size: 42px; - width: 70%; -} - -@media (max-width: 767px) { - #dcl-cms_page-text h3 { - font-size: 30px; - line-height: 40px; - width: 100%; - } -} - -/* only for editing mode */ +/* only for cms editing mode */ .section-figure .cms-plugin { flex-basis: 50%; flex-grow: 1; @@ -58,4 +6,10 @@ .split-section-plain .section-figure .cms-plugin { flex-grow: 0; +} + +@media (max-width: 767px) { + .section-figure .cms-plugin { + flex-basis: 100%; + } } \ No newline at end of file diff --git a/datacenterlight/static/datacenterlight/css/header-slider.css b/datacenterlight/static/datacenterlight/css/header-slider.css index 3c31adcf..9f5161d7 100644 --- a/datacenterlight/static/datacenterlight/css/header-slider.css +++ b/datacenterlight/static/datacenterlight/css/header-slider.css @@ -65,6 +65,13 @@ position: relative; } +@media (max-width: 767px) { + .header_slider .intro-cap, + .header_slider .intro_lead { + font-weight: 400; + } +} + @media (min-width: 768px) { .header_slider .intro-cap { font-size: 2.5em; diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index 1bb9308d..763867b2 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -244,6 +244,44 @@ textarea { padding: 5px 10px !important; } + +/* dcl header */ +.dcl-header { + padding: 150px 0 150px 0; + text-align: center; + color: #f8f8f8; + background: url(../img/pattern.jpg) no-repeat center center; + background-size: cover; + position: relative; + background-attachment: fixed; +} + +.dcl-header::before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: rgba(90, 116, 175, 0.85); +} + +.dcl-header .container { + position: relative; +} + +.dcl-header h1 { + font-size: 65px; + margin: 0; + padding: 0; +} + +@media(max-width:767px) { + .dcl-header h1 { + font-size: 50px; + } +} + .intro-header { min-height: 100vh; text-align: center; @@ -479,12 +517,6 @@ textarea { color: #999 !important; } -@media (max-width: 575px) { - .section-figure .cms-plugin { - flex-basis: 100%; - } -} - .price-calc-section .card { width: 350px; margin: 0 auto; @@ -685,43 +717,6 @@ textarea { /*Why DCL*/ -.full-whydcl-sec { - color: #fff; - text-align: center; - background-image: -ms-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -moz-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -o-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -webkit-gradient(linear, right top, left top, color-stop(50, #29427A), color-stop(100, #4F6699)); - background-image: -webkit-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: linear-gradient(to left, #29427A 50%, #4F6699 100%); -} - -.whydcl-header { - padding: 150px 0 150px 0; - text-align: center; - color: #f8f8f8; - background: url(../img/pattern.jpg) no-repeat center center; - background-size: cover; - position: relative; - background-attachment: fixed; -} - -.whydcl-header::before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background: rgba(90, 116, 175, 0.85); -} - -.single-heading h2 { - font-size: 65px; - margin: 0; - padding: 0; -} - #tech_stack { background: #fff; } @@ -994,9 +989,6 @@ tech-sub-sec h2 { } @media(max-width:767px) { - .single-heading h2 { - font-size: 50px; - } .logo-wrap { padding: 10px; } @@ -1274,10 +1266,6 @@ footer .dcl-link-separator::before { background: #777; } -.whydcl-header .container { - position: relative -} - /* new styles for whydcl section cms plugin (to replace older style) */ .banner-list { diff --git a/datacenterlight/templates/datacenterlight/cms/base.html b/datacenterlight/templates/datacenterlight/cms/base.html index 100ed883..a6123cc3 100644 --- a/datacenterlight/templates/datacenterlight/cms/base.html +++ b/datacenterlight/templates/datacenterlight/cms/base.html @@ -20,8 +20,10 @@ - + {% if request.toolbar.edit_mode %} + + {% endif %} {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %} {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %} @@ -48,7 +50,7 @@ {% placeholder 'datacenterlight_navbar' %} {% placeholder 'Datacenterlight Header' or %} -
+

{% page_attribute page_title %}

diff --git a/datacenterlight/templates/datacenterlight/cms_page.html b/datacenterlight/templates/datacenterlight/cms_page.html index b770773c..a6201b39 100644 --- a/datacenterlight/templates/datacenterlight/cms_page.html +++ b/datacenterlight/templates/datacenterlight/cms_page.html @@ -10,13 +10,13 @@ {% endblock %} {% block content %} -
+

{% page_attribute page_title %}

-
+
{% placeholder 'datacenterlight_cms_page_text' %} diff --git a/datacenterlight/templates/datacenterlight/whydatacenterlight.html b/datacenterlight/templates/datacenterlight/whydatacenterlight.html index ee882e4f..442ef405 100644 --- a/datacenterlight/templates/datacenterlight/whydatacenterlight.html +++ b/datacenterlight/templates/datacenterlight/whydatacenterlight.html @@ -3,13 +3,9 @@ {% block content %} -
-
-
-
-

{% trans "Why Data Center Light?" %}

-
-
+
+
+

{% trans "Why Data Center Light?" %}

diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html index 02bb36ea..0a7bc3e2 100644 --- a/hosting/templates/hosting/calculator_form.html +++ b/hosting/templates/hosting/calculator_form.html @@ -71,15 +71,6 @@ {% endfor %}
-
- {% for message in messages %} - {% if 'cores' in message.tags %} -
  • - {{ message|safe }} -
- {% endif %} - {% endfor %} -
From fc659cab9fcc4078aa7f0ffaa644647e43e96ee2 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 7 Mar 2018 19:22:13 +0530 Subject: [PATCH 0126/1032] number localization format for de set same as en --- dynamicweb/formats/__init__.py | 0 dynamicweb/formats/de/__init__.py | 0 dynamicweb/formats/de/formats.py | 2 ++ dynamicweb/settings/base.py | 19 ++++++++++--------- hosting/templates/hosting/orders.html | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 dynamicweb/formats/__init__.py create mode 100644 dynamicweb/formats/de/__init__.py create mode 100644 dynamicweb/formats/de/formats.py diff --git a/dynamicweb/formats/__init__.py b/dynamicweb/formats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/dynamicweb/formats/de/__init__.py b/dynamicweb/formats/de/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/dynamicweb/formats/de/formats.py b/dynamicweb/formats/de/formats.py new file mode 100644 index 00000000..c1f28af7 --- /dev/null +++ b/dynamicweb/formats/de/formats.py @@ -0,0 +1,2 @@ +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index 5027afef..11666ab7 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -255,6 +255,12 @@ USE_L10N = True USE_TZ = True +USE_THOUSAND_SEPARATOR = True + +FORMAT_MODULE_PATH = [ + 'dynamicweb.formats' +] + LANGUAGES = ( ('en-us', _('English')), ('de', _('Deutsch')), @@ -262,11 +268,6 @@ LANGUAGES = ( LANGUAGE_CODE = 'en-us' -LOCALE_PATHS = [ - - os.path.join(PROJECT_DIR, 'digitalglarus/locale'), -] - CMS_PLACEHOLDER_CONF = { 'logo_image': { 'name': 'Logo Image', @@ -334,7 +335,7 @@ CMS_PLACEHOLDER_CONF = { }, } -CMS_PERMISSION=True +CMS_PERMISSION = True CACHES = { 'default': { @@ -522,14 +523,14 @@ if UNGLEICH_SITE_CONFIGS == "": raise Exception("Please define UNGLEICH_SITE_CONFIGS in your .env") else: try: - configs_dict=json.loads(UNGLEICH_SITE_CONFIGS) + configs_dict = json.loads(UNGLEICH_SITE_CONFIGS) except ValueError as verr: raise Exception("UNGLEICH_SITE_CONFIGS is not a valid JSON: {}".format( str(verr) )) else: MULTISITE_CMS_URLS = { - k:v['MULTISITE_CMS_URL'] for (k,v) in configs_dict.items() + k: v['MULTISITE_CMS_URL'] for (k, v) in configs_dict.items() } MULTISITE_CMS_ALIASES = { @@ -611,7 +612,7 @@ DCL_ERROR_EMAILS_TO_LIST = [] if DCL_ERROR_EMAILS_TO is not None: DCL_ERROR_EMAILS_TO_LIST = [x.strip() for x in DCL_ERROR_EMAILS_TO.split( - ',')] \ + ',')] \ if "," in DCL_ERROR_EMAILS_TO else [DCL_ERROR_EMAILS_TO.strip()] if 'info@ungleich.ch' not in DCL_ERROR_EMAILS_TO_LIST: diff --git a/hosting/templates/hosting/orders.html b/hosting/templates/hosting/orders.html index d747979d..e0e85cfd 100644 --- a/hosting/templates/hosting/orders.html +++ b/hosting/templates/hosting/orders.html @@ -30,7 +30,7 @@ {{ order.id }} {{ order.created_at | date:"M d, Y H:i" }} - {{ order.price|unlocalize }} + {{ order.price }} {% trans 'See Invoice' %} From 82b8952595ef7d0b14254e9f446a5f57a3e2896e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 9 Mar 2018 03:35:50 +0530 Subject: [PATCH 0127/1032] removed unused tags from templated --- .../datacenterlight/cms/banner_list.html | 2 +- .../templates/datacenterlight/cms/base.html | 2 +- .../datacenterlight/cms/contact.html | 2 -- .../templates/datacenterlight/cms/link.html | 2 -- .../templates/datacenterlight/cms_page.html | 26 ------------------- .../datacenterlight/includes/_footer.html | 2 +- .../templates/hosting/calculator_form.html | 9 +++++++ 7 files changed, 12 insertions(+), 33 deletions(-) delete mode 100644 datacenterlight/templates/datacenterlight/cms_page.html diff --git a/datacenterlight/templates/datacenterlight/cms/banner_list.html b/datacenterlight/templates/datacenterlight/cms/banner_list.html index ed1a3d49..7ef1c1c5 100644 --- a/datacenterlight/templates/datacenterlight/cms/banner_list.html +++ b/datacenterlight/templates/datacenterlight/cms/banner_list.html @@ -1,4 +1,4 @@ -{% load static i18n cms_tags %} +{% load cms_tags %}
diff --git a/hosting/static/hosting/css/landing-page.css b/hosting/static/hosting/css/landing-page.css index 275292d5..d5236324 100644 --- a/hosting/static/hosting/css/landing-page.css +++ b/hosting/static/hosting/css/landing-page.css @@ -426,6 +426,7 @@ footer { right: 0; bottom: 0; left: 0; + font-weight: 300; } p.copyright { diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index 2a1e645c..9c1538db 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -63,7 +63,7 @@ {% if request.user.is_authenticated %}
- +
{% else %} diff --git a/hosting/templates/hosting/includes/_footer.html b/hosting/templates/hosting/includes/_footer.html index 24f4cea6..a74e529f 100644 --- a/hosting/templates/hosting/includes/_footer.html +++ b/hosting/templates/hosting/includes/_footer.html @@ -1,5 +1,5 @@ -{% load staticfiles %} {% load i18n %} +