undo url change

This commit is contained in:
Arvind Tiwari 2018-03-07 19:27:50 +05:30
commit e7aa8e6139
373 changed files with 16436 additions and 32663 deletions

7
.gitignore vendored
View file

@ -35,3 +35,10 @@ secret-key
.env .env
*.mo *.mo
*.log
*.sql
/utils/optimize/
# to keep empty dirs
!.gitkeep

View file

@ -1,13 +1,14 @@
language: python language: python
python: python:
- "3.5" - "3.4.2"
- "3.6" # - "3.6"
env: env:
# Set a dummy secret key - DJANGO_SECRET_KEY=0 OPENNEBULA_USERNAME='test' OPENNEBULA_PASSWORD='test' OPENNEBULA_PROTOCOL='http' OPENNEBULA_DOMAIN='test_domain' OPENNEBULA_PORT='2633' OPENNEBULA_ENDPOINT='/RPC2' DCL_TEXT='Data Center Light' CELERY_MAX_RETRIES=0 UNGLEICH_SITE_CONFIGS='{"localhost":{"MULTISITE_CMS_URL":"dynamicweb.urls"}}'
- DJANGO_SECRET_KEY=0
# install dependencies # install dependencies
install: "pip install -r requirements.txt" install: "pip install -r requirements.txt"
script: script:
- flake8 - flake8
- python manage.py test - python manage.py test -v 3
# - coverage run --source='.' manage.py test dynamicweb -v 3
# - coverage report

162
Changelog
View file

@ -1,3 +1,150 @@
Next:
* #3554: [dcl] Remove some more beta access resources (some were left in the earlier release)
1.4.1: 2018-02-23
* #3798: [dg] Redirect user to digital glarus on clicking logo in the email
* #3554: [dcl] Remove beta access resources
* #4166: [glasfaser] heading text not to be blocked by topnav on mobile after navbar menu click
* bgfix: [hosting] Change sdd_size to ssd_size in VirtualMachineSerializer
* bgfix: [dg] fix error on /digitalglarus/supporters/
* #4166: [dcl] Fix scroll on top menu click
* #4150: [ungleich] mobile font alignment
* #3713: [dcl] clean up css
* bgfix: [glasfaser] mobile top navigation toggle button fixed
1.4: 2018-02-22
* #4104: [cms, nuglarus] Multisite and access control of cms pages per user
1.3.3: 2018-02-21
* Add ALLOWED_HOST nüglarus.ch IDN
* #4105: [cms] Add cms footer plugin
* #4049: [blog] Replace header background image
* #3670: [hosting] Shorten ssh key name
* #4046: [hosting] Add sdd_size, hdd_size to VirtualMachineSerializer (No visual change)
* bgfix: [hosting] increase invoice pdf resolution
1.3.2: 2018-01-16
* #4000: [all] Replace all ungleich.com with ungleich.ch
* #4067: [ungleich] mobile navbar toggle fix
* #4103: [dcl] Add "Terms of Service" item to the footer
1.3.1: 2017-12-31
* feature: [all] Load email configurations host, port and use_tls from env
* bugfix: [all] Use ungleich's smtp as relayhost for sending emails
1.3: 2017-12-27
* #3911: [dcl] Integrate resend activation link into dcl landing payment page
* #3972: [hosting] Add ungleich company info to invoice footer
* #3974: [hosting] Improve invoice number: Show 404 for invoice resources that do not belong to the user
* #3961: [ungleich] Add video cover to the header on ungleich.ch landing page and add corresponding cms plugin
* #3774: [hosting] Update Stripe subscription on vm delete
* [ungleich] Update text on landing page
* #3601: [dcl, hosting] Change minimum required RAM from 2GB to 1GB
* #3973: [dcl] Update datacenterlight and glasfaser contact address to Linthal and company name to "ungleich glarus ag"
* #3993: [dg] Fix new user membership payment by setting cardholder_name field for UserBillingAddressForm
* #3799: [dg] Make digital glarus billing work as monthly subscription
* #3994: [dg] Add a line on signup for clarifying dcl users can login without new signup
1.2.13: 2017-12-09
* [cms] Introduce UngleichHeaderBackgroundImageAndTextSliderPlugin that allows to have scrolling images and texts
* [cms] Remove <p> tag for ungleich cms customer item template
1.2.12: 2017-12-09
* #3594: [digitalglarus] Remove white scroll bar on the right in mobile
* #3905: [ungleich] Update ungleich.ch header into a slider
* #3968: [ungleich] Fix navbar logo alignment
* [all] Enable logging custom modules
1.2.11: 2017-11-30
* [all] TravisCI: Test against python 3.4.2 only
* [ungleich] Remove data-replaced image in ungleich CMS services item plugin template
1.2.10: 2017-11-26
* #3843: [ungleich] Add generic ungleich CMS template
* #3672: [all] Clean existing automated tests
1.2.9: 2017-11-13
* #3848: [ungleich] Optimize ungleich.ch landing page
* #3360: [ungleich] Ungleich.ch landing page animation fix
* #3421: [hosting] Signup form placeholder translations
* #3856: [ungleich] Glasfaser text modified
* bugfix: [blog] Redirect user to ungleich home on ungleich logo click
* #3858: [dcl] Change "affordable vm ..." text to "Ready in 30 seconds ..."
1.2.8: 2017-10-21
* Remove ALLOWED_HOST alplora.ch
* Add ALLOWED_HOST hack4glarus.ch
* Fetch page_title and meta_description dynamically in glasfaser CMS template
1.2.7: 2017-10-20
* Bugfix: [dcl, hosting] Fix Stripe js error in confirm payment page
* #3847: [ungleich] change text 'hosting products' -> 'our products'
* #3829: [dcl] Handle landing login fail in payment page itself
* #3794: [dcl, hosting] Update email styles
* #3828: [dcl, hosting] invoice period set to show monthly subscription
* #3838: [hosting] restyle signup/login/password reset/password pages
* Bugfix: [dg] Remove validate email link in the registration email
* Feature: [ungleich_page] Add new glasfaser CMS template
1.2.6: 2017-10-10
* Bugfix: [dcl] Refactor and optimize images, links in glasfaser page
* Bugfix: [dcl] Fix email not being sent issue
1.2.5: 2017-10-10
* #3785: [hosting] update 'my bills' page design
* Bugfix: [hosting] card details input form alignment fix
* #3823: [hosting] favicon link fixed
* #3844: [dcl] Add Glasfaser page for advertisement
1.2.4: 2017-10-02
* #3780: [hosting] Store VM details locally
* #3764: [hosting] Show cancelled VMs' invoices
* #3736: [dcl] Refactor the place where we compute the VM price
* #3730: [dcl] Refactor price parameter passed in the DCL flow
* #3807: [dcl] Remove PricingView as it is no more used
* #3813: [hosting] JS error in create ssh key page
* #3756: [dcl] Update landing calculator and billing info page
* Bugfix: Fix PR 493 bug that creates a new StripeCustomer for each buying of VM with the same email id
* #3835: [all] Forbidden (403) CSRF verification failed issue.
* Bugfix: [hosting] Dashboard strictly available after login
* #3808: [dcl] Order confirmation page redesign
1.2.3: 2017-09-25
* #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email
* #3731: [dcl, hosting] Added cdist ssh key handler
* #3628: [dcl] on hosting, VM is created at credit card info submit
* #3772: [dcl] Updated hosting app billing into monthly subscription and added new text and translations
* #3786: [hosting] Redesigned the hosting invoice and order-confirmation page
* #3728: [hosting] VM Termination animation added
* #3777: [hosting] Create new VM calculator added like dcl landing
* #3781: [hosting] Resend activation mail
* #3806: [hosting] Fix can not create VMs after password reset
* #3812: [hosting] Modal check icon made thin and font-size fixed
* Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls
* Bugfix: [dcl, hosting] added host to celery error mails
* Bugfix: [ungleich] Fixed wrong subdomain digitalglarus.ungleich.ch
1.2.2: 2017-09-08
* #3704: [hosting] Added my settings page
* #3771: [datacenterlight] Fixed the inconsistency in navbar style in billing page and onward
* #3769: [datacenterlight] Fixed EN dashboard url redirecting to the wrong page
* #3775: [hosting] Made the dashboard as the default start page for hosting app
* #3779: [hosting] Changed signup validation and activation page navbar transparent
* #3759: [hosting] Made the navbar style consistent to the dcl navbar and changed font weight from 300 to 400 for mobile navbar text
* #3644: [datacenterlight] Added a login button on landing
* #3659: [hosting] Changed hosting navbar design
1.2.1: 2017-09-06
* #3757: [datacenterlight] Added /l route for linkedin
1.2: 2017-09-01
* #3703: [hosting] Added a new dashboard
* #3717: [datacenterlight, hosting] Changed warning color for box
* #3748: [datacenterlight] Changed order msg position for mobile
* #3762: [hosting] Text fix View details to See Invoice
* #3765: [hosting] Text fix Your SSH Keys to My SSH Keys
* #3639: [datacenterlight] Added navbar menu after payment page on landing
* #3735: [hosting] Increased modal width and modal button width
* #3709: Activated Text Plugin by default for the Page Title Text, enabled <title> tag text management
* #3768: [datacenterlight, hosting] Fixed missing DE translation
* #3678: [datacenterlight, hosting] Removed Lato font files
1.1.1: 2017-08-29
* #3709: [datacenterlight] Added faq tos cms template
* #3657: [datacenterlight] Added a new contact section at landing
* #3740: [datacenterlight] Made contact section to send email to info when user submits a message
* #3757: [datacenterlight] Added new routes to dcl
1.1: 2017-08-24
* #3637: [datacenterlight, hosting] Added Stripe error handler
* #3695: [hosting] Applied new design for VM list in hosting
* #3565: [datacenterlight, hosting] Changed warning text color
* #3622: [datacenterlight] Moved the create vm xml-rpc call made in the DCL VM purchase flow into a celery asynchronous task
[datacenterlight] Added test for create vm celery task
* #3711: [hosting] Displayed all IPv4s and IPv6s in the VM list
* #3697: [hosting] Applied new design for VM detail page
* #3645: [hosting] Fixed navbar movement on modal popup
* #3698: [hosting] Applied new design for My Orders page
* #3737: [all] Corrected/added missing google analytics and reformated code, fixed broken head tag
* #3701: [datacenterlight] Enabled monthly Stripe subscriptions
1.0.24: 2017-08-15 1.0.24: 2017-08-15
* #3699: [datacenterlight] Added oneadmin ssh key by default to the created VM via DCL landing * #3699: [datacenterlight] Added oneadmin ssh key by default to the created VM via DCL landing
* #3687: [datacenterlight] Added the name of the customer as description field of the stripe metadata * #3687: [datacenterlight] Added the name of the customer as description field of the stripe metadata
@ -24,7 +171,7 @@
1.0.22: 2017-07-30 1.0.22: 2017-07-30
* #3593: [datacenterlight] Removed underbars between social icons in index * #3593: [datacenterlight] Removed underbars between social icons in index
* #3509: [datacenterlight, hosting] Made navbar transparent and removed mobile navbar bug in login/signup/reset-password * #3509: [datacenterlight, hosting] Made navbar transparent and removed mobile navbar bug in login/signup/reset-password
* #3592: [datacenterlight] Changed “Order Now” button text to “Continue/weiter” * #3592: [datacenterlight] Changed “Order Now” button text to “Continue/weiter”
* #3579: [datacenterlight] Removed “blinks” on click on navbar menus * #3579: [datacenterlight] Removed “blinks” on click on navbar menus
* #3577: [datacenterlight] Added backend CPU, RAM, SSD fields validation * #3577: [datacenterlight] Added backend CPU, RAM, SSD fields validation
* #3615: [datacenterlight] Decoupled landing VM templates from OpenNebula * #3615: [datacenterlight] Decoupled landing VM templates from OpenNebula
@ -35,7 +182,7 @@
* #3629: [datacenterlight] Fixed navbar language switching bug * #3629: [datacenterlight] Fixed navbar language switching bug
1.0.21: 2017-07-21 1.0.21: 2017-07-21
* #3591: [datacenterlight, payment] Fixed card holder name to appear on Confirm Order page * #3591: [datacenterlight, payment] Fixed card holder name to appear on Confirm Order page
* #3558: [datacenterlight] Changed font family and background color for header * #3558: [datacenterlight] Changed font family and background color for header
* #3581: [datacenterlight] Lead font weight change * #3581: [datacenterlight] Lead font weight change
* #3584: [all] Add flag is_superuser=True in MyUserManager * #3584: [all] Add flag is_superuser=True in MyUserManager
1.0.20: 2017-07-18 1.0.20: 2017-07-18
@ -107,14 +254,14 @@
1.0.5: 2017-06-06 1.0.5: 2017-06-06
* [all] General cleanup * [all] General cleanup
* [datacenterlight] Add German translations * [datacenterlight] Add German translations
* [datacenterlight] Change beta access to subscriptions * [datacenterlight] Change beta access to subscriptions
* [hosting] Add German translations * [hosting] Add German translations
* [blog] Add German translation for header * [blog] Add German translation for header
* [opennebula_api] Improve testing, add ssh key functions * [opennebula_api] Improve testing, add ssh key functions
* [opennebula_api] Remove template views * [opennebula_api] Remove template views
* [datacenterlight] Allow user to have multiple ssh keys * [datacenterlight] Allow user to have multiple ssh keys
* [datacenterlight] Changed stripe.js v2 to v3 * [datacenterlight] Changed stripe.js v2 to v3
* [datacenterlight] Added support for stripe payment errors on current user language * [datacenterlight] Added support for stripe payment errors on current user language
1.0.4: 2017-06-05 1.0.4: 2017-06-05
* [all] Added new Domains to accept * [all] Added new Domains to accept
1.0.3: 2017-06-02 1.0.3: 2017-06-02
@ -126,6 +273,3 @@
* [datacenterlight] Fix initially shown price * [datacenterlight] Fix initially shown price
1.0.0: 2017-05-25 1.0.0: 2017-05-25
* Initial stable release * Initial stable release
Next:
[datacenterlight] Fixed credit card input issue

View file

@ -3,6 +3,10 @@ ungleich
dynamicweb dynamicweb
---------- ----------
.. image:: https://travis-ci.org/ungleich/dynamicweb.svg?branch=master
:target: https://travis-ci.org/ungleich/dynamicweb
Website for ungleich GmbH Website for ungleich GmbH
======= =======

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-05-30 13:47+0000\n" "POT-Creation-Date: 2017-10-10 21:35+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,137 +18,99 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: alplora/templates/alplora/contact.html:6
msgid "New message" msgid "New message"
msgstr "Neue Nachricht" msgstr "Neue Nachricht"
#: alplora/templates/alplora/contact.html:13
msgid "Name:" msgid "Name:"
msgstr "Name:" msgstr "Name:"
#: alplora/templates/alplora/contact.html:15
msgid "What is your name ?" msgid "What is your name ?"
msgstr "Was ist Dein Name?" msgstr "Was ist Dein Name?"
#: alplora/templates/alplora/contact.html:19
msgid "From:" msgid "From:"
msgstr "Von:" msgstr "Von:"
#: alplora/templates/alplora/contact.html:21
msgid "You email" msgid "You email"
msgstr "Deine Email" msgstr "Deine Email"
#: alplora/templates/alplora/contact.html:25
msgid "Message:" msgid "Message:"
msgstr "Nachricht:" msgstr "Nachricht:"
#: alplora/templates/alplora/contact.html:27
msgid "Leave us your message" msgid "Leave us your message"
msgstr "Schreibe hier Deine Nachricht" msgstr "Schreibe hier Deine Nachricht"
#: alplora/templates/alplora/contact.html:32
msgid "Close" msgid "Close"
msgstr "schliessen" msgstr "schliessen"
#: alplora/templates/alplora/contact.html:33
msgid "Send message" msgid "Send message"
msgstr "Nachricht senden" msgstr "Nachricht senden"
#: alplora/templates/alplora/contact_success.html:6
msgid "Message Sent" msgid "Message Sent"
msgstr "Nachricht gesendet" msgstr "Nachricht gesendet"
#: alplora/templates/alplora/contact_success.html:9
msgid "Thank you, we will contact you as soon as possible" msgid "Thank you, we will contact you as soon as possible"
msgstr "Dankeschön! Wir melden uns sobald wie möglich!" msgstr "Dankeschön! Wir melden uns sobald wie möglich!"
#: alplora/templates/alplora/index.html:13
msgid "Find your animal anywhere, anytime" msgid "Find your animal anywhere, anytime"
msgstr "Finde deine Tiere" msgstr "Finde deine Tiere"
#: alplora/templates/alplora/index.html:99
#: alplora/templates/alplora/index.html:463
msgid "About" msgid "About"
msgstr "Über" msgstr "Über"
#: alplora/templates/alplora/index.html:102
#: alplora/templates/alplora/index.html:248
#: alplora/templates/alplora/index.html:469
msgid "Why Alplora?" msgid "Why Alplora?"
msgstr "Warum Alplora?" msgstr "Warum Alplora?"
#: alplora/templates/alplora/index.html:105
#: alplora/templates/alplora/index.html:466
msgid "Usecase" msgid "Usecase"
msgstr "" msgstr ""
#: alplora/templates/alplora/index.html:108
#: alplora/templates/alplora/index.html:358
msgid "Testimonials" msgid "Testimonials"
msgstr "Referenzen" msgstr "Referenzen"
#: alplora/templates/alplora/index.html:111
#: alplora/templates/alplora/index.html:423
#: alplora/templates/alplora/index.html:477
msgid "Contact" msgid "Contact"
msgstr "Kontakt" msgstr "Kontakt"
#: alplora/templates/alplora/index.html:114
msgid "Login" msgid "Login"
msgstr "Login" msgstr "Login"
#: alplora/templates/alplora/index.html:137
msgid "Find your herd anytime, anywhere" msgid "Find your herd anytime, anywhere"
msgstr "Finde deine Herde jederzeit und überall" msgstr "Finde deine Herde jederzeit und überall"
#: alplora/templates/alplora/index.html:138
msgid "Perfect fit for Swiss Alps" msgid "Perfect fit for Swiss Alps"
msgstr "Perfekt für die Schweizer Alpen" msgstr "Perfekt für die Schweizer Alpen"
#: alplora/templates/alplora/index.html:163
msgid "What is Alplora?" msgid "What is Alplora?"
msgstr "Was ist Alplora?" msgstr "Was ist Alplora?"
#: alplora/templates/alplora/index.html:164
msgid "" msgid ""
"Alplora is an animal tracker made for outdoor grazing animals in Swiss Alps." "Alplora is an animal tracker made for outdoor grazing animals in Swiss Alps."
msgstr "" msgstr ""
"Alplora ist ein Sender, der speziell für Weidetiere in den Schweizer Alpen " "Alplora ist ein Sender, der speziell für Weidetiere in den Schweizer Alpen "
"entwickelt wurde." "entwickelt wurde."
#: alplora/templates/alplora/index.html:165
msgid "Alplora is just like a cattle bell, but much better." msgid "Alplora is just like a cattle bell, but much better."
msgstr "Alplora ist wie eine Kuhglocke, nur viel besser." msgstr "Alplora ist wie eine Kuhglocke, nur viel besser."
#: alplora/templates/alplora/index.html:174
msgid "LOST" msgid "LOST"
msgstr "VERLOREN" msgstr "VERLOREN"
#: alplora/templates/alplora/index.html:176
msgid "When an animal gets separated from the herd and is lost." msgid "When an animal gets separated from the herd and is lost."
msgstr "Wenn ein Tier sich von der Herde absondert und verloren geht." msgstr "Wenn ein Tier sich von der Herde absondert und verloren geht."
#: alplora/templates/alplora/index.html:184
msgid "WOLF" msgid "WOLF"
msgstr "WOLF" msgstr "WOLF"
#: alplora/templates/alplora/index.html:186
msgid "When a wolf gets close to the herd." msgid "When a wolf gets close to the herd."
msgstr "Wenn ein Wolf sich der Herde nähert." msgstr "Wenn ein Wolf sich der Herde nähert."
#: alplora/templates/alplora/index.html:193
msgid "INJURED" msgid "INJURED"
msgstr "VERLETZT" msgstr "VERLETZT"
#: alplora/templates/alplora/index.html:195
msgid "When one of the animals is hurt." msgid "When one of the animals is hurt."
msgstr "Wenn eins der Tiere verletzt ist." msgstr "Wenn eins der Tiere verletzt ist."
#: alplora/templates/alplora/index.html:205
msgid "How does Alplora track my animals?" msgid "How does Alplora track my animals?"
msgstr "Wie kann Alplora meine Tiere verfolgen und ausfindig machen ?" msgstr "Wie kann Alplora meine Tiere verfolgen und ausfindig machen ?"
#: alplora/templates/alplora/index.html:206
msgid "" msgid ""
"Each animal will be wearing a small tracker,<P></P>and the tracker will be " "Each animal will be wearing a small tracker,<P></P>and the tracker will be "
"sending a signal every 30 to 60 minutes." "sending a signal every 30 to 60 minutes."
@ -156,33 +118,27 @@ msgstr ""
"Jedes Tier wird einen kleinen Sender tragen, <P></P> welcher alle 30 bis 60 " "Jedes Tier wird einen kleinen Sender tragen, <P></P> welcher alle 30 bis 60 "
"Minuten ein Signal senden wird." "Minuten ein Signal senden wird."
#: alplora/templates/alplora/index.html:215
msgid "Access app" msgid "Access app"
msgstr "Zugang zur App" msgstr "Zugang zur App"
#: alplora/templates/alplora/index.html:217
msgid "" msgid ""
"You can see the animal locations on a map by logging into our Alplora app." "You can see the animal locations on a map by logging into our Alplora app."
msgstr "" msgstr ""
"Du kannst den Standort deiner Tiere jederzeit auf einer Karte verfolgen, " "Du kannst den Standort deiner Tiere jederzeit auf einer Karte verfolgen, "
"indem du dich in unsere Alplora App einloggst." "indem du dich in unsere Alplora App einloggst."
#: alplora/templates/alplora/index.html:225
msgid "Get an alarm" msgid "Get an alarm"
msgstr "Erhalte ein Warnsignal" msgstr "Erhalte ein Warnsignal"
#: alplora/templates/alplora/index.html:227
msgid "" msgid ""
"When certain signals for danger are detected, Alplora sends an alarm to you." "When certain signals for danger are detected, Alplora sends an alarm to you."
msgstr "" msgstr ""
"Wenn Anzeichen von Gefahr bestehen, sendet dir die Alplora App einen " "Wenn Anzeichen von Gefahr bestehen, sendet dir die Alplora App einen "
"Warnsignal." "Warnsignal."
#: alplora/templates/alplora/index.html:235
msgid "Find your animal" msgid "Find your animal"
msgstr "Finde deine Tiere" msgstr "Finde deine Tiere"
#: alplora/templates/alplora/index.html:238
msgid "" msgid ""
"You can locate the animal in trouble on the realtime map and can take " "You can locate the animal in trouble on the realtime map and can take "
"actions for keeping the animal safe." "actions for keeping the animal safe."
@ -190,11 +146,9 @@ msgstr ""
"Du kannst dein Tier in Notsituationen auf einer Echtzeit-Karte lokalisieren " "Du kannst dein Tier in Notsituationen auf einer Echtzeit-Karte lokalisieren "
"und hast die Möglichkeit es in Sicherheit zu bringen." "und hast die Möglichkeit es in Sicherheit zu bringen."
#: alplora/templates/alplora/index.html:255
msgid "Perfect fit for Swiss mountains" msgid "Perfect fit for Swiss mountains"
msgstr "Perfekt für die Schweizer Alpen" msgstr "Perfekt für die Schweizer Alpen"
#: alplora/templates/alplora/index.html:257
msgid "" msgid ""
"Alplora is made and tested for Swiss Alps. It is a perfect fit for Swiss " "Alplora is made and tested for Swiss Alps. It is a perfect fit for Swiss "
"environment." "environment."
@ -202,11 +156,9 @@ msgstr ""
"Alplora wurde speziell für die Schweizer Alpen entwickelt und vor Ort " "Alplora wurde speziell für die Schweizer Alpen entwickelt und vor Ort "
"getestet. Das Produkt passt perfekt in die Schweiz!" "getestet. Das Produkt passt perfekt in die Schweiz!"
#: alplora/templates/alplora/index.html:263
msgid "Energy efficient" msgid "Energy efficient"
msgstr "Energieeffizient" msgstr "Energieeffizient"
#: alplora/templates/alplora/index.html:265
msgid "" msgid ""
"Alplora uses the latest wireless technology, our batteries last the whole " "Alplora uses the latest wireless technology, our batteries last the whole "
"alp season." "alp season."
@ -214,11 +166,9 @@ msgstr ""
"Alplora arbeitet mit den neuesten Technologien, so dass der Akku die gesamte " "Alplora arbeitet mit den neuesten Technologien, so dass der Akku die gesamte "
"Alpsaison überdauert." "Alpsaison überdauert."
#: alplora/templates/alplora/index.html:271
msgid "Made with love" msgid "Made with love"
msgstr "Mit Liebe gemacht" msgstr "Mit Liebe gemacht"
#: alplora/templates/alplora/index.html:273
msgid "" msgid ""
"With a lot of love and respect for Swiss agriculture and nature, Alplora is " "With a lot of love and respect for Swiss agriculture and nature, Alplora is "
"made by a Swiss company." "made by a Swiss company."
@ -226,61 +176,49 @@ msgstr ""
"Alplora wurde mit viel Liebe und Respekt für die Schweizer Natur und " "Alplora wurde mit viel Liebe und Respekt für die Schweizer Natur und "
"Landwirtschaft von einer Schweizer Firma entwickelt." "Landwirtschaft von einer Schweizer Firma entwickelt."
#: alplora/templates/alplora/index.html:285
msgid "Who needs Alplora?" msgid "Who needs Alplora?"
msgstr "Wer benötigt Alplora?" msgstr "Wer benötigt Alplora?"
#: alplora/templates/alplora/index.html:301
msgid " Are your animals..." msgid " Are your animals..."
msgstr "Sind deine Tiere..." msgstr "Sind deine Tiere..."
#: alplora/templates/alplora/index.html:304
msgid "sheep, goats, cows or llamas living freely in the Alps?" msgid "sheep, goats, cows or llamas living freely in the Alps?"
msgstr "Schafe, Ziegen, Kühe oder Lamas, die frei in den Alpen leben?" msgstr "Schafe, Ziegen, Kühe oder Lamas, die frei in den Alpen leben?"
#: alplora/templates/alplora/index.html:306
msgid "wearing bells?" msgid "wearing bells?"
msgstr "solche, die Glocken tragen?" msgstr "solche, die Glocken tragen?"
#: alplora/templates/alplora/index.html:308
msgid "" msgid ""
"sometimes getting confused and going too far away from where they are " "sometimes getting confused and going too far away from where they are "
"supposed to be?" "supposed to be?"
msgstr "" msgstr ""
"manchmal verwirrt und entfernen sich zu weit von ihrem vorgesehenen Standort?" "manchmal verwirrt und entfernen sich zu weit von ihrem vorgesehenen Standort?"
#: alplora/templates/alplora/index.html:332
msgid "Do you..." msgid "Do you..."
msgstr "Möchtest du..." msgstr "Möchtest du..."
#: alplora/templates/alplora/index.html:335
msgid "have animals which are staying outdoor during some time of the year?" msgid "have animals which are staying outdoor during some time of the year?"
msgstr "" msgstr ""
"deine Tiere, die eine längere Zeit im Jahr unbeobachtet Draussen verbringen, " "deine Tiere, die eine längere Zeit im Jahr unbeobachtet Draussen verbringen, "
"schützen und überwachen können?" "schützen und überwachen können?"
#: alplora/templates/alplora/index.html:337
msgid "want to get an alarm when your animal is hurt, or in danger?" msgid "want to get an alarm when your animal is hurt, or in danger?"
msgstr "" msgstr ""
"alarmiert werden, wenn sich eines deiner Tiere verletzt oder in Gefahr " "alarmiert werden, wenn sich eines deiner Tiere verletzt oder in Gefahr "
"befindet ?" "befindet ?"
#: alplora/templates/alplora/index.html:339
msgid "want to see where your animals are on your cell phone map?" msgid "want to see where your animals are on your cell phone map?"
msgstr "" msgstr ""
"mit deinem Smartphone auf einer Karte sehen können, wo sich deine Tiere " "mit deinem Smartphone auf einer Karte sehen können, wo sich deine Tiere "
"befinden? " "befinden? "
#: alplora/templates/alplora/index.html:341
msgid "want to make sure 24/7 that your animals are safe?" msgid "want to make sure 24/7 that your animals are safe?"
msgstr "" msgstr ""
"sicherstellen, dass sich deine Tiere rund um die Uhr in Sicherheit befinden?" "sicherstellen, dass sich deine Tiere rund um die Uhr in Sicherheit befinden?"
#: alplora/templates/alplora/index.html:359
msgid "What our customers say" msgid "What our customers say"
msgstr "" msgstr ""
#: alplora/templates/alplora/index.html:379
msgid "" msgid ""
"“Alplora is an innovation in looking after my cows. I can check where my " "“Alplora is an innovation in looking after my cows. I can check where my "
"cows have been in the higher mountain all day while doing other works at the " "cows have been in the higher mountain all day while doing other works at the "
@ -292,11 +230,9 @@ msgstr ""
"selben Zeit andereDinge auf dem Hof unten im Dorf erledigen. Dank Alplora " "selben Zeit andereDinge auf dem Hof unten im Dorf erledigen. Dank Alplora "
"kann ich meinen Kühenmehr Sicherheit gewährleisten." "kann ich meinen Kühenmehr Sicherheit gewährleisten."
#: alplora/templates/alplora/index.html:382
msgid "Farmer in canton Glarus" msgid "Farmer in canton Glarus"
msgstr "Bauern im Kanton Glarus" msgstr "Bauern im Kanton Glarus"
#: alplora/templates/alplora/index.html:388
msgid "" msgid ""
"\"Alplora is exactly what I was waiting for. I have lost my sheep almost " "\"Alplora is exactly what I was waiting for. I have lost my sheep almost "
"every year. Finally I have a way when I want to locate them.\"" "every year. Finally I have a way when I want to locate them.\""
@ -305,11 +241,9 @@ msgstr ""
"Schafe fastjedes Jahr aus den Augen verloren. Nun habe ich endlich die " "Schafe fastjedes Jahr aus den Augen verloren. Nun habe ich endlich die "
"Möglichkeit, sie zulokalisieren.\"" "Möglichkeit, sie zulokalisieren.\""
#: alplora/templates/alplora/index.html:391
msgid "Owner of 50 sheep " msgid "Owner of 50 sheep "
msgstr "Besitzerin von 50 Schafen" msgstr "Besitzerin von 50 Schafen"
#: alplora/templates/alplora/index.html:397
msgid "" msgid ""
"\"I have a farm down all the way down in the village and y goats are always " "\"I have a farm down all the way down in the village and y goats are always "
"freely grazing in the Alps. There are times that I am worried about them but " "freely grazing in the Alps. There are times that I am worried about them but "
@ -323,30 +257,23 @@ msgstr ""
"noch um meineanderen Tiere kümmern muss. Mit Alplora kann ich nun ohne " "noch um meineanderen Tiere kümmern muss. Mit Alplora kann ich nun ohne "
"Probleme beides tun.\"" "Probleme beides tun.\""
#: alplora/templates/alplora/index.html:401
msgid "Farmer at Berner Oberland" msgid "Farmer at Berner Oberland"
msgstr "Bauer aus dem Berner Oberland" msgstr "Bauer aus dem Berner Oberland"
#: alplora/templates/alplora/index.html:418
msgid "How do I get Alplora?" msgid "How do I get Alplora?"
msgstr "Wie kriege ich Zugriff zu Alplora?" msgstr "Wie kriege ich Zugriff zu Alplora?"
#: alplora/templates/alplora/index.html:419
msgid "Click the button below and leave us your contact." msgid "Click the button below and leave us your contact."
msgstr "Klicke unten auf Kontakt und hinterlasse uns deine Angaben." msgstr "Klicke unten auf Kontakt und hinterlasse uns deine Angaben."
#: alplora/templates/alplora/index.html:419
msgid "Team Alplora will contact you and visit you with a tracking device." msgid "Team Alplora will contact you and visit you with a tracking device."
msgstr "Das Alpora Team wird sich mit Dir schnellstens in Verbindung setzen." msgstr "Das Alpora Team wird sich mit Dir schnellstens in Verbindung setzen."
#: alplora/templates/alplora/index.html:459
msgid "Home" msgid "Home"
msgstr "Startseite" msgstr "Startseite"
#: alplora/templates/alplora/index.html:472
msgid "Testimonials " msgid "Testimonials "
msgstr "Referenzen" msgstr "Referenzen"
#: alplora/views.py:24
msgid "Message Successfully Sent" msgid "Message Successfully Sent"
msgstr "" msgstr ""

View file

@ -1,9 +0,0 @@
from django.contrib import admin
from .models import BetaAccess, BetaAccessVMType, BetaAccessVM
# Register your models here.
admin.site.register(BetaAccess)
admin.site.register(BetaAccessVMType)
admin.site.register(BetaAccessVM)

View file

