From fe69cbcee1a0dcf7ba60e6fa82769cdb9ea953f9 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Tue, 12 Sep 2017 21:10:32 +0200 Subject: [PATCH 01/16] Add page for clubs and inactive clubs --- api/views/club.py | 2 +- club/migrations/0010_auto_20170912_2028.py | 32 ++++++++++++++++++++++ club/models.py | 25 +++++++++++++++-- club/templates/club/club_detail.jinja | 4 +++ club/views.py | 8 +++++- core/management/commands/populate.py | 4 +++ core/models.py | 5 ++++ core/templates/core/page.jinja | 6 +++- core/templates/core/page_prop.jinja | 6 ++++ core/templates/core/pagerev_edit.jinja | 1 - core/views/forms.py | 14 ++++++++++ core/views/page.py | 31 ++++++++++----------- migrate.py | 14 +++++++++- sith/settings.py | 3 ++ 14 files changed, 132 insertions(+), 23 deletions(-) create mode 100644 club/migrations/0010_auto_20170912_2028.py diff --git a/api/views/club.py b/api/views/club.py index ca2a8c1b..42d70eb6 100644 --- a/api/views/club.py +++ b/api/views/club.py @@ -58,6 +58,6 @@ def FetchMailingLists(request): if key != settings.SITH_MAILING_FETCH_KEY: raise PermissionDenied data = '' - for mailing in Mailing.objects.filter(is_moderated=True).all(): + for mailing in Mailing.objects.filter(is_moderated=True, club__is_active=False).all(): data += mailing.fetch_format() + "\n" return Response(data) diff --git a/club/migrations/0010_auto_20170912_2028.py b/club/migrations/0010_auto_20170912_2028.py new file mode 100644 index 00000000..71bd639b --- /dev/null +++ b/club/migrations/0010_auto_20170912_2028.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +from club.models import Club + + +def generate_club_pages(apps, schema_editor): + for club in Club.objects.all(): + club.make_page() + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0024_auto_20170906_1317'), + ('club', '0009_auto_20170822_2232'), + ] + + operations = [ + migrations.AddField( + model_name='club', + name='is_active', + field=models.BooleanField(default=True, verbose_name='is active'), + ), + migrations.AddField( + model_name='club', + name='page', + field=models.OneToOneField(related_name='club', blank=True, null=True, to='core.Page'), + ), + migrations.RunPython(generate_club_pages), + ] diff --git a/club/models.py b/club/models.py index d2901505..0b51e830 100644 --- a/club/models.py +++ b/club/models.py @@ -33,11 +33,11 @@ from django.core.urlresolvers import reverse from django.utils import timezone from django.core.validators import RegexValidator, validate_email -from core.models import User, MetaGroup, Group, SithFile, RealGroup, Notification - +from core.models import User, MetaGroup, Group, SithFile, RealGroup, Notification, Page # Create your models here. + class Club(models.Model): """ The Club class, made as a tree to allow nice tidy organization @@ -58,6 +58,7 @@ class Club(models.Model): }, ) logo = models.ImageField(upload_to='club_logos', verbose_name=_('logo'), null=True, blank=True) + is_active = models.BooleanField(_('is active'), default=True) address = models.CharField(_('address'), max_length=254) # email = models.EmailField(_('email address'), unique=True) # This should, and will be generated automatically owner_group = models.ForeignKey(Group, related_name="owned_club", @@ -66,6 +67,7 @@ class Club(models.Model): view_groups = models.ManyToManyField(Group, related_name="viewable_club", blank=True) home = models.OneToOneField(SithFile, related_name='home_of_club', verbose_name=_("home"), null=True, blank=True, on_delete=models.SET_NULL) + page = models.OneToOneField(Page, related_name="club", blank=True, null=True) class Meta: ordering = ['name', 'unix_name'] @@ -102,6 +104,24 @@ class Club(models.Model): self.home = home self.save() + def make_page(self): + if not self.page: + root = User.objects.filter(username="root").first() + club_root = Page.objects.filter(name=settings.SITH_CLUB_ROOT_PAGE).first() + if root and club_root: + public = Group.objects.filter(id=settings.SITH_GROUP_PUBLIC_ID).first() + office = Group.objects.filter(name=self.unix_name + settings.SITH_BOARD_SUFFIX).first() + p = Page(name=self.unix_name) + p.parent = club_root + p.set_lock(root) + if public: + p.view_groups.add(public) + if office: + p.edit_groups.add(office) + p.save() + self.page = p + self.save() + def save(self, *args, **kwargs): with transaction.atomic(): creation = False @@ -122,6 +142,7 @@ class Club(models.Model): self.home.edit_groups = [board] self.home.view_groups = [member, subscribers] self.home.save() + self.make_page() def __str__(self): return self.name diff --git a/club/templates/club/club_detail.jinja b/club/templates/club/club_detail.jinja index daedbfcb..492ab30b 100644 --- a/club/templates/club/club_detail.jinja +++ b/club/templates/club/club_detail.jinja @@ -2,7 +2,11 @@ {% from 'core/macros.jinja' import user_profile_link %} {% block content %} + {% if club.page and club.page.revisions.exists() %} + {{ club.page.revisions.last().content|markdown }} + {% else %}

