From 0e72f8a4367c8ada9c81513b1b36b24469ed19dd Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Sun, 20 Aug 2017 03:30:10 +0530 Subject: [PATCH 0001/1840] downtime page --- .../datacenterlight/css/downtime-page.css | 52 +++++++++++++++ .../templates/datacenterlight/downtime.html | 63 +++++++++++++++++++ datacenterlight/urls.py | 11 +++- 3 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 datacenterlight/static/datacenterlight/css/downtime-page.css create mode 100644 datacenterlight/templates/datacenterlight/downtime.html diff --git a/datacenterlight/static/datacenterlight/css/downtime-page.css b/datacenterlight/static/datacenterlight/css/downtime-page.css new file mode 100644 index 00000000..9bbfa5bc --- /dev/null +++ b/datacenterlight/static/datacenterlight/css/downtime-page.css @@ -0,0 +1,52 @@ +body { + font-family: Lato, sans-serif; + font-weight: 300; + font-size: 20px; + line-height: 1; +} + +h1 { + font-weight: 300; + font-size: 52px; + text-align: center; +} + +nav { + padding: 15px; +} + +.downtime-container { + max-width: 1200px; + margin: auto; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.downtime-msg { + text-align: center; + font-size: 30px; +} + +.downtime-contact { + max-width: 300px; + margin: auto; + color: #4a90e2; +} + +h2 { + font-weight: 300; + font-size: 24px; + text-align: center; +} +p { + margin: 15px auto +} +.xl_p { + margin: 15px auto; +} + +a { + color: #4a90e2; + text-decoration: none; +} \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/downtime.html b/datacenterlight/templates/datacenterlight/downtime.html new file mode 100644 index 00000000..dd5954ca --- /dev/null +++ b/datacenterlight/templates/datacenterlight/downtime.html @@ -0,0 +1,63 @@ +{% load staticfiles bootstrap3%} +{% load i18n %} + + + + + + + + + + + + ungleich + + + + + + + + + + + + + + {% include "google_analytics.html" %} + + + + + +
+ + +

{% trans "You caught us while working!" %}

+
+

{% trans "We're doing scheduled maintainence from" %}

+

17:00 21.08.2017 {% trans "to" %} 23:00 21.08.2017 CEST.

+
+

{% trans "If you need immediate assistance, please contact us at" %}

+ +
+ + + diff --git a/datacenterlight/urls.py b/datacenterlight/urls.py index a3aed7a6..a0942695 100644 --- a/datacenterlight/urls.py +++ b/datacenterlight/urls.py @@ -1,17 +1,22 @@ from django.conf.urls import url +from django.views.generic import TemplateView from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView, SuccessView, \ - PaymentOrderView, OrderConfirmationView, WhyDataCenterLightView + PaymentOrderView, OrderConfirmationView, WhyDataCenterLightView urlpatterns = [ url(r'^$', IndexView.as_view(), name='index'), - url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(), name='whydatacenterlight'), + url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(), + 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'^order-confirmation/?$', OrderConfirmationView.as_view(), name='order_confirmation'), + url(r'^order-confirmation/?$', OrderConfirmationView.as_view(), + name='order_confirmation'), url(r'^order-success/?$', SuccessView.as_view(), name='order_success'), url(r'^beta_access?$', BetaAccessView.as_view(), name='beta_access'), + + url(r'test/?$', TemplateView.as_view(template_name='datacenterlight/downtime.html')), ] From 06c68873aea768ba04419a36aac3ae123fd08713 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Sun, 20 Aug 2017 03:59:24 +0530 Subject: [PATCH 0002/1840] downtime.html modified as a static html page --- .../datacenterlight/css/downtime-page.css | 52 ----------- .../templates/datacenterlight/downtime.html | 86 ++++++++++++++----- 2 files changed, 64 insertions(+), 74 deletions(-) delete mode 100644 datacenterlight/static/datacenterlight/css/downtime-page.css diff --git a/datacenterlight/static/datacenterlight/css/downtime-page.css b/datacenterlight/static/datacenterlight/css/downtime-page.css deleted file mode 100644 index 9bbfa5bc..00000000 --- a/datacenterlight/static/datacenterlight/css/downtime-page.css +++ /dev/null @@ -1,52 +0,0 @@ -body { - font-family: Lato, sans-serif; - font-weight: 300; - font-size: 20px; - line-height: 1; -} - -h1 { - font-weight: 300; - font-size: 52px; - text-align: center; -} - -nav { - padding: 15px; -} - -.downtime-container { - max-width: 1200px; - margin: auto; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.downtime-msg { - text-align: center; - font-size: 30px; -} - -.downtime-contact { - max-width: 300px; - margin: auto; - color: #4a90e2; -} - -h2 { - font-weight: 300; - font-size: 24px; - text-align: center; -} -p { - margin: 15px auto -} -.xl_p { - margin: 15px auto; -} - -a { - color: #4a90e2; - text-decoration: none; -} \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/downtime.html b/datacenterlight/templates/datacenterlight/downtime.html index dd5954ca..17c40d79 100644 --- a/datacenterlight/templates/datacenterlight/downtime.html +++ b/datacenterlight/templates/datacenterlight/downtime.html @@ -1,5 +1,3 @@ -{% load staticfiles bootstrap3%} -{% load i18n %} @@ -13,23 +11,69 @@ ungleich - - + @@ -37,25 +81,23 @@
-

{% trans "You caught us while working!" %}

+

You caught us while working!

-

{% trans "We're doing scheduled maintainence from" %}

-

17:00 21.08.2017 {% trans "to" %} 23:00 21.08.2017 CEST.

+

We're doing scheduled maintenance from

+

17:00 21.08.2017 to 23:00 21.08.2017 CEST.

-

{% trans "If you need immediate assistance, please contact us at" %}

+

If you need immediate assistance, please contact us at

From 8b5117ba8054ab9dd4b4caab30b7999705ae90a8 Mon Sep 17 00:00:00 2001 From: PCoder Date: Fri, 25 Aug 2017 13:28:16 +0530 Subject: [PATCH 0003/1840] Commented code that was causing the error when executing the tests --- hosting/test_forms.py | 67 ++++++++---------- hosting/test_models.py | 150 ++++++++++++++++++++--------------------- hosting/test_views.py | 70 +++++++++---------- 3 files changed, 139 insertions(+), 148 deletions(-) diff --git a/hosting/test_forms.py b/hosting/test_forms.py index e0f5df30..dd5ee94a 100644 --- a/hosting/test_forms.py +++ b/hosting/test_forms.py @@ -1,14 +1,9 @@ from django.test import TestCase - -from unittest import mock from model_mommy import mommy - -from .forms import HostingOrderAdminForm, HostingUserLoginForm, HostingUserSignupForm -from .models import VirtualMachinePlan +from .forms import HostingUserLoginForm, HostingUserSignupForm class HostingUserLoginFormTest(TestCase): - def setUp(self): password = 'user_password' self.user = mommy.make('CustomUser') @@ -34,9 +29,7 @@ class HostingUserLoginFormTest(TestCase): class HostingUserSignupFormTest(TestCase): - def setUp(self): - self.completed_data = { 'name': 'test name', 'email': 'test@ungleich.com', @@ -58,13 +51,11 @@ class HostingUserSignupFormTest(TestCase): class HostingOrderAdminFormTest(TestCase): - def setUp(self): - self.customer = mommy.make('StripeCustomer') self.vm_plan = mommy.make('VirtualMachinePlan') - self.vm_canceled_plan = mommy.make('VirtualMachinePlan', - status=VirtualMachinePlan.CANCELED_STATUS) + # self.vm_canceled_plan = mommy.make('VirtualMachinePlan', + # status=VirtualMachinePlan.CANCELED_STATUS) self.mocked_charge = { 'amount': 5100, @@ -87,30 +78,30 @@ class HostingOrderAdminFormTest(TestCase): 'customer': None } - @mock.patch('utils.stripe_utils.StripeUtils.make_charge') - def test_valid_form(self, stripe_mocked_call): - stripe_mocked_call.return_value = { - 'paid': True, - 'response_object': self.mocked_charge, - 'error': None - } - form = HostingOrderAdminForm(data=self.completed_data) - self.assertTrue(form.is_valid()) + # @mock.patch('utils.stripe_utils.StripeUtils.make_charge') + # def test_valid_form(self, stripe_mocked_call): + # stripe_mocked_call.return_value = { + # 'paid': True, + # 'response_object': self.mocked_charge, + # 'error': None + # } + # form = HostingOrderAdminForm(data=self.completed_data) + # self.assertTrue(form.is_valid()) - @mock.patch('utils.stripe_utils.StripeUtils.make_charge') - def test_invalid_form_canceled_vm(self, stripe_mocked_call): - - self.completed_data.update({ - 'vm_plan': self.vm_canceled_plan.id - }) - stripe_mocked_call.return_value = { - 'paid': True, - 'response_object': self.mocked_charge, - 'error': None - } - form = HostingOrderAdminForm(data=self.completed_data) - self.assertFalse(form.is_valid()) - - def test_invalid_form(self): - form = HostingOrderAdminForm(data=self.incompleted_data) - self.assertFalse(form.is_valid()) + # @mock.patch('utils.stripe_utils.StripeUtils.make_charge') + # def test_invalid_form_canceled_vm(self, stripe_mocked_call): + # + # self.completed_data.update({ + # 'vm_plan': self.vm_canceled_plan.id + # }) + # stripe_mocked_call.return_value = { + # 'paid': True, + # 'response_object': self.mocked_charge, + # 'error': None + # } + # form = HostingOrderAdminForm(data=self.completed_data) + # self.assertFalse(form.is_valid()) + # + # def test_invalid_form(self): + # form = HostingOrderAdminForm(data=self.incompleted_data) + # self.assertFalse(form.is_valid()) diff --git a/hosting/test_models.py b/hosting/test_models.py index 2b41045b..944044ea 100644 --- a/hosting/test_models.py +++ b/hosting/test_models.py @@ -1,75 +1,75 @@ -from django.test import TestCase - -from django.core.management import call_command - - -from .models import VirtualMachineType - - -class VirtualMachineTypeModelTest(TestCase): - - def setUp(self): - self.HETZNER_NUG_NAME = 'hetzner_nug' - self.HETZNER_NAME = 'hetzner' - self.HETZNER_RAID6_NAME = 'hetzner_raid6' - self.HETZNER_GLUSTERFS_NAME = 'hetzner_glusterfs' - self.BERN_NAME = 'bern' - self.HETZNER_NUG_EXPECTED_PRICE = 79 - self.HETZNER_EXPECTED_PRICE = 180 - self.HETZNER_RAID6_EXPECTED_PRICE = 216 - self.HETZNER_GLUSTERFS_EXPECTED_PRICE = 252 - self.BERN_EXPECTED_PRICE = 202 - - call_command('create_vm_types') - - def test_calculate_price(self): - - # hetzner_nug - # specifications = { - # 'cores': 2, - # 'memory': 10, - # 'disk_size': 100 - # } - # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NUG_NAME) - # calculated_price = vm_type.calculate_price(specifications) - # self.assertEqual(calculated_price, self.HETZNER_NUG_EXPECTED_PRICE) - - # hetzner - specifications = { - 'cores': 2, - 'memory': 10, - 'disk_size': 100 - } - vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NAME) - calculated_price = vm_type.calculate_price(specifications) - self.assertEqual(calculated_price, self.HETZNER_EXPECTED_PRICE) - - # hetzner_raid6 - # specifications = { - # 'cores': 2, - # 'memory': 10, - # 'disk_size': 100 - # } - # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_RAID6_NAME) - # calculated_price = vm_type.calculate_price(specifications) - # self.assertEqual(calculated_price, self.HETZNER_RAID6_EXPECTED_PRICE) - - # hetzner_glusterfs - # specifications = { - # 'cores': 2, - # 'memory': 10, - # 'disk_size': 100 - # } - # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_GLUSTERFS_NAME) - # calculated_price = vm_type.calculate_price(specifications) - # self.assertEqual(calculated_price, self.HETZNER_GLUSTERFS_EXPECTED_PRICE) - - # bern - specifications = { - 'cores': 2, - 'memory': 10, - 'disk_size': 100 - } - vm_type = VirtualMachineType.objects.get(hosting_company=self.BERN_NAME) - calculated_price = vm_type.calculate_price(specifications) - self.assertEqual(calculated_price, self.BERN_EXPECTED_PRICE) +# from django.test import TestCase +# +# from django.core.management import call_command +# +# +# #from .models import VirtualMachineType +# +# +# class VirtualMachineTypeModelTest(TestCase): +# +# def setUp(self): +# self.HETZNER_NUG_NAME = 'hetzner_nug' +# self.HETZNER_NAME = 'hetzner' +# self.HETZNER_RAID6_NAME = 'hetzner_raid6' +# self.HETZNER_GLUSTERFS_NAME = 'hetzner_glusterfs' +# self.BERN_NAME = 'bern' +# self.HETZNER_NUG_EXPECTED_PRICE = 79 +# self.HETZNER_EXPECTED_PRICE = 180 +# self.HETZNER_RAID6_EXPECTED_PRICE = 216 +# self.HETZNER_GLUSTERFS_EXPECTED_PRICE = 252 +# self.BERN_EXPECTED_PRICE = 202 +# +# call_command('create_vm_types') +# +# def test_calculate_price(self): +# +# # hetzner_nug +# # specifications = { +# # 'cores': 2, +# # 'memory': 10, +# # 'disk_size': 100 +# # } +# # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NUG_NAME) +# # calculated_price = vm_type.calculate_price(specifications) +# # self.assertEqual(calculated_price, self.HETZNER_NUG_EXPECTED_PRICE) +# +# # hetzner +# specifications = { +# 'cores': 2, +# 'memory': 10, +# 'disk_size': 100 +# } +# vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_NAME) +# calculated_price = vm_type.calculate_price(specifications) +# self.assertEqual(calculated_price, self.HETZNER_EXPECTED_PRICE) +# +# # hetzner_raid6 +# # specifications = { +# # 'cores': 2, +# # 'memory': 10, +# # 'disk_size': 100 +# # } +# # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_RAID6_NAME) +# # calculated_price = vm_type.calculate_price(specifications) +# # self.assertEqual(calculated_price, self.HETZNER_RAID6_EXPECTED_PRICE) +# +# # hetzner_glusterfs +# # specifications = { +# # 'cores': 2, +# # 'memory': 10, +# # 'disk_size': 100 +# # } +# # vm_type = VirtualMachineType.objects.get(hosting_company=self.HETZNER_GLUSTERFS_NAME) +# # calculated_price = vm_type.calculate_price(specifications) +# # self.assertEqual(calculated_price, self.HETZNER_GLUSTERFS_EXPECTED_PRICE) +# +# # bern +# specifications = { +# 'cores': 2, +# 'memory': 10, +# 'disk_size': 100 +# } +# vm_type = VirtualMachineType.objects.get(hosting_company=self.BERN_NAME) +# calculated_price = vm_type.calculate_price(specifications) +# self.assertEqual(calculated_price, self.BERN_EXPECTED_PRICE) diff --git a/hosting/test_views.py b/hosting/test_views.py index aa9a9ace..e8853c9f 100644 --- a/hosting/test_views.py +++ b/hosting/test_views.py @@ -13,11 +13,11 @@ from stored_messages.models import Inbox from membership.models import CustomUser, StripeCustomer -from .models import VirtualMachineType, HostingOrder, VirtualMachinePlan +from .models import HostingOrder from .views import DjangoHostingView, RailsHostingView, NodeJSHostingView, LoginView, SignupView, \ PaymentVMView, OrdersHostingDetailView, OrdersHostingListView, VirtualMachineView, \ VirtualMachinesPlanListView, PasswordResetView, PasswordResetConfirmView, HostingPricingView, \ - NotificationsView, MarkAsReadNotificationView, GenerateVMSSHKeysView + NotificationsView, MarkAsReadNotificationView from utils.tests import BaseTestCase @@ -47,15 +47,15 @@ class DjangoHostingViewTest(TestCase, ProcessVMSelectionTestMixin): self.view = DjangoHostingView() self.expected_template = 'hosting/django.html' HOSTING = 'django' - configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) + #configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) self.expected_context = { 'hosting': HOSTING, 'hosting_long': "Django", - 'configuration_detail': configuration_detail, + #'configuration_detail': configuration_detail, 'domain': "django-hosting.ch", 'google_analytics': "UA-62285904-6", 'email': "info@django-hosting.ch", - 'vm_types': VirtualMachineType.get_serialized_vm_types(), + #'vm_types': VirtualMachineType.get_serialized_vm_types(), } @@ -66,15 +66,15 @@ class RailsHostingViewTest(TestCase, ProcessVMSelectionTestMixin): self.view = RailsHostingView() self.expected_template = 'hosting/rails.html' HOSTING = 'rails' - configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) + #configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) self.expected_context = { 'hosting': HOSTING, 'hosting_long': "Ruby On Rails", - 'configuration_detail': configuration_detail, + #'configuration_detail': configuration_detail, 'domain': "rails-hosting.ch", 'google_analytics': "UA-62285904-5", 'email': "info@rails-hosting.ch", - 'vm_types': VirtualMachineType.get_serialized_vm_types(), + #'vm_types': VirtualMachineType.get_serialized_vm_types(), } @@ -85,15 +85,15 @@ class NodeJSHostingViewTest(TestCase, ProcessVMSelectionTestMixin): self.view = NodeJSHostingView() self.expected_template = 'hosting/nodejs.html' HOSTING = 'nodejs' - configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) + #configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) self.expected_context = { 'hosting': HOSTING, 'hosting_long': "NodeJS", - 'configuration_detail': configuration_detail, + #'configuration_detail': configuration_detail, 'domain': "node-hosting.ch", 'google_analytics': "UA-62285904-7", 'email': "info@node-hosting.ch", - 'vm_types': VirtualMachineType.get_serialized_vm_types(), + #'vm_types': VirtualMachineType.get_serialized_vm_types(), } @@ -104,11 +104,11 @@ class HostingPricingViewTest(TestCase): self.view = HostingPricingView() self.expected_template = 'hosting/hosting_pricing.html' - configuration_options = dict(VirtualMachinePlan.VM_CONFIGURATION) + #configuration_options = dict(VirtualMachinePlan.VM_CONFIGURATION) self.expected_context = { - 'configuration_options': configuration_options, + #'configuration_options': configuration_options, 'email': "info@django-hosting.ch", - 'vm_types': VirtualMachineType.get_serialized_vm_types(), + #'vm_types': VirtualMachineType.get_serialized_vm_types(), } def url_resolve_to_view_correctly(self): @@ -135,10 +135,10 @@ class PaymentVMViewTest(BaseTestCase): self.view = PaymentVMView # VM - self.vm = mommy.make(VirtualMachineType, base_price=10000, - memory_price=100, - core_price=1000, - disk_size_price=1) + # self.vm = mommy.make(VirtualMachineType, base_price=10000, + # memory_price=100, + # core_price=1000, + # disk_size_price=1) # post data self.billing_address = { @@ -153,16 +153,16 @@ class PaymentVMViewTest(BaseTestCase): self.url = reverse('hosting:payment') # Session data - self.session_data = { - 'vm_specs': { - 'hosting_company': self.vm.hosting_company, - 'cores': 1, - 'memory': 10, - 'disk_size': 10000, - 'price': 22000, - 'configuration': dict(VirtualMachinePlan.VM_CONFIGURATION).get('django') - } - } + # self.session_data = { + # 'vm_specs': { + # 'hosting_company': self.vm.hosting_company, + # 'cores': 1, + # 'memory': 10, + # 'disk_size': 10000, + # 'price': 22000, + # 'configuration': dict(VirtualMachinePlan.VM_CONFIGURATION).get('django') + # } + # } session = self.customer_client.session session.update(self.session_data) @@ -290,8 +290,8 @@ class GenerateVMSSHKeysViewTest(BaseTestCase): def setUp(self): super(GenerateVMSSHKeysViewTest, self).setUp() - self.view = GenerateVMSSHKeysView - self.vm = mommy.make(VirtualMachinePlan) + # self.view = GenerateVMSSHKeysView + # self.vm = mommy.make(VirtualMachinePlan) self.expected_template = 'hosting/virtual_machine_key.html' self.url = reverse('hosting:virtual_machine_key', kwargs={'pk': self.vm.id}) @@ -312,8 +312,8 @@ class GenerateVMSSHKeysViewTest(BaseTestCase): # Logged user should get the page response = self.customer_client.get(self.url, follow=True) self.assertEqual(response.status_code, 200) - updated_vm = VirtualMachinePlan.objects.get(id=self.vm.id) - self.assertEqual(response.context['public_key'].decode("utf-8"), updated_vm.public_key) + #updated_vm = VirtualMachinePlan.objects.get(id=self.vm.id) + #self.assertEqual(response.context['public_key'].decode("utf-8"), updated_vm.public_key) self.assertTrue(response.context['private_key'] is not None) self.assertEqual(len(response.context['public_key']), 380) self.assertTrue(len(response.context['private_key']) is 1678 or 1674) @@ -326,7 +326,7 @@ class VirtualMachineViewTest(BaseTestCase): super(VirtualMachineViewTest, self).setUp() self.stripe_customer = mommy.make(StripeCustomer, user=self.customer) - self.vm = mommy.make(VirtualMachinePlan) + #self.vm = mommy.make(VirtualMachinePlan) self.vm.assign_permissions(self.customer) self.order = mommy.make(HostingOrder, customer=self.stripe_customer, vm_plan=self.vm) self.url = reverse('hosting:virtual_machines', kwargs={'pk': self.vm.id}) @@ -361,8 +361,8 @@ class VirtualMachinesPlanListViewTest(BaseTestCase): self.stripe_customer = mommy.make(StripeCustomer, user=self.customer) mommy.make(HostingOrder, customer=self.stripe_customer, approved=True, _quantity=20) - _vms = VirtualMachinePlan.objects.all() - self.vms = sorted(_vms, key=lambda vm: vm.id, reverse=True) + #_vms = VirtualMachinePlan.objects.all() + #self.vms = sorted(_vms, key=lambda vm: vm.id, reverse=True) self.url = reverse('hosting:virtual_machines') self.view = VirtualMachinesPlanListView() self.expected_template = 'hosting/virtual_machines.html' From e2188cc166666d4cab69ec7a1db1dce6008a6a07 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Mon, 2 Oct 2017 17:19:51 +0200 Subject: [PATCH 0004/1840] Added some skipIf conditions --- utils/tests.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/utils/tests.py b/utils/tests.py index d5c2d726..1da5ba28 100644 --- a/utils/tests.py +++ b/utils/tests.py @@ -139,6 +139,10 @@ class TestStripeCustomerDescription(TestCase): self.assertEqual(customer_data.description, self.customer_name) +@skipIf(settings.STRIPE_API_PRIVATE_KEY_TEST == "" or + settings.TEST_MANAGE_SSH_KEY_HOST == "", + """Skipping test_save_ssh_key_add because either host + or public key were not specified or were empty""") class StripePlanTestCase(TestStripeCustomerDescription): """ A class to test Stripe plans @@ -161,6 +165,10 @@ class StripePlanTestCase(TestStripeCustomerDescription): self.assertIsNone(stripe_plan.get('error')) self.assertIsInstance(stripe_plan.get('response_object'), StripePlan) + @skipIf(settings.TEST_MANAGE_SSH_KEY_PUBKEY == "" or + settings.TEST_MANAGE_SSH_KEY_HOST == "", + """Skipping test_save_ssh_key_add because either host + or public key were not specified or were empty""") @patch('utils.stripe_utils.logger') def test_create_duplicate_plans_error_handling(self, mock_logger): """ @@ -254,10 +262,8 @@ class SaveSSHKeyTestCase(TestCase): self.public_key = settings.TEST_MANAGE_SSH_KEY_PUBKEY self.hosts = settings.TEST_MANAGE_SSH_KEY_HOST - @skipIf(settings.TEST_MANAGE_SSH_KEY_PUBKEY is None or - settings.TEST_MANAGE_SSH_KEY_PUBKEY == "" or - settings.TEST_MANAGE_SSH_KEY_HOST is None or - settings.TEST_MANAGE_SSH_KEY_HOST is "", + @skipIf(settings.TEST_MANAGE_SSH_KEY_PUBKEY == "" or + settings.TEST_MANAGE_SSH_KEY_HOST == "", """Skipping test_save_ssh_key_add because either host or public key were not specified or were empty""") def test_save_ssh_key_add(self): From f044b83b8f1be5220270dbb12980459c5d2a7b69 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Tue, 3 Oct 2017 13:06:26 +0200 Subject: [PATCH 0005/1840] Add Stripe unsubscribe_customer method --- utils/stripe_utils.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/utils/stripe_utils.py b/utils/stripe_utils.py index 8fcf0ab1..58840be0 100644 --- a/utils/stripe_utils.py +++ b/utils/stripe_utils.py @@ -232,6 +232,17 @@ class StripeUtils(object): ) return subscription_result + @handleStripeError + def unsubscribe_customer(self, subscription_id): + """ + Cancels a given subscription + + :param subscription_id: The Stripe subscription id string + :return: + """ + sub = stripe.Subscription.retrieve(subscription_id) + return sub.delete() + @handleStripeError def make_payment(self, customer, amount, token): charge = self.stripe.Charge.create( From 777aab711503d268767ba096043073df79129066 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Tue, 3 Oct 2017 13:07:41 +0200 Subject: [PATCH 0006/1840] Add cancel subscription code on VM cancel --- hosting/views.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/hosting/views.py b/hosting/views.py index 6d4f15ca..d534ccbe 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -11,6 +11,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.tokens import default_token_generator from django.core.exceptions import ValidationError from django.core.files.base import ContentFile +from django.core.mail import EmailMessage from django.core.urlresolvers import reverse_lazy, reverse from django.http import Http404, HttpResponseRedirect, HttpResponse @@ -1071,6 +1072,52 @@ class VirtualMachineView(LoginRequiredMixin, View): vm_id=opennebula_vm_id).first() vm_detail_obj.terminated_at = datetime.utcnow() vm_detail_obj.save() + # Cancel subscription + stripe_utils = StripeUtils() + error_msg_subject = ( + 'Error canceling subscription for ' + '{user} and vm id {vm_id}'.format( + user=owner.email, + vm_id=opennebula_vm_id + ) + ) + try: + hosting_order = HostingOrder.objects.get( + vm_id=opennebula_vm_id + ) + result = stripe_utils.unsubscribe_customer( + subscription_id=hosting_order.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(error_msg) + email_data = { + 'subject': error_msg_subject, + 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, + 'to': settings.DCL_ERROR_EMAILS_TO_LIST, + 'body': error_msg, + } + email = EmailMessage(**email_data) + email.send() + except HostingOrder.DoesNotExist: + error_msg = ( + "HostingOrder corresponding to vm_id={vm_id} does" + "not exist. Hence, can not find subscription to " + "cancel ".format(vm_id=opennebula_vm_id) + ) + logger.error(error_msg) + email_data = { + 'subject': error_msg_subject, + 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, + 'to': settings.DCL_ERROR_EMAILS_TO_LIST, + 'body': error_msg, + } + email = EmailMessage(**email_data) + email.send() break except BaseException: break From 6536991209fc25af113a91dfa93988ede3a00952 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 6 Oct 2017 01:17:35 +0530 Subject: [PATCH 0007/1840] list all cards, card_input template --- .../datacenterlight/landing_payment.html | 58 +-------------- hosting/templates/hosting/payment.html | 57 +------------- hosting/templates/hosting/settings.html | 74 +++---------------- hosting/views.py | 19 +++-- 4 files changed, 20 insertions(+), 188 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index fa638d77..1a476797 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -121,63 +121,7 @@ {% else %} -
- -
-
-
- -
-
-
-
- -
-
-
- -
-
-
-
- - -
-
-
-
- {% if not messages and not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After placing your order, you will be taken to the Submit Payment Page." %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' in message.tags or 'make_charge_error' in message.tags %} -
    -
  • {{ message|safe }}

  • -
- {% elif not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After placing your order, you will be taken to the Submit Payment Page." %} -

- {% endif %} - {% endfor %} - - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
- -
- -
-

-
-
+ {% include "hosting/includes/_card_input.html" %} {% endif %} diff --git a/hosting/templates/hosting/payment.html b/hosting/templates/hosting/payment.html index e9d6476f..a10cfbca 100644 --- a/hosting/templates/hosting/payment.html +++ b/hosting/templates/hosting/payment.html @@ -105,62 +105,7 @@ {% else %} -
- -
-
-
- -
-
-
-
- -
-
-
- -
-
-
-
- - -
-
-
-
- {% if not messages and not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' or 'make_charge_error' in message.tags %} -
    -
  • -

    {{ message|safe }}

    -
  • -
- {% endif %} - {% endfor %} - - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
- -
- - -
-

-
-
+ {% include "hosting/includes/_card_input.html" %} {% endif %} diff --git a/hosting/templates/hosting/settings.html b/hosting/templates/hosting/settings.html index 0bafe8e5..5e898b04 100644 --- a/hosting/templates/hosting/settings.html +++ b/hosting/templates/hosting/settings.html @@ -30,12 +30,13 @@

{%trans "Credit Card"%}


- {% if credit_card_data.last4 %} + {% for card in cards_list %}
{% trans "Credit Card" %}
-
{% trans "Last" %} 4: *****{{credit_card_data.last4}}
-
{% trans "Type" %}: {{credit_card_data.cc_brand}}
+
{% trans "Last" %} 4: *****{{card.last4}}
+
{% trans "Type" %}: {{card.cc_brand}}
{% comment %} + {% endcomment %}
@@ -46,75 +47,18 @@
- {% endcomment %}
+ {% endfor %} + {% if credit_card_data.last4 %} {% else %}

{% trans "No Credit Cards Added" %}

{% blocktrans %}We are using Stripe for payment and do not store your information in our database.{% endblocktrans %}

- {% comment %}

{% trans "Add a new Card." %}

-

- {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} -

-
- -
-
- -
-
-
-
- -
-
-
- -
-
-
-
- - -
-
- -
- {% if not messages and not form.non_field_errors %} -

- {% blocktrans %}You are not making any payment here.{% endblocktrans %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' or 'make_charge_error' in message.tags %} -
  • -

    {{ message|safe }}

    -
- {% endif %} - {% endfor %} - - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
-
- -
-
-
- -
-

-
-
+ {% include "hosting/includes/_card_input.html" %} + {% comment %} {% endcomment %} {% endif %}
@@ -123,7 +67,6 @@ - {% comment %} {% if stripe_key %} {% get_current_language as LANGUAGE_CODE %} @@ -138,6 +81,7 @@ {%endif%} + {% comment %} {% if credit_card_data.last4 and credit_card_data.cc_brand %} {%endif%} - -{% if credit_card_data.last4 and credit_card_data.cc_brand %} - -{%endif%} - {%endblock%} From 248283b369c55b3989c421a93921453d33248f42 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 28 Oct 2017 23:44:06 +0200 Subject: [PATCH 0077/1840] Show user's credit cards dynamically in landing payment page --- .../datacenterlight/landing_payment.html | 35 ++++++++++++++----- datacenterlight/views.py | 11 +++++- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index 58246b6a..69c80d35 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -84,11 +84,35 @@
+ {% with card_list_len=cards_list|length %}

{%trans "Credit Card"%}


+ {% if card_list_len > 0 %} + {% blocktrans %}Please select one of the previous cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% else %} {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% endif %}

+
+ {% for card in cards_list %} +
+
+
{% trans "Credit Card" %}
+
{% trans "Last" %} 4: ***** {{card.last4}}
+
{% trans "Type" %}: {{card.brand}}
+
+ +
+ {% endfor %} + {% if card_list_len > 0 %} +
Use another card
+ {% endif %} + {% include "hosting/includes/_card_input.html" %} +
+ {% comment %}
{% if credit_card_data.last4 %}
@@ -125,6 +149,8 @@ {% include "hosting/includes/_card_input.html" %} {% endif %}
+ {% endcomment %} + {% endwith %}
@@ -144,13 +170,4 @@ })(); {%endif%} - -{% if credit_card_data.last4 and credit_card_data.cc_brand %} - -{%endif%} - {%endblock%} diff --git a/datacenterlight/views.py b/datacenterlight/views.py index bd1a7f51..861817e1 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -14,7 +14,7 @@ from django.views.decorators.cache import cache_control from django.views.generic import FormView, CreateView, TemplateView, DetailView from datacenterlight.tasks import create_vm_task -from hosting.models import HostingOrder +from hosting.models import HostingOrder, UserCardDetail from hosting.forms import HostingUserLoginForm from membership.models import CustomUser, StripeCustomer from opennebula_api.serializers import VMTemplateSerializer @@ -347,6 +347,14 @@ class PaymentOrderView(FormView): def get_context_data(self, **kwargs): context = super(PaymentOrderView, self).get_context_data(**kwargs) + user = self.request.user + if hasattr(user, 'stripecustomer'): + stripe_customer = user.stripecustomer + else: + stripe_customer = None + cards_list = UserCardDetail.get_all_cards_list( + stripe_customer=stripe_customer + ) if 'billing_address_data' in self.request.session: billing_address_data = self.request.session['billing_address_data'] else: @@ -380,6 +388,7 @@ class PaymentOrderView(FormView): ) context.update({ + 'cards_list': cards_list, 'stripe_key': settings.STRIPE_API_PUBLIC_KEY, 'site_url': reverse('datacenterlight:index'), 'login_form': HostingUserLoginForm(prefix='login_form'), From 2ffaee2d5b9722a50ed33e5d6a338df77af5232c Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 13:14:29 +0100 Subject: [PATCH 0078/1840] Add clear_items_from_list utility function --- utils/hosting_utils.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index 3c193ad7..9541588d 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -60,3 +60,23 @@ def get_vm_price(cpu, memory, disk_size): :return: The price of the VM """ return (cpu * 5) + (memory * 2) + (disk_size * 0.6) + + +class HostingUtils: + @staticmethod + def clear_items_from_list(from_list, items_list): + """ + A utility function to clear items from a given list. + Useful when deleting items in bulk from session. + e.g.: + HostingUtils.clear_items_from_list( + request.session, + ['token', 'billing_address_data', 'card_id',] + ) + :param from_list: + :param items_list: + :return: + """ + for var in items_list: + if var in from_list: + del from_list[var] From 82ad9ac337a9f9ab83256debecc05160b7379274 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 13:17:26 +0100 Subject: [PATCH 0079/1840] Add selected card handling in landing flow "Order confirmation" page --- datacenterlight/views.py | 172 +++++++++++++++++++++++++++------------ 1 file changed, 122 insertions(+), 50 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 861817e1..baec4ee6 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -21,7 +21,7 @@ from opennebula_api.serializers import VMTemplateSerializer from utils.forms import ( BillingAddressForm, BillingAddressFormSignup ) -from utils.hosting_utils import get_vm_price +from utils.hosting_utils import get_vm_price, HostingUtils from utils.mailer import BaseEmail from utils.stripe_utils import StripeUtils from utils.tasks import send_plain_email_task @@ -401,6 +401,13 @@ class PaymentOrderView(FormView): # user is no longer added to session on the index page if 'specs' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:index')) + HostingUtils.clear_items_from_list( + request.session, + ['token', 'billing_address_data', 'card_id', 'customer', + 'user'] + ) + if 'token' in request.session: + del request.session['token'] return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): @@ -436,8 +443,40 @@ class PaymentOrderView(FormView): 'name': request.user.name } customer = StripeCustomer.get_or_create( - email=this_user.get('email'), - token=token) + email=this_user.get('email'), token=token + ) + if token is '': + # card selected case + card_id = address_form.cleaned_data.get('card') + try: + user_card_detail = UserCardDetail.objects.get( + id=card_id) + if not request.user.has_perm( + 'view_usercarddetail', user_card_detail + ): + raise UserCardDetail.DoesNotExist( + _( + "{user} does not have permission to access the " + "card").format(user=request.user.email) + ) + except UserCardDetail.DoesNotExist as e: + ex = str(e) + logger.error( + "Card Id: {card_id}, Exception: {ex}".format( + card_id=card_id, ex=ex + ) + ) + msg = _("An error occurred. Details: {}".format(ex)) + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='make_charge_error' + ) + return HttpResponseRedirect( + reverse('hosting:payment') + '#payment_error' + ) + request.session['card_id'] = user_card_detail.id + else: + request.session['token'] = token else: user_email = address_form.cleaned_data.get('email') user_name = address_form.cleaned_data.get('name') @@ -472,7 +511,7 @@ class PaymentOrderView(FormView): email=user_email, token=token, customer_name=user_name) - + request.session['token'] = token request.session['billing_address_data'] = address_form.cleaned_data request.session['user'] = this_user # Get or create stripe customer @@ -485,7 +524,6 @@ class PaymentOrderView(FormView): billing_address_form=address_form ) ) - request.session['token'] = token if type(customer) is StripeCustomer: request.session['customer'] = customer.stripe_id else: @@ -508,27 +546,33 @@ class OrderConfirmationView(DetailView): def get(self, request, *args, **kwargs): if 'specs' not in request.session or 'user' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:index')) - if 'token' not in request.session: + if 'token' not in request.session and 'card_id' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:payment')) - stripe_api_cus_id = request.session.get('customer') - stripe_utils = StripeUtils() - card_details = stripe_utils.get_card_details(stripe_api_cus_id, - 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 = { 'site_url': reverse('datacenterlight:index'), - 'cc_last4': card_details.get('response_object').get('last4'), - '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') } + if 'token' in request.session: + stripe_utils = StripeUtils() + card_details = stripe_utils.get_cards_details_from_token( + request.session.get('token') + ) + card_detail_resp = card_details.get('response_object') + if not card_detail_resp: + 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['cc_last4'] = card_detail_resp.get('last4') + context['cc_brand'] = card_detail_resp.get('brand') + else: + card_id = self.request.session.get('card_id') + card_detail = UserCardDetail.objects.get(id=card_id) + context['cc_last4'] = card_detail.last4 + context['cc_brand'] = card_detail.brand return render(request, self.template_name, context) def post(self, request, *args, **kwargs): @@ -538,43 +582,62 @@ class OrderConfirmationView(DetailView): stripe_api_cus_id = request.session.get('customer') vm_template_id = template.get('id', 1) stripe_utils = StripeUtils() - card_details = stripe_utils.get_card_details(stripe_api_cus_id, - 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') - 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.')) + if 'token' in self.request.session: + card_details = stripe_utils.get_cards_details_from_token( + request.session['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') + ucd = UserCardDetail.contains( + request.user.stripecustomer, card_details_dict + ) + if not ucd: + stripe_utils.associate_customer_card( + stripe_api_cus_id, request.session['token'], + set_as_default=True + ) + else: + card_id = request.session.get('card_id') + user_card_detail = UserCardDetail.objects.get(id=card_id) + card_details_dict = { + 'last4': user_card_detail.last4, + 'brand': user_card_detail.brand } - return HttpResponse(json.dumps(response), - content_type="application/json") - card_details_dict = card_details.get('response_object') + if not user_card_detail.preferred: + UserCardDetail.set_default_card( + stripe_api_cus_id=stripe_api_cus_id, + stripe_source_id=user_card_detail.card_id + ) 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') + 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) + 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( @@ -644,6 +707,15 @@ class OrderConfirmationView(DetailView): billing_address_data.update({ 'user': custom_user.id }) + if 'token' in request.session: + ucd = UserCardDetail.get_or_create_user_card_detail( + stripe_customer=self.request.user.stripecustomer, + card_details=card_details_dict + ) + UserCardDetail.save_default_card_local( + self.request.user.stripecustomer.stripe_id, + ucd.card_id + ) user = { 'name': custom_user.name, 'email': custom_user.email, From 23e7edf7c28af39b0d8d93517a47538b5cd1911c Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 14:40:15 +0100 Subject: [PATCH 0080/1840] Return True if associate_customer_card runs ok --- utils/stripe_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/stripe_utils.py b/utils/stripe_utils.py index 2742045a..cb9ae6fb 100644 --- a/utils/stripe_utils.py +++ b/utils/stripe_utils.py @@ -86,6 +86,7 @@ class StripeUtils(object): if set_as_default: customer.default_source = card.id customer.save() + return True @handleStripeError def dissociate_customer_card(self, stripe_customer_id, card_id): From bea3477d848a8f87526e44ece06df5c0352ee801 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 14:45:14 +0100 Subject: [PATCH 0081/1840] Handle errors related to payment by redirecting to payment page --- datacenterlight/views.py | 39 ++++++++++++++++++++++++++--- hosting/views.py | 54 +++++++++++++++++++++++++++++++++++----- 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index baec4ee6..d9c0fbc1 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -603,21 +603,46 @@ class OrderConfirmationView(DetailView): } return HttpResponse(json.dumps(response), content_type="application/json") - card_details_dict = card_details.get('response_object') + card_details_response = card_details['response_object'] + card_details_dict = { + 'last4': card_details_response['last4'], + 'brand': card_details_response['brand'], + 'card_id': card_details_response['card_id'] + } ucd = UserCardDetail.contains( request.user.stripecustomer, card_details_dict ) if not ucd: - stripe_utils.associate_customer_card( + acc_result = stripe_utils.associate_customer_card( stripe_api_cus_id, request.session['token'], set_as_default=True ) + if acc_result['response_object'] is None: + 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.')) + } + logger.error( + "Card association failed. Error {error}".format( + error=acc_result['error'] + ) + ) + return HttpResponse(json.dumps(response), + content_type="application/json") else: card_id = request.session.get('card_id') user_card_detail = UserCardDetail.objects.get(id=card_id) card_details_dict = { 'last4': user_card_detail.last4, - 'brand': user_card_detail.brand + 'brand': user_card_detail.brand, + 'card_id': user_card_detail.card_id } if not user_card_detail.preferred: UserCardDetail.set_default_card( @@ -646,6 +671,14 @@ class OrderConfirmationView(DetailView): # Check if the subscription was approved and is active if (stripe_subscription_obj is None or stripe_subscription_obj.status != 'active'): + if request.user.is_authenticated(): + sac_id = request.user.stripecustomer.stripe_id + else: + sac_id = stripe_api_cus_id + stripe_utils.dissociate_customer_card( + sac_id, + card_details_dict['card_id'] + ) msg = subscription_result.get('error') messages.add_message(self.request, messages.ERROR, msg, extra_tags='failed_payment') diff --git a/hosting/views.py b/hosting/views.py index f61a4b19..6d5c9a78 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -632,6 +632,18 @@ class SettingsView(LoginRequiredMixin, FormView): msg = _('You seem to have already added this card') messages.add_message(request, messages.ERROR, msg) else: + acc_result = stripe_utils.associate_customer_card( + request.user.stripecustomer.stripe_id, token + ) + if acc_result['response_object'] is None: + msg = _( + 'An error occurred while associating the card.' + ' Details: {details}'.format( + details=acc_result['error'] + ) + ) + messages.add_message(request, messages.ERROR, msg) + return self.render_to_response(self.get_context_data()) preferred = False if stripe_customer.usercarddetail_set.count() == 0: preferred = True @@ -645,9 +657,6 @@ class SettingsView(LoginRequiredMixin, FormView): card_id=card['card_id'], preferred=preferred ) - stripe_utils.associate_customer_card( - request.user.stripecustomer.stripe_id, token - ) msg = _( "Successfully associated the card with your account" ) @@ -866,22 +875,48 @@ class OrdersHostingDetailView(LoginRequiredMixin, card_details_response = card_details['response_object'] card_details_dict = { 'last4': card_details_response['last4'], - 'brand': card_details_response['brand'] + 'brand': card_details_response['brand'], + 'card_id': card_details_response['card_id'] } ucd = UserCardDetail.contains( request.user.stripecustomer, card_details_response ) if not ucd: - stripe_utils.associate_customer_card( + acc_result = stripe_utils.associate_customer_card( stripe_api_cus_id, request.session['token'], set_as_default=True ) + if acc_result['response_object'] is None: + msg = _( + 'An error occurred while associating the card.' + ' Details: {details}'.format( + details=acc_result['error'] + ) + ) + messages.add_message(self.request, messages.ERROR, msg, + extra_tags='failed_payment') + response = { + 'status': False, + 'redirect': "{url}#{section}".format( + url=reverse('hosting: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" + ) else: card_id = request.session.get('card_id') user_card_detail = UserCardDetail.objects.get(id=card_id) card_details_dict = { 'last4': user_card_detail.last4, - 'brand': user_card_detail.brand + 'brand': user_card_detail.brand, + 'card_id': user_card_detail.card_id } if not user_card_detail.preferred: UserCardDetail.set_default_card( @@ -911,6 +946,13 @@ class OrdersHostingDetailView(LoginRequiredMixin, # Check if the subscription was approved and is active if (stripe_subscription_obj is None or stripe_subscription_obj.status != 'active'): + # At this point, we have created a Stripe API card, but and + # associated it with the customer; but the transaction failed + # due to some reason. So, we dissociate this card. + stripe_utils.dissociate_customer_card( + request.user.stripecustomer.stripe_id, + card_details_dict['card_id'] + ) msg = subscription_result.get('error') messages.add_message(self.request, messages.ERROR, msg, extra_tags='failed_payment') From abe8c9efa52b13f4d87eb07392b63c0d3494a4ad Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 15:05:32 +0100 Subject: [PATCH 0082/1840] Add error details to messages datacenterlight landing flow --- datacenterlight/views.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index d9c0fbc1..f58b8276 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -610,7 +610,7 @@ class OrderConfirmationView(DetailView): 'card_id': card_details_response['card_id'] } ucd = UserCardDetail.contains( - request.user.stripecustomer, card_details_dict + request.user.stripecustomer, card_details_response ) if not ucd: acc_result = stripe_utils.associate_customer_card( @@ -618,6 +618,11 @@ class OrderConfirmationView(DetailView): set_as_default=True ) if acc_result['response_object'] is None: + msg = acc_result.get('error') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) response = { 'status': False, 'redirect': "{url}#{section}".format( From 63eb7fc0e2278721932adebe114e3cfe7236313e Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:31:11 +0100 Subject: [PATCH 0083/1840] Rename contains to get_user_card_details --- hosting/models.py | 9 +++++---- hosting/views.py | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hosting/models.py b/hosting/models.py index 9486eae7..7a181fe1 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -312,21 +312,22 @@ class UserCardDetail(AssignPermissionsMixin, models.Model): user_card_detail.save() @staticmethod - def contains(stripe_customer, card_details): + def get_user_card_details(stripe_customer, card_details): """ A utility function to check whether a StripeCustomer is already associated with the card having given details + :param stripe_customer: :param card_details: - :return: + :return: The UserCardDetails object if it exists, False otherwise """ try: - UserCardDetail.objects.get( + ucd = UserCardDetail.objects.get( stripe_customer=stripe_customer, fingerprint=card_details['fingerprint'], exp_month=card_details['exp_month'], exp_year=card_details['exp_year'] ) - return True + return ucd except UserCardDetail.DoesNotExist: return False diff --git a/hosting/views.py b/hosting/views.py index 6d5c9a78..5a9c2e2e 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -628,7 +628,7 @@ class SettingsView(LoginRequiredMixin, FormView): email=request.user.email, token=token ) card = card_details['response_object'] - if UserCardDetail.contains(stripe_customer, card): + if UserCardDetail.get_user_card_details(stripe_customer, card): msg = _('You seem to have already added this card') messages.add_message(request, messages.ERROR, msg) else: @@ -878,7 +878,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, 'brand': card_details_response['brand'], 'card_id': card_details_response['card_id'] } - ucd = UserCardDetail.contains( + ucd = UserCardDetail.get_user_card_details( request.user.stripecustomer, card_details_response ) if not ucd: From af1690b84621322c86fa27a07031d72388da614f Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:36:12 +0100 Subject: [PATCH 0084/1840] Fix: obtaining stripe_customer in landing flow --- datacenterlight/views.py | 82 ++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index f58b8276..1a817310 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -403,8 +403,7 @@ class PaymentOrderView(FormView): return HttpResponseRedirect(reverse('datacenterlight:index')) HostingUtils.clear_items_from_list( request.session, - ['token', 'billing_address_data', 'card_id', 'customer', - 'user'] + ['token', 'card_id', 'customer', 'user'] ) if 'token' in request.session: del request.session['token'] @@ -609,38 +608,49 @@ class OrderConfirmationView(DetailView): 'brand': card_details_response['brand'], 'card_id': card_details_response['card_id'] } - ucd = UserCardDetail.contains( - request.user.stripecustomer, card_details_response - ) - if not ucd: - acc_result = stripe_utils.associate_customer_card( - stripe_api_cus_id, request.session['token'], - set_as_default=True - ) - if acc_result['response_object'] is None: - msg = acc_result.get('error') - messages.add_message( - self.request, messages.ERROR, msg, - extra_tags='failed_payment' + s_cus = None + try: + s_cus = StripeCustomer.objects.get(stripe_id=stripe_api_cus_id) + except StripeCustomer.DoesNotExist: + pass + if s_cus: + ucd = UserCardDetail.get_user_card_details(s_cus, card_details_response) + if not ucd: + acc_result = stripe_utils.associate_customer_card( + stripe_api_cus_id, request.session['token'], + set_as_default=True ) - 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.')) - } - logger.error( - "Card association failed. Error {error}".format( - error=acc_result['error'] + if acc_result['response_object'] is None: + msg = acc_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.') + ) + } + logger.error( + "Card association failed. Error {error}".format( + error=acc_result['error'] + ) + ) + return HttpResponse(json.dumps(response), + content_type="application/json") + else: + if not ucd.preferred: + UserCardDetail.set_default_card( + stripe_api_cus_id=stripe_api_cus_id, + stripe_source_id=ucd.card_id ) - ) - return HttpResponse(json.dumps(response), - content_type="application/json") else: card_id = request.session.get('card_id') user_card_detail = UserCardDetail.objects.get(id=card_id) @@ -745,13 +755,13 @@ class OrderConfirmationView(DetailView): billing_address_data.update({ 'user': custom_user.id }) - if 'token' in request.session: + if 'token' in request.session and s_cus is not None: ucd = UserCardDetail.get_or_create_user_card_detail( - stripe_customer=self.request.user.stripecustomer, - card_details=card_details_dict + stripe_customer=s_cus, + card_details=card_details_response ) UserCardDetail.save_default_card_local( - self.request.user.stripecustomer.stripe_id, + s_cus.stripe_id, ucd.card_id ) user = { From 618d0004f2456b236d4d427e98631234ea355922 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:41:54 +0100 Subject: [PATCH 0085/1840] Rearrange code --- datacenterlight/views.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 1a817310..36ca81d6 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -451,12 +451,11 @@ class PaymentOrderView(FormView): user_card_detail = UserCardDetail.objects.get( id=card_id) if not request.user.has_perm( - 'view_usercarddetail', user_card_detail + 'view_usercarddetail', user_card_detail ): raise UserCardDetail.DoesNotExist( - _( - "{user} does not have permission to access the " - "card").format(user=request.user.email) + _("{user} does not have permission to access" + " the card").format(user=request.user.email) ) except UserCardDetail.DoesNotExist as e: ex = str(e) @@ -496,9 +495,9 @@ class PaymentOrderView(FormView): ) ) customer = StripeCustomer.create_stripe_api_customer( - email=user_email, - token=token, - customer_name=user_name) + email=user_email, token=token, + customer_name=user_name + ) except CustomUser.DoesNotExist: logger.debug( ("StripeCustomer does not exist for {email}." @@ -597,8 +596,8 @@ class OrderConfirmationView(DetailView): '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.')) + ' On close of this popup, you will be redirected ' + 'back to the payment page.')) } return HttpResponse(json.dumps(response), content_type="application/json") From 3d8f81339b41218e58a2d8f2659d37781188838d Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:49:15 +0100 Subject: [PATCH 0086/1840] Refactor, reorganize some code --- datacenterlight/views.py | 42 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 36ca81d6..51cd18fd 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -560,10 +560,13 @@ class OrderConfirmationView(DetailView): card_detail_resp = card_details.get('response_object') if not card_detail_resp: msg = card_details.get('error') - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='failed_payment') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) return HttpResponseRedirect( - reverse('datacenterlight:payment') + '#payment_error') + reverse('datacenterlight:payment') + '#payment_error' + ) context['cc_last4'] = card_detail_resp.get('last4') context['cc_brand'] = card_detail_resp.get('brand') else: @@ -586,8 +589,10 @@ class OrderConfirmationView(DetailView): ) if not card_details.get('response_object'): msg = card_details.get('error') - messages.add_message(self.request, messages.ERROR, msg, - extra_tags='failed_payment') + messages.add_message( + self.request, messages.ERROR, msg, + extra_tags='failed_payment' + ) response = { 'status': False, 'redirect': "{url}#{section}".format( @@ -599,8 +604,9 @@ class OrderConfirmationView(DetailView): ' On close of this popup, you will be redirected ' 'back to the payment page.')) } - return HttpResponse(json.dumps(response), - content_type="application/json") + return HttpResponse( + json.dumps(response), content_type="application/json" + ) card_details_response = card_details['response_object'] card_details_dict = { 'last4': card_details_response['last4'], @@ -709,7 +715,6 @@ class OrderConfirmationView(DetailView): } return HttpResponse(json.dumps(response), content_type="application/json") - # Create user if the user is not logged in and if he is not already # registered if not request.user.is_authenticated(): @@ -747,7 +752,6 @@ class OrderConfirmationView(DetailView): # object already exists stripe_customer_id = request.user.stripecustomer.id custom_user = request.user - # Save billing address billing_address_data = request.session.get('billing_address_data') logger.debug('billing_address_data is {}'.format(billing_address_data)) @@ -771,16 +775,16 @@ class OrderConfirmationView(DetailView): 'request_host': request.get_host(), 'language': get_language(), } - - create_vm_task.delay(vm_template_id, user, specs, template, - stripe_customer_id, billing_address_data, - stripe_subscription_obj.id, card_details_dict) - for session_var in ['specs', 'template', 'billing_address', - 'billing_address_data', - 'token', 'customer']: - if session_var in request.session: - del request.session[session_var] - + create_vm_task.delay( + vm_template_id, user, specs, template, stripe_customer_id, + billing_address_data, stripe_subscription_obj.id, + card_details_dict + ) + HostingUtils.clear_items_from_list( + request.session, + ['specs', 'template', 'billing_address', 'billing_address_data', + 'token', 'customer'] + ) response = { 'status': True, 'redirect': reverse( From edac806c118f642b737c7999c02d99643a67b639 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 21:56:29 +0100 Subject: [PATCH 0087/1840] Some more refactoring --- datacenterlight/views.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 51cd18fd..50148418 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -785,17 +785,18 @@ class OrderConfirmationView(DetailView): ['specs', 'template', 'billing_address', 'billing_address_data', 'token', 'customer'] ) + if request.user.is_authenticated(): + redirect_url = reverse('hosting:virtual_machines') + else: + redirect_url = reverse('datacenterlight:index') response = { 'status': True, - 'redirect': reverse( - 'hosting:virtual_machines') if request.user.is_authenticated() else reverse( - 'datacenterlight:index'), + 'redirect': redirect_url, '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.')) } - return HttpResponse(json.dumps(response), content_type="application/json") From 62f30bf03c37301061b357ab14daa90ea363b648 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 22:03:19 +0100 Subject: [PATCH 0088/1840] Remove some commented and unnecessary code --- .../datacenterlight/landing_payment.html | 38 ------------------- datacenterlight/views.py | 15 -------- hosting/templates/hosting/settings.html | 10 ----- 3 files changed, 63 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index 69c80d35..5ac601ce 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -112,44 +112,6 @@ {% endif %} {% include "hosting/includes/_card_input.html" %} - {% comment %} -
- {% if credit_card_data.last4 %} - -
Credit Card
-
Last 4: *****{{credit_card_data.last4}}
-
Type: {{credit_card_data.cc_brand}}
- - - {% if not messages and not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %} -

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' or 'make_charge_error' in message.tags %} -
    -
  • -

    {{ message|safe }}

    -
  • -
- {% endif %} - {% endfor %} - {% for error in form.non_field_errors %} -

- {{ error|escape }} -

- {% endfor %} -
-
- -
- {% else %} - {% include "hosting/includes/_card_input.html" %} - {% endif %} -
- {% endcomment %} {% endwith %} diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 50148418..3a8bdac6 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -359,7 +359,6 @@ class PaymentOrderView(FormView): 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( @@ -369,24 +368,10 @@ class PaymentOrderView(FormView): 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({ 'cards_list': cards_list, 'stripe_key': settings.STRIPE_API_PUBLIC_KEY, diff --git a/hosting/templates/hosting/settings.html b/hosting/templates/hosting/settings.html index 6b5acbee..64057747 100644 --- a/hosting/templates/hosting/settings.html +++ b/hosting/templates/hosting/settings.html @@ -123,14 +123,4 @@ })(); {%endif%} - - {% comment %} - {% if credit_card_data.last4 and credit_card_data.cc_brand %} - - {%endif%} - {% endcomment %} {%endblock%} From 4be27962703cdb2774e1b0d13842ba3df3b22846 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 22:40:21 +0100 Subject: [PATCH 0089/1840] Clean up some unnecessary code --- datacenterlight/views.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 3a8bdac6..fb34f5b4 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -348,10 +348,9 @@ class PaymentOrderView(FormView): def get_context_data(self, **kwargs): context = super(PaymentOrderView, self).get_context_data(**kwargs) user = self.request.user + stripe_customer = None if hasattr(user, 'stripecustomer'): stripe_customer = user.stripecustomer - else: - stripe_customer = None cards_list = UserCardDetail.get_all_cards_list( stripe_customer=stripe_customer ) @@ -390,8 +389,6 @@ class PaymentOrderView(FormView): request.session, ['token', 'card_id', 'customer', 'user'] ) - if 'token' in request.session: - del request.session['token'] return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): From 83dbae74e6a661b649f79d2b691ea8dc73a2e8d2 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 22:54:33 +0100 Subject: [PATCH 0090/1840] Add missing card_id to session variables to be cleared --- datacenterlight/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index fb34f5b4..f9d1dede 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -765,7 +765,7 @@ class OrderConfirmationView(DetailView): HostingUtils.clear_items_from_list( request.session, ['specs', 'template', 'billing_address', 'billing_address_data', - 'token', 'customer'] + 'token', 'customer', 'card_id'] ) if request.user.is_authenticated(): redirect_url = reverse('hosting:virtual_machines') From 16b6ecb38cdc87737c54e9f51e3ffa7eff51014a Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 29 Oct 2017 23:48:33 +0100 Subject: [PATCH 0091/1840] Clear session variables on payment error --- hosting/views.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index 5a9c2e2e..37d6eabb 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -39,7 +39,7 @@ from utils.forms import ( BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm, ResendActivationEmailForm ) -from utils.hosting_utils import get_vm_price +from utils.hosting_utils import get_vm_price, HostingUtils from utils.mailer import BaseEmail from utils.stripe_utils import StripeUtils from utils.views import ( @@ -707,6 +707,10 @@ class PaymentVMView(LoginRequiredMixin, FormView): def get(self, request, *args, **kwargs): if 'next' in request.session: del request.session['next'] + HostingUtils.clear_items_from_list( + request.session, + ['token', 'card_id', 'customer', 'user'] + ) return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): From 24d904288fd0724178af021fcbeec01fadf54947 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 30 Oct 2017 00:26:18 +0100 Subject: [PATCH 0092/1840] Clear token and card form variables explicitly --- datacenterlight/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index f9d1dede..f2af35cd 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -356,6 +356,10 @@ class PaymentOrderView(FormView): ) if 'billing_address_data' in self.request.session: billing_address_data = self.request.session['billing_address_data'] + if 'token' in billing_address_data: + billing_address_data.pop('token') + if 'card' in billing_address_data: + billing_address_data.pop('card') else: billing_address_data = {} if self.request.user.is_authenticated(): From a2a35a9475eb6bafd7d6d70d991416a21caab0f4 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 30 Oct 2017 08:26:35 +0100 Subject: [PATCH 0093/1840] Fix error accessing stripecustomer for user when it doesn't exist --- hosting/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hosting/views.py b/hosting/views.py index 37d6eabb..3b259242 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -552,8 +552,11 @@ class SettingsView(LoginRequiredMixin, FormView): def get_context_data(self, **kwargs): context = super(SettingsView, self).get_context_data(**kwargs) user = self.request.user + stripe_customer = None + if hasattr(user, 'stripecustomer'): + stripe_customer = user.stripecustomer cards_list = UserCardDetail.get_all_cards_list( - stripe_customer=user.stripecustomer + stripe_customer=stripe_customer ) context.update({ 'cards_list': cards_list, From 3e08760e044bfed66cb1363a4bfcb8de95b93d52 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 08:58:43 +0100 Subject: [PATCH 0094/1840] Change letter-spacing to 2px for settings-container buttons --- hosting/static/hosting/css/commons.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/static/hosting/css/commons.css b/hosting/static/hosting/css/commons.css index 33381370..32a1338e 100644 --- a/hosting/static/hosting/css/commons.css +++ b/hosting/static/hosting/css/commons.css @@ -363,7 +363,7 @@ } .settings-container .choice-btn { - letter-spacing: 1px; + letter-spacing: 2px; min-width: 127px; } From d8ce0f95c5d92d2c9648051e5cef5f54f03ce04b Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 09:02:07 +0100 Subject: [PATCH 0095/1840] Change letter-spacing to 2px for btn-vm-contact --- hosting/static/hosting/css/virtual-machine.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/static/hosting/css/virtual-machine.css b/hosting/static/hosting/css/virtual-machine.css index 3329d6fe..5f91fe2f 100644 --- a/hosting/static/hosting/css/virtual-machine.css +++ b/hosting/static/hosting/css/virtual-machine.css @@ -413,7 +413,7 @@ border: 2px solid #A3C0E2; padding: 5px 25px; font-size: 12px; - letter-spacing: 1.3px; + letter-spacing: 2px; } .btn-vm-contact:hover, .btn-vm-contact:focus { background: #fff; From f9bd8493330cd809f4c47ea98e7c21ba8b1fb1cd Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 09:05:49 +0100 Subject: [PATCH 0096/1840] Remove redundant "previous" text --- .../templates/datacenterlight/landing_payment.html | 4 ++-- hosting/templates/hosting/payment.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index 5ac601ce..e0bd56a9 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -89,7 +89,7 @@

{% if card_list_len > 0 %} - {% blocktrans %}Please select one of the previous cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% blocktrans %}Please select one of the cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% else %} {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% endif %} @@ -108,7 +108,7 @@ {% endfor %} {% if card_list_len > 0 %} -

Use another card
+
{% trans "Use another card" %}
{% endif %} {% include "hosting/includes/_card_input.html" %} diff --git a/hosting/templates/hosting/payment.html b/hosting/templates/hosting/payment.html index 10fd4674..a321b44c 100644 --- a/hosting/templates/hosting/payment.html +++ b/hosting/templates/hosting/payment.html @@ -72,7 +72,7 @@

{% if card_list_len > 0 %} - {% blocktrans %}Please select one of the previous cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} + {% blocktrans %}Please select one of the cards that you used before or fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% else %} {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %} {% endif %} @@ -91,7 +91,7 @@

{% endfor %} {% if card_list_len > 0 %} -
Use another card
+
{% trans "Use another card" %}
{% endif %} {% include "hosting/includes/_card_input.html" %} From c438c0d8cbab7d8518d929cc675fa5d8fc5d1d13 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 31 Oct 2017 09:38:36 +0100 Subject: [PATCH 0097/1840] Add some de translations --- .../locale/de/LC_MESSAGES/django.po | 48 +++++++--- hosting/locale/de/LC_MESSAGES/django.po | 87 +++++++++++++++---- 2 files changed, 108 insertions(+), 27 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 3b8c9ca6..2fe8dba8 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-17 00:32+0530\n" +"POT-Creation-Date: 2017-10-31 08:23+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -345,6 +345,17 @@ msgstr "Monat" msgid "Credit Card" msgstr "Kreditkarte" +msgid "" +"Please select one of the cards that you used before or fill in your credit " +"card information below. We are using Stripe for payment and do not store your information in our " +"database." +msgstr "" +"Bitte wähle Seine der Karten aus, die du zuvor verwendet hast, oder gib " +"deine Kreditkartendaten unten ein. Wir verwenden Stripe als " +"Zahlungdiensleister und speichern deine Daten nicht in unserer Datenbank." + msgid "" "Please fill in your credit card information below. We are using Stripe for payment and do not " @@ -354,12 +365,17 @@ msgstr "" "\"https://stripe.com\" target=\"_blank\">Stripe 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 "Last" +msgstr "Vor" + +msgid "Type" +msgstr "Kartentyp" + +msgid "SELECT" +msgstr "Auswählen" + +msgid "Use another card" +msgstr "Benutze eine andere Kreditkarte" msgid "Processing" msgstr "Weiter" @@ -471,6 +487,13 @@ msgstr "Ungültige RAM-Grösse" msgid "Invalid storage size" msgstr "Ungültige Speicher-Grösse" +#, python-brace-format +msgid "{user} does not have permission to access the card" +msgstr "" + +msgid "An error occurred. Details: {}" +msgstr "" + msgid "Confirm Order" msgstr "Bestellung Bestätigen" @@ -494,15 +517,20 @@ msgstr "" "Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du " "auf sie zugreifen kannst." +#~ 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 "Card Type" -#~ msgstr "Kartentyp" - #~ msgid "Processing..." #~ msgstr "Abarbeitung..." diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 64e4a73e..3614dc49 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-17 00:32+0530\n" +"POT-Creation-Date: 2017-10-31 08:23+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -437,6 +437,17 @@ msgstr "inkl. Mehrwertsteuer" msgid "Billing Address" msgstr "Rechnungsadresse" +msgid "" +"Please select one of the cards that you used before or fill in your credit " +"card information below. We are using Stripe for payment and do not store your information in our " +"database." +msgstr "" +"Bitte wähle Seine der Karten aus, die du zuvor verwendet hast, oder gib " +"deine Kreditkartendaten unten ein. Wir verwenden Stripe als " +"Zahlungdiensleister und speichern deine Daten nicht in unserer Datenbank." + msgid "" "Please fill in your credit card information below. We are using Stripe for payment and do not " @@ -446,12 +457,17 @@ msgstr "" "\"https://stripe.com\" target=\"_blank\">Stripe 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 "Last" +msgstr "Vor" + +msgid "Type" +msgstr "Kartentyp" + +msgid "SELECT" +msgstr "Auswählen" + +msgid "Use another card" +msgstr "Benutze eine andere Kreditkarte" msgid "Processing" msgstr "Weiter" @@ -468,16 +484,19 @@ msgstr "Passwort zurücksetzen" msgid "UPDATE" msgstr "" -msgid "Last" -msgstr "" - -msgid "Type" -msgstr "Kartentyp" - msgid "REMOVE CARD" msgstr "KARTE ENTFERNEN" -msgid "SELECT" +msgid "Remove Card" +msgstr "Karte Entfernen" + +msgid "Do you want to remove this associated card?" +msgstr "" + +msgid "Delete" +msgstr "Löschen" + +msgid "DEFAULT" msgstr "" msgid "No Credit Cards Added" @@ -534,9 +553,6 @@ msgstr "" msgid "Private Key" msgstr "" -msgid "Delete" -msgstr "Löschen" - msgid "Delete SSH Key" msgstr "SSH Key löschen" @@ -668,6 +684,35 @@ msgstr "Dein Passwort konnte nicht zurückgesetzt werden." msgid "The reset password link is no longer valid." msgstr "Der Link zum Zurücksetzen Deines Passwortes ist nicht mehr gültig." +msgid "Card deassociation successful" +msgstr "" + +msgid "You are not permitted to do this operation" +msgstr "" + +msgid "The selected card does not exist" +msgstr "" + +msgid "Billing address updated successfully" +msgstr "" + +msgid "You seem to have already added this card" +msgstr "" + +#, python-brace-format +msgid "An error occurred while associating the card. Details: {details}" +msgstr "Beim Zuordnen der Karte ist ein Fehler aufgetreten. Details: {details}" + +msgid "Successfully associated the card with your account" +msgstr "" + +#, python-brace-format +msgid "{user} does not have permission to access the card" +msgstr "" + +msgid "An error occurred. Details: {}" +msgstr "" + msgid "Invalid credit card" msgstr "Ungültige Kreditkarte" @@ -735,6 +780,14 @@ msgstr "" "Es gab einen Fehler bei der Bearbeitung Deine Anfrage. Bitte versuche es " "noch einmal." +#~ 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 "Reset your password" #~ msgstr "Passwort zurücksetzen" From 07dfd3d67533c6ca72d5d1c45f26d1a60b5cfa5e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Tue, 31 Oct 2017 15:10:10 +0530 Subject: [PATCH 0098/1840] images changed to something more relatable --- ungleich_page/templates/ungleich_page/includes/_about.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ungleich_page/templates/ungleich_page/includes/_about.html b/ungleich_page/templates/ungleich_page/includes/_about.html index 37fc378a..e01b22e3 100644 --- a/ungleich_page/templates/ungleich_page/includes/_about.html +++ b/ungleich_page/templates/ungleich_page/includes/_about.html @@ -81,7 +81,7 @@
  • - +
    @@ -94,7 +94,7 @@
  • - +
    From fcc22945a47857ecb48a880b45aaf4ed4ab67d0c Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Thu, 2 Nov 2017 23:49:38 +0530 Subject: [PATCH 0099/1840] digitalglarus landing page animation direction changed, bootstrap grid fix --- .../static/digitalglarus/css/ungleich.css | 2 +- .../templates/digitalglarus/index.html | 786 +++++++++--------- 2 files changed, 386 insertions(+), 402 deletions(-) diff --git a/digitalglarus/static/digitalglarus/css/ungleich.css b/digitalglarus/static/digitalglarus/css/ungleich.css index 03a2b47c..0b47b04f 100644 --- a/digitalglarus/static/digitalglarus/css/ungleich.css +++ b/digitalglarus/static/digitalglarus/css/ungleich.css @@ -1,4 +1,4 @@ -#page-top #services .container .row .col-lg-12.text-center .section-heading { +#page-top #services .section-heading { font-style: normal; color: #494949; padding-top: 50px; diff --git a/digitalglarus/templates/digitalglarus/index.html b/digitalglarus/templates/digitalglarus/index.html index b57e54b5..504af551 100644 --- a/digitalglarus/templates/digitalglarus/index.html +++ b/digitalglarus/templates/digitalglarus/index.html @@ -3,251 +3,255 @@ {% block content %} - -
    -
    -
    -

    -

    -
    - - Where great minds work - -
    -
    -
    - -
    -

    - Book a date today and dive in

    - Join now - - -
    + - - -
    - - -
    -
    -
    -
    -
    -
    -
    Partner of
    -
    -
    -
    + +
    +
    +
    +
    + + Where great minds work + +
    -
    +
    + +
    +

    Book a date today and dive in

    + Join now + + {% comment %} +
    +
    + + +
    + + +
    +
    + +
    + {% endcomment %} +
    + +
    + + + +
    +
    +
    +
    Partner of
    +
    + + + +
    +
    +

    In Digital Glarus you can..


    -
    - -
    -
    -
    - + + +
    +
    +
    + +
    -
    -
    -
    - +
    +
    + +
    -
    -
    -
    - +
    +
    + +
    -
    -
    -
    - -
    -
    -
    -
    -
    - +
    +
    + +
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    - -
    -
    +
    +
    + +
    - - -
    + +
    -
    - - -
    -
      -
    • - -
      -
      - -
      -
    • -
    -
    cultural events
    -
    - -
    -
      -
    • - -
      -
      - -
      -
    • -
    -
    be inspired
    -
    - - - -
    -
      -
    • - +
      +
        +
      • +
        -
      • -
      -
      workshops
      -
      +
    • +
    +
    cultural events
    +
    -
    -
      -
    • - +
      +
        +
      • +
        -
        -
      • -
      -
      recharge
      +
      +
    • +
    +
    be inspired
    +
    + +
    +
      +
    • + +
      +
      +
      +
    • +
    +
    workshops
    +
    + +
    +
      +
    • + +
      +
      +
      +
    • +
    +
    recharge
    +
    - - - -
    + - - - - - - - - -
    -
    -
    -
    -

    Contact Us

    -
    -
    -
    - Digital Glarus
    - In der Au 7 Schwanden 8762 Switzerland -
    info@digitalglarus.ch + +
    + + + + +
    + +
    + +
    +
    + +
    + +
    +
    + +
    + +
    +
    + + + + + + + + +
    + +
    +
    +
    +
    +
    +

    Contact Us

    +
    + +
    +
    + Digital Glarus
    + In der Au 7 Schwanden 8762 Switzerland +
    info@digitalglarus.ch +
    + (044) 534-66-22 +

     

    +
    +
    +

     

    +
    +
    +
    +
    +
    - - - - - @@ -41,37 +41,37 @@

    the story of Digital Glarus

    - + + place. That's how it all started... +

    we fell in love

    - +

    Our crowdfunding success

    - + @@ -80,11 +80,11 @@

    And the story continues..!


    @@ -107,7 +107,7 @@

    Our Supporters


    -

    @@ -132,7 +132,7 @@

    - +
    Digital Glarus
    diff --git a/digitalglarus/templates/digitalglarus/index.html b/digitalglarus/templates/digitalglarus/index.html index da8d762e..03cb2bc0 100644 --- a/digitalglarus/templates/digitalglarus/index.html +++ b/digitalglarus/templates/digitalglarus/index.html @@ -443,10 +443,10 @@
    -
    +

    Contact Us

    -
    - +
    +
    Digital Glarus
    From 49ea549c73ca6cf0f04c7f4240b53d2e9e85c838 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Sun, 5 Nov 2017 23:48:20 +0530 Subject: [PATCH 0102/1840] ungleich header slider --- .../static/ungleich_page/css/ungleich.css | 15 +++++++ .../ungleich_page/includes/_header.html | 41 ++++++++++++++----- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/ungleich_page/static/ungleich_page/css/ungleich.css b/ungleich_page/static/ungleich_page/css/ungleich.css index 40ddf2fd..fc8a460e 100644 --- a/ungleich_page/static/ungleich_page/css/ungleich.css +++ b/ungleich_page/static/ungleich_page/css/ungleich.css @@ -111,3 +111,18 @@ paddding: 10px; } } + +.header_slider { + height: 100vh; +} + +.header_slider > .carousel { + display: flex; + flex-direction: column; + height: 100%; + align-items: stretch; +} + +.header_slider > .carousel .item { + padding-top: 150px; +} \ No newline at end of file diff --git a/ungleich_page/templates/ungleich_page/includes/_header.html b/ungleich_page/templates/ungleich_page/includes/_header.html index a86f2f24..996b297c 100644 --- a/ungleich_page/templates/ungleich_page/includes/_header.html +++ b/ungleich_page/templates/ungleich_page/includes/_header.html @@ -1,17 +1,36 @@ {% load static %} {% load i18n %} -
    -
    -
    - -


    -
    - - {% trans "We Design, Configure & Maintain
    Your Linux Infrastructure " %} -
    -
    +
    + + + +
    \ No newline at end of file From e35d9a27895d9ca978165d96375cedf4e7de8b36 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Thu, 16 Nov 2017 17:44:15 +0100 Subject: [PATCH 0103/1840] Add ungleich_cms_page.html --- .../ungleich_page/ungleich_cms_page.html | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 ungleich_page/templates/ungleich_page/ungleich_cms_page.html diff --git a/ungleich_page/templates/ungleich_page/ungleich_cms_page.html b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html new file mode 100644 index 00000000..9f863f1f --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html @@ -0,0 +1,145 @@ +{% load static i18n cms_tags sekizai_tags %} + + + + + + + + + + + + {% page_attribute "page_title" %} + + + + + + + + + + + + + + {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %} + {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %} + + {% include "google_analytics.html" %} + + + + + + +{% cms_toolbar %} + + + + + {% placeholder 'Ungleich Page Contents' %} + + + {% include "ungleich_page/includes/_header.html" %} + + + {% include "ungleich_page/includes/_services.html" %} + + + {% include "ungleich_page/includes/_portfolio.html" %} + + + {% include "ungleich_page/includes/_about.html" %} + + + {% include "ungleich_page/includes/_team.html" %} + + + {% include "ungleich_page/includes/_softwares.html" %} + + + {% include "ungleich_page/includes/_contact_us.html" %} + + + {% include "ungleich_page/includes/_footer.html" %} + + + + + + + + + + + + + + + + + + + + + + + + + From e9b3e77752d8eb71e3f7e441551f0deca3b515a1 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Fri, 17 Nov 2017 15:48:44 +0100 Subject: [PATCH 0104/1840] Change title char field in UngleichPicture to HTML field --- ungleich_page/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ungleich_page/models.py b/ungleich_page/models.py index 3759ee25..5ea6a9dc 100644 --- a/ungleich_page/models.py +++ b/ungleich_page/models.py @@ -11,7 +11,7 @@ class UngelichPicture(CMSPlugin): related_name="image", on_delete=models.SET_NULL ) - title = models.CharField(max_length=400) + title = HTMLField() class SectionWithImage(UngelichPicture): From 501dc08b0ef86dffcd4b181df768532a8a544395 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Fri, 17 Nov 2017 16:30:44 +0100 Subject: [PATCH 0105/1840] Align text to flex-start or flex-end for timeline --- .../static/ungleich_page/css/ungleich.css | 36 ++++++++++++++++++- .../ungleich_page/glasfaser/_about_item.html | 2 +- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ungleich_page/static/ungleich_page/css/ungleich.css b/ungleich_page/static/ungleich_page/css/ungleich.css index fc8a460e..fe34ee6b 100644 --- a/ungleich_page/static/ungleich_page/css/ungleich.css +++ b/ungleich_page/static/ungleich_page/css/ungleich.css @@ -125,4 +125,38 @@ .header_slider > .carousel .item { padding-top: 150px; -} \ No newline at end of file +} + + +.timeline>li .timeline-panel { + display: flex; + min-height: 80px; + align-items: center; + padding-bottom: 15px; +} + +.flex-justify-content-end{ + justify-content: flex-end; +} + +.flex-justify-content-start{ + justify-content: flex-start; +} + +.timeline>li.timeline-inverted>.timeline-panel { + padding-bottom: 0; +} + + +@media (min-width: 768px) and (max-width: 991px) { + .timeline>li .timeline-panel { + min-height: 100px; + } +} + +@media (min-width: 992px) { + .timeline>li .timeline-panel { + min-height: 170px; + } +} + diff --git a/ungleich_page/templates/ungleich_page/glasfaser/_about_item.html b/ungleich_page/templates/ungleich_page/glasfaser/_about_item.html index 0ccdff9a..6b619579 100644 --- a/ungleich_page/templates/ungleich_page/glasfaser/_about_item.html +++ b/ungleich_page/templates/ungleich_page/glasfaser/_about_item.html @@ -4,7 +4,7 @@
    {% if instance.link_url %}{% endif %} -
    +

    {{ instance.title }}

    From 4367b9e58a6d8386285ba357a6ef7aafd13be445 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Fri, 17 Nov 2017 16:32:40 +0100 Subject: [PATCH 0106/1840] Add ungleich cms page template --- dynamicweb/settings/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index 48a2399f..19c263d5 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -219,6 +219,7 @@ CMS_TEMPLATES = ( # dcl ('datacenterlight/cms_page.html', gettext('Data Center Light')), ('ungleich_page/glasfaser_cms_page.html', gettext('Glasfaser')), + ('ungleich_page/ungleich_cms_page.html', gettext('ungleich')), ) DATABASES = { From 432d109c48c8f3ed67b018f8e81b904fd584b2c0 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Fri, 17 Nov 2017 16:36:25 +0100 Subject: [PATCH 0107/1840] Add migration --- .../migrations/0007_auto_20171117_1011.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 ungleich_page/migrations/0007_auto_20171117_1011.py diff --git a/ungleich_page/migrations/0007_auto_20171117_1011.py b/ungleich_page/migrations/0007_auto_20171117_1011.py new file mode 100644 index 00000000..71b4017a --- /dev/null +++ b/ungleich_page/migrations/0007_auto_20171117_1011.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-11-17 10:11 +from __future__ import unicode_literals + +from django.db import migrations +import djangocms_text_ckeditor.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('ungleich_page', '0006_aboutitem_link_url'), + ] + + operations = [ + migrations.AlterField( + model_name='ungelichpicture', + name='title', + field=djangocms_text_ckeditor.fields.HTMLField(), + ), + ] From 8a2eb8307a6991fedbf414af90f2ffab4d70e3fe Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Fri, 17 Nov 2017 17:36:01 +0100 Subject: [PATCH 0108/1840] Add UngleichServiceItem model --- ungleich_page/models.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ungleich_page/models.py b/ungleich_page/models.py index 5ea6a9dc..894e4101 100644 --- a/ungleich_page/models.py +++ b/ungleich_page/models.py @@ -87,3 +87,12 @@ class AboutItem(UngelichPicture): return "{alignment} - {title}".format( alignment=alignment, title=self.title ) + + +class UngleichServiceItem(ServiceItem): + data_replaced_image = FilerImageField( + null=True, + blank=True, + related_name="service_item_data_replaced_image", + on_delete=models.SET_NULL + ) \ No newline at end of file From cf1f7d6141344847fd79a00f6705046aa39a3ad0 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Fri, 17 Nov 2017 17:37:05 +0100 Subject: [PATCH 0109/1840] Add UngleichServicesPlugin and UngleichServicesItemPlugin --- ungleich_page/cms_plugins.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/ungleich_page/cms_plugins.py b/ungleich_page/cms_plugins.py index a5b10d5f..4c842093 100644 --- a/ungleich_page/cms_plugins.py +++ b/ungleich_page/cms_plugins.py @@ -3,7 +3,7 @@ from cms.plugin_pool import plugin_pool from .models import ( UngelichContactUsSection, UngelichTextSection, Service, ServiceItem, - About, AboutItem, SectionWithImage + About, AboutItem, SectionWithImage, UngleichServiceItem ) @@ -145,3 +145,35 @@ class GlasfaserAboutItemPlugin(CMSPluginBase): ) context['instance'] = instance return context + + +@plugin_pool.register_plugin +class UngleichServicesPlugin(CMSPluginBase): + name = "ungleich Services Plugin" + model = Service + render_template = "ungleich_page/ungleich/section_services.html" + cache = False + allow_children = True + child_classes = ['UngleichServicesItemPlugin'] + + def render(self, context, instance, placeholder): + context['service_instance'] = instance + context['section_id'] = get_section_id(instance, 'services') + return context + + +@plugin_pool.register_plugin +class UngleichServicesItemPlugin(CMSPluginBase): + name = "ungleich Service Item Plugin" + model = UngleichServiceItem + render_template = "ungleich_page/ungleich/_services_item.html" + cache = False + require_parent = True + parent_classes = ['UngleichServicesPlugin'] + + def render(self, context, instance, placeholder): + context = super(UngleichServicesItemPlugin, self).render( + context, instance, placeholder + ) + context['instance'] = instance + return context \ No newline at end of file From 2af78be195170d853ddd48740f9875c17212f96f Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Fri, 17 Nov 2017 17:39:46 +0100 Subject: [PATCH 0110/1840] First version of ungleich/section_services.html (wip) --- .../ungleich/section_services.html | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 ungleich_page/templates/ungleich_page/ungleich/section_services.html diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_services.html b/ungleich_page/templates/ungleich_page/ungleich/section_services.html new file mode 100644 index 00000000..10a682b7 --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/section_services.html @@ -0,0 +1,44 @@ +{% load static i18n cms_tags %} +
    +
    +
    +

    {{ service_instance.title }}

    +

    + {% trans "We support our clients in all areas of Unix infrastructure." %}
    + {% trans "Our top notch configuration management is refreshingly simple and reliable." %} +

    +
    +
    +
    +
    + +
    +

    {% trans "Hosting" %}

    +

     

    +

    {% trans "Ruby on Rails. Java hosting, Django hosting, we make it everything run smooth and safe." %}

    +
    +
    +
    +
    +
    + +
    +

    {% trans "Configuration as a Service" %}

    +

     

    +

    {% trans "Ruby on Rails, Django, Java, Webserver, Mailserver, any infrastructure that needs to configured, we provide comprehensive solutions. Amazon, rackspace or bare metal servers, we configure for you." %}

    +
    +
    +
    +
    +
    + +
    +

    {% trans "Linux System Engineering" %}

    +

     

    +

    {% trans "Let your developers develop! We take care of your system administration. Gentoo, Archlinux, Debian, Ubuntu, and many more." %}

    +
    +
    +
    +
    +
    +
    From 06e8b3acc99aa7e855ff8fa74552cbd1065e10ee Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 08:16:50 +0100 Subject: [PATCH 0111/1840] Remove new line --- .../templates/ungleich_page/glasfaser/section_services.html | 1 - 1 file changed, 1 deletion(-) diff --git a/ungleich_page/templates/ungleich_page/glasfaser/section_services.html b/ungleich_page/templates/ungleich_page/glasfaser/section_services.html index a4b50e5c..4f373653 100644 --- a/ungleich_page/templates/ungleich_page/glasfaser/section_services.html +++ b/ungleich_page/templates/ungleich_page/glasfaser/section_services.html @@ -11,7 +11,6 @@ {% render_plugin plugin %}
    {% endfor %} -
    \ No newline at end of file From 41b68365ed275dc64f04ddff71c4509afd4bfc34 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 10:22:32 +0100 Subject: [PATCH 0112/1840] Add ungleichserviceitem migration --- .../migrations/0008_ungleichserviceitem.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 ungleich_page/migrations/0008_ungleichserviceitem.py diff --git a/ungleich_page/migrations/0008_ungleichserviceitem.py b/ungleich_page/migrations/0008_ungleichserviceitem.py new file mode 100644 index 00000000..3a029110 --- /dev/null +++ b/ungleich_page/migrations/0008_ungleichserviceitem.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-11-17 18:49 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import filer.fields.image + + +class Migration(migrations.Migration): + + dependencies = [ + ('filer', '0005_auto_20171015_0703'), + ('ungleich_page', '0007_auto_20171117_1011'), + ] + + operations = [ + migrations.CreateModel( + name='UngleichServiceItem', + fields=[ + ('serviceitem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='ungleich_page.ServiceItem')), + ('data_replaced_image', filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='service_item_data_replaced_image', to='filer.Image')), + ], + options={ + 'abstract': False, + }, + bases=('ungleich_page.serviceitem',), + ), + ] From 7aca2512600cf1a5d57d180fb85c5a0f64d5f575 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 10:25:30 +0100 Subject: [PATCH 0113/1840] Add ungleich services and serivce item htmls --- .../ungleich/_services_item.html | 8 ++++ .../ungleich/section_services.html | 42 ++++--------------- 2 files changed, 15 insertions(+), 35 deletions(-) create mode 100644 ungleich_page/templates/ungleich_page/ungleich/_services_item.html diff --git a/ungleich_page/templates/ungleich_page/ungleich/_services_item.html b/ungleich_page/templates/ungleich_page/ungleich/_services_item.html new file mode 100644 index 00000000..87fda196 --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/_services_item.html @@ -0,0 +1,8 @@ +
    + +
    +

    {{ instance.title }}

    +

     

    +

    {{ instance.description }}

    +
    +
    \ No newline at end of file diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_services.html b/ungleich_page/templates/ungleich_page/ungleich/section_services.html index 10a682b7..2c9e5246 100644 --- a/ungleich_page/templates/ungleich_page/ungleich/section_services.html +++ b/ungleich_page/templates/ungleich_page/ungleich/section_services.html @@ -1,44 +1,16 @@ -{% load static i18n cms_tags %} +{% load cms_tags %}

    {{ service_instance.title }}

    -

    - {% trans "We support our clients in all areas of Unix infrastructure." %}
    - {% trans "Our top notch configuration management is refreshingly simple and reliable." %} -

    +

    {{ service_instance.sub_title }}

    -
    -
    - -
    -

    {% trans "Hosting" %}

    -

     

    -

    {% trans "Ruby on Rails. Java hosting, Django hosting, we make it everything run smooth and safe." %}

    -
    -
    -
    -
    -
    - -
    -

    {% trans "Configuration as a Service" %}

    -

     

    -

    {% trans "Ruby on Rails, Django, Java, Webserver, Mailserver, any infrastructure that needs to configured, we provide comprehensive solutions. Amazon, rackspace or bare metal servers, we configure for you." %}

    -
    -
    -
    -
    -
    - -
    -

    {% trans "Linux System Engineering" %}

    -

     

    -

    {% trans "Let your developers develop! We take care of your system administration. Gentoo, Archlinux, Debian, Ubuntu, and many more." %}

    -
    -
    -
    + {% for plugin in service_instance.child_plugin_instances %} +
    + {% render_plugin plugin %} +
    + {% endfor %}
    From d006ddcf0db26b638e8b906d7ab842a22ca7edac Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 13:19:01 +0100 Subject: [PATCH 0114/1840] Add UngleichHeaderWithTextAndImageSliderPlugin and UngleichHeaderItemPlugin --- ungleich_page/cms_plugins.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/ungleich_page/cms_plugins.py b/ungleich_page/cms_plugins.py index 4c842093..9d5cfda0 100644 --- a/ungleich_page/cms_plugins.py +++ b/ungleich_page/cms_plugins.py @@ -3,7 +3,8 @@ from cms.plugin_pool import plugin_pool from .models import ( UngelichContactUsSection, UngelichTextSection, Service, ServiceItem, - About, AboutItem, SectionWithImage, UngleichServiceItem + About, AboutItem, SectionWithImage, UngleichServiceItem, UngleichHeader, + UngleichHeaderItem ) @@ -176,4 +177,35 @@ class UngleichServicesItemPlugin(CMSPluginBase): context, instance, placeholder ) context['instance'] = instance + return context + + +@plugin_pool.register_plugin +class UngleichHeaderWithTextAndImageSliderPlugin(CMSPluginBase): + name = "ungleich Header with Text and Image Slider Plugin" + model = UngleichHeader + render_template = "ungleich_page/ungleich/header.html" + cache = False + allow_children = True + child_classes = ['UngleichHeaderItemPlugin'] + + def render(self, context, instance, placeholder): + context['instance'] = instance + return context + + +@plugin_pool.register_plugin +class UngleichHeaderItemPlugin(CMSPluginBase): + name = "ungleich Header Item Plugin" + model = UngleichHeaderItem + render_template = "ungleich_page/ungleich/_header_item.html" + cache = False + require_parent = True + parent_classes = ['UngleichHeaderWithTextAndImageSliderPlugin'] + + def render(self, context, instance, placeholder): + context = super(UngleichHeaderItemPlugin, self).render( + context, instance, placeholder + ) + context['instance'] = instance return context \ No newline at end of file From e05a2eab7e4a2b985dd5fac426e9a87a210dd8ec Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 13:19:40 +0100 Subject: [PATCH 0115/1840] Add UngleichHeader and UngleichHeaderItem models --- ungleich_page/models.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ungleich_page/models.py b/ungleich_page/models.py index 894e4101..640e599b 100644 --- a/ungleich_page/models.py +++ b/ungleich_page/models.py @@ -95,4 +95,24 @@ class UngleichServiceItem(ServiceItem): blank=True, related_name="service_item_data_replaced_image", on_delete=models.SET_NULL - ) \ No newline at end of file + ) + + +class UngleichHeader(CMSPlugin): + background_image = FilerImageField( + null=True, + blank=True, + related_name="ungleich_header_background_image", + on_delete=models.SET_NULL + ) + carousel_data_interval = models.IntegerField(default=5000) + + +class UngleichHeaderItem(CMSPlugin): + image = FilerImageField( + null=True, + blank=True, + related_name="ungleich_header_item_image", + on_delete=models.SET_NULL + ) + description = HTMLField() \ No newline at end of file From 09b118b3119764107511df031558b6bd062a77fe Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 13:20:26 +0100 Subject: [PATCH 0116/1840] Add intro-cap-sans-transform p class --- ungleich_page/static/ungleich_page/css/ungleich.css | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ungleich_page/static/ungleich_page/css/ungleich.css b/ungleich_page/static/ungleich_page/css/ungleich.css index fe34ee6b..b3296ca1 100644 --- a/ungleich_page/static/ungleich_page/css/ungleich.css +++ b/ungleich_page/static/ungleich_page/css/ungleich.css @@ -7,6 +7,17 @@ color: #494949; } +.header-vh { + height: 30px; +} +.intro-cap-sans-transform p { + font-family: 'Raleway', 'Helvetica Neue', 'Open Sans Bold', Helvetica, Arial, 'Arial Bold', sans-serif; + font-size: 26px; + font-style: normal; + font-weight: 200; + color: #FFF; +} + .intro-cap { font-family: 'Raleway', 'Helvetica Neue', 'Open Sans Bold', Helvetica, Arial, 'Arial Bold', sans-serif; font-size: 26px; From 7a9c624012ffe5e7fae09bc0df0a194c25e9cda1 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 13:21:00 +0100 Subject: [PATCH 0117/1840] Add ungleich header migration --- .../0009_ungleichheader_ungleichheaderitem.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py diff --git a/ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py b/ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py new file mode 100644 index 00000000..499917a2 --- /dev/null +++ b/ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-11-19 11:28 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import djangocms_text_ckeditor.fields +import filer.fields.image + + +class Migration(migrations.Migration): + + dependencies = [ + ('filer', '0005_auto_20171015_0703'), + ('cms', '0014_auto_20160404_1908'), + ('ungleich_page', '0008_ungleichserviceitem'), + ] + + operations = [ + migrations.CreateModel( + name='UngleichHeader', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('carousel_data_interval', models.IntegerField(default=5000)), + ('background_image', filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ungleich_header_background_image', to='filer.Image')), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.CreateModel( + name='UngleichHeaderItem', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('description', djangocms_text_ckeditor.fields.HTMLField()), + ('image', filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ungleich_header_item_image', to='filer.Image')), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + ] From 4e8b3cdbe8441ce22e75df294f4ed299abce264c Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 13:22:37 +0100 Subject: [PATCH 0118/1840] Add ungleich header.html _header_item.html --- .../ungleich_page/ungleich/_header_item.html | 14 +++++++++++++ .../ungleich_page/ungleich/header.html | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 ungleich_page/templates/ungleich_page/ungleich/_header_item.html create mode 100644 ungleich_page/templates/ungleich_page/ungleich/header.html diff --git a/ungleich_page/templates/ungleich_page/ungleich/_header_item.html b/ungleich_page/templates/ungleich_page/ungleich/_header_item.html new file mode 100644 index 00000000..ca4303db --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/_header_item.html @@ -0,0 +1,14 @@ +
    +
    + {% if instance.image %} + +
    + {% endif %} +
    + + {{ instance.description }} + +
    +
    +
    diff --git a/ungleich_page/templates/ungleich_page/ungleich/header.html b/ungleich_page/templates/ungleich_page/ungleich/header.html new file mode 100644 index 00000000..89def4ee --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/header.html @@ -0,0 +1,20 @@ +{% load cms_tags %} +
    + +
    \ No newline at end of file From f927220a889e05ea17c1d2b2c36c831b6a91cb5a Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 14:54:16 +0100 Subject: [PATCH 0119/1840] Use image width 300px --- .../templates/ungleich_page/ungleich/_header_item.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ungleich_page/templates/ungleich_page/ungleich/_header_item.html b/ungleich_page/templates/ungleich_page/ungleich/_header_item.html index ca4303db..a770d1ed 100644 --- a/ungleich_page/templates/ungleich_page/ungleich/_header_item.html +++ b/ungleich_page/templates/ungleich_page/ungleich/_header_item.html @@ -1,7 +1,7 @@
    {% if instance.image %} -
    {% endif %} From 567ff8d314044a9f88f1289315e5388ff91b8306 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sun, 19 Nov 2017 15:51:52 +0100 Subject: [PATCH 0120/1840] Change subtitle to HTMLfield --- .../migrations/0010_auto_20171119_1404.py | 21 +++++++++++++++++++ ungleich_page/models.py | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 ungleich_page/migrations/0010_auto_20171119_1404.py diff --git a/ungleich_page/migrations/0010_auto_20171119_1404.py b/ungleich_page/migrations/0010_auto_20171119_1404.py new file mode 100644 index 00000000..4057a90b --- /dev/null +++ b/ungleich_page/migrations/0010_auto_20171119_1404.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-11-19 14:04 +from __future__ import unicode_literals + +from django.db import migrations +import djangocms_text_ckeditor.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('ungleich_page', '0009_ungleichheader_ungleichheaderitem'), + ] + + operations = [ + migrations.AlterField( + model_name='service', + name='sub_title', + field=djangocms_text_ckeditor.fields.HTMLField(), + ), + ] diff --git a/ungleich_page/models.py b/ungleich_page/models.py index 640e599b..d1e0199b 100644 --- a/ungleich_page/models.py +++ b/ungleich_page/models.py @@ -54,7 +54,7 @@ class UngelichTextSection(CMSPlugin): class Service(CMSPlugin): menu_text = models.CharField(max_length=100, default="", blank=True) title = models.CharField(max_length=200) - sub_title = models.CharField(max_length=200) + sub_title = HTMLField() def __str__(self): return self.title From 16e5fb8f5c9a03cc814c7ddde3537dd32059ed3d Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 22 Nov 2017 00:16:39 +0100 Subject: [PATCH 0121/1840] Add multiply filter --- datacenterlight/templatetags/custom_tags.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/datacenterlight/templatetags/custom_tags.py b/datacenterlight/templatetags/custom_tags.py index ce6e6724..908b1f89 100644 --- a/datacenterlight/templatetags/custom_tags.py +++ b/datacenterlight/templatetags/custom_tags.py @@ -31,3 +31,14 @@ def get_value_from_dict(dict_data, key): return dict_data.get(key) else: return "" + + +@register.filter('multiply') +def multiply(value, arg): + """ + usage: {{ quantity|multiply:price }} + :param value: + :param arg: + :return: + """ + return value*arg From 1e567ef6ad0e86ec1f438d2e6240944f74bfd9d9 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 22 Nov 2017 00:19:07 +0100 Subject: [PATCH 0122/1840] Add ungleichproduct and ungleichproductitem plugins --- ungleich_page/cms_plugins.py | 36 +++++++++++++++++- ...011_ungleichproduct_ungleichproductitem.py | 38 +++++++++++++++++++ ungleich_page/models.py | 10 ++++- 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 ungleich_page/migrations/0011_ungleichproduct_ungleichproductitem.py diff --git a/ungleich_page/cms_plugins.py b/ungleich_page/cms_plugins.py index 9d5cfda0..1b10375a 100644 --- a/ungleich_page/cms_plugins.py +++ b/ungleich_page/cms_plugins.py @@ -4,7 +4,7 @@ from cms.plugin_pool import plugin_pool from .models import ( UngelichContactUsSection, UngelichTextSection, Service, ServiceItem, About, AboutItem, SectionWithImage, UngleichServiceItem, UngleichHeader, - UngleichHeaderItem + UngleichHeaderItem, UngleichProductItem, UngleichProduct ) @@ -208,4 +208,36 @@ class UngleichHeaderItemPlugin(CMSPluginBase): context, instance, placeholder ) context['instance'] = instance - return context \ No newline at end of file + return context + + +@plugin_pool.register_plugin +class UngleichProductsPlugin(CMSPluginBase): + name = "ungleich Products Plugin" + model = UngleichProduct + render_template = "ungleich_page/ungleich/section_products.html" + cache = False + allow_children = True + child_classes = ['UngleichProductsItemPlugin'] + + def render(self, context, instance, placeholder): + context['product_instance'] = instance + context['section_id'] = get_section_id(instance, 'products') + return context + + +@plugin_pool.register_plugin +class UngleichProductsItemPlugin(CMSPluginBase): + name = "ungleich Product Item Plugin" + model = UngleichProductItem + render_template = "ungleich_page/ungleich/_products_item.html" + cache = False + require_parent = True + parent_classes = ['UngleichProductsPlugin'] + + def render(self, context, instance, placeholder): + context = super(UngleichProductsItemPlugin, self).render( + context, instance, placeholder + ) + context['instance'] = instance + return context diff --git a/ungleich_page/migrations/0011_ungleichproduct_ungleichproductitem.py b/ungleich_page/migrations/0011_ungleichproduct_ungleichproductitem.py new file mode 100644 index 00000000..c4984f5a --- /dev/null +++ b/ungleich_page/migrations/0011_ungleichproduct_ungleichproductitem.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-11-21 19:04 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('ungleich_page', '0010_auto_20171119_1404'), + ] + + operations = [ + migrations.CreateModel( + name='UngleichProduct', + fields=[ + ('service_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='ungleich_page.Service')), + ('section_class', models.CharField(blank=True, default='', max_length=100)), + ], + options={ + 'abstract': False, + }, + bases=('ungleich_page.service',), + ), + migrations.CreateModel( + name='UngleichProductItem', + fields=[ + ('serviceitem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='ungleich_page.ServiceItem')), + ('url', models.URLField(blank=True, default='', max_length=300)), + ], + options={ + 'abstract': False, + }, + bases=('ungleich_page.serviceitem',), + ), + ] diff --git a/ungleich_page/models.py b/ungleich_page/models.py index d1e0199b..f936f23b 100644 --- a/ungleich_page/models.py +++ b/ungleich_page/models.py @@ -115,4 +115,12 @@ class UngleichHeaderItem(CMSPlugin): related_name="ungleich_header_item_image", on_delete=models.SET_NULL ) - description = HTMLField() \ No newline at end of file + description = HTMLField() + + +class UngleichProductItem(ServiceItem): + url = models.URLField(max_length=300, default="", blank=True) + + +class UngleichProduct(Service): + section_class = models.CharField(max_length=100, default="", blank=True) \ No newline at end of file From 609a49cdbb825c6aa7dbaa54884758d7c62c36ad Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 22 Nov 2017 00:20:06 +0100 Subject: [PATCH 0123/1840] Add section_products and _products_item templates --- .../ungleich/_products_item.html | 6 ++++++ .../ungleich/section_products.html | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 ungleich_page/templates/ungleich_page/ungleich/_products_item.html create mode 100644 ungleich_page/templates/ungleich_page/ungleich/section_products.html diff --git a/ungleich_page/templates/ungleich_page/ungleich/_products_item.html b/ungleich_page/templates/ungleich_page/ungleich/_products_item.html new file mode 100644 index 00000000..0a09640d --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/_products_item.html @@ -0,0 +1,6 @@ + +
    +

    {{ instance.title }}

    +

     

    +

    {{ instance.description }}

    +
    \ No newline at end of file diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_products.html b/ungleich_page/templates/ungleich_page/ungleich/section_products.html new file mode 100644 index 00000000..8eb2f312 --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/section_products.html @@ -0,0 +1,20 @@ +{% load cms_tags custom_tags %} +
    +
    +
    +
    +
    +

    {{ product_instance.title }}

    +

    {{ product_instance.sub_title }}

    +
    +
    +
    + {% for plugin in product_instance.child_plugin_instances %} +
    + {% render_plugin plugin %} +
    + {% endfor %} +
    +
    +
    +
    \ No newline at end of file From 85289c2eeddc7682e6c66a94469464b2fb95f6dd Mon Sep 17 00:00:00 2001 From: PCoder Date: Thu, 23 Nov 2017 09:45:38 +0100 Subject: [PATCH 0124/1840] Add ungleich customer section, templates and migration --- ungleich_page/cms_plugins.py | 35 +++++++++++++- ...2_ungleichcustomer_ungleichcustomeritem.py | 46 +++++++++++++++++++ ungleich_page/models.py | 22 ++++++++- .../ungleich/_customer_item.html | 2 + .../ungleich/section_customers.html | 35 ++++++++++++++ 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py create mode 100644 ungleich_page/templates/ungleich_page/ungleich/_customer_item.html create mode 100644 ungleich_page/templates/ungleich_page/ungleich/section_customers.html diff --git a/ungleich_page/cms_plugins.py b/ungleich_page/cms_plugins.py index 1b10375a..d7c3c1a6 100644 --- a/ungleich_page/cms_plugins.py +++ b/ungleich_page/cms_plugins.py @@ -4,7 +4,8 @@ from cms.plugin_pool import plugin_pool from .models import ( UngelichContactUsSection, UngelichTextSection, Service, ServiceItem, About, AboutItem, SectionWithImage, UngleichServiceItem, UngleichHeader, - UngleichHeaderItem, UngleichProductItem, UngleichProduct + UngleichHeaderItem, UngleichProductItem, UngleichProduct, UngleichCustomer, + UngleichCustomerItem ) @@ -241,3 +242,35 @@ class UngleichProductsItemPlugin(CMSPluginBase): ) context['instance'] = instance return context + + +@plugin_pool.register_plugin +class UngleichCustomerSectionPlugin(CMSPluginBase): + name = "ungleich Customer Section Plugin" + model = UngleichCustomer + render_template = "ungleich_page/ungleich/section_customers.html" + cache = False + allow_children = True + child_classes = ['UngleichCustomerItemPlugin'] + + def render(self, context, instance, placeholder): + context['customer_instance'] = instance + context['section_id'] = get_section_id(instance, 'customer') + return context + + +@plugin_pool.register_plugin +class UngleichCustomerItemPlugin(CMSPluginBase): + name = "ungleich Customer Item Plugin" + model = UngleichCustomerItem + render_template = "ungleich_page/ungleich/_customer_item.html" + cache = False + require_parent = True + parent_classes = ['UngleichCustomerSectionPlugin'] + + def render(self, context, instance, placeholder): + context = super(UngleichCustomerItemPlugin, self).render( + context, instance, placeholder + ) + context['instance'] = instance + return context diff --git a/ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py b/ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py new file mode 100644 index 00000000..148ce241 --- /dev/null +++ b/ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-11-23 08:11 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import djangocms_text_ckeditor.fields +import filer.fields.image + + +class Migration(migrations.Migration): + + dependencies = [ + ('filer', '0005_auto_20171015_0703'), + ('cms', '0014_auto_20160404_1908'), + ('ungleich_page', '0011_ungleichproduct_ungleichproductitem'), + ] + + operations = [ + migrations.CreateModel( + name='UngleichCustomer', + fields=[ + ('service_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='ungleich_page.Service')), + ('section_class', models.CharField(blank=True, default='', max_length=100)), + ('carousel_data_interval', models.IntegerField(default=3000)), + ('bottom_text', djangocms_text_ckeditor.fields.HTMLField(default='

    *ungleich means not equal to (≠) U+2260.

    ')), + ], + options={ + 'abstract': False, + }, + bases=('ungleich_page.service',), + ), + migrations.CreateModel( + name='UngleichCustomerItem', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('url', models.URLField(blank=True, default='', max_length=300)), + ('description', djangocms_text_ckeditor.fields.HTMLField()), + ('image', filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='customer_item_image', to='filer.Image')), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + ] diff --git a/ungleich_page/models.py b/ungleich_page/models.py index f936f23b..9024ac28 100644 --- a/ungleich_page/models.py +++ b/ungleich_page/models.py @@ -123,4 +123,24 @@ class UngleichProductItem(ServiceItem): class UngleichProduct(Service): - section_class = models.CharField(max_length=100, default="", blank=True) \ No newline at end of file + section_class = models.CharField(max_length=100, default="", blank=True) + + +class UngleichCustomer(Service): + section_class = models.CharField(max_length=100, default="", blank=True) + carousel_data_interval = models.IntegerField(default=3000) + bottom_text = HTMLField( + default='

    *ungleich means ' + 'not equal to (≠) U+2260.

    ' + ) + + +class UngleichCustomerItem(CMSPlugin): + image = FilerImageField( + null=True, + blank=True, + related_name="customer_item_image", + on_delete=models.SET_NULL + ) + url = models.URLField(max_length=300, default="", blank=True) + description = HTMLField() diff --git a/ungleich_page/templates/ungleich_page/ungleich/_customer_item.html b/ungleich_page/templates/ungleich_page/ungleich/_customer_item.html new file mode 100644 index 00000000..794bcb06 --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/_customer_item.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_customers.html b/ungleich_page/templates/ungleich_page/ungleich/section_customers.html new file mode 100644 index 00000000..afe67b2a --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/section_customers.html @@ -0,0 +1,35 @@ +{% load cms_tags custom_tags %} +
    +
    +
    +

    {{ customer_instance.title }}

    +

    {{ customer_instance.sub_title }}

    +
    +
    +
    + + + +
    +
    +
    +
    + {{customer_instance.bottom_text}} +
    +
    \ No newline at end of file From 0fff040a9be8ab92758dbf097e1bd3ebc2590d66 Mon Sep 17 00:00:00 2001 From: PCoder Date: Thu, 23 Nov 2017 09:46:42 +0100 Subject: [PATCH 0125/1840] Use forloop.counter --- .../templates/ungleich_page/ungleich/section_products.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ungleich_page/templates/ungleich_page/ungleich/section_products.html b/ungleich_page/templates/ungleich_page/ungleich/section_products.html index 8eb2f312..06e6632d 100644 --- a/ungleich_page/templates/ungleich_page/ungleich/section_products.html +++ b/ungleich_page/templates/ungleich_page/ungleich/section_products.html @@ -10,7 +10,7 @@
    {% for plugin in product_instance.child_plugin_instances %} -
    +
    {% render_plugin plugin %}
    {% endfor %} From 7fa23577f62fa788e11772444bebf3f5f56a63b8 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Thu, 23 Nov 2017 11:35:39 +0100 Subject: [PATCH 0126/1840] Change 0005_auto_20171015_0703 dependency to 0004_auto_20160328_1434 --- ungleich_page/migrations/0008_ungleichserviceitem.py | 2 +- .../migrations/0009_ungleichheader_ungleichheaderitem.py | 2 +- .../migrations/0012_ungleichcustomer_ungleichcustomeritem.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ungleich_page/migrations/0008_ungleichserviceitem.py b/ungleich_page/migrations/0008_ungleichserviceitem.py index 3a029110..2037dcf6 100644 --- a/ungleich_page/migrations/0008_ungleichserviceitem.py +++ b/ungleich_page/migrations/0008_ungleichserviceitem.py @@ -10,7 +10,7 @@ import filer.fields.image class Migration(migrations.Migration): dependencies = [ - ('filer', '0005_auto_20171015_0703'), + ('filer', '0004_auto_20160328_1434'), ('ungleich_page', '0007_auto_20171117_1011'), ] diff --git a/ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py b/ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py index 499917a2..2faabe45 100644 --- a/ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py +++ b/ungleich_page/migrations/0009_ungleichheader_ungleichheaderitem.py @@ -11,7 +11,7 @@ import filer.fields.image class Migration(migrations.Migration): dependencies = [ - ('filer', '0005_auto_20171015_0703'), + ('filer', '0004_auto_20160328_1434'), ('cms', '0014_auto_20160404_1908'), ('ungleich_page', '0008_ungleichserviceitem'), ] diff --git a/ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py b/ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py index 148ce241..85b1c203 100644 --- a/ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py +++ b/ungleich_page/migrations/0012_ungleichcustomer_ungleichcustomeritem.py @@ -11,7 +11,7 @@ import filer.fields.image class Migration(migrations.Migration): dependencies = [ - ('filer', '0005_auto_20171015_0703'), + ('filer', '0004_auto_20160328_1434'), ('cms', '0014_auto_20160404_1908'), ('ungleich_page', '0011_ungleichproduct_ungleichproductitem'), ] From 6ec7fc182b4a60fb8d2ff49205347fb3fc260d81 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Thu, 23 Nov 2017 13:02:08 +0100 Subject: [PATCH 0127/1840] Add ungleich HTML only template --- ungleich_page/cms_plugins.py | 17 ++++++++++- .../migrations/0013_ungleichhtmlonly.py | 29 +++++++++++++++++++ ungleich_page/models.py | 4 +++ .../ungleich_page/ungleich/html_block.html | 5 ++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 ungleich_page/migrations/0013_ungleichhtmlonly.py create mode 100644 ungleich_page/templates/ungleich_page/ungleich/html_block.html diff --git a/ungleich_page/cms_plugins.py b/ungleich_page/cms_plugins.py index d7c3c1a6..52762a1b 100644 --- a/ungleich_page/cms_plugins.py +++ b/ungleich_page/cms_plugins.py @@ -5,7 +5,7 @@ from .models import ( UngelichContactUsSection, UngelichTextSection, Service, ServiceItem, About, AboutItem, SectionWithImage, UngleichServiceItem, UngleichHeader, UngleichHeaderItem, UngleichProductItem, UngleichProduct, UngleichCustomer, - UngleichCustomerItem + UngleichCustomerItem, UngleichHTMLOnly ) @@ -274,3 +274,18 @@ class UngleichCustomerItemPlugin(CMSPluginBase): ) context['instance'] = instance return context + + +@plugin_pool.register_plugin +class UngleichHTMLPlugin(CMSPluginBase): + name = "ungleich HTML Plugin" + model = UngleichHTMLOnly + render_template = "ungleich_page/ungleich/html_block.html" + cache = False + + def render(self, context, instance, placeholder): + context = super(UngleichHTMLPlugin, self).render( + context, instance, placeholder + ) + context['instance'] = instance + return context diff --git a/ungleich_page/migrations/0013_ungleichhtmlonly.py b/ungleich_page/migrations/0013_ungleichhtmlonly.py new file mode 100644 index 00000000..c726a5a0 --- /dev/null +++ b/ungleich_page/migrations/0013_ungleichhtmlonly.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-11-23 11:49 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import djangocms_text_ckeditor.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('cms', '0014_auto_20160404_1908'), + ('ungleich_page', '0012_ungleichcustomer_ungleichcustomeritem'), + ] + + operations = [ + migrations.CreateModel( + name='UngleichHTMLOnly', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), + ('HTML', djangocms_text_ckeditor.fields.HTMLField()), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + ] diff --git a/ungleich_page/models.py b/ungleich_page/models.py index 9024ac28..2113b4c0 100644 --- a/ungleich_page/models.py +++ b/ungleich_page/models.py @@ -144,3 +144,7 @@ class UngleichCustomerItem(CMSPlugin): ) url = models.URLField(max_length=300, default="", blank=True) description = HTMLField() + + +class UngleichHTMLOnly(CMSPlugin): + HTML = HTMLField() diff --git a/ungleich_page/templates/ungleich_page/ungleich/html_block.html b/ungleich_page/templates/ungleich_page/ungleich/html_block.html new file mode 100644 index 00000000..65c7b792 --- /dev/null +++ b/ungleich_page/templates/ungleich_page/ungleich/html_block.html @@ -0,0 +1,5 @@ +{% load cms_tags static %} +{{instance.HTML}} +{% for plugin in instance.child_plugin_instances %} + {% render_plugin plugin %} +{% endfor %} From db4362af01a7e6650773fd99619b4d8c2f77a957 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Thu, 23 Nov 2017 14:52:21 +0100 Subject: [PATCH 0128/1840] Remove unused includes in ungleich_cms_page --- .../ungleich_page/ungleich_cms_page.html | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/ungleich_page/templates/ungleich_page/ungleich_cms_page.html b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html index 9f863f1f..763e25c1 100644 --- a/ungleich_page/templates/ungleich_page/ungleich_cms_page.html +++ b/ungleich_page/templates/ungleich_page/ungleich_cms_page.html @@ -89,27 +89,6 @@ {% placeholder 'Ungleich Page Contents' %} - - {% include "ungleich_page/includes/_header.html" %} - - - {% include "ungleich_page/includes/_services.html" %} - - - {% include "ungleich_page/includes/_portfolio.html" %} - - - {% include "ungleich_page/includes/_about.html" %} - - - {% include "ungleich_page/includes/_team.html" %} - - - {% include "ungleich_page/includes/_softwares.html" %} - - - {% include "ungleich_page/includes/_contact_us.html" %} - {% include "ungleich_page/includes/_footer.html" %} From f4b252ff090d3116205392989d1a144192a19268 Mon Sep 17 00:00:00 2001 From: "M.Ravi" Date: Thu, 23 Nov 2017 17:15:19 +0100 Subject: [PATCH 0129/1840] Show carousel indicators only if we have more than 1 item --- .../templates/ungleich_page/ungleich/header.html | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ungleich_page/templates/ungleich_page/ungleich/header.html b/ungleich_page/templates/ungleich_page/ungleich/header.html index 89def4ee..9cf759e6 100644 --- a/ungleich_page/templates/ungleich_page/ungleich/header.html +++ b/ungleich_page/templates/ungleich_page/ungleich/header.html @@ -2,12 +2,13 @@
    @@ -26,8 +25,7 @@

    {% trans "Configuration as a Service" %}

    -

     

    -

    {% trans "Ruby on Rails, Django, Java, Webserver, Mailserver, any infrastructure that needs to configured, we provide comprehensive solutions. Amazon, rackspace or bare metal servers, we configure for you." %}

    +

    {% trans "Ruby on Rails, Django, Java, Webserver, Mailserver, any infrastructure that needs to configured, we provide comprehensive solutions. Amazon, rackspace or bare metal servers, we configure for you." %}

    @@ -36,7 +34,6 @@

    {% trans "Linux System Engineering" %}

    -

     

    {% trans "Let your developers develop! We take care of your system administration. Gentoo, Archlinux, Debian, Ubuntu, and many more." %}

    From 3eebed6245fb48b27180ae0a9f208bfd9ada65c6 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 29 Nov 2017 00:55:13 +0530 Subject: [PATCH 0188/1840] about section heading margin fix --- ungleich_page/static/ungleich_page/css/agency.css | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ungleich_page/static/ungleich_page/css/agency.css b/ungleich_page/static/ungleich_page/css/agency.css index c8687625..eb485f78 100755 --- a/ungleich_page/static/ungleich_page/css/agency.css +++ b/ungleich_page/static/ungleich_page/css/agency.css @@ -560,10 +560,6 @@ section h3.section-subheading { color: inherit; } -.timeline .timeline-heading-last h4 { - margin-top: 15px; -} - .timeline .timeline-heading h4.subheading { text-transform: none; } @@ -631,10 +627,6 @@ section h3.section-subheading { line-height: 26px; } - .timeline .timeline-heading-last h4 { - margin-top: 45px; - } - .timeline>li.timeline-inverted>.timeline-panel { padding: 10px 20px 20px; } From 1d3307043e06235709c009a103ce43f0687e1bad Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 29 Nov 2017 01:30:50 +0530 Subject: [PATCH 0189/1840] mobile text size and alignment fix --- .../static/digitalglarus/css/agency.css | 23 ------ .../static/digitalglarus/css/agency1.css | 23 ------ .../static/ungleich_page/css/agency.css | 82 +++++++++++-------- .../static/ungleich_page/css/ungleich.css | 18 ++-- .../ungleich_page/includes/_contact_us.html | 8 +- .../ungleich_page/includes/_portfolio.html | 12 +-- .../ungleich_page/includes/_services.html | 4 +- 7 files changed, 69 insertions(+), 101 deletions(-) diff --git a/digitalglarus/static/digitalglarus/css/agency.css b/digitalglarus/static/digitalglarus/css/agency.css index 1ce961ba..4ac531c2 100755 --- a/digitalglarus/static/digitalglarus/css/agency.css +++ b/digitalglarus/static/digitalglarus/css/agency.css @@ -964,29 +964,6 @@ section h3.section-comment { 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-small { font-family: 'Montserrat' ,'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif; font-size: 20px; diff --git a/digitalglarus/static/digitalglarus/css/agency1.css b/digitalglarus/static/digitalglarus/css/agency1.css index 40507f78..6178630c 100755 --- a/digitalglarus/static/digitalglarus/css/agency1.css +++ b/digitalglarus/static/digitalglarus/css/agency1.css @@ -960,29 +960,6 @@ section h3.section-comment { 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-small { font-family: 'Montserrat' ,'Raleway', "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif; font-size: 20px; diff --git a/ungleich_page/static/ungleich_page/css/agency.css b/ungleich_page/static/ungleich_page/css/agency.css index eb485f78..e5d30bc0 100755 --- a/ungleich_page/static/ungleich_page/css/agency.css +++ b/ungleich_page/static/ungleich_page/css/agency.css @@ -345,15 +345,15 @@ section { section h2.section-heading { margin-top: 0; margin-bottom: 15px; - font-size: 24px; + font-size: 18px; color: #494949; } section h3.section-subheading { - margin-bottom: 75px; + margin-bottom: 50px; text-transform: none; font-family: 'Raleway', "Helvetica Neue", "Open Sans", "Droid Serif", Helvetica, Arial, sans-serif; - font-size: 18px; + font-size: 16px; font-weight: 400; color: #494949; line-height: 1.4; @@ -366,6 +366,10 @@ section h3.section-subheading { section h2.section-heading { font-size: 40px; } + section h3.section-subheading { + font-size: 18px; + margin-bottom: 75px; + } } .service-heading { @@ -431,7 +435,7 @@ section h3.section-subheading { } #portfolio .portfolio-item .portfolio-caption h4 { - margin: 0 0 20px; + margin: 0 0 17px; text-transform: none; color: #494949; } @@ -450,7 +454,7 @@ section h3.section-subheading { display: inline-block } -@media(min-width:767px) { +@media(min-width:768px) { #portfolio .portfolio-item { margin: 0 0 30px; } @@ -560,6 +564,10 @@ section h3.section-subheading { color: inherit; } +.timeline .timeline-heading h4 { + margin-bottom: 0; +} + .timeline .timeline-heading h4.subheading { text-transform: none; } @@ -657,7 +665,7 @@ section h3.section-subheading { } .team-member { - margin-bottom: 50px; + margin-bottom: 25px; text-align: center; } @@ -667,11 +675,27 @@ section h3.section-subheading { } .team-member h4 { - margin-top: 20px; - margin-bottom: 20px; + margin-top: 10px; + margin-bottom: 10px; text-transform: none; } +@media(max-width:767px) { + .team-member .team-member-caption p { + line-height: 1.5; + } +} + +@media(min-width:768px) { + .team-member { + margin-bottom: 50px; + } + .team-member h4 { + margin-top: 20px; + margin-bottom: 20px; + } +} + .team-member p { margin-top: 0; } @@ -692,6 +716,15 @@ section#contact .section-heading { font-size: 32px; } +@media(max-width:767px) { + section#contact .section-heading { + font-size: 20px; + } + section#contact .intro-smallcap { + font-size: 18px; + } +} + section#contact .form-group { color:white; margin-bottom: 25px; @@ -903,36 +936,15 @@ section h3.section-comment { 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: #fed136; -} - .carousel-indicators li.active, .text-carousel .carousel-indicators li.active { border: 0; background-color: #fed136; } -@media (min-width: 740px) -.carousel-inner, .text-carousel .carousel-inner { - min-height: 225px; + +@media (min-width: 740px) { + .carousel-inner, .text-carousel .carousel-inner { + min-height: 225px; + } } .carousel-text { @@ -943,4 +955,4 @@ logo-image { lign-heignt: 2px; color : #666; text-align : center; -} +} \ No newline at end of file diff --git a/ungleich_page/static/ungleich_page/css/ungleich.css b/ungleich_page/static/ungleich_page/css/ungleich.css index d8c6e8b5..623060b3 100644 --- a/ungleich_page/static/ungleich_page/css/ungleich.css +++ b/ungleich_page/static/ungleich_page/css/ungleich.css @@ -120,15 +120,11 @@ } @media (max-width: 767px) { - .portfolio-item .portfolio-caption p, - section h2.section-heading, - section h3.section-subheading, - #portfolio .portfolio-item .portfolio-caption h4 { - text-align: left; - } - section h2.section-heading, - section h3.section-subheading { + .intro-smallcap.sm_left, + .section-heading.sm_left, + .section-subheading.sm_left { padding-left: 15px; + padding-right: 15px; } } @@ -251,6 +247,12 @@ padding-bottom: 0; } +@media (max-width: 767px) { + .sm_left { + text-align: left !important; + } +} + @media (min-width: 768px) and (max-width: 991px) { .timeline>li .timeline-panel { diff --git a/ungleich_page/templates/ungleich_page/includes/_contact_us.html b/ungleich_page/templates/ungleich_page/includes/_contact_us.html index 6078ae4b..2a2ef246 100644 --- a/ungleich_page/templates/ungleich_page/includes/_contact_us.html +++ b/ungleich_page/templates/ungleich_page/includes/_contact_us.html @@ -12,16 +12,16 @@ {{ message }}
    {% endfor %} -

    {% trans "Contact Us" %}

    -

    +

    {% trans "Contact Us" %}

    +

    {% trans "Join us at" %} {% trans "Digital Glarus" %}, {% trans "a great co-working space in the middle of Alps!" %}
    {% trans "You can contact us at" %}

    -

    +

    info@ungleich.ch

    -

    (044) 534-66-22

    +

    (044) 534-66-22

    diff --git a/ungleich_page/templates/ungleich_page/includes/_portfolio.html b/ungleich_page/templates/ungleich_page/includes/_portfolio.html index b195ead8..db5ce56e 100644 --- a/ungleich_page/templates/ungleich_page/includes/_portfolio.html +++ b/ungleich_page/templates/ungleich_page/includes/_portfolio.html @@ -4,27 +4,27 @@
    -

    {% trans "Our Products" %}

    -

    {% blocktrans %}Our products include an innovative datacenter,
    affordable VM hosting, and high speed fiber internet for canton Glarus.{% endblocktrans %}

    +

    {% trans "Our Products" %}

    +

    {% blocktrans %}Our products include an innovative datacenter,
    affordable VM hosting, and high speed fiber internet for canton Glarus.{% endblocktrans %}

    -
    +

    {% trans "Data Center Light" %}

    -

    {% trans "We offer the most affordable hosting in Switzerland. Data Center Light has full FOSS stack, 100% IPv6 and 100% SSD. Choose any configuration among CentOS, Debian, Ubuntu, Devuan, and FreeBSD." %}

    +

    {% trans "We offer the most affordable hosting in Switzerland. Data Center Light has full FOSS stack, 100% IPv6 and 100% SSD. Choose any configuration among CentOS, Debian, Ubuntu, Devuan, and FreeBSD." %}

    -
    +

    {% trans "Rails Hosting" %}

    {% trans "Ready to go live with your Ruby on Rails application? We offer you ready-to-deploy virtual machines or configure your existing infrastructure for Ruby on Rails." %}

    -
    +

    {% trans "High Speed Internet" %}

    {% trans "We offer high speed fiber internet in Glarus Süd, Glarus and Glarus Nord. Experience 100 Mbit/s and see how speed can change everything." %}

    diff --git a/ungleich_page/templates/ungleich_page/includes/_services.html b/ungleich_page/templates/ungleich_page/includes/_services.html index 37140629..55db52f1 100644 --- a/ungleich_page/templates/ungleich_page/includes/_services.html +++ b/ungleich_page/templates/ungleich_page/includes/_services.html @@ -4,8 +4,8 @@
    -

    {% trans "our services" %}

    -

    +

    {% trans "our services" %}

    +

    {% trans "We support our clients in all areas of Unix infrastructure." %}
    {% trans "Our top notch configuration management is refreshingly simple and reliable." %}

    From bb8195bc0a16e82f4194d36b3be7d6afef81369a Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 29 Nov 2017 02:56:31 +0530 Subject: [PATCH 0190/1840] contact section background, logos width --- .../static/ungleich_page/css/agency.css | 42 +++++++++++++--- .../static/ungleich_page/css/ungleich.css | 22 ++++---- .../ungleich_page/includes/_contact_us.html | 5 +- .../ungleich_page/includes/_portfolio.html | 2 +- .../ungleich_page/includes/_services.html | 2 +- .../ungleich_page/includes/_softwares.html | 50 +++++++++---------- .../ungleich_page/includes/_team.html | 8 +-- 7 files changed, 79 insertions(+), 52 deletions(-) diff --git a/ungleich_page/static/ungleich_page/css/agency.css b/ungleich_page/static/ungleich_page/css/agency.css index e5d30bc0..cccc1de6 100755 --- a/ungleich_page/static/ungleich_page/css/agency.css +++ b/ungleich_page/static/ungleich_page/css/agency.css @@ -13,6 +13,14 @@ body { font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; } +.row-eq-height { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + flex-wrap: wrap; +} + .text-muted { color: #494949; font-family: 'Raleway' , "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; @@ -345,7 +353,7 @@ section { section h2.section-heading { margin-top: 0; margin-bottom: 15px; - font-size: 18px; + font-size: 22px; color: #494949; } @@ -705,10 +713,16 @@ aside.clients img { } section#contact { - background-color: #222; - background-image: url(../img/map-image.png); - background-position: center; - background-repeat: no-repeat; + position: relative; + background: rgba(0,0,0,0.75); +} + +section#contact .bg_img { + filter: blur(1px); +} + +section#contact a { + color: #79bcf7; } section#contact .section-heading { @@ -717,8 +731,11 @@ section#contact .section-heading { } @media(max-width:767px) { + aside.clients img { + margin: 20px auto; + } section#contact .section-heading { - font-size: 20px; + font-size: 24px; } section#contact .intro-smallcap { font-size: 18px; @@ -943,7 +960,7 @@ section h3.section-comment { @media (min-width: 740px) { .carousel-inner, .text-carousel .carousel-inner { - min-height: 225px; + min-height: 225px; } } @@ -952,7 +969,16 @@ section h3.section-comment { font-family:'Raleway' , Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif; font-size : 20px; font-weight : 100; - lign-heignt: 2px; color : #666; text-align : center; +} + +@media (max-width: 767px) { + .carousel-text { + height: 220px; + overflow: scroll; + } + .carousel-author { + height: 72px; + } } \ No newline at end of file diff --git a/ungleich_page/static/ungleich_page/css/ungleich.css b/ungleich_page/static/ungleich_page/css/ungleich.css index 623060b3..6a00c584 100644 --- a/ungleich_page/static/ungleich_page/css/ungleich.css +++ b/ungleich_page/static/ungleich_page/css/ungleich.css @@ -165,17 +165,6 @@ justify-content: flex-end; } -.header_slider > .carousel .bg_img { - position: absolute; - top: 0; - left: 0; - z-index: -1; - width: 100%; - height: 100%; - background-size: cover; - background-position: center; -} - .header_slider .intro-cap { text-align: right; line-height: 1.1; @@ -226,6 +215,17 @@ } } +.bg_img { + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 100%; + background-size: cover; + background-position: center; +} + .timeline>li .timeline-panel { display: flex; flex-direction: column; diff --git a/ungleich_page/templates/ungleich_page/includes/_contact_us.html b/ungleich_page/templates/ungleich_page/includes/_contact_us.html index 2a2ef246..1038f358 100644 --- a/ungleich_page/templates/ungleich_page/includes/_contact_us.html +++ b/ungleich_page/templates/ungleich_page/includes/_contact_us.html @@ -2,6 +2,7 @@ {% load i18n %}
    +
    @@ -12,13 +13,13 @@ {{ message }}
    {% endfor %} -

    {% trans "Contact Us" %}

    +

    {% trans "Contact Us" %}

    {% trans "Join us at" %} {% trans "Digital Glarus" %}, {% trans "a great co-working space in the middle of Alps!" %}
    {% trans "You can contact us at" %}

    - info@ungleich.ch + info@ungleich.ch

    (044) 534-66-22

    diff --git a/ungleich_page/templates/ungleich_page/includes/_portfolio.html b/ungleich_page/templates/ungleich_page/includes/_portfolio.html index db5ce56e..7ea376b1 100644 --- a/ungleich_page/templates/ungleich_page/includes/_portfolio.html +++ b/ungleich_page/templates/ungleich_page/includes/_portfolio.html @@ -4,7 +4,7 @@
    -

    {% trans "Our Products" %}

    +

    {% trans "Our Products" %}

    {% blocktrans %}Our products include an innovative datacenter,
    affordable VM hosting, and high speed fiber internet for canton Glarus.{% endblocktrans %}

    diff --git a/ungleich_page/templates/ungleich_page/includes/_services.html b/ungleich_page/templates/ungleich_page/includes/_services.html index 55db52f1..3f2311f0 100644 --- a/ungleich_page/templates/ungleich_page/includes/_services.html +++ b/ungleich_page/templates/ungleich_page/includes/_services.html @@ -4,7 +4,7 @@
    -

    {% trans "our services" %}

    +

    {% trans "our services" %}

    {% trans "We support our clients in all areas of Unix infrastructure." %}
    {% trans "Our top notch configuration management is refreshingly simple and reliable." %} diff --git a/ungleich_page/templates/ungleich_page/includes/_softwares.html b/ungleich_page/templates/ungleich_page/includes/_softwares.html index b5ece4d8..2af2a3e1 100644 --- a/ungleich_page/templates/ungleich_page/includes/_softwares.html +++ b/ungleich_page/templates/ungleich_page/includes/_softwares.html @@ -2,112 +2,112 @@

  • @@ -60,8 +60,10 @@

    {% trans "ungleich introduces HA-Hosting" %}

    {% trans "and introduces affordable 24X7 support." %}

    -

    {% trans "ungleich launches" %} - {% trans "Digital Glarus project" %}

    +

    + {% trans "ungleich launches" %} + {% trans "Digital Glarus project" %} +

  • From 93d706e97da2a310fda00f2b343c94af32b92dcd Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 1 Dec 2017 20:43:55 +0530 Subject: [PATCH 0205/1840] timleine heading margin bottom fix --- ungleich_page/static/ungleich_page/css/agency.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ungleich_page/static/ungleich_page/css/agency.css b/ungleich_page/static/ungleich_page/css/agency.css index 86d41b2d..1a27a4e1 100755 --- a/ungleich_page/static/ungleich_page/css/agency.css +++ b/ungleich_page/static/ungleich_page/css/agency.css @@ -573,7 +573,7 @@ section h3.section-subheading { } .timeline .timeline-heading h4 { - margin-bottom: 0; + margin-bottom: 7px; } .timeline .timeline-heading h4.subheading { From b2d6874090026c8727ac9f3290a7de4c2023fe7c Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 1 Dec 2017 21:07:00 +0530 Subject: [PATCH 0206/1840] softwares image links style to block --- .../ungleich_page/includes/_softwares.html | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/ungleich_page/templates/ungleich_page/includes/_softwares.html b/ungleich_page/templates/ungleich_page/includes/_softwares.html index e9aee73e..cbbaeb5f 100644 --- a/ungleich_page/templates/ungleich_page/includes/_softwares.html +++ b/ungleich_page/templates/ungleich_page/includes/_softwares.html @@ -4,44 +4,44 @@
    @@ -49,66 +49,66 @@
    From 9c8910a1ffa95d4c4176adae21a77a0ba6d9a632 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 1 Dec 2017 23:23:11 +0530 Subject: [PATCH 0207/1840] row flex removed --- ungleich_page/templates/ungleich_page/includes/_softwares.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ungleich_page/templates/ungleich_page/includes/_softwares.html b/ungleich_page/templates/ungleich_page/includes/_softwares.html index cbbaeb5f..4b24b13f 100644 --- a/ungleich_page/templates/ungleich_page/includes/_softwares.html +++ b/ungleich_page/templates/ungleich_page/includes/_softwares.html @@ -2,7 +2,7 @@