Merge branch 'master' into task/3774/update_stripe_subscription_on_vm_delete

This commit is contained in:
PCoder 2017-12-12 20:23:25 +01:00
commit 1306dbe46a
158 changed files with 4279 additions and 2015 deletions

View file

@ -29,6 +29,8 @@ class HostingUserLoginForm(forms.Form):
def clean(self):
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if self.errors:
return self.cleaned_data
is_auth = authenticate(email=email, password=password)
if not is_auth:
raise forms.ValidationError(
@ -48,15 +50,17 @@ class HostingUserLoginForm(forms.Form):
class HostingUserSignupForm(forms.ModelForm):
confirm_password = forms.CharField(widget=forms.PasswordInput())
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(label=_("Confirm Password"),
widget=forms.PasswordInput())
password = forms.CharField(label=_("Password"),
widget=forms.PasswordInput())
class Meta:
model = CustomUser
fields = ['name', 'email', 'password']
widgets = {
'name': forms.TextInput(
attrs={'placeholder': 'Enter your name or company name'}),
attrs={'placeholder': _('Enter your name or company name')}),
}
def clean_confirm_password(self):
@ -104,7 +108,7 @@ class UserHostingKeyForm(forms.ModelForm):
public_key=openssh_pubkey_str).first().name
KEY_EXISTS_MESSAGE = _(
"This key exists already with the name \"%(name)s\"") % {
'name': key_name}
'name': key_name}
raise forms.ValidationError(KEY_EXISTS_MESSAGE)
with tempfile.NamedTemporaryFile(delete=True) as tmp_public_key_file:

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-10 21:35+0530\n"
"POT-Creation-Date: 2017-10-26 03:21+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"
@ -27,6 +27,15 @@ msgstr "Dein Account wurde noch nicht aktiviert."
msgid "User does not exist"
msgstr "Der Benutzer existiert nicht"
msgid "Confirm Password"
msgstr "Passwort Bestätigung"
msgid "Password"
msgstr "Passwort"
msgid "Enter your name or company name"
msgstr "Gib Deinen Namen oder den Name Deines Unternehmens ein"
msgid "Paste here your public key"
msgstr "Füge Deinen Public Key ein"
@ -155,9 +164,6 @@ msgstr "Ich möchte einen existierenden SSH-Key nutzen"
msgid "Upload"
msgstr "Hochladen"
msgid "Your VM hosted in Switzerland"
msgstr "Deine VM in der Schweiz"
msgid "Set your new password"
msgstr "Setze Dein neues Passwort"
@ -195,101 +201,78 @@ msgid "Support / Contact"
msgstr "Support / Kontakt"
#, python-format
msgid ""
"You have ordered a new virtual machine!\n"
"<br/>\n"
"Your order of [%(vm_name)s] has been charged.<br/><br/>\n"
"You can view your invoice by clicking the button below.<br/><br/>\n"
msgstr ""
"Du hast eine neue virtuelle Maschine bestellt!<br/>\n"
"Deine Bestellung von [%(vm_name)s] wurde erhoben.<br/><br/>\n"
"Um die Rechnung zu sehen, klicke auf den Button unten.<br/><br/>\n"
msgid "Your New VM %(vm_name)s"
msgstr "Deine Neue VM %(vm_name)s"
msgid "View Invoice"
msgstr "Zur Rechnung"
msgid "You have ordered a new virtual machine!"
msgstr "Du hast eine neue virtuelle Maschine bestellt!"
#, python-format
msgid ""
"You have ordered a new virtual machine!\n"
"Your order of [%(vm_name)s] has been charged.\n"
"You can view your invoice here.\n"
msgstr ""
"Du hast eine neue virtuelle Maschine bestellt!\n"
"Deine Bestellung von [%(vm_name)s] wurde erhoben.\n"
"Um die Rechnung zu sehen, klicke hier.\n"
msgid "Your order of <strong>%(vm_name)s</strong> has been charged."
msgstr "Deine Bestellung von <strong>%(vm_name)s</strong> wurde erhoben."
msgid "You can view your VM detail by clicking the button below."
msgstr "Um die Rechnung zu sehen, klicke auf den Button unten."
msgid "View Detail"
msgstr "Details anzeigen"
msgid "Your Data Center Light Team"
msgstr "Dein Data Center Light Team"
#, python-format
msgid "Your order of %(vm_name)s has been charged."
msgstr "Deine Bestellung von %(vm_name)s wurde erhoben."
msgid "You can view your VM detail by following the link below."
msgstr "Um die Rechnung zu sehen, klicke auf den Link unten."
msgid "Password Reset"
msgstr "Passwort zurücksetzen"
#, python-format
msgid ""
"\n"
"You're receiving this email because you requested a password reset for your "
"user account at %(site_name)s.<br/>\n"
"Please go to the following page and choose a new password: %(base_url)s"
"%(password_reset_url)s<br/>\n"
"If you didn't request a new password, ignore this e-mail.<br/>\n"
"Thank you!\n"
msgid "We received a request to reset your password."
msgstr "Wir haben eine Anfrage erhalten, um Dein Passwort zurückzusetzen."
msgid "If you didn't make this request you can safely ignore this email."
msgstr ""
"\n"
"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, "
"dann ignoriere diese E-Mail.<br/>\n"
"Dankeschön!\n"
"Falls Du kein neues Passwort angefragt hast, kannst Du diese E-mail "
"ignorieren."
msgid "Otherwise, click here to reset your password."
msgstr "Andernfalls klicke hier, um Dein Passwort zurückzusetzen."
msgid "Thank you!"
msgstr "Dankeschön!"
msgid "Virtual Machine Cancellation"
msgstr "VM Kündigung"
#, python-format
msgid ""
"You're receiving this email because you requested a password reset for your "
"user account at %(site_name)s.\n"
"Please go to the following page and choose a new password: %(base_url)s"
"%(password_reset_url)s\n"
"If you didn't request a new password, ignore this e-mail.\n"
"Thank you!\n"
"You are receiving this email because your virutal machine <strong>"
"%(vm_name)s</strong> has been cancelled."
msgstr ""
"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, "
"dann ignoriere diese E-Mail.\n"
"Dankeschön!\n"
"Du erhälst diese E-Mail, da deine virtuelle Maschine <strong>%(vm_name)s</"
"strong> gekündigt wurde."
msgid "You can always order a new VM by clicking the button below."
msgstr ""
"Du kannst einfach eine neue VM bestellen, indem Du den Knopf weiter unten "
"drückst."
msgid "CREATE VM"
msgstr "NEUE VM"
#, python-format
msgid ""
"You're receiving this mail because your virtual machine [%(vm_name)s] has "
"been cancelled.<br/>\n"
"You can see your order status by clicking [my VM page] below.<br/>\n"
"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"
"You are receiving this email because your virutal machine %(vm_name)s has "
"been cancelled."
msgstr ""
"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 "
"Link klickst</a>.<br/>\n"
"Du erhälst diese E-Mail, da deine virtuelle Maschine %(vm_name)s gekündigt "
"wurde."
msgid "My VM page"
msgstr "Meine VM page"
#, python-format
msgid ""
"You're receiving this mail because your virtual machine [%(vm_name)s] has "
"been cancelled.\n"
"You can see your order status by clicking here\n"
"%(base_url)s%(vm_order_url)s\n"
"If you want to order a new virtual machine, you can do it by clicking this "
"link.\n"
"%(base_url)s%(my_virtual_machines_url)s\n"
msgid "You can always order a new VM by following the link below."
msgstr ""
"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"
"%(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"
"%(base_url)s%(my_virtual_machines_url)s\n"
msgid "Toggle navigation"
msgstr "Umschalten"
@ -300,13 +283,16 @@ msgstr "Dashboard"
msgid "Logout"
msgstr "Abmelden"
msgid "Don't have an account yet ? "
msgid "Log in"
msgstr "Anmelden"
msgid "Don't have an account yet ?"
msgstr "Besitzt du kein Benutzerkonto?"
msgid "Sign up"
msgstr "Registrieren"
msgid "Forgot your password ? "
msgid "Forgot your password ?"
msgstr "Passwort vergessen?"
msgid "Resend activation link"
@ -478,7 +464,7 @@ msgstr "Deine Kreditkartennummer"
msgid "Submit"
msgstr "Absenden"
msgid "Reset your password"
msgid "Password reset"
msgstr "Passwort zurücksetzen"
msgid "UPDATE"
@ -630,12 +616,6 @@ msgstr ""
"Um auf Deine VM zuzugreifen, <a href=\"%(create_ssh_url)s\">füge Deinen SSH-"
"Key hinzu</a>"
msgid "CREATE VM"
msgstr "NEUE VM"
msgid "View Detail"
msgstr "Details anzeigen"
msgid "login"
msgstr "anmelden"
@ -660,6 +640,9 @@ msgstr "Dein Account wurde aktiviert."
msgid "You can now"
msgstr "Du kannst dich nun"
msgid "Welcome to Data Center Light!"
msgstr "Willkommen beim Data Center Light!"
msgid "Sorry. Your request is invalid."
msgstr "Entschuldigung, deine Anfrage ist ungültig."
@ -730,14 +713,21 @@ msgstr ""
msgid "Error terminating VM"
msgstr "Fehler beenden VM"
msgid "Virtual Machine Cancellation"
msgstr "VM Kündigung"
#, python-format
msgid "Virtual Machine %(vm_name)s Cancelled"
msgstr "Virtuelle Maschine %(vm_name)s Kündigung"
msgid "There was an error processing your request. Please try again."
msgstr ""
"Es gab einen Fehler bei der Bearbeitung Deine Anfrage. Bitte versuche es "
"noch einmal."
#~ msgid "Reset your password"
#~ msgstr "Passwort zurücksetzen"
#~ msgid "My VM page"
#~ msgstr "Meine VM page"
#~ msgid "Invoice Date"
#~ msgstr "Rechnung Datum"
@ -765,12 +755,27 @@ msgstr ""
#~ msgid "Start VM"
#~ msgstr "VM jetzt starten"
#~ msgid "View Invoice"
#~ msgstr "Zur Rechnung"
#~ msgid ""
#~ "You're receiving this mail because your virtual machine [%(vm_name)s] has "
#~ "been cancelled.<br/>\n"
#~ "You can see your order status by clicking [my VM page] below.<br/>\n"
#~ "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 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 "
#~ "Link klickst</a>.<br/>\n"
#~ 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"
@ -828,9 +833,6 @@ msgstr ""
#~ msgid "Keys"
#~ msgstr "Keys"
#~ msgid "Log in"
#~ msgstr "Anmelden"
#~ msgid "You haven been logged out"
#~ msgstr "Du wurdest abgemeldet"

