Suppression des vieilleries
This commit is contained in:
parent
b77a45a56a
commit
d1243280d8
38 changed files with 0 additions and 2204 deletions
|
@ -1,110 +0,0 @@
|
|||
"""
|
||||
Django settings for experiENS project.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.7/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/1.7/ref/settings/
|
||||
"""
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = '9+h+8jp2jphi4@m==cggy75^ghm_l**%4@y957k_*u)t4o%)*u'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
TEMPLATE_DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.gis',
|
||||
'monstage',
|
||||
'taggit',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'django_cas.backends.CASBackend',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'experiENS.urls'
|
||||
|
||||
WSGI_APPLICATION = 'experiENS.wsgi.application'
|
||||
|
||||
CAS_SERVER_URL = "https://cas.eleves.ens.fr/" #SPI CAS
|
||||
CAS_VERIFY_URL = "https://cas.eleves.ens.fr/"
|
||||
CAS_IGNORE_REFERER = True
|
||||
CAS_REDIRECT_URL = '/home/'
|
||||
CAS_EMAIL_FORMAT = "%s@clipper.ens.fr"
|
||||
|
||||
LOGIN_URL = '/login/'
|
||||
LOGOUT_URL = '/logout/'
|
||||
|
||||
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS = TCP + (
|
||||
'django.core.context_processors.request',
|
||||
)
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.contrib.gis.db.backends.postgis',
|
||||
# 'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'experiens',
|
||||
'USER': 'experiens',
|
||||
'PASSWORD': 'experiens',
|
||||
'HOST': 'localhost',
|
||||
}
|
||||
}
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.7/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'fr-fr'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.7/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
|
@ -1,9 +0,0 @@
|
|||
from django.conf.urls import patterns, include, url
|
||||
from django.contrib import admin
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^login/$', 'django_cas.views.login', name = "login"),
|
||||
url(r'^logout/$', 'django_cas.views.logout', name = "logout"),
|
||||
url(r'^', include('monstage.urls', namespace="monstage")),
|
||||
)
|
|
@ -1,14 +0,0 @@
|
|||
"""
|
||||
WSGI config for experiENS project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "experiENS.settings")
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "experiENS.settings")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
execute_from_command_line(sys.argv)
|
|
@ -1,26 +0,0 @@
|
|||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.contrib.auth.models import User
|
||||
from monstage.models import *
|
||||
|
||||
class NormalienInline(admin.StackedInline):
|
||||
model = Normalien
|
||||
inline_classes = ("collapse open",)
|
||||
|
||||
class UserAdmin(UserAdmin):
|
||||
inlines = (NormalienInline, )
|
||||
|
||||
|
||||
class LieuStageInline(admin.StackedInline):
|
||||
model = LieuStage
|
||||
inline_classes = ("collapse open",)
|
||||
extra = 0
|
||||
|
||||
class StageAdmin(admin.ModelAdmin):
|
||||
inlines = (LieuStageInline, )
|
||||
|
||||
admin.site.unregister(User)
|
||||
admin.site.register(User, UserAdmin)
|
||||
admin.site.register(Lieu)
|
||||
admin.site.register(StageMatiere)
|
||||
admin.site.register(Stage, StageAdmin)
|
|
@ -1,245 +0,0 @@
|
|||
# coding: utf-8
|
||||
|
||||
PAYS_CHOICES = (
|
||||
("AF", u"Afghanistan"),
|
||||
("AL", u"Albanie"),
|
||||
("AQ", u"Antarctique"),
|
||||
("DZ", u"Algérie"),
|
||||
("AS", u"Samoa Américaines"),
|
||||
("AD", u"Andorre"),
|
||||
("AO", u"Angola"),
|
||||
("AG", u"Antigua-et-Barbuda"),
|
||||
("AZ", u"Azerbaïdjan"),
|
||||
("AR", u"Argentine"),
|
||||
("AU", u"Australie"),
|
||||
("AT", u"Autriche"),
|
||||
("BS", u"Bahamas"),
|
||||
("BH", u"Bahreïn"),
|
||||
("BD", u"Bangladesh"),
|
||||
("AM", u"Arménie"),
|
||||
("BB", u"Barbade"),
|
||||
("BE", u"Belgique"),
|
||||
("BM", u"Bermudes"),
|
||||
("BT", u"Bhoutan"),
|
||||
("BO", u"Bolivie"),
|
||||
("BA", u"Bosnie-Herzégovine"),
|
||||
("BW", u"Botswana"),
|
||||
("BV", u"Île Bouvet"),
|
||||
("BR", u"Brésil"),
|
||||
("BZ", u"Belize"),
|
||||
("IO", u"Territoire Britannique de l'Océan Indien"),
|
||||
("SB", u"Îles Salomon"),
|
||||
("VG", u"Îles Vierges Britanniques"),
|
||||
("BN", u"Brunéi Darussalam"),
|
||||
("BG", u"Bulgarie"),
|
||||
("MM", u"Myanmar"),
|
||||
("BI", u"Burundi"),
|
||||
("BY", u"Bélarus"),
|
||||
("KH", u"Cambodge"),
|
||||
("CM", u"Cameroun"),
|
||||
("CA", u"Canada"),
|
||||
("CV", u"Cap-vert"),
|
||||
("KY", u"Îles Caïmanes"),
|
||||
("CF", u"République Centrafricaine"),
|
||||
("LK", u"Sri Lanka"),
|
||||
("TD", u"Tchad"),
|
||||
("CL", u"Chili"),
|
||||
("CN", u"Chine"),
|
||||
("TW", u"Taïwan"),
|
||||
("CX", u"Île Christmas"),
|
||||
("CC", u"Îles Cocos (Keeling)"),
|
||||
("CO", u"Colombie"),
|
||||
("KM", u"Comores"),
|
||||
("YT", u"Mayotte"),
|
||||
("CG", u"République du Congo"),
|
||||
("CD", u"République Démocratique du Congo"),
|
||||
("CK", u"Îles Cook"),
|
||||
("CR", u"Costa Rica"),
|
||||
("HR", u"Croatie"),
|
||||
("CU", u"Cuba"),
|
||||
("CY", u"Chypre"),
|
||||
("CZ", u"République Tchèque"),
|
||||
("BJ", u"Bénin"),
|
||||
("DK", u"Danemark"),
|
||||
("DM", u"Dominique"),
|
||||
("DO", u"République Dominicaine"),
|
||||
("EC", u"Équateur"),
|
||||
("SV", u"El Salvador"),
|
||||
("GQ", u"Guinée Équatoriale"),
|
||||
("ET", u"Éthiopie"),
|
||||
("ER", u"Érythrée"),
|
||||
("EE", u"Estonie"),
|
||||
("FO", u"Îles Féroé"),
|
||||
("FK", u"Îles (malvinas) Falkland"),
|
||||
("GS", u"Géorgie du Sud et les Îles Sandwich du Sud"),
|
||||
("FJ", u"Fidji"),
|
||||
("FI", u"Finlande"),
|
||||
("AX", u"Îles Åland"),
|
||||
("FR", u"France"),
|
||||
("GF", u"Guyane Française"),
|
||||
("PF", u"Polynésie Française"),
|
||||
("TF", u"Terres Australes Françaises"),
|
||||
("DJ", u"Djibouti"),
|
||||
("GA", u"Gabon"),
|
||||
("GE", u"Géorgie"),
|
||||
("GM", u"Gambie"),
|
||||
("PS", u"Territoire Palestinien Occupé"),
|
||||
("DE", u"Allemagne"),
|
||||
("GH", u"Ghana"),
|
||||
("GI", u"Gibraltar"),
|
||||
("KI", u"Kiribati"),
|
||||
("GR", u"Grèce"),
|
||||
("GL", u"Groenland"),
|
||||
("GD", u"Grenade"),
|
||||
("GP", u"Guadeloupe"),
|
||||
("GU", u"Guam"),
|
||||
("GT", u"Guatemala"),
|
||||
("GN", u"Guinée"),
|
||||
("GY", u"Guyana"),
|
||||
("HT", u"Haïti"),
|
||||
("HM", u"Îles Heard et Mcdonald"),
|
||||
("VA", u"Saint-Siège (état de la Cité du Vatican)"),
|
||||
("HN", u"Honduras"),
|
||||
("HK", u"Hong-Kong"),
|
||||
("HU", u"Hongrie"),
|
||||
("IS", u"Islande"),
|
||||
("IN", u"Inde"),
|
||||
("ID", u"Indonésie"),
|
||||
("IR", u"République Islamique d'Iran"),
|
||||
("IQ", u"Iraq"),
|
||||
("IE", u"Irlande"),
|
||||
("IL", u"Israël"),
|
||||
("IT", u"Italie"),
|
||||
("CI", u"Côte d'Ivoire"),
|
||||
("JM", u"Jamaïque"),
|
||||
("JP", u"Japon"),
|
||||
("KZ", u"Kazakhstan"),
|
||||
("JO", u"Jordanie"),
|
||||
("KE", u"Kenya"),
|
||||
("KP", u"République Populaire Démocratique de Corée"),
|
||||
("KR", u"République de Corée"),
|
||||
("KW", u"Koweït"),
|
||||
("KG", u"Kirghizistan"),
|
||||
("LA", u"République Démocratique Populaire Lao"),
|
||||
("LB", u"Liban"),
|
||||
("LS", u"Lesotho"),
|
||||
("LV", u"Lettonie"),
|
||||
("LR", u"Libéria"),
|
||||
("LY", u"Jamahiriya Arabe Libyenne"),
|
||||
("LI", u"Liechtenstein"),
|
||||
("LT", u"Lituanie"),
|
||||
("LU", u"Luxembourg"),
|
||||
("MO", u"Macao"),
|
||||
("MG", u"Madagascar"),
|
||||
("MW", u"Malawi"),
|
||||
("MY", u"Malaisie"),
|
||||
("MV", u"Maldives"),
|
||||
("ML", u"Mali"),
|
||||
("MT", u"Malte"),
|
||||
("MQ", u"Martinique"),
|
||||
("MR", u"Mauritanie"),
|
||||
("MU", u"Maurice"),
|
||||
("MX", u"Mexique"),
|
||||
("MC", u"Monaco"),
|
||||
("MN", u"Mongolie"),
|
||||
("MD", u"République de Moldova"),
|
||||
("MS", u"Montserrat"),
|
||||
("MA", u"Maroc"),
|
||||
("MZ", u"Mozambique"),
|
||||
("OM", u"Oman"),
|
||||
("NA", u"Namibie"),
|
||||
("NR", u"Nauru"),
|
||||
("NP", u"Népal"),
|
||||
("NL", u"Pays-Bas"),
|
||||
("AN", u"Antilles Néerlandaises"),
|
||||
("AW", u"Aruba"),
|
||||
("NC", u"Nouvelle-Calédonie"),
|
||||
("VU", u"Vanuatu"),
|
||||
("NZ", u"Nouvelle-Zélande"),
|
||||
("NI", u"Nicaragua"),
|
||||
("NE", u"Niger"),
|
||||
("NG", u"Nigéria"),
|
||||
("NU", u"Niué"),
|
||||
("NF", u"Île Norfolk"),
|
||||
("NO", u"Norvège"),
|
||||
("MP", u"Îles Mariannes du Nord"),
|
||||
("UM", u"Îles Mineures Éloignées des États-Unis"),
|
||||
("FM", u"États Fédérés de Micronésie"),
|
||||
("MH", u"Îles Marshall"),
|
||||
("PW", u"Palaos"),
|
||||
("PK", u"Pakistan"),
|
||||
("PA", u"Panama"),
|
||||
("PG", u"Papouasie-Nouvelle-Guinée"),
|
||||
("PY", u"Paraguay"),
|
||||
("PE", u"Pérou"),
|
||||
("PH", u"Philippines"),
|
||||
("PN", u"Pitcairn"),
|
||||
("PL", u"Pologne"),
|
||||
("PT", u"Portugal"),
|
||||
("GW", u"Guinée-Bissau"),
|
||||
("TL", u"Timor-Leste"),
|
||||
("PR", u"Porto Rico"),
|
||||
("QA", u"Qatar"),
|
||||
("RE", u"Réunion"),
|
||||
("RO", u"Roumanie"),
|
||||
("RU", u"Fédération de Russie"),
|
||||
("RW", u"Rwanda"),
|
||||
("SH", u"Sainte-Hélène"),
|
||||
("KN", u"Saint-Kitts-et-Nevis"),
|
||||
("AI", u"Anguilla"),
|
||||
("LC", u"Sainte-Lucie"),
|
||||
("PM", u"Saint-Pierre-et-Miquelon"),
|
||||
("VC", u"Saint-Vincent-et-les Grenadines"),
|
||||
("SM", u"Saint-Marin"),
|
||||
("ST", u"Sao Tomé-et-Principe"),
|
||||
("SA", u"Arabie Saoudite"),
|
||||
("SN", u"Sénégal"),
|
||||
("SC", u"Seychelles"),
|
||||
("SL", u"Sierra Leone"),
|
||||
("SG", u"Singapour"),
|
||||
("SK", u"Slovaquie"),
|
||||
("VN", u"Viet Nam"),
|
||||
("SI", u"Slovénie"),
|
||||
("SO", u"Somalie"),
|
||||
("ZA", u"Afrique du Sud"),
|
||||
("ZW", u"Zimbabwe"),
|
||||
("ES", u"Espagne"),
|
||||
("EH", u"Sahara Occidental"),
|
||||
("SD", u"Soudan"),
|
||||
("SR", u"Suriname"),
|
||||
("SJ", u"Svalbard etÎle Jan Mayen"),
|
||||
("SZ", u"Swaziland"),
|
||||
("SE", u"Suède"),
|
||||
("CH", u"Suisse"),
|
||||
("SY", u"République Arabe Syrienne"),
|
||||
("TJ", u"Tadjikistan"),
|
||||
("TH", u"Thaïlande"),
|
||||
("TG", u"Togo"),
|
||||
("TK", u"Tokelau"),
|
||||
("TO", u"Tonga"),
|
||||
("TT", u"Trinité-et-Tobago"),
|
||||
("AE", u"Émirats Arabes Unis"),
|
||||
("TN", u"Tunisie"),
|
||||
("TR", u"Turquie"),
|
||||
("TM", u"Turkménistan"),
|
||||
("TC", u"Îles Turks et Caïques"),
|
||||
("TV", u"Tuvalu"),
|
||||
("UG", u"Ouganda"),
|
||||
("UA", u"Ukraine"),
|
||||
("MK", u"L'ex-République Yougoslave de Macédoine"),
|
||||
("EG", u"Égypte"),
|
||||
("GB", u"Royaume-Uni"),
|
||||
("IM", u"Île de Man"),
|
||||
("TZ", u"République-Unie de Tanzanie"),
|
||||
("US", u"États-Unis"),
|
||||
("VI", u"Îles Vierges des États-Unis"),
|
||||
("BF", u"Burkina Faso"),
|
||||
("UY", u"Uruguay"),
|
||||
("UZ", u"Ouzbékistan"),
|
||||
("VE", u"Venezuela"),
|
||||
("WF", u"Wallis et Futuna"),
|
||||
("WS", u"Samoa"),
|
||||
("YE", u"Yémen"),
|
||||
("CS", u"Serbie-et-Monténégro"),
|
||||
("ZM", u"Zambie"),
|
||||
)
|
|
@ -1,98 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
import django.contrib.gis.db.models.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Lieu',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('name', models.CharField(max_length=250, verbose_name="Nom de l'institution d'accueil")),
|
||||
('ville', models.CharField(max_length=200, verbose_name='Ville, Pays')),
|
||||
('coord', django.contrib.gis.db.models.fields.PointField(srid=4326, verbose_name='Coordonn\xe9es', geography=True)),
|
||||
('type_lieu', models.CharField(default=b'universite', max_length=15, verbose_name="Type de structure d'accueil", choices=[(b'universite', 'Universit\xe9'), (b'entreprise', 'Entreprise'), (b'centrerecherche', 'Centre de recherche'), (b'administration', 'Administration'), (b'autre', 'Autre')])),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LieuStage',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('avis_global', models.TextField(verbose_name='Ressenti global', blank=True)),
|
||||
('avis_lieudevie', models.TextField(verbose_name='Mon lieu de vie', blank=True)),
|
||||
('avis_lieustage', models.TextField(verbose_name='Le lieu du stage', blank=True)),
|
||||
('avis_pratique', models.TextField(verbose_name="S'installer / Conseils pratiques", blank=True)),
|
||||
('avis_visite', models.TextField(verbose_name='Que voir / que faire', blank=True)),
|
||||
('avis_anecdotes', models.TextField(verbose_name='Anecdotes', blank=True)),
|
||||
('lieu', models.ForeignKey(to='monstage.Lieu')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Normalien',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('permanent_mail', models.CharField(max_length=200, verbose_name=b'Adresse e-mail permanente', blank=True)),
|
||||
('user', models.OneToOneField(related_name='profil', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Profil \xe9l\xe8ve',
|
||||
'verbose_name_plural': 'Profils \xe9l\xe8ves',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Stage',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('published', models.BooleanField(default=False, verbose_name='Visible publiquement')),
|
||||
('type_stage', models.CharField(default=b'stage', max_length=5, verbose_name='Type', choices=[(b'stage', 'Stage')])),
|
||||
('start_date', models.DateField(null=True, verbose_name='Date de d\xe9but')),
|
||||
('end_date', models.DateField(null=True, verbose_name='Date de fin')),
|
||||
('sujet', models.CharField(max_length=500, verbose_name='Sujet')),
|
||||
('encadrants', models.CharField(max_length=500, verbose_name='Encadrants', blank=True)),
|
||||
('avis_encadrants', models.TextField(verbose_name='Avis sur les encadrants', blank=True)),
|
||||
('avis_equipe', models.TextField(verbose_name="Avis sur l'\xe9quipe", blank=True)),
|
||||
('avis_stage', models.TextField(verbose_name='Int\xe9r\xeat du stage', blank=True)),
|
||||
('avis_admin', models.TextField(verbose_name='Visa et administratif', blank=True)),
|
||||
('lieux', models.ManyToManyField(related_name='stages', through='monstage.LieuStage', to='monstage.Lieu')),
|
||||
('user', models.ForeignKey(related_name='stages', to='monstage.Normalien')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StageMatiere',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('name', models.CharField(max_length=30, verbose_name='Mati\xe8re')),
|
||||
('users', models.ManyToManyField(related_name='matieres', to='monstage.Stage')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Mati\xe8re des stages',
|
||||
'verbose_name_plural': 'Mati\xe8res des stages',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lieustage',
|
||||
name='stage',
|
||||
field=models.ForeignKey(to='monstage.Stage'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -1,41 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('monstage', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='lieu',
|
||||
options={'verbose_name': 'Lieu', 'verbose_name_plural': 'Lieux'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='lieustage',
|
||||
options={'verbose_name': 'Avis sur un lieu de stage', 'verbose_name_plural': 'Avis sur un lieu de stage'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='stage',
|
||||
options={'verbose_name': 'Stage', 'verbose_name_plural': 'Stages'},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='stage',
|
||||
old_name='user',
|
||||
new_name='profil_user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='stagematiere',
|
||||
name='users',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='stage',
|
||||
name='matieres',
|
||||
field=models.ManyToManyField(related_name='stages', to='monstage.StageMatiere'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -1,26 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('monstage', '0002_auto_20150612_2003'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='lieu',
|
||||
name='pays',
|
||||
field=models.CharField(default='', max_length=200, verbose_name='Pays'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='lieu',
|
||||
name='ville',
|
||||
field=models.CharField(max_length=200, verbose_name='Ville'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
File diff suppressed because one or more lines are too long
|
@ -1,22 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import taggit.managers
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('taggit', '0001_initial'),
|
||||
('monstage', '0004_auto_20150614_1517'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='stage',
|
||||
name='thematiques',
|
||||
field=taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Th\xe9matiques'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -1,136 +0,0 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.gis.db import models as geomodels
|
||||
from django.db.models.signals import post_save
|
||||
|
||||
from taggit.managers import TaggableManager
|
||||
|
||||
from monstage.listepays import PAYS_CHOICES
|
||||
|
||||
import ldap
|
||||
|
||||
TYPE_STAGE_CHOICES = (
|
||||
('stage', _(u"Stage")),
|
||||
)
|
||||
|
||||
TYPE_LIEU_CHOICES = (
|
||||
('universite', _(u"Université")),
|
||||
('entreprise', _(u"Entreprise")),
|
||||
('centrerecherche', _(u"Centre de recherche")),
|
||||
('administration', _(u"Administration")),
|
||||
('autre', _(u"Autre")),
|
||||
)
|
||||
|
||||
def choices_length (choices):
|
||||
return reduce (lambda m, choice: max (m, len (choice[0])), choices, 0)
|
||||
|
||||
class Normalien(models.Model):
|
||||
user = models.OneToOneField(User, related_name = "profil")
|
||||
permanent_mail = models.CharField("Adresse e-mail permanente", max_length = 200, blank = True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = u"Profil élève"
|
||||
verbose_name_plural = u"Profils élèves"
|
||||
|
||||
def __unicode__(self):
|
||||
if self.user.first_name:
|
||||
return unicode(self.user.first_name + " " + self.user.last_name)
|
||||
return unicode(self.user)
|
||||
|
||||
def create_user_profile(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
Normalien.objects.get_or_create(user = instance)
|
||||
try:
|
||||
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
|
||||
l = ldap.initialize("ldaps://ldap.spi.ens.fr:636")
|
||||
l.set_option(ldap.OPT_REFERRALS, 0)
|
||||
l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
|
||||
l.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
|
||||
l.set_option( ldap.OPT_X_TLS_DEMAND, True )
|
||||
l.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
|
||||
info = l.search_s('dc=spi,dc=ens,dc=fr',ldap.SCOPE_SUBTREE,'(uid=%s)' % (instance.username,),['cn','mail'])
|
||||
if len(info) > 0:
|
||||
noms = info[0][1]['cn'][0].split(" ")
|
||||
instance.first_name = noms[0]
|
||||
instance.last_name = ' '.join(noms[1:])
|
||||
instance.save()
|
||||
except ldap.LDAPError:
|
||||
pass
|
||||
post_save.connect(create_user_profile, sender = User)
|
||||
|
||||
class Lieu(models.Model):
|
||||
name = models.CharField(_(u"Nom de l'institution d'accueil"), max_length = 250)
|
||||
ville = models.CharField(_(u"Ville"), max_length = 200)
|
||||
pays = models.CharField(_(u"Pays"),
|
||||
choices = PAYS_CHOICES,
|
||||
max_length = choices_length (TYPE_STAGE_CHOICES))
|
||||
coord = geomodels.PointField(_(u"Coordonnées"), geography = True)
|
||||
objects = geomodels.GeoManager() # Requis par GeoDjango
|
||||
type_lieu = models.CharField( _(u"Type de structure d'accueil"),
|
||||
default = "universite",
|
||||
choices = TYPE_LIEU_CHOICES,
|
||||
max_length = choices_length (TYPE_LIEU_CHOICES))
|
||||
|
||||
def __unicode__(self):
|
||||
return u"%s (%s)" % (self.name, self.ville)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Lieu"
|
||||
verbose_name_plural = "Lieux"
|
||||
|
||||
class StageMatiere(models.Model):
|
||||
name = models.CharField(_(u"Matière"), max_length = 30)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Matière des stages"
|
||||
verbose_name_plural = "Matières des stages"
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Stage(models.Model):
|
||||
profil_user = models.ForeignKey(Normalien, related_name = "stages")
|
||||
published = models.BooleanField(_("Visible publiquement"), default = False)
|
||||
type_stage = models.CharField (_(u"Type"),
|
||||
default = "stage",
|
||||
choices = TYPE_STAGE_CHOICES,
|
||||
max_length = choices_length (TYPE_STAGE_CHOICES))
|
||||
start_date = models.DateField(_(u"Date de début"), null = True)
|
||||
end_date = models.DateField(_(u"Date de fin"), null = True)
|
||||
sujet = models.CharField(_(u"Sujet"), max_length = 500)
|
||||
thematiques = TaggableManager(_(u"Thématiques"), blank = True)
|
||||
encadrants = models.CharField(_(u"Encadrants"), max_length = 500, blank = True)
|
||||
lieux = models.ManyToManyField(Lieu, related_name = "stages", through = "LieuStage")
|
||||
matieres = models.ManyToManyField(StageMatiere, related_name = "stages")
|
||||
|
||||
# Avis
|
||||
avis_encadrants = models.TextField(_(u"Avis sur les encadrants"), blank = True)
|
||||
avis_equipe = models.TextField(_(u"Avis sur l'équipe"), blank = True)
|
||||
avis_stage = models.TextField(_(u"Intérêt du stage"), blank = True)
|
||||
avis_admin = models.TextField(_(u"Visa et administratif"), blank = True)
|
||||
|
||||
def __unicode__(self):
|
||||
return u"%s : %s" % (self.profil_user.user.username, self.sujet)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Stage"
|
||||
verbose_name_plural = "Stages"
|
||||
|
||||
class LieuStage(models.Model):
|
||||
stage = models.ForeignKey(Stage)
|
||||
lieu = models.ForeignKey(Lieu)
|
||||
|
||||
# Avis
|
||||
avis_global = models.TextField(_(u"Ressenti global"), blank = True)
|
||||
avis_lieudevie = models.TextField(_(u"Mon lieu de vie"), blank = True)
|
||||
avis_lieustage = models.TextField(_(u"Le lieu du stage"), blank = True)
|
||||
avis_pratique = models.TextField(_(u"S'installer / Conseils pratiques"), blank = True)
|
||||
avis_visite = models.TextField(_(u"Que voir / que faire"), blank = True)
|
||||
avis_anecdotes = models.TextField(_(u"Anecdotes"), blank = True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Avis sur un lieu de stage"
|
||||
verbose_name_plural = "Avis sur un lieu de stage"
|
Binary file not shown.
Before Width: | Height: | Size: 32 KiB |
Binary file not shown.
Before Width: | Height: | Size: 33 KiB |
|
@ -1,62 +0,0 @@
|
|||
@charset "utf-8";
|
||||
|
||||
.entrer {
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.entrer a, a.btn {
|
||||
display:inline-block;
|
||||
background:#FFA41E;
|
||||
color:#fff;
|
||||
font-size:1.5em;
|
||||
padding:8px;
|
||||
border-radius:5px;
|
||||
}
|
||||
|
||||
a.btn {
|
||||
display:inline-block;
|
||||
background:#FFA41E;
|
||||
color:#fff;
|
||||
font-size:1.2em;
|
||||
padding:10px;
|
||||
margin-top:12px;
|
||||
border-radius:5px;
|
||||
}
|
||||
|
||||
.explications {
|
||||
background:#348d68;
|
||||
display:table-row;
|
||||
}
|
||||
|
||||
.explications img, .explications p {
|
||||
display:table-cell;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.explications p {
|
||||
color:#fff;
|
||||
padding:20px;
|
||||
font-size:1.1em;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.homeh1 p {
|
||||
float:right;
|
||||
}
|
||||
|
||||
.homeh1 h1 {
|
||||
display:inline-block;
|
||||
margin-bottom:3px;
|
||||
}
|
||||
|
||||
.homeh1 {
|
||||
border-bottom:1px solid #888;
|
||||
overflow:hidden;
|
||||
margin-bottom:15px;
|
||||
}
|
||||
|
||||
.betacadre {
|
||||
background:#bbb;
|
||||
padding:20px;
|
||||
margin:20px 0;
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,415 +0,0 @@
|
|||
@charset "utf-8";
|
||||
@import url(http://fonts.googleapis.com/css?family=Lato:300,700,300italic);
|
||||
|
||||
body {
|
||||
font: 18px 'Lato', sans-serif;
|
||||
background:#4FB088;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight:bold;
|
||||
color:#4FB088;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
.beta {
|
||||
font-size:0.5em;
|
||||
display:inline-block;
|
||||
transform:rotate(-20deg);
|
||||
color:#aaa;
|
||||
}
|
||||
|
||||
header {
|
||||
background:#166142;
|
||||
padding:10px;
|
||||
margin:0;
|
||||
overflow:hidden;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
header li {
|
||||
display:inline-block;
|
||||
text-align:center;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
float:left;
|
||||
color:#fff;
|
||||
margin:20px;
|
||||
}
|
||||
|
||||
header h1 a {
|
||||
color:#fff;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
header li a {
|
||||
display:inline-block;
|
||||
padding:20px 20px;
|
||||
margin:0 5px;
|
||||
}
|
||||
|
||||
header li a:hover {
|
||||
background:#4FB088;
|
||||
color:#166142;
|
||||
}
|
||||
|
||||
header ul {
|
||||
float:right;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
header .username {
|
||||
color:#fff;
|
||||
font-weight:normal;
|
||||
}
|
||||
|
||||
.footer {
|
||||
clear:both;
|
||||
font-size:14px;
|
||||
color:#555;
|
||||
text-align:right;
|
||||
margin-top:25px;
|
||||
}
|
||||
|
||||
#content {
|
||||
width:80%;
|
||||
max-width:700px;
|
||||
padding:30px;
|
||||
margin:20px auto;
|
||||
background:#eee;
|
||||
}
|
||||
|
||||
/* formulaires */
|
||||
label {
|
||||
display:inline-block;
|
||||
font-weight:bold;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
form {
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
form p {
|
||||
padding:10px;
|
||||
overflow:hidden;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
form p:nth-child(2n) {
|
||||
background:#fff;
|
||||
}
|
||||
|
||||
form p:nth-child(2n+1) {
|
||||
background:#ddd;
|
||||
}
|
||||
|
||||
form textarea, form input, form select {
|
||||
display:block;
|
||||
font:16px 'Lato', sans-serif;
|
||||
margin:10px;
|
||||
float:right;
|
||||
}
|
||||
|
||||
form textarea {
|
||||
resize:vertical;
|
||||
}
|
||||
|
||||
form textarea {
|
||||
width:90%;
|
||||
}
|
||||
|
||||
.helptext {
|
||||
display:block;
|
||||
font-size:0.8em;
|
||||
color:#333;
|
||||
text-align:right;
|
||||
margin-top:10px;
|
||||
width:100%;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
/* lieux */
|
||||
#map_addlieu {
|
||||
width:100%;
|
||||
height:300px;
|
||||
}
|
||||
|
||||
input#addlieu {
|
||||
font-size:20px;
|
||||
padding:15px;
|
||||
width:70%;
|
||||
margin:0 auto;
|
||||
float:none;
|
||||
}
|
||||
|
||||
div.lieuform {
|
||||
display:block;
|
||||
border:1px solid #337359;
|
||||
padding:10px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
div.lieuform h3 {
|
||||
margin:0px;
|
||||
margin-bottom:5px;
|
||||
}
|
||||
|
||||
div.lieuform p {
|
||||
background:none;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
div#candidats ul {
|
||||
list-style:none;
|
||||
padding:10px;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
div#candidats li{
|
||||
list-style:none;
|
||||
display:block;
|
||||
overflow:hidden;
|
||||
padding:0;
|
||||
border:2px #fff;
|
||||
}
|
||||
|
||||
div#candidats li a, div#candidats #addcandidat {
|
||||
display:block;
|
||||
background:#5AC99C;
|
||||
padding:10px;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
div#candidats li a .choice_btn {
|
||||
float:right;
|
||||
background:none;
|
||||
text-decoration:underline;
|
||||
border:none;
|
||||
}
|
||||
|
||||
div#candidats #addcandidat {
|
||||
width:90%;
|
||||
margin:15px auto;
|
||||
}
|
||||
|
||||
|
||||
div#candidats input {
|
||||
float:none;
|
||||
}
|
||||
|
||||
div#candidats #addcandidat {
|
||||
font-size:20px;
|
||||
}
|
||||
|
||||
#addlieu_win .win_content{
|
||||
max-width:600px;
|
||||
}
|
||||
|
||||
.btn_like {
|
||||
display:block;
|
||||
background:#5AC99C;
|
||||
padding:10px;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
#addlieu_btn {
|
||||
text-align:center;
|
||||
font-size:1.5em;
|
||||
padding:30px;
|
||||
}
|
||||
|
||||
#addlieu_btn:before {
|
||||
content:"+";
|
||||
margin-right:12px;
|
||||
}
|
||||
|
||||
/* stages */
|
||||
#stage_present {
|
||||
display:table;
|
||||
background: #fff;
|
||||
border-spacing:20px;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#stage_misc {
|
||||
display:table-cell;
|
||||
min-width:300px;
|
||||
}
|
||||
|
||||
#stage_map {
|
||||
display:table-cell;
|
||||
min-width:300px;
|
||||
}
|
||||
|
||||
#stage_published.published {
|
||||
background:#9f9;
|
||||
}
|
||||
|
||||
#stage_published.unpublished {
|
||||
background:#f99;
|
||||
}
|
||||
|
||||
#stage_published input {
|
||||
display:inline;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#stage_published p {
|
||||
background:none;
|
||||
}
|
||||
|
||||
ul.bigger {
|
||||
display:block;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
ul.bigger li {
|
||||
display:table-row;
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
ul.bigger li:hover{
|
||||
background:#ccc;
|
||||
}
|
||||
|
||||
.stagestatus {
|
||||
display:table-cell;
|
||||
width:100px;
|
||||
text-align:right;
|
||||
padding-right:20px;
|
||||
}
|
||||
|
||||
.stagelink {
|
||||
display:table-cell;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
.stagestatus.draft {
|
||||
color:#f00;
|
||||
}
|
||||
|
||||
.changestage {
|
||||
color:#B8741A;
|
||||
}
|
||||
|
||||
/* Fenêtre */
|
||||
|
||||
.win_bg {
|
||||
display:none;
|
||||
position:fixed;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:rgba(0,0,0,0.6);
|
||||
z-index:300;
|
||||
top:0;
|
||||
left:0;
|
||||
}
|
||||
|
||||
.win_centrer {
|
||||
display:table-cell;
|
||||
vertical-align:middle;
|
||||
text-align:center;
|
||||
overflow-y:auto;
|
||||
}
|
||||
|
||||
.win_close {
|
||||
float:right;
|
||||
}
|
||||
|
||||
.win_content {
|
||||
text-align:left;
|
||||
display:inline-block;
|
||||
padding:0;
|
||||
max-width:500px;
|
||||
width:90%;
|
||||
background:#fff;
|
||||
}
|
||||
|
||||
.win_content h2 {
|
||||
background:#000;
|
||||
color:#fff;
|
||||
padding:20px;
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
.win_content textarea {
|
||||
min-height:150px;
|
||||
}
|
||||
|
||||
/* Fenêtres spéciales */
|
||||
|
||||
#feedback_btn {
|
||||
position:fixed;
|
||||
top:65%;
|
||||
left:0;
|
||||
z-index:40;
|
||||
background:#000;
|
||||
color:#fff;
|
||||
padding:20px;
|
||||
transform:rotate(-90deg);
|
||||
font-weight:bold;
|
||||
transform-origin:top left;
|
||||
}
|
||||
|
||||
.success {
|
||||
background:#9f9;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
.failure {
|
||||
padding:5px;
|
||||
background:#f99;
|
||||
}
|
||||
|
||||
/* Recherche */
|
||||
form.recherche p {
|
||||
background:none;
|
||||
}
|
||||
form.recherche {
|
||||
background:#ddd;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
form.recherche .criteria {
|
||||
display:table;
|
||||
width:100%;
|
||||
}
|
||||
form.recherche .criteria p {
|
||||
display:table-cell;
|
||||
}
|
||||
|
||||
form.recherche .lieu {
|
||||
display:table;
|
||||
}
|
||||
|
||||
form.recherche .lieu div {
|
||||
display:table-cell;
|
||||
}
|
||||
|
||||
#map_searchlieu {
|
||||
width:50%;
|
||||
}
|
||||
|
||||
.stagefound {
|
||||
background:#fff;
|
||||
padding:10px;
|
||||
margin:10px 0;
|
||||
}
|
||||
|
||||
.stagefound h3 {
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
.stagefound p {
|
||||
margin-bottom:0px;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block extra_head %}
|
||||
<link type="text/css" href="{% static 'index.css' %}" rel="stylesheet" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Accès interdit</h1>
|
||||
{% if unpublished %}<p>Le stage n'est pas encore publié</p>
|
||||
{% elif notowned %}<p>Ce stage ne vous appartient pas, vous ne pouvez pas le modifier</p>
|
||||
{% else %}<p>L'accès à ce contenu est interdit</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% if user.first_name %}
|
||||
<h1>Bonjour {{ user.first_name }} !</h1>
|
||||
<p><a href="{% url 'monstage:profil_edit' %}" class="changestage">Modifier mon profil</a></p>
|
||||
{% else %}
|
||||
<h1>Bonjour {{ user.username }} !</h1>
|
||||
<p>Je ne connais pas votre prénom. Pensez à le <a href="{% url 'monstage:profil_edit' %}" class="changestage">renseigner ici</a> !</p>
|
||||
{% endif %}
|
||||
<h2>Mes stages</h2>
|
||||
<ul class="bigger">
|
||||
{% for stage in stages %}
|
||||
<li>
|
||||
<span class="stagestatus {{ stage.published|yesno:'published,draft' }}">{{ stage.published|yesno:"Publié,Brouillon" }}</span>
|
||||
<a href="{% url 'monstage:stage' stage.id %}" class="stagelink">{{ stage.sujet }}</a></li>
|
||||
{% endfor %}
|
||||
<li><span class="stagestatus">+</span><a href="{% url 'monstage:stage_add' %}" class="stagelink changestage">Ajouter un stage</a></li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block extra_head %}
|
||||
<link type="text/css" href="{% static 'index.css' %}" rel="stylesheet" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="homeh1">
|
||||
<h1>ExperiENS<span class="beta">beta</span></h1>
|
||||
<p>Partagez vos expériences de stages !</p>
|
||||
</div>
|
||||
<div class="betacadre">
|
||||
Ce site est en cours de développement, et fait l'objet de mises à jours régulières. N'hésitez pas cependant à remplir une fiche pour vos stages, utiliser la recherche, et donner votre avis en utilisant le bouton "feedback".
|
||||
</div>
|
||||
{% if not user.username %}
|
||||
<div class="entrer">
|
||||
<p><a href="{% url 'login' %}">Connexion</a></p>
|
||||
<p class="helptext">Connexion via le serveur central d'authentification ENS (identifiants clipper)</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="explications">
|
||||
<p>Ne partez plus en stage en terre inconnue : nourrissez-vous de l'expérience de {{ stats.num_stages }} stages effectués par la communauté normalienne, repérez les bons plans, et ne faites pas les mêmes erreurs !
|
||||
{% if user.username %}<br /><a href="{% url 'monstage:search' %}" class="btn">Rechercher des stages</a>{% endif %}</p>
|
||||
<img src="{% static 'home2.jpg' %}" width="350"/>
|
||||
</div>
|
||||
<div class="explications">
|
||||
<img src="{% static 'home1.jpg' %}" width="350"/>
|
||||
<p>Vous revenez du bout du monde (ou de la rue d'à côté) ? N'attendez plus, rédigez un avis sur votre stage pour que votre expérience profite à d'autres !
|
||||
{% if user.username %}<br /><a href="{% url 'monstage:home' %}" class="btn">Partager ses stages</a>{% endif %}</p>
|
||||
</div>
|
||||
<div class="footer">Propulsé par Django, <a href="http://evarin.fr" target="_blank">Evarin</a> et Damien</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"lieux": [ {% for lieu in lieux %} {% if not forloop.first %},{% endif %}
|
||||
{ "name": "{{ lieu.name }}", "id": "{{ lieu.id }}", "lat": {{ lieu.lat }}, "lon": {{ lieu.lon }}, "distance": "{{ lieu.distance }}" }
|
||||
{% endfor %} ]
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ profil }}</h1>
|
||||
<h2>Ses stages</h2>
|
||||
{% if stages %}
|
||||
<ul class="bigger">
|
||||
{% for stage in stages %}
|
||||
<li><a href="{% url 'monstage:stage' stage.id %}" class="stagelink">{{ stage.sujet }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>Aucun stage pour le moment</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Modifier son profil</h1>
|
||||
<p><a href="{% url 'monstage:home' %}">Retour</a></p>
|
||||
<form action="{% url 'monstage:profil_edit' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<p><label for="first_name">Prénom : </label><input type="text" name="first_name" id="first_name" value="{{ user.first_name }}" /> </p>
|
||||
<p><label for="last_name">Nom : </label><input type="text" name="last_name" id="last_name" value="{{ user.last_name }}" /> </p>
|
||||
<input type="submit" value="Enregistrer" />
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block extra_head %}
|
||||
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places" type="text/javascript"></script>
|
||||
<script src="{% static 'script/jquery-1.11.1.min.js' %}" type="text/javascript"></script>
|
||||
<script src="{% static 'script/jquery.geocomplete.min.js' %}" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Rechercher des stages</h1>
|
||||
<div id="searchbox">
|
||||
<form action="{% url 'monstage:search' %}" method="get" class="recherche">
|
||||
<p>Critères :</p>
|
||||
<div class="criteria">
|
||||
<p>
|
||||
{{ form.matiere.errors }}
|
||||
{{ form.matiere.label_tag }}
|
||||
{{ form.matiere }}
|
||||
</p>
|
||||
<p>
|
||||
{{ form.thematiques.errors }}
|
||||
{{ form.thematiques.label_tag }}
|
||||
{{ form.thematiques }}
|
||||
</p>
|
||||
</div>
|
||||
{{ form.latitude }}
|
||||
{{ form.longitude }}
|
||||
<div class="lieu">
|
||||
<div class="champs">
|
||||
<p>
|
||||
{{ form.lieu.errors }}
|
||||
{{ form.lieu.label_tag }}
|
||||
{{ form.lieu }}
|
||||
</p>
|
||||
<p id="search_tolerance" style="display:none">
|
||||
{{ form.tolerance.errors }}
|
||||
{{ form.tolerance.label_tag }}
|
||||
{{ form.tolerance }}
|
||||
</p>
|
||||
</div>
|
||||
<div id="map_searchlieu"></div>
|
||||
</div>
|
||||
<script>
|
||||
$(function(){
|
||||
$("#id_lieu").attr("placeholder", "(N'importe où)").geocomplete({
|
||||
map: "#map_searchlieu",
|
||||
types: ["geocode", "establishment"],
|
||||
}).on("geocode:result", function(event, result){
|
||||
$("#map_searchlieu").css("display", "table-cell");
|
||||
digere(result);
|
||||
console.log(result);
|
||||
if($("#id_latitude").val() != "") {
|
||||
$("#search_tolerance").css("display", "block");
|
||||
}
|
||||
});
|
||||
if($("#id_latitude").val() != "") {
|
||||
$("#search_tolerance").css("display", "block");
|
||||
}
|
||||
});
|
||||
|
||||
var predata;
|
||||
function digere (gdata) {
|
||||
var data = {};
|
||||
for (var i in gdata.address_components) {
|
||||
var obj = gdata.address_components[i];
|
||||
for (var j in obj.types) {
|
||||
switch(obj.types[j]) {
|
||||
case "locality":
|
||||
data["ville"] = obj.long_name;
|
||||
break;
|
||||
case "country":
|
||||
data["pays"] = obj.short_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
data["name"] = gdata.name;
|
||||
data["longitude"] = gdata.geometry.location.lng();
|
||||
data["latitude"] = gdata.geometry.location.lat();
|
||||
$("#id_longitude").val(data["longitude"]);
|
||||
$("#id_latitude").val(data["latitude"]);
|
||||
}
|
||||
|
||||
</script>
|
||||
<input type="submit" action="submit" value="Rechercher" />
|
||||
</form>
|
||||
</div>
|
||||
{% if resultats != None %}
|
||||
<p><a name="resultats"></a>{{ resultats|length }} stage(s) trouvé(s)</p>
|
||||
{% for stage in resultats %}
|
||||
<div class="stagefound">
|
||||
<h3><a href="{% url 'monstage:stage' stage.id %}">{{ stage.sujet }}</a></h3>
|
||||
<p>Par <a href="{% url 'monstage:profil' stage.profil_user.user.username %}">{{ stage.profil_user }}</a> à {% for lieu in stage.lieux.all %}{% if not forloop.first %}{% if forloop.last %} et {% else %}, {% endif %}{% endif %}{{ lieu.name }} ({{ lieu.ville }}){% endfor %}, en {{ stage.end_date|date:'Y' }}.</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,102 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
|
||||
{% block extra_head %}
|
||||
<script src="http://maps.googleapis.com/maps/api/js"></script>
|
||||
<script>
|
||||
function initialize() {
|
||||
var lieux = [ {% for coords in lieux_latlng %}
|
||||
new google.maps.LatLng({{ coords }}) {% if not forloop.last %},{% endif %}
|
||||
{% endfor %} ];
|
||||
var mapProp = {
|
||||
center:new google.maps.LatLng({{ lieux_latlng.0 }}),
|
||||
zoom:7,
|
||||
mapTypeId:google.maps.MapTypeId.ROADMAP
|
||||
};
|
||||
var map = new google.maps.Map(document.getElementById("stage_map"),mapProp);
|
||||
for (var i in lieux) {
|
||||
var marker = new google.maps.Marker({
|
||||
position:lieux[i],
|
||||
});
|
||||
marker.setMap(map);
|
||||
}
|
||||
}
|
||||
google.maps.event.addDomListener(window, 'load', initialize);
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p><a href="{% url 'monstage:home' %}">Retour</a></p>
|
||||
<h1>{{ stage.sujet }}</h1>
|
||||
{% if modifiable %}
|
||||
<form action="{% url 'monstage:stage_publish' stage.id %}" method="post">
|
||||
{% csrf_token %}
|
||||
<div id="stage_published" class="{{ published|yesno:'published,unpublished' }}">
|
||||
<input type="hidden" name="publishit" value="{{ published|yesno:'no,yes' }}" />
|
||||
{% if published %}
|
||||
<p>Ce stage est publié et visible des autres utilisateurs <input type="submit" value="Masquer" /></p>
|
||||
{% else %}
|
||||
<p>Ce stage est un brouillon invisible des autres utilisateurs <input type="submit" value="Publier" /></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
<div id="stage_present">
|
||||
{% if stage.lieux.all %}
|
||||
<div id="stage_map"></div>
|
||||
{% endif %}
|
||||
<div id="stage_misc">
|
||||
{% if modifiable %}<p><a href="{% url 'monstage:stage_edit_desc' stage.id %}" class="changestage">Modifier la description du stage (sujet, ...)</a></p>{% endif %}
|
||||
<p><a href="{% url 'monstage:profil' stage.profil_user.user.username %}">{{ stage.profil_user.user.first_name }} {{ stage.profil_user.user.last_name }}</a> a fait ce stage du {{ stage.start_date }} au {{ stage.end_date }}{% if stage.encadrants %}, supervisé par {{ stage.encadrants }}{% endif %}.</p>
|
||||
<p>Matières : {% for matiere in stage.matieres.all %}{% if not forloop.first %}, {% endif %}{{ matiere.name }}{% endfor %}</p>
|
||||
<p>Thématiques : {% for tag in stage.thematiques.names %}{% if not forloop.first %}, {% endif %}{{ tag }}{% endfor %}</p>
|
||||
{% if stage.lieux.all %}<p>À {% for lieu in stage.lieux.all %}{% if not forloop.first %}{% if forloop.last %} et {% else %}, {% endif %}{% endif %}{{ lieu.name }} ({{ lieu.ville }}){% endfor %}</p>{% endif %}
|
||||
{% if modifiable %}<p><a href="{% url 'monstage:stage_edit_lieu' stage.id %}" class="changestage">Modifier les lieux du stage</a></p>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if modifiable %}<p><a href="{% url 'monstage:stage_edit_feedback' stage.id %}" class="changestage">Modifier les avis sur le stage</a></p>{% endif %}
|
||||
<h2>Ressenti sur le stage</h2>
|
||||
{% if stage.avis_encadrants %}
|
||||
<h3>Les encadrants : {{ stage.encadrants }}</h3>
|
||||
{{ stage.avis_encadrants|linebreaks }}
|
||||
{% endif %}
|
||||
{% if stage.avis_equipe %}
|
||||
<h3>L'équipe</h3>
|
||||
{{ stage.avis_equipe|linebreaks }}
|
||||
{% endif %}
|
||||
{% if stage.avis_stage %}
|
||||
<h3>Le stage en général</h3>
|
||||
{{ stage.avis_stage|linebreaks }}
|
||||
{% endif %}
|
||||
{% if stage.avis_admin %}
|
||||
<h3>L'administratif et le visa</h3>
|
||||
{{ stage.avis_admin|linebreaks }}
|
||||
{% endif %}
|
||||
{% for lieustage in stage.lieustage_set.all %}
|
||||
<h2>La vie à {{ lieustage.lieu.ville }}, {{ lieustage.lieu.get_pays_display }}</h2>
|
||||
{% if lieustage.avis_global %}
|
||||
<h3>Ressenti global du séjour</h3>
|
||||
{{ lieustage.avis_global|linebreaks }}
|
||||
{% endif %}
|
||||
{% if lieustage.avis_lieudevie %}
|
||||
<h3>Mon lieu de vie</h3>
|
||||
{{ lieustage.avis_lieudevie|linebreaks }}
|
||||
{% endif %}
|
||||
{% if lieustage.avis_lieustage %}
|
||||
<h3>Le lieu du stage : {{ lieustage.lieu.name }}</h3>
|
||||
{{ lieustage.avis_lieustage|linebreaks }}
|
||||
{% endif %}
|
||||
{% if lieustage.avis_pratique %}
|
||||
<h3>S'installer / conseils pratiques</h3>
|
||||
{{ lieustage.avis_pratique|linebreaks }}
|
||||
{% endif %}
|
||||
{% if lieustage.avis_visite %}
|
||||
<h3>A voir, à faire aux alentours de {{ lieustage.lieu.ville }}</h3>
|
||||
{{ lieustage.avis_visite|linebreaks }}
|
||||
{% endif %}
|
||||
{% if lieustage.avis_anecdotes %}
|
||||
<h3>Anecdotes</h3>
|
||||
{{ lieustage.avis_anecdotes|linebreaks }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Ajouter un stage</h1>
|
||||
<p><a href="{% url 'monstage:index' %}">Retour</a></p>
|
||||
<form action="{% url 'monstage:stage_add' %}" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Etape suivante" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Editer le stage {{ stage.sujet }}</h1>
|
||||
<p><a href="{% url 'monstage:stage' stage.id %}">Retour</a></p>
|
||||
<p><a href="{% url 'monstage:stage_edit_desc' stage.id %}">Modifier la description du stage (sujet, ...)</a></p>
|
||||
<p><a href="{% url 'monstage:stage_edit_lieu' stage.id %}">Modifier les lieux du stage</a></p>
|
||||
<p><a href="{% url 'monstage:stage_edit_feedback' stage.id %}">Modifier son avis sur le stage</a></p>
|
||||
{% endblock %}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Modifier la description du stage "{{ stage.sujet }}"</h1>
|
||||
<p><a href="{% url 'monstage:stage' stage.id %}">Retour</a></p>
|
||||
<form action="{% url 'monstage:stage_edit_desc' stage.id %}" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Enregistrer" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Avis sur le stage "{{ stage.sujet }}"</h1>
|
||||
<p><a href="{% url 'monstage:stage' stage.id %}">Retour</a></p>
|
||||
<p>{{ debug }}</p>
|
||||
<form action="{% url 'monstage:stage_edit_feedback' stage.id %}" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="avis_gen">
|
||||
<h2>Le déroulement du stage</h2>
|
||||
{{ form_gen.as_p }}
|
||||
</div>
|
||||
{% for obj in forms_lieux %}
|
||||
<div class="avis_lieux">
|
||||
<h2>Avis sur le lieu "{{ obj.1.name }}"</h2>
|
||||
{{ obj.0.as_p }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<input type="submit" value="Enregistrer" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
{% extends "skeleton.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block extra_head %}
|
||||
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places" type="text/javascript"></script>
|
||||
<script src="{% static 'script/jquery-1.11.1.min.js' %}" type="text/javascript"></script>
|
||||
<script src="{% static 'script/jquery.geocomplete.min.js' %}" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Lieux du stage "{{ stage.sujet }}"</h1>
|
||||
<p><a href="{% url 'monstage:stage' stage.id %}">Retour</a></p>
|
||||
|
||||
<form action="{% url 'monstage:stage_edit_lieu' stage.id %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" id="numplaces" name="numplaces" value="{{ numforms }}" />
|
||||
<div id="places">
|
||||
<h2>Liste des lieux de ce stage</h2>
|
||||
{% for lieuform in lieuforms %}
|
||||
<div class="lieuform">
|
||||
<h3>{{ lieuform.0.name }}</h3>
|
||||
<p>{{ lieuform.0.ville }}, {{ lieuform.0.get_pays_display }}</p>
|
||||
{{ lieuform.1.as_p }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<a id="addlieu_btn" class="btn_like" href="javascript:showAddLieu(true);">Ajouter un lieu</a>
|
||||
|
||||
<div id="addlieu_win" class="win_bg">
|
||||
<div class="win_centrer">
|
||||
<div class="win_content">
|
||||
<h2>Ajouter un autre lieu<a class="win_close" href="javascript:showAddLieu(false)">X</a></h2>
|
||||
<p><input id="addlieu" type="text" placeholder="Chercher un établissement" /></p>
|
||||
<div id="map_addlieu"></div>
|
||||
<div id="candidats"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Enregistrer" onclick="return checkForm();"/>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
var emptyform = "{{ emptyform |safe }}";
|
||||
var emptylieu = "{{ emptylieu |safe }}";
|
||||
|
||||
$(function(){
|
||||
$("#addlieu").geocomplete({
|
||||
map: "#map_addlieu",
|
||||
types: ["geocode", "establishment"],
|
||||
}).on("geocode:result", function(event, result){ digere(result); console.log(result); });
|
||||
});
|
||||
var fieldcount = {{ numforms }};
|
||||
var places = $("#places");
|
||||
|
||||
function addNewPlace (data) {
|
||||
if (data == undefined) return;
|
||||
var t = $("<div>", {class:"lieuform"})
|
||||
t.html(emptyform.replace(/\{\{ID\}\}/gi, fieldcount));
|
||||
places.append(t);
|
||||
document.getElementById('id_'+fieldcount+'-name').value = data.name;
|
||||
document.getElementById('id_'+fieldcount+'-ville').value = data.ville;
|
||||
document.getElementById('id_'+fieldcount+'-pays').value = data.pays;
|
||||
document.getElementById('id_'+fieldcount+'-latitude').value = data.latitude;
|
||||
document.getElementById('id_'+fieldcount+'-longitude').value = data.longitude;
|
||||
fieldcount++;
|
||||
document.getElementById('numplaces').value = fieldcount;
|
||||
predata = undefined;
|
||||
showAddLieu(false);
|
||||
clearCandidats();
|
||||
}
|
||||
|
||||
function addKnownPlace(data) {
|
||||
if (data == undefined) return;
|
||||
var t = $("<div>", {class:"lieuform"})
|
||||
t.html(emptylieu.replace(/\{\{ID\}\}/gi, fieldcount));
|
||||
t.prepend($("<h3>", {html:data.name}));
|
||||
places.append(t);
|
||||
document.getElementById('id_'+fieldcount+'-lieu_id').value = data.id;
|
||||
fieldcount++;
|
||||
document.getElementById('numplaces').value = fieldcount;
|
||||
predata = undefined;
|
||||
showAddLieu(false);
|
||||
clearCandidats();
|
||||
$("#map_addlieu").css("display", "none");
|
||||
}
|
||||
|
||||
var predata;
|
||||
function digere (gdata) {
|
||||
var data = {};
|
||||
for (var i in gdata.address_components) {
|
||||
var obj = gdata.address_components[i];
|
||||
for (var j in obj.types) {
|
||||
switch(obj.types[j]) {
|
||||
case "locality":
|
||||
data["ville"] = obj.long_name;
|
||||
break;
|
||||
case "country":
|
||||
data["pays"] = obj.short_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
data["name"] = gdata.name;
|
||||
data["longitude"] = gdata.geometry.location.lng();
|
||||
data["latitude"] = gdata.geometry.location.lat();
|
||||
predata = data;
|
||||
getCandidats(data);
|
||||
}
|
||||
|
||||
function getCandidats (data) {
|
||||
$.getJSON("{% url 'monstage:lieux_candidats' %}", {lat:data.latitude, lon:data.longitude}, showCandidats);
|
||||
clearCandidats();
|
||||
$("#candidats").append($("<p>", {text:"Recherche des lieux connus..."}));
|
||||
|
||||
}
|
||||
|
||||
function showCandidats (candidats) {
|
||||
var liste = $("<ul>");
|
||||
for (var i in candidats.lieux) {
|
||||
lieu = candidats.lieux[i];
|
||||
console.log(lieu)
|
||||
liste.append($("<li>", {html: "<a class=\"choose_lieu\" href=\"javascript:void(0);\"> "+lieu.name + " ("+lieu.distance+") <span class=\"choice_btn\">Choisir cet établissement</span></a>"}).prop("data", lieu).click(clickCandidat));
|
||||
}
|
||||
var candi = $("#candidats");
|
||||
clearCandidats();
|
||||
if (candidats.lieux.length == 0) {
|
||||
candi.append($("<h3>", {text:"(Aucun établissement déjà référencé à proximité)"}));
|
||||
candi.append($("<input>", {id:"addcandidat", type:"button", class:"btn_like", value:"Enregistrer une nouvelle institution"})
|
||||
.click(function(){addNewPlace(predata)}) );
|
||||
} else {
|
||||
candi.append($("<h3>", {text:"Choisir parmi les lieux déjà référencés :"}));
|
||||
candi.append(liste);
|
||||
candi.append($("<input>", {id:"addcandidat", type:"button", class:"btn_like", value:"Ou bien créer une nouvelle institution"})
|
||||
.click(function(){addNewPlace(predata)}) );
|
||||
}
|
||||
hackForGMaps();
|
||||
}
|
||||
|
||||
function clearCandidats () {
|
||||
var candi = $("#candidats");
|
||||
$.each(candi.children(), function(i, item){$(item).remove()});
|
||||
}
|
||||
|
||||
function clickCandidat () {
|
||||
addKnownPlace(this.data);
|
||||
clearCandidats();
|
||||
}
|
||||
|
||||
function checkForm () {
|
||||
for(var i=0; i<fieldcount; i++){
|
||||
if (!document.getElementById('id_'+i+'-delete').checked)
|
||||
return true;
|
||||
}
|
||||
if(confirm("Vous n'avez aucun lieu de précisé, vous ne pourrez pas donner d'avis complet sur votre stage !\nÊtes-vous sûr de vouloir continuer ?")) {
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
}
|
||||
|
||||
function showAddLieu(show) {
|
||||
document.getElementById("addlieu_win").style.display=show?"table":"none";
|
||||
}
|
||||
|
||||
function hackForGMaps() { // le widget google maps ne s'affiche pas correctement. un event resize le fait s'afficher normalement, don't ask why
|
||||
var v = document.createEvent("UIEvent");
|
||||
v.initUIEvent('resize', true, false, window, 0);
|
||||
window.dispatchEvent(v);
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
{% load staticfiles %}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block title %}ExperiENS{% endblock %}</title>
|
||||
<link type="text/css" rel="stylesheet" href="{% static 'style.css' %}" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<script type="text/javascript">function showFeedback(show){document.getElementById("feedback_win").style.display=show?"table":"none";}</script>
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<h1><a href="{% url 'monstage:index' %}">ExperiENS<span class='beta'>beta</span></a></h1>
|
||||
|
||||
<nav>
|
||||
<ul id="menu">
|
||||
<li><a href="{% url 'monstage:index' %}">Accueil</a></li>
|
||||
{% if user.username %}
|
||||
<li><a href="{% url 'monstage:home' %}">Mon expérience</a></li>
|
||||
<li><a href="{% url 'monstage:search' %}">Recherche</a></li>
|
||||
{% endif %}
|
||||
{% if user.is_staff %}
|
||||
<li><a href="{% url 'admin:index' %}">Administration</a></li>
|
||||
{% endif %}
|
||||
{% if user.username %}<li><a href="{% url 'logout' %}"><span class="username">{{ user.username }}</span><br/> Déconnexion</a></li>
|
||||
{% else %}<li><a href="{% url 'login' %}">Connexion</a></li>{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{% if user.username %}
|
||||
<div id="feedback_win" class="win_bg">
|
||||
<div class="win_centrer">
|
||||
<div class="win_content">
|
||||
<h2>Envoyer un avis sur le site<a class="win_close" href="javascript:showFeedback(false)">X</a></h2>
|
||||
<form method="POST" action="{% url 'monstage:send_feedback' %}?next={{ request.path|urlencode }}">
|
||||
{% csrf_token %}
|
||||
<p>Connecté en tant que {{ user.profil }}</p>
|
||||
<p><label for="id_feedback-message">Commentaire :</label><textarea name="feedback-message" id="id_feedback-message"></textarea></p>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a id="feedback_btn" href="javascript:showFeedback(true)">
|
||||
Feedback
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<div id="content">
|
||||
{% if request.GET.feedback_sent %}<p class="success">Merci pour votre message !</p>{% endif %}
|
||||
{% if request.GET.feedback_error %}<p class="failure">Erreur lors de l'envoi du message.</p>{% endif %}
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,3 +0,0 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -1,19 +0,0 @@
|
|||
from django.conf.urls import patterns, url
|
||||
|
||||
from monstage import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', views.index, name='index'),
|
||||
url(r'^home/$', views.home, name='home'),
|
||||
url(r'^profil/show/(?P<profil_id>\w+)/$', views.profil, name='profil'),
|
||||
url(r'^profil/edit/$', views.profil_edit, name='profil_edit'),
|
||||
url(r'^api/lieux/candidats/$', views.lieux_candidats, name='lieux_candidats'),
|
||||
url(r'^stage/(?P<stage_id>\d+)/$', views.stage, name='stage'),
|
||||
url(r'^stage/new/$', views.stage_add, name='stage_add'),
|
||||
url(r'^stage/(?P<stage_id>\d+)/edit/description/$', views.stage_edit_desc, name='stage_edit_desc'),
|
||||
url(r'^stage/(?P<stage_id>\d+)/edit/lieu/$', views.stage_edit_lieu, name='stage_edit_lieu'),
|
||||
url(r'^stage/(?P<stage_id>\d+)/edit/avis/$', views.stage_edit_feedback, name='stage_edit_feedback'),
|
||||
url(r'^stage/(?P<stage_id>\d+)/edit/publish/$', views.stage_publish, name='stage_publish'),
|
||||
url(r'^recherche/$', views.search, name='search'),
|
||||
url(r'^feedback/send/$', views.send_feedback, name='send_feedback'),
|
||||
)
|
|
@ -1,340 +0,0 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, HttpResponseNotFound
|
||||
from django.core.urlresolvers import reverse
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.gis.geos import GEOSGeometry
|
||||
from django.contrib.gis import measure
|
||||
from django.forms.widgets import HiddenInput
|
||||
from django.core.mail import send_mail
|
||||
from django.template.defaultfilters import slugify
|
||||
|
||||
from monstage.models import *
|
||||
|
||||
def addslashes(s):
|
||||
d = {'"':'\\"', "\0":"\\\0", "\\":"\\\\", '\n':'\\n'}
|
||||
return ''.join(d.get(c, c) for c in s)
|
||||
|
||||
def index(request):
|
||||
stats = { 'num_stages': Stage.objects.filter(published=True).count() }
|
||||
return render(request, 'monstage/index.html', {'stats': stats})
|
||||
|
||||
def forbidden(request, type):
|
||||
context = {}
|
||||
context[type] = True
|
||||
return render(request, 'monstage/forbidden.html', context)
|
||||
|
||||
@login_required
|
||||
def home(request):
|
||||
stages = request.user.profil.stages.all()
|
||||
return render(request, 'monstage/home.html', {"stages" : stages})
|
||||
|
||||
#
|
||||
# Utilisateurs et profils
|
||||
#
|
||||
|
||||
def profil(request, profil_id):
|
||||
user = get_object_or_404( User, username = profil_id )
|
||||
profil = user.profil
|
||||
stages = Stage.objects.filter( profil_user = profil )
|
||||
return render(request, 'monstage/profil.html', {'profil': profil, 'stages': stages})
|
||||
|
||||
@login_required
|
||||
def profil_edit(request):
|
||||
if request.POST:
|
||||
user = request.user
|
||||
user.first_name = request.POST['first_name']
|
||||
user.last_name = request.POST['last_name']
|
||||
user.save()
|
||||
return HttpResponseRedirect(reverse('monstage:home'))
|
||||
else:
|
||||
(profil, _) = Normalien.objects.get_or_create( user = request.user )
|
||||
return render(request, 'monstage/profil_edit.html', {'normalien': profil})
|
||||
|
||||
#
|
||||
# Stages
|
||||
#
|
||||
|
||||
@login_required
|
||||
def stage(request, stage_id):
|
||||
stage = get_object_or_404( Stage, pk = stage_id)
|
||||
lieux_latlng = []
|
||||
if not stage.published and not stage.profil_user == request.user.profil:
|
||||
return forbidden(request, 'unpublished')
|
||||
for lieu in stage.lieux.all():
|
||||
# GEOS Format : (longitude, latitude)
|
||||
lieux_latlng.append("%f, %f" % (lieu.coord.y, lieu.coord.x))
|
||||
context = {
|
||||
'stage': stage,
|
||||
'modifiable': (stage.profil_user == request.user.profil),
|
||||
'lieux_latlng': lieux_latlng,
|
||||
'published':stage.published,
|
||||
}
|
||||
return render(request, 'monstage/stage.html', context)
|
||||
|
||||
class StageForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Stage
|
||||
fields = ("type_stage", "start_date", "end_date", "matieres", "sujet", "thematiques", "encadrants")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(StageForm, self).__init__(*args, **kwargs)
|
||||
self.fields['matieres'].label = "Matières"
|
||||
self.fields['thematiques'].help_text = "Une liste de tags séparés par des virgules (ou des espaces)"
|
||||
self.fields['start_date'].widget.attrs['placeholder'] = "JJ/MM/AAAA"
|
||||
self.fields['end_date'].widget.attrs['placeholder'] = "JJ/MM/AAAA"
|
||||
|
||||
@login_required
|
||||
def stage_add(request):
|
||||
if request.POST:
|
||||
form = StageForm(request.POST)
|
||||
if form.is_valid:
|
||||
new_stage = form.save(commit = False)
|
||||
new_stage.profil_user = request.user.profil
|
||||
new_stage.save()
|
||||
form.save_m2m()
|
||||
return HttpResponseRedirect(reverse('monstage:stage_edit_lieu', args=(new_stage.id,)))
|
||||
else:
|
||||
form = StageForm()
|
||||
return render(request, 'monstage/stage_add.html', { 'form': form })
|
||||
|
||||
@login_required
|
||||
def stage_edit_desc(request, stage_id):
|
||||
stage = get_object_or_404( Stage, pk = stage_id)
|
||||
if stage.profil_user != request.user.profil:
|
||||
return forbidden(request, 'notowned')
|
||||
bullshit = ""
|
||||
if request.POST:
|
||||
form = StageForm(request.POST, instance = stage)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect(reverse('monstage:stage', args=(stage.id,)))
|
||||
else:
|
||||
form = StageForm(instance = stage)
|
||||
return render(request, 'monstage/stage_edit_desc.html', { 'stage': stage, 'form':form })
|
||||
|
||||
class LieuStageForm(forms.Form):
|
||||
lieu_id = forms.IntegerField(widget = HiddenInput())
|
||||
delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '')
|
||||
|
||||
def is_to_delete(self):
|
||||
return self.cleaned_data['delete']
|
||||
|
||||
class LieuForm(forms.ModelForm):
|
||||
latitude = forms.DecimalField()
|
||||
longitude = forms.DecimalField()
|
||||
delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LieuForm, self).__init__(*args, **kwargs)
|
||||
self.fields['latitude'].widget = HiddenInput()
|
||||
self.fields['longitude'].widget = HiddenInput()
|
||||
lieu = kwargs.pop('instance', None)
|
||||
if lieu:
|
||||
# GEOS Format : (longitude, latitude)
|
||||
self.fields['longitude'].initial = lieu.coord.x
|
||||
self.fields['latitude'].initial = lieu.coord.y
|
||||
|
||||
class Meta:
|
||||
model = Lieu
|
||||
fields = ("name", "type_lieu", "ville", "pays")
|
||||
|
||||
def is_to_delete(self):
|
||||
return self.cleaned_data['delete']
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
lieu = super(LieuForm, self).save(commit=False, *args, **kwargs)
|
||||
# GEOS Format : (longitude, latitude)
|
||||
lieu.coord = GEOSGeometry('POINT(%f %f)' % (self.cleaned_data['longitude'], self.cleaned_data['latitude']), srid=4326)
|
||||
return lieu
|
||||
|
||||
def lieux_candidats(request):
|
||||
if request.GET:
|
||||
lat = float(request.GET.get('lat', False))
|
||||
lon = float(request.GET.get('lon', False))
|
||||
if lat and lon:
|
||||
# GEOS Format : (longitude, latitude)
|
||||
coords = GEOSGeometry('POINT(%f %f)' % (lon, lat), srid=4326)
|
||||
distance = {'km': 0.5}
|
||||
lieux = Lieu.objects.filter(coord__distance_lte=(coords, measure.D(**distance)))
|
||||
lieux = lieux.distance(coords).order_by('distance')
|
||||
retour = [ {'name': addslashes(lieu.name), 'id': lieu.id, 'lat':str(lieu.coord.coords[0]), 'lon':str(lieu.coord.coords[1]), 'distance':lieu.distance } for lieu in lieux.distance(coords) ]
|
||||
return render(request, 'monstage/lieux_proches.json', { 'lieux':retour }, content_type='text/plain; charset=utf-8')
|
||||
return HttpResponseNotFound()
|
||||
|
||||
def stage_edit_lieu(request, stage_id):
|
||||
stage = get_object_or_404( Stage, pk = stage_id)
|
||||
bullshit = ''
|
||||
if stage.profil_user != request.user.profil:
|
||||
return forbidden(request, 'notowned')
|
||||
if request.POST:
|
||||
valid = True
|
||||
prevLieuxStage = [k for k in stage.lieustage_set.all()]
|
||||
lieuforms = []
|
||||
deleted = []
|
||||
for i in range(0, int(request.POST['numplaces'])): # Pour chaque lieu
|
||||
toSave = False
|
||||
if request.POST.get('%d-name' % i, False): # Lieu à créer
|
||||
bullshit += str(i) + 'a '
|
||||
lieuform = LieuForm(request.POST, prefix = str(i))
|
||||
if not lieuform.is_valid():
|
||||
valid = False
|
||||
lieuforms.append(lieuform)
|
||||
continue
|
||||
if lieuform.is_to_delete(): # On ne fait rien : le lieu est nouveau donc n'était pas encore en mémoire
|
||||
pass
|
||||
else: # On crée un nouveau lieu
|
||||
lieu = lieuform.save()
|
||||
lieu.save()
|
||||
lieuform.save_m2m()
|
||||
toSave = True
|
||||
lieuforms.append(LieuStageForm(initial = {'lieu_id': lieu.id}, prefix = str(i)))
|
||||
elif request.POST.get('%d-lieu_id' % i, False): # Lien vers un lieu déjà existant
|
||||
bullshit += str(i) + 'b '
|
||||
lieuform = LieuStageForm(request.POST, prefix = str(i))
|
||||
if not lieuform.is_valid():
|
||||
bullshit += 'invalid '
|
||||
valid = False
|
||||
lieuforms.append(lieuform)
|
||||
continue
|
||||
if lieuform.is_to_delete(): # On transvase de prevLieuxStage vers deleted pour conserver l'assignation des commentaires
|
||||
if len(prevLieuxStage) > 0:
|
||||
deleted.append(prevLieuxStage.pop(0))
|
||||
else: # On récupère le lieu concerné
|
||||
lieuforms.append(lieuform)
|
||||
lieu = Lieu.objects.get( pk = lieuform.cleaned_data['lieu_id'] )
|
||||
toSave = True
|
||||
if toSave: # Mise à jour des lieuStage
|
||||
if len(prevLieuxStage) > 0: # On met à jour un lieuStage conservé (même lieu)
|
||||
lieustage = prevLieuxStage.pop(0)
|
||||
lieustage.lieu = lieu
|
||||
lieustage.save()
|
||||
elif len(deleted) > 0: # On réutilise l'emplacement d'un lieuStage qui a été supprimé (pour éviter de perdre les commentaires)
|
||||
lieustage = deleted.pop(0)
|
||||
lieustage.lieu = lieu
|
||||
lieustage.save()
|
||||
else: # On en crée un nouveau
|
||||
LieuStage.objects.create(lieu = lieu, stage = stage)
|
||||
if valid:
|
||||
for lieustage in deleted: # On supprime effectivement les lieuStages non réutilisé
|
||||
lieustage.delete()
|
||||
return HttpResponseRedirect(reverse('monstage:stage_edit_feedback', args=(stage.id,)))
|
||||
else:
|
||||
lieuforms = [(lieu, LieuStageForm(initial={'lieu_id': lieu.id}, prefix=str(counter))) for counter, lieu in enumerate(stage.lieux.all())]
|
||||
emptyform = LieuForm(prefix='{{ID}}')
|
||||
emptylieu = LieuStageForm(prefix='{{ID}}')
|
||||
return render(request, 'monstage/stage_edit_lieu.html', { 'stage': stage, 'debug': bullshit, 'lieuforms': lieuforms, 'emptyform': addslashes(emptyform.as_p()), 'emptylieu': addslashes(emptylieu.as_p()), 'numforms':len(lieuforms) })
|
||||
|
||||
class StageFeedbackForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Stage
|
||||
fields = ("avis_encadrants", "avis_equipe", "avis_stage", "avis_admin")
|
||||
|
||||
class LieuStageFeedbackForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = LieuStage
|
||||
fields = ("avis_global", "avis_lieudevie", "avis_lieustage", "avis_pratique", "avis_visite", "avis_anecdotes")
|
||||
|
||||
def stage_edit_feedback(request, stage_id):
|
||||
stage = get_object_or_404( Stage, pk = stage_id)
|
||||
if stage.profil_user != request.user.profil:
|
||||
return forbidden(request, 'notowned')
|
||||
if request.POST:
|
||||
form_gen = StageFeedbackForm(request.POST, instance = stage, prefix = 'gen')
|
||||
forms_lieux = [(LieuStageFeedbackForm(request.POST, instance = lieustage, prefix = lieustage.id), lieustage.lieu) for lieustage in stage.lieustage_set.all()]
|
||||
valid = form_gen.is_valid()
|
||||
for (form, _) in forms_lieux:
|
||||
if not form.is_valid():
|
||||
valid = False
|
||||
if valid:
|
||||
form_gen.save()
|
||||
for (form, _) in forms_lieux:
|
||||
form.save()
|
||||
return HttpResponseRedirect(reverse('monstage:stage', args=(stage.id,)))
|
||||
else:
|
||||
form_gen = StageFeedbackForm(instance = stage, prefix = 'gen')
|
||||
forms_lieux = [(LieuStageFeedbackForm(instance = lieustage, prefix = lieustage.id), lieustage.lieu) for lieustage in stage.lieustage_set.all()]
|
||||
return render(request, 'monstage/stage_edit_feedback.html', { 'stage': stage, 'form_gen':form_gen, 'forms_lieux':forms_lieux })
|
||||
|
||||
def stage_publish(request, stage_id):
|
||||
stage = get_object_or_404( Stage, pk = stage_id)
|
||||
if request.POST:
|
||||
publishit = request.POST.get('publishit', False)
|
||||
if publishit == "yes":
|
||||
stage.published = True
|
||||
stage.save()
|
||||
elif publishit == "no":
|
||||
stage.published = False
|
||||
stage.save()
|
||||
return HttpResponseRedirect(reverse('monstage:stage', args=(stage_id,)))
|
||||
|
||||
def detail(request, question_id):
|
||||
question = get_object_or_404(Question, pk=question_id)
|
||||
return render(request, 'monstage/detail.html', {'question': question})
|
||||
|
||||
|
||||
#
|
||||
# Recherche de stages
|
||||
#
|
||||
from django.db.models import Q
|
||||
|
||||
class SearchForm(forms.Form):
|
||||
matiere = forms.ModelChoiceField(label='Matière :', required=False, queryset = StageMatiere.objects.all(), empty_label="Toute matière")
|
||||
thematiques = forms.CharField(label='Thématiques :', required=False)
|
||||
|
||||
latitude = forms.DecimalField(widget=HiddenInput(), required=False)
|
||||
longitude = forms.DecimalField(widget=HiddenInput(), required=False)
|
||||
lieu = forms.CharField(label=u'A proximité de :', required=False)
|
||||
tolerance = forms.DecimalField(label='Dans un rayon de (en km) :', initial=100, required=False)
|
||||
|
||||
@login_required
|
||||
def search(request):
|
||||
stages = None
|
||||
if request.GET:
|
||||
form = SearchForm(request.GET)
|
||||
if form.is_valid():
|
||||
lon = form.cleaned_data['longitude']
|
||||
lat = form.cleaned_data['latitude']
|
||||
lieu = form.cleaned_data['lieu']
|
||||
stages = Stage.objects.filter(published=True)
|
||||
if lat and lon and lieu:
|
||||
coords = GEOSGeometry('POINT(%f %f)' % (lon, lat), srid=4326)
|
||||
distance = {'km': form.cleaned_data['tolerance']}
|
||||
lieux = Lieu.objects.filter(coord__distance_lte=(coords, measure.D(**distance)))
|
||||
lieux = lieux.distance(coords).order_by('distance')
|
||||
stages = stages.filter(lieux__in=lieux)
|
||||
matiere = form.cleaned_data['matiere']
|
||||
if matiere:
|
||||
stages = stages.filter(matieres=matiere)
|
||||
thematiques = form.cleaned_data['thematiques'].split(',')
|
||||
if thematiques:
|
||||
q = Q()
|
||||
for thematique in thematiques:
|
||||
q |= Q(thematiques__slug__contains = slugify(thematique))
|
||||
stages = stages.filter(q).distinct()
|
||||
stages = stages.all()
|
||||
else:
|
||||
form = SearchForm()
|
||||
return render(request, 'monstage/search.html', {'form':form, 'resultats':stages})
|
||||
|
||||
#
|
||||
# Feedback
|
||||
#
|
||||
|
||||
class FeedbackForm(forms.Form):
|
||||
message = forms.CharField(label='Commentaire')
|
||||
|
||||
@login_required
|
||||
def send_feedback(request):
|
||||
redirection = request.GET.get('next', reverse('monstage:index')) if request.GET else reverse('monstage:index')
|
||||
if request.POST:
|
||||
form = FeedbackForm(request.POST, prefix="feedback")
|
||||
if form.is_valid():
|
||||
dests = [ mail for (nom, mail) in settings.ADMINS ]
|
||||
send_mail('Commentaire à propos d\'experiENS', form.cleaned_data["message"], ("%s@clipper.ens.fr" % (request.user.username,)), dests)
|
||||
return HttpResponseRedirect(redirection+"?feedback_sent=1")
|
||||
return HttpResponseRedirect(redirection+"?feedback_error=1")
|
||||
return HttpResponseRedirect(redirection)
|
Loading…
Reference in a new issue