diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index acfff9eb..d32560e5 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -18,6 +18,7 @@ from subscription.models import Subscription from counter.models import Customer, ProductType, Product, Counter from com.models import Sith, Weekmail from election.models import Election, Role, Candidature, ElectionList +from forum.models import Forum, ForumMessage class Command(BaseCommand): @@ -429,3 +430,13 @@ Welcome to the wiki page! cand = Candidature(role=pres, user=sli, election_list=listeT, program="En fait j'aime pas l'info, je voulais faire GMC") cand.save() + # Forum + room = Forum(name="Salon de discussions", description="Pour causer de tout", is_category=True) + room.save() + Forum(name="AE", description="Réservé au bureau AE", parent=room).save() + Forum(name="BdF", description="Réservé au bureau BdF", parent=room).save() + Forum(name="Hall de discussions", description="Pour toutes les discussions", parent=room).save() + various = Forum(name="Divers", description="Pour causer de rien", is_category=True) + various.save() + Forum(name="Promos", description="Réservé aux Promos", parent=various).save() + diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index cc9207c2..542e9f21 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -91,7 +91,7 @@ {% trans %}Matmatronch{% endtrans %} {% trans %}Wiki{% endtrans %} {% trans %}SAS{% endtrans %} - {% trans %}Forum{% endtrans %} + {% trans %}Forum{% endtrans %} {% trans %}Services{% endtrans %} {% trans %}Files{% endtrans %} {% trans %}Sponsors{% endtrans %} diff --git a/forum/__init__.py b/forum/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/forum/admin.py b/forum/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/forum/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/forum/migrations/0001_initial.py b/forum/migrations/0001_initial.py new file mode 100644 index 00000000..da8dbdfc --- /dev/null +++ b/forum/migrations/0001_initial.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('core', '0019_preferences_receive_weekmail'), + ] + + operations = [ + migrations.CreateModel( + name='Forum', + fields=[ + ('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)), + ('name', models.CharField(verbose_name='name', max_length=64)), + ('description', models.CharField(default='', verbose_name='description', max_length=256)), + ('is_category', models.BooleanField(default=False, verbose_name='is a category')), + ('edit_groups', models.ManyToManyField(to='core.Group', blank=True, related_name='editable_forums')), + ('owner_group', models.ForeignKey(to='core.Group', default=4, related_name='owned_forums')), + ('parent', models.ForeignKey(blank=True, null=True, to='forum.Forum', related_name='children')), + ('view_groups', models.ManyToManyField(to='core.Group', blank=True, related_name='viewable_forums')), + ], + ), + migrations.CreateModel( + name='ForumMessage', + fields=[ + ('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)), + ('title', models.CharField(default='', blank=True, verbose_name='title', max_length=64)), + ('message', models.TextField(verbose_name='message', default='')), + ('author', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='forum_messages')), + ], + ), + migrations.CreateModel( + name='ForumTopic', + fields=[ + ('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)), + ('author', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='forum_topics')), + ('forum', models.ForeignKey(to='forum.Forum', related_name='topics')), + ], + ), + migrations.AddField( + model_name='forummessage', + name='topic', + field=models.ForeignKey(to='forum.ForumTopic', related_name='messages'), + ), + ] diff --git a/forum/migrations/0002_forumtopic_title.py b/forum/migrations/0002_forumtopic_title.py new file mode 100644 index 00000000..17407dad --- /dev/null +++ b/forum/migrations/0002_forumtopic_title.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('forum', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='forumtopic', + name='title', + field=models.CharField(verbose_name='title', max_length=64, default=''), + ), + ] diff --git a/forum/migrations/0003_auto_20170121_0311.py b/forum/migrations/0003_auto_20170121_0311.py new file mode 100644 index 00000000..f66151e2 --- /dev/null +++ b/forum/migrations/0003_auto_20170121_0311.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('forum', '0002_forumtopic_title'), + ] + + operations = [ + migrations.AlterModelOptions( + name='forumtopic', + options={'ordering': ['messages__date', '-id']}, + ), + migrations.AddField( + model_name='forummessage', + name='date', + field=models.DateTimeField(verbose_name='date', default=django.utils.timezone.now), + ), + ] diff --git a/forum/migrations/0004_forumtopic_description.py b/forum/migrations/0004_forumtopic_description.py new file mode 100644 index 00000000..b1e3fe96 --- /dev/null +++ b/forum/migrations/0004_forumtopic_description.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('forum', '0003_auto_20170121_0311'), + ] + + operations = [ + migrations.AddField( + model_name='forumtopic', + name='description', + field=models.CharField(max_length=256, verbose_name='description', default=''), + ), + ] diff --git a/forum/migrations/__init__.py b/forum/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/forum/models.py b/forum/models.py new file mode 100644 index 00000000..a9953066 --- /dev/null +++ b/forum/models.py @@ -0,0 +1,79 @@ +from django.db import models +from django.core import validators +from django.conf import settings +from django.utils.translation import ugettext_lazy as _ +from django.core.exceptions import ValidationError +from django.db import IntegrityError, transaction +from django.core.urlresolvers import reverse +from django.utils import timezone + +from core.models import User, MetaGroup, Group, SithFile + +class Forum(models.Model): + """ + The Forum class, made as a tree to allow nice tidy organization + """ + name = models.CharField(_('name'), max_length=64) + description = models.CharField(_('description'), max_length=256, default="") + is_category = models.BooleanField(_('is a category'), default=False) + parent = models.ForeignKey('Forum', related_name='children', null=True, blank=True) + owner_group = models.ForeignKey(Group, related_name="owned_forums", + default=settings.SITH_GROUP_COM_ADMIN_ID) + edit_groups = models.ManyToManyField(Group, related_name="editable_forums", blank=True) + view_groups = models.ManyToManyField(Group, related_name="viewable_forums", blank=True) + + def check_loop(self): + """Raise a validation error when a loop is found within the parent list""" + objs = [] + cur = self + while cur.parent is not None: + if cur in objs: + raise ValidationError(_('You can not make loops in forums')) + objs.append(cur) + cur = cur.parent + + def clean(self): + self.check_loop() + + def __str__(self): + return "%s" % (self.name) + + def get_absolute_url(self): + return reverse('forum:view_forum', kwargs={'forum_id': self.id}) + + def get_parent_list(self): + l = [] + p = self.parent + while p is not None: + l.append(p) + p = p.parent + return l + +class ForumTopic(models.Model): + forum = models.ForeignKey(Forum, related_name='topics') + author = models.ForeignKey(User, related_name='forum_topics') + title = models.CharField(_("title"), default="", max_length=64) + description = models.CharField(_('description'), max_length=256, default="") + + class Meta: + ordering = ['-id'] + + def get_absolute_url(self): + return reverse('forum:view_topic', kwargs={'topic_id': self.id}) + +class ForumMessage(models.Model): + """ + "A ForumMessage object is a message in the forum" Cpt. Obvious + """ + topic = models.ForeignKey(ForumTopic, related_name='messages') + author = models.ForeignKey(User, related_name='forum_messages') + title = models.CharField(_("title"), default="", max_length=64, blank=True) + message = models.TextField(_("message"), default="") + date = models.DateTimeField(_('date'), default=timezone.now) + + class Meta: + ordering = ['-id'] + + def get_absolute_url(self): + return self.topic.get_absolute_url() + diff --git a/forum/templates/forum/forum.jinja b/forum/templates/forum/forum.jinja new file mode 100644 index 00000000..6b0fa851 --- /dev/null +++ b/forum/templates/forum/forum.jinja @@ -0,0 +1,44 @@ +{% extends "core/base.jinja" %} +{% from 'forum/macros.jinja' import display_forum %} + +{% block head %} +{{ super() }} + +{% endblock %} + +{% block content %} +
{{ forum.get_parent_list() }}
++ {% if not forum.is_category %} + View + {% endif %} + Edit +
+{{ forum.description }}
+{{ topic.description }}
+ + {% for m in topic.messages.all() %} +{{ m.author.get_display_name() }} - {{ m.date|date(DATETIME_FORMAT) }} + {{ m.date|time(DATETIME_FORMAT) }} - + Reply as quote
+{{ m.message|markdown }}
+