Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
|
02d07cb83d | ||
|
fbb7cbe11a |
21 changed files with 225 additions and 127 deletions
1
.credentials/SECRET_KEY
Normal file
1
.credentials/SECRET_KEY
Normal file
|
@ -0,0 +1 @@
|
|||
insecure-secret_key
|
|
@ -1,39 +1,26 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from loadcredential import Credentials
|
||||
|
||||
try:
|
||||
from . import secret
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"The secret.py file is missing.\n"
|
||||
"For a development environment, simply copy secret_example.py"
|
||||
)
|
||||
credentials = Credentials(env_prefix="ERNESTOPHONE_")
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
DEBUG = credentials.get_json("DEBUG", False)
|
||||
|
||||
ALLOWED_HOSTS = credentials.get_json("ALLOWED_HOSTS", [])
|
||||
|
||||
SECRET_KEY = credentials["SECRET_KEY"]
|
||||
|
||||
ADMINS = credentials.get_json("ADMINS", [])
|
||||
|
||||
SERVER_EMAIL = credentials.get("SERVER_EMAIL", "ernesto@localhost")
|
||||
|
||||
|
||||
def import_secret(name):
|
||||
"""
|
||||
Shorthand for importing a value from the secret module and raising an
|
||||
informative exception if a secret is missing.
|
||||
"""
|
||||
try:
|
||||
return getattr(secret, name)
|
||||
except AttributeError:
|
||||
raise RuntimeError("Secret missing: {}".format(name))
|
||||
ACCOUNT_CREATION_PASS = credentials.get("ACCOUNT_CREATION_PASS", "dummy")
|
||||
|
||||
|
||||
SECRET_KEY = import_secret("SECRET_KEY")
|
||||
ADMINS = import_secret("ADMINS")
|
||||
SERVER_EMAIL = import_secret("SERVER_EMAIL")
|
||||
|
||||
DBNAME = import_secret("DBNAME")
|
||||
DBUSER = import_secret("DBUSER")
|
||||
DBPASSWD = import_secret("DBPASSWD")
|
||||
|
||||
ACCOUNT_CREATION_PASS = import_secret("ACCOUNT_CREATION_PASS")
|
||||
|
||||
BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..")
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"propositions",
|
||||
"trombonoscope",
|
||||
|
@ -90,15 +77,22 @@ TEMPLATES = [
|
|||
|
||||
WSGI_APPLICATION = "Ernestophone.wsgi.application"
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": DBNAME,
|
||||
"USER": DBUSER,
|
||||
"PASSWORD": DBPASSWD,
|
||||
"HOST": "localhost",
|
||||
}
|
||||
}
|
||||
|
||||
###
|
||||
# Database configuration
|
||||
# -> https://docs.djangoproject.com/en/4.2/ref/settings/#databases
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||
|
||||
DATABASES = credentials.get_json(
|
||||
"DATABASES",
|
||||
{
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": BASE_DIR / "db.sqlite3",
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
|
@ -129,7 +123,7 @@ USE_L10N = True
|
|||
USE_TZ = True
|
||||
|
||||
|
||||
LOCALE_PATHS = (os.path.join(BASE_DIR, "locale"),)
|
||||
LOCALE_PATHS = (BASE_DIR / "locale",)
|
||||
|
||||
|
||||
AUTH_PROFILE_MODEL = "gestion.ErnestoUser"
|
||||
|
@ -150,3 +144,18 @@ AVATAR_PROVIDERS = (
|
|||
"avatar.providers.DefaultAvatarProvider",
|
||||
)
|
||||
AVATAR_THUMB_FORMAT = "JPEG"
|
||||
|
||||
###
|
||||
# Staticfiles configuration
|
||||
|
||||
STATIC_ROOT = credentials["STATIC_ROOT"]
|
||||
STATIC_URL = "/static/"
|
||||
|
||||
MEDIA_ROOT = credentials.get("MEDIA_ROOT", BASE_DIR / "media")
|
||||
MEDIA_URL = "/media/"
|
||||
|
||||
if DEBUG:
|
||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
|
||||
INSTALLED_APPS += ["debug_toolbar"]
|
||||
MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE
|
|
@ -1,23 +0,0 @@
|
|||
import os
|
||||
|
||||
from .common import * # noqa
|
||||
from .common import BASE_DIR, INSTALLED_APPS, MIDDLEWARE
|
||||
|
||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
|
||||
DEBUG = True
|
||||
|
||||
INSTALLED_APPS += ["debug_toolbar"]
|
||||
MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE
|
||||
|
||||
STATIC_URL = "/static/"
|
||||
STATIC_ROOT = "static"
|
||||
MEDIA_URL = "/media/"
|
||||
MEDIA_ROOT = "media"
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import os
|
||||
|
||||
from .common import * # noqa
|
||||
from .common import BASE_DIR
|
||||
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = [
|
||||
"ernestophone.ens.fr",
|
||||
"www.ernestophone.ens.fr",
|
||||
]
|
||||
|
||||
STATIC_URL = "/static/"
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "..", "..", "public", "ernesto", "static")
|
||||
|
||||
MEDIA_URL = "/media/"
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "..", "media")
|
|
@ -1,9 +0,0 @@
|
|||
SECRET_KEY = "vpb%-1@$ha98w5^ji#@9v2_kxj)zdk5+e!9!fqniu2$#eg+46="
|
||||
ADMINS = None
|
||||
SERVER_EMAIL = "ernesto@localhost"
|
||||
|
||||
DBNAME = "ernesto"
|
||||
DBUSER = "ernesto"
|
||||
DBPASSWD = "YNp2rrXowJnDAFF3"
|
||||
|
||||
ACCOUNT_CREATION_PASS = "dummy"
|
|
@ -13,13 +13,13 @@ Including another URLconf
|
|||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls.i18n import i18n_patterns
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import views as auth_views
|
||||
from django.urls import include, path
|
||||
|
||||
from gestion import views as gestion_views
|
||||
|
||||
urlpatterns = []
|
||||
|
@ -69,4 +69,5 @@ urlpatterns += i18n_patterns(
|
|||
),
|
||||
prefix_default_language=False,
|
||||
)
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load frenchmonth %}
|
||||
{% load i18n %}
|
||||
{% load translate %}
|
||||
|
@ -43,35 +43,35 @@
|
|||
<tr>
|
||||
<td width="20%" align="left">
|
||||
<<
|
||||
{% ifequal current_language "fr" %}
|
||||
{% if current_language == "fr" %}
|
||||
<a href="{% url "calendrier:view-month" PreviousYear PreviousMonth %}">{{PreviousMonthName|frenchmonth}} {{PreviousYear}}</a>
|
||||
{% else %}
|
||||
<a href="{% url "calendrier:view-month" PreviousYear PreviousMonth %}">{{PreviousMonthName}} {{PreviousYear}}</a>
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td width="20%" align="center"><a href="{% url "calendrier:home" %}">{% trans "Aujourd'hui" %}</a></td>
|
||||
<td width="20%" align="right">
|
||||
{% ifequal current_language "fr" %}
|
||||
{% if current_language == "fr" %}
|
||||
<a href="{% url "calendrier:view-month" NextYear NextMonth %}">{{NextMonthName|frenchmonth}} {{NextYear}}</a> >>
|
||||
{% else %}
|
||||
<a href="{% url "calendrier:view-month" NextYear NextMonth %}">{{NextMonthName}} {{NextYear}}</a> >>
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="calendar">
|
||||
{% if user.profile.is_chef_event or user.profile.is_chef %}
|
||||
{% ifequal current_language "fr" %}
|
||||
{% if current_language == "fr" %}
|
||||
{{Calendar_chef|translate}}
|
||||
{% else %}
|
||||
{{Calendar_chef}}
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% ifequal current_language "fr" %}
|
||||
{% if current_language == "fr" %}
|
||||
{{Calendar|translate}}
|
||||
{% else %}
|
||||
{{Calendar}}
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
{% endif%}
|
||||
</div>
|
||||
{% if user.profile.is_chef_event or user.profile.is_chef %}
|
||||
|
|
|
@ -261,11 +261,11 @@ singleEvent.createWidget('#single-normal', function() {
|
|||
console.log('#single-normal widget has been created');
|
||||
});
|
||||
|
||||
{% ifequal current_language "fr" %}
|
||||
{% if current_language == "fr" %}
|
||||
singleEvent.setOption({ lang: 'fr' });
|
||||
{% else %}
|
||||
singleEvent.setOption({ lang: 'en' });
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
</script>
|
||||
{% if event.id == 573 %}
|
||||
<script src="https://unpkg.com/fireworks-js@2.x/dist/index.umd.js"></script>
|
||||
|
|
|
@ -124,11 +124,11 @@
|
|||
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
{% ifequal current_language "fr" %}
|
||||
{% if current_language == "fr" %}
|
||||
<a class="nav-link" href="{% changelang "en" %}" ><img src="{% static 'images\en_flag.jpg' %}" width="60" height="40" style="vertical-align: middle"></a>
|
||||
{% else %}
|
||||
<a class="nav-link" href="{% changelang "fr" %}" ><img src="{% static 'images\fr_flag.jpg' %}" width="60" height="40" style="vertical-align: middle"></a>
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
<div class="7u 12u$(small)">
|
||||
<p>{% trans "Propriétaire : "%} {% if instru.owner %}{{instru.owner}} {% else %}-{% endif %}<br>
|
||||
{% trans "Statut : "%} {{instru.statut}} <br>
|
||||
{% ifequal instru.statut 'Prêté' %}
|
||||
{% if instru.statut == 'Prêté' %}
|
||||
{% trans "Utilisateur : "%} {% if instru.user %}{{instru.user}} {% else %}-{% endif %}<br>
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
{% trans "Marque : "%} {% if instru.marque %}{{instru.marque}} {% else %}-{% endif %} <br>
|
||||
{% trans "Modele : "%} {% if instru.model %}{{instru.model}} {% else %}-{% endif %}<br>
|
||||
{% trans "Numéro de série : "%} {% if instru.serial %}{{instru.serial}}{% else %}-{% endif %} <br>
|
||||
|
@ -55,7 +55,7 @@
|
|||
<tr>
|
||||
|
||||
<td> {{ rep.date }} </td>
|
||||
<td> {% ifequal current_language "fr" %}
|
||||
<td> {% if current_language == "fr" %}
|
||||
{{ rep.description }}
|
||||
{% else %}
|
||||
{% if instru.description_en %}
|
||||
|
@ -63,7 +63,7 @@
|
|||
{% else %}
|
||||
{{ rep.description }}
|
||||
{% endif %}
|
||||
{% endifequal %} </td>
|
||||
{% endif %} </td>
|
||||
<td> {{ rep.prix }} </td>
|
||||
<td> {{ rep.lieux }} </td>
|
||||
{%if user.profile.is_chef or user.profile.is_chef_instru %}
|
||||
|
|
|
@ -3,7 +3,7 @@ import os
|
|||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ernestophone.settings.local")
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ernestophone.settings")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
|
|
80
npins/default.nix
Normal file
80
npins/default.nix
Normal file
|
@ -0,0 +1,80 @@
|
|||
# Generated by npins. Do not modify; will be overwritten regularly
|
||||
let
|
||||
data = builtins.fromJSON (builtins.readFile ./sources.json);
|
||||
version = data.version;
|
||||
|
||||
mkSource =
|
||||
spec:
|
||||
assert spec ? type;
|
||||
let
|
||||
path =
|
||||
if spec.type == "Git" then
|
||||
mkGitSource spec
|
||||
else if spec.type == "GitRelease" then
|
||||
mkGitSource spec
|
||||
else if spec.type == "PyPi" then
|
||||
mkPyPiSource spec
|
||||
else if spec.type == "Channel" then
|
||||
mkChannelSource spec
|
||||
else
|
||||
builtins.throw "Unknown source type ${spec.type}";
|
||||
in
|
||||
spec // { outPath = path; };
|
||||
|
||||
mkGitSource =
|
||||
{
|
||||
repository,
|
||||
revision,
|
||||
url ? null,
|
||||
hash,
|
||||
branch ? null,
|
||||
...
|
||||
}:
|
||||
assert repository ? type;
|
||||
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
|
||||
# In the latter case, there we will always be an url to the tarball
|
||||
if url != null then
|
||||
(builtins.fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash; # FIXME: check nix version & use SRI hashes
|
||||
})
|
||||
else
|
||||
assert repository.type == "Git";
|
||||
let
|
||||
urlToName =
|
||||
url: rev:
|
||||
let
|
||||
matched = builtins.match "^.*/([^/]*)(\\.git)?$" repository.url;
|
||||
|
||||
short = builtins.substring 0 7 rev;
|
||||
|
||||
appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else "";
|
||||
in
|
||||
"${if matched == null then "source" else builtins.head matched}${appendShort}";
|
||||
name = urlToName repository.url revision;
|
||||
in
|
||||
builtins.fetchGit {
|
||||
url = repository.url;
|
||||
rev = revision;
|
||||
inherit name;
|
||||
# hash = hash;
|
||||
};
|
||||
|
||||
mkPyPiSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchurl {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkChannelSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
in
|
||||
if version == 3 then
|
||||
builtins.mapAttrs (_: mkSource) data.pins
|
||||
else
|
||||
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
|
22
npins/sources.json
Normal file
22
npins/sources.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"pins": {
|
||||
"nix-pkgs": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
"type": "Git",
|
||||
"url": "https://git.hubrecht.ovh/hubrecht/nix-pkgs.git"
|
||||
},
|
||||
"branch": "main",
|
||||
"revision": "cc01e1c2a6ecb1e38fde35ee54995a6a639fb057",
|
||||
"url": null,
|
||||
"hash": "17a9vlwrk9365ccyl7a5xspqsn9wizcpwdpvr3qdimvq4fpwhjal"
|
||||
},
|
||||
"nixpkgs": {
|
||||
"type": "Channel",
|
||||
"name": "nixpkgs-unstable",
|
||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre723402.4989a246d7a3/nixexprs.tar.xz",
|
||||
"hash": "0hjng6rhkjiql1dqbanjm6jl6npik29q2lmba032j897fhyzin91"
|
||||
}
|
||||
},
|
||||
"version": 3
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
-r requirements.txt
|
||||
|
||||
django-debug-toolbar
|
||||
ipython
|
|
@ -1,8 +0,0 @@
|
|||
Django==2.2.28
|
||||
django-appconf==1.0.4
|
||||
django-avatar==5.0.0
|
||||
django-colorful==1.3
|
||||
gunicorn==20.1.0
|
||||
Pillow==9.2.0
|
||||
#Pour le prod
|
||||
#psycopg2==2.8.6
|
46
shell.nix
Normal file
46
shell.nix
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
sources ? import ./npins,
|
||||
pkgs ? import sources.nixpkgs {
|
||||
overlays = [
|
||||
(import "${sources.nix-pkgs}/overlay.nix").default
|
||||
];
|
||||
},
|
||||
dev ? true,
|
||||
}:
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
(pkgs.python3.withPackages (
|
||||
ps:
|
||||
[
|
||||
ps.django
|
||||
ps.django-avatar
|
||||
ps.django-colorful
|
||||
ps.gunicorn
|
||||
ps.pillow
|
||||
ps.loadcredential
|
||||
]
|
||||
++ (
|
||||
if dev then
|
||||
[
|
||||
ps.ipython
|
||||
ps.django-debug-toolbar
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
)
|
||||
))
|
||||
];
|
||||
env = {
|
||||
DJANGO_SETTINGS_MODULE = "Ernestophone.settings";
|
||||
|
||||
CREDENTIALS_DIRECTORY = builtins.toString ./.credentials;
|
||||
|
||||
ERNESTOPHONE_DEBUG = builtins.toJSON true;
|
||||
ERNESTOPHONE_STATIC_ROOT = builtins.toString ./.static;
|
||||
};
|
||||
shellHook = ''
|
||||
if [ ! -d .static ]; then
|
||||
mkdir .static
|
||||
fi
|
||||
'';
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
<p>{% trans "Avatar courant: " %}</p>
|
||||
{% avatar user %}
|
||||
|
||||
<form enctype="multipart/form-data" method="POST" action="{% url 'avatar_add' %}">
|
||||
<form enctype="multipart/form-data" method="POST" action="{% url 'avatar:add' %}">
|
||||
{{ upload_avatar_form.as_p }}
|
||||
<p>{% csrf_token %}<input type="submit" value="{% trans "Ajouter une nouvelle image" %}" /></p>
|
||||
</form>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<p>{% trans "Tu n'as pas encore ajouté d'avatar. Le logo Ernestophone sera utilisé par defaut." %}</p>
|
||||
{% endif %}
|
||||
|
||||
<form enctype="multipart/form-data" method="POST" action="{% url 'avatar_add' %}">
|
||||
<form enctype="multipart/form-data" method="POST" action="{% url 'avatar:add' %}">
|
||||
{{ upload_avatar_form.as_p }}
|
||||
<p>{% csrf_token %}<input type="submit" value="{% trans "Modifier mon avatar" %}" /></p>
|
||||
</form>
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
<a href="{% url "trombonoscope:change" %}" class="button alt">{% trans "Retour au profil"%}</a>
|
||||
{% if avatars %}
|
||||
<a class="button alt" href="{% url 'avatar_delete' %}">{% trans "Supprimer l'avatar "%}</a>
|
||||
<a class="button alt" href="{% url 'avatar:delete' %}">{% trans "Supprimer l'avatar "%}</a>
|
||||
{% endif %}
|
||||
</div></div></div></section></div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
{% endif %}
|
||||
|
||||
<p>
|
||||
<a class="button alt" href="{% url 'avatar_change' %}">{% trans "Changer l'avatar "%}</a>
|
||||
<a class="button alt" href="{% url 'avatar:change' %}">{% trans "Changer l'avatar "%}</a>
|
||||
{% if request.user|has_avatar %}
|
||||
<a class="button alt" href="{% url 'avatar_delete' %}">{% trans "Supprimer l'avatar "%}</a>
|
||||
<a class="button alt" href="{% url 'avatar:delete' %}">{% trans "Supprimer l'avatar "%}</a>
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
<div class="6u 12u$(small)">
|
||||
<h2>{% trans "Suppression de l'avatar" %} :</h2>
|
||||
{% if not avatars %}
|
||||
{% url 'avatar_change' as avatar_change_url %}
|
||||
{% url 'avatar:change' as avatar_change_url %}
|
||||
<p>{% trans "Vous n'avez pas d'avatar à supprimer."%}</p>
|
||||
<a href="{{ avatar_change_url }}" class="button">{% trans "Télécharger un avatar" %}</a> <a href="{% url "trombonoscope:change" %}" class="button alt">{% trans "Retour au profil"%}</a>
|
||||
{% else %}
|
||||
<p>{% trans "Séléctione l'avatar pour le supprimer" %}</p>
|
||||
<form method="POST" action="{% url 'avatar_delete' %}">
|
||||
<form method="POST" action="{% url 'avatar:delete' %}">
|
||||
|
||||
|
||||
{% for field in delete_avatar_form %}
|
||||
|
|
Loading…
Reference in a new issue