mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-22 06:03:20 +00:00
Add notification
This commit is contained in:
parent
c1397ef5a5
commit
80fa99d2ac
27
core/migrations/0012_notification.py
Normal file
27
core/migrations/0012_notification.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
from django.conf import settings
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('core', '0011_auto_20161124_0848'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Notification',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
|
||||||
|
('url', models.CharField(max_length=255, verbose_name='url')),
|
||||||
|
('text', models.CharField(max_length=512, verbose_name='text')),
|
||||||
|
('type', models.CharField(max_length=16, choices=[('FILE_MODERATION', 'File moderation'), ('SAS_MODERATION', 'SAS moderation'), ('NEW_PICTURES', 'New pictures')], verbose_name='text', null=True, blank=True)),
|
||||||
|
('date', models.DateTimeField(verbose_name='date', default=django.utils.timezone.now)),
|
||||||
|
('user', models.ForeignKey(related_name='notifications', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -850,3 +850,11 @@ class PageRev(models.Model):
|
|||||||
# Don't forget to unlock, otherwise, people will have to wait for the page's timeout
|
# Don't forget to unlock, otherwise, people will have to wait for the page's timeout
|
||||||
self.page.unset_lock()
|
self.page.unset_lock()
|
||||||
|
|
||||||
|
class Notification(models.Model):
|
||||||
|
user = models.ForeignKey(User, related_name='notifications')
|
||||||
|
url = models.CharField(_("url"), max_length=255)
|
||||||
|
text = models.CharField(_("text"), max_length=512)
|
||||||
|
type = models.CharField(_("text"), max_length=16, choices=settings.SITH_NOTIFICATIONS, blank=True, null=True)
|
||||||
|
date = models.DateTimeField(_('date'), default=timezone.now)
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,3 +36,7 @@ $( function() {
|
|||||||
popup.dialog({title: $(this).text()}).dialog( "open" );
|
popup.dialog({title: $(this).text()}).dialog( "open" );
|
||||||
});
|
});
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
function display_notif() {
|
||||||
|
$('#notif').toggle();
|
||||||
|
}
|
||||||
|
@ -63,6 +63,14 @@ header form {
|
|||||||
width: 3em;
|
width: 3em;
|
||||||
height: 2em;
|
height: 2em;
|
||||||
}
|
}
|
||||||
|
#notif {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
background: lightgrey;
|
||||||
|
}
|
||||||
|
#notif li:hover {
|
||||||
|
background: #bcc;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------NAV---------------------------------*/
|
/*---------------------------------NAV---------------------------------*/
|
||||||
nav {
|
nav {
|
||||||
|
@ -39,6 +39,17 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<a href="{{ url('core:user_profile', user_id=user.id) }}">{{ user.get_display_name() }}</a>
|
<a href="{{ url('core:user_profile', user_id=user.id) }}">{{ user.get_display_name() }}</a>
|
||||||
|
{% if user.notifications.exists() %}
|
||||||
|
<a href="#" onclick="display_notif()">🔔 ({{ user.notifications.count() }})</a>
|
||||||
|
<ul id="notif">
|
||||||
|
{% for n in user.notifications.order_by('-id') %}
|
||||||
|
<li><a href="{{ url("core:notification", notif_id=n.id) }}">
|
||||||
|
<span style="font-size: small; ">{{ n.date|date(DATE_FORMAT) }} {{
|
||||||
|
n.date|time(DATETIME_FORMAT) }}</span><br>
|
||||||
|
{{ n.text }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
<a href="{{ url('core:user_tools') }}">{% trans %}Tools{% endtrans %}</a>
|
<a href="{{ url('core:user_tools') }}">{% trans %}Tools{% endtrans %}</a>
|
||||||
<a href="{{ url('core:logout') }}">{% trans %}Logout{% endtrans %}</a>
|
<a href="{{ url('core:logout') }}">{% trans %}Logout{% endtrans %}</a>
|
||||||
<form action="{{ url('core:search') }}" method="GET">
|
<form action="{{ url('core:search') }}" method="GET">
|
||||||
|
@ -4,6 +4,7 @@ from core.views import *
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', index, name='index'),
|
url(r'^$', index, name='index'),
|
||||||
|
url(r'^notification/(?P<notif_id>[0-9]+)$', notification, name='notification'),
|
||||||
|
|
||||||
# Search
|
# Search
|
||||||
url(r'^search/$', search_view, name='search'),
|
url(r'^search/$', search_view, name='search'),
|
||||||
|
@ -16,7 +16,7 @@ from django import forms
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from core.models import SithFile
|
from core.models import SithFile, RealGroup, Notification
|
||||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, can_view, not_found
|
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, can_view, not_found
|
||||||
|
|
||||||
def send_file(request, file_id, file_class=SithFile, file_attr="file"):
|
def send_file(request, file_id, file_class=SithFile, file_attr="file"):
|
||||||
@ -49,11 +49,13 @@ class AddFilesForm(forms.Form):
|
|||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
def process(self, parent, owner, files):
|
def process(self, parent, owner, files):
|
||||||
|
notif = False
|
||||||
try:
|
try:
|
||||||
if self.cleaned_data['folder_name'] != "":
|
if self.cleaned_data['folder_name'] != "":
|
||||||
folder = SithFile(parent=parent, name=self.cleaned_data['folder_name'], owner=owner)
|
folder = SithFile(parent=parent, name=self.cleaned_data['folder_name'], owner=owner)
|
||||||
folder.clean()
|
folder.clean()
|
||||||
folder.save()
|
folder.save()
|
||||||
|
notif = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.add_error(None, _("Error creating folder %(folder_name)s: %(msg)s") %
|
self.add_error(None, _("Error creating folder %(folder_name)s: %(msg)s") %
|
||||||
{'folder_name': self.cleaned_data['folder_name'], 'msg': str(e.message)})
|
{'folder_name': self.cleaned_data['folder_name'], 'msg': str(e.message)})
|
||||||
@ -63,8 +65,15 @@ class AddFilesForm(forms.Form):
|
|||||||
try:
|
try:
|
||||||
new_file.clean()
|
new_file.clean()
|
||||||
new_file.save()
|
new_file.save()
|
||||||
|
notif = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
|
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
|
||||||
|
if notif:
|
||||||
|
for u in RealGroup.objects.filter(id=settings.SITH_SAS_ADMIN_GROUP_ID).first().users.all():
|
||||||
|
if not u.notifications.filter(type="FILE_MODERATION").exists():
|
||||||
|
Notification(user=u, text=_("New files to be moderated"),
|
||||||
|
url=reverse("core:file_moderation"), type="FILE_MODERATION").save()
|
||||||
|
|
||||||
|
|
||||||
class FileListView(ListView):
|
class FileListView(ListView):
|
||||||
template_name = 'core/file_list.jinja'
|
template_name = 'core/file_list.jinja'
|
||||||
|
@ -9,12 +9,19 @@ import os
|
|||||||
import json
|
import json
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from core.models import User
|
from core.models import User, Notification
|
||||||
from club.models import Club
|
from club.models import Club
|
||||||
|
|
||||||
def index(request, context=None):
|
def index(request, context=None):
|
||||||
return render(request, "core/index.jinja")
|
return render(request, "core/index.jinja")
|
||||||
|
|
||||||
|
def notification(request, notif_id):
|
||||||
|
notif = Notification.objects.filter(id=notif_id).first()
|
||||||
|
if notif:
|
||||||
|
notif.delete()
|
||||||
|
return redirect(notif.url)
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
def search_user(query, as_json=False):
|
def search_user(query, as_json=False):
|
||||||
users = []
|
users = []
|
||||||
if query:
|
if query:
|
||||||
|
@ -15,7 +15,7 @@ import datetime
|
|||||||
|
|
||||||
from club.models import Club
|
from club.models import Club
|
||||||
from accounting.models import CurrencyField
|
from accounting.models import CurrencyField
|
||||||
from core.models import Group, User
|
from core.models import Group, User, Notification
|
||||||
from subscription.models import Subscriber, Subscription
|
from subscription.models import Subscriber, Subscription
|
||||||
from subscription.views import get_subscriber
|
from subscription.views import get_subscriber
|
||||||
|
|
||||||
@ -270,6 +270,12 @@ class Refilling(models.Model):
|
|||||||
self.customer.amount += self.amount
|
self.customer.amount += self.amount
|
||||||
self.customer.save()
|
self.customer.save()
|
||||||
self.is_validated = True
|
self.is_validated = True
|
||||||
|
Notification(
|
||||||
|
user=self.customer.user,
|
||||||
|
url=reverse('core:user_account_detail',
|
||||||
|
kwargs={'user_id': self.customer.user.id, 'year': self.date.year, 'month': self.date.month}),
|
||||||
|
text=_("You just refilled of %(amount)s €") % {'amount': self.amount}
|
||||||
|
).save()
|
||||||
super(Refilling, self).save(*args, **kwargs)
|
super(Refilling, self).save(*args, **kwargs)
|
||||||
|
|
||||||
class Selling(models.Model):
|
class Selling(models.Model):
|
||||||
@ -377,6 +383,13 @@ class Selling(models.Model):
|
|||||||
if self.product.eticket:
|
if self.product.eticket:
|
||||||
self.send_mail_customer()
|
self.send_mail_customer()
|
||||||
except: pass
|
except: pass
|
||||||
|
Notification(
|
||||||
|
user=self.customer.user,
|
||||||
|
url=reverse('core:user_account_detail',
|
||||||
|
kwargs={'user_id': self.customer.user.id, 'year': self.date.year, 'month': self.date.month}),
|
||||||
|
text=_("You just bought %(quantity)d %(product_name)s") % {'quantity': self.quantity, 'product_name': self.label}
|
||||||
|
).save()
|
||||||
|
|
||||||
super(Selling, self).save(*args, **kwargs)
|
super(Selling, self).save(*args, **kwargs)
|
||||||
|
|
||||||
class Permanency(models.Model):
|
class Permanency(models.Model):
|
||||||
|
File diff suppressed because it is too large
Load Diff
13
sas/views.py
13
sas/views.py
@ -18,7 +18,7 @@ from PIL import Image
|
|||||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
|
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
|
||||||
from core.views.forms import SelectUser, LoginForm, SelectDate, SelectDateTime
|
from core.views.forms import SelectUser, LoginForm, SelectDate, SelectDateTime
|
||||||
from core.views.files import send_file
|
from core.views.files import send_file
|
||||||
from core.models import SithFile, User
|
from core.models import SithFile, User, Notification, RealGroup
|
||||||
|
|
||||||
from sas.models import Picture, Album, PeoplePictureRelation
|
from sas.models import Picture, Album, PeoplePictureRelation
|
||||||
|
|
||||||
@ -28,11 +28,13 @@ class SASForm(forms.Form):
|
|||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
def process(self, parent, owner, files, automodere=False):
|
def process(self, parent, owner, files, automodere=False):
|
||||||
|
notif = False
|
||||||
try:
|
try:
|
||||||
if self.cleaned_data['album_name'] != "":
|
if self.cleaned_data['album_name'] != "":
|
||||||
album = Album(parent=parent, name=self.cleaned_data['album_name'], owner=owner, is_moderated=automodere)
|
album = Album(parent=parent, name=self.cleaned_data['album_name'], owner=owner, is_moderated=automodere)
|
||||||
album.clean()
|
album.clean()
|
||||||
album.save()
|
album.save()
|
||||||
|
notif = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.add_error(None, _("Error creating album %(album)s: %(msg)s") %
|
self.add_error(None, _("Error creating album %(album)s: %(msg)s") %
|
||||||
{'album': self.cleaned_data['album_name'], 'msg': repr(e)})
|
{'album': self.cleaned_data['album_name'], 'msg': repr(e)})
|
||||||
@ -43,8 +45,14 @@ class SASForm(forms.Form):
|
|||||||
new_file.clean()
|
new_file.clean()
|
||||||
new_file.generate_thumbnails()
|
new_file.generate_thumbnails()
|
||||||
new_file.save()
|
new_file.save()
|
||||||
|
notif = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
|
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
|
||||||
|
if notif:
|
||||||
|
for u in RealGroup.objects.filter(id=settings.SITH_SAS_ADMIN_GROUP_ID).first().users.all():
|
||||||
|
if not u.notifications.filter(type="SAS_MODERATION").exists():
|
||||||
|
Notification(user=u, text=_("New pictures/album to be moderated in the SAS"),
|
||||||
|
url=reverse("sas:moderation"), type="SAS_MODERATION").save()
|
||||||
|
|
||||||
class RelationForm(forms.ModelForm):
|
class RelationForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -115,6 +123,9 @@ class PictureView(CanViewMixin, DetailView, FormMixin):
|
|||||||
u = User.objects.filter(id=uid).first()
|
u = User.objects.filter(id=uid).first()
|
||||||
PeoplePictureRelation(user=u,
|
PeoplePictureRelation(user=u,
|
||||||
picture=self.form.cleaned_data['picture']).save()
|
picture=self.form.cleaned_data['picture']).save()
|
||||||
|
if not u.notifications.filter(type="NEW_PICTURES").exists():
|
||||||
|
Notification(user=u, text=_("You've been identified on some pictures"),
|
||||||
|
url=reverse("core:user_pictures", kwargs={'user_id': u.id}), type="NEW_PICTURES").save()
|
||||||
return super(PictureView, self).form_valid(self.form)
|
return super(PictureView, self).form_valid(self.form)
|
||||||
else:
|
else:
|
||||||
self.form.add_error(None, _("You do not have the permission to do that"))
|
self.form.add_error(None, _("You do not have the permission to do that"))
|
||||||
|
@ -248,6 +248,8 @@ SITH_START_DATE = (8, 15) # 15th August
|
|||||||
# Used to determine the valid promos
|
# Used to determine the valid promos
|
||||||
SITH_SCHOOL_START_YEAR = 1999
|
SITH_SCHOOL_START_YEAR = 1999
|
||||||
|
|
||||||
|
SITH_GROUP_ROOT_ID = 1
|
||||||
|
|
||||||
SITH_GROUPS = {
|
SITH_GROUPS = {
|
||||||
'root': {
|
'root': {
|
||||||
'id': 1,
|
'id': 1,
|
||||||
@ -450,6 +452,12 @@ SITH_LAUNDERETTE_PRICES = {
|
|||||||
SITH_SAS_ROOT_DIR_ID = 4
|
SITH_SAS_ROOT_DIR_ID = 4
|
||||||
SITH_SAS_ADMIN_GROUP_ID = 9
|
SITH_SAS_ADMIN_GROUP_ID = 9
|
||||||
|
|
||||||
|
SITH_NOTIFICATIONS = [
|
||||||
|
('FILE_MODERATION', _("File moderation")),
|
||||||
|
('SAS_MODERATION', _("SAS moderation")),
|
||||||
|
('NEW_PICTURES', _("New pictures")),
|
||||||
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .settings_custom import *
|
from .settings_custom import *
|
||||||
print("Custom settings imported")
|
print("Custom settings imported")
|
||||||
|
Loading…
Reference in New Issue
Block a user