From 07a464231d541203c9baef9dd0e13b95f79a60eb Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 14 Sep 2017 02:24:10 +0530 Subject: [PATCH 01/82] animation added to vm termination --- hosting/static/hosting/css/landing-page.css | 3 + .../static/hosting/css/virtual-machine.css | 33 ++++++++ hosting/static/hosting/img/ajax-loader.gif | Bin 0 -> 404 bytes .../hosting/js/virtual_machine_detail.js | 38 ++++++++- .../hosting/includes/_navbar_user.html | 5 -- .../hosting/virtual_machine_detail.html | 35 ++++---- hosting/urls.py | 2 + hosting/views.py | 76 +++++++++++------- 8 files changed, 141 insertions(+), 51 deletions(-) create mode 100644 hosting/static/hosting/img/ajax-loader.gif diff --git a/hosting/static/hosting/css/landing-page.css b/hosting/static/hosting/css/landing-page.css index 71b7a33d..9d067b3c 100644 --- a/hosting/static/hosting/css/landing-page.css +++ b/hosting/static/hosting/css/landing-page.css @@ -853,6 +853,9 @@ a.list-group-item-danger:focus, .panel-danger > .panel-heading { color: #eb4d5c; } +.alert-danger{ + background: rgba(235, 204, 209, 0.2); +} .has-error .form-control, .has-error .input-group-addon { color: #eb4d5c; diff --git a/hosting/static/hosting/css/virtual-machine.css b/hosting/static/hosting/css/virtual-machine.css index b4916da0..b6afe4ef 100644 --- a/hosting/static/hosting/css/virtual-machine.css +++ b/hosting/static/hosting/css/virtual-machine.css @@ -290,6 +290,11 @@ text-align: center; } +.vm-vmid .alert { + margin-top: 15px; + margin-bottom: -60px; +} + .vm-item-lg { font-size: 22px; margin-top: 5px; @@ -305,6 +310,10 @@ color: #e47f2f; } +.vm-color-failed { + color: #eb4d5c; +} + .vm-detail-item .value{ font-weight: 400; } @@ -627,4 +636,28 @@ left: auto; right: 8px; } +} + +.processing > .btn { + position: relative; + border-color: #eee; +} +.processing > .btn:hover, +.processing > .btn:focus, +.processing > .btn:active { + border-color: #eee; +} + +.processing > .btn:after { + content: ' '; + display: block; + position: absolute; + background-image: url('/static/hosting/img/ajax-loader.gif'); + background-repeat: no-repeat; + background-position: center; + background-color: #eee; + width: 100%; + top: 0; + height: 100%; + left: 0; } \ No newline at end of file diff --git a/hosting/static/hosting/img/ajax-loader.gif b/hosting/static/hosting/img/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..a7c3f2bacbe630950c16f53e3c27dd840f2e8622 GIT binary patch literal 404 zcmZ?wbhEHb)Mnsj_{hNU?%lhzw6s;LRsl)He^Smxsfi`2DGKG8B^e5dS&0=n`H3ld znR#jX42nNl7`PZ17!?0=`?-b$J39ur8tEA@GXjNlfS3VfAOn+8OCQJSX*X{)e?H13 zeJ||u>DC8kZ4r?R)6{G4&Dyt|CtcU`diyE8Uq?3owA-;j!N^AxXd>8TMr31bj{uEP z;7?56IIHFOnwrlu67PNQNtrQY{;7pt&RzvNJJ_?&Ze06Pg>MsMs)$s6#HZT6Q+}5p z&C*E<I=&ueA`^;<Acq+MO<XxEEBa3UBYrO7?UfHJdzM^TuwobAGVVjKeUi;OpPxMU z@@LSj8EZ_>81%TGdiiN4(8Lw%U?wsno9F=b>WnG7*rn?>{@R)9v%+M)yIi1FiTcrX vD}VECG@HG3ZvWp+k0+)$$G&~0?NxTdRajt8g3>tw(O*m=3=Gzwa03GXAUBr* literal 0 HcmV?d00001 diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 303f95ca..ce97d44e 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -2,7 +2,43 @@ $( document ).ready(function() { $('#confirm-cancel').on('click', '.btn-ok', function(e) { - $('#virtual_machine_cancel_form').trigger('submit'); + var url = $('#virtual_machine_cancel_form').attr('action'); + var $container = $('#terminate-VM'); + var $btn = $container.find('.btn'); + var text = $container.find('.vm-item-lg').text(); + var altText = $container.attr('data-alt'); + $container.find('.alert-danger').addClass('hide'); + $container.addClass('processing') + .find('.vm-item-lg').attr('class', '') + .addClass('vm-item-lg vm-color-failed') + .text(altText); + $btn.prop('disabled', true); + $('#confirm-cancel').modal('hide'); + $.post(url) + .done(function(data) { + console.log( "success" , data); + if (data.status == true) { + $container.addClass('terminate-success') + .find('.vm-item-lg').text(data.text); + $btn.remove(); + // window.location = data.redirect; + } + else { + $container.addClass('terminate-fail') + .find('.vm-item-lg').text(text); + $container.find('.btn').prop('disabled', false); + $container.find('.alert-danger').text(data.text).removeClass('hide'); + } + }) + .fail(function(data) { + $container.addClass('terminate-fail') + .find('.vm-item-lg').text(text); + $container.find('.btn').prop('disabled', false); + $container.find('.alert-danger').removeClass('hide'); + }) + .always(function(data) { + $container.removeClass('processing'); + }); }); var hash = window.location.hash; diff --git a/hosting/templates/hosting/includes/_navbar_user.html b/hosting/templates/hosting/includes/_navbar_user.html index d06477ca..37c01109 100644 --- a/hosting/templates/hosting/includes/_navbar_user.html +++ b/hosting/templates/hosting/includes/_navbar_user.html @@ -37,11 +37,6 @@ </li> <li> {% get_current_language as LANGUAGE_CODE %} - {% if LANGUAGE_CODE == 'en-us'%} - <a href="{% change_lang 'de' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> Deutsch</a> - {% else %} - <a href="{% change_lang 'en-us' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> English</a> - {% endif %} </li> </ul> </div> diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index 6243c309..a5c82e90 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -46,26 +46,33 @@ <div class="vm-vmid"> <div class="vm-item-subtitle">{% trans "Current Pricing" %}</div> <div class="vm-item-lg">{{virtual_machine.price|floatformat}} CHF/{% trans "Month" %}</div> - <a class="btn btn-vm-invoice" href="{% url 'hosting:orders' order.pk %}">{% trans "See Invoice" %}</a> + <a class="btn btn-vm-invoice" href="{% url 'hosting:orders' 2 %}">{% trans "See Invoice" %}</a> </div> </div> <div class="vm-detail-item"> <h2 class="vm-detail-title">{% trans "Status" %} <img src="{% static 'hosting/img/connected.svg' %}" class="un-icon"></h2> <div class="vm-vmid"> <div class="vm-item-subtitle">{% trans "Your VM is" %}</div> - {% if virtual_machine.state == 'PENDING' %} - <div class="vm-item-lg vm-color-pending">{% trans "Pending" %}</div> - {% elif virtual_machine.state == 'ACTIVE' %} - <div class="vm-item-lg vm-color-online">{% trans "Online" %}</div> - {% elif virtual_machine.state == 'FAILED'%} - <div class="vm-item-lg vm-color-failed">{% trans "Failed" %}</div> - {% endif %} - {% if not virtual_machine.status == 'canceled' %} - <form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}"> - {% csrf_token %} - </form> - <button data-href="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}" data-toggle="modal" data-target="#confirm-cancel" class="btn btn-vm-term">{% trans "Terminate VM" %}</button> - {% endif %} + <div id="terminate-VM" data-alt="{% trans 'Terminating' %}"> + {% if virtual_machine.state == 'PENDING' %} + <div class="vm-item-lg vm-color-pending">{% trans "Pending" %}</div> + {% elif virtual_machine.state == 'ACTIVE' %} + <div class="vm-item-lg vm-color-online">{% trans "Online" %}</div> + {% elif virtual_machine.state == 'FAILED'%} + <div class="vm-item-lg vm-color-failed">{% trans "Failed" %}</div> + {% else %} + <div class="vm-item-lg"></div> + {% endif %} + {% if not virtual_machine.status == 'canceled' %} + <form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' 2 %}"> + {% csrf_token %} + </form> + <button data-toggle="modal" data-target="#confirm-cancel" class="btn btn-vm-term">{% trans "Terminate VM" %}</button> + <div class="alert alert-danger hide"> + {% trans "Sorry, there was an unexpected error. Kindly retry." %} + </div> + {% endif %} + </div> </div> </div> </div> diff --git a/hosting/urls.py b/hosting/urls.py index 10e09dd0..c3b982cb 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -10,9 +10,11 @@ from .views import ( HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, SSHKeyChoiceView, DashboardView, SettingsView) +from django.views.generic import TemplateView urlpatterns = [ + url(r'test/?$', TemplateView.as_view(template_name='hosting/virtual_machine_detail.html')), url(r'index/?$', IndexView.as_view(), name='index'), url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'), diff --git a/hosting/views.py b/hosting/views.py index f7d6e414..df6e6100 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -1,4 +1,6 @@ import uuid +import json +from time import sleep from django.conf import settings from django.contrib import messages @@ -6,13 +8,12 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.tokens import default_token_generator from django.core.files.base import ContentFile from django.core.urlresolvers import reverse_lazy, reverse -from django.http import Http404 -from django.http import HttpResponseRedirect -from django.shortcuts import redirect -from django.shortcuts import render +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 ugettext_lazy as _ +from django.utils.translation import ugettext from django.views.generic import View, CreateView, FormView, ListView, \ DetailView, \ DeleteView, TemplateView, UpdateView @@ -711,7 +712,7 @@ class PaymentVMView(LoginRequiredMixin, FormView): request.get_host()), 'page_header': _( 'Your New VM %(vm_name)s at Data Center Light') % { - 'vm_name': vm.get('name')} + 'vm_name': vm.get('name')} } email_data = { 'subject': context.get('page_header'), @@ -924,6 +925,7 @@ class VirtualMachineView(LoginRequiredMixin, View): return render(request, self.template_name, context) def post(self, request, *args, **kwargs): + response = {} owner = self.request.user vm = self.get_object() @@ -934,41 +936,53 @@ class VirtualMachineView(LoginRequiredMixin, View): password=owner.password ) vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data - terminated = manager.delete_vm( - vm.id - ) + + terminated = manager.delete_vm(vm.id) if not terminated: messages.error( request, 'Error terminating VM %s' % (opennebula_vm_id) ) - return HttpResponseRedirect(self.get_success_url()) - context = { - 'vm': vm_data, - 'base_url': "{0}://{1}".format(self.request.scheme, - self.request.get_host()), - 'page_header': _('Virtual Machine Cancellation') - } - email_data = { - 'subject': context['page_header'], - 'to': self.request.user.email, - 'context': context, - 'template_name': 'vm_canceled', - 'template_path': 'hosting/emails/', - 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS, - } - email = BaseEmail(**email_data) - email.send() + response['status'] = False + else: + context = { + 'vm': vm_data, + 'base_url': "{0}://{1}".format(self.request.scheme, + self.request.get_host()), + 'page_header': _('Virtual Machine Cancellation') + } + email_data = { + 'subject': context['page_header'], + 'to': self.request.user.email, + 'context': context, + 'template_name': 'vm_canceled', + 'template_path': 'hosting/emails/', + 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS, + } + email = BaseEmail(**email_data) + email.send() - messages.error( - request, - _('VM %(VM_ID)s terminated successfully') % { - 'VM_ID': opennebula_vm_id} + # messages.error( + # request, + # _('VM %(VM_ID)s terminated successfully') % { + # 'VM_ID': opennebula_vm_id} + # ) + deleting = True + t = 0 + while deleting: + if t < 150 and manager.get_vm(self.kwargs.get('pk')): + sleep(2) + else: + deleting = False + response['status'] = True + response['redirect'] = self.get_success_url() + response['text'] = ugettext('Terminated') + return HttpResponse( + json.dumps(response), + content_type="application/json" ) - return HttpResponseRedirect(self.get_success_url()) - class HostingBillListView(PermissionRequiredMixin, LoginRequiredMixin, ListView): From 8ca1b13f80a70c7ed1bdf29836d60ae3e302b1b9 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 14 Sep 2017 02:29:51 +0530 Subject: [PATCH 02/82] template fixed --- hosting/templates/hosting/virtual_machine_detail.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index a5c82e90..d0bfae47 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -46,7 +46,7 @@ <div class="vm-vmid"> <div class="vm-item-subtitle">{% trans "Current Pricing" %}</div> <div class="vm-item-lg">{{virtual_machine.price|floatformat}} CHF/{% trans "Month" %}</div> - <a class="btn btn-vm-invoice" href="{% url 'hosting:orders' 2 %}">{% trans "See Invoice" %}</a> + <a class="btn btn-vm-invoice" href="{% url 'hosting:orders' order.pk %}">{% trans "See Invoice" %}</a> </div> </div> <div class="vm-detail-item"> @@ -64,7 +64,7 @@ <div class="vm-item-lg"></div> {% endif %} {% if not virtual_machine.status == 'canceled' %} - <form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' 2 %}"> + <form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}"> {% csrf_token %} </form> <button data-toggle="modal" data-target="#confirm-cancel" class="btn btn-vm-term">{% trans "Terminate VM" %}</button> From abc290de61c748a22f0ae85d5ffe8820ff9d455d Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 14 Sep 2017 02:43:01 +0530 Subject: [PATCH 03/82] added error msg --- hosting/views.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index df6e6100..ca80a8d1 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -940,11 +940,8 @@ class VirtualMachineView(LoginRequiredMixin, View): terminated = manager.delete_vm(vm.id) if not terminated: - messages.error( - request, - 'Error terminating VM %s' % (opennebula_vm_id) - ) response['status'] = False + response['text'] = 'Error terminating VM %s' % (opennebula_vm_id) else: context = { 'vm': vm_data, From a808f3bf7e2173fbf44e0521591981f2e38e4d57 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 14 Sep 2017 02:48:56 +0530 Subject: [PATCH 04/82] error fix on termination --- hosting/views.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index ca80a8d1..685fe0b4 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -965,13 +965,17 @@ class VirtualMachineView(LoginRequiredMixin, View): # _('VM %(VM_ID)s terminated successfully') % { # 'VM_ID': opennebula_vm_id} # ) - deleting = True t = 0 - while deleting: - if t < 150 and manager.get_vm(self.kwargs.get('pk')): - sleep(2) + while True: + if t > 150: + break + try: + manager.get_vm(self.kwargs.get('pk')) + except: + break else: - deleting = False + sleep(2) + response['status'] = True response['redirect'] = self.get_success_url() response['text'] = ugettext('Terminated') From e045caebbe6f704b6a95fc7763365de1c2e18a2e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 14 Sep 2017 02:52:37 +0530 Subject: [PATCH 05/82] redirect on success --- hosting/static/hosting/js/virtual_machine_detail.js | 2 +- hosting/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index ce97d44e..076ec344 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -21,7 +21,7 @@ $( document ).ready(function() { $container.addClass('terminate-success') .find('.vm-item-lg').text(data.text); $btn.remove(); - // window.location = data.redirect; + window.location = data.redirect; } else { $container.addClass('terminate-fail') diff --git a/hosting/views.py b/hosting/views.py index 685fe0b4..cf17c9f8 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -971,7 +971,7 @@ class VirtualMachineView(LoginRequiredMixin, View): break try: manager.get_vm(self.kwargs.get('pk')) - except: + except BaseException: break else: sleep(2) From 8393afe1418408b8cfac9c7d71c608e10b446293 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 14 Sep 2017 02:59:08 +0530 Subject: [PATCH 06/82] translations and test methods removed --- hosting/locale/de/LC_MESSAGES/django.po | 21 +++++++++++++++++---- hosting/urls.py | 3 --- hosting/views.py | 3 ++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 780419b1..2f6cee4e 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-09-09 06:04+0000\n" +"POT-Creation-Date: 2017-09-14 02:55+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -524,6 +524,9 @@ msgstr "Aktueller Preis" msgid "Your VM is" msgstr "Deine VM ist" +msgid "Terminating" +msgstr "Beenden" + msgid "Pending" msgstr "In Vorbereitung" @@ -536,6 +539,11 @@ msgstr "Fehlgeschlagen" msgid "Terminate VM" msgstr "VM Beenden" +msgid "Sorry, there was an unexpected error. Kindly retry." +msgstr "" +"Bitte entschuldige, es scheint ein unerwarteter Fehler aufgetreten zu sein. " +"Versuche es doch bitte noch einmal." + msgid "Something doesn't work?" msgstr "Etwas funktioniert nicht?" @@ -624,12 +632,17 @@ msgid "" "contact Data Center Light Support." msgstr "Kontaktiere den Data Center Light Support." +msgid "Error terminating VM" +msgstr "Fehler beenden VM" + msgid "Virtual Machine Cancellation" msgstr "VM Kündigung" -#, python-format -msgid "VM %(VM_ID)s terminated successfully" -msgstr "VM %(VM_ID)s erfolgreich beendet" +msgid "Terminated" +msgstr "Beendet" + +#~ msgid "VM %(VM_ID)s terminated successfully" +#~ msgstr "VM %(VM_ID)s erfolgreich beendet" #~ msgid "My Virtual Machines" #~ msgstr "Meine virtuellen Maschinen" diff --git a/hosting/urls.py b/hosting/urls.py index c3b982cb..455aa97f 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -10,11 +10,8 @@ from .views import ( HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, SSHKeyChoiceView, DashboardView, SettingsView) -from django.views.generic import TemplateView - urlpatterns = [ - url(r'test/?$', TemplateView.as_view(template_name='hosting/virtual_machine_detail.html')), url(r'index/?$', IndexView.as_view(), name='index'), url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'), diff --git a/hosting/views.py b/hosting/views.py index cf17c9f8..4d9aeb18 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -941,7 +941,8 @@ class VirtualMachineView(LoginRequiredMixin, View): if not terminated: response['status'] = False - response['text'] = 'Error terminating VM %s' % (opennebula_vm_id) + response['text'] = ugettext( + 'Error terminating VM') + opennebula_vm_id else: context = { 'vm': vm_data, From a1a90ed5d0a79940fc1528d2e7ec061e4a3323d4 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 00:14:09 +0530 Subject: [PATCH 07/82] while loop code formating --- hosting/views.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index 4d9aeb18..290d5f0f 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -968,14 +968,16 @@ class VirtualMachineView(LoginRequiredMixin, View): # ) t = 0 while True: - if t > 150: - break - try: - manager.get_vm(self.kwargs.get('pk')) - except BaseException: - break + if t < 150: + t += 1 + try: + manager.get_vm(self.kwargs.get('pk')) + except BaseException: + break + else: + sleep(2) else: - sleep(2) + break response['status'] = True response['redirect'] = self.get_success_url() From c2b5c620147231de927719384b92091a94fb31ab Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 00:49:39 +0530 Subject: [PATCH 08/82] hosting calculator added --- .../static/hosting/css/price_calculator.css | 186 ++++++++++++++++++ hosting/templates/hosting/base_short.html | 4 +- .../templates/hosting/calculator_form.html | 123 ++++++++++++ .../hosting/create_virtual_machine.html | 87 +++----- 4 files changed, 334 insertions(+), 66 deletions(-) create mode 100644 hosting/static/hosting/css/price_calculator.css create mode 100644 hosting/templates/hosting/calculator_form.html diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css new file mode 100644 index 00000000..bf99c66f --- /dev/null +++ b/hosting/static/hosting/css/price_calculator.css @@ -0,0 +1,186 @@ +/*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; + /*font-family: 'Lato', sans-serif;*/ +/* font-weight: normal; */ +} + +.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%; + 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); + padding-bottom: 40px; + border-radius: 7px; + text-align: center; + /* margin-right: auto; */ + max-width: 400px; + 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; +} + +.price-calc-section .card .title h3 { + /*font-family: 'Lato', sans-serif;*/ + font-weight: normal; +} + +.price-calc-section .card .price { + background: #5A74AF; + padding: 22px; + color: #fff; + font-size: 32px; +} + +.price-calc-section .card .price .price-text { + font-size: 14px; +} + +.price-calc-section .card .description { + padding: 12px; + position: relative; + display: flex; + justify-content: space-around !important; + align-items: center !important; +} + +.price-calc-section .card .description span { + font-size: 16px; + margin-left: 4px; + margin-left: 0px; + /* justify-self: start; */ + width: 30%; + text-align: left; +} + +.price-calc-section .card .description .select-number{ + font-size: 20px; + text-align: center; + width: 85px; +} + +.price-calc-section .card .description i { + color: #29427A; + cursor: pointer; + font-size: 24px; +} + +.price-calc-section .card .description .left { + margin-right: 7px; +} + +.price-calc-section .card .description .right { + margin-left: 7px; +} + +.price-calc-section .card .descriptions { + padding: 10px 30px; +} + +.price-calc-section .card .description p { + margin: 0; +} + +.price-calc-section .card .btn { + margin-top: 20px; + font-size: 20px; + width: 200px; + border: none; +} + +.price-calc-section .card .select-configuration select { + outline: none; + background: #fff; + border-color: #d0d0d0; + height: 40px; + width: 200px; + text-align: center; + font-size: 16px; + margin-left: 10px; +} + +.price-calc-section .card .check-ip { + font-size: 18px; +} + +.price-calc-section .card .justify-center { + justify-content: center !important; +} + +.price-calc-section .card .description.input label { + font-size: 15px; + font-weight: 700; + /*font-weight: 800;*/ + /*font-family: 'Lato';*/ + margin-bottom: 0; + width: 40px; +} + + +/*Changed class****.price-calc-section .card .description.input input*/ + +.price-calc-section .card .description input { + width: 200px; + font-size: 14px; + text-align: left; + padding: 5px 10px; + border-radius: 4px; + border: 1px solid #d0d0d0; + background: #fff; + margin-left: 10px; +} + +.price-calc-section .card .check-ip input[type=checkbox] { + font-size: 17px; + margin: 0 8px; +} \ No newline at end of file diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index 63a0681d..becb7873 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -25,6 +25,7 @@ <link href="{% static 'hosting/css/commons.css' %}" rel="stylesheet"> <link href="{% static 'hosting/css/virtual-machine.css' %}" rel="stylesheet"> <link href="{% static 'hosting/css/dashboard.css' %}" rel="stylesheet"> + <link href="{% static 'hosting/css/price_calculator.css' %}" rel="stylesheet"> {% block css_extra %} {% endblock css_extra %} @@ -33,9 +34,6 @@ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> <link href="//fonts.googleapis.com/css?family=Lato:300,400,500,700,300italic,400italic,700italic" rel="stylesheet" type="text/css"> <link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" /> - <link rel="stylesheet" href="{% static 'hosting/css/owl.carousel.min.css' %}"> - <link rel="stylesheet" href="{% static 'hosting/css/owl.theme.default.min.css' %}"> - <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html new file mode 100644 index 00000000..cdba4809 --- /dev/null +++ b/hosting/templates/hosting/calculator_form.html @@ -0,0 +1,123 @@ +{% load staticfiles i18n%} +<form id="order_form" method="POST" action="" data-toggle="validator" role="form"> + {% csrf_token %} + <div class="title"> + <h3>{% trans "VM hosting" %} </h3> + </div> + <div class="price"> + <span id="total">15</span> + <span>CHF/{% trans "month" %}</span> + <div class="price-text"> + <p>{% trans "VAT included" %}</p> + </div> + </div> + <div class="descriptions"> + <div class="description form-group"> + <p>{% trans "Hosted in Switzerland" %}</p> + </div> + <div class="form-group"> + <div class="description input"> + <i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i> + <input class="input-price select-number" type="number" min="1" max="48" id="coreValue" name="cpu" + data-error="{% trans 'Please enter a value in range 1 - 48.' %}" required> + <span> Core</span> + <i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i> + </div> + <div class="help-block with-errors"> + {% for message in messages %} + {% if 'cores' in message.tags %} + <ul class="list-unstyled"><li> + {{ message|safe }} + </li></ul> + {% endif %} + {% endfor %} + </div> + </div> + <div class="form-group"> + <div class="description input"> + <i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i> + <input id="ramValue" class="input-price select-number" type="number" min="2" max="200" name="ram" + data-error="{% trans 'Please enter a value in range 2 - 200.' %}" required> + <span> GB RAM</span> + <i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i> + </div> + <div class="help-block with-errors"> + {% for message in messages %} + {% if 'memory' in message.tags %} + <ul class="list-unstyled"><li> + {{ message|safe }} + </li></ul> + {% endif %} + {% endfor %} + </div> + </div> + <div class="form-group"> + <div class="description input"> + <i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i> + <input id="storageValue" class="input-price select-number" type="number" min="10" max="2000" step="10" + name="storage" data-error="{% trans 'Please enter a value in range 10 - 2000.' %}" required> + <span>{% trans "GB Storage (SSD)" %}</span> + <i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i> + </div> + <div class="help-block with-errors"> + {% for message in messages %} + {% if 'storage' in message.tags %} + <ul class="list-unstyled"><li> + {{ message|safe }} + </li></ul> + {% endif %} + {% endfor %} + </div> + </div> + <div class="description select-configuration input form-group justify-center"> + <label for="config">OS</label> + <select name="config" id=""> + {% for template in templates %} + <option value="{{template.opennebula_vm_template_id}}">{{template.name}}</option> + {% endfor %} + </select> + </div> + <input type="hidden" name="total"> + <!--<div class="description check-ip"> + <input type="checkbox" name="ipv6"> Ipv6 Only<br> + </div>--> + <div class="form-group"> + <div class="description input justify-center"> + <label for="name" class="control-label">{% trans "Name"%}</label> + <input type="text" name="name" class="form-control" placeholder="{% trans 'Your Name'%}" + data-minlength="3" data-error="{% trans 'Please enter your name.' %}" required> + </div> + <div class="help-block with-errors"> + {% for message in messages %} + {% if 'name' in message.tags %} + <ul class="list-unstyled"> + <li> + {{ message|safe }} + </li> + </ul> + {% endif %} + {% endfor %} + </div> + </div> + <div class="form-group"> + <div class="description input justify-center"> + <label for="email" class="control-label">{% trans "Email"%}</label> + <input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control" + placeholder="{% trans 'Your Email' %}" + data-error="{% trans 'Please enter a valid email address.' %}" required> + </div> + <div class="help-block with-errors"> + {% for message in messages %} + {% if 'email' in message.tags %} + <ul class="list-unstyled"> + <li> + {{ message|safe }} + </li> + </ul> + {% endif %} + {% endfor %} + </div> + </div> + </div> + <input type="submit" class="btn btn-primary disabled" value="{% trans 'Continue' %}"></input> +</form> diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index f876ad76..5a5e789e 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -1,70 +1,31 @@ {% extends "hosting/base_short.html" %} {% load staticfiles bootstrap3 i18n %} -{% block content %} -<div> - <div class="dashboard-container" > - <div class="row"> - <div class="col-md-12"> - <br/> - {% if messages %} - <div class="alert alert-warning"> - {% for message in messages %} - <span>{{ message }}</span> - {% endfor %} - </div> - {% endif %} +{% block content %} +<div class="dashboard-container"> + <div class="row"> + <div class="col-sm-6"> + <div class="dashboard-container-head"> + <h3 class="dashboard-title-thin"><img src="{% static 'hosting/img/plusVM.svg' %}" class="un-icon" style="margin-top: -18px;width: 42px;height: 42px;"> {% trans "Create VM" %}</h3> + {% if messages %} + <div class="alert alert-warning"> + {% for message in messages %} + <span>{{ message }}</span> + {% endfor %} + </div> + {% endif %} + </div> + </div> + <div class="col-sm-6"> + <div class="price-calc-section no-padding"> + <div class="landing card"> + <img class="img-beta" src="{% static 'datacenterlight/img/beta-img.png' %}" alt=""> + <div class="caption"> + {% include "hosting/calculator_form.html" %} + </div> </div> - {% if not error %} - <div class="dashboard-title"> - <h3>{% trans "New Virtual Machine"%} </h3> - <hr/> - </div> - - <form method="POST" action=""> - {% csrf_token %} - - <div class="step-title"> - <h4>{% trans "Step 1. Select VM Template:" %} </h4> - </div> - <div class="parent-container"> - <div class="container-os owl-carousel owl-theme" id="containerOs"> - - {% for template in templates %} - <div class="os-circle" data-id="{{template.id}}"> - <span class="text" >{{template.name}}</span> - </div> - {% endfor %} - </div> - <input type="hidden" name="vm_template_id"> - </div> - <div class="step-title"> - <h4>{% trans "Step2. Select VM Configuration" %}</h4> - </div> - <div class="parent-container"> - <div class="container-os config owl-carousel owl-theme"> - - {% for config in configuration_options %} - <div class="config-box" data-id="{{config.id}}" data-price="{{config.price|floatformat}}"> - <span>CORE: {{config.cpu|floatformat}}</span> - <span>RAM: {{config.memory|floatformat}} GB</span> - <span>SSD: {{config.disk_size|floatformat}} GB</span> - </div> - {% endfor %} - </div> - <input type="hidden" name="configuration"> - </div> - <div class="container-button"> - <div class="price"> - <span class="label-price">{% trans "Price " %}<span id="priceValue">0</span>{% trans "CHF/Month" %}</span> - </div> - <button class="btn btn-success" >{% trans "Start VM"%} </button> - </div> - </form> - {% endif %} + </div> </div> </div> - </div> - -{%endblock%} +{%endblock%} \ No newline at end of file From a935871722f530f0ac08e2b658cf58315db5df0e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 00:57:59 +0530 Subject: [PATCH 09/82] code reformating --- .../hosting/js/virtual_machine_detail.js | 96 +++++++++---------- hosting/views.py | 28 ++---- 2 files changed, 56 insertions(+), 68 deletions(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 076ec344..898ecbaa 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -1,54 +1,52 @@ +$(document).ready(function() { -$( document ).ready(function() { + $('#confirm-cancel').on('click', '.btn-ok', function(e) { + var url = $('#virtual_machine_cancel_form').attr('action'); + var $container = $('#terminate-VM'); + var $btn = $container.find('.btn'); + var text = $container.find('.vm-item-lg').text(); + var altText = $container.attr('data-alt'); + $container.find('.alert-danger').addClass('hide'); + $container.addClass('processing') + .find('.vm-item-lg').attr('class', '') + .addClass('vm-item-lg vm-color-failed') + .text(altText); + $btn.prop('disabled', true); + $('#confirm-cancel').modal('hide'); + $.post(url) + .done(function(data) { + console.log("success", data); + if (data.status == true) { + $container.addClass('terminate-success') + .find('.vm-item-lg').text(data.text); + $btn.remove(); + window.location = data.redirect; + } else { + $container.addClass('terminate-fail') + .find('.vm-item-lg').text(text); + $container.find('.btn').prop('disabled', false); + $container.find('.alert-danger').text(data.text).removeClass('hide'); + } + }) + .fail(function(data) { + $container.addClass('terminate-fail') + .find('.vm-item-lg').text(text); + $container.find('.btn').prop('disabled', false); + $container.find('.alert-danger').removeClass('hide'); + }) + .always(function(data) { + $container.removeClass('processing'); + }); + }); - $('#confirm-cancel').on('click', '.btn-ok', function(e) { - var url = $('#virtual_machine_cancel_form').attr('action'); - var $container = $('#terminate-VM'); - var $btn = $container.find('.btn'); - var text = $container.find('.vm-item-lg').text(); - var altText = $container.attr('data-alt'); - $container.find('.alert-danger').addClass('hide'); - $container.addClass('processing') - .find('.vm-item-lg').attr('class', '') - .addClass('vm-item-lg vm-color-failed') - .text(altText); - $btn.prop('disabled', true); - $('#confirm-cancel').modal('hide'); - $.post(url) - .done(function(data) { - console.log( "success" , data); - if (data.status == true) { - $container.addClass('terminate-success') - .find('.vm-item-lg').text(data.text); - $btn.remove(); - window.location = data.redirect; - } - else { - $container.addClass('terminate-fail') - .find('.vm-item-lg').text(text); - $container.find('.btn').prop('disabled', false); - $container.find('.alert-danger').text(data.text).removeClass('hide'); - } - }) - .fail(function(data) { - $container.addClass('terminate-fail') - .find('.vm-item-lg').text(text); - $container.find('.btn').prop('disabled', false); - $container.find('.alert-danger').removeClass('hide'); - }) - .always(function(data) { - $container.removeClass('processing'); - }); - }); + var hash = window.location.hash; + hash && $('ul.nav a[href="' + hash + '"]').tab('show'); - var hash = window.location.hash; - hash && $('ul.nav a[href="' + hash + '"]').tab('show'); - - $('.nav-tabs a').click(function (e) { - $(this).tab('show'); - var scrollmem = $('body').scrollTop() || $('html').scrollTop(); - window.location.hash = this.hash; - $('html,body').scrollTop(scrollmem); - }); + $('.nav-tabs a').click(function(e) { + $(this).tab('show'); + var scrollmem = $('body').scrollTop() || $('html').scrollTop(); + window.location.hash = this.hash; + $('html,body').scrollTop(scrollmem); + }); }); \ No newline at end of file diff --git a/hosting/views.py b/hosting/views.py index ed85dbdb..f25d6567 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -957,6 +957,14 @@ class VirtualMachineView(LoginRequiredMixin, View): response['text'] = ugettext( 'Error terminating VM') + opennebula_vm_id else: + for t in range(150): + try: + manager.get_vm(self.kwargs.get('pk')) + except BaseException: + break + else: + sleep(2) + context = { 'vm': vm_data, 'base_url': "{0}://{1}".format(self.request.scheme, @@ -973,28 +981,10 @@ class VirtualMachineView(LoginRequiredMixin, View): } email = BaseEmail(**email_data) email.send() - - # messages.error( - # request, - # _('VM %(VM_ID)s terminated successfully') % { - # 'VM_ID': opennebula_vm_id} - # ) - t = 0 - while True: - if t < 150: - t += 1 - try: - manager.get_vm(self.kwargs.get('pk')) - except BaseException: - break - else: - sleep(2) - else: - break - response['status'] = True response['redirect'] = self.get_success_url() response['text'] = ugettext('Terminated') + return HttpResponse( json.dumps(response), content_type="application/json" From 75156d2c00389bf2e15a38202f90a68e844a85d1 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 01:00:07 +0530 Subject: [PATCH 10/82] undo changes in navbar --- hosting/templates/hosting/includes/_navbar_user.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hosting/templates/hosting/includes/_navbar_user.html b/hosting/templates/hosting/includes/_navbar_user.html index 37c01109..d06477ca 100644 --- a/hosting/templates/hosting/includes/_navbar_user.html +++ b/hosting/templates/hosting/includes/_navbar_user.html @@ -37,6 +37,11 @@ </li> <li> {% get_current_language as LANGUAGE_CODE %} + {% if LANGUAGE_CODE == 'en-us'%} + <a href="{% change_lang 'de' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> Deutsch</a> + {% else %} + <a href="{% change_lang 'en-us' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> English</a> + {% endif %} </li> </ul> </div> From 852c1228bad339bdfbe5939fa4a2cbe39258d4a3 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 14:48:11 +0530 Subject: [PATCH 11/82] minor fix --- hosting/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index f25d6567..f5780aed 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -957,7 +957,7 @@ class VirtualMachineView(LoginRequiredMixin, View): response['text'] = ugettext( 'Error terminating VM') + opennebula_vm_id else: - for t in range(150): + for t in range(50): try: manager.get_vm(self.kwargs.get('pk')) except BaseException: From 6136a48961b0b17146cffdb4298fa788a15ed1fa Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 16:46:56 +0530 Subject: [PATCH 12/82] edge cases handled --- .../hosting/js/virtual_machine_detail.js | 74 +++++++++++++------ hosting/views.py | 19 ++--- 2 files changed, 62 insertions(+), 31 deletions(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 898ecbaa..0485bc36 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -1,42 +1,72 @@ +function VMTerminateStatus($container, url) { + $.get(url) + .done(function(data) { + setTimeout(function(){ + VMTerminateStatus($container, url); + }, 2000); + }) + .fail(function(data) { + VMTerminateSuccess($container, data) + window.location.reload(true); + }); +} + +function VMTerminateActive($container, altText) { + $container.find('.alert-danger').addClass('hide'); + $container.addClass('processing') + .find('.vm-item-lg').attr('class', '') + .addClass('vm-item-lg vm-color-failed') + .text(altText); + $container.find('.btn').prop('disabled', true); + $('#confirm-cancel').modal('hide'); +} + +function VMTerminateSuccess($container, data) { + $container.addClass('terminate-success') + .find('.vm-item-lg').text(data.text); + $container.find('.btn').remove(); +} + +function VMTerminateFail($container, data, text) { + $container.addClass('terminate-fail') + .find('.vm-item-lg').text(text); + $container.find('.btn').prop('disabled', false); + $container.find('.alert-danger').text(data.text).removeClass('hide'); + $container.removeClass('processing'); +} + + $(document).ready(function() { $('#confirm-cancel').on('click', '.btn-ok', function(e) { var url = $('#virtual_machine_cancel_form').attr('action'); var $container = $('#terminate-VM'); - var $btn = $container.find('.btn'); var text = $container.find('.vm-item-lg').text(); var altText = $container.attr('data-alt'); - $container.find('.alert-danger').addClass('hide'); - $container.addClass('processing') - .find('.vm-item-lg').attr('class', '') - .addClass('vm-item-lg vm-color-failed') - .text(altText); - $btn.prop('disabled', true); - $('#confirm-cancel').modal('hide'); + VMTerminateActive($container, altText); + $.post(url) .done(function(data) { console.log("success", data); if (data.status == true) { - $container.addClass('terminate-success') - .find('.vm-item-lg').text(data.text); - $btn.remove(); + VMTerminateSuccess($container, data); window.location = data.redirect; } else { - $container.addClass('terminate-fail') - .find('.vm-item-lg').text(text); - $container.find('.btn').prop('disabled', false); - $container.find('.alert-danger').text(data.text).removeClass('hide'); + if ('text' in data) { + VMTerminateFail($container, data, text); + } else { + VMTerminateStatus($container, url); + } } }) .fail(function(data) { - $container.addClass('terminate-fail') - .find('.vm-item-lg').text(text); - $container.find('.btn').prop('disabled', false); - $container.find('.alert-danger').removeClass('hide'); + console.log(data) + if (data.status==504) { + VMTerminateStatus($container, url); + } else { + VMTerminateFail($container, data, text); + } }) - .always(function(data) { - $container.removeClass('processing'); - }); }); var hash = window.location.hash; diff --git a/hosting/views.py b/hosting/views.py index f5780aed..848ac9e8 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -923,7 +923,10 @@ class VirtualMachineView(LoginRequiredMixin, View): def get(self, request, *args, **kwargs): vm = self.get_object() if vm is None: - return redirect(reverse('hosting:virtual_machines')) + if self.request.is_ajax(): + raise Http404() + else: + return redirect(reverse('hosting:virtual_machines')) try: serializer = VirtualMachineSerializer(vm) context = { @@ -938,7 +941,7 @@ class VirtualMachineView(LoginRequiredMixin, View): return render(request, self.template_name, context) def post(self, request, *args, **kwargs): - response = {} + response = {'status': False} owner = self.request.user vm = self.get_object() @@ -948,23 +951,25 @@ class VirtualMachineView(LoginRequiredMixin, View): email=owner.email, password=owner.password ) + vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data terminated = manager.delete_vm(vm.id) if not terminated: - response['status'] = False response['text'] = ugettext( 'Error terminating VM') + opennebula_vm_id else: - for t in range(50): + for t in range(15): try: manager.get_vm(self.kwargs.get('pk')) except BaseException: + response['status'] = True + response['redirect'] = self.get_success_url() + response['text'] = ugettext('Terminated') break else: sleep(2) - context = { 'vm': vm_data, 'base_url': "{0}://{1}".format(self.request.scheme, @@ -981,10 +986,6 @@ class VirtualMachineView(LoginRequiredMixin, View): } email = BaseEmail(**email_data) email.send() - response['status'] = True - response['redirect'] = self.get_success_url() - response['text'] = ugettext('Terminated') - return HttpResponse( json.dumps(response), content_type="application/json" From fdb5039c029c59ae177fdc9f71d9429e5919256f Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 16:57:17 +0530 Subject: [PATCH 13/82] minor adjustments --- hosting/static/hosting/css/virtual-machine.css | 3 +++ hosting/static/hosting/js/virtual_machine_detail.js | 2 +- hosting/views.py | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hosting/static/hosting/css/virtual-machine.css b/hosting/static/hosting/css/virtual-machine.css index b6afe4ef..48932350 100644 --- a/hosting/static/hosting/css/virtual-machine.css +++ b/hosting/static/hosting/css/virtual-machine.css @@ -530,6 +530,9 @@ .vm-status-failed { color: #eb4d5c; } +.vm-status-failed { + color: #e47f2f; +} @media (min-width:768px) { .dashboard-subtitle { diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 0485bc36..df401ebe 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -3,7 +3,7 @@ function VMTerminateStatus($container, url) { .done(function(data) { setTimeout(function(){ VMTerminateStatus($container, url); - }, 2000); + }, 4000); }) .fail(function(data) { VMTerminateSuccess($container, data) diff --git a/hosting/views.py b/hosting/views.py index 848ac9e8..77c4b8dc 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -924,6 +924,8 @@ class VirtualMachineView(LoginRequiredMixin, View): vm = self.get_object() if vm is None: if self.request.is_ajax(): + storage = messages.get_messages(request) + storage.used = True raise Http404() else: return redirect(reverse('hosting:virtual_machines')) From 0c3f60573568d7a18620f9c125fd767c2af791d9 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 17:02:02 +0530 Subject: [PATCH 14/82] status pending style in vm-list --- hosting/static/hosting/css/virtual-machine.css | 4 ++-- hosting/templates/hosting/virtual_machines.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hosting/static/hosting/css/virtual-machine.css b/hosting/static/hosting/css/virtual-machine.css index 48932350..a14abc31 100644 --- a/hosting/static/hosting/css/virtual-machine.css +++ b/hosting/static/hosting/css/virtual-machine.css @@ -521,7 +521,7 @@ color: #87B6EA; } -.vm-status, .vm-status-active, .vm-status-failed { +.vm-status, .vm-status-active, .vm-status-failed, .vm-status-pending { font-weight: 600; } .vm-status-active { @@ -530,7 +530,7 @@ .vm-status-failed { color: #eb4d5c; } -.vm-status-failed { +.vm-status-pending { color: #e47f2f; } diff --git a/hosting/templates/hosting/virtual_machines.html b/hosting/templates/hosting/virtual_machines.html index f7461abe..da8c79a5 100644 --- a/hosting/templates/hosting/virtual_machines.html +++ b/hosting/templates/hosting/virtual_machines.html @@ -46,7 +46,7 @@ {% elif vm.state == 'FAILED' %} <span class="vm-status-failed"><strong>{{vm.state|title}}</strong></span> {% else %} - <span class="vm-status"><strong>{{vm.state|title}}</strong></span> + <span class="vm-status-pending"><strong>{{vm.state|title}}</strong></span> {% endif %} </td> <td class="text-right last-td"> From 77f2454e3cc1b1c1480e1e46ae2646cd7bc771d6 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 17:20:42 +0530 Subject: [PATCH 15/82] remove error msg on successful termination --- .../hosting/js/virtual_machine_detail.js | 18 ++++++++++-------- hosting/views.py | 7 ++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index df401ebe..47080cd4 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -1,14 +1,16 @@ function VMTerminateStatus($container, url) { - $.get(url) - .done(function(data) { + $.ajax({ + url: url, + dataType: 'json', + success: function(data) { + VMTerminateSuccess($container, data); + }, + error: function() { setTimeout(function(){ VMTerminateStatus($container, url); }, 4000); - }) - .fail(function(data) { - VMTerminateSuccess($container, data) - window.location.reload(true); - }); + } + }); } function VMTerminateActive($container, altText) { @@ -25,6 +27,7 @@ function VMTerminateSuccess($container, data) { $container.addClass('terminate-success') .find('.vm-item-lg').text(data.text); $container.find('.btn').remove(); + window.location = data.redirect; } function VMTerminateFail($container, data, text) { @@ -50,7 +53,6 @@ $(document).ready(function() { console.log("success", data); if (data.status == true) { VMTerminateSuccess($container, data); - window.location = data.redirect; } else { if ('text' in data) { VMTerminateFail($container, data, text); diff --git a/hosting/views.py b/hosting/views.py index 77c4b8dc..072ada8e 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -926,9 +926,14 @@ class VirtualMachineView(LoginRequiredMixin, View): if self.request.is_ajax(): storage = messages.get_messages(request) storage.used = True - raise Http404() + return HttpResponse( + json.dumps({'redirect': self.get_success_url()}), + content_type="application/json" + ) else: return redirect(reverse('hosting:virtual_machines')) + elif self.request.is_ajax(): + return HttpResponse() try: serializer = VirtualMachineSerializer(vm) context = { From bbb1919404085b145a95e00f58a4ee2e4f37f9db Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 17:38:52 +0530 Subject: [PATCH 16/82] error msg fix --- hosting/static/hosting/js/virtual_machine_detail.js | 2 -- hosting/views.py | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 47080cd4..29b08cda 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -50,7 +50,6 @@ $(document).ready(function() { $.post(url) .done(function(data) { - console.log("success", data); if (data.status == true) { VMTerminateSuccess($container, data); } else { @@ -62,7 +61,6 @@ $(document).ready(function() { } }) .fail(function(data) { - console.log(data) if (data.status==504) { VMTerminateStatus($container, url); } else { diff --git a/hosting/views.py b/hosting/views.py index 072ada8e..201f590a 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -925,6 +925,8 @@ class VirtualMachineView(LoginRequiredMixin, View): if vm is None: if self.request.is_ajax(): storage = messages.get_messages(request) + for m in storage: + pass storage.used = True return HttpResponse( json.dumps({'redirect': self.get_success_url()}), From 9c0cefd41968ef03b65dacb6572accc702fdd277 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 17:44:27 +0530 Subject: [PATCH 17/82] js polling timing to 5s --- hosting/static/hosting/js/virtual_machine_detail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 29b08cda..d6387dbc 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -8,7 +8,7 @@ function VMTerminateStatus($container, url) { error: function() { setTimeout(function(){ VMTerminateStatus($container, url); - }, 4000); + }, 5000); } }); } From d49e90bd209868b710f6f4d61a45c146482cc5ff Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 18:15:06 +0530 Subject: [PATCH 18/82] catching WrongIdError --- hosting/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index 201f590a..acd7e67b 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -972,10 +972,13 @@ class VirtualMachineView(LoginRequiredMixin, View): for t in range(15): try: manager.get_vm(self.kwargs.get('pk')) - except BaseException: + except WrongIdError: response['status'] = True response['redirect'] = self.get_success_url() response['text'] = ugettext('Terminated') + self.send_mail() + break + except BaseException: break else: sleep(2) From 87327d028a1fac59192783082a9f181b5c2022ad Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 20:03:52 +0530 Subject: [PATCH 19/82] hosting form view modified --- .../datacenterlight/calculator_form.html | 6 +- .../static/hosting/css/price_calculator.css | 99 +++++++++---- hosting/static/hosting/js/createvm.js | 137 +++++++++--------- hosting/static/hosting/js/createvm_old.js | 73 ++++++++++ hosting/templates/hosting/base_short.html | 6 +- .../templates/hosting/calculator_form.html | 86 ++++------- .../hosting/create_virtual_machine.html | 19 ++- hosting/views.py | 102 ++++++++----- 8 files changed, 324 insertions(+), 204 deletions(-) create mode 100644 hosting/static/hosting/js/createvm_old.js diff --git a/datacenterlight/templates/datacenterlight/calculator_form.html b/datacenterlight/templates/datacenterlight/calculator_form.html index cdba4809..b5bac1f9 100644 --- a/datacenterlight/templates/datacenterlight/calculator_form.html +++ b/datacenterlight/templates/datacenterlight/calculator_form.html @@ -26,9 +26,9 @@ <div class="help-block with-errors"> {% for message in messages %} {% if 'cores' in message.tags %} - <ul class="list-unstyled"><li> - {{ message|safe }} - </li></ul> + <ul class="list-unstyled"> + <li>{{ message|safe }}</li> + </ul> {% endif %} {% endfor %} </div> diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index bf99c66f..5aac2c97 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -1,12 +1,13 @@ -/*Pricing page*/ +/* Create VM calculator */ .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; - /*font-family: 'Lato', sans-serif;*/ -/* font-weight: normal; */ +} + +@media (max-width: 768px) { + .price-calc-section { + margin-top: 40px; + } } .price-calc-section .text { @@ -42,12 +43,12 @@ width: 50%; 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); - padding-bottom: 40px; - border-radius: 7px; + box-shadow: 1px 3px 6px 2px rgba(0, 0, 0, 0.2); + padding-bottom: 30px; + /* border-radius: 7px; */ text-align: center; /* margin-right: auto; */ - max-width: 400px; + max-width: 320px; position: relative; } @@ -87,7 +88,7 @@ } .price-calc-section .card .description { - padding: 12px; + padding: 7px 8px 2px; position: relative; display: flex; justify-content: space-around !important; @@ -95,24 +96,29 @@ } .price-calc-section .card .description span { - font-size: 16px; - margin-left: 4px; - margin-left: 0px; + font-size: 14px; + margin-left: 5px; + /* margin-left: 0px; */ /* justify-self: start; */ - width: 30%; + width: 29%; text-align: left; + line-height: 16px; + /* font-weight: normal; */ } .price-calc-section .card .description .select-number{ - font-size: 20px; + font-size: 16px; text-align: center; width: 85px; } .price-calc-section .card .description i { - color: #29427A; + color: #29427a; cursor: pointer; - font-size: 24px; + font-size: 20px; + border: 1px solid #eee; + padding: 5px 6px 3px; + border-radius: 5px; } .price-calc-section .card .description .left { @@ -124,7 +130,7 @@ } .price-calc-section .card .descriptions { - padding: 10px 30px; + padding: 10px; } .price-calc-section .card .description p { @@ -132,9 +138,9 @@ } .price-calc-section .card .btn { - margin-top: 20px; + margin-top: 15px; font-size: 20px; - width: 200px; + width: 150px; border: none; } @@ -142,11 +148,13 @@ outline: none; background: #fff; border-color: #d0d0d0; - height: 40px; - width: 200px; + height: 32px; + width: 150px; text-align: center; - font-size: 16px; + font-size: 14px; margin-left: 10px; + padding: 6px; + border-radius: 4px; } .price-calc-section .card .check-ip { @@ -173,7 +181,7 @@ width: 200px; font-size: 14px; text-align: left; - padding: 5px 10px; + padding: 4px 10px; border-radius: 4px; border: 1px solid #d0d0d0; background: #fff; @@ -183,4 +191,43 @@ .price-calc-section .card .check-ip input[type=checkbox] { font-size: 17px; margin: 0 8px; -} \ No newline at end of file +} + +.help-block.with-errors { + text-align: center; + margin: 0 0; + padding: 0 0 5px; +} +.help-block.with-errors ul { + margin-bottom: 0; +} + +.form-group { + margin: 0; + position: relative; +} + +.form-group:after { + content: ' '; + display: block; + position: absolute; + bottom: 0; + left: 18%; + z-index: 20; + height: 1px; + width: 65%; + background: rgba(128, 128, 128, 0.2); +} + +.btn-primary { + background: #29427A; + border-color: #29427A; + color: #fff; + width: auto; +} + +@media(min-width: 768px) { + .create-vm-container { + padding-top: 120px; + } +} diff --git a/hosting/static/hosting/js/createvm.js b/hosting/static/hosting/js/createvm.js index 53646b40..344aedfb 100644 --- a/hosting/static/hosting/js/createvm.js +++ b/hosting/static/hosting/js/createvm.js @@ -1,73 +1,76 @@ (function($){ "use strict"; // Start of use strict - - - $(window).load(function(){ - - - }); - - $(document).ready(function(){ - _initOs(); - - }); - - $(window).resize(function(){ - - - }); - - - function _initOs(){ - - - $('.os-circle').click(function(event){ - $('.os-circle').removeClass('active'); - $(this).addClass('active'); - - var idTemplate = $(this).data('id'); - $('input[name=vm_template_id]').val(idTemplate); - }); - $('.config-box').click(function(event){ - $('.config-box').removeClass('active'); - $(this).addClass('active'); - var idConfig = $(this).data('id'); - var price = $(this).data('price'); - $('input[name=configuration]').val(idConfig); - $('.container-button').fadeIn(); - $('#priceValue').text(price); - }); - - $('.owl-carousel').owlCarousel({ - items:4, - nav: true, - margin:30, - responsiveClass:true, - navText: ['<i class="fa fa-angle-left"></i>', '<i class="fa fa-angle-right"></i>'], - responsive:{ - 0:{ - items:1, - nav:true - }, - 600:{ - items:2, - nav:true - }, - 768:{ - items:3, - nav:true - }, - 990:{ - items:4, - nav:true - } + var cardPricing = { + 'cpu': { + 'id': 'coreValue', + 'value': 1, + 'min': 1, + 'max': 48, + 'interval': 1 + }, + 'ram': { + 'id': 'ramValue', + 'value': 2, + 'min': 2, + 'max': 200, + 'interval': 1 + }, + 'storage': { + 'id': 'storageValue', + 'value': 10, + 'min': 10, + 'max': 2000, + 'interval': 10 } - }); - } - - - -})(jQuery); + }; + + function _initPricing() { + _fetchPricing(); + + $('.fa-minus.left').click(function(event) { + var data = $(this).data('minus'); + + if (cardPricing[data].value > cardPricing[data].min) { + cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval; + } + _fetchPricing(); + }); + $('.fa-plus.right').click(function(event) { + var data = $(this).data('plus'); + if (cardPricing[data].value < cardPricing[data].max) { + cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval; + } + _fetchPricing(); + }); + + $('.input-price').change(function() { + var data = $(this).attr("name"); + cardPricing[data].value = $('input[name=' + data + ']').val(); + _fetchPricing(); + }); + } + + function _fetchPricing() { + Object.keys(cardPricing).map(function(element) { + //$('#'+cardPricing[element].id).val(cardPricing[element].value); + $('input[name=' + element + ']').val(cardPricing[element].value); + }); + _calcPricing(); + } + + function _calcPricing() { + var total = (cardPricing['cpu'].value * 5) + (2 * cardPricing['ram'].value) + (0.6 * cardPricing['storage'].value); + total = parseFloat(total.toFixed(2)); + + $("#total").text(total); + $('input[name=total]').val(total); + } + + $(document).ready(function() { + _initPricing(); + }); + +})(jQuery); diff --git a/hosting/static/hosting/js/createvm_old.js b/hosting/static/hosting/js/createvm_old.js new file mode 100644 index 00000000..53646b40 --- /dev/null +++ b/hosting/static/hosting/js/createvm_old.js @@ -0,0 +1,73 @@ +(function($){ + "use strict"; // Start of use strict + + + $(window).load(function(){ + + + }); + + $(document).ready(function(){ + _initOs(); + + }); + + $(window).resize(function(){ + + + }); + + + + function _initOs(){ + + + $('.os-circle').click(function(event){ + $('.os-circle').removeClass('active'); + $(this).addClass('active'); + + var idTemplate = $(this).data('id'); + $('input[name=vm_template_id]').val(idTemplate); + }); + $('.config-box').click(function(event){ + $('.config-box').removeClass('active'); + $(this).addClass('active'); + var idConfig = $(this).data('id'); + var price = $(this).data('price'); + $('input[name=configuration]').val(idConfig); + $('.container-button').fadeIn(); + $('#priceValue').text(price); + }); + + $('.owl-carousel').owlCarousel({ + items:4, + nav: true, + margin:30, + responsiveClass:true, + navText: ['<i class="fa fa-angle-left"></i>', '<i class="fa fa-angle-right"></i>'], + responsive:{ + 0:{ + items:1, + nav:true + }, + 600:{ + items:2, + nav:true + }, + 768:{ + items:3, + nav:true + }, + 990:{ + items:4, + nav:true + } + } + }); + } + + + +})(jQuery); + + diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index becb7873..382e763f 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -74,8 +74,8 @@ {% endif %} <!-- jQuery --> <script src="{% static 'hosting/js/jquery.js' %}"></script> - <script type="text/javascript" src="//cdn.jsdelivr.net/jquery.validation/1.13.1/jquery.validate.min.js"></script> - <script src="{% static 'hosting/js/vendor/owl.carousel.min.js'%}"></script> + <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script> + <script src="//cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.9/validator.min.js"></script> <!-- Copy Clipboard --> <script src="//cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.10/clipboard.min.js"></script> @@ -106,8 +106,6 @@ <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.js"></script> - - </body> </html> diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html index cdba4809..5ba2a4c3 100644 --- a/hosting/templates/hosting/calculator_form.html +++ b/hosting/templates/hosting/calculator_form.html @@ -1,27 +1,20 @@ {% load staticfiles i18n%} <form id="order_form" method="POST" action="" data-toggle="validator" role="form"> {% csrf_token %} - <div class="title"> - <h3>{% trans "VM hosting" %} </h3> - </div> <div class="price"> <span id="total">15</span> - <span>CHF/{% trans "month" %}</span> + <span>CHF/30 {% trans "days" %}</span> <div class="price-text"> <p>{% trans "VAT included" %}</p> </div> </div> <div class="descriptions"> - <div class="description form-group"> - <p>{% trans "Hosted in Switzerland" %}</p> - </div> <div class="form-group"> <div class="description input"> - <i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i> - <input class="input-price select-number" type="number" min="1" max="48" id="coreValue" name="cpu" - data-error="{% trans 'Please enter a value in range 1 - 48.' %}" required> + <i class="fa fa-minus left" data-minus="cpu" aria-hidden="true"></i> + <input class="input-price select-number" type="number" min="1" max="48" id="coreValue" name="cpu" data-error="{% trans 'Please enter a value in range 1 - 48.' %}" required> <span> Core</span> - <i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i> + <i class="fa fa-plus right" data-plus="cpu" aria-hidden="true"></i> </div> <div class="help-block with-errors"> {% for message in messages %} @@ -35,11 +28,11 @@ </div> <div class="form-group"> <div class="description input"> - <i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i> + <i class="fa fa-minus left" data-minus="ram" aria-hidden="true"></i> <input id="ramValue" class="input-price select-number" type="number" min="2" max="200" name="ram" data-error="{% trans 'Please enter a value in range 2 - 200.' %}" required> <span> GB RAM</span> - <i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i> + <i class="fa fa-plus right" data-plus="ram" aria-hidden="true"></i> </div> <div class="help-block with-errors"> {% for message in messages %} @@ -53,11 +46,11 @@ </div> <div class="form-group"> <div class="description input"> - <i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i> + <i class="fa fa-minus left" data-minus="storage" aria-hidden="true"></i> <input id="storageValue" class="input-price select-number" type="number" min="10" max="2000" step="10" name="storage" data-error="{% trans 'Please enter a value in range 10 - 2000.' %}" required> <span>{% trans "GB Storage (SSD)" %}</span> - <i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i> + <i class="fa fa-plus right" data-plus="storage" aria-hidden="true"></i> </div> <div class="help-block with-errors"> {% for message in messages %} @@ -69,55 +62,26 @@ {% endfor %} </div> </div> - <div class="description select-configuration input form-group justify-center"> - <label for="config">OS</label> - <select name="config" id=""> - {% for template in templates %} - <option value="{{template.opennebula_vm_template_id}}">{{template.name}}</option> + <div class="form-group"> + <div class="description select-configuration input justify-center"> + <label for="config">OS</label> + <select name="config" id=""> + {% for template in templates %} + <option value="{{template.opennebula_vm_template_id}}">{{template.name}}</option> + {% endfor %} + </select> + </div> + <div class="help-block with-errors"> + {% for message in messages %} + {% if 'cores' in message.tags %} + <ul class="list-unstyled"><li> + {{ message|safe }} + </li></ul> + {% endif %} {% endfor %} - </select> + </div> </div> <input type="hidden" name="total"> - <!--<div class="description check-ip"> - <input type="checkbox" name="ipv6"> Ipv6 Only<br> - </div>--> - <div class="form-group"> - <div class="description input justify-center"> - <label for="name" class="control-label">{% trans "Name"%}</label> - <input type="text" name="name" class="form-control" placeholder="{% trans 'Your Name'%}" - data-minlength="3" data-error="{% trans 'Please enter your name.' %}" required> - </div> - <div class="help-block with-errors"> - {% for message in messages %} - {% if 'name' in message.tags %} - <ul class="list-unstyled"> - <li> - {{ message|safe }} - </li> - </ul> - {% endif %} - {% endfor %} - </div> - </div> - <div class="form-group"> - <div class="description input justify-center"> - <label for="email" class="control-label">{% trans "Email"%}</label> - <input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control" - placeholder="{% trans 'Your Email' %}" - data-error="{% trans 'Please enter a valid email address.' %}" required> - </div> - <div class="help-block with-errors"> - {% for message in messages %} - {% if 'email' in message.tags %} - <ul class="list-unstyled"> - <li> - {{ message|safe }} - </li> - </ul> - {% endif %} - {% endfor %} - </div> - </div> </div> <input type="submit" class="btn btn-primary disabled" value="{% trans 'Continue' %}"></input> </form> diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index 5a5e789e..dff82199 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -2,24 +2,23 @@ {% load staticfiles bootstrap3 i18n %} {% block content %} -<div class="dashboard-container"> +<div class="dashboard-container create-vm-container"> <div class="row"> <div class="col-sm-6"> <div class="dashboard-container-head"> - <h3 class="dashboard-title-thin"><img src="{% static 'hosting/img/plusVM.svg' %}" class="un-icon" style="margin-top: -18px;width: 42px;height: 42px;"> {% trans "Create VM" %}</h3> - {% if messages %} - <div class="alert alert-warning"> - {% for message in messages %} - <span>{{ message }}</span> - {% endfor %} - </div> - {% endif %} + <h3 class="dashboard-title-thin"><img src="{% static 'hosting/img/plusVM.svg' %}" class="un-icon" style="margin-top: -18px;width: 42px;height: 42px;"> {% trans "Create VM" %}</h3> + {% if messages %} + <div class="alert alert-warning"> + {% for message in messages %} + <span>{{ message }}</span> + {% endfor %} + </div> + {% endif %} </div> </div> <div class="col-sm-6"> <div class="price-calc-section no-padding"> <div class="landing card"> - <img class="img-beta" src="{% static 'datacenterlight/img/beta-img.png' %}" alt=""> <div class="caption"> {% include "hosting/calculator_form.html" %} </div> diff --git a/hosting/views.py b/hosting/views.py index f7d6e414..a61f4e41 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -1,9 +1,11 @@ import uuid +from django import forms from django.conf import settings from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin 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 @@ -25,7 +27,7 @@ from stored_messages.settings import stored_messages_settings from membership.models import CustomUser, StripeCustomer from opennebula_api.models import OpenNebulaManager from opennebula_api.serializers import VirtualMachineSerializer, \ - VirtualMachineTemplateSerializer + VirtualMachineTemplateSerializer, VMTemplateSerializer from utils.forms import BillingAddressForm, PasswordResetRequestForm, \ UserBillingAddressForm from utils.mailer import BaseEmail @@ -36,6 +38,8 @@ from .forms import HostingUserSignupForm, HostingUserLoginForm, \ UserHostingKeyForm, generate_ssh_key_name from .mixins import ProcessVMSelectionMixin from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey +from datacenterlight.models import VMTemplate + CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \ connection error. please try again in a few minutes." @@ -711,7 +715,7 @@ class PaymentVMView(LoginRequiredMixin, FormView): request.get_host()), 'page_header': _( 'Your New VM %(vm_name)s at Data Center Light') % { - 'vm_name': vm.get('name')} + 'vm_name': vm.get('name')} } email_data = { 'subject': context.get('page_header'), @@ -827,48 +831,80 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): template_name = "hosting/create_virtual_machine.html" login_url = reverse_lazy('hosting:login') - def get(self, request, *args, **kwargs): + def validate_cores(self, value): + if (value > 48) or (value < 1): + raise ValidationError(_('Invalid number of cores')) + def validate_memory(self, value): + if (value > 200) or (value < 2): + raise ValidationError(_('Invalid RAM size')) + + def validate_storage(self, value): + if (value > 2000) or (value < 10): + raise ValidationError(_('Invalid storage size')) + + def get(self, request, *args, **kwargs): if not UserHostingKey.objects.filter(user=self.request.user).exists(): messages.success( request, _( - 'In order to create a VM, you need to create/upload your SSH KEY first.') + 'In order to create a VM, you need to' + 'create/upload your SSH KEY first.' + ) ) return HttpResponseRedirect(reverse('hosting:ssh_keys')) - - try: - manager = OpenNebulaManager() - templates = manager.get_templates() - configuration_options = HostingPlan.get_serialized_configs() - - context = { - 'templates': VirtualMachineTemplateSerializer(templates, - many=True).data, - 'configuration_options': configuration_options, - } - except: - messages.error( - request, - 'We could not load the VM templates due to a backend connection \ - error. Please try again in a few minutes' - ) - context = { - 'error': 'connection' - } - + context = {'templates': VMTemplate.objects.all()} return render(request, self.template_name, context) def post(self, request): - manager = OpenNebulaManager() - template_id = request.POST.get('vm_template_id') - template = manager.get_template(template_id) - configuration_id = int(request.POST.get('configuration')) - configuration = HostingPlan.objects.get(id=configuration_id) - request.session['template'] = VirtualMachineTemplateSerializer( - template).data + cores = request.POST.get('cpu') + cores_field = forms.IntegerField(validators=[self.validate_cores]) + memory = request.POST.get('ram') + memory_field = forms.IntegerField(validators=[self.validate_memory]) + storage = request.POST.get('storage') + storage_field = forms.IntegerField(validators=[self.validate_storage]) + price = request.POST.get('total') + template_id = int(request.POST.get('config')) + template = VMTemplate.objects.filter( + opennebula_vm_template_id=template_id).first() + template_data = VMTemplateSerializer(template).data - request.session['specs'] = configuration.serialize() + 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") + + 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") + + 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") + + specs = { + 'cpu': cores, + 'memory': memory, + 'disk_size': storage, + 'price': price + } + + request.session['specs'] = specs + request.session['template'] = template_data return redirect(reverse('hosting:payment')) From 556ed75262087ba55478bfcbbcdf91370db47222 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 20:14:32 +0530 Subject: [PATCH 20/82] translations --- .../locale/de/LC_MESSAGES/django.po | 11 ++- hosting/locale/de/LC_MESSAGES/django.po | 72 +++++++++++++------ .../static/hosting/css/price_calculator.css | 10 +-- hosting/views.py | 2 +- 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 6c9d36ae..4be77f10 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-09-03 16:44+0000\n" +"POT-Creation-Date: 2017-09-15 20:11+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -183,9 +183,18 @@ msgstr "Kontakt" msgid "All Rights Reserved" msgstr "Alle Rechte vorbehalten" +msgid "Toggle navigation" +msgstr "umschalten" + msgid "Why Data Center Light?" msgstr "Warum Data Center Light?" +msgid "Login" +msgstr "Anmelden" + +msgid "Dashboard" +msgstr "Mein Dashboard" + msgid "Finally, an affordable VM hosting in Switzerland!" msgstr "Endlich: bezahlbares VM Hosting in der Schweiz" diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 780419b1..5a72c715 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-09-09 06:04+0000\n" +"POT-Creation-Date: 2017-09-15 20:11+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -100,6 +100,27 @@ msgstr "vorherige" msgid "next" msgstr "nächste" +msgid "days" +msgstr "tage" + +msgid "VAT included" +msgstr "MwSt. inklusive" + +msgid "Please enter a value in range 1 - 48." +msgstr "Bitte gib einen Wert von 1 bis 48 ein." + +msgid "Please enter a value in range 2 - 200." +msgstr "Bitte gib einen Wert von 2 bis 200 ein." + +msgid "Please enter a value in range 10 - 2000." +msgstr "Bitte gib einen Wert von 10 bis 200 ein." + +msgid "GB Storage (SSD)" +msgstr "GB Storage (SSD)" + +msgid "Continue" +msgstr "Weiter" + msgid "SSH Key" msgstr "SSH Key" @@ -139,30 +160,12 @@ msgstr "Hast Du bereits ein Benutzerkonto?" msgid "Login" msgstr "Anmelden" -msgid "New Virtual Machine" -msgstr "Neue virtuelle Maschine" - -msgid "Step 1. Select VM Template:" -msgstr "Wähle eine Vorlage" - -msgid "Step2. Select VM Configuration" -msgstr "Wähle eine Konfiguration" - -msgid "Price " -msgstr "Preis" - -msgid "CHF/Month" -msgstr "CHF/Monat" - -msgid "Start VM" -msgstr "VM jetzt starten" +msgid "Create VM" +msgstr "VM erstellen" msgid "My Dashboard" msgstr "Mein Dashboard" -msgid "Create VM" -msgstr "VM erstellen" - msgid "My VMs" msgstr "Meine VMs" @@ -619,6 +622,15 @@ msgid "In order to create a VM, you need to create/upload your SSH KEY first." msgstr "" "Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen." +msgid "Invalid number of cores" +msgstr "Ungültige Anzahle CPU-Kerne" + +msgid "Invalid RAM size" +msgstr "Ungültige RAM-Grösse" + +msgid "Invalid storage size" +msgstr "Ungültige Speicher-Grösse" + msgid "" "We could not find the requested VM. Please " "contact Data Center Light Support." @@ -631,6 +643,24 @@ msgstr "VM Kündigung" msgid "VM %(VM_ID)s terminated successfully" msgstr "VM %(VM_ID)s erfolgreich beendet" +#~ msgid "New Virtual Machine" +#~ msgstr "Neue virtuelle Maschine" + +#~ msgid "Step 1. Select VM Template:" +#~ msgstr "Wähle eine Vorlage" + +#~ msgid "Step2. Select VM Configuration" +#~ msgstr "Wähle eine Konfiguration" + +#~ msgid "Price " +#~ msgstr "Preis" + +#~ msgid "CHF/Month" +#~ msgstr "CHF/Monat" + +#~ msgid "Start VM" +#~ msgstr "VM jetzt starten" + #~ msgid "My Virtual Machines" #~ msgstr "Meine virtuellen Maschinen" diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index 5aac2c97..43daa713 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -193,21 +193,21 @@ margin: 0 8px; } -.help-block.with-errors { +.price-calc-section .help-block.with-errors { text-align: center; margin: 0 0; padding: 0 0 5px; } -.help-block.with-errors ul { +.price-calc-section .help-block.with-errors ul { margin-bottom: 0; } -.form-group { +.price-calc-section .form-group { margin: 0; position: relative; } -.form-group:after { +.price-calc-section .form-group:after { content: ' '; display: block; position: absolute; @@ -219,7 +219,7 @@ background: rgba(128, 128, 128, 0.2); } -.btn-primary { +.price-calc-section .btn-primary { background: #29427A; border-color: #29427A; color: #fff; diff --git a/hosting/views.py b/hosting/views.py index a61f4e41..75162536 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -848,7 +848,7 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): messages.success( request, _( - 'In order to create a VM, you need to' + 'In order to create a VM, you need to ' 'create/upload your SSH KEY first.' ) ) From 2de0fc13b9c4506489a33cf75daa026eac4f4f1e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Fri, 15 Sep 2017 20:17:54 +0530 Subject: [PATCH 21/82] translation fix --- datacenterlight/locale/de/LC_MESSAGES/django.po | 2 +- hosting/locale/de/LC_MESSAGES/django.po | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 4be77f10..fe120a25 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -193,7 +193,7 @@ msgid "Login" msgstr "Anmelden" msgid "Dashboard" -msgstr "Mein Dashboard" +msgstr "Dashboard" msgid "Finally, an affordable VM hosting in Switzerland!" msgstr "Endlich: bezahlbares VM Hosting in der Schweiz" diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 5a72c715..0c031b6a 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -279,7 +279,7 @@ msgstr "" "%(base_url)s%(my_virtual_machines_url)s\n" msgid "Toggle navigation" -msgstr "Konfiguration" +msgstr "Umschalten" msgid "Dashboard" msgstr "Mein Dashboard" From 772469a23e4a6a5362ba5f2f20ef331c1900c0ea Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Mon, 18 Sep 2017 19:49:14 +0530 Subject: [PATCH 22/82] design modifications --- datacenterlight/locale/de/LC_MESSAGES/django.po | 2 +- hosting/locale/de/LC_MESSAGES/django.po | 12 ++++++------ hosting/static/hosting/css/price_calculator.css | 4 +++- hosting/templates/hosting/calculator_form.html | 2 +- .../templates/hosting/create_virtual_machine.html | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index fe120a25..234f2a3b 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-09-15 20:11+0530\n" +"POT-Creation-Date: 2017-09-17 01:31+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 0c031b6a..c7a13e34 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-09-15 20:11+0530\n" +"POT-Creation-Date: 2017-09-17 01:31+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -100,8 +100,8 @@ msgstr "vorherige" msgid "next" msgstr "nächste" -msgid "days" -msgstr "tage" +msgid "Month" +msgstr "Monat" msgid "VAT included" msgstr "MwSt. inklusive" @@ -380,9 +380,6 @@ msgstr "Konfiguration" msgid "including VAT" msgstr "inkl. Mehrwertsteuer" -msgid "Month" -msgstr "Monat" - msgid "Billing Address" msgstr "Rechnungsadresse" @@ -643,6 +640,9 @@ msgstr "VM Kündigung" msgid "VM %(VM_ID)s terminated successfully" msgstr "VM %(VM_ID)s erfolgreich beendet" +#~ msgid "days" +#~ msgstr "tage" + #~ msgid "New Virtual Machine" #~ msgstr "Neue virtuelle Maschine" diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index 43daa713..e1ea2a5f 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -116,7 +116,7 @@ color: #29427a; cursor: pointer; font-size: 20px; - border: 1px solid #eee; + border: 1px solid #ccc; padding: 5px 6px 3px; border-radius: 5px; } @@ -229,5 +229,7 @@ @media(min-width: 768px) { .create-vm-container { padding-top: 120px; + max-width: 1120px; + /* width: 100%; */ } } diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html index 5ba2a4c3..879f2054 100644 --- a/hosting/templates/hosting/calculator_form.html +++ b/hosting/templates/hosting/calculator_form.html @@ -3,7 +3,7 @@ {% csrf_token %} <div class="price"> <span id="total">15</span> - <span>CHF/30 {% trans "days" %}</span> + <span>CHF/{% trans "Month" %}</span> <div class="price-text"> <p>{% trans "VAT included" %}</p> </div> diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index dff82199..5f61eae8 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -4,7 +4,7 @@ {% block content %} <div class="dashboard-container create-vm-container"> <div class="row"> - <div class="col-sm-6"> + <div class="col-sm-4"> <div class="dashboard-container-head"> <h3 class="dashboard-title-thin"><img src="{% static 'hosting/img/plusVM.svg' %}" class="un-icon" style="margin-top: -18px;width: 42px;height: 42px;"> {% trans "Create VM" %}</h3> {% if messages %} @@ -16,7 +16,7 @@ {% endif %} </div> </div> - <div class="col-sm-6"> + <div class="col-sm-5"> <div class="price-calc-section no-padding"> <div class="landing card"> <div class="caption"> From b276194f31cbacb41aaa6702181a9a617f98b98d Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Mon, 18 Sep 2017 20:18:02 +0530 Subject: [PATCH 23/82] width normalized --- hosting/static/hosting/css/price_calculator.css | 2 -- hosting/templates/hosting/create_virtual_machine.html | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index e1ea2a5f..310a9d05 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -229,7 +229,5 @@ @media(min-width: 768px) { .create-vm-container { padding-top: 120px; - max-width: 1120px; - /* width: 100%; */ } } diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index 5f61eae8..aff7862a 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -16,7 +16,7 @@ {% endif %} </div> </div> - <div class="col-sm-5"> + <div class="col-sm-6"> <div class="price-calc-section no-padding"> <div class="landing card"> <div class="caption"> From 226f744bae4307c6b4fd984614340430d1a61d69 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Mon, 18 Sep 2017 21:52:59 +0530 Subject: [PATCH 24/82] success modal added --- .../hosting/js/virtual_machine_detail.js | 2 +- .../hosting/virtual_machine_detail.html | 19 ++++++++++++++++++- hosting/views.py | 12 ++++++++---- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index d6387dbc..711b486b 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -27,7 +27,7 @@ function VMTerminateSuccess($container, data) { $container.addClass('terminate-success') .find('.vm-item-lg').text(data.text); $container.find('.btn').remove(); - window.location = data.redirect; + $('#terminate-success').modal('show'); } function VMTerminateFail($container, data, text) { diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index d0bfae47..9d77c31d 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -103,7 +103,7 @@ </div> <div class="modal-body"> <div class="modal-icon"><i class="fa fa-ban" aria-hidden="true"></i></div> - <h4 class="modal-title" id="ModalLabel">{% trans "Terminate your Virtual Machine"%}</h4> + <h4 class="modal-title" id="ModalLabel">{% trans "Terminate your Virtual Machine" %}</h4> <div class="modal-text"> <p>{% trans "Do you want to cancel your Virtual Machine" %} ?</p> <p><strong>{{virtual_machine.name}}</strong></p> @@ -116,4 +116,21 @@ </div> </div> <!-- / Cancel Modal --> + <!-- Success Modal --> + <div class="modal fade" id="terminate-success" tabindex="-1" role="dialog" aria-hidden="true"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + </div> + <div class="modal-body"> + <div class="modal-icon"><i class="fa fa-ban" aria-hidden="true"></i></div> + <h4 class="modal-title" id="ModalLabel">{% trans "Your Virtual Machine" %} {{vm.id}} {% trans "was successfully terminated!" %}</h4> + <div class="modal-footer"> + <a href="{% url 'hosting:virtual_machines' %}" class="btn btn-danger btn-wide">{% trans "Close" %}</a> + </div> + </div> + </div> + </div> + </div> + <!-- / Cancel Modal --> {%endblock%} diff --git a/hosting/views.py b/hosting/views.py index acd7e67b..8356d5ad 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -961,7 +961,13 @@ class VirtualMachineView(LoginRequiredMixin, View): password=owner.password ) - vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data + try: + vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data + except BaseException: + return redirect( + reverse('hosting:virtual_machines', + kwargs={'pk': opennebula_vm_id}) + ) terminated = manager.delete_vm(vm.id) @@ -971,12 +977,10 @@ class VirtualMachineView(LoginRequiredMixin, View): else: for t in range(15): try: - manager.get_vm(self.kwargs.get('pk')) + manager.get_vm(opennebula_vm_id) except WrongIdError: response['status'] = True - response['redirect'] = self.get_success_url() response['text'] = ugettext('Terminated') - self.send_mail() break except BaseException: break From 43300c72269faa80983c38aa43a20ccd3f1f4d4f Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Mon, 18 Sep 2017 23:21:04 +0530 Subject: [PATCH 25/82] translations added, modal fixed --- hosting/locale/de/LC_MESSAGES/django.po | 20 +++++++++------ .../hosting/js/virtual_machine_detail.js | 1 - .../hosting/virtual_machine_detail.html | 25 +++++++++++-------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 1c0f3faa..ca78a381 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-09-14 12:27+0000\n" +"POT-Creation-Date: 2017-09-18 23:16+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -575,6 +575,15 @@ msgstr "Bist Du sicher, dass Du Deine virtuelle Maschine beenden willst" msgid "OK" msgstr "" +msgid "Your Virtual Machine" +msgstr "Deine Maschinen Detail" + +msgid "was successfully terminated!" +msgstr "wurde erfolgreich beendet!" + +msgid "Close" +msgstr "Schliessen" + msgid "Virtual Machines" msgstr "Virtuelle Maschinen" @@ -645,12 +654,12 @@ msgstr "Kontaktiere den Data Center Light Support." msgid "Error terminating VM" msgstr "Fehler beenden VM" -msgid "Virtual Machine Cancellation" -msgstr "VM Kündigung" - msgid "Terminated" msgstr "Beendet" +msgid "Virtual Machine Cancellation" +msgstr "VM Kündigung" + #~ msgid "VM %(VM_ID)s terminated successfully" #~ msgstr "VM %(VM_ID)s erfolgreich beendet" @@ -702,9 +711,6 @@ msgstr "Beendet" #~ msgid "Ipv6" #~ msgstr "IPv6" -#~ msgid "Close" -#~ msgstr "Schliessen" - #~ msgid "Cancel" #~ msgstr "Beenden" diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 711b486b..e611246b 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -40,7 +40,6 @@ function VMTerminateFail($container, data, text) { $(document).ready(function() { - $('#confirm-cancel').on('click', '.btn-ok', function(e) { var url = $('#virtual_machine_cancel_form').attr('action'); var $container = $('#terminate-VM'); diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index 9d77c31d..08872c1e 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -96,24 +96,24 @@ </div> <!-- Cancel Modal --> <div class="modal fade" id="confirm-cancel" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> - <div class="modal-dialog"> - <div class="modal-content"> + <div class="modal-dialog"> + <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Confirm"><span aria-hidden="true">×</span></button> </div> - <div class="modal-body"> + <div class="modal-body"> <div class="modal-icon"><i class="fa fa-ban" aria-hidden="true"></i></div> <h4 class="modal-title" id="ModalLabel">{% trans "Terminate your Virtual Machine" %}</h4> <div class="modal-text"> <p>{% trans "Do you want to cancel your Virtual Machine" %} ?</p> <p><strong>{{virtual_machine.name}}</strong></p> </div> - <div class="modal-footer"> - <a class="btn btn-danger btn-ok btn-wide">{% trans "OK" %}</a> - </div> - </div> - </div> - </div> + <div class="modal-footer"> + <a class="btn btn-danger btn-ok btn-wide">{% trans "OK" %}</a> + </div> + </div> + </div> + </div> </div> <!-- / Cancel Modal --> <!-- Success Modal --> @@ -123,10 +123,13 @@ <div class="modal-header"> </div> <div class="modal-body"> - <div class="modal-icon"><i class="fa fa-ban" aria-hidden="true"></i></div> + <div class="modal-icon"><i class="fa fa-check" aria-hidden="true"></i></div> <h4 class="modal-title" id="ModalLabel">{% trans "Your Virtual Machine" %} {{vm.id}} {% trans "was successfully terminated!" %}</h4> + <div class="modal-text"> + <p><strong>{{virtual_machine.name}}</strong></p> + </div> <div class="modal-footer"> - <a href="{% url 'hosting:virtual_machines' %}" class="btn btn-danger btn-wide">{% trans "Close" %}</a> + <a href="{% url 'hosting:virtual_machines' %}" class="btn btn-success btn-wide">{% trans "Close" %}</a> </div> </div> </div> From 8db7ead9e272e2c9536c31e245d2765915bcf1c3 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 00:24:06 +0530 Subject: [PATCH 26/82] checking VM termination error --- hosting/views.py | 5 +++-- opennebula_api/models.py | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index 8356d5ad..5f123dd4 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -969,11 +969,12 @@ class VirtualMachineView(LoginRequiredMixin, View): kwargs={'pk': opennebula_vm_id}) ) - terminated = manager.delete_vm(vm.id) + terminated, err = manager.delete_vm(vm.id) if not terminated: response['text'] = ugettext( - 'Error terminating VM') + opennebula_vm_id + 'Error terminating VM') + opennebula_vm_id + '\n' + + err else: for t in range(15): try: diff --git a/opennebula_api/models.py b/opennebula_api/models.py index d584bf26..9eb89fdf 100644 --- a/opennebula_api/models.py +++ b/opennebula_api/models.py @@ -324,6 +324,7 @@ class OpenNebulaManager(): def delete_vm(self, vm_id): TERMINATE_ACTION = 'terminate' vm_terminated = False + err = '' try: self.oneadmin_client.call( oca.VirtualMachine.METHODS['action'], @@ -333,15 +334,19 @@ class OpenNebulaManager(): vm_terminated = True except socket.timeout as socket_err: logger.info("Socket timeout error: {0}".format(socket_err)) + err = ("Socket timeout error: {0}".format(socket_err)) except OpenNebulaException as opennebula_err: logger.info( "OpenNebulaException error: {0}".format(opennebula_err)) + err = ("OpenNebulaException error: {0}".format(opennebula_err)) except OSError as os_err: logger.info("OSError : {0}".format(os_err)) + err = ("OSError : {0}".format(os_err)) except ValueError as value_err: logger.info("ValueError : {0}".format(value_err)) + err = ("ValueError : {0}".format(value_err)) - return vm_terminated + return (vm_terminated, err) def _get_template_pool(self): try: From 61bf15823861fd45a06b0cafdf399ff73d4189ac Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 00:25:38 +0530 Subject: [PATCH 27/82] fix --- hosting/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index 5f123dd4..8e01bb22 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -973,8 +973,7 @@ class VirtualMachineView(LoginRequiredMixin, View): if not terminated: response['text'] = ugettext( - 'Error terminating VM') + opennebula_vm_id + '\n' + - err + 'Error terminating VM') + opennebula_vm_id + '\n' + err else: for t in range(15): try: From 78423c83e3721da584f917ea6521969e38d68d5d Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 00:59:51 +0530 Subject: [PATCH 28/82] removed error details from error msg --- hosting/static/hosting/js/virtual_machine_detail.js | 1 + hosting/views.py | 4 ++-- opennebula_api/models.py | 7 +------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index e611246b..76c00a91 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -1,6 +1,7 @@ function VMTerminateStatus($container, url) { $.ajax({ url: url, + type: 'GET', dataType: 'json', success: function(data) { VMTerminateSuccess($container, data); diff --git a/hosting/views.py b/hosting/views.py index 8e01bb22..8356d5ad 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -969,11 +969,11 @@ class VirtualMachineView(LoginRequiredMixin, View): kwargs={'pk': opennebula_vm_id}) ) - terminated, err = manager.delete_vm(vm.id) + terminated = manager.delete_vm(vm.id) if not terminated: response['text'] = ugettext( - 'Error terminating VM') + opennebula_vm_id + '\n' + err + 'Error terminating VM') + opennebula_vm_id else: for t in range(15): try: diff --git a/opennebula_api/models.py b/opennebula_api/models.py index 9eb89fdf..d584bf26 100644 --- a/opennebula_api/models.py +++ b/opennebula_api/models.py @@ -324,7 +324,6 @@ class OpenNebulaManager(): def delete_vm(self, vm_id): TERMINATE_ACTION = 'terminate' vm_terminated = False - err = '' try: self.oneadmin_client.call( oca.VirtualMachine.METHODS['action'], @@ -334,19 +333,15 @@ class OpenNebulaManager(): vm_terminated = True except socket.timeout as socket_err: logger.info("Socket timeout error: {0}".format(socket_err)) - err = ("Socket timeout error: {0}".format(socket_err)) except OpenNebulaException as opennebula_err: logger.info( "OpenNebulaException error: {0}".format(opennebula_err)) - err = ("OpenNebulaException error: {0}".format(opennebula_err)) except OSError as os_err: logger.info("OSError : {0}".format(os_err)) - err = ("OSError : {0}".format(os_err)) except ValueError as value_err: logger.info("ValueError : {0}".format(value_err)) - err = ("ValueError : {0}".format(value_err)) - return (vm_terminated, err) + return vm_terminated def _get_template_pool(self): try: From 3ef07758effebf0fdea8c4e1bc6a904a35a02fed Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 01:08:27 +0530 Subject: [PATCH 29/82] translation and text fix --- hosting/locale/de/LC_MESSAGES/django.po | 14 +++++++------- .../templates/hosting/virtual_machine_detail.html | 2 +- hosting/views.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index ca78a381..cd47faa3 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-09-18 23:16+0530\n" +"POT-Creation-Date: 2017-09-19 01:04+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -575,10 +575,10 @@ msgstr "Bist Du sicher, dass Du Deine virtuelle Maschine beenden willst" msgid "OK" msgstr "" -msgid "Your Virtual Machine" -msgstr "Deine Maschinen Detail" +msgid "Your virtual machine" +msgstr "Deine Virtuelle Machine (VM)" -msgid "was successfully terminated!" +msgid "is successfully terminated!" msgstr "wurde erfolgreich beendet!" msgid "Close" @@ -651,12 +651,12 @@ msgid "" "contact Data Center Light Support." msgstr "Kontaktiere den Data Center Light Support." -msgid "Error terminating VM" -msgstr "Fehler beenden VM" - msgid "Terminated" msgstr "Beendet" +msgid "Error terminating VM" +msgstr "Fehler beenden VM" + msgid "Virtual Machine Cancellation" msgstr "VM Kündigung" diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index 08872c1e..d2d23db8 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -124,7 +124,7 @@ </div> <div class="modal-body"> <div class="modal-icon"><i class="fa fa-check" aria-hidden="true"></i></div> - <h4 class="modal-title" id="ModalLabel">{% trans "Your Virtual Machine" %} {{vm.id}} {% trans "was successfully terminated!" %}</h4> + <h4 class="modal-title" id="ModalLabel">{% trans "Your Virtual Machine" %} {{vm.id}} {% trans "is successfully terminated!" %}</h4> <div class="modal-text"> <p><strong>{{virtual_machine.name}}</strong></p> </div> diff --git a/hosting/views.py b/hosting/views.py index 8356d5ad..107e0b7b 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -929,7 +929,7 @@ class VirtualMachineView(LoginRequiredMixin, View): pass storage.used = True return HttpResponse( - json.dumps({'redirect': self.get_success_url()}), + json.dumps({'text': ugettext('Terminated')}), content_type="application/json" ) else: From e893f1baf170fd12f8caec3349c93b4361123681 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 01:17:15 +0530 Subject: [PATCH 30/82] padding fix --- hosting/static/hosting/css/price_calculator.css | 8 ++++++-- hosting/templates/hosting/calculator_form.html | 2 +- hosting/templates/hosting/create_virtual_machine.html | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index 310a9d05..24624f10 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -45,13 +45,17 @@ background: #fff; box-shadow: 1px 3px 6px 2px rgba(0, 0, 0, 0.2); padding-bottom: 30px; - /* border-radius: 7px; */ text-align: center; - /* margin-right: auto; */ max-width: 320px; position: relative; } +@media (min-width: 768px) { + .price-calc-section .card { + margin-left: 0; + } +} + .price-calc-section .landing { width: 100% !important; } diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html index 879f2054..18bdd3cb 100644 --- a/hosting/templates/hosting/calculator_form.html +++ b/hosting/templates/hosting/calculator_form.html @@ -5,7 +5,7 @@ <span id="total">15</span> <span>CHF/{% trans "Month" %}</span> <div class="price-text"> - <p>{% trans "VAT included" %}</p> + <span>{% trans "VAT included" %}</span> </div> </div> <div class="descriptions"> diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index aff7862a..4ba5274e 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -4,7 +4,7 @@ {% block content %} <div class="dashboard-container create-vm-container"> <div class="row"> - <div class="col-sm-4"> + <div class="col-sm-5"> <div class="dashboard-container-head"> <h3 class="dashboard-title-thin"><img src="{% static 'hosting/img/plusVM.svg' %}" class="un-icon" style="margin-top: -18px;width: 42px;height: 42px;"> {% trans "Create VM" %}</h3> {% if messages %} From c53c9661365576cd39c1805b0cbbeca257fb92e0 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 14:24:23 +0530 Subject: [PATCH 31/82] success modal modification --- hosting/locale/de/LC_MESSAGES/django.po | 17 ++++++++--------- .../hosting/virtual_machine_detail.html | 7 ++----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index cd47faa3..3d824deb 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-09-19 01:04+0530\n" +"POT-Creation-Date: 2017-09-19 14:20+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -575,14 +575,10 @@ msgstr "Bist Du sicher, dass Du Deine virtuelle Maschine beenden willst" msgid "OK" msgstr "" -msgid "Your virtual machine" -msgstr "Deine Virtuelle Machine (VM)" - -msgid "is successfully terminated!" -msgstr "wurde erfolgreich beendet!" - -msgid "Close" -msgstr "Schliessen" +#, python-format +msgid "" +"Your Virtual Machine %(virtual_machine.name)s is successfully terminated!" +msgstr "Deine Virtuelle Machine (VM) %(virtual_machine.name)s wurde erfolgreich beendet!" msgid "Virtual Machines" msgstr "Virtuelle Maschinen" @@ -660,6 +656,9 @@ msgstr "Fehler beenden VM" msgid "Virtual Machine Cancellation" msgstr "VM Kündigung" +#~ msgid "Close" +#~ msgstr "Schliessen" + #~ msgid "VM %(VM_ID)s terminated successfully" #~ msgstr "VM %(VM_ID)s erfolgreich beendet" diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index d2d23db8..33c5bf2a 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -124,12 +124,9 @@ </div> <div class="modal-body"> <div class="modal-icon"><i class="fa fa-check" aria-hidden="true"></i></div> - <h4 class="modal-title" id="ModalLabel">{% trans "Your Virtual Machine" %} {{vm.id}} {% trans "is successfully terminated!" %}</h4> - <div class="modal-text"> - <p><strong>{{virtual_machine.name}}</strong></p> - </div> + <h4 class="modal-title" id="ModalLabel">{% blocktrans %}Your Virtual Machine <strong>{{virtual_machine.name}}asdas</strong> is successfully terminated!{% endblocktrans %}</h4> <div class="modal-footer"> - <a href="{% url 'hosting:virtual_machines' %}" class="btn btn-success btn-wide">{% trans "Close" %}</a> + <a href="{% url 'hosting:virtual_machines' %}" class="btn btn-success btn-wide">{% trans "OK" %}</a> </div> </div> </div> From 445359e1ed3c9319118004a265403975fe83561e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 14:29:18 +0530 Subject: [PATCH 32/82] modal restyle --- hosting/static/hosting/css/commons.css | 4 ++++ hosting/templates/hosting/virtual_machine_detail.html | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hosting/static/hosting/css/commons.css b/hosting/static/hosting/css/commons.css index 01ff5090..a922174c 100644 --- a/hosting/static/hosting/css/commons.css +++ b/hosting/static/hosting/css/commons.css @@ -139,6 +139,10 @@ .modal-text p:not(:last-of-type){ margin-bottom: 5px; } + +.modal-title + .modal-footer { + margin-top: 5px; +} .modal-footer { border-top: 0px solid #e5e5e5; width: 100%; diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index 33c5bf2a..e91fd0eb 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -124,7 +124,7 @@ </div> <div class="modal-body"> <div class="modal-icon"><i class="fa fa-check" aria-hidden="true"></i></div> - <h4 class="modal-title" id="ModalLabel">{% blocktrans %}Your Virtual Machine <strong>{{virtual_machine.name}}asdas</strong> is successfully terminated!{% endblocktrans %}</h4> + <h4 class="modal-title" id="ModalLabel">{% blocktrans %}Your Virtual Machine <strong>{{virtual_machine.name}}</strong> is successfully terminated!{% endblocktrans %}</h4> <div class="modal-footer"> <a href="{% url 'hosting:virtual_machines' %}" class="btn btn-success btn-wide">{% trans "OK" %}</a> </div> From 04126c69eeb2769d1cceaffa0b00b4bff181d8f8 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 14:34:53 +0530 Subject: [PATCH 33/82] vm name added --- hosting/templates/hosting/virtual_machine_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index e91fd0eb..06d86032 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -124,7 +124,7 @@ </div> <div class="modal-body"> <div class="modal-icon"><i class="fa fa-check" aria-hidden="true"></i></div> - <h4 class="modal-title" id="ModalLabel">{% blocktrans %}Your Virtual Machine <strong>{{virtual_machine.name}}</strong> is successfully terminated!{% endblocktrans %}</h4> + <h4 class="modal-title" id="ModalLabel">{% blocktrans with machine_name=virtual_machine.name %}Your Virtual Machine <strong>{{machine_name}}</strong> is successfully terminated!{% endblocktrans %}</h4> <div class="modal-footer"> <a href="{% url 'hosting:virtual_machines' %}" class="btn btn-success btn-wide">{% trans "OK" %}</a> </div> From 98f094e5b850daa09b8575670eee6ce3cfd6812b Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Tue, 19 Sep 2017 15:03:06 +0530 Subject: [PATCH 34/82] initial changes --- hosting/static/hosting/css/order.css | 2 +- hosting/static/hosting/img/icon-pdf.svg | 18 ++ hosting/static/hosting/img/icon-print.svg | 17 ++ .../hosting/includes/_navbar_user.html | 6 +- hosting/templates/hosting/order_detail.html | 287 +++++++++--------- hosting/urls.py | 3 +- 6 files changed, 180 insertions(+), 153 deletions(-) create mode 100644 hosting/static/hosting/img/icon-pdf.svg create mode 100644 hosting/static/hosting/img/icon-print.svg diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index e8bc0328..f2f7993b 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -1,4 +1,4 @@ -.order-detail-container {padding-top: 70px; padding-bottom: 70px; margin-bottom: 70px;} +.order-detail-container {padding-top: 70px;padding-bottom: 70px;/* margin-bottom: 70px; */max-width: 720px;margin: 0 auto;} .order-detail-container .invoice-title h2, .invoice-title h3 { display: inline-block; diff --git a/hosting/static/hosting/img/icon-pdf.svg b/hosting/static/hosting/img/icon-pdf.svg new file mode 100644 index 00000000..20fc9c48 --- /dev/null +++ b/hosting/static/hosting/img/icon-pdf.svg @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="492px" height="649px" viewBox="0 0 492 649" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch --> + <title>icon-pdf</title> + <desc>Created with Sketch.</desc> + <defs></defs> + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="icon-pdf" fill-rule="nonzero" fill="#000000"> + <g id="Group" transform="translate(93.000000, 269.000000)"> + <path d="M98,47.8 C98,54.8 97,61.7 95.1,66.6 C93.1,72.5 90.1,76.5 86.2,80.5 C82.2,84.5 76.3,87.4 70.4,89.4 C64.5,91.4 55.6,92.3 46.6,92.3 L34.7,92.3 L34.7,134 L0,134 L0,0.3 L45.5,0.3 C54.4,0.3 62.4,1.3 69.3,3.2 C76.2,5.2 81.2,8.2 85.1,12.1 C89.1,16.1 92.1,21 94,27 C96.9,32 98,38.9 98,47.8 Z M61.3,46.8 C61.3,42.8 61.3,39.9 60.3,37.9 C60.3,35.9 59.3,33.9 57.4,32 C56.4,31 54.5,30 52.4,29.1 C50.4,29.1 47.4,28.1 44.5,28.1 L34.6,28.1 L34.6,63.7 L45.5,63.7 C48.4,63.7 50.4,63.7 52.5,62.7 C54.5,61.7 56.5,61.7 57.5,59.8 C58.5,57.8 59.5,56.9 60.4,54.8 C61.3,53.8 61.3,50.8 61.3,46.8 Z" id="Shape"></path> + <path d="M214.8,66.6 C214.8,78.5 213.8,89.3 210.8,97.3 C208.8,106.2 204.9,113.1 199.9,118.1 C195,123.1 189,127 182.1,130 C175.2,132 167.3,134 157.3,134 L108.8,134 L108.8,0.3 L156.3,0.3 C166.2,0.3 175.1,1.3 182,4.3 C188.9,7.2 194.9,10.2 199.8,16.2 C204.8,21.2 207.7,28.1 209.7,37 C213.8,44.8 214.8,54.7 214.8,66.6 Z M178.1,65.6 C178.1,58.7 178.1,52.7 177.1,47.8 C176.1,42.8 175.1,39.9 174.2,36.9 C172.2,34 170.2,32.9 168.3,31.9 C165.4,30.9 162.4,30.9 158.4,30.9 L145.6,30.9 L145.6,103.2 L158.4,103.2 C162.4,103.2 165.4,103.2 168.3,102.2 C171.2,101.2 173.3,99.3 174.2,97.2 C176.2,94.3 177.1,91.3 178.2,86.3 C178.1,80.5 178.1,74.5 178.1,65.6 Z" id="Shape"></path> + <polygon id="Shape" points="264.3 32 264.3 55.8 304.9 55.8 304.9 85.5 264.3 85.5 264.3 135 229.7 135 229.7 0.3 312.9 0.3 313.9 31 264.4 31 264.4 32"></polygon> + </g> + <path d="M491.3,649 L0.7,649 L0.7,0 L346.1,0 L491.3,145.2 L491.3,649 L491.3,649 Z M44.7,605 L448.4,605 L448.4,162.8 L327.4,42.9 L44.7,42.9 L44.7,605 Z" id="Shape"></path> + <polygon id="Shape" points="469.3 176 315.3 176 315.3 20.9 359.3 20.9 359.3 132 469.3 132"></polygon> + </g> + </g> +</svg> \ No newline at end of file diff --git a/hosting/static/hosting/img/icon-print.svg b/hosting/static/hosting/img/icon-print.svg new file mode 100644 index 00000000..e440f326 --- /dev/null +++ b/hosting/static/hosting/img/icon-print.svg @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="612px" height="612px" viewBox="0 0 612 612" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch --> + <title>54471</title> + <desc>Created with Sketch.</desc> + <defs></defs> + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="54471" fill-rule="nonzero" fill="#000000"> + <path d="M0,225.633 L0,386.367 C0,417.272 30.6,417.272 30.6,417.272 L83.454,417.272 L83.454,389.454 L27.818,389.454 L27.818,222.545 L584.181,222.545 L584.181,389.454 L528.545,389.454 L528.545,417.272 L581.4,417.272 C581.4,417.272 612,417.272 612,386.367 L612,225.633 C612,225.633 612,194.727 581.4,194.727 L30.6,194.727 C0,194.728 0,225.633 0,225.633 Z" id="Shape"></path> + <polygon id="Shape" points="500.728 166.909 500.728 0 111.273 0 111.273 166.909 139.091 166.909 139.091 27.818 472.909 27.818 472.909 166.909"></polygon> + <path d="M528.546,292.091 C528.546,278.182 514.358,278.182 514.358,278.182 L97.642,278.182 C97.642,278.182 83.455,278.182 83.455,292.091 C83.455,306 97.642,306 97.642,306 L514.359,306 C514.358,306 528.546,306 528.546,292.091 Z" id="Shape"></path> + <rect id="Rectangle-path" x="166.909" y="500.728" width="278.182" height="27.818"></rect> + <path d="M500.728,612 L500.728,389.454 L111.273,389.454 L111.273,612 L500.728,612 Z M139.091,417.272 L472.909,417.272 L472.909,584.181 L139.091,584.181 L139.091,417.272 Z" id="Shape"></path> + <rect id="Rectangle-path" x="166.909" y="445.091" width="278.182" height="27.818"></rect> + </g> + </g> +</svg> \ No newline at end of file diff --git a/hosting/templates/hosting/includes/_navbar_user.html b/hosting/templates/hosting/includes/_navbar_user.html index d06477ca..126dd1e6 100644 --- a/hosting/templates/hosting/includes/_navbar_user.html +++ b/hosting/templates/hosting/includes/_navbar_user.html @@ -37,11 +37,7 @@ </li> <li> {% get_current_language as LANGUAGE_CODE %} - {% if LANGUAGE_CODE == 'en-us'%} - <a href="{% change_lang 'de' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> Deutsch</a> - {% else %} - <a href="{% change_lang 'en-us' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> English</a> - {% endif %} + </li> </ul> </div> diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 39c59808..f07aa998 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -7,168 +7,163 @@ <div class="order-detail-container"> {% if messages %} - <div class="row"> - <div class="col-xs-12 col-md-8 col-md-offset-2"> - <br/> - <div class="alert alert-warning"> - {% for message in messages %} - <span>{{ message }}</span> - {% endfor %} - </div> + <div class="alert alert-warning"> + {% for message in messages %} + <span>{{ message }}</span> + {% endfor %} </div> - </div> {% endif %} {% if not error %} - <div class="row"> - <div class="col-xs-12 col-md-8 col-md-offset-2"> - <div class="invoice-title"> - <h2>{{page_header_text}}</h2> - <h3 class="pull-right"> - {% if order %} - {% trans "Order #"%} {{order.id}} - {% endif %} - </h3> - </div> - <hr> - <div class="row"> - <div class="col-xs-12 col-md-6 pull-right order-confirm-date"> - <address> - <strong>{% trans "Date"%}:</strong><br> - <span id="order-created_at"> - {% if order %} - {{order.created_at|date:'Y-m-d H:i'}} - {% else %} - {% now "Y-m-d H:i" %} - {% endif %} - </span><br><br> + <div class="row"> + <div class="col-xs-12 col-md-8 col-md-offset-2"> + <div class="invoice-title"> + <h2>{{page_header_text}}</h2> + <h3 class="pull-right"> {% if order %} - <strong>{% trans "Status:"%}</strong><br> - {% if order.status == 'Approved' %} - <strong class="text-success"> - {% trans "Approved" %} - </strong> - {% else %} - <strong class="text-danger"> - {% trans "Declined" %} - </strong> + {% trans "Order #"%} {{order.id}} {% endif %} - <br><br> - {% endif %} - </address> + </h3> + </div> + <hr> + <div class="row"> + <div class="col-xs-12 col-md-6 pull-right order-confirm-date"> + <address> + <strong>{% trans "Date"%}:</strong><br> + <span id="order-created_at"> + {% if order %} + {{order.created_at|date:'Y-m-d H:i'}} + {% else %} + {% now "Y-m-d H:i" %} + {% endif %} + </span><br><br> + {% if order %} + <strong>{% trans "Status:"%}</strong><br> + {% if order.status == 'Approved' %} + <strong class="text-success"> + {% trans "Approved" %} + </strong> + {% else %} + <strong class="text-danger"> + {% trans "Declined" %} + </strong> + {% endif %} + <br><br> + {% endif %} + </address> + + </div> + <div class="col-xs-12 col-md-6"> + <address> + <h3><b>{% trans "Billed To:"%}</b></h3> + {% if order %} + {{user.name}}<br> + {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> + {{order.billing_address.city}}, + {{order.billing_address.country}}. + {% else %} + {% with request.session.billing_address_data as billing_address %} + {{billing_address.cardholder_name}}<br> + {{billing_address.street_address}}, + {{billing_address.postal_code}}<br> + {{billing_address.city}}, + {{billing_address.country}}. + {% endwith %} + {% endif %} + </address> + </div> </div> - <div class="col-xs-12 col-md-6"> - <address> - <h3><b>{% trans "Billed To:"%}</b></h3> - {% if order %} - {{user.name}}<br> - {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> - {{order.billing_address.city}}, - {{order.billing_address.country}}. - {% else %} - {% with request.session.billing_address_data as billing_address %} - {{billing_address|get_value_from_dict:'cardholder_name'}}<br> - {{billing_address|get_value_from_dict:'street_address'}}, - {{billing_address|get_value_from_dict:'postal_code'}}<br> - {{billing_address|get_value_from_dict:'city'}}, - {{billing_address|get_value_from_dict:'country'}}. - {% endwith %} - {% endif %} - </address> - </div> - - </div> - <div class="row"> - <div class="col-xs-6"> - <address> - <strong>{% trans "Payment Method:"%}</strong><br> - {% if order %} - {{order.cc_brand}} {% trans "ending in" %} **** - {{order.last4}}<br> - {{user.email}} - {% else %} - {{cc_brand}} {% trans "ending in" %} **** - {{cc_last4}}<br> - {{request.session.user.email}} - {% endif %} - </address> + <div class="row"> + <div class="col-xs-6"> + <address> + <strong>{% trans "Payment Method:"%}</strong><br> + {% if order %} + {{order.cc_brand}} {% trans "ending in" %} **** + {{order.last4}}<br> + {{user.email}} + {% else %} + {{cc_brand}} {% trans "ending in" %} **** + {{cc_last4}}<br> + {{request.session.user.email}} + {% endif %} + </address> + </div> </div> </div> </div> - </div> - <div class="row"> - <div class="col-md-8 col-md-offset-2"> - <h3><b>{% trans "Order summary"%}</b></h3> - <hr> - <div class="content"> - {% if request.session.specs %} - {% with request.session.specs as vm %} - <p><b>{% trans "Cores"%}</b> - <span class="pull-right">{{vm.cpu}}</span> - </p> + <div class="row"> + <div class="col-md-8 col-md-offset-2"> + <h3><b>{% trans "Order summary"%}</b></h3> <hr> - <p><b>{% trans "Memory"%}</b> - <span class="pull-right">{{vm.memory}} GB</span> - </p> - <hr> - <p><b>{% trans "Disk space"%}</b> - <span class="pull-right">{{vm.disk_size}} GB</span> - </p> - <hr> - <p><b>{% trans "Configuration"%}</b> - <span class="pull-right">{{request.session.template.name}}</span> - </p> - <hr> - <h4>{% trans "Total"%} - <p class="pull-right"> - <b>{{vm.price}} CHF</b> - <span class="dcl-price-month"> /{% trans "Month" %} - </span> + <div class="content"> + {% if request.session.specs %} + {% with request.session.specs as vm %} + <p><b>{% trans "Cores"%}</b> + <span class="pull-right">{{vm.cpu}}</span> </p> - </h4> - {% endwith %} - {% else %} - <p><b>{% trans "Cores"%}</b> - <span class="pull-right">{{vm.cores}}</span> - </p> - <hr> - <p><b>{% trans "Memory"%}</b> - <span class="pull-right">{{vm.memory}} GB</span> - </p> - <hr> - <p><b>{% trans "Disk space"%}</b> - <span class="pull-right">{{vm.disk_size}} GB</span> - </p> - <hr> - <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} - CHF</b><span - class="dcl-price-month"> /{% trans "Month" %}</span> - </p></h4> + <hr> + <p><b>{% trans "Memory"%}</b> + <span class="pull-right">{{vm.memory}} GB</span> + </p> + <hr> + <p><b>{% trans "Disk space"%}</b> + <span class="pull-right">{{vm.disk_size}} GB</span> + </p> + <hr> + <p><b>{% trans "Configuration"%}</b> + <span class="pull-right">{{request.session.template.name}}</span> + </p> + <hr> + <h4>{% trans "Total"%} + <p class="pull-right"> + <b>{{vm.price}} CHF</b> + <span class="dcl-price-month"> /{% trans "Month" %} + </span> + </p> + </h4> + {% endwith %} + {% else %} + <p><b>{% trans "Cores"%}</b> + <span class="pull-right">{{vm.cores}}</span> + </p> + <hr> + <p><b>{% trans "Memory"%}</b> + <span class="pull-right">{{vm.memory}} GB</span> + </p> + <hr> + <p><b>{% trans "Disk space"%}</b> + <span class="pull-right">{{vm.disk_size}} GB</span> + </p> + <hr> + <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} + CHF</b><span + class="dcl-price-month"> /{% trans "Month" %}</span> + </p></h4> + {% endif %} + </div> + <br/> + {% if not order %} + <form method="post" id="virtual_machine_create_form"> + {% csrf_token %} + <div class="row"> + <div class="col-sm-8"> + <p class="dcl-place-order-text">{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.</p> + </div> + <div class="col-sm-4 content"> + <button class="btn btn-info pull-right" + id="btn-create-vm" + data-href="{% url 'hosting:order-confirmation' %}" + data-toggle="modal" + data-target="#createvm-modal"> + {% trans "Place order"%} + </button> + </div> + </div> + </form> {% endif %} </div> - <br/> - {% if not order %} - <form method="post" id="virtual_machine_create_form"> - {% csrf_token %} - <div class="row"> - <div class="col-sm-8"> - <p class="dcl-place-order-text">{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.</p> - </div> - <div class="col-sm-4 content"> - <button class="btn btn-info pull-right" - id="btn-create-vm" - data-href="{% url 'hosting:order-confirmation' %}" - data-toggle="modal" - data-target="#createvm-modal"> - {% trans "Place order"%} - </button> - </div> - </div> - </form> - {% endif %} </div> - </div> {% endif %} </div> <!-- Create VM Modal --> diff --git a/hosting/urls.py b/hosting/urls.py index 2868c717..bc14c3a6 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -9,9 +9,10 @@ from .views import ( HostingPricingView, CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, SSHKeyChoiceView, DashboardView, SettingsView) - +from django.views.generic import TemplateView urlpatterns = [ + url(r'test/?$', TemplateView.as_view(template_name='hosting/order_detail.html')), url(r'index/?$', IndexView.as_view(), name='index'), url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'), From 37017dd31ad0adafda7a59106c3789f15c192ce3 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Wed, 20 Sep 2017 23:06:51 +0530 Subject: [PATCH 35/82] minor mods --- hosting/static/hosting/css/order.css | 7 +- hosting/templates/hosting/order_detail.html | 290 ++++++++++---------- 2 files changed, 148 insertions(+), 149 deletions(-) diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index f2f7993b..bdd124c9 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -1,4 +1,9 @@ -.order-detail-container {padding-top: 70px;padding-bottom: 70px;/* margin-bottom: 70px; */max-width: 720px;margin: 0 auto;} +.order-detail-container { + max-width: 600px; + margin: 100px auto; + border: 1px solid #ccc; + padding: 30px; +} .order-detail-container .invoice-title h2, .invoice-title h3 { display: inline-block; diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index f07aa998..3d1ffd35 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -9,161 +9,155 @@ {% if messages %} <div class="alert alert-warning"> {% for message in messages %} - <span>{{ message }}</span> + <span>{{ message }}</span> {% endfor %} </div> {% endif %} {% if not error %} - <div class="row"> - <div class="col-xs-12 col-md-8 col-md-offset-2"> - <div class="invoice-title"> - <h2>{{page_header_text}}</h2> - <h3 class="pull-right"> - {% if order %} - {% trans "Order #"%} {{order.id}} - {% endif %} - </h3> - </div> - <hr> - <div class="row"> - <div class="col-xs-12 col-md-6 pull-right order-confirm-date"> - <address> - <strong>{% trans "Date"%}:</strong><br> - <span id="order-created_at"> - {% if order %} - {{order.created_at|date:'Y-m-d H:i'}} - {% else %} - {% now "Y-m-d H:i" %} - {% endif %} - </span><br><br> - {% if order %} - <strong>{% trans "Status:"%}</strong><br> - {% if order.status == 'Approved' %} - <strong class="text-success"> - {% trans "Approved" %} - </strong> - {% else %} - <strong class="text-danger"> - {% trans "Declined" %} - </strong> - {% endif %} - <br><br> - {% endif %} - </address> - - </div> - <div class="col-xs-12 col-md-6"> - <address> - <h3><b>{% trans "Billed To:"%}</b></h3> - {% if order %} - {{user.name}}<br> - {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> - {{order.billing_address.city}}, - {{order.billing_address.country}}. - {% else %} - {% with request.session.billing_address_data as billing_address %} - {{billing_address.cardholder_name}}<br> - {{billing_address.street_address}}, - {{billing_address.postal_code}}<br> - {{billing_address.city}}, - {{billing_address.country}}. - {% endwith %} - {% endif %} - </address> - </div> - - </div> - <div class="row"> - <div class="col-xs-6"> - <address> - <strong>{% trans "Payment Method:"%}</strong><br> - {% if order %} - {{order.cc_brand}} {% trans "ending in" %} **** - {{order.last4}}<br> - {{user.email}} - {% else %} - {{cc_brand}} {% trans "ending in" %} **** - {{cc_last4}}<br> - {{request.session.user.email}} - {% endif %} - </address> - </div> - </div> - </div> - </div> - - <div class="row"> - <div class="col-md-8 col-md-offset-2"> - <h3><b>{% trans "Order summary"%}</b></h3> - <hr> - <div class="content"> - {% if request.session.specs %} - {% with request.session.specs as vm %} - <p><b>{% trans "Cores"%}</b> - <span class="pull-right">{{vm.cpu}}</span> - </p> - <hr> - <p><b>{% trans "Memory"%}</b> - <span class="pull-right">{{vm.memory}} GB</span> - </p> - <hr> - <p><b>{% trans "Disk space"%}</b> - <span class="pull-right">{{vm.disk_size}} GB</span> - </p> - <hr> - <p><b>{% trans "Configuration"%}</b> - <span class="pull-right">{{request.session.template.name}}</span> - </p> - <hr> - <h4>{% trans "Total"%} - <p class="pull-right"> - <b>{{vm.price}} CHF</b> - <span class="dcl-price-month"> /{% trans "Month" %} - </span> - </p> - </h4> - {% endwith %} - {% else %} - <p><b>{% trans "Cores"%}</b> - <span class="pull-right">{{vm.cores}}</span> - </p> - <hr> - <p><b>{% trans "Memory"%}</b> - <span class="pull-right">{{vm.memory}} GB</span> - </p> - <hr> - <p><b>{% trans "Disk space"%}</b> - <span class="pull-right">{{vm.disk_size}} GB</span> - </p> - <hr> - <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} - CHF</b><span - class="dcl-price-month"> /{% trans "Month" %}</span> - </p></h4> - {% endif %} - </div> - <br/> - {% if not order %} - <form method="post" id="virtual_machine_create_form"> - {% csrf_token %} - <div class="row"> - <div class="col-sm-8"> - <p class="dcl-place-order-text">{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.</p> - </div> - <div class="col-sm-4 content"> - <button class="btn btn-info pull-right" - id="btn-create-vm" - data-href="{% url 'hosting:order-confirmation' %}" - data-toggle="modal" - data-target="#createvm-modal"> - {% trans "Place order"%} - </button> - </div> - </div> - </form> + <h1 class="dashboard-title-thin"> + {% blocktrans %}{{page_header_text|default:'Invoice'}}{% endblocktrans %} + </h1> + <div class="invoice-title"> + <h3 class="pull-right"> + {% if order %} + {% trans "Order #"%} {{order.id}} {% endif %} + </h3> + </div> + <hr> + <div class="row"> + <div class="col-xs-12 col-md-6 pull-right order-confirm-date"> + <address> + <strong>{% trans "Date"%}:</strong><br> + <span id="order-created_at"> + {% if order %} + {{order.created_at|date:'Y-m-d H:i'}} + {% else %} + {% now "Y-m-d H:i" %} + {% endif %} + </span><br><br> + {% if order %} + <strong>{% trans "Status:"%}</strong><br> + {% if order.status == 'Approved' %} + <strong class="text-success"> + {% trans "Approved" %} + </strong> + {% else %} + <strong class="text-danger"> + {% trans "Declined" %} + </strong> + {% endif %} + <br><br> + {% endif %} + </address> + + </div> + <div class="col-xs-12 col-md-6"> + <address> + <h3><b>{% trans "Billed To:"%}</b></h3> + {% if order %} + {{user.name}}<br> + {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> + {{order.billing_address.city}}, + {{order.billing_address.country}}. + {% else %} + {% with request.session.billing_address_data as billing_address %} + {{billing_address.cardholder_name}}<br> + {{billing_address.street_address}}, + {{billing_address.postal_code}}<br> + {{billing_address.city}}, + {{billing_address.country}}. + {% endwith %} + {% endif %} + </address> + </div> + + </div> + <div class="row"> + <div class="col-xs-6"> + <address> + <strong>{% trans "Payment Method:"%}</strong><br> + {% if order %} + {{order.cc_brand}} {% trans "ending in" %} **** + {{order.last4}}<br> + {{user.email}} + {% else %} + {{cc_brand}} {% trans "ending in" %} **** + {{cc_last4}}<br> + {{request.session.user.email}} + {% endif %} + </address> </div> </div> + + <h3><b>{% trans "Order summary"%}</b></h3> + <hr> + <div class="content"> + {% if request.session.specs %} + {% with request.session.specs as vm %} + <p><b>{% trans "Cores"%}</b> + <span class="pull-right">{{vm.cpu}}</span> + </p> + <hr> + <p><b>{% trans "Memory"%}</b> + <span class="pull-right">{{vm.memory}} GB</span> + </p> + <hr> + <p><b>{% trans "Disk space"%}</b> + <span class="pull-right">{{vm.disk_size}} GB</span> + </p> + <hr> + <p><b>{% trans "Configuration"%}</b> + <span class="pull-right">{{request.session.template.name}}</span> + </p> + <hr> + <h4>{% trans "Total"%} + <p class="pull-right"> + <b>{{vm.price}} CHF</b> + <span class="dcl-price-month"> /{% trans "Month" %} + </span> + </p> + </h4> + {% endwith %} + {% else %} + <p><b>{% trans "Cores"%}</b> + <span class="pull-right">{{vm.cores}}</span> + </p> + <hr> + <p><b>{% trans "Memory"%}</b> + <span class="pull-right">{{vm.memory}} GB</span> + </p> + <hr> + <p><b>{% trans "Disk space"%}</b> + <span class="pull-right">{{vm.disk_size}} GB</span> + </p> + <hr> + <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} + CHF</b><span + class="dcl-price-month"> /{% trans "Month" %}</span> + </p></h4> + {% endif %} + </div> + <br/> + {% if not order %} + <form method="post" id="virtual_machine_create_form"> + {% csrf_token %} + <div class="row"> + <div class="col-sm-8"> + <p class="dcl-place-order-text">{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.</p> + </div> + <div class="col-sm-4 content"> + <button class="btn btn-info pull-right" + id="btn-create-vm" + data-href="{% url 'hosting:order-confirmation' %}" + data-toggle="modal" + data-target="#createvm-modal"> + {% trans "Place order"%} + </button> + </div> + </div> + </form> + {% endif %} {% endif %} </div> <!-- Create VM Modal --> From ec354332f8b0159e62e6925a04e5d9bc700c66a8 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Wed, 20 Sep 2017 23:28:36 +0530 Subject: [PATCH 36/82] translation fix --- hosting/locale/de/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 006e8b20..b0cc0bf6 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -292,7 +292,7 @@ msgid "Toggle navigation" msgstr "Umschalten" msgid "Dashboard" -msgstr "Mein Dashboard" +msgstr "Dashboard" msgid "Logout" msgstr "Abmelden" From 98eb2f85d8913d36733467eedea0f1dce9ed50df Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 01:19:38 +0530 Subject: [PATCH 37/82] printing pdf --- hosting/static/hosting/css/order.css | 16 + hosting/static/hosting/js/html2pdf.js | 387 ++++++++++++++++++++ hosting/templates/hosting/order_detail.html | 27 +- 3 files changed, 421 insertions(+), 9 deletions(-) create mode 100644 hosting/static/hosting/js/html2pdf.js diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index bdd124c9..3e916cdd 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -20,3 +20,19 @@ .order-detail-container .table > tbody > tr > .thick-line { border-top: 2px solid; } + +.order-detail-container .dashboard-title-thin { + margin-top: 0; +} + +.order-detail-container .dashboard-title-thin .un-icon { + margin-top: -6px; +} + +.order-detail-container .dashboard-title-thin .svg-img { + height: 20px; + margin-right: 5px; + margin-top: -2px; + width: 20px; + margin-top: -6px; +} \ No newline at end of file diff --git a/hosting/static/hosting/js/html2pdf.js b/hosting/static/hosting/js/html2pdf.js new file mode 100644 index 00000000..45ae5b0c --- /dev/null +++ b/hosting/static/hosting/js/html2pdf.js @@ -0,0 +1,387 @@ +/** + * @license + * + * MIT License + * + * Copyright (c) 2017 Erik Koopmans + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Generate a PDF from an HTML element or string using html2canvas and jsPDF. + * + * @param {Element|string} source The source element or HTML string. + * @param {Object=} opt An object of optional settings: 'margin', 'filename', + * 'image' ('type' and 'quality'), and 'html2canvas' / 'jspdf', which are + * sent as settings to their corresponding functions. + */ +var html2pdf = (function(html2canvas, jsPDF) { + + /* ---------- MAIN FUNCTION ---------- */ + + var html2pdf = function(source, opt) { + // Handle input. + opt = objType(opt) === 'object' ? opt : {}; + var source = html2pdf.parseInput(source, opt); + + // Determine the PDF page size. + var pageSize = jsPDF.getPageSize(opt.jsPDF); + pageSize.inner = { + width: pageSize.width - opt.margin[1] - opt.margin[3], + height: pageSize.height - opt.margin[0] - opt.margin[2] + }; + pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width; + + // Copy the source element into a PDF-styled container div. + var container = html2pdf.makeContainer(source, pageSize); + var overlay = container.parentElement; + + // Get the locations of all hyperlinks. + if (opt.enableLinks) { + // Find all anchor tags and get the container's bounds for reference. + opt.links = []; + var links = container.querySelectorAll('a'); + var containerRect = unitConvert(container.getBoundingClientRect(), pageSize.k); + + // Treat each client rect as a separate link (for text-wrapping). + Array.prototype.forEach.call(links, function(link) { + var clientRects = link.getClientRects(); + for (var i=0; i<clientRects.length; i++) { + var clientRect = unitConvert(clientRects[i], pageSize.k); + clientRect.left -= containerRect.left; + clientRect.top -= containerRect.top; + opt.links.push({ el: link, clientRect: clientRect }); + } + }); + } + + // Render the canvas and pass the result to makePDF. + var onRendered = opt.html2canvas.onrendered || function() {}; + opt.html2canvas.onrendered = function(canvas) { + onRendered(canvas); + document.body.removeChild(overlay); + html2pdf.makePDF(canvas, pageSize, opt); + } + html2canvas(container, opt.html2canvas); + }; + + html2pdf.parseInput = function(source, opt) { + // Parse the opt object. + opt.jsPDF = opt.jsPDF || {}; + opt.html2canvas = opt.html2canvas || {}; + opt.filename = opt.filename && objType(opt.filename) === 'string' ? opt.filename : 'file.pdf'; + opt.enableLinks = opt.hasOwnProperty('enableLinks') ? opt.enableLinks : true; + opt.image = opt.image || {}; + opt.image.type = opt.image.type || 'jpeg'; + opt.image.quality = opt.image.quality || 0.95; + + // Parse the margin property of the opt object. + switch (objType(opt.margin)) { + case 'undefined': + opt.margin = 0; + case 'number': + opt.margin = [opt.margin, opt.margin, opt.margin, opt.margin]; + break; + case 'array': + if (opt.margin.length === 2) { + opt.margin = [opt.margin[0], opt.margin[1], opt.margin[0], opt.margin[1]]; + } + if (opt.margin.length === 4) { + break; + } + default: + throw 'Invalid margin array.'; + } + + // Parse the source element/string. + if (!source) { + throw 'Missing source element or string.'; + } else if (objType(source) === 'string') { + source = createElement('div', { innerHTML: source }); + } else if (objType(source) === 'element') { + source = cloneNode(source, opt.html2canvas.javascriptEnabled); + } else { + throw 'Invalid source - please specify an HTML Element or string.'; + } + + // Return the parsed input (opt is modified in-place, no need to return). + return source; + }; + + html2pdf.makeContainer = function(source, pageSize) { + // Define the CSS styles for the container and its overlay parent. + var overlayCSS = { + position: 'fixed', overflow: 'hidden', zIndex: 1000, + left: 0, right: 0, bottom: 0, top: 0, + backgroundColor: 'rgba(0,0,0,0.8)' + }; + var containerCSS = { + position: 'absolute', width: pageSize.inner.width + pageSize.unit, + left: 0, right: 0, top: 0, height: 'auto', margin: 'auto', + backgroundColor: 'white' + }; + + // Set the overlay to hidden (could be changed in the future to provide a print preview). + overlayCSS.opacity = 0; + + // Create and attach the elements. + var overlay = createElement('div', { className: 'html2pdf__overlay', style: overlayCSS }); + var container = createElement('div', { className: 'html2pdf__container', style: containerCSS }); + container.appendChild(source); + overlay.appendChild(container); + document.body.appendChild(overlay); + + // Enable page-breaks. + var pageBreaks = source.querySelectorAll('.html2pdf__page-break'); + var pxPageHeight = pageSize.inner.height * pageSize.k / 72 * 96; + Array.prototype.forEach.call(pageBreaks, function(el) { + el.style.display = 'block'; + var clientRect = el.getBoundingClientRect(); + el.style.height = pxPageHeight - (clientRect.top % pxPageHeight) + 'px'; + }, this); + + // Return the container. + return container; + }; + + html2pdf.makePDF = function(canvas, pageSize, opt) { + // Calculate the number of pages. + var ctx = canvas.getContext('2d'); + var pxFullHeight = canvas.height; + var pxPageHeight = Math.floor(canvas.width * pageSize.inner.ratio); + var nPages = Math.ceil(pxFullHeight / pxPageHeight); + + // Create a one-page canvas to split up the full image. + var pageCanvas = document.createElement('canvas'); + var pageCtx = pageCanvas.getContext('2d'); + var pageHeight = pageSize.inner.height; + pageCanvas.width = canvas.width; + pageCanvas.height = pxPageHeight; + + // Initialize the PDF. + var pdf = new jsPDF(opt.jsPDF); + + for (var page=0; page<nPages; page++) { + // Trim the final page to reduce file size. + if (page === nPages-1) { + pageCanvas.height = pxFullHeight % pxPageHeight; + pageHeight = pageCanvas.height * pageSize.inner.width / pageCanvas.width; + } + + // Display the page. + var w = pageCanvas.width; + var h = pageCanvas.height; + pageCtx.fillStyle = 'white'; + pageCtx.fillRect(0, 0, w, h); + pageCtx.drawImage(canvas, 0, page*pxPageHeight, w, h, 0, 0, w, h); + + // Add the page to the PDF. + if (page) pdf.addPage(); + var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality); + pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], + pageSize.inner.width, pageHeight); + + // Add hyperlinks. + if (opt.enableLinks) { + var pageTop = page * pageSize.inner.height; + opt.links.forEach(function(link) { + if (link.clientRect.top > pageTop && link.clientRect.top < pageTop + pageSize.inner.height) { + var left = opt.margin[1] + link.clientRect.left; + var top = opt.margin[0] + link.clientRect.top - pageTop; + pdf.link(left, top, link.clientRect.width, link.clientRect.height, { url: link.el.href }); + } + }); + } + } + + // Finish the PDF. + pdf.save( opt.filename ); + } + + + /* ---------- UTILS ---------- */ + + // Determine the type of a variable/object. + var objType = function(obj) { + if (typeof obj === 'undefined') return 'undefined'; + else if (typeof obj === 'string' || obj instanceof String) return 'string'; + else if (typeof obj === 'number' || obj instanceof Number) return 'number'; + else if (!!obj && obj.constructor === Array) return 'array'; + else if (obj && obj.nodeType === 1) return 'element'; + else if (typeof obj === 'object') return 'object'; + else return 'unknown'; + }; + + // Create an HTML element with optional className, innerHTML, and style. + var createElement = function(tagName, opt) { + var el = document.createElement(tagName); + if (opt.className) el.className = opt.className; + if (opt.innerHTML) { + el.innerHTML = opt.innerHTML; + var scripts = el.getElementsByTagName('script'); + for (var i = scripts.length; i-- > 0; null) { + scripts[i].parentNode.removeChild(scripts[i]); + } + } + for (var key in opt.style) { + el.style[key] = opt.style[key]; + } + return el; + }; + + // Deep-clone a node and preserve contents/properties. + var cloneNode = function(node, javascriptEnabled) { + // Recursively clone the node. + var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false); + for (var child = node.firstChild; child; child = child.nextSibling) { + if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') { + clone.appendChild(cloneNode(child, javascriptEnabled)); + } + } + + if (node.nodeType === 1) { + // Preserve contents/properties of special nodes. + if (node.nodeName === 'CANVAS') { + clone.width = node.width; + clone.height = node.height; + clone.getContext('2d').drawImage(node, 0, 0); + } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') { + clone.value = node.value; + } + + // Preserve the node's scroll position when it loads. + clone.addEventListener('load', function() { + clone.scrollTop = node.scrollTop; + clone.scrollLeft = node.scrollLeft; + }, true); + } + + // Return the cloned node. + return clone; + } + + // Convert units using the conversion value 'k' from jsPDF. + var unitConvert = function(obj, k) { + var newObj = {}; + for (var key in obj) { + newObj[key] = obj[key] * 72 / 96 / k; + } + return newObj; + }; + + // Get dimensions of a PDF page, as determined by jsPDF. + jsPDF.getPageSize = function(orientation, unit, format) { + // Decode options object + if (typeof orientation === 'object') { + var options = orientation; + orientation = options.orientation; + unit = options.unit || unit; + format = options.format || format; + } + + // Default options + unit = unit || 'mm'; + format = format || 'a4'; + orientation = ('' + (orientation || 'P')).toLowerCase(); + var format_as_string = ('' + format).toLowerCase(); + + // Size in pt of various paper formats + pageFormats = { + 'a0' : [2383.94, 3370.39], 'a1' : [1683.78, 2383.94], + 'a2' : [1190.55, 1683.78], 'a3' : [ 841.89, 1190.55], + 'a4' : [ 595.28, 841.89], 'a5' : [ 419.53, 595.28], + 'a6' : [ 297.64, 419.53], 'a7' : [ 209.76, 297.64], + 'a8' : [ 147.40, 209.76], 'a9' : [ 104.88, 147.40], + 'a10' : [ 73.70, 104.88], 'b0' : [2834.65, 4008.19], + 'b1' : [2004.09, 2834.65], 'b2' : [1417.32, 2004.09], + 'b3' : [1000.63, 1417.32], 'b4' : [ 708.66, 1000.63], + 'b5' : [ 498.90, 708.66], 'b6' : [ 354.33, 498.90], + 'b7' : [ 249.45, 354.33], 'b8' : [ 175.75, 249.45], + 'b9' : [ 124.72, 175.75], 'b10' : [ 87.87, 124.72], + 'c0' : [2599.37, 3676.54], 'c1' : [1836.85, 2599.37], + 'c2' : [1298.27, 1836.85], 'c3' : [ 918.43, 1298.27], + 'c4' : [ 649.13, 918.43], 'c5' : [ 459.21, 649.13], + 'c6' : [ 323.15, 459.21], 'c7' : [ 229.61, 323.15], + 'c8' : [ 161.57, 229.61], 'c9' : [ 113.39, 161.57], + 'c10' : [ 79.37, 113.39], 'dl' : [ 311.81, 623.62], + 'letter' : [612, 792], + 'government-letter' : [576, 756], + 'legal' : [612, 1008], + 'junior-legal' : [576, 360], + 'ledger' : [1224, 792], + 'tabloid' : [792, 1224], + 'credit-card' : [153, 243] + }; + + // Unit conversion + switch (unit) { + case 'pt': k = 1; break; + case 'mm': k = 72 / 25.4; break; + case 'cm': k = 72 / 2.54; break; + case 'in': k = 72; break; + case 'px': k = 72 / 96; break; + case 'pc': k = 12; break; + case 'em': k = 12; break; + case 'ex': k = 6; break; + default: + throw ('Invalid unit: ' + unit); + } + + // Dimensions are stored as user units and converted to points on output + if (pageFormats.hasOwnProperty(format_as_string)) { + pageHeight = pageFormats[format_as_string][1] / k; + pageWidth = pageFormats[format_as_string][0] / k; + } else { + try { + pageHeight = format[1]; + pageWidth = format[0]; + } catch (err) { + throw new Error('Invalid format: ' + format); + } + } + + // Handle page orientation + if (orientation === 'p' || orientation === 'portrait') { + orientation = 'p'; + if (pageWidth > pageHeight) { + tmp = pageWidth; + pageWidth = pageHeight; + pageHeight = tmp; + } + } else if (orientation === 'l' || orientation === 'landscape') { + orientation = 'l'; + if (pageHeight > pageWidth) { + tmp = pageWidth; + pageWidth = pageHeight; + pageHeight = tmp; + } + } else { + throw('Invalid orientation: ' + orientation); + } + + // Return information (k is the unit conversion ratio from pts) + var info = { 'width': pageWidth, 'height': pageHeight, 'unit': unit, 'k': k }; + return info; + }; + + + // Expose the html2pdf function. + return html2pdf; +}(html2canvas, jsPDF)); diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 3d1ffd35..8278db45 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -5,7 +5,7 @@ {% block content %} -<div class="order-detail-container"> +<div id="order-detail" class="order-detail-container"> {% if messages %} <div class="alert alert-warning"> {% for message in messages %} @@ -14,17 +14,20 @@ </div> {% endif %} {% if not error %} - <h1 class="dashboard-title-thin"> - {% blocktrans %}{{page_header_text|default:'Invoice'}}{% endblocktrans %} - </h1> + <div class="dashboard-container-head"> + <h1 class="dashboard-title-thin"> + <img src="{% static 'hosting/img/billing.svg' %}" class="un-icon">{% blocktrans with page_header_text=page_header_text|default:"Invoice" %}{{page_header_text}}{% endblocktrans %} + </h1> + + <button></button> + <img src="{% static 'hosting/img/icon-pdf.svg' %}" class="svg-img pull-right"> + <img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img pull-right"> + </div> <div class="invoice-title"> - <h3 class="pull-right"> - {% if order %} - {% trans "Order #"%} {{order.id}} - {% endif %} + <h3> + {% trans "Order #"%} {{order.id}} </h3> </div> - <hr> <div class="row"> <div class="col-xs-12 col-md-6 pull-right order-confirm-date"> <address> @@ -202,5 +205,11 @@ }; </script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script> +<script src="{% static 'hosting/js/html2pdf.js' %}"></script> +<script> + html2pdf(document.getElementById('order-detail')); +</script> {%endblock%} From f0e50a4e948be7a86d025fae300071db059edece Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 01:20:51 +0530 Subject: [PATCH 38/82] removed commented code --- datacenterlight/static/datacenterlight/js/main.js | 1 - hosting/static/hosting/js/createvm.js | 1 - 2 files changed, 2 deletions(-) diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js index c508d76d..ab37a68b 100644 --- a/datacenterlight/static/datacenterlight/js/main.js +++ b/datacenterlight/static/datacenterlight/js/main.js @@ -147,7 +147,6 @@ function _fetchPricing() { Object.keys(cardPricing).map(function(element) { - //$('#'+cardPricing[element].id).val(cardPricing[element].value); $('input[name=' + element + ']').val(cardPricing[element].value); }); _calcPricing(); diff --git a/hosting/static/hosting/js/createvm.js b/hosting/static/hosting/js/createvm.js index 344aedfb..726513ad 100644 --- a/hosting/static/hosting/js/createvm.js +++ b/hosting/static/hosting/js/createvm.js @@ -53,7 +53,6 @@ function _fetchPricing() { Object.keys(cardPricing).map(function(element) { - //$('#'+cardPricing[element].id).val(cardPricing[element].value); $('input[name=' + element + ']').val(cardPricing[element].value); }); _calcPricing(); From dd77f407074282c168ecd05a2f39c6a7d60df069 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 02:23:08 +0530 Subject: [PATCH 39/82] top options added --- hosting/static/hosting/css/commons.css | 16 ++++++++++++++++ hosting/static/hosting/css/order.css | 16 ++++++++++++---- hosting/static/hosting/img/icon-pdf.svg | 4 ++-- hosting/static/hosting/img/icon-print.svg | 4 ++-- hosting/templates/hosting/order_detail.html | 8 ++++---- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/hosting/static/hosting/css/commons.css b/hosting/static/hosting/css/commons.css index 01ff5090..c70051b6 100644 --- a/hosting/static/hosting/css/commons.css +++ b/hosting/static/hosting/css/commons.css @@ -355,4 +355,20 @@ .no-cards a { color: #7ca3d0; +} + +.btn-plain { + background: transparent; + border: none; + fill: #595959; + color: #595959; + outline: none; +} +.btn-plain:hover, +.btn-plain:focus, +.btn-plain:active, +.btn-plain:active:focus { + outline: none; + color: #999; + fill: #999; } \ No newline at end of file diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index 3e916cdd..186f7c16 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -29,10 +29,18 @@ margin-top: -6px; } -.order-detail-container .dashboard-title-thin .svg-img { +.order-detail-container .dashboard-container-head { + position: relative; + padding: 0; +} + +.order-detail-container .dashboard-container-options { + position: absolute; + top: 10px; + right: 0; +} +.order-detail-container .dashboard-container-options .svg-img { height: 20px; - margin-right: 5px; - margin-top: -2px; + /* margin-right: 5px; */ width: 20px; - margin-top: -6px; } \ No newline at end of file diff --git a/hosting/static/hosting/img/icon-pdf.svg b/hosting/static/hosting/img/icon-pdf.svg index 20fc9c48..3743bbb8 100644 --- a/hosting/static/hosting/img/icon-pdf.svg +++ b/hosting/static/hosting/img/icon-pdf.svg @@ -4,8 +4,8 @@ <title>icon-pdf</title> <desc>Created with Sketch.</desc> <defs></defs> - <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> - <g id="icon-pdf" fill-rule="nonzero" fill="#000000"> + <g id="Page-1" stroke="none" stroke-width="1" fill-rule="evenodd"> + <g id="icon-pdf" fill-rule="nonzero"> <g id="Group" transform="translate(93.000000, 269.000000)"> <path d="M98,47.8 C98,54.8 97,61.7 95.1,66.6 C93.1,72.5 90.1,76.5 86.2,80.5 C82.2,84.5 76.3,87.4 70.4,89.4 C64.5,91.4 55.6,92.3 46.6,92.3 L34.7,92.3 L34.7,134 L0,134 L0,0.3 L45.5,0.3 C54.4,0.3 62.4,1.3 69.3,3.2 C76.2,5.2 81.2,8.2 85.1,12.1 C89.1,16.1 92.1,21 94,27 C96.9,32 98,38.9 98,47.8 Z M61.3,46.8 C61.3,42.8 61.3,39.9 60.3,37.9 C60.3,35.9 59.3,33.9 57.4,32 C56.4,31 54.5,30 52.4,29.1 C50.4,29.1 47.4,28.1 44.5,28.1 L34.6,28.1 L34.6,63.7 L45.5,63.7 C48.4,63.7 50.4,63.7 52.5,62.7 C54.5,61.7 56.5,61.7 57.5,59.8 C58.5,57.8 59.5,56.9 60.4,54.8 C61.3,53.8 61.3,50.8 61.3,46.8 Z" id="Shape"></path> <path d="M214.8,66.6 C214.8,78.5 213.8,89.3 210.8,97.3 C208.8,106.2 204.9,113.1 199.9,118.1 C195,123.1 189,127 182.1,130 C175.2,132 167.3,134 157.3,134 L108.8,134 L108.8,0.3 L156.3,0.3 C166.2,0.3 175.1,1.3 182,4.3 C188.9,7.2 194.9,10.2 199.8,16.2 C204.8,21.2 207.7,28.1 209.7,37 C213.8,44.8 214.8,54.7 214.8,66.6 Z M178.1,65.6 C178.1,58.7 178.1,52.7 177.1,47.8 C176.1,42.8 175.1,39.9 174.2,36.9 C172.2,34 170.2,32.9 168.3,31.9 C165.4,30.9 162.4,30.9 158.4,30.9 L145.6,30.9 L145.6,103.2 L158.4,103.2 C162.4,103.2 165.4,103.2 168.3,102.2 C171.2,101.2 173.3,99.3 174.2,97.2 C176.2,94.3 177.1,91.3 178.2,86.3 C178.1,80.5 178.1,74.5 178.1,65.6 Z" id="Shape"></path> diff --git a/hosting/static/hosting/img/icon-print.svg b/hosting/static/hosting/img/icon-print.svg index e440f326..75eb175f 100644 --- a/hosting/static/hosting/img/icon-print.svg +++ b/hosting/static/hosting/img/icon-print.svg @@ -4,8 +4,8 @@ <title>54471</title> <desc>Created with Sketch.</desc> <defs></defs> - <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> - <g id="54471" fill-rule="nonzero" fill="#000000"> + <g id="Page-1" stroke="none" stroke-width="1" fill-rule="evenodd"> + <g id="54471" fill-rule="nonzero"> <path d="M0,225.633 L0,386.367 C0,417.272 30.6,417.272 30.6,417.272 L83.454,417.272 L83.454,389.454 L27.818,389.454 L27.818,222.545 L584.181,222.545 L584.181,389.454 L528.545,389.454 L528.545,417.272 L581.4,417.272 C581.4,417.272 612,417.272 612,386.367 L612,225.633 C612,225.633 612,194.727 581.4,194.727 L30.6,194.727 C0,194.728 0,225.633 0,225.633 Z" id="Shape"></path> <polygon id="Shape" points="500.728 166.909 500.728 0 111.273 0 111.273 166.909 139.091 166.909 139.091 27.818 472.909 27.818 472.909 166.909"></polygon> <path d="M528.546,292.091 C528.546,278.182 514.358,278.182 514.358,278.182 L97.642,278.182 C97.642,278.182 83.455,278.182 83.455,292.091 C83.455,306 97.642,306 97.642,306 L514.359,306 C514.358,306 528.546,306 528.546,292.091 Z" id="Shape"></path> diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 8278db45..56154d29 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -18,10 +18,10 @@ <h1 class="dashboard-title-thin"> <img src="{% static 'hosting/img/billing.svg' %}" class="un-icon">{% blocktrans with page_header_text=page_header_text|default:"Invoice" %}{{page_header_text}}{% endblocktrans %} </h1> - - <button></button> - <img src="{% static 'hosting/img/icon-pdf.svg' %}" class="svg-img pull-right"> - <img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img pull-right"> + <div class="dashboard-container-options"> + <button class="btn-plain"><img src="{% static 'hosting/img/icon-pdf.svg' %}" class="svg-img"></button> + <button class="btn-plain"><img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img"></button> + </div> </div> <div class="invoice-title"> <h3> From 1eff51099c09618e98c35144bc3fafacae269265 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 02:26:42 +0530 Subject: [PATCH 40/82] exception handling fix --- hosting/views.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index 06d5051c..21444b41 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -967,11 +967,8 @@ class VirtualMachineView(LoginRequiredMixin, View): try: vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data - except BaseException: - return redirect( - reverse('hosting:virtual_machines', - kwargs={'pk': opennebula_vm_id}) - ) + except WrongIdError: + return redirect(reverse('hosting:virtual_machines')) terminated = manager.delete_vm(vm.id) From 6dfbf67d7d9c092fe2b8cfe47417985cd6c5b963 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 02:50:07 +0530 Subject: [PATCH 41/82] rearranging text --- hosting/templates/hosting/order_detail.html | 133 +++++++++--------- .../templates/hosting/virtual_machines.html | 16 ++- 2 files changed, 79 insertions(+), 70 deletions(-) diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 56154d29..38b186db 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -23,81 +23,88 @@ <button class="btn-plain"><img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img"></button> </div> </div> - <div class="invoice-title"> - <h3> - {% trans "Order #"%} {{order.id}} - </h3> - </div> - <div class="row"> - <div class="col-xs-12 col-md-6 pull-right order-confirm-date"> - <address> - <strong>{% trans "Date"%}:</strong><br> - <span id="order-created_at"> - {% if order %} - {{order.created_at|date:'Y-m-d H:i'}} - {% else %} - {% now "Y-m-d H:i" %} - {% endif %} - </span><br><br> + <div class="order-details"> + {% if order %} + <div> + <strong>{% trans "Order #"%} {{order.id}}</strong> + </div> + {% endif %} + <div> + <strong>{% trans "Invoice Date"%}:</strong> + <span id="order-created_at"> {% if order %} - <strong>{% trans "Status:"%}</strong><br> + {{order.created_at|date:'Y-m-d H:i'}} + {% else %} + {% now "Y-m-d H:i" %} + {% endif %} + </span> + </div> + {% if order %} + + {% endif %} + <div> + <strong>{% trans "Status" %}: </strong> + <strong> {% if order.status == 'Approved' %} - <strong class="text-success"> - {% trans "Approved" %} - </strong> + <span class="vm-status-active">{% trans "Approved" %}</span> {% else %} - <strong class="text-danger"> - {% trans "Declined" %} - </strong> + <span class="vm-status-failed">{% trans "Declined" %}</span> {% endif %} - <br><br> - {% endif %} - </address> - + </strong> </div> - <div class="col-xs-12 col-md-6"> + <hr> + <div> <address> - <h3><b>{% trans "Billed To:"%}</b></h3> - {% if order %} - {{user.name}}<br> - {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> - {{order.billing_address.city}}, - {{order.billing_address.country}}. - {% else %} - {% with request.session.billing_address_data as billing_address %} - {{billing_address.cardholder_name}}<br> - {{billing_address.street_address}}, - {{billing_address.postal_code}}<br> - {{billing_address.city}}, - {{billing_address.country}}. - {% endwith %} - {% endif %} + <h4>{% trans "Billed to" %}:</h4> + <div> + {% if order %} + {{user.name}}<br> + {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> + {{order.billing_address.city}}, + {{order.billing_address.country}}. + {% else %} + {% with request.session.billing_address_data as billing_address %} + {{billing_address.cardholder_name}}<br> + {{billing_address.street_address}}, + {{billing_address.postal_code}}<br> + {{billing_address.city}}, + {{billing_address.country}}. + {% endwith %} + {% endif %} + </div> </address> </div> + <hr> + <div> + <h4>{% trans "Payment method" %}:</h4> + <div> + {% if order %} + {{order.cc_brand}} {% trans "ending in" %} **** + {{order.last4}}<br> + {{user.email}} + {% else %} + {{cc_brand}} {% trans "ending in" %} **** + {{cc_last4}}<br> + {{request.session.user.email}} + {% endif %} + </div> + </div> + <div> + <h4>{% trans "Order summary"%}</h4> + <div> + {% if request.session.specs %} + {% request.session.specs as vm %} + {% endif %} + <strong>{% trans "Product" %}:</strong> {{request.session.template.name}} + </div> + </div> </div> - <div class="row"> - <div class="col-xs-6"> - <address> - <strong>{% trans "Payment Method:"%}</strong><br> - {% if order %} - {{order.cc_brand}} {% trans "ending in" %} **** - {{order.last4}}<br> - {{user.email}} - {% else %} - {{cc_brand}} {% trans "ending in" %} **** - {{cc_last4}}<br> - {{request.session.user.email}} - {% endif %} - </address> - </div> - </div> - <h3><b>{% trans "Order summary"%}</b></h3> + <h3><b></b></h3> <hr> <div class="content"> - {% if request.session.specs %} - {% with request.session.specs as vm %} + <p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cpu}}</span> </p> @@ -195,7 +202,7 @@ <script type="text/javascript"> {% trans "Some problem encountered. Please try again later." as err_msg %} - var create_vm_error_message = '{{err_msg|safe}}.'; + var create_vm_error_message = '{{err_msg|safe}}'; window.onload = function () { var locale_date = moment.utc(document.getElementById("order-created_at").textContent, 'YYYY-MM-DD HH:mm').toDate(); diff --git a/hosting/templates/hosting/virtual_machines.html b/hosting/templates/hosting/virtual_machines.html index f7461abe..622e7a55 100644 --- a/hosting/templates/hosting/virtual_machines.html +++ b/hosting/templates/hosting/virtual_machines.html @@ -41,13 +41,15 @@ <td data-header="IPv6">{{vm.ipv6}}</td> {% endif %} <td data-header="{% trans 'Status' %}"> - {% if vm.state == 'ACTIVE' %} - <span class="vm-status-active"><strong>{{vm.state|title}}</strong></span> - {% elif vm.state == 'FAILED' %} - <span class="vm-status-failed"><strong>{{vm.state|title}}</strong></span> - {% else %} - <span class="vm-status"><strong>{{vm.state|title}}</strong></span> - {% endif %} + <strong> + {% if vm.state == 'ACTIVE' %} + <span class="vm-status-active">{{vm.state|title}}</span> + {% elif vm.state == 'FAILED' %} + <span class="vm-status-failed">{{vm.state|title}}</span> + {% else %} + <span class="vm-status">{{vm.state|title}}</span> + {% endif %} + </strong> </td> <td class="text-right last-td"> <a class="btn btn-vm-detail" href="{% url 'hosting:virtual_machines' vm.vm_id %}">{% trans "View Detail" %}</a> From 6c381dd3fbc435a4741a0cc8634a7be4c40527e9 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 15:03:00 +0530 Subject: [PATCH 42/82] invoice page redesigned --- hosting/static/hosting/css/landing-page.css | 4 +- hosting/static/hosting/css/order.css | 34 ++- hosting/static/hosting/js/order.js | 15 ++ .../hosting/js/virtual_machine_detail.js | 2 + hosting/templates/hosting/base_short.html | 9 +- hosting/templates/hosting/order_detail.html | 217 ++++++++---------- hosting/views.py | 1 + 7 files changed, 157 insertions(+), 125 deletions(-) create mode 100644 hosting/static/hosting/js/order.js diff --git a/hosting/static/hosting/css/landing-page.css b/hosting/static/hosting/css/landing-page.css index 71b7a33d..5c71b7ca 100644 --- a/hosting/static/hosting/css/landing-page.css +++ b/hosting/static/hosting/css/landing-page.css @@ -580,9 +580,9 @@ a.unlink:hover { } .dcl-place-order-text{ - font-size: 13px; + /* font-size: 13px; */ color: #808080; - margin-bottom: 15px; + /* margin-bottom: 15px; */ } .dcl-order-table-total .tbl-total { diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index 186f7c16..0377bfac 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -1,6 +1,6 @@ .order-detail-container { max-width: 600px; - margin: 100px auto; + margin: 100px auto 40px; border: 1px solid #ccc; padding: 30px; } @@ -23,6 +23,7 @@ .order-detail-container .dashboard-title-thin { margin-top: 0; + margin-left: -3px; } .order-detail-container .dashboard-title-thin .un-icon { @@ -32,6 +33,7 @@ .order-detail-container .dashboard-container-head { position: relative; padding: 0; + margin-bottom: 38px; } .order-detail-container .dashboard-container-options { @@ -43,4 +45,34 @@ height: 20px; /* margin-right: 5px; */ width: 20px; +} + +.order-detail-container .order-details { + margin-bottom: 30px; +} + +.order-detail-container .order-details strong { + color: #777; +} + +.order-detail-container h4 { + font-size: 16px; + font-weight: bold; + margin-bottom: 15px; +} + +.order-detail-container p { + margin-bottom: 5px; + color: #595959; +} + +.order-detail-container hr { + margin: 15px 0; +} + +@media (max-width: 767px) { + .order-confirm-btn { + text-align: center; + margin-top: 10px; + } } \ No newline at end of file diff --git a/hosting/static/hosting/js/order.js b/hosting/static/hosting/js/order.js new file mode 100644 index 00000000..e9de4cf9 --- /dev/null +++ b/hosting/static/hosting/js/order.js @@ -0,0 +1,15 @@ +$(document).ready(function() { + $('.btn-pdf').click(function(e) { + e.preventDefault(); + var $target = $($(this).attr('data-target')) || $('body'); + var fileName = $target.attr('id') + '.pdf'; + html2pdf($target[0], { + filename: fileName, + }); + }); + $('.btn-print').click(function(e) { + e.preventDefault(); + console.log('a'); + window.print(); + }); +}); \ No newline at end of file diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index b6202e97..7d66afaf 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -1,4 +1,5 @@ $(document).ready(function () { + $('.modal-text').removeClass('hide'); var create_vm_form = $('#virtual_machine_create_form'); create_vm_form.submit(function () { $('#btn-create-vm').prop('disabled', true); @@ -22,6 +23,7 @@ $(document).ready(function () { fa_icon = $('.modal-icon > .fa'); fa_icon.attr('class', 'fa fa-times'); $('.modal-header > .close').attr('class', 'close'); + $('.modal-text').addClass('hide'); if (typeof(create_vm_error_message) !== 'undefined') { $('#createvm-modal-title').text(create_vm_error_message); } diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index 63a0681d..3906133b 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -94,6 +94,13 @@ <!-- Init JavaScript --> <script src="{% static 'hosting/js/initial.js' %}"></script> + {% block js_extra %} + {% comment %} + this block is above some files, because on stripe error scripts below the stripe + script are not properly executed. + {% endcomment %} + {% endblock js_extra %} + <script src="https://js.stripe.com/v3/"></script> <script src="https://js.stripe.com/v2/"></script> <!-- Stripe Lib --> @@ -108,8 +115,6 @@ <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.js"></script> - - </body> </html> diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 38b186db..49f7ba6b 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -5,7 +5,7 @@ {% block content %} -<div id="order-detail" class="order-detail-container"> +<div id="order-detail{{order.pk}}" class="order-detail-container"> {% if messages %} <div class="alert alert-warning"> {% for message in messages %} @@ -19,18 +19,18 @@ <img src="{% static 'hosting/img/billing.svg' %}" class="un-icon">{% blocktrans with page_header_text=page_header_text|default:"Invoice" %}{{page_header_text}}{% endblocktrans %} </h1> <div class="dashboard-container-options"> - <button class="btn-plain"><img src="{% static 'hosting/img/icon-pdf.svg' %}" class="svg-img"></button> - <button class="btn-plain"><img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img"></button> + <button type="button" class="btn-plain btn-pdf" data-target="#order-detail{{order.pk}}"><img src="{% static 'hosting/img/icon-pdf.svg' %}" class="svg-img"></button> + <button type="button" class="btn-plain btn-print"><img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img"></button> </div> </div> <div class="order-details"> {% if order %} - <div> - <strong>{% trans "Order #"%} {{order.id}}</strong> - </div> {% endif %} - <div> - <strong>{% trans "Invoice Date"%}:</strong> + <p> + <strong>{% trans "Order #" %} {{order.id}}</strong> + </p> + <p> + <strong>{% trans "Invoice Date" %}:</strong> <span id="order-created_at"> {% if order %} {{order.created_at|date:'Y-m-d H:i'}} @@ -38,46 +38,43 @@ {% now "Y-m-d H:i" %} {% endif %} </span> - </div> + </p> {% if order %} {% endif %} - <div> + <p> <strong>{% trans "Status" %}: </strong> <strong> {% if order.status == 'Approved' %} - <span class="vm-status-active">{% trans "Approved" %}</span> + <span class="vm-color-online">{% trans "Approved" %}</span> {% else %} <span class="vm-status-failed">{% trans "Declined" %}</span> {% endif %} </strong> - </div> + </p> <hr> <div> <address> <h4>{% trans "Billed to" %}:</h4> - <div> + <p> {% if order %} {{user.name}}<br> - {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> - {{order.billing_address.city}}, - {{order.billing_address.country}}. + {{order.billing_address.street_address}}, {{order.billing_address.postal_code}}<br> + {{order.billing_address.city}}, {{order.billing_address.country}} {% else %} {% with request.session.billing_address_data as billing_address %} - {{billing_address.cardholder_name}}<br> - {{billing_address.street_address}}, - {{billing_address.postal_code}}<br> - {{billing_address.city}}, - {{billing_address.country}}. + {{billing_address.cardholder_name}}<br> + {{billing_address.street_address}}, {{billing_address.postal_code}}<br> + {{billing_address.city}}, {{billing_address.country}} {% endwith %} {% endif %} - </div> + </p> </address> </div> <hr> <div> <h4>{% trans "Payment method" %}:</h4> - <div> + <p> {% if order %} {{order.cc_brand}} {% trans "ending in" %} **** {{order.last4}}<br> @@ -87,82 +84,55 @@ {{cc_last4}}<br> {{request.session.user.email}} {% endif %} - </div> - </div> - <div> - <h4>{% trans "Order summary"%}</h4> - <div> - {% if request.session.specs %} - {% request.session.specs as vm %} - {% endif %} - <strong>{% trans "Product" %}:</strong> {{request.session.template.name}} - </div> - </div> - - </div> - - <h3><b></b></h3> - <hr> - <div class="content"> - - <p><b>{% trans "Cores"%}</b> - <span class="pull-right">{{vm.cpu}}</span> - </p> - <hr> - <p><b>{% trans "Memory"%}</b> - <span class="pull-right">{{vm.memory}} GB</span> - </p> - <hr> - <p><b>{% trans "Disk space"%}</b> - <span class="pull-right">{{vm.disk_size}} GB</span> - </p> - <hr> - <p><b>{% trans "Configuration"%}</b> - <span class="pull-right">{{request.session.template.name}}</span> - </p> - <hr> - <h4>{% trans "Total"%} - <p class="pull-right"> - <b>{{vm.price}} CHF</b> - <span class="dcl-price-month"> /{% trans "Month" %} - </span> </p> - </h4> - {% endwith %} - {% else %} - <p><b>{% trans "Cores"%}</b> - <span class="pull-right">{{vm.cores}}</span> - </p> + </div> <hr> - <p><b>{% trans "Memory"%}</b> - <span class="pull-right">{{vm.memory}} GB</span> - </p> - <hr> - <p><b>{% trans "Disk space"%}</b> - <span class="pull-right">{{vm.disk_size}} GB</span> - </p> - <hr> - <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} - CHF</b><span - class="dcl-price-month"> /{% trans "Month" %}</span> - </p></h4> + <div> + <h4>{% trans "Order summary" %}</h4> + <p> + <strong>{% trans "Product" %}:</strong> {{vm.name}} + </p> + <div class="row"> + <div class="col-sm-6"> + {% comment %} + <p> + <span>{% trans "Period" %}</span> + <span class="pull-right">{{vm.cpu}}</span> + </p> + {% endcomment %} + <p> + <span>{% trans "Cores" %}</span> + <span class="pull-right">{{vm.cpu}}</span> + </p> + <p> + <span>{% trans "Memory" %}</span> + <span class="pull-right">{{vm.memory}} GB</span> + </p> + <p> + <span>{% trans "Disk space" %}</span> + <span class="pull-right">{{vm.disk_size}} GB</span> + </p> + <p> + <span>{% trans "Total" %}</span> + <span class="pull-right">{{vm.price}} CHF</span> + </p> + </div> + </div> + </div> + {% if not order %} + <hr> {% endif %} </div> - <br/> {% if not order %} <form method="post" id="virtual_machine_create_form"> {% csrf_token %} <div class="row"> <div class="col-sm-8"> - <p class="dcl-place-order-text">{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.</p> + <div class="dcl-place-order-text">{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.</div> </div> - <div class="col-sm-4 content"> - <button class="btn btn-info pull-right" - id="btn-create-vm" - data-href="{% url 'hosting:order-confirmation' %}" - data-toggle="modal" - data-target="#createvm-modal"> - {% trans "Place order"%} + <div class="col-sm-4 order-confirm-btn text-right"> + <button class="btn choice-btn" id="btn-create-vm" data-href="{% url 'hosting:order-confirmation' %}" data-toggle="modal" data-target="#createvm-modal"> + {% trans "Place order" %} </button> </div> </div> @@ -170,35 +140,43 @@ {% endif %} {% endif %} </div> -<!-- Create VM Modal --> -<div class="modal fade" id="createvm-modal" tabindex="-1" role="dialog" - aria-hidden="true" data-backdrop="static" data-keyboard="false"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <button type="button" class="close hidden" data-dismiss="modal" - aria-label="create-vm-close"> - <span aria-hidden="true">×</span> - </button> - </div> - <div class="modal-body"> - <div class="modal-icon"> - <i class="fa fa-cog fa-spin fa-3x fa-fw"></i> - <span class="sr-only">{% trans "Processing..." %}</span> + + <div class="text-center" style="margin-bottom: 50px;"> + <a class="btn btn-vm-back" href="{% url 'hosting:orders' %}">{% trans "BACK TO LIST" %}</a> + </div> +{% if order %} +{% endif %} + +{% if not order %} + <!-- Create VM Modal --> + <div class="modal fade" id="createvm-modal" tabindex="-1" role="dialog" + aria-hidden="true" data-backdrop="static" data-keyboard="false"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close hidden" data-dismiss="modal" + aria-label="create-vm-close"> + <span aria-hidden="true">×</span> + </button> </div> - <h4 class="modal-title" id="createvm-modal-title"> - </h4> - <div class="modal-text" id="createvm-modal-body"> - {% trans "Hold tight, we are processing your request" %} - </div> - <div class="modal-footer"> + <div class="modal-body"> + <div class="modal-icon"> + <i class="fa fa-cog fa-spin fa-3x fa-fw"></i> + <span class="sr-only">{% trans "Processing..." %}</span> + </div> + <h4 class="modal-title" id="createvm-modal-title"> + </h4> + <div class="modal-text" id="createvm-modal-body"> + {% trans "Hold tight, we are processing your request" %} + </div> + <div class="modal-footer"> + </div> </div> </div> </div> </div> -</div> -<!-- / Create VM Modal --> - + <!-- / Create VM Modal --> +{% endif %} <script type="text/javascript"> {% trans "Some problem encountered. Please try again later." as err_msg %} @@ -210,13 +188,12 @@ document.getElementById('order-created_at').innerHTML = locale_date; }; - -</script> -<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script> -<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script> -<script src="{% static 'hosting/js/html2pdf.js' %}"></script> -<script> - html2pdf(document.getElementById('order-detail')); </script> {%endblock%} +{% block js_extra %} + <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script> + <script src="{% static 'hosting/js/html2pdf.js' %}"></script> + <script src="{% static 'hosting/js/order.js' %}"></script> +{% endblock js_extra %} \ No newline at end of file diff --git a/hosting/views.py b/hosting/views.py index e1d2feb2..20c2cc78 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -698,6 +698,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, 'last4') context['cc_brand'] = card_details.get('response_object').get( 'cc_brand') + context['vm'] = request.session.get('specs') return context def post(self, request): From 2c4390767d99ca3e73a4c9fb3854a7c846909e18 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 15:14:15 +0530 Subject: [PATCH 43/82] minor fixes --- hosting/templates/hosting/includes/_navbar_user.html | 6 +++++- hosting/views.py | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hosting/templates/hosting/includes/_navbar_user.html b/hosting/templates/hosting/includes/_navbar_user.html index 126dd1e6..d06477ca 100644 --- a/hosting/templates/hosting/includes/_navbar_user.html +++ b/hosting/templates/hosting/includes/_navbar_user.html @@ -37,7 +37,11 @@ </li> <li> {% get_current_language as LANGUAGE_CODE %} - + {% if LANGUAGE_CODE == 'en-us'%} + <a href="{% change_lang 'de' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> Deutsch</a> + {% else %} + <a href="{% change_lang 'en-us' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i> English</a> + {% endif %} </li> </ul> </div> diff --git a/hosting/views.py b/hosting/views.py index 20c2cc78..4d2d4f42 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -698,7 +698,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, 'last4') context['cc_brand'] = card_details.get('response_object').get( 'cc_brand') - context['vm'] = request.session.get('specs') + context['vm'] = self.request.session.get('specs') return context def post(self, request): @@ -776,8 +776,8 @@ class OrdersHostingDetailView(LoginRequiredMixin, 'redirect': reverse('hosting:virtual_machines'), '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.')) + ' We will send you a confirmation email as soon as' + ' it is ready.')) } return HttpResponse(json.dumps(response), From 5d8fb712153feffe5c7d31f49d53a256af1db264 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 16:38:54 +0530 Subject: [PATCH 44/82] removed redirects form get_context() to get() --- hosting/views.py | 64 ++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index 4d2d4f42..cbb2be1f 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -652,46 +652,42 @@ class OrdersHostingDetailView(LoginRequiredMixin, context = super(DetailView, self).get_context_data(**kwargs) obj = self.get_object() owner = self.request.user - if 'specs' not in self.request.session: - return HttpResponseRedirect( - reverse('hosting:create_virtual_machine')) - if 'token' not in self.request.session: - return HttpResponseRedirect(reverse('hosting:payment')) stripe_customer_id = self.request.session.get('customer') customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() stripe_utils = StripeUtils() - card_details = stripe_utils.get_card_details(customer.stripe_id, - self.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('hosting:payment') + '#payment_error') + card_details = stripe_utils.get_card_details( + customer.stripe_id, + self.request.session.get('token') + ) - if self.request.GET.get('page', '') == 'payment': + if self.request.GET.get('page') == 'payment': context['page_header_text'] = _('Confirm Order') else: context['page_header_text'] = _('Invoice') if obj is not None: try: - manager = OpenNebulaManager(email=owner.email, - password=owner.password) + manager = OpenNebulaManager( + email=owner.email, password=owner.password + ) vm = manager.get_vm(obj.vm_id) context['vm'] = VirtualMachineSerializer(vm).data except WrongIdError: - messages.error(self.request, - 'The VM you are looking for is unavailable at the moment. \ - Please contact Data Center Light support.' - ) + messages.error( + self.request, + 'The VM you are looking for is unavailable at the moment. \ + Please contact Data Center Light support.' + ) self.kwargs['error'] = 'WrongIdError' context['error'] = 'WrongIdError' except ConnectionRefusedError: - messages.error(self.request, - 'In order to create a VM, you need to create/upload your SSH KEY first.' - ) + messages.error( + self.request, + 'In order to create a VM, you need to create/upload your SSH KEY first.' + ) + elif not card_details.get('response_object'): + context['failed_payment'] = True + context['card_details'] = card_details else: context['site_url'] = reverse('hosting:create_virtual_machine') context['cc_last4'] = card_details.get('response_object').get( @@ -701,6 +697,26 @@ class OrdersHostingDetailView(LoginRequiredMixin, context['vm'] = self.request.session.get('specs') return context + def get(self, request, *args, **kwargs): + if 'specs' not in self.request.session: + return HttpResponseRedirect( + reverse('hosting:create_virtual_machine') + ) + if 'token' not in self.request.session: + return HttpResponseRedirect(reverse('hosting:payment')) + self.object = self.get_object() + context = self.get_context_data(object=self.object) + if 'failed_payment' in context: + msg = context['card_details'].get('error') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) + return HttpResponseRedirect( + reverse('hosting:payment') + '#payment_error' + ) + return self.render_to_response(context) + def post(self, request): template = request.session.get('template') specs = request.session.get('specs') From a792911dea8872da79ae96016551a962f2ba0a47 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 17:22:02 +0530 Subject: [PATCH 45/82] hosting view fix --- hosting/templates/hosting/order_detail.html | 25 ++++++++++---------- hosting/views.py | 26 +++++++++++++-------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 49f7ba6b..3ee79eaa 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -4,7 +4,7 @@ {% load custom_tags %} {% block content %} - +{{order.pk}} <div id="order-detail{{order.pk}}" class="order-detail-container"> {% if messages %} <div class="alert alert-warning"> @@ -25,10 +25,10 @@ </div> <div class="order-details"> {% if order %} - {% endif %} <p> <strong>{% trans "Order #" %} {{order.id}}</strong> </p> + {% endif %} <p> <strong>{% trans "Invoice Date" %}:</strong> <span id="order-created_at"> @@ -40,18 +40,17 @@ </span> </p> {% if order %} - + <p> + <strong>{% trans "Status" %}: </strong> + <strong> + {% if order.status == 'Approved' %} + <span class="vm-color-online">{% trans "Approved" %}</span> + {% else %} + <span class="vm-status-failed">{% trans "Declined" %}</span> + {% endif %} + </strong> + </p> {% endif %} - <p> - <strong>{% trans "Status" %}: </strong> - <strong> - {% if order.status == 'Approved' %} - <span class="vm-color-online">{% trans "Approved" %}</span> - {% else %} - <span class="vm-status-failed">{% trans "Declined" %}</span> - {% endif %} - </strong> - </p> <hr> <div> <address> diff --git a/hosting/views.py b/hosting/views.py index cbb2be1f..13b9fd80 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -655,10 +655,13 @@ class OrdersHostingDetailView(LoginRequiredMixin, stripe_customer_id = self.request.session.get('customer') customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() stripe_utils = StripeUtils() - card_details = stripe_utils.get_card_details( - customer.stripe_id, - self.request.session.get('token') - ) + if customer: + card_details = stripe_utils.get_card_details( + customer.stripe_id, + self.request.session.get('token') + ) + else: + card_details = None if self.request.GET.get('page') == 'payment': context['page_header_text'] = _('Confirm Order') @@ -666,6 +669,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, context['page_header_text'] = _('Invoice') if obj is not None: + # invoice for previous order try: manager = OpenNebulaManager( email=owner.email, password=owner.password @@ -686,9 +690,11 @@ class OrdersHostingDetailView(LoginRequiredMixin, 'In order to create a VM, you need to create/upload your SSH KEY first.' ) elif not card_details.get('response_object'): + # new order, failed to get card details context['failed_payment'] = True context['card_details'] = card_details else: + # new order, confirm payment context['site_url'] = reverse('hosting:create_virtual_machine') context['cc_last4'] = card_details.get('response_object').get( 'last4') @@ -698,12 +704,12 @@ class OrdersHostingDetailView(LoginRequiredMixin, return context def get(self, request, *args, **kwargs): - if 'specs' not in self.request.session: - return HttpResponseRedirect( - reverse('hosting:create_virtual_machine') - ) - if 'token' not in self.request.session: - return HttpResponseRedirect(reverse('hosting:payment')) + # if 'specs' not in self.request.session: + # return HttpResponseRedirect( + # reverse('hosting:create_virtual_machine') + # ) + # if 'token' not in self.request.session: + # return HttpResponseRedirect(reverse('hosting:payment')) self.object = self.get_object() context = self.get_context_data(object=self.object) if 'failed_payment' in context: From db3955ab94597b01f5cc404a5e00f7a0124ce964 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 17:45:12 +0530 Subject: [PATCH 46/82] error 500 fixed --- hosting/static/hosting/css/order.css | 2 +- hosting/templates/hosting/order_detail.html | 4 ++-- hosting/views.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index 0377bfac..8213610e 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -58,7 +58,7 @@ .order-detail-container h4 { font-size: 16px; font-weight: bold; - margin-bottom: 15px; + margin-bottom: 10px; } .order-detail-container p { diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 3ee79eaa..d5599fbe 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -96,12 +96,12 @@ {% comment %} <p> <span>{% trans "Period" %}</span> - <span class="pull-right">{{vm.cpu}}</span> + <span class="pull-right">{{}}</span> </p> {% endcomment %} <p> <span>{% trans "Cores" %}</span> - <span class="pull-right">{{vm.cpu}}</span> + <span class="pull-right">{{vm.cores}}</span> </p> <p> <span>{% trans "Memory" %}</span> diff --git a/hosting/views.py b/hosting/views.py index 13b9fd80..0458464d 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -644,7 +644,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, model = HostingOrder def get_object(self): - return HostingOrder.objects.filter( + return HostingOrder.objects.get( pk=self.kwargs.get('pk')) if self.kwargs.get('pk') else None def get_context_data(self, **kwargs): From a16dbb50d8e1f9b2705c9f91bfa0b0d881046d86 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 19:17:10 +0530 Subject: [PATCH 47/82] design fixes --- hosting/static/hosting/css/order.css | 22 ++++++++++++++++----- hosting/templates/hosting/order_detail.html | 10 +++++++--- hosting/urls.py | 2 +- hosting/views.py | 14 ++++++------- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index 8213610e..383b23f4 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -2,6 +2,10 @@ max-width: 600px; margin: 100px auto 40px; border: 1px solid #ccc; + padding: 15px; +} + +@media(min-width: 768px) { padding: 30px; } @@ -42,9 +46,8 @@ right: 0; } .order-detail-container .dashboard-container-options .svg-img { - height: 20px; - /* margin-right: 5px; */ - width: 20px; + height: 22px; + width: 22px; } .order-detail-container .order-details { @@ -52,7 +55,7 @@ } .order-detail-container .order-details strong { - color: #777; + color: #595959; } .order-detail-container h4 { @@ -75,4 +78,13 @@ text-align: center; margin-top: 10px; } -} \ No newline at end of file + .order-detail-container .dashboard-container-options { + position: absolute; + top: 4px; + right: -4px; + } + .order-detail-container .dashboard-container-options .svg-img { + height: 16px; + width: 16px; + } +} diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index d5599fbe..c4cf5892 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -81,7 +81,11 @@ {% else %} {{cc_brand}} {% trans "ending in" %} **** {{cc_last4}}<br> - {{request.session.user.email}} + {% if request.user.is_authenticated %} + {{request.user.email}} + {% else %} + {{request.session.user.email}} + {% endif %} {% endif %} </p> </div> @@ -101,7 +105,7 @@ {% endcomment %} <p> <span>{% trans "Cores" %}</span> - <span class="pull-right">{{vm.cores}}</span> + <span class="pull-right">{{vm.cores|floatformat}}</span> </p> <p> <span>{% trans "Memory" %}</span> @@ -140,10 +144,10 @@ {% endif %} </div> +{% if order %} <div class="text-center" style="margin-bottom: 50px;"> <a class="btn btn-vm-back" href="{% url 'hosting:orders' %}">{% trans "BACK TO LIST" %}</a> </div> -{% if order %} {% endif %} {% if not order %} diff --git a/hosting/urls.py b/hosting/urls.py index bc14c3a6..a946fee1 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -12,7 +12,7 @@ from .views import ( from django.views.generic import TemplateView urlpatterns = [ - url(r'test/?$', TemplateView.as_view(template_name='hosting/order_detail.html')), + url(r'test/?$', TemplateView.as_view(template_name='hosting/order_detail.html'), name='test'), url(r'index/?$', IndexView.as_view(), name='index'), url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'), diff --git a/hosting/views.py b/hosting/views.py index 0458464d..95304212 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -661,7 +661,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, self.request.session.get('token') ) else: - card_details = None + card_details = {} if self.request.GET.get('page') == 'payment': context['page_header_text'] = _('Confirm Order') @@ -704,12 +704,12 @@ class OrdersHostingDetailView(LoginRequiredMixin, return context def get(self, request, *args, **kwargs): - # if 'specs' not in self.request.session: - # return HttpResponseRedirect( - # reverse('hosting:create_virtual_machine') - # ) - # if 'token' not in self.request.session: - # return HttpResponseRedirect(reverse('hosting:payment')) + if 'specs' not in self.request.session: + return HttpResponseRedirect( + reverse('hosting:create_virtual_machine') + ) + if 'token' not in self.request.session: + return HttpResponseRedirect(reverse('hosting:payment')) self.object = self.get_object() context = self.get_context_data(object=self.object) if 'failed_payment' in context: From 1c0f0da96eb3bb84d4adada1f563474c341bbd23 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Thu, 21 Sep 2017 19:32:22 +0530 Subject: [PATCH 48/82] conditional texts --- hosting/locale/de/LC_MESSAGES/django.po | 75 +++++++++++++++------ hosting/templates/hosting/order_detail.html | 8 ++- hosting/urls.py | 3 +- hosting/views.py | 13 ++-- 4 files changed, 67 insertions(+), 32 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index d684bec7..49ebedd2 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-09-14 12:27+0000\n" +"POT-Creation-Date: 2017-09-21 19:20+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -321,10 +321,14 @@ msgstr "Als gelesen markieren" msgid "All notifications" msgstr "Alle Benachrichtigungen" -msgid "Date" -msgstr "Datum" +#, python-format +msgid "%(page_header_text)s" +msgstr "" -msgid "Status:" +msgid "Invoice Date" +msgstr "Rechnung Datum" + +msgid "Status" msgstr "" msgid "Approved" @@ -333,10 +337,10 @@ msgstr "Akzeptiert" msgid "Declined" msgstr "Abgelehnt" -msgid "Billed To:" +msgid "Billed to" msgstr "Rechnungsadresse" -msgid "Payment Method:" +msgid "Payment method" msgstr "Bezahlmethode" msgid "ending in" @@ -345,6 +349,9 @@ msgstr "endend in" msgid "Order summary" msgstr "Bestellungsübersicht" +msgid "Product" +msgstr "" + msgid "Cores" msgstr "Prozessorkerne" @@ -357,20 +364,40 @@ msgstr "Festplattenkapazität" msgid "Total" msgstr "Gesamt" -msgid "Finish Configuration" -msgstr "Konfiguration beenden" +#, python-format +msgid "" +"By clicking \"Place order\" this plan will charge your credit card account " +"with the fee of %(vm_price)sCHF/month" +msgstr "" +"Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit %(vm_price)sCHF " +"pro Monat belastet" + +msgid "Place order" +msgstr "Bestellen" + +msgid "BACK TO LIST" +msgstr "ZURÜCK ZUR LISTE" + +msgid "Processing..." +msgstr "Weiter..." + +msgid "Hold tight, we are processing your request" +msgstr "" + +msgid "Some problem encountered. Please try again later." +msgstr "" msgid "Order Nr." msgstr "Bestellung Nr." +msgid "Date" +msgstr "Datum" + msgid "Amount" msgstr "Betrag" -msgid "Status" -msgstr "" - msgid "See Invoice" -msgstr "Rechnung" +msgstr "Siehe Rechnung" msgid "Page" msgstr "" @@ -555,9 +582,6 @@ msgstr "Wir sind hier, um Dir zu helfen!" msgid "CONTACT" msgstr "KONTACT" -msgid "BACK TO LIST" -msgstr "ZURÜCK ZUR LISTE" - msgid "Terminate your Virtual Machine" msgstr "Deine Virtuelle Maschine beenden" @@ -618,13 +642,17 @@ msgstr "" msgid "Invalid credit card" msgstr "Ungültige Kreditkarte" -#, python-format -msgid "Your New VM %(vm_name)s at Data Center Light" -msgstr "Deine neue VM %(vm_name)s bei Data Center Light" - msgid "Confirm Order" msgstr "Bestellung Bestätigen" +msgid "Thank you for the order." +msgstr "Danke für den Auftrag" + +msgid "" +"Your VM will be up and running in a few moments. We will send you a " +"confirmation email as soon as it is ready." +msgstr "" + msgid "In order to create a VM, you need to create/upload your SSH KEY first." msgstr "" "Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen." @@ -641,6 +669,12 @@ msgstr "VM Kündigung" msgid "VM %(VM_ID)s terminated successfully" msgstr "VM %(VM_ID)s erfolgreich beendet" +#~ msgid "Finish Configuration" +#~ msgstr "Konfiguration beenden" + +#~ msgid "Your New VM %(vm_name)s at Data Center Light" +#~ msgstr "Deine neue VM %(vm_name)s bei Data Center Light" + #~ msgid "My Virtual Machines" #~ msgstr "Meine virtuellen Maschinen" @@ -734,9 +768,6 @@ msgstr "VM %(VM_ID)s erfolgreich beendet" #~ msgid "Payment Details" #~ msgstr "Rechnungsdetails" -#~ msgid "Place Order" -#~ msgstr "Bestelle" - #~ msgid "CARD NUMBER" #~ msgstr "Kreditkartennummer" diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index c4cf5892..9466f396 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -79,7 +79,7 @@ {{order.last4}}<br> {{user.email}} {% else %} - {{cc_brand}} {% trans "ending in" %} **** + {{cc_brand|default:'Card'}} {% trans "ending in" %} **** {{cc_last4}}<br> {% if request.user.is_authenticated %} {{request.user.email}} @@ -105,7 +105,11 @@ {% endcomment %} <p> <span>{% trans "Cores" %}</span> - <span class="pull-right">{{vm.cores|floatformat}}</span> + {% if vm.cores %} + <span class="pull-right">{{vm.cores|floatformat}}</span> + {% else %} + <span class="pull-right">{{vm.cpu|floatformat}}</span> + {% endif %} </p> <p> <span>{% trans "Memory" %}</span> diff --git a/hosting/urls.py b/hosting/urls.py index a946fee1..2868c717 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -9,10 +9,9 @@ from .views import ( HostingPricingView, CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, SSHKeyChoiceView, DashboardView, SettingsView) -from django.views.generic import TemplateView + urlpatterns = [ - url(r'test/?$', TemplateView.as_view(template_name='hosting/order_detail.html'), name='test'), url(r'index/?$', IndexView.as_view(), name='index'), url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'), diff --git a/hosting/views.py b/hosting/views.py index 95304212..2f31442a 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -704,12 +704,13 @@ class OrdersHostingDetailView(LoginRequiredMixin, return context def get(self, request, *args, **kwargs): - if 'specs' not in self.request.session: - return HttpResponseRedirect( - reverse('hosting:create_virtual_machine') - ) - if 'token' not in self.request.session: - return HttpResponseRedirect(reverse('hosting:payment')) + if not self.kwargs.get('pk'): + if 'specs' not in self.request.session: + return HttpResponseRedirect( + reverse('hosting:create_virtual_machine') + ) + if 'token' not in self.request.session: + return HttpResponseRedirect(reverse('hosting:payment')) self.object = self.get_object() context = self.get_context_data(object=self.object) if 'failed_payment' in context: From 2b0dbfa1e50cdf97b3810872fe740152d9663a2e Mon Sep 17 00:00:00 2001 From: "M.Ravi" <mondi.ravi@gmail.com> Date: Fri, 22 Sep 2017 08:47:42 +0200 Subject: [PATCH 49/82] Added /cms prefix to django-cms urls --- dynamicweb/urls.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dynamicweb/urls.py b/dynamicweb/urls.py index 84f3fb3d..2adce271 100644 --- a/dynamicweb/urls.py +++ b/dynamicweb/urls.py @@ -5,7 +5,8 @@ from django.conf.urls.static import static from django.views import i18n, static as static_view from django.conf import settings -from hosting.views import RailsHostingView, DjangoHostingView, NodeJSHostingView +from hosting.views import RailsHostingView, DjangoHostingView, \ + NodeJSHostingView from membership import urls as membership_urls from ungleich_page.views import LandingView from django.views.generic import RedirectView @@ -49,9 +50,14 @@ urlpatterns += i18n_patterns( include('ungleich_page.urls', namespace='ungleich_page'), name='ungleich_page'), - url(r'^blog/', include('ungleich.urls', - namespace='ungleich')), - url(r'^', include('cms.urls')) + url(r'^cms/blog/', + include('ungleich.urls', namespace='ungleich')), + url( + r'^blog/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>\w[-\w]*)/$', + RedirectView.as_view(pattern_name='ungleich:post-detail')), + url(r'^blog/|cms/$', RedirectView.as_view( + url=reverse_lazy('ungleich:post-list')), name='blog_list_view'), + url(r'^cms/', include('cms.urls')), ) urlpatterns += [ From faa26a05dd8f66e726be5eb7cae03ad41f4ba79c Mon Sep 17 00:00:00 2001 From: "M.Ravi" <mondi.ravi@gmail.com> Date: Fri, 22 Sep 2017 08:51:35 +0200 Subject: [PATCH 50/82] Reverted back some lines for preserving format --- dynamicweb/urls.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dynamicweb/urls.py b/dynamicweb/urls.py index 2adce271..699ce50b 100644 --- a/dynamicweb/urls.py +++ b/dynamicweb/urls.py @@ -5,8 +5,7 @@ from django.conf.urls.static import static from django.views import i18n, static as static_view from django.conf import settings -from hosting.views import RailsHostingView, DjangoHostingView, \ - NodeJSHostingView +from hosting.views import RailsHostingView, DjangoHostingView, NodeJSHostingView from membership import urls as membership_urls from ungleich_page.views import LandingView from django.views.generic import RedirectView From dec1f34250169b1e6ec1b4a8f1d70667365d67a4 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sat, 23 Sep 2017 17:17:24 +0530 Subject: [PATCH 51/82] Updated Changelog with pre-1.2.3 text --- Changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Changelog b/Changelog index 423517ee..ac3253f1 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,11 @@ +Pre-changelog: 1.2.3 2017-09-20 + * #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email + * #3731: [dcl, hosting] Added cdist ssh key handler + * #3628: [dcl] on hosting, VM is created at credit card info submit + * #3772: [dcl] Updated hosting app billing into monthly subscription and added new text and translations + * Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls + * Bugfix: [dcl, hosting] added host to celery error mails + * Bugfix: [ungleich] Fixed wrong subdomain digitalglarus.ungleich.ch 1.2.2: 2017-09-08 * #3704: [hosting] Added my settings page * #3771: [datacenterlight] Fixed the inconsistency in navbar style in billing page and onward From be0c50aa2f40de68a13f0fecb58cb6d2d429ff1c Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Sat, 23 Sep 2017 19:01:22 +0530 Subject: [PATCH 52/82] error msgs translation --- hosting/locale/de/LC_MESSAGES/django.po | 31 ++++++++++++++----------- hosting/views.py | 7 +++--- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index ad5c779d..7ad85a7d 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-09-21 19:20+0530\n" +"POT-Creation-Date: 2017-09-23 19:00+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -361,15 +361,9 @@ msgstr "Arbeitsspeicher" msgid "Disk space" msgstr "Festplattenkapazität" -msgid "Configuration" -msgstr "Konfiguration" - msgid "Total" msgstr "Gesamt" -msgid "Month" -msgstr "Monat" - #, python-format msgid "" "By clicking \"Place order\" this plan will charge your credit card account " @@ -414,9 +408,15 @@ msgstr "" msgid "Your Order" msgstr "Deine Bestellung" +msgid "Configuration" +msgstr "Konfiguration" + msgid "including VAT" msgstr "inkl. Mehrwertsteuer" +msgid "Month" +msgstr "Monat" + msgid "Billing Address" msgstr "Rechnungsadresse" @@ -645,6 +645,15 @@ msgstr "Ungültige Kreditkarte" msgid "Confirm Order" msgstr "Bestellung Bestätigen" +msgid "" +"The VM you are looking for is unavailable at the moment. Please contact Data " +"Center Light support." +msgstr "" + +msgid "In order to create a VM, you need to create/upload your SSH KEY first." +msgstr "" +"Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen." + msgid "Thank you for the order." msgstr "Danke für Deine Bestellung." @@ -652,12 +661,8 @@ msgid "" "Your VM will be up and running in a few moments. We will send you a " "confirmation email as soon as it is ready." msgstr "" -"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, " -"sobald Du auf sie zugreifen kannst." - -msgid "In order to create a VM, you need to create/upload your SSH KEY first." -msgstr "" -"Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen." +"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du " +"auf sie zugreifen kannst." msgid "" "We could not find the requested VM. Please " diff --git a/hosting/views.py b/hosting/views.py index 2f31442a..c736a576 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -679,15 +679,16 @@ class OrdersHostingDetailView(LoginRequiredMixin, except WrongIdError: messages.error( self.request, - 'The VM you are looking for is unavailable at the moment. \ - Please contact Data Center Light support.' + _('The VM you are looking for is unavailable at the ' + 'moment. Please contact Data Center Light support.') ) self.kwargs['error'] = 'WrongIdError' context['error'] = 'WrongIdError' except ConnectionRefusedError: messages.error( self.request, - 'In order to create a VM, you need to create/upload your SSH KEY first.' + _('In order to create a VM, you need to create/upload ' + 'your SSH KEY first.') ) elif not card_details.get('response_object'): # new order, failed to get card details From 3685bf591dad6554a2130f0569a99d5b15729c5b Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Sat, 23 Sep 2017 19:02:23 +0530 Subject: [PATCH 53/82] error msgs translation --- hosting/locale/de/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 7ad85a7d..37b29cbd 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -648,7 +648,7 @@ msgstr "Bestellung Bestätigen" msgid "" "The VM you are looking for is unavailable at the moment. Please contact Data " "Center Light support." -msgstr "" +msgstr "Kontaktiere den Data Center Light Support." msgid "In order to create a VM, you need to create/upload your SSH KEY first." msgstr "" From e9721705ca1e72e592f218b4639263129dc30999 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Sat, 23 Sep 2017 20:30:53 +0530 Subject: [PATCH 54/82] margin fix --- hosting/static/hosting/css/order.css | 4 +++- hosting/templates/hosting/order_detail.html | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index 383b23f4..8e9226e2 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -6,7 +6,9 @@ } @media(min-width: 768px) { - padding: 30px; + .order-detail-container { + padding: 30px; + } } .order-detail-container .invoice-title h2, .invoice-title h3 { diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 9466f396..345632d2 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -4,7 +4,6 @@ {% load custom_tags %} {% block content %} -{{order.pk}} <div id="order-detail{{order.pk}}" class="order-detail-container"> {% if messages %} <div class="alert alert-warning"> From 487af6e1c825da3443882ea1faf880910d295d66 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Sat, 23 Sep 2017 20:44:53 +0530 Subject: [PATCH 55/82] Update Changelog --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index ac3253f1..4bbcba4d 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,7 @@ Pre-changelog: 1.2.3 2017-09-20 * #3731: [dcl, hosting] Added cdist ssh key handler * #3628: [dcl] on hosting, VM is created at credit card info submit * #3772: [dcl] Updated hosting app billing into monthly subscription and added new text and translations + * #3786: [hosting] Redesigned the hosting invoice and order-confirmation page * Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls * Bugfix: [dcl, hosting] added host to celery error mails * Bugfix: [ungleich] Fixed wrong subdomain digitalglarus.ungleich.ch From eca7ba01c583b053d75ad5aee34aeb06ad18c5c9 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Sat, 23 Sep 2017 22:54:17 +0530 Subject: [PATCH 56/82] fixed duplicate translation --- hosting/locale/de/LC_MESSAGES/django.po | 3 --- 1 file changed, 3 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 5231b04d..16babbfa 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -417,9 +417,6 @@ msgstr "Konfiguration" msgid "including VAT" msgstr "inkl. Mehrwertsteuer" -msgid "Month" -msgstr "Monat" - msgid "Billing Address" msgstr "Rechnungsadresse" From cd3fdcf9356c6bdf8f14d5a56fa769ba8d217e2e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Sat, 23 Sep 2017 23:33:48 +0530 Subject: [PATCH 57/82] Updated pre-changelog 1.2.3 --- Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog b/Changelog index 4bbcba4d..33184f98 100644 --- a/Changelog +++ b/Changelog @@ -4,6 +4,8 @@ Pre-changelog: 1.2.3 2017-09-20 * #3628: [dcl] on hosting, VM is created at credit card info submit * #3772: [dcl] Updated hosting app billing into monthly subscription and added new text and translations * #3786: [hosting] Redesigned the hosting invoice and order-confirmation page + * #3728: [hosting] VM Termination animation added + * #3777: [hosting] Create new VM calculator added like dcl landing * Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls * Bugfix: [dcl, hosting] added host to celery error mails * Bugfix: [ungleich] Fixed wrong subdomain digitalglarus.ungleich.ch From 313b2b2f576a741f3fa2e161ad24e1f1e02083d7 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari <tiwariav@gmail.com> Date: Sat, 23 Sep 2017 23:47:25 +0530 Subject: [PATCH 58/82] fixed vreate vm error --- hosting/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index d7c4c168..e0fe041e 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -17,7 +17,7 @@ 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 ugettext_lazy as _ -from django.utils.translation import ugettext +from django.utils.translation import ugettext, get_language from django.views.generic import ( View, CreateView, FormView, ListView, DetailView, DeleteView, TemplateView, UpdateView From afc368e9dd6cf470a3aaa547a5f6a63e2768e816 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sun, 24 Sep 2017 15:49:40 +0530 Subject: [PATCH 59/82] Added ResendActivationEmailView --- hosting/views.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index d7c4c168..02e68bbd 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -33,12 +33,15 @@ from membership.models import CustomUser, StripeCustomer from opennebula_api.models import OpenNebulaManager from opennebula_api.serializers import VirtualMachineSerializer, \ VirtualMachineTemplateSerializer, VMTemplateSerializer -from utils.forms import BillingAddressForm, PasswordResetRequestForm, \ - UserBillingAddressForm +from utils.forms import ( + BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm, + ResendActivationEmailForm +) from utils.mailer import BaseEmail from utils.stripe_utils import StripeUtils from utils.views import ( - PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin + PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin, + ResendActivationLinkViewMixin ) from .forms import HostingUserSignupForm, HostingUserLoginForm, \ UserHostingKeyForm, generate_ssh_key_name @@ -282,6 +285,14 @@ class SignupValidatedView(SignupValidateView): return context +class ResendActivationEmailView(ResendActivationLinkViewMixin): + template_name = 'hosting/resend_activation_link.html' + form_class = ResendActivationEmailForm + success_url = reverse_lazy('hosting:login') + email_template_path = 'datacenterlight/emails/' + email_template_name = 'user_activation' + + class PasswordResetView(PasswordResetViewMixin): site = 'dcl' template_name = 'hosting/reset_password.html' From 324761613752d77a2824df67feec22047b445722 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sun, 24 Sep 2017 15:53:08 +0530 Subject: [PATCH 60/82] Added resend activation link url --- hosting/urls.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hosting/urls.py b/hosting/urls.py index 2868c717..f40e803a 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -8,8 +8,7 @@ from .views import ( MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView, HostingPricingView, CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, - SSHKeyChoiceView, DashboardView, SettingsView) - + SSHKeyChoiceView, DashboardView, SettingsView, ResendActivationEmailView) urlpatterns = [ url(r'index/?$', IndexView.as_view(), name='index'), @@ -52,6 +51,8 @@ urlpatterns = [ url(r'signup/?$', SignupView.as_view(), name='signup'), url(r'signup-validate/?$', SignupValidateView.as_view(), name='signup-validate'), + url(r'resend-activation-link/?$', ResendActivationEmailView.as_view(), + name='resend_activation_link'), url(r'reset-password/?$', PasswordResetView.as_view(), name='reset_password'), url(r'reset-password-confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', From af426c5b7a19f943f95a174f51924c5d52360c78 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sun, 24 Sep 2017 15:54:38 +0530 Subject: [PATCH 61/82] Added ResendActivationEmailForm and translation function to untranslated texts --- utils/forms.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/utils/forms.py b/utils/forms.py index c3f3b6db..a12034dd 100644 --- a/utils/forms.py +++ b/utils/forms.py @@ -18,7 +18,8 @@ class SignupFormMixin(forms.ModelForm): model = CustomUser fields = ['name', 'email', 'password'] widgets = { - 'name': forms.TextInput(attrs={'placeholder': _('Enter your name or company name')}), + 'name': forms.TextInput( + attrs={'placeholder': _('Enter your name or company name')}), } def clean_confirm_password(self): @@ -42,7 +43,7 @@ class LoginFormMixin(forms.Form): is_auth = authenticate(email=email, password=password) if not is_auth: raise forms.ValidationError( - "Your username and/or password were incorrect.") + _("Your username and/or password were incorrect.")) return self.cleaned_data def clean_email(self): @@ -51,7 +52,24 @@ class LoginFormMixin(forms.Form): CustomUser.objects.get(email=email) return email except CustomUser.DoesNotExist: - raise forms.ValidationError("User does not exist") + raise forms.ValidationError(_("User does not exist")) + + +class ResendActivationEmailForm(forms.Form): + email = forms.CharField(widget=forms.EmailInput()) + + class Meta: + fields = ['email'] + + def clean_email(self): + email = self.cleaned_data.get('email') + try: + c = CustomUser.objects.get(email=email) + if c.validated == 1: + raise forms.ValidationError(_("The account is already active.")) + return email + except CustomUser.DoesNotExist: + raise forms.ValidationError(_("User does not exist")) class PasswordResetRequestForm(forms.Form): @@ -66,7 +84,7 @@ class PasswordResetRequestForm(forms.Form): CustomUser.objects.get(email=email) return email except CustomUser.DoesNotExist: - raise forms.ValidationError("User does not exist") + raise forms.ValidationError(_("User does not exist")) class SetPasswordForm(forms.Form): @@ -75,11 +93,11 @@ class SetPasswordForm(forms.Form): password """ error_messages = { - 'password_mismatch': ("The two password fields didn't match."), + 'password_mismatch': _("The two password fields didn't match."), } - new_password1 = forms.CharField(label=("New password"), + new_password1 = forms.CharField(label=_("New password"), widget=forms.PasswordInput) - new_password2 = forms.CharField(label=("New password confirmation"), + new_password2 = forms.CharField(label=_("New password confirmation"), widget=forms.PasswordInput) def clean_new_password2(self): From 3e32e5127be5eebc9107edd7c791ad3f87f9a1c9 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sun, 24 Sep 2017 15:55:52 +0530 Subject: [PATCH 62/82] Added ResendActivationLinkViewMixin --- utils/views.py | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/utils/views.py b/utils/views.py index 3150fa6d..4ec39bce 100644 --- a/utils/views.py +++ b/utils/views.py @@ -2,6 +2,7 @@ from django.conf import settings from django.contrib import messages from django.contrib.auth import authenticate, login from django.contrib.auth.tokens import default_token_generator +from django.core.urlresolvers import reverse_lazy from django.http import HttpResponseRedirect from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode @@ -63,9 +64,45 @@ class LoginViewMixin(FormView): return super(LoginViewMixin, self).get(request, *args, **kwargs) +class ResendActivationLinkViewMixin(FormView): + success_message = _( + "An email with the activation link has been sent to your email") + + def generate_email_context(self, user): + context = { + 'base_url': "{0}://{1}".format(self.request.scheme, + self.request.get_host()), + 'activation_link': reverse_lazy( + 'hosting:validate', + kwargs={'validate_slug': user.validation_slug} + ), + 'dcl_text': settings.DCL_TEXT, + } + return context + + def form_valid(self, form): + email = form.cleaned_data.get('email') + user = CustomUser.objects.get(email=email) + messages.add_message(self.request, messages.SUCCESS, + self.success_message) + context = self.generate_email_context(user) + email_data = { + 'subject': '{dcl_text} {account_activation}'.format( + dcl_text=settings.DCL_TEXT, + account_activation=_('Account Activation') + ), + 'to': email, + 'context': context, + 'template_name': self.email_template_name, + 'template_path': self.email_template_path, + 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS + } + email = BaseEmail(**email_data) + email.send() + return HttpResponseRedirect(self.get_success_url()) + + class PasswordResetViewMixin(FormView): - # template_name = 'hosting/reset_password.html' - # form_class = PasswordResetRequestForm success_message = _( "The link to reset your email has been sent to your email") site = '' @@ -78,7 +115,6 @@ class PasswordResetViewMixin(FormView): 'site_name': 'ungleich' if self.site != 'dcl' else settings.DCL_TEXT, 'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host()) - } return context @@ -104,11 +140,8 @@ class PasswordResetViewMixin(FormView): class PasswordResetConfirmViewMixin(FormView): - # template_name = 'hosting/confirm_reset_password.html' form_class = SetPasswordForm - # success_url = reverse_lazy('hosting:login') - def post(self, request, uidb64=None, token=None, *arg, **kwargs): try: uid = urlsafe_base64_decode(uidb64) From 24522908e0332b6135fadc7c789df662a591d85f Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sun, 24 Sep 2017 16:02:06 +0530 Subject: [PATCH 63/82] Added resend activation link to login page --- hosting/templates/hosting/login.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hosting/templates/hosting/login.html b/hosting/templates/hosting/login.html index 9f18fda9..82056d2f 100644 --- a/hosting/templates/hosting/login.html +++ b/hosting/templates/hosting/login.html @@ -44,6 +44,8 @@ <a class="unlink" href="{% url 'hosting:signup' %}">{% trans "Sign up"%}</a> <span class="text"> or </span> <a class="unlink" href="{% url 'hosting:reset_password' %}">{% trans "Forgot your password ? "%}</a> + <span class="text"> or </span><br/> + <a class="unlink" href="{% url 'hosting:resend_activation_link' %}">{% trans "Resend activation link"%}</a> </div> </div> </div> From 84db1606a346707ec50464a5c7d9dd16a95ffec1 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sun, 24 Sep 2017 18:04:11 +0530 Subject: [PATCH 64/82] Added resend_activation_link.html template file --- .../hosting/resend_activation_link.html | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 hosting/templates/hosting/resend_activation_link.html diff --git a/hosting/templates/hosting/resend_activation_link.html b/hosting/templates/hosting/resend_activation_link.html new file mode 100644 index 00000000..fffb6e59 --- /dev/null +++ b/hosting/templates/hosting/resend_activation_link.html @@ -0,0 +1,36 @@ +{% extends "hosting/base_short.html" %} +{% load staticfiles bootstrap3%} +{% load i18n %} + +{% block navbar %} + {% include 'hosting/includes/_navbar_transparent.html' %} +{% endblock navbar %} + + +{% block content %} +<div class="auth-container"> + <div class="auth-bg"></div> + <div class="auth-center"> + <div class="auth-title"> + <h2>{% trans "Your VM hosted in Switzerland"%}</h2> + </div> + <div class="auth-content"> + <div class="intro-message auth-box sign-up"> + <h2 class="section-heading">{% trans "Resend activation link"%}</h2> + <form action="{% url 'hosting:resend_activation_link' %}" method="post" class="form" novalidate> + {% csrf_token %} + {% for field in form %} + {% bootstrap_field field show_label=False %} + {% endfor %} + {% buttons %} + <button type="submit" class="btn btn-block btn-success"> + {% trans "Submit"%} + </button> + {% endbuttons %} + </form> + + </div> + </div> + </div> +</div> +{% endblock %} From cd5607b44e9f062707450601026e99fcdf9f0246 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sun, 24 Sep 2017 19:04:18 +0530 Subject: [PATCH 65/82] Updated hosting django.po --- hosting/locale/de/LC_MESSAGES/django.po | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index b273dbcf..0db6580d 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-09-23 19:00+0530\n" +"POT-Creation-Date: 2017-09-24 12:34+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -306,6 +306,9 @@ msgstr "Registrieren" msgid "Forgot your password ? " msgstr "Passwort vergessen?" +msgid "Resend activation link" +msgstr "" + msgid "Notifications" msgstr "Benachrichtigungen" @@ -601,8 +604,11 @@ msgstr "" #, python-format msgid "" -"Your Virtual Machine %(virtual_machine.name)s is successfully terminated!" -msgstr "Deine Virtuelle Machine (VM) %(virtual_machine.name)s wurde erfolgreich beendet!" +"Your Virtual Machine <strong>%(machine_name)s</strong> is successfully " +"terminated!" +msgstr "" +"Deine Virtuelle Machine (VM) <strong>%(machine_name)s</strong> wurde erfolgreich " +"beendet!" msgid "Virtual Machines" msgstr "Virtuelle Maschinen" From 70d5efb21a230c53de61f1c51219a75567d63d5f Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Mon, 25 Sep 2017 02:09:49 +0530 Subject: [PATCH 66/82] Update hosting django.po with a de translation --- hosting/locale/de/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 0db6580d..ec11986b 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -307,7 +307,7 @@ msgid "Forgot your password ? " msgstr "Passwort vergessen?" msgid "Resend activation link" -msgstr "" +msgstr "Aktivierungslink noch einmal senden" msgid "Notifications" msgstr "Benachrichtigungen" From a73bcaef05053ee585fe5d08e03716ab964bc0f2 Mon Sep 17 00:00:00 2001 From: "M.Ravi" <mondi.ravi@gmail.com> Date: Mon, 25 Sep 2017 09:35:18 +0200 Subject: [PATCH 67/82] Store hash --- hosting/views.py | 2 +- opennebula_api/models.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hosting/views.py b/hosting/views.py index d7c4c168..887a4bb6 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -319,7 +319,7 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin): messages.success(request, _('Password has been reset.')) # Change opennebula password - opennebula_client.change_user_password(new_password) + opennebula_client.change_user_password(user.password) return self.form_valid(form) else: diff --git a/opennebula_api/models.py b/opennebula_api/models.py index d584bf26..057139c0 100644 --- a/opennebula_api/models.py +++ b/opennebula_api/models.py @@ -438,11 +438,11 @@ class OpenNebulaManager(): self.oneadmin_client.call(oca.VmTemplate.METHODS[ 'delete'], template_id, False) - def change_user_password(self, new_password): + def change_user_password(self, passwd_hash): self.oneadmin_client.call( oca.User.METHODS['passwd'], self.opennebula_user.id, - new_password + passwd_hash ) def add_public_key(self, user, public_key='', merge=False): From 04c29d0622f491641f0633c3054d49164fe86495 Mon Sep 17 00:00:00 2001 From: verysanghee <verysanghee@gmail.com> Date: Mon, 25 Sep 2017 20:17:12 +0200 Subject: [PATCH 68/82] Update django.po --- utils/locale/de/LC_MESSAGES/django.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/locale/de/LC_MESSAGES/django.po b/utils/locale/de/LC_MESSAGES/django.po index fdc21502..92593c40 100644 --- a/utils/locale/de/LC_MESSAGES/django.po +++ b/utils/locale/de/LC_MESSAGES/django.po @@ -772,13 +772,13 @@ msgid "The link to reset your email has been sent to your email" msgstr "Der Link zum Zur?cksetzen deines Passwortes wurde an deine E-Mail gesendet" msgid "Password Reset" -msgstr "" +msgstr "Passwort zurücksetzen" msgid "Password has been reset." -msgstr "Das Passwort wurde zur?ckgesetzt." +msgstr "Das Passwort wurde zurückgesetzt." msgid "Password reset has not been successful." -msgstr "Das Zur?cksetzen war nicht erfolgreich." +msgstr "Das Zurücksetzen war nicht erfolgreich." msgid "The reset password link is no longer valid." -msgstr "Der Link zum Zur?cksetzen deines Passwortes ist nicht l?nger g?ltig." +msgstr "Der Link zum Zurücksetzen Deines Passwortes ist nicht länger gültig." From bb8c1a72fde2f7da13cfbc63e6abb08637b16b8f Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Mon, 25 Sep 2017 23:52:40 +0530 Subject: [PATCH 69/82] Add missing import get_language --- hosting/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index d7c4c168..7ce66e57 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -16,7 +16,7 @@ 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 ugettext_lazy as _ +from django.utils.translation import get_language, ugettext_lazy as _ from django.utils.translation import ugettext from django.views.generic import ( View, CreateView, FormView, ListView, DetailView, DeleteView, From c2844d25ed53ee5b1834b2bc47176698cc05c9b4 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 00:06:17 +0530 Subject: [PATCH 70/82] Corrected a de spelling --- utils/locale/de/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/locale/de/LC_MESSAGES/django.po b/utils/locale/de/LC_MESSAGES/django.po index 92593c40..794b5fd9 100644 --- a/utils/locale/de/LC_MESSAGES/django.po +++ b/utils/locale/de/LC_MESSAGES/django.po @@ -769,7 +769,7 @@ msgid "Message" msgstr "Nachricht" msgid "The link to reset your email has been sent to your email" -msgstr "Der Link zum Zur?cksetzen deines Passwortes wurde an deine E-Mail gesendet" +msgstr "Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet" msgid "Password Reset" msgstr "Passwort zurücksetzen" From e2779314b053c142764839c2f545ddc1b2474ac5 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 00:25:54 +0530 Subject: [PATCH 71/82] Fix cancel vm modal text translation --- hosting/locale/de/LC_MESSAGES/django.po | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index b273dbcf..f28fe9db 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -602,7 +602,8 @@ msgstr "" #, python-format msgid "" "Your Virtual Machine %(virtual_machine.name)s is successfully terminated!" -msgstr "Deine Virtuelle Machine (VM) %(virtual_machine.name)s wurde erfolgreich beendet!" +msgstr "" +"Deine Virtuelle Machine (VM) %(virtual_machine.name)s wurde erfolgreich beendet!" msgid "Virtual Machines" msgstr "Virtuelle Maschinen" From 889d737c7ca779c4285967020d5b21d622008693 Mon Sep 17 00:00:00 2001 From: verysanghee <verysanghee@gmail.com> Date: Mon, 25 Sep 2017 20:58:59 +0200 Subject: [PATCH 72/82] Update django.po --- hosting/locale/de/LC_MESSAGES/django.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index b273dbcf..8d4db60e 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -644,13 +644,13 @@ msgid "Sorry. Your request is invalid." msgstr "Entschuldigung, deine Anfrage ist ungültig." msgid "Password has been reset." -msgstr "" +msgstr "Dein Passwort wurde erfolgreich zurückgesetzt." msgid "Password reset has not been successful." -msgstr "" +msgstr "Dein Passwort konnte nicht zurückgesetzt werden." msgid "The reset password link is no longer valid." -msgstr "" +msgstr "Der Link zum Zurücksetzen Deines Passwortes ist nicht mehr gültig." msgid "Invalid credit card" msgstr "Ungültige Kreditkarte" From a9755ccbff787df6f85d471f01ea7570f7c89125 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 00:34:33 +0530 Subject: [PATCH 73/82] Updated hosting django.po --- hosting/locale/de/LC_MESSAGES/django.po | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 8d4db60e..d6b01d6e 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-09-23 19:00+0530\n" +"POT-Creation-Date: 2017-09-25 19:00+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -601,8 +601,11 @@ msgstr "" #, python-format msgid "" -"Your Virtual Machine %(virtual_machine.name)s is successfully terminated!" -msgstr "Deine Virtuelle Machine (VM) %(virtual_machine.name)s wurde erfolgreich beendet!" +"Your Virtual Machine <strong>%(machine_name)s</strong> is successfully " +"terminated!" +msgstr "" +"Deine Virtuelle Machine (VM) <strong>%(machine_name)s</strong> wurde erfolgreich " +"beendet!" msgid "Virtual Machines" msgstr "Virtuelle Maschinen" From 2f4b7bb7492bd43d78e3c887de6d2834de327c8f Mon Sep 17 00:00:00 2001 From: verysanghee <verysanghee@gmail.com> Date: Mon, 25 Sep 2017 21:07:33 +0200 Subject: [PATCH 74/82] Update django.po --- hosting/locale/de/LC_MESSAGES/django.po | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 8d4db60e..34129d5b 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -353,7 +353,7 @@ msgid "Order summary" msgstr "Bestellungsübersicht" msgid "Product" -msgstr "" +msgstr "Produkt" msgid "Cores" msgstr "Prozessorkerne" @@ -588,7 +588,7 @@ msgid "We are here to help you!" msgstr "Wir sind hier, um Dir zu helfen!" msgid "CONTACT" -msgstr "KONTACT" +msgstr "KONTAKT" msgid "Terminate your Virtual Machine" msgstr "Deine Virtuelle Maschine beenden" @@ -707,7 +707,7 @@ msgstr "VM Kündigung" #~ msgstr "VM %(VM_ID)s erfolgreich beendet" #~ msgid "days" -#~ msgstr "tage" +#~ msgstr "Tage" #~ msgid "New Virtual Machine" #~ msgstr "Neue virtuelle Maschine" @@ -740,7 +740,7 @@ msgstr "VM Kündigung" #~ msgstr "Meine Bestellungen" #~ msgid "SSH Keys" -#~ msgstr "SSH Key" +#~ msgstr "SSH Keys" #~ msgid "Notifications " #~ msgstr "Benachrichtigungen" @@ -788,19 +788,19 @@ msgstr "VM Kündigung" #~ msgstr "Hinzufügen" #~ msgid "Keys" -#~ msgstr "Schlüssel" +#~ msgstr "Keys" #~ msgid "Log in" #~ msgstr "Anmelden" #~ msgid "You haven been logged out" -#~ msgstr "Sie wurden abgmeldet" +#~ msgstr "Du wurdest abgemeldet" #~ msgid "How it works" #~ msgstr "So funktioniert es" #~ msgid "Your infrastructure" -#~ msgstr "deine Infrastruktur" +#~ msgstr "Deine Infrastruktur" #~ msgid "Our inftrastructure" #~ msgstr "Unsere Infrastruktur" @@ -808,11 +808,11 @@ msgstr "VM Kündigung" #~ msgid "Pricing" #~ msgstr "Preise" -#~ msgid "Access Key" -#~ msgstr "Zugriffsschlüssel" +#~ msgid "SSH Key" +#~ msgstr "SSH Key" #~ msgid "Upload your own key. " -#~ msgstr "Lade deinen Key hoch" +#~ msgstr "Lade Deinen Key hoch" #~ msgid "Generate Key Pair" #~ msgstr "Schlüsselpaar generieren" @@ -836,5 +836,5 @@ msgstr "VM Kündigung" #~ "Your SSH private key was already generated and downloaded, if you lost " #~ "it, contact us. " #~ msgstr "" -#~ "Dein privater SSH Schlüssel wurde bereits generiert und heruntergeladen. " -#~ "Falls du ihn verloren hast, kontaktiere uns." +#~ "Dein privater SSH Key wurde bereits generiert und heruntergeladen. " +#~ "Falls Du ihn verloren hast, kontaktiere uns." From e85a7c9e2a2a8ac52362c6e07f7650ab75c28800 Mon Sep 17 00:00:00 2001 From: verysanghee <verysanghee@gmail.com> Date: Mon, 25 Sep 2017 21:14:19 +0200 Subject: [PATCH 75/82] Update django.po --- hosting/locale/de/LC_MESSAGES/django.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 34129d5b..e4300f27 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -28,10 +28,10 @@ msgid "User does not exist" msgstr "Der Benutzer existiert nicht" msgid "Paste here your public key" -msgstr "Füge deinen Public Key ein" +msgstr "Füge Deinen Public Key ein" msgid "Give a name to your key" -msgstr "Gebe deinem SSH-Key einen Name" +msgstr "Gebe Deinem SSH-Key einen Name" msgid "Key name" msgstr "Key-Name" @@ -808,7 +808,7 @@ msgstr "VM Kündigung" #~ msgid "Pricing" #~ msgstr "Preise" -#~ msgid "SSH Key" +#~ msgid "Access Key" #~ msgstr "SSH Key" #~ msgid "Upload your own key. " From f35663b5ac4bde37b7095b203298d11f45a956c6 Mon Sep 17 00:00:00 2001 From: verysanghee <verysanghee@gmail.com> Date: Mon, 25 Sep 2017 21:18:46 +0200 Subject: [PATCH 76/82] Update django.po --- hosting/locale/de/LC_MESSAGES/django.po | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index e4300f27..27ff9bb2 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -156,10 +156,10 @@ msgid "Upload" msgstr "Hochladen" msgid "Your VM hosted in Switzerland" -msgstr "deine VM in der Schweiz" +msgstr "Deine VM in der Schweiz" msgid "Set your new password" -msgstr "Setze dein neues Passwort" +msgstr "Setze Dein neues Passwort" msgid "Reset" msgstr "Zurücksetzen" @@ -180,7 +180,7 @@ msgid "My VMs" msgstr "Meine VMs" msgid "My SSH Keys" -msgstr "Meine SSH Keys" +msgstr "Meine SSH-Keys" msgid "My Bills" msgstr "Meine Rechnungen" @@ -229,10 +229,10 @@ msgid "" "Thank you!\n" msgstr "" "\n" -"Du erhälst diese E-Mail da du dein Passwort für deinen Account bei " +"Du erhälst diese E-Mail da Du Dein Passwort für Deinen Account bei " "%(site_name)s zurücksetzen möchtest.<br/>\n" "Bitte folge diesem Link und wähle ein neues Passwort: %(base_url)s" -"%(password_reset_url)s Solltest du kein neues Passwort angefordert haben, " +"%(password_reset_url)s Solltest Du kein neues Passwort angefordert haben, " "dann ignoriere diese E-Mail.<br/>\n" "Dankeschön!\n" @@ -245,10 +245,10 @@ msgid "" "If you didn't request a new password, ignore this e-mail.\n" "Thank you!\n" msgstr "" -"Du erhälst diese E-Mail da du dein Passwort für deinen Account bei " +"Du erhälst diese E-Mail da Du Dein Passwort für Deinen Account bei " "%(site_name)s zurücksetzen möchtest.\n" "Bitte folge diesem Link und wähle ein neues Passwort: %(base_url)s" -"%(password_reset_url)s Solltest du kein neues Passwort angefordert haben, " +"%(password_reset_url)s Solltest Du kein neues Passwort angefordert haben, " "dann ignoriere diese E-Mail.\n" "Dankeschön!\n" @@ -260,11 +260,11 @@ msgid "" "If you want to order a new virtual machine, you can do it by clicking <a " "href=\"%(base_url)s%(my_virtual_machines_url)s\">this link</a>.<br/>\n" msgstr "" -"Du erhälst diese E-Mail, da deine virtuelle Maschine [%(vm_name)s] gekündigt " +"Du erhälst diese E-Mail, Da Deine virtuelle Maschine [%(vm_name)s] gekündigt " "wurde.<br/>\n" -"Um deinen Auftragsstatus zu sehen, klicke auf die [my VM page] unten.<br/>\n" -"Falls du eine neue virtuelle Maschine bestellen möchtest, kannst du dies " -"tun, indem du <a href=\"%(base_url)s%(my_virtual_machines_url)s\">diesen " +"Um Deinen Auftragsstatus zu sehen, klicke auf die [my VM page] unten.<br/>\n" +"Falls Du eine neue virtuelle Maschine bestellen möchtest, kannst Du dies " +"tun, indem Du <a href=\"%(base_url)s%(my_virtual_machines_url)s\">diesen " "Link klickst</a>.<br/>\n" msgid "My VM page" @@ -280,12 +280,12 @@ msgid "" "link.\n" "%(base_url)s%(my_virtual_machines_url)s\n" msgstr "" -"Du erhälst diese E-Mail, da deine virtuelle Maschine [%(vm_name)s] gekündigt " +"Du erhälst diese E-Mail, da Deine virtuelle Maschine [%(vm_name)s] gekündigt " "wurde.\n" -"Um deinen Auftragsstatus zu sehen, klicke hier.\n" +"Um Deinen Auftragsstatus zu sehen, klicke hier.\n" "%(base_url)s%(vm_order_url)s\n" -"Falls du eine neue virtuelle Maschine bestellen möchtest, kannst du dies " -"tun, indem du diesen Link klickst.\n" +"Falls Du eine neue virtuelle Maschine bestellen möchtest, kannst Du dies " +"tun, indem Du diesen Link klickst.\n" "%(base_url)s%(my_virtual_machines_url)s\n" msgid "Toggle navigation" From 25f3118126f8777ed166e93c46b9b48f1060355d Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 01:06:35 +0530 Subject: [PATCH 77/82] Updated Changelog --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index 33184f98..7ba5e634 100644 --- a/Changelog +++ b/Changelog @@ -6,6 +6,7 @@ Pre-changelog: 1.2.3 2017-09-20 * #3786: [hosting] Redesigned the hosting invoice and order-confirmation page * #3728: [hosting] VM Termination animation added * #3777: [hosting] Create new VM calculator added like dcl landing + * #3806: [hosting] Fix can not create VMs after password reset * Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls * Bugfix: [dcl, hosting] added host to celery error mails * Bugfix: [ungleich] Fixed wrong subdomain digitalglarus.ungleich.ch From 75ff7e4ea86f14bce202d2cf0dc202734a1e2872 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 01:53:19 +0530 Subject: [PATCH 78/82] Added some translations --- utils/locale/de/LC_MESSAGES/django.po | 30 +++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/utils/locale/de/LC_MESSAGES/django.po b/utils/locale/de/LC_MESSAGES/django.po index 794b5fd9..04d1f4dc 100644 --- a/utils/locale/de/LC_MESSAGES/django.po +++ b/utils/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-09-02 11:50+0000\n" +"POT-Creation-Date: 2017-09-25 20:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -738,6 +738,24 @@ msgstr "" msgid "Enter your name or company name" msgstr "Geben Sie Ihren Namen oder der Ihrer Firma ein" +msgid "Your username and/or password were incorrect." +msgstr "Dein Benutzername und/oder Dein Passwort ist falsch." + +msgid "User does not exist" +msgstr "Der Benutzer existiert nicht" + +msgid "The account is already active." +msgstr "" + +msgid "The two password fields didn't match." +msgstr "" + +msgid "New password" +msgstr "" + +msgid "New password confirmation" +msgstr "" + msgid "Cardholder Name" msgstr "Name des Kartenbesitzer" @@ -768,8 +786,16 @@ msgstr "Telefon" msgid "Message" msgstr "Nachricht" +msgid "An email with the activation link has been sent to your email" +msgstr "" +"Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet" + +msgid "Account Activation" +msgstr "Accountaktivierung" + msgid "The link to reset your email has been sent to your email" -msgstr "Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet" +msgstr "" +"Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet" msgid "Password Reset" msgstr "Passwort zurücksetzen" From 6bf89669eff4b8faef57eba42097a97778a5e33c Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 02:07:28 +0530 Subject: [PATCH 79/82] some more de translations --- utils/locale/de/LC_MESSAGES/django.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/locale/de/LC_MESSAGES/django.po b/utils/locale/de/LC_MESSAGES/django.po index 04d1f4dc..f8374e4e 100644 --- a/utils/locale/de/LC_MESSAGES/django.po +++ b/utils/locale/de/LC_MESSAGES/django.po @@ -745,16 +745,16 @@ msgid "User does not exist" msgstr "Der Benutzer existiert nicht" msgid "The account is already active." -msgstr "" +msgstr "Das Benutzerkonto ist bereits aktiv." msgid "The two password fields didn't match." -msgstr "" +msgstr "Die beiden Passwörter stimmen nicht überein." msgid "New password" -msgstr "" +msgstr "Neues Passwort" msgid "New password confirmation" -msgstr "" +msgstr "Neues Passwort Bestätigung" msgid "Cardholder Name" msgstr "Name des Kartenbesitzer" From 7933584942bee21a167c46e21c0f06f75410249d Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 02:13:49 +0530 Subject: [PATCH 80/82] Updated changelog --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index 7ba5e634..7f4394dd 100644 --- a/Changelog +++ b/Changelog @@ -6,6 +6,7 @@ Pre-changelog: 1.2.3 2017-09-20 * #3786: [hosting] Redesigned the hosting invoice and order-confirmation page * #3728: [hosting] VM Termination animation added * #3777: [hosting] Create new VM calculator added like dcl landing + * #3781: [hosting] Resend activation mail * #3806: [hosting] Fix can not create VMs after password reset * Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls * Bugfix: [dcl, hosting] added host to celery error mails From 29a45e81bf943beeeaf43260b096f0c38bbc32af Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 02:24:17 +0530 Subject: [PATCH 81/82] Include cdist 4.7.0 in requirements.txt --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6446a5c9..89285c83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -96,5 +96,4 @@ pyflakes==1.5.0 billiard==3.5.0.3 amqp==2.2.1 vine==1.1.4 -#git+https://github.com/ungleich/cdist.git#egg=cdist -file:///home/app/cdist#egg=cdist +cdist==4.7.0 From 543465e89bbb154d0845f3287d64967e0320ca77 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Tue, 26 Sep 2017 02:34:10 +0530 Subject: [PATCH 82/82] Update Changelog for 1.2.3 --- Changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 7f4394dd..f03a04ed 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,4 @@ -Pre-changelog: 1.2.3 2017-09-20 +1.2.3: 2017-09-25 * #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email * #3731: [dcl, hosting] Added cdist ssh key handler * #3628: [dcl] on hosting, VM is created at credit card info submit