View file

@ -1,7 +1,9 @@
import os
import logging
from dateutil.relativedelta import relativedelta
from django.db import models
from django.utils import timezone
from django.utils.functional import cached_property
from Crypto.PublicKey import RSA
from membership.models import StripeCustomer, CustomUser
@ -172,3 +174,9 @@ class VMDetail(models.Model):
ipv6 = models.TextField(default='')
created_at = models.DateTimeField(auto_now_add=True)
terminated_at = models.DateTimeField(null=True)
def end_date(self):
end_date = self.terminated_at if self.terminated_at else timezone.now()
months = relativedelta(end_date, self.created_at).months or 1
end_date = self.created_at + relativedelta(months=months, days=-1)
return end_date

View file

@ -18,7 +18,7 @@
}
.content-dashboard{
min-height: calc(100vh - 70px);
min-height: calc(100vh - 60px);
width: 80%;
margin: 0 auto;
max-width: 1120px;
@ -66,7 +66,9 @@
width: 280px;
}
.content-dashboard {
width: 90%;
padding-left: 15px;
padding-right: 15px;
width: 100%;
}
}
.btn:focus, .btn:active:focus {
@ -296,10 +298,6 @@
max-width: 360px;
}
.btn-wide {
min-width: 100px;
}
.caps-link {
font-weight: 600;
color: #8da4c0;
@ -375,4 +373,12 @@
outline: none;
color: #999;
fill: #999;
}
.locale_date {
opacity: 0;
}
.locale_date.done{
opacity: 1;
}

View file

