1 Commits

Author SHA1 Message Date
Eric Coissac
021e2a3919 A pretty jupyter login 2025-11-21 14:40:46 +01:00
26 changed files with 1057178 additions and 111 deletions

2
.gitignore vendored
View File

@@ -3,6 +3,7 @@
/jupyterhub_volumes/shared /jupyterhub_volumes/shared
/jupyterhub_volumes/jupyterhub /jupyterhub_volumes/jupyterhub
/jupyterhub_volumes/caddy /jupyterhub_volumes/caddy
/jupyterhub_volumes/course/data/Genbank
/**/.DS_Store /**/.DS_Store
/web_src/**/*.RData /web_src/**/*.RData
/web_src/**/*.pdf /web_src/**/*.pdf
@@ -11,3 +12,4 @@
/.luarc.json /.luarc.json
/sandbox /sandbox
*.log *.log
ncbitaxo_*

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
@param,matching,strict
@param,primer_mismatches,2
@param,indels,false
experiment,sample,sample_tag,forward_primer,reverse_primer
wolf_diet,13a_F730603,aattaac,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
wolf_diet,15a_F730814,gaagtag,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
wolf_diet,26a_F040644,gaatatc,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
wolf_diet,29a_F260619,gcctcct,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
1 @param,matching,strict
2 @param,primer_mismatches,2
3 @param,indels,false
4 experiment,sample,sample_tag,forward_primer,reverse_primer
5 wolf_diet,13a_F730603,aattaac,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
6 wolf_diet,15a_F730814,gaagtag,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
7 wolf_diet,26a_F040644,gaatatc,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
8 wolf_diet,29a_F260619,gcctcct,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

File diff suppressed because one or more lines are too long

View File

@@ -76,7 +76,7 @@ c.DockerSpawner.volumes = {
} }
# Memory and CPU configuration (adjust according to your needs) # Memory and CPU configuration (adjust according to your needs)
c.DockerSpawner.mem_limit = '2G' c.DockerSpawner.mem_limit = '6G'
c.DockerSpawner.cpu_limit = 1.0 c.DockerSpawner.cpu_limit = 1.0
# User configuration - Simple password authentication for lab # User configuration - Simple password authentication for lab

View File