@ -1,19 +1,9 @@
from django import forms from django import forms
from .models import BetaAccess from .models import ContactUs
class BetaAccessForm(forms.ModelForm): class ContactForm(forms.ModelForm):
email = forms.CharField(widget=forms.EmailInput())
class Meta: class Meta:
fields = ['name', 'email'] fields = ['name', 'email', 'message']
model = BetaAccess model = ContactUs
# class BetaAccessVMForm(forms.ModelForm):
# type = forms.CharField(widget=forms.EmailInput())
# class Meta:
# fields = ['email']
# model = BetaAccessVM

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-08-03 03:10+0530\n" "POT-Creation-Date: 2018-01-15 23:12+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,6 +18,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#, python-format
msgid "Your New VM %(vm_name)s at Data Center Light"
msgstr "Deine neue VM %(vm_name)s bei Data Center Light"
msgid "Enter name" msgid "Enter name"
msgstr "Name" msgstr "Name"
@ -52,38 +56,55 @@ msgstr "Standort: Schweiz"
msgid "Please enter a value in range 1 - 48." msgid "Please enter a value in range 1 - 48."
msgstr "Bitte gib einen Wert von 1 bis 48 ein." msgstr "Bitte gib einen Wert von 1 bis 48 ein."
msgid "Please enter a value in range 2 - 200." msgid "Please enter a value in range 1 - 200."
msgstr "Bitte gib einen Wert von 2 bis 200 ein." msgstr "Bitte gib einen Wert von 1 bis 200 ein."
msgid "Please enter a value in range 10 - 2000." msgid "Please enter a value in range 10 - 2000."
msgstr "Bitte gib einen Wert von 10 bis 200 ein." msgstr "Bitte gib einen Wert von 10 bis 2000 ein."
msgid "GB Storage (SSD)" msgid "GB Storage (SSD)"
msgstr "GB Storage (SSD)" msgstr "GB Storage (SSD)"
msgid "Continue"
msgstr "Weiter"
msgid "Thank you for contacting us."
msgstr "Nachricht gesendet."
msgid "Your message was successfully sent to our team."
msgstr "Vielen Dank für Deine Nachricht."
msgid "Get in touch with us!"
msgstr "Sende uns eine Nachricht."
msgid "Name" msgid "Name"
msgstr "" msgstr ""
msgid "Your Name"
msgstr "Dein Name"
msgid "Please enter your name." msgid "Please enter your name."
msgstr "Bitte gib Deinen Namen ein." msgstr "Bitte gib Deinen Namen ein."
msgid "Email" msgid "Email"
msgstr "E-Mail-Adresse" msgstr "E-Mail-Adresse"
msgid "Your Email"
msgstr "Deine E-Mail"
msgid "Please enter a valid email address." msgid "Please enter a valid email address."
msgstr "Bitte gib eine gültige E-Mailadresse ein." msgstr "Bitte gib eine gültige E-Mailadresse ein."
msgid "Continue" msgid "Message"
msgstr "Weiter" msgstr "Nachricht"
msgid "Sorry, there was an unexpected error. Kindly retry."
msgstr ""
"Bitte entschuldige, es scheint ein unerwarteter Fehler aufgetreten zu sein. "
"Versuche es doch bitte noch einmal."
msgid "SUBMIT"
msgstr "ABSENDEN"
msgid "Your Data Center Light Team"
msgstr "Dein Data Center Light Team"
msgid "Thank you for your request." msgid "Thank you for your request."
msgstr "Vielen Dank für Ihre Anfrage." msgstr "Vielen Dank für Deine Anfrage."
msgid "You are one step away from being our beta tester!" msgid "You are one step away from being our beta tester!"
msgstr "" msgstr ""
@ -105,48 +126,60 @@ msgstr ""
msgid "Thank you!" msgid "Thank you!"
msgstr "Vielen Dank!" msgstr "Vielen Dank!"
msgid "account activation" msgid "Data Center Light Account Activation"
msgstr "Accountaktivierung" msgstr "Data Center Light Account Aktivierung"
#, python-format #, python-format
msgid "" msgid ""
"\n" "You can activate your Data Center Light account by clicking <a href="
" You can activate your %(dcl_text)s account by <a href=" "\"%(base_url)s%(activation_link)s\" style=\"text-decoration: none; color: "
"\"%(base_url)s%(activation_link)s\">clicking here</a>.<br/><br/>\n" "#4382c8; font-weight: 400;\">here</a>."
" 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.<br/>\n"
" %(base_url)s%(activation_link)s\n"
" "
msgstr "" msgstr ""
"\n" "Klicke <a href=\"%(base_url)s%(activation_link)s\"style=\"text-decoration: "
" <a href=\"%(base_url)s%(activation_link)s\">Klicke hier</a> " "none; color: #4382c8; font-weight: 400;\">here</a> um deinen Data Center "
"um deinen %(dcl_text)s zu aktivieren.<br/><br/>\n" "Light Account zu aktivieren."
" Oder kopiere den folgenden Link in die Adressleiste deines "
"Browsers und folge dann dem Link um deinen %(dcl_text)s Account zu "
"aktivieren.<br/>\n"
" %(base_url)s%(activation_link)s\n"
" "
msgid "Your"
msgstr "Dein"
msgid "team"
msgstr "Team"
#, python-format
msgid "" msgid ""
"\n" "You can also copy and paste the following link into the address bar of your "
"Hi,\n" "browser to activate your Data Center Light account."
"\n" msgstr "Kopiere den folgenden Link in die Adressleiste deines Browsers."
"You can activate your %(dcl_text)s account by clicking here %(base_url)s"
"%(activation_link)s\n" msgid "Your account details are as follows"
msgstr "" msgstr "Deine Account Details sind unten aufgelistet"
"\n"
"Hallo,\n" msgid "Username"
"\n" msgstr "Username"
"Du kannst deinen %(dcl_text)s Account aktivieren, indem du hier klickst "
"%(base_url)s%(activation_link)s\n" msgid "Your email address"
msgstr "Deine E-Mail-Adresse"
msgid "Password"
msgstr "Passwort"
msgid "You can reset your password here"
msgstr "Du kannst dein Passwort hier zurück setzen"
msgid ""
"You can copy and paste the following link into the address bar of your "
"browser to activate your Data Center Light account."
msgstr "Kopiere den folgenden Link in die Adressleiste deines Browsers."
msgid "Welcome to Data Center Light!"
msgstr "Willkommen beim Data Center Light!"
msgid ""
"Thanks for joining us! We provide the most affordable virtual machines from "
"the heart of Switzerland."
msgstr "Bei uns findest Du die günstiges VMs aus der Schweiz."
msgid "Try now, order a VM. VM price starts from only 15CHF per month."
msgstr "Unser Angebot beginnt bei 15 CHF pro Monat. Probier's jetzt aus!"
msgid "ORDER VM"
msgstr "VM BESTELLEN"
msgid "Home"
msgstr "Home"
msgid "Highlights" msgid "Highlights"
msgstr "" msgstr ""
@ -157,24 +190,33 @@ msgstr "Skalierung"
msgid "Reliable and light" msgid "Reliable and light"
msgstr "Zuverlässig und leicht" msgstr "Zuverlässig und leicht"
msgid "Pricing"
msgstr "Preise"
msgid "Order VM" msgid "Order VM"
msgstr "VM bestellen" msgstr "VM bestellen"
msgid "Contact" msgid "Contact"
msgstr "Kontakt" msgstr "Kontakt"
msgid "Home" msgid "Terms of Service"
msgstr "Home" msgstr "Nutzungsbedingungen"
msgid "Pricing"
msgstr "Preise"
msgid "All Rights Reserved" msgid "All Rights Reserved"
msgstr "Alle Rechte vorbehalten" msgstr "Alle Rechte vorbehalten"
msgid "Toggle navigation"
msgstr "Umschalten"
msgid "Why Data Center Light?" msgid "Why Data Center Light?"
msgstr "Warum Data Center Light?" msgstr "Warum Data Center Light?"
msgid "Login"
msgstr "Anmelden"
msgid "Dashboard"
msgstr ""
msgid "Finally, an affordable VM hosting in Switzerland!" msgid "Finally, an affordable VM hosting in Switzerland!"
msgstr "Endlich: bezahlbares VM Hosting in der Schweiz" msgstr "Endlich: bezahlbares VM Hosting in der Schweiz"
@ -231,35 +273,63 @@ msgstr ""
"Einfach und bezahlbar: Teste nun unsere virtuellen Maschinen mit " "Einfach und bezahlbar: Teste nun unsere virtuellen Maschinen mit "
"federleichten Preisen." "federleichten Preisen."
msgid "Affordable VM hosting based in Switzerland" msgid ""
msgstr "Bezahlbares VM Hosting in der Schweiz" "Ready in 30 seconds.<br/>Experience the unbeatable speed from Data Center "
"Light."
msgstr ""
"Fertig in 30 Sekunden.<br/>Erlebe die unschlagbare Geschwindigkeit von Data "
"Center Light."
msgid "Contact us"
msgstr "Kontaktiere uns"
msgid "Switzerland " msgid "Switzerland "
msgstr "Schweiz" msgstr "Schweiz "
msgid "Questions?" msgid "Welcome back"
msgstr "Fragen?" msgstr "Willkommen zurück"
msgid "Contact us!" msgid ""
msgstr "Kontaktiere uns!" "Review your billing address and card details and proceed to make payment."
msgstr ""
"Überprüfe die Rechnungsadresse und Kreditkartendaten und fahre mit der "
"Zahlung fort."
msgid "Confirm Order" msgid "Log in"
msgstr "Bestellung Bestätigen" msgstr "Anmelden"
msgid "Date" msgid ""
msgstr "Datum" "Already signed up?<br>By logging in you can retrieve saved billing "
"information."
msgstr ""
"Bereits eingeloggt? Nach der Anmeldung kannst Du gespeicherte "
"Rechnungsinformationen abrufen."
msgid "Billed To:" msgid "LOGIN"
msgstr "ANMELDEN"
msgid "Don't have an account yet?"
msgstr "Besitzt du kein Benutzerkonto?"
msgid "You can sign up by filling in the information below."
msgstr ""
"Du kannst Dich anmelden, indem Du die die untenstehenden Informationen "
"ausfüllst."
msgid "Forgot password?"
msgstr "Passwort vergessen?"
msgid "Resend activation link"
msgstr "Aktivierungslink noch einmal senden"
msgid "Sign up"
msgstr "Registrieren"
msgid "Billing Address"
msgstr "Rechnungsadresse" msgstr "Rechnungsadresse"
msgid "Payment Method:" msgid "Your Order"
msgstr "Bezahlmethode" msgstr "Deine Bestellung"
msgid "ending"
msgstr "endend in"
msgid "Order summary"
msgstr "Bestellungsübersicht"
msgid "Cores" msgid "Cores"
msgstr "Prozessorkerne" msgstr "Prozessorkerne"
@ -274,36 +344,73 @@ msgid "Configuration"
msgstr "Konfiguration" msgstr "Konfiguration"
msgid "Total" msgid "Total"
msgstr "Gesamt"
msgid "including VAT"
msgstr "inkl. Mehrwertsteuer"
msgid "Month"
msgstr "Monat"
msgid "Credit Card"
msgstr "Kreditkarte"
msgid ""
"Please fill in your credit card information below. We are using <a href="
"\"https://stripe.com\" target=\"_blank\">Stripe</a> for payment and do not "
"store your information in our database."
msgstr "" msgstr ""
"Bitte fülle Deine Kreditkarteninformationen unten aus. Wir nutzen <a href="
"\"https://stripe.com\" target=\"_blank\">Stripe</a> für die Bezahlung und "
"speichern keine Informationen in unserer Datenbank."
msgid ""
"You are not making any payment yet. After submitting your card information, "
"you will be taken to the Confirm Order Page."
msgstr ""
"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, "
"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast."
msgid "Card Number"
msgstr "Kreditkartennummer"
msgid "Expiry Date"
msgstr "Ablaufdatum"
msgid "CVC"
msgstr ""
msgid "Card Type"
msgstr "Kartentyp"
msgid ""
"You are not making any payment yet. After placing your order, you will be "
"taken to the Submit Payment Page."
msgstr ""
"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, "
"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast."
msgid "Processing"
msgstr "Weiter"
msgid "Enter your credit card number"
msgstr "Deine Kreditkartennummer"
#, python-format
msgid ""
"By clicking \"Place order\" this plan will charge your credit card account "
"with the fee of %(vm_price)sCHF/month"
msgstr ""
"Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit %(vm_price)sCHF "
"pro Monat belastet"
msgid "Place order" msgid "Place order"
msgstr "Bestellen" msgstr "Bestellen"
msgid "We are cutting down the costs significantly!"
msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen"
msgid "Order Now!"
msgstr "Bestelle jetzt!"
msgid ""
"Our VMs are hosted in Glarus, Switzerland, and our website is currently "
"running in BETA mode. If you want more information that you did not find on "
"our website, or if your order is more detailed, or if you encounter any "
"technical hiccups, please contact us at support@datacenterlight.ch, our team "
"will get in touch with you asap."
msgstr ""
"Unsere VMs werden in der Schweiz im Kanton Glarus gehostet und befinden sich "
"zur Zeit noch in der BETA-Phase. Möchtest du mehr über uns erfahren und hast "
"auf unserer Website nicht genügend Informationen gefunden? Möchtest eine "
"detailliertere Bestellung aufgeben? Bist du auf technische Probleme "
"gestossen, die du uns mitteilen möchtest? Dann zögere nicht und kontaktiere "
"uns unter support@datacenterlight.ch. Unser Team wird sich umgehend um dein "
"Anliegen kümmern!"
msgid "Thank you for order! Our team will contact you via email" msgid "Thank you for order! Our team will contact you via email"
msgstr "" msgstr ""
"Vielen Dank für die Bestellung. Unser Team setzt sich sobald wie möglich mit " "Vielen Dank für die Bestellung. Unser Team setzt sich sobald wie möglich mit "
"Ihnen via E-Mail in Verbindung." "Dir via E-Mail in Verbindung."
msgid "as soon as possible!" msgid "as soon as possible!"
msgstr "" msgstr ""
@ -322,7 +429,7 @@ msgstr ""
"nicht Open-Source ist.<br/>Yep, so cool sind wir." "nicht Open-Source ist.<br/>Yep, so cool sind wir."
msgid "Our services run on" msgid "Our services run on"
msgstr "Unsere Dienste läuft auf" msgstr "Unsere Dienste läufen auf"
msgid "Our monitoring" msgid "Our monitoring"
msgstr "Unser Monitoring" msgstr "Unser Monitoring"
@ -393,11 +500,113 @@ msgstr "Ungültige RAM-Grösse"
msgid "Invalid storage size" msgid "Invalid storage size"
msgstr "Ungültige Speicher-Grösse" msgstr "Ungültige Speicher-Grösse"
msgid "is not a proper name" msgid "Confirm Order"
msgstr "ist kein gültiger Name" msgstr "Bestellung Bestätigen"
msgid "is not a proper email" msgid "Error."
msgstr "ist keine gültige E-Mailadresse" msgstr ""
msgid ""
"There was a payment related error. On close of this popup, you will be "
"redirected back to the payment page."
msgstr ""
"Es ist ein Fehler bei der Zahlung betreten. Du wirst nach dem Schliessen vom "
"Popup zur Bezahlseite weitergeleitet."
msgid "Thank you for the order."
msgstr "Danke für Deine Bestellung."
msgid ""
"Your VM will be up and running in a few moments. We will send you a "
"confirmation email as soon as it is ready."
msgstr ""
"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
"auf sie zugreifen kannst."
#~ msgid "Affordable VM hosting based in Switzerland"
#~ msgstr "Bezahlbares VM Hosting in der Schweiz"
#~ msgid "Processing..."
#~ msgstr "Abarbeitung..."
#~ msgid "Hold tight, we are processing your request"
#~ msgstr "Bitte warten - wir verbeiten Deine Anfrage gerade"
#~ msgid "Some problem encountered. Please try again later."
#~ msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
#~ msgid "Submit"
#~ msgstr "Absenden"
#~ msgid "Date"
#~ msgstr "Datum"
#~ msgid "Billed To:"
#~ msgstr "Rechnungsadresse"
#~ msgid "Payment Method:"
#~ msgstr "Bezahlmethode"
#~ msgid "ending in"
#~ msgstr "endend in"
#~ msgid "Order summary"
#~ msgstr "Bestellungsübersicht"
#~ msgid "We are cutting down the costs significantly!"
#~ msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen"
#~ msgid "Order Now!"
#~ msgstr "Bestelle jetzt!"
#~ msgid ""
#~ "Our VMs are hosted in Glarus, Switzerland, and our website is currently "
#~ "running in BETA mode. If you want more information that you did not find "
#~ "on our website, or if your order is more detailed, or if you encounter "
#~ "any technical hiccups, please contact us at support@datacenterlight.ch, "
#~ "our team will get in touch with you asap."
#~ msgstr ""
#~ "Unsere VMs werden in der Schweiz im Kanton Glarus gehostet und befinden "
#~ "sich zur Zeit noch in der BETA-Phase. Möchtest du mehr über uns erfahren "
#~ "und hast auf unserer Website nicht genügend Informationen gefunden? "
#~ "Möchtest eine detailliertere Bestellung aufgeben? Bist du auf technische "
#~ "Probleme gestossen, die du uns mitteilen möchtest? Dann zögere nicht und "
#~ "kontaktiere uns unter support@datacenterlight.ch. Unser Team wird sich "
#~ "umgehend um dein Anliegen kümmern!"
#~ msgid "is not a proper name"
#~ msgstr "ist kein gültiger Name"
#~ msgid "is not a proper email"
#~ msgstr "ist keine gültige E-Mailadresse"
#~ msgid "Your Name"
#~ msgstr "Dein Name"
#~ msgid "Your Email"
#~ msgstr "Deine E-Mail"
#~ 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"
#~ msgid "Your"
#~ msgstr "Dein"
#~ msgid "team"
#~ msgstr "Team"
#~ msgid "Questions?"
#~ msgstr "Fragen?"
#~ msgid "Please enter a value greater than or equal to 1." #~ msgid "Please enter a value greater than or equal to 1."
#~ msgstr "Bitte gib einen Wert größer oder gleich 1 ein." #~ msgstr "Bitte gib einen Wert größer oder gleich 1 ein."
@ -464,9 +673,6 @@ msgstr "ist keine gültige E-Mailadresse"
#~ msgid "Buy Now!" #~ msgid "Buy Now!"
#~ msgstr "Kaufe jetzt!" #~ msgstr "Kaufe jetzt!"
#~ msgid "Email address"
#~ msgstr "E-Mail Adresse"
#~ msgid "Our promise" #~ msgid "Our promise"
#~ msgstr "Unser Versprechen" #~ msgstr "Unser Versprechen"

View file

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-08-19 21:08
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('datacenterlight', '0006_vmtemplate'),
]
operations = [
migrations.CreateModel(
name='ContactUs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=250)),
('email', models.CharField(max_length=250)),
('message', models.TextField()),
],
),
]

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-08-16 19:47
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('datacenterlight', '0006_vmtemplate'),
]
operations = [
migrations.CreateModel(
name='StripePlan',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('stripe_plan_id', models.CharField(max_length=100, null=True)),
],
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-08-21 20:24
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('datacenterlight', '0007_stripeplan'),
]
operations = [
migrations.AlterField(
model_name='stripeplan',
name='stripe_plan_id',
field=models.CharField(max_length=256, null=True),
),
]

View file

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-08-23 13:06
from __future__ import unicode_literals
import datetime
from django.db import migrations, models
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
('datacenterlight', '0007_contactus'),
]
operations = [
migrations.AddField(
model_name='contactus',
name='field',
field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2017, 8, 23, 13, 6, 24, 650869, tzinfo=utc)),
preserve_default=False,
),
]

View file

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-08-27 07:55
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('datacenterlight', '0007_contactus'),
('datacenterlight', '0008_auto_20170821_2024'),
]
operations = [
]

View file

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-08-27 08:02
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('datacenterlight', '0009_merge'),
('datacenterlight', '0008_contactus_field'),
]
operations = [
]

View file

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-02-20 14:23
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('datacenterlight', '0010_merge'),
]
operations = [
migrations.RemoveField(
model_name='betaaccessvm',
name='access',
),
migrations.RemoveField(
model_name='betaaccessvm',
name='type',
),
migrations.DeleteModel(
name='BetaAccess',
),
migrations.DeleteModel(
name='BetaAccessVM',
),
migrations.DeleteModel(
name='BetaAccessVMType',
),
]

View file

