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