diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 72977d27..f6628b9f 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-06-15 23:57+0530\n" +"POT-Creation-Date: 2017-06-19 12:22+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -83,6 +83,53 @@ msgstr "" msgid "Thank you!" msgstr "Vielen Dank!" +#: templates/datacenterlight/emails/user_activation.html:99 +#: templates/datacenterlight/emails/user_activation.txt:3 +msgid "account activation" +msgstr "Accountaktivierung" + +#: templates/datacenterlight/emails/user_activation.html:105 +#, python-format +msgid "" +"\n" +" You can activate your %(dcl_text)s account by clicking here.

\n" +" You can also copy and paste the following link into the " +"address bar of your browser and follow the link in order to activate your " +"datacenterlight account.
\n" +" %(base_url)s%(activation_link)s\n" +" " +msgstr "\n" +" Klicke hier um deinen %(dcl_text)s zu aktivieren.

\n" +" Oder kopiere den folgenden Link in die Adressleiste deines Browsers und folge dann dem Link um deinen %(dcl_text)s Account zu aktivieren.
\n" +" %(base_url)s%(activation_link)s\n" +" " + +#: templates/datacenterlight/emails/user_activation.html:123 +#: templates/datacenterlight/emails/user_activation.txt:11 +#| msgid "Your Name" +msgid "Your" +msgstr "Dein" + +#: templates/datacenterlight/emails/user_activation.html:123 +#: templates/datacenterlight/emails/user_activation.txt:11 +msgid "team" +msgstr "Team" + +#: templates/datacenterlight/emails/user_activation.txt:5 +#, python-format +msgid "" +"\n" +"Hi,\n" +"\n" +"You can activate your %(dcl_text)s account by clicking here %(base_url)s" +"%(activation_link)s\n" +msgstr "" +"\n" +"Hallo,\n" +"\n" +"Du kannst deinen %(dcl_text)s Account aktivieren, indem du hier klickst %(base_url)s" +"%(activation_link)s\n" #: templates/datacenterlight/includes/_footer.html:11 #: templates/datacenterlight/includes/_footer.html:31 #: templates/datacenterlight/includes/_navbar.html:27 @@ -184,7 +231,6 @@ msgstr "" "Angebot ist aufgrund unserer leichten Infrastruktur überaus kostengünstig." #: templates/datacenterlight/index.html:133 -#: templates/datacenterlight/order.html:87 #: templates/datacenterlight/pricing.html:86 msgid "Simple and affordable: Try our virtual machine with featherlight price." msgstr "" @@ -196,7 +242,6 @@ msgid "Affordable VM hosting based in Switzerland" msgstr "Bezahlbares VM Hosting in der Schweiz" #: templates/datacenterlight/index.html:145 -#: templates/datacenterlight/order.html:22 #: templates/datacenterlight/pricing.html:22 msgid "VM hosting" msgstr "" @@ -206,19 +251,16 @@ msgid "month" msgstr "Monat" #: templates/datacenterlight/index.html:151 -#: templates/datacenterlight/order.html:28 #: templates/datacenterlight/pricing.html:28 msgid "VAT included" msgstr "MwSt. inklusive" #: templates/datacenterlight/index.html:156 -#: templates/datacenterlight/order.html:33 #: templates/datacenterlight/pricing.html:33 msgid "Hosted in Switzerland" msgstr "Standort: Schweiz" #: templates/datacenterlight/index.html:173 -#: templates/datacenterlight/order.html:50 #: templates/datacenterlight/pricing.html:50 msgid "GB Storage (SSD)" msgstr "GB Storage (SSD)" @@ -240,7 +282,6 @@ msgid "Your Email" msgstr "Deine E-Mail" #: templates/datacenterlight/index.html:197 -#: templates/datacenterlight/order.html:77 #: templates/datacenterlight/pricing.html:79 msgid "Order Now!" msgstr "Bestelle jetzt!" @@ -257,12 +298,10 @@ msgstr "Fragen?" msgid "Contact us!" msgstr "Kontaktiere uns!" -#: templates/datacenterlight/order.html:9 #: templates/datacenterlight/pricing.html:9 msgid "We are cutting down the costs significantly!" msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen" -#: templates/datacenterlight/order.html:90 #: templates/datacenterlight/pricing.html:89 msgid "" "Our VMs are hosted in Glarus, Switzerland, and our website is currently " diff --git a/datacenterlight/templates/datacenterlight/emails/user_activation.html b/datacenterlight/templates/datacenterlight/emails/user_activation.html index 2948b797..bf688127 100644 --- a/datacenterlight/templates/datacenterlight/emails/user_activation.html +++ b/datacenterlight/templates/datacenterlight/emails/user_activation.html @@ -1,11 +1,12 @@ {% load static from staticfiles %} +{% load i18n %} -Oxygen Invoice +{{dcl_text}} - - - - - - - - - - -
-
- - -
- -
- - - -
- logo - -
-
- -
-
-
-
- - - - - - - - - - -
- Datacenterlight user activation -
-

- You can activate your datacenterlight account by clicking here.

- You can also copy and paste the following link into the address bar of your browser and follow the link in order to activate your datacenterlight account.
- {{base_url}}{{activation_link}} -

 
-
-
-
- - -
Your data center light team
-
-
-
- - +{% load i18n %} +{{dcl_text}} {% trans 'account activation' %} +{% blocktrans %} +Hi, + +You can activate your {{dcl_text}} account by clicking here {{base_url}}{{activation_link}} +{% endblocktrans %} + +{% trans 'Your' %} {{dcl_text}} {% trans 'team' %} diff --git a/datacenterlight/templates/datacenterlight/order_detail.html b/datacenterlight/templates/datacenterlight/order_detail.html new file mode 100644 index 00000000..cb412558 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/order_detail.html @@ -0,0 +1,79 @@ +{% extends "hosting/base_short.html" %} +{% load staticfiles bootstrap3 %} +{% load i18n %} +{% block content %} + +
+ {% if messages %} +
+
+
+
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+
+
+ {% endif %} + {% if not error %} +
+
+
+

