Make file modale chooser and complete user profile
@@ -53,7 +53,7 @@
 | 
			
		||||
            {% endif %}
 | 
			
		||||
            <td>{{ o.remark }}</td>
 | 
			
		||||
            {% if o.invoice %}
 | 
			
		||||
            <td><a href="{{ url('core:download') + '?file=' + o.invoice.name }}">{{ o.invoice.name }}</a></td>
 | 
			
		||||
            <td><a href="{{ url('core:download', file_id=o.invoice.id) }}">{{ o.invoice.name }}</a></td>
 | 
			
		||||
            {% else %}
 | 
			
		||||
            <td>-</td>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,9 @@ from django.shortcuts import render
 | 
			
		||||
from django.core.urlresolvers import reverse_lazy
 | 
			
		||||
from django.forms.models import modelform_factory
 | 
			
		||||
from django.forms import HiddenInput
 | 
			
		||||
from django.forms.extras.widgets import SelectDateWidget
 | 
			
		||||
 | 
			
		||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
 | 
			
		||||
from core.views.forms import SelectFile
 | 
			
		||||
from core.views.forms import SelectFile, SelectDate
 | 
			
		||||
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company
 | 
			
		||||
 | 
			
		||||
# Accounting types
 | 
			
		||||
@@ -168,7 +167,7 @@ class OperationCreateView(CanCreateMixin, CreateView):
 | 
			
		||||
    form_class = modelform_factory(Operation,
 | 
			
		||||
            fields=['amount', 'label', 'remark', 'journal', 'target_type', 'target_id', 'target_label', 'date', 'mode',
 | 
			
		||||
                'cheque_number', 'invoice', 'accounting_type', 'done'],
 | 
			
		||||
            widgets={'journal': HiddenInput, 'date': SelectDateWidget})
 | 
			
		||||
            widgets={'journal': HiddenInput, 'date': SelectDate})
 | 
			
		||||
    template_name = 'core/create.jinja'
 | 
			
		||||
 | 
			
		||||
    def get_initial(self):
 | 
			
		||||
@@ -188,7 +187,7 @@ class OperationEditView(CanEditMixin, UpdateView):
 | 
			
		||||
    form_class = modelform_factory(Operation,
 | 
			
		||||
            fields = ['amount', 'label', 'remark', 'target_type', 'target_id', 'target_label', 'date', 'mode', 'cheque_number',
 | 
			
		||||
                    'invoice', 'accounting_type', 'done'],
 | 
			
		||||
            widgets={'date': SelectDateWidget, 'invoice': SelectFile})
 | 
			
		||||
            widgets={'date': SelectDate, 'invoice': SelectFile})
 | 
			
		||||
    template_name = 'core/edit.jinja'
 | 
			
		||||
 | 
			
		||||