@ -1,61 +1,31 @@
from django.db import models from django.db import models
class BetaAccessVMType(models.Model):
ssd = models.IntegerField()
ram = models.IntegerField()
cpu = models.IntegerField()
price = models.FloatField()
def __str__(self):
return "ID: %s - SSD %s - RAM %s - CPU %s - Price %s " % \
(self.id, str(self.ssd), self.ram, self.cpu, self.price)
class BetaAccess(models.Model):
email = models.CharField(max_length=250)
name = models.CharField(max_length=250)
# vm = models.ForeignKey(BetaAccessVM)
def __str__(self):
vms = self.betaaccessvm_set.all()
rep = "Email: %s " % self.email
for vm in vms:
rep += "(vm:%s - amount:%s) - " % (vm.type.id, vm.amount)
return rep
class BetaAccessVM(models.Model):
type = models.ForeignKey(BetaAccessVMType)
access = models.ForeignKey(BetaAccess)
amount = models.IntegerField()
@classmethod
def create(cls, data):
VM_KEY_ID = 0
VM_AMOUNT = 1
ZERO = 0
email = data.get('email')
beta_access = BetaAccess.objects.create(email=email)
vm_data = [(key, value) for key, value in data.items() if 'vm' in key]
created_vms = []
for vm in vm_data:
if int(vm[VM_AMOUNT]) == ZERO:
continue
vm_id = vm[VM_KEY_ID].split('-').pop()
vm_type = BetaAccessVMType.objects.get(id=vm_id)
created_vms.append(cls.objects.create(access=beta_access,
amount=vm[VM_AMOUNT], type=vm_type))
return created_vms
class VMTemplate(models.Model): class VMTemplate(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
opennebula_vm_template_id = models.IntegerField() opennebula_vm_template_id = models.IntegerField()
@classmethod @classmethod
def create(cls, name, opennebula_vm_template_id): def create(cls, name, opennebula_vm_template_id):
vm_template = cls(name=name, opennebula_vm_template_id=opennebula_vm_template_id) vm_template = cls(
name=name, opennebula_vm_template_id=opennebula_vm_template_id)
return vm_template return vm_template
class StripePlan(models.Model):
"""
A model to store Data Center Light's created Stripe plans
"""
stripe_plan_id = models.CharField(max_length=256, null=True)
@classmethod
def create(cls, stripe_plan_id):
stripe_plan = cls(stripe_plan_id=stripe_plan_id)
return stripe_plan
class ContactUs(models.Model):
name = models.CharField(max_length=250)
email = models.CharField(max_length=250)
message = models.TextField()
field = models.DateTimeField(auto_now_add=True)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,51 @@
.dcl-cms_page-full-width {
color: #fff;
text-align: center;
background-image: -ms-linear-gradient(right, #29427A 50%, #4F6699 100%);
background-image: -moz-linear-gradient(right, #29427A 50%, #4F6699 100%);
background-image: -o-linear-gradient(right, #29427A 50%, #4F6699 100%);
background-image: -webkit-gradient(linear, right top, left top, color-stop(50, #29427A), color-stop(100, #4F6699));
background-image: -webkit-linear-gradient(right, #29427A 50%, #4F6699 100%);
background-image: linear-gradient(to left, #29427A 50%, #4F6699 100%);
}
.dcl-cms_page-header {
padding: 150px 0 150px 0;
text-align: center;
color: #f8f8f8;
background: url(../img/pattern.jpg) no-repeat center center;
background-size: cover;
position: relative;
background-attachment: fixed;
}
.dcl-cms_page-header::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(90, 116, 175, 0.85);
}
.dcl-cms_page-header .container {
position: relative;
}
#dcl-cms_page-text {
background: #fff;
}
#dcl-cms_page-text h3 {
font-size: 42px;
width: 70%;
}
@media (max-width: 767px) {
#dcl-cms_page-text h3 {
font-size: 30px;
line-height: 40px;
width: 100%;
}
}

View file

@ -0,0 +1,98 @@
body,
html {
width: 100%;
min-height: 100%;
}
body,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Lato', sans-serif;
}
/* bootstrap danger color override from #a94442 */
.text-danger,
.has-error .help-block,
.has-error .control-label,
.has-error .radio,
.has-error .checkbox,
.has-error .radio-inline,
.has-error .checkbox-inline,
.has-error.radio label,
.has-error.checkbox label,
.has-error.radio-inline label,
.has-error.checkbox-inline label,
.has-error .form-control-feedback,
.alert-danger,
.list-group-item-danger,
a.list-group-item-danger,
a.list-group-item-danger:hover,
a.list-group-item-danger:focus,
.panel-danger>.panel-heading {
color: #eb4d5c;
}
.alert-danger {
background: rgba(235, 204, 209, 0.2);
}
.has-error .form-control,
.has-error .form-control:focus,
.has-error .form-control:active,
.has-error .input-group-addon {
color: #eb4d5c;
border-color: #eb4d5c;
}
a.list-group-item-danger.active,
a.list-group-item-danger.active:hover,
a.list-group-item-danger.active:focus {
background-color: #eb4d5c;
border-color: #eb4d5c;
}
.panel-danger>.panel-heading .badge {
background-color: #eb4d5c;
}
.topnav {
font-size: 14px;
}
.navbar-default {
background: #fff;
padding: 5px;
}
.navbar-brand {
padding: 10px;
}
@media (min-width: 768px) {
.navbar-right {
margin-right: 10px;
}
.navbar-brand {
padding-right: 15px;
padding-left: 15px;
}
}
p.copyright {
margin: 15px 0 0;
}
footer {
padding: 20px 0;
background-color: #f8f8f8;
}
footer a {
color: #777;
}

View file

@ -0,0 +1,591 @@
.topnav .navbar-fixed-top .navbar-collapse {
max-height: 740px;
}
.navbar-default .navbar-header {
position: relative;
z-index: 1;
}
.navbar-right .highlights-dropdown .dropdown-menu {
left: 0 !important;
min-width: 155px;
margin-left: 15px;
padding: 0 5px 8px !important;
}
@media(min-width: 768px) {
.navbar-default .navbar-nav>li>a,
.navbar-right .highlights-dropdown .dropdown-menu>li>a {
font-weight: 300;
}
.navbar-right .highlights-dropdown .dropdown-menu {
border-width: 0 0 1px 0;
border-color: #e7e7e7;
box-shadow: -8px 14px 20px -5px rgba(77, 77, 77, 0.5);
}
}
.navbar-right .highlights-dropdown .dropdown-menu>li>a {
font-size: 13px;
font-family: 'Lato', sans-serif;
padding: 1px 10px 1px 18px !important;
background: transparent;
color: #333;
}
.navbar-right .highlights-dropdown .dropdown-menu>li>a:hover,
.navbar-right .highlights-dropdown .dropdown-menu>li>a:focus,
.navbar-right .highlights-dropdown .dropdown-menu>li>a:active {
background: transparent;
text-decoration: underline !important;
}
.un-icon {
width: 15px;
height: 15px;
opacity: 0.5;
margin-top: -1px;
}
/***** DCL payment page **********/
.dcl-order-container {
font-weight: 300;
}
.dcl-place-order-text {
color: #808080;
}
.card-warning-content {
font-weight: 300;
border: 1px solid #a1a1a1;
border-radius: 3px;
padding: 5px;
margin-bottom: 15px;
}
.card-warning-error {
border: 1px solid #EB4D5C;
color: #EB4D5C;
}
.card-warning-addtional-margin {
margin-top: 15px;
}
.card-cvc-element label {
padding-left: 10px;
}
.card-element {
margin-bottom: 10px;
}
.card-element label {
width: 100%;
margin-bottom: 0px;
}
.my-input {
border-bottom: 1px solid #ccc;
}
.card-cvc-element .my-input {
padding-left: 10px;
}
#card-errors {
clear: both;
padding: 0 0 10px;
color: #eb4d5c;
}
.credit-card-goup {
padding: 0;
}
@media (max-width: 767px) {
.card-expiry-element {
padding-right: 10px;
}
.card-cvc-element {
padding-left: 10px;
}
#billing-form .form-control {
box-shadow: none !important;
font-weight: 400;
}
}
@media (min-width: 1200px) {
.dcl-order-container {
width: 990px;
padding: 0 15px;
margin: 0 auto;
}
}
.footer-vm p.copyright {
margin-top: 4px;
}
.navbar-default .navbar-nav>.open>a,
.navbar-default .navbar-nav>.open>a:focus,
.navbar-default .navbar-nav>.open>a:hover,
.navbar-default .navbar-nav>.active>a,
.navbar-default .navbar-nav>.active>a:focus,
.navbar-default .navbar-nav>.active>a:hover {
background-color: transparent;
}
@media (max-width: 767px) {
.navbar-default .navbar-nav .open .dropdown-menu>.active>a,
.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,
.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover {
background-color: transparent;
}
}
/* bootstrap input box-shadow disable */
.has-error .form-control:focus,
.has-error .form-control:active,
.has-success .form-control:focus,
.has-success .form-control:active {
box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.25);
}
.content-dashboard {
min-height: calc(100vh - 60px);
width: 100%;
margin: 0 auto;
max-width: 1120px;
}
@media (max-width: 767px) {
.content-dashboard {
padding: 0 15px;
}
}
@media (max-width: 575px) {
select {
width: 280px;
}
}
.btn:focus,
.btn:active:focus {
outline: 0;
}
/***********Styles for Model********************/
.modal-content {
border-radius: 0px;
font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 100%;
float: left;
border-radius: 0;
font-weight: 300;
}
.modal-header {
min-height: 30px;
border-bottom: 0px solid #e5e5e5;
padding: 0px 15px;
width: 100%;
}
.modal-header .close {
font-size: 75px;
font-weight: 300;
margin-top: 0;
position: absolute;
top: 0;
right: 11px;
z-index: 10;
line-height: 60px;
}
.modal-header .close span {
display: block;
}
.modal-header .close:focus {
outline: 0;
}
.modal-body {
text-align: center;
width: 100%;
float: left;
padding: 0px 30px 15px 30px;
}
.modal-body .modal-icon i {
font-size: 80px;
font-weight: 100;
color: #999;
}
.modal-body .modal-icon {
margin-bottom: 15px;
}
.modal-title {
margin: 0;
line-height: 1.42857143;
font-size: 25px;
padding: 0;
font-weight: 300;
}
.modal-text {
padding-top: 5px;
font-size: 16px;
}
.modal-text p:not(:last-of-type) {
margin-bottom: 5px;
}
.modal-title+.modal-footer {
margin-top: 5px;
}
.modal-footer {
border-top: 0px solid #e5e5e5;
width: 100%;
float: left;
text-align: center;
padding: 15px 15px;
}
.modal {
text-align: center;
}
.modal-dialog {
display: inline-block;
text-align: left;
vertical-align: middle;
width: 40%;
margin: 15px auto;
}
@media (min-width: 768px) and (max-width: 991px) {
.modal-dialog {
width: 50%;
}
}
@media (max-width: 767px) {
.modal-dialog {
width: 95%;
}
}
@media(min-width: 576px) {
.modal:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -4px;
}
}
/* ========= */
.btn-wide {
min-width: 100px;
}
.choice-btn {
min-width: 110px;
background-color: #3C5480;
color: #fff;
border: 2px solid #3C5480;
padding: 4px 10px;
transition: 0.3s all ease-out;
}
.choice-btn:focus,
.choice-btn:hover,
.choice-btn:active {
color: #3C5480;
background-color: #fff;
}
@media (max-width: 767px) {
.choice-btn {
margin-top: 15px;
}
}
.payment-container {
padding-top: 70px;
padding-bottom: 11%;
}
.last-p {
margin-bottom: 0;
}
.dcl-payment-section {
max-width: 391px;
margin: 0 auto 30px;
padding: 0 10px 30px;
border-bottom: 1px solid #edebeb;
height: 100%;
}
.dcl-payment-section hr {
margin-top: 15px;
margin-bottom: 15px;
}
.dcl-payment-section .top-hr {
margin-left: -10px;
}
.dcl-payment-section h3 {
font-weight: 600;
}
.dcl-payment-section p {
font-weight: 400;
}
.dcl-payment-section .card-warning-content {
padding: 8px 10px;
font-weight: 300;
}
.dcl-payment-order strong {
font-size: 17px;
}
.dcl-payment-order p {
font-weight: 300;
}
.dcl-payment-section .form-group {
margin-bottom: 10px;
}
.dcl-payment-section .form-control {
box-shadow: none;
padding: 6px 12px;
height: 32px;
}
.dcl-payment-user {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.dcl-payment-user h4 {
font-weight: 600;
font-size: 17px;
}
@media (min-width: 768px) {
.dcl-payment-grid {
display: flex;
align-items: stretch;
flex-wrap: wrap;
}
.dcl-payment-box {
width: 50%;
position: relative;
padding: 0 30px;
}
.dcl-payment-box:nth-child(2) {
order: 1;
}
.dcl-payment-box:nth-child(4) {
order: 2;
}
.dcl-payment-section {
padding-top: 15px;
padding-bottom: 15px;
margin-bottom: 0;
border-bottom-width: 5px;
}
.dcl-payment-box:nth-child(2n) .dcl-payment-section {
border-bottom: none;
}
.dcl-payment-box:nth-child(1):after,
.dcl-payment-box:nth-child(2):after {
content: ' ';
display: block;
background: #eee;
width: 1px;
position: absolute;
right: 0;
z-index: 2;
top: 20px;
bottom: 20px;
}
}
#virtual_machine_create_form {
padding: 15px 0;
}
.btn-vm-contact {
color: #fff;
background: #A3C0E2;
border: 2px solid #A3C0E2;
padding: 5px 25px;
font-size: 12px;
letter-spacing: 1.3px;
}
.btn-vm-contact:hover,
.btn-vm-contact:focus {
background: #fff;
color: #a3c0e2;
}
/* hosting-order */
.order-detail-container {
max-width: 600px;
margin: 100px auto 40px;
border: 1px solid #ccc;
padding: 30px 30px 20px;
}
.order-detail-container .dashboard-title-thin {
margin-top: 0;
margin-left: -3px;
}
.order-detail-container .dashboard-title-thin .un-icon {
margin-top: -6px;
}
.order-detail-container .dashboard-container-head {
position: relative;
padding: 0;
margin-bottom: 38px;
}
.order-detail-container .order-details {
margin-bottom: 15px;
}
.order-detail-container .order-details strong {
color: #595959;
}
.order-detail-container h4 {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
}
.order-detail-container p {
margin-bottom: 5px;
color: #595959;
}
.order-detail-container hr {
margin: 15px 0;
}
@media (max-width: 767px) {
.order-detail-container {
padding: 15px;
}
.order-confirm-btn {
text-align: center;
margin-top: 10px;
}
.order-detail-container .dashboard-container-options {
position: absolute;
top: 4px;
right: -4px;
}
.order-detail-container .dashboard-container-options .svg-img {
height: 16px;
width: 16px;
}
}
.order_detail_footer {
font-size: 9px;
letter-spacing: 1px;
color: #333333;
}
.order_detail_footer strong {
font-size: 11px;
}
.dashboard-title-thin {
font-weight: 300;
font-size: 32px;
}
.dashboard-title-thin .un-icon {
height: 34px;
margin-right: 5px;
margin-top: -2px;
width: 34px;
vertical-align: middle;
}
@media (max-width:767px) {
.dashboard-title-thin {
font-size: 22px;
}
.dashboard-title-thin .un-icon {
height: 22px;
width: 22px;
margin-top: -3px;
}
}
.locale_date {
opacity: 0;
}
.locale_date.done {
opacity: 1;
}
.btn-vm-back {
color: #fff;
background: #C4CEDA;
border: 2px solid #C4CEDA;
padding: 5px 25px;
font-size: 12px;
letter-spacing: 1.3px;
}
.btn-vm-back:hover,
.btn-vm-back:focus {
color: #fff;
background: #8da4c0;
border-color: #8da4c0;
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -1,92 +0,0 @@
Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato"
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="57px" height="66px" viewBox="0 0 57 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
<title>Slice 20</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="contact-us" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<ellipse id="Oval-2" fill="#FFFFFF" cx="28.7865939" cy="33.4691264" rx="19.7865939" ry="19.4691264"></ellipse>
<path d="M35.3784886,34.6387051 L30.2336176,34.6387051 L30.2336176,50.2467762 L22.6226844,50.2467762 L22.6226844,34.6387051 L19,34.6387051 L19,29.1194625 L22.6226844,29.1194625 L22.6226844,25.5403791 C22.6226844,22.9849851 24.0459888,19 30.3115248,19 L35.9567996,19.0178699 L35.9567996,24.3762836 L31.8546864,24.3762836 C31.1894789,24.3762836 30.2426069,24.6596489 30.2426069,25.8824599 L30.2426069,29.1194625 L36.0436961,29.1194625 L35.3784886,34.6387051 Z" id="Shape" fill="#5E79AD" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -1,55 +0,0 @@
(function($){
'use strict'; // Start of use strict
$(document).ready(function(){
verifiedUrl();
init_options_interested();
init_nav();
change_values();
});
function verifiedUrl(){
if(window.location.href.indexOf('#success') > -1){
form_success();
}
}
function init_options_interested(){
$('.row-vms').click(function(){
$('.row-vms').removeClass('row-vms__active');
$(this).addClass('row-vms__active');
var number = $('.row-vms__active input').val();
var price = $('.row-vms__active input').data('price');
_calculate(number, price);
});
}
function init_nav(){
$('.nav-local').click(function(){
$('html, body').animate({
scrollTop: $('#'+$(this).data('href')).offset().top
});
});
}
function change_values(){
$('.number-vms').keyup(function () {
var number = $(this).val();
var price = $(this).data('price');
_calculate(number, price);
});
}
function form_success(){
$('#sucessModal').modal('show');
}
function _calculate(numbers, price){
$('#valueTotal').text(numbers*price*31);
}
})(jQuery); // End of use strict

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -16,7 +16,7 @@
'ram': { 'ram': {
'id': 'ramValue', 'id': 'ramValue',
'value': 2, 'value': 2,
'min': 2, 'min': 1,
'max': 200, 'max': 200,
'interval': 1 'interval': 1
}, },
@ -39,7 +39,7 @@
_initScroll(); _initScroll();
_initNavUrl(); _initNavUrl();
_initPricing(); _initPricing();
ajaxForms();
}); });
$(window).resize(function() { $(window).resize(function() {
@ -85,18 +85,32 @@
} }
} }
_navScroll();
function _initNavUrl() { function _initNavUrl() {
$('.url-init').each(function(idx, el) {
var $this = $(el);
var currentPath = window.location.pathname;
var thisPaths = $this.attr('href').split('#')
if ($this.hasClass('dropdown-toggle') && window.matchMedia("(max-width: 767px)").matches) {
$this.removeClass('url-init');
$this.attr('href', '');
} else if ($('#'+thisPaths[1]).length) {
$this.removeClass('url-init').addClass('url');
$this.attr('href', '#' + thisPaths[1]);
} else {
$this.removeClass('url-init');
}
});
$('.url').click(function(event) { $('.url').click(function(event) {
event.preventDefault(); event.preventDefault();
var href = $(this).attr('data-url'); var href = $(this).attr('href');
$('.navbar-collapse').removeClass('in'); $('.navbar-collapse').removeClass('in');
$('.navbar-collapse').addClass('collapsing'); $('.navbar-collapse').addClass('collapsing');
if ($(href).length) { if ($(href).length) {
$('html, body').animate({ $('html, body').animate({
scrollTop: $(href).offset().top scrollTop: $(href).offset().top - 50
}, 1000); }, 1000);
} else {
window.location.href = '/datacenterlight' + href;
} }
}); });
} }
@ -135,7 +149,6 @@
function _fetchPricing() { function _fetchPricing() {
Object.keys(cardPricing).map(function(element) { Object.keys(cardPricing).map(function(element) {
//$('#'+cardPricing[element].id).val(cardPricing[element].value);
$('input[name=' + element + ']').val(cardPricing[element].value); $('input[name=' + element + ']').val(cardPricing[element].value);
}); });
_calcPricing(); _calcPricing();
@ -144,9 +157,7 @@
function _calcPricing() { function _calcPricing() {
var total = (cardPricing['cpu'].value * 5) + (2 * cardPricing['ram'].value) + (0.6 * cardPricing['storage'].value); var total = (cardPricing['cpu'].value * 5) + (2 * cardPricing['ram'].value) + (0.6 * cardPricing['storage'].value);
total = parseFloat(total.toFixed(2)); total = parseFloat(total.toFixed(2));
$("#total").text(total); $("#total").text(total);
$('input[name=total]').val(total);
} }
function form_success() { function form_success() {
@ -157,4 +168,27 @@
$('#valueTotal').text(numbers * price * 31); $('#valueTotal').text(numbers * price * 31);
} }
function ajaxForms() {
$('body').on('submit', '.ajax-form', function(e){
e.preventDefault();
var $form = $(this);
$form.find('[type=submit]').addClass('sending');
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: $form.serialize(),
success: function(response) {
var responseContain = $($form.attr('data-response'));
responseContain.html(response);
$form.find('[type=submit]').removeClass('sending');
},
error: function() {
$form.find('[type=submit]').removeClass('sending');
$form.find('.form-error').removeClass('hide');
}
});
})
}
})(jQuery); })(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,181 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="156.5px" height="40px" viewBox="0 0 156.5 40" enable-background="new 0 0 156.5 40" xml:space="preserve">
<g display="none">
<g display="inline">
<path fill="#231916" d="M32.599,25.896c0-0.429,0.15-0.845,0.453-1.25c0.303-0.408,0.734-0.773,1.296-1.097v-0.092
c-0.294-0.16-0.554-0.388-0.777-0.674c-0.22-0.289-0.332-0.662-0.332-1.119c0-0.354,0.115-0.712,0.345-1.076
c0.227-0.36,0.55-0.683,0.964-0.962v-0.09c-0.386-0.28-0.711-0.654-0.978-1.12c-0.263-0.464-0.397-1.021-0.397-1.67
c0-0.606,0.118-1.149,0.354-1.63c0.236-0.48,0.555-0.889,0.954-1.229c0.398-0.34,0.86-0.598,1.385-0.775
c0.523-0.178,1.081-0.266,1.672-0.266c0.605,0,1.152,0.088,1.64,0.266h4.452v1.662h-2.702c0.222,0.237,0.42,0.528,0.598,0.875
c0.178,0.348,0.267,0.735,0.267,1.165c0,0.59-0.111,1.117-0.332,1.572c-0.222,0.459-0.525,0.846-0.91,1.163
c-0.384,0.318-0.834,0.558-1.351,0.72c-0.517,0.162-1.071,0.246-1.663,0.246c-0.265,0-0.55-0.031-0.854-0.091
c-0.302-0.058-0.601-0.147-0.896-0.267c-0.503,0.326-0.753,0.701-0.753,1.131c0,0.398,0.185,0.686,0.553,0.865
c0.369,0.176,0.901,0.266,1.596,0.266h2.303c1.42,0,2.47,0.203,3.159,0.607c0.687,0.406,1.029,1.076,1.029,2.006
c0,0.518-0.145,1.004-0.431,1.461c-0.29,0.459-0.699,0.861-1.23,1.209c-0.531,0.348-1.174,0.621-1.929,0.82
c-0.751,0.199-1.594,0.299-2.525,0.299c-1.537,0-2.747-0.25-3.633-0.744C33.042,27.586,32.599,26.857,32.599,25.896z
M34.458,25.633c0,0.516,0.285,0.932,0.854,1.25s1.393,0.477,2.47,0.477c0.577,0,1.097-0.055,1.562-0.166
c0.465-0.11,0.864-0.258,1.197-0.442s0.585-0.396,0.764-0.631c0.177-0.234,0.266-0.486,0.266-0.754
c0-0.474-0.196-0.785-0.587-0.941c-0.392-0.153-0.979-0.231-1.762-0.231h-1.905c-0.34,0-0.641-0.012-0.907-0.033
c-0.268-0.021-0.519-0.07-0.754-0.145c-0.444,0.25-0.753,0.51-0.932,0.776C34.549,25.057,34.458,25.334,34.458,25.633z
M37.539,19.095c0.621,0,1.152-0.206,1.597-0.62c0.442-0.414,0.665-0.989,0.665-1.727c0-0.71-0.223-1.279-0.665-1.707
c-0.445-0.428-0.976-0.643-1.597-0.643s-1.152,0.215-1.595,0.643c-0.442,0.428-0.665,0.997-0.665,1.707
c0,0.738,0.223,1.313,0.665,1.727C36.386,18.889,36.918,19.095,37.539,19.095z"/>
</g>
<path display="inline" fill="#231916" d="M15.983,24.24h-1.857l-0.183-1.854h-0.092c-0.551,0.642-1.151,1.154-1.8,1.548
c-0.649,0.387-1.401,0.582-2.258,0.582c-1.329,0-2.3-0.384-2.91-1.156c-0.612-0.771-0.917-1.898-0.917-3.381V14.35L3,14.293
l5.258-2.023l-0.023,1.529v5.882c0,0.994,0.176,1.724,0.528,2.189c0.351,0.467,0.954,0.7,1.811,0.7
c0.581,0,1.111-0.143,1.593-0.426c0.48-0.283,0.998-0.762,1.547-1.433v-7.678h2.269V24.24z"/>
<path display="inline" fill="#231916" d="M19.742,13.033h1.856l0.184,1.812h0.091c0.565-0.582,1.176-1.075,1.834-1.479
c0.655-0.405,1.42-0.607,2.292-0.607c1.313,0,2.278,0.39,2.888,1.168c0.611,0.778,0.917,1.903,0.917,3.37v6.942h-2.271v-6.646
c0-0.976-0.174-1.7-0.525-2.165c-0.352-0.467-0.955-0.701-1.811-0.701c-0.597,0-1.131,0.151-1.605,0.447
c-0.473,0.299-1.002,0.744-1.582,1.343v7.721h-2.268V13.033z"/>
<path display="inline" fill="#231916" d="M55.129,18.65c0-0.917,0.162-1.74,0.482-2.465c0.321-0.725,0.748-1.345,1.284-1.856
c0.533-0.511,1.146-0.902,1.834-1.17c0.687-0.267,1.398-0.4,2.13-0.4c0.826,0,1.555,0.13,2.19,0.39
c0.633,0.26,1.172,0.621,1.615,1.086c0.443,0.468,0.779,1.025,1.01,1.676c0.229,0.648,0.344,1.362,0.344,2.142
c0,0.229-0.012,0.447-0.035,0.652c-0.022,0.208-0.049,0.38-0.08,0.516h-8.436c0.077,1.1,0.485,1.96,1.229,2.58
c0.739,0.619,1.675,0.928,2.807,0.928c0.611,0,1.18-0.084,1.708-0.252c0.527-0.166,1.042-0.403,1.546-0.709l0.802,1.443
c-0.578,0.367-1.23,0.676-1.959,0.928c-0.726,0.252-1.525,0.377-2.396,0.377c-0.842,0-1.631-0.131-2.371-0.399
c-0.742-0.267-1.387-0.65-1.938-1.156c-0.551-0.504-0.982-1.119-1.296-1.846C55.286,20.386,55.129,19.566,55.129,18.65z
M63.909,17.665c0-1.01-0.263-1.781-0.779-2.317c-0.521-0.534-1.262-0.8-2.225-0.8c-0.84,0-1.587,0.266-2.245,0.8
c-0.658,0.536-1.062,1.307-1.214,2.317H63.909z"/>
<path display="inline" fill="#231916" d="M73.475,12.679l0.008,11.793h-2.27v-8.611h-4.256L73.475,12.679z M72.152,10.368
c-0.488,0-0.894-0.146-1.215-0.435c-0.32-0.291-0.48-0.681-0.48-1.17c0-0.489,0.16-0.882,0.48-1.18
c0.321-0.298,0.727-0.446,1.215-0.446s0.896,0.148,1.215,0.446c0.32,0.298,0.482,0.691,0.482,1.18c0,0.489-0.162,0.879-0.482,1.17
C73.049,10.221,72.641,10.368,72.152,10.368z"/>
<path display="inline" fill="#231916" d="M76.629,18.878c0-0.932,0.168-1.766,0.504-2.497c0.336-0.735,0.795-1.353,1.375-1.859
c0.582-0.503,1.25-0.884,2.008-1.145c0.756-0.26,1.562-0.389,2.416-0.389c0.918,0,1.719,0.156,2.406,0.469
c0.689,0.312,1.262,0.693,1.721,1.135l-1.1,1.443c-0.443-0.367-0.904-0.653-1.379-0.86c-0.471-0.206-0.984-0.309-1.535-0.309
c-0.594,0-1.143,0.095-1.65,0.287c-0.502,0.19-0.936,0.462-1.293,0.813c-0.358,0.352-0.639,0.776-0.838,1.272
c-0.197,0.495-0.297,1.042-0.297,1.638c0,0.595,0.096,1.144,0.287,1.64c0.189,0.496,0.465,0.92,0.824,1.273
c0.359,0.35,0.785,0.623,1.273,0.812c0.487,0.188,1.028,0.284,1.627,0.284c0.686,0,1.307-0.129,1.856-0.387
c0.549-0.263,1.043-0.574,1.488-0.94l0.965,1.467c-0.644,0.551-1.347,0.975-2.111,1.272c-0.764,0.298-1.559,0.445-2.383,0.445
c-0.871,0-1.687-0.129-2.44-0.39c-0.756-0.26-1.41-0.643-1.961-1.146c-0.55-0.506-0.98-1.121-1.293-1.847
C76.785,20.641,76.629,19.811,76.629,18.878z"/>
<path display="inline" fill="#231916" d="M87.4,8.285l4.752-2.356v6.601l-0.139,2.521c0.565-0.58,1.178-1.07,1.836-1.467
c0.655-0.396,1.42-0.595,2.293-0.595c1.312,0,2.274,0.389,2.885,1.168c0.611,0.78,0.918,1.903,0.918,3.371v6.945h-2.271v-6.648
c0-0.978-0.176-1.7-0.526-2.165c-0.353-0.466-0.953-0.7-1.812-0.7c-0.596,0-1.131,0.149-1.604,0.448
c-0.475,0.298-1.002,0.745-1.582,1.342v7.726h-2.27L89.836,8.189L87.4,8.285z"/>
<g display="inline">
<polygon fill="#010000" points="100.371,3.218 99.607,4.815 109.109,4.855 109.873,3.228 "/>
<polygon fill="#010000" points="99.619,6.703 98.83,8.378 108.346,8.397 109.109,6.74 "/>
<polygon fill="#010000" points="101.475,10.278 105.832,1 107.512,1.024 103.203,10.281 "/>
</g>
<g display="inline">
<path fill="#231916" d="M49.446,20.596c0,0.754,0.188,1.297,0.566,1.631c0.376,0.33,0.866,0.498,1.472,0.498
c0.295,0,0.599-0.037,0.909-0.111s0.658-0.193,1.042-0.355l0.532,1.643c-0.252,0.086-0.492,0.166-0.721,0.242
c-0.231,0.074-0.461,0.135-0.698,0.187c-0.237,0.055-0.483,0.098-0.741,0.135c-0.26,0.035-0.543,0.058-0.853,0.058
c-1.212,0-2.131-0.349-2.76-1.043c-0.627-0.693-0.941-1.697-0.941-3.014V5.711h-3.544l5.737-4.043"/>
</g>
</g>
<path fill="#29427A" d="M12.927,23.013v-1.46h-0.045c-0.359,0.569-0.873,1.007-1.539,1.313s-1.374,0.461-2.122,0.461
c-0.839,0-1.587-0.165-2.246-0.494c-0.659-0.329-1.216-0.768-1.673-1.313c-0.457-0.547-0.805-1.18-1.044-1.898
c-0.24-0.718-0.359-1.467-0.359-2.245s0.124-1.523,0.371-2.234s0.599-1.337,1.055-1.875c0.457-0.539,1.011-0.966,1.662-1.28
c0.651-0.314,1.381-0.472,2.189-0.472c0.823,0,1.52,0.157,2.089,0.472c0.568,0.314,1.011,0.659,1.325,1.033h0.045V6.035h3.683
v16.978H12.927z M12.792,17.398c0-0.359-0.064-0.711-0.191-1.056c-0.128-0.345-0.307-0.651-0.54-0.921
c-0.232-0.27-0.513-0.486-0.842-0.651c-0.329-0.164-0.704-0.247-1.123-0.247c-0.434,0-0.816,0.083-1.145,0.247
c-0.33,0.165-0.606,0.379-0.831,0.64c-0.225,0.263-0.393,0.565-0.505,0.91s-0.168,0.696-0.168,1.056
c0,0.358,0.056,0.715,0.168,1.066s0.281,0.663,0.505,0.932c0.225,0.27,0.501,0.487,0.831,0.651c0.329,0.165,0.711,0.247,1.145,0.247
c0.419,0,0.793-0.082,1.123-0.247c0.33-0.164,0.61-0.382,0.842-0.651c0.232-0.269,0.412-0.575,0.54-0.921
C12.728,18.109,12.792,17.758,12.792,17.398z"/>
<path fill="#29427A" d="M19.08,13.355c0.659-0.628,1.426-1.1,2.302-1.415s1.771-0.472,2.684-0.472c0.944,0,1.741,0.116,2.392,0.348
c0.651,0.232,1.179,0.591,1.583,1.078c0.404,0.486,0.7,1.101,0.887,1.842c0.187,0.74,0.281,1.62,0.281,2.639v5.637H25.84v-1.19
h-0.067c-0.285,0.464-0.715,0.823-1.291,1.078c-0.577,0.254-1.202,0.382-1.875,0.382c-0.449,0-0.913-0.061-1.393-0.18
c-0.479-0.12-0.917-0.314-1.313-0.584c-0.397-0.27-0.723-0.629-0.977-1.078c-0.255-0.449-0.382-1.003-0.382-1.662
c0-0.809,0.221-1.459,0.663-1.953s1.011-0.876,1.707-1.146c0.696-0.27,1.471-0.449,2.324-0.539s1.685-0.135,2.493-0.135v-0.18
c0-0.554-0.195-0.962-0.584-1.225c-0.389-0.262-0.868-0.393-1.437-0.393c-0.524,0-1.03,0.112-1.516,0.337
c-0.487,0.225-0.902,0.494-1.247,0.809L19.08,13.355z M25.84,18.139h-0.472c-0.404,0-0.812,0.02-1.224,0.057
c-0.412,0.037-0.779,0.108-1.101,0.213c-0.322,0.105-0.588,0.259-0.797,0.461c-0.21,0.202-0.314,0.468-0.314,0.797
c0,0.21,0.049,0.39,0.146,0.539c0.097,0.15,0.221,0.27,0.371,0.359c0.149,0.09,0.322,0.153,0.517,0.191
c0.194,0.037,0.382,0.056,0.562,0.056c0.749,0,1.321-0.205,1.718-0.617c0.396-0.412,0.595-0.97,0.595-1.673V18.139z"/>
<path fill="#29427A" d="M36.067,14.568v4.283c0,0.526,0.101,0.921,0.303,1.184c0.202,0.264,0.565,0.395,1.089,0.395
c0.18,0,0.371-0.015,0.573-0.045c0.202-0.029,0.371-0.074,0.505-0.135l0.045,2.695c-0.255,0.09-0.577,0.169-0.966,0.235
c-0.389,0.067-0.779,0.102-1.168,0.102c-0.749,0-1.377-0.094-1.886-0.281c-0.509-0.188-0.917-0.458-1.224-0.811
c-0.307-0.354-0.528-0.773-0.662-1.261c-0.135-0.488-0.202-1.032-0.202-1.633v-4.729h-1.797v-2.74h1.774V8.887h3.616v2.942h2.627
v2.74H36.067z"/>
<path fill="#29427A" d="M40.957,13.355c0.659-0.628,1.426-1.1,2.302-1.415s1.771-0.472,2.684-0.472c0.943,0,1.741,0.116,2.392,0.348
c0.651,0.232,1.179,0.591,1.583,1.078c0.404,0.486,0.7,1.101,0.887,1.842c0.188,0.74,0.281,1.62,0.281,2.639v5.637h-3.369v-1.19
h-0.067c-0.285,0.464-0.715,0.823-1.291,1.078c-0.577,0.254-1.202,0.382-1.875,0.382c-0.449,0-0.913-0.061-1.392-0.18
c-0.479-0.12-0.917-0.314-1.314-0.584c-0.397-0.27-0.723-0.629-0.977-1.078s-0.382-1.003-0.382-1.662
c0-0.809,0.221-1.459,0.663-1.953s1.011-0.876,1.707-1.146s1.471-0.449,2.324-0.539s1.685-0.135,2.493-0.135v-0.18
c0-0.554-0.195-0.962-0.584-1.225c-0.389-0.262-0.868-0.393-1.437-0.393c-0.524,0-1.03,0.112-1.516,0.337s-0.902,0.494-1.247,0.809
L40.957,13.355z M47.717,18.139h-0.471c-0.404,0-0.812,0.02-1.224,0.057c-0.412,0.037-0.779,0.108-1.101,0.213
c-0.322,0.105-0.587,0.259-0.797,0.461c-0.209,0.202-0.314,0.468-0.314,0.797c0,0.21,0.049,0.39,0.146,0.539
c0.097,0.15,0.22,0.27,0.37,0.359c0.149,0.09,0.322,0.153,0.517,0.191c0.194,0.037,0.382,0.056,0.562,0.056
c0.749,0,1.321-0.205,1.718-0.617c0.396-0.412,0.595-0.97,0.595-1.673V18.139z"/>
<path fill="#5A74AF" d="M61.874,15.197c-0.375-0.389-0.768-0.685-1.179-0.887c-0.412-0.202-0.902-0.304-1.471-0.304
c-0.554,0-1.037,0.102-1.449,0.304c-0.412,0.202-0.756,0.479-1.033,0.831s-0.487,0.756-0.629,1.212
c-0.142,0.457-0.213,0.933-0.213,1.427s0.082,0.962,0.247,1.403c0.165,0.441,0.396,0.827,0.696,1.156
c0.3,0.33,0.659,0.588,1.078,0.775c0.419,0.188,0.891,0.28,1.415,0.28c0.568,0,1.055-0.101,1.459-0.303s0.778-0.498,1.123-0.888
l1.438,1.438c-0.524,0.584-1.134,1.003-1.831,1.258c-0.696,0.254-1.434,0.382-2.212,0.382c-0.823,0-1.576-0.135-2.257-0.404
s-1.269-0.647-1.763-1.135c-0.494-0.485-0.876-1.07-1.146-1.751c-0.27-0.682-0.404-1.434-0.404-2.258
c0-0.822,0.135-1.579,0.404-2.268s0.647-1.28,1.134-1.774c0.486-0.494,1.07-0.879,1.751-1.156s1.441-0.416,2.279-0.416
c0.779,0,1.523,0.139,2.235,0.416c0.711,0.277,1.329,0.7,1.853,1.269L61.874,15.197z"/>
<path fill="#5A74AF" d="M66.612,18.432c0,0.464,0.101,0.887,0.304,1.269c0.201,0.382,0.467,0.707,0.797,0.977
c0.329,0.27,0.711,0.479,1.145,0.629c0.435,0.15,0.884,0.225,1.348,0.225c0.629,0,1.176-0.146,1.64-0.438
c0.464-0.292,0.891-0.678,1.28-1.157l1.527,1.168c-1.123,1.452-2.695,2.179-4.717,2.179c-0.838,0-1.598-0.143-2.279-0.427
s-1.258-0.678-1.729-1.179c-0.473-0.502-0.836-1.093-1.09-1.774s-0.382-1.418-0.382-2.212s0.139-1.531,0.416-2.213
c0.276-0.681,0.658-1.271,1.146-1.773c0.486-0.501,1.066-0.895,1.74-1.18c0.674-0.284,1.406-0.426,2.201-0.426
c0.942,0,1.74,0.165,2.391,0.494c0.652,0.33,1.187,0.76,1.605,1.292c0.42,0.531,0.723,1.13,0.91,1.796
c0.188,0.667,0.281,1.345,0.281,2.033v0.719H66.612z M72.99,16.814c-0.016-0.449-0.086-0.861-0.213-1.235
c-0.128-0.374-0.318-0.7-0.573-0.978c-0.255-0.276-0.573-0.493-0.954-0.65c-0.383-0.157-0.828-0.236-1.337-0.236
c-0.493,0-0.946,0.094-1.358,0.281s-0.76,0.43-1.044,0.729s-0.505,0.633-0.663,0.999c-0.156,0.367-0.235,0.73-0.235,1.09H72.99z"/>
<path fill="#5A74AF" d="M77.572,12.368h2.021v1.639h0.046c0.254-0.568,0.695-1.029,1.324-1.381s1.355-0.528,2.178-0.528
c0.51,0,1,0.079,1.472,0.236s0.883,0.4,1.235,0.73c0.352,0.329,0.633,0.752,0.842,1.269c0.209,0.516,0.314,1.126,0.314,1.83v6.85
h-2.021v-6.288c0-0.494-0.066-0.917-0.201-1.269c-0.135-0.353-0.314-0.637-0.539-0.854c-0.225-0.216-0.483-0.373-0.775-0.471
s-0.596-0.146-0.91-0.146c-0.418,0-0.808,0.067-1.167,0.202s-0.674,0.349-0.943,0.641c-0.27,0.291-0.479,0.662-0.629,1.111
s-0.225,0.98-0.225,1.595v5.479h-2.021V12.368z"/>
<path fill="#5A74AF" d="M95.762,14.119h-2.896v4.829c0,0.299,0.008,0.595,0.022,0.887s0.071,0.554,0.169,0.786
c0.097,0.232,0.246,0.419,0.449,0.561c0.201,0.144,0.497,0.214,0.887,0.214c0.239,0,0.486-0.022,0.741-0.067
s0.486-0.127,0.696-0.247v1.842c-0.24,0.135-0.551,0.229-0.932,0.28c-0.383,0.053-0.678,0.079-0.888,0.079
c-0.778,0-1.382-0.109-1.808-0.325c-0.427-0.218-0.741-0.498-0.943-0.843s-0.322-0.73-0.359-1.156
c-0.037-0.427-0.057-0.857-0.057-1.292v-5.547h-2.336v-1.751h2.336V9.381h2.021v2.987h2.896V14.119z"/>
<path fill="#5A74AF" d="M99.895,18.432c0,0.464,0.102,0.887,0.304,1.269s0.467,0.707,0.797,0.977
c0.329,0.27,0.711,0.479,1.146,0.629c0.434,0.15,0.883,0.225,1.348,0.225c0.628,0,1.175-0.146,1.639-0.438
c0.464-0.292,0.891-0.678,1.28-1.157l1.527,1.168c-1.123,1.452-2.695,2.179-4.716,2.179c-0.839,0-1.599-0.143-2.28-0.427
c-0.681-0.284-1.257-0.678-1.729-1.179c-0.471-0.502-0.834-1.093-1.088-1.774c-0.256-0.682-0.383-1.418-0.383-2.212
s0.139-1.531,0.416-2.213c0.276-0.681,0.658-1.271,1.145-1.773c0.487-0.501,1.067-0.895,1.741-1.18
c0.674-0.284,1.407-0.426,2.201-0.426c0.942,0,1.74,0.165,2.392,0.494c0.65,0.33,1.186,0.76,1.605,1.292
c0.419,0.531,0.723,1.13,0.909,1.796c0.188,0.667,0.281,1.345,0.281,2.033v0.719H99.895z M106.272,16.814
c-0.016-0.449-0.086-0.861-0.213-1.235c-0.128-0.374-0.318-0.7-0.573-0.978c-0.255-0.276-0.572-0.493-0.954-0.65
s-0.828-0.236-1.337-0.236c-0.493,0-0.946,0.094-1.358,0.281c-0.411,0.188-0.76,0.43-1.044,0.729
c-0.285,0.3-0.506,0.633-0.663,0.999c-0.157,0.367-0.235,0.73-0.235,1.09H106.272z"/>
<path fill="#5A74AF" d="M110.854,12.368h2.021v1.639h0.045c0.135-0.284,0.314-0.542,0.539-0.774
c0.225-0.232,0.475-0.431,0.752-0.595s0.58-0.295,0.909-0.393c0.33-0.097,0.659-0.146,0.988-0.146c0.33,0,0.629,0.045,0.899,0.135
l-0.091,2.178c-0.165-0.045-0.329-0.082-0.494-0.112c-0.165-0.029-0.329-0.045-0.493-0.045c-0.988,0-1.745,0.277-2.269,0.831
c-0.524,0.554-0.786,1.415-0.786,2.583v5.345h-2.021V12.368z"/>
<path fill="#5E6060" d="M120.156,5.513h1.368v11.493h-1.368V5.513z"/>
<path fill="#5E6060" d="M123.485,7.215c0-0.274,0.099-0.509,0.297-0.707c0.197-0.198,0.433-0.296,0.707-0.296
c0.273,0,0.509,0.099,0.707,0.296c0.197,0.198,0.296,0.433,0.296,0.707c0,0.273-0.099,0.509-0.296,0.707
c-0.198,0.198-0.434,0.297-0.707,0.297c-0.274,0-0.51-0.099-0.707-0.297C123.584,7.725,123.485,7.489,123.485,7.215z M123.805,9.799
h1.368v7.207h-1.368V9.799z"/>
<path fill="#5E6060" d="M134.567,16.944c0,0.548-0.094,1.047-0.281,1.498c-0.188,0.45-0.453,0.841-0.798,1.17
s-0.76,0.586-1.246,0.768c-0.487,0.183-1.024,0.273-1.611,0.273c-0.689,0-1.32-0.096-1.894-0.288
c-0.572-0.193-1.117-0.527-1.634-1.003l0.927-1.156c0.355,0.386,0.74,0.677,1.156,0.874c0.415,0.198,0.887,0.297,1.413,0.297
c0.507,0,0.928-0.074,1.262-0.221c0.335-0.146,0.601-0.337,0.799-0.569c0.197-0.234,0.337-0.5,0.418-0.799s0.121-0.601,0.121-0.904
v-1.064h-0.045c-0.264,0.436-0.621,0.758-1.072,0.966s-0.925,0.312-1.421,0.312c-0.527,0-1.017-0.094-1.468-0.281
s-0.838-0.446-1.163-0.775c-0.324-0.329-0.577-0.72-0.76-1.171c-0.183-0.45-0.273-0.939-0.273-1.467
c0-0.527,0.086-1.021,0.259-1.482c0.172-0.461,0.418-0.864,0.737-1.208c0.319-0.345,0.704-0.613,1.155-0.806
c0.45-0.192,0.955-0.289,1.513-0.289c0.486,0,0.96,0.106,1.421,0.319s0.823,0.512,1.087,0.896h0.03V9.799h1.368V16.944z
M130.828,10.894c-0.365,0-0.694,0.063-0.988,0.19c-0.294,0.126-0.542,0.299-0.745,0.517c-0.202,0.218-0.359,0.481-0.471,0.791
c-0.112,0.309-0.167,0.646-0.167,1.011c0,0.729,0.213,1.315,0.638,1.756c0.426,0.44,1.004,0.661,1.733,0.661
s1.307-0.221,1.733-0.661c0.426-0.44,0.638-1.026,0.638-1.756c0-0.365-0.056-0.702-0.167-1.011s-0.269-0.572-0.471-0.791
c-0.203-0.218-0.451-0.39-0.745-0.517C131.522,10.958,131.193,10.894,130.828,10.894z"/>
<path fill="#5E6060" d="M136.29,5.513h1.368v5.397h0.03c0.172-0.385,0.471-0.697,0.896-0.935s0.917-0.357,1.475-0.357
c0.345,0,0.677,0.053,0.996,0.16s0.598,0.271,0.836,0.494c0.238,0.223,0.429,0.509,0.57,0.859s0.213,0.763,0.213,1.239v4.637h-1.368
v-4.257c0-0.334-0.046-0.62-0.137-0.858c-0.092-0.238-0.213-0.431-0.365-0.578c-0.152-0.147-0.327-0.253-0.524-0.32
c-0.198-0.065-0.403-0.099-0.616-0.099c-0.283,0-0.547,0.046-0.79,0.137c-0.243,0.091-0.456,0.236-0.639,0.434
s-0.324,0.448-0.426,0.752c-0.101,0.304-0.151,0.664-0.151,1.079v3.71h-1.368V5.513z"/>
<path fill="#5E6060" d="M148.604,10.985h-1.961v3.269c0,0.203,0.005,0.402,0.015,0.601c0.01,0.197,0.048,0.375,0.114,0.532
c0.065,0.157,0.167,0.283,0.304,0.38s0.337,0.145,0.601,0.145c0.162,0,0.329-0.016,0.502-0.046c0.172-0.03,0.329-0.086,0.471-0.167
v1.246c-0.162,0.092-0.372,0.154-0.631,0.19c-0.258,0.035-0.458,0.053-0.6,0.053c-0.527,0-0.936-0.073-1.224-0.221
c-0.289-0.146-0.502-0.336-0.639-0.569s-0.219-0.494-0.244-0.783c-0.024-0.289-0.037-0.58-0.037-0.874v-3.755h-1.581V9.799h1.581
V7.778h1.368v2.021h1.961V10.985z"/>
<path fill="#95BDE5" d="M142.227,20.314c-0.039,0.215-0.129,0.432-0.129,0.432c-0.024,0.059-0.107,0.25-0.125,0.288
c-0.064,0.138-0.097,0.224-0.17,0.38c-0.084,0.178,0,0-0.136,0.268c-1.126,2.234-4.158,4.755-8.376,4.658
c-3.922-0.09-6.719-1.806-8.072-4.173c-0.103-0.18-0.262-0.42-0.383-0.684c-0.034-0.074-0.242-0.511-0.265-0.575
c-0.116-0.333-0.2-0.368-0.216-0.594c0,0,0.259,0.528,0.779,1.091c1.227,1.325,3.915,3.426,8.156,3.477
c4.143,0.049,6.907-2.123,8.163-3.477C141.972,20.849,142.227,20.314,142.227,20.314z"/>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

221
datacenterlight/tasks.py Normal file
View file

@ -0,0 +1,221 @@
from datetime import datetime
from celery.exceptions import MaxRetriesExceededError
from celery.utils.log import get_task_logger
from celery import current_task
from django.conf import settings
from django.core.mail import EmailMessage
from django.core.urlresolvers import reverse
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from dynamicweb.celery import app
from hosting.models import HostingOrder, HostingBill
from membership.models import StripeCustomer, CustomUser
from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineSerializer
from utils.hosting_utils import get_all_public_keys, get_or_create_vm_detail
from utils.forms import UserBillingAddressForm
from utils.mailer import BaseEmail
from utils.models import BillingAddress
logger = get_task_logger(__name__)
def retry_task(task, exception=None):
"""Retries the specified task using a "backing off countdown",
meaning that the interval between retries grows exponentially
with every retry.
Arguments:
task:
The task to retry.
exception:
Optionally, the exception that caused the retry.
"""
def backoff(attempts):
return 2 ** attempts
kwargs = {
'countdown': backoff(task.request.retries),
}
if exception:
kwargs['exc'] = exception
raise task.retry(**kwargs)
@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
def create_vm_task(self, vm_template_id, user, specs, template,
stripe_customer_id, billing_address_data,
stripe_subscription_id, cc_details):
logger.debug(
"Running create_vm_task on {}".format(current_task.request.hostname))
vm_id = None
try:
final_price = specs.get('price')
billing_address = BillingAddress(
cardholder_name=billing_address_data['cardholder_name'],
street_address=billing_address_data['street_address'],
city=billing_address_data['city'],
postal_code=billing_address_data['postal_code'],
country=billing_address_data['country']
)
billing_address.save()
customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
if 'pass' in user:
on_user = user.get('email')
on_pass = user.get('pass')
logger.debug("Using user {user} to create VM".format(user=on_user))
vm_name = None
else:
on_user = settings.OPENNEBULA_USERNAME
on_pass = settings.OPENNEBULA_PASSWORD
logger.debug("Using OpenNebula admin user to create VM")
vm_name = "{email}-{template_name}-{date}".format(
email=user.get('email'),
template_name=template.get('name'),
date=int(datetime.now().strftime("%s")))
# Create OpenNebulaManager
manager = OpenNebulaManager(email=on_user, password=on_pass)
vm_id = manager.create_vm(
template_id=vm_template_id,
specs=specs,
ssh_key=settings.ONEADMIN_USER_SSH_PUBLIC_KEY,
vm_name=vm_name
)
if vm_id is None:
raise Exception("Could not create VM")
# Create a Hosting Order
order = HostingOrder.create(
price=final_price,
vm_id=vm_id,
customer=customer,
billing_address=billing_address
)
# Create a Hosting 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 subscription
order.set_subscription_id(stripe_subscription_id, cc_details)
# If the Stripe payment succeeds, 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.get('name'),
'vm_id': vm['vm_id'],
'order_id': order.id
}
email_data = {
'subject': settings.DCL_TEXT + " Order from %s" % context['email'],
'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
'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()
if 'pass' in user:
lang = 'en-us'
if user.get('language') is not None:
logger.debug(
"Language is set to {}".format(user.get('language')))
lang = user.get('language')
translation.activate(lang)
# Send notification to the user as soon as VM has been booked
context = {
'base_url': "{0}://{1}".format(user.get('request_scheme'),
user.get('request_host')),
'order_url': reverse('hosting:orders',
kwargs={'pk': order.id}),
'page_header': _(
'Your New VM %(vm_name)s at Data Center Light') % {
'vm_name': vm.get('name')},
'vm_name': vm.get('name')
}
email_data = {
'subject': context.get('page_header'),
'to': user.get('email'),
'context': context,
'template_name': 'new_booked_vm',
'template_path': 'hosting/emails/',
'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
}
email = BaseEmail(**email_data)
email.send()
# try to see if we have the IP and that if the ssh keys can
# be configured
new_host = manager.get_primary_ipv4(vm_id)
logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id))
if new_host is not None:
custom_user = CustomUser.objects.get(email=user.get('email'))
get_or_create_vm_detail(custom_user, manager, vm_id)
if custom_user is not None:
public_keys = get_all_public_keys(custom_user)
keys = [{'value': key, 'state': True} for key in
public_keys]
if len(keys) > 0:
logger.debug(
"Calling configure on {host} for "
"{num_keys} keys".format(
host=new_host, num_keys=len(keys)))
# Let's delay the task by 75 seconds to be sure
# that we run the cdist configure after the host
# is up
manager.manage_public_key(keys,
hosts=[new_host],
countdown=75)
except Exception as e:
logger.error(str(e))
try:
retry_task(self)
except MaxRetriesExceededError:
msg_text = 'Finished {} retries for create_vm_task'.format(
self.request.retries)
logger.error(msg_text)
# Try sending email and stop
email_data = {
'subject': '{} CELERY TASK ERROR: {}'.format(settings.DCL_TEXT,
msg_text),
'from_email': current_task.request.hostname,
'to': settings.DCL_ERROR_EMAILS_TO_LIST,
'body': ',\n'.join(str(i) for i in self.request.args)
}
email = EmailMessage(**email_data)
email.send()
return
return vm_id

View file