{% trans "Confirm Order"%}

{% trans "Order #"%} {{order.id}}

+
+
+
+
+
+

{% trans "Billed To:"%}

+ {{user.name}}
+ {{order.billing_address.street_address}},{{order.billing_address.postal_code}}
+ {{order.billing_address.city}}, {{order.billing_address.country}}. +
+
+
+
+ {% trans "Date"%}:
+ {{order.created_at}}

+
+ +
+
+
+
+
+ {% trans "Payment Method:"%}
+ {{order.cc_brand}} ending **** {{order.last4}}
+ {{user.email}} +
+
+
+
+
+ +
+
+

{% trans "Order summary"%}

+
+
+

{% trans "Cores"%} {{vm.cores}}

+
+

{% trans "Memory"%} {{vm.memory}} GB

+
+

{% trans "Disk space"%} {{vm.disk_size}} GB

+
+

{% trans "Total"%}

{{vm.price}} CHF

+
+
+ {% url 'datacenterlight:payment' as payment_url %} + {% if payment_url in request.META.HTTP_REFERER %} + + {% endif %} +
+
+ {% endif %} +
+{%endblock%} diff --git a/datacenterlight/urls.py b/datacenterlight/urls.py index aad6442e..65401b13 100644 --- a/datacenterlight/urls.py +++ b/datacenterlight/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import url -from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView, SuccessView +from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView, SuccessView, PaymentOrderView, OrderConfirmationView urlpatterns = [ @@ -8,6 +8,8 @@ urlpatterns = [ url(r'^/beta-program/?$', BetaProgramView.as_view(), name='beta'), url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'), url(r'^/pricing/?$', PricingView.as_view(), name='pricing'), + url(r'^/payment/?$', PaymentOrderView.as_view(), name='payment'), + url(r'^/order-confirmation/(?P\d+)/?$', OrderConfirmationView.as_view(), name='order_confirmation'), url(r'^/order-success/?$', SuccessView.as_view(), name='order_success'), url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'), ] diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 427f8c70..e4329b89 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -1,4 +1,4 @@ -from django.views.generic import FormView, CreateView, TemplateView +from django.views.generic import FormView, CreateView, TemplateView, DetailView from django.http import HttpResponseRedirect from .forms import BetaAccessForm from .models import BetaAccess, BetaAccessVMType, BetaAccessVM @@ -10,9 +10,17 @@ from django.shortcuts import render from django.shortcuts import redirect from django import forms from django.core.exceptions import ValidationError +from django.views.decorators.cache import cache_control +from django.conf import settings +from utils.forms import BillingAddressForm, UserBillingAddressForm +from membership.models import StripeCustomer +from hosting.models import HostingOrder, HostingBill +from utils.stripe_utils import StripeUtils +from datetime import datetime +from membership.models import CustomUser, StripeCustomer from opennebula_api.models import OpenNebulaManager -from opennebula_api.serializers import VirtualMachineTemplateSerializer +from opennebula_api.serializers import VirtualMachineTemplateSerializer, VirtualMachineSerializer class LandingProgramView(TemplateView): template_name = "datacenterlight/landing.html" @@ -20,6 +28,14 @@ class LandingProgramView(TemplateView): class SuccessView(TemplateView): template_name = "datacenterlight/success.html" + def get(self, request, *args, **kwargs): + if 'specs' not in request.session or 'user' not in request.session: + return HttpResponseRedirect(reverse('datacenterlight:index')) + else : + del request.session['specs'] + del request.session['user'] + return render(request, self.template_name) + class PricingView(TemplateView): template_name = "datacenterlight/pricing.html" @@ -170,7 +186,12 @@ class IndexView(CreateView): success_url = "/datacenterlight#requestform" success_message = "Thank you, we will contact you as soon as possible" + @cache_control(no_cache=True, must_revalidate=True, no_store=True) def get(self, request, *args, **kwargs): + if 'specs' in request.session : + del request.session['specs'] + if 'user' in request.session : + del request.session['user'] try: manager = OpenNebulaManager() templates = manager.get_templates() @@ -213,26 +234,22 @@ class IndexView(CreateView): messages.add_message(self.request, messages.ERROR, '%(value) is not a proper email.'.format(email)) return HttpResponseRedirect(reverse('datacenterlight:index')) - context = { - 'name': name, - 'email': email, - 'cores': cores, + specs = { + 'cpu': cores, 'memory': memory, - 'storage': storage, - 'price': price, - 'template': template_data['name'], + 'disk_size': storage, + 'price': price } - email_data = { - 'subject': "Data Center Light Order from %s" % context['email'], - 'from_email': '(datacenterlight) datacenterlight Support ', - 'to': ['info@ungleich.ch'], - 'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), - 'reply_to': [context['email']], + + this_user = { + 'name': name, + 'email': email } - email = EmailMessage(**email_data) - email.send() - - return HttpResponseRedirect(reverse('datacenterlight:order_success')) + + request.session['specs'] = specs + request.session['template'] = template_data + request.session['user'] = this_user + return HttpResponseRedirect(reverse('datacenterlight:payment')) def get_success_url(self): success_url = reverse('datacenterlight:index') @@ -281,3 +298,167 @@ class IndexView(CreateView): messages.add_message(self.request, messages.SUCCESS, self.success_message) return super(IndexView, self).form_valid(form) + + +class PaymentOrderView(FormView): + template_name = 'hosting/payment.html' + form_class = BillingAddressForm + + def get_context_data(self, **kwargs): + context = super(PaymentOrderView, self).get_context_data(**kwargs) + context.update({ + 'stripe_key': settings.STRIPE_API_PUBLIC_KEY + }) + return context + + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + if 'specs' not in request.session or 'user' not in request.session: + return HttpResponseRedirect(reverse('datacenterlight:index')) + return self.render_to_response(self.get_context_data()) + + def post(self, request, *args, **kwargs): + form = self.get_form() + if form.is_valid(): + # Get billing address data + billing_address_data = form.cleaned_data + context = self.get_context_data() + template = request.session.get('template') + specs = request.session.get('specs') + user = request.session.get('user') + vm_template_id = template.get('id', 1) + final_price = specs.get('price') + token = form.cleaned_data.get('token') + try: + custom_user = CustomUser.objects.get(email=user.get('email')) + except CustomUser.DoesNotExist: + password = CustomUser.get_random_password() + # Register the user, and do not send emails + CustomUser.register(user.get('name'), + password, + user.get('email'), + app='dcl', + base_url=None, send_email=False) + + + # Get or create stripe customer + customer = StripeCustomer.get_or_create(email=user.get('email'), + token=token) + if not customer: + form.add_error("__all__", "Invalid credit card") + return self.render_to_response(self.get_context_data(form=form)) + + # Create Billing Address + billing_address = form.save() + + # Make stripe charge to a customer + stripe_utils = StripeUtils() + charge_response = stripe_utils.make_charge(amount=final_price, + customer=customer.stripe_id) + charge = charge_response.get('response_object') + + # Check if the payment was approved + if not charge: + context.update({ + 'paymentError': charge_response.get('error'), + 'form': form + }) + return render(request, self.template_name, context) + + charge = charge_response.get('response_object') + + # Create OpenNebulaManager + manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, + password=settings.OPENNEBULA_PASSWORD) + + # Create a vm using logged user + vm_id = manager.create_vm( + template_id=vm_template_id, + specs=specs, + vm_name="{email}-{template_name}-{date}".format( + email=user.get('email'), + template_name=template.get('name'), + date=int(datetime.now().strftime("%s"))) + ) + + # Create a Hosting Order + order = HostingOrder.create( + price=final_price, + vm_id=vm_id, + customer=customer, + billing_address=billing_address + ) + + # Create a Hosting Bill + bill = HostingBill.create( + customer=customer, billing_address=billing_address) + + # Create Billing Address for User if he does not have one + if not customer.user.billing_addresses.count(): + billing_address_data.update({ + 'user': customer.user.id + }) + billing_address_user_form = UserBillingAddressForm( + billing_address_data) + billing_address_user_form.is_valid() + billing_address_user_form.save() + + # Associate an order with a stripe payment + order.set_stripe_charge(charge) + + # If the Stripe payment was successed, set order status approved + order.set_approved() + + vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data + + context = { + 'name': user.get('name'), + 'email': user.get('email'), + 'cores': specs.get('cpu'), + 'memory': specs.get('memory'), + 'storage': specs.get('disk_size'), + 'price': specs.get('price'), + 'template': template.get('name'), + 'vm.name': vm['name'], + 'vm.id': vm['vm_id'], + 'order.id': order.id + } + email_data = { + 'subject': "Data Center Light Order from %s" % context['email'], + 'from_email': '(Data Center Light) Data Center Light Support ', + 'to': ['info@ungleich.ch'], + 'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), + 'reply_to': [context['email']], + } + email = EmailMessage(**email_data) + email.send() + return HttpResponseRedirect(reverse('datacenterlight:order_confirmation', kwargs={'pk': order.id})) + else: + return self.form_invalid(form) + +class OrderConfirmationView(DetailView): + template_name = "datacenterlight/order_detail.html" + context_object_name = "order" + model = HostingOrder + def get_context_data(self, **kwargs): + # Get context + context = super(DetailView, self).get_context_data(**kwargs) + obj = self.get_object() + manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, + password=settings.OPENNEBULA_PASSWORD) + try: + vm = manager.get_vm(obj.vm_id) + context['vm'] = VirtualMachineSerializer(vm).data + context['next_url'] = reverse('datacenterlight:order_success') + except WrongIdError: + 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.' + ) + return context diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index ec240691..d276f022 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -504,3 +504,8 @@ OPENNEBULA_PORT = env('OPENNEBULA_PORT') # The endpoint to which the XML RPC request needs to be sent to. The # default value is /RPC2 OPENNEBULA_ENDPOINT = env('OPENNEBULA_ENDPOINT') + + +# dcl email configurations +DCL_TEXT = env('DCL_TEXT') +DCL_SUPPORT_FROM_ADDRESS = env('DCL_SUPPORT_FROM_ADDRESS') diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 9ee6f63c..674f3db4 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-05-30 13:47+0000\n" +"POT-Creation-Date: 2017-06-23 02:28+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,74 +18,68 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: hosting/forms.py:63 +#: forms.py:28 +msgid "Your account is not activated yet." +msgstr "Dein Account wurde noch nicht aktiviert." + +#: forms.py:65 msgid "Paste here your public key" msgstr "Fügen Sie Ihren public key ein" -#: hosting/templates/hosting/base_short.html:68 -#: hosting/templates/hosting/base_short.html:139 +#: templates/hosting/base_short.html:67 msgid "My Virtual Machines" msgstr "Meine virtuellen Maschinen" -#: hosting/templates/hosting/base_short.html:73 -#: hosting/templates/hosting/base_short.html:145 -#: hosting/templates/hosting/orders.html:12 +#: templates/hosting/base_short.html:72 templates/hosting/orders.html.py:12 msgid "My Orders" msgstr "Meine Bestellungen" -#: hosting/templates/hosting/base_short.html:78 -#: hosting/templates/hosting/base_short.html:152 +#: templates/hosting/base_short.html:81 msgid "Keys" msgstr "Schlüssel" -#: hosting/templates/hosting/base_short.html:83 -#: hosting/templates/hosting/base_short.html:158 +#: templates/hosting/base_short.html:86 msgid "Notifications " msgstr "Benachrichtigungen" -#: hosting/templates/hosting/base_short.html:90 +#: templates/hosting/base_short.html:89 msgid "Logout" -msgstr "Abmeleden" +msgstr "Abmelden" -#: hosting/templates/hosting/base_short.html:95 +#: templates/hosting/base_short.html:94 msgid "How it works" -msgstr "Wie es funktioniert" +msgstr "So funktioniert es" -#: hosting/templates/hosting/base_short.html:98 +#: templates/hosting/base_short.html:97 msgid "Your infrastructure" -msgstr "Ihre Infrastruktur" +msgstr "deine Infrastruktur" -#: hosting/templates/hosting/base_short.html:101 +#: templates/hosting/base_short.html:100 msgid "Our inftrastructure" msgstr "Unsere Infrastruktur" -#: hosting/templates/hosting/base_short.html:104 +#: templates/hosting/base_short.html:103 msgid "Pricing" msgstr "Preise" -#: hosting/templates/hosting/base_short.html:107 +#: templates/hosting/base_short.html:106 msgid "Contact" msgstr "Kontakt" -#: hosting/templates/hosting/base_short.html:110 -#: hosting/templates/hosting/login.html:32 -#: hosting/templates/hosting/login.html:41 -#: hosting/templates/hosting/reset_password.html:31 -#: hosting/templates/hosting/signup.html:30 +#: templates/hosting/base_short.html:109 +#: templates/hosting/confirm_reset_password.html:38 +#: templates/hosting/login.html:17 templates/hosting/login.html.py:26 +#: templates/hosting/reset_password.html:32 templates/hosting/signup.html:30 msgid "Login" msgstr "Anmelden" -#: hosting/templates/hosting/base_short.html:134 -msgid "Home" -msgstr "Home" - -#: templates/hosting/bill_detail.html:11 templates/hosting/order_detail.html:10 +#: templates/hosting/bill_detail.html:11 msgid "Invoice" msgstr "Rechnung" -#: templates/hosting/bill_detail.html:11 templates/hosting/order_detail.html:10 +#: templates/hosting/bill_detail.html:11 templates/hosting/order_detail.html:23 msgid "Order #" -msgstr "Rechnung #" +msgstr "Bestellung #" #: templates/hosting/bill_detail.html:25 msgid "ungleich GmbH" @@ -144,8 +138,7 @@ msgstr "" msgid "Customers" msgstr "Kunden" -#: hosting/templates/hosting/bills.html:16 -#: hosting/templates/hosting/virtual_machine_key.html:42 +#: templates/hosting/bills.html:16 templates/hosting/user_keys.html.py:25 msgid "Name" msgstr "" @@ -157,60 +150,65 @@ msgstr "" msgid "View Bill" msgstr "Rechnung anzeigen" -#: templates/hosting/bills.html:41 templates/hosting/orders.html.py:83 +#: templates/hosting/bills.html:41 templates/hosting/orders.html.py:82 #: templates/hosting/virtual_machines.html:70 msgid "previous" msgstr "vorherige" -#: templates/hosting/bills.html:47 templates/hosting/orders.html.py:89 +#: templates/hosting/bills.html:47 templates/hosting/orders.html.py:88 #: templates/hosting/virtual_machines.html:76 msgid "next" msgstr "nächste" #: templates/hosting/confirm_reset_password.html:10 -#: templates/hosting/login.html:9 templates/hosting/reset_password.html.py:9 -#: templates/hosting/signup.html:8 +#: templates/hosting/login.html:12 templates/hosting/reset_password.html:10 +#: templates/hosting/signup.html:9 templates/hosting/signup_validate.html:9 msgid "Your VM hosted in Switzerland" -msgstr "Ihre VM in der Schweiz" +msgstr "deine VM in der Schweiz" #: templates/hosting/confirm_reset_password.html:14 msgid "Set your new password" -msgstr "Setzen Ihr neues Passwort" +msgstr "Setze dein neues Passwort" -#: hosting/templates/hosting/confirm_reset_password.html:28 -#: hosting/templates/hosting/reset_password.html:22 +#: templates/hosting/confirm_reset_password.html:29 +#: templates/hosting/reset_password.html:23 msgid "Reset" msgstr "Zurücksetzen" -#: hosting/templates/hosting/confirm_reset_password.html:32 -#: hosting/templates/hosting/reset_password.html:28 -#: hosting/templates/hosting/signup.html:27 +#: templates/hosting/confirm_reset_password.html:35 +#: templates/hosting/reset_password.html:29 templates/hosting/signup.html:27 msgid "Already have an account ?" -msgstr "Besitzen sie bereits ein Bentzerkonto" +msgstr "Hast Du bereits ein Benutzerkonto?" -#: hosting/templates/hosting/confirm_reset_password.html:32 -msgid "Log in" -msgstr "Anmelden" - -#: hosting/templates/hosting/create_virtual_machine.html:19 +#: templates/hosting/create_virtual_machine.html:20 msgid "New Virtual Machine" msgstr "Neue virtuelle Maschine" -#: hosting/templates/hosting/create_virtual_machine.html:24 -msgid "Select VM Template:" -msgstr "Wählen Sie eine Vorlage" +#: templates/hosting/create_virtual_machine.html:28 +#, fuzzy +#| msgid "Select VM Template:" +msgid "Step 1. Select VM Template:" +msgstr "Wähle eine Vorlage" -#: hosting/templates/hosting/create_virtual_machine.html:32 -msgid "Select VM Configuration:" -msgstr "Wählen Sie eine Konfiguration" +#: templates/hosting/create_virtual_machine.html:42 +#, fuzzy +#| msgid "Select VM Configuration:" +msgid "Step2. Select VM Configuration" +msgstr "Wähle eine Konfiguration" -#: hosting/templates/hosting/create_virtual_machine.html:39 +#: templates/hosting/create_virtual_machine.html:59 +#, fuzzy +#| msgid "Pricing" +msgid "Price " +msgstr "Preis" + +#: templates/hosting/create_virtual_machine.html:59 msgid "CHF/Month" msgstr "CHF/Monat" -#: templates/hosting/create_virtual_machine.html:45 +#: templates/hosting/create_virtual_machine.html:61 msgid "Start VM" -msgstr "Start VM" +msgstr "VM jetzt starten" #: templates/hosting/emails/password_reset_email.html:2 #: templates/hosting/emails/password_reset_email.txt:2 @@ -236,21 +234,16 @@ msgstr "" msgid "The %(site_name)s team" msgstr "" -#: hosting/templates/hosting/login.html:26 -msgid "You haven been logged out" -msgstr "Sie wurden abgmeldet" - -#: hosting/templates/hosting/login.html:49 +#: templates/hosting/login.html:34 msgid "Don't have an account yet ? " -msgstr "Besitzen Sie kein Benutzerkonto?" +msgstr "Besitzt du kein Benutzerkonto?" -#: hosting/templates/hosting/login.html:52 -#: hosting/templates/hosting/signup.html:13 -#: hosting/templates/hosting/signup.html:21 +#: templates/hosting/login.html:37 templates/hosting/signup.html.py:13 +#: templates/hosting/signup.html:21 views.py:223 msgid "Sign up" msgstr "Registrieren" -#: hosting/templates/hosting/login.html:54 +#: templates/hosting/login.html:39 msgid "Forgot your password ? " msgstr "Passwort vergessen?" @@ -278,62 +271,59 @@ msgstr "Als gelesen markieren" msgid "All notifications" msgstr "Alle Benachrichtigungen" -#: templates/hosting/order_detail.html:16 -#: templates/hosting/order_detail.html:24 -msgid "Billed To:" -msgstr "" +#: templates/hosting/order_detail.html:23 +msgid "Confirm Order" +msgstr "Bestellung Bestätigen" -#: templates/hosting/order_detail.html:26 +#: templates/hosting/order_detail.html:29 +msgid "Billed To:" +msgstr "Rechnungsadresse" + +#: templates/hosting/order_detail.html:37 templates/hosting/orders.html:17 +msgid "Date" +msgstr "Datum" + +#: templates/hosting/order_detail.html:39 msgid "Status:" msgstr "" -#: templates/hosting/order_detail.html:38 +#: templates/hosting/order_detail.html:51 msgid "Payment Method:" msgstr "Bezahlmethode" -#: templates/hosting/order_detail.html:49 +#: templates/hosting/order_detail.html:62 msgid "Order summary" msgstr "Bestellungsübersicht" -#: hosting/templates/hosting/order_detail.html:52 -#: hosting/templates/hosting/payment.html:17 -#: hosting/templates/hosting/virtual_machine_detail.html:75 +#: templates/hosting/order_detail.html:65 templates/hosting/payment.html:17 +#: templates/hosting/virtual_machine_detail.html:76 msgid "Cores" msgstr "Prozessorkerne" -#: hosting/templates/hosting/order_detail.html:54 -#: hosting/templates/hosting/payment.html:20 -#: hosting/templates/hosting/virtual_machine_detail.html:81 -#: templates/hosting/order_detail.html:54 +#: templates/hosting/order_detail.html:67 templates/hosting/payment.html:20 #: templates/hosting/virtual_machine_detail.html:82 msgid "Memory" msgstr "Arbeitsspeicher" -#: hosting/templates/hosting/order_detail.html:56 -#: hosting/templates/hosting/payment.html:23 +#: templates/hosting/order_detail.html:69 templates/hosting/payment.html:23 msgid "Disk space" msgstr "Festplattenkapazität" -#: templates/hosting/order_detail.html:58 +#: templates/hosting/order_detail.html:71 msgid "Total" msgstr "" -#: templates/hosting/order_detail.html:64 +#: templates/hosting/order_detail.html:77 msgid "Finish Configuration" msgstr "Konfiguration beenden" -#: templates/hosting/orders.html:17 -msgid "Date" -msgstr "Datum" - #: templates/hosting/orders.html:18 msgid "Amount" msgstr "Betrag" -#: hosting/templates/hosting/orders.html:19 -#: hosting/templates/hosting/virtual_machine_detail.html:30 -#: hosting/templates/hosting/virtual_machine_key.html:44 -#: hosting/templates/hosting/virtual_machines.html:31 +#: templates/hosting/orders.html:19 templates/hosting/user_keys.html.py:27 +#: templates/hosting/virtual_machine_detail.html:30 +#: templates/hosting/virtual_machines.html:31 msgid "Status" msgstr "" @@ -349,59 +339,104 @@ msgstr "Abgelehnt" msgid "View Detail" msgstr "Details anzeigen" -#: templates/hosting/orders.html:41 +#: templates/hosting/orders.html:40 msgid "Cancel Order" msgstr "Bestellung stornieren" -#: templates/hosting/orders.html:56 -msgid "Do You want do delete your order?" -msgstr "Wollen Sie ihre Bestellung löschen?" +#: templates/hosting/orders.html:55 +msgid "Do You want to delete your order?" +msgstr "Willst du deine Bestellung löschen?" -#: templates/hosting/orders.html:64 +#: templates/hosting/orders.html:63 templates/hosting/user_keys.html.py:62 msgid "Close" msgstr "Schliessen" -#: templates/hosting/orders.html:66 +#: templates/hosting/orders.html:65 templates/hosting/user_keys.html.py:64 msgid "Delete" msgstr "Löschen" -#: hosting/templates/hosting/payment.html:12 +#: templates/hosting/payment.html:12 msgid "Billing Amount" msgstr "Rechnungsbetrag" -#: hosting/templates/hosting/payment.html:35 +#: templates/hosting/payment.html:35 msgid "Billing Address" msgstr "Rechnungsadresse" -#: hosting/templates/hosting/payment.html:49 +#: templates/hosting/payment.html:49 msgid "Payment Details" msgstr "Rechnungsdetails" -#: hosting/templates/hosting/payment.html:61 -#: hosting/templates/hosting/payment.html:103 +#: templates/hosting/payment.html:62 msgid "Submit Payment" msgstr "Betrag überweisen" -#: hosting/templates/hosting/payment.html:70 +#: templates/hosting/payment.html:81 msgid "CARD NUMBER" msgstr "Kreditkartennummer" -#: hosting/templates/hosting/payment.html:75 +#: templates/hosting/payment.html:86 msgid "Valid Card Number" msgstr "Gültige Kreditkartennummer" -#: hosting/templates/hosting/payment.html:84 +#: templates/hosting/payment.html:95 msgid "EXPIRATION DATE" msgstr "Ablaufdatum" -#: hosting/templates/hosting/payment.html:95 +#: templates/hosting/payment.html:106 msgid "CV CODE" msgstr "CV Code" -#: hosting/templates/hosting/reset_password.html:14 +#: templates/hosting/reset_password.html:15 msgid "Reset your password" msgstr "Passwort zurücksetzen" +#: templates/hosting/user_key.html:11 templates/hosting/user_keys.html.py:9 +msgid "Access Key" +msgstr "Zugriffsschlüssel" + +#: templates/hosting/user_key.html:24 +msgid "Upload your own key. " +msgstr "Lade deinen Key hoch" + +#: templates/hosting/user_key.html:28 +msgid "Or generate a new key pair." +msgstr "Oder erstelle dein neues Keypaar" + +#: templates/hosting/user_key.html:30 +msgid "Generate Key Pair" +msgstr "Schlüsselpaar generieren" + +#: templates/hosting/user_key.html:40 +msgid "Warning!" +msgstr "Achtung!" + +#: templates/hosting/user_key.html:40 +msgid "You can download your SSH private key once. Don't lost your key" +msgstr "" +"Du kannst deinen privaten SSH Schlüssel nur einmal herunterladen. Beware ihn " +"sicher auf." + +#: templates/hosting/user_keys.html:18 +msgid "Add Key" +msgstr "Schlüssel hinzufügen" + +#: templates/hosting/user_keys.html:26 +msgid "Created at" +msgstr "Erstellt am" + +#: templates/hosting/user_keys.html:42 +#, fuzzy +#| msgid "Delete" +msgid "Delete Key" +msgstr "Löschen" + +#: templates/hosting/user_keys.html:55 +#, fuzzy +#| msgid "Do You want do delete your order?" +msgid "Do You want to delete this key?" +msgstr "Möchtest Du den Schlüssel löschen?" + #: templates/hosting/virtual_machine_detail.html:19 msgid "Settings" msgstr "Einstellungen" @@ -446,68 +481,6 @@ msgstr "Sind Sie sicher, dass Sie ihre virtuelle Maschine beenden wollen " msgid "Cancel" msgstr "Beenden" -#: templates/hosting/virtual_machine_key.html:11 -msgid "Access Key" -msgstr "Zugriffsschlüssel" - -#: hosting/templates/hosting/virtual_machine_key.html:25 -msgid "Upload your own key. " -msgstr "Laden Sie ihren Schlüssel hoch" - -#: hosting/templates/hosting/virtual_machine_key.html:29 -msgid "Upload Key" -msgstr "Schlüssel hochladen" - -#: hosting/templates/hosting/virtual_machine_key.html:33 -msgid "Or generate a new key pair." -msgstr "Oder erstellen Sie ein neues Schlüsselpaar" - -#: hosting/templates/hosting/virtual_machine_key.html:31 -msgid "Generate Key Pair" -msgstr "Schlüsselpaar generieren" - -#: hosting/templates/hosting/virtual_machine_key.html:40 -msgid "" -"Use your created key to access to the machine. If you lost it, contact us." -msgstr "" -"Verwenden Sie Ihren privaten SSH Schlüssel um sich mit Ihren Maschinen zu " -"verbinden. Falls Sie ihn verloren haben kontaktieren Sie uns." - -#: hosting/templates/hosting/virtual_machine_key.html:43 -msgid "Created at" -msgstr "Erstellt am" - -#: hosting/templates/hosting/virtual_machine_key.html:66 -#: hosting/templates/hosting/virtual_machine_key.html:79 -msgid "Warning!" -msgstr "Achtung!" - -#: hosting/templates/hosting/virtual_machine_key.html:66 -msgid "You can download your SSH private key once. Don't lost your key" -msgstr "" -"Sie können ihren privaten SSH Schlüssel nur einmal herunterladen. Bewaren " -"Sie ihn sicher auf." - -#: hosting/templates/hosting/virtual_machine_key.html:74 -msgid "Copy to Clipboard" -msgstr "Kopieren" - -#: hosting/templates/hosting/virtual_machine_key.html:75 -msgid "Download" -msgstr "" - -#: hosting/templates/hosting/virtual_machine_key.html:79 -msgid "" -"Your SSH private key was already generated and downloaded, if you lost it, " -"contact us. " -msgstr "" -"Ihr privater SSH Schlüssel wurde bereits generiert und heruntergeladen, " -"falls Sie ihn verloren haben kontaktieren Sie uns." - -#: hosting/templates/hosting/virtual_machine_key.html:82 -msgid "Generate my key" -msgstr "Generiere meinen Schlüssel" - #: templates/hosting/virtual_machines.html:9 msgid "Virtual Machines" msgstr "Virtuelle Maschinen" @@ -522,8 +495,80 @@ msgstr "" #: templates/hosting/virtual_machines.html:29 msgid "Ipv4" -msgstr "" +msgstr "IPv4" #: templates/hosting/virtual_machines.html:30 msgid "Ipv6" +msgstr "IPv6" + +#: views.py:213 views.py:232 +msgid "login" +msgstr "einloggen" + +#: views.py:217 +msgid "" +"Thank you for signing up. We have sent an email to you. Please follow the " +"instructions in it to activate your account. Once activated, you can login " +"using" msgstr "" +"Danke für deine Anmeldung. Wir haben dir eine E-Mail geschickt. Bitte folge " +"den Anweisungen um deinen Account zu aktivieren. Danach kannst du dich über " +"diesen" + +#: views.py:218 views.py:243 +msgid "Go back to" +msgstr "Zurück" + +#: views.py:233 +msgid "Account activation" +msgstr "Accountaktivierung" + +#: views.py:236 +msgid "Your account has been activated." +msgstr "Dein Account wurde aktiviert." + +#: views.py:237 +msgid "You can now" +msgstr "Du kannst dich nun" + +#: views.py:242 +msgid "Sorry. Your request is invalid." +msgstr "Entschuldigung, deine Anfrage ist ungültig." + +#: views.py:760 +msgid "" +"We could not find the requested VM. Please " +"contact Data Center Light Support." +msgstr "" + +#~ msgid "Home" +#~ msgstr "Home" + +#~ msgid "Log in" +#~ msgstr "Anmelden" + +#~ msgid "You haven been logged out" +#~ msgstr "Sie wurden abgmeldet" + +#~ msgid "Upload Key" +#~ msgstr "Schlüssel hochladen" + +#~ msgid "" +#~ "Use your created key to access to the machine. If you lost it, contact us." +#~ msgstr "" +#~ "Verwende deinen privaten SSH Schlüssel, um dich mit deinen Maschinen zu " +#~ "verbinden. Solltest du deinen privaten Schlüssel verloren haben, dann " +#~ "kontaktiere uns." + +#~ msgid "Copy to Clipboard" +#~ msgstr "Kopieren" + +#~ msgid "" +#~ "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." + +#~ msgid "Generate my key" +#~ msgstr "Generiere meinen Schlüssel" diff --git a/hosting/static/hosting/css/landing-page.css b/hosting/static/hosting/css/landing-page.css index d7d72ee2..0c927239 100644 --- a/hosting/static/hosting/css/landing-page.css +++ b/hosting/static/hosting/css/landing-page.css @@ -270,7 +270,7 @@ h6 { .auth-box .section-heading{ color: #5a5a5a; - padding-top: 20px; + padding-top: 30px; padding-bottom: 5px; text-align: center; text-transform: uppercase; @@ -320,9 +320,10 @@ h6 { .sign-up-message { padding: 25px 30px 25px 30px; - text-align: justify; + text-align: center; font-size: 18px; line-height: 30px; + font-family: 'Lato' !important; } .sign-up-message a { font-size: 18px; diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index 704e2b6d..e1a6a027 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -46,7 +46,7 @@ - {% if request.user.is_authenticated %} + - {% endif %} +
{% block content %} diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index cb0dba4e..3f64c54d 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -20,7 +20,7 @@
-

