Commit b0f214b30bfca9030005c9b9ecc65d711f3c12b5

Authored by fbormann
2 parents 8e9249aa 1bee2035

Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring

amadeus/static/js/socket.js
@@ -26,9 +26,10 @@ if (socket.readyState == WebSocket.OPEN) socket.onopen(); @@ -26,9 +26,10 @@ if (socket.readyState == WebSocket.OPEN) socket.onopen();
26 26
27 function muralNotificationPost(content) { 27 function muralNotificationPost(content) {
28 var page = window.location.pathname, 28 var page = window.location.pathname,
29 - render = (content.paths.indexOf(page) != -1); 29 + render = (content.paths.indexOf(page) != -1),
  30 + is_resource = (page.indexOf("resource") != -1);
30 31
31 - if ((render && page.indexOf(content.post_type) != -1) || (render && content.post_type == "general")) { 32 + if ((render && page.indexOf(content.post_type) != -1) || (render && content.post_type == "general") || (render && is_resource)) {
32 if (content.accordion) { 33 if (content.accordion) {
33 var section = $(content.container); 34 var section = $(content.container);
34 35
@@ -72,7 +73,7 @@ function muralNotificationPost(content) { @@ -72,7 +73,7 @@ function muralNotificationPost(content) {
72 } 73 }
73 }); 74 });
74 75
75 - if (content.post_type == "subject") { 76 + if (content.post_type == "subjects") {
76 var slug = content.container.substring(1, content.container.length), 77 var slug = content.container.substring(1, content.container.length),
77 subject_mbadge = $("#subject_" + slug).find('.mural_notify'), 78 subject_mbadge = $("#subject_" + slug).find('.mural_notify'),
78 actual = subject_mbadge.text(); 79 actual = subject_mbadge.text();
@@ -136,6 +137,7 @@ function muralNotificationMuralDelete(content) { @@ -136,6 +137,7 @@ function muralNotificationMuralDelete(content) {
136 function muralNotificationComment(content) { 137 function muralNotificationComment(content) {
137 var page = window.location.pathname, 138 var page = window.location.pathname,
138 render = (content.paths.indexOf(page) != -1), 139 render = (content.paths.indexOf(page) != -1),
  140 + is_resource = (page.indexOf("resource") != -1),
139 checker = "general"; 141 checker = "general";
140 142
141 switch (content.post_type) { 143 switch (content.post_type) {
@@ -147,7 +149,7 @@ function muralNotificationComment(content) { @@ -147,7 +149,7 @@ function muralNotificationComment(content) {
147 break; 149 break;
148 } 150 }
149 151
150 - if ((render && page.indexOf(checker) != -1) || (render && content.post_type == "generalpost" && page.indexOf("categories") == -1 && page.indexOf("subjects") == -1)) { 152 + if ((render && page.indexOf(checker) != -1) || (render && content.post_type == "generalpost" && page.indexOf("categories") == -1 && page.indexOf("subjects") == -1) || (render && is_resource)) {
151 var section = $(content.container); 153 var section = $(content.container);
152 154
153 if (section.is(":visible") || section.is(":hidden")) { 155 if (section.is(":visible") || section.is(":hidden")) {
@@ -156,8 +158,6 @@ function muralNotificationComment(content) { @@ -156,8 +158,6 @@ function muralNotificationComment(content) {
156 comments.append(content.complete); 158 comments.append(content.complete);
157 } 159 }
158 } else { 160 } else {
159 - console.log("Lester");  
160 -  
161 $('.mural_badge').each(function () { 161 $('.mural_badge').each(function () {
162 var actual = $(this).text(); 162 var actual = $(this).text();
163 163
mural/forms.py
@@ -77,6 +77,15 @@ class SubjectPostForm(Validation): @@ -77,6 +77,15 @@ class SubjectPostForm(Validation):
77 'post': forms.Textarea 77 'post': forms.Textarea
78 } 78 }
79 79
  80 +class ResourcePostForm(Validation):
  81 + class Meta:
  82 + model = SubjectPost
  83 + fields = ['action', 'post', 'image']
  84 + widgets = {
  85 + 'action': forms.RadioSelect,
  86 + 'post': forms.Textarea
  87 + }
  88 +
80 class CommentForm(forms.ModelForm): 89 class CommentForm(forms.ModelForm):
81 MAX_UPLOAD_SIZE = 5*1024*1024 90 MAX_UPLOAD_SIZE = 5*1024*1024
82 91
mural/templates/mural/resource_view.html 0 → 100644
@@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
  1 +{% extends 'subjects/view.html' %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block breadcrumbs %}
  7 + {{ block.super }}
  8 +
  9 + {% breadcrumb resource.topic 'subjects:topic_view' subject.slug resource.topic.slug %}
  10 + {% breadcrumb resource resource.access_link %}
  11 +
  12 + {% trans 'Mural' as mural %}
  13 + {% breadcrumb mural 'mural:resource_view' resource.slug %}
  14 +{% endblock %}
  15 +
  16 +{% block content %}
  17 + {% subject_permissions request.user subject as has_subject_permissions %}
  18 +
  19 + {% if subject.visible %}
  20 + <div class="panel panel-info topic-panel" id="subject_{{subject.slug}}">
  21 + <div class="panel-heading">
  22 + {% elif has_subject_permissions %}
  23 + <div class="panel panel-info topic-panel-invisible" id="subject_{{subject.slug}}">
  24 + <div class="panel-heading panel-invisible">
  25 + {% endif %}
  26 + <div class="row">
  27 + <div class="col-md-12 category-header">
  28 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  29 + <span>{{ resource }}</span>
  30 + </h4>
  31 +
  32 + <div class="col-md-5 pull-right category-card-items">
  33 + <a href="{% url 'mural:resource_view' resource.slug %}" class="pull-right action_icon">
  34 + <i class="fa fa-list" aria-hidden="true"></i>
  35 + {% resource_mural_number resource request.user %}
  36 + </a>
  37 + </div>
  38 + </div>
  39 + </div>
  40 + </div>
  41 + <div id="{{subject.slug}}" class="panel-collapse panel-body in collapse mural-ungeneral">
  42 + <div class="col-md-12 cards-content mural" data-url="{% url 'mural:resource_view' resource.slug %}" data-pages="{{ paginator.num_pages }}" data-page="{{ page_obj.number }}" data-fav="{{ favorites }}" data-mine="{{ mines }}">
  43 + <div class="col-md-9 col-sm-9 col-xs-9 mural-list">
  44 + <div class="post_make panel panel-default">
  45 + <div class="panel-body">
  46 + <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 user-img text-center">
  47 + <img src="{{ request.user.image_url }}" class="img-responsive" />
  48 + </div>
  49 + <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 post-field">
  50 + <div>
  51 + <h4 data-url="{% url 'mural:create_resource' subject.slug resource.slug %}">{% trans 'Wish to make a new post?' %}</h4>
  52 + </div>
  53 + </div>
  54 + </div>
  55 + </div>
  56 +
  57 + <div class="posts">
  58 + {% for post in posts %}
  59 + {% include 'mural/_view.html' %}
  60 + {% endfor %}
  61 + </div>
  62 + <div id="loading_posts" class="alert alert-success" role="alert" style="display:none">
  63 + <center>
  64 + <span class="fa fa-spin fa-circle-o-notch"></span>
  65 + </center>
  66 + </div>
  67 + <div class="text-center no-subjects" {% if posts.count > 0 %} style="display:none" {% endif %}>
  68 + <i class="fa fa-list"></i>
  69 + <h4>{% trans 'There are no posts in this mural yet.' %}</h4>
  70 + </div>
  71 + </div>
  72 + <div class="col-md-3 col-sm-3 col-xs-3 post-filter">
  73 + <h4>{% trans 'Filter' %}</h4>
  74 +
  75 + <form id="post-filters" action="" method="GET">
  76 + <div class="checkbox">
  77 + <label>
  78 + <input name="favorite" type="checkbox" {{ favorites }}> {% trans 'Favorite posts' %} <i class="fa fa-thumb-tack"></i>
  79 + </label>
  80 + </div>
  81 + <div class="checkbox">
  82 + <label>
  83 + <input name="mine" type="checkbox" {{ mines }}> {% trans 'Only my posts' %}
  84 + </label>
  85 + </div>
  86 + <button type="submit" class="btn btn-success btn-raised btn-block">{% trans 'Filter' %}</button>
  87 + <button type="button" id="clear_filter" class="btn btn-default btn-raised btn-block clear_filter">{% trans 'Clean Filters' %}</button>
  88 + </form>
  89 + </div>
  90 + </div>
  91 + </div>
  92 + </div>
  93 +
  94 + <div class="modal fade" id="post-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  95 +
  96 + <script type="text/javascript" src="{% static 'js/mural.js' %}"></script>
  97 + <script type="text/javascript" src="{% static 'js/mural_general.js' %}"></script>
  98 +{% endblock %}
0 \ No newline at end of file 99 \ No newline at end of file
mural/templatetags/mural_filters.py
@@ -66,14 +66,14 @@ def show_settings(post, user): @@ -66,14 +66,14 @@ def show_settings(post, user):
66 return True 66 return True
67 67
68 if post._my_subclass == "categorypost": 68 if post._my_subclass == "categorypost":
69 - if post.categorypost.space.coordinators == user: 69 + if user in post.categorypost.space.coordinators.all():
70 return True 70 return True
71 71
72 if post._my_subclass == "subjectpost": 72 if post._my_subclass == "subjectpost":
73 - if post.subjectpost.space.professor == user: 73 + if user in post.subjectpost.space.professor.all():
74 return True 74 return True
75 75
76 - if post.subjectpost.space.category.coordinators == user: 76 + if user in post.subjectpost.space.category.coordinators.all():
77 return True 77 return True
78 78
79 return False 79 return False
@@ -87,14 +87,14 @@ def show_settings_comment(comment, user): @@ -87,14 +87,14 @@ def show_settings_comment(comment, user):
87 return True 87 return True
88 88
89 if comment.post._my_subclass == "categorypost": 89 if comment.post._my_subclass == "categorypost":
90 - if comment.post.categorypost.space.coordinators == user: 90 + if user in comment.post.categorypost.space.coordinators.all():
91 return True 91 return True
92 92
93 if comment.post._my_subclass == "subjectpost": 93 if comment.post._my_subclass == "subjectpost":
94 - if comment.post.subjectpost.space.professor == user: 94 + if user in comment.post.subjectpost.space.professor.all():
95 return True 95 return True
96 96
97 - if comment.post.subjectpost.space.category.coordinators == user: 97 + if user in comment.post.subjectpost.space.category.coordinators.all():
98 return True 98 return True
99 99
100 return False 100 return False
@@ -8,6 +8,7 @@ urlpatterns = [ @@ -8,6 +8,7 @@ urlpatterns = [
8 url(r'^create_gen/$', views.GeneralCreate.as_view(), name='create_general'), 8 url(r'^create_gen/$', views.GeneralCreate.as_view(), name='create_general'),
9 url(r'^create_cat/(?P<slug>[\w_-]+)/$', views.CategoryCreate.as_view(), name='create_category'), 9 url(r'^create_cat/(?P<slug>[\w_-]+)/$', views.CategoryCreate.as_view(), name='create_category'),
10 url(r'^create_sub/(?P<slug>[\w_-]+)/$', views.SubjectCreate.as_view(), name='create_subject'), 10 url(r'^create_sub/(?P<slug>[\w_-]+)/$', views.SubjectCreate.as_view(), name='create_subject'),
  11 + url(r'^create_res/(?P<slug>[\w_-]+)/(?P<rslug>[\w_-]+)/$', views.ResourceCreate.as_view(), name='create_resource'),
11 url(r'^update_gen/(?P<pk>[\w_-]+)/$', views.GeneralUpdate.as_view(), name='update_general'), 12 url(r'^update_gen/(?P<pk>[\w_-]+)/$', views.GeneralUpdate.as_view(), name='update_general'),
12 url(r'^update_cat/(?P<pk>[\w_-]+)/$', views.CategoryUpdate.as_view(), name='update_category'), 13 url(r'^update_cat/(?P<pk>[\w_-]+)/$', views.CategoryUpdate.as_view(), name='update_category'),
13 url(r'^update_sub/(?P<pk>[\w_-]+)/$', views.SubjectUpdate.as_view(), name='update_subject'), 14 url(r'^update_sub/(?P<pk>[\w_-]+)/$', views.SubjectUpdate.as_view(), name='update_subject'),
@@ -15,6 +16,7 @@ urlpatterns = [ @@ -15,6 +16,7 @@ urlpatterns = [
15 url(r'^delete_cat/(?P<pk>[\w_-]+)/$', views.CategoryDelete.as_view(), name='delete_category'), 16 url(r'^delete_cat/(?P<pk>[\w_-]+)/$', views.CategoryDelete.as_view(), name='delete_category'),
16 url(r'^delete_sub/(?P<pk>[\w_-]+)/$', views.SubjectDelete.as_view(), name='delete_subject'), 17 url(r'^delete_sub/(?P<pk>[\w_-]+)/$', views.SubjectDelete.as_view(), name='delete_subject'),
17 url(r'^subject/(?P<slug>[\w_-]+)/$', views.SubjectView.as_view(), name='subject_view'), 18 url(r'^subject/(?P<slug>[\w_-]+)/$', views.SubjectView.as_view(), name='subject_view'),
  19 + url(r'^resource/(?P<slug>[\w_-]+)/$', views.ResourceView.as_view(), name='resource_view'),
18 url(r'^load_category/([\w_-]+)/$', views.load_category_posts, name='load_category'), 20 url(r'^load_category/([\w_-]+)/$', views.load_category_posts, name='load_category'),
19 url(r'^load_subject/([\w_-]+)/$', views.load_subject_posts, name='load_subject'), 21 url(r'^load_subject/([\w_-]+)/$', views.load_subject_posts, name='load_subject'),
20 url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'), 22 url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'),
mural/views.py
@@ -16,12 +16,15 @@ import json @@ -16,12 +16,15 @@ import json
16 16
17 from categories.models import Category 17 from categories.models import Category
18 from subjects.models import Subject 18 from subjects.models import Subject
  19 +from topics.models import Resource
19 from users.models import User 20 from users.models import User
20 21
21 from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites, Comment 22 from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites, Comment
22 -from .forms import GeneralPostForm, CategoryPostForm, SubjectPostForm, CommentForm 23 +from .forms import GeneralPostForm, CategoryPostForm, SubjectPostForm, ResourcePostForm, CommentForm
23 from .utils import getSpaceUsers 24 from .utils import getSpaceUsers
24 25
  26 +from amadeus.permissions import has_subject_view_permissions, has_resource_permissions
  27 +
25 """ 28 """
26 Section for GeneralPost classes 29 Section for GeneralPost classes
27 """ 30 """
@@ -594,7 +597,13 @@ class SubjectCreate(LoginRequiredMixin, generic.edit.CreateView): @@ -594,7 +597,13 @@ class SubjectCreate(LoginRequiredMixin, generic.edit.CreateView):
594 users = getSpaceUsers(self.request.user.id, self.object) 597 users = getSpaceUsers(self.request.user.id, self.object)
595 entries = [] 598 entries = []
596 599
597 - paths = [reverse("mural:manage_subject")] 600 + paths = [
  601 + reverse("mural:manage_subject"),
  602 + reverse("mural:subject_view", args = (), kwargs = {'slug': self.object.space.slug})
  603 + ]
  604 +
  605 + if self.object.resource:
  606 + paths.append(reverse("mural:resource_view", args = (), kwargs = {'slug': self.object.resource.slug}))
598 607
599 notification = { 608 notification = {
600 "type": "mural", 609 "type": "mural",
@@ -643,6 +652,13 @@ class SubjectUpdate(LoginRequiredMixin, generic.UpdateView): @@ -643,6 +652,13 @@ class SubjectUpdate(LoginRequiredMixin, generic.UpdateView):
643 652
644 return initial 653 return initial
645 654
  655 + def get_form_class(self):
  656 + if self.object.resource:
  657 + if "resource" in self.request.META.get('HTTP_REFERER'):
  658 + self.form_class = ResourcePostForm
  659 +
  660 + return self.form_class
  661 +
646 def form_invalid(self, form): 662 def form_invalid(self, form):
647 context = super(SubjectUpdate, self).form_invalid(form) 663 context = super(SubjectUpdate, self).form_invalid(form)
648 context.status_code = 400 664 context.status_code = 400
@@ -658,7 +674,13 @@ class SubjectUpdate(LoginRequiredMixin, generic.UpdateView): @@ -658,7 +674,13 @@ class SubjectUpdate(LoginRequiredMixin, generic.UpdateView):
658 674
659 users = getSpaceUsers(self.request.user.id, self.object) 675 users = getSpaceUsers(self.request.user.id, self.object)
660 676
661 - paths = [reverse("mural:manage_subject")] 677 + paths = [
  678 + reverse("mural:manage_subject"),
  679 + reverse("mural:subject_view", args = (), kwargs = {'slug': self.object.space.slug})
  680 + ]
  681 +
  682 + if self.object.resource:
  683 + paths.append(reverse("mural:resource_view", args = (), kwargs = {'slug': self.object.resource.slug}))
662 684
663 notification = { 685 notification = {
664 "type": "mural", 686 "type": "mural",
@@ -703,7 +725,13 @@ class SubjectDelete(LoginRequiredMixin, generic.DeleteView): @@ -703,7 +725,13 @@ class SubjectDelete(LoginRequiredMixin, generic.DeleteView):
703 def get_success_url(self): 725 def get_success_url(self):
704 users = getSpaceUsers(self.request.user.id, self.object) 726 users = getSpaceUsers(self.request.user.id, self.object)
705 727
706 - paths = [reverse("mural:manage_subject")] 728 + paths = [
  729 + reverse("mural:manage_subject"),
  730 + reverse("mural:subject_view", args = (), kwargs = {'slug': self.object.space.slug})
  731 + ]
  732 +
  733 + if self.object.resource:
  734 + paths.append(reverse("mural:resource_view", args = (), kwargs = {'slug': self.object.resource.slug}))
707 735
708 notification = { 736 notification = {
709 "type": "mural", 737 "type": "mural",
@@ -727,6 +755,14 @@ class SubjectView(LoginRequiredMixin, generic.ListView): @@ -727,6 +755,14 @@ class SubjectView(LoginRequiredMixin, generic.ListView):
727 context_object_name = "posts" 755 context_object_name = "posts"
728 paginate_by = 10 756 paginate_by = 10
729 757
  758 + def dispatch(self, request, *args,**kwargs):
  759 + subject = get_object_or_404(Subject, slug = kwargs.get('slug', ''))
  760 +
  761 + if not has_subject_view_permissions(request.user, subject):
  762 + return redirect(reverse_lazy('subjects:home'))
  763 +
  764 + return super(SubjectView, self).dispatch(request, *args, **kwargs)
  765 +
730 def get_queryset(self): 766 def get_queryset(self):
731 user = self.request.user 767 user = self.request.user
732 favorites = self.request.GET.get('favorite', False) 768 favorites = self.request.GET.get('favorite', False)
@@ -785,6 +821,155 @@ class SubjectView(LoginRequiredMixin, generic.ListView): @@ -785,6 +821,155 @@ class SubjectView(LoginRequiredMixin, generic.ListView):
785 return context 821 return context
786 822
787 """ 823 """
  824 + Section for specific resource post classes
  825 +"""
  826 +class ResourceView(LoginRequiredMixin, generic.ListView):
  827 + login_url = reverse_lazy("users:login")
  828 + redirect_field_name = 'next'
  829 +
  830 + template_name = 'mural/resource_view.html'
  831 + context_object_name = "posts"
  832 + paginate_by = 10
  833 +
  834 + def dispatch(self, request, *args, **kwargs):
  835 + slug = self.kwargs.get('slug', '')
  836 + resource = get_object_or_404(Resource, slug = slug)
  837 +
  838 + if not has_resource_permissions(request.user, resource):
  839 + return redirect(reverse_lazy('subjects:home'))
  840 +
  841 + return super(ResourceView, self).dispatch(request, *args, **kwargs)
  842 +
  843 + def get_queryset(self):
  844 + user = self.request.user
  845 + favorites = self.request.GET.get('favorite', False)
  846 + mines = self.request.GET.get('mine', False)
  847 + showing = self.request.GET.get('showing', False)
  848 + page = self.request.GET.get('page', False)
  849 + slug = self.kwargs.get('slug')
  850 + resource = get_object_or_404(Resource, slug = slug)
  851 +
  852 + if not favorites:
  853 + if mines:
  854 + posts = SubjectPost.objects.extra(select = {"most_recent": "greatest(last_update, (select max(mural_comment.last_update) from mural_comment where mural_comment.post_id = mural_subjectpost.mural_ptr_id))"}).filter(mural_ptr__user = user, resource = resource)
  855 + else:
  856 + posts = SubjectPost.objects.extra(select = {"most_recent": "greatest(last_update, (select max(mural_comment.last_update) from mural_comment where mural_comment.post_id = mural_subjectpost.mural_ptr_id))"}).filter(resource = resource)
  857 + else:
  858 + if mines:
  859 + posts = SubjectPost.objects.extra(select = {"most_recent": "greatest(last_update, (select max(mural_comment.last_update) from mural_comment where mural_comment.post_id = mural_subjectpost.mural_ptr_id))"}).filter(favorites_post__isnull = False, favorites_post__user = user, mural_ptr__user = user, resource = resource)
  860 + else:
  861 + posts = SubjectPost.objects.extra(select = {"most_recent": "greatest(last_update, (select max(mural_comment.last_update) from mural_comment where mural_comment.post_id = mural_subjectpost.mural_ptr_id))"}).filter(favorites_post__isnull = False, favorites_post__user = user, resource = resource)
  862 +
  863 + if showing: #Exclude ajax creation posts results
  864 + showing = showing.split(',')
  865 + posts = posts.exclude(id__in = showing)
  866 +
  867 + if not page: #Don't need this if is pagination
  868 + MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__subjectpost__resource = resource) | Q(comment__post__subjectpost__resource = resource))).update(viewed = True)
  869 +
  870 + return posts.order_by("-most_recent")
  871 +
  872 + def get_context_data(self, **kwargs):
  873 + context = super(ResourceView, self).get_context_data(**kwargs)
  874 +
  875 + page = self.request.GET.get('page', '')
  876 +
  877 + slug = self.kwargs.get('slug', None)
  878 + resource = get_object_or_404(Resource, slug = slug)
  879 +
  880 + if page:
  881 + self.template_name = "mural/_list_view.html"
  882 +
  883 + context['title'] = _('%s - Mural')%(str(resource))
  884 + context['subject'] = resource.topic.subject
  885 + context['resource'] = resource
  886 + context['favorites'] = ""
  887 + context['mines'] = ""
  888 +
  889 + favs = self.request.GET.get('favorite', False)
  890 +
  891 + if favs:
  892 + context['favorites'] = "checked"
  893 +
  894 + mines = self.request.GET.get('mine', False)
  895 +
  896 + if mines:
  897 + context['mines'] = "checked"
  898 +
  899 + return context
  900 +
  901 +class ResourceCreate(LoginRequiredMixin, generic.edit.CreateView):
  902 + login_url = reverse_lazy("users:login")
  903 + redirect_field_name = 'next'
  904 +
  905 + template_name = 'mural/_form.html'
  906 + form_class = ResourcePostForm
  907 +
  908 + def form_invalid(self, form):
  909 + context = super(SubjectCreate, self).form_invalid(form)
  910 + context.status_code = 400
  911 +
  912 + return context
  913 +
  914 + def form_valid(self, form):
  915 + self.object = form.save(commit = False)
  916 +
  917 + slug = self.kwargs.get('slug', None)
  918 + sub = get_object_or_404(Subject, slug = slug)
  919 +
  920 + rslug = self.kwargs.get('rslug', None)
  921 + resource = get_object_or_404(Resource, slug = rslug)
  922 +
  923 + self.object.space = sub
  924 + self.object.resource = resource
  925 + self.object.user = self.request.user
  926 +
  927 + self.object.save()
  928 +
  929 + users = getSpaceUsers(self.request.user.id, self.object)
  930 + entries = []
  931 +
  932 + paths = [
  933 + reverse("mural:manage_subject"),
  934 + reverse("mural:subject_view", args = (), kwargs = {'slug': self.object.space.slug})
  935 + ]
  936 +
  937 + if self.object.resource:
  938 + paths.append(reverse("mural:resource_view", args = (), kwargs = {'slug': self.object.resource.slug}))
  939 +
  940 + notification = {
  941 + "type": "mural",
  942 + "subtype": "post",
  943 + "paths": paths,
  944 + "user_icon": self.object.user.image_url,
  945 + "simple_notify": _("%s has made a post in %s")%(str(self.object.user), str(self.object.space)),
  946 + "complete": render_to_string("mural/_view.html", {"post": self.object}, self.request),
  947 + "container": "#" + slug,
  948 + "accordion": True,
  949 + "post_type": "subjects"
  950 + }
  951 +
  952 + notification = json.dumps(notification)
  953 +
  954 + for user in users:
  955 + entries.append(MuralVisualizations(viewed = False, user = user, post = self.object))
  956 + Group("user-%s" % user.id).send({'text': notification})
  957 +
  958 + MuralVisualizations.objects.bulk_create(entries)
  959 +
  960 + return super(ResourceCreate, self).form_valid(form)
  961 +
  962 + def get_context_data(self, *args, **kwargs):
  963 + context = super(ResourceCreate, self).get_context_data(*args, **kwargs)
  964 +
  965 + context['form_url'] = reverse_lazy("mural:create_resource", args = (), kwargs = {'slug': self.kwargs.get('slug', None), 'rslug': self.kwargs.get('rslug', None)})
  966 +
  967 + return context
  968 +
  969 + def get_success_url(self):
  970 + return reverse_lazy('mural:render_post', args = (self.object.id, 'create', 'sub', ))
  971 +
  972 +"""
788 Section for common post functions 973 Section for common post functions
789 """ 974 """
790 def render_post(request, post, msg, ptype): 975 def render_post(request, post, msg, ptype):
@@ -862,6 +1047,12 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView): @@ -862,6 +1047,12 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView):
862 reverse("mural:manage_subject") 1047 reverse("mural:manage_subject")
863 ] 1048 ]
864 1049
  1050 + if post._my_subclass == "subjectpost":
  1051 + paths.append(reverse("mural:subject_view", args = (), kwargs = {'slug': post.get_space_slug()}))
  1052 +
  1053 + if post.subjectpost.resource:
  1054 + paths.append(reverse("mural:resource_view", args = (), kwargs = {'slug': post.subjectpost.resource.slug}))
  1055 +
865 notification = { 1056 notification = {
866 "type": "mural", 1057 "type": "mural",
867 "subtype": "comment", 1058 "subtype": "comment",
@@ -925,6 +1116,12 @@ class CommentUpdate(LoginRequiredMixin, generic.UpdateView): @@ -925,6 +1116,12 @@ class CommentUpdate(LoginRequiredMixin, generic.UpdateView):
925 reverse("mural:manage_subject") 1116 reverse("mural:manage_subject")
926 ] 1117 ]
927 1118
  1119 + if self.object.post._my_subclass == "subjectpost":
  1120 + paths.append(reverse("mural:subject_view", args = (), kwargs = {'slug': self.object.post.get_space_slug()}))
  1121 +
  1122 + if self.object.post.subjectpost.resource:
  1123 + paths.append(reverse("mural:resource_view", args = (), kwargs = {'slug': self.object.post.subjectpost.resource.slug}))
  1124 +
928 notification = { 1125 notification = {
929 "type": "mural", 1126 "type": "mural",
930 "subtype": "mural_update", 1127 "subtype": "mural_update",
@@ -974,6 +1171,12 @@ class CommentDelete(LoginRequiredMixin, generic.DeleteView): @@ -974,6 +1171,12 @@ class CommentDelete(LoginRequiredMixin, generic.DeleteView):
974 reverse("mural:manage_subject") 1171 reverse("mural:manage_subject")
975 ] 1172 ]
976 1173
  1174 + if self.object.post._my_subclass == "subjectpost":
  1175 + paths.append(reverse("mural:subject_view", args = (), kwargs = {'slug': self.object.post.get_space_slug()}))
  1176 +
  1177 + if self.object.post.subjectpost.resource:
  1178 + paths.append(reverse("mural:resource_view", args = (), kwargs = {'slug': self.object.post.subjectpost.resource.slug}))
  1179 +
977 notification = { 1180 notification = {
978 "type": "mural", 1181 "type": "mural",
979 "subtype": "mural_delete", 1182 "subtype": "mural_delete",
pdf_file/templates/pdf_file/view.html
1 {% extends "subjects/view.html" %} 1 {% extends "subjects/view.html" %}
2 2
3 -{% load static i18n django_bootstrap_breadcrumbs %} 3 +{% load static i18n django_bootstrap_breadcrumbs permissions_tags subject_counter %}
4 4
5 {% block style %} 5 {% block style %}
6 {{block.super}} 6 {{block.super}}
@@ -24,6 +24,8 @@ @@ -24,6 +24,8 @@
24 24
25 25
26 {% block content %} 26 {% block content %}
  27 + {% subject_permissions request.user subject as has_subject_permissions %}
  28 +
27 {% if subject.visible %} 29 {% if subject.visible %}
28 <div class="panel panel-info topic-panel"> 30 <div class="panel panel-info topic-panel">
29 <div class="panel-heading"> 31 <div class="panel-heading">
@@ -38,7 +40,10 @@ @@ -38,7 +40,10 @@
38 </h4> 40 </h4>
39 41
40 <div class="col-md-5 pull-right category-card-items"> 42 <div class="col-md-5 pull-right category-card-items">
41 - <a href="" ><i class="fa fa-list" aria-hidden="true"></i></a> 43 + <a href="{% url 'mural:resource_view' pdf_file.slug %}" class="pull-right action_icon">
  44 + <i class="fa fa-list" aria-hidden="true"></i>
  45 + {% resource_mural_number pdf_file request.user %}
  46 + </a>
42 </div> 47 </div>
43 </div> 48 </div>
44 </div> 49 </div>
webpage/templates/webpages/view.html
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 </h4> 41 </h4>
42 42
43 <div class="col-md-5 pull-right category-card-items"> 43 <div class="col-md-5 pull-right category-card-items">
44 - <a href="" > 44 + <a href="{% url 'mural:resource_view' webpage.slug %}" class="pull-right action_icon">
45 <i class="fa fa-list" aria-hidden="true"></i> 45 <i class="fa fa-list" aria-hidden="true"></i>
46 {% resource_mural_number webpage request.user %} 46 {% resource_mural_number webpage request.user %}
47 </a> 47 </a>
youtube_video/templates/youtube/view.html
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 </h4> 41 </h4>
42 42
43 <div class="col-md-5 pull-right category-card-items"> 43 <div class="col-md-5 pull-right category-card-items">
44 - <a href=""> 44 + <a href="{% url 'mural:resource_view' youtube.slug %}" class="pull-right action_icon">
45 <i class="fa fa-list" aria-hidden="true"></i> 45 <i class="fa fa-list" aria-hidden="true"></i>
46 {% resource_mural_number youtube request.user %} 46 {% resource_mural_number youtube request.user %}
47 </a> 47 </a>