@ -1,68 +1,65 @@
{% load staticfiles i18n%} {% load staticfiles i18n cms_tags sekizai_tags %}
{% get_current_language as LANGUAGE_CODE %} {% get_current_language as LANGUAGE_CODE %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{LANGUAGE_CODE}}"> <html lang="{{LANGUAGE_CODE}}">
<head>
<head> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Data Center Light by ungleich">
<meta name="author" content="ungleich GmbH">
<title>Data Center Light - {% block title %}VM hosting made in Switzerland{% endblock %}</title>
<meta charset="utf-8"> <!-- Vendor CSS -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Bootstrap Core CSS -->
<meta name="viewport" content="width=device-width, initial-scale=1"> <link href="{% static 'datacenterlight/css/bootstrap-3.3.7.min.css' %}" rel="stylesheet">
<meta name="description" content="Data Center Light by ungleich"> <!-- Icon Fonts -->
<meta name="author" content="ungleich GmbH"> <link href="{% static 'datacenterlight/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">
<!-- Custom CSS -->
<link href="{% static 'datacenterlight/css/common.css' %}" rel="stylesheet">
<link href="{% static 'datacenterlight/css/landing-page.css' %}" rel="stylesheet">
{% block css_extra %}
{% endblock css_extra %}
<title>Data Center Light - <!-- External Fonts -->
{% block title %}VM hosting made in Switzerland{% endblock %}</title> <link href="//fonts.googleapis.com/css?family=Lato:300,400,600,700" rel="stylesheet" type="text/css">
<!-- Bootstrap Core CSS -->
<link href="{% static 'datacenterlight/css/bootstrap.min.css' %}" rel="stylesheet">
<!-- Custom Fonts --> <link rel="shortcut icon" href="{% static 'datacenterlight/img/favicon.ico' %}" type="image/x-icon">
<!--Import Google Icon Font-->
<link href="//fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="{% static 'datacenterlight/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="{% static 'datacenterlight/img/favicon.ico' %}" type="image/x-icon" />
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.min.css" rel="stylesheet">
<!-- Custom CSS --> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<link href="{% static 'datacenterlight/css/landing-page.css' %}" rel="stylesheet"> <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- Google analytics -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// --> {% include "google_analytics.html" %}
<!--[if lt IE 9]> <!-- End Google Analytics -->
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> </head>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Google analytics -->
{% include "google_analytics.html" %}
<!-- End Google Analytics -->
</head>
<body> <body>
<!-- Navigation --> {% block navbar %}
{% include "datacenterlight/includes/_navbar.html" %} {% include "datacenterlight/includes/_navbar.html" %}
{% endblock navbar %}
{% block content %}
{% endblock %}
{% block content %} {% include "datacenterlight/includes/_footer.html" %}
{% endblock %}
{% include "datacenterlight/includes/_footer.html" %} <!-- jQuery -->
<!-- Footer --> <script src="{% static 'datacenterlight/js/jquery-2.2.4.min.js' %}"></script>
<!-- Bootstrap Core JavaScript -->
<script src="{% static 'datacenterlight/js/bootstrap-3.3.7.min.js' %}"></script>
<!-- Bootstrap Validator -->
<script src="//cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.9/validator.min.js"></script>
<!-- jQuery --> <!-- Custom JS -->
<script src="{% static 'datacenterlight/js/jquery.js' %}"></script> <script src="{% static 'datacenterlight/js/main.js' %}"></script>
</body>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="{% static 'datacenterlight/js/bootstrap.min.js' %}"></script>
<script src="{% static 'datacenterlight/js/main.js' %}"></script>
<!-- Load form js -->
<script src="{% static 'datacenterlight/js/form.js' %}"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.9/validator.min.js"></script>
</body>
</html> </html>

View file

@ -0,0 +1,99 @@
{% load staticfiles i18n %}
{% get_current_language as LANGUAGE_CODE %}
<!DOCTYPE html>
<html lang="{{LANGUAGE_CODE}}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Data Center Light by ungleich">
<meta name="author" content="ungleich GmbH">
<title>Data Center Light - {% block title %}VM hosting made in Switzerland{% endblock %}</title>
<!-- Vendor CSS -->
<!-- Bootstrap Core CSS -->
<link href="{% static 'datacenterlight/css/bootstrap-3.3.7.min.css' %}" rel="stylesheet">
<!-- Icon Fonts -->
<link href="{% static 'datacenterlight/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Lato:300,400,600,700" rel="stylesheet" type="text/css">
<!-- Custom CSS -->
<link href="{% static 'datacenterlight/css/common.css' %}" rel="stylesheet">
<link href="{% static 'datacenterlight/css/hosting.css' %}" rel="stylesheet">
{% block css_extra %}
{% endblock css_extra %}
<!-- External Fonts -->
<link rel="shortcut icon" href="{% static 'datacenterlight/img/favicon.ico' %}" type="image/x-icon">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Google analytics -->
{% include "google_analytics.html" %}
<!-- End Google Analytics -->
</head>
<body>
{% block navbar %}
{% include "hosting/includes/_navbar_user.html" %}
{% endblock navbar %}
<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>
{% else %}
<div class="footer-vm">
{% include "datacenterlight/includes/_footer.html" %}
</div>
{% endif %}
<!-- Moment -->
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.js"></script>
<!-- jQuery -->
<script src="{% static 'datacenterlight/js/jquery-2.2.4.min.js' %}"></script>
<!-- Bootstrap Core JavaScript -->
<script src="{% static 'datacenterlight/js/bootstrap-3.3.7.min.js' %}"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.9/validator.min.js"></script>
<!-- Copy Clipboard (not required for dcl, but dependency in virtual_machine_detail.js) -->
<script src="//cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.10/clipboard.min.js"></script>
<!-- Custom JS -->
<script src="{% static 'hosting/js/virtual_machine_detail.js' %}"></script>
<script src="{% static 'hosting/js/createvm.js' %}"></script>
<script src="{% static 'hosting/js/initial.js' %}"></script>
{% block js_extra %}
{% comment %}
this block is above some files, because on stripe error scripts below the stripe
script are not properly executed.
{% endcomment %}
{% endblock js_extra %}
<!-- Stripe Lib -->
<script src="https://js.stripe.com/v3/"></script>
<script src="https://js.stripe.com/v2/"></script>
<!-- Proccess payment lib -->
<script type="text/javascript" src="{% static 'hosting/js/payment.js' %}"></script>
</body>
</html>

View file

@ -1,27 +0,0 @@
{% load i18n %}
<form novalidate id ="beta_access" class="form-beta" method="POST" action="{% url 'datacenterlight:beta_access'%}">
{% csrf_token %}
{{ form.non_field_errors }}
<div>
{% for message in messages %}
<strong>{{ message }}</strong>
{% endfor %}
</div>
<div class="inputs">
<div class="form-group">
<input type="text" name="name" class="form-control" id="name" placeholder="{% trans 'Enter name' %}">
<span style="color: white">{{ form.name.errors|striptags}}</span>
</div>
<div class="form-group">
<input type="email" name="email" class="form-control" id="email" placeholder="{% trans 'Enter email' %}">
<span style="color: white">{{ form.email.errors|striptags}}</span>
</div>
</div>
<button type="submit" class="btn btn-default btn-transparent btn-lg">{% trans "Request Beta Access" %}</button>
</form>
<script>
$('#beta_access').ajaxForm({
target: '#beta_access_form', success: function(response) { }
});
</script>

View file

@ -1,47 +0,0 @@
{% load i18n %}
<div class="modal fade bs-example-modal-sm" style="color:black;" id="successModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div class="modal-icon"><i class="fa fa-check" aria-hidden="true"></i></div>
<h4 class="modal-title">{% trans "Request Sent" %}</h4>
<p class="modal-text">{% trans "Thank you for your subscription! You will receive a confirmation mail from our team" %}</p>
</div>
</div><!-- /.modal-content -->
</div>
</div><!-- /.modal -->
<script>
// Show modal
$('#successModal').modal('show');
// close the modal after 3 seconds
setTimeout(function() {
$('#successModal').modal('hide');
}, 5000);
</script>
<style>
.vertical-alignment-helper {
display:table;
height: 100%;
width: 100%;
pointer-events:none; /* This makes sure that we can still click outside of the modal to close it */
}
.vertical-align-center {
/* To center vertically */
display: table-cell;
vertical-align: middle;
pointer-events:none;
}
.modal-content {
/* Bootstrap sets the size of the modal in the modal-dialog class, we need to inherit it */
width:inherit;
height:inherit;
/* To center horizontally */
margin: 0 auto;
pointer-events: all;
}
</style>

View file

@ -0,0 +1,26 @@
{% extends "datacenterlight/base.html" %}
{% load staticfiles cms_tags sekizai_tags %}
{% block css_extra %}
<link href="{% static 'datacenterlight/css/cms.css' %}" media="screen" rel="stylesheet" type="text/css"/>
{% endblock css_extra %}
{% block title %}
{% page_attribute page_title %}
{% endblock %}
{% block content %}
<div class="dcl-cms_page-header">
<div class="container">
<h1>{% page_attribute page_title %}</h1>
</div>
</div>
<div class="split-section left" id="dcl-cms_page-text">
<div class="space">
<div class="container">
{% placeholder 'datacenterlight_cms_page_text' %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,53 @@
{% load i18n %}
{% if success %}
<div class="contact-form-success">
<div class="subtitle text-center">
<h3>{% trans "Thank you for contacting us." %}</h3>
</div>
<p>
{% trans "Your message was successfully sent to our team." %}
</p>
</div>
{% else %}
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<div class="subtitle">
<h3>{% trans "Get in touch with us!" %}</h3>
</div>
</div>
</div>
<form class="form-horizontal ajax-form" method="POST" action="{% url 'datacenterlight:contact_us' %}" data-toggle="validator" data-response="#contact-form" role="form">
{% csrf_token %}
<div class="form-group">
<label class="control-label col-sm-2" for="name">{% trans "Name" %}</label>
<div class="col-sm-10">
<input type="text" name="name" class="form-control" data-minlength="3" data-error="{% trans 'Please enter your name.' %}" required>
<div class="help-block with-errors"></div>
{{contact_form.name.errors}}
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="email">{% trans "Email" %}</label>
<div class="col-sm-10">
<input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control" data-error="{% trans 'Please enter a valid email address.' %}" required>
<div class="help-block with-errors"></div>
{{contact_form.email.errors}}
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="message">{% trans "Message" %}</label>
<div class="col-sm-10">
<textarea class="form-control" name="message" id="message" rows="6" required></textarea>
<div class="help-block with-errors"></div>
{{contact_form.message.errors}}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10 text-right">
<div class="form-error hide">{% trans "Sorry, there was an unexpected error. Kindly retry." %}</div>
<button type="submit" class="btn btn-default">{% trans "SUBMIT" %}</button>
</div>
</div>
</form>
{% endif %}

View file

@ -1,129 +0,0 @@
{% load static from staticfiles %}
{% load i18n%}
<!-- Inliner Build Version 4380b7741bb759d6cb997545f3add21ad48f010b -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Oxygen Invoice</title>
</head>
<body bgcolor="#ffffff" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; color: white; margin: 0;">
<style type="text/css">
@media only screen and (max-width: 480px) {
table[class*="container-for-gmail-android"] {
min-width: 290px !important; width: 100% !important;
}
img[class="force-width-gmail"] {
display: none !important; width: 0 !important; height: 0 !important;
}
table[class="w320"] {
width: 320px !important;
}
td[class*="mobile-header-padding-left"] {
width: 160px !important; padding-left: 0 !important;
}
td[class*="mobile-header-padding-right"] {
width: 160px !important; padding-right: 0 !important;
}
td[class="header-lg"] {
font-size: 24px !important; padding-bottom: 5px !important;
}
td[class="content-padding"] {
padding: 5px 0 5px !important;
}
td[class="button"] {
padding: 5px 5px 30px !important;
}
td[class*="free-text"] {
padding: 10px 18px 30px !important;
}
td[class~="mobile-hide-img"] {
display: none !important; height: 0 !important; width: 0 !important; line-height: 0 !important;
}
td[class~="item"] {
width: 140px !important; vertical-align: top !important;
}
td[class~="quantity"] {
width: 50px !important;
}
td[class~="price"] {
width: 90px !important;
}
td[class="item-table"] {
padding: 30px 20px !important;
}
td[class="mini-container-left"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
td[class="mini-container-right"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
}
</style>
<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%" style="border-collapse: collapse !important; min-width: 600px; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="left" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) repeat-x;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; background: transparent;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td width="100%" height="80" valign="top" style="text-align: center; vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; line-height: 21px; background-color: #ffffff" align="center">
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;">
<v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'datacenterlight/img/datacenterlight.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td>
</tr></table>
</center>
<!--[if gte mso 9]>
</v:textbox>
</v:rect>
<![endif]-->
</td>
</tr></table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff; padding: 20px 0 5px;" class="content-padding" bgcolor="#f7f7f7">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="header-lg" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 32px; color: #4d4d4d; text-align: left; line-height: normal; font-weight: 400; padding: 35px 5 0;" align="center">
{% trans "Thank you for your request." %}
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="free-text" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 100% !important; padding: 40px 7px 20px;" align="center">
<p>{% trans "You are one step away from being our beta tester!" %} <br/><br/>
{% trans "Currently we are running our tests to make sure everything runs perfectly." %}<br/>
{% trans "In the meantime, we would like to ask you a little patience<br/> until our team contacts you with beta access." %}<br/>
{% trans "Thank you!" %} </p></td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="button" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 0;" align="center">&nbsp;</td>
</tr>
</table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="height: 100px; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: 600; color: #7293de; padding: 25px 9px 0px;text-align: left; line-height: 21px;;" align="left">Your data center light team<br style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
</td>
</tr></table>
</center>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,129 +0,0 @@
{% load static from staticfiles %}
{% load i18n%}
<!-- Inliner Build Version 4380b7741bb759d6cb997545f3add21ad48f010b -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Oxygen Invoice</title>
</head>
<body bgcolor="#ffffff" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; color: white; margin: 0;">
<style type="text/css">
@media only screen and (max-width: 480px) {
table[class*="container-for-gmail-android"] {
min-width: 290px !important; width: 100% !important;
}
img[class="force-width-gmail"] {
display: none !important; width: 0 !important; height: 0 !important;
}
table[class="w320"] {
width: 320px !important;
}
td[class*="mobile-header-padding-left"] {
width: 160px !important; padding-left: 0 !important;
}
td[class*="mobile-header-padding-right"] {
width: 160px !important; padding-right: 0 !important;
}
td[class="header-lg"] {
font-size: 24px !important; padding-bottom: 5px !important;
}
td[class="content-padding"] {
padding: 5px 0 5px !important;
}
td[class="button"] {
padding: 5px 5px 30px !important;
}
td[class*="free-text"] {
padding: 10px 18px 30px !important;
}
td[class~="mobile-hide-img"] {
display: none !important; height: 0 !important; width: 0 !important; line-height: 0 !important;
}
td[class~="item"] {
width: 140px !important; vertical-align: top !important;
}
td[class~="quantity"] {
width: 50px !important;
}
td[class~="price"] {
width: 90px !important;
}
td[class="item-table"] {
padding: 30px 20px !important;
}
td[class="mini-container-left"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
td[class="mini-container-right"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
}
</style>
<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%" style="border-collapse: collapse !important; min-width: 600px; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="left" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) repeat-x;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; background: transparent;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td width="100%" height="80" valign="top" style="text-align: center; vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; line-height: 21px; background-color: #ffffff" align="center">
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;">
<v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'datacenterlight/img/datacenterlight.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td>
</tr></table>
</center>
<!--[if gte mso 9]>
</v:textbox>
</v:rect>
<![endif]-->
</td>
</tr></table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff; padding: 20px 0 5px;" class="content-padding" bgcolor="#f7f7f7">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="header-lg" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 32px; color: #4d4d4d; text-align: left; line-height: normal; font-weight: 400; padding: 35px 5 0;" align="center">
{% trans "Thank you for your request." %}
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="free-text" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 100% !important; padding: 40px 7px 20px;" align="center">
<p>{% trans "You are one step away from being our beta tester!" %} <br/><br/>
{% trans "Currently we are running our tests to make sure everything runs perfectly." %}<br/>
{% trans "In the meantime, we would like to ask you a little patience<br/> until our team contacts you with beta access." %}<br/>
{% trans "Thank you!" %} </p></td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="button" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 0;" align="center">&nbsp;</td>
</tr>
</table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="height: 100px; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: 600; color: #7293de; padding: 25px 9px 0px;text-align: left; line-height: 21px;;" align="left">Your data center light team<br style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
</td>
</tr></table>
</center>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,125 +0,0 @@
{% load static from staticfiles %}
<!-- Inliner Build Version 4380b7741bb759d6cb997545f3add21ad48f010b -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Oxygen Invoice</title>
</head>
<body bgcolor="#ffffff" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; color: white; margin: 0;">
<style type="text/css">
@media only screen and (max-width: 480px) {
table[class*="container-for-gmail-android"] {
min-width: 290px !important; width: 100% !important;
}
img[class="force-width-gmail"] {
display: none !important; width: 0 !important; height: 0 !important;
}
table[class="w320"] {
width: 320px !important;
}
td[class*="mobile-header-padding-left"] {
width: 160px !important; padding-left: 0 !important;
}
td[class*="mobile-header-padding-right"] {
width: 160px !important; padding-right: 0 !important;
}
td[class="header-lg"] {
font-size: 24px !important; padding-bottom: 5px !important;
}
td[class="content-padding"] {
padding: 5px 0 5px !important;
}
td[class="button"] {
padding: 5px 5px 30px !important;
}
td[class*="free-text"] {
padding: 10px 18px 30px !important;
}
td[class~="mobile-hide-img"] {
display: none !important; height: 0 !important; width: 0 !important; line-height: 0 !important;
}
td[class~="item"] {
width: 140px !important; vertical-align: top !important;
}
td[class~="quantity"] {
width: 50px !important;
}
td[class~="price"] {
width: 90px !important;
}
td[class="item-table"] {
padding: 30px 20px !important;
}
td[class="mini-container-left"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
td[class="mini-container-right"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
}
</style>
<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%" style="border-collapse: collapse !important; min-width: 600px; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="left" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) repeat-x;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; background: transparent;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td width="100%" height="80" valign="top" style="text-align: center; vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; line-height: 21px; background-color: #ffffff" align="center">
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;">
<v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'datacenterlight/img/datacenterlight.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td>
</tr></table>
</center>
<!--[if gte mso 9]>
</v:textbox>
</v:rect>
<![endif]-->
</td>
</tr></table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff; padding: 20px 0 5px;" class="content-padding" bgcolor="#f7f7f7">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="header-lg" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 32px; color: #4d4d4d; text-align: left; line-height: normal; font-weight: 400; padding: 35px 5 0;" align="center">
An user requested a beta access
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="free-text" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 100% !important; padding: 40px 7px 20px;" align="center">
<p>User {{email}} requested beta access </p></td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="button" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 0;" align="center">&nbsp;</td>
</tr>
</table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="height: 100px; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: 600; color: #7293de; padding: 25px 9px 0px;text-align: left; line-height: 21px;;" align="left">Your data center light team<br style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
</td>
</tr></table>
</center>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,125 +0,0 @@
{% load static from staticfiles %}
<!-- Inliner Build Version 4380b7741bb759d6cb997545f3add21ad48f010b -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Oxygen Invoice</title>
</head>
<body bgcolor="#ffffff" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; color: white; margin: 0;">
<style type="text/css">
@media only screen and (max-width: 480px) {
table[class*="container-for-gmail-android"] {
min-width: 290px !important; width: 100% !important;
}
img[class="force-width-gmail"] {
display: none !important; width: 0 !important; height: 0 !important;
}
table[class="w320"] {
width: 320px !important;
}
td[class*="mobile-header-padding-left"] {
width: 160px !important; padding-left: 0 !important;
}
td[class*="mobile-header-padding-right"] {
width: 160px !important; padding-right: 0 !important;
}
td[class="header-lg"] {
font-size: 24px !important; padding-bottom: 5px !important;
}
td[class="content-padding"] {
padding: 5px 0 5px !important;
}
td[class="button"] {
padding: 5px 5px 30px !important;
}
td[class*="free-text"] {
padding: 10px 18px 30px !important;
}
td[class~="mobile-hide-img"] {
display: none !important; height: 0 !important; width: 0 !important; line-height: 0 !important;
}
td[class~="item"] {
width: 140px !important; vertical-align: top !important;
}
td[class~="quantity"] {
width: 50px !important;
}
td[class~="price"] {
width: 90px !important;
}
td[class="item-table"] {
padding: 30px 20px !important;
}
td[class="mini-container-left"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
td[class="mini-container-right"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
}
</style>
<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%" style="border-collapse: collapse !important; min-width: 600px; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="left" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) repeat-x;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; background: transparent;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td width="100%" height="80" valign="top" style="text-align: center; vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; line-height: 21px; background-color: #ffffff" align="center">
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;">
<v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'datacenterlight/img/datacenterlight.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td>
</tr></table>
</center>
<!--[if gte mso 9]>
</v:textbox>
</v:rect>
<![endif]-->
</td>
</tr></table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff; padding: 20px 0 5px;" class="content-padding" bgcolor="#f7f7f7">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="header-lg" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 32px; color: #4d4d4d; text-align: left; line-height: normal; font-weight: 400; padding: 35px 5 0;" align="center">
An user requested a beta access
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="free-text" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 100% !important; padding: 40px 7px 20px;" align="center">
<p>User {{email}} requested beta access </p></td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="button" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 0;" align="center">&nbsp;</td>
</tr>
</table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="height: 100px; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: 600; color: #7293de; padding: 25px 9px 0px;text-align: left; line-height: 21px;;" align="left">Your data center light team<br style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
</td>
</tr></table>
</center>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,131 +0,0 @@
{% load static from staticfiles %}
<!-- Inliner Build Version 4380b7741bb759d6cb997545f3add21ad48f010b -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Oxygen Invoice</title>
</head>
<body bgcolor="#ffffff" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; color: white; margin: 0;">
<style type="text/css">
@media only screen and (max-width: 480px) {
table[class*="container-for-gmail-android"] {
min-width: 290px !important; width: 100% !important;
}
img[class="force-width-gmail"] {
display: none !important; width: 0 !important; height: 0 !important;
}
table[class="w320"] {
width: 320px !important;
}
td[class*="mobile-header-padding-left"] {
width: 160px !important; padding-left: 0 !important;
}
td[class*="mobile-header-padding-right"] {
width: 160px !important; padding-right: 0 !important;
}
td[class="header-lg"] {
font-size: 24px !important; padding-bottom: 5px !important;
}
td[class="content-padding"] {
padding: 5px 0 5px !important;
}
td[class="button"] {
padding: 5px 5px 30px !important;
}
td[class*="free-text"] {
padding: 10px 18px 30px !important;
}
td[class~="mobile-hide-img"] {
display: none !important; height: 0 !important; width: 0 !important; line-height: 0 !important;
}
td[class~="item"] {
width: 140px !important; vertical-align: top !important;
}
td[class~="quantity"] {
width: 50px !important;
}
td[class~="price"] {
width: 90px !important;
}
td[class="item-table"] {
padding: 30px 20px !important;
}
td[class="mini-container-left"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
td[class="mini-container-right"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
}
</style>
<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%" style="border-collapse: collapse !important; min-width: 600px; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="left" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) repeat-x;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; background: transparent;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td width="100%" height="80" valign="top" style="text-align: center; vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; line-height: 21px; background-color: #ffffff" align="center">
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;">
<v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'datacenterlight/img/datacenterlight.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td>
</tr></table>
</center>
<!--[if gte mso 9]>
</v:textbox>
</v:rect>
<![endif]-->
</td>
</tr></table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff; padding: 20px 0 5px;" class="content-padding" bgcolor="#f7f7f7">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="header-lg" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 32px; color: #4d4d4d; text-align: left; line-height: normal; font-weight: 400; padding: 35px 5 0;" align="center">
An user requested a beta access
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="free-text" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 100% !important; padding: 40px 7px 20px;" align="center">
<p>User {{email}} requested beta access </p>
{% for vm in vms %}
Type: {{vm.type}} - Amount: {{vm.amount}}
{% endfor %}
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="button" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 0;" align="center">&nbsp;</td>
</tr>
</table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="height: 100px; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: 600; color: #7293de; padding: 25px 9px 0px;text-align: left; line-height: 21px;;" align="left">Your data center light team<br style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
</td>
</tr></table>
</center>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,131 +0,0 @@
{% load static from staticfiles %}
<!-- Inliner Build Version 4380b7741bb759d6cb997545f3add21ad48f010b -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Oxygen Invoice</title>
</head>
<body bgcolor="#ffffff" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; color: white; margin: 0;">
<style type="text/css">
@media only screen and (max-width: 480px) {
table[class*="container-for-gmail-android"] {
min-width: 290px !important; width: 100% !important;
}
img[class="force-width-gmail"] {
display: none !important; width: 0 !important; height: 0 !important;
}
table[class="w320"] {
width: 320px !important;
}
td[class*="mobile-header-padding-left"] {
width: 160px !important; padding-left: 0 !important;
}
td[class*="mobile-header-padding-right"] {
width: 160px !important; padding-right: 0 !important;
}
td[class="header-lg"] {
font-size: 24px !important; padding-bottom: 5px !important;
}
td[class="content-padding"] {
padding: 5px 0 5px !important;
}
td[class="button"] {
padding: 5px 5px 30px !important;
}
td[class*="free-text"] {
padding: 10px 18px 30px !important;
}
td[class~="mobile-hide-img"] {
display: none !important; height: 0 !important; width: 0 !important; line-height: 0 !important;
}
td[class~="item"] {
width: 140px !important; vertical-align: top !important;
}
td[class~="quantity"] {
width: 50px !important;
}
td[class~="price"] {
width: 90px !important;
}
td[class="item-table"] {
padding: 30px 20px !important;
}
td[class="mini-container-left"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
td[class="mini-container-right"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
}
</style>
<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%" style="border-collapse: collapse !important; min-width: 600px; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="left" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) repeat-x;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; background: transparent;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td width="100%" height="80" valign="top" style="text-align: center; vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; line-height: 21px; background-color: #ffffff" align="center">
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;">
<v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'datacenterlight/img/datacenterlight.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td>
</tr></table>
</center>
<!--[if gte mso 9]>
</v:textbox>
</v:rect>
<![endif]-->
</td>
</tr></table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff; padding: 20px 0 5px;" class="content-padding" bgcolor="#f7f7f7">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="header-lg" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 32px; color: #4d4d4d; text-align: left; line-height: normal; font-weight: 400; padding: 35px 5 0;" align="center">
An user requested a beta access
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="free-text" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 100% !important; padding: 40px 7px 20px;" align="center">
<p>User {{email}} requested beta access </p>
{% for vm in vms %}
Type: {{vm.type}}
{% endfor %}
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="button" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 0;" align="center">&nbsp;</td>
</tr>
</table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="height: 100px; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: 600; color: #7293de; padding: 25px 9px 0px;text-align: left; line-height: 21px;;" align="left">Your data center light team<br style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
</td>
</tr></table>
</center>
</td>
</tr>
</table>
</body>
</html>

View file

@ -1,132 +1,58 @@
{% load static from staticfiles %} {% load static i18n %}
{% load i18n %} <!DOCTYPE html>
<!-- Inliner Build Version 4380b7741bb759d6cb997545f3add21ad48f010b --> <html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{dcl_text}}</title>
</head>
<body bgcolor="#ffffff" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; color: white; margin: 0;">
<style type="text/css">
@media only screen and (max-width: 480px) {
table[class*="container-for-gmail-android"] {
min-width: 290px !important; width: 100% !important;
}
img[class="force-width-gmail"] {
display: none !important; width: 0 !important; height: 0 !important;
}
table[class="w320"] {
width: 320px !important;
}
td[class*="mobile-header-padding-left"] {
width: 160px !important; padding-left: 0 !important;
}
td[class*="mobile-header-padding-right"] {
width: 160px !important; padding-right: 0 !important;
}
td[class="header-lg"] {
font-size: 24px !important; padding-bottom: 5px !important;
}
td[class="content-padding"] {
padding: 5px 0 5px !important;
}
td[class="button"] {
padding: 5px 5px 30px !important;
}
td[class*="free-text"] {
padding: 10px 18px 30px !important;
}
td[class~="mobile-hide-img"] {
display: none !important; height: 0 !important; width: 0 !important; line-height: 0 !important;
}
td[class~="item"] {
width: 140px !important; vertical-align: top !important;
}
td[class~="quantity"] {
width: 50px !important;
}
td[class~="price"] {
width: 90px !important;
}
td[class="item-table"] {
padding: 30px 20px !important;
}
td[class="mini-container-left"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
td[class="mini-container-right"] {
padding: 0 15px 15px !important; display: block !important; width: 290px !important;
}
}
</style>
<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%" style="border-collapse: collapse !important; min-width: 600px; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="left" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) repeat-x;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; background: transparent;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td width="100%" height="80" valign="top" style="text-align: center; vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; line-height: 21px; background-color: #ffffff" align="center">
<!--[if gte mso 9]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;">
<v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'datacenterlight/img/datacenterlight.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td>
</tr></table>
</center>
<!--[if gte mso 9]>
</v:textbox>
</v:rect>
<![endif]-->
</td>
</tr></table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff; padding: 20px 0 5px;" class="content-padding" bgcolor="#f7f7f7">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="header-lg" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 32px; color: #4d4d4d; text-align: left; line-height: normal; font-weight: 400; padding: 35px 5 0;" align="center">
{{dcl_text}} {% trans 'account activation' %}
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="free-text" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 100% !important; padding: 40px 7px 20px;" align="center">
<p>
{% blocktrans %}
You can activate your {{dcl_text}} account by <a href="{{base_url}}{{activation_link}}">clicking here</a>.<br/><br/>
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.<br/>
{{base_url}}{{activation_link}}
{% endblocktrans %}
</p></td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="button" style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; padding: 0;" align="center">&nbsp;</td>
</tr>
</table>
</center>
</td>
</tr>
<tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td align="center" valign="top" width="100%" style="height: 100px; border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; background: #ffffff;" bgcolor="#ffffff">
<center style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellspacing="0" cellpadding="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td style="border-collapse: collapse; font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: 600; color: #7293de; padding: 25px 9px 0px;text-align: left; line-height: 21px;;" align="left">{% trans 'Your' %} {{dcl_text}} {% trans 'team' %}<br style="font-family: 'Raleway', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
</td>
</tr></table>
</center>
</td>
</tr>
</table>
</body>
</html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% trans "Data Center Light Account Activation" %}</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 "Data Center Light Account Activation" %}</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;">
{% blocktrans %}You can activate your Data Center Light account by clicking <a href="{{base_url}}{{activation_link}}" style="text-decoration: none; color: #4382c8; font-weight: 400;">here</a>.{% endblocktrans %}
</p>
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin-bottom: 10px; margin-top: 0;">
{% blocktrans %}You can also copy and paste the following link into the address bar of your browser to activate your Data Center Light account.{% endblocktrans %}
</p>
<p style="color: #4382c8; line-height: 1.4; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{{base_url}}{{activation_link}}
</p>
<p>
{% if account_details %}
{% url 'hosting:reset_password' as reset_password_url %}
{% trans "Your account details are as follows" %}:
{% trans "Username" %} : {% trans "Your email address" %}
{% trans "Password" %} : {{account_details}}
{% trans "You can reset your password here" %}:
{{base_url}}{{reset_password_url}}
{% endif %}
</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,20 @@
{% load static from staticfiles %}
{% load i18n %} {% load i18n %}
{{dcl_text}} {% trans 'account activation' %}
{% blocktrans %} {% trans "Data Center Light Account Activation" %}
Hi,
You can activate your {{dcl_text}} account by clicking here {{base_url}}{{activation_link}} {% blocktrans %}You can copy and paste the following link into the address bar of your browser to activate your Data Center Light account.{% endblocktrans %}
{% endblocktrans %}
{% trans 'Your' %} {{dcl_text}} {% trans 'team' %} {{base_url}}{{activation_link}}
{% if account_details %}
{% url 'hosting:reset_password' as reset_password_url %}
{% trans "Your account details are as follows" %}:
{% trans "Username" %} : {% trans "Your email address" %}
{% trans "Password" %} : {{account_details}}
{% trans "You can reset your password here" %}:
{{base_url}}{{reset_password_url}}
{% endif %}
{% trans "Your Data Center Light Team" %}

View file

@ -0,0 +1,48 @@
{% load static i18n %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% trans "Welcome to Data Center Light!" %}</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 "Welcome to Data Center Light!" %}</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 %}Thanks for joining us! We provide the most affordable virtual machines from the heart of Switzerland.{% endblocktrans %}
</p>
<p style="line-height: 1.75; font-family: Lato, Arial, sans-serif; font-weight: 300; margin: 0;">
{% blocktrans %}Try now, order a VM. VM price starts from only 15CHF per month.{% 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;">{% trans "ORDER 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

@ -0,0 +1,10 @@
{% load i18n %}
{% trans "Welcome to Data Center Light!" %}
{% blocktrans %}Thanks for joining us! We provide the most affordable virtual machines from the heart of Switzerland.{% endblocktrans %}
{% blocktrans %}Try now, order a VM. VM price starts from only 15CHF per month.{% endblocktrans %}
{{ base_url }}{% url 'hosting:create_virtual_machine' %}
{% trans "Your Data Center Light Team" %}

View file

@ -26,9 +26,9 @@
<div class="help-block with-errors"> <div class="help-block with-errors">
{% for message in messages %} {% for message in messages %}
{% if 'cores' in message.tags %} {% if 'cores' in message.tags %}
<ul class="list-unstyled"><li> <ul class="list-unstyled">
{{ message|safe }} <li>{{ message|safe }}</li>
</li></ul> </ul>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
@ -36,8 +36,8 @@
<div class="form-group"> <div class="form-group">
<div class="description input"> <div class="description input">
<i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i> <i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i>
<input id="ramValue" class="input-price select-number" type="number" min="2" max="200" name="ram" <input id="ramValue" class="input-price select-number" type="number" min="1" max="200" name="ram"
data-error="{% trans 'Please enter a value in range 2 - 200.' %}" required> data-error="{% trans 'Please enter a value in range 1 - 200.' %}" required>
<span> GB RAM</span> <span> GB RAM</span>
<i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i> <i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i>
</div> </div>
@ -71,53 +71,15 @@
</div> </div>
<div class="description select-configuration input form-group justify-center"> <div class="description select-configuration input form-group justify-center">
<label for="config">OS</label> <label for="config">OS</label>
<select name="config" id=""> <select name="config">
{% for template in templates %} {% for template in templates %}
<option value="{{template.opennebula_vm_template_id}}">{{template.name}}</option> <option value="{{template.opennebula_vm_template_id}}">{{template.name}}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
<input type="hidden" name="total">
<!--<div class="description check-ip"> <!--<div class="description check-ip">
<input type="checkbox" name="ipv6"> Ipv6 Only<br> <input type="checkbox" name="ipv6"> Ipv6 Only<br>
</div>--> </div>-->
<div class="form-group">
<div class="description input justify-center">
<label for="name" class="control-label">{% trans "Name"%}</label>
<input type="text" name="name" class="form-control" placeholder="{% trans 'Your Name'%}"
data-minlength="3" data-error="{% trans 'Please enter your name.' %}" required>
</div>
<div class="help-block with-errors">
{% for message in messages %}
{% if 'name' in message.tags %}
<ul class="list-unstyled">
<li>
{{ message|safe }}
</li>
</ul>
{% endif %}
{% endfor %}
</div>
</div>
<div class="form-group">
<div class="description input justify-center">
<label for="email" class="control-label">{% trans "Email"%}</label>
<input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control"
placeholder="{% trans 'Your Email' %}"
data-error="{% trans 'Please enter a valid email address.' %}" required>
</div>
<div class="help-block with-errors">
{% for message in messages %}
{% if 'email' in message.tags %}
<ul class="list-unstyled">
<li>
{{ message|safe }}
</li>
</ul>
{% endif %}
{% endfor %}
</div>
</div>
</div> </div>
<input type="submit" class="btn btn-primary disabled" value="{% trans 'Continue' %}"></input> <input type="submit" class="btn btn-primary disabled" value="{% trans 'Continue' %}"></input>
</form> </form>

View file

@ -1,53 +1,45 @@
{% load staticfiles i18n%} {% load staticfiles i18n%}
{% get_current_language as LANGUAGE_CODE %} {% get_current_language as LANGUAGE_CODE %}
<footer>
<div class="container">
<div class="row">
<div class="col-lg-12">
<ul class="list-inline"> <footer>
{% if request.resolver_match.url_name == "index" %} <div class="container">
<li> <ul class="list-inline">
<a class="url" href="javascript:void(0)" data-url="#how" >{% trans "Highlights" %}</a> {% if request.resolver_match.url_name != "index" %}
</li> <li>
<li> <a href="{% url 'datacenterlight:index' %}">{% trans "Home" %}</a>
<a class="url" href="javascript:void(0)" data-url="#your" >{% trans "Scale out" %}</a> </li>
</li> <li class="footer-menu-divider">&sdot;</li>
<li> {% endif %}
<a class="url" href="javascript:void(0)" data-url="#our">{% trans "Reliable and light" %}</a> <li>
</li> <a class="url-init" href="{% url 'datacenterlight:index' %}#how">{% trans "Highlights" %}</a>
<li> </li>
<a class="url" href="javascript:void(0)" data-url="#price" >{% trans "Order VM" %}</a> <li>
</li> <a class="url-init" href="{% url 'datacenterlight:index' %}#your">{% trans "Scale out" %}</a>
<li> </li>
<a class="url" href="javascript:void(0)" data-url="#contact" >{% trans "Contact" %}</a> <li>
</li> <a class="url-init" href="{% url 'datacenterlight:index' %}#our">{% trans "Reliable and light" %}</a>
{% else %} </li>
<li> {% if request.resolver_match.url_name != "index" %}
<a href="{% url 'datacenterlight:index' %}">{% trans "Home" %}</a> <li>
</li> <a class="url-init" href="{% url 'datacenterlight:index' %}#price">{% trans "Pricing" %}</a>
<li class="footer-menu-divider">&sdot;</li> </li>
<li> <li class="footer-menu-divider">&sdot;</li>
<a href="{% url 'datacenterlight:index' %}#how">{% trans "Highlights" %}</a></li> {% else %}
<li class="footer-menu-divider">&sdot;</li> <li>
<li> <a class="url-init" href="{% url 'datacenterlight:index' %}#price">{% trans "Order VM" %}</a>
<a href="{% url 'datacenterlight:index' %}#your">{% trans "Scale out" %}</a></li> </li>
<li>&sdot;</li> {% endif %}
<li> <li>
<a href="{% url 'datacenterlight:index' %}#our">{% trans "Reliable and light" %}</a></li> <a class="url-init" href="{% url 'datacenterlight:index' %}#contact">{% trans "Contact" %}</a>
<li class="footer-menu-divider">&sdot;</li> </li>
<li> {% if request.resolver_match.url_name != "index" %}
<a href="{% url 'datacenterlight:index' %}#price">{% trans "Pricing" %}</a> <li class="footer-menu-divider">&sdot;</li>
</li> {% endif %}
<li class="footer-menu-divider">&sdot;</li> <li>
<li> <a class="url-init" href="/cms/terms-of-service">{% trans "Terms of Service" %}</a>
<a href="{% url 'datacenterlight:index' %}#contact">{% trans "Contact" %}</a> </li>
</li> </ul>
{% endif %}
</ul>
<p class="copyright text-muted small">Copyright &copy; ungleich GmbH {% now "Y" %}. {% trans "All Rights Reserved" %}</p> <p class="copyright text-muted small">Copyright &copy; ungleich GmbH {% now "Y" %}. {% trans "All Rights Reserved" %}</p>
</div> </div>
</div> </footer>
</div>
</footer>

View file

@ -1,74 +1,70 @@
{% load staticfiles i18n%} {% get_current_language as LANGUAGE_CODE %} {% load custom_tags %} {% load staticfiles i18n custom_tags %}
<nav class="navbar navbar-default navbar-fixed-top topnav"> {% get_current_language as LANGUAGE_CODE %}
<div class="topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %}
<a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav" data-url="#home"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
<a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav" data-url="#home"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
{% else %}
<a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
<a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
{% endif %}
</div> <nav class="navbar navbar-default navbar-fixed-top topnav navbar-transparent">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><!-- Start Navbar collapse--> <!-- Brand and toggle get grouped for better mobile display -->
<ul class="nav navbar-nav navbar-right"> <div class="navbar-header">
{% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %} <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<li class="dropdown"> <span class="sr-only">{% trans "Toggle navigation" %}</span>
<a class="dropdown-toggle visible-mobile" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a> <span class="icon-bar"></span>
<a class="dropdown-toggle url disabled visible-desktop menu-url" data-url="#how" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a> <span class="icon-bar"></span>
<ul class="dropdown-menu"> <span class="icon-bar"></span>
<li><a class="url menu-url" data-url="#your" href="#your">{% trans "Scale out" %}</a></li> </button>
<li><a class="url menu-url" data-url="#our" href="#our">{% trans "Reliable and light" %}</a></li> <a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
<li> <a class="url menu-url" data-url="#price" href="#price">{% trans "Order VM" %}</a></li> <a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
</ul>
</li>
<li>
<a href="{% url 'datacenterlight:whydatacenterlight' %}" >{% trans "Why Data Center Light?" %}</a>
</li>
<li>
<a class="url" href="{% url 'datacenterlight:index' %}#contact" data-url="#contact" >{% trans "Contact" %}</a>
</li>
{% endif %}
<li>
{% if LANGUAGE_CODE == 'en-us'%}
<a class="on-hover-border" href="{% change_lang 'de' %}">Deutsch&nbsp;&nbsp;<i class="fa fa-globe" aria-hidden="true"></i></a>
{% else %}
<a class="on-hover-border" href="{% change_lang 'en-us' %}">English&nbsp;&nbsp;<i class="fa fa-globe" aria-hidden="true"></i></a>
{% endif %}
</li>
{% comment %}
<!-- to be used when more than one option for language -->
<li class="nav-language">
<div class="dropdown">
<div class="dropdown-toggle select-language" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
{% if LANGUAGE_CODE == 'en-us'%}
<span>English</span>
{% else %}
<span>Deutsch</span>
{% endif %}
<i class="fa fa-globe" aria-hidden="true"></i>
</div>
<ul class="dropdown-menu drop-language dropdown-menu-right">
{% if LANGUAGE_CODE == 'en-us'%}
<li><a class="url" href="{% change_lang 'de' %}">Deutsch</a></li>
{% else %}
<li><a class="url" href="{% change_lang 'en-us' %}">English</a></li>
{% endif %}
</ul>
</div>
</li>
{% endcomment %}
</ul>
</div> </div>
<!-- /.navbar-collapse --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
</div> <!-- Start Navbar collapse-->
</nav> <ul class="nav navbar-nav navbar-right">
<li class="dropdown highlights-dropdown">
<a class="dropdown-toggle url-init" href="{% url 'datacenterlight:index' %}#how" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}&nbsp;<span class="caret"></span></a>
<ul class="dropdown-menu ">
<li><a class="url-init" href="{% url 'datacenterlight:index' %}#your">{% trans "Scale out" %}</a></li>
<li><a class="url-init" href="{% url 'datacenterlight:index' %}#our">{% trans "Reliable and light" %}</a></li>
<li> <a class="url-init" href="{% url 'datacenterlight:index' %}#price">{% trans "Order VM" %}</a></li>
</ul>
</li>
<li>
<a href="{% url 'datacenterlight:whydatacenterlight' %}">{% trans "Why Data Center Light?" %}</a>
</li>
<li>
<a class="url-init" href="{% url 'datacenterlight:index' %}#contact">{% trans "Contact" %}</a>
</li>
<li>
{% if LANGUAGE_CODE == 'en-us'%}
<a class="on-hover-border" href="{% change_lang 'de' %}">Deutsch&nbsp;&nbsp;<i class="fa fa-globe" aria-hidden="true"></i></a> {% else %}
<a class="on-hover-border" href="{% change_lang 'en-us' %}">English&nbsp;&nbsp;<i class="fa fa-globe" aria-hidden="true"></i></a> {% endif %}
</li>
{% if not request.user.is_authenticated %}
<li>
<a href="{% url 'hosting:login' %}">{% trans "Login" %}&nbsp;&nbsp;<span class="fa fa-sign-in"></span></a>
</li>
{% else %}
<li>
<a href="{% url 'hosting:dashboard' %}">{% trans "Dashboard" %}</a>
</li>
{% endif %}
{% comment %}
<!-- to be used when more than one option for language -->
<li class="nav-language">
<div class="dropdown">
<div class="dropdown-toggle select-language" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
{% if LANGUAGE_CODE == 'en-us'%}
<span>English</span> {% else %}
<span>Deutsch</span> {% endif %}
<i class="fa fa-globe" aria-hidden="true"></i>
</div>
<ul class="dropdown-menu drop-language dropdown-menu-right">
{% if LANGUAGE_CODE == 'en-us'%}
<li><a class="url" href="{% change_lang 'de' %}">Deutsch</a></li>
{% else %}
<li><a class="url" href="{% change_lang 'en-us' %}">English</a></li>
{% endif %}
</ul>
</div>
</li>
{% endcomment %}
</ul>
<!-- /.navbar-collapse -->
</div>
</nav>

View file

@ -1,5 +1,5 @@
{% extends "datacenterlight/base.html" %} {% extends "datacenterlight/base.html" %}
{% load staticfiles i18n%} {% load staticfiles i18n %}
{% block content %} {% block content %}
@ -16,10 +16,10 @@
<hr class="intro-divider"> <hr class="intro-divider">
<ul class="list-inline intro-social-buttons"> <ul class="list-inline intro-social-buttons">
<li> <li>
<a class="btn btn-default btn-lg btn-transparent url" href="javascript:void(0)" data-url="#how" ><i class="#Services"></i> <span class="network-name">{% trans "Highlights" %}</span></a> <a class="btn btn-default btn-lg btn-transparent url" href="#how"><span class="network-name">{% trans "Highlights" %}</span></a>
</li> </li>
<li> <li>
<a class="btn btn-primary btn-lg page-scroll url" href="javascript:void(0)" data-url="#price" ><span class="network-name">{% trans "I want it!" %}</span></a> <a class="btn btn-primary btn-lg page-scroll url" href="#price"><span class="network-name">{% trans "I want it!" %}</span></a>
</li> </li>
</ul> </ul>
</div> </div>
@ -130,15 +130,14 @@
<div class="row text-center"> <div class="row text-center">
<div class="col-xs-12 col-md-6 text"> <div class="col-xs-12 col-md-6 text">
<h2 class="section-heading">{% trans "Simple and affordable: Try our virtual machine with featherlight price." %}</h2> <h2 class="section-heading">{% trans "Simple and affordable: Try our virtual machine with featherlight price." %}</h2>
<p class="lead new-lead">{% trans "Affordable VM hosting based in Switzerland" %}</p> <p class="lead new-lead">{% blocktrans %}Ready in 30 seconds.<br/>Experience the unbeatable speed from Data Center Light.{% endblocktrans %}</p>
</div> </div>
<div class="col-xs-12 col-md-6 hero-feature"> <div class="col-xs-12 col-md-6 hero-feature">
<div class="price-calc-section no-padding"> <div class="price-calc-section no-padding">
<div class="landing card"> <div class="landing card">
<img class="img-beta" src="{% static 'datacenterlight/img/beta-img.png' %}" alt="">
<div class="caption"> <div class="caption">
{% include "datacenterlight/calculator_form.html" %} {% include "datacenterlight/includes/_calculator_form.html" %}
</div> </div>
</div> </div>
</div> </div>
@ -149,32 +148,34 @@
</div> </div>
<!-- / contact section --> <!-- / contact section -->
<div class="full-contact-section"> <div class="full-contact-section">
<div class="intro-header-2 contact-section" id="contact"> <div class="intro-header-2 contact-section" id="contact">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-sm-6">
<div class="col-sm-6 col-md-6"> <div class="title">
<div class="card"> <h2>{% trans "Contact us" %}</h2>
</div>
<div class="contact-details">
<div class="subtitle"> <div class="subtitle">
<h3>ungleich GmbH </h3> <h3>ungleich glarus ag</h3>
</div> </div>
<div class="description"> <div class="description">
<p><i class="fa fa-envelope-o"></i> info@datacenterlight.ch</p> <p>info@datacenterlight.ch</p>
<p>In der Au 7, Schwanden 8762</p> <p>Bahnhofstrasse 1, 8783 Linthal</p>
<p>{% trans "Switzerland " %}</p> <p>{% trans "Switzerland " %}</p>
</div> </div>
<div class="social"> </div>
<a target="_blank" class="" href="https://twitter.com/datacenterlight"><i class="fa fa-twitter fa-fw"></i></a> <div class="social">
<a target="_blank" class="" href="https://github.com/ungleich"><i class="fa fa-github fa-fw"></i></a> <a target="_blank" href="https://twitter.com/datacenterlight"><i class="fa fa-twitter fa-fw"></i></a>
<a target="_blank" class="" href="https://www.facebook.com/ungleich.ch/"><i class="fa fa-facebook fa-fw"></i></a> <a target="_blank" href="https://github.com/ungleich"><i class="fa fa-github fa-fw"></i></a>
</div> <a target="_blank" href="https://www.facebook.com/ungleich.ch/"><i class="fa fa-facebook"></i></a>
</div> </div>
</div> </div>
<div class="col-sm-6 col-md-6"> <div class="col-sm-6">
<div class="title"> <div id="contact-form" class="contact-form">
<h2>{% trans "Questions?" %} {% trans "Contact us!" %}</h2> {% include "datacenterlight/contact_form.html" %}
</div> </div>
</div> </div>
</div> </div>

View file

@ -0,0 +1,202 @@
{% extends "datacenterlight/base_hosting.html" %}
{% load staticfiles bootstrap3 i18n %}
{% block css_extra %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/paymentfont/1.1.2/css/paymentfont.min.css"/>
{% endblock css_extra %}
{% block navbar %}
{% include "datacenterlight/includes/_navbar.html" %}
{% endblock navbar %}
{% block content %}
<!-- Credit card form -->
<div class="dcl-order-container">
<div class="payment-container">
<div class="dcl-payment-grid">
<div class="dcl-payment-box">
<div class="dcl-payment-section">
{% if request.user.is_authenticated %}
<div class="dcl-payment-user">
<h4>{% trans "Welcome back" %} {{request.user.name}}!</h4>
<p>{% trans "Review your billing address and card details and proceed to make payment." %}</p>
</div>
{% else %}
<h3>{%trans "Log in" %}</h3>
<hr class="top-hr">
<p style="margin-bottom: 20px;">{% blocktrans %}Already signed up?<br>By logging in you can retrieve saved billing information.{% endblocktrans %}</p>
<form role="form" id="login-form" method="post" action="" novalidate>
{% for field in login_form %}
{% csrf_token %}
{% bootstrap_field field show_label=False type='fields'%}
{% endfor %}
<p class="text-danger">{{login_form.non_field_errors|striptags}}</p>
<input type='hidden' name='next' value='{{request.path}}'/>
<div class="form-group text-right">
<button type="submit" class="btn btn-wide btn-vm-contact" name="login_form">{% trans "LOGIN" %}</button>
</div>
</form>
<p>
{% trans "Don't have an account yet?" %}<br>
{% trans "You can sign up by filling in the information below." %}<br>
<a href="{% url 'hosting:reset_password' %}" target="_blank">{% trans "Forgot password?" %}</a> or <a href="{% url 'hosting:resend_activation_link' %}" target="_blank">{% trans "Resend activation link" %}?</a>
</p>
{% endif %}
</div>
</div>
<div class="dcl-payment-box">
<div class="dcl-payment-section">
{% if not request.user.is_authenticated %}
<h3><b>{%trans "Sign up"%}</b></h3>
{% else %}
<h3><b>{%trans "Billing Address"%}</b></h3>
{% endif %}
<hr class="top-hr">
{% for message in messages %}
{% if 'duplicate_email' in message.tags %}
<p class="text-danger">{{message}}</p>
{% endif %}
{% endfor %}
<form role="form" id="billing-form" method="post" action="" novalidate>
{% csrf_token %}
{% for field in billing_address_form %}
{% bootstrap_field field show_label=False type='fields'%}
{% endfor %}
</form>
</div>
</div>
<div class="dcl-payment-box">
<div class="dcl-payment-section">
<h3>{%trans "Your Order" %}</h3>
<hr class="top-hr">
<div class="dcl-payment-order">
<p>{% trans "Cores"%} <strong class="pull-right">{{request.session.specs.cpu|floatformat}}</strong></p>
<hr>
<p>{% trans "Memory"%} <strong class="pull-right">{{request.session.specs.memory|floatformat}} GB</strong></p>
<hr>
<p>{% trans "Disk space"%} <strong class="pull-right">{{request.session.specs.disk_size|floatformat}} GB</strong></p>
<hr>
<p>{% trans "Configuration"%} <strong class="pull-right">{{request.session.template.name}}</strong></p>
<hr>
<p class="last-p"><strong>{%trans "Total" %}</strong>&nbsp;&nbsp;<small>({%trans "including VAT" %})</small> <strong class="pull-right">{{request.session.specs.price}} CHF/{% trans "Month" %}</strong></p>
</div>
</div>
</div>
<div class="dcl-payment-box">
<div class="dcl-payment-section">
<h3><b>{%trans "Credit Card"%}</b></h3>
<hr class="top-hr">
<p>
{% blocktrans %}Please fill in your credit card information below. We are using <a href="https://stripe.com" target="_blank">Stripe</a> for payment and do not store your information in our database.{% endblocktrans %}
</p>
<div>
{% if credit_card_data.last4 %}
<form role="form" id="payment-form-with-creditcard" novalidate>
<h5 class="billing-head">Credit Card</h5>
<h5 class="membership-lead">Last 4: *****{{credit_card_data.last4}}</h5>
<h5 class="membership-lead">Type: {{credit_card_data.cc_brand}}</h5>
<input type="hidden" name="credit_card_needed" value="false"/>
</form>
{% if not messages and not form.non_field_errors %}
<p class="card-warning-content card-warning-addtional-margin">
{% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %}
</p>
{% endif %}
<div id='payment_error'>
{% for message in messages %}
{% if 'failed_payment' or 'make_charge_error' in message.tags %}
<ul class="list-unstyled">
<li>
<p class="card-warning-content card-warning-error">{{ message|safe }}</p>
</li>
</ul>
{% endif %}
{% endfor %}
{% for error in form.non_field_errors %}
<p class="card-warning-content card-warning-error">
{{ error|escape }}
</p>
{% endfor %}
</div>
<div class="text-right">
<button id="payment_button_with_creditcard" class="btn btn-vm-contact" type="submit">{%trans "SUBMIT" %}</button>
</div>
{% else %}
<form action="" id="payment-form-new" method="POST">
<input type="hidden" name="token"/>
<div class="group">
<div class="credit-card-goup">
<div class="card-element card-number-element">
<label>{%trans "Card Number" %}</label>
<div id="card-number-element" class="field my-input"></div>
</div>
<div class="row">
<div class="col-xs-5 card-element card-expiry-element">
<label>{%trans "Expiry Date" %}</label>
<div id="card-expiry-element" class="field my-input"></div>
</div>
<div class="col-xs-3 col-xs-offset-4 card-element card-cvc-element">
<label>{%trans "CVC" %}</label>
<div id="card-cvc-element" class="field my-input"></div>
</div>
</div>
<div class="card-element brand">
<label>{%trans "Card Type" %}</label>
<i class="pf pf-credit-card" id="brand-icon"></i>
</div>
</div>
</div>
<div id="card-errors"></div>
{% if not messages and not form.non_field_errors %}
<p class="card-warning-content">
{% trans "You are not making any payment yet. After placing your order, you will be taken to the Submit Payment Page." %}
</p>
{% endif %}
<div id='payment_error'>
{% for message in messages %}
{% if 'failed_payment' in message.tags or 'make_charge_error' in message.tags or 'error' in message.tags %}
<ul class="list-unstyled">
<li><p class="card-warning-content card-warning-error">{{ message|safe }}</p></li>
</ul>
{% endif %}
{% endfor %}
</div>
<div class="text-right">
<button class="btn btn-vm-contact btn-wide" type="submit">{%trans "SUBMIT" %}</button>
</div>
<div style="display:none;">
<p class="payment-errors"></p>
</div>
</form>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- stripe key data -->
{% if stripe_key %}
{% get_current_language as LANGUAGE_CODE %}
<script type="text/javascript">
window.processing_text = '{%trans "Processing" %}';
window.enter_your_card_text = '{%trans "Enter your credit card number" %}';
(function () {
window.stripeKey = "{{stripe_key}}";
window.current_lan = "{{LANGUAGE_CODE}}";
})();
</script>
{%endif%}
{% if credit_card_data.last4 and credit_card_data.cc_brand %}
<script type="text/javascript">
(function () {
window.hasCreditcard = true;
})();
</script>
{%endif%}
{%endblock%}

View file

@ -1,96 +1,135 @@
{% extends "hosting/base_short.html" %} {% extends "datacenterlight/base_hosting.html" %}
{% load staticfiles bootstrap3 %} {% load staticfiles bootstrap3 i18n custom_tags %}
{% load i18n %}
{% load custom_tags %}
{% block content %} {% block content %}
<div id="order-detail{{order.pk}}" class="order-detail-container">
{% if messages %}
<div class="alert alert-warning">
{% for message in messages %}
<span>{{ message }}</span>
{% endfor %}
</div>
{% endif %}
{% if not error %}
<div class="dashboard-container-head">
<h1 class="dashboard-title-thin">
<img src="{% static 'hosting/img/billing.svg' %}" class="un-icon">{% blocktrans with page_header_text=page_header_text|default:"Invoice" %}{{page_header_text}}{% endblocktrans %}
</h1>
</div>
<div class="order-details">
<p>
<strong>{% trans "Date" %}:</strong>
<span class="locale_date">
{% now "Y-m-d h:i a" %}
</span>
</p>
<hr>
<div>
<address>
<h4>{% trans "Billed to" %}:</h4>
<p>
{% with request.session.billing_address_data as billing_address %}
{{billing_address.cardholder_name}}<br>
{{billing_address.street_address}}, {{billing_address.postal_code}}<br>
{{billing_address.city}}, {{billing_address.country}}
{% endwith %}
</p>
</address>
</div>
<hr>
<div>
<h4>{% trans "Payment method" %}:</h4>
<p>
{{cc_brand|default:_('Credit Card')}} {% trans "ending in" %} ****{{cc_last4}}<br>
{{request.user.email}}
</p>
</div>
<hr>
<div>
<h4>{% trans "Order summary" %}</h4>
<p>
<strong>{% trans "Product" %}:</strong>&nbsp;
{{ request.session.template.name }}
</p>
<div class="row">
<div class="col-sm-6">
<p>
<span>{% trans "Cores" %}: </span>
<span class="pull-right">{{vm.cpu|floatformat}}</span>
</p>
<p>
<span>{% trans "Memory" %}: </span>
<span class="pull-right">{{vm.memory}} GB</span>
</p>
<p>
<span>{% trans "Disk space" %}: </span>
<span class="pull-right">{{vm.disk_size}} GB</span>
</p>
<p>
<span>{% trans "Total" %}</span>
<span class="pull-right">{{vm.price}} CHF</span>
</p>
</div>
</div>
</div>
<hr>
</div>
<form id="virtual_machine_create_form" action="" method="POST">
{% csrf_token %}
<div class="row">
<div class="col-sm-8">
<div class="dcl-place-order-text">{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.</div>
</div>
<div class="col-sm-4 order-confirm-btn text-right">
<button class="btn choice-btn" id="btn-create-vm" data-toggle="modal" data-target="#createvm-modal">
{% trans "Place order" %}
</button>
</div>
</div>
</form>
{% endif %}
</div>
<div class="order-detail-container">
{% if messages %}
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<br/>
<div class="alert alert-warning">
{% for message in messages %}
<span>{{ message }}</span>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% if not error %}
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<div class="invoice-title">
<h2>{% trans "Confirm Order"%}</h2>
</div>
<hr>
<div class="row">
<div class="col-xs-12 col-sm-6 pull-right order-confirm-date">
<address>
<strong>{% trans "Date"%}:</strong><br>
<span id="order-created_at">{% now "Y-m-d H:i" %}</span><br><br>
</address>
</div>
<div class="col-xs-12 col-sm-6">
<address>
<h3><b>{% trans "Billed To:"%}</b></h3>
{% with request.session.billing_address_data as billing_address %}
{{billing_address|get_value_from_dict:'cardholder_name'}}<br> {{billing_address|get_value_from_dict:'street_address'}}, {{billing_address|get_value_from_dict:'postal_code'}}<br>
{{billing_address|get_value_from_dict:'city'}}, {{billing_address|get_value_from_dict:'country'}}.
{% endwith %}
</address>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<address>
<strong>{% trans "Payment Method:"%}</strong><br>
{{cc_brand}} {% trans "ending" %} **** {{cc_last4}}<br>
{{request.session.user.email}}
</address>
</div>
</div>
</div>
</div>
<div class="row"> <!-- Create VM Modal -->
<div class="col-md-8 col-md-offset-2"> <div class="modal fade" id="createvm-modal" tabindex="-1" role="dialog"
<h3><b>{% trans "Order summary"%}</b></h3> aria-hidden="true" data-backdrop="static" data-keyboard="false">
<hr> <div class="modal-dialog">
<div class="content"> <div class="modal-content">
{% with request.session.specs as vm %} <div class="modal-header">
<p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cpu}}</span></p> </div>
<hr> <div class="modal-body">
<p><b>{% trans "Memory"%}</b> <span class="pull-right">{{vm.memory}} GB</span></p> <div class="modal-icon">
<hr> <i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
<p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p> <span class="sr-only">{% trans "Processing..." %}</span>
<hr> </div>
<p><b>{% trans "Configuration"%}</b> <span class="pull-right">{{request.session.template.name}}</span></p> <h4 class="modal-title" id="createvm-modal-title"></h4>
<hr> <div class="modal-text" id="createvm-modal-body">
<h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4> {% trans "Hold tight, we are processing your request" %}
{% endwith %} </div>
</div> <div class="modal-footer">
<br/> <a id="createvm-modal-done-btn" class="btn btn-success btn-ok btn-wide hide" href="{% url 'hosting:virtual_machines' %}">{% trans "OK" %}</a>
<form method="post"> <button id="createvm-modal-close-btn" type="button" class="btn btn-danger btn-ok btn-wide hide" data-dismiss="modal" aria-label="create-vm-close">{% trans "Close" %}</button>
{% csrf_token %}
<div class=" content pull-right">
<a href="{{next_url}}" ><button class="btn btn-info">{% trans "Place order"%}</button></a>
</div>
</form>
</div> </div>
</div> </div>
{% endif %} </div>
</div> </div>
</div>
<!-- / Create VM Modal -->
<script type="text/javascript">
<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 () { window.onload = function () {
var locale_date = moment.utc(document.getElementById("order-created_at").textContent,'YYYY-MM-DD HH:mm').toDate(); var locale_dates = document.getElementsByClassName("locale_date");
locale_date = moment(locale_date).format("YYYY-MM-DD h:mm:ss a"); var formats = ['YYYY-MM-DD hh:mm a']
document.getElementById('order-created_at').innerHTML = locale_date; 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;
</script> locale_dates[i].innerHTML = oldDate.local().format(outputFormat);
{%endblock%} locale_dates[i].className += ' done';
}
};
</script>
{%endblock%}

View file

@ -1,96 +0,0 @@
{% extends "datacenterlight/base.html" %}
{% load staticfiles i18n%}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="intro-pricing">
<div class="intro-message">
<h2 class="section-heading">{% trans "We are cutting down the costs significantly!" %}</h2>
</div>
</div>
<div class="price-calc-section">
<div class="card">
<img class="img-beta" src="{% static 'datacenterlight/img/beta-img.png' %}" alt="">
<div class="caption">
<form method="POST" action="">
{% csrf_token %}
<div class="title">
<h3>{% trans "VM hosting" %} </h3>
</div>
<div class="price">
<span id="total">15</span>
<span>CHF</span>
<div class="price-text">
<p>{% trans "VAT included" %}</p>
</div>
</div>
<div class="descriptions">
<div class="description">
<p>{% trans "Hosted in Switzerland" %}</p>
</div>
<div class="description">
<i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i>
<input class="input-price" type="number" min="1" max="42" id="coreValue" name="cpu">
<span> Core</span>
<i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i>
</div>
<div class="description">
<i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i>
<input id="ramValue" class="input-price" type="number" min="2" max="200" name="ram">
<span> GB RAM</span>
<i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i>
</div>
<div class="description">
<i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i>
<input id="storageValue" class="input-price" type="number" min="10" max="500" step="10" name="storage">
<span>{% trans "GB Storage (SSD)" %}</span>
<i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i>
</div>
<div class="description select-configuration input">
<label for="name">OS</label>
<select name="config" id="">
{% for template in templates %}
<option value="{{template.id}}">{{template.name}} </option>
{% endfor %}
</select>
</div>
<input type="hidden" name="total">
<!-- <div class="description input">
<label for="name">Name</label>
<input type="text" name="name" placeholder="Your Name">
</div>
<div class="description input">
<label for="email">Email</label>
<input type="email" name="email" placeholder="Your Email">
</div> -->
<!--<div class="description check-ip">
<input type="checkbox" name="ipv6"> Ipv6 Only<br>
</div>-->
</div>
<input type="submit" class="btn btn-primary" value="{% trans 'Order Now!' %}"></input>
</form>
</div>
</div>
<div class="text">
<h2 class="section-heading">{% trans "Simple and affordable: Try our virtual machine with featherlight price." %}</h2>
<div class="description">
<p>{% trans "Our VMs are hosted in Glarus, Switzerland, and our website is currently running in BETA mode. If you want more information that you did not find on our website, or if your order is more detailed, or if you encounter any technical hiccups, please contact us at support@datacenterlight.ch, our team will get in touch with you asap." %}</p>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,32 +0,0 @@
{% extends "datacenterlight/base.html" %}
{% load staticfiles i18n %}
{% block content %}
<div class="intro-pricing success-pricing">
<div class="intro-message">
<h2 class="section-heading">{% trans "Thank you for order! Our team will contact you via email" %}</h2>
{% if LANGUAGE_CODE == 'en-us'%}
<h2 class="section-heading">{% trans "as soon as possible!" %}</h2>
{% endif %}
</div>
</div>
<script type="text/javascript">
window.onload=function(){
$('.selectpicker').selectpicker({
style: 'btn-link',
windowPadding: 10,
});
var hash = window.location.hash.substr(1);
console.log(hash);
if (hash == 'requestform'){
$('#reques-success-message').modal('show');
}
};
</script>
{% endblock %}

View file

@ -135,9 +135,8 @@
<div class="col-xs-12 col-md-6 hero-feature"> <div class="col-xs-12 col-md-6 hero-feature">
<div class="price-calc-section no-padding"> <div class="price-calc-section no-padding">
<div class="landing card"> <div class="landing card">
<img class="img-beta" src="{% static 'datacenterlight/img/beta-img.png' %}" alt="">
<div class="caption"> <div class="caption">
{% include "datacenterlight/calculator_form.html" %} {% include "datacenterlight/includes/_calculator_form.html" %}
</div> </div>
</div> </div>
</div> </div>

View file

@ -31,3 +31,14 @@ def get_value_from_dict(dict_data, key):
return dict_data.get(key) return dict_data.get(key)
else: else:
return "" return ""
@register.filter('multiply')
def multiply(value, arg):
"""
usage: {{ quantity|multiply:price }}
:param value:
:param arg:
:return:
"""
return value*arg

View file

@ -1,3 +1,142 @@
# from django.test import TestCase # from django.test import TestCase
# Create your tests here. from time import sleep
import stripe
from celery.result import AsyncResult
from django.conf import settings
from django.core.management import call_command
from django.test import TestCase, override_settings
from model_mommy import mommy
from unittest import skipIf
from datacenterlight.models import VMTemplate
from datacenterlight.tasks import create_vm_task
from membership.models import StripeCustomer
from opennebula_api.serializers import VMTemplateSerializer
from utils.hosting_utils import get_vm_price
from utils.stripe_utils import StripeUtils
@skipIf(
settings.STRIPE_API_PRIVATE_KEY_TEST is None or
settings.STRIPE_API_PRIVATE_KEY_TEST is "",
"""Stripe details unavailable, so skipping CeleryTaskTestCase"""
)
class CeleryTaskTestCase(TestCase):
@override_settings(
task_eager_propagates=True,
task_always_eager=True,
)
def setUp(self):
self.customer_password = 'test_password'
self.customer_email = 'celery-createvm-task-test@ungleich.ch'
self.customer_name = "Monty Python"
self.user = {
'email': self.customer_email,
'name': self.customer_name
}
self.customer = mommy.make('membership.CustomUser')
self.customer.set_password(self.customer_password)
self.customer.email = self.customer_email
self.customer.save()
self.stripe_utils = StripeUtils()
stripe.api_key = settings.STRIPE_API_PRIVATE_KEY_TEST
self.token = stripe.Token.create(
card={
"number": '4111111111111111',
"exp_month": 12,
"exp_year": 2022,
"cvc": '123'
},
)
# Run fetchvmtemplates so that we have the VM templates from
# OpenNebula
call_command('fetchvmtemplates')
@skipIf(
settings.OPENNEBULA_DOMAIN is None or settings.OPENNEBULA_DOMAIN is
"test_domain",
"""OpenNebula details unavailable, so skipping test_create_vm_task"""
)
def test_create_vm_task(self):
"""Tests the create vm task for monthly subscription
This test is supposed to validate the proper execution
of celery create_vm_task on production, as we have no
other way to do this.
"""
# We create a VM from the first template available to DCL
vm_template = VMTemplate.objects.all().first()
template_data = VMTemplateSerializer(vm_template).data
# The specs of VM that we want to create
specs = {
'cpu': 1,
'memory': 2,
'disk_size': 10,
'price': 15
}
stripe_customer = StripeCustomer.get_or_create(
email=self.customer_email,
token=self.token)
card_details = self.stripe_utils.get_card_details(
stripe_customer.stripe_id,
self.token)
card_details_dict = card_details.get('response_object')
billing_address_data = {'cardholder_name': self.customer_name,
'postal_code': '1231',
'country': 'CH',
'token': self.token,
'street_address': 'Monty\'s Street',
'city': 'Hollywood'}
vm_template_id = template_data.get('id', 1)
cpu = specs.get('cpu')
memory = specs.get('memory')
disk_size = specs.get('disk_size')
amount_to_be_charged = get_vm_price(cpu=cpu, memory=memory,
disk_size=disk_size)
plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu,
memory=memory,
disk_size=disk_size)
stripe_plan_id = StripeUtils.get_stripe_plan_id(cpu=cpu,
ram=memory,
ssd=disk_size,
version=1,
app='dcl')
stripe_plan = self.stripe_utils.get_or_create_stripe_plan(
amount=amount_to_be_charged,
name=plan_name,
stripe_plan_id=stripe_plan_id)
subscription_result = self.stripe_utils.subscribe_customer_to_plan(
stripe_customer.stripe_id,
[{"plan": stripe_plan.get(
'response_object').stripe_plan_id}])
stripe_subscription_obj = subscription_result.get('response_object')
# Check if the subscription was approved and is active
if stripe_subscription_obj is None \
or stripe_subscription_obj.status != 'active':
msg = subscription_result.get('error')
raise Exception("Creating subscription failed: {}".format(msg))
async_task = create_vm_task.delay(
vm_template_id, self.user, specs, template_data,
stripe_customer.id, billing_address_data,
stripe_subscription_obj.id, card_details_dict
)
new_vm_id = 0
res = None
for i in range(0, 10):
sleep(5)
res = AsyncResult(async_task.task_id)
if res.result is not None and res.result > 0:
new_vm_id = res.result
break
# We expect a VM to be created within 50 seconds
self.assertGreater(new_vm_id, 0,
"VM could not be created. res._get_task_meta() = {}"
.format(res._get_task_meta()))

View file

@ -1,22 +1,24 @@
from django.conf.urls import url from django.conf.urls import url
from django.views.generic import TemplateView from django.views.generic import TemplateView
from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView, SuccessView, \ from .views import (
PaymentOrderView, OrderConfirmationView, WhyDataCenterLightView IndexView, PaymentOrderView, OrderConfirmationView,
WhyDataCenterLightView, ContactUsView
)
urlpatterns = [ urlpatterns = [
url(r'^$', IndexView.as_view(), name='index'), url(r'^$', IndexView.as_view(), name='index'),
url(r'^t/$', IndexView.as_view(), name='index_t'),
url(r'^g/$', IndexView.as_view(), name='index_g'),
url(r'^f/$', IndexView.as_view(), name='index_f'),
url(r'^l/$', IndexView.as_view(), name='index_l'),
url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(), url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(),
name='whydatacenterlight'), name='whydatacenterlight'),
url(r'^beta-program/?$', BetaProgramView.as_view(), name='beta'),
url(r'^landing/?$', LandingProgramView.as_view(), name='landing'),
url(r'^pricing/?$', PricingView.as_view(), name='pricing'),
url(r'^payment/?$', PaymentOrderView.as_view(), name='payment'), url(r'^payment/?$', PaymentOrderView.as_view(), name='payment'),
url(r'^order-confirmation/?$', OrderConfirmationView.as_view(), url(r'^order-confirmation/?$', OrderConfirmationView.as_view(),
name='order_confirmation'), name='order_confirmation'),
url(r'^order-success/?$', SuccessView.as_view(), name='order_success'), url(r'^contact/?$', ContactUsView.as_view(), name='contact_us'),
url(r'^beta_access?$', BetaAccessView.as_view(), name='beta_access'), url(r'glasfaser/?$',
TemplateView.as_view(template_name='ungleich_page/glasfaser.html'),
url(r'test/?$', TemplateView.as_view(template_name='datacenterlight/downtime.html')), name='glasfaser'),
] ]