@ -17,9 +17,11 @@ h3,
h4,
h5,
h6 {
/*font-family: 'Lato-Regular', sans-serif;*/
font-family: 'Lato', sans-serif;
/*font-weight: 300;*/
}
.allcaps {
text-transform: uppercase;
}
.topnav {
@ -31,6 +33,11 @@ h6 {
.navbar-brand {
padding: 10px 15px;
}
@media (max-width: 767px) {
.navbar-brand {
padding: 10px 0;
}
}
.navbar-default {
background: #fff;
@ -46,7 +53,7 @@ h6 {
.navbar-transparent {
background: transparent;
border: none;
padding: 20px;
padding: 20px 0;
box-shadow: none;
}
@ -72,7 +79,6 @@ h6 {
.navbar-transparent #logoWhite{
display: block;
width: 220px;
/* color: #fff; */
}
.navbar-right .highlights-dropdown .dropdown-menu {
@ -92,16 +98,6 @@ h6 {
border-color: #e7e7e7;
box-shadow: -8px 14px 20px -5px rgba(77, 77, 77, 0.5);
}
/* .navbar-right .highlights-dropdown .dropdown-menu:before {
content: '';
display: block;
height: 1px;
background: #e7e7e7;
position: absolute;
top: -1px;
left: -1px;
right: -1px;
} */
}
.navbar-right .highlights-dropdown .dropdown-menu > li > a{
font-size: 13px;
@ -274,16 +270,15 @@ h6 {
/*------Auth section---------*/
.auth-container {
min-height: calc(100vh - 120px);
min-height: calc(100vh - 180px);
position: relative;
/* flex-grow: 1; */
display: flex;
flex-direction: column;
justify-content: center;
}
.auth-bg {
background: url(../img/auth-bg-sm.jpg);
background: url(../img/pattern.jpg) no-repeat center center;
position: fixed;
left: 0;
top: 0;
@ -293,7 +288,6 @@ h6 {
background-position: center center;
background-size: cover;
background-attachment: fixed;
}
.auth-bg::before {
@ -303,7 +297,7 @@ h6 {
bottom: 0;
left: 0;
right: 0;
background: rgba(75, 75, 101, 0.55);
background: rgba(90, 116, 175, 0.7);
z-index: 1;
}
@ -313,69 +307,38 @@ h6 {
.auth-container .auth-content {
width: 100%;
margin: 0 auto;
max-width: 390px;
margin: 0 auto 15px;
max-width: 400px;
padding: 0 15px;
}
.auth-container .auth-center {
/* position: absolute; */
/* left: 50%; */
/* top: 50%; */
/* transform: translate(-50%, -50%); */
/* width: 100%; */
}
.auth-container .auth-title {
margin-bottom: 50px;
}
.auth-container .auth-title h2 {
color: #fff;
font-size: 44px;
text-align: center;
width: 425px;
margin: 0 auto;
margin-bottom: 30px;
position: relative;
}
.auth-container .auth-title h2::after {
content: "";
position: absolute;
bottom: -20px;
background: #fff;
height: 7px;
width: 70px;
left: 50%;
transform: translate(-50%, 0);
.auth-container .auth-content.wide {
max-width: 480px;
}
.auth-box {
position: relative;
background: #fff;
padding: 0;
padding-bottom: 30px;
padding: 40px 20px 20px;
box-sizing: border-box;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
border-radius: 4px;
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.09), 0 5px 5px rgba(0, 0, 0, 0.23);
z-index: 10;
}
.auth-box .section-heading {
color: #5a5a5a;
padding-top: 30px;
padding-bottom: 5px;
font-weight: 300;
text-align: center;
text-transform: uppercase;
letter-spacing: 3px;
font-size: 20px;
letter-spacing: 1px;
font-size: 36px;
border-radius: 3px 3px 0px 0px;
margin: 0 auto;
margin: 0 auto 10px;
}
.auth-box .form {
padding: 20px;
width: 80%;
margin: 0 auto;
max-width: 360px;
}
.auth-box .form .red {
@ -383,27 +346,56 @@ h6 {
}
.auth-box .form .btn {
box-shadow: 0 0px 9px rgba(0, 0, 0, 0.19), 0 3px 5px rgba(0, 0, 0, 0.23);
letter-spacing: 3px;
font-size: 17px;
letter-spacing: 2px;
font-size: 16px;
padding: 6px 12px;
min-width: 140px;
margin-top: 15px;
text-transform: uppercase;
}
.auth-box .form .form-control {
height: 44px;
font-size: 16px;
height: 48px;
font-size: 14px;
padding: 10px 17px;
line-height: 30px;
border-color: #aaa;
}
.auth-box .form .form-control:focus,
.auth-box .form .form-control:active {
box-shadow: none;
border-radius: 0;
}
.auth-box .form-control::-webkit-input-placeholder {
color: #aaa;
}
.auth-box .form-control:-moz-placeholder{
/* Firefox 18- */
color: #aaa;
}
.auth-box .form-control::-moz-placeholder{
/* Firefox 19+ */
color: #aaa;
}
.auth-box .form-control:-ms-input-placeholder {
color: #aaa;
}
.auth-box .auth-footer {
text-align: center;
padding: 10px;
padding: 5px;
}
.auth-box .auth-footer .text {
.auth-box .auth-footer {
color: #777;
}
.auth-box .auth-footer .links a {
.auth-box .auth-footer a {
color: #1e94cc;
}
@ -411,20 +403,11 @@ h6 {
color: #1e94cc;
}
.auth-box.sign-up {
padding-bottom: 5px;
}
.auth-box.sign-up .form {
padding: 15px 20px 0 20px;
}
.sign-up-message {
padding: 25px 30px 25px 30px;
text-align: center;
font-size: 18px;
line-height: 30px;
/*font-family: 'Lato' !important;*/
font-weight: 300 !important;
}
@ -458,16 +441,7 @@ h6 {
}
.auth-box .form {
padding: 15px 0px 0 0;
}
.auth-box.sign-up .form {
padding: 15px 0px 0 0;
}
.auth-box .form .form-control {
height: 44px;
font-size: 13px;
padding: 15px 0 15px 0;
}
.auth-container .auth-title {
@ -476,7 +450,7 @@ h6 {
}
.auth-box .msg-list {
padding: 15px 25px 5px;
padding: 20px 25px 0;
text-align: center;
}
@ -493,19 +467,14 @@ h6 {
margin-bottom: 50px;
}
.auth-box .form {
width: 90%;
}
.auth-box .section-heading {
font-size: 15px;
font-size: 32px;
}
}
footer {
padding: 20px;
padding: 20px 0;
background-color: #f8f8f8;
/* position: absolute */
right: 0;
bottom: 0;
left: 0;
@ -537,7 +506,6 @@ a.unlink:hover {
/***** DCL payment page **********/
.dcl-order-container {
/*font-family: Lato;*/
font-weight: 300;
}
@ -580,9 +548,7 @@ a.unlink:hover {
}
.dcl-place-order-text{
/* font-size: 13px; */
color: #808080;
/* margin-bottom: 15px; */
}
.dcl-order-table-total .tbl-total {
@ -610,7 +576,6 @@ a.unlink:hover {
}
.card-warning-content {
/*font-family: Lato;*/
font-weight: 300;
border: 1px solid #a1a1a1;
border-radius: 3px;
@ -638,18 +603,6 @@ a.unlink:hover {
right: 0;
}
.brand {
}
.brand #brand-icon {
}
.card-number-element {
}
.card-expiry-element {
}
.card-cvc-element label {
padding-left: 10px;
}
@ -735,9 +688,6 @@ a.unlink:hover {
margin-bottom: 30px;
}
.brand {
}
.card-expiry-element {
padding-right: 10px;
}
@ -802,10 +752,23 @@ a.unlink:hover {
}
}
.footer-light a:hover, .footer-light a:focus, .footer-light a:active {
.footer-light {
position: relative;
}
.footer-light footer {
background: transparent;
color: #eee;
}
.footer-light a,
.footer-light .text-muted {
color: #ddd;
}
.footer-light a:hover, .footer-light a:focus, .footer-light a:active {
color: #fff;
}
.footer-vm p.copyright {
margin-top: 4px;
}
.visible-mobile {
display: none !important;

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

View file

@ -54,19 +54,18 @@
{% include "hosting/includes/_navbar_user.html" %}
{% endblock navbar %}
<div class="content-dashboard">
<div class="{% if request.user.is_authenticated %}content-dashboard{% endif %}">
{% block content %}
{% endblock %}
</div>
<!-- Footer -->
{% if request.user.is_authenticated %}
<footer class="footer-vm">
<div class="container">
<p class="copyright text-muted small">Copyright &copy; ungleich GmbH {% now "Y" %}. {% trans "All Rights Reserved" %}</p>
</div>
</footer>
<footer class="footer-vm">
<div class="container">
<p class="copyright text-muted small">Copyright &copy; ungleich GmbH {% now "Y" %}. {% trans "All Rights Reserved" %}</p>
</div>
</footer>
{% else %}
<div class="footer-light">
{% include "datacenterlight/includes/_footer.html" %}

View file

@ -1,21 +1,17 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3%}
{% load i18n %}
{% load staticfiles bootstrap3 i18n %}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %}
<div class="auth-container">
<div class="auth-bg"></div>
<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 "Set your new password"%}</h2>
<div class="auth-box sign-up">
<h1 class="section-heading">{% trans "Set your new password" %}</h1>
{% if messages %}
<ul class="list-unstyled msg-list">
{% for message in messages %}
@ -28,23 +24,18 @@
{% for field in form %}
{% bootstrap_field field show_label=False %}
{% endfor %}
{% buttons %}
<button type="submit" class="btn btn-block btn-success">
{% trans "Reset"%}
<div class="text-center">
<button type="submit" class="btn choice-btn">
{% trans "Reset" %}
</button>
{% endbuttons %}
</div>
</form>
<div class="auth-footer">
<div class="text">
<span>{% trans "Already have an account ?"%}</span>
</div>
<div class="links">
<a class="unlink" href="{% url 'hosting:login' %}">{% trans "Login"%}</a>
</div>
<span>{% trans "Already have an account ?" %}</span>&nbsp;
<a class="unlink" href="{% url 'hosting:login' %}">{% trans "Login" %}</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,14 +1,51 @@
{% extends "datacenterlight/emails/base_email_datacenterlight.html" %}
{% load i18n %}
{% block email_head %}{{page_header}}{% endblock %}
{% block email_body %}
{% url 'hosting:orders' order.id as order_url %}
{% blocktrans with vm.name as vm_name %}You have ordered a new virtual machine!
<br/>
Your order of [{{vm_name}}] has been charged.<br/><br/>
You can view your invoice by clicking the button below.<br/><br/>
{% endblocktrans %}
<div class="button" style="border-collapse: collapse; font-family: 'Lato', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 30px 0;" align="center">
<a href="{{ base_url }}{{order_url}}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">{% trans 'View Invoice' %}</a>
</div>
{% endblock %}
{% load static i18n %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% blocktrans %}Your New VM {{vm_name}}{% endblocktrans %}</title>
<link rel="shortcut icon" href="{{ base_url }}{% static 'datacenterlight/img/favicon.ico' %}" type="image/x-icon">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400">
</head>
<body style="margin: 0; padding: 20px 0;">
<table style="width: 100%; border-spacing: 0; border-collapse: collapse; max-width: 560px;">
<tr>
<td>
<img src="{{ base_url }}{% static 'datacenterlight/img/logo_black.png' %}" style="width: 200px; height: 50px;">
</td>
</tr>
<tr>
<td style="padding-top: 15px;">
<h1 style="font-family: Lato, Arial, sans-serif; font-size: 25px; font-weight: 400; margin: 0;">{% blocktrans %}Your New VM {{ vm_name }}{% endblocktrans %}</h1>
</td>
</tr>
<tr>
<td style="padding-top: 25px; font-size: 16px;">
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{% blocktrans %}You have ordered a new virtual machine!{% endblocktrans %}
</p>
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{% blocktrans %}Your order of <strong>{{ vm_name }}</strong> has been charged.{% endblocktrans %}
</p>
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{% blocktrans %}You can view your VM detail by clicking the button below.{% endblocktrans %}
</p>
</td>
</tr>
<tr>
<td style="padding-top: 30px;">
<a class="btn" href="{{ base_url }}{{ order_url }}" style="font-family: Lato, Arial, sans-serif; text-decoration: none; background-color: #1596da; color: #fff; padding-top: 10px; padding-bottom: 10px; padding-left: 30px; padding-right: 30px; letter-spacing: 0.5px; border-radius: 3px; display: inline-block; position: relative;">{% trans "View Detail" %}</a>
</td>
</tr>
<tr>
<td style="padding-top: 40px; padding-bottom: 25px;">
<h3 style="font-family: Lato, Arial, sans-serif; margin: 0; font-weight: 400; font-size: 15px;">{% trans "Your Data Center Light Team" %}</h3>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,11 +1,11 @@
{% extends "datacenterlight/emails/base_email_datacenterlight.txt" %}
{% load i18n %}
{% block email_head %}{{page_header}}{% endblock %}
{% block email_body %}
{% url 'hosting:orders' order.id as order_url %}
{% blocktrans with vm.name as vm_name %}You have ordered a new virtual machine!
Your order of [{{vm_name}}] has been charged.
You can view your invoice here.
{% endblocktrans %}
{{ base_url }}{{order_url}}
{% endblock %}
{% blocktrans %}Your New VM {{vm_name}}{% endblocktrans %}
{% blocktrans %}You have ordered a new virtual machine!{% endblocktrans %}
{% blocktrans %}Your order of {{vm_name}} has been charged.{% endblocktrans %}
{% blocktrans %}You can view your VM detail by following the link below.{% endblocktrans %}
{{ base_url }}{{ order_url }}
{% trans "Your Data Center Light Team" %}

View file

@ -1,14 +1,52 @@
{% extends "datacenterlight/emails/base_email_datacenterlight.html" %}
{% load i18n %}
{% block email_head %}
{% trans 'Password Reset' %}
{% endblock %}
{% block email_body %}
{% url 'hosting:reset_password_confirm' uidb64=uid token=token as password_reset_url %}
{% blocktrans %}
You're receiving this email because you requested a password reset for your user account at {{site_name}}.<br/>
Please go to the following page and choose a new password: {{base_url}}{{ password_reset_url }}<br/>
If you didn't request a new password, ignore this e-mail.<br/>
Thank you!
{% endblocktrans %}
{% endblock %}
{% load static i18n %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% trans "Password Reset" %}</title>
<link rel="shortcut icon" href="{{ base_url }}{% static 'datacenterlight/img/favicon.ico' %}" type="image/x-icon">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400">
</head>
<body style="margin: 0; padding: 20px 0;">
<table style="width: 100%; border-spacing: 0; border-collapse: collapse; max-width: 560px;">
<tr>
<td>
<img src="{{base_url}}{% static 'datacenterlight/img/logo_black.png' %}" style="width: 200px; height: 50px;">
</td>
</tr>
<tr>
<td style="padding-top: 15px;">
<h1 style="font-family: Lato, Arial, sans-serif; font-size: 25px; font-weight: 400; margin: 0;">{% trans "Password Reset" %}</h1>
</td>
</tr>
<tr>
<td style="padding-top: 25px; font-size: 16px;">
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin-bottom: 10px; margin-top: 0;">
{% trans "We received a request to reset your password." %}
</p>
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin-bottom: 10px; margin-top: 0;">
{% trans "If you didn't make this request you can safely ignore this email." %}
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin-bottom: 10px; margin-top: 0;">
{% trans "Otherwise, click here to reset your password." %}
</p>
<p style="color: #4382c8; line-height: 1.4; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{% url 'hosting:reset_password_confirm' uidb64=uid token=token as password_reset_url %}
{{base_url}}{{ password_reset_url }}
</p>
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin-bottom: 0; margin-top: 10px;">
{% trans "Thank you!" %}
</p>
</td>
</tr>
<tr>
<td style="padding-top: 40px; padding-bottom: 25px;">
<h3 style="font-family: Lato, Arial, sans-serif; margin: 0; font-weight: 400; font-size: 15px;">{% trans "Your Data Center Light Team" %}</h3>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,11 +1,14 @@
{% extends "datacenterlight/emails/base_email_datacenterlight.txt" %}
{% load i18n %}
{% block email_head %}{% trans 'Password Reset' %}{% endblock %}
{% block email_body %}
{% trans "Password Reset" %}
{% trans "We received a request to reset your password." %}
{% trans "If you didn't make this request you can safely ignore this email." %}
{% trans "Otherwise, click here to reset your password." %}
{% url 'hosting:reset_password_confirm' uidb64=uid token=token as password_reset_url %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{site_name}}.
Please go to the following page and choose a new password: {{base_url}}{{ password_reset_url }}
If you didn't request a new password, ignore this e-mail.
Thank you!
{% endblocktrans %}
{% endblock %}
{{base_url}}{{ password_reset_url }}
{% trans "Thank you!" %}
{% trans "Your Data Center Light Team" %}

View file

@ -1,15 +1,49 @@
{% extends "datacenterlight/emails/base_email_datacenterlight.html" %}
{% load i18n %}
{% block email_head %}{{page_header}}{% endblock %}
{% block email_body %}
{% url 'hosting:virtual_machines' as my_virtual_machines_url %}
{% url 'hosting:orders' as vm_orders_url %}
{% blocktrans with vm.name as vm_name %}You're receiving this mail because your virtual machine [{{vm_name}}] has been cancelled.<br/>
You can see your order status by clicking [my VM page] below.<br/>
If you want to order a new virtual machine, you can do it by clicking <a href="{{base_url}}{{my_virtual_machines_url}}">this link</a>.<br/>
{% endblocktrans %}
<div class="button" style="border-collapse: collapse; font-family: 'Lato', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 30px 0;" align="center">
<a href="{{ base_url }}{{vm_orders_url}}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">{% trans 'My VM page' %}</a>
</div>
{% endblock %}
{% load static i18n %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% trans "Virtual Machine Cancellation" %}</title>
<link rel="shortcut icon" href="{{ base_url }}{% static 'datacenterlight/img/favicon.ico' %}" type="image/x-icon">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400">
</head>
<body style="margin: 0; padding: 20px 0;">
<table style="width: 100%; border-spacing: 0; border-collapse: collapse; max-width: 560px;">
<tr>
<td>
<img src="{{ base_url }}{% static 'datacenterlight/img/logo_black.png' %}" style="width: 200px; height: 50px;">
</td>
</tr>
<tr>
<td style="padding-top: 15px;">
<h1 style="font-family: Lato, Arial, sans-serif; font-size: 25px; font-weight: 400; margin: 0;">{% trans "Virtual Machine Cancellation" %}</h1>
</td>
</tr>
<tr>
<td style="padding-top: 25px; font-size: 16px;">
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{% blocktrans %}You are receiving this email because your virutal machine <strong>{{ vm_name }}</strong> has been cancelled.{% endblocktrans %}
</p>
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{% blocktrans %}You can always order a new VM by clicking the button below.{% endblocktrans %}
</p>
</td>
</tr>
<tr>
<td style="padding-top: 30px;">
<a class="btn" href="{{ base_url }}{% url 'hosting:create_virtual_machine' %}" style="font-family: Lato, Arial, sans-serif; text-decoration: none; background-color: #1596da; color: #fff; padding-top: 10px; padding-bottom: 10px; padding-left: 30px; padding-right: 30px; letter-spacing: 0.5px; border-radius: 3px; display: inline-block; position: relative;">{% trans "CREATE VM" %}</a>
</td>
</tr>
<tr>
<td style="padding-top: 40px; padding-bottom: 25px;">
<h3 style="font-family: Lato, Arial, sans-serif; margin: 0; font-weight: 400; font-size: 15px;">{% trans "Your Data Center Light Team" %}</h3>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,13 +1,10 @@
{% extends "datacenterlight/emails/base_email_datacenterlight.txt" %}
{% load i18n %}
{% block email_head %}{{page_header}}{% endblock %}
{% block email_body %}
{% url 'hosting:virtual_machines' as my_virtual_machines_url %}
{% url 'hosting:orders' order.id as vm_order_url %}
{% blocktrans with vm.name as vm_name %}You're receiving this mail because your virtual machine [{{vm_name}}] has been cancelled.
You can see your order status by clicking here
{{base_url}}{{vm_order_url}}
If you want to order a new virtual machine, you can do it by clicking this link.
{{base_url}}{{my_virtual_machines_url}}
{% endblocktrans %}
{% endblock %}
{% trans "Virtual Machine Cancellation" %}
{% blocktrans %}You are receiving this email because your virutal machine {{vm_name}} has been cancelled.{% endblocktrans %}
{% blocktrans %}You can always order a new VM by following the link below.{% endblocktrans %}
{{ base_url }}{% url 'hosting:create_virtual_machine' %}
{% trans "Your Data Center Light Team" %}

View file

@ -1,8 +1,7 @@
{% if messages %}
<ul class="list-unstyled msg-list">
{% for message in messages %}
<div
class="alert {% if message.tags and message.tags == 'error' %} alert-danger {% else %} alert-{{message.tags}} {% endif %}">{{ message|safe }}</div>
<div class="alert {% if message.tags and message.tags == 'error' %} alert-danger {% else %} alert-{{message.tags}} {% endif %}">{{ message|safe }}</div>
{% endfor %}
</ul>
{% endif %}

View file

@ -1,11 +1,13 @@
{% load static i18n %}
<nav class="navbar navbar-default topnav navbar-transparent" role="navigation">
<div class="topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a id="logoWhite" class="navbar-brand topnav" href="{% url 'datacenterlight:index' %}"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
<div class="container">
<div class="topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a id="logoWhite" class="navbar-brand topnav" href="{% url 'datacenterlight:index' %}"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
</div>
</div>
<!-- /.container -->
</div>
<!-- /.container -->
</nav>

View file

@ -1,49 +1,43 @@
{% extends "hosting/base_short.html" %}
{% load i18n %}
{% load staticfiles bootstrap3%}
{% load i18n staticfiles bootstrap3%}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% 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">
<h2 class="section-heading">{% trans "Login"%}</h2>
{% include 'hosting/includes/_messages.html' %}
<form action="{% url 'hosting:login' %}" method="post" class="form" novalidated>
{% csrf_token %}
{% for field in form %}
{% bootstrap_field field show_label=False type='fields'%}
{% endfor %}
<p class="red">{{form.non_field_errors|striptags}}</p>
{% buttons %}
<button type="submit" class="btn btn-block btn-success">
{% trans "Login"%}
</button>
{% endbuttons %}
<input type='hidden' name='next' value='{{request.GET.next}}'/>
</form>
<div class="auth-footer">
<div class="text">
<span>{% trans "Don't have an account yet ? "%}</span>
</div>
<div class="links">
<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 class="auth-container">
<div class="auth-bg"></div>
<div class="auth-center">
<div class="auth-content">
<div class="auth-box">
<h1 class="section-heading allcaps">{% trans "Log in" %}</h1>
{% include 'hosting/includes/_messages.html' %}
<form action="{% url 'hosting:login' %}" method="post" class="form" novalidated>
{% csrf_token %}
{% for field in form %}
{% bootstrap_field field show_label=False type='fields'%}
{% endfor %}
<p class="red">{{form.non_field_errors|striptags}}</p>
<div class="text-center">
<button type="submit" class="btn choice-btn">
{% trans "Log in" %}
</button>
</div>
<input type='hidden' name='next' value='{{request.GET.next}}'/>
</form>
<div class="auth-footer">
<div>
{% trans "Don't have an account yet ?" %}&nbsp;
<a class="" href="{% url 'hosting:signup' %}">{% trans "Sign up" %}</a>
</div>
<div>
or <a href="{% url 'hosting:reset_password' %}">{% trans "Forgot your password ?" %}</a><br>
or <a href="{% url 'hosting:resend_activation_link' %}">{% trans "Resend activation link" %}</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -32,11 +32,11 @@
{% endif %}
<p>
<strong>{% trans "Date" %}:</strong>
<span id="order-created_at">
<span class="locale_date">
{% if order %}
{{order.created_at|date:'Y-m-d H:i'}}
{{order.created_at|date:'Y-m-d h:i a'}}
{% else %}
{% now "Y-m-d H:i" %}
{% now "Y-m-d h:i a" %}
{% endif %}
</span>
</p>
@ -107,7 +107,9 @@
{% if vm.created_at %}
<p>
<span>{% trans "Period" %}: </span>
<span>{{ vm.created_at|date:'Y/m/d' }} - {% if vm.terminated_at %}{{ vm.terminated_at|date:'Y/m/d' }}{% else %}{% now 'Y/m/d' %}{% endif %}</span>
<span>
<span class="locale_date" data-format="YYYY/MM/DD">{{ vm.created_at|date:'Y-m-d h:i a' }}</span> - <span class="locale_date" data-format="YYYY/MM/DD">{{ subscription_end_date|date:'Y-m-d h:i a' }}</span>
</span>
</p>
{% endif %}
<p>
@ -194,12 +196,16 @@
<script type="text/javascript">
{% trans "Some problem encountered. Please try again later." as err_msg %}
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();
locale_date = moment(locale_date).format("YYYY-MM-DD h:mm:ss a");
document.getElementById('order-created_at').innerHTML = locale_date;
var locale_dates = document.getElementsByClassName("locale_date");
var formats = ['YYYY-MM-DD hh:mm a']
var i;
for (i = 0; i < locale_dates.length; i++) {
var oldDate = moment.utc(locale_dates[i].textContent, formats);
var outputFormat = locale_dates[i].getAttribute('data-format') || oldDate._f;
locale_dates[i].innerHTML = oldDate.local().format(outputFormat);
locale_dates[i].className += ' done';
}
};
</script>
{%endblock%}

View file

@ -1,37 +1,40 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3%}
{% load i18n %}
{% load staticfiles bootstrap3 i18n %}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %}
<div class="auth-container">
<div class="auth-bg"></div>
<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>
{% include 'hosting/includes/_messages.html' %}
<div class="auth-content wide">
<div class="auth-box sign-up">
<h1 class="section-heading">{% trans "Resend activation link" %}</h1>
{% include 'hosting/includes/_messages.html' %}
<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">
<div class="text-center">
<button type="submit" class="btn choice-btn">
{% trans "Submit"%}
</button>
{% endbuttons %}
</div>
</form>
<div class="auth-footer">
<div>
{% trans "Don't have an account yet ?" %}&nbsp;
<a class="" href="{% url 'hosting:signup' %}">{% trans "Sign up" %}</a>
</div>
<div>
or <a href="{% url 'hosting:reset_password' %}">{% trans "Forgot your password ?" %}</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,44 +1,37 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3%}
{% load i18n %}
{% load i18n staticfiles bootstrap3%}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %}
<div class="auth-container">
<div class="auth-bg"></div>
<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 "Reset your password"%}</h2>
{% include 'hosting/includes/_messages.html' %}
<div class="auth-box sign-up">
<h1 class="section-heading">{% trans "Password reset" %}</h1>
{% include 'hosting/includes/_messages.html' %}
<form action="{% url 'hosting:reset_password' %}" 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 "Reset"%}
<div class="text-center">
<button type="submit" class="btn choice-btn">
{% trans "Reset" %}
</button>
{% endbuttons %}
</div>
</form>
<div class="auth-footer">
<div class="text">
<span>{% trans "Already have an account ?"%}</span>
</div>
<div class="links">
<a class="unlink" href="{% url 'hosting:login' %}">{% trans "Login"%}</a>
<div>
<span>{% trans "Already have an account ?" %}</span>&nbsp;
<a href="{% url 'hosting:login' %}">{% trans "Login" %}</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -2,41 +2,36 @@
{% load staticfiles bootstrap3 i18n %}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %}
<div class="auth-container auth-signup">
<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 "Sign up"%}</h2>
{% include 'hosting/includes/_messages.html' %}
<form action="{% url 'hosting:signup' %}" 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-info">
{% trans "Sign up"%}
</button>
{% endbuttons %}
</form>
<div class="auth-footer">
<div class="text">
<span>{% trans "Already have an account ?"%}</span>
</div>
<div class="links">
<a class="unlink" href="{% url 'hosting:login' %}">{% trans "Login"%}</a>
<div class="auth-container auth-signup">
<div class="auth-bg"></div>
<div class="auth-center ">
<div class="auth-content">
<div class="auth-box sign-up">
<h1 class="section-heading allcaps">{% trans "Sign up" %}</h1>
{% include 'hosting/includes/_messages.html' %}
<form action="{% url 'hosting:signup' %}" method="post" class="form" novalidate>
{% csrf_token %}
{% for field in form %}
{% bootstrap_field field show_label=False %}
{% endfor %}
<div class="text-center">
<button type="submit" class="btn choice-btn">
{% trans "Sign up" %}
</button>
</div>
</form>
<div class="auth-footer">
<div>
<span>{% trans "Already have an account ?" %}</span>&nbsp;
<a href="{% url 'hosting:login' %}">{% trans "Login" %}</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -6,21 +6,17 @@
{% 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>
{% include 'hosting/includes/_messages.html' %}
</div>
<div class="auth-content">
<div class="auth-container">
<div class="auth-bg"></div>
<div class="auth-center">
<div class="auth-content wide">
<div class="intro-message auth-box sign-up">
<h2 class="section-heading">{{section_title}}</h2>
<h2 class="section-heading">{{section_title}}</h2>
<div class="sign-up-message">
{{message}}
{{message}}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,25 +1,18 @@
from django.test import TestCase
from unittest import mock
from model_mommy import mommy
from .forms import HostingOrderAdminForm, HostingUserLoginForm, HostingUserSignupForm
from .models import VirtualMachinePlan
from .forms import HostingUserLoginForm, HostingUserSignupForm
class HostingUserLoginFormTest(TestCase):
def setUp(self):
password = 'user_password'
self.user = mommy.make('CustomUser')
self.user = mommy.make('CustomUser', validated=1)
self.user.set_password(password)
self.user.save()
self.completed_data = {
'email': self.user.email,
'password': password
}
self.incorrect_data = {
'email': 'test',
}
@ -34,9 +27,7 @@ class HostingUserLoginFormTest(TestCase):
class HostingUserSignupFormTest(TestCase):
def setUp(self):
self.completed_data = {
'name': 'test name',
'email': 'test@ungleich.com',
@ -58,13 +49,11 @@ class HostingUserSignupFormTest(TestCase):
class HostingOrderAdminFormTest(TestCase):
def setUp(self):
self.customer = mommy.make('StripeCustomer')
self.vm_plan = mommy.make('VirtualMachinePlan')
self.vm_canceled_plan = mommy.make('VirtualMachinePlan',
status=VirtualMachinePlan.CANCELED_STATUS)
# self.vm_canceled_plan = mommy.make('VirtualMachinePlan',
# status=VirtualMachinePlan.CANCELED_STATUS)
self.mocked_charge = {
'amount': 5100,
@ -87,30 +76,30 @@ class HostingOrderAdminFormTest(TestCase):
'customer': None
}
@mock.patch('utils.stripe_utils.StripeUtils.make_charge')
def test_valid_form(self, stripe_mocked_call):
stripe_mocked_call.return_value = {
'paid': True,
'response_object': self.mocked_charge,
'error': None
}
form = HostingOrderAdminForm(data=self.completed_data)
self.assertTrue(form.is_valid())
# @mock.patch('utils.stripe_utils.StripeUtils.make_charge')
# def test_valid_form(self, stripe_mocked_call):
# stripe_mocked_call.return_value = {
# 'paid': True,
# 'response_object': self.mocked_charge,
# 'error': None
# }
# form = HostingOrderAdminForm(data=self.completed_data)
# self.assertTrue(form.is_valid())
@mock.patch('utils.stripe_utils.StripeUtils.make_charge')
def test_invalid_form_canceled_vm(self, stripe_mocked_call):
self.completed_data.update({
'vm_plan': self.vm_canceled_plan.id
})
stripe_mocked_call.return_value = {
'paid': True,
'response_object': self.mocked_charge,
'error': None
}
form = HostingOrderAdminForm(data=self.completed_data)
self.assertFalse(form.is_valid())
def test_invalid_form(self):
form = HostingOrderAdminForm(data=self.incompleted_data)
self.assertFalse(form.is_valid())
# @mock.patch('utils.stripe_utils.StripeUtils.make_charge')
# def test_invalid_form_canceled_vm(self, stripe_mocked_call):
#
# self.completed_data.update({
# 'vm_plan': self.vm_canceled_plan.id
# })
# stripe_mocked_call.return_value = {
# 'paid': True,
# 'response_object': self.mocked_charge,
# 'error': None
# }
# form = HostingOrderAdminForm(data=self.completed_data)
# self.assertFalse(form.is_valid())
#
# def test_invalid_form(self):
# form = HostingOrderAdminForm(data=self.incompleted_data)
# self.assertFalse(form.is_valid())

View file

@ -1,75 +1,75 @@
from django.test import TestCase
from django.core.management import call_command
from .models import VirtualMachineType
class VirtualMachineTypeModelTest(TestCase):
def setUp(self):
self.HETZNER_NUG_NAME = 'hetzner_nug'
self.HETZNER_NAME = 'hetzner'
self.HETZNER_RAID6_NAME = 'hetzner_raid6'
self.HETZNER_GLUSTERFS_NAME = 'hetzner_glusterfs'
self.BERN_NAME = 'bern'
self.HETZNER_NUG_EXPECTED_PRICE = 79
self.HETZNER_EXPECTED_PRICE = 180
self.HETZNER_RAID6_EXPECTED_PRICE = 216
self.HETZNER_GLUSTERFS_EXPECTED_PRICE = 252
self.BERN_EXPECTED_PRICE = 202
call_command('create_vm_types')
def test_calculate_price(self):
# hetzner_nug
# specifications = {
# 'cores': 2,
# 'memory': 10,
# 'disk_size': 100
# }
# vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NUG_NAME)
# calculated_price = vm_type.calculate_price(specifications)
# self.assertEqual(calculated_price, self.HETZNER_NUG_EXPECTED_PRICE)
# hetzner
specifications = {
'cores': 2,
'memory': 10,
'disk_size': 100
}
vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NAME)
calculated_price = vm_type.calculate_price(specifications)
self.assertEqual(calculated_price, self.HETZNER_EXPECTED_PRICE)
# hetzner_raid6
# specifications = {
# 'cores': 2,
# 'memory': 10,
# 'disk_size': 100
# }
# vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_RAID6_NAME)
# calculated_price = vm_type.calculate_price(specifications)
# self.assertEqual(calculated_price, self.HETZNER_RAID6_EXPECTED_PRICE)
# hetzner_glusterfs
# specifications = {
# 'cores': 2,
# 'memory': 10,
# 'disk_size': 100
# }
# vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_GLUSTERFS_NAME)
# calculated_price = vm_type.calculate_price(specifications)
# self.assertEqual(calculated_price, self.HETZNER_GLUSTERFS_EXPECTED_PRICE)
# bern
specifications = {
'cores': 2,
'memory': 10,
'disk_size': 100
}
vm_type = VirtualMachineType.objects.get(hosting_company=self.BERN_NAME)
calculated_price = vm_type.calculate_price(specifications)
self.assertEqual(calculated_price, self.BERN_EXPECTED_PRICE)
# from django.test import TestCase
#
# from django.core.management import call_command
#
#
# #from .models import VirtualMachineType
#
#
# class VirtualMachineTypeModelTest(TestCase):
#
# def setUp(self):
# self.HETZNER_NUG_NAME = 'hetzner_nug'
# self.HETZNER_NAME = 'hetzner'
# self.HETZNER_RAID6_NAME = 'hetzner_raid6'
# self.HETZNER_GLUSTERFS_NAME = 'hetzner_glusterfs'
# self.BERN_NAME = 'bern'
# self.HETZNER_NUG_EXPECTED_PRICE = 79
# self.HETZNER_EXPECTED_PRICE = 180
# self.HETZNER_RAID6_EXPECTED_PRICE = 216
# self.HETZNER_GLUSTERFS_EXPECTED_PRICE = 252
# self.BERN_EXPECTED_PRICE = 202
#
# call_command('create_vm_types')
#
# def test_calculate_price(self):
#
# # hetzner_nug
# # specifications = {
# # 'cores': 2,
# # 'memory': 10,
# # 'disk_size': 100
# # }
# # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NUG_NAME)
# # calculated_price = vm_type.calculate_price(specifications)
# # self.assertEqual(calculated_price, self.HETZNER_NUG_EXPECTED_PRICE)
#
# # hetzner
# specifications = {
# 'cores': 2,
# 'memory': 10,
# 'disk_size': 100
# }
# vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NAME)
# calculated_price = vm_type.calculate_price(specifications)
# self.assertEqual(calculated_price, self.HETZNER_EXPECTED_PRICE)
#
# # hetzner_raid6
# # specifications = {
# # 'cores': 2,
# # 'memory': 10,
# # 'disk_size': 100
# # }
# # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_RAID6_NAME)
# # calculated_price = vm_type.calculate_price(specifications)
# # self.assertEqual(calculated_price, self.HETZNER_RAID6_EXPECTED_PRICE)
#
# # hetzner_glusterfs
# # specifications = {
# # 'cores': 2,
# # 'memory': 10,
# # 'disk_size': 100
# # }
# # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_GLUSTERFS_NAME)
# # calculated_price = vm_type.calculate_price(specifications)
# # self.assertEqual(calculated_price, self.HETZNER_GLUSTERFS_EXPECTED_PRICE)
#
# # bern
# specifications = {
# 'cores': 2,
# 'memory': 10,
# 'disk_size': 100
# }
# vm_type = VirtualMachineType.objects.get(hosting_company=self.BERN_NAME)
# calculated_price = vm_type.calculate_price(specifications)
# self.assertEqual(calculated_price, self.BERN_EXPECTED_PRICE)

View file

@ -1,4 +1,3 @@
from unittest import mock
from django.conf import settings
from django.test import TestCase
from django.core.urlresolvers import reverse
@ -6,21 +5,29 @@ from django.core.urlresolvers import resolve
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from unittest import skipIf
from model_mommy import mommy
from stored_messages.models import Inbox
from membership.models import CustomUser, StripeCustomer
from .models import VirtualMachineType, HostingOrder, VirtualMachinePlan
from .views import DjangoHostingView, RailsHostingView, NodeJSHostingView, LoginView, SignupView, \
PaymentVMView, OrdersHostingDetailView, OrdersHostingListView, VirtualMachineView, \
VirtualMachinesPlanListView, PasswordResetView, PasswordResetConfirmView, HostingPricingView, \
NotificationsView, MarkAsReadNotificationView, GenerateVMSSHKeysView
from .models import HostingOrder
from .views import (
DjangoHostingView, RailsHostingView, NodeJSHostingView, LoginView,
SignupView, PaymentVMView, OrdersHostingDetailView, OrdersHostingListView,
VirtualMachinesPlanListView, PasswordResetView, PasswordResetConfirmView,
HostingPricingView, NotificationsView, MarkAsReadNotificationView
)
from utils.tests import BaseTestCase
@skipIf(
(settings.OPENNEBULA_DOMAIN is None or
settings.OPENNEBULA_DOMAIN == "test_domain"),
"""OpenNebula details unavailable, so skipping
ProcessVMSelectionTestMixin"""
)
class ProcessVMSelectionTestMixin(object):
def url_resolve_to_view_correctly(self):
@ -30,14 +37,15 @@ class ProcessVMSelectionTestMixin(object):
def test_get(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.view.get_context_data(), self.expected_context)
# self.assertEqual(self.view.get_context_data(), self.expected_context)
self.assertEqual(response.context['hosting'], self.expected_context['hosting'])
self.assertTemplateUsed(response, self.expected_template)
def test_anonymous_post(self):
response = self.client.post(self.url)
self.assertRedirects(response, expected_url=reverse('hosting:login'),
status_code=302, target_status_code=200)
# def test_anonymous_post(self):
# params = {'vm_template_id': 1, 'configuration': 1}
# response = self.client.post(self.url, params)
# self.assertRedirects(response, expected_url=reverse('hosting:login'),
# status_code=302, target_status_code=200)
class DjangoHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
@ -47,15 +55,16 @@ class DjangoHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
self.view = DjangoHostingView()
self.expected_template = 'hosting/django.html'
HOSTING = 'django'
configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
# configuration_detail = dict(
# VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
self.expected_context = {
'hosting': HOSTING,
'hosting_long': "Django",
'configuration_detail': configuration_detail,
# 'configuration_detail': configuration_detail,
'domain': "django-hosting.ch",
'google_analytics': "UA-62285904-6",
'email': "info@django-hosting.ch",
'vm_types': VirtualMachineType.get_serialized_vm_types(),
# 'vm_types': VirtualMachineType.get_serialized_vm_types(),
}
@ -66,15 +75,16 @@ class RailsHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
self.view = RailsHostingView()
self.expected_template = 'hosting/rails.html'
HOSTING = 'rails'
configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
# configuration_detail = dict(
# VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
self.expected_context = {
'hosting': HOSTING,
'hosting_long': "Ruby On Rails",
'configuration_detail': configuration_detail,
# 'configuration_detail': configuration_detail,
'domain': "rails-hosting.ch",
'google_analytics': "UA-62285904-5",
'email': "info@rails-hosting.ch",
'vm_types': VirtualMachineType.get_serialized_vm_types(),
# 'vm_types': VirtualMachineType.get_serialized_vm_types(),
}
@ -85,18 +95,25 @@ class NodeJSHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
self.view = NodeJSHostingView()
self.expected_template = 'hosting/nodejs.html'
HOSTING = 'nodejs'
configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
# configuration_detail = dict(
# VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
self.expected_context = {
'hosting': HOSTING,
'hosting_long': "NodeJS",
'configuration_detail': configuration_detail,
# 'configuration_detail': configuration_detail,
'domain': "node-hosting.ch",
'google_analytics': "UA-62285904-7",
'email': "info@node-hosting.ch",
'vm_types': VirtualMachineType.get_serialized_vm_types(),
# 'vm_types': VirtualMachineType.get_serialized_vm_types(),
}
@skipIf(
(settings.OPENNEBULA_DOMAIN is None or
settings.OPENNEBULA_DOMAIN == "test_domain"),
"""OpenNebula details unavailable, so skipping
HostingPricingViewTest.test_get"""
)
class HostingPricingViewTest(TestCase):
def setUp(self):
@ -104,11 +121,11 @@ class HostingPricingViewTest(TestCase):
self.view = HostingPricingView()
self.expected_template = 'hosting/hosting_pricing.html'
configuration_options = dict(VirtualMachinePlan.VM_CONFIGURATION)
# configuration_options = dict(VirtualMachinePlan.VM_CONFIGURATION)
self.expected_context = {
'configuration_options': configuration_options,
# 'configuration_options': configuration_options,
'email': "info@django-hosting.ch",
'vm_types': VirtualMachineType.get_serialized_vm_types(),
# 'vm_types': VirtualMachineType.get_serialized_vm_types(),
}
def url_resolve_to_view_correctly(self):
@ -118,13 +135,13 @@ class HostingPricingViewTest(TestCase):
def test_get(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.view.get_context_data(), self.expected_context)
# self.assertEqual(self.view.get_context_data(), self.expected_context)
self.assertTemplateUsed(response, self.expected_template)
def test_anonymous_post(self):
response = self.client.post(self.url)
self.assertRedirects(response, expected_url=reverse('hosting:login'),
status_code=302, target_status_code=200)
# def test_anonymous_post(self):
# response = self.client.post(self.url)
# self.assertRedirects(response, expected_url=reverse('hosting:login'),
# status_code=302, target_status_code=200)
class PaymentVMViewTest(BaseTestCase):
@ -135,10 +152,10 @@ class PaymentVMViewTest(BaseTestCase):
self.view = PaymentVMView
# VM
self.vm = mommy.make(VirtualMachineType, base_price=10000,
memory_price=100,
core_price=1000,
disk_size_price=1)
# self.vm = mommy.make(VirtualMachineType, base_price=10000,
# memory_price=100,
# core_price=1000,
# disk_size_price=1)
# post data
self.billing_address = {
@ -153,56 +170,56 @@ class PaymentVMViewTest(BaseTestCase):
self.url = reverse('hosting:payment')
# Session data
self.session_data = {
'vm_specs': {
'hosting_company': self.vm.hosting_company,
'cores': 1,
'memory': 10,
'disk_size': 10000,
'price': 22000,
'configuration': dict(VirtualMachinePlan.VM_CONFIGURATION).get('django')
}
}
# self.session_data = {
# 'vm_specs': {
# 'hosting_company': self.vm.hosting_company,
# 'cores': 1,
# 'memory': 10,
# 'disk_size': 10000,
# 'price': 22000,
# 'configuration': dict(VirtualMachinePlan.VM_CONFIGURATION).get('django')
# }
# }
session = self.customer_client.session
session.update(self.session_data)
session.save()
# session = self.customer_client.session
# session.update(self.session_data)
# session.save()
def test_url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
@mock.patch('utils.stripe_utils.StripeUtils.create_customer')
def test_post(self, stripe_mocked_call):
# Anonymous user should get redirect to login
response = self.client.post(self.url)
expected_url = "%s?next=%s" % (reverse('hosting:login'), reverse('hosting:payment'))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Customer user should be able to pay
stripe_mocked_call.return_value = {
'paid': True,
'response_object': self.stripe_mocked_customer,
'error': None
}
response = self.customer_client.post(self.url, self.billing_address)
self.assertEqual(response.status_code, 200)
self.assertTrue(StripeCustomer.objects.filter(user__email=self.customer.email).exists())
stripe_customer = StripeCustomer.objects.get(user__email=self.customer.email)
self.assertEqual(stripe_customer.user, self.customer)
self.assertTrue(HostingOrder.objects.filter(customer=stripe_customer).exists())
hosting_order = HostingOrder.objects.filter(customer=stripe_customer)[0]
vm_plan = {
'cores': hosting_order.vm_plan.cores,
'memory': hosting_order.vm_plan.memory,
'disk_size': hosting_order.vm_plan.disk_size,
'price': hosting_order.vm_plan.price,
'hosting_company': hosting_order.vm_plan.vm_type.hosting_company,
'configuration': hosting_order.vm_plan.configuration
}
self.assertEqual(vm_plan, self.session_data.get('vm_specs'))
# @mock.patch('utils.stripe_utils.StripeUtils.create_customer')
# def test_post(self, stripe_mocked_call):
#
# # Anonymous user should get redirect to login
# response = self.client.post(self.url)
# expected_url = "%s?next=%s" % (reverse('hosting:login'), reverse('hosting:payment'))
# self.assertRedirects(response, expected_url=expected_url,
# status_code=302, target_status_code=200)
#
# # Customer user should be able to pay
# stripe_mocked_call.return_value = {
# 'paid': True,
# 'response_object': self.stripe_mocked_customer,
# 'error': None
# }
# response = self.customer_client.post(self.url, self.billing_address)
# self.assertEqual(response.status_code, 200)
# self.assertTrue(StripeCustomer.objects.filter(user__email=self.customer.email).exists())
# stripe_customer = StripeCustomer.objects.get(user__email=self.customer.email)
# self.assertEqual(stripe_customer.user, self.customer)
# self.assertTrue(HostingOrder.objects.filter(customer=stripe_customer).exists())
# hosting_order = HostingOrder.objects.filter(customer=stripe_customer)[0]
# vm_plan = {
# 'cores': hosting_order.vm_plan.cores,
# 'memory': hosting_order.vm_plan.memory,
# 'disk_size': hosting_order.vm_plan.disk_size,
# 'price': hosting_order.vm_plan.price,
# 'hosting_company': hosting_order.vm_plan.vm_type.hosting_company,
# 'configuration': hosting_order.vm_plan.configuration
# }
# self.assertEqual(vm_plan, self.session_data.get('vm_specs'))
def test_get(self):
@ -285,73 +302,73 @@ class MarkAsReadNotificationViewTest(BaseTestCase):
self.assertTemplateUsed(response, self.expected_template)
class GenerateVMSSHKeysViewTest(BaseTestCase):
def setUp(self):
super(GenerateVMSSHKeysViewTest, self).setUp()
self.view = GenerateVMSSHKeysView
self.vm = mommy.make(VirtualMachinePlan)
self.expected_template = 'hosting/virtual_machine_key.html'
self.url = reverse('hosting:virtual_machine_key', kwargs={'pk': self.vm.id})
def test_url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
def test_get(self):
# Anonymous user should get redirect to login
response = self.client.get(self.url)
expected_url = "%s?next=%s" % (reverse('hosting:login'),
reverse('hosting:virtual_machine_key',
kwargs={'pk': self.vm.id}))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Logged user should get the page
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
updated_vm = VirtualMachinePlan.objects.get(id=self.vm.id)
self.assertEqual(response.context['public_key'].decode("utf-8"), updated_vm.public_key)
self.assertTrue(response.context['private_key'] is not None)
self.assertEqual(len(response.context['public_key']), 380)
self.assertTrue(len(response.context['private_key']) is 1678 or 1674)
self.assertTemplateUsed(response, self.expected_template)
# class GenerateVMSSHKeysViewTest(BaseTestCase):
#
# def setUp(self):
# super(GenerateVMSSHKeysViewTest, self).setUp()
#
# # self.view = GenerateVMSSHKeysView
# # self.vm = mommy.make(VirtualMachinePlan)
# self.expected_template = 'hosting/virtual_machine_key.html'
# self.url = reverse('hosting:virtual_machine_key', kwargs={'pk': self.vm.id})
#
# def test_url_resolve_to_view_correctly(self):
# found = resolve(self.url)
# self.assertEqual(found.func.__name__, self.view.__name__)
#
# def test_get(self):
#
# # Anonymous user should get redirect to login
# response = self.client.get(self.url)
# expected_url = "%s?next=%s" % (reverse('hosting:login'),
# reverse('hosting:virtual_machine_key',
# kwargs={'pk': self.vm.id}))
# self.assertRedirects(response, expected_url=expected_url,
# status_code=302, target_status_code=200)
#
# # Logged user should get the page
# response = self.customer_client.get(self.url, follow=True)
# self.assertEqual(response.status_code, 200)
# #updated_vm = VirtualMachinePlan.objects.get(id=self.vm.id)
# #self.assertEqual(response.context['public_key'].decode("utf-8"), updated_vm.public_key)
# self.assertTrue(response.context['private_key'] is not None)
# self.assertEqual(len(response.context['public_key']), 380)
# self.assertTrue(len(response.context['private_key']) is 1678 or 1674)
# self.assertTemplateUsed(response, self.expected_template)
class VirtualMachineViewTest(BaseTestCase):
def setUp(self):
super(VirtualMachineViewTest, self).setUp()
self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
self.vm = mommy.make(VirtualMachinePlan)
self.vm.assign_permissions(self.customer)
self.order = mommy.make(HostingOrder, customer=self.stripe_customer, vm_plan=self.vm)
self.url = reverse('hosting:virtual_machines', kwargs={'pk': self.vm.id})
self.view = VirtualMachineView()
self.expected_template = 'hosting/virtual_machine_detail.html'
def url_resolve_to_view_correctly(self):
found = resolve(self.url)
self.assertEqual(found.func.__name__, self.view.__name__)
def test_get(self):
# Anonymous user should get redirect to login
response = self.client.get(self.url)
expected_url = "%s?next=%s" % (reverse('hosting:login'),
reverse('hosting:virtual_machines',
kwargs={'pk': self.vm.id}))
self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200)
# Customer should be able to get data
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['virtual_machine'], self.vm)
self.assertTemplateUsed(response, self.expected_template)
# class VirtualMachineViewTest(BaseTestCase):
#
# def setUp(self):
# super(VirtualMachineViewTest, self).setUp()
#
# self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
# #self.vm = mommy.make(VirtualMachinePlan)
# self.vm.assign_permissions(self.customer)
# self.order = mommy.make(HostingOrder, customer=self.stripe_customer, vm_plan=self.vm)
# self.url = reverse('hosting:virtual_machines', kwargs={'pk': self.vm.id})
# self.view = VirtualMachineView()
# self.expected_template = 'hosting/virtual_machine_detail.html'
#
# def url_resolve_to_view_correctly(self):
# found = resolve(self.url)
# self.assertEqual(found.func.__name__, self.view.__name__)
#
# def test_get(self):
#
# # Anonymous user should get redirect to login
# response = self.client.get(self.url)
# expected_url = "%s?next=%s" % (reverse('hosting:login'),
# reverse('hosting:virtual_machines',
# kwargs={'pk': self.vm.id}))
# self.assertRedirects(response, expected_url=expected_url,
# status_code=302, target_status_code=200)
#
# # Customer should be able to get data
# response = self.customer_client.get(self.url, follow=True)
# self.assertEqual(response.status_code, 200)
# self.assertEqual(response.context['virtual_machine'], self.vm)
# self.assertTemplateUsed(response, self.expected_template)
class VirtualMachinesPlanListViewTest(BaseTestCase):
@ -361,8 +378,8 @@ class VirtualMachinesPlanListViewTest(BaseTestCase):
self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
mommy.make(HostingOrder, customer=self.stripe_customer, approved=True, _quantity=20)
_vms = VirtualMachinePlan.objects.all()
self.vms = sorted(_vms, key=lambda vm: vm.id, reverse=True)
# _vms = VirtualMachinePlan.objects.all()
# self.vms = sorted(_vms, key=lambda vm: vm.id, reverse=True)
self.url = reverse('hosting:virtual_machines')
self.view = VirtualMachinesPlanListView()
self.expected_template = 'hosting/virtual_machines.html'
@ -383,7 +400,7 @@ class VirtualMachinesPlanListViewTest(BaseTestCase):
# Customer should be able to get his orders
response = self.customer_client.get(self.url, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(list(response.context['vms']), self.vms[:10])
# self.assertEqual(list(response.context['vms']), self.vms[:10])
self.assertTemplateUsed(response, self.expected_template)
@ -456,7 +473,7 @@ class LoginViewTest(TestCase):
self.url = reverse('hosting:login')
self.view = LoginView
self.expected_template = 'hosting/login.html'
self.user = mommy.make('membership.CustomUser')
self.user = mommy.make('membership.CustomUser', validated=1)
self.password = 'fake_password'
self.user.set_password(self.password)
self.user.save()
@ -505,7 +522,7 @@ class SignupViewTest(TestCase):
def test_anonymous_user_can_signup(self):
response = self.client.post(self.url, data=self.signup_data, follow=True)
self.user = CustomUser.objects.get(email=self.signup_data.get('email'))
self.assertEqual(response.context['user'], self.user)
# self.assertEqual(response.context['user'], self.user)
self.assertEqual(response.status_code, 200)
@ -540,10 +557,11 @@ class PasswordResetViewTest(BaseTestCase):
self.assertEqual(response.status_code, 200)
def test_test_generate_email_context(self):
context = self.setup_view(self.view()).\
test_generate_email_context(self.user)
context = self.setup_view(self.view()).test_generate_email_context(
self.user
)
self.assertEqual(context.get('user'), self.user)
self.assertEqual(context.get('site_name'), 'ungleich')
self.assertEqual(context.get('site_name'), settings.DCL_TEXT)
self.assertEqual(len(context.get('token')), 24)
@ -578,7 +596,9 @@ class PasswordResetConfirmViewTest(BaseTestCase):
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, self.expected_template)
def test_post(self):
response = self.client.post(self.url, data=self.post_data, follow=True)
self.assertEqual(response.status_code, 200)
self.assertTrue(not response.context['form'].errors)
# def test_post(self):
# response = self.client.post(
# self.url, data=self.post_data, follow=True
# )
# self.assertEqual(response.status_code, 200)
# self.assertTrue(not response.context['form'].errors)

View file

@ -268,6 +268,8 @@ class SignupValidatedView(SignupValidateView):
login_url = '<a href="' + \
reverse('hosting:login') + '">' + str(_('login')) + '</a>'
section_title = _('Account activation')
user = CustomUser.objects.filter(
validation_slug=self.kwargs['validate_slug']).first()
if validated:
message = ('{account_activation_string} <br />'
' {login_string} {lurl}.').format(
@ -275,6 +277,21 @@ class SignupValidatedView(SignupValidateView):
"Your account has been activated."),
login_string=_("You can now"),
lurl=login_url)
email_data = {
'subject': _('Welcome to Data Center Light!'),
'to': user.email,
'context': {
'base_url': "{0}://{1}".format(
self.request.scheme,
self.request.get_host()
)
},
'template_name': 'welcome_user',
'template_path': 'datacenterlight/emails/',
'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
}
email = BaseEmail(**email_data)
email.send()
else:
home_url = '<a href="' + \
reverse('datacenterlight:index') + \
@ -687,6 +704,7 @@ class OrdersHostingDetailView(LoginRequiredMixin,
disk_size=context['vm']['disk_size'],
memory=context['vm']['memory']
)
context['subscription_end_date'] = vm_detail.end_date()
except VMDetail.DoesNotExist:
try:
manager = OpenNebulaManager(
@ -1049,6 +1067,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
try:
vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data
vm_name = vm_data.get('name')
except WrongIdError:
return redirect(reverse('hosting:virtual_machines'))
@ -1120,10 +1139,11 @@ class VirtualMachineView(LoginRequiredMixin, View):
else:
sleep(2)
context = {
'vm': vm_data,
'vm_name': vm_name,
'base_url': "{0}://{1}".format(self.request.scheme,
self.request.get_host()),
'page_header': _('Virtual Machine Cancellation')
'page_header': _('Virtual Machine %(vm_name)s Cancelled') % {
'vm_name': vm_name}
}
email_data = {
'subject': context['page_header'],