{% trans %}Club{% endtrans %}

+ {% endif %} {% endblock %} diff --git a/club/views.py b/club/views.py index a8206fe6..8ec785be 100644 --- a/club/views.py +++ b/club/views.py @@ -117,6 +117,12 @@ class ClubTabsMixin(TabedViewMixin): 'slug': 'edit', 'name': _("Edit"), }) + if self.object.page: + tab_list.append({ + 'url': reverse('core:page_edit', kwargs={'page_name': self.object.page.get_full_name()}), + 'slug': 'page_edit', + 'name': _('Edit club page') + }) tab_list.append({ 'url': reverse('club:club_sellings', kwargs={'club_id': self.object.id}), 'slug': 'sellings', @@ -348,7 +354,7 @@ class ClubEditPropView(ClubTabsMixin, CanEditPropMixin, UpdateView): """ model = Club pk_url_kwarg = "club_id" - fields = ['name', 'unix_name', 'parent'] + fields = ['name', 'unix_name', 'parent', 'is_active'] template_name = 'core/edit.jinja' current_tab = "props" diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index 108a1fb5..2b870a38 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -147,6 +147,10 @@ Welcome to the wiki page! p.set_lock(root) PageRev(page=p, title="Laverie", author=root, content="Fonctionnement de la laverie").save() + p = Page(name=settings.SITH_CLUB_ROOT_PAGE) + p.set_lock(root) + p.save() + # Here we add a lot of test datas, that are not necessary for the Sith, but that provide a basic development environment if not options['prod']: # Adding user Skia diff --git a/core/models.py b/core/models.py index 8573fd4a..72e5a658 100644 --- a/core/models.py +++ b/core/models.py @@ -999,6 +999,11 @@ class Page(models.Model): except: return self.name + @property + def is_club_page(self): + unauthorized_parent = Page.objects.filter(name=settings.SITH_CLUB_ROOT_PAGE).first() + return unauthorized_parent is not None and (self == unauthorized_parent or unauthorized_parent in self.get_parent_list()) + def delete(self): self.unset_lock_recursive() self.set_lock_recursive(User.objects.get(id=0)) diff --git a/core/templates/core/page.jinja b/core/templates/core/page.jinja index 1e3d2368..a0acf036 100644 --- a/core/templates/core/page.jinja +++ b/core/templates/core/page.jinja @@ -25,12 +25,16 @@
{% if page %} + {% if page.club %} + {% trans %}View{% endtrans %} + {% else %} {% trans %}View{% endtrans %} + {% endif %} {% trans %}History{% endtrans %} {% if can_edit(page, user) %} {% trans %}Edit{% endtrans %} {% endif %} - {% if can_edit_prop(page, user) %} + {% if can_edit_prop(page, user) and not page.is_club_page %} {% trans %}Prop{% endtrans %} {% endif %} {% endif %} diff --git a/core/templates/core/page_prop.jinja b/core/templates/core/page_prop.jinja index 9f144cbb..9207f52c 100644 --- a/core/templates/core/page_prop.jinja +++ b/core/templates/core/page_prop.jinja @@ -1,12 +1,18 @@ {% extends "core/page.jinja" %} {% block content %} +{% if page %} +{{ super() }} +{% endif %}

{% trans %}Page properties{% endtrans %}

{% csrf_token %} {{ form.as_p() }}

+{% if page %} +{% trans %}Delete{% endtrans %} +{% endif %} {% endblock %} diff --git a/core/templates/core/pagerev_edit.jinja b/core/templates/core/pagerev_edit.jinja index 1cab48cb..a91c0d04 100644 --- a/core/templates/core/pagerev_edit.jinja +++ b/core/templates/core/pagerev_edit.jinja @@ -25,7 +25,6 @@ function make_preview() {

-{% trans %}Delete{% endtrans %}
{% endblock %} diff --git a/core/views/forms.py b/core/views/forms.py index 0bf40cd8..8770df79 100644 --- a/core/views/forms.py +++ b/core/views/forms.py @@ -269,3 +269,17 @@ class PagePropForm(forms.ModelForm): super(PagePropForm, self).__init__(*arg, **kwargs) self.fields['edit_groups'].required = False self.fields['view_groups'].required = False + + +class PageForm(forms.ModelForm): + class Meta: + model = Page + fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups'] + widgets = { + 'edit_groups': CheckboxSelectMultiple, + 'view_groups': CheckboxSelectMultiple, + } + + def __init__(self, *args, **kwargs): + super(PageForm, self).__init__(*args, **kwargs) + self.fields['parent'].queryset = self.fields['parent'].queryset.exclude(name=settings.SITH_CLUB_ROOT_PAGE).filter(club=None) diff --git a/core/views/page.py b/core/views/page.py index 9c6cfc37..64028fc5 100644 --- a/core/views/page.py +++ b/core/views/page.py @@ -27,13 +27,22 @@ from django.core.urlresolvers import reverse_lazy from django.views.generic import ListView, DetailView from django.views.generic.edit import UpdateView, CreateView, DeleteView from django.forms.models import modelform_factory -from django.forms import CheckboxSelectMultiple +from django.http import Http404 from core.models import Page, PageRev, LockError -from core.views.forms import MarkdownInput +from core.views.forms import MarkdownInput, PageForm, PagePropForm from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin +class CanEditPagePropMixin(CanEditPropMixin): + + def dispatch(self, request, *args, **kwargs): + res = super(CanEditPagePropMixin, self).dispatch(request, *args, **kwargs) + if self.object.is_club_page: + raise Http404 + return res + + class PageListView(CanViewMixin, ListView): model = Page template_name = 'core/page_list.jinja' @@ -88,12 +97,7 @@ class PageRevView(CanViewMixin, DetailView): class PageCreateView(CanCreateMixin, CreateView): model = Page - form_class = modelform_factory(Page, - fields=['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ], - widgets={ - 'edit_groups': CheckboxSelectMultiple, - 'view_groups': CheckboxSelectMultiple, - }) + form_class = PageForm template_name = 'core/page_prop.jinja' def get_initial(self): @@ -118,14 +122,9 @@ class PageCreateView(CanCreateMixin, CreateView): return ret -class PagePropView(CanEditPropMixin, UpdateView): +class PagePropView(CanEditPagePropMixin, UpdateView): model = Page - form_class = modelform_factory(Page, - fields=['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ], - widgets={ - 'edit_groups': CheckboxSelectMultiple, - 'view_groups': CheckboxSelectMultiple, - }) + form_class = PagePropForm template_name = 'core/page_prop.jinja' slug_field = '_full_name' slug_url_kwarg = 'page_name' @@ -189,7 +188,7 @@ class PageEditView(CanEditMixin, UpdateView): return super(PageEditView, self).form_valid(form) -class PageDeleteView(CanEditPropMixin, DeleteView): +class PageDeleteView(CanEditPagePropMixin, DeleteView): model = Page template_name = 'core/delete_confirm.jinja' pk_url_kwarg = 'page_id' diff --git a/migrate.py b/migrate.py index ce1ad397..3a2fbe33 100644 --- a/migrate.py +++ b/migrate.py @@ -1375,6 +1375,17 @@ def migrate_mailings(): MailingSubscription(mailing=mailing, email=to_unicode(mailing_sub['email'])).save() +def migrate_club_again(): + cur = db.cursor(MySQLdb.cursors.SSDictCursor) + cur.execute("SELECT * FROM asso") + + for club in cur: + try: + c = Club.objects.get(id=club['id_asso']) + c.is_disabled = club['hidden'] == 1 + except: pass + + def main(): print("Start at %s" % start) # Core @@ -1396,7 +1407,8 @@ def main(): # reset_sas_moderators() # migrate_forum() # reset_index('forum') - migrate_mailings() + # migrate_mailings() + migrate_club_again() end = datetime.datetime.now() print("End at %s" % end) print("Running time: %s" % (end - start)) diff --git a/sith/settings.py b/sith/settings.py index 4fc5e7fb..978ca479 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -296,6 +296,9 @@ SITH_LAUNDERETTE_MANAGER = { 'address': "6 Boulevard Anatole France, 90000 Belfort" } +# Main root for club pages +SITH_CLUB_ROOT_PAGE = "clubs" + # Define the date in the year serving as reference for the subscriptions calendar # (month, day) SITH_START_DATE = (8, 15) # 15th August From 939146bddd4e7c25ca241d49808198728b2ab190 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Wed, 13 Sep 2017 11:20:55 +0200 Subject: [PATCH 02/16] Sync pages with club unix_name --- club/models.py | 12 +++++++----- core/management/commands/populate.py | 10 ++++++---- core/models.py | 6 ++++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/club/models.py b/club/models.py index 0b51e830..09f11134 100644 --- a/club/models.py +++ b/club/models.py @@ -105,22 +105,24 @@ class Club(models.Model): self.save() def make_page(self): + root = User.objects.filter(username="root").first() if not self.page: - root = User.objects.filter(username="root").first() club_root = Page.objects.filter(name=settings.SITH_CLUB_ROOT_PAGE).first() if root and club_root: public = Group.objects.filter(id=settings.SITH_GROUP_PUBLIC_ID).first() - office = Group.objects.filter(name=self.unix_name + settings.SITH_BOARD_SUFFIX).first() p = Page(name=self.unix_name) p.parent = club_root p.set_lock(root) if public: p.view_groups.add(public) - if office: - p.edit_groups.add(office) p.save() self.page = p self.save() + elif self.page and self.page.name != self.unix_name: + self.page.unset_lock() + self.page.set_lock(root) + self.page.name = self.unix_name + self.page.save() def save(self, *args, **kwargs): with transaction.atomic(): @@ -142,7 +144,7 @@ class Club(models.Model): self.home.edit_groups = [board] self.home.view_groups = [member, subscribers] self.home.save() - self.make_page() + self.make_page() def __str__(self): return self.name diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index 2b870a38..579a58ca 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -85,6 +85,12 @@ class Command(BaseCommand): profiles_root.save() home_root = SithFile(parent=None, name="users", is_folder=True, owner=root) home_root.save() + + # Page needed for club creation + p = Page(name=settings.SITH_CLUB_ROOT_PAGE) + p.set_lock(root) + p.save() + club_root = SithFile(parent=None, name="clubs", is_folder=True, owner=root) club_root.save() SithFile(parent=None, name="SAS", is_folder=True, owner=root).save() @@ -147,10 +153,6 @@ Welcome to the wiki page! p.set_lock(root) PageRev(page=p, title="Laverie", author=root, content="Fonctionnement de la laverie").save() - p = Page(name=settings.SITH_CLUB_ROOT_PAGE) - p.set_lock(root) - p.save() - # Here we add a lot of test datas, that are not necessary for the Sith, but that provide a basic development environment if not options['prod']: # Adding user Skia diff --git a/core/models.py b/core/models.py index 72e5a658..c6d7c997 100644 --- a/core/models.py +++ b/core/models.py @@ -892,6 +892,12 @@ class Page(models.Model): code='loop', ) + def can_be_edited_by(self, user): + if self.is_club_page and self.club.can_be_edited_by(user): + # Override normal behavior for clubs + return True + return False + def get_parent_list(self): l = [] p = self.parent From e2078a8c15f7dd3f8af8eae0a488d30e3799117f Mon Sep 17 00:00:00 2001 From: klmp200 Date: Wed, 13 Sep 2017 16:51:34 +0200 Subject: [PATCH 03/16] Sync club pages with club tree --- club/models.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/club/models.py b/club/models.py index 09f11134..235de34a 100644 --- a/club/models.py +++ b/club/models.py @@ -116,6 +116,8 @@ class Club(models.Model): if public: p.view_groups.add(public) p.save() + if self.parent and self.parent.page: + p.parent = self.parent.page self.page = p self.save() elif self.page and self.page.name != self.unix_name: @@ -123,6 +125,11 @@ class Club(models.Model): self.page.set_lock(root) self.page.name = self.unix_name self.page.save() + elif self.page and self.parent and self.parent.page and self.page.parent != self.parent.page: + self.page.unset_lock() + self.page.set_lock(root) + self.page.parent = self.parent.page + self.page.save() def save(self, *args, **kwargs): with transaction.atomic(): From aa49b2d4ce286d328af3846ffa78fb038db3157c Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 17 Sep 2017 14:59:50 +0200 Subject: [PATCH 04/16] Fix regex for pages --- club/migrations/0010_auto_20170912_2028.py | 8 +++++++- core/models.py | 2 +- core/urls.py | 10 +++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/club/migrations/0010_auto_20170912_2028.py b/club/migrations/0010_auto_20170912_2028.py index 71bd639b..d80a4cb6 100644 --- a/club/migrations/0010_auto_20170912_2028.py +++ b/club/migrations/0010_auto_20170912_2028.py @@ -6,8 +6,12 @@ from club.models import Club def generate_club_pages(apps, schema_editor): - for club in Club.objects.all(): + def recursive_generate_club_page(club): club.make_page() + for child in Club.objects.filter(parent=club).all(): + recursive_generate_club_page(child) + for club in Club.objects.filter(parent=None).all(): + recursive_generate_club_page(club) class Migration(migrations.Migration): @@ -28,5 +32,7 @@ class Migration(migrations.Migration): name='page', field=models.OneToOneField(related_name='club', blank=True, null=True, to='core.Page'), ), + migrations.RunSQL('SET CONSTRAINTS ALL IMMEDIATE', reverse_sql=migrations.RunSQL.noop), migrations.RunPython(generate_club_pages), + migrations.RunSQL(migrations.RunSQL.noop, reverse_sql='SET CONSTRAINTS ALL IMMEDIATE'), ] diff --git a/core/models.py b/core/models.py index c6d7c997..f7972863 100644 --- a/core/models.py +++ b/core/models.py @@ -841,7 +841,7 @@ class Page(models.Model): name = models.CharField(_('page unix name'), max_length=30, validators=[ validators.RegexValidator( - r'^[A-z.+-]+$', + r'^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$', _('Enter a valid page name. This value may contain only ' 'unaccented letters, numbers ' 'and ./+/-/_ characters.') ), ], diff --git a/core/urls.py b/core/urls.py index 9242eee5..27a63070 100644 --- a/core/urls.py +++ b/core/urls.py @@ -87,9 +87,9 @@ urlpatterns = [ url(r'^page/$', PageListView.as_view(), name='page_list'), url(r'^page/create$', PageCreateView.as_view(), name='page_new'), url(r'^page/(?P[0-9]*)/delete$', PageDeleteView.as_view(), name='page_delete'), - url(r'^page/(?P[a-z0-9/-_]*)/edit$', PageEditView.as_view(), name='page_edit'), - url(r'^page/(?P[a-z0-9/-_]*)/prop$', PagePropView.as_view(), name='page_prop'), - url(r'^page/(?P[a-z0-9/-_]*)/hist$', PageHistView.as_view(), name='page_hist'), - url(r'^page/(?P[a-z0-9/-_]*)/rev/(?P[0-9]+)/', PageRevView.as_view(), name='page_rev'), - url(r'^page/(?P[a-z0-9/-_]*)/$', PageView.as_view(), name='page'), + url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/edit$', PageEditView.as_view(), name='page_edit'), + url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/prop$', PagePropView.as_view(), name='page_prop'), + url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/hist$', PageHistView.as_view(), name='page_hist'), + url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/rev/(?P[0-9]+)/', PageRevView.as_view(), name='page_rev'), + url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/$', PageView.as_view(), name='page'), ] From 12c49b285a6afd355eb6e9c5c1e9b85316377dd9 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 17 Sep 2017 17:35:47 +0200 Subject: [PATCH 05/16] Fix page permissions and fix migration when on sqlite backend --- club/migrations/0010_auto_20170912_2028.py | 6 ++-- core/models.py | 2 +- core/operations.py | 32 ++++++++++++++++++++++ core/urls.py | 10 +++---- 4 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 core/operations.py diff --git a/club/migrations/0010_auto_20170912_2028.py b/club/migrations/0010_auto_20170912_2028.py index d80a4cb6..06cad259 100644 --- a/club/migrations/0010_auto_20170912_2028.py +++ b/club/migrations/0010_auto_20170912_2028.py @@ -2,7 +2,9 @@ from __future__ import unicode_literals from django.db import migrations, models + from club.models import Club +from core.operations import PsqlRunOnly def generate_club_pages(apps, schema_editor): @@ -32,7 +34,7 @@ class Migration(migrations.Migration): name='page', field=models.OneToOneField(related_name='club', blank=True, null=True, to='core.Page'), ), - migrations.RunSQL('SET CONSTRAINTS ALL IMMEDIATE', reverse_sql=migrations.RunSQL.noop), + PsqlRunOnly('SET CONSTRAINTS ALL IMMEDIATE', reverse_sql=migrations.RunSQL.noop), migrations.RunPython(generate_club_pages), - migrations.RunSQL(migrations.RunSQL.noop, reverse_sql='SET CONSTRAINTS ALL IMMEDIATE'), + PsqlRunOnly(migrations.RunSQL.noop, reverse_sql='SET CONSTRAINTS ALL IMMEDIATE'), ] diff --git a/core/models.py b/core/models.py index f7972863..b9dda65f 100644 --- a/core/models.py +++ b/core/models.py @@ -893,7 +893,7 @@ class Page(models.Model): ) def can_be_edited_by(self, user): - if self.is_club_page and self.club.can_be_edited_by(user): + if hasattr(self, 'club') and self.club.can_be_edited_by(user): # Override normal behavior for clubs return True return False diff --git a/core/operations.py b/core/operations.py new file mode 100644 index 00000000..fedc1cde --- /dev/null +++ b/core/operations.py @@ -0,0 +1,32 @@ +# -*- coding:utf-8 -* +# +# Copyright 2016,2017 +# - Sli +# +# 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.db import connection, migrations + + +class PsqlRunOnly(migrations.RunSQL): + + def _run_sql(self, schema_editor, sqls): + if connection.vendor == 'postgresql': + super(PsqlRunOnly, self)._run_sql(schema_editor, sqls) diff --git a/core/urls.py b/core/urls.py index 27a63070..a056b4b7 100644 --- a/core/urls.py +++ b/core/urls.py @@ -87,9 +87,9 @@ urlpatterns = [ url(r'^page/$', PageListView.as_view(), name='page_list'), url(r'^page/create$', PageCreateView.as_view(), name='page_new'), url(r'^page/(?P[0-9]*)/delete$', PageDeleteView.as_view(), name='page_delete'), - url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/edit$', PageEditView.as_view(), name='page_edit'), - url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/prop$', PagePropView.as_view(), name='page_prop'), - url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/hist$', PageHistView.as_view(), name='page_hist'), - url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/rev/(?P[0-9]+)/', PageRevView.as_view(), name='page_rev'), - url(r'^page/(?P[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])/$', PageView.as_view(), name='page'), + url(r'^page/(?P([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/edit$', PageEditView.as_view(), name='page_edit'), + url(r'^page/(?P([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/prop$', PagePropView.as_view(), name='page_prop'), + url(r'^page/(?P([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/hist$', PageHistView.as_view(), name='page_hist'), + url(r'^page/(?P([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/rev/(?P[0-9]+)/', PageRevView.as_view(), name='page_rev'), + url(r'^page/(?P([/a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9])+)/$', PageView.as_view(), name='page'), ] From f4bc1b140c772505ea46c304a45ed69295a3b187 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 17 Sep 2017 18:09:16 +0200 Subject: [PATCH 06/16] Fix is_active migration --- migrate.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/migrate.py b/migrate.py index 3a2fbe33..cf424b51 100644 --- a/migrate.py +++ b/migrate.py @@ -1379,10 +1379,13 @@ def migrate_club_again(): cur = db.cursor(MySQLdb.cursors.SSDictCursor) cur.execute("SELECT * FROM asso") + print("Migrating club is_active") + for club in cur: try: - c = Club.objects.get(id=club['id_asso']) - c.is_disabled = club['hidden'] == 1 + c = Club.objects.get(unix_name=club['nom_unix_asso']) + c.is_active = club['hidden'] == 0 + c.save() except: pass From 790d723d08e29e2a9dce0d8f5095dfbb27b40a37 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Tue, 19 Sep 2017 14:48:56 +0200 Subject: [PATCH 07/16] Fix page creation method for clubs --- club/models.py | 12 ++++++------ core/models.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/club/models.py b/club/models.py index 235de34a..e31af2af 100644 --- a/club/models.py +++ b/club/models.py @@ -112,24 +112,24 @@ class Club(models.Model): public = Group.objects.filter(id=settings.SITH_GROUP_PUBLIC_ID).first() p = Page(name=self.unix_name) p.parent = club_root - p.set_lock(root) + p.save(force_lock=True) if public: p.view_groups.add(public) - p.save() + p.save(force_lock=True) if self.parent and self.parent.page: p.parent = self.parent.page self.page = p self.save() elif self.page and self.page.name != self.unix_name: self.page.unset_lock() - self.page.set_lock(root) + # self.page.set_lock(root) self.page.name = self.unix_name - self.page.save() + self.page.save(force_lock=True) elif self.page and self.parent and self.parent.page and self.page.parent != self.parent.page: self.page.unset_lock() - self.page.set_lock(root) + # self.page.set_lock(root) self.page.parent = self.parent.page - self.page.save() + self.page.save(force_lock=True) def save(self, *args, **kwargs): with transaction.atomic(): diff --git a/core/models.py b/core/models.py index b9dda65f..b5fc8c4a 100644 --- a/core/models.py +++ b/core/models.py @@ -1007,8 +1007,8 @@ class Page(models.Model): @property def is_club_page(self): - unauthorized_parent = Page.objects.filter(name=settings.SITH_CLUB_ROOT_PAGE).first() - return unauthorized_parent is not None and (self == unauthorized_parent or unauthorized_parent in self.get_parent_list()) + club_root_page = Page.objects.filter(name=settings.SITH_CLUB_ROOT_PAGE).first() + return club_root_page is not None and (self == club_root_page or club_root_page in self.get_parent_list()) def delete(self): self.unset_lock_recursive() From db509bf060b57ac167f9a228ef9ff77c95cb9c2d Mon Sep 17 00:00:00 2001 From: klmp200 Date: Tue, 19 Sep 2017 16:27:48 +0200 Subject: [PATCH 08/16] Nice club presentation --- .../migrations/0011_club_short_description.py | 19 ++++++++++++++++++ club/models.py | 6 ++++++ club/templates/club/club_list.jinja | 6 ++++-- club/views.py | 2 +- core/migrations/0025_auto_20170919_1521.py | 20 +++++++++++++++++++ core/templates/core/base.jinja | 1 + 6 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 club/migrations/0011_club_short_description.py create mode 100644 core/migrations/0025_auto_20170919_1521.py diff --git a/club/migrations/0011_club_short_description.py b/club/migrations/0011_club_short_description.py new file mode 100644 index 00000000..f3120d1c --- /dev/null +++ b/club/migrations/0011_club_short_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 = [ + ('club', '0010_auto_20170912_2028'), + ] + + operations = [ + migrations.AddField( + model_name='club', + name='short_description', + field=models.CharField(max_length=1000, verbose_name='short description', blank=True), + ), + ] diff --git a/club/models.py b/club/models.py index e31af2af..39071e9e 100644 --- a/club/models.py +++ b/club/models.py @@ -32,6 +32,7 @@ from django.db import transaction from django.core.urlresolvers import reverse from django.utils import timezone from django.core.validators import RegexValidator, validate_email +from django.utils.functional import cached_property from core.models import User, MetaGroup, Group, SithFile, RealGroup, Notification, Page @@ -59,6 +60,7 @@ class Club(models.Model): ) logo = models.ImageField(upload_to='club_logos', verbose_name=_('logo'), null=True, blank=True) is_active = models.BooleanField(_('is active'), default=True) + short_description = models.CharField(_('short description'), max_length=1000, blank=True) address = models.CharField(_('address'), max_length=254) # email = models.EmailField(_('email address'), unique=True) # This should, and will be generated automatically owner_group = models.ForeignKey(Group, related_name="owned_club", @@ -72,6 +74,10 @@ class Club(models.Model): class Meta: ordering = ['name', 'unix_name'] + @cached_property + def president(self): + return self.members.filter(role=settings.SITH_CLUB_ROLES_ID['President'], start_date__lte=timezone.now()).first() + def check_loop(self): """Raise a validation error when a loop is found within the parent list""" objs = [] diff --git a/club/templates/club/club_list.jinja b/club/templates/club/club_list.jinja index 059ad85a..b348a2cc 100644 --- a/club/templates/club/club_list.jinja +++ b/club/templates/club/club_list.jinja @@ -6,7 +6,9 @@ {% macro display_club(club) -%}
  • {{ club.name }} - {%- if club.children.all()|length != 0 %} + {% if club.president %} - {{ club.president.user }}{% endif %} + {% if club.short_description %}

    {{ club.short_description|markdown }}

    {% endif %} + {%- if club.children.exclude(is_active=False).all()|length != 0 %}
      {%- for c in club.children.order_by('name') %} {{ display_club(c) }} @@ -23,7 +25,7 @@ {% if club_list %}

      {% trans %}Club list{% endtrans %}

        - {%- for c in club_list.order_by('name') if c.parent is none %} + {%- for c in club_list.exclude(is_active=False).order_by('name') if c.parent is none %} {{ display_club(c) }} {%- endfor %}
      diff --git a/club/views.py b/club/views.py index 8ec785be..7da32e8b 100644 --- a/club/views.py +++ b/club/views.py @@ -343,7 +343,7 @@ class ClubEditView(ClubTabsMixin, CanEditMixin, UpdateView): """ model = Club pk_url_kwarg = "club_id" - fields = ['address', 'logo'] + fields = ['address', 'logo', 'short_description'] template_name = 'core/edit.jinja' current_tab = "edit" diff --git a/core/migrations/0025_auto_20170919_1521.py b/core/migrations/0025_auto_20170919_1521.py new file mode 100644 index 00000000..039f9dd2 --- /dev/null +++ b/core/migrations/0025_auto_20170919_1521.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.core.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0024_auto_20170906_1317'), + ] + + operations = [ + migrations.AlterField( + model_name='page', + name='name', + field=models.CharField(max_length=30, verbose_name='page unix name', validators=[django.core.validators.RegexValidator('^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$', 'Enter a valid page name. This value may contain only unaccented letters, numbers and ./+/-/_ characters.')]), + ), + ] diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index b3d733ee..a7951efe 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -150,6 +150,7 @@ {% if not popup %}