View file

@ -1,199 +1,81 @@
from django.views.generic import FormView, CreateView, TemplateView, DetailView import json
from django.http import HttpResponseRedirect import logging
from .forms import BetaAccessForm
from .models import BetaAccess, BetaAccessVMType, BetaAccessVM, VMTemplate
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.core.mail import EmailMessage
from utils.mailer import BaseEmail
from django.shortcuts import render
from django.shortcuts import redirect
from django import forms from django import forms
from django.core.exceptions import ValidationError
from django.views.decorators.cache import cache_control
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.contrib import messages
from utils.forms import BillingAddressForm, UserBillingAddressForm from django.contrib.auth import login, authenticate
from utils.models import BillingAddress from django.core.exceptions import ValidationError
from hosting.models import HostingOrder, HostingBill from django.core.urlresolvers import reverse
from utils.stripe_utils import StripeUtils from django.http import HttpResponseRedirect, HttpResponse
from datetime import datetime from django.shortcuts import render
from django.utils.translation import get_language, ugettext_lazy as _
from django.views.decorators.cache import cache_control
from django.views.generic import FormView, CreateView, DetailView
from datacenterlight.tasks import create_vm_task
from hosting.forms import HostingUserLoginForm
from hosting.models import HostingOrder
from membership.models import CustomUser, StripeCustomer from membership.models import CustomUser, StripeCustomer
from opennebula_api.models import OpenNebulaManager from opennebula_api.serializers import VMTemplateSerializer
from opennebula_api.serializers import VirtualMachineTemplateSerializer, VirtualMachineSerializer, VMTemplateSerializer from utils.forms import (
BillingAddressForm, BillingAddressFormSignup
)
from utils.hosting_utils import get_vm_price
from utils.stripe_utils import StripeUtils
from utils.tasks import send_plain_email_task
from .forms import ContactForm
from .models import VMTemplate
logger = logging.getLogger(__name__)
class LandingProgramView(TemplateView): class ContactUsView(FormView):
template_name = "datacenterlight/landing.html" template_name = "datacenterlight/contact_form.html"
form_class = ContactForm
class SuccessView(TemplateView):
template_name = "datacenterlight/success.html"
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if 'specs' not in request.session or 'user' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:index'))
return HttpResponseRedirect(reverse('datacenterlight:index'))
elif 'token' not in request.session: def form_invalid(self, form):
return HttpResponseRedirect(reverse('datacenterlight:payment')) if self.request.is_ajax():
elif 'order_confirmation' not in request.session: return self.render_to_response(
return HttpResponseRedirect(reverse('datacenterlight:order_confirmation')) self.get_context_data(contact_form=form))
else: else:
for session_var in ['specs', 'user', 'template', 'billing_address', 'billing_address_data', return render(self.request,
'token', 'customer']: 'datacenterlight/index.html',
if session_var in request.session: self.get_context_data(contact_form=form))
del request.session[session_var]
return render(request, self.template_name)
class PricingView(TemplateView):
template_name = "datacenterlight/pricing.html"
def get(self, request, *args, **kwargs):
try:
manager = OpenNebulaManager()
templates = manager.get_templates()
context = {
'templates': VirtualMachineTemplateSerializer(templates, many=True).data,
}
except:
messages.error(request,
'We have a temporary problem to connect to our backend. \
Please try again in a few minutes'
)
context = {
'error': 'connection'
}
return render(request, self.template_name, context)
def post(self, request):
cores = request.POST.get('cpu')
memory = request.POST.get('ram')
storage = request.POST.get('storage')
price = request.POST.get('total')
template_id = int(request.POST.get('config'))
manager = OpenNebulaManager()
template = manager.get_template(template_id)
request.session['template'] = VirtualMachineTemplateSerializer(
template).data
if not request.user.is_authenticated():
request.session['next'] = reverse('hosting:payment')
request.session['specs'] = {
'cpu': cores,
'memory': memory,
'disk_size': storage,
'price': price,
}
return redirect(reverse('hosting:payment'))
class BetaAccessView(FormView):
template_name = "datacenterlight/beta_access.html"
form_class = BetaAccessForm
success_message = "Thank you, we will contact you as soon as possible"
def form_valid(self, form): def form_valid(self, form):
context = { form.save()
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host()) from_emails = {
'glasfaser': 'glasfaser@ungleich.ch'
} }
from_page = self.request.POST.get('from_page')
email_data = { email_data = {
'subject': 'DatacenterLight Beta Access Request', 'subject': "{dcl_text} Message from {sender}".format(
'from_address': '(datacenterlight) datacenterlight Support <support@datacenterlight.ch>', dcl_text=settings.DCL_TEXT,
'to': form.cleaned_data.get('email'), sender=form.cleaned_data.get('email')
'from': '(datacenterlight) DatacenterLight Support support@datacenterlight.ch', ),
'context': context, 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
'template_name': 'request_access_confirmation', 'to': [from_emails.get(from_page, 'info@ungleich.ch')],
'template_path': 'datacenterlight/emails/' 'body': "\n".join(
["%s=%s" % (k, v) for (k, v) in form.cleaned_data.items()]),
'reply_to': [form.cleaned_data.get('email')],
} }
email = BaseEmail(**email_data) send_plain_email_task.delay(email_data)
email.send() if self.request.is_ajax():
return self.render_to_response(
context.update({ self.get_context_data(success=True, contact_form=form))
'email': form.cleaned_data.get('email') else:
}) return render(self.request,
'datacenterlight/index.html',
email_data = { self.get_context_data(success=True,
'subject': 'DatacenterLight Beta Access Request', contact_form=form))
'from_address': '(datacenterlight) datacenterlight Support <support@datacenterlight.ch>',
'to': 'info@ungleich.ch',
'context': context,
'template_name': 'request_access_notification',
'template_path': 'datacenterlight/emails/'
}
email = BaseEmail(**email_data)
email.send()
messages.add_message(
self.request, messages.SUCCESS, self.success_message)
return render(self.request, 'datacenterlight/beta_success.html', {})
class BetaProgramView(CreateView):
template_name = "datacenterlight/beta.html"
model = BetaAccessVM
fields = '__all__'
# form_class = BetaAccessForm
# success_url = "/datacenterlight#requestform"
success_message = "Thank you, we will contact you as soon as possible"
def get_success_url(self):
success_url = reverse('datacenterlight:beta')
success_url += "#success"
return success_url
def get_context_data(self, **kwargs):
vms = BetaAccessVMType.objects.all()
context = super(BetaProgramView, self).get_context_data(**kwargs)
# templates = OpenNebulaManager().get_templates()
# data = VirtualMachineTemplateSerializer(templates, many=True).data
context.update({
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host()),
'vms': vms
})
return context
def post(self, request, *args, **kwargs):
data = request.POST
vms = BetaAccessVM.create(data)
context = {
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host()),
'email': data.get('email'),
'name': data.get('name'),
'vms': vms
}
email_data = {
'subject': 'DatacenterLight Beta Access Request',
'from_address': '(datacenterlight) datacenterlight Support <support@datacenterlight.ch>',
'to': 'info@ungleich.ch',
'context': context,
'template_name': 'request_beta_access_notification',
'template_path': 'datacenterlight/emails/'
}
email = BaseEmail(**email_data)
email.send()
messages.add_message(
self.request, messages.SUCCESS, self.success_message)
return HttpResponseRedirect(self.get_success_url())
class IndexView(CreateView): class IndexView(CreateView):
template_name = "datacenterlight/index.html" template_name = "datacenterlight/index.html"
model = BetaAccess
form_class = BetaAccessForm
success_url = "/datacenterlight#requestform" success_url = "/datacenterlight#requestform"
success_message = "Thank you, we will contact you as soon as possible" success_message = "Thank you, we will contact you as soon as possible"
@ -202,7 +84,7 @@ class IndexView(CreateView):
raise ValidationError(_('Invalid number of cores')) raise ValidationError(_('Invalid number of cores'))
def validate_memory(self, value): def validate_memory(self, value):
if (value > 200) or (value < 2): if (value > 200) or (value < 1):
raise ValidationError(_('Invalid RAM size')) raise ValidationError(_('Invalid RAM size'))
def validate_storage(self, value): def validate_storage(self, value):
@ -228,72 +110,47 @@ class IndexView(CreateView):
memory_field = forms.IntegerField(validators=[self.validate_memory]) memory_field = forms.IntegerField(validators=[self.validate_memory])
storage = request.POST.get('storage') storage = request.POST.get('storage')
storage_field = forms.IntegerField(validators=[self.validate_storage]) storage_field = forms.IntegerField(validators=[self.validate_storage])
price = request.POST.get('total')
template_id = int(request.POST.get('config')) template_id = int(request.POST.get('config'))
template = VMTemplate.objects.filter( template = VMTemplate.objects.filter(
opennebula_vm_template_id=template_id).first() opennebula_vm_template_id=template_id).first()
template_data = VMTemplateSerializer(template).data template_data = VMTemplateSerializer(template).data
name = request.POST.get('name')
email = request.POST.get('email')
name_field = forms.CharField()
email_field = forms.EmailField()
try: try:
cores = cores_field.clean(cores) cores = cores_field.clean(cores)
except ValidationError as err: except ValidationError as err:
msg = '{} : {}.'.format(cores, str(err)) msg = '{} : {}.'.format(cores, str(err))
messages.add_message( messages.add_message(self.request, messages.ERROR, msg,
self.request, messages.ERROR, msg, extra_tags='cores') extra_tags='cores')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(
reverse('datacenterlight:index') + "#order_form")
try: try:
memory = memory_field.clean(memory) memory = memory_field.clean(memory)
except ValidationError as err: except ValidationError as err:
msg = '{} : {}.'.format(memory, str(err)) msg = '{} : {}.'.format(memory, str(err))
messages.add_message( messages.add_message(self.request, messages.ERROR, msg,
self.request, messages.ERROR, msg, extra_tags='memory') extra_tags='memory')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(
reverse('datacenterlight:index') + "#order_form")
try: try:
storage = storage_field.clean(storage) storage = storage_field.clean(storage)
except ValidationError as err: except ValidationError as err:
msg = '{} : {}.'.format(storage, str(err)) msg = '{} : {}.'.format(storage, str(err))
messages.add_message( messages.add_message(self.request, messages.ERROR, msg,
self.request, messages.ERROR, msg, extra_tags='storage') extra_tags='storage')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(
reverse('datacenterlight:index') + "#order_form")
try: amount_to_be_charged = get_vm_price(cpu=cores, memory=memory,
name = name_field.clean(name) disk_size=storage)
except ValidationError as err:
msg = '{} {}.'.format(name, _('is not a proper name'))
messages.add_message(
self.request, messages.ERROR, msg, extra_tags='name')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try:
email = email_field.clean(email)
except ValidationError as err:
msg = '{} {}.'.format(email, _('is not a proper email'))
messages.add_message(
self.request, messages.ERROR, msg, extra_tags='email')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
specs = { specs = {
'cpu': cores, 'cpu': cores,
'memory': memory, 'memory': memory,
'disk_size': storage, 'disk_size': storage,
'price': price 'price': amount_to_be_charged
} }
this_user = {
'name': name,
'email': email
}
request.session['specs'] = specs request.session['specs'] = specs
request.session['template'] = template_data request.session['template'] = template_data
request.session['user'] = this_user
return HttpResponseRedirect(reverse('datacenterlight:payment')) return HttpResponseRedirect(reverse('datacenterlight:payment'))
def get_success_url(self): def get_success_url(self):
@ -304,126 +161,172 @@ class IndexView(CreateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs) context = super(IndexView, self).get_context_data(**kwargs)
context.update({ context.update({
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host()) 'base_url': "{0}://{1}".format(self.request.scheme,
self.request.get_host()),
'contact_form': ContactForm
}) })
return context return context
def form_valid(self, form):
context = {
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host())
}
email_data = {
'subject': 'DatacenterLight Beta Access Request',
'from_address': '(datacenterlight) datacenterlight Support <support@datacenterlight.ch>',
'to': form.cleaned_data.get('email'),
'from': '(datacenterlight) DatacenterLight Support support@datacenterlight.ch',
'context': context,
'template_name': 'request_access_confirmation',
'template_path': 'datacenterlight/emails/'
}
email = BaseEmail(**email_data)
email.send()
context.update({
'email': form.cleaned_data.get('email')
})
email_data = {
'subject': 'DatacenterLight Beta Access Request',
'from_address': '(datacenterlight) datacenterlight Support <support@datacenterlight.ch>',
'to': 'info@ungleich.ch',
'context': context,
'template_name': 'request_access_notification',
'template_path': 'datacenterlight/emails/'
}
email = BaseEmail(**email_data)
email.send()
messages.add_message(
self.request, messages.SUCCESS, self.success_message)
return super(IndexView, self).form_valid(form)
class WhyDataCenterLightView(IndexView): class WhyDataCenterLightView(IndexView):
template_name = "datacenterlight/whydatacenterlight.html" template_name = "datacenterlight/whydatacenterlight.html"
model = BetaAccess
class PaymentOrderView(FormView): class PaymentOrderView(FormView):
template_name = 'hosting/payment.html' template_name = 'datacenterlight/landing_payment.html'
form_class = BillingAddressForm
def get_form_kwargs(self): def get_form_class(self):
form_kwargs = super(PaymentOrderView, self).get_form_kwargs() if self.request.user.is_authenticated():
billing_address_data = self.request.session.get('billing_address_data') return BillingAddressForm
if billing_address_data: else:
form_kwargs.update({ return BillingAddressFormSignup
'initial': {
'cardholder_name': billing_address_data['cardholder_name'],
'street_address': billing_address_data['street_address'],
'city': billing_address_data['city'],
'postal_code': billing_address_data['postal_code'],
'country': billing_address_data['country'],
}
})
return form_kwargs
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(PaymentOrderView, self).get_context_data(**kwargs) context = super(PaymentOrderView, self).get_context_data(**kwargs)
if 'billing_address_data' in self.request.session:
billing_address_data = self.request.session['billing_address_data']
else:
billing_address_data = {}
if self.request.user.is_authenticated():
if billing_address_data:
billing_address_form = BillingAddressForm(
initial=billing_address_data
)
else:
billing_address_form = BillingAddressForm(
instance=self.request.user.billing_addresses.first()
)
# Get user last order
last_hosting_order = HostingOrder.objects.filter(
customer__user=self.request.user
).last()
# If user has already an hosting order, get the credit card
# data from it
if last_hosting_order:
credit_card_data = last_hosting_order.get_cc_data()
if credit_card_data:
context['credit_card_data'] = credit_card_data
else:
context['credit_card_data'] = None
else:
billing_address_form = BillingAddressFormSignup(
initial=billing_address_data
)
context.update({ context.update({
'stripe_key': settings.STRIPE_API_PUBLIC_KEY, 'stripe_key': settings.STRIPE_API_PUBLIC_KEY,
'site_url': reverse('datacenterlight:index') 'site_url': reverse('datacenterlight:index'),
'login_form': HostingUserLoginForm(prefix='login_form'),
'billing_address_form': billing_address_form
}) })
return context return context
@cache_control(no_cache=True, must_revalidate=True, no_store=True) @cache_control(no_cache=True, must_revalidate=True, no_store=True)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if 'specs' not in request.session or 'user' not in request.session: if 'specs' not in request.session:
return HttpResponseRedirect(reverse('datacenterlight:index')) return HttpResponseRedirect(reverse('datacenterlight:index'))
return self.render_to_response(self.get_context_data()) return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
form = self.get_form() if 'login_form' in request.POST:
if form.is_valid(): login_form = HostingUserLoginForm(data=request.POST,
# Get billing address data prefix='login_form')
billing_address_data = form.cleaned_data if login_form.is_valid():
token = form.cleaned_data.get('token') email = login_form.cleaned_data.get('email')
user = request.session.get('user') password = login_form.cleaned_data.get('password')
try: auth_user = authenticate(email=email, password=password)
CustomUser.objects.get(email=user.get('email')) if auth_user:
except CustomUser.DoesNotExist: login(self.request, auth_user)
password = CustomUser.get_random_password() return HttpResponseRedirect(
# Register the user, and do not send emails reverse('datacenterlight:payment')
CustomUser.register(user.get('name'), )
password, else:
user.get('email'), context = self.get_context_data()
app='dcl', context['login_form'] = login_form
base_url=None, send_email=False) return self.render_to_response(context)
if request.user.is_authenticated():
# Get or create stripe customer address_form = BillingAddressForm(
customer = StripeCustomer.get_or_create(email=user.get('email'), data=request.POST,
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()
request.session['billing_address_data'] = billing_address_data
request.session['billing_address'] = billing_address.id
request.session['token'] = token
request.session['customer'] = customer.id
return HttpResponseRedirect(reverse('datacenterlight:order_confirmation'))
else: else:
return self.form_invalid(form) address_form = BillingAddressFormSignup(
data=request.POST,
)
if address_form.is_valid():
token = address_form.cleaned_data.get('token')
if request.user.is_authenticated():
this_user = {
'email': request.user.email,
'name': request.user.name
}
customer = StripeCustomer.get_or_create(
email=this_user.get('email'),
token=token)
else:
user_email = address_form.cleaned_data.get('email')
user_name = address_form.cleaned_data.get('name')
this_user = {
'email': user_email,
'name': user_name
}
try:
custom_user = CustomUser.objects.get(email=user_email)
customer = StripeCustomer.objects.filter(
user_id=custom_user.id).first()
if customer is None:
logger.debug(
("User {email} is already registered with us."
"But, StripeCustomer does not exist for {email}."
"Hence, creating a new StripeCustomer.").format(
email=user_email
)
)
customer = StripeCustomer.create_stripe_api_customer(
email=user_email,
token=token,
customer_name=user_name)
except CustomUser.DoesNotExist:
logger.debug(
("StripeCustomer does not exist for {email}."
"Hence, creating a new StripeCustomer.").format(
email=user_email
)
)
customer = StripeCustomer.create_stripe_api_customer(
email=user_email,
token=token,
customer_name=user_name)
request.session['billing_address_data'] = address_form.cleaned_data
request.session['user'] = this_user
# Get or create stripe customer
if not customer:
address_form.add_error(
"__all__", "Invalid credit card"
)
return self.render_to_response(
self.get_context_data(
billing_address_form=address_form
)
)
request.session['token'] = token
if type(customer) is StripeCustomer:
request.session['customer'] = customer.stripe_id
else:
request.session['customer'] = customer
return HttpResponseRedirect(
reverse('datacenterlight:order_confirmation'))
else:
context = self.get_context_data()
context['billing_address_form'] = address_form
return self.render_to_response(context)
class OrderConfirmationView(DetailView): class OrderConfirmationView(DetailView):
template_name = "datacenterlight/order_detail.html" template_name = "datacenterlight/order_detail.html"
payment_template_name = 'hosting/payment.html' payment_template_name = 'datacenterlight/landing_payment.html'
context_object_name = "order" context_object_name = "order"
model = HostingOrder model = HostingOrder
@ -433,15 +336,24 @@ class OrderConfirmationView(DetailView):
return HttpResponseRedirect(reverse('datacenterlight:index')) return HttpResponseRedirect(reverse('datacenterlight:index'))
if 'token' not in request.session: if 'token' not in request.session:
return HttpResponseRedirect(reverse('datacenterlight:payment')) return HttpResponseRedirect(reverse('datacenterlight:payment'))
stripe_customer_id = request.session.get('customer') stripe_api_cus_id = request.session.get('customer')
customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
stripe_utils = StripeUtils() stripe_utils = StripeUtils()
card_details = stripe_utils.get_card_details( card_details = stripe_utils.get_card_details(stripe_api_cus_id,
customer.stripe_id, request.session.get('token')) request.session.get(
'token'))
if not card_details.get('response_object'):
msg = card_details.get('error')
messages.add_message(self.request, messages.ERROR, msg,
extra_tags='failed_payment')
return HttpResponseRedirect(
reverse('datacenterlight:payment') + '#payment_error')
context = { context = {
'site_url': reverse('datacenterlight:index'), 'site_url': reverse('datacenterlight:index'),
'cc_last4': card_details.get('response_object').get('last4'), 'cc_last4': card_details.get('response_object').get('last4'),
'cc_brand': card_details.get('response_object').get('brand') 'cc_brand': card_details.get('response_object').get('brand'),
'vm': request.session.get('specs'),
'page_header_text': _('Confirm Order'),
'billing_address_data': request.session.get('billing_address_data')
} }
return render(request, self.template_name, context) return render(request, self.template_name, context)
@ -449,96 +361,144 @@ class OrderConfirmationView(DetailView):
template = request.session.get('template') template = request.session.get('template')
specs = request.session.get('specs') specs = request.session.get('specs')
user = request.session.get('user') user = request.session.get('user')
stripe_customer_id = request.session.get('customer') stripe_api_cus_id = request.session.get('customer')
customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
billing_address_data = request.session.get('billing_address_data')
billing_address_id = request.session.get('billing_address')
billing_address = BillingAddress.objects.filter(
id=billing_address_id).first()
vm_template_id = template.get('id', 1) vm_template_id = template.get('id', 1)
final_price = specs.get('price')
# Make stripe charge to a customer
stripe_utils = StripeUtils() stripe_utils = StripeUtils()
charge_response = stripe_utils.make_charge(amount=final_price, card_details = stripe_utils.get_card_details(stripe_api_cus_id,
customer=customer.stripe_id) request.session.get(
charge = charge_response.get('response_object') 'token'))
if not card_details.get('response_object'):
msg = card_details.get('error')
messages.add_message(self.request, messages.ERROR, msg,
extra_tags='failed_payment')
response = {
'status': False,
'redirect': "{url}#{section}".format(
url=reverse('datacenterlight:payment'),
section='payment_error'),
'msg_title': str(_('Error.')),
'msg_body': str(
_('There was a payment related error.'
' On close of this popup, you will be redirected back to'
' the payment page.'))
}
return HttpResponse(json.dumps(response),
content_type="application/json")
card_details_dict = card_details.get('response_object')
cpu = specs.get('cpu')
memory = specs.get('memory')
disk_size = specs.get('disk_size')
amount_to_be_charged = specs.get('price')
plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu,
memory=memory,
disk_size=disk_size)
stripe_plan_id = StripeUtils.get_stripe_plan_id(cpu=cpu,
ram=memory,
ssd=disk_size,
version=1,
app='dcl')
stripe_plan = stripe_utils.get_or_create_stripe_plan(
amount=amount_to_be_charged,
name=plan_name,
stripe_plan_id=stripe_plan_id)
subscription_result = stripe_utils.subscribe_customer_to_plan(
stripe_api_cus_id,
[{"plan": stripe_plan.get(
'response_object').stripe_plan_id}])
stripe_subscription_obj = subscription_result.get('response_object')
# Check if the subscription was approved and is active
if (stripe_subscription_obj is None
or stripe_subscription_obj.status != 'active'):
msg = subscription_result.get('error')
messages.add_message(self.request, messages.ERROR, msg,
extra_tags='failed_payment')
response = {
'status': False,
'redirect': "{url}#{section}".format(
url=reverse('datacenterlight:payment'),
section='payment_error'),
'msg_title': str(_('Error.')),
'msg_body': str(
_('There was a payment related error.'
' On close of this popup, you will be redirected back to'
' the payment page.'))
}
return HttpResponse(json.dumps(response),
content_type="application/json")
# Check if the payment was approved # Create user if the user is not logged in and if he is not already
if not charge: # registered
context = {} if not request.user.is_authenticated():
context.update({ try:
'paymentError': charge_response.get('error') custom_user = CustomUser.objects.get(
}) email=user.get('email'))
return render(request, self.payment_template_name, context) stripe_customer = StripeCustomer.objects.filter(
user_id=custom_user.id).first()
if stripe_customer is None:
stripe_customer = StripeCustomer.objects.create(
user=custom_user, stripe_id=stripe_api_cus_id
)
stripe_customer_id = stripe_customer.id
except CustomUser.DoesNotExist:
logger.debug(
"Customer {} does not exist.".format(user.get('email')))
password = CustomUser.get_random_password()
base_url = "{0}://{1}".format(self.request.scheme,
self.request.get_host())
custom_user = CustomUser.register(
user.get('name'), password,
user.get('email'),
app='dcl', base_url=base_url, send_email=True,
account_details=password
)
logger.debug("Created user {}.".format(user.get('email')))
stripe_customer = StripeCustomer.objects. \
create(user=custom_user, stripe_id=stripe_api_cus_id)
stripe_customer_id = stripe_customer.id
new_user = authenticate(username=custom_user.email,
password=password)
login(request, new_user)
else:
# We assume that if the user is here, his/her StripeCustomer
# object already exists
stripe_customer_id = request.user.stripecustomer.id
custom_user = request.user
charge = charge_response.get('response_object') # Save billing address
billing_address_data = request.session.get('billing_address_data')
# Create OpenNebulaManager logger.debug('billing_address_data is {}'.format(billing_address_data))
manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, billing_address_data.update({
password=settings.OPENNEBULA_PASSWORD) 'user': custom_user.id
})
# Create a vm using oneadmin, also specify the name user = {
vm_id = manager.create_vm( 'name': custom_user.name,
template_id=vm_template_id, 'email': custom_user.email,
specs=specs, 'pass': custom_user.password,
ssh_key=settings.ONEADMIN_USER_SSH_PUBLIC_KEY, 'request_scheme': request.scheme,
vm_name="{email}-{template_name}-{date}".format( 'request_host': request.get_host(),
email=user.get('email'), 'language': get_language(),
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
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': settings.DCL_TEXT + " Order from %s" % context['email'], create_vm_task.delay(vm_template_id, user, specs, template,
'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, stripe_customer_id, billing_address_data,
'to': ['info@ungleich.ch'], stripe_subscription_obj.id, card_details_dict)
'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), for session_var in ['specs', 'template', 'billing_address',
'reply_to': [context['email']], 'billing_address_data',
'token', 'customer']:
if session_var in request.session:
del request.session[session_var]
response = {
'status': True,
'redirect': reverse(
'hosting:virtual_machines') if request.user.is_authenticated() else reverse(
'datacenterlight:index'),
'msg_title': str(_('Thank you for the order.')),
'msg_body': str(
_('Your VM will be up and running in a few moments.'
' We will send you a confirmation email as soon as'
' it is ready.'))
} }
email = EmailMessage(**email_data)
email.send() return HttpResponse(json.dumps(response),
request.session['order_confirmation'] = True content_type="application/json")
return HttpResponseRedirect(reverse('datacenterlight:order_success'))

