From 7cc0ac9c9f8b70973071901240002e1cd0542fc3 Mon Sep 17 00:00:00 2001 From: Zambom Date: Mon, 13 Feb 2017 20:00:41 -0200 Subject: [PATCH] Adding category post crud --- amadeus/static/js/mural.js | 63 +++------------------------------------------------------------ amadeus/static/js/mural_category.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ amadeus/static/js/mural_general.js | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mural/forms.py | 11 ++++++++++- mural/models.py | 6 +++--- mural/templates/mural/list.html | 3 ++- mural/templates/mural/list_category.html | 17 ++++++++++++++--- mural/urls.py | 6 +++++- mural/views.py | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 9 files changed, 307 insertions(+), 80 deletions(-) create mode 100644 amadeus/static/js/mural_category.js create mode 100644 amadeus/static/js/mural_general.js diff --git a/amadeus/static/js/mural.js b/amadeus/static/js/mural.js index 45f1f38..3f6921f 100644 --- a/amadeus/static/js/mural.js +++ b/amadeus/static/js/mural.js @@ -1,56 +1,7 @@ var new_posts = []; var new_comments = {}; -// loadOnScroll handler -var loadOnScroll = function() { - // If the current scroll position is past out cutoff point... - if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) { - // temporarily unhook the scroll event watcher so we don't call a bunch of times in a row - $(window).unbind(); - // execute the load function below that will visit the view and return the content - loadPosts(); - } -}; - -var loadPosts = function() { - var loadUrl = $('.mural').data('url'), - pageNum = $('.mural').data('page'), - numberPages = $('.mural').data('pages'), - favorites = $('.mural').data('fav'), - mine = $('.mural').data('mine'), - showing = new_posts.join(','); - // Check if page is equal to the number of pages - if (pageNum == numberPages) { - return false - } - // Update the page number - pageNum = pageNum + 1; - - $("#loading_posts").show(); - // Configure the url we're about to hit - setTimeout(function (){ - $.ajax({ - url: loadUrl, - data: {'page': pageNum, "favorite": favorites, "mine": mine, "showing": showing}, - success: function(data) { - $("#loading_posts").hide(); - - $(".posts").append(data); - - $('.mural').data('page', pageNum); - - setTimeout(function () { postHeightLimits() }, 10); - }, - complete: function(data, textStatus){ - // Turn the scroll monitor back on - $(window).bind('scroll', loadOnScroll); - } - }); - }, 1000) -}; $(function () { - $(window).bind('scroll', loadOnScroll); - $(".post-field").click(function () { var url = $(this).find('h4').data('url'); @@ -66,15 +17,7 @@ $(function () { }); }); - $("#clear_filter").click(function () { - var frm = $(this).parent(); - - frm.find("input[type='checkbox']").prop('checked', false); - - frm.submit(); - }); - - $(".comment-section").each(function () { + $(".comment-section:visible").each(function () { var height = $(this)[0].scrollHeight; $(this).animate({scrollTop: height}, 0); @@ -127,11 +70,11 @@ function setPostFormSubmit(post = "") { old.remove(); } else { - $('.posts').prepend(data.view); + $('.posts:visible').prepend(data.view); new_posts.push(data.new_id); - $('.no-subjects').attr('style', 'display:none'); + $('.no-subjects:visible').attr('style', 'display:none'); } setTimeout(function () { postHeightLimits() }, 100); diff --git a/amadeus/static/js/mural_category.js b/amadeus/static/js/mural_category.js new file mode 100644 index 0000000..8c4d513 --- /dev/null +++ b/amadeus/static/js/mural_category.js @@ -0,0 +1,50 @@ +$('.mural-category').on('shown.bs.collapse', function(e) { + if($(this).is(e.target)){ + var li = $(".breadcrumb").find('li:last-child'); + var li_text = $(li).html(); + var url = $(".mural_url").val(); + var new_li = $(li).clone(); + + new_li.html($(this).parent().find('.panel-title span').text()); + + $(li).html("" + li_text + ""); + $(li).append("/"); + + new_li.appendTo('.breadcrumb'); + + var post_section = $(this).find('.posts'), + without = $(this).find('.no-subjects'), + loading = $(this).find('.loading-posts'); + + if (post_section.children().length == 0) { + var url = $(this).find('.mural').data('url'); + + $.ajax({ + url: url, + dataType: 'json', + success: function (data) { + loading.hide(); + + if (data.count > 0) { + post_section.append(data.posts); + + without.hide(); + } else { + without.show(); + } + } + }); + } + } +}); + +$('.mural-category').on('hidden.bs.collapse', function(e) { + if($(this).is(e.target)){ + $(".breadcrumb").find('li:last-child').remove(); + + var li = $(".breadcrumb").find('li:last-child'); + var text = $(li).find('a').text(); + + $(li).html(text); + } +}); \ No newline at end of file diff --git a/amadeus/static/js/mural_general.js b/amadeus/static/js/mural_general.js new file mode 100644 index 0000000..c8ddaad --- /dev/null +++ b/amadeus/static/js/mural_general.js @@ -0,0 +1,59 @@ +// loadOnScroll handler +var loadOnScroll = function() { + // If the current scroll position is past out cutoff point... + if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) { + // temporarily unhook the scroll event watcher so we don't call a bunch of times in a row + $(window).unbind(); + // execute the load function below that will visit the view and return the content + loadPosts(); + } +}; + +var loadPosts = function() { + var loadUrl = $('.mural').data('url'), + pageNum = $('.mural').data('page'), + numberPages = $('.mural').data('pages'), + favorites = $('.mural').data('fav'), + mine = $('.mural').data('mine'), + showing = new_posts.join(','); + // Check if page is equal to the number of pages + if (pageNum == numberPages) { + return false + } + // Update the page number + pageNum = pageNum + 1; + + $("#loading_posts").show(); + // Configure the url we're about to hit + setTimeout(function (){ + $.ajax({ + url: loadUrl, + data: {'page': pageNum, "favorite": favorites, "mine": mine, "showing": showing}, + success: function(data) { + $("#loading_posts").hide(); + + $(".posts").append(data); + + $('.mural').data('page', pageNum); + + setTimeout(function () { postHeightLimits() }, 10); + }, + complete: function(data, textStatus){ + // Turn the scroll monitor back on + $(window).bind('scroll', loadOnScroll); + } + }); + }, 1000) +}; + +$(function () { + $(window).bind('scroll', loadOnScroll); + + $("#clear_filter").click(function () { + var frm = $(this).parent(); + + frm.find("input[type='checkbox']").prop('checked', false); + + frm.submit(); + }); +}); \ No newline at end of file diff --git a/mural/forms.py b/mural/forms.py index eebc153..624b131 100644 --- a/mural/forms.py +++ b/mural/forms.py @@ -3,7 +3,7 @@ from django import forms from django.utils.translation import ugettext_lazy as _ from django.utils.html import strip_tags -from .models import GeneralPost, Comment +from .models import GeneralPost, CategoryPost, Comment class Validation(forms.ModelForm): MAX_UPLOAD_SIZE = 5*1024*1024 @@ -40,6 +40,15 @@ class GeneralPostForm(Validation): 'post': forms.Textarea } +class CategoryPostForm(Validation): + class Meta: + model = CategoryPost + fields = ['action', 'post', 'image'] + widgets = { + 'action': forms.RadioSelect, + 'post': forms.Textarea + } + class CommentForm(forms.ModelForm): MAX_UPLOAD_SIZE = 5*1024*1024 diff --git a/mural/models.py b/mural/models.py index 2504800..965b405 100644 --- a/mural/models.py +++ b/mural/models.py @@ -51,7 +51,7 @@ class GeneralPost(Mural): return "mural:delete_general" class CategoryPost(Mural): - space = models.ForeignKey(Category, verbose_name = ('Category'), related_name = 'post_category') + space = models.ForeignKey(Category, verbose_name = ('Category'), related_name = 'post_category', null = True) def get_id(self): return self.id @@ -60,10 +60,10 @@ class CategoryPost(Mural): return self.id def update_link(self): - return "" + return "mural:update_category" def delete_link(self): - return "" + return "mural:delete_category" class SubjectPost(Mural): space = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name = 'post_subject') diff --git a/mural/templates/mural/list.html b/mural/templates/mural/list.html index 260eedd..4dc5c06 100644 --- a/mural/templates/mural/list.html +++ b/mural/templates/mural/list.html @@ -65,7 +65,7 @@ - + @@ -73,4 +73,5 @@ + {% endblock %} \ No newline at end of file diff --git a/mural/templates/mural/list_category.html b/mural/templates/mural/list_category.html index 7c0db39..186ff5d 100644 --- a/mural/templates/mural/list_category.html +++ b/mural/templates/mural/list_category.html @@ -12,6 +12,8 @@ {% endblock %} {% block content %} + +
-
+
@@ -72,14 +74,19 @@
-

