Migration des fichiers depuis decp-table-schema-utils

This commit is contained in:
Colin Maudry
2021-05-28 12:24:01 +02:00
parent 4307ccaa95
commit 2b2f7f6dfe
44 changed files with 3470 additions and 0 deletions
@@ -0,0 +1,16 @@
<script>
document.body.addEventListener('click', (ev) => {
/* Close any open details elements that this click is outside of */
var target = ev.target;
var detailsClickedWithin = null;
while (target && target.tagName != 'DETAILS') {
target = target.parentNode;
}
if (target && target.tagName == 'DETAILS') {
detailsClickedWithin = target;
}
Array.from(document.getElementsByTagName('details')).filter(
(details) => details.open && details != detailsClickedWithin
).forEach(details => details.open = false);
});
</script>
+14
View File
@@ -0,0 +1,14 @@
<script src="{{ base_url }}-/static/sql-formatter-2.3.3.min.js" defer></script>
<script src="{{ base_url }}-/static/codemirror-5.57.0.min.js"></script>
<link rel="stylesheet" href="{{ base_url }}-/static/codemirror-5.57.0.min.css" />
<script src="{{ base_url }}-/static/codemirror-5.57.0-sql.min.js"></script>
<script src="{{ base_url }}-/static/cm-resize-1.0.1.min.js"></script>
<style>
.CodeMirror { height: auto; min-height: 70px; width: 80%; border: 1px solid #ddd; }
.cm-resize-handle {
background: url("data:image/svg+xml,%3Csvg%20aria-labelledby%3D%22cm-drag-to-resize%22%20role%3D%22img%22%20fill%3D%22%23ccc%22%20stroke%3D%22%23ccc%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%20width%3D%2216%22%20height%3D%2216%22%3E%0A%20%20%3Ctitle%20id%3D%22cm-drag-to-resize%22%3EDrag%20to%20resize%3C%2Ftitle%3E%0A%20%20%3Cpath%20fill-rule%3D%22evenodd%22%20d%3D%22M1%202.75A.75.75%200%20011.75%202h12.5a.75.75%200%20110%201.5H1.75A.75.75%200%20011%202.75zm0%205A.75.75%200%20011.75%207h12.5a.75.75%200%20110%201.5H1.75A.75.75%200%20011%207.75zM1.75%2012a.75.75%200%20100%201.5h12.5a.75.75%200%20100-1.5H1.75z%22%3E%3C%2Fpath%3E%0A%3C%2Fsvg%3E");
background-repeat: no-repeat;
box-shadow: none;
cursor: ns-resize;
}
</style>
+38
View File
@@ -0,0 +1,38 @@
<script>
window.onload = () => {
const sqlFormat = document.querySelector("button#sql-format");
const readOnly = document.querySelector("pre#sql-query");
const sqlInput = document.querySelector("textarea#sql-editor");
if (sqlFormat && !readOnly) {
sqlFormat.hidden = false;
}
if (sqlInput) {
var editor = CodeMirror.fromTextArea(sqlInput, {
lineNumbers: true,
mode: "text/x-sql",
lineWrapping: true,
});
editor.setOption("extraKeys", {
"Shift-Enter": function() {
document.getElementsByClassName("sql")[0].submit();
},
Tab: false
});
if (sqlFormat) {
sqlFormat.addEventListener("click", ev => {
editor.setValue(sqlFormatter.format(editor.getValue()));
})
}
cmResize(editor, {resizableWidth: false});
}
if (sqlFormat && readOnly) {
const formatted = sqlFormatter.format(readOnly.innerHTML);
if (formatted != readOnly.innerHTML) {
sqlFormat.hidden = false;
sqlFormat.addEventListener("click", ev => {
readOnly.innerHTML = formatted;
})
}
}
}
</script>
@@ -0,0 +1,30 @@
{% if metadata.description_html or metadata.description %}
<div class="metadata-description">
{% if metadata.description_html %}
{{ metadata.description_html|safe }}
{% else %}
{{ metadata.description }}
{% endif %}
</div>
{% endif %}
{% if metadata.license or metadata.license_url or metadata.source or metadata.source_url %}
<p>
{% if metadata.license or metadata.license_url %}Licence des données :
{% if metadata.license_url %}
<a href="{{ metadata.license_url }}">{{ metadata.license or metadata.license_url }}</a>
{% else %}
{{ metadata.license }}
{% endif %}
{% endif %}
{% if metadata.source or metadata.source_url %}{% if metadata.license or metadata.license_url %}&middot;{% endif %}
Source des données : {% if metadata.source_url %}
<a href="{{ metadata.source_url }}">
{% endif %}{{ metadata.source or metadata.source_url }}{% if metadata.source_url %}</a>{% endif %}
{% endif %}
{% if metadata.about or metadata.about_url %}{% if metadata.license or metadata.license_url or metadata.source or metadata.source_url %}&middot;{% endif %}
Plus d'informations : {% if metadata.about_url %}
<a href="{{ metadata.about_url }}">
{% endif %}{{ metadata.about or metadata.about_url }}{% if metadata.about_url %}</a>{% endif %}
{% endif %}
</p>
{% endif %}
+23
View File
@@ -0,0 +1,23 @@
Propulsé par <a href="https://datasette.io/" title="Datasette v{{ datasette_version }}">Datasette</a>
<!-- {% if query_ms %}&middot; Durée de la requ {{ query_ms|round(3) }}ms{% endif %} -->
{% if metadata %}
{% if metadata.license or metadata.license_url %}&middot; Licence des données :
{% if metadata.license_url %}
<a href="{{ metadata.license_url }}">{{ metadata.license or metadata.license_url }}</a>
{% else %}
{{ metadata.license }}
{% endif %}
{% endif %}
{% if metadata.source or metadata.source_url %}&middot;
Source des données : {% if metadata.source_url %}
<a href="{{ metadata.source_url }}">
{% endif %}{{ metadata.source or metadata.source_url }}{% if metadata.source_url %}</a>{% endif %}
{% endif %}
&middot; Code source : <a href="https://github.com/ColinMaudry/decp-table-schema-utils">Github</a>
{% if metadata.about or metadata.about_url %}&middot;
Plus d'informations : {% if metadata.about_url %}
<a href="{{ metadata.about_url }}">
{% endif %}{{ metadata.about or metadata.about_url }}{% if metadata.about_url %}</a>{% endif %}
{% endif %}
&middot; <a href="/mentions-legales">Mentions légales</a>
{% endif %}
+34
View File
@@ -0,0 +1,34 @@
{% if display_rows %}
<div class="table-wrapper">
<table class="rows-and-columns">
<thead>
<tr>
{% for column in display_columns %}
<th class="col-{{ column.name|to_css_class }}" scope="col" data-column="{{ column.name }}" data-column-type="{{ column.type }}" data-column-not-null="{{ column.notnull }}" data-is-pk="{% if column.is_pk %}1{% else %}0{% endif %}">
{% if not column.sortable %}
{{ column.name }}
{% else %}
{% if column.name == sort %}
<a href="{{ path_with_replaced_args(request, {'_sort_desc': column.name, '_sort': None, '_next': None}) }}" rel="nofollow">{{ column.name }}&nbsp;</a>
{% else %}
<a href="{{ path_with_replaced_args(request, {'_sort': column.name, '_sort_desc': None, '_next': None}) }}" rel="nofollow">{{ column.name }}{% if column.name == sort_desc %}&nbsp;▲{% endif %}</a>
{% endif %}
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in display_rows %}
<tr>
{% for cell in row %}
<td class="col-{{ cell.column|to_css_class }} type-{{ cell.value_type }}"><div>{% if cell.column == "titulaire.id" or cell.column == "acheteur.id" %}<a href="https://annuaire-entreprises.data.gouv.fr/etablissement/{{ cell.value }}" target="_blank">{{ cell.value }}</a>{% elif cell.column == "codeAPE" %} <a href="https://www.insee.fr/fr/metadonnees/nafr2/sousClasse/{{ cell.value }}?champRecherche=true" target="_blank">{{ cell.value }}</a> {% else %}{{ cell.value }}{% endif %}</div></td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="zero-results">0 lignes</p>
{% endif %}
+3
View File
@@ -0,0 +1,3 @@
{% extends "base.html" %}
<h1>Coucou</h1>
+58
View File
@@ -0,0 +1,58 @@
{% extends "base.html" %}
{% block title %}Debug allow rules{% endblock %}
{% block extra_head %}
<style>
textarea {
height: 10em;
width: 95%;
box-sizing: border-box;
padding: 0.5em;
border: 2px dotted black;
}
.two-col {
display: inline-block;
width: 48%;
}
.two-col label {
width: 48%;
}
p.message-warning {
white-space: pre-wrap;
}
@media only screen and (max-width: 576px) {
.two-col {
width: 100%;
}
}
</style>
{% endblock %}
{% block content %}
<h1>Debug allow rules</h1>
<p>Use this tool to try out different actor and allow combinations. See <a href="https://docs.datasette.io/en/stable/authentication.html#defining-permissions-with-allow-blocks">Defining permissions with "allow" blocks</a> for documentation.</p>
<form action="{{ urls.path('-/allow-debug') }}" method="get">
<div class="two-col">
<p><label>Allow block</label></p>
<textarea name="allow">{{ allow_input }}</textarea>
</div>
<div class="two-col">
<p><label>Actor</label></p>
<textarea name="actor">{{ actor_input }}</textarea>
</div>
<div style="margin-top: 1em;">
<input type="submit" value="Apply allow block to actor">
</div>
</form>
{% if error %}<p class="message-warning">{{ error }}</p>{% endif %}
{% if result == "True" %}<p class="message-info">Result: allow</p>{% endif %}
{% if result == "False" %}<p class="message-error">Result: deny</p>{% endif %}
{% endblock %}
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{{ urls.static('app.css') }}?{{ app_css_hash }}">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="manifest" href="/static/manifest.webmanifest">
{% for url in extra_css_urls %}
<link rel="stylesheet" href="{{ url.url }}"{% if url.sri %} integrity="{{ url.sri }}" crossorigin="anonymous"{% endif %}>
{% endfor %}
{% for url in extra_js_urls %}
<script {% if url.module %}type="module" {% endif %}src="{{ url.url }}"{% if url.sri %} integrity="{{ url.sri }}" crossorigin="anonymous"{% endif %}></script>
{% endfor %}
{% block extra_head %}{% endblock %}
<link rel="shortcut icon" href="/static/icons/icon-192x192.png" />
<!-- Matomo -->
<script type="text/javascript">
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.maudry.com/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '14']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body class="{% block body_class %}{% endblock %}">
<header><nav>{% block nav %}
{% set links = menu_links() %}{% if links or show_logout %}
<details class="nav-menu">
<summary>Menu</summary>
<div class="nav-menu-inner">
{% if links %}
<ul>
{% for link in links %}
<li><a href="{{ link.href }}">{{ link.label }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% if show_logout %}
<form action="{{ urls.logout() }}" method="post">
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
<button class="button-as-link">Déconnexion</button>
</form>{% endif %}
</div>
</details>{% endif %}
{% if actor %}
<div class="actor">
<strong>{{ display_actor(actor) }}</strong>
</div>
{% endif %}
{% endblock %}</nav></header>
{% block messages %}
{% if show_messages %}
{% for message, message_type in show_messages() %}
<p class="message-{% if message_type == 1 %}info{% elif message_type == 2 %}warning{% elif message_type == 3 %}error{% endif %}">{{ message }}</p>
{% endfor %}
{% endif %}
{% endblock %}
<section class="content">
{% block content %}
{% endblock %}
</section>
<footer class="ft">{% block footer %}{% include "_footer.html" %}{% endblock %}</footer>
{% include "_close_open_menus.html" %}
{% for body_script in body_scripts %}
<script{% if body_script.module %} type="module"{% endif %}>{{ body_script.script }}</script>
{% endfor %}
{% if select_templates %}<!-- Templates considered: {{ select_templates|join(", ") }} -->{% endif %}
</body>
</html>
+113
View File
@@ -0,0 +1,113 @@
{% extends "base.html" %}
{% block title %}{{ database }}{% endblock %}
{% block extra_head %}
{{ super() }}
{% include "_codemirror.html" %}
{% endblock %}
{% block body_class %}db db-{{ database|to_css_class }}{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">accueil</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<!-- <div class="page-header" style="border-color: #{{ database_color(database) }}">
<h1>{{ metadata.title or database }}{% if private %} 🔒{% endif %}</h1>
{% set links = database_actions() %}{% if links %}
<details class="actions-menu-links">
<summary><svg aria-labelledby="actions-menu-links-title" role="img"
style="color: #666" xmlns="http://www.w3.org/2000/svg"
width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<title id="actions-menu-links-title">Table actions</title>
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg></summary>
<div class="dropdown-menu">
{% if links %}
<ul>
{% for link in links %}
<li><a href="{{ link.href }}">{{ link.label }}</a></li>
{% endfor %}
</ul>
{% endif %}
</div>
</details>{% endif %}
</div> -->
<!-- {% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %} -->
{% if attached_databases %}
<div class="message-info">
<p>The following databases are attached to this connection, and can be used for cross-database joins:</p>
<ul class="bullets">
{% for db_name in attached_databases %}
<li><strong>{{ db_name }}</strong> - <a href="?sql=select+*+from+[{{ db_name }}].sqlite_master+where+type='table'">tables</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
<p class="db-presentation">decp.info vous permet d'explorer les données à travers différentes vues. Selon que vous soyez plutôt intéressé·e par le montant, les titulaires ou les caractériques d'un marché public, une vue vous sera plus utile qu'une autre.</p>
{% for table in tables %}
{% if show_hidden or not table.hidden %}
<div class="db-table">
<h2><a href="{{ urls.table(database, table.name) }}">{{ metadata.tables[table.name].title }}</a>{% if table.private %} 🔒{% endif %}{% if table.hidden %}<em> (hidden)</em>{% endif %}</h2>
<p>Description : {{ metadata.tables[table.name].description_html | safe }} (<a target="_blank" href="{{ metadata.tables[table.name].download }}">CSV</a>)</p>
<p class="columns">Colonnes : {% for column in table.columns %}{{ column }}{% if not loop.last %}, {% endif %}{% endfor %}</p>
<p>{% if table.count is none %}{% else %}{{ "{:,}".format(table.count) }} ligne{% if table.count == 1 %}{% else %}s{% endif %}{% endif %}</p>
</div>
{% endif %}
{% endfor %}
{% if hidden_count and not show_hidden %}
<p>... and <a href="{{ urls.database(database) }}?_show_hidden=1">{{ "{:,}".format(hidden_count) }} hidden table{% if hidden_count == 1 %}{% else %}s{% endif %}</a></p>
{% endif %}
{% if views %}
<h2 id="views">Views</h2>
<ul class="bullets">
{% for view in views %}
<li><a href="{{ urls.database(database) }}/{{ view.name|urlencode }}">{{ view.name }}</a>{% if view.private %} 🔒{% endif %}</li>
{% endfor %}
</ul>
{% endif %}
{% if queries %}
<h2 id="queries">Queries</h2>
<ul class="bullets">
{% for query in queries %}
<li><a href="{{ urls.query(database, query.name) }}{% if query.fragment %}#{{ query.fragment }}{% endif %}" title="{{ query.description or query.sql }}">{{ query.title or query.name }}</a>{% if query.private %} 🔒{% endif %}</li>
{% endfor %}
</ul>
{% endif %}
{% if allow_execute_sql %}
<form class="sql" action="{{ urls.database(database) }}" method="get">
<h3>Requête SQL personnalisée</h3>
<p><textarea id="sql-editor" name="sql">{% if tables %}select * from {{ tables[0].name|escape_sqlite }}{% else %}select sqlite_version(){% endif %}</textarea></p>
<p>
<button id="sql-format" type="button" hidden>Formater le SQL</button>
<input type="submit" value="Exécuter">
</p>
</form>
{% endif %}
{% if allow_download %}
<p class="download-sqlite">Download SQLite DB: <a href="{{ urls.database(database) }}.db">{{ database }}.db</a> <em>{{ format_bytes(size) }}</em></p>
{% endif %}
{% include "_codemirror_foot.html" %}
{% endblock %}
+18
View File
@@ -0,0 +1,18 @@
{% extends "base.html" %}
{% block title %}{% if title %}{{ title }}{% else %}Error {{ status }}{% endif %}{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">accueil</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<h1>{% if title %}{{ title }}{% else %}Erreur {{ status }}{% endif %}</h1>
<div style="padding: 1em; margin: 1em 0; border: 3px solid red;">{{ error }}</div>
{% endblock %}
+38
View File
@@ -0,0 +1,38 @@
{% extends "base.html" %}
{% block title %}{{ metadata.title or "Datasette" }}: {% for database in databases %}{{ database.name }}{% if not loop.last %}, {% endif %}{% endfor %}{% endblock %}
{% block body_class %}index{% endblock %}
{% block content %}
<h1>{{ metadata.title or "Datasette" }}{% if private %} 🔒{% endif %}</h1>
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
<p><a class="explore nodec" href="/db"><i class="flaticon-magnifying-glass"></i></a> <a class="explore" href="/db">Explorer les données</a></p>
<p><a class="explore nodec" href="https://teamopendata.org/t/decp-info-les-donnees-de-la-commande-publique-pour-tous-questions-reponses-discussions/2948"><i class="flaticon-chat-2"></i></a> <a href="https://teamopendata.org/t/decp-info-les-donnees-de-la-commande-publique-pour-tous-questions-reponses-discussions/2948">Présentation / FAQ / discussions</a></p>
<p><a class="explore nodec" href="/versions"><i class="flaticon-copy"></i></a> <a href="/versions">Notes de version</a></p>
<p><a class="explore nodec" href="/inscription"><i class="flaticon-paper-plane"></i></a> <a href="/inscription">Se tenir informé des nouveautés de decp.info</a></p>
<p><a class="explore nodec" href="mailto:colin+decp@maudry.com"><i class="flaticon-envelope"></i></a> <a href="mailto:colin+decp@maudry.com">colin+decp@maudry.com</a></p>
<!-- {% for database in databases %}
<h2 style="padding-left: 10px; border-left: 10px solid #{{ database.color }}">
<a href="{{ urls.database(database.name) }}">{{ database.name }}</a>{% if database.private %} 🔒{% endif %}</h2>
<p>
{% if database.show_table_row_counts %}{{ "{:,}".format(database.table_rows_sum) }} rows in {% endif %}{{ database.tables_count }} table{% if database.tables_count != 1 %}s{% endif %}{% if database.tables_count and database.hidden_tables_count %}, {% endif -%}
{% if database.hidden_tables_count -%}
{% if database.show_table_row_counts %}{{ "{:,}".format(database.hidden_table_rows_sum) }} rows in {% endif %}{{ database.hidden_tables_count }} hidden table{% if database.hidden_tables_count != 1 %}s{% endif -%}
{% endif -%}
{% if database.views_count -%}
{% if database.tables_count or database.hidden_tables_count %}, {% endif -%}
{{ "{:,}".format(database.views_count) }} view{% if database.views_count != 1 %}s{% endif %}
{% endif %}
</p>
<p>{% for table in database.tables_and_views_truncated %}<a href="{{ urls.table(database.name, table.name) }}"{% if table.count %} title="{{ table.count }} rows"{% endif %}>{{ table.name }}</a>{% if table.private %} 🔒{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}{% if database.tables_and_views_more %}, <a href="{{ urls.database(database.name) }}">...</a>{% endif %}</p>
{% endfor %} -->
{% endblock %}
+25
View File
@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block title %}Log out{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ base_url }}">home</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<h1>Log out</h1>
<p>You are logged in as <strong>{{ display_actor(actor) }}</strong></p>
<form action="{{ urls.logout() }}" method="post">
<div>
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
<input type="submit" value="Log out">
</div>
</form>
{% endblock %}
+27
View File
@@ -0,0 +1,27 @@
{% extends "base.html" %}
{% block title %}Debug messages{% endblock %}
{% block content %}
<h1>Debug messages</h1>
<p>Set a message:</p>
<form action="{{ urls.path('-/messages') }}" method="post">
<div>
<input type="text" name="message" style="width: 40%">
<div class="select-wrapper">
<select name="message_type">
<option>INFO</option>
<option>WARNING</option>
<option>ERROR</option>
<option>all</option>
</select>
</div>
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
<input type="submit" value="Add message">
</div>
</form>
{% endblock %}
+240
View File
@@ -0,0 +1,240 @@
{% extends "base.html" %}
{% block title %}Se tenir informé{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">accueil</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<h1>Se tenir informé des nouveautés de decp.info</h1>
<p><a href="/mentions-legales">Mentions légales et politique de confidentialité</a></p>
<!-- Begin Sendinblue Form -->
<!-- START - We recommend to place the below code in head tag of your website html -->
<style>
@font-face {
font-display: block;
font-family: Roboto;
src: url(https://assets.sendinblue.com/font/Roboto/Latin/normal/normal/7529907e9eaf8ebb5220c5f9850e3811.woff2) format("woff2"), url(https://assets.sendinblue.com/font/Roboto/Latin/normal/normal/25c678feafdc175a70922a116c9be3e7.woff) format("woff")
}
@font-face {
font-display: fallback;
font-family: Roboto;
font-weight: 600;
src: url(https://assets.sendinblue.com/font/Roboto/Latin/medium/normal/6e9caeeafb1f3491be3e32744bc30440.woff2) format("woff2"), url(https://assets.sendinblue.com/font/Roboto/Latin/medium/normal/71501f0d8d5aa95960f6475d5487d4c2.woff) format("woff")
}
@font-face {
font-display: fallback;
font-family: Roboto;
font-weight: 700;
src: url(https://assets.sendinblue.com/font/Roboto/Latin/bold/normal/3ef7cf158f310cf752d5ad08cd0e7e60.woff2) format("woff2"), url(https://assets.sendinblue.com/font/Roboto/Latin/bold/normal/ece3a1d82f18b60bcce0211725c476aa.woff) format("woff")
}
#sib-container input:-ms-input-placeholder {
text-align: left;
font-family: "Helvetica", sans-serif;
color: #c0ccda;
}
#sib-container input::placeholder {
text-align: left;
font-family: "Helvetica", sans-serif;
color: #c0ccda;
}
#sib-container textarea::placeholder {
text-align: left;
font-family: "Helvetica", sans-serif;
color: #c0ccda;
}
</style>
<link rel="stylesheet" href="https://sibforms.com/forms/end-form/build/sib-styles.css">
<!-- END - We recommend to place the above code in head tag of your website html -->
<!-- START - We recommend to place the below code where you want the form in your website html -->
<div class="sib-form" style="text-align: center;
background-color: #EFF2F7; ">
<div id="sib-form-container" class="sib-form-container">
<div id="error-message" class="sib-form-message-panel" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#661d1d; background-color:#ffeded; border-radius:3px; border-color:#ff4949;max-width:540px;">
<div class="sib-form-message-panel__text sib-form-message-panel__text--center">
<svg viewBox="0 0 512 512" class="sib-icon sib-notification__icon">
<path d="M256 40c118.621 0 216 96.075 216 216 0 119.291-96.61 216-216 216-119.244 0-216-96.562-216-216 0-119.203 96.602-216 216-216m0-32C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm-11.49 120h22.979c6.823 0 12.274 5.682 11.99 12.5l-7 168c-.268 6.428-5.556 11.5-11.99 11.5h-8.979c-6.433 0-11.722-5.073-11.99-11.5l-7-168c-.283-6.818 5.167-12.5 11.99-12.5zM256 340c-15.464 0-28 12.536-28 28s12.536 28 28 28 28-12.536 28-28-12.536-28-28-28z"
/>
</svg>
<span class="sib-form-message-panel__inner-text">
Il y a eu un problème lors de votre inscription.
</span>
</div>
</div>
<div></div>
<div id="success-message" class="sib-form-message-panel" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#085229; background-color:#F8FAFB; border-radius:3px; border-color:#13ce66;max-width:540px;">
<div class="sib-form-message-panel__text sib-form-message-panel__text--center">
<svg viewBox="0 0 512 512" class="sib-icon sib-notification__icon">
<path d="M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 464c-118.664 0-216-96.055-216-216 0-118.663 96.055-216 216-216 118.664 0 216 96.055 216 216 0 118.663-96.055 216-216 216zm141.63-274.961L217.15 376.071c-4.705 4.667-12.303 4.637-16.97-.068l-85.878-86.572c-4.667-4.705-4.637-12.303.068-16.97l8.52-8.451c4.705-4.667 12.303-4.637 16.97.068l68.976 69.533 163.441-162.13c4.705-4.667 12.303-4.637 16.97.068l8.451 8.52c4.668 4.705 4.637 12.303-.068 16.97z"
/>
</svg>
<span class="sib-form-message-panel__inner-text">
Votre inscription à la lettre d&#039;information de decp.info est confirmée !
</span>
</div>
</div>
<div></div>
<div id="sib-container" class="sib-container--large sib-container--vertical" style="text-align:center; background-color:rgba(255,255,255,1); max-width:540px; border-radius:3px; border-width:1px; border-color:#C0CCD9; border-style:solid;">
<form id="sib-form" method="POST" action="https://6254d9a3.sibforms.com/serve/MUIEAFh0B8R5fTSPBmKbkiziso8TBxEbUSvq4FaHCK9EL8CT6H41du2IXKnJZhVBXFYxxZgnOVqO7hribE8qPWpY5IE5yraVm7d7uKdlGqurkl0XgHUy4fILW8aPuGAcn60ZsZzJf7gxINtPUpSlrOsjZPcdl4vvWgsaAU51rM9cXCC8Mm_MrlvOkuZk_uah-YUNMjj6qLONk1WR"
data-type="subscription">
<div style="padding: 8px 0;">
<div class="sib-form-block" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#3C4858; background-color:transparent;">
<div class="sib-text-form-block">
<p>Inscrivez-vous à la lettre d'information de decp.info afin d'être informé·e de l'ajout de nouvelles fonctionnalités (2 mails par mois maximum).</p>
</div>
</div>
</div>
<div style="padding: 8px 0;">
<div class="sib-input sib-form-block">
<div class="form__entry entry_block">
<div class="form__label-row ">
<label class="entry__label" style="font-size:16px; text-align:left; font-weight:700; font-family:&quot;Helvetica&quot;, sans-serif; color:#3c4858;" for="EMAIL" data-required="*">
Votre adresse email :
</label>
<div class="entry__field">
<input class="input" type="text" id="EMAIL" name="EMAIL" autocomplete="off" data-required="true" required />
</div>
</div>
<label class="entry__error entry__error--primary" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#661d1d; background-color:#ffeded; border-radius:3px; border-color:#ff4949;">
</label>
</div>
</div>
</div>
<div style="padding: 8px 0;">
<div class="sib-input sib-form-block">
<div class="form__entry entry_block">
<div class="form__label-row ">
<label class="entry__label" style="font-size:16px; text-align:left; font-weight:700; font-family:&quot;Helvetica&quot;, sans-serif; color:#3c4858;" for="NOM">
Votre nom :
</label>
<div class="entry__field">
<input class="input" maxlength="200" type="text" id="NOM" name="NOM" autocomplete="off" placeholder="Optionnel" />
</div>
</div>
<label class="entry__error entry__error--primary" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#661d1d; background-color:#ffeded; border-radius:3px; border-color:#ff4949;">
</label>
</div>
</div>
</div>
<div style="padding: 8px 0;">
<div class="sib-input sib-form-block">
<div class="form__entry entry_block">
<div class="form__label-row ">
<label class="entry__label" style="font-size:16px; text-align:left; font-weight:700; font-family:&quot;Helvetica&quot;, sans-serif; color:#3c4858;" for="ORGANISME">
Votre organisme :
</label>
<div class="entry__field">
<input class="input" maxlength="200" type="text" id="ORGANISME" name="ORGANISME" autocomplete="off" placeholder="Optionnel" />
</div>
</div>
<label class="entry__error entry__error--primary" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#661d1d; background-color:#ffeded; border-radius:3px; border-color:#ff4949;">
</label>
</div>
</div>
</div>
<div style="padding: 8px 0;">
<div class="sib-optin sib-form-block">
<div class="form__entry entry_mcq">
<div class="form__label-row ">
<div class="entry__choice">
<label>
<input type="checkbox" class="input_replaced" value="1" id="OPT_IN" name="OPT_IN" />
<span class="checkbox checkbox_tick_positive"></span><span style="font-size:14px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#3C4858; background-color:transparent;"><p>J'accepte de recevoir vos e-mails et confirme avoir pris connaissance de votre politique de confidentialité et mentions légales.</p></span> </label>
</div>
</div>
<label class="entry__error entry__error--primary" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#661d1d; background-color:#ffeded; border-radius:3px; border-color:#ff4949;">
</label>
<label class="entry__specification" style="font-size:12px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#8390A4;">
Vous pouvez vous désinscrire à tout moment en cliquant sur le lien présent dans nos emails.
</label>
</div>
</div>
</div>
<div style="padding: 8px 0;">
<div class="sib-form__declaration">
<div class="declaration-block-icon">
<svg class="icon__SVG" width="0" height="0" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="svgIcon-sphere" viewBox="0 0 63 63">
<path class="path1" d="M31.54 0l1.05 3.06 3.385-.01-2.735 1.897 1.05 3.042-2.748-1.886-2.738 1.886 1.044-3.05-2.745-1.897h3.393zm13.97 3.019L46.555 6.4l3.384.01-2.743 2.101 1.048 3.387-2.752-2.1-2.752 2.1 1.054-3.382-2.745-2.105h3.385zm9.998 10.056l1.039 3.382h3.38l-2.751 2.1 1.05 3.382-2.744-2.091-2.743 2.091 1.054-3.381-2.754-2.1h3.385zM58.58 27.1l1.04 3.372h3.379l-2.752 2.096 1.05 3.387-2.744-2.091-2.75 2.092 1.054-3.387-2.747-2.097h3.376zm-3.076 14.02l1.044 3.364h3.385l-2.743 2.09 1.05 3.392-2.744-2.097-2.743 2.097 1.052-3.377-2.752-2.117 3.385-.01zm-9.985 9.91l1.045 3.364h3.393l-2.752 2.09 1.05 3.393-2.745-2.097-2.743 2.097 1.05-3.383-2.751-2.1 3.384-.01zM31.45 55.01l1.044 3.043 3.393-.008-2.752 1.9L34.19 63l-2.744-1.895-2.748 1.891 1.054-3.05-2.743-1.9h3.384zm-13.934-3.98l1.036 3.364h3.402l-2.752 2.09 1.053 3.393-2.747-2.097-2.752 2.097 1.053-3.382-2.743-2.1 3.384-.01zm-9.981-9.91l1.045 3.364h3.398l-2.748 2.09 1.05 3.392-2.753-2.1-2.752 2.096 1.053-3.382-2.743-2.102 3.384-.009zM4.466 27.1l1.038 3.372H8.88l-2.752 2.097 1.053 3.387-2.743-2.09-2.748 2.09 1.053-3.387L0 30.472h3.385zm3.069-14.025l1.045 3.382h3.395L9.23 18.56l1.05 3.381-2.752-2.09-2.752 2.09 1.053-3.381-2.744-2.1h3.384zm9.99-10.056L18.57 6.4l3.393.01-2.743 2.1 1.05 3.373-2.754-2.092-2.751 2.092 1.053-3.382-2.744-2.1h3.384zm24.938 19.394l-10-4.22a2.48 2.48 0 00-1.921 0l-10 4.22A2.529 2.529 0 0019 24.75c0 10.47 5.964 17.705 11.537 20.057a2.48 2.48 0 001.921 0C36.921 42.924 44 36.421 44 24.75a2.532 2.532 0 00-1.537-2.336zm-2.46 6.023l-9.583 9.705a.83.83 0 01-1.177 0l-5.416-5.485a.855.855 0 010-1.192l1.177-1.192a.83.83 0 011.177 0l3.65 3.697 7.819-7.916a.83.83 0 011.177 0l1.177 1.191a.843.843 0 010 1.192z"
fill="#0092FF"></path>
</symbol>
</defs>
</svg>
<svg class="svgIcon-sphere" style="width:63px; height:63px;">
<use xlink:href="#svgIcon-sphere"></use>
</svg>
</div>
<p style="font-size:14px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#687484; background-color:transparent;">
Nous utilisons Sendinblue en tant que plateforme marketing. En soumettant ce formulaire, vous reconnaissez que les informations que vous allez fournir seront transmises à Sendinblue en sa qualité de processeur de données; et ce conformément à ses
<a target="_blank" class="clickable_link" href="https://fr.sendinblue.com/legal/termsofuse/">conditions générales d'utilisation</a>.
</p>
</div>
</div>
<div style="padding: 8px 0;">
<div class="sib-form-block" style="text-align: left">
<button class="sib-form-block__button sib-form-block__button-with-loader" style="font-size:16px; text-align:left; font-weight:700; font-family:&quot;Helvetica&quot;, sans-serif; color:#FFFFFF; background-color:#3E4857; border-radius:3px; border-width:0px;"
form="sib-form" type="submit">
<svg class="icon clickable__icon progress-indicator__icon sib-hide-loader-icon" viewBox="0 0 512 512">
<path d="M460.116 373.846l-20.823-12.022c-5.541-3.199-7.54-10.159-4.663-15.874 30.137-59.886 28.343-131.652-5.386-189.946-33.641-58.394-94.896-95.833-161.827-99.676C261.028 55.961 256 50.751 256 44.352V20.309c0-6.904 5.808-12.337 12.703-11.982 83.556 4.306 160.163 50.864 202.11 123.677 42.063 72.696 44.079 162.316 6.031 236.832-3.14 6.148-10.75 8.461-16.728 5.01z"
/>
</svg>
Je m&#039;inscris
</button>
</div>
</div>
<input type="text" name="email_address_check" value="" class="input--hidden">
<input type="hidden" name="locale" value="fr">
</form>
</div>
</div>
</div>
<!-- END - We recommend to place the below code where you want the form in your website html -->
<!-- START - We recommend to place the below code in footer or bottom of your website html -->
<script>
window.REQUIRED_CODE_ERROR_MESSAGE = 'Veuillez choisir un code pays';
window.EMAIL_INVALID_MESSAGE = window.SMS_INVALID_MESSAGE = "Les informations que vous avez fournies ne sont pas valides. Veuillez vérifier votre adresse email et réessayer.";
window.REQUIRED_ERROR_MESSAGE = "Ce champ est obligatoire pour vous inscrire. ";
window.GENERIC_INVALID_MESSAGE = "Les informations que vous avez fournies ne sont pas valides. Veuillez vérifier votre adresse email et réessayer.";
window.translation = {
common: {
selectedList: '{quantity} liste sélectionnée',
selectedLists: '{quantity} listes sélectionnées'
}
};
var AUTOHIDE = Boolean(0);
</script>
<script src="https://sibforms.com/forms/end-form/build/main.js"></script>
<!-- END - We recommend to place the above code in footer or bottom of your website html -->
<!-- End Sendinblue Form -->
{% endblock %}
@@ -0,0 +1,53 @@
{% extends "base.html" %}
{% block title %}Mentions légales{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">accueil</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<div style="max-width: 700px;margin:auto">
<h1 id="mentionslgales">Mentions légales</h1>
<p>Le site decp.info est édité par Colin Maudry, inscrit au répertoire SIRENE sous le numéro 812 231 132, dont le siège social est situé à Rennes, et dont l'adresse email est <a href="mailto:colin@maudry.com">colin@maudry.com</a>.</p>
<p>Le site est hébergé en France par :</p>
<p>Scaleway par ONLINE, SAS, au capital de 214 410,50 Euros<br/>
Siège social : 8 rue de la ville l'Evêque-75008 PARIS<br/>
RCS Paris B 433 115 904, TVA FR35433115904<br/>
<a href="https://www.scaleway.com" rel="nofollow">https://www.scaleway.com</a></p>
<p>Les icônes de la page d'accueil ont été dessinées par <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> de <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></p>
<h1 id="vieprive">Vie privée</h1>
<h2>Les cookies</h2>
<p>Ce site dépose un petit fichier texte (un « cookie ») sur votre ordinateur lorsque vous le consultez (<a href="https://fr.wikipedia.org/wiki/Cookie_(informatique)">Wikipédia</a>). Cela me permet de mesurer le nombre de visites et de distinguer les nouveaux visiteurs des utilisateurs réguliers.</p>
<div style="background-color: #ccc;"><iframe style="border: 0; height: 200px; width: 100%;" title="Opt-out du cookie de suivi" src="https://analytics.maudry.com/index.php?module=CoreAdminHome&amp;action=optOut&amp;language=fr&amp;backgroundColor=&amp;fontColor=&amp;fontSize=&amp;fontFamily="></iframe></div>
<h3 id="cesitenaffichepasdebanniredeconsentementauxcookiespourquoi">Ce site naffiche pas de bannière de consentement aux cookies, pourquoi ?</h3>
<p>Cest vrai, vous navez pas eu à cliquer sur un bloc qui recouvre la moitié de la page pour dire que vous êtes daccord avec le dépôt de cookies.</p>
<p>Rien dexceptionnel, je respecte simplement la loi, qui dit que certains outils de suivi daudience, correctement configurés pour respecter la vie privée, sont exemptés dautorisation préalable.</p>
<p>Jutilise pour cela <a href="https://matomo.org/">Matomo</a>, un outil <a href="https://matomo.org/free-software/">libre</a>, paramétré pour être en conformité avec la <a href="https://www.cnil.fr/fr/solutions-pour-les-cookies-de-mesure-daudience">recommandation « Cookies »</a> de la <a href="http://sigl.es/cnil">CNIL</a>. Cela signifie que votre adresse IP, par exemple, est anonymisée avant d’être enregistrée. Il mest donc impossible dassocier vos visites sur ce site à votre personne.</p>
<h2>La lettre d'information et conformité RGPD</h2>
Ce site <a href="/inscription">vous propose</a> de vous inscrire à une lettre d'information. Pour ce faire, vous devez donner votre accord par deux fois : au moment de remplir le formulaire, et en cliquant sur un lien dans le mail de confirmation.
Tous les emails qui vous sont envoyés dans le cadre de cette lettre d'information comportent un lien de désinscription.
Votre adresse email est stockée en France chez Sendinblue, entreprise française.
</div>
{% endblock %}
+14
View File
@@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block title %}Mentions légales{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">accueil</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<div style="max-width: 700px;margin:auto">
<h1>Notes de version</h1>
</div>
+495
View File
@@ -0,0 +1,495 @@
<!DOCTYPE html>
<html>
<head>
<title>Datasette: Pattern Portfolio</title>
<link rel="stylesheet" href="{{ base_url }}-/static/app.css?{{ app_css_hash }}">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="noindex">
<style></style>
</head>
<body>
<header><nav>
<p class="crumbs">
<a href="/">home</a>
</p>
<details class="nav-menu">
<summary><svg aria-labelledby="nav-menu-svg-title" role="img"
fill="currentColor" stroke="currentColor" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16" width="16" height="16">
<title id="nav-menu-svg-title">Menu</title>
<path fill-rule="evenodd" d="M1 2.75A.75.75 0 011.75 2h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 2.75zm0 5A.75.75 0 011.75 7h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 7.75zM1.75 12a.75.75 0 100 1.5h12.5a.75.75 0 100-1.5H1.75z"></path>
</svg></summary>
<div class="nav-menu-inner">
<ul>
<li><a href="/-/databases">Databases</a></li>
<li><a href="/-/plugins">Installed plugins</a></li>
<li><a href="/-/versions">Version info</a></li>
</ul>
<form action="/-/logout" method="post">
<button class="button-as-link">Log out</button>
</form>
</div>
</details>
<div class="actor">
<strong>root</strong>
</div>
</nav></header>
<section class="content">
<h1>Pattern Portfolio</h1>
</section>
<h2 class="pattern-heading">Header for /database/table/row and Messages</h2>
<header>
<nav>
<p class="crumbs">
<a href="/">home</a> /
<a href="/fixtures">fixtures</a> /
<a href="/fixtures/attraction_characteristic">attraction_characteristic</a>
</p>
<div class="actor">
<strong>testuser</strong>
</div>
</nav>
</header>
<p class="message-info">Example message</p>
<p class="message-warning">Example message</p>
<p class="message-error">Example message</p>
<h2 class="pattern-heading">.bd for /</h2>
<section class="content">
<h1>Datasette Fixtures</h1>
<div class="metadata-description">
An example SQLite database demonstrating Datasette
</div>
<p>
Data license:
<a href="https://github.com/simonw/datasette/blob/main/LICENSE">Apache License 2.0</a>
&middot;
Data source:
<a href="https://github.com/simonw/datasette/blob/main/tests/fixtures.py">
tests/fixtures.py</a>
&middot;
About:
<a href="https://github.com/simonw/datasette">
About Datasette</a>
</p>
<h2 style="padding-left: 10px; border-left: 10px solid #9403e5"><a href="/fixtures">fixtures</a></h2>
<p>
1,258 rows in 24 tables, 206 rows in 5 hidden tables, 4 views
</p>
<p><a href="/fixtures/compound_three_primary_keys" title="1001 rows">compound_three_primary_keys</a>, <a href="/fixtures/sortable" title="201 rows">sortable</a>, <a href="/fixtures/facetable" title="15 rows">facetable</a>, <a href="/fixtures/roadside_attraction_characteristics" title="5 rows">roadside_attraction_characteristics</a>, <a href="/fixtures/simple_primary_key" title="4 rows">simple_primary_key</a>, <a href="/fixtures">...</a></p>
<h2 style="padding-left: 10px; border-left: 10px solid #8d777f"><a href="/data">data</a></h2>
<p>
6 rows in 2 tables
</p>
<p><a href="/data/names" title="6 rows">names</a>, <a href="/data/foo">foo</a></p>
</section>
<h2 class="pattern-heading">.bd for /database</h2>
<section class="content">
<div class="page-header" style="border-color: #ff0000">
<h1>fixtures</h1>
<details class="actions-menu-links">
<summary><svg aria-labelledby="actions-menu-links-title" role="img"
style="color: #666" xmlns="http://www.w3.org/2000/svg"
width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<title id="actions-menu-links-title">Table actions</title>
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg></summary>
<div class="dropdown-menu">
<ul>
<li><a href="#">Database action</a></li>
</ul>
</div>
</details>
</div>
<div class="metadata-description">
Test tables description
</div>
<p>
Data license:
<a href="https://github.com/simonw/datasette/blob/main/LICENSE">Apache License 2.0</a>
&middot;
Data source:
<a href="https://github.com/simonw/datasette/blob/main/tests/fixtures.py">
tests/fixtures.py</a>
&middot;
About:
<a href="https://github.com/simonw/datasette">
About Datasette</a>
</p>
<form class="sql" action="/fixtures" method="get">
<h3>Custom SQL query</h3>
<p><textarea id="sql-editor" name="sql">select * from [123_starts_with_digits]</textarea></p>
<p>
<button id="sql-format" type="button" hidden>Format SQL</button>
<input type="submit" value="Run SQL">
</p>
</form>
<div class="db-table">
<h2><a href="/fixtures/123_starts_with_digits">123_starts_with_digits</a></h2>
<p><em>content</em></p>
<p>0 rows</p>
</div>
<div class="db-table">
<h2><a href="/fixtures/Table+With+Space+In+Name">Table With Space In Name</a></h2>
<p><em>pk, content</em></p>
<p>0 rows</p>
</div>
<div class="db-table">
<h2><a href="/fixtures/attraction_characteristic">attraction_characteristic</a></h2>
<p><em>pk, name</em></p>
<p>2 rows</p>
</div>
</section>
<h2 class="pattern-heading">.bd for /database/table</h2>
<section class="content">
<div class="page-header" style="border-color: #ff0000">
<h1>roadside_attraction_characteristics</h1>
<details class="actions-menu-links">
<summary><svg aria-labelledby="actions-menu-links-title" role="img"
style="color: #666" xmlns="http://www.w3.org/2000/svg"
width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<title id="actions-menu-links-title">Table actions</title>
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg></summary>
<div class="dropdown-menu">
<ul>
<li><a href="#">Table action</a></li>
</ul>
</div>
</details>
</div>
<p>
Data license:
<a href="https://github.com/simonw/datasette/blob/main/LICENSE">Apache License 2.0</a>
&middot;
Data source:
<a href="https://github.com/simonw/datasette/blob/main/tests/fixtures.py">
tests/fixtures.py</a>
&middot;
About:
<a href="https://github.com/simonw/datasette">
About Datasette</a>
</p>
<h3>3 rows
where characteristic_id = 2
</h3>
<form class="filters" action="/fixtures/roadside_attraction_characteristics" method="get">
<div class="search-row"><label for="_search">Search:</label><input id="_search" type="search" name="_search" value=""></div>
<div class="filter-row">
<div class="select-wrapper">
<select name="_filter_column_1">
<option value="">- remove filter -</option>
<option>rowid</option>
<option>attraction_id</option>
<option selected>characteristic_id</option>
</select>
</div>
<div class="select-wrapper filter-op">
<select name="_filter_op_1">
<option value="exact" selected>=</option>
<option value="not">!=</option>
<option value="contains">contains</option>
<option value="endswith">ends with</option>
<option value="startswith">starts with</option>
<option value="gt">&gt;</option>
<option value="gte"></option>
<option value="lt">&lt;</option>
<option value="lte"></option>
<option value="like">like</option>
<option value="notlike">not like</option>
<option value="glob">glob</option>
<option value="in">in</option>
<option value="notin">not in</option>
<option value="arraycontains">array contains</option>
<option value="date">date</option>
<option value="isnull__1">is null</option>
<option value="notnull__1">is not null</option>
<option value="isblank__1">is blank</option>
<option value="notblank__1">is not blank</option>
</select>
</div><input type="text" name="_filter_value_1" class="filter-value" value="2">
</div>
<div class="filter-row">
<div class="select-wrapper">
<select name="_filter_column">
<option value="">- column -</option>
<option>rowid</option>
<option>attraction_id</option>
<option>characteristic_id</option>
</select>
</div>
<div class="select-wrapper filter-op">
<select name="_filter_op">
<option value="exact">=</option>
<option value="not">!=</option>
<option value="contains">contains</option>
<option value="endswith">ends with</option>
<option value="startswith">starts with</option>
<option value="gt">&gt;</option>
<option value="gte"></option>
<option value="lt">&lt;</option>
<option value="lte"></option>
<option value="like">like</option>
<option value="notlike">not like</option>
<option value="glob">glob</option>
<option value="in">in</option>
<option value="notin">not in</option>
<option value="arraycontains">array contains</option>
<option value="date">date</option>
<option value="isnull__1">is null</option>
<option value="notnull__1">is not null</option>
<option value="isblank__1">is blank</option>
<option value="notblank__1">is not blank</option>
</select>
</div><input type="text" name="_filter_value" class="filter-value">
</div>
<div class="filter-row">
<div class="select-wrapper small-screen-only">
<select name="_sort" id="sort_by">
<option value="">Sort...</option>
<option value="rowid" selected>Sort by rowid</option>
<option value="attraction_id">Sort by attraction_id</option>
<option value="characteristic_id">Sort by characteristic_id</option>
</select>
</div>
<label class="sort_by_desc small-screen-only"><input type="checkbox" name="_sort_by_desc"> descending</label>
<input type="submit" value="Apply">
</div>
</form>
<div class="extra-wheres">
<h3>2 extra where clauses</h3>
<ul>
<li><code>planet_int=1</code> [<a href="/fixtures/facetable?_where=state%3D%27CA%27">remove</a>]</li>
<li><code>state='CA'</code> [<a href="/fixtures/facetable?_where=planet_int%3D1">remove</a>]</li>
</ul>
</div>
<p><a class="not-underlined" title="select rowid, attraction_id, characteristic_id from roadside_attraction_characteristics where &#34;characteristic_id&#34; = :p0 order by rowid limit 101" href="/fixtures?sql=select+rowid%2C+attraction_id%2C+characteristic_id+from+roadside_attraction_characteristics+where+%22characteristic_id%22+%3D+%3Ap0+order+by+rowid+limit+101&amp;p0=2">&#x270e; <span class="underlined">View and edit SQL</span></a></p>
<p class="export-links">This data as <a href="/fixtures/roadside_attraction_characteristics.json?characteristic_id=2&amp;_labels=on">json</a>, <a href="/fixtures/roadside_attraction_characteristics.csv?characteristic_id=2&amp;_labels=on&amp;_size=max">CSV</a> (<a href="#export">advanced</a>)</p>
<p class="suggested-facets">
Suggested facets: <a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet=complex_array&amp;_facet=tags#facet-tags">tags</a>, <a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet=complex_array&amp;_facet_date=created#facet-created">created</a> (date), <a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet=complex_array&amp;_facet_array=tags#facet-tags">tags</a> (array)
</p>
<div class="facet-results">
<div class="facet-info facet-fixtures-facetable-tags" id="facet-tags">
<p class="facet-info-name">
<strong>tags (array)</strong>
<a href="/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created" class="cross"></a>
</p>
<ul>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;tags__arraycontains=tag1">tag1</a> 2</li>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;tags__arraycontains=tag2">tag2</a> 1</li>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;tags__arraycontains=tag3">tag3</a> 1</li>
</ul>
</div>
<div class="facet-info facet-fixtures-facetable-created" id="facet-created">
<p class="facet-info-name">
<strong>created</strong>
<a href="/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet_array=tags" class="cross"></a>
</p>
<ul>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;created=2019-01-14+08%3A00%3A00">2019-01-14 08:00:00</a> 4</li>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;created=2019-01-15+08%3A00%3A00">2019-01-15 08:00:00</a> 4</li>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;created=2019-01-16+08%3A00%3A00">2019-01-16 08:00:00</a> 2</li>
</ul>
</div>
<div class="facet-info facet-fixtures-facetable-city_id" id="facet-city_id">
<p class="facet-info-name">
<strong>city_id</strong>
<a href="/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=created&amp;_facet_array=tags" class="cross"></a>
</p>
<ul>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;city_id=1">San Francisco</a> 6</li>
<li><a href="http://latest.datasette.io/fixtures/facetable?_where=planet_int%3D1&amp;_where=state%3D%27CA%27&amp;_facet=city_id&amp;_facet=created&amp;_facet_array=tags&amp;city_id=2">Los Angeles</a> 4</li>
</ul>
</div>
</div>
<table class="rows-and-columns">
<thead>
<tr>
<th class="col-Link" scope="col">
Link
</th>
<th class="col-rowid" scope="col">
<a href="/fixtures/roadside_attraction_characteristics?characteristic_id=2&amp;_sort_desc=rowid" rel="nofollow">rowid&nbsp;</a>
</th>
<th class="col-attraction_id" scope="col">
<a href="/fixtures/roadside_attraction_characteristics?characteristic_id=2&amp;_sort=attraction_id" rel="nofollow">attraction_id</a>
</th>
<th class="col-characteristic_id" scope="col">
<a href="/fixtures/roadside_attraction_characteristics?characteristic_id=2&amp;_sort=characteristic_id" rel="nofollow">characteristic_id</a>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col-Link"><a href="/fixtures/roadside_attraction_characteristics/1">1</a></td>
<td class="col-rowid">1</td>
<td class="col-attraction_id"><a href="/fixtures/roadside_attractions/1">The Mystery Spot</a>&nbsp;<em>1</em></td>
<td class="col-characteristic_id"><a href="/fixtures/attraction_characteristic/2">Paranormal</a>&nbsp;<em>2</em></td>
</tr>
<tr>
<td class="col-Link"><a href="/fixtures/roadside_attraction_characteristics/2">2</a></td>
<td class="col-rowid">2</td>
<td class="col-attraction_id"><a href="/fixtures/roadside_attractions/2">Winchester Mystery House</a>&nbsp;<em>2</em></td>
<td class="col-characteristic_id"><a href="/fixtures/attraction_characteristic/2">Paranormal</a>&nbsp;<em>2</em></td>
</tr>
<tr>
<td class="col-Link"><a href="/fixtures/roadside_attraction_characteristics/3">3</a></td>
<td class="col-rowid">3</td>
<td class="col-attraction_id"><a href="/fixtures/roadside_attractions/4">Bigfoot Discovery Museum</a>&nbsp;<em>4</em></td>
<td class="col-characteristic_id"><a href="/fixtures/attraction_characteristic/2">Paranormal</a>&nbsp;<em>2</em></td>
</tr>
</tbody>
</table>
<div id="export" class="advanced-export">
<h3>Advanced export</h3>
<p>JSON shape:
<a href="/fixtures/roadside_attraction_characteristics.json?characteristic_id=2&amp;_labels=on">default</a>,
<a href="/fixtures/roadside_attraction_characteristics.json?characteristic_id=2&amp;_labels=on&amp;_shape=array">array</a>,
<a href="/fixtures/roadside_attraction_characteristics.json?characteristic_id=2&amp;_labels=on&amp;_shape=array&amp;_nl=on">newline-delimited</a>
</p>
<form action="/fixtures/roadside_attraction_characteristics.csv" method="get">
<p>
CSV options:
<label><input type="checkbox" name="_dl"> download file</label>
<label><input type="checkbox" name="_labels" checked> expand labels</label>
<input type="submit" value="Export CSV">
<input type="hidden" name="characteristic_id" value="2">
<input type="hidden" name="_size" value="max">
</p>
</form>
</div>
<pre class="wrapped-sql">CREATE TABLE roadside_attraction_characteristics (
attraction_id INTEGER REFERENCES roadside_attractions(pk),
characteristic_id INTEGER REFERENCES attraction_characteristic(pk)
);</pre>
</section>
<h2 class="pattern-heading">.bd for /database/table/row</h2>
<section class="content">
<h1 style="padding-left: 10px; border-left: 10px solid #ff0000">roadside_attractions: 2</h1>
<p>This data as <a href="/fixtures/roadside_attractions/2.json">json</a></p>
<table class="rows-and-columns">
<thead>
<tr>
<th class="col-pk" scope="col">
pk
</th>
<th class="col-name" scope="col">
name
</th>
<th class="col-address" scope="col">
address
</th>
<th class="col-latitude" scope="col">
latitude
</th>
<th class="col-longitude" scope="col">
longitude
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col-pk">2</td>
<td class="col-name">Winchester Mystery House</td>
<td class="col-address">525 South Winchester Boulevard, San Jose, CA 95128</td>
<td class="col-latitude">37.3184</td>
<td class="col-longitude">-121.9511</td>
</tr>
</tbody>
</table>
<h2>Links from other tables</h2>
<ul>
<li>
<a href="/fixtures/roadside_attraction_characteristics?attraction_id=2">
1 row</a>
from attraction_id in roadside_attraction_characteristics
</li>
</ul>
</section>
<h2 class="pattern-heading">.ft</h2>
<footer class="ft">Powered by <a href="https://datasette.io/" title="Datasette v0+unknown">Datasette</a>
&middot; Data license:
<a href="https://github.com/simonw/datasette/blob/main/LICENSE">Apache License 2.0</a>
&middot;
Data source:
<a href="https://github.com/simonw/datasette/blob/main/tests/fixtures.py">
tests/fixtures.py</a>
&middot;
About:
<a href="https://github.com/simonw/datasette">
About Datasette</a>
</footer>
{% include "_close_open_menus.html" %}
</body>
</html>
@@ -0,0 +1,55 @@
{% extends "base.html" %}
{% block title %}Debug permissions{% endblock %}
{% block extra_head %}
<style type="text/css">
.check-result-true {
color: green;
}
.check-result-false {
color: red;
}
.check h2 {
font-size: 1em
}
.check-action, .check-when, .check-result {
font-size: 1.3em;
}
</style>
{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ base_url }}">home</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<h1>Recent permissions checks</h1>
{% for check in permission_checks %}
<div class="check">
<h2>
<span class="check-action">{{ check.action }}</span>
checked at
<span class="check-when">{{ check.when }}</span>
{% if check.result %}
<span class="check-result check-result-true"></span>
{% else %}
<span class="check-result check-result-false"></span>
{% endif %}
{% if check.used_default %}
<span class="check-used-default">(used default)</span>
{% endif %}
</h2>
<p><strong>Actor:</strong> {{ check.actor|tojson }}</p>
{% if check.resource %}
<p><strong>Resource:</strong> {{ check.resource }}</p>
{% endif %}
</div>
{% endfor %}
{% endblock %}
+87
View File
@@ -0,0 +1,87 @@
{% extends "base.html" %}
{% block title %}{{ database }}{% if query and query.sql %}: {{ query.sql }}{% endif %}{% endblock %}
{% block extra_head %}
{{ super() }}
{% if columns %}
<style>
@media only screen and (max-width: 576px) {
{% for column in columns %}
.rows-and-columns td:nth-of-type({{ loop.index }}):before { content: "{{ column|escape_css_string }}"; }
{% endfor %}
}
</style>
{% endif %}
{% include "_codemirror.html" %}
{% endblock %}
{% block body_class %}query db-{{ database|to_css_class }}{% if canned_query %} query-{{ canned_query|to_css_class }}{% endif %}{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">home</a> /
<a href="{{ urls.database(database) }}">{{ database }}</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_color(database) }}">{{ metadata.title or database }}{% if canned_query and not metadata.title %}: {{ canned_query }}{% endif %}{% if private %} 🔒{% endif %}</h1>
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
<form class="sql" action="{{ urls.database(database) }}{% if canned_query %}/{{ canned_query }}{% endif %}" method="{% if canned_write %}post{% else %}get{% endif %}">
<h3>Custom SQL query{% if display_rows %} returning {% if truncated %}more than {% endif %}{{ "{:,}".format(display_rows|length) }} row{% if display_rows|length == 1 %}{% else %}s{% endif %}{% endif %} <span class="show-hide-sql">{% if hide_sql %}(<a href="{{ path_with_removed_args(request, {'_hide_sql': '1'}) }}">show</a>){% else %}(<a href="{{ path_with_added_args(request, {'_hide_sql': '1'}) }}">hide</a>){% endif %}</span></h3>
{% if not hide_sql %}
{% if editable and allow_execute_sql %}
<p><textarea id="sql-editor" name="sql">{% if query and query.sql %}{{ query.sql }}{% else %}select * from {{ tables[0].name|escape_sqlite }}{% endif %}</textarea></p>
{% else %}
<pre id="sql-query">{% if query %}{{ query.sql }}{% endif %}</pre>
{% endif %}
{% else %}
<input type="hidden" name="sql" value="{% if query and query.sql %}{{ query.sql }}{% else %}select * from {{ tables[0].name|escape_sqlite }}{% endif %}">
<input type="hidden" name="_hide_sql" value="1">
{% endif %}
{% if named_parameter_values %}
<h3>Query parameters</h3>
{% for name, value in named_parameter_values.items() %}
<p><label for="qp{{ loop.index }}">{{ name }}</label> <input type="text" id="qp{{ loop.index }}" name="{{ name }}" value="{{ value }}"></p>
{% endfor %}
{% endif %}
<p>
<button id="sql-format" type="button" hidden>Format SQL</button>
{% if canned_write %}<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">{% endif %}
<input type="submit" value="Run SQL">
{% if canned_query and edit_sql_url %}<a href="{{ edit_sql_url }}" class="canned-query-edit-sql">Edit SQL</a>{% endif %}
</p>
</form>
{% if display_rows %}
<p class="export-links">This data as {% for name, url in renderers.items() %}<a href="{{ url }}">{{ name }}</a>{{ ", " if not loop.last }}{% endfor %}, <a href="{{ url_csv }}">CSV</a></p>
<div class="table-wrapper"><table class="rows-and-columns">
<thead>
<tr>
{% for column in columns %}<th class="col-{{ column|to_css_class }}" scope="col">{{ column }}</th>{% endfor %}
</tr>
</thead>
<tbody>
{% for row in display_rows %}
<tr>
{% for column, td in zip(columns, row) %}
<td class="col-{{ column|to_css_class }}">{{ td }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table></div>
{% else %}
{% if not canned_write %}
<p class="zero-results">0 results</p>
{% endif %}
{% endif %}
{% include "_codemirror_foot.html" %}
{% endblock %}
+49
View File
@@ -0,0 +1,49 @@
{% extends "base.html" %}
{% block title %}{{ database }}: {{ table }}{% endblock %}
{% block extra_head %}
{{ super() }}
<style>
@media only screen and (max-width: 576px) {
{% for column in columns %}
.rows-and-columns td:nth-of-type({{ loop.index }}):before { content: "{{ column|escape_css_string }}"; }
{% endfor %}
}
</style>
{% endblock %}
{% block body_class %}row db-{{ database|to_css_class }} table-{{ table|to_css_class }}{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">accueil</a> /
<a href="{{ urls.database(database) }}">{{ database }}</a> /
<a href="{{ urls.table(database, table) }}">{{ table }}</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_color(database) }}">{{ table }}: {{ ', '.join(primary_key_values) }}</h1>
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
<p>Télcharger ces données au format {% for name, url in renderers.items() %}<a href="{{ url }}">{{ name }}</a>{{ ", " if not loop.last }}{% endfor %}</p>
{% include custom_table_templates %}
{% if foreign_key_tables %}
<h2>Liens depuis d'autres tables</h2>
<ul>
{% for other in foreign_key_tables %}
<li>
<a href="{{ urls.table(database, other.other_table) }}?{{ other.other_column }}={{ ', '.join(primary_key_values) }}">
{{ "{:,}".format(other.count) }} row{% if other.count == 1 %}{% else %}s{% endif %}</a>
from {{ other.other_column }} in {{ other.other_table }}
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
+19
View File
@@ -0,0 +1,19 @@
{% extends "base.html" %}
{% block title %}{{ filename }}{% endblock %}
{% block body_class %}show-json{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">home</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<h1>{{ filename }}</h1>
<pre>{{ data_json }}</pre>
{% endblock %}
+216
View File
@@ -0,0 +1,216 @@
{% extends "base.html" %}
{% block title %}{{ database }}: {{ table }}: {% if filtered_table_rows_count or filtered_table_rows_count == 0 %}{{ "{:,}".format(filtered_table_rows_count) }} ligne{% if filtered_table_rows_count == 1 %}{% else %}s{% endif %}{% endif %}
{% if human_description_en %}où {{ human_description_en }}{% endif %}{% endblock %}
{% block extra_head %}
{{ super() }}
<script src="{{ urls.static('table.js') }}" defer></script>
<style>
@media only screen and (max-width: 576px) {
{% for column in display_columns -%}
.rows-and-columns td:nth-of-type({{ loop.index }}):before { content: "{{ column.name|escape_css_string }}"; }
{% endfor %}}
</style>
{% endblock %}
{% block body_class %}table db-{{ database|to_css_class }} table-{{ table|to_css_class }}{% endblock %}
{% block nav %}
<p class="crumbs">
<a href="{{ urls.instance() }}">accueil</a> /
<a href="{{ urls.database(database) }}">{{ database }}</a>
</p>
{{ super() }}
{% endblock %}
{% block content %}
<div class="page-header" style="border-color: #{{ database_color(database) }}">
<h1>{{ metadata.title or table }}{% if is_view %} (view){% endif %}{% if private %} 🔒{% endif %}</h1>
{% set links = table_actions() %}{% if links %}
<details class="actions-menu-links">
<summary><svg aria-labelledby="actions-menu-links-title" role="img"
style="color: #666" xmlns="http://www.w3.org/2000/svg"
width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<title id="actions-menu-links-title">Actions</title>
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg></summary>
<div class="dropdown-menu">
{% if links %}
<ul>
{% for link in links %}
<li><a href="{{ link.href }}">{{ link.label }}</a></li>
{% endfor %}
</ul>
{% endif %}
</div>
</details>{% endif %}
</div>
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
{% if filtered_table_rows_count or human_description_en %}
<h4>{% if filtered_table_rows_count or filtered_table_rows_count == 0 %}{{ "{:,}".format(filtered_table_rows_count) }} ligne{% if filtered_table_rows_count == 1 %}{% else %}s{% endif %}{% endif %}
{% if human_description_en %}{{ human_description_en }}{% endif %}
</h4>
{% endif %}
<form class="filters" action="{{ urls.table(database, table) }}" method="get">
{% if supports_search %}
<div class="search-row"><label for="_search">Rechercher :</label><input id="_search" type="search" name="_search" value="{{ search }}"></div>
{% endif %}
{% for column, lookup, value in filters.selections() %}
<div class="filter-row">
<div class="select-wrapper">
<select name="_filter_column_{{ loop.index }}">
<option value="">- supprimer le filtre -</option>
{% for c in filter_columns %}
<option{% if c == column %} selected{% endif %}>{{ c }}</option>
{% endfor %}
</select>
</div><div class="select-wrapper filter-op">
<select name="_filter_op_{{ loop.index }}">
{% for key, display, no_argument in filters.lookups() %}
<option value="{{ key }}{% if no_argument %}__1{% endif %}"{% if key == lookup %} selected{% endif %}>{{ display }}</option>
{% endfor %}
</select>
</div><input type="text" name="_filter_value_{{ loop.index }}" class="filter-value" value="{{ value }}">
</div>
{% endfor %}
<div class="filter-row">
<div class="select-wrapper">
<select name="_filter_column">
<option value="">- colonne -</option>
{% for column in filter_columns %}
<option>{{ column }}</option>
{% endfor %}
</select>
</div><div class="select-wrapper filter-op">
<select name="_filter_op">
{% for key, display, no_argument in filters.lookups() %}
<option value="{{ key }}{% if no_argument %}__1{% endif %}"{% if key == lookup %} selected{% endif %}>{{ display }}</option>
{% endfor %}
</select>
</div><input type="text" name="_filter_value" class="filter-value">
</div>
<div class="filter-row">
{% if is_sortable %}
<div class="select-wrapper small-screen-only">
<select name="_sort" id="sort_by">
<option value="">Trier...</option>
{% for column in display_columns %}
{% if column.sortable %}
<option value="{{ column.name }}"{% if column.name == sort or column.name == sort_desc %} selected{% endif %}>Trier par {{ column.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<label class="sort_by_desc small-screen-only"><input type="checkbox" name="_sort_by_desc"{% if sort_desc %} checked{% endif %}> décroissant</label>
{% endif %}
{% for key, value in form_hidden_args %}
<input type="hidden" name="{{ key }}" value="{{ value }}">
{% endfor %}
<input type="submit" value="Filtrer">
</div>
</form>
{% if extra_wheres_for_ui %}
<div class="extra-wheres">
<h3>{{ extra_wheres_for_ui|length }} extra where clause{% if extra_wheres_for_ui|length != 1 %}s{% endif %}</h3>
<ul>
{% for extra_where in extra_wheres_for_ui %}
<li><code>{{ extra_where.text }}</code> [<a href="{{ extra_where.remove_url }}">supprimer</a>]</li>
{% endfor %}
</ul>
</div>
{% endif %}
<p class="export-links">Télécharger ces données au format <a href="{{ url_csv | replace('.csv','.xlsx')}}&_dl=1">Excel</a> ou <a href="{{ url_csv }}&_dl=1">CSV</a>{% if filtered_table_rows_count > 50000 %} (50 000 premières lignes){% endif %}.
{% if query.sql and allow_execute_sql %}
- <a class="not-underlined" title="{{ query.sql }}" href="{{ urls.database(database) }}?{{ {'sql': query.sql}|urlencode|safe }}{% if query.params %}&amp;{{ query.params|urlencode|safe }}{% endif %}">&#x270e; <span class="underlined">Voir et éditer le SQL</span></a>
{% endif %}
</p>
<!-- {% if suggested_facets %}
<p class="suggested-facets">
Facettes suggérées : {% for facet in suggested_facets %}<a href="{{ facet.toggle_url }}#facet-{{ facet.name|to_css_class }}">{{ facet.name }}</a>{% if facet.type %} ({{ facet.type }}){% endif %}{% if not loop.last %}, {% endif %}{% endfor %}
</p>
{% endif %}
{% if facets_timed_out %}
<p class="facets-timed-out">Ces facettes ont pris trop temps à être générées : {{ ", ".join(facets_timed_out) }}</p>
{% endif %}
{% if facet_results %}
<div class="facet-results">
{% for facet_info in sorted_facet_results %}
<div class="facet-info facet-{{ database|to_css_class }}-{{ table|to_css_class }}-{{ facet_info.name|to_css_class }}" id="facet-{{ facet_info.name|to_css_class }}">
<p class="facet-info-name">
<strong>{{ facet_info.name }}{% if facet_info.type != "column" %} ({{ facet_info.type }}){% endif %}</strong>
{% if facet_info.hideable %}
<a href="{{ facet_info.toggle_url }}" class="cross">&#x2716;</a>
{% endif %}
</p>
<ul class="tight-bullets">
{% for facet_value in facet_info.results %}
{% if not facet_value.selected %}
<li><a href="{{ facet_value.toggle_url }}">{{ (facet_value.label | string()) or "-" }}</a> {{ "{:,}".format(facet_value.count) }}</li>
{% else %}
<li>{{ facet_value.label or "-" }} &middot; {{ "{:,}".format(facet_value.count) }} <a href="{{ facet_value.toggle_url }}" class="cross">&#x2716;</a></li>
{% endif %}
{% endfor %}
{% if facet_info.truncated %}
<li>...</li>
{% endif %}
</ul>
</div>
{% endfor %}
</div>
{% endif %}-->
{% include custom_table_templates %}
{% if next_url %}
<p><a href="{{ next_url }}">Page suivante</a></p>
{% endif %}
<!-- {% if display_rows %}
<div id="export" class="advanced-export">
<h3>Export avancé</h3>
<p>JSON shape:
<a href="{{ renderers['json'] }}">par défaut</a>,
<a href="{{ append_querystring(renderers['json'], '_shape=array') }}">array</a>,
<a href="{{ append_querystring(renderers['json'], '_shape=array&_nl=on') }}">newline-delimited</a>{% if primary_keys %},
<a href="{{ append_querystring(renderers['json'], '_shape=object') }}">objet</a>
{% endif %}
</p>
<form action="{{ url_csv_path }}" method="get">
<p>
Options CSV :
<label><input type="checkbox" name="_dl"> télécharger le fichier</label>
{% if expandable_columns %}<label><input type="checkbox" name="_labels" checked> récupérer les libellés</label>{% endif %}
{% if next_url and config.allow_csv_stream %}<label><input type="checkbox" name="_stream"> stream de lignes</label>{% endif %}
<input type="submit" value="Exporter le CSV">
{% for key, value in url_csv_hidden_args %}
<input type="hidden" name="{{ key }}" value="{{ value }}">
{% endfor %}
</p>
</form>
</div>
{% endif %} -->
<!-- {% if table_definition %}
<pre class="wrapped-sql">{{ table_definition }}</pre>
{% endif %}
{% if view_definition %}
<pre class="wrapped-sql">{{ view_definition }}</pre>
{% endif %} -->
{% endblock %}