{% trans "Invoice"%}

{% trans "Order #"%} {{order.id}}

+

{% trans "Confirm Order"%}

{% trans "Order #"%} {{order.id}}


diff --git a/hosting/views.py b/hosting/views.py index 45e23df4..f5ab73ee 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -210,11 +210,17 @@ class SignupValidateView(TemplateView): def get_context_data(self, **kwargs): context = super(SignupValidateView, self).get_context_data(**kwargs) - login_url = reverse('hosting:login') - message= _("Thank you for signing up. We have sent an email to you. Please follow the instructions in it to activate your account. Once activated, you can login using ") + 'login' - section_title='Sign up' + login_url = '' + str(_('login')) +'' + home_url = 'Data Center Light' + message='{signup_success_message} {lurl} \ +
{go_back} {hurl}.'.format( + signup_success_message = _('Thank you for signing up. We have sent an email to you. Please follow the instructions in it to activate your account. Once activated, you can login using'), + go_back = _('Go back to'), + lurl = login_url, + hurl = home_url + ) context['message'] = mark_safe(message) - context['section_title'] = section_title + context['section_title'] = _('Sign up') return context class SignupValidatedView(SignupValidateView): @@ -223,13 +229,20 @@ class SignupValidatedView(SignupValidateView): def get_context_data(self, **kwargs): context = super(SignupValidateView, self).get_context_data(**kwargs) validated = CustomUser.validate_url(self.kwargs['validate_slug']) - login_url = reverse('hosting:login') + login_url = '' + str(_('login')) +'' + section_title=_('Account activation') if validated: - message= _("Your account has been activated. You can now ") + 'login' - section_title=_('Account activation') + message='{account_activation_string}
{login_string} {lurl}.'.format( + account_activation_string = _("Your account has been activated."), + login_string = _("You can now"), + lurl = login_url) else: - message= _("Sorry. Your request is invalid.") + 'login' - section_title=_('Account activation') + home_url = 'Data Center Light' + message = '{sorry_message}
{go_back_to} {hurl}'.format( + sorry_message = _("Sorry. Your request is invalid."), + go_back_to = _('Go back to'), + hurl = home_url + ) context['message'] = mark_safe(message) context['section_title'] = section_title return context diff --git a/membership/locale/de/LC_MESSAGES/django.po b/membership/locale/de/LC_MESSAGES/django.po new file mode 100644 index 00000000..42846dab --- /dev/null +++ b/membership/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,59 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-23 02:05+0530\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: forms.py:43 +msgid "Name" +msgstr "" + +#: forms.py:43 +msgid "Card number" +msgstr "" + +#: forms.py:43 +msgid "Expiry date" +msgstr "" + +#: forms.py:44 +msgid "CCV" +msgstr "" + +#: models.py:66 +msgid "staff status" +msgstr "" + +#: models.py:68 +msgid "Designates whether the user can log into this admin site." +msgstr "" + +#: models.py:90 +msgid "Activate your " +msgstr "Aktiviere deinen " + +#: models.py:90 +msgid " account" +msgstr " Account" + +#: models.py:198 +msgid "Use this pattern(MM/YYYY)." +msgstr "" + +#: models.py:199 +msgid "Wrong CCV number." +msgstr "" diff --git a/membership/models.py b/membership/models.py index 8bd9feec..16fe71e8 100644 --- a/membership/models.py +++ b/membership/models.py @@ -6,6 +6,8 @@ from django.contrib.auth.hashers import make_password from django.core.validators import RegexValidator from django.contrib.auth.models import User from django.contrib.sites.models import Site +from django.conf import settings +from django.utils.crypto import get_random_string from utils.stripe_utils import StripeUtils from utils.mailer import DigitalGlarusRegistrationMailer @@ -73,7 +75,7 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): REQUIRED_FIELDS = ['name', 'password'] @classmethod - def register(cls, name, password, email, app='digital_glarus', base_url=None): + def register(cls, name, password, email, app='digital_glarus', base_url=None, send_email=True): user = cls.objects.filter(email=email).first() if not user: user = cls.objects.create_user(name=name, email=email, password=password) @@ -82,18 +84,23 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): dg = DigitalGlarusRegistrationMailer(user.validation_slug) dg.send_mail(to=user.email) elif app == 'dcl': + dcl_text = settings.DCL_TEXT + dcl_from_address = settings.DCL_SUPPORT_FROM_ADDRESS user.is_active = False - email_data = { - 'subject': _('Activate your Data Center Light account'), - 'from_address': '(Data Center Light) Data Center Light Support ', - 'to': user.email, - 'context': {'base_url' : base_url, - 'activation_link' : reverse('hosting:validate', kwargs={'validate_slug': user.validation_slug})}, - 'template_name': 'user_activation', - 'template_path': 'datacenterlight/emails/' - } - email = BaseEmail(**email_data) - email.send() + if send_email is True: + email_data = { + 'subject': str(_('Activate your ')) + dcl_text + str(_(' account')), + 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS, + 'to': user.email, + 'context': {'base_url' : base_url, + 'activation_link' : reverse('hosting:validate', kwargs={'validate_slug': user.validation_slug}), + 'dcl_text' : dcl_text + }, + 'template_name': 'user_activation', + 'template_path': 'datacenterlight/emails/' + } + email = BaseEmail(**email_data) + email.send() return user else: return None @@ -113,6 +120,10 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): return True return False + @classmethod + def get_random_password(cls): + return get_random_string(24) + def is_superuser(self): return False diff --git a/opennebula_api/models.py b/opennebula_api/models.py index 397c0f0c..d18524c5 100644 --- a/opennebula_api/models.py +++ b/opennebula_api/models.py @@ -239,7 +239,7 @@ class OpenNebulaManager(): ) ) - def create_vm(self, template_id, specs, ssh_key=None): + def create_vm(self, template_id, specs, ssh_key=None, vm_name=None): template = self.get_template(template_id) vm_specs_formatter = """ - """.format(ssh=ssh_key) + + """ vm_id = self.client.call(oca.VmTemplate.METHODS['instantiate'], template.id, '', @@ -307,6 +306,13 @@ class OpenNebulaManager(): 'release', vm_id ) + + if vm_name is not None: + self.oneadmin_client.call( + 'vm.rename', + vm_id, + vm_name + ) return vm_id def delete_vm(self, vm_id):