diff --git a/club/migrations/0008_auto_20170515_2214.py b/club/migrations/0008_auto_20170515_2214.py
new file mode 100644
index 00000000..48f5b3b6
--- /dev/null
+++ b/club/migrations/0008_auto_20170515_2214.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('club', '0007_auto_20170324_0917'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='club',
+ name='id',
+ field=models.AutoField(primary_key=True, serialize=False, db_index=True),
+ ),
+ ]
diff --git a/club/models.py b/club/models.py
index 587dd56c..4f1f4852 100644
--- a/club/models.py
+++ b/club/models.py
@@ -39,6 +39,7 @@ class Club(models.Model):
"""
The Club class, made as a tree to allow nice tidy organization
"""
+ id = models.AutoField(primary_key=True, db_index=True)
name = models.CharField(_('name'), max_length=64)
parent = models.ForeignKey('Club', related_name='children', null=True, blank=True)
unix_name = models.CharField(_('unix name'), max_length=30, unique=True,
@@ -151,11 +152,21 @@ class Club(models.Model):
return False
return sub.is_subscribed
+ _memberships = {}
def get_membership_for(self, user):
"""
Returns the current membership the given user
"""
- return self.members.filter(user=user.id).filter(end_date=None).first()
+ try:
+ return Club._memberships[self.id][user.id]
+ except:
+ m = self.members.filter(user=user.id).filter(end_date=None).first()
+ try:
+ Club._memberships[self.id][user.id] = m
+ except:
+ Club._memberships[self.id] = {}
+ Club._memberships[self.id][user.id] = m
+ return m
class Membership(models.Model):
"""
diff --git a/core/__init__.py b/core/__init__.py
index 0a9419f8..ffb9c1e7 100644
--- a/core/__init__.py
+++ b/core/__init__.py
@@ -22,3 +22,4 @@
#
#
+default_app_config = 'core.apps.SithConfig'
diff --git a/core/apps.py b/core/apps.py
new file mode 100644
index 00000000..88702ff5
--- /dev/null
+++ b/core/apps.py
@@ -0,0 +1,57 @@
+# -*- coding:utf-8 -*
+#
+# Copyright 2017
+# - Skia
+#
+# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
+# http://ae.utbm.fr.
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License a published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
+# Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+
+from django.apps import AppConfig
+from django.dispatch import receiver
+from django.db.models.signals import pre_save, post_save, m2m_changed
+
+class SithConfig(AppConfig):
+ name = 'core'
+ verbose_name = "Core app of the Sith"
+
+ def ready(self):
+ from core.models import User, Group
+ from club.models import Club, Membership
+ from forum.models import Forum
+
+ def clear_cached_groups(sender, **kwargs):
+ if kwargs['model'] == Group:
+ User._group_ids = {}
+ User._group_name = {}
+
+ def clear_cached_memberships(sender, **kwargs):
+ User._club_memberships = {}
+ Club._memberships = {}
+ Forum._club_memberships = {}
+
+ print("Connecting signals!")
+ m2m_changed.connect(clear_cached_groups, weak=False, dispatch_uid="clear_cached_groups")
+ post_save.connect(clear_cached_memberships, weak=False, sender=Membership, # Membership is cached
+ dispatch_uid="clear_cached_memberships_membership")
+ post_save.connect(clear_cached_memberships, weak=False, sender=Club, # Club has a cache of Membership
+ dispatch_uid="clear_cached_memberships_club")
+ post_save.connect(clear_cached_memberships, weak=False, sender=Forum, # Forum has a cache of Membership
+ dispatch_uid="clear_cached_memberships_forum")
+ # TODO: there may be a need to add more cache clearing
+
diff --git a/core/models.py b/core/models.py
index 809224a8..dcf1202e 100644
--- a/core/models.py
+++ b/core/models.py
@@ -223,14 +223,25 @@ class User(AbstractBaseUser):
s = self.subscriptions.last()
return s.is_valid_now() if s is not None else False
+ _club_memberships = {}
+ _group_names = {}
+ _group_ids = {}
def is_in_group(self, group_name):
"""If the user is in the group passed in argument (as string or by id)"""
group_id = 0
g = None
if isinstance(group_name, int): # Handle the case where group_name is an ID
- g = Group.objects.filter(id=group_name).first()
+ if group_name in User._group_ids.keys():
+ g = User._group_ids[group_name]
+ else:
+ g = Group.objects.filter(id=group_name).first()
+ User._group_ids[group_name] = g
else:
- g = Group.objects.filter(name=group_name).first()
+ if group_name in User._group_names.keys():
+ g = User._group_names[group_name]
+ else:
+ g = Group.objects.filter(name=group_name).first()
+ User._group_names[group_name] = g
if g:
group_name = g.name
group_id = g.id
@@ -245,18 +256,26 @@ class User(AbstractBaseUser):
if group_name == settings.SITH_MAIN_MEMBERS_GROUP: # We check the subscription if asked
return self.is_subscribed
if group_name[-len(settings.SITH_BOARD_SUFFIX):] == settings.SITH_BOARD_SUFFIX:
- from club.models import Club
name = group_name[:-len(settings.SITH_BOARD_SUFFIX)]
- c = Club.objects.filter(unix_name=name).first()
- mem = c.get_membership_for(self)
+ if name in User._club_memberships.keys():
+ mem = User._club_memberships[name]
+ else:
+ from club.models import Club
+ c = Club.objects.filter(unix_name=name).first()
+ mem = c.get_membership_for(self)
+ User._club_memberships[name] = mem
if mem:
return mem.role > settings.SITH_MAXIMUM_FREE_ROLE
return False
if group_name[-len(settings.SITH_MEMBER_SUFFIX):] == settings.SITH_MEMBER_SUFFIX:
- from club.models import Club
name = group_name[:-len(settings.SITH_MEMBER_SUFFIX)]
- c = Club.objects.filter(unix_name=name).first()
- mem = c.get_membership_for(self)
+ if name in User._club_memberships.keys():
+ mem = User._club_memberships[name]
+ else:
+ from club.models import Club
+ c = Club.objects.filter(unix_name=name).first()
+ mem = c.get_membership_for(self)
+ User._club_memberships[name] = mem
if mem:
return True
return False
diff --git a/core/static/core/style.scss b/core/static/core/style.scss
index 5db187ad..dc5e4eeb 100644
--- a/core/static/core/style.scss
+++ b/core/static/core/style.scss
@@ -48,8 +48,8 @@ a {
.ib {
display: inline-block;
- padding: 2px;
- margin: 2px;
+ padding: 1px;
+ margin: 1px;
}
.w_big {
@@ -57,11 +57,11 @@ a {
}
.w_medium {
- width: 45%;
+ width: 47%;
}
.w_small {
- width: 20%;
+ width: 23%;
}
/*--------------------------------HEADER-------------------------------*/
@@ -271,11 +271,15 @@ code {
}
blockquote {
- margin: 10px;
- padding: 5px;
+ margin: 5px;
+ padding: 2px;
border: solid 1px $black-color;
}
+blockquote h5:first-child {
+ font-size: 100%;
+}
+
.edit-bar {
display: block;
margin: 4px;
@@ -498,86 +502,132 @@ textarea {
/*------------------------------FORUM----------------------------------*/
-.topic a, .forum a, .category a {
- color: $black-color;
-}
-
-.topic a:hover, .forum a:hover, .category a:hover {
- color: #424242;
- text-decoration: underline;
-}
-
-.topic {
- border: solid $primary-neutral-color 1px;
- padding: 2px;
- margin: 2px;
-}
-
-.forum {
- background: $primary-neutral-light-color;
- padding: 2px;
- margin: 2px;
-}
-
-.category {
- background: $secondary-color;
-}
-
-.message {
- padding: 2px;
- margin: 2px;
- background: $white-color;
- &:nth-child(odd) {
- background: $primary-neutral-light-color;
- }
- h5 {
- font-size: 100%;
- }
- &.unread {
- background: #d8e7f3;
- }
-}
-
-.msg_author.deleted {
- background: #ffcfcf;
-}
-
-.msg_content {
- &.deleted {
- background: #ffefef;
- }
- display: inline-block;
- width: 80%;
- vertical-align: top;
-}
-
-.msg_author {
- display: inline-block;
- width: 19%;
- text-align: center;
- background: $primary-light-color;
- img {
- max-width: 70%;
- margin: 0px auto;
- }
-}
-
-.msg_meta {
- font-size: small;
- list-style-type: none;
- li {
- padding: 2px;
- margin: 2px;
- }
-}
-
-.forum_signature {
- color: #C0C0C0;
- border-top: 1px solid #C0C0C0;
+#forum {
a {
+ color: $black-color;
+ }
+
+ a:hover {
+ color: #424242;
+ text-decoration: underline;
+ }
+
+ .topic {
+ border: solid $primary-neutral-color 1px;
+ padding: 1px;
+ margin: 1px;
+ p {
+ margin: 1px;
+ font-size: smaller;
+ }
+ }
+
+ .tools {
+ font-size: x-small;
+ border: none;
+ a {
+ padding: 1px;
+ }
+ }
+
+ .title {
+ font-size: small;
+ font-weight: bold;
+ padding: 2px;
+ }
+
+ .last_message date {
+ white-space: nowrap;
+ }
+
+ .last_message span {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow:hidden;
+ width: 100%;
+ display: block;
+ }
+
+ .forum {
+ background: $primary-neutral-light-color;
+ padding: 1px;
+ margin: 1px;
+ p {
+ margin: 1px;
+ font-size: smaller;
+ }
+ }
+
+ .category {
+ margin-top: 5px;
+ background: $secondary-color;
+ .title {
+ text-transform: uppercase;
+ }
+ }
+
+ .message {
+ padding: 1px;
+ margin: 1px;
+ background: $white-color;
+ &:nth-child(odd) {
+ background: $primary-neutral-light-color;
+ }
+ .title {
+ font-size: 100%;
+ }
+ &.unread {
+ background: #d8e7f3;
+ }
+ }
+
+ .msg_author.deleted {
+ background: #ffcfcf;
+ }
+
+ .msg_content {
+ &.deleted {
+ background: #ffefef;
+ }
+ display: inline-block;
+ width: 80%;
+ vertical-align: top;
+ }
+
+ .msg_author {
+ display: inline-block;
+ width: 19%;
+ text-align: center;
+ background: $primary-light-color;
+ img {
+ max-width: 70%;
+ margin: 0px auto;
+ }
+ }
+
+ .msg_header {
+ display: inline-block;
+ width: 100%;
+ font-size: small;
+ }
+
+ .msg_meta {
+ font-size: small;
+ list-style-type: none;
+ li {
+ padding: 1px;
+ margin: 1px;
+ }
+ }
+
+ .forum_signature {
color: #C0C0C0;
- &:hover {
- text-decoration: underline;
+ border-top: 1px solid #C0C0C0;
+ a {
+ color: #C0C0C0;
+ &:hover {
+ text-decoration: underline;
+ }
}
}
}
diff --git a/core/templates/core/macros.jinja b/core/templates/core/macros.jinja
index 6239c695..244617c5 100644
--- a/core/templates/core/macros.jinja
+++ b/core/templates/core/macros.jinja
@@ -2,6 +2,10 @@
{{ user.get_display_name() }}
{%- endmacro %}
+{% macro user_profile_link_short_name(user) -%}
+{{ user.get_short_name() }}
+{%- endmacro %}
+
{% macro user_link_with_pict(user) -%}
{{ user.get_mini_item()|safe }}
diff --git a/core/templates/core/doku_to_markdown.jinja b/core/templates/core/to_markdown.jinja
similarity index 70%
rename from core/templates/core/doku_to_markdown.jinja
rename to core/templates/core/to_markdown.jinja
index ede16ee5..85ef0a71 100644
--- a/core/templates/core/doku_to_markdown.jinja
+++ b/core/templates/core/to_markdown.jinja
@@ -1,12 +1,14 @@
{% extends "core/base.jinja" %}
{% block title %}
-{% trans %}Doku to Markdown{% endtrans %}
+{% trans %}To Markdown{% endtrans %}
{% endblock %}
{% block content %}
+
{% endblock %}
diff --git a/forum/templates/forum/macros.jinja b/forum/templates/forum/macros.jinja
index d8b529f7..c8331d1d 100644
--- a/forum/templates/forum/macros.jinja
+++ b/forum/templates/forum/macros.jinja
@@ -1,37 +1,43 @@
-{% from 'core/macros.jinja' import user_profile_link %}
+{% from 'core/macros.jinja' import user_profile_link_short_name %}
-{% macro display_forum(forum, user) %}
-
+{% macro display_forum(forum, user, is_root=False) %}
+
- {% if not forum.is_category %}
+ {% if not is_root %}
-
+
{{ forum.topic_number }}
-
-
-
- {% if m.title %}
-
{{ m.title }}
- {% endif %}
-
-