From a846f42bf6050ba80e7087ccfd0b62c20431319a Mon Sep 17 00:00:00 2001
From: Levi <levinoelvm@gmail.com>
Date: Sun, 29 May 2016 13:37:43 -0500
Subject: [PATCH] Added mark a notification as read feature, Fixed some errors

---
 dynamicweb/settings/base.py                  |  1 +
 hosting/models.py                            | 14 ++-
 hosting/templates/hosting/base_short.html    |  6 +-
 hosting/templates/hosting/notifications.html | 90 ++++++++++++++++++++
 hosting/urls.py                              |  8 +-
 hosting/views.py                             | 44 ++++++++--
 requirements.txt                             |  1 +
 7 files changed, 153 insertions(+), 11 deletions(-)
 create mode 100644 hosting/templates/hosting/notifications.html

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