Merge branch 'master' into Kerl/venv

This commit is contained in:
Martin Pépin 2016-11-18 01:09:39 +01:00
commit 6de2fa307b
12 changed files with 82 additions and 61 deletions

40
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,40 @@
services:
- mysql:latest
- redis:latest
variables:
# GestioCOF settings
DJANGO_SETTINGS_MODULE: "cof.settings_dev"
DBNAME: "cof_gestion"
DBUSER: "cof_gestion"
DBPASSWD: "cof_password"
DBHOST: "mysql"
REDIS_HOST: "redis"
# Cached packages
PYTHONPATH: "$CI_PROJECT_DIR/vendor/python"
# mysql service configuration
MYSQL_DATABASE: "$DBNAME"
MYSQL_USER: "$DBUSER"
MYSQL_PASSWORD: "$DBPASSWD"
MYSQL_ROOT_PASSWORD: "root_password"
cache:
paths:
- vendor/python
- vendor/pip
- vendor/apt
before_script:
- mkdir -p vendor/{python,pip,apt}
- apt-get update -q && apt-get -o dir::cache::archives="vendor/apt" install -yqq mysql-client
- mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host="$DBHOST"
-e "GRANT ALL ON test_$DBNAME.* TO '$DBUSER'@'%'"
- pip install --cache-dir vendor/pip -t vendor/python -r requirements-devel.txt
test:
stage: test
script:
- python manage.py test

View file

@ -257,7 +257,8 @@ class SpectacleReventeAdmin(admin.ModelAdmin):
Réinitialise les reventes. Réinitialise les reventes.
""" """
count = queryset.count() count = queryset.count()
for revente in queryset.all(): for revente in queryset.filter(
attribution__spectacle__date__gte=timezone.now()):
revente.date = timezone.now() - timedelta(hours=1) revente.date = timezone.now() - timedelta(hours=1)
revente.soldTo = None revente.soldTo = None
revente.notif_sent = False revente.notif_sent = False

View file

@ -86,9 +86,6 @@ class Spectacle(models.Model):
verbose_name = "Spectacle" verbose_name = "Spectacle"
ordering = ("date", "title",) ordering = ("date", "title",)
def __repr__(self):
return "[%s]" % self
def timestamp(self): def timestamp(self):
return "%d" % calendar.timegm(self.date.utctimetuple()) return "%d" % calendar.timegm(self.date.utctimetuple())

View file

