diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index db2912bd..ab2d6763 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -54,6 +54,7 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'easy_thumbnails', 'utils', + 'stored_messages', 'mptt', 'parler', 'taggit', diff --git a/hosting/models.py b/hosting/models.py index ef33c056..518ba175 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -3,12 +3,13 @@ import os from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils.functional import cached_property -from membership.models import StripeCustomer -from utils.models import BillingAddress + from Crypto.PublicKey import RSA +from stored_messages.settings import stored_messages_settings - +from membership.models import StripeCustomer +from utils.models import BillingAddress from .managers import VMPlansManager @@ -118,6 +119,13 @@ class VirtualMachinePlan(models.Model): name = 'vm-%s' % self.id return name + @cached_property + def notifications(self): + stripe_customer = StripeCustomer.objects.get(hostingorder__vm_plan=self) + backend = stored_messages_settings.STORAGE_BACKEND() + messages = backend.inbox_list(stripe_customer.user) + return messages + @classmethod def create(cls, data, user): instance = cls.objects.create(**data) diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index 874b590f..55466815 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -71,7 +71,11 @@ <i class="fa fa-credit-card"></i> My Orders </a> </li> - + <li> + <a href="{% url 'hosting:notifications' %}"> + <i class="fa fa-bell"></i> Notifications + </a> + </li> <li class="dropdown"> <a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#"> <i class="glyphicon glyphicon-user"></i> {{request.user.name}} <span class="caret"></span></a> diff --git a/hosting/templates/hosting/notifications.html b/hosting/templates/hosting/notifications.html new file mode 100644 index 00000000..959dfe4f --- /dev/null +++ b/hosting/templates/hosting/notifications.html @@ -0,0 +1,90 @@ +{% extends "hosting/base_short.html" %} +{% load staticfiles bootstrap3 %} +{% block content %} +<div> + <div class="container virtual-machine-container dashboard-container "> + <div class="row"> + <div class="col-md-9 col-md-offset-2"> + <div class="col-sm-12"> + <h3><i class="fa fa-bell" aria-hidden="true"></i> Notifications</h3> + <hr/> + <div class="col-md-3"> <!-- required for floating --> + <!-- Nav tabs --> + <ul class="nav nav-tabs tabs-left sideways"> + <li class="active"> + <a href="#unread-v" data-toggle="tab"> + Unread <span class="badge">{{unread_notifications|length}}</span> + </a> + </li> + <li> + <a href="#all-v" data-toggle="tab"> + All + </a> + </li> + </ul> + </div> + + <div class="col-md-9"> + <!-- Tab panes --> + <div class="tab-content"> + <div class="tab-pane active" id="unread-v"> + <div class="row"> + <div class="col-md-12"> + <h3>Unread notifications</h3> + <hr> + </div> + </div> + <div class="row"> + <div class="col-md-12"> + {% for notification in unread_notifications %} + <form method="POST" action="{% url 'hosting:read_notification' notification.id %}"> + {% csrf_token %} + <span>{{notification}} -</span> + <button type="submit" class="btn btn-link">Mark as read</button> + <span class="pull-right" style="font-size: 11px;color: #999;">{{notification.date}}</span> + </form> + <hr/> + {% endfor %} + </div><!--/col-12--> + </div><!--/row--> + </div> + <div class="tab-pane" id="all-v"> + <div class="row"> + <div class="col-md-12"> + <h3>All notifications</h3> + <hr> + {% for notification in all_notifications %} + <span>{{notification.message}} </span> + <span class="pull-right" style="font-size: 11px;color: #999;">{{notification.message.date}}</span> + <hr/> + {% endfor %} + </div> + </div> + <div class="row"> + <div class="col-md-12"> + </div><!--/col-12--> + </div><!--/row--> + </div> + + </div> + </div> + + <div class="clearfix"></div> + </div> + </div> + + </div> + </div> + +</div> + +{%endblock%} + + + + + + + + + diff --git a/hosting/urls.py b/hosting/urls.py index 702f2b30..bc72a636 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -1,9 +1,10 @@ from django.conf.urls import url -from .views import DjangoHostingView, RailsHostingView, PaymentVMView, \ +from .views import DjangoHostingView, RailsHostingView, PaymentVMView,\ NodeJSHostingView, LoginView, SignupView, IndexView, \ OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\ - VirtualMachineDetailView, GenerateVMSSHKeysView, OrdersHostingDeleteView + VirtualMachineDetailView, GenerateVMSSHKeysView, OrdersHostingDeleteView, NotificationsView, \ + MarkAsReadNotificationView urlpatterns = [ # url(r'pricing/?$', VMPricingView.as_view(), name='pricing'), @@ -20,6 +21,9 @@ urlpatterns = [ name='virtual_machines'), url(r'my-virtual-machines/(?P<pk>\d+)/key/?$', GenerateVMSSHKeysView.as_view(), name='virtual_machine_key'), + url(r'^notifications/$', NotificationsView.as_view(), name='notifications'), + url(r'^notifications/(?P<pk>\d+)/?$', MarkAsReadNotificationView.as_view(), + name='read_notification'), url(r'login/?$', LoginView.as_view(), name='login'), url(r'signup/?$', SignupView.as_view(), name='signup'), url(r'^logout/?$', 'django.contrib.auth.views.logout', diff --git a/hosting/views.py b/hosting/views.py index 60733274..bb4b5b1e 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -2,12 +2,17 @@ from django.shortcuts import get_object_or_404, render,render_to_response from django.core.urlresolvers import reverse_lazy, reverse from django.contrib.auth.mixins import LoginRequiredMixin - -from django.views.generic import View, CreateView, FormView, ListView, DetailView, UpdateView, DeleteView -from django.http import HttpResponseRedirect, HttpResponse +from django.views.generic import View, CreateView, FormView, ListView, DetailView,\ + DeleteView, TemplateView, UpdateView +from django.http import HttpResponseRedirect from django.contrib.auth import authenticate, login from django.conf import settings -from django.contrib import messages + + +from stored_messages.settings import stored_messages_settings +from stored_messages.models import Message +from stored_messages.api import mark_read + from membership.models import CustomUser, StripeCustomer from utils.stripe_utils import StripeUtils @@ -145,6 +150,34 @@ class SignupView(CreateView): return HttpResponseRedirect(self.get_success_url()) +class NotificationsView(TemplateView): + template_name = 'hosting/notifications.html' + + def get_context_data(self, **kwargs): + context = super(NotificationsView, self).get_context_data(**kwargs) + backend = stored_messages_settings.STORAGE_BACKEND() + unread_notifications = backend.inbox_list(self.request.user) + read_notifications = backend.archive_list(self.request.user) + context.update({ + 'unread_notifications': unread_notifications, + 'all_notifications': read_notifications + unread_notifications + }) + return context + + +class MarkAsReadNotificationView(LoginRequiredMixin, UpdateView): + model = Message + success_url = reverse_lazy('hosting:notifications') + fields = '__all__' + + def post(self, *args, **kwargs): + message = self.get_object() + backend = stored_messages_settings.STORAGE_BACKEND() + backend.archive_store([self.request.user], message) + mark_read(self.request.user, message) + return HttpResponseRedirect(reverse('hosting:notifications')) + + class GenerateVMSSHKeysView(LoginRequiredMixin, DetailView): model = VirtualMachinePlan template_name = 'hosting/virtual_machine_key.html' @@ -278,10 +311,11 @@ class OrdersHostingListView(LoginRequiredMixin, ListView): class OrdersHostingDeleteView(LoginRequiredMixin, DeleteView): - login_url=reverse_lazy('hosting:login') + login_url = reverse_lazy('hosting:login') success_url = reverse_lazy('hosting:orders') model = HostingOrder + class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): template_name = "hosting/virtual_machines.html" login_url = reverse_lazy('hosting:login') diff --git a/requirements.txt b/requirements.txt index dcf2b02b..4bd93ee0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,7 @@ easy_thumbnails django-polymorphic model-mommy pycryptodome +django-stored-messages #PLUGINS djangocms_flash