# Company views
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,7 @@ class Command(BaseCommand):
 | 
			
		||||
                 is_superuser=True, is_staff=True)
 | 
			
		||||
        root.set_password("plop")
 | 
			
		||||
        root.save()
 | 
			
		||||
        SithFile(parent=None, name="profiles", is_folder=True, owner=root).save()
 | 
			
		||||
        home_root = SithFile(parent=None, name="users", is_folder=True, owner=root)
 | 
			
		||||
        home_root.save()
 | 
			
		||||
        club_root = SithFile(parent=None, name="clubs", is_folder=True, owner=root)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								core/migrations/0003_auto_20160810_1949.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,29 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('core', '0002_user_home'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='avatar_pict',
 | 
			
		||||
            field=models.OneToOneField(related_name='avatar_of', verbose_name='avatar', to='core.SithFile', null=True, blank=True),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='profile_pict',
 | 
			
		||||
            field=models.OneToOneField(related_name='profile_of', verbose_name='profile', to='core.SithFile', null=True, blank=True),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='scrub_pict',
 | 
			
		||||
            field=models.OneToOneField(related_name='scrub_of', verbose_name='scrub', to='core.SithFile', null=True, blank=True),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										19
									
								
								core/migrations/0004_auto_20160811_0206.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,19 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('core', '0003_auto_20160810_1949'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='nick_name',
 | 
			
		||||
            field=models.CharField(verbose_name='nick name', max_length=30, blank=True),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										65
									
								
								core/migrations/0005_auto_20160811_0319.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,65 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
import core.models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('core', '0004_auto_20160811_0206'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='department',
 | 
			
		||||
            field=models.CharField(max_length=15, choices=[('TC', 'TC'), ('IMSI', 'IMSI'), ('IMAP', 'IMAP'), ('INFO', 'INFO'), ('GI', 'GI'), ('E', 'E'), ('EE', 'EE'), ('GESC', 'GESC'), ('GMC', 'GMC'), ('MC', 'MC'), ('EDIM', 'EDIM'), ('HUMAN', 'Humanities'), ('NA', 'N/A')], default='NA', verbose_name='department'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='dpt_option',
 | 
			
		||||
            field=models.CharField(max_length=32, default='', verbose_name='dpt option'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='forum_signature',
 | 
			
		||||
            field=models.TextField(max_length=256, default='', verbose_name='forum signature'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='promo',
 | 
			
		||||
            field=models.IntegerField(blank=True, null=True, validators=[core.models.validate_promo], verbose_name='promo'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='quote',
 | 
			
		||||
            field=models.CharField(max_length=64, default='', verbose_name='quote'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='role',
 | 
			
		||||
            field=models.CharField(max_length=15, choices=[('STUDENT', 'Student'), ('ADMINISTRATIVE', 'Administrative agent'), ('TEACHER', 'Teacher'), ('AGENT', 'Agent'), ('DOCTOR', 'Doctor'), ('FORMER STUDENT', 'Former student'), ('SERVICE', 'Service')], default='STUDENT', verbose_name='role'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='school',
 | 
			
		||||
            field=models.CharField(max_length=32, default='', verbose_name='school'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='semester',
 | 
			
		||||
            field=models.CharField(max_length=5, default='', verbose_name='semester'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='sex',
 | 
			
		||||
            field=models.CharField(max_length=10, choices=[('MAN', 'Man'), ('WOMAN', 'Woman')], default='MAN', verbose_name='sex'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='tshirt_size',
 | 
			
		||||
            field=models.CharField(max_length=5, choices=[('-', '-'), ('XS', 'XS'), ('S', 'S'), ('M', 'M'), ('L', 'L'), ('XL', 'XL'), ('XXL', 'XXL'), ('XXXL', 'XXXL')], default='M', verbose_name='tshirt size'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError
 | 
			
		||||
from django.core.urlresolvers import reverse
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.db import transaction
 | 
			
		||||
from datetime import datetime, timedelta
 | 
			
		||||
from datetime import datetime, timedelta, date
 | 
			
		||||
 | 
			
		||||
import unicodedata
 | 
			
		||||
 | 
			
		||||
@@ -46,6 +46,15 @@ class RealGroup(Group):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        proxy = True
 | 
			
		||||
 | 
			
		||||
def validate_promo(value):
 | 
			
		||||
    start_year = settings.SITH_SCHOOL_START_YEAR
 | 
			
		||||
    delta = (date.today()+timedelta(days=180)).year - start_year
 | 
			
		||||
    if value < 0 or delta < value:
 | 
			
		||||
        raise ValidationError(
 | 
			
		||||
            _('%(value)s is not a valid promo (between 0 and %(end)s)'),
 | 
			
		||||
            params={'value': value, 'end': delta},
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
class User(AbstractBaseUser):
 | 
			
		||||
    """
 | 
			
		||||
    Defines the base user class, useable in every app
 | 
			
		||||
@@ -77,7 +86,7 @@ class User(AbstractBaseUser):
 | 
			
		||||
    last_name = models.CharField(_('last name'), max_length=30)
 | 
			
		||||
    email = models.EmailField(_('email address'), unique=True)
 | 
			
		||||
    date_of_birth = models.DateField(_('date of birth'), blank=True, null=True)
 | 
			
		||||
    nick_name = models.CharField(max_length=30, blank=True)
 | 
			
		||||
    nick_name = models.CharField(_('nick name'), max_length=30, blank=True)
 | 
			
		||||
    is_staff = models.BooleanField(
 | 
			
		||||
        _('staff status'),
 | 
			
		||||
        default=False,
 | 
			
		||||
@@ -101,6 +110,51 @@ class User(AbstractBaseUser):
 | 
			
		||||
    )
 | 
			
		||||
    groups = models.ManyToManyField(RealGroup, related_name='users', blank=True)
 | 
			
		||||
    home = models.OneToOneField('SithFile', related_name='home_of', verbose_name=_("home"), null=True, blank=True)
 | 
			
		||||
    profile_pict = models.OneToOneField('SithFile', related_name='profile_of', verbose_name=_("profile"), null=True, blank=True)
 | 
			
		||||
    avatar_pict = models.OneToOneField('SithFile', related_name='avatar_of', verbose_name=_("avatar"), null=True, blank=True)
 | 
			
		||||
    scrub_pict = models.OneToOneField('SithFile', related_name='scrub_of', verbose_name=_("scrub"), null=True, blank=True)
 | 
			
		||||
    sex = models.CharField(_("sex"), max_length=10, choices=[("MAN", _("Man")), ("WOMAN", _("Woman"))], default="MAN")
 | 
			
		||||
    tshirt_size = models.CharField(_("tshirt size"), max_length=5, choices=[
 | 
			
		||||
        ("-", _("-")),
 | 
			
		||||
        ("XS", _("XS")),
 | 
			
		||||
        ("S", _("S")),
 | 
			
		||||
        ("M", _("M")),
 | 
			
		||||
        ("L", _("L")),
 | 
			
		||||
        ("XL", _("XL")),
 | 
			
		||||
        ("XXL", _("XXL")),
 | 
			
		||||
        ("XXXL", _("XXXL")),
 | 
			
		||||
        ], default="M")
 | 
			
		||||
    role = models.CharField(_("role"), max_length=15, choices=[
 | 
			
		||||
        ("STUDENT", _("Student")),
 | 
			
		||||
        ("ADMINISTRATIVE", _("Administrative agent")),
 | 
			
		||||
        ("TEACHER", _("Teacher")),
 | 
			
		||||
        ("AGENT", _("Agent")),
 | 
			
		||||
        ("DOCTOR", _("Doctor")),
 | 
			
		||||
        ("FORMER STUDENT", _("Former student")),
 | 
			
		||||
        ("SERVICE", _("Service")),
 | 
			
		||||
        ], default="STUDENT")
 | 
			
		||||
    department = models.CharField(_("department"), max_length=15, choices=[
 | 
			
		||||
        ("TC", _("TC")),
 | 
			
		||||
        ("IMSI", _("IMSI")),
 | 
			
		||||
        ("IMAP", _("IMAP")),
 | 
			
		||||
        ("INFO", _("INFO")),
 | 
			
		||||
        ("GI", _("GI")),
 | 
			
		||||
        ("E", _("E")),
 | 
			
		||||
        ("EE", _("EE")),
 | 
			
		||||
        ("GESC", _("GESC")),
 | 
			
		||||
        ("GMC", _("GMC")),
 | 
			
		||||
        ("MC", _("MC")),
 | 
			
		||||
        ("EDIM", _("EDIM")),
 | 
			
		||||
        ("HUMAN", _("Humanities")),
 | 
			
		||||
        ("NA", _("N/A")),
 | 
			
		||||
        ], default="NA")
 | 
			
		||||
    dpt_option = models.CharField(_("dpt option"), max_length=32, default="")
 | 
			
		||||
    semester = models.CharField(_("semester"), max_length=5, default="")
 | 
			
		||||
    quote = models.CharField(_("quote"), max_length=64, default="")
 | 
			
		||||
    school = models.CharField(_("school"), max_length=32, default="")
 | 
			
		||||
    promo = models.IntegerField(_("promo"), validators=[validate_promo], null=True, blank=True)
 | 
			
		||||
    forum_signature = models.TextField(_("forum signature"), max_length=256, default="")
 | 
			
		||||
    # TODO: add phone numbers with https://github.com/stefanfoulis/django-phonenumber-field
 | 
			
		||||
 | 
			
		||||
    objects = UserManager()
 | 
			
		||||
 | 
			
		||||
@@ -341,6 +395,15 @@ class SithFile(models.Model):
 | 
			
		||||
    def is_owned_by(self, user):
 | 
			
		||||
        return user.id == self.owner.id
 | 
			
		||||
 | 
			
		||||
    def can_be_viewed_by(self, user):
 | 
			
		||||
        if hasattr(self, 'profile_of'):
 | 
			
		||||
            return user.can_view(self.profile_of)
 | 
			
		||||
        if hasattr(self, 'avatar_of'):
 | 
			
		||||
            return user.can_view(self.avatar_of)
 | 
			
		||||
        if hasattr(self, 'scrub_of'):
 | 
			
		||||
            return user.can_view(self.scrub_of)
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    def delete(self):
 | 
			
		||||
        for c in self.children.all():
 | 
			
		||||
            c.delete()
 | 
			
		||||
@@ -422,6 +485,9 @@ class SithFile(models.Model):
 | 
			
		||||
    def get_display_name(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
 | 
			
		||||
    def get_download_url(self):
 | 
			
		||||
        return reverse('core:download', kwargs={'file_id': self.id})
 | 
			
		||||
 | 
			
		||||
class LockError(Exception):
 | 
			
		||||
    """There was a lock error on the object"""
 | 
			
		||||
    pass
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,11 @@
 | 
			
		||||
Super Form Reset
 | 
			
		||||
----------------------------------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
form {
 | 
			
		||||
    margin: 0px auto;
 | 
			
		||||
    width: 60%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
input,
 | 
			
		||||
label,
 | 
			
		||||
select,
 | 
			
		||||
@@ -22,6 +27,10 @@ textarea
 | 
			
		||||
    font-family: Arial;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
label {
 | 
			
		||||
    min-width: 50%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Remove the stupid outer glow in Webkit */
 | 
			
		||||
input:focus
 | 
			
		||||
{
 | 
			
		||||
@@ -70,7 +79,8 @@ input[type=tel],
 | 
			
		||||
input[type=text],
 | 
			
		||||
input[type=time],
 | 
			
		||||
input[type=url],
 | 
			
		||||
input[type=week]
 | 
			
		||||
input[type=week],
 | 
			
		||||
textarea
 | 
			
		||||
{
 | 
			
		||||
    background-color: white;
 | 
			
		||||
    border: 1px solid black;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_01.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_02.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_03.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_04.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_05.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_06.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_07.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_08.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_09.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_10.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_11.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_12.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_13.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_14.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_15.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								core/static/core/img/promo_16.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.4 KiB  | 
@@ -1,11 +1,29 @@
 | 
			
		||||
console.log('Guy');
 | 
			
		||||
 | 
			
		||||
$( function() {
 | 
			
		||||
    dialog = $( ".choose_file_widget" ).dialog({
 | 
			
		||||
    buttons = $(".choose_file_button");
 | 
			
		||||
    popups = $(".choose_file_widget");
 | 
			
		||||
    popups.dialog({
 | 
			
		||||
        autoOpen: false,
 | 
			
		||||
        modal: true,
 | 
			
		||||
        width: "80%",
 | 
			
		||||
        minHeight: "300",
 | 
			
		||||
        buttons: {
 | 
			
		||||
            "Choose": function() {
 | 
			
		||||
                console.log($("#file_id"));
 | 
			
		||||
                $("input[name="+$(this).attr('name')+"]").attr('value', $("#file_id").attr('value'));
 | 
			
		||||
                $( this ).dialog( "close" );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    $('.select_date').datepicker({
 | 
			
		||||
        changeMonth: true,
 | 
			
		||||
        changeYear: true
 | 
			
		||||
    });
 | 
			
		||||
    $( ".choose_file_button" ).button().on( "click", function() {
 | 
			
		||||
        dialog.dialog( "open" );
 | 
			
		||||
        popup = popups.filter("[name="+$(this).attr('name')+"]");
 | 
			
		||||
        console.log(popup);
 | 
			
		||||
        popup.html('<iframe src="/file/popup" width="95%"></iframe><span id="file_id" value="null" />');
 | 
			
		||||
        popup.dialog({title: $(this).attr('name')}).dialog( "open" );
 | 
			
		||||
    });
 | 
			
		||||
} );
 | 
			
		||||
 
 | 
			
		||||
@@ -118,12 +118,16 @@ ul, ol {
 | 
			
		||||
}
 | 
			
		||||
table {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    font-size: 0.90em;
 | 
			
		||||
}
 | 
			
		||||
td {
 | 
			
		||||
    padding: 4px;
 | 
			
		||||
    border: solid 1px black;
 | 
			
		||||
    border-collapse: collapse;
 | 
			
		||||
    vertical-align: top;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    text-overflow: ellipsis;
 | 
			
		||||
    max-width: 0;
 | 
			
		||||
}
 | 
			
		||||
td>ul {
 | 
			
		||||
    margin-top: 0px;
 | 
			
		||||
@@ -152,7 +156,27 @@ tbody>tr:hover {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------USER PROFILE----------------------------*/
 | 
			
		||||
.user_profile {
 | 
			
		||||
#user_profile {
 | 
			
		||||
    width: 80%;
 | 
			
		||||
    margin: 0px auto;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
#user_profile h4 { border-bottom: 1px solid grey; max-width: 60%; }
 | 
			
		||||
#user_profile #pictures {
 | 
			
		||||
   width: 30%;
 | 
			
		||||
   float: right;
 | 
			
		||||
   font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
#user_profile #nickname {
 | 
			
		||||
   font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
#user_profile #pictures img {
 | 
			
		||||
   max-width: 96%;
 | 
			
		||||
   max-height: 96%;
 | 
			
		||||
}
 | 
			
		||||
#user_profile .promo_pict {
 | 
			
		||||
   height: 45px;
 | 
			
		||||
}
 | 
			
		||||
/*---------------------------------PAGE--------------------------------*/
 | 
			
		||||
.page_content {
 | 
			
		||||
 
 | 
			
		||||
@@ -60,23 +60,25 @@
 | 
			
		||||
            {{ tests }}
 | 
			
		||||
            {% endblock %}
 | 
			
		||||
        -->
 | 
			
		||||
        {% block script %}
 | 
			
		||||
        <script src="{{ static('core/js/jquery-3.1.0.min.js') }}"></script>
 | 
			
		||||
        <script src="{{ static('core/js/ui/jquery-ui.min.js') }}"></script>
 | 
			
		||||
        <script src="{{ static('core/js/multiple-select.js') }}"></script>
 | 
			
		||||
        <script src="{{ static('core/js/script.js') }}"></script>
 | 
			
		||||
        <script>
 | 
			
		||||
    $('select:not([multiple])').multipleSelect({
 | 
			
		||||
$('.select_single').multipleSelect({
 | 
			
		||||
    single: true,
 | 
			
		||||
    {% if not popup %}
 | 
			
		||||
    position: 'top',
 | 
			
		||||
    {% endif %}
 | 
			
		||||
});
 | 
			
		||||
    $('select[multiple=multiple]').multipleSelect({
 | 
			
		||||
$('.select_multiple').multipleSelect({
 | 
			
		||||
    filter: true,
 | 
			
		||||
    {% if not popup %}
 | 
			
		||||
    position: 'top',
 | 
			
		||||
    {% endif %}
 | 
			
		||||
});
 | 
			
		||||
        </script>
 | 
			
		||||
        {% endblock %}
 | 
			
		||||
    </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
{% extends "core/base.jinja" %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{% trans obj=object %}Edit {{ obj }}{% endtrans %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<h2>{% trans obj=object %}Edit {{ obj }}{% endtrans %}</h2>
 | 
			
		||||
<form action="" method="post">
 | 
			
		||||
 
 | 
			
		||||
@@ -42,8 +42,18 @@
 | 
			
		||||
{% if not file.home_of and not file.home_of_club and file.parent %}
 | 
			
		||||
<p><a href="{{ url('core:file_delete', file_id=file.id, popup=popup) }}">{% trans %}Delete{% endtrans %}</a></p>
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if popup %}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
{{ super() }}
 | 
			
		||||
{% if popup and file.is_file %}
 | 
			
		||||
<script>
 | 
			
		||||
parent.$("#file_id").replaceWith('<span id="file_id" value="{{ file.id }}">{{ file.name }}</span>');
 | 
			
		||||
</script>
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,9 @@
 | 
			
		||||
 | 
			
		||||
<form method="post" action="{{ url('core:login') }}">
 | 
			
		||||
{% csrf_token %}
 | 
			
		||||
{{ form.as_p() }}
 | 
			
		||||
<p>{{ form.username.errors }}<label for="{{ form.username.name }}">{{ form.username.label }}
 | 
			
		||||
</label><input id="id_username" maxlength="254" name="username" type="text" autofocus="autofocus" /></p>
 | 
			
		||||
<p>{{ form.password.errors }}<label for="{{ form.password.name }}">{{ form.password.label }}</label>{{ form.password }}</p>
 | 
			
		||||
<input type="hidden" name="next" value="{{ next }}">
 | 
			
		||||
<p><input type="submit" value="{% trans %}login{% endtrans %}"></p>
 | 
			
		||||
</form>
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,26 @@
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block infos %}
 | 
			
		||||
<h3>{% trans %}User Profile{% endtrans %}</h3>
 | 
			
		||||
 | 
			
		||||
<div class="user_profile">
 | 
			
		||||
<div id="user_profile">
 | 
			
		||||
    <div id="pictures">
 | 
			
		||||
        {% if profile.profile_pict %}
 | 
			
		||||
        <img src="{{ profile.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}" />
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        <p><em>{{ profile.quote }}</em></p>
 | 
			
		||||
    </div>
 | 
			
		||||
    <h4>{{ profile.get_full_name() }}</h4>
 | 
			
		||||
    <p>{{ profile.nick_name }}</p>
 | 
			
		||||
    <p id="nickname">« {{ profile.nick_name }} »</p>
 | 
			
		||||
    <p>{% trans %}Born: {% endtrans %}{{ profile.date_of_birth|date("d/m/Y") }}</p>
 | 
			
		||||
    <p>{{ profile.department }}{{ profile.semester }}
 | 
			
		||||
    {% if profile.dpt_option %}
 | 
			
		||||
    <br>{% trans %}Option: {% endtrans %}{{ profile.dpt_option }}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    </p>
 | 
			
		||||
    {% if profile.promo %}
 | 
			
		||||
    <p><img src="{{ static('core/img/promo_%02d.png' % profile.promo) }}" alt="Promo {{ profile.promo }}" class="promo_pict" />
 | 
			
		||||
    {% trans %}Promo: {% endtrans %}{{ profile.promo }}</p>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% if user.membership.filter(end_date=None).exists() or user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) %}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,31 @@
 | 
			
		||||
{% extends "core/base.jinja" %}
 | 
			
		||||
{% extends "core/user_base.jinja" %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% block infos %}
 | 
			
		||||
<h2>{% trans %}Edit user profile{% endtrans %}</h2>
 | 
			
		||||
<form action="" method="post">
 | 
			
		||||
<form action="" method="post" enctype="multipart/form-data">
 | 
			
		||||
    {% csrf_token %}
 | 
			
		||||
    {{ form.as_p() }}
 | 
			
		||||
    {% for field in form %}
 | 
			
		||||
    <p>{{ field.errors }}<label for="{{ field.name }}">{{ field.label }}
 | 
			
		||||
    {%- if field.name == "profile_pict" and form.instance.profile_pict -%}
 | 
			
		||||
    <br>{% trans %}Current profile: {% endtrans %}
 | 
			
		||||
    <img src="{{ form.instance.profile_pict.get_download_url() }}" title="{% trans %}Profile{% endtrans %}" width="50px" /><br>
 | 
			
		||||
    {%- elif field.name == "avatar_pict" and form.instance.avatar_pict -%}
 | 
			
		||||
    <br>{% trans %}Current avatar: {% endtrans %}
 | 
			
		||||
    <img src="{{ form.instance.avatar_pict.get_download_url() }}" title="{% trans %}Avatar{% endtrans %}" width="50px" /><br>
 | 
			
		||||
    {%- elif field.name == "scrub_pict" and form.instance.scrub_pict -%}
 | 
			
		||||
    <br>{% trans %}Current scrub: {% endtrans %}
 | 
			
		||||
    <img src="{{ form.instance.scrub_pict.get_download_url() }}" title="{% trans %}Scrub{% endtrans %}" width="50px" /><br>
 | 
			
		||||
    {%- endif %}</label> {{ field }}</p>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
    <p><input type="submit" value="{% trans %}Update{% endtrans %}" /></p>
 | 
			
		||||
</form>
 | 
			
		||||
    <p>{% trans %}Username: {% endtrans %}{{ form.instance.username }}</p>
 | 
			
		||||
    {% if form.instance.customer %}
 | 
			
		||||
    <p>{% trans %}Account number: {% endtrans %}{{ form.instance.customer.account_id }}</p>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if form.instance == user %}
 | 
			
		||||
    <p><a href="{{ url('core:password_change') }}">{% trans %}Change my password{% endtrans %}</a></p>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
</form>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{% extends "core/base.jinja" %}
 | 
			
		||||
{% extends "core/user_base.jinja" %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% block infos %}
 | 
			
		||||
<h2>{% trans user_name=profile.get_full_name() %}Edit user groups for {{ user_name }}{% endtrans %}</h2>
 | 
			
		||||
<form action="" method="post">
 | 
			
		||||
    {% csrf_token %}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,11 @@ from django.contrib.auth.forms import AuthenticationForm
 | 
			
		||||
from core.models import Group
 | 
			
		||||
 | 
			
		||||
def forbidden(request):
 | 
			
		||||
    try:
 | 
			
		||||
        return HttpResponseForbidden(render(request, "core/403.jinja", context={'next': request.path, 'form':
 | 
			
		||||
            AuthenticationForm(), 'popup': request.resolver_match.kwargs['popup'] or ""}))
 | 
			
		||||
    except:
 | 
			
		||||
        return HttpResponseForbidden(render(request, "core/403.jinja", context={'next': request.path, 'form': AuthenticationForm()}))
 | 
			
		||||
 | 
			
		||||
def not_found(request):
 | 
			
		||||
    return HttpResponseNotFound(render(request, "core/404.jinja"))
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ def send_file(request, file_id):
 | 
			
		||||
        response['Content-Disposition'] = 'inline; filename="%s"' % f.name
 | 
			
		||||
        return response
 | 
			
		||||
 | 
			
		||||
class AddFileForm(forms.Form):
 | 
			
		||||
class AddFilesForm(forms.Form):
 | 
			
		||||
    folder_name = forms.CharField(label=_("Add a new folder"), max_length=30, required=False)
 | 
			
		||||
    file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}), label=_("Files"),
 | 
			
		||||
            required=False)
 | 
			
		||||
@@ -128,7 +128,7 @@ class FileView(CanViewMixin, DetailView, FormMixin):
 | 
			
		||||
    pk_url_kwarg = "file_id"
 | 
			
		||||
    template_name = 'core/file_detail.jinja'
 | 
			
		||||
    context_object_name = "file"
 | 
			
		||||
    form_class = AddFileForm
 | 
			
		||||
    form_class = AddFilesForm
 | 
			
		||||
 | 
			
		||||
    def get(self, request, *args, **kwargs):
 | 
			
		||||
        self.form = self.get_form()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,56 @@
 | 
			
		||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, UserChangeForm
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.db import transaction
 | 
			
		||||
from django.core.exceptions import ValidationError
 | 
			
		||||
from django.contrib.auth import logout, login, authenticate
 | 
			
		||||
from django.forms import CheckboxSelectMultiple, Select
 | 
			
		||||
from django.forms import CheckboxSelectMultiple, Select, DateInput, TextInput
 | 
			
		||||
from django.utils.translation import ugettext as _
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
from core.models import User, Page, RealGroup
 | 
			
		||||
from core.models import User, Page, RealGroup, SithFile
 | 
			
		||||
 | 
			
		||||
# Widgets
 | 
			
		||||
 | 
			
		||||
class SelectSingle(Select):
 | 
			
		||||
    def render(self, name, value, attrs=None):
 | 
			
		||||
        if attrs:
 | 
			
		||||
            attrs['class'] = "select_single"
 | 
			
		||||
        else:
 | 
			
		||||
            attrs = {'class': "select_single"}
 | 
			
		||||
        return super(SelectSingle, self).render(name, value, attrs)
 | 
			
		||||
 | 
			
		||||
class SelectMultiple(Select):
 | 
			
		||||
    def render(self, name, value, attrs=None):
 | 
			
		||||
        if attrs:
 | 
			
		||||
            attrs['class'] = "select_multiple"
 | 
			
		||||
        else:
 | 
			
		||||
            attrs = {'class': "select_multiple"}
 | 
			
		||||
        return super(SelectMultiple, self).render(name, value, attrs)
 | 
			
		||||
 | 
			
		||||
class SelectDate(DateInput):
 | 
			
		||||
    def render(self, name, value, attrs=None):
 | 
			
		||||
        if attrs:
 | 
			
		||||
            attrs['class'] = "select_date"
 | 
			
		||||
        else:
 | 
			
		||||
            attrs = {'class': "select_date"}
 | 
			
		||||
        return super(SelectDate, self).render(name, value, attrs)
 | 
			
		||||
 | 
			
		||||
class SelectFile(TextInput):
 | 
			
		||||
    def render(self, name, value, attrs=None):
 | 
			
		||||
        if attrs:
 | 
			
		||||
            attrs['class'] = "select_file"
 | 
			
		||||
        else:
 | 
			
		||||
            attrs = {'class': "select_file"}
 | 
			
		||||
        output = '%(content)s<div name="%(name)s" class="choose_file_widget" title="%(title)s"></div>' % {
 | 
			
		||||
                'content': super(SelectFile, self).render(name, value, attrs),
 | 
			
		||||
                'title': _("Choose file"),
 | 
			
		||||
                'name': name,
 | 
			
		||||
                }
 | 
			
		||||
        output += '<span name="' + name + '" class="choose_file_button">' + _("Choose file") + '</span>'
 | 
			
		||||
        print(output)
 | 
			
		||||
        return output
 | 
			
		||||
 | 
			
		||||
# Forms
 | 
			
		||||
 | 
			
		||||
class RegisteringForm(UserCreationForm):
 | 
			
		||||
    error_css_class = 'error'
 | 
			
		||||
@@ -22,6 +67,69 @@ class RegisteringForm(UserCreationForm):
 | 
			
		||||
            user.save()
 | 
			
		||||
        return user
 | 
			
		||||
 | 
			
		||||
class UserProfileForm(forms.ModelForm):
 | 
			
		||||
    """
 | 
			
		||||
    Form handling the user profile, managing the files
 | 
			
		||||
    This form is actually pretty bad and was made in the rush before the migration. It should be refactored.
 | 
			
		||||
    TODO: refactor this form
 | 
			
		||||
    """
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = User
 | 
			
		||||
        fields = ['first_name', 'last_name', 'nick_name', 'email', 'date_of_birth', 'profile_pict', 'avatar_pict',
 | 
			
		||||
                'scrub_pict', 'sex', 'tshirt_size', 'role', 'department', 'dpt_option', 'semester', 'quote', 'school',
 | 
			
		||||
                'promo', 'forum_signature']
 | 
			
		||||
        widgets = {
 | 
			
		||||
                'date_of_birth': SelectDate,
 | 
			
		||||
                'profile_pict': forms.ClearableFileInput,
 | 
			
		||||
                'avatar_pict': forms.ClearableFileInput,
 | 
			
		||||
                'scrub_pict': forms.ClearableFileInput,
 | 
			
		||||
                }
 | 
			
		||||
        labels = {
 | 
			
		||||
                'profile_pict': _("Profile: you need to be visible on the picture, in order to be recognized (e.g. by the barmen)"),
 | 
			
		||||
                'avatar_pict': _("Avatar: used on the forum"),
 | 
			
		||||
                'scrub_pict': _("Scrub: let other know how your scrub looks like!"),
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *arg, **kwargs):
 | 
			
		||||
        super(UserProfileForm, self).__init__(*arg, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def full_clean(self):
 | 
			
		||||
        super(UserProfileForm, self).full_clean()
 | 
			
		||||
 | 
			
		||||
    def generate_name(self, field_name, f):
 | 
			
		||||
        field_name = field_name[:-4]
 | 
			
		||||
        return field_name + str(self.instance.id) + "." + f.content_type.split('/')[-1]
 | 
			
		||||
 | 
			
		||||
    def process(self, files):
 | 
			
		||||
        avatar = self.instance.avatar_pict
 | 
			
		||||
        profile = self.instance.profile_pict
 | 
			
		||||
        scrub = self.instance.scrub_pict
 | 
			
		||||
        self.full_clean()
 | 
			
		||||
        self.cleaned_data['avatar_pict'] = avatar
 | 
			
		||||
        self.cleaned_data['profile_pict'] = profile
 | 
			
		||||
        self.cleaned_data['scrub_pict'] = scrub
 | 
			
		||||
        parent = SithFile.objects.filter(parent=None, name="profiles").first()
 | 
			
		||||
        for field,f in files:
 | 
			
		||||
            with transaction.atomic():
 | 
			
		||||
                new_file = SithFile(parent=parent, name=self.generate_name(field, f), file=f, owner=self.instance, is_folder=False,
 | 
			
		||||
                        mime_type=f.content_type, size=f._size)
 | 
			
		||||
                try:
 | 
			
		||||
                    if not (f.content_type == "image/jpeg" or
 | 
			
		||||
                            f.content_type == "image/png" or
 | 
			
		||||
                            f.content_type == "image/gif"):
 | 
			
		||||
                        raise ValidationError(_("Bad image format, only jpeg, png, and gif are accepted"))
 | 
			
		||||
                    old = SithFile.objects.filter(parent=parent, name=new_file.name).first()
 | 
			
		||||
                    if old:
 | 
			
		||||
                        old.delete()
 | 
			
		||||
                    new_file.clean()
 | 
			
		||||
                    new_file.save()
 | 
			
		||||
                    self.cleaned_data[field] = new_file
 | 
			
		||||
                    self._errors.pop(field, None)
 | 
			
		||||
                except ValidationError as e:
 | 
			
		||||
                    self._errors.pop(field, None)
 | 
			
		||||
                    self.add_error(field, _("Error uploading file %(file_name)s: %(msg)s") %
 | 
			
		||||
                            {'file_name': f, 'msg': str(e.message)})
 | 
			
		||||
        self._post_clean()
 | 
			
		||||
 | 
			
		||||
class UserPropForm(forms.ModelForm):
 | 
			
		||||
    error_css_class = 'error'
 | 
			
		||||
@@ -52,13 +160,3 @@ class PagePropForm(forms.ModelForm):
 | 
			
		||||
        self.fields['edit_groups'].required = False
 | 
			
		||||
        self.fields['view_groups'].required = False
 | 
			
		||||
 | 
			
		||||
class SelectFile(Select):
 | 
			
		||||
    def render(self, name, value, attrs=None):
 | 
			
		||||
        output = '<span class="choose_file_widget" title="%(title)s">%(content)s</span>' % {
 | 
			
		||||
                'title': _("Choose file"),
 | 
			
		||||
                'content': super(SelectFile, self).render(name, value, attrs),
 | 
			
		||||
                }
 | 
			
		||||
        output += '<span class="choose_file_button">' + _("Choose file") + '</span>'
 | 
			
		||||
        print(output)
 | 
			
		||||
        return output
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ from django.conf import settings
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin
 | 
			
		||||
from core.views.forms import RegisteringForm, UserPropForm
 | 
			
		||||
from core.views.forms import RegisteringForm, UserPropForm, UserProfileForm
 | 
			
		||||
from core.models import User
 | 
			
		||||
 | 
			
		||||
def login(request):
 | 
			
		||||
@@ -115,7 +115,31 @@ class UserUpdateProfileView(CanEditMixin, UpdateView):
 | 
			
		||||
    model = User
 | 
			
		||||
    pk_url_kwarg = "user_id"
 | 
			
		||||
    template_name = "core/user_edit.jinja"
 | 
			
		||||
    fields = ('first_name', 'last_name', 'nick_name', 'email', 'date_of_birth', )
 | 
			
		||||
    form_class = UserProfileForm
 | 
			
		||||
 | 
			
		||||
    def get(self, request, *args, **kwargs):
 | 
			
		||||
        self.object = self.get_object()
 | 
			
		||||
        self.form = self.get_form()
 | 
			
		||||
        if self.form.instance.profile_pict and not request.user.is_in_group(settings.SITH_MAIN_BOARD_GROUP):
 | 
			
		||||
            self.form.fields.pop('profile_pict', None)
 | 
			
		||||
        return self.render_to_response(self.get_context_data(form=self.form))
 | 
			
		||||
 | 
			
		||||
    def post(self, request, *args, **kwargs):
 | 
			
		||||
        self.object = self.get_object()
 | 
			
		||||
        self.form = self.get_form()
 | 
			
		||||
        if self.form.instance.profile_pict and not request.user.is_in_group(settings.SITH_MAIN_BOARD_GROUP):
 | 
			
		||||
            self.form.fields.pop('profile_pict', None)
 | 
			
		||||
        files = request.FILES.items()
 | 
			
		||||
        self.form.process(files)
 | 
			
		||||
        if request.user.is_authenticated() and request.user.can_edit(self.object) and self.form.is_valid():
 | 
			
		||||
            return super(UserUpdateProfileView, self).form_valid(self.form)
 | 
			
		||||
        return self.form_invalid(self.form)
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        kwargs = super(UserUpdateProfileView, self).get_context_data(**kwargs)
 | 
			
		||||
        kwargs['profile'] = self.form.instance
 | 
			
		||||
        kwargs['form'] = self.form
 | 
			
		||||
        return kwargs
 | 
			
		||||
 | 
			
		||||
class UserUpdateGroupView(CanEditPropMixin, UpdateView):
 | 
			
		||||
    """
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2016-08-10 05:00+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2016-08-11 04:02+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2016-07-18\n"
 | 
			
		||||
"Last-Translator: Skia <skia@libskia.so>\n"
 | 
			
		||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
 | 
			
		||||
@@ -40,12 +40,12 @@ msgstr "numero de compte"
 | 
			
		||||
msgid "%(club_account)s on %(bank_account)s"
 | 
			
		||||
msgstr "%(club_account)s sur %(bank_account)s"
 | 
			
		||||
 | 
			
		||||
#: accounting/models.py:109 club/models.py:112 counter/models.py:268
 | 
			
		||||
#: accounting/models.py:109 club/models.py:147 counter/models.py:268
 | 
			
		||||
#: launderette/models.py:112
 | 
			
		||||
msgid "start date"
 | 
			
		||||
msgstr "date de début"
 | 
			
		||||
 | 
			
		||||
#: accounting/models.py:110 club/models.py:113 counter/models.py:269
 | 
			
		||||
#: accounting/models.py:110 club/models.py:148 counter/models.py:269
 | 
			
		||||
msgid "end date"
 | 
			
		||||
msgstr "date de fin"
 | 
			
		||||
 | 
			
		||||
@@ -66,8 +66,9 @@ msgstr "montant effectif"
 | 
			
		||||
msgid "number"
 | 
			
		||||
msgstr "numéro"
 | 
			
		||||
 | 
			
		||||
#: accounting/models.py:154 core/models.py:560 counter/models.py:209
 | 
			
		||||
#: counter/models.py:244 eboutic/models.py:13 eboutic/models.py:46
 | 
			
		||||
#: accounting/models.py:154 core/models.py:390 core/models.py:666
 | 
			
		||||
#: counter/models.py:209 counter/models.py:244 eboutic/models.py:13
 | 
			
		||||
#: eboutic/models.py:46
 | 
			
		||||
msgid "date"
 | 
			
		||||
msgstr "date"
 | 
			
		||||
 | 
			
		||||
@@ -121,7 +122,7 @@ msgstr "Compte"
 | 
			
		||||
msgid "Company"
 | 
			
		||||
msgstr "Entreprise"
 | 
			
		||||
 | 
			
		||||
#: accounting/models.py:163 sith/settings.py:260 sith/settings_sample.py:260
 | 
			
		||||
#: accounting/models.py:163 sith/settings.py:263 sith/settings_sample.py:263
 | 
			
		||||
msgid "Other"
 | 
			
		||||
msgstr "Autre"
 | 
			
		||||
 | 
			
		||||
@@ -205,7 +206,7 @@ msgstr "Nouveau compte club"
 | 
			
		||||
#: accounting/templates/accounting/bank_account_list.jinja:15
 | 
			
		||||
#: accounting/templates/accounting/club_account_details.jinja:44
 | 
			
		||||
#: accounting/templates/accounting/journal_details.jinja:62
 | 
			
		||||
#: club/templates/club/club_detail.jinja:7 core/templates/core/file.jinja:46
 | 
			
		||||
#: club/templates/club/club_detail.jinja:7 core/templates/core/file.jinja:38
 | 
			
		||||
#: core/templates/core/page.jinja:31 core/templates/core/user_base.jinja:8
 | 
			
		||||
#: core/templates/core/user_tools.jinja:37
 | 
			
		||||
#: counter/templates/counter/counter_list.jinja:15
 | 
			
		||||
@@ -216,7 +217,7 @@ msgstr "Éditer"
 | 
			
		||||
 | 
			
		||||
#: accounting/templates/accounting/bank_account_details.jinja:19
 | 
			
		||||
#: accounting/templates/accounting/bank_account_list.jinja:16
 | 
			
		||||
#: core/templates/core/file_detail.jinja:38
 | 
			
		||||
#: core/templates/core/file_detail.jinja:43
 | 
			
		||||
#: core/templates/core/group_list.jinja:13
 | 
			
		||||
#: launderette/templates/launderette/launderette_admin.jinja:16
 | 
			
		||||
#: launderette/views.py:146
 | 
			
		||||
@@ -296,7 +297,7 @@ msgid "No"
 | 
			
		||||
msgstr "Non"
 | 
			
		||||
 | 
			
		||||
#: accounting/templates/accounting/club_account_details.jinja:43
 | 
			
		||||
#: core/templates/core/file.jinja:44 core/templates/core/page.jinja:28
 | 
			
		||||
#: core/templates/core/file.jinja:36 core/templates/core/page.jinja:28
 | 
			
		||||
msgid "View"
 | 
			
		||||
msgstr "Voir"
 | 
			
		||||
 | 
			
		||||
@@ -381,37 +382,45 @@ msgstr "Un club avec ce nom UNIX existe déjà."
 | 
			
		||||
msgid "address"
 | 
			
		||||
msgstr "Adresse"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:45
 | 
			
		||||
#: club/models.py:38 core/models.py:112
 | 
			
		||||
msgid "home"
 | 
			
		||||
msgstr "home"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:46
 | 
			
		||||
msgid "You can not make loops in clubs"
 | 
			
		||||
msgstr "Vous ne pouvez pas faire de boucles dans les clubs"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:110 eboutic/models.py:12 eboutic/models.py:45
 | 
			
		||||
#: club/models.py:60
 | 
			
		||||
msgid "A club with that unix_name already exists"
 | 
			
		||||
msgstr "Un club avec ce nom UNIX existe déjà."
 | 
			
		||||
 | 
			
		||||
#: club/models.py:145 eboutic/models.py:12 eboutic/models.py:45
 | 
			
		||||
#: launderette/models.py:81 launderette/models.py:116
 | 
			
		||||
msgid "user"
 | 
			
		||||
msgstr "nom d'utilisateur"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:111
 | 
			
		||||
#: club/models.py:146
 | 
			
		||||
msgid "club"
 | 
			
		||||
msgstr "club"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:114
 | 
			
		||||
#: club/models.py:149 core/models.py:127
 | 
			
		||||
msgid "role"
 | 
			
		||||
msgstr "rôle"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:116 core/models.py:27 counter/models.py:53
 | 
			
		||||
#: club/models.py:151 core/models.py:28 counter/models.py:53
 | 
			
		||||
#: counter/models.py:78
 | 
			
		||||
msgid "description"
 | 
			
		||||
msgstr "description"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:121
 | 
			
		||||
#: club/models.py:156
 | 
			
		||||
msgid "User must be subscriber to take part to a club"
 | 
			
		||||
msgstr "L'utilisateur doit être cotisant pour faire partie d'un club"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:123
 | 
			
		||||
#: club/models.py:158
 | 
			
		||||
msgid "User is already member of that club"
 | 
			
		||||
msgstr "L'utilisateur est déjà membre de ce club"
 | 
			
		||||
 | 
			
		||||
#: club/models.py:127
 | 
			
		||||
#: club/models.py:162
 | 
			
		||||
msgid "past member"
 | 
			
		||||
msgstr "Anciens membres"
 | 
			
		||||
 | 
			
		||||
@@ -420,7 +429,7 @@ msgstr "Anciens membres"
 | 
			
		||||
msgid "Back to list"
 | 
			
		||||
msgstr "Retour à la liste"
 | 
			
		||||
 | 
			
		||||
#: club/templates/club/club_detail.jinja:10 core/templates/core/file.jinja:49
 | 
			
		||||
#: club/templates/club/club_detail.jinja:10 core/templates/core/file.jinja:41
 | 
			
		||||
#: core/templates/core/page.jinja:34
 | 
			
		||||
msgid "Prop"
 | 
			
		||||
msgstr "Propriétés"
 | 
			
		||||
@@ -435,7 +444,7 @@ msgstr "Éditer le club"
 | 
			
		||||
 | 
			
		||||
#: club/templates/club/club_edit.jinja:8
 | 
			
		||||
#: club/templates/club/club_edit_prop.jinja:8
 | 
			
		||||
#: core/templates/core/create.jinja:8 core/templates/core/edit.jinja:8
 | 
			
		||||
#: core/templates/core/create.jinja:8 core/templates/core/edit.jinja:12
 | 
			
		||||
#: core/templates/core/file_edit.jinja:8 core/templates/core/page_prop.jinja:8
 | 
			
		||||
#: core/templates/core/pagerev_edit.jinja:24
 | 
			
		||||
#: counter/templates/counter/counter_edit.jinja:8
 | 
			
		||||
@@ -463,7 +472,8 @@ msgstr "Il n'y a pas de club dans ce site web."
 | 
			
		||||
msgid "Club members"
 | 
			
		||||
msgstr "Membres du club"
 | 
			
		||||
 | 
			
		||||
#: club/templates/club/club_members.jinja:13 launderette/views.py:146
 | 
			
		||||
#: club/templates/club/club_members.jinja:13
 | 
			
		||||
#: core/templates/core/file_detail.jinja:19 launderette/views.py:146
 | 
			
		||||
msgid "Add"
 | 
			
		||||
msgstr "Ajouter"
 | 
			
		||||
 | 
			
		||||
@@ -476,25 +486,30 @@ msgstr "Outils club"
 | 
			
		||||
msgid "Counters:"
 | 
			
		||||
msgstr "Comptoirs : "
 | 
			
		||||
 | 
			
		||||
#: core/models.py:23
 | 
			
		||||
#: core/models.py:24
 | 
			
		||||
msgid "meta group status"
 | 
			
		||||
msgstr "status du meta-groupe"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:25
 | 
			
		||||
#: core/models.py:26
 | 
			
		||||
msgid "Whether a group is a meta group or not"
 | 
			
		||||
msgstr "Si un groupe est un meta-groupe ou pas"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:60
 | 
			
		||||
#: core/models.py:54
 | 
			
		||||
#, python-format
 | 
			
		||||
msgid "%(value)s is not a valid promo (between 0 and %(end)s)"
 | 
			
		||||
msgstr "%(value)s n'est pas une promo valide (doit être entre 0 et %(end)s)"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:70
 | 
			
		||||
msgid "username"
 | 
			
		||||
msgstr "nom d'utilisateur"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:63
 | 
			
		||||
#: core/models.py:73
 | 
			
		||||
msgid "Required. 254 characters or fewer. Letters, digits and @/./+/-/_ only."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Requis. Pas plus de 254 caractères. Uniquement des lettres, numéros, et @/./"
 | 
			
		||||
"+/-/_"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:67
 | 
			
		||||
#: core/models.py:77
 | 
			
		||||
msgid ""
 | 
			
		||||
"Enter a valid username. This value may contain only letters, numbers and @/./"
 | 
			
		||||
"+/-/_ characters."
 | 
			
		||||
@@ -502,39 +517,43 @@ msgstr ""
 | 
			
		||||
"Entrez un nom d'utilisateur correct. Uniquement des lettres, numéros, et @/./"
 | 
			
		||||
"+/-/_"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:72
 | 
			
		||||
#: core/models.py:82
 | 
			
		||||
msgid "A user with that username already exists."
 | 
			
		||||
msgstr "Un utilisateur de ce nom existe déjà"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:75
 | 
			
		||||
#: core/models.py:85
 | 
			
		||||
msgid "first name"
 | 
			
		||||
msgstr "Prénom"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:76
 | 
			
		||||
#: core/models.py:86
 | 
			
		||||
msgid "last name"
 | 
			
		||||
msgstr "Nom"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:77
 | 
			
		||||
#: core/models.py:87
 | 
			
		||||
msgid "email address"
 | 
			
		||||
msgstr "adresse email"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:78
 | 
			
		||||
#: core/models.py:88
 | 
			
		||||
msgid "date of birth"
 | 
			
		||||
msgstr "date de naissance"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:81
 | 
			
		||||
#: core/models.py:89
 | 
			
		||||
msgid "nick name"
 | 
			
		||||
msgstr "surnom"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:91
 | 
			
		||||
msgid "staff status"
 | 
			
		||||
msgstr "status \"staff\""
 | 
			
		||||
 | 
			
		||||
#: core/models.py:83
 | 
			
		||||
#: core/models.py:93
 | 
			
		||||
msgid "Designates whether the user can log into this admin site."
 | 
			
		||||
msgstr "Est-ce que l'utilisateur peut se logger à la partie admin du site."
 | 
			
		||||
 | 
			
		||||
#: core/models.py:86
 | 
			
		||||
#: core/models.py:96
 | 
			
		||||
msgid "active"
 | 
			
		||||
msgstr "actif"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:89
 | 
			
		||||
#: core/models.py:99
 | 
			
		||||
msgid ""
 | 
			
		||||
"Designates whether this user should be treated as active. Unselect this "
 | 
			
		||||
"instead of deleting accounts."
 | 
			
		||||
@@ -542,121 +561,293 @@ msgstr ""
 | 
			
		||||
"Est-ce que l'utilisateur doit être traité comme actif. Déselectionnez au "
 | 
			
		||||
"lieu de supprimer les comptes."
 | 
			
		||||
 | 
			
		||||
#: core/models.py:93
 | 
			
		||||
#: core/models.py:103
 | 
			
		||||
msgid "date joined"
 | 
			
		||||
msgstr "date d'inscription"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:95
 | 
			
		||||
#: core/models.py:105
 | 
			
		||||
msgid "superuser"
 | 
			
		||||
msgstr "super-utilisateur"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:98
 | 
			
		||||
#: core/models.py:108
 | 
			
		||||
msgid "Designates whether this user is a superuser. "
 | 
			
		||||
msgstr "Est-ce que l'utilisateur est super-utilisateur."
 | 
			
		||||
 | 
			
		||||
#: core/models.py:280
 | 
			
		||||
#: core/models.py:113
 | 
			
		||||
msgid "profile"
 | 
			
		||||
msgstr "profil"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:114
 | 
			
		||||
msgid "avatar"
 | 
			
		||||
msgstr "avatar"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:115
 | 
			
		||||
msgid "scrub"
 | 
			
		||||
msgstr "blouse"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:116
 | 
			
		||||
msgid "sex"
 | 
			
		||||
msgstr "sexe"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:116
 | 
			
		||||
msgid "Man"
 | 
			
		||||
msgstr "Homme"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:116
 | 
			
		||||
msgid "Woman"
 | 
			
		||||
msgstr "Femme"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:117
 | 
			
		||||
msgid "tshirt size"
 | 
			
		||||
msgstr "taille de tshirt"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:118
 | 
			
		||||
msgid "-"
 | 
			
		||||
msgstr "-"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:119
 | 
			
		||||
msgid "XS"
 | 
			
		||||
msgstr "XS"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:120
 | 
			
		||||
msgid "S"
 | 
			
		||||
msgstr "S"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:121
 | 
			
		||||
msgid "M"
 | 
			
		||||
msgstr "M"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:122
 | 
			
		||||
msgid "L"
 | 
			
		||||
msgstr "L"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:123
 | 
			
		||||
msgid "XL"
 | 
			
		||||
msgstr "XL"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:124
 | 
			
		||||
msgid "XXL"
 | 
			
		||||
msgstr "XXL"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:125
 | 
			
		||||
msgid "XXXL"
 | 
			
		||||
msgstr "XXXL"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:128
 | 
			
		||||
msgid "Student"
 | 
			
		||||
msgstr "Étudiant"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:129
 | 
			
		||||
msgid "Administrative agent"
 | 
			
		||||
msgstr "Personnel administratif"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:130
 | 
			
		||||
msgid "Teacher"
 | 
			
		||||
msgstr "Enseignant"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:131
 | 
			
		||||
msgid "Agent"
 | 
			
		||||
msgstr "Personnel"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:132
 | 
			
		||||
msgid "Doctor"
 | 
			
		||||
msgstr "Doctorant"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:133
 | 
			
		||||
msgid "Former student"
 | 
			
		||||
msgstr "Ancien étudiant"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:134
 | 
			
		||||
msgid "Service"
 | 
			
		||||
msgstr "Service"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:136
 | 
			
		||||
msgid "department"
 | 
			
		||||
msgstr "département"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:137
 | 
			
		||||
msgid "TC"
 | 
			
		||||
msgstr "TC"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:138
 | 
			
		||||
msgid "IMSI"
 | 
			
		||||
msgstr "IMSI"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:139
 | 
			
		||||
msgid "IMAP"
 | 
			
		||||
msgstr "IMAP"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:140
 | 
			
		||||
msgid "INFO"
 | 
			
		||||
msgstr "INFO"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:141
 | 
			
		||||
msgid "GI"
 | 
			
		||||
msgstr "GI"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:142
 | 
			
		||||
msgid "E"
 | 
			
		||||
msgstr "E"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:143
 | 
			
		||||
msgid "EE"
 | 
			
		||||
msgstr "EE"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:144
 | 
			
		||||
msgid "GESC"
 | 
			
		||||
msgstr "GESC"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:145
 | 
			
		||||
msgid "GMC"
 | 
			
		||||
msgstr "GMC"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:146
 | 
			
		||||
msgid "MC"
 | 
			
		||||
msgstr "MC"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:147
 | 
			
		||||
msgid "EDIM"
 | 
			
		||||
msgstr "EDIM"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:148
 | 
			
		||||
msgid "Humanities"
 | 
			
		||||
msgstr "Humanités"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:149
 | 
			
		||||
msgid "N/A"
 | 
			
		||||
msgstr "N/A"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:151
 | 
			
		||||
msgid "dpt option"
 | 
			
		||||
msgstr "Filière"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:152
 | 
			
		||||
msgid "semester"
 | 
			
		||||
msgstr "semestre"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:153
 | 
			
		||||
msgid "quote"
 | 
			
		||||
msgstr "citation"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:154
 | 
			
		||||
msgid "school"
 | 
			
		||||
msgstr "école"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:155
 | 
			
		||||
msgid "promo"
 | 
			
		||||
msgstr "promo"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:156
 | 
			
		||||
msgid "forum signature"
 | 
			
		||||
msgstr "signature du forum"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:240
 | 
			
		||||
msgid "A user with that username already exists"
 | 
			
		||||
msgstr "Un utilisateur de ce nom d'utilisateur existe déjà"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:367
 | 
			
		||||
msgid "Visitor"
 | 
			
		||||
msgstr "Visiteur"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:285
 | 
			
		||||
#: core/models.py:372
 | 
			
		||||
msgid "define if we show a users stats"
 | 
			
		||||
msgstr "Definit si l'on montre les statistiques de l'utilisateur"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:287
 | 
			
		||||
#: core/models.py:374
 | 
			
		||||
msgid "Show your account statistics to others"
 | 
			
		||||
msgstr "Montrez vos statistiques de compte aux autres"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:294
 | 
			
		||||
#: core/models.py:381
 | 
			
		||||
msgid "file name"
 | 
			
		||||
msgstr "nom du fichier"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:295 core/models.py:409
 | 
			
		||||
#: core/models.py:382 core/models.py:515
 | 
			
		||||
msgid "parent"
 | 
			
		||||
msgstr "parent"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:296 core/models.py:305
 | 
			
		||||
#: core/models.py:383 core/models.py:393
 | 
			
		||||
msgid "file"
 | 
			
		||||
msgstr "fichier"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:297
 | 
			
		||||
#: core/models.py:384
 | 
			
		||||
msgid "owner"
 | 
			
		||||
msgstr "propriétaire"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:298 core/models.py:415
 | 
			
		||||
#: core/models.py:385 core/models.py:521
 | 
			
		||||
msgid "edit group"
 | 
			
		||||
msgstr "groupe d'édition"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:299 core/models.py:416
 | 
			
		||||
#: core/models.py:386 core/models.py:522
 | 
			
		||||
msgid "view group"
 | 
			
		||||
msgstr "groupe de vue"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:300
 | 
			
		||||
#: core/models.py:387
 | 
			
		||||
msgid "is folder"
 | 
			
		||||
msgstr "est un dossier"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:301
 | 
			
		||||
#: core/models.py:388
 | 
			
		||||
msgid "mime type"
 | 
			
		||||
msgstr "type mime"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:302
 | 
			
		||||
#: core/models.py:389
 | 
			
		||||
msgid "size"
 | 
			
		||||
msgstr "taille"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:316
 | 
			
		||||
#: core/models.py:419
 | 
			
		||||
msgid "Character '/' not authorized in name"
 | 
			
		||||
msgstr "Le caractère '/' n'est pas autorisé dans les noms de fichier"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:319 core/models.py:324
 | 
			
		||||
#: core/models.py:422 core/models.py:427
 | 
			
		||||
msgid "Loop in folder tree"
 | 
			
		||||
msgstr "Boucle dans l'arborescence des dossiers"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:328
 | 
			
		||||
#: core/models.py:431
 | 
			
		||||
msgid "You can not make a file be a children of a non folder file"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Vous ne pouvez pas mettre un fichier enfant de quelque chose qui n'est pas "
 | 
			
		||||
"un dossier"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:332
 | 
			
		||||
#: core/models.py:435
 | 
			
		||||
msgid "Duplicate file"
 | 
			
		||||
msgstr "Un fichier de ce nom existe déjà"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:342
 | 
			
		||||
#: core/models.py:445
 | 
			
		||||
msgid "You must provide a file"
 | 
			
		||||
msgstr "Vous devez fournir un fichier"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:367
 | 
			
		||||
#: core/models.py:470
 | 
			
		||||
msgid "Folder: "
 | 
			
		||||
msgstr "Dossier : "
 | 
			
		||||
 | 
			
		||||
#: core/models.py:369
 | 
			
		||||
#: core/models.py:472
 | 
			
		||||
msgid "File: "
 | 
			
		||||
msgstr "Fichier : "
 | 
			
		||||
 | 
			
		||||
#: core/models.py:408 core/models.py:412
 | 
			
		||||
#: core/models.py:514 core/models.py:518
 | 
			
		||||
msgid "page name"
 | 
			
		||||
msgstr "nom de la page"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:413
 | 
			
		||||
#: core/models.py:519
 | 
			
		||||
msgid "owner group"
 | 
			
		||||
msgstr "groupe propriétaire"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:444
 | 
			
		||||
#: core/models.py:550
 | 
			
		||||
msgid "Duplicate page"
 | 
			
		||||
msgstr "Une page de ce nom existe déjà"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:450
 | 
			
		||||
#: core/models.py:556
 | 
			
		||||
msgid "Loop in page tree"
 | 
			
		||||
msgstr "Boucle dans l'arborescence des pages"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:557
 | 
			
		||||
#: core/models.py:663
 | 
			
		||||
msgid "revision"
 | 
			
		||||
msgstr "révision"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:558
 | 
			
		||||
#: core/models.py:664
 | 
			
		||||
msgid "page title"
 | 
			
		||||
msgstr "titre de la page"
 | 
			
		||||
 | 
			
		||||
#: core/models.py:559
 | 
			
		||||
#: core/models.py:665
 | 
			
		||||
msgid "page content"
 | 
			
		||||
msgstr "contenu de la page"
 | 
			
		||||
 | 
			
		||||
@@ -672,48 +863,48 @@ msgstr "404. Non trouvé"
 | 
			
		||||
msgid "Welcome!"
 | 
			
		||||
msgstr "Bienvenue!"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:17
 | 
			
		||||
#: core/templates/core/base.jinja:18
 | 
			
		||||
msgid "Logo"
 | 
			
		||||
msgstr "Logo"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:20 core/templates/core/login.jinja:4
 | 
			
		||||
#: core/templates/core/base.jinja:21 core/templates/core/login.jinja:4
 | 
			
		||||
#: core/templates/core/password_reset_complete.jinja:5
 | 
			
		||||
msgid "Login"
 | 
			
		||||
msgstr "Connexion"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:21 core/templates/core/register.jinja:18
 | 
			
		||||
#: core/templates/core/base.jinja:22 core/templates/core/register.jinja:18
 | 
			
		||||
msgid "Register"
 | 
			
		||||
msgstr "S'enregister"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:24
 | 
			
		||||
#: core/templates/core/base.jinja:25
 | 
			
		||||
msgid "Tools"
 | 
			
		||||
msgstr "Outils"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:25
 | 
			
		||||
#: core/templates/core/base.jinja:26
 | 
			
		||||
msgid "Logout"
 | 
			
		||||
msgstr "Déconnexion"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:31
 | 
			
		||||
#: core/templates/core/base.jinja:36
 | 
			
		||||
msgid "Users"
 | 
			
		||||
msgstr "Utilisateurs"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:32
 | 
			
		||||
#: core/templates/core/base.jinja:37
 | 
			
		||||
msgid "Wiki"
 | 
			
		||||
msgstr "Wiki"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:33
 | 
			
		||||
#: core/templates/core/base.jinja:38
 | 
			
		||||
msgid "Pages"
 | 
			
		||||
msgstr "Pages"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:34
 | 
			
		||||
#: core/templates/core/base.jinja:39
 | 
			
		||||
msgid "Clubs"
 | 
			
		||||
msgstr "Clubs"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:35
 | 
			
		||||
#: core/templates/core/base.jinja:40
 | 
			
		||||
msgid "Services"
 | 
			
		||||
msgstr "Services"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/base.jinja:49
 | 
			
		||||
#: core/templates/core/base.jinja:55
 | 
			
		||||
msgid "Site made by good people"
 | 
			
		||||
msgstr "Site réalisé par des gens biens"
 | 
			
		||||
 | 
			
		||||
@@ -723,24 +914,29 @@ msgid "Create %(name)s"
 | 
			
		||||
msgstr "Créer %(name)s"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/delete_confirm.jinja:4
 | 
			
		||||
#: core/templates/core/file_delete_confirm.jinja:4
 | 
			
		||||
msgid "Delete confirmation"
 | 
			
		||||
msgstr "Confirmation de suppression"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/delete_confirm.jinja:6
 | 
			
		||||
#: core/templates/core/file_delete_confirm.jinja:6
 | 
			
		||||
#, python-format
 | 
			
		||||
msgid "Are you sure you want to delete \"%(obj)s\"?"
 | 
			
		||||
msgstr "Êtes-vous sûr de vouloir supprimer \"%(obj)s\" ?"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/delete_confirm.jinja:7
 | 
			
		||||
#: core/templates/core/file_delete_confirm.jinja:7
 | 
			
		||||
msgid "Confirm"
 | 
			
		||||
msgstr "Confirmation"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/delete_confirm.jinja:8
 | 
			
		||||
#: core/templates/core/file_delete_confirm.jinja:8
 | 
			
		||||
#: counter/templates/counter/counter_click.jinja:71
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
msgstr "Annuler"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/edit.jinja:4 core/templates/core/file_edit.jinja:4
 | 
			
		||||
#: core/templates/core/edit.jinja:4 core/templates/core/edit.jinja.py:8
 | 
			
		||||
#: core/templates/core/file_edit.jinja:4
 | 
			
		||||
#, python-format
 | 
			
		||||
msgid "Edit %(obj)s"
 | 
			
		||||
msgstr "Éditer %(obj)s"
 | 
			
		||||
@@ -757,35 +953,39 @@ msgstr "Nouveau fichier"
 | 
			
		||||
msgid "Not found"
 | 
			
		||||
msgstr "Non trouvé"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file.jinja:20 core/views/files.py:103
 | 
			
		||||
#: core/templates/core/file.jinja:20 core/views/files.py:42
 | 
			
		||||
msgid "Files"
 | 
			
		||||
msgstr "Fichiers"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:15
 | 
			
		||||
#: core/templates/core/file.jinja:32
 | 
			
		||||
msgid "My files"
 | 
			
		||||
msgstr "Mes fichiers"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:13
 | 
			
		||||
msgid "Owner: "
 | 
			
		||||
msgstr "Propriétaire : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:20
 | 
			
		||||
msgid "Upload"
 | 
			
		||||
msgstr "Téléverser"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:34
 | 
			
		||||
msgid "Real name: "
 | 
			
		||||
msgstr "Nom réel : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:35
 | 
			
		||||
msgid "Date: "
 | 
			
		||||
msgstr "Date : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:37
 | 
			
		||||
msgid "Type: "
 | 
			
		||||
msgstr "Type : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:36
 | 
			
		||||
#: core/templates/core/file_detail.jinja:38
 | 
			
		||||
msgid "Size: "
 | 
			
		||||
msgstr "Taille : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:36
 | 
			
		||||
#: core/templates/core/file_detail.jinja:38
 | 
			
		||||
msgid "bytes"
 | 
			
		||||
msgstr "octets"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/file_detail.jinja:37
 | 
			
		||||
#: core/templates/core/file_detail.jinja:40
 | 
			
		||||
msgid "Download"
 | 
			
		||||
msgstr "Télécharger"
 | 
			
		||||
 | 
			
		||||
@@ -797,7 +997,8 @@ msgstr "Il n'y a pas de fichier sur ce site web."
 | 
			
		||||
msgid "Edit group"
 | 
			
		||||
msgstr "Éditer le groupe"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/group_edit.jinja:9 core/templates/core/user_edit.jinja:8
 | 
			
		||||
#: core/templates/core/group_edit.jinja:9
 | 
			
		||||
#: core/templates/core/user_edit.jinja:20
 | 
			
		||||
#: core/templates/core/user_group.jinja:8
 | 
			
		||||
msgid "Update"
 | 
			
		||||
msgstr "Mettre à jour"
 | 
			
		||||
@@ -833,12 +1034,12 @@ msgstr ""
 | 
			
		||||
msgid "Please login to see this page."
 | 
			
		||||
msgstr "Merci de vous identifier pour voir cette page."
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/login.jinja:26
 | 
			
		||||
#: core/templates/core/login.jinja:28
 | 
			
		||||
#: counter/templates/counter/counter_main.jinja:48
 | 
			
		||||
msgid "login"
 | 
			
		||||
msgstr "login"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/login.jinja:30
 | 
			
		||||
#: core/templates/core/login.jinja:32
 | 
			
		||||
msgid "Lost password?"
 | 
			
		||||
msgstr "Mot de passe perdu ?"
 | 
			
		||||
 | 
			
		||||
@@ -1041,24 +1242,29 @@ msgstr "Groupes"
 | 
			
		||||
msgid "%(user_name)s's profile"
 | 
			
		||||
msgstr "Profil de %(user_name)s"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_detail.jinja:8
 | 
			
		||||
msgid "User Profile"
 | 
			
		||||
msgstr "Profil de l'utilisateur"
 | 
			
		||||
#: core/templates/core/user_detail.jinja:12
 | 
			
		||||
#: core/templates/core/user_edit.jinja:11
 | 
			
		||||
msgid "Profile"
 | 
			
		||||
msgstr "Profil"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_detail.jinja:13
 | 
			
		||||
#: core/templates/core/user_detail.jinja:17
 | 
			
		||||
msgid "Born: "
 | 
			
		||||
msgstr "Né le : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_detail.jinja:20
 | 
			
		||||
msgid "Option: "
 | 
			
		||||
msgstr "Filière : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_detail.jinja:29
 | 
			
		||||
#, python-format
 | 
			
		||||
msgid "User is subscriber until %(subscription_end)s"
 | 
			
		||||
msgstr "L'utilisateur est cotisant jusqu'au %(subscription_end)s"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_detail.jinja:22
 | 
			
		||||
#: core/templates/core/user_detail.jinja:31
 | 
			
		||||
msgid "User is not subscribed. "
 | 
			
		||||
msgstr "L'utilisateur n'est pas cotisant."
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_detail.jinja:23
 | 
			
		||||
#: core/templates/core/user_detail.jinja:32
 | 
			
		||||
#: subscription/templates/subscription/subscription.jinja:4
 | 
			
		||||
#: subscription/templates/subscription/subscription.jinja:8
 | 
			
		||||
msgid "New subscription"
 | 
			
		||||
@@ -1068,7 +1274,35 @@ msgstr "Nouvelle cotisation"
 | 
			
		||||
msgid "Edit user profile"
 | 
			
		||||
msgstr "Éditer le profil de l'utilisateur"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:11
 | 
			
		||||
#: core/templates/core/user_edit.jinja:10
 | 
			
		||||
msgid "Current profile: "
 | 
			
		||||
msgstr "Profil actuel : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:13
 | 
			
		||||
msgid "Current avatar: "
 | 
			
		||||
msgstr "Avatar actuel : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:14
 | 
			
		||||
msgid "Avatar"
 | 
			
		||||
msgstr "Avatar"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:16
 | 
			
		||||
msgid "Current scrub: "
 | 
			
		||||
msgstr "Blouse actuelle : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:17
 | 
			
		||||
msgid "Scrub"
 | 
			
		||||
msgstr "Blouse"
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:21
 | 
			
		||||
msgid "Username: "
 | 
			
		||||
msgstr "Nom d'utilisateur : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:23
 | 
			
		||||
msgid "Account number: "
 | 
			
		||||
msgstr "Numero de compte : "
 | 
			
		||||
 | 
			
		||||
#: core/templates/core/user_edit.jinja:26
 | 
			
		||||
msgid "Change my password"
 | 
			
		||||
msgstr "Changer mon mot de passe"
 | 
			
		||||
 | 
			
		||||
@@ -1134,15 +1368,44 @@ msgstr "Comptabilité générale"
 | 
			
		||||
msgid "Club account: "
 | 
			
		||||
msgstr "Compte club : "
 | 
			
		||||
 | 
			
		||||
#: core/views/files.py:134
 | 
			
		||||
#: core/views/files.py:41
 | 
			
		||||
msgid "Add a new folder"
 | 
			
		||||
msgstr "Ajouter un nouveau dossier"
 | 
			
		||||
 | 
			
		||||
#: core/views/files.py:52
 | 
			
		||||
#, python-format
 | 
			
		||||
msgid "Error creating folder %(folder_name)s: %(msg)s"
 | 
			
		||||
msgstr "Erreur de création du dossier %(folder_name)s : %(msg)s"
 | 
			
		||||
 | 
			
		||||
#: core/views/files.py:62 core/views/forms.py:130
 | 
			
		||||
#, python-format
 | 
			
		||||
msgid "Error uploading file %(file_name)s: %(msg)s"
 | 
			
		||||
msgstr "Erreur d'envoie du fichier %(file_name)s : %(msg)s"
 | 
			
		||||
 | 
			
		||||
#: core/views/forms.py:58 core/views/forms.py:61
 | 
			
		||||
#: core/views/forms.py:46 core/views/forms.py:49
 | 
			
		||||
msgid "Choose file"
 | 
			
		||||
msgstr "Choisir un fichier"
 | 
			
		||||
 | 
			
		||||
#: core/views/forms.py:88
 | 
			
		||||
msgid ""
 | 
			
		||||
"Profile: you need to be visible on the picture, in order to be recognized (e."
 | 
			
		||||
"g. by the barmen)"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Photo de profil: vous devez être visible sur la photo afin d'être reconnu "
 | 
			
		||||
"(par exemple par les barmen)"
 | 
			
		||||
 | 
			
		||||
#: core/views/forms.py:89
 | 
			
		||||
msgid "Avatar: used on the forum"
 | 
			
		||||
msgstr "Avatar : utilisé sur le forum"
 | 
			
		||||
 | 
			
		||||
#: core/views/forms.py:90
 | 
			
		||||
msgid "Scrub: let other know how your scrub looks like!"
 | 
			
		||||
msgstr "Blouse : montrez aux autres à quoi ressemble votre blouse !"
 | 
			
		||||
 | 
			
		||||
#: core/views/forms.py:120
 | 
			
		||||
msgid "Bad image format, only jpeg, png, and gif are accepted"
 | 
			
		||||
msgstr "Mauvais format d'image, seuls les jpeg, png, et gif sont acceptés"
 | 
			
		||||
 | 
			
		||||
#: counter/models.py:24
 | 
			
		||||
msgid "account id"
 | 
			
		||||
msgstr "numéro de compte"
 | 
			
		||||
@@ -1379,7 +1642,7 @@ msgstr "ANN"
 | 
			
		||||
msgid "You have not enough money to buy all the basket"
 | 
			
		||||
msgstr "Vous n'avez pas assez d'argent pour acheter le panier"
 | 
			
		||||
 | 
			
		||||
#: eboutic/models.py:47 sith/settings.py:254 sith/settings_sample.py:254
 | 
			
		||||
#: eboutic/models.py:47 sith/settings.py:257 sith/settings_sample.py:257
 | 
			
		||||
msgid "Credit card"
 | 
			
		||||
msgstr "Carte banquaire"
 | 
			
		||||
 | 
			
		||||
@@ -1520,12 +1783,12 @@ msgid "Washing and drying"
 | 
			
		||||
msgstr "Lavage et séchage"
 | 
			
		||||
 | 
			
		||||
#: launderette/templates/launderette/launderette_book.jinja:26
 | 
			
		||||
#: sith/settings.py:342 sith/settings_sample.py:342
 | 
			
		||||
#: sith/settings.py:345 sith/settings_sample.py:345
 | 
			
		||||
msgid "Washing"
 | 
			
		||||
msgstr "Lavage"
 | 
			
		||||
 | 
			
		||||
#: launderette/templates/launderette/launderette_book.jinja:30
 | 
			
		||||
#: sith/settings.py:342 sith/settings_sample.py:342
 | 
			
		||||
#: sith/settings.py:345 sith/settings_sample.py:345
 | 
			
		||||
msgid "Drying"
 | 
			
		||||
msgstr "Séchage"
 | 
			
		||||
 | 
			
		||||
@@ -1580,83 +1843,83 @@ msgstr "L'utilisateur n'a pas réservé de créneau"
 | 
			
		||||
msgid "Token not found"
 | 
			
		||||
msgstr "Jeton non trouvé"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:251 sith/settings.py:258 sith/settings.py:276
 | 
			
		||||
#: sith/settings_sample.py:251 sith/settings_sample.py:258
 | 
			
		||||
#: sith/settings_sample.py:276
 | 
			
		||||
#: sith/settings.py:254 sith/settings.py:261 sith/settings.py:279
 | 
			
		||||
#: sith/settings_sample.py:254 sith/settings_sample.py:261
 | 
			
		||||
#: sith/settings_sample.py:279
 | 
			
		||||
msgid "Check"
 | 
			
		||||
msgstr "Chèque"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:252 sith/settings.py:259 sith/settings.py:277
 | 
			
		||||
#: sith/settings_sample.py:252 sith/settings_sample.py:259
 | 
			
		||||
#: sith/settings_sample.py:277
 | 
			
		||||
#: sith/settings.py:255 sith/settings.py:262 sith/settings.py:280
 | 
			
		||||
#: sith/settings_sample.py:255 sith/settings_sample.py:262
 | 
			
		||||
#: sith/settings_sample.py:280
 | 
			
		||||
msgid "Cash"
 | 
			
		||||
msgstr "Espèces"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:253 sith/settings_sample.py:253
 | 
			
		||||
#: sith/settings.py:256 sith/settings_sample.py:256
 | 
			
		||||
msgid "Transfert"
 | 
			
		||||
msgstr "Virement"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:264 sith/settings_sample.py:264
 | 
			
		||||
#: sith/settings.py:267 sith/settings_sample.py:267
 | 
			
		||||
msgid "Belfort"
 | 
			
		||||
msgstr "Belfort"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:265 sith/settings_sample.py:265
 | 
			
		||||
#: sith/settings.py:268 sith/settings_sample.py:268
 | 
			
		||||
msgid "Sevenans"
 | 
			
		||||
msgstr "Sevenans"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:266 sith/settings_sample.py:266
 | 
			
		||||
#: sith/settings.py:269 sith/settings_sample.py:269
 | 
			
		||||
msgid "Montbéliard"
 | 
			
		||||
msgstr "Montbéliard"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:290 sith/settings_sample.py:290
 | 
			
		||||
#: sith/settings.py:293 sith/settings_sample.py:293
 | 
			
		||||
msgid "One semester"
 | 
			
		||||
msgstr "Un semestre"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:295 sith/settings_sample.py:295
 | 
			
		||||
#: sith/settings.py:298 sith/settings_sample.py:298
 | 
			
		||||
msgid "Two semesters"
 | 
			
		||||
msgstr "Deux semestres"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:300 sith/settings_sample.py:300
 | 
			
		||||
#: sith/settings.py:303 sith/settings_sample.py:303
 | 
			
		||||
msgid "Common core cursus"
 | 
			
		||||
msgstr "Cursus tronc commun"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:305 sith/settings_sample.py:305
 | 
			
		||||
#: sith/settings.py:308 sith/settings_sample.py:308
 | 
			
		||||
msgid "Branch cursus"
 | 
			
		||||
msgstr "Cursus branche"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:313 sith/settings_sample.py:313
 | 
			
		||||
#: sith/settings.py:316 sith/settings_sample.py:316
 | 
			
		||||
msgid "President"
 | 
			
		||||
msgstr "Président"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:314 sith/settings_sample.py:314
 | 
			
		||||
#: sith/settings.py:317 sith/settings_sample.py:317
 | 
			
		||||
msgid "Vice-President"
 | 
			
		||||
msgstr "Vice-Président"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:315 sith/settings_sample.py:315
 | 
			
		||||
#: sith/settings.py:318 sith/settings_sample.py:318
 | 
			
		||||
msgid "Treasurer"
 | 
			
		||||
msgstr "Trésorier"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:316 sith/settings_sample.py:316
 | 
			
		||||
#: sith/settings.py:319 sith/settings_sample.py:319
 | 
			
		||||
msgid "Communication supervisor"
 | 
			
		||||
msgstr "Responsable com"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:317 sith/settings_sample.py:317
 | 
			
		||||
#: sith/settings.py:320 sith/settings_sample.py:320
 | 
			
		||||
msgid "Secretary"
 | 
			
		||||
msgstr "Secrétaire"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:318 sith/settings_sample.py:318
 | 
			
		||||
#: sith/settings.py:321 sith/settings_sample.py:321
 | 
			
		||||
msgid "IT supervisor"
 | 
			
		||||
msgstr "Responsable info"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:319 sith/settings_sample.py:319
 | 
			
		||||
#: sith/settings.py:322 sith/settings_sample.py:322
 | 
			
		||||
msgid "Board member"
 | 
			
		||||
msgstr "Membre du bureau"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:320 sith/settings_sample.py:320
 | 
			
		||||
#: sith/settings.py:323 sith/settings_sample.py:323
 | 
			
		||||
msgid "Active member"
 | 
			
		||||
msgstr "Membre actif"
 | 
			
		||||
 | 
			
		||||
#: sith/settings.py:321 sith/settings_sample.py:321
 | 
			
		||||
#: sith/settings.py:324 sith/settings_sample.py:324
 | 
			
		||||
msgid "Curious"
 | 
			
		||||
msgstr "Curieux"
 | 
			
		||||
 | 
			
		||||
@@ -1696,3 +1959,6 @@ msgstr "Un utilisateur avec cette adresse email existe déjà"
 | 
			
		||||
msgid "You must either choose an existing user or create a new one properly"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Vous devez soit choisir un utilisateur existant, ou en créer un proprement."
 | 
			
		||||
 | 
			
		||||
#~ msgid "User Profile"
 | 
			
		||||
#~ msgstr "Profil de l'utilisateur"
 | 
			
		||||
 
 | 
			
		||||
@@ -214,6 +214,9 @@ SITH_LAUNDERETTE_MANAGER = {
 | 
			
		||||
# (month, day)
 | 
			
		||||
SITH_START_DATE = (8, 15) # 15th August
 | 
			
		||||
 | 
			
		||||
# Used to determine the valid promos
 | 
			
		||||
SITH_SCHOOL_START_YEAR = 1999
 | 
			
		||||
 | 
			
		||||
SITH_GROUPS = {
 | 
			
		||||
    'root': {
 | 
			
		||||
        'id': 1,
 | 
			
		||||
 
 | 
			
		||||