@ -263,25 +263,6 @@ def tirage(request, tirage_id):
return render(request, "bda-token.html", {"form": form}) return render(request, "bda-token.html", {"form": form})
def do_resell(request, form):
spectacle = form.cleaned_data["spectacle"]
count = form.cleaned_data["count"]
places = "2 places" if count == "2" else "une place"
mail = """Bonjour,
Je souhaite revendre %s pour %s le %s (%s) à %.02f.
Contactez moi par email si vous êtes intéressé·e·s !
%s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(),
spectacle.location, spectacle.price,
request.user.get_full_name(), request.user.email)
send_mail("%s" % spectacle, mail,
request.user.email, ["bda-revente@lists.ens.fr"],
fail_silently=False)
return render(request, "bda-success.html",
{"show": spectacle, "places": places})
@login_required @login_required
def revente(request, tirage_id): def revente(request, tirage_id):
tirage = get_object_or_404(Tirage, id=tirage_id) tirage = get_object_or_404(Tirage, id=tirage_id)
@ -348,13 +329,14 @@ def revente(request, tirage_id):
id=revente_id) id=revente_id)
if rev.exists(): if rev.exists():
revente = rev.get() revente = rev.get()
revente.date = timezone.now() - timedelta(hours=1) if revente.attribution.spectacle.date > timezone.now():
revente.soldTo = None revente.date = timezone.now() - timedelta(hours=1)
revente.notif_sent = False revente.soldTo = None
revente.tirage_done = False revente.notif_sent = False
if revente.answered_mail: revente.tirage_done = False
revente.answered_mail.clear() if revente.answered_mail:
revente.save() revente.answered_mail.clear()
revente.save()
else: else:
resellform = ResellForm(participant, prefix='resell') resellform = ResellForm(participant, prefix='resell')

View file

@ -99,6 +99,7 @@ DATABASES = {
'NAME': os.environ['DBNAME'], 'NAME': os.environ['DBNAME'],
'USER': os.environ['DBUSER'], 'USER': os.environ['DBUSER'],
'PASSWORD': os.environ['DBPASSWD'], 'PASSWORD': os.environ['DBPASSWD'],
'HOST': os.environ.get('DBHOST', 'localhost'),
} }
} }
@ -136,10 +137,6 @@ MEDIA_URL = '/media/'
# Various additional settings # Various additional settings
SITE_ID = 1 SITE_ID = 1
# URL prefix for admin static files -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
# Examples: "http://foo.com/static/admin/", "/static/admin/".
ADMIN_MEDIA_PREFIX = '/static/grappelli/'
GRAPPELLI_ADMIN_HEADLINE = "GestioCOF" GRAPPELLI_ADMIN_HEADLINE = "GestioCOF"
GRAPPELLI_ADMIN_TITLE = "<a href=\"/\">GestioCOF</a>" GRAPPELLI_ADMIN_TITLE = "<a href=\"/\">GestioCOF</a>"
@ -156,12 +153,12 @@ MAIL_DATA = {
'REPLYTO': 'BdA-Revente <bda-revente@ens.fr>'}, 'REPLYTO': 'BdA-Revente <bda-revente@ens.fr>'},
} }
LOGIN_URL = "/gestion/login" LOGIN_URL = "cof-login"
LOGIN_REDIRECT_URL = "/gestion/" LOGIN_REDIRECT_URL = "home"
CAS_SERVER_URL = 'https://cas.eleves.ens.fr/' CAS_SERVER_URL = 'https://cas.eleves.ens.fr/'
CAS_IGNORE_REFERER = True CAS_IGNORE_REFERER = True
CAS_REDIRECT_URL = '/gestion/' CAS_REDIRECT_URL = '/'
CAS_EMAIL_FORMAT = "%s@clipper.ens.fr" CAS_EMAIL_FORMAT = "%s@clipper.ens.fr"
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', 'django.contrib.auth.backends.ModelBackend',
@ -180,7 +177,7 @@ CHANNEL_LAYERS = {
"default": { "default": {
"BACKEND": "asgi_redis.RedisChannelLayer", "BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": { "CONFIG": {
"hosts": [("localhost", 6379)], "hosts": [(os.environ.get("REDIS_HOST", "localhost"), 6379)],
}, },
"ROUTING": "cof.routing.channel_routing", "ROUTING": "cof.routing.channel_routing",
} }

View file

@ -27,7 +27,7 @@ from gestioncof.autocomplete import autocomplete
autocomplete_light.autodiscover() autocomplete_light.autodiscover()
admin.autodiscover() admin.autodiscover()
my_urlpatterns = [ urlpatterns = [
# Page d'accueil # Page d'accueil
url(r'^$', gestioncof_views.home, name='home'), url(r'^$', gestioncof_views.home, name='home'),
# Le BdA # Le BdA
@ -51,7 +51,7 @@ my_urlpatterns = [
url(r'^cas/logout$', django_cas_views.logout), url(r'^cas/logout$', django_cas_views.logout),
url(r'^outsider/login$', gestioncof_views.login_ext), url(r'^outsider/login$', gestioncof_views.login_ext),
url(r'^outsider/logout$', django_views.logout, {'next_page': 'home'}), url(r'^outsider/logout$', django_views.logout, {'next_page': 'home'}),
url(r'^login$', gestioncof_views.login), url(r'^login$', gestioncof_views.login, name="cof-login"),
url(r'^logout$', gestioncof_views.logout), url(r'^logout$', gestioncof_views.logout),
# Infos persos # Infos persos
url(r'^profile$', gestioncof_views.profile), url(r'^profile$', gestioncof_views.profile),
@ -84,21 +84,16 @@ my_urlpatterns = [
url(r'^utile_bda/bda_diff$', gestioncof_views.liste_bdadiff), url(r'^utile_bda/bda_diff$', gestioncof_views.liste_bdadiff),
url(r'^utile_cof/diff_cof$', gestioncof_views.liste_diffcof), url(r'^utile_cof/diff_cof$', gestioncof_views.liste_diffcof),
url(r'^utile_bda/bda_revente$', gestioncof_views.liste_bdarevente), url(r'^utile_bda/bda_revente$', gestioncof_views.liste_bdarevente),
url(r'^k-fet/', include('kfet.urls')) url(r'^k-fet/', include('kfet.urls')),
] + \ ]
(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG
else [])
# Si on est en production, MEDIA_ROOT est servi par Apache.
# Il faut dire à Django de servir MEDIA_ROOT lui-même en développement.
if settings.DEBUG: if settings.DEBUG:
import debug_toolbar import debug_toolbar
my_urlpatterns += [ urlpatterns += [
url(r'^__debug__/', url(r'^__debug__/', include(debug_toolbar.urls)),
include(debug_toolbar.urls)),
] ]
urlpatterns = [ # Si on est en production, MEDIA_ROOT est servi par Apache.
url(r'^gestion/', include(my_urlpatterns)) # Il faut dire à Django de servir MEDIA_ROOT lui-même en développement.
] urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)

View file

@ -30,7 +30,7 @@ from captcha.fields import ReCaptchaField
from datetime import datetime from datetime import datetime
import base64 import base64
import simplejson import json
def render_template(template_path, data): def render_template(template_path, data):
@ -153,7 +153,7 @@ def _finalize_traitement(request, demande, proposals, proposed_for,
"proposed_mails": proposed_mails, "proposed_mails": proposed_mails,
"mainmail": mainmail, "mainmail": mainmail,
"attribdata": "attribdata":
base64.b64encode(simplejson.dumps(attribdata) base64.b64encode(json.dumps(attribdata)
.encode('utf_8')), .encode('utf_8')),
"redo": redo, "redo": redo,
"errors": errors, "errors": errors,
@ -262,7 +262,7 @@ def _traitement_post(request, demande):
extra = request.POST["extra"].strip() extra = request.POST["extra"].strip()
redo = "redo" in request.POST redo = "redo" in request.POST
attribdata = request.POST["attribdata"] attribdata = request.POST["attribdata"]
attribdata = dict(simplejson.loads(base64.b64decode(attribdata))) attribdata = dict(json.loads(base64.b64decode(attribdata)))
for matiere in demande.matieres.all(): for matiere in demande.matieres.all():
if matiere.id not in attribdata: if matiere.id not in attribdata:
unsatisfied.append(matiere) unsatisfied.append(matiere)

View file

@ -8,7 +8,5 @@ from channels.routing import route, route_class
from kfet import consumers from kfet import consumers
channel_routing = [ channel_routing = [
route_class(consumers.KPsul, path=r"^/gestion/ws/k-fet/k-psul/$"), route_class(consumers.KPsul, path=r"^ws/k-fet/k-psul/$"),
#route("websocket.connect", ws_kpsul_history_connect),
#route('websocket.receive', ws_message)
] ]

View file

@ -6,6 +6,16 @@
ProxyRequests Off ProxyRequests Off
ProxyPass /static/ ! ProxyPass /static/ !
ProxyPass /media/ ! ProxyPass /media/ !
# Pour utiliser un sous-dossier (typiquement /gestion/), il faut faire a la
# place des lignes suivantes:
#
# RequestHeader set Daphne-Root-Path /gestion
# ProxyPass /gestion/ws/ ws://127.0.0.1:8001/gestion/ws/
# ProxyPass /gestion http://127.0.0.1:8001/gestion
# ProxyPassReverse /gestion http://127.0.0.1:8001/gestion
#
# Penser egalement a changer les /static/ et /media/ dans la config apache
# ainsi que dans les settings django.
ProxyPass /ws/ ws://127.0.0.1:8001/ws/ ProxyPass /ws/ ws://127.0.0.1:8001/ws/
ProxyPass / http://127.0.0.1:8001/ ProxyPass / http://127.0.0.1:8001/
ProxyPassReverse / http://127.0.0.1:8001/ ProxyPassReverse / http://127.0.0.1:8001/

View file

@ -10,6 +10,7 @@ DBPASSWD="4KZt3nGPLVeWSvtBZPSM3fSzXpzEU4"
# Installation de paquets utiles # Installation de paquets utiles
apt-get update && apt-get install -y python3-pip python3-dev python3-venv \ apt-get update && apt-get install -y python3-pip python3-dev python3-venv \
libmysqlclient-dev libjpeg-dev git redis-server libmysqlclient-dev libjpeg-dev git redis-server
pip install -U pip
# Configuration et installation de mysql. Le mot de passe root est le même que # Configuration et installation de mysql. Le mot de passe root est le même que
# le mot de passe pour l'utilisateur local - pour rappel, ceci est une instance # le mot de passe pour l'utilisateur local - pour rappel, ceci est une instance
@ -23,7 +24,7 @@ mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME; GRANT ALL PRIVILEGES ON $D
# Installation et configuration d'Apache # Installation et configuration d'Apache
apt-get install -y apache2 apt-get install -y apache2
a2enmod proxy proxy_http a2enmod proxy proxy_http proxy_wstunnel headers
cp /vagrant/provisioning/apache.conf /etc/apache2/sites-available/gestiocof.conf cp /vagrant/provisioning/apache.conf /etc/apache2/sites-available/gestiocof.conf
a2ensite gestiocof a2ensite gestiocof
a2dissite 000-default a2dissite 000-default

View file

@ -1,2 +1,3 @@
-r requirements.txt
django-debug-toolbar django-debug-toolbar
ipython ipython

View file

@ -7,7 +7,6 @@ django-grappelli==2.8.1
django-recaptcha==1.0.5 django-recaptcha==1.0.5
mysqlclient==1.3.7 mysqlclient==1.3.7
Pillow==3.3.0 Pillow==3.3.0
simplejson==3.8.2
six==1.10.0 six==1.10.0
unicodecsv==0.14.1 unicodecsv==0.14.1
icalendar==3.10 icalendar==3.10