View file

@ -13,6 +13,7 @@ while true; do
case "$1" in case "$1" in
-h | --help ) HELP=true; shift ;; -h | --help ) HELP=true; shift ;;
-v | --verbose ) VERBOSE=true; shift ;; -v | --verbose ) VERBOSE=true; shift ;;
-D | --dbmakemigrations ) DB_MAKE_MIGRATIONS=true; shift ;;
-d | --dbmigrate ) DB_MIGRATE=true; shift ;; -d | --dbmigrate ) DB_MIGRATE=true; shift ;;
-n | --nogit ) NO_GIT=true; shift ;; -n | --nogit ) NO_GIT=true; shift ;;
-b | --branch ) BRANCH="$2"; shift 2 ;; -b | --branch ) BRANCH="$2"; shift 2 ;;
@ -31,13 +32,15 @@ if [ "$HELP" == "true" ]; then
echo "options are : " echo "options are : "
echo " -h, --help: Print this help message" echo " -h, --help: Print this help message"
echo " -v, --verbose: Show verbose output to stdout. Without this a deploy.log is written to ~/app folder" echo " -v, --verbose: Show verbose output to stdout. Without this a deploy.log is written to ~/app folder"
echo " -d, --dbmigrate: Do DB migrate" echo " -D, --dbmakemigrations: Do DB makemigrations"
echo " -n, --nogit: Don't execute git commands. With this --branch has no effect." echo " -d, --dbmigrate: Do DB migrate. To do both makemigrations and migrate, supply both switches -D and -d"
echo " -n, --nogit: Don't execute git commands. This is used to deploy the current code in the project repo. With this --branch has no effect."
echo " -b, --branch: The branch to pull from origin repo." echo " -b, --branch: The branch to pull from origin repo."
exit exit
fi fi
echo "BRANCH="$BRANCH echo "BRANCH="$BRANCH
echo "DB_MAKE_MIGRATIONS="$DB_MAKE_MIGRATIONS
echo "DB_MIGRATE="$DB_MIGRATE echo "DB_MIGRATE="$DB_MIGRATE
echo "NO_GIT="$NO_GIT echo "NO_GIT="$NO_GIT
echo "VERBOSE="$VERBOSE echo "VERBOSE="$VERBOSE
@ -45,7 +48,7 @@ echo "VERBOSE="$VERBOSE
# The project directory exists, we pull the specified branch # The project directory exists, we pull the specified branch
cd $APP_HOME_DIR cd $APP_HOME_DIR
if [ -z "$NO_GIT" ]; then if [ -z "$NO_GIT" ]; then
echo 'We are executing default git commands. Please -no_git to not use this.' echo 'We are executing default git commands. Please add --nogit to not do this.'
# Save any modified changes before git pulling # Save any modified changes before git pulling
git stash git stash
# Fetch all branches/tags # Fetch all branches/tags
@ -59,16 +62,23 @@ fi
source ~/pyvenv/bin/activate source ~/pyvenv/bin/activate
pip install -r requirements.txt > deploy.log 2>&1 pip install -r requirements.txt > deploy.log 2>&1
echo "###" >> deploy.log echo "###" >> deploy.log
if [ -z "$DB_MIGRATE" ]; then if [ -z "$DB_MAKE_MIGRATIONS" ]; then
echo 'We are not doing DB migration' echo 'We are not doing DB makemigrations'
else else
echo 'Doing DB makemigrations'
./manage.py makemigrations >> deploy.log 2>&1 ./manage.py makemigrations >> deploy.log 2>&1
echo "###" >> deploy.log echo "###" >> deploy.log
fi
if [ -z "$DB_MIGRATE" ]; then
echo 'We are not doing DB migrate'
else
echo 'Doing DB migrate'
./manage.py migrate >> deploy.log 2>&1 ./manage.py migrate >> deploy.log 2>&1
echo "###" >> deploy.log echo "###" >> deploy.log
fi fi
printf 'yes' | ./manage.py collectstatic >> deploy.log 2>&1 printf 'yes' | ./manage.py collectstatic >> deploy.log 2>&1
echo "###" >> deploy.log echo "###" >> deploy.log
django-admin compilemessages django-admin compilemessages
sudo systemctl restart celery.service
sudo systemctl restart uwsgi sudo systemctl restart uwsgi

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-12-23 22:56
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('digitalglarus', '0024_bookingcancellation'),
]
operations = [
migrations.AddField(
model_name='membershiporder',
name='stripe_subscription_id',
field=models.CharField(max_length=100, null=True),
),
]

View file

@ -1,6 +1,6 @@
import calendar import calendar
import time
from datetime import datetime, date, timedelta from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from django.db import models from django.db import models
@ -59,6 +59,17 @@ class MembershipType(models.Model):
return "{} - {}".format(datetime.strftime(start_date, "%b, %d %Y"), return "{} - {}".format(datetime.strftime(start_date, "%b, %d %Y"),
datetime.strftime(end_date, "%b, %d %Y")) datetime.strftime(end_date, "%b, %d %Y"))
@cached_property
def next_month_in_sec_since_epoch(self):
"""
First day of the next month expressed in seconds since the epoch time
:return: Time in seconds
"""
start_date, end_date = self.first_month_range
first_day_next_month = end_date + timedelta(days=1)
epoch_time = int(time.mktime(first_day_next_month.timetuple()))
return epoch_time
class Membership(models.Model): class Membership(models.Model):
type = models.ForeignKey(MembershipType) type = models.ForeignKey(MembershipType)
@ -71,12 +82,12 @@ class Membership(models.Model):
@classmethod @classmethod
def get_current_membership(cls, user): def get_current_membership(cls, user):
has_order_current_month = Q(
has_order_current_month = Q(membershiporder__customer__user=user, membershiporder__customer__user=user,
membershiporder__created_at__month=datetime.today().month) membershiporder__created_at__month=datetime.today().month
)
# import pdb;pdb.set_trace() # import pdb;pdb.set_trace()
return cls.objects.\ return cls.objects.filter(has_order_current_month).last()
filter(has_order_current_month).last()
# def get_current_active_membership(cls, user): # def get_current_active_membership(cls, user):
# membership = cls.get_current_membership(user) # membership = cls.get_current_membership(user)
@ -84,8 +95,7 @@ class Membership(models.Model):
@classmethod @classmethod
def get_by_user(cls, user): def get_by_user(cls, user):
return cls.objects.\ return cls.objects.filter(membershiporder__customer__user=user).last()
filter(membershiporder__customer__user=user).last()
@classmethod @classmethod
def create(cls, data): def create(cls, data):
@ -96,18 +106,23 @@ class Membership(models.Model):
def activate_or_crete(cls, data, user): def activate_or_crete(cls, data, user):
membership = cls.get_by_user(user) membership = cls.get_by_user(user)
membership_id = membership.id if membership else None membership_id = membership.id if membership else None
obj, created = cls.objects.update_or_create(id=membership_id, defaults=data) obj, created = cls.objects.update_or_create(
id=membership_id, defaults=data
)
return obj return obj
@classmethod @classmethod
def is_digitalglarus_active_member(cls, user): def is_digitalglarus_active_member(cls, user):
# past_month = (datetime.today() - relativedelta(months=1)).month # past_month = (datetime.today() - relativedelta(months=1)).month
has_order_current_month = Q(membershiporder__customer__user=user, has_order_current_month = Q(
membershiporder__created_at__month=datetime.today().month) membershiporder__customer__user=user,
membershiporder__created_at__month=datetime.today().month
)
# has_order_past_month = Q(membershiporder__customer__user=user, # has_order_past_month = Q(membershiporder__customer__user=user,
# membershiporder__created_at__month=past_month) # membershiporder__created_at__month=past_month)
active_membership = Q(active=True) active_membership = Q(active=True)
# return cls.objects.filter(has_order_past_month | has_order_current_month).\ # return cls.objects.filter(
# has_order_past_month | has_order_current_month).\
return cls.objects.filter(has_order_current_month).\ return cls.objects.filter(has_order_current_month).\
filter(active_membership).exists() filter(active_membership).exists()
@ -129,6 +144,7 @@ class MembershipOrder(Ordereable, models.Model):
membership = models.ForeignKey(Membership) membership = models.ForeignKey(Membership)
start_date = models.DateField() start_date = models.DateField()
end_date = models.DateField() end_date = models.DateField()
stripe_subscription_id = models.CharField(max_length=100, null=True)
@classmethod @classmethod
def current_membership_dates(cls, user): def current_membership_dates(cls, user):
@ -172,10 +188,12 @@ class MembershipOrder(Ordereable, models.Model):
@classmethod @classmethod
def create(cls, data): def create(cls, data):
stripe_charge = data.pop('stripe_charge', None) stripe_charge = data.pop('stripe_charge', None)
stripe_subscription_id = data.pop('stripe_subscription_id', None)
instance = cls.objects.create(**data) instance = cls.objects.create(**data)
instance.stripe_charge_id = stripe_charge.id instance.stripe_charge_id = stripe_charge.id
instance.last4 = stripe_charge.source.last4 instance.last4 = stripe_charge.source.last4
instance.cc_brand = stripe_charge.source.brand instance.cc_brand = stripe_charge.source.brand
instance.stripe_subscription_id = stripe_subscription_id
instance.save() instance.save()
return instance return instance

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View file

@ -67,7 +67,7 @@ h6 {
font-size: 18px; font-size: 18px;
} }
@media only screen and (max-width: 400px){ @media only screen and (max-width: 400px){
h1, h2 { h1, h2 {
font-size: 20px; font-size: 20px;
} }
@ -235,7 +235,7 @@ fieldset[disabled] .btn-xl.active {
.navbar-default .navbar-brand { .navbar-default .navbar-brand {
font-family: "Helvetica Neue", Helvetica, Arial, cursive; font-family: "Helvetica Neue", Helvetica, Arial, cursive;
color: #a1cfd7; color: #a1cfd7;
padding-top: 10px; padding-top: 11px;
} }
.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:hover,
@ -404,8 +404,8 @@ section h3.section-subheading {
@media(min-width:768px) { @media(min-width:768px) {
section { section {
padding: 50px 0; padding: 50px 0;
} }
} }
*/ */
.service-heading { .service-heading {
margin: 15px 0; margin: 15px 0;
@ -416,7 +416,7 @@ section h3.section-subheading {
.no-padding { .no-padding {
padding:0; padding:0;
} }
.no-gutter > [class*='col-'] { .no-gutter > [class*='col-'] {
padding-top:0; padding-top:0;
@ -964,40 +964,6 @@ section h3.section-comment {
color: #494949; color: #494949;
} }
small-comment {
font-family: "Open Sans", "Droid Serif", "Helvetica Neue", Helvetica, Arial, sans-serif;
margin-bottom: none;
font-transform: none;
font-size:10px;
font-weight:400;
color: #777
}
logo-image {
z-index: 100;
position: absolute;
left: 0;
width: 80px;
height: 80px;
margin-left: 0;
border: 7px solid #f1f1f1;
border-radius: 100%;
text-align: center;
color: #fff;
background-color: #a1cfd7;
}
intro-cap {
margin-bottom: 25px;
text-transform: uppercase;
font-family: 'Raleway', "Helvetica Neue", "Helvetica Neue", Helvetica,Arial,sans-serif;
font-size: 24px;
font-weight: 400;
line-height: 50px;
color:#fff
background-color: #a1cfd7;
}
.intro-small { .intro-small {
font-family: 'Montserrat' ,'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif; font-family: 'Montserrat' ,'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif;
font-size: 20px; font-size: 20px;
@ -1006,26 +972,7 @@ intro-cap {
text-transform: uppercase; text-transform: uppercase;
color: #FFF; color: #FFF;
} }
intro-headline {
margin-bottom: 25px;
text-transform: uppercase;
font-family: 'Raleway', "Helvetica Neue", "Helvetica Neue", Helvetica,Arial,sans-serif;
font-size: 24px;
font-weight: 400;
line-height: 100px;
color:#fff
background-color: #a1cfd7;
}
h6 intro-smallcap {
margin-bottom: 25px;
text-transform: none;
font-family:'Raleway' , Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 18px;
font-weight: 400;
line-height: 50px;
color:#fff
background-color: #a1cfd7;
}
.darkened-container { .darkened-container {
/* Fallback for web browsers that doesn't support RGBa */ /* Fallback for web browsers that doesn't support RGBa */
background: rgb(0, 0, 0); background: rgb(0, 0, 0);
@ -1043,7 +990,7 @@ h6 intro-smallcap {
font-size: 14px; font-size: 14px;
line-height: 1.43; line-height: 1.43;
height: 86px; /* this is wrong */ height: 86px; /* this is wrong */
/*color: #484848;*/ /*color: #484848;*/
} }
.carousel-indicators li { .carousel-indicators li {
@ -1143,7 +1090,7 @@ body {
.carousel-control { .carousel-control {
height: 100%; height: 100%;
} }
/* Background images are set within the HTML using inline CSS, not here */ /* Background images are set within the HTML using inline CSS, not here */
@ -1231,7 +1178,7 @@ hr {
padding-top: 2em; padding-top: 2em;
} }
.donate { .donate {
font-weight: 600; font-weight: 600;
font-size: 24px; font-size: 24px;
} }

View file

@ -400,8 +400,8 @@ section h3.section-subheading {
@media(min-width:768px) { @media(min-width:768px) {
section { section {
padding: 50px 0; padding: 50px 0;
} }
} }
*/ */
.service-heading { .service-heading {
margin: 15px 0; margin: 15px 0;
@ -412,7 +412,7 @@ section h3.section-subheading {
.no-padding { .no-padding {
padding:0; padding:0;
} }
.no-gutter > [class*='col-'] { .no-gutter > [class*='col-'] {
padding-top:0; padding-top:0;
@ -960,40 +960,6 @@ section h3.section-comment {
color: #494949; color: #494949;
} }
small-comment {
font-family: "Open Sans", "Droid Serif", "Helvetica Neue", Helvetica, Arial, sans-serif;
margin-bottom: none;
font-transform: none;
font-size:10px;
font-weight:400;
color: #777
}
logo-image {
z-index: 100;
position: absolute;
left: 0;
width: 80px;
height: 80px;
margin-left: 0;
border: 7px solid #f1f1f1;
border-radius: 100%;
text-align: center;
color: #fff;
background-color: #a1cfd7;
}
intro-cap {
margin-bottom: 25px;
text-transform: uppercase;
font-family: 'Raleway', "Helvetica Neue", "Helvetica Neue", Helvetica,Arial,sans-serif;
font-size: 24px;
font-weight: 400;
line-height: 50px;
color:#fff
background-color: #a1cfd7;
}
.intro-small { .intro-small {
font-family: 'Montserrat' ,'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif; font-family: 'Montserrat' ,'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif;
font-size: 20px; font-size: 20px;
@ -1002,26 +968,7 @@ intro-cap {
text-transform: uppercase; text-transform: uppercase;
color: #FFF; color: #FFF;
} }
intro-headline {
margin-bottom: 25px;
text-transform: uppercase;
font-family: 'Raleway', "Helvetica Neue", "Helvetica Neue", Helvetica,Arial,sans-serif;
font-size: 24px;
font-weight: 400;
line-height: 100px;
color:#fff
background-color: #a1cfd7;
}
h6 intro-smallcap {
margin-bottom: 25px;
text-transform: none;
font-family:'Raleway' , Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 18px;
font-weight: 400;
line-height: 50px;
color:#fff
background-color: #a1cfd7;
}
.darkened-container { .darkened-container {
/* Fallback for web browsers that doesn't support RGBa */ /* Fallback for web browsers that doesn't support RGBa */
background: rgb(0, 0, 0); background: rgb(0, 0, 0);
@ -1039,7 +986,7 @@ h6 intro-smallcap {
font-size: 14px; font-size: 14px;
line-height: 1.43; line-height: 1.43;
height: 86px; /* this is wrong */ height: 86px; /* this is wrong */
/*color: #484848;*/ /*color: #484848;*/
} }
.carousel-indicators li { .carousel-indicators li {
@ -1139,7 +1086,7 @@ body {
.carousel-control { .carousel-control {
height: 100%; height: 100%;
} }
/* Background images are set within the HTML using inline CSS, not here */ /* Background images are set within the HTML using inline CSS, not here */

View file

@ -88,7 +88,7 @@ header.history {
line-height: 75px; line-height: 75px;
} }
.supportus .intro-headline-big { .supportus .intro-headline-big {
font-family: 'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold", font-family: 'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold",
font-size: 2.6em; font-size: 2.6em;
font-style: normal; font-style: normal;
font-weight: 800; font-weight: 800;
@ -96,7 +96,7 @@ header.history {
color: #ffffff; color: #ffffff;
line-height: 1; line-height: 1;
opacity: 0.85; opacity: 0.85;
} }
.supportus-box { .supportus-box {
@ -114,7 +114,7 @@ header.history {
margin: 0; margin: 0;
text-align: center; text-align: center;
display: block; display: block;
max-width: 650px; max-width: 650px;
border: 1px; border: 1px;
border-color: #ddd; border-color: #ddd;
} }
@ -250,6 +250,7 @@ header.history {
text-align:center; text-align:center;
line-height: 2.5; line-height: 2.5;
color: #fff; color: #fff;
margin-bottom: 100px;
} }
.supporter-intro { .supporter-intro {
@ -269,7 +270,7 @@ header.history {
@media (max-width: 979px) @media (max-width: 979px)
.supporter-black{ .supporter-black{
width: 100%; width: 100%;
} }
.supporter-headline { .supporter-headline {
@ -291,7 +292,7 @@ header.history {
background-size: cover; background-size: cover;
-o-background-size: cover; -o-background-size: cover;
} }
.glyphicon-star { .glyphicon-star {
font-size: 44px; font-size: 44px;
display: block; display: block;
@ -339,7 +340,7 @@ header.history {
-moz-transition: all .3s; -moz-transition: all .3s;
transition: all .3s; transition: all .3s;
}*/ }*/
#hr.grey { #hr.grey {
border-color: #ddd; border-color: #ddd;
border-width: 1px; border-width: 1px;

View file

@ -1,4 +1,4 @@
#page-top #services .container .row .col-lg-12.text-center .section-heading { #page-top #services .section-heading {
font-style: normal; font-style: normal;
color: #494949; color: #494949;
padding-top: 50px; padding-top: 50px;
@ -10,17 +10,13 @@
.intro-cap { .intro-cap {
font-family: 'Raleway', 'Helvetica Neue', 'Open Sans Bold', Helvetica, Arial, 'Arial Bold', sans-serif; font-family: 'Raleway', 'Helvetica Neue', 'Open Sans Bold', Helvetica, Arial, 'Arial Bold', sans-serif;
font-size: 26px; font-size: 24px;
font-style: normal; font-style: normal;
font-weight: 200; font-weight: 200;
text-transform: uppercase; text-transform: uppercase;
color: #FFF; color: #FFF;
} }
.intro-cap {
font-size: 24px;
}
.intro-smallcap { .intro-smallcap {
font-family: 'Raleway' , "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif; font-family: 'Raleway' , "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif;
font-size: 22px; font-size: 22px;

View file

@ -74,7 +74,7 @@
<center style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"> <center style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"> <table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle"> <td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'digitalglarus/img/digitalgalrus_logo_white.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a> <a href="https://www.digitalglarus.ch" style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static 'digitalglarus/img/digitalgalrus_logo_white.png' %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td> </td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right"> <td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td> </td>

View file

@ -74,7 +74,7 @@
<center style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"> <center style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"> <table cellpadding="0" cellspacing="0" width="600" class="w320" style="border-collapse: collapse !important; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;"><tr style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important;">
<td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle"> <td class="pull-left mobile-header-padding-left" style="vertical-align: middle; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: left; line-height: 21px; width: 290px; padding-left: 10px;" align="left" valign="middle">
<a href="{{base_url}}" style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static "hosting/img/logo_black.png" %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a> <a href="https://www.digitalglarus.ch" style="font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; color: #676767; text-decoration: none !important;"><img width="137" src="{{base_url}}{% static "hosting/img/logo_black.png" %}" alt="logo" style="max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; border: none;"></a>
</td> </td>
<td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right"> <td class="pull-right mobile-header-padding-right" style="color: #4d4d4d; border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; text-align: right; line-height: 21px; width: 290px; padding-left: 10px;" align="right">
</td> </td>

View file

@ -4,150 +4,148 @@
{% block content %} {% block content %}
<style type="text/css"> <style type="text/css">
@media screen and (max-width: 600px) {
@media screen and (max-width: 600px) { #timeline{
display: none;
#timeline{ }
display: none; h2 {font-size: 2em !important;}
} }
h2 {font-size: 2em !important;}
}
</style> </style>
<!-- Header --> <!-- Header -->
<header class="history"> <header class="history">
<div class="container header-history"> <div class="container header-history">
<div class="intro-text"> <div class="intro-text">
<p> <div class="intro-headline">
</p> <span class="intro-headline">
<div class="intro-headline"> Where great minds work
<span class="intro-headline"> </span>
Where great minds work
</span>
</div>
</div> </div>
</div> </div>
</div> </div>
</header> </header>
<!-- form section ends--> <!-- form section ends-->
<!-- Services Section -->
<section id="history">
<div class="container-fluid">
<div class="row-fluid">
<div class="col-lg-12 col-md-12 text-center wow fadeInDown">
<span class="glyphicon glyphicon-star glyphicon-inverse"></span>
<h2 class="section-heading">the story of Digital Glarus</h2>
<p class="carousel-text text-center supporter-black">
In search for a better environment for creativity, ungleich
arrived at a small village in Glarus. First we were driven by the
cheap real estate price, then we were genuinely surprised by the beauty of its nature. People were incredibly friendly as well. Working just became so relaxed and enjoyable in such a beautiful
surrounding..How come we are the only ones here?! We can't be
enjoying this alone, we need to let others know about this great
place. That's how it all started...
</p>
<span class="glyphicon glyphicon-heart glyphicon-inverse"></span>
<h2 class="section-heading">we fell in love</h2>
<p class="carousel-text text-center supporter-black">
We didn't see this coming, but we really fell in love with Glarus. The lakes, the mountains, the mist, the (amazing) snow,
the fresh air, the stream, the people, the stars...how could we not? And before long, we found an 100 something years old house,
formerly a family home, but long time unused, next to a river in
Schwanden. Full of old furniture, the house and the neighborhood
was stepping in a time machine. There, we found our first
coworking space in Glarus.</p>
<span class="glyphicon glyphicon-home glyphicon-inverse"></span>
<h2 class="section-heading">Our crowdfunding success</h2>
<p class="carousel-text text-center supporter-black">
What comes with a very old house? Lots of charm, yes. Great
history, yes. A contract stating that we can park our goats in the
storage room, yes. And, yes, tons of things to be fixed. We
couldn't afford much of renovation-we are a young start up rich
with creativity but not much money (yet)-that is why we decided to ask for help. To our surprise, generous people found hope and
inspiration from our project. We got much supports from people we
know and we don't know. People wrote to us, called us, met us. We
were on the cover of newspaper. We were on TV. We became the talk
of the town.
</p>
<!-- Services Section -->
<section id="history">
<div class="container-fluid">
<div class="text-center wow fadeInDown">
<span class="glyphicon glyphicon-star glyphicon-inverse"></span>
<h2 class="section-heading">the story of Digital Glarus</h2>
<p class="carousel-text text-center supporter-black">
In search for a better environment for creativity, ungleich
arrived at a small village in Glarus. First we were driven by the
cheap real estate price, then we were genuinely surprised by the
beauty of its nature. People were incredibly friendly as well.
Working just became so relaxed and enjoyable in such a beautiful
surrounding..How come we are the only ones here?! We can't be
enjoying this alone, we need to let others know about this great
place. That's how it all started...
</p>
<span class="glyphicon glyphicon-heart glyphicon-inverse"></span>
<div><iframe class="center-block" frameborder="0" height="330" scrolling="no" src="//www.100-days.net/de/projekt/start-digital-glarus/widget/v2" width="220"></iframe></div> <h2 class="section-heading">we fell in love</h2>
<span class="glyphicon glyphicon-road glyphicon-inverse"></span> <p class="carousel-text text-center supporter-black">
<h2 class="section-heading text-cente">And the story continues..!</h2> We didn't see this coming, but we really fell in love with Glarus.
<p class="carousel-text text-center supporter-black"> The lakes, the mountains, the mist, the (amazing) snow,
With the money we raised from our crowdfunding campaign, we the fresh air, the stream, the people, the stars...how could we
started renovating the hourse, ripping floors off and fixing not? And before long, we found an 100 something years old house,
walls, giving a fresh coat of paint on old walls. We hired Samuel, formerly a family home, but long time unused, next to a river in
who came to Glarus as a refugee from Eritrea, as our intern to Schwanden. Full of old furniture, the house and the neighborhood
renovate the house and learn computer science. We opened our door for students to live. Our coworking space is growing slowly but was stepping in a time machine. There, we found our first
meaningfully. Our journey only started! coworking space in Glarus.
</p> </p>
<hr class="primary"> <span class="glyphicon glyphicon-home glyphicon-inverse"></span>
</div>
<h2 class="section-heading">Our crowdfunding success</h2>
<p class="carousel-text text-center supporter-black">
What comes with a very old house? Lots of charm, yes. Great
history, yes. A contract stating that we can park our goats in the
storage room, yes. And, yes, tons of things to be fixed. We
couldn't afford much of renovation-we are a young start up rich
with creativity but not much money (yet)-that is why we decided to
ask for help. To our surprise, generous people found hope and
inspiration from our project. We got much supports from people we
know and we don't know. People wrote to us, called us, met us. We
were on the cover of newspaper. We were on TV. We became the talk
of the town.
</p>
<div>
<iframe class="center-block" frameborder="0" height="330" scrolling="no" src="//www.100-days.net/de/projekt/start-digital-glarus/widget/v2" width="220"></iframe>
</div>
<span class="glyphicon glyphicon-road glyphicon-inverse"></span>
<h2 class="section-heading text-cente">And the story continues..!</h2>
<p class="carousel-text text-center supporter-black">
With the money we raised from our crowdfunding campaign, we
started renovating the hourse, ripping floors off and fixing
walls, giving a fresh coat of paint on old walls. We hired Samuel,
who came to Glarus as a refugee from Eritrea, as our intern to
renovate the house and learn computer science. We opened our door
for students to live. Our coworking space is growing slowly but
meaningfully. Our journey only started!
</p>
<hr class="primary">
</div>
</div>
</section>
<!-- Half Page Image Background Carousel -->
<section>
<div id="timeline">
<iframe frameborder="0" width="100%" height="650" src="//cdn.knightlab.com/libs/timeline3/latest/embed/index.html?source=15clFd1fjnVScVziBlF-X7j5M7V6uNFt9jt9QZVylaYI&amp;font=Default&amp;lang=en&amp;initial_zoom=2&amp;height=650" width="100%"></iframe>
</div>
</section>
<!-- Supporters -->
<section id="supporters">
<div class="supporter-bg">
<div class="container">
<div class="text-center wow fadeInUp">
<h2 class="supporter-headline">Our Supporters</h2>
<hr class="primary">
<p class="carousel-text supporter-intro text-muted text-center">
Here are our proud supporters of project Digital Glarus. Thanks to our supporters,
the first cowerking space in Glarus is going to have a new look!
</p>
<p class="supporter" style="text-transform: uppercase;">
{% for supporter in supporters %}
{{ supporter.name }}
<br>
{% endfor %}
<br>
<a href="{% url 'digitalglarus:supportus' %}" class="btn btn-default btn-primary sr-button">Become a supporter</a>
</p>
</div> </div>
</div> </div>
</section> </div>
</section>
<!-- Half Page Image Background Carousel --> <section id="contact">
<section> <div class="fill">
<div id="timeline"> <div class="container">
<iframe frameborder="0" width="100%" height="650" src="//cdn.knightlab.com/libs/timeline3/latest/embed/index.html?source=15clFd1fjnVScVziBlF-X7j5M7V6uNFt9jt9QZVylaYI&amp;font=Default&amp;lang=en&amp;initial_zoom=2&amp;height=650" width="100%"></iframe> <div class="wow fadeInUp text-center">
</div> <h2 class="section-heading" style="margin-top: 40px;">Contact Us</h2>
<div class="map-wrap">
</section> <iframe style="margin-top:20px;" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2721.4267495037207!2d9.070190915609343!3d46.99259307914885!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47852e9322cc1971%3A0xf1558647dfdfaa60!2sIn+der+Au+7%2C+8762+Glarus+S%C3%BCd!5e0!3m2!1sen!2sch!4v1470238006004" width="100%" height="450" frameborder="0" style="border:0"></iframe>
<!-- Supporters -->
<section id="supporters">
<div class="supporter-bg">
<div class="container">
<div class="col-lg-12 text-center wow fadeInDown">
<h2 class="supporter-headline">Our Supporters</h2>
<hr class="primary">
<p class="carousel-text supporter-intro text-muted text-center"> Here are our proud supporters of project Digital Glarus. Thanks to our supporters, the first cowerking space in Glarus
is going to have a new look!</p>
<p class="supporter" style="text-transform: uppercase;">
{% for supporter in supporters %}
{{ supporter.name }}
<br>
{% endfor %}
<br>
<a href="{% url 'digitalglarus:supportus' %}" class="btn btn-default btn-primary sr-button">Become a supporter</a>
<br>
<br>
<br>
<br>
</div>
</div>
</div>
</section>
<section id="contact">
<div class="fill">
<div class="row" class="wow fadeInDown">
<div class="col-lg-12 text-center wow fadeInDown">
<div class=" map-wrap">
<iframe style="pointer-events:none;margin-top:20px;" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2721.4267495037207!2d9.070190915609343!3d46.99259307914885!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47852e9322cc1971%3A0xf1558647dfdfaa60!2sIn+der+Au+7%2C+8762+Glarus+S%C3%BCd!5e0!3m2!1sen!2sch!4v1470238006004" width="100%" height="450" frameborder="0" style="border:0"></iframe>
</div> </div>
<div class="col-md-4 map-title"> </div>
Digital Glarus<br> <div class="row">
<span class="map-caption">In der Au 7 Schwanden 8762 Switzerland <div class="col-md-4 map-title">
Digital Glarus<br>
<span class="map-caption">
In der Au 7 Schwanden 8762 Switzerland
<br>info@digitalglarus.ch <br>info@digitalglarus.ch
<br> <br>
(044) 534-66-22 (044) 534-66-22
<p>&nbsp;</p> <br>
</span> </span>
</div> <p>&nbsp;</p>
<p>&nbsp;</p>
</div> </div>
</div> </div>
</div> </div>
</section> </div>
</section>
{% endblock %} {% endblock %}

View file

@ -3,251 +3,254 @@
{% block content %} {% block content %}
<!-- Header --> <style type="text/css">
<header>
<div class="container">
<div class="intro-text">
<p>
</p>
<div class="intro-headline">
<span class="intro-headline">
Where great minds work
</span>
</div>
</div>
</div>
<div class="container-fluid darkened-container">
<h3 class="intro-small">
Book a date today and dive in</h3>
<a href="{% url 'digitalglarus:booking' %}" class="btn btn-primary">Join now</a>
<!-- <form class="form-inline">
<div class="form-group">
<label class="sr-only" for="exampleInputPassword3">Pick a date</label>
<input type="password" class="form-control" id="exampleInputPassword3" placeholder="Pick a date">
<div class="form-group">
<label class="sr-only" for="exampleInputEmail3">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail3" placeholder="Enter email">
</div>
</div>
<button type="submit" class="btn btn-primary">book a date</button>
</form> -->
</div>
<style type="text/css"> .caption-style-1{
list-style-type: none;
margin: 0px;
padding: 0px;
}
.caption-style-1{ .caption-style-1 li{
list-style-type: none; float: left;
margin: 0px; padding: 0px;
padding: 0px; position: relative;
overflow: hidden;
} }
.caption-style-1 li{ .caption-style-1 li:hover .caption{
float: left; opacity: 1;
padding: 0px; }
position: relative;
overflow: hidden;
}
.caption-style-1 li:hover .caption{ .caption-style-1 img{
opacity: 1; margin: 0px;
padding: 0px;
float: left;
z-index: 4;
}
} .caption-style-1 .caption{
cursor: pointer;
opacity: 0;
-webkit-transition:all 0.45s ease-in-out;
-moz-transition:all 0.45s ease-in-out;
-o-transition:all 0.45s ease-in-out;
-ms-transition:all 0.45s ease-in-out;
transition:all 0.45s ease-in-out;
}
.caption-style-1 .blur{
background-color: rgba(0,0,0,0.65);
height: 800px;
width: 800px;
z-index: 10;
position: absolute;
}
.caption-style-1 .caption-text h1{
text-transform: uppercase;
font-size: 24px;
}
.caption-style-1 .caption-text{
z-index: 0;
color: #fff;
width: 400px;
height: 200px;
text-align: center;
top:30px;
}
.caption-style-1 img{ /** content **/
margin: 0px; .content{
padding: 0px; margin-top: 100px;
float: left; margin-left: 100px;
z-index: 4; width: 700px;
} }
.content p{
color: #ecf0f1;
font-family: "Lato";
line-height: 28px;
font-size: 15px;
padding-top: 50px;
}
.caption-style-1 .caption{ p.credit{
cursor: pointer; padding-top: 20px;
opacity: 0; font-size: 12px;
-webkit-transition:all 0.45s ease-in-out; }
-moz-transition:all 0.45s ease-in-out;
-o-transition:all 0.45s ease-in-out;
-ms-transition:all 0.45s ease-in-out;
transition:all 0.45s ease-in-out;
} p a{
.caption-style-1 .blur{ color: #ecf0f1;
background-color: rgba(0,0,0,0.65); }
height: 800px; .section-top-content {
width: 800px; font-size: 30px;
z-index: 10; font-weight: 600;
position: absolute; padding-top: 50px;
} display: flex;
justify-content: center;
.caption-style-1 .caption-text h1{ }
text-transform: uppercase; .section-top-content span{
font-size: 24px; font-weight: 300;
} }
.caption-style-1 .caption-text{ .section-top-txt {
z-index: 0; padding-top: 80px;
color: #fff; text-transform: uppercase;
width: 400px; text-align: right;
height: 200px; }
text-align: center; .section-top-img {
top:30px; max-width: 50%;
padding: 0px;
}
} @media(max-width:500px) {
.section-top-txt {
/** content **/ padding: 55px 5px 0 0px;
.content{ }
margin-top: 100px; .section-top-content {
margin-left: 100px; font-size: 28px;
width: 700px; }
} }
@media(max-width:360px) {
.content p{ .section-top-txt {
color: #ecf0f1; padding: 32px 5px 0 0px;
font-family: "Lato"; }
line-height: 28px; .section-top-content {
font-size: 15px; font-size: 18px;
padding-top: 50px; }
} }
@media screen and (min-device-width: 768px) and (max-device-width: 991px) {
p.credit{ .section-top-txt {
padding-top: 20px; padding-top: 43px;
font-size: 12px; }
} }
@media screen and (min-device-width: 992px) and (max-device-width: 1200px) {
p a{ .section-top-txt {
color: #ecf0f1; padding-top: 65px;
} }
.section-top-content { }
font-size: 30px; @media screen and (min-device-width: 361px) and (max-device-width: 428px) {
font-weight: 600; .section-top-txt {
padding-top: 50px; padding: 35px 5px 0 0px;
} }
.section-top-content span{ .section-top-content {
font-weight: 300; font-size: 22px;
} }
.section-top-txt { }
padding-top: 80px;
text-transform: uppercase;
text-align: right;
}
.section-top-img {
padding:0px;
}
@media(max-width:500px) {
.section-top-txt {
padding: 55px 5px 0 0px;
}
.section-top-content {
font-size: 28px;
}
}
@media(max-width:360px) {
.section-top-txt {
padding: 32px 5px 0 0px;
}
.section-top-content {
font-size: 18px;
}
}
@media screen and (min-device-width: 768px) and (max-device-width: 991px) {
.section-top-txt {
padding-top: 43px;
}
}
@media screen and (min-device-width: 992px) and (max-device-width: 1200px) {
.section-top-txt {
padding-top: 65px;
}
}
</style> </style>
<!-- Header -->
<header>
</header> <div class="container">
<!-- form section ends--> <div class="intro-text">
<!-- Services Section --> <div class="intro-headline">
<section id="services"> <span class="intro-headline">
<div class="container"> Where great minds work
<div class="row"> </span>
<div class="col-lg-12 text-center wow fadeInDown section-top-content"> </div>
<div class="col-lg-3 col-sm-2 col-xs-12"></div>
<div class="col-lg-6 col-sm-10 col-xs-12">
<div class="col-lg-5 col-sm-5 col-xs-6 section-top-txt">Partner <span>of</span></div>
<div class="col-lg-7 col-sm-4 col-xs-6 section-top-img"><a href="https://zurich.impacthub.ch" target="_blank"><img src="{% static 'digitalglarus/img/impacthub_logo.jpg' %}" class="img-responsive" alt=""></a></div>
</div>
<div class="col-lg-3 col-sm-12 col-xs-12"></div>
</div> </div>
<div class="col-lg-12 col-xs-12 text-center wow fadeInDown"> </div>
<div class="container-fluid darkened-container">
<h3 class="intro-small">Book a date today and dive in</h3>
<a href="{% url 'digitalglarus:booking' %}" class="btn btn-primary">Join now</a>
{% comment %}
<form class="form-inline">
<div class="form-group">
<label class="sr-only" for="exampleInputPassword3">Pick a date</label>
<input type="password" class="form-control" id="exampleInputPassword3" placeholder="Pick a date">
<div class="form-group">
<label class="sr-only" for="exampleInputEmail3">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail3" placeholder="Enter email">
</div>
</div>
<button type="submit" class="btn btn-primary">book a date</button>
</form>
{% endcomment %}
</div>
</header>
<!-- form section ends-->
<!-- Services Section -->
<section id="services">
<div class="container">
<div class="text-center wow fadeInUp section-top-content">
<div class="section-top-txt">Partner <span>of</span></div>
<div class="section-top-img">
<a href="https://zurich.impacthub.ch" target="_blank">
<img src="{% static 'digitalglarus/img/impacthub_logo.jpg' %}" class="img-responsive" alt="">
</a>
</div>
</div>
<div class="text-center wow fadeInUp">
<h2 class="section-heading">In Digital Glarus you can..</h2> <h2 class="section-heading">In Digital Glarus you can..</h2>
<hr class="primary"> <hr class="primary">
</div> </div>
</div>
<!--dropdown icons--> <!--dropdown icons-->
<div class="row text-center"> <div class="row text-center">
<div class="col-xs-6 col-sm-3"> <div class="col-xs-6 col-sm-3">
<div class="team-member wow fadeInDown" data-wow-delay="0.3s"> <div class="team-member wow fadeInUp" data-wow-delay="0.3s">
<img src="{% static 'digitalglarus/img/services/sleep.svg' %}" class="img-responsive img-toggle" alt=""> <img src="{% static 'digitalglarus/img/services/sleep.svg' %}" class="img-responsive img-toggle" alt="">
</div>
</div> </div>
</div> <div class="col-xs-6 col-sm-3">
<div class="col-xs-6 col-sm-3"> <div class="team-member wow fadeInUp" data-wow-delay="0.5s">
<div class="team-member wow fadeInDown" data-wow-delay="0.5s"> <img src="{% static 'digitalglarus/img/services/eat.svg' %}" class="img-responsive img-toggle" alt="">
<img src="{% static 'digitalglarus/img/services/eat.svg' %}" class="img-responsive img-toggle" alt=""> </div>
</div> </div>
</div> <div class="col-xs-6 col-sm-3">
<div class="col-xs-6 col-sm-3"> <div class="team-member wow fadeInUp" data-wow-delay="0.7s">
<div class="team-member wow fadeInDown" data-wow-delay="0.7s"> <img src="{% static 'digitalglarus/img/services/freshenup.svg' %}" class="img-responsive img-toggle cursor-pointer" alt="">
<img src="{% static 'digitalglarus/img/services/freshenup.svg' %}" class="img-responsive img-toggle cursor-pointer" alt=""> </div>
</div> </div>
</div> <div class="col-xs-6 col-sm-3">
<div class="col-xs-6 col-sm-3"> <div class="team-member wow fadeInUp" data-wow-delay="0.8s">
<div class="team-member wow fadeInDown" data-wow-delay="0.8s"> <img src="{% static 'digitalglarus/img/services/work.svg' %}" class="img-responsive img-toggle" alt="">
<img src="{% static 'digitalglarus/img/services/work.svg' %}" class="img-responsive img-toggle" alt=""> </div>
</div>
</div>
<div class="row text-center" style="margin-left: 0px; margin-right: 0px;">
<div class="col-xs-6 col-sm-3">
<div class="team-member wow fadeInDown" data-wow-delay="0.9s">
<img src="{% static 'digitalglarus/img/services/enjoy.svg' %}" class="img-responsive img-toggle" alt="">
</div> </div>
</div> <div class="row text-center" style="margin-left: 0px; margin-right: 0px;">
<div class="col-xs-6 col-sm-3"> <div class="col-xs-6 col-sm-3">
<div class="team-member wow fadeInDown" data-wow-delay="1s"> <div class="team-member wow fadeInUp" data-wow-delay="0.9s">
<img src="{% static 'digitalglarus/img/services/network.svg' %}" class="img-responsive img-toggle" alt=""> <img src="{% static 'digitalglarus/img/services/enjoy.svg' %}" class="img-responsive img-toggle" alt="">
</div> </div>
</div> </div>
<div class="col-xs-6 col-sm-3"> <div class="col-xs-6 col-sm-3">
<div class="team-member wow fadeInDown" data-wow-delay="1.1s"> <div class="team-member wow fadeInUp" data-wow-delay="1s">
<img src="{% static 'digitalglarus/img/services/lightbulb.svg' %}" class="img-responsive img-toggle cursor-pointer" alt=""> <img src="{% static 'digitalglarus/img/services/network.svg' %}" class="img-responsive img-toggle" alt="">
</div> </div>
</div> </div>
<div class="col-xs-6 col-sm-3"> <div class="col-xs-6 col-sm-3">
<div class="team-member wow fadeInDown" data-wow-delay="1.2s"> <div class="team-member wow fadeInUp" data-wow-delay="1.1s">
<img src="{% static 'digitalglarus/img/services/beinspired.svg' %}" class="img-responsive img-toggle" alt=""> <img src="{% static 'digitalglarus/img/services/lightbulb.svg' %}" class="img-responsive img-toggle cursor-pointer" alt="">
</div>
</div>
<div class="col-xs-6 col-sm-3">
<div class="team-member wow fadeInUp" data-wow-delay="1.2s">
<img src="{% static 'digitalglarus/img/services/beinspired.svg' %}" class="img-responsive img-toggle" alt="">
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<!-- start:recommendationSlider --> <!-- start:recommendationSlider -->
<hr class="primary"> <hr class="primary">
<div id="carousel-recommendation-ungleich" class="carousel slide ungleich ungleich-gallery ungleich-gallery-text-carousel" data-ride="carousel" data-interval="false"> <div id="carousel-recommendation-ungleich" class="carousel slide ungleich ungleich-gallery ungleich-gallery-text-carousel" data-ride="carousel" data-interval="false">
<!-- Indicators --> <!-- Indicators -->
<ol class="carousel-indicators"> <ol class="carousel-indicators">
<li data-target="#carousel-recommendation-ungleich" data-slide-to="0" class="active"></li> <li data-target="#carousel-recommendation-ungleich" data-slide-to="0" class="active"></li>
<li data-target="#carousel-recommendation-ungleich" data-slide-to="1"></li> <li data-target="#carousel-recommendation-ungleich" data-slide-to="1"></li>
<li data-target="#carousel-recommendation-ungleich" data-slide-to="2"></li> <li data-target="#carousel-recommendation-ungleich" data-slide-to="2"></li>
</ol> </ol>
<!-- Wrapper for slides --> <!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox"> <div class="carousel-inner" role="listbox">
<div class="item active"> <div class="item active">
<p class="carousel-text text-muted text-center"> <p class="carousel-text text-muted text-center">
When we first moved our company HQ to Glarus, When we first moved our company HQ to Glarus,
we couldn't believe how beautiful and peaceful we couldn't believe how beautiful and peaceful
a workplace could be. Then we thought, we can't be a workplace could be. Then we thought, we can't be
the only ones appreciating it, more people should the only ones appreciating it, more people should
know about this. know about this.
</p> </p>
<p class="text-center"> <p class="text-center">
@ -256,13 +259,13 @@
</div> </div>
<div class="item"> <div class="item">
<p class="carousel-text text-muted text-center"> <p class="carousel-text text-muted text-center">
After my first visit to Digital Glarus, I felt After my first visit to Digital Glarus, I felt
right at home and at peace. Now that 200ok has a right at home and at peace. Now that 200ok has a
mountain-side office, our meetings, workshops and mountain-side office, our meetings, workshops and
code-retreats are so much more intense and productive code-retreats are so much more intense and productive
for everyone. And in the end, when people came for everyone. And in the end, when people came
over from the city for work, they want to come back over from the city for work, they want to come back
real soon, because it just feels like going on vacation. real soon, because it just feels like going on vacation.
</p> </p>
<p class="text-center"> <p class="text-center">
<strong> - Alain Lafon </strong>, CEO of 200ok GmbH <strong> - Alain Lafon </strong>, CEO of 200ok GmbH
@ -270,219 +273,199 @@
</div> </div>
<div class="item"> <div class="item">
<p class="carousel-text text-muted text-center"> <p class="carousel-text text-muted text-center">
You get on the train from the city and in an hour You get on the train from the city and in an hour
you arrive at a completely different environment. you arrive at a completely different environment.
Just looking around, is amazing.We have this beautiful Just looking around, is amazing.We have this beautiful
nature like on a holiday, but it is still a working nature like on a holiday, but it is still a working
environment and you can really focus and be productive. environment and you can really focus and be productive.
I really like this building. it's full of old charm. I really like this building. it's full of old charm.
<p class="text-center"> <p class="text-center">
<strong>- Gregor Martius,</strong> <strong>- Gregor Martius,</strong>
Swiss Federal Institute for Forest, Snow and Landscape Research WSL Swiss Federal Institute for Forest, Snow and Landscape Research WSL
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<!-- end:recommendationSlider --> <!-- end:recommendationSlider -->
</div></section> </section>
<!-- Portfolio Grid Section -->
<!-- Portfolio Grid Section --> <section id="portfolio" class="no-padding">
<section id="portfolio" class="no-padding">
<div class="container-fluid"> <div class="container-fluid">
<!--<div class="row"> <!--<div class="row">
<div class="col-lg-12 text-center wow fadeInDown"> <div class="col-lg-12 text-center wow fadeInUp">
<h2 class="section-heading">here you can</h2> <h2 class="section-heading">here you can</h2>
<h3 class="section-subheading text-muted">Join our community. Inspire and be inspired.</h3> <h3 class="section-subheading text-muted">Join our community. Inspire and be inspired.</h3>
</div>--> </div>-->
</div>
<div class="row no-gutter popup-gallery"> <div class="row no-gutter popup-gallery">
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInUp text-center" data-wow-delay="0.5s">
<ul class="caption-style-1">
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInDown text-center" data-wow-delay="0.5s"> <li>
<ul class="caption-style-1"> <img src="{% static 'digitalglarus/img/portfolio/excursion.png' %}" class="img-responsive inline-block" alt="">
<li>
<img src="{% static 'digitalglarus/img/portfolio/excursion.png' %}" class="img-responsive inline-block" alt="">
<div class="caption"> <div class="caption">
<div class="blur"></div> <div class="blur"></div>
</div>
</li>
</div> </ul>
</li> <div class="caption portfolio-caption-white">excursions</div>
</ul> </div>
<div class="caption portfolio-caption-white">excursions</div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInUp text-center" data-wow-delay="0.8s">
</div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInDown text-center" data-wow-delay="0.8s">
<ul class="caption-style-1"> <ul class="caption-style-1">
<li> <li>
<img src="{% static 'digitalglarus/img/portfolio/ski.png' %}" class="img-responsive inline-block" alt=""> <img src="{% static 'digitalglarus/img/portfolio/ski.png' %}" class="img-responsive inline-block" alt="">
<div class="caption"> <div class="caption">
<div class="blur"></div> <div class="blur"></div>
</div>
</div>
</li> </li>
</ul> </ul>
<div class="caption portfolio-caption-white">enjoy the great outdoors</div> <div class="caption portfolio-caption-white">enjoy the great outdoors</div>
</div> </div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInUp text-center" data-wow-delay="1.1s">
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInDown text-center" data-wow-delay="1.1s"> <ul class="caption-style-1">
<ul class="caption-style-1"> <li>
<li> <img src="{% static 'digitalglarus/img/portfolio/concert.png' %}" class="img-responsive inline-block" alt="">
<img src="{% static 'digitalglarus/img/portfolio/concert.png' %}" class="img-responsive inline-block" alt="">
<div class="caption">
<div class="blur"></div>
</div>
</li>
</ul>
<div class="caption portfolio-caption-white">cultural events</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInDown text-center" data-wow-delay="1.2s">
<ul class="caption-style-1">
<li>
<img src="{% static 'digitalglarus/img/portfolio/inspire.png' %}" class="img-responsive inline-block" alt="">
<div class="caption">
<div class="blur"></div>
</div>
</li>
</ul>
<div class="caption portfolio-caption-white">be inspired</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInDown text-center" data-wow-delay="1.3s">
<ul class="caption-style-1">
<li>
<img src="{% static 'digitalglarus/img/portfolio/workshop.png' %}" class="img-responsive inline-block" alt="">
<div class="caption"> <div class="caption">
<div class="blur"></div> <div class="blur"></div>
</div> </div>
</li> </li>
</ul> </ul>
<div class="caption portfolio-caption-white">workshops</div> <div class="caption portfolio-caption-white">cultural events</div>
</div> </div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInDown text-center" data-wow-delay="1.4s"> <div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInUp text-center" data-wow-delay="1.2s">
<ul class="caption-style-1"> <ul class="caption-style-1">
<li> <li>
<img src="{% static 'digitalglarus/img/portfolio/recharge.png' %}" class="img-responsive inline-block" alt=""> <img src="{% static 'digitalglarus/img/portfolio/inspire.png' %}" class="img-responsive inline-block" alt="">
<div class="caption"> <div class="caption">
<div class="blur"></div> <div class="blur"></div>
</div> </div>
</li> </li>
</ul> </ul>
<div class="caption portfolio-caption-white">recharge</div> <div class="caption portfolio-caption-white">be inspired</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInUp text-center" data-wow-delay="1.3s">
<ul class="caption-style-1">
<li>
<img src="{% static 'digitalglarus/img/portfolio/workshop.png' %}" class="img-responsive inline-block" alt="">
<div class="caption">
<div class="blur"></div>
</div>
</li>
</ul>
<div class="caption portfolio-caption-white">workshops</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-6 portfolio-item wow fadeInUp text-center" data-wow-delay="1.4s">
<ul class="caption-style-1">
<li>
<img src="{% static 'digitalglarus/img/portfolio/recharge.png' %}" class="img-responsive inline-block" alt="">
<div class="caption">
<div class="blur"></div>
</div>
</li>
</ul>
<div class="caption portfolio-caption-white">recharge</div>
</div>
</div> </div>
</div>
</div>
</section> </section>
<!--aside-->
<!--aside--> <aside class="bg-dark">
<aside class="bg-dark"> <div class="container text-center">
<div class="container text-center"> <div class="call-to-action aside-caption-white">
<div class="call-to-action aside-caption-white"> Join our community. Be our member now!
Join our community. Be our member now!
<br>
<br>
<a href="{% url 'digitalglarus:signup' %}" class="btn btn-default btn-primary sr-button"> Sign Up </a>
</div>
</div>
</aside>
<!-- Half Page Image Background Carousel -->
<section id="myCarousel" class="carousel slide">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li>
</ol>
<!-- Wrapper for Slides -->
<div class="carousel-inner">
<div class="item active">
<!-- Set the first background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_1.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
<strong>OpenNebula workshop</strong> : <br>
push your geeky boundary with us at Digital Chalet
</div>
</div>
<div class="item">
<!-- Set the second background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_2.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
<strong>Lorawan meetup</strong> : <br>
connect with like-minded people and discuss your latest tech obsession.
</div>
</div>
<div class="item">
<!-- Set the third background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_3.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
Cooking and Hacking at Digital Chalet Schwanden
</div>
</div>
<div class="item">
<!-- Set the third background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_4.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
Dive into the beautiful nature around you anytime you want
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</section>
<section id="contact">
<div class="fill">
<div class="row" class="wow fadeInDown">
<div class="col-lg-12 text-center wow fadeInDown">
<h2 class="section-heading">Contact Us</h2>
<div class=" map-wrap">
<iframe style="pointer-events:none" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2721.4267495037207!2d9.070190915609343!3d46.99259307914885!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47852e9322cc1971%3A0xf1558647dfdfaa60!2sIn+der+Au+7%2C+8762+Glarus+S%C3%BCd!5e0!3m2!1sen!2sch!4v1470238006004" width="100%" height="450" frameborder="0" style="border:0"></iframe></div>
<div class="col-md-4 map-title">
Digital Glarus<br>
<span class="map-caption">In der Au 7 Schwanden 8762 Switzerland
<br>info@digitalglarus.ch
<br> <br>
(044) 534-66-22 <br>
<p>&nbsp;</p> <a href="{% url 'digitalglarus:signup' %}" class="btn btn-default btn-primary sr-button"> Sign Up </a>
</span>
</div> </div>
<p>&nbsp;</p>
</div>
</div>
</div> </div>
</aside>
<!-- Half Page Image Background Carousel -->
<section id="myCarousel" class="carousel slide">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li>
</ol>
<!-- Wrapper for Slides -->
<div class="carousel-inner">
<div class="item active">
<!-- Set the first background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_1.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
<strong>OpenNebula workshop</strong> : <br>
push your geeky boundary with us at Digital Chalet
</div>
</div> </div>
</section> <div class="item">
<!-- Set the second background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_2.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
<strong>Lorawan meetup</strong> : <br>
connect with like-minded people and discuss your latest tech obsession.
</div>
</div>
<div class="item">
<!-- Set the third background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_3.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
Cooking and Hacking at Digital Chalet Schwanden
</div>
</div>
<div class="item">
<!-- Set the third background image using inline CSS below. -->
<div class="fill" style="background-image:url({% static 'digitalglarus/img/portfolio/slider_4.png' %})"></div>
<div class="carousel-caption carousel-caption-text">
Dive into the beautiful nature around you anytime you want
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</section>
<section id="contact">
<div class="fill">
<div class="container">
<div class="wow fadeInUp">
<div class="text-center">
<h2 class="section-heading">Contact Us</h2>
<div class="map-wrap">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2721.4267495037207!2d9.070190915609343!3d46.99259307914885!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47852e9322cc1971%3A0xf1558647dfdfaa60!2sIn+der+Au+7%2C+8762+Glarus+S%C3%BCd!5e0!3m2!1sen!2sch!4v1470238006004" width="100%" height="450" frameborder="0" style="border:0"></iframe>
</div>
<div class="map-title">
Digital Glarus<br>
<span class="map-caption">In der Au 7 Schwanden 8762 Switzerland
<br>info@digitalglarus.ch
<br>
(044) 534-66-22
<p>&nbsp;</p>
</span>
</div>
<p>&nbsp;</p>
</div>
</div>
</div>
</div>
</section>
<!--
<!--
<div class="row"> <div class="row">
<div class="box"> <div class="box">
<div class="col-lg-12 text-center"> <div class="col-lg-12 text-center">

View file

@ -95,12 +95,9 @@
<a class="btn btn-primary btn-grey btn-deactivate print" href="{% url 'digitalglarus:membership_deactivate' %}">Deactivate</a> <a class="btn btn-primary btn-grey btn-deactivate print" href="{% url 'digitalglarus:membership_deactivate' %}">Deactivate</a>
</div> </div>
{% elif not current_membership.active %} {% elif not current_membership.active %}
<form method="POST" action="{% url 'digitalglarus:membership_reactivate' %}">
{% csrf_token %}
<div class="edit-button"> <div class="edit-button">
<button type="submit" class="btn btn-primary btn-grey btn-deactivate print" href="{% url 'digitalglarus:membership_reactivate' %}">Reactivate</button> <a class="btn btn-primary btn-grey btn-deactivate" href="{% url 'digitalglarus:membership_pricing' %}">Reactivate</a>
</div> </div>
</form>
{% endif %} {% endif %}
{% else %} {% else %}
<div class="edit-button"> <div class="edit-button">

View file

@ -29,6 +29,9 @@
<br> <br>
<div class="notice-box"> <div class="notice-box">
<p class="signup-text">Already a member?<a href="{% url 'digitalglarus:login' %}">Log in</a></p> <p class="signup-text">Already a member?<a href="{% url 'digitalglarus:login' %}">Log in</a></p>
<p class="signup-text">If you are a user of <a href="{% url 'datacenterlight:index' %}" style="margin:0;">Data Center Light</a>,
you can <a href="{% url 'digitalglarus:login' %}" style="margin:0;">login</a> on Digital Glarus without a new signup.
</p>
</div> </div>
</div> </div>
@ -56,4 +59,4 @@
</div> </div>
</div> </div>
</section> </section>
{% endblock %} {% endblock %}

View file

@ -72,8 +72,8 @@
margin: 0px; margin: 0px;
color:white; color:white;
} }
@media only screen and (min-width: 769px){ @media only screen and (min-width: 769px){
.dropdown.home-dropdown-mobile { .dropdown.home-dropdown-mobile {
display: none; display: none;
} }
@ -81,14 +81,13 @@
display: block; display: block;
} }
} }
@media only screen and (max-width: 768px){ @media only screen and (max-width: 768px){
.dropdown.home-dropdown-mobile { .dropdown.home-dropdown-mobile {
display: block; display: block;
background-color:
} }
.dropdown.home-dropdown-mobile .dropdown-menu{ .dropdown.home-dropdown-mobile .dropdown-menu{
display: block; display: block;
background-color: #0f1221; background-color: #0f1221;
@ -104,19 +103,19 @@
.dropdown.home-dropdown { .dropdown.home-dropdown {
display: none; display: none;
} }
} }
</style> </style>
</head> </head>
<body id="page-top" class="index"> <body id="page-top" class="index">
<!-- Navigation --> <!-- Navigation -->
<nav class="navbar navbar-default navbar-fixed-top"> <nav class="navbar navbar-default navbar-fixed-top">
<div class="" style="margin-right: -; margin-left: 0px;margin-right: 0px;"> <div style="margin-left: 0px; margin-right: 0px;">
<!-- Brand and toggle get grouped for better mobile display --> <!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header page-scroll"> <div class="navbar-header page-scroll">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
@ -147,10 +146,10 @@
<a class="page-scroll" href="#contact">Contact</a> <a class="page-scroll" href="#contact">Contact</a>
</li> </li>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<li class="dropdown home-dropdown-mobile open"> <li class="dropdown home-dropdown-mobile open">
<a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#"> <a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
<i class="glyphicon glyphicon-user"></i>{{request.user.name}} <span class="caret"></span> <i class="glyphicon glyphicon-user"></i>{{request.user.name}} <span class="caret"></span>
@ -162,7 +161,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="{% url 'digitalglarus:membership_orders_list' %}"><i class="fa fa-heart-o" aria-hidden="true"></i> {% trans "Membership"%} <a href="{% url 'digitalglarus:membership_orders_list' %}"><i class="fa fa-heart-o" aria-hidden="true"></i> {% trans "Membership"%}
</a> </a>
</li> </li>
<li> <li>
@ -173,7 +172,7 @@
</li> </li>
</ul> </ul>
</li> </li>
<li class="dropdown home-dropdown"> <li class="dropdown home-dropdown">
<a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#"> <a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
<i class="glyphicon glyphicon-user"></i>{{request.user.name}} <span class="caret"></span> <i class="glyphicon glyphicon-user"></i>{{request.user.name}} <span class="caret"></span>
@ -181,11 +180,11 @@
<ul id="g-account-menu" class="dropdown-menu" role="menu"> <ul id="g-account-menu" class="dropdown-menu" role="menu">
<li> <li>
<a href="{% url 'digitalglarus:booking_orders_list' %}"> <a href="{% url 'digitalglarus:booking_orders_list' %}">
<i class="fa fa-home" aria-hidden="true"></i> {% trans "Bookings"%} <i class="fa fa-home" aria-hidden="true"></i> {% trans "Bookings"%}
</a> </a>
</li> </li>
<li> <li>
<a href="{% url 'digitalglarus:membership_orders_list' %}"><i class="fa fa-heart-o" aria-hidden="true"></i> {% trans "Membership"%} <a href="{% url 'digitalglarus:membership_orders_list' %}"><i class="fa fa-heart-o" aria-hidden="true"></i> {% trans "Membership"%}
</a> </a>
</li> </li>
<li> <li>
@ -195,12 +194,12 @@
</a> </a>
</li> </li>
</ul> </ul>
</li> </li>
{% else %} {% else %}
<li> <li>
<a class="page-scroll" href="{% url 'digitalglarus:login' %}">Login</a> <a class="page-scroll" href="{% url 'digitalglarus:login' %}">Login</a>
</li> </li>
{% endif %} {% endif %}
<!-- <li> <!-- <li>
<a class="page-scroll" href="{% url 'digitalglarus:signup' %}">Sign Up</a> <a class="page-scroll" href="{% url 'digitalglarus:signup' %}">Sign Up</a>
@ -213,7 +212,7 @@
</nav> </nav>
{% block content %} {% endblock %} {% block content %} {% endblock %}
<footer> <footer>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
@ -241,7 +240,7 @@
</div> </div>
</div> </div>
</footer> </footer>
<script type="text/javascript" src="{% static 'digitalglarus/bower_components/jquery/dist/jquery.min.js' %}"></script> <script type="text/javascript" src="{% static 'digitalglarus/bower_components/jquery/dist/jquery.min.js' %}"></script>
<!-- jQuery --> <!-- jQuery -->
@ -282,7 +281,7 @@
<!-- <script type="text/javascript" src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"></script> --> <!-- <script type="text/javascript" src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"></script> -->
<script type="text/javascript" src="//cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script> <script type="text/javascript" src="//cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<!-- <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap/latest/css/bootstrap.css" /> <!-- <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap/latest/css/bootstrap.css" />
--> -->
<!-- Include Date Range Picker --> <!-- Include Date Range Picker -->
<script type="text/javascript" src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script> <script type="text/javascript" src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.42/js/bootstrap-datetimepicker.min.js <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.42/js/bootstrap-datetimepicker.min.js

View file

@ -1,5 +1,5 @@
from model_mommy import mommy from model_mommy import mommy
from unittest import mock from unittest import mock, skipIf
from django.test import TestCase from django.test import TestCase
from django.conf import settings from django.conf import settings
@ -15,9 +15,11 @@ from membership.models import CustomUser, StripeCustomer
from utils.tests import BaseTestCase from utils.tests import BaseTestCase
from .views import LoginView, SignupView, PasswordResetView, PasswordResetConfirmView,\ from .views import (
LoginView, SignupView, PasswordResetView, PasswordResetConfirmView,
MembershipPricingView, MembershipPaymentView MembershipPricingView, MembershipPaymentView
from .models import MembershipType, MembershipOrder )
from .models import MembershipType
class ContactViewTest(TestCase): class ContactViewTest(TestCase):
@ -41,13 +43,19 @@ class ContactViewTest(TestCase):
class ViewsTest(CMSTestCase): class ViewsTest(CMSTestCase):
def setUp(self): def setUp(self):
self.page1 = create_page('home', 'home_digitalglarus.html', published=True, language='en-us') self.page1 = create_page(
self.page2 = create_page('about', 'about.html', published=True, language='en-us', slug='about') 'home', 'home_digitalglarus.html', published=True,
language='en-us'
)
self.page2 = create_page(
'about', 'about.html', published=True, language='en-us',
slug='about'
)
def test_digitalglarus_templates(self): def test_digitalglarus_templates(self):
res1 = self.client.get('/en-us/') res1 = self.client.get('/en-us/')
self.assertContains(res1, 'Digital Glarus', status_code=200) self.assertContains(res1, 'Digital Glarus', status_code=200)
res2 = self.client.get('/en-us/about/') res2 = self.client.get('/en-us/cms/about/')
self.assertEqual(res2.status_code, 200) self.assertEqual(res2.status_code, 200)
@ -69,7 +77,9 @@ class MembershipPricingViewTest(BaseTestCase):
# Anonymous user should get data # Anonymous user should get data
response = self.client.get(self.url) response = self.client.get(self.url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['membership_type'], self.membership_type) self.assertEqual(
response.context['membership_type'], self.membership_type
)
self.assertTemplateUsed(response, self.expected_template) self.assertTemplateUsed(response, self.expected_template)
@ -101,8 +111,10 @@ class MembershipPaymentViewTest(BaseTestCase):
# Anonymous user should get redirect to login # Anonymous user should get redirect to login
response = self.client.get(self.url) response = self.client.get(self.url)
expected_url = "%s?next=%s" % (reverse('digitalglarus:signup'), expected_url = "%s?next=%s" % (
reverse('digitalglarus:membership_payment')) reverse('digitalglarus:signup'),
reverse('digitalglarus:membership_payment')
)
self.assertRedirects(response, expected_url=expected_url, self.assertRedirects(response, expected_url=expected_url,
status_code=302, target_status_code=200) status_code=302, target_status_code=200)
@ -114,6 +126,11 @@ class MembershipPaymentViewTest(BaseTestCase):
self.assertEqual(response.context['membership_type'], self.assertEqual(response.context['membership_type'],
self.membership_type) self.membership_type)
@skipIf(
settings.STRIPE_API_PRIVATE_KEY_TEST is None or
settings.STRIPE_API_PRIVATE_KEY_TEST is "",
"""Stripe details unavailable, so skipping CeleryTaskTestCase"""
)
@mock.patch('utils.stripe_utils.StripeUtils.create_customer') @mock.patch('utils.stripe_utils.StripeUtils.create_customer')
def test_post(self, stripe_mocked_call): def test_post(self, stripe_mocked_call):
@ -132,19 +149,29 @@ class MembershipPaymentViewTest(BaseTestCase):
} }
response = self.customer_client.post(self.url, self.billing_address) response = self.customer_client.post(self.url, self.billing_address)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertTrue(StripeCustomer.objects.filter(user__email=self.customer.email).exists()) self.assertTrue(
stripe_customer = StripeCustomer.objects.get(user__email=self.customer.email) 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.assertEqual(stripe_customer.user, self.customer)
self.assertTrue(MembershipOrder.objects.filter(customer=stripe_customer).exists()) # self.assertTrue(MembershipOrder.objects.filter(customer=stripe_customer).exists())
membership_order = MembershipOrder.objects.filter(customer=stripe_customer).first() # membership_order = MembershipOrder.objects.filter(
session_data = { # customer=stripe_customer
'membership_price': membership_order.membership.type.first_month_price, # ).first()
'membership_dates': membership_order.membership.type.first_month_formated_range # session_data = {
} # 'membership_price':
self.assertEqual(session_data.get('membership_price'), # membership_order.membership.type.first_month_price,
self.session_data.get('membership_price')) # 'membership_dates':
self.assertEqual(session_data.get('membership_dates'), # membership_order.membership.type.first_month_formated_range
self.session_data.get('membership_dates')) # }
# self.assertEqual(session_data.get('membership_price'),
# self.session_data.get('membership_price'))
# self.assertEqual(session_data.get('membership_dates'),
# self.session_data.get('membership_dates'))
# self.assertTrue(HostingOrder.objects.filter(customer=stripe_customer).exists()) # self.assertTrue(HostingOrder.objects.filter(customer=stripe_customer).exists())
# hosting_order = HostingOrder.objects.filter(customer=stripe_customer)[0] # hosting_order = HostingOrder.objects.filter(customer=stripe_customer)[0]
@ -197,7 +224,7 @@ class SignupViewTest(TestCase):
self.view = SignupView self.view = SignupView
self.signup_data = { self.signup_data = {
'name': 'ungleich', 'name': 'ungleich',
'email': 'test@ungleich.com', 'email': 'test@ungleich.ch',
'password': 'fake_password', 'password': 'fake_password',
'confirm_password': 'fake_password', 'confirm_password': 'fake_password',
} }
@ -212,7 +239,9 @@ class SignupViewTest(TestCase):
self.assertTemplateUsed(response, self.expected_template) self.assertTemplateUsed(response, self.expected_template)
def test_anonymous_user_can_signup(self): def test_anonymous_user_can_signup(self):
response = self.client.post(self.url, data=self.signup_data, follow=True) response = self.client.post(
self.url, data=self.signup_data, follow=True
)
self.user = CustomUser.objects.get(email=self.signup_data.get('email')) 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) self.assertEqual(response.status_code, 200)

View file

@ -14,7 +14,8 @@ from .views import ContactView, IndexView, HistoryView, LoginView, SignupView,\
# from membership.views import LoginRegistrationView # from membership.views import LoginRegistrationView
urlpatterns = [ urlpatterns = [
url(_(r'booking/payment/edit/?$'), EditCreditCardView.as_view(), name='edit_credit_card'), url(_(r'booking/payment/edit/?$'),
EditCreditCardView.as_view(), name='edit_credit_card'),
url(_(r'^$'), IndexView.as_view(), name='landing'), url(_(r'^$'), IndexView.as_view(), name='landing'),
# url(_(r'new_credit_card/?$'), TermsAndConditions, name='TermsAndConditions'), # url(_(r'new_credit_card/?$'), TermsAndConditions, name='TermsAndConditions'),
url(_(r'support-us/?$'), SupportusView.as_view(), name='supportus'), url(_(r'support-us/?$'), SupportusView.as_view(), name='supportus'),
@ -30,14 +31,16 @@ urlpatterns = [
url(_(r'users/billing_address/?$'), UserBillingAddressView.as_view(), url(_(r'users/billing_address/?$'), UserBillingAddressView.as_view(),
name='user_billing_address'), name='user_billing_address'),
url(_(r'booking/?$'), BookingSelectDatesView.as_view(), name='booking'), url(_(r'booking/?$'), BookingSelectDatesView.as_view(), name='booking'),
url(_(r'booking/payment/?$'), BookingPaymentView.as_view(), name='booking_payment'), url(_(r'booking/payment/?$'),
BookingPaymentView.as_view(), name='booking_payment'),
url(_(r'booking/orders/(?P<pk>\d+)/?$'), OrdersBookingDetailView.as_view(), url(_(r'booking/orders/(?P<pk>\d+)/?$'), OrdersBookingDetailView.as_view(),
name='booking_orders_detail'), name='booking_orders_detail'),
# url(_(r'booking/orders/(?P<pk>\d+)/cancel/?$'), BookingCancelView.as_view(), # url(_(r'booking/orders/(?P<pk>\d+)/cancel/?$'), BookingCancelView.as_view(),
# name='booking_orders_cancel'), # name='booking_orders_cancel'),
url(_(r'booking/orders/?$'), BookingOrdersListView.as_view(), url(_(r'booking/orders/?$'), BookingOrdersListView.as_view(),
name='booking_orders_list'), name='booking_orders_list'),
url(_(r'membership/payment/?$'), MembershipPaymentView.as_view(), name='membership_payment'), url(_(r'membership/payment/?$'),
MembershipPaymentView.as_view(), name='membership_payment'),
url(_(r'membership/activated/?$'), MembershipActivatedView.as_view(), url(_(r'membership/activated/?$'), MembershipActivatedView.as_view(),
name='membership_activated'), name='membership_activated'),
url(_(r'membership/deactivate/?$'), MembershipDeactivateView.as_view(), url(_(r'membership/deactivate/?$'), MembershipDeactivateView.as_view(),
@ -53,7 +56,7 @@ urlpatterns = [
url(_(r'membership/orders/?$'), MembershipOrdersListView.as_view(), url(_(r'membership/orders/?$'), MembershipOrdersListView.as_view(),
name='membership_orders_list'), name='membership_orders_list'),
url(_(r'supporters/?$'), views.supporters, name='supporters'), url(_(r'supporters/?$'), views.supporters, name='supporters'),
# url(_(r'support-us/?$'), views.support, name='support'), url(_(r'support-us/?$'), views.support, name='support'),
url(r'^blog/(?P<slug>\w[-\w]*)/$', views.blog_detail, name='blog-detail'), url(r'^blog/(?P<slug>\w[-\w]*)/$', views.blog_detail, name='blog-detail'),
url(r'blog/$', views.blog, name='blog'), url(r'blog/$', views.blog, name='blog'),
] ]

View file

@ -1,3 +1,5 @@
import logging
from django.conf import settings from django.conf import settings
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
@ -9,25 +11,34 @@ from django.utils.translation import get_language
from djangocms_blog.models import Post from djangocms_blog.models import Post
from django.contrib import messages from django.contrib import messages
from django.views.generic import DetailView, ListView from django.views.generic import DetailView, ListView
from .models import Supporter
from .mixins import ChangeMembershipStatusMixin
from utils.forms import ContactUsForm from utils.forms import ContactUsForm
from utils.mailer import BaseEmail from utils.mailer import BaseEmail
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from membership.models import StripeCustomer from membership.models import StripeCustomer
from utils.views import LoginViewMixin, SignupViewMixin, \ from utils.views import (
PasswordResetViewMixin, PasswordResetConfirmViewMixin LoginViewMixin, SignupViewMixin, PasswordResetViewMixin,
from utils.forms import PasswordResetRequestForm, UserBillingAddressForm, EditCreditCardForm PasswordResetConfirmViewMixin
)
from utils.forms import (
PasswordResetRequestForm, UserBillingAddressForm, EditCreditCardForm
)
from utils.stripe_utils import StripeUtils from utils.stripe_utils import StripeUtils
from utils.models import UserBillingAddress from utils.models import UserBillingAddress
from utils.tasks import send_plain_email_task
from .forms import LoginForm, SignupForm, MembershipBillingForm, BookingDateForm,\ from .forms import (
LoginForm, SignupForm, MembershipBillingForm, BookingDateForm,
BookingBillingForm, CancelBookingForm BookingBillingForm, CancelBookingForm
)
from .models import (
MembershipType, Membership, MembershipOrder, Booking, BookingPrice,
BookingOrder, BookingCancellation, Supporter
)
from .mixins import (
MembershipRequiredMixin, IsNotMemberMixin, ChangeMembershipStatusMixin
)
from .models import MembershipType, Membership, MembershipOrder, Booking, BookingPrice,\ logger = logging.getLogger(__name__)
BookingOrder, BookingCancellation
from .mixins import MembershipRequiredMixin, IsNotMemberMixin
class IndexView(TemplateView): class IndexView(TemplateView):
@ -271,7 +282,6 @@ class BookingPaymentView(LoginRequiredMixin, MembershipRequiredMixin, FormView):
booking_data = { booking_data = {
'start_date': start_date, 'start_date': start_date,
'end_date': end_date, 'end_date': end_date,
'start_date': start_date,
'free_days': free_days, 'free_days': free_days,
'price': normal_price, 'price': normal_price,
'final_price': final_price, 'final_price': final_price,
@ -355,16 +365,21 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
membership_type = data.get('membership_type') membership_type = data.get('membership_type')
# Get or create stripe customer # Get or create stripe customer
customer = StripeCustomer.get_or_create(email=self.request.user.email, customer = StripeCustomer.get_or_create(
token=token) email=self.request.user.email, token=token
)
if not customer: if not customer:
form.add_error("__all__", "Invalid credit card") form.add_error("__all__", "Invalid credit card")
return self.render_to_response(self.get_context_data(form=form)) return self.render_to_response(
self.get_context_data(form=form)
)
# Make stripe charge to a customer # Make stripe charge to a customer
stripe_utils = StripeUtils() stripe_utils = StripeUtils()
charge_response = stripe_utils.make_charge(amount=membership_type.first_month_price, charge_response = stripe_utils.make_charge(
customer=customer.stripe_id) amount=membership_type.first_month_price,
customer=customer.stripe_id
)
charge = charge_response.get('response_object') charge = charge_response.get('response_object')
# Check if the payment was approved # Check if the payment was approved
@ -373,9 +388,65 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
'paymentError': charge_response.get('error'), 'paymentError': charge_response.get('error'),
'form': form 'form': form
}) })
email_to_admin_data = {
'subject': "Could not create charge for Digital Glarus "
"user: {user}".format(
user=self.request.user.email
),
'from_email': 'info@digitalglarus.ch',
'to': ['info@ungleich.ch'],
'body': "\n".join(
["%s=%s" % (k, v) for (k, v) in
charge_response.items()]),
}
send_plain_email_task.delay(email_to_admin_data)
return render(request, self.template_name, context)
# Subscribe the customer to dg plan from the next month onwards
stripe_plan = stripe_utils.get_or_create_stripe_plan(
amount=membership_type.price,
name='Digital Glarus {sub_type_name} Subscription'.format(
sub_type_name=membership_type.name
),
stripe_plan_id='dg-{sub_type_name}'.format(
sub_type_name=membership_type.name
)
)
subscription_result = stripe_utils.subscribe_customer_to_plan(
customer.stripe_id,
[{"plan": stripe_plan.get('response_object').stripe_plan_id}],
trial_end=membership_type.next_month_in_sec_since_epoch
)
stripe_subscription_obj = subscription_result.get(
'response_object'
)
# Check if call to create subscription was ok
if (stripe_subscription_obj is None or
(stripe_subscription_obj.status != 'active' and
stripe_subscription_obj.status != 'trialing')):
context.update({
'paymentError': subscription_result.get('error'),
'form': form
})
email_to_admin_data = {
'subject': "Could not create Stripe subscription for "
"Digital Glarus user: {user}".format(
user=self.request.user.email
),
'from_email': 'info@digitalglarus.ch',
'to': ['info@ungleich.ch'],
'body': "\n".join(
["%s=%s" % (k, v) for (k, v) in
subscription_result.items()]),
}
send_plain_email_task.delay(email_to_admin_data)
return render(request, self.template_name, context) return render(request, self.template_name, context)
charge = charge_response.get('response_object') charge = charge_response.get('response_object')
if 'source' in charge:
cardholder_name = charge['source']['name']
else:
cardholder_name = customer.user.name
# Create Billing Address # Create Billing Address
billing_address = form.save() billing_address = form.save()
@ -383,7 +454,8 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
# Create Billing Address for User if he does not have one # Create Billing Address for User if he does not have one
if not customer.user.billing_addresses.count(): if not customer.user.billing_addresses.count():
data.update({ data.update({
'user': customer.user.id 'user': customer.user.id,
'cardholder_name': cardholder_name
}) })
billing_address_user_form = UserBillingAddressForm(data) billing_address_user_form = UserBillingAddressForm(data)
billing_address_user_form.is_valid() billing_address_user_form.is_valid()
@ -407,6 +479,7 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
'customer': customer, 'customer': customer,
'billing_address': billing_address, 'billing_address': billing_address,
'stripe_charge': charge, 'stripe_charge': charge,
'stripe_subscription_id': stripe_subscription_obj.id,
'amount': membership_type.first_month_price, 'amount': membership_type.first_month_price,
'start_date': membership_start_date, 'start_date': membership_start_date,
'end_date': membership_end_date 'end_date': membership_end_date
@ -476,8 +549,43 @@ class MembershipDeactivateView(LoginRequiredMixin, UpdateView):
def post(self, *args, **kwargs): def post(self, *args, **kwargs):
membership = self.get_object() membership = self.get_object()
membership.deactivate() membership.deactivate()
messages.add_message(
messages.add_message(self.request, messages.SUCCESS, self.success_message) self.request, messages.SUCCESS, self.success_message
)
# cancel Stripe subscription
stripe_utils = StripeUtils()
membership_order = MembershipOrder.objects.filter(
customer__user=self.request.user
).last()
if membership_order:
if membership_order.stripe_subscription_id:
result = stripe_utils.unsubscribe_customer(
subscription_id=membership_order.stripe_subscription_id
)
stripe_subscription_obj = result.get('response_object')
# Check if the subscription was canceled
if (stripe_subscription_obj is None or
stripe_subscription_obj.status != 'canceled'):
error_msg = result.get('error')
logger.error(
"Could not cancel Digital Glarus subscription. "
"Reason: {reason}".format(
reason=error_msg
)
)
else:
logger.error(
"User {user} may have Stripe subscriptions created "
"manually. Please check.".format(
user=self.request.user.name
)
)
else:
logger.error(
"MembershipOrder for {user} not found".format(
user=self.request.user.name
)
)
return HttpResponseRedirect(self.success_url) return HttpResponseRedirect(self.success_url)

Some files were not shown because too many files have changed in this diff Show more