@@ -1,112 +1,229 @@
{% extends "page.html" %} {% extends "page.html" %} {% if announcement_login is string %} {% set
{% if announcement_login is string %} announcement = announcement_login %} {% endif %} {% block head %} {{ super() }}
{% set announcement = announcement_login %} <style>
{% endif %} body {
{% block login_widget %} background: radial-gradient(
{% endblock login_widget %} circle at top,
{% block main %} #f9f8ff 0%,
{% block login %} #f1f5ff 45%,
<div id="login-main" class="container"> #e7eefb 100%
{% block login_container %} );
{% if custom_html %} min-height: 100vh;
{{ custom_html | safe }} font-family: "Inter", "Helvetica Neue", Arial, sans-serif;
{% elif login_service %} }
<div class="service-login"> #login-main {
<a role="button" max-width: 950px;
class='btn btn-jupyter btn-lg' margin: 4rem auto;
href='{{ authenticator_login_url | safe }}'>Sign in with {{ login_service }}</a> padding: 0;
</div> }
{% else %} .metabar-card {
<form action="{{ authenticator_login_url | safe }}" display: flex;
method="post" flex-wrap: wrap;
role="form"> box-shadow: 0 20px 60px rgba(30, 50, 120, 0.15);
<div class="auth-form-header"> border-radius: 28px;
<h1>Sign in</h1> overflow: hidden;
</div> background: white;
<div class='auth-form-body m-auto'> }
{% if login_error %}<p class="login_error">{{ login_error }}</p>{% endif %} .auth-form-body img#metabar-img {
<input type="hidden" name="_xsrf" value="{{ xsrf }}" /> width: 200px; /* ajuste selon le rendu souhaité */
{# Allow full override of the "label" and "input" elements of the username and password fields. #} height: auto;
{% block username_input %} display: block;
<label for="username_input">Username:</label> margin: 0 auto 1rem;
<input id="username_input" }
{% block username_input_attrs %} .login-panel {
type="text" flex: 1 1 360px;
autocapitalize="off" padding: 2.5rem;
autocorrect="off" }
autocomplete="username" .login-panel h2 {
class="form-control" font-weight: 600;
name="username" margin-bottom: 0.25rem;
value="{{ username }}" }
autofocus="autofocus" .login-panel p.subtitle {
{% endblock username_input_attrs %} /> color: #667080;
{% endblock username_input %} margin-bottom: 1.75rem;
{% block password_input %} }
<label for='password_input'>Password:</label> .auth-form-body label {
<input id="password_input" font-size: 0.85rem;
{% block password_input_attrs %} text-transform: uppercase;
type="password" letter-spacing: 0.08em;
class="form-control" font-weight: 600;
autocomplete="current-password" color: #6b7280;
name="password" }
{% endblock password_input_attrs %} /> .auth-form-body input.form-control {
{% endblock password_input %} border-radius: 14px;
{% if authenticator.request_otp %} padding: 0.85rem 1rem;
{% block otp_input %} border: 1px solid #d7def0;
<label for="otp_input">{{ authenticator.otp_prompt }}</label> transition: border-color 0.2s ease, box-shadow 0.2s ease;
<input id="otp_input" }
{% block otp_input_attrs %} .auth-form-body input.form-control:focus {
class="form-control" border-color: #6b8afd;
autocomplete="one-time-password" box-shadow: 0 0 0 3px rgba(107, 138, 253, 0.2);
name="otp" outline: none;
{% endblock otp_input_attrs %} /> }
{% endblock otp_input %} .btn.btn-jupyter {
{% endif %} background: linear-gradient(135deg, #6b8afd, #3f6dd9);
<div class="feedback-container"> border: none;
<input id="login_submit" border-radius: 14px;
type="submit" padding: 0.85rem 0;
class='btn btn-jupyter form-control' font-weight: 600;
value='Sign in' text-transform: uppercase;
tabindex="3" /> letter-spacing: 0.08em;
<div class="feedback-widget hidden"> }
<i class="fa fa-spinner"></i> .metabar-footnote {
</div> font-size: 0.82rem;
</div> color: #94a3b8;
{% block login_terms %} margin-top: 1.5rem;
{% if login_term_url %} }
<div id="login_terms" class="login_terms"> @media (max-width: 900px) {
<input type="checkbox" #login-main {
id="login_terms_checkbox" margin: 2rem 1rem;
name="login_terms_checkbox"
required />
{% block login_terms_text %}
{# allow overriding the text #}
By logging into the platform you accept the <a href="{{ login_term_url }}">terms and conditions</a>.
{% endblock login_terms_text %}
</div>
{% endif %}
{% endblock login_terms %}
</div>
</form>
{% endif %}
{% endblock login_container %}
</div>
{% endblock login %}
{% endblock main %}
{% block script %}
{{ super() }}
<script>
if (!window.isSecureContext) {
// unhide http warning
var warning = document.getElementById('insecure-login-warning');
warning.className = warning.className.replace(/\bhidden\b/, '');
} }
// setup onSubmit feedback .metabar-card {
$('form').submit((e) => { flex-direction: column;
var form = $(e.target); }
form.find('.feedback-container>input').attr('disabled', true); .metabar-hero img {
form.find('.feedback-container>*').toggleClass('hidden'); position: relative;
form.find('.feedback-widget>*').toggleClass('fa-pulse'); opacity: 1;
}); }
</script> .metabar-hero__overlay {
background: rgba(4, 20, 43, 0.85);
border-radius: inherit;
}
}
</style>
{% endblock head %} {% block login_widget %}{% endblock login_widget %} {% block
main %} {% block login %}
<div id="login-main" class="container">
<div class="metabar-card">
<section class="login-panel">
<h2></h2>
<p class="subtitle"></p>
{% block login_container %} {% if custom_html %} {{ custom_html | safe }}
{% elif login_service %}
<div class="service-login">
<a
role="button"
class="btn btn-jupyter btn-lg w-100"
href="{{ authenticator_login_url | safe }}"
>Sign in with {{ login_service }}</a
>
</div>
{% else %}
<form
action="{{ authenticator_login_url | safe }}"
method="post"
role="form"
>
<div class="auth-form-body">
{% if login_error %}
<p class="login_error">{{ login_error }}</p>
{% endif %}
<img
id="metabar-img"
src="/img/welcome_metabar.webp"
alt="Metabarcoding welcome illustration"
style="
width: 308px;
height: auto;
display: block;
margin: 0 auto 1rem;
"
/>
<input type="hidden" name="_xsrf" value="{{ xsrf }}" />
{% block username_input %}
<label for="username_input">Username</label>
<input
id="username_input"
{%
block
username_input_attrs
%}
type="text"
autocapitalize="off"
autocorrect="off"
autocomplete="username"
class="form-control"
name="username"
value="{{ username }}"
autofocus="autofocus"
{%
endblock
username_input_attrs
%}
/>
{% endblock username_input %} {% block password_input %}
<label for="password_input">Password</label>
<input
id="password_input"
{%
block
password_input_attrs
%}
type="password"
class="form-control"
autocomplete="current-password"
name="password"
{%
endblock
password_input_attrs
%}
/>
{% endblock password_input %} {% if authenticator.request_otp %} {%
block otp_input %}
<label for="otp_input">{{ authenticator.otp_prompt }}</label>
<input
id="otp_input"
{%
block
otp_input_attrs
%}
class="form-control"
autocomplete="one-time-password"
name="otp"
{%
endblock
otp_input_attrs
%}
/>
{% endblock otp_input %} {% endif %}
<div class="feedback-container mt-4">
<input
id="login_submit"
type="submit"
class="btn btn-jupyter form-control"
value="Sign in"
tabindex="3"
/>
<div class="feedback-widget hidden">
<i class="fa fa-spinner"></i>
</div>
</div>
{% block login_terms %} {% if login_term_url %}
<div id="login_terms" class="login_terms mt-3">
<input
type="checkbox"
id="login_terms_checkbox"
name="login_terms_checkbox"
required
/>
{% block login_terms_text %} By logging in you accept the
<a href="{{ login_term_url }}">terms and conditions</a>. {% endblock
login_terms_text %}
</div>
{% endif %} {% endblock login_terms %}
</div>
</form>
{% endif %} {% endblock login_container %}
</section>
</div>
</div>
{% endblock login %} {% endblock main %} {% block script %} {{ super() }}
<script>
$("form").submit((e) => {
const form = $(e.target);
form.find(".feedback-container>input").attr("disabled", true);
form.find(".feedback-container>*").toggleClass("hidden");
form.find(".feedback-widget>*").toggleClass("fa-pulse");
});
</script>
{% endblock script %} {% endblock script %}

93675
ref_db_raw.fasta Normal file

File diff suppressed because it is too large Load Diff