{% trans 'Wish to make a new post?' %}

+

{% trans 'Wish to make a new post?' %}

+
+

{% trans 'Filter' %}

@@ -109,5 +116,9 @@ {% endif %}
+ + + + {% endblock %} \ No newline at end of file diff --git a/mural/urls.py b/mural/urls.py index b3b744a..b5c15bc 100644 --- a/mural/urls.py +++ b/mural/urls.py @@ -5,8 +5,12 @@ urlpatterns = [ url(r'^$', views.GeneralIndex.as_view(), name='manage_general'), url(r'^categories/$', views.CategoryIndex.as_view(), name='manage_category'), url(r'^create_gen/$', views.GeneralCreate.as_view(), name='create_general'), + url(r'^create_cat/(?P[\w_-]+)/$', views.CategoryCreate.as_view(), name='create_category'), url(r'^update_gen/(?P[\w_-]+)/$', views.GeneralUpdate.as_view(), name='update_general'), + url(r'^update_cat/(?P[\w_-]+)/$', views.CategoryUpdate.as_view(), name='update_category'), url(r'^delete_gen/(?P[\w_-]+)/$', views.GeneralDelete.as_view(), name='delete_general'), + url(r'^delete_cat/(?P[\w_-]+)/$', views.CategoryDelete.as_view(), name='delete_category'), + url(r'^load_category/([\w_-]+)/$', views.load_category_posts, name='load_category'), url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'), url(r'^deleted/$', views.deleted_post, name='deleted_post'), url(r'^comment/(?P[\w_-]+)/$', views.CommentCreate.as_view(), name='create_comment'), @@ -14,7 +18,7 @@ urlpatterns = [ url(r'^delete_comment/(?P[\w_-]+)/$', views.CommentDelete.as_view(), name='delete_comment'), url(r'^deleted_comment/$', views.deleted_comment, name='deleted_comment'), url(r'^render_comment/([\w_-]+)/([\w_-]+)/$', views.render_comment, name='render_comment'), - url(r'^render_post/([\w_-]+)/([\w_-]+)/$', views.render_gen_post, name='render_post_general'), + url(r'^render_post/([\w_-]+)/([\w_-]+)/([\w_-]+)/$', views.render_post, name='render_post'), url(r'^load_comments/([\w_-]+)/([\w_-]+)/$', views.load_comments, name='load_comments'), url(r'^suggest_users/$', views.suggest_users, name='suggest_users'), ] \ No newline at end of file diff --git a/mural/views.py b/mural/views.py index 5995b6f..5bc7a0c 100644 --- a/mural/views.py +++ b/mural/views.py @@ -19,7 +19,7 @@ from subjects.models import Subject from users.models import User from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites, Comment -from .forms import GeneralPostForm, CommentForm +from .forms import GeneralPostForm, CategoryPostForm, CommentForm """ Section for GeneralPost classes @@ -140,7 +140,7 @@ class GeneralCreate(LoginRequiredMixin, generic.edit.CreateView): return context def get_success_url(self): - return reverse_lazy('mural:render_post_general', args = (self.object.id, 'create', )) + return reverse_lazy('mural:render_post', args = (self.object.id, 'create', 'gen', )) class GeneralUpdate(LoginRequiredMixin, generic.UpdateView): login_url = reverse_lazy("users:login") @@ -182,7 +182,7 @@ class GeneralUpdate(LoginRequiredMixin, generic.UpdateView): return context def get_success_url(self): - return reverse_lazy('mural:render_post_general', args = (self.object.id, 'update', )) + return reverse_lazy('mural:render_post', args = (self.object.id, 'update', 'gen', )) class GeneralDelete(LoginRequiredMixin, generic.DeleteView): login_url = reverse_lazy("users:login") @@ -213,6 +213,33 @@ class GeneralDelete(LoginRequiredMixin, generic.DeleteView): """ Section for CategoryPost classes """ +def load_category_posts(request, category): + context = { + 'request': request, + } + + showing = request.GET.get('showing', '') + + posts = CategoryPost.objects.extra(select = {"most_recent": "greatest(last_update, (select max(mural_comment.last_update) from mural_comment where mural_comment.post_id = mural_categorypost.mural_ptr_id))"}).filter(space__id = category).order_by("-most_recent") + + paginator = Paginator(posts, 10) + + try: + page_number = int(request.GET.get('page', 1)) + except ValueError: + raise Http404 + + try: + page_obj = paginator.page(page_number) + except EmptyPage: + raise Http404 + + context['posts'] = page_obj.object_list + + response = render_to_string("mural/_list_view.html", context, request) + + return JsonResponse({"posts": response, "count": posts.count(), "num_pages": paginator.num_pages, "num_page": page_obj.number}) + class CategoryIndex(LoginRequiredMixin, generic.ListView): login_url = reverse_lazy("users:login") redirect_field_name = 'next' @@ -235,8 +262,6 @@ class CategoryIndex(LoginRequiredMixin, generic.ListView): self.totals['category'] = MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__categorypost__space__coordinators = user) | Q(comment__post__categorypost__space__coordinators = user) | Q(post__categorypost__space__subject_category__professor = user) | Q(post__categorypost__space__subject_category__students = user) | Q(comment__post__categorypost__space__subject_category__professor = user) | Q(comment__post__categorypost__space__subject_category__students = user))).distinct().count() self.totals['subject'] = MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__subjectpost__space__professor = user) | Q(comment__post__subjectpost__space__professor = user) | Q(post__subjectpost__space__students = user) | Q(comment__post__subjectpost__space__students = user))).distinct().count() - print(categories) - return categories def get_context_data(self, **kwargs): @@ -248,22 +273,144 @@ class CategoryIndex(LoginRequiredMixin, generic.ListView): return context -def render_gen_post(request, post, msg): - post = get_object_or_404(GeneralPost, id = post) +class CategoryCreate(LoginRequiredMixin, generic.edit.CreateView): + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'mural/_form.html' + form_class = CategoryPostForm + + def form_invalid(self, form): + context = super(CategoryCreate, self).form_invalid(form) + context.status_code = 400 + + return context + + def form_valid(self, form): + self.object = form.save(commit = False) + + slug = self.kwargs.get('slug', None) + cat = get_object_or_404(Category, slug = slug) + + self.object.space = cat + self.object.user = self.request.user + + self.object.save() + + users = User.objects.all().exclude(id = self.request.user.id) + entries = [] + + notify_type = "mural" + user_icon = self.object.user.image_url + #_view = render_to_string("mural/_view.html", {"post": self.object}, self.request) + simple_notify = _("%s has made a post in General")%(str(self.object.user)) + pathname = reverse("mural:manage_general") + + #for user in users: + # entries.append(MuralVisualizations(viewed = False, user = user, post = self.object)) + # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "create", "user_icon": user_icon, "pathname": pathname, "simple": simple_notify, "complete": _view})}) + + #MuralVisualizations.objects.bulk_create(entries) + + return super(CategoryCreate, self).form_valid(form) + + def get_context_data(self, *args, **kwargs): + context = super(CategoryCreate, self).get_context_data(*args, **kwargs) + + context['form_url'] = reverse_lazy("mural:create_category", args = (), kwargs = {'slug': self.kwargs.get('slug', None)}) + + return context + + def get_success_url(self): + return reverse_lazy('mural:render_post', args = (self.object.id, 'create', 'cat', )) + +class CategoryUpdate(LoginRequiredMixin, generic.UpdateView): + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'mural/_form.html' + model = CategoryPost + form_class = CategoryPostForm + + def form_invalid(self, form): + context = super(CategoryUpdate, self).form_invalid(form) + context.status_code = 400 + + return context + + def form_valid(self, form): + self.object = form.save(commit = False) + + self.object.edited = True + + self.object.save() + + users = User.objects.all().exclude(id = self.request.user.id) + + notify_type = "mural" + #_view = render_to_string("mural/_view.html", {"post": self.object}, self.request) + pathname = reverse("mural:manage_general") + + #for user in users: + # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "update", "pathname": pathname, "complete": _view, "post_id": self.object.id})}) + + return super(CategoryUpdate, self).form_valid(form) + + def get_context_data(self, *args, **kwargs): + context = super(CategoryUpdate, self).get_context_data(*args, **kwargs) + + context['form_url'] = reverse_lazy("mural:update_category", args = (), kwargs = {'pk': self.object.id}) + + return context + + def get_success_url(self): + return reverse_lazy('mural:render_post', args = (self.object.id, 'update', 'cat', )) + +class CategoryDelete(LoginRequiredMixin, generic.DeleteView): + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'mural/delete.html' + model = CategoryPost + + def get_context_data(self, *args, **kwargs): + context = super(CategoryDelete, self).get_context_data(*args, **kwargs) + + context['form_url'] = reverse_lazy("mural:delete_category", args = (), kwargs = {'pk': self.object.id}) + context['message'] = _('Are you sure you want to delete this post?') + + return context + + def get_success_url(self): + users = User.objects.all().exclude(id = self.request.user.id) + + notify_type = "mural" + pathname = reverse("mural:manage_general") + + #for user in users: + # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "delete", "pathname": pathname, "post_id": self.object.id})}) + + return reverse_lazy('mural:deleted_post') + +def render_post(request, post, msg, ptype): + if ptype == 'gen': + post = get_object_or_404(GeneralPost, id = post) + elif ptype == 'cat': + post = get_object_or_404(CategoryPost, id = post) context = {} context['post'] = post - msg = "" + message = "" if msg == 'create': - msg = _('Your post was published successfully!') + message = _('Your post was published successfully!') else: - msg = _('Your post was edited successfully!') + message = _('Your post was edited successfully!') html = render_to_string("mural/_view.html", context, request) - return JsonResponse({'message': msg, 'view': html, 'new_id': post.id}) + return JsonResponse({'message': message, 'view': html, 'new_id': post.id}) def deleted_post(request): return JsonResponse({'msg': _('Post deleted successfully!')}) @@ -282,6 +429,9 @@ def favorite(request, post): return JsonResponse({'label': _('Favorite')}) +""" + Section for comment functions +""" class CommentCreate(LoginRequiredMixin, generic.edit.CreateView): login_url = reverse_lazy("users:login") redirect_field_name = 'next' -- libgit2 0.21.2