diff --git a/bulletin/__init__.py b/bulletin/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/bulletin/__init__.py diff --git a/bulletin/admin.py b/bulletin/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/bulletin/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/bulletin/apps.py b/bulletin/apps.py new file mode 100644 index 0000000..b027b77 --- /dev/null +++ b/bulletin/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class BulletinConfig(AppConfig): + name = 'bulletin' diff --git a/bulletin/forms.py b/bulletin/forms.py new file mode 100644 index 0000000..5af7684 --- /dev/null +++ b/bulletin/forms.py @@ -0,0 +1,128 @@ +# coding=utf-8 +from django import forms +from django.utils.translation import ugettext_lazy as _ +from django.utils.html import strip_tags + +from subjects.models import Tag + +from .models import Bulletin + +from resubmit.widgets import ResubmitFileWidget + +class BulletinForm(forms.ModelForm): + subject = None + + def __init__(self, *args, **kwargs): + super(BulletinForm, self).__init__(*args, **kwargs) + + self.subject = kwargs['initial'].get('subject', None) + + if self.instance.id: + self.subject = self.instance.topic.subject + self.initial['tags'] = ", ".join(self.instance.tags.all().values_list("name", flat = True)) + + self.fields['students'].queryset = self.subject.students.all() + self.fields['groups'].queryset = self.subject.group_subject.all() + + tags = forms.CharField(label = _('Tags'), required = False) + + class Meta: + model = Bulletin + fields = ['name', 'content', 'brief_description', 'all_students', 'students', 'groups', 'show_window', 'visible'] + labels = { + 'name': _('Bulletin name'), + 'content': _('Bulletin content'), + } + widgets = { + 'content': forms.Textarea, + 'brief_description': forms.Textarea, + 'students': forms.SelectMultiple, + 'groups': forms.SelectMultiple, + } + + def clean_name(self): + name = self.cleaned_data.get('name', '') + + topics = self.subject.topic_subject.all() + + for topic in topics: + if self.instance.id: + same_name = topic.resource_topic.filter(name__unaccent__iexact = name).exclude(id = self.instance.id).count() + else: + same_name = topic.resource_topic.filter(name__unaccent__iexact = name).count() + + if same_name > 0: + self._errors['name'] = [_('This subject already has a bulletin with this name')] + + return ValueError + + return name + + def clean_content(self): + content = self.cleaned_data.get('content', '') + cleaned_content = strip_tags(content) + + if cleaned_content == '': + self._errors['content'] = [_('This field is required.')] + + return ValueError + + return content + + def save(self, commit = True): + super(BulletinForm, self).save(commit = True) + + self.instance.save() + + previous_tags = self.instance.tags.all() + + tags = self.cleaned_data['tags'].split(",") + + #Excluding unwanted tags + for prev in previous_tags: + if not prev.name in tags: + self.instance.tags.remove(prev) + + for tag in tags: + tag = tag.strip() + + exist = Tag.objects.filter(name = tag).exists() + + if exist: + new_tag = Tag.objects.get(name = tag) + else: + new_tag = Tag.objects.create(name = tag) + + if not new_tag in self.instance.tags.all(): + self.instance.tags.add(new_tag) + + return self.instance + +class FormModalMessage(forms.Form): + MAX_UPLOAD_SIZE = 5*1024*1024 + + comment = forms.CharField(widget=forms.Textarea,label=_("Message")) + image = forms.FileField(widget=ResubmitFileWidget(attrs={'accept':'image/*'}),required=False) + + def clean_comment(self): + comment = self.cleaned_data.get('comment', '') + cleaned_comment = strip_tags(comment) + + if cleaned_comment == '': + self._errors['comment'] = [_('This field is required.')] + + return ValueError + + return comment + + def clean_image(self): + image = self.cleaned_data.get('image', False) + + if image: + if hasattr(image, '_size'): + if image._size > self.MAX_UPLOAD_SIZE: + self._errors['image'] = [_("The image is too large. It should have less than 5MB.")] + + return ValueError + + return image diff --git a/bulletin/migrations/__init__.py b/bulletin/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/bulletin/migrations/__init__.py diff --git a/bulletin/models.py b/bulletin/models.py new file mode 100644 index 0000000..43c5732 --- /dev/null +++ b/bulletin/models.py @@ -0,0 +1,49 @@ +import os +from django.db import models +from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ +from django.core.urlresolvers import reverse_lazy + +from topics.models import Resource + +def validate_file_extension(value): + valid_formats = [ + 'image/jpeg','image/x-citrix-jpeg','image/png','image/x-citrix-png','image/x-png', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/vnd.ms-excel','text/html','application/msword','application/vnd.oasis.opendocument.presentation', + 'application/vnd.oasis.opendocument.spreadsheet','application/vnd.oasis.opendocument.text', + 'application/pdf' + ] + + if hasattr(value.file, 'content_type'): + if not value.file.content_type in valid_formats: + raise ValidationError(_('Please select a valid file. The uploaded file must have one of the following extensions: .doc, .docx, .html, .jpg, .odp, .ods, .odt, .pdf, .png, .ppt, .pptx, .xlx e .xlsx')) + +class Bulletin(Resource): + content = models.TextField(_('Bulletin Content'), blank = True) + file_content = models.FileField(_('File'), blank = True, upload_to = 'files/', validators = [validate_file_extension]) + + class Meta: + verbose_name = _('Bulletin') + verbose_name_plural = _('Bulletins') + + def __str__(self): + return self.name + + def access_link(self): + if self.show_window: + return reverse_lazy('bulletin:window_view', args = (), kwargs = {'slug': self.slug}) + + return reverse_lazy('bulletin:view', args = (), kwargs = {'slug': self.slug}) + + def update_link(self): + return 'bulletin:update' + + def delete_link(self): + return 'bulletin:delete' + + def delete_message(self): + return _('Are you sure you want delete the bulletin') diff --git a/bulletin/templates/bulletin/_form.html b/bulletin/templates/bulletin/_form.html new file mode 100644 index 0000000..72d2a72 --- /dev/null +++ b/bulletin/templates/bulletin/_form.html @@ -0,0 +1,347 @@ +{% load static i18n %} +{% load widget_tweaks %} + +
+ {% csrf_token %} + + {% render_field form.control_subject %} + +
+ + {% render_field form.name class='form-control' %} + + {{ form.name.help_text }} + + {% if form.name.errors %} + + {% endif %} +
+ +
+ + {% render_field form.content class='form-control text_wysiwyg' %} + + {{ form.content.help_text }} + + {% if form.content.errors %} + + {% endif %} +
+ + {% trans 'Common resources settings' %} + +
+ + {% render_field form.brief_description class='form-control text_wysiwyg' %} + + {{ form.brief_description.help_text }} + + {% if form.brief_description.errors %} + + {% endif %} +
+ +
+ + {% render_field form.tags class='form-control' data-role="tagsinput" %} + + {{ form.tags.help_text }} + + {% if form.tags.errors %} + + {% endif %} +
+ +
+
+ +
+ +
+
+ {% render_field pendencies_form.id %} + {% render_field pendencies_form.resource %} + {% render_field pendencies_form.subject class='pend_subj' %} + +
+ +
+ {% render_field pendencies_form.action class='form-control' %} +
+ +
+ + {{ pendencies_form.action.help_text }} + + {% if pendencies_form.action.errors %} + + {% endif %} +
+
+
+
+

{% trans 'Wished period' %}:

+
+
+
+
+ +
+
+ {% render_field pendencies_form.begin_date class='form-control datetime-picker begin_date_input' %} +
+
+
+ {{ pendencies_form.begin_date.help_text }} + + {% if pendencies_form.begin_date.errors %} + + {% endif %} +
+
+
+ +
+
+ {% render_field pendencies_form.end_date class='form-control datetime-picker end_date_input' %} +
+
+
+ {{ pendencies_form.end_date.help_text }} + + {% if pendencies_form.end_date.errors %} + + {% endif %} +
+
+
+
+
+ +
+ +
+
+
+ +
+ + {{ form.all_students.help_text }} + + {% if form.all_students.errors %} + + {% endif %} +
+ +

{% trans 'Attribute students to bulletin' %}:

+ {% render_field form.students class='form-control' %} + + {{ form.students.help_text }} + + {% if form.students.errors %} + + {% endif %} + +
+ +

{% trans 'Attribute groups to bulletin' %}:

+ {% render_field form.groups class='form-control' %} + + {{ form.groups.help_text }} + + {% if form.groups.errors %} + + {% endif %} +
+
+
+ +
+
+ +
+ + {{ form.show_window.help_text }} + + {% if form.show_window.errors %} + + {% endif %} +
+ +
+
+ +
+ + {{ form.visible.help_text }} + + {% if form.visible.errors %} + + {% endif %} +
+ +
+
+ +
+
+
+ + diff --git a/bulletin/templates/bulletin/create.html b/bulletin/templates/bulletin/create.html new file mode 100644 index 0000000..33c4698 --- /dev/null +++ b/bulletin/templates/bulletin/create.html @@ -0,0 +1,34 @@ +{% extends 'subjects/view.html' %} + +{% load static i18n django_bootstrap_breadcrumbs %} + +{% block style %} + {{block.super}} + +{% endblock %} + +{% block javascript %} + {{block.super}} + +{% endblock %} + +{% block breadcrumbs %} + {{ block.super }} + + {% breadcrumb topic 'subjects:topic_view' topic.subject.slug topic.slug %} + + {% trans 'Create Bulletin' as bread %} + {% breadcrumb bread 'bulletin:create' topic.slug %} +{% endblock %} + +{% block content %} +
+
+
+ {% include 'bulletin/_form.html' %} +
+
+
+
+
+{% endblock %} diff --git a/bulletin/templates/bulletin/relatorios.html b/bulletin/templates/bulletin/relatorios.html new file mode 100644 index 0000000..de505e5 --- /dev/null +++ b/bulletin/templates/bulletin/relatorios.html @@ -0,0 +1,435 @@ +{% extends "bulletin/view.html" %} + +{% load static i18n pagination permissions_tags subject_counter %} +{% load django_bootstrap_breadcrumbs %} + +{% block javascript%} + {{ block.super }} + + + + + +{% endblock%} + +{% block breadcrumbs %} + {{ block.super }} + {% trans 'Reports' as bread %} + {% breadcrumb bread bulletin%} +{% endblock %} + +{% block content %} +
+ {% if messages %} + {% for message in messages %} + + {% endfor %} + {% endif %} +
+
+
+
+
+

+ {{bulletin}} / {% trans "Reports" %} +

+
+
+
+
+
+

{% trans "Report of the resource " %}{{bulletin}}

+
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
    + +
+
+
+
+ +
+

+
+
+ + +{% endblock %} diff --git a/bulletin/templates/bulletin/send_message.html b/bulletin/templates/bulletin/send_message.html new file mode 100644 index 0000000..8c48540 --- /dev/null +++ b/bulletin/templates/bulletin/send_message.html @@ -0,0 +1,112 @@ + + {% load widget_tweaks i18n %} + + + + \ No newline at end of file diff --git a/bulletin/templates/bulletin/update.html b/bulletin/templates/bulletin/update.html new file mode 100644 index 0000000..186939a --- /dev/null +++ b/bulletin/templates/bulletin/update.html @@ -0,0 +1,36 @@ +{% extends 'subjects/view.html' %} + +{% load static i18n django_bootstrap_breadcrumbs %} + +{% block style %} + {{block.super}} + +{% endblock %} + +{% block javascript %} + {{block.super}} + +{% endblock %} + +{% block breadcrumbs %} + {{ block.super }} + + {% breadcrumb topic 'subjects:topic_view' topic.subject.slug topic.slug %} + + {% trans 'Edit: ' as bread %} + {% with bread|add:bulletin.name as bread_slug %} + {% breadcrumb bread_slug 'bulletin:update' topic.slug bulletin.slug %} + {% endwith %} +{% endblock %} + +{% block content %} +
+
+
+ {% include 'bulletin/_form.html' %} +
+
+
+
+
+{% endblock %} diff --git a/bulletin/templates/bulletin/view.html b/bulletin/templates/bulletin/view.html new file mode 100644 index 0000000..03b900e --- /dev/null +++ b/bulletin/templates/bulletin/view.html @@ -0,0 +1,58 @@ +{% extends 'subjects/view.html' %} + +{% load static i18n pagination permissions_tags subject_counter %} +{% load django_bootstrap_breadcrumbs %} + +{% block javascript%} + {{ block.super }} +{% endblock%} + +{% block breadcrumbs %} + {{ block.super }} + {% breadcrumb topic 'subjects:topic_view' subject.slug topic.slug %} + {% breadcrumb bulletin 'bulletin:view' bulletin.slug %} +{% endblock %} + +{% block content %} + {% if messages %} + {% for message in messages %} + + {% endfor %} + {% endif %} + + {% resource_permissions request.user bulletin as has_resource_permissions %} + + {% if bulletin.visible %} +
+
+ {% elif has_resource_permissions %} +
+
+ {% endif %} + +
+
+ {% autoescape off %} + {{ bulletin.content }} + {% endautoescape %} +
+
+{% endblock %} diff --git a/bulletin/templates/bulletin/window_view.html b/bulletin/templates/bulletin/window_view.html new file mode 100644 index 0000000..fa09684 --- /dev/null +++ b/bulletin/templates/bulletin/window_view.html @@ -0,0 +1 @@ +{{ bulletin.content|safe }} diff --git a/bulletin/tests.py b/bulletin/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/bulletin/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/bulletin/urls.py b/bulletin/urls.py new file mode 100644 index 0000000..4b84991 --- /dev/null +++ b/bulletin/urls.py @@ -0,0 +1,14 @@ +from django.conf.urls import url +from django.contrib.auth import views as auth_views + +from . import views + +urlpatterns = [ + url(r'^create/(?P[\w_-]+)/$', views.CreateView.as_view(), name = 'create'), + url(r'^update/(?P[\w_-]+)/(?P[\w_-]+)/$', views.UpdateView.as_view(), name = 'update'), + url(r'^delete/(?P[\w_-]+)/$', views.DeleteView.as_view(), name = 'delete'), + url(r'^window_view/(?P[\w_-]+)/$', views.NewWindowView.as_view(), name = 'window_view'), + url(r'^view/(?P[\w_-]+)/$', views.InsideView.as_view(), name = 'view'), + url(r'^chart/(?P[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'), + url(r'^send-message/(?P[\w_-]+)/$', views.SendMessage.as_view(), name = 'send_message'), +] diff --git a/bulletin/views.py b/bulletin/views.py new file mode 100644 index 0000000..786bd76 --- /dev/null +++ b/bulletin/views.py @@ -0,0 +1,590 @@ +from django.shortcuts import get_object_or_404, redirect, render +from django.views import generic +from django.contrib import messages +from django.core.urlresolvers import reverse, reverse_lazy +from django.utils.translation import ugettext_lazy as _ +from django.contrib.auth.mixins import LoginRequiredMixin +from django.http import JsonResponse + +from amadeus.permissions import has_subject_permissions, has_resource_permissions + +import time +import datetime +from log.mixins import LogMixin + +from topics.models import Topic + +from pendencies.forms import PendenciesForm + +from .forms import BulletinForm +from .models import Bulletin + +from log.models import Log +from chat.models import Conversation, TalkMessages, ChatVisualizations +from users.models import User +from subjects.models import Subject + +from .forms import FormModalMessage + +from django.template.loader import render_to_string +from django.utils import formats +import textwrap +from django.utils.html import strip_tags +import json +from channels import Group + +class NewWindowView(LoginRequiredMixin, LogMixin, generic.DetailView): + log_component = 'resources' + log_action = 'view' + log_resource = 'bulletin' + log_context = {} + + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'bulletin/window_view.html' + model = Bulletin + context_object_name = 'bulletin' + + def dispatch(self, request, *args, **kwargs): + slug = self.kwargs.get('slug', '') + bulletin = get_object_or_404(Bulletin, slug=slug) + + if not has_resource_permissions(request.user, bulletin): + return redirect(reverse_lazy('subjects:home')) + + return super(NewWindowView, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super(NewWindowView, self).get_context_data(**kwargs) + + self.log_context['category_id'] = self.object.topic.subject.category.id + self.log_context['category_name'] = self.object.topic.subject.category.name + self.log_context['category_slug'] = self.object.topic.subject.category.slug + self.log_context['subject_id'] = self.object.topic.subject.id + self.log_context['subject_name'] = self.object.topic.subject.name + self.log_context['subject_slug'] = self.object.topic.subject.slug + self.log_context['topic_id'] = self.object.topic.id + self.log_context['topic_name'] = self.object.topic.name + self.log_context['topic_slug'] = self.object.topic.slug + self.log_context['bulletin_id'] = self.object.id + self.log_context['bulletin_name'] = self.object.name + self.log_context['bulletin_slug'] = self.object.slug + self.log_context['timestamp_start'] = str(int(time.time())) + + super(NewWindowView, self).createLog(self.request.user, self.log_component, self.log_action, + self.log_resource, self.log_context) + + self.request.session['log_id'] = Log.objects.latest('id').id + + return context + +class InsideView(LoginRequiredMixin, LogMixin, generic.DetailView): + log_component = 'resources' + log_action = 'view' + log_resource = 'bulletin' + log_context = {} + + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'bulletins/view.html' + model = Bulletin + context_object_name = 'bulletin' + + def dispatch(self, request, *args, **kwargs): + slug = self.kwargs.get('slug', '') + bulletin = get_object_or_404(Bulletin, slug=slug) + + if not has_resource_permissions(request.user, bulletin): + return redirect(reverse_lazy('subjects:home')) + + return super(InsideView, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super(InsideView, self).get_context_data(**kwargs) + + context['title'] = self.object.name + + context['topic'] = self.object.topic + context['subject'] = self.object.topic.subject + + self.log_context['category_id'] = self.object.topic.subject.category.id + self.log_context['category_name'] = self.object.topic.subject.category.name + self.log_context['category_slug'] = self.object.topic.subject.category.slug + self.log_context['subject_id'] = self.object.topic.subject.id + self.log_context['subject_name'] = self.object.topic.subject.name + self.log_context['subject_slug'] = self.object.topic.subject.slug + self.log_context['topic_id'] = self.object.topic.id + self.log_context['topic_name'] = self.object.topic.name + self.log_context['topic_slug'] = self.object.topic.slug + self.log_context['bulletin_id'] = self.object.id + self.log_context['bulletin_name'] = self.object.name + self.log_context['bulletin_slug'] = self.object.slug + self.log_context['timestamp_start'] = str(int(time.time())) + + super(InsideView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) + + self.request.session['log_id'] = Log.objects.latest('id').id + + return context + +class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView): + log_component = 'resources' + log_action = 'create' + log_resource = 'bulletin' + log_context = {} + + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'bulletin/create.html' + form_class = BulletinForm + + def dispatch(self, request, *args, **kwargs): + slug = self.kwargs.get('slug', '') + topic = get_object_or_404(Topic, slug = slug) + + if not has_subject_permissions(request.user, topic.subject): + return redirect(reverse_lazy('subjects:home')) + + return super(CreateView, self).dispatch(request, *args, **kwargs) + + def get(self, request, *args, **kwargs): + self.object = None + + form_class = self.get_form_class() + form = self.get_form(form_class) + + slug = self.kwargs.get('slug', '') + topic = get_object_or_404(Topic, slug = slug) + + pendencies_form = PendenciesForm(initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) + + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form)) + + def post(self, request, *args, **kwargs): + self.object = None + + form_class = self.get_form_class() + form = self.get_form(form_class) + + slug = self.kwargs.get('slug', '') + topic = get_object_or_404(Topic, slug = slug) + + pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) + + if (form.is_valid() and pendencies_form.is_valid()): + return self.form_valid(form, pendencies_form) + else: + return self.form_invalid(form, pendencies_form) + + def get_initial(self): + initial = super(CreateView, self).get_initial() + + slug = self.kwargs.get('slug', '') + + topic = get_object_or_404(Topic, slug = slug) + initial['subject'] = topic.subject + + return initial + + def form_invalid(self, form, pendencies_form): + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form)) + + def form_valid(self, form, pendencies_form): + self.object = form.save(commit = False) + slug = self.kwargs.get('slug', '') + topic = get_object_or_404(Topic, slug = slug) + + self.object.topic = topic + self.object.order = topic.resource_topic.count() + 1 + + if not self.object.topic.visible and not self.object.topic.repository: + self.object.visible = False + + self.object.save() + + pend_form = pendencies_form.save(commit = False) + pend_form.resource = self.object + + if not pend_form.action == "": + pend_form.save() + + self.log_context['category_id'] = self.object.topic.subject.category.id + self.log_context['category_name'] = self.object.topic.subject.category.name + self.log_context['category_slug'] = self.object.topic.subject.category.slug + self.log_context['subject_id'] = self.object.topic.subject.id + self.log_context['subject_name'] = self.object.topic.subject.name + self.log_context['subject_slug'] = self.object.topic.subject.slug + self.log_context['topic_id'] = self.object.topic.id + self.log_context['topic_name'] = self.object.topic.name + self.log_context['topic_slug'] = self.object.topic.slug + self.log_context['bulletin_id'] = self.object.id + self.log_context['bulletin_name'] = self.object.name + self.log_context['bulletin_slug'] = self.object.slug + + super(CreateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) + + return redirect(self.get_success_url()) + + def get_context_data(self, **kwargs): + context = super(CreateView, self).get_context_data(**kwargs) + + context['title'] = _('Create Bulletin') + + slug = self.kwargs.get('slug', '') + topic = get_object_or_404(Topic, slug = slug) + + context['topic'] = topic + context['subject'] = topic.subject + + return context + + def get_success_url(self): + messages.success(self.request, _('The Bulletin "%s" was added to the Topic "%s" of the virtual environment "%s" successfully!')%(self.object.name, self.object.topic.name, self.object.topic.subject.name)) + + success_url = reverse_lazy('bulletin:view', kwargs = {'slug': self.object.slug}) + + if self.object.show_window: + self.request.session['resources'] = {} + self.request.session['resources']['new_page'] = True + self.request.session['resources']['new_page_url'] = reverse('bulletin:window_view', kwargs = {'slug': self.object.slug}) + + success_url = reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug}) + + return success_url + +class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): + log_component = 'resources' + log_action = 'update' + log_resource = 'bulletin' + log_context = {} + + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'bulletin/update.html' + model = Bulletin + form_class = BulletinForm + + def dispatch(self, request, *args, **kwargs): + slug = self.kwargs.get('topic_slug', '') + topic = get_object_or_404(Topic, slug = slug) + + if not has_subject_permissions(request.user, topic.subject): + return redirect(reverse_lazy('subjects:home')) + + return super(UpdateView, self).dispatch(request, *args, **kwargs) + + def get(self, request, *args, **kwargs): + self.object = self.get_object() + + form_class = self.get_form_class() + form = self.get_form(form_class) + + slug = self.kwargs.get('topic_slug', '') + topic = get_object_or_404(Topic, slug = slug) + + pend_form = self.object.pendencies_resource.all() + + if len(pend_form) > 0: + pendencies_form = PendenciesForm(instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) + else: + pendencies_form = PendenciesForm(initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) + + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form)) + + def post(self, request, *args, **kwargs): + self.object = self.get_object() + + form_class = self.get_form_class() + form = self.get_form(form_class) + + slug = self.kwargs.get('topic_slug', '') + topic = get_object_or_404(Topic, slug = slug) + + pend_form = self.object.pendencies_resource.all() + + if len(pend_form) > 0: + pendencies_form = PendenciesForm(self.request.POST, instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) + else: + pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) + + if (form.is_valid() and pendencies_form.is_valid()): + return self.form_valid(form, pendencies_form) + else: + return self.form_invalid(form, pendencies_form) + + def form_invalid(self, form, pendencies_form): + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form)) + + def form_valid(self, form, pendencies_form): + self.object = form.save(commit = False) + + if not self.object.topic.visible and not self.object.topic.repository: + self.object.visible = False + + self.object.save() + + pend_form = pendencies_form.save(commit = False) + pend_form.resource = self.object + + if not pend_form.action == "": + pend_form.save() + + self.log_context['category_id'] = self.object.topic.subject.category.id + self.log_context['category_name'] = self.object.topic.subject.category.name + self.log_context['category_slug'] = self.object.topic.subject.category.slug + self.log_context['subject_id'] = self.object.topic.subject.id + self.log_context['subject_name'] = self.object.topic.subject.name + self.log_context['subject_slug'] = self.object.topic.subject.slug + self.log_context['topic_id'] = self.object.topic.id + self.log_context['topic_name'] = self.object.topic.name + self.log_context['topic_slug'] = self.object.topic.slug + self.log_context['bulletin_id'] = self.object.id + self.log_context['bulletin_name'] = self.object.name + self.log_context['bulletin_slug'] = self.object.slug + + super(UpdateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) + + return redirect(self.get_success_url()) + + def get_context_data(self, **kwargs): + context = super(UpdateView, self).get_context_data(**kwargs) + + context['title'] = _('Update Bulletin') + + slug = self.kwargs.get('topic_slug', '') + topic = get_object_or_404(Topic, slug = slug) + + context['topic'] = topic + context['subject'] = topic.subject + + return context + + def get_success_url(self): + messages.success(self.request, _('The Bulletin "%s" was updated successfully!')%(self.object.name)) + + success_url = reverse_lazy('bulletin:view', kwargs = {'slug': self.object.slug}) + + if self.object.show_window: + self.request.session['resources'] = {} + self.request.session['resources']['new_page'] = True + self.request.session['resources']['new_page_url'] = reverse('bulletin:window_view', kwargs = {'slug': self.object.slug}) + + success_url = reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug}) + + return success_url + +class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView): + log_component = 'resources' + log_action = 'delete' + log_resource = 'bulletin' + log_context = {} + + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'resources/delete.html' + model = Bulletin + context_object_name = 'resource' + + def dispatch(self, request, *args, **kwargs): + slug = self.kwargs.get('slug', '') + bulletin = get_object_or_404(Bulletin, slug = slug) + + if not has_subject_permissions(request.user, bulletin.topic.subject): + return redirect(reverse_lazy('subjects:home')) + + return super(DeleteView, self).dispatch(request, *args, **kwargs) + + def get_success_url(self): + messages.success(self.request, _('The bulletin "%s" was removed successfully from virtual environment "%s"!')%(self.object.name, self.object.topic.subject.name)) + + self.log_context['category_id'] = self.object.topic.subject.category.id + self.log_context['category_name'] = self.object.topic.subject.category.name + self.log_context['category_slug'] = self.object.topic.subject.category.slug + self.log_context['subject_id'] = self.object.topic.subject.id + self.log_context['subject_name'] = self.object.topic.subject.name + self.log_context['subject_slug'] = self.object.topic.subject.slug + self.log_context['topic_id'] = self.object.topic.id + self.log_context['topic_name'] = self.object.topic.name + self.log_context['topic_slug'] = self.object.topic.slug + self.log_context['bulletin_id'] = self.object.id + self.log_context['bulletin_name'] = self.object.name + self.log_context['bulletin_slug'] = self.object.slug + + super(DeleteView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) + + return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug}) + + +class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView): + log_component = 'resources' + log_action = 'view_statistics' + log_resource = 'bulletin' + log_context = {} + + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + model = Bulletin + template_name = 'bulletin/relatorios.html' + + def dispatch(self, request, *args, **kwargs): + slug = self.kwargs.get('slug', '') + bulletin = get_object_or_404(Bulletin, slug = slug) + + if not has_subject_permissions(request.user, bulletin.topic.subject): + return redirect(reverse_lazy('subjects:home')) + + return super(StatisticsView, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super(StatisticsView, self).get_context_data(**kwargs) + + self.log_context['category_id'] = self.object.topic.subject.category.id + self.log_context['category_name'] = self.object.topic.subject.category.name + self.log_context['category_slug'] = self.object.topic.subject.category.slug + self.log_context['subject_id'] = self.object.topic.subject.id + self.log_context['subject_name'] = self.object.topic.subject.name + self.log_context['subject_slug'] = self.object.topic.subject.slug + self.log_context['topic_id'] = self.object.topic.id + self.log_context['topic_name'] = self.object.topic.name + self.log_context['topic_slug'] = self.object.topic.slug + self.log_context['bulletin_id'] = self.object.id + self.log_context['bulletin_name'] = self.object.name + self.log_context['bulletin_slug'] = self.object.slug + + super(StatisticsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) + + + context['title'] = _('Bulletin Reports') + + slug = self.kwargs.get('slug') + bulletin = get_object_or_404(Bulletin, slug = slug) + + date_format = "%d/%m/%Y %H:%M" if self.request.GET.get('language','') == 'pt-br' else "%m/%d/%Y %I:%M %p" + if self.request.GET.get('language','') == "": + start_date = datetime.datetime.now() - datetime.timedelta(30) + end_date = datetime.datetime.now() + else : + start_date = datetime.datetime.strptime(self.request.GET.get('init_date',''),date_format) + end_date = datetime.datetime.strptime(self.request.GET.get('end_date',''),date_format) + context["init_date"] = start_date + context["end_date"] = end_date + alunos = bulletin.students.all() + if bulletin.all_students : + alunos = bulletin.topic.subject.students.all() + + vis_ou = Log.objects.filter(context__contains={'bulletin_id':bulletin.id},resource="bulletin",action="view",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1))) + did,n_did,history = str(_("Realized")),str(_("Unrealized")),str(_("Historic")) + re = [] + data_n_did,data_history = [],[] + json_n_did, json_history = {},{} + + for log_al in vis_ou.order_by("datetime"): + data_history.append([str(alunos.get(email=log_al.user_email)), + ", ".join([str(x) for x in bulletin.topic.subject.group_subject.filter(participants__email=log_al.user_email)]), + log_al.action,log_al.datetime]) + + json_history["data"] = data_history + + not_view = alunos.exclude(email__in=[log.user_email for log in vis_ou.distinct("user_email")]) + index = 0 + for alun in not_view: + data_n_did.append([index,str(alun),", ".join([str(x) for x in bulletin.topic.subject.group_subject.filter(participants__email=alun.email)]),str(_('View')), str(alun.email)]) + index += 1 + json_n_did["data"] = data_n_did + + + context["json_n_did"] = json_n_did + context["json_history"] = json_history + c_visualizou = vis_ou.distinct("user_email").count() + column_view = str(_('View')) + re.append([str(_('Bulletin')),did,n_did]) + re.append([column_view,c_visualizou, alunos.count() - c_visualizou]) + context['topic'] = bulletin.topic + context['subject'] = bulletin.topic.subject + context['db_data'] = re + context['title_chart'] = _('Actions about resource') + context['title_vAxis'] = _('Quantity') + context['view'] = column_view + context["n_did_table"] = n_did + context["did_table"] = did + context["history_table"] = history + return context + + + +from django.http import HttpResponse #used to send HTTP 404 error to ajax + +class SendMessage(LoginRequiredMixin, LogMixin, generic.edit.FormView): + log_component = 'resources' + log_action = 'send' + log_resource = 'bulletin' + log_context = {} + + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + template_name = 'bulletin/send_message.html' + form_class = FormModalMessage + + def dispatch(self, request, *args, **kwargs): + slug = self.kwargs.get('slug', '') + bulletin = get_object_or_404(Bulletin, slug = slug) + self.bulletin = bulletin + + if not has_subject_permissions(request.user, bulletin.topic.subject): + return redirect(reverse_lazy('subjects:home')) + + return super(SendMessage, self).dispatch(request, *args, **kwargs) + + def form_valid(self, form): + message = form.cleaned_data.get('comment') + image = form.cleaned_data.get("image") + users = (self.request.POST.get('users[]','')).split(",") + user = self.request.user + subject = self.bulletin.topic.subject + + if (users[0] is not ''): + for u in users: + to_user = User.objects.get(email=u) + talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user) + created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject,image=image) + + simple_notify = textwrap.shorten(strip_tags(message), width = 30, placeholder = "...") + + if image is not '': + simple_notify += " ".join(_("[Photo]")) + + notification = { + "type": "chat", + "subtype": "subject", + "space": subject.slug, + "user_icon": created.user.image_url, + "notify_title": str(created.user), + "simple_notify": simple_notify, + "view_url": reverse("chat:view_message", args = (created.id, ), kwargs = {}), + "complete": render_to_string("chat/_message.html", {"talk_msg": created}, self.request), + "container": "chat-" + str(created.user.id), + "last_date": _("Last message in %s")%(formats.date_format(created.create_date, "SHORT_DATETIME_FORMAT")) + } + + notification = json.dumps(notification) + + Group("user-%s" % to_user.id).send({'text': notification}) + + ChatVisualizations.objects.create(viewed = False, message = created, user = to_user) + + success = str(_('The message was successfull sent!')) + return JsonResponse({"message":success}) + erro = HttpResponse(str(_("No user selected!"))) + erro.status_code = 404 + return erro + + def get_context_data(self, **kwargs): + context = super(SendMessage,self).get_context_data() + context["bulletin"] = get_object_or_404(Bulletin, slug=self.kwargs.get('slug', '')) + return context -- libgit2 0.21.2