diff --git a/.gitignore b/.gitignore
index 2bfa8cdf..1b2b4d16 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,11 @@ secret-key
.env
*.mo
+*.log
+*.sql
+
+/utils/optimize/
+
+# to keep empty dirs
+!.gitkeep
+*.orig
diff --git a/.travis.yml b/.travis.yml
index a1d0aacc..3a3d7027 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,13 +1,15 @@
language: python
python:
- - "3.5"
- - "3.6"
+ - "3.4.2"
+# - "3.6"
env:
- # Set a dummy secret key
- - DJANGO_SECRET_KEY=0
+ - 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"}}'
# install dependencies
install: "pip install -r requirements.txt"
script:
- flake8
-- python manage.py test
+- python manage.py compilemessages
+- python manage.py test -v 3
+# - coverage run --source='.' manage.py test dynamicweb -v 3
+# - coverage report
diff --git a/Changelog b/Changelog
index 98142cd4..04b699a9 100644
--- a/Changelog
+++ b/Changelog
@@ -1,20 +1,387 @@
+2.6.9: 2019-11-15
+ * feature: Allow creating yearly subscriptions for Generic Products (MR!718)
+ Notes for deployment:
+ - do a db migrate for new column added to Generic Product model
+ ./manage.py migrate hosting
+2.6.8: 2019-11-15
+ * feature: [EU VAT] Add EU VAT feature for generic products (MR!717)
+ Notes for deployment:
+ - do a db migrate a to create VATRates table
+ ./manage.py migrate hosting
+ - load vat_rates.csv
+ ./manage.py import_vat_rates vat_rates.csv
+2.6.7: 2019-11-04
+ * bugfix: [admin] Improve dumpuser: show proper dates + bugfix
+ * bugfix: [admin] Improve fetch_stripe_bills:
+ - fix wrong assigment of string to num_invoice_created
+ variable,
+ - return None (do not handle the case) if we don't have an
+ order
+ * bugfix: [admin] Improve deleteuser: do not delete order, bill and vm_detail
+2.6.6: 2019-11-04
+ * feature: [admin] Add dumpuser management command that dumps a user's data in json (MR!716)
+2.6.5: 2019-09-24
+ * #7169: [hosting] Fix server error while vm terminate takes longer than 30 seconds
+ * #7170: [hosting] Improve admin email body contents for hosting vm terminate error case
+2.6.4: 2019-09-15
+ * #7147: [OpenBSD vm] Add an explanatory text for username puffy on OpenBSD (MR!714)
+2.6.3: 2019-08-28
+ * #7032: [hosting] Bugfix: Reentering the same SSH key used before does allow user to proceed further; complains key exists (MR!712)
+ * #7070: [check_vm/api] Bugfix: Provide oneadmin credentials to check whether a user is the owner of a VM (MR!713)
+2.6.2: 2019-08-22
+ * #7068: [django/node/rails] Remove public- prefix from OS template names (MR!711)
+2.6.1: 2019-07-09
+ * #6941: [hosting dashboard] Show the card's expiry year & month too in the list of added cards (MR!710)
+2.6: 2019-07-03
+ * #5509: Getting rid of our key by still supporting multiple user keys (MR!709)
+2.5.11: 2019-06-11
+ * #6672: [api] Check VM belongs to user in the infrastructure directly (MR!707)
+ * #bugfix: DE translation fix "Learn mehr" -> "Lerne mehr" (MR!708)
+2.5.10: 2019-05-16
+ * #6672: [api] REST endpoint for ungleich-cli to verify if a VM belongs to a user (MR!705)
+ * #6670: [hosting/save_ssh_key] Upgrade cdist version to 5.0.1 to manage keys on Alpine linux
+2.5.9: 2019-05-09
+ * #6669: [hosting] Fix opennebula vm query takes long (MR!703)
+ * [hosting] Increase VMDetail model's configuration parameter length to 128 (MR!702)
+2.5.8: 2019-05-06
+ * #6631: Add `deleteuser` management command (MR!701)
+2.5.7: 2019-05-05
+ * #6657: [all] Remove dependency on code.jquery.com, maxcdn.bootstrapcdn.com and oss.maxcdn.com and add them locally (MR!700)
+2.5.6: 2019-05-05
+ * [blog] Check if the blog page is IPv6.Blog and load header image accordingly
+2.5.5: 2019-05-04
+ * [blog] Use modified djangocms_blog module to not show "Category - ... " (MR!699)
+2.5.4: 2019-05-04
+ * #6124: [blog] Allow setting title, subtitle of the blog page by passing GET params (MR!698)
+2.5.3: 2019-04-20
+ * #6561: [bills] Show mutiple line items in the invoice details (MR!697)
+ * #6561: [bills] Link line item to a Stripe Plan (MR!697)
+2.5.2: 2019-04-20
+ * #6561: [bills] Fix fetch_stripe_bills to import bills containing multiple line items belonging to same subscription (MR!695)
+2.5.1: 2019-04-17
+ * #6561: [hosting] Preparation for monthly invoices for customers (MR!689)
+ * [logging] Enhance logger, Include timestamp + module name in the logging messages (MR!693)
+2.5: 2019-04-11
+ * #6589: [vm creation, listing] Fix obtaining ip address/template related info from oca api call (MR!690, MR!691 and MR!692)
+ [python-oca] VirtualMachinePool infoextended (https://github.com/ungleich/python-oca/pull/3)
+2.4.10: 2019-02-14
+ * #6451: [dg, gdpr banner] Update phone number (MR!688 by pcoder)
+2.4.9: 2019-02-01
+ * bugfix: Fix inconsistent styles in GDPR modal (MR!679 by pcoder)
+2.4.8: 2019-01-31
+ * #5151: [all] Add GDPR banner (MR!678 by pcoder)
+ * #6059: [dcl] Change topnav font to 400 by default (MR! 680 by Sanghee)
+2.4.7: 2019-01-30
+ * #6213: [cms] Make ungleich product items equal heights and add option to animate or not animate the contents (MR!682 by Aatish)
+2.4.6: 2019-01-09
+ * #6261: Add ungleich black logo to blog template for mobile view (MR!685)
+2.4.5: 2019-01-07
+ * bugfix: [blog] Fix DE language option not being shown in the blog (MR!684) and revert back the RSS URL to the old one
+2.4.4: 2019-01-02
+ * bugfix: [blog] Create blog config for ungleich.ch and change RSS URL accordingly
+2.4.3: 2018-12-24
+ * #6260: Add viewport and other missing meta tags (MR!683)
+2.4.2: 2018-12-23
+ * Update djangcocms-blog version (0.7.0 -> 0.9.0)
+ * #6038: Change datacenterlight.ch message form to send email to support@ungleich.ch (MR!679)
+ * bugfix: Use correct version of django-multisite (MR #676)
+2.4.1: 2018-10-18
+ * bugfix: Update pycryptodome module from 3.4 to 3.6.6 (PR #674)
+2.4: 2018-10-18
+ * #5681: [hosting,dcl] Allow admin to lower minimum RAM to 512 MB (PR #672)
+2.3.1: 2018-10-17
+ * bugfix: [hosting, dcl] Show VAT percent rounded to 2 decimal places in the order confirmation page (PR #673)
+2.3: 2018-10-08
+ * #5690: Generic payment page - allow admin to add a onetime/monthly product and the frontend for user to pay for this product (PR #666)
+2.2.2: 2018-09-28
+ * #5721: Set calculator OS list in alphabetical order and set `Devuan Ascii` as the default (PR #668)
+ * bugfix: Fix some typos and correct DE translations (PR #667)
+2.2.1: 2018-09-25
+ * feature: Change DCLNavbarPlugin to show login option only if set (PR #665)
+ * bugfix: Log opennebula errors and send proper message when vm terminate is not completed in the stipulated time (PR #648)
+2.2: 2018-09-06
+ * bugfix: Include price in the Stripe plan name to make it distinct and to correct pricing since version 1.9
+2.1.2: 2018-08-30
+ * bugfix: [blog, comic] Set blog rss feed for all blog templates
+2.1.1: 2018-08-24
+ * #5487: [hosting] Add explicit warning message for teminating VM (PR #656)
+ * bugfix: [dg] Send email to admin on dg subscription and increase cc_brand field to 128 characters (PR #652)
+ * #5458: [admin] Make hostingorder more readable (PR #657)
+ * bugfix: [CMS templates] Set description meta field of ungleich template (was missing before) and set ungleich glarus ag uniformly as author of various CMS pages (PR #653)
+ * #5473: Ping a VM before saving ssh key of the user (PR #655)
+2.1: 2018-08-21
+ * Bugfix: Increase CC brand name fields from 10 to 128 characters (PR #654)
+2.0.5: 2018-08-08
+ * Fix IPv6 VM name in the billing invoice
+2.0.4: 2018-08-07
+ * Add RSS feed link to the footer of the blog template (PR #651)
+ * #5308: [ipv6only] Fix - when creating a VM, the name begins with v6only (PR #649)
+ * #5293: Use `terminate-hard` action instead of `terminate` in the opennebula call to terminate a vm (PR #650)
+2.0.3: 2018-07-18
+ * Remove unused /comic url (PR #644)
+ * #5126: Allow dynamicweb sites to be iframed on other by setting `X_FRAME_OPTIONS_ALLOW_FROM_URI` (PR #645)
+2.0.2: 2018-07-14
+ * bugfix: [blog] Add missing content block in the blog_ungleich.html template file
+2.0.1: 2018-07-14
+ * bugfix: [blog] Enable content/structure mode in blog page
+2.0: 2018-07-07
+ * #3747: [dcl,hosting] Add multiple cards support (PR #530)
+ * #3934: [dcl,hosting] Create HostingOrder outside celery task and add and associate OrderDetail with HostingOrder (PR #624)
+ * #4890: [hosting] Manage SSH keys using IPv6 of the VM (PR #640)
+ * bugfix: Fix flake8 error that was ignored in release 1.9.1
+1.9.1: 2018-06-24
+ * #4799: [dcl] Show selected vm templates only in calculator (PR #638)
+ * #4847: [comic] Add google analytics code for comic.ungleich.ch (PR #639)
+ * feature: add vm_type option to vm_template and dcl calculator to distinguish between public and ipv6only templates (PR #635)
+1.9: 2018-05-16
+ * #4559: [cms] enable discount on cms calculator
+1.8: 2018-05-01
+ * #4527: [hosting] cms calculator on non-cms pages for the hosting app
+ * bgfix: [dcl] navbar dropdown target fix
+ * bgfix: [hosting] login/signup pages footer link fix
+1.7.2: 2018-04-30
+ * bgfix: [cms] add favicon extension to ungleich cms pages
+ * #4474: [cms] reduce heading slider side padding
+1.7.1: 2018-04-21
+ * #4481: [blog] fix de blog pages 500 error
+ * #4370: [comic] new url /comic to show only comic blogs
+1.7: 2018-04-20
+ * bgfix: [all] Make /blog available on all domains
+ * #4367: [dcl] email logo resolution fix
+ * #4376: [cms] dcl promo section plugin link color changed to brighter shade
+ * #4379: [dcl] pricing without VAT
+ * bgfix: [blog] fix top menu items to show only one item
+ * #4297: [cms] favicon as a page attribute for dcl template
+1.6.5: 2018-04-08
+ * #4396: [ungleich] add favicon to ungleich blog
+ * #4327: [dcl] fix navbar logo repeat
+ * bgfix: [hosting] fix broken footer links
+ * bgfix: [dcl] remove ghost migrations from squashed migration
+ * bgfix: [cms] redirect multi-tenant urls to /cms also
+1.6.4: 2018-04-06
+ * #4362: [cms] Fix the need of dummy home page for different CMS-based sites
+1.6.3: 2018-04-05
+ * #4377: [cms] header btn external link fix
+ * #4378: [dcl cms] update CMS Integration to have different content for different domains
+1.6.2: 2018-04-01
+ * bgfix: [dcl] Fix user activation email style; add/correct some DE text
+ * #4373: [dcl] update footer menu for pw reset/login/signup/activation request pages
+1.6.1: 2018-03-28
+ * bgfix: fix header slider interval issue
+ * #4315: [cms] navbar consistency from cms page to static page
+ * #4313: [hosting] footer style fix
+1.6: 2018-03-25
+ * #4266: [dcl cms] add promotional section plugin
+ * #3842: [dcl, hosting] change number formatting for all the numbers from german to english locale
+1.5.5: 2018-03-22
+ * #4278: [dcl cms] edit options for cms navbar and header plugins
+ * bgfix: [dcl cms] fix link plugin issues and section image alignment
+1.5.4: 2018-03-17
+ * bgfix: [dcl cms] update DCLNavbarPlugin to allow change of brand logo and url
+1.5.3: 2018-03-16
+ * #4262: [dcl] Bugfix for incorrect template name
+1.5.2: 2018-03-14
+ * [devuan, ipv6] Add google analytics code for devuanhosting.com, ipv6onlyhosting.{com,net}
+ * #4246: [dcl cms] Enable full width options for DCL plugins
+ * #4247: [dcl cms] Fix alignment issues with the "plain heading" option
+1.5.1: 2018-03-11
+ * bgfix: [dcl cms] Remove datacenterlight_content placeholder conf so that we can create a cms page without calculator
+1.5: 2018-03-09
+ * #3554: [dcl] Remove some more beta access resources (some were left in the earlier release)
+ * #3452: [hosting] Back button management and cache control for hosting views
+ * #3718: [dcl] downtime page
+ * #4119: [dcl] CMS plugins for dcl pages
+ * #4231: [hosting] add company fiscal number to invoice footer
+1.4.1: 2018-02-23
+ * bgfix: [dcl] fix header style for tos page
+ * #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
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
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
+ * #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
+ [all] Added CustomUser as a parameter in get_anonymous_user function to resolve issues with tests
+1.0.23: 2017-08-11
+ * #3629: [datacentlight] Fixed navbar changing language from DE to EN between menus bug
+ * #3623: [hosting] Fixed “Confirm Order” text appearing in “Invoice” place
+ * #3633: [datacenterlight, hosting] Translated “All Rights Reserved” for German pages
+ * #3627: [datacenterlight, hosting] Added border for payment warning message when the user has already submitted card information
+ * #3620: [hosting] Updated SSH Key page with new style: new key choice page, upload key page, added icons for downloading and deleting key on mobile
+ * [hosting] bug fix: added modal icon and translation back for delete SSH Key
+ * #3660: [datacenterlight] Rearranged desktop and mobile view for “Why Data Centre Light?” IPv6/SSD section
+ * #3646: Added file with VM Template hosting migration
+ * #3617: [hosting] Fixed Password reset confirmation page style bug
+ * #3408: [hosting] Changed background image of signup/login background into smaller size
+ * #3621: [hosting] Fixed signup/login/password reset page navbar logo overlapping with form
+ * #3354: [hosting] Restyled modal
+ * #3638: [hosting] Added “download” btn on generated key list for generated keys from upload your key page
+ * #3655: [hosting] Disabled deleting SSH keys from other users
+ * #3619: [datacenterlight, hosting] Replaced 'Lato-Light' and 'Lato-Regular' with only ‘Lato’ with appropriate font-weights
+ * #3677: [hosting] Added wrapping for show SSH key modal text
+ * #3683: [hosting] Fixed footer floating bug on VM creating page
+ * #3676: [datacenterlight, hosting] Added missing card holder's name field migration
+1.0.22: 2017-07-30
+ * #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
+ * #3592: [datacenterlight] Changed “Order Now” button text to “Continue/weiter”
+ * #3579: [datacenterlight] Removed “blinks” on click on navbar menus
+ * #3577: [datacenterlight] Added backend CPU, RAM, SSD fields validation
+ * #3615: [datacenterlight] Decoupled landing VM templates from OpenNebula
+ * #3604: [datacenterlight, hosting] Font colour change for better visibility in signup/login/password request footer links
+ [all] Introduced ENABLE_DEBUG_LOGGING
+ * #3542: [datacenterlight, hosting] Fixed warning messages and deprecated url
+ * #3603: [datacenterlight] Removed navbar language option dropdown
+ * #3629: [datacenterlight] Fixed navbar language switching bug
1.0.21: 2017-07-21
* #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
* #3584: [all] Add flag is_superuser=True in MyUserManager
1.0.20: 2017-07-18
- * #3590: [digitalglarus] Added impact hub partner logo and text in digitalglarus
- [datacenterlight, hosting] Fixed overlapping of date and billing address in the mobile view
- * #3580: [datacenterlight, hosting] Introduced newly designed payment page. Cust1.0.20: 2017-07-18
* #3590: [digitalglarus] Added impact hub partner logo and text in digitalglarus
[datacenterlight, hosting] Fixed overlapping of date and billing address in the mobile view
* #3580: [datacenterlight, hosting] Introduced newly designed payment page. Customized Stripe credit card input fields
- * #3568: [all] Improved the way of adding Google analytics (ga) code. We now have ga code for ungleich, digitalglarus, blog, hosting
- and datacenterlight
- * #3564: [datacenterlight] Improved calculator form validations, both client side and server side
- [datacenterlight] Changed "Place order" button to "Submit" in the payment page
- * #3540: [datacenterlight] Improved credit card section with Stripe clarification texts and corresponding DE translationsomized Stripe credit card input fields
* #3568: [all] Improved the way of adding Google analytics (ga) code. We now have ga code for ungleich, digitalglarus, blog, hosting
and datacenterlight
* #3564: [datacenterlight] Improved calculator form validations, both client side and server side
@@ -80,14 +447,14 @@
1.0.5: 2017-06-06
* [all] General cleanup
* [datacenterlight] Add German translations
- * [datacenterlight] Change beta access to subscriptions
- * [hosting] Add German translations
+ * [datacenterlight] Change beta access to subscriptions
+ * [hosting] Add German translations
* [blog] Add German translation for header
* [opennebula_api] Improve testing, add ssh key functions
* [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] 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
* [all] Added new Domains to accept
1.0.3: 2017-06-02
@@ -99,6 +466,3 @@
* [datacenterlight] Fix initially shown price
1.0.0: 2017-05-25
* Initial stable release
-
- Next:
- [datacenterlight] Fixed credit card input issue
diff --git a/README.rst b/README.rst
index 8c8c8ddb..f297018c 100644
--- a/README.rst
+++ b/README.rst
@@ -3,6 +3,10 @@ ungleich
dynamicweb
----------
+
+.. image:: https://travis-ci.org/ungleich/dynamicweb.svg?branch=master
+ :target: https://travis-ci.org/ungleich/dynamicweb
+
Website for ungleich GmbH
=======
diff --git a/alplora/locale/de/LC_MESSAGES/django.po b/alplora/locale/de/LC_MESSAGES/django.po
index c39a4595..616ec68d 100644
--- a/alplora/locale/de/LC_MESSAGES/django.po
+++ b/alplora/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-05-30 13:47+0000\n"
+"POT-Creation-Date: 2017-10-10 21:35+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -18,137 +18,99 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: alplora/templates/alplora/contact.html:6
msgid "New message"
msgstr "Neue Nachricht"
-#: alplora/templates/alplora/contact.html:13
msgid "Name:"
msgstr "Name:"
-#: alplora/templates/alplora/contact.html:15
msgid "What is your name ?"
msgstr "Was ist Dein Name?"
-#: alplora/templates/alplora/contact.html:19
msgid "From:"
msgstr "Von:"
-#: alplora/templates/alplora/contact.html:21
msgid "You email"
msgstr "Deine Email"
-#: alplora/templates/alplora/contact.html:25
msgid "Message:"
msgstr "Nachricht:"
-#: alplora/templates/alplora/contact.html:27
msgid "Leave us your message"
msgstr "Schreibe hier Deine Nachricht"
-#: alplora/templates/alplora/contact.html:32
msgid "Close"
msgstr "schliessen"
-#: alplora/templates/alplora/contact.html:33
msgid "Send message"
msgstr "Nachricht senden"
-#: alplora/templates/alplora/contact_success.html:6
msgid "Message Sent"
msgstr "Nachricht gesendet"
-#: alplora/templates/alplora/contact_success.html:9
msgid "Thank you, we will contact you as soon as possible"
msgstr "Dankeschön! Wir melden uns sobald wie möglich!"
-#: alplora/templates/alplora/index.html:13
msgid "Find your animal anywhere, anytime"
msgstr "Finde deine Tiere"
-#: alplora/templates/alplora/index.html:99
-#: alplora/templates/alplora/index.html:463
msgid "About"
msgstr "Über"
-#: alplora/templates/alplora/index.html:102
-#: alplora/templates/alplora/index.html:248
-#: alplora/templates/alplora/index.html:469
msgid "Why Alplora?"
msgstr "Warum Alplora?"
-#: alplora/templates/alplora/index.html:105
-#: alplora/templates/alplora/index.html:466
msgid "Usecase"
msgstr ""
-#: alplora/templates/alplora/index.html:108
-#: alplora/templates/alplora/index.html:358
msgid "Testimonials"
msgstr "Referenzen"
-#: alplora/templates/alplora/index.html:111
-#: alplora/templates/alplora/index.html:423
-#: alplora/templates/alplora/index.html:477
msgid "Contact"
msgstr "Kontakt"
-#: alplora/templates/alplora/index.html:114
msgid "Login"
msgstr "Login"
-#: alplora/templates/alplora/index.html:137
msgid "Find your herd anytime, anywhere"
msgstr "Finde deine Herde jederzeit und überall"
-#: alplora/templates/alplora/index.html:138
msgid "Perfect fit for Swiss Alps"
msgstr "Perfekt für die Schweizer Alpen"
-#: alplora/templates/alplora/index.html:163
msgid "What is Alplora?"
msgstr "Was ist Alplora?"
-#: alplora/templates/alplora/index.html:164
msgid ""
"Alplora is an animal tracker made for outdoor grazing animals in Swiss Alps."
msgstr ""
"Alplora ist ein Sender, der speziell für Weidetiere in den Schweizer Alpen "
"entwickelt wurde."
-#: alplora/templates/alplora/index.html:165
msgid "Alplora is just like a cattle bell, but much better."
msgstr "Alplora ist wie eine Kuhglocke, nur viel besser."
-#: alplora/templates/alplora/index.html:174
msgid "LOST"
msgstr "VERLOREN"
-#: alplora/templates/alplora/index.html:176
msgid "When an animal gets separated from the herd and is lost."
msgstr "Wenn ein Tier sich von der Herde absondert und verloren geht."
-#: alplora/templates/alplora/index.html:184
msgid "WOLF"
msgstr "WOLF"
-#: alplora/templates/alplora/index.html:186
msgid "When a wolf gets close to the herd."
msgstr "Wenn ein Wolf sich der Herde nähert."
-#: alplora/templates/alplora/index.html:193
msgid "INJURED"
msgstr "VERLETZT"
-#: alplora/templates/alplora/index.html:195
msgid "When one of the animals is hurt."
msgstr "Wenn eins der Tiere verletzt ist."
-#: alplora/templates/alplora/index.html:205
msgid "How does Alplora track my animals?"
msgstr "Wie kann Alplora meine Tiere verfolgen und ausfindig machen ?"
-#: alplora/templates/alplora/index.html:206
msgid ""
"Each animal will be wearing a small tracker,and the tracker will be "
"sending a signal every 30 to 60 minutes."
@@ -156,33 +118,27 @@ msgstr ""
"Jedes Tier wird einen kleinen Sender tragen, welcher alle 30 bis 60 "
"Minuten ein Signal senden wird."
-#: alplora/templates/alplora/index.html:215
msgid "Access app"
msgstr "Zugang zur App"
-#: alplora/templates/alplora/index.html:217
msgid ""
"You can see the animal locations on a map by logging into our Alplora app."
msgstr ""
"Du kannst den Standort deiner Tiere jederzeit auf einer Karte verfolgen, "
"indem du dich in unsere Alplora App einloggst."
-#: alplora/templates/alplora/index.html:225
msgid "Get an alarm"
msgstr "Erhalte ein Warnsignal"
-#: alplora/templates/alplora/index.html:227
msgid ""
"When certain signals for danger are detected, Alplora sends an alarm to you."
msgstr ""
"Wenn Anzeichen von Gefahr bestehen, sendet dir die Alplora App einen "
"Warnsignal."
-#: alplora/templates/alplora/index.html:235
msgid "Find your animal"
msgstr "Finde deine Tiere"
-#: alplora/templates/alplora/index.html:238
msgid ""
"You can locate the animal in trouble on the realtime map and can take "
"actions for keeping the animal safe."
@@ -190,11 +146,9 @@ msgstr ""
"Du kannst dein Tier in Notsituationen auf einer Echtzeit-Karte lokalisieren "
"und hast die Möglichkeit es in Sicherheit zu bringen."
-#: alplora/templates/alplora/index.html:255
msgid "Perfect fit for Swiss mountains"
msgstr "Perfekt für die Schweizer Alpen"
-#: alplora/templates/alplora/index.html:257
msgid ""
"Alplora is made and tested for Swiss Alps. It is a perfect fit for Swiss "
"environment."
@@ -202,11 +156,9 @@ msgstr ""
"Alplora wurde speziell für die Schweizer Alpen entwickelt und vor Ort "
"getestet. Das Produkt passt perfekt in die Schweiz!"
-#: alplora/templates/alplora/index.html:263
msgid "Energy efficient"
msgstr "Energieeffizient"
-#: alplora/templates/alplora/index.html:265
msgid ""
"Alplora uses the latest wireless technology, our batteries last the whole "
"alp season."
@@ -214,11 +166,9 @@ msgstr ""
"Alplora arbeitet mit den neuesten Technologien, so dass der Akku die gesamte "
"Alpsaison überdauert."
-#: alplora/templates/alplora/index.html:271
msgid "Made with love"
msgstr "Mit Liebe gemacht"
-#: alplora/templates/alplora/index.html:273
msgid ""
"With a lot of love and respect for Swiss agriculture and nature, Alplora is "
"made by a Swiss company."
@@ -226,61 +176,49 @@ msgstr ""
"Alplora wurde mit viel Liebe und Respekt für die Schweizer Natur und "
"Landwirtschaft von einer Schweizer Firma entwickelt."
-#: alplora/templates/alplora/index.html:285
msgid "Who needs Alplora?"
msgstr "Wer benötigt Alplora?"
-#: alplora/templates/alplora/index.html:301
msgid " Are your animals..."
msgstr "Sind deine Tiere..."
-#: alplora/templates/alplora/index.html:304
msgid "sheep, goats, cows or llamas living freely in the Alps?"
msgstr "Schafe, Ziegen, Kühe oder Lamas, die frei in den Alpen leben?"
-#: alplora/templates/alplora/index.html:306
msgid "wearing bells?"
msgstr "solche, die Glocken tragen?"
-#: alplora/templates/alplora/index.html:308
msgid ""
"sometimes getting confused and going too far away from where they are "
"supposed to be?"
msgstr ""
"manchmal verwirrt und entfernen sich zu weit von ihrem vorgesehenen Standort?"
-#: alplora/templates/alplora/index.html:332
msgid "Do you..."
msgstr "Möchtest du..."
-#: alplora/templates/alplora/index.html:335
msgid "have animals which are staying outdoor during some time of the year?"
msgstr ""
"deine Tiere, die eine längere Zeit im Jahr unbeobachtet Draussen verbringen, "
"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?"
msgstr ""
"alarmiert werden, wenn sich eines deiner Tiere verletzt oder in Gefahr "
"befindet ?"
-#: alplora/templates/alplora/index.html:339
msgid "want to see where your animals are on your cell phone map?"
msgstr ""
"mit deinem Smartphone auf einer Karte sehen können, wo sich deine Tiere "
"befinden? "
-#: alplora/templates/alplora/index.html:341
msgid "want to make sure 24/7 that your animals are safe?"
msgstr ""
"sicherstellen, dass sich deine Tiere rund um die Uhr in Sicherheit befinden?"
-#: alplora/templates/alplora/index.html:359
msgid "What our customers say"
msgstr ""
-#: alplora/templates/alplora/index.html:379
msgid ""
"“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 "
@@ -292,11 +230,9 @@ msgstr ""
"selben Zeit andereDinge auf dem Hof unten im Dorf erledigen. Dank Alplora "
"kann ich meinen Kühenmehr Sicherheit gewährleisten."
-#: alplora/templates/alplora/index.html:382
msgid "Farmer in canton Glarus"
msgstr "Bauern im Kanton Glarus"
-#: alplora/templates/alplora/index.html:388
msgid ""
"\"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.\""
@@ -305,11 +241,9 @@ msgstr ""
"Schafe fastjedes Jahr aus den Augen verloren. Nun habe ich endlich die "
"Möglichkeit, sie zulokalisieren.\""
-#: alplora/templates/alplora/index.html:391
msgid "Owner of 50 sheep "
msgstr "Besitzerin von 50 Schafen"
-#: alplora/templates/alplora/index.html:397
msgid ""
"\"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 "
@@ -323,30 +257,23 @@ msgstr ""
"noch um meineanderen Tiere kümmern muss. Mit Alplora kann ich nun ohne "
"Probleme beides tun.\""
-#: alplora/templates/alplora/index.html:401
msgid "Farmer at Berner Oberland"
msgstr "Bauer aus dem Berner Oberland"
-#: alplora/templates/alplora/index.html:418
msgid "How do I get Alplora?"
msgstr "Wie kriege ich Zugriff zu Alplora?"
-#: alplora/templates/alplora/index.html:419
msgid "Click the button below and leave us your contact."
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."
msgstr "Das Alpora Team wird sich mit Dir schnellstens in Verbindung setzen."
-#: alplora/templates/alplora/index.html:459
msgid "Home"
msgstr "Startseite"
-#: alplora/templates/alplora/index.html:472
msgid "Testimonials "
msgstr "Referenzen"
-#: alplora/views.py:24
msgid "Message Successfully Sent"
msgstr ""
diff --git a/alplora/urls.py b/alplora/urls.py
index 071bb2ac..058f5499 100644
--- a/alplora/urls.py
+++ b/alplora/urls.py
@@ -4,9 +4,9 @@ from .views import IndexView, LoginView, ContactView
urlpatterns = [
- url(r'^/?$', IndexView.as_view(), name='index'),
- url(r'/login/', LoginView.as_view(), name='login'),
- url(r'/contact', ContactView.as_view(), name='contact'),
+ url(r'^$', IndexView.as_view(), name='index'),
+ url(r'login/', LoginView.as_view(), name='login'),
+ url(r'contact', ContactView.as_view(), name='contact'),
# url(r'^/beta-program/?$', BetaProgramView.as_view(), name='beta'),
# url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'),
]
diff --git a/cms_templates/djangocms_blog/post_list.html b/cms_templates/djangocms_blog/post_list.html
index eb1ce71b..90712e16 100644
--- a/cms_templates/djangocms_blog/post_list.html
+++ b/cms_templates/djangocms_blog/post_list.html
@@ -6,14 +6,6 @@
{% block content_blog %}
{% block blog_title %}
-
-
- {% if author %}{% trans "Articles by" %} {{ author.get_full_name }}
- {% elif archive_date %}{% trans "Archive" %} – {% if month %}{{ archive_date|date:'F' }} {% endif %}{{ year }}
- {% elif tagged_entries %}{% trans "Tag" %} – {{ tagged_entries|capfirst }}
- {% elif category %}{% trans "Category" %} – {{ category }}{% endif %}
-
-
{% endblock %}
{% for post in post_list %}
{% include "djangocms_blog/includes/blog_item.html" with post=post image="true" TRUNCWORDS_COUNT=TRUNCWORDS_COUNT %}
diff --git a/datacenterlight/admin.py b/datacenterlight/admin.py
index 7a846c71..5a1fc8a2 100644
--- a/datacenterlight/admin.py
+++ b/datacenterlight/admin.py
@@ -1,9 +1,19 @@
from django.contrib import admin
-
-from .models import BetaAccess, BetaAccessVMType, BetaAccessVM
-# Register your models here.
+from cms.admin.placeholderadmin import PlaceholderAdminMixin
+from cms.extensions import PageExtensionAdmin
+from .cms_models import CMSIntegration, CMSFaviconExtension
+from .models import VMPricing, VMTemplate
-admin.site.register(BetaAccess)
-admin.site.register(BetaAccessVMType)
-admin.site.register(BetaAccessVM)
+class CMSIntegrationAdmin(PlaceholderAdminMixin, admin.ModelAdmin):
+ list_display = ('name', 'domain')
+
+
+class CMSFaviconExtensionAdmin(PageExtensionAdmin):
+ pass
+
+
+admin.site.register(CMSIntegration, CMSIntegrationAdmin)
+admin.site.register(CMSFaviconExtension, CMSFaviconExtensionAdmin)
+admin.site.register(VMPricing)
+admin.site.register(VMTemplate)
diff --git a/datacenterlight/cms_models.py b/datacenterlight/cms_models.py
new file mode 100644
index 00000000..2d1a98b5
--- /dev/null
+++ b/datacenterlight/cms_models.py
@@ -0,0 +1,364 @@
+from cms.extensions import PageExtension
+from cms.extensions.extension_pool import extension_pool
+from cms.models.fields import PlaceholderField
+from cms.models.pluginmodel import CMSPlugin
+from django import forms
+from django.conf import settings
+from django.contrib.postgres.fields import ArrayField
+from django.contrib.sites.models import Site
+from django.db import models
+from django.utils.safestring import mark_safe
+from djangocms_text_ckeditor.fields import HTMLField
+from filer.fields.file import FilerFileField
+from filer.fields.image import FilerImageField
+
+from datacenterlight.models import VMPricing, VMTemplate
+
+
+class CMSIntegration(models.Model):
+ name = models.CharField(
+ max_length=100, default='default',
+ help_text=(
+ 'A unique name for the Integration. This name will be used to '
+ 'fetch the Integration into pages'
+ )
+ )
+ footer_placeholder = PlaceholderField(
+ 'datacenterlight_footer', related_name='dcl-footer-placeholder+'
+ )
+ navbar_placeholder = PlaceholderField(
+ 'datacenterlight_navbar', related_name='dcl-navbar-placeholder+'
+ )
+ calculator_placeholder = PlaceholderField(
+ 'datacenterlight_calculator',
+ related_name='dcl-calculator-placeholder+'
+ )
+ domain = models.ForeignKey(Site, null=True, blank=True)
+
+ class Meta:
+ unique_together = ('name', 'domain')
+
+ def __str__(self):
+ return self.name
+
+
+class CMSFaviconExtension(PageExtension):
+ favicon = FilerFileField(related_name="cms_favicon_image")
+
+
+extension_pool.register(CMSFaviconExtension)
+
+
+# Models for CMS Plugins
+
+class DCLSectionPluginModel(CMSPlugin):
+ heading = models.CharField(
+ blank=True, null=True, max_length=100,
+ help_text='An optional heading for the Section',
+ )
+ content = HTMLField()
+ TEXT_DIRECTIONS = (
+ ('left', 'Left'),
+ ('right', 'Right')
+ )
+ text_direction = models.CharField(
+ choices=TEXT_DIRECTIONS, max_length=10, default=True,
+ help_text='The alignment of text in the section'
+ )
+ html_id = models.SlugField(
+ blank=True, null=True,
+ help_text=(
+ 'An optional html id for the Section. Required to set as target '
+ 'of a link on page'
+ )
+ )
+ plain_heading = models.BooleanField(
+ default=False,
+ help_text='Select to keep the heading style simpler.'
+ )
+ center_on_mobile = models.BooleanField(
+ default=False,
+ help_text='Select to center align content on small screens.'
+ )
+ background_gradient = models.BooleanField(
+ default=False,
+ help_text='Select to add a gradient background to the section.'
+ )
+
+ def get_extra_classes(self):
+ extra_classes = self.text_direction
+ if self.center_on_mobile:
+ extra_classes += ' section-sm-center'
+ if self.background_gradient:
+ extra_classes += ' section-gradient'
+ if self.plain_heading:
+ extra_classes += ' split-section-plain'
+ return extra_classes
+
+ def __str__(self):
+ return '#' + self.html_id if self.html_id else str(self.pk)
+
+
+class DCLBannerListPluginModel(CMSPlugin):
+ heading = models.CharField(
+ blank=True, null=True, max_length=100,
+ help_text='An optional heading for the Section',
+ )
+ html_id = models.SlugField(
+ blank=True, null=True,
+ help_text=(
+ 'An optional html id for the Section. Required to set as target '
+ 'of a link on page'
+ )
+ )
+
+ def __str__(self):
+ return '#' + self.html_id if self.html_id else str(self.pk)
+
+
+class DCLBannerItemPluginModel(CMSPlugin):
+ content = HTMLField()
+ banner_text = HTMLField(
+ blank=True, null=True, max_length=100,
+ help_text='Optional text to be shown as banner in other half.',
+ )
+ banner_image = FilerImageField(
+ on_delete=models.CASCADE, null=True, blank=True,
+ help_text='Optional image to be used in the banner in other half.'
+ )
+ TEXT_DIRECTIONS = (
+ ('left', 'Left'),
+ ('right', 'Right')
+ )
+ text_direction = models.CharField(
+ choices=TEXT_DIRECTIONS, max_length=10, default=True,
+ help_text='The alignment of text in the section'
+ )
+
+ def get_extra_classes(self):
+ extra_classes = ''
+ if self.text_direction == 'left':
+ extra_classes = 'flex-row-rev'
+ return extra_classes
+
+
+class DCLLinkPluginModel(CMSPlugin):
+ target = models.CharField(
+ max_length=100,
+ help_text='Url or #id to navigate to'
+ )
+ text = models.CharField(
+ max_length=50,
+ help_text='Text for the menu item'
+ )
+ title = models.CharField(
+ blank=True, null=True, max_length=100,
+ help_text=(
+ 'Optional title text, that will be shown when a user '
+ 'hovers over the link'
+ )
+ )
+ separator = models.BooleanField(
+ default=False,
+ help_text='Select to include a separator after the previous link'
+ )
+
+
+class DCLNavbarPluginModel(CMSPlugin):
+ logo_light = FilerImageField(
+ on_delete=models.CASCADE, null=True, blank=True,
+ help_text='Logo to be used on transparent navbar',
+ related_name="dcl_navbar_logo_light",
+ )
+ logo_dark = FilerImageField(
+ on_delete=models.CASCADE, null=True, blank=True,
+ help_text='Logo to be used on white navbar',
+ related_name="dcl_navbar_logo_dark",
+ )
+ logo_url = models.URLField(max_length=300, null=True, blank=True)
+ language_dropdown = models.BooleanField(
+ default=True,
+ help_text='Select to include the language selection dropdown.'
+ )
+ show_login_option = models.BooleanField(
+ default=True,
+ help_text='Uncheck this if you do not want to show login/dashboard.'
+ )
+
+ def get_logo_dark(self):
+ # used only if atleast one logo exists
+ return self.logo_dark.url if self.logo_dark else self.logo_light.url
+
+ def get_logo_light(self):
+ # used only if atleast one logo exists
+ return self.logo_light.url if self.logo_light else self.logo_dark.url
+
+
+class DCLNavbarDropdownPluginModel(CMSPlugin):
+ target = models.CharField(
+ max_length=100, null=True, blank=True,
+ help_text='Optional Url or #id to navigate on click'
+ )
+ text = models.CharField(
+ max_length=50,
+ help_text='Text for the dropdown toggle'
+ )
+
+
+class DCLContactPluginModel(CMSPlugin):
+ heading = models.CharField(max_length=100, default="Contact", blank=True)
+ organization_name = models.CharField(
+ max_length=100, default="ungleich glarus ag", blank=True
+ )
+ email = models.EmailField(max_length=200, default="info@ungleich.ch")
+ address = models.CharField(
+ max_length=100, default="In der Au 7, Schwanden 8762", blank=True
+ )
+ country = models.CharField(
+ max_length=100, default="Switzerland", blank=True
+ )
+ form_header = models.CharField(
+ max_length=100, default="Send us a message.", blank=True
+ )
+
+
+class DCLFooterPluginModel(CMSPlugin):
+ copyright_label = models.CharField(
+ max_length=100, default='ungleich glarus ag', blank=True,
+ help_text='Name of the company alongside the copyright year'
+ )
+
+
+class DCLSectionIconPluginModel(CMSPlugin):
+ fontawesome_icon_name = models.CharField(
+ max_length=30,
+ help_text=mark_safe(
+ 'Name of the fontawesome icon to use. '
+ ''
+ 'Refer docs.'
+ )
+ )
+
+
+class DCLSectionImagePluginModel(CMSPlugin):
+ image = FilerImageField(
+ on_delete=models.CASCADE,
+ help_text=(
+ 'Image file to be used in section. Add multiple plugins '
+ 'to add more than one image'
+ )
+ )
+ caption = models.CharField(
+ max_length=100, null=True, blank=True,
+ help_text='Optional caption for the image.'
+ )
+
+
+class DCLSectionPromoPluginModel(CMSPlugin):
+ background_image = FilerImageField(
+ on_delete=models.CASCADE, null=True, blank=True,
+ help_text=('Optional background image for the Promo Section'),
+ related_name="dcl_section_promo_promo",
+ )
+ heading = models.CharField(
+ blank=True, null=True, max_length=100,
+ help_text='An optional heading for the Promo Section',
+ )
+ subheading = models.CharField(
+ blank=True, null=True, max_length=200,
+ help_text='An optional subheading for the Promo Section',
+ )
+ content = HTMLField()
+ html_id = models.SlugField(
+ blank=True, null=True,
+ help_text=(
+ 'An optional html id for the Section. Required to set as target '
+ 'of a link on page'
+ )
+ )
+ plain_heading = models.BooleanField(
+ default=False,
+ help_text='Select to keep the heading style simpler.'
+ )
+ text_center = models.BooleanField(
+ default=False,
+ help_text='Select to center align content on small screens.'
+ )
+
+ def __str__(self):
+ return '#' + self.html_id if self.html_id else str(self.pk)
+
+ def get_extra_classes(self):
+ extra_classes = ''
+ if self.text_center:
+ extra_classes += ' text-center'
+ if self.plain_heading:
+ extra_classes += ' promo-section-plain'
+ if self.background_image:
+ extra_classes += ' promo-with-bg'
+ return extra_classes
+
+
+class MultipleChoiceArrayField(ArrayField):
+ """
+ A field that allows us to store an array of choices.
+ Uses Django's Postgres ArrayField
+ and a MultipleChoiceField for its formfield.
+ """
+ VMTemplateChoices = []
+ if settings.OPENNEBULA_DOMAIN != 'test_domain':
+ VMTemplateChoices = list(
+ (
+ str(obj.opennebula_vm_template_id),
+ (obj.name + ' - ' + VMTemplate.IPV6.title()
+ if obj.vm_type == VMTemplate.IPV6 else obj.name
+ )
+ )
+ for obj in VMTemplate.objects.all()
+ )
+
+ def formfield(self, **kwargs):
+ defaults = {
+ 'form_class': forms.MultipleChoiceField,
+ 'choices': self.VMTemplateChoices,
+ }
+ defaults.update(kwargs)
+ # Skip our parent's formfield implementation completely as we don't
+ # care for it.
+ # pylint:disable=bad-super-call
+ return super(ArrayField, self).formfield(**defaults)
+
+
+class DCLCalculatorPluginModel(CMSPlugin):
+ pricing = models.ForeignKey(
+ VMPricing,
+ related_name="dcl_custom_pricing_vm_pricing",
+ help_text='Choose a pricing that will be associated with this '
+ 'Calculator'
+ )
+ vm_type = models.CharField(
+ max_length=50, choices=VMTemplate.VM_TYPE_CHOICES,
+ default=VMTemplate.PUBLIC
+ )
+ vm_templates_to_show = MultipleChoiceArrayField(
+ base_field=models.CharField(
+ blank=True,
+ max_length=256,
+ ),
+ default=list,
+ blank=True,
+ help_text="Recommended: If you wish to show all templates of the "
+ "corresponding VM Type (public/ipv6only), please do not "
+ "select any of the items in the above field. "
+ "This will allow any new template(s) added "
+ "in the backend to be automatically listed in this "
+ "calculator instance."
+ )
+ default_selected_template = models.CharField(
+ default="Devuan Ascii",
+ null=True,
+ max_length=128,
+ help_text="Write the name of the template that you need selected as"
+ " default when the calculator loads"
+ )
+ enable_512mb_ram = models.BooleanField(default=False)
diff --git a/datacenterlight/cms_plugins.py b/datacenterlight/cms_plugins.py
new file mode 100644
index 00000000..c3ec974f
--- /dev/null
+++ b/datacenterlight/cms_plugins.py
@@ -0,0 +1,180 @@
+from cms.plugin_base import CMSPluginBase
+from cms.plugin_pool import plugin_pool
+
+from .cms_models import (
+ DCLBannerItemPluginModel, DCLBannerListPluginModel, DCLContactPluginModel,
+ DCLFooterPluginModel, DCLLinkPluginModel, DCLNavbarDropdownPluginModel,
+ DCLSectionIconPluginModel, DCLSectionImagePluginModel,
+ DCLSectionPluginModel, DCLNavbarPluginModel,
+ DCLSectionPromoPluginModel, DCLCalculatorPluginModel
+)
+from .models import VMTemplate
+from datacenterlight.utils import clear_all_session_vars
+
+
+@plugin_pool.register_plugin
+class DCLSectionPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Section Plugin"
+ model = DCLSectionPluginModel
+ render_template = "datacenterlight/cms/section.html"
+ cache = False
+ allow_children = True
+ child_classes = [
+ 'DCLSectionIconPlugin', 'DCLSectionImagePlugin',
+ 'DCLSectionPromoPlugin', 'UngleichHTMLPlugin', 'DCLCalculatorPlugin'
+ ]
+
+ def render(self, context, instance, placeholder):
+ context = super(DCLSectionPlugin, self).render(
+ context, instance, placeholder
+ )
+ context['children_to_side'] = []
+ context['children_to_content'] = []
+ context['children_calculator'] = []
+ if instance.child_plugin_instances is not None:
+ right_children = [
+ 'DCLSectionImagePluginModel',
+ 'DCLSectionIconPluginModel',
+ ]
+ for child in instance.child_plugin_instances:
+ if child.__class__.__name__ in right_children:
+ context['children_to_side'].append(child)
+ elif child.plugin_type == 'DCLCalculatorPlugin':
+ context['children_calculator'].append(child)
+ else:
+ context['children_to_content'].append(child)
+ return context
+
+
+@plugin_pool.register_plugin
+class DCLSectionIconPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Section Icon Plugin"
+ model = DCLSectionIconPluginModel
+ render_template = "datacenterlight/cms/section_icon.html"
+ cache = False
+ require_parent = True
+
+
+@plugin_pool.register_plugin
+class DCLSectionImagePlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Section Image Plugin"
+ model = DCLSectionImagePluginModel
+ render_template = "datacenterlight/cms/section_image.html"
+ cache = False
+ require_parent = True
+
+
+@plugin_pool.register_plugin
+class DCLSectionPromoPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Section Promo Plugin"
+ model = DCLSectionPromoPluginModel
+ render_template = "datacenterlight/cms/section_promo.html"
+ cache = False
+
+
+@plugin_pool.register_plugin
+class DCLCalculatorPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Calculator Plugin"
+ model = DCLCalculatorPluginModel
+ render_template = "datacenterlight/cms/calculator.html"
+ cache = False
+ require_parent = True
+
+ def render(self, context, instance, placeholder):
+ clear_all_session_vars(context['request'])
+ context = super(DCLCalculatorPlugin, self).render(
+ context, instance, placeholder
+ )
+ ids = instance.vm_templates_to_show
+ if ids:
+ context['templates'] = VMTemplate.objects.filter(
+ vm_type=instance.vm_type
+ ).filter(opennebula_vm_template_id__in=ids).order_by('name')
+ else:
+ context['templates'] = VMTemplate.objects.filter(
+ vm_type=instance.vm_type
+ ).order_by('name')
+ context['instance'] = instance
+ context['min_ram'] = 0.5 if instance.enable_512mb_ram else 1
+ return context
+
+
+@plugin_pool.register_plugin
+class DCLBannerListPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Banner List Plugin"
+ model = DCLBannerListPluginModel
+ render_template = "datacenterlight/cms/banner_list.html"
+ cache = False
+ allow_children = True
+ child_classes = ['DCLBannerItemPlugin']
+
+
+@plugin_pool.register_plugin
+class DCLBannerItemPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Banner Item Plugin"
+ model = DCLBannerItemPluginModel
+ render_template = "datacenterlight/cms/banner_item.html"
+ cache = False
+ require_parent = True
+ parent_classes = ['DCLBannerListPlugin']
+
+
+@plugin_pool.register_plugin
+class DCLNavbarPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Navbar Plugin"
+ model = DCLNavbarPluginModel
+ render_template = "datacenterlight/cms/navbar.html"
+ cache = False
+ allow_children = True
+ child_classes = ['DCLLinkPlugin', 'DCLNavbarDropdownPlugin']
+
+
+@plugin_pool.register_plugin
+class DCLNavbarDropdownPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Navbar Dropdown Plugin"
+ model = DCLNavbarDropdownPluginModel
+ render_template = "datacenterlight/cms/navbar_dropdown.html"
+ cache = False
+ allow_children = True
+ child_classes = ['DCLLinkPlugin']
+ require_parent = True
+ parent_classes = ['DCLNavbarPlugin']
+
+
+@plugin_pool.register_plugin
+class DCLLinkPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Link Plugin"
+ model = DCLLinkPluginModel
+ render_template = "datacenterlight/cms/link.html"
+ cache = False
+ require_parent = True
+
+
+@plugin_pool.register_plugin
+class DCLContactPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Contact Plugin"
+ model = DCLContactPluginModel
+ render_template = "datacenterlight/cms/contact.html"
+ cache = False
+
+
+@plugin_pool.register_plugin
+class DCLFooterPlugin(CMSPluginBase):
+ module = "Datacenterlight"
+ name = "DCL Footer Plugin"
+ model = DCLFooterPluginModel
+ render_template = "datacenterlight/cms/footer.html"
+ cache = False
+ allow_children = True
+ child_classes = ['DCLLinkPlugin']
diff --git a/datacenterlight/cms_toolbar.py b/datacenterlight/cms_toolbar.py
new file mode 100644
index 00000000..15a8cb4b
--- /dev/null
+++ b/datacenterlight/cms_toolbar.py
@@ -0,0 +1,24 @@
+from cms.extensions.toolbar import ExtensionToolbar
+from cms.toolbar_pool import toolbar_pool
+from django.utils.translation import ugettext_lazy as _
+
+from .cms_models import CMSFaviconExtension
+
+
+@toolbar_pool.register
+class CMSFaviconExtensionToolbar(ExtensionToolbar):
+ # defineds the model for the current toolbar
+ model = CMSFaviconExtension
+
+ def populate(self):
+ # setup the extension toolbar with permissions and sanity checks
+ current_page_menu = self._setup_extension_toolbar()
+ # if it's all ok
+ if current_page_menu:
+ # retrieves the instance of the current extension (if any) and the toolbar item url
+ page_extension, url = self.get_page_extension_admin()
+ if url:
+ # adds a toolbar item
+ current_page_menu.add_modal_item(
+ _('CMS Favicon'), url=url, disabled=not self.toolbar.edit_mode
+ )
diff --git a/datacenterlight/forms.py b/datacenterlight/forms.py
index 33d95c29..b697f694 100644
--- a/datacenterlight/forms.py
+++ b/datacenterlight/forms.py
@@ -1,19 +1,9 @@
from django import forms
-from .models import BetaAccess
+from .models import ContactUs
-class BetaAccessForm(forms.ModelForm):
- email = forms.CharField(widget=forms.EmailInput())
-
+class ContactForm(forms.ModelForm):
class Meta:
- fields = ['name', 'email']
- model = BetaAccess
-
-
-# class BetaAccessVMForm(forms.ModelForm):
-# type = forms.CharField(widget=forms.EmailInput())
-
-# class Meta:
-# fields = ['email']
-# model = BetaAccessVM
+ fields = ['name', 'email', 'message']
+ model = ContactUs
diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po
index 5aa97bdd..6d58673a 100644
--- a/datacenterlight/locale/de/LC_MESSAGES/django.po
+++ b/datacenterlight/locale/de/LC_MESSAGES/django.po
@@ -8,276 +8,227 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-13 23:55+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME \n"
+"POT-Creation-Date: 2019-11-15 17:33+0000\n"
+"PO-Revision-Date: 2018-03-30 23:22+0000\n"
+"Last-Translator: b'Anonymous User '\n"
"Language-Team: LANGUAGE \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Translated-Using: django-rosetta 0.8.1\n"
-#: templates/datacenterlight/beta_access.html:13
-msgid "Enter name"
+msgid "CMS Favicon"
+msgstr "CMS Favicon"
+
+#, 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 "Your VM is almost ready!"
+msgstr "Deine VM ist fast fertig!"
+
+msgid ""
+"You need to specify your public SSH key to access your VM. You can either "
+"add your existing key, or generate a new key pair by clicking the generate "
+"button below. After choosing your public SSH key option you’ll be directed "
+"to the order confirmation page."
+msgstr ""
+"Du musst deinen öffentlichen SSH-Schlüssel angeben, um auf deine VM "
+"zugreifen zu können. Du kannst entweder deinen vorhandenen Schlüssel "
+"hinzufügen oder ein neues Schlüsselpaar generieren, indem du auf die "
+"Schaltfläche \"Generieren\" unten klickst. Nachdem du deine öffentliche SSH-"
+"Schlüsseloption ausgewählt hast, wirst du zur Bestellbestätigungsseite "
+"weitergeleitet. "
+
+msgid "All Rights Reserved"
+msgstr "Alle Rechte vorbehalten"
+
+msgid "Toggle navigation"
+msgstr "Umschalten"
+
+msgid "Login"
+msgstr "Anmelden"
+
+msgid "Dashboard"
+msgstr "Dashboard"
+
+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"
msgstr "Name"
-#: templates/datacenterlight/beta_access.html:17
-msgid "Enter email"
-msgstr "E-Mail-Adresse"
-
-#: templates/datacenterlight/beta_access.html:21
-msgid "Request Beta Access"
-msgstr "Beantrage Beta-Zugang"
-
-#: templates/datacenterlight/beta_success.html:10
-msgid "Request Sent"
-msgstr "Anfrage verschickt"
-
-#: templates/datacenterlight/beta_success.html:13
-msgid ""
-"Thank you for your subscription! You will receive a confirmation mail from "
-"our team"
-msgstr ""
-"Vielen dank für Ihre Anmeldung. Sie erhalten in kürze eine Bestätigungsmail "
-"von unserem Team"
-
-#: templates/datacenterlight/calculator_form.html:5
-#: templates/datacenterlight/pricing.html:22
-msgid "VM hosting"
-msgstr ""
-
-#: templates/datacenterlight/calculator_form.html:9
-msgid "month"
-msgstr "Monat"
-
-#: templates/datacenterlight/calculator_form.html:11
-#: templates/datacenterlight/pricing.html:28
-msgid "VAT included"
-msgstr "MwSt. inklusive"
-
-#: templates/datacenterlight/calculator_form.html:16
-#: templates/datacenterlight/pricing.html:33
-msgid "Hosted in Switzerland"
-msgstr "Standort: Schweiz"
-
-#: templates/datacenterlight/calculator_form.html:21
-msgid "Please enter a value in range 1 - 48."
-msgstr "Bitte gib einen Wert von 1 bis 48 ein."
-
-#: templates/datacenterlight/calculator_form.html:30
-msgid "Please enter a value in range 2 - 200."
-msgstr "Bitte gib einen Wert von 2 bis 200 ein."
-
-#: templates/datacenterlight/calculator_form.html:39
-msgid "Please enter a value in range 10 - 2000."
-msgstr "Bitte gib einen Wert von 10 bis 200 ein."
-
-#: templates/datacenterlight/calculator_form.html:40
-#: templates/datacenterlight/pricing.html:50
-msgid "GB Storage (SSD)"
-msgstr "GB Storage (SSD)"
-
-#: templates/datacenterlight/calculator_form.html:59
-msgid "Name"
-msgstr ""
-
-#: templates/datacenterlight/calculator_form.html:60
-msgid "Your Name"
-msgstr "Dein Name"
-
-#: templates/datacenterlight/calculator_form.html:60
msgid "Please enter your name."
msgstr "Bitte gib Deinen Namen ein."
-#: templates/datacenterlight/calculator_form.html:74
msgid "Email"
msgstr "E-Mail-Adresse"
-#: templates/datacenterlight/calculator_form.html:75
-msgid "Your Email"
-msgstr "Deine E-Mail"
-
-#: templates/datacenterlight/calculator_form.html:75
msgid "Please enter a valid email address."
msgstr "Bitte gib eine gültige E-Mailadresse ein."
-#: templates/datacenterlight/calculator_form.html:88
-#: templates/datacenterlight/pricing.html:79
-msgid "Order Now!"
-msgstr "Bestelle jetzt!"
+msgid "Message"
+msgstr "Nachricht"
-#: templates/datacenterlight/emails/request_access_confirmation.html:99
-#: templates/datacenterlight/emails/request_access_confirmation.txt:99
-msgid "Thank you for your request."
-msgstr "Vielen Dank für Ihre Anfrage."
-
-#: templates/datacenterlight/emails/request_access_confirmation.html:104
-#: templates/datacenterlight/emails/request_access_confirmation.txt:104
-msgid "You are one step away from being our beta tester!"
+msgid "Sorry, there was an unexpected error. Kindly retry."
msgstr ""
-"Sie sind nur noch einen Schritt davon entfernt, unser Beta-Tester zu werden!"
+"Bitte entschuldige, es scheint ein unerwarteter Fehler aufgetreten zu sein. "
+"Versuche es doch bitte noch einmal."
-#: templates/datacenterlight/emails/request_access_confirmation.html:105
-#: templates/datacenterlight/emails/request_access_confirmation.txt:105
-msgid ""
-"Currently we are running our tests to make sure everything runs perfectly."
-msgstr ""
-"Momentan testen wir die Beta-Umgebung um sie für Ihren Gebrauch "
-"sicherzustellen."
+msgid "SUBMIT"
+msgstr "ABSENDEN"
-#: templates/datacenterlight/emails/request_access_confirmation.html:106
-#: templates/datacenterlight/emails/request_access_confirmation.txt:106
-msgid ""
-"In the meantime, we would like to ask you a little patience until our "
-"team contacts you with beta access."
-msgstr ""
-"Wir werden dann sobald als möglich Ihren Beta-Zugang erstellen und Sie "
-"daraufhin kontaktieren.Bis dahin bitten wir Sie um etwas Geduld."
+msgid "Data Center Light Account Activation"
+msgstr "Data Center Light Account Aktivierung"
-#: templates/datacenterlight/emails/request_access_confirmation.html:107
-#: templates/datacenterlight/emails/request_access_confirmation.txt:107
-msgid "Thank you!"
-msgstr "Vielen Dank!"
-
-#: templates/datacenterlight/emails/user_activation.html:99
-#: templates/datacenterlight/emails/user_activation.txt:3
-msgid "account activation"
-msgstr "Accountaktivierung"
-
-#: templates/datacenterlight/emails/user_activation.html:105
#, python-format
msgid ""
-"\n"
-" You can activate your %(dcl_text)s account by clicking here.
\n"
-" You can also copy and paste the following link into the "
-"address bar of your browser and follow the link in order to activate your "
-"datacenterlight account. \n"
-" %(base_url)s%(activation_link)s\n"
-" "
+"You can activate your Data Center Light account by clicking here."
msgstr ""
-"\n"
-" Klicke hier "
-"um deinen %(dcl_text)s zu aktivieren.