From 82999ef056e0c65a4c9dcd3c84ca35af191b2a28 Mon Sep 17 00:00:00 2001 From: Colin Maudry Date: Thu, 25 Jun 2026 01:19:36 +0200 Subject: [PATCH] Redesign de a-propos --- src/assets/css/style.css | 4 + src/figures.py | 2 +- src/pages/_apropos_shell.py | 67 ++++++++ src/pages/a-propos.py | 221 +++---------------------- src/pages/a_propos/__init__.py | 0 src/pages/a_propos/contact.py | 29 ++++ src/pages/a_propos/contribuer.py | 28 ++++ src/pages/a_propos/donnees_brutes.py | 28 ++++ src/pages/a_propos/explorer.py | 32 ++++ src/pages/a_propos/mentions_legales.py | 61 +++++++ src/pages/a_propos/presentation.py | 35 ++++ src/pages/a_propos/qualite.py | 33 ++++ src/pages/a_propos/sources.py | 25 +++ 13 files changed, 365 insertions(+), 200 deletions(-) create mode 100644 src/pages/_apropos_shell.py create mode 100644 src/pages/a_propos/__init__.py create mode 100644 src/pages/a_propos/contact.py create mode 100644 src/pages/a_propos/contribuer.py create mode 100644 src/pages/a_propos/donnees_brutes.py create mode 100644 src/pages/a_propos/explorer.py create mode 100644 src/pages/a_propos/mentions_legales.py create mode 100644 src/pages/a_propos/presentation.py create mode 100644 src/pages/a_propos/qualite.py create mode 100644 src/pages/a_propos/sources.py diff --git a/src/assets/css/style.css b/src/assets/css/style.css index 6fe3c2f..78f1466 100644 --- a/src/assets/css/style.css +++ b/src/assets/css/style.css @@ -141,6 +141,10 @@ p.version > a { border-radius: 0; } +.account-nav .nav-link:hover { + background-color: rgba(255, 240, 240, 0.9); +} + .account-nav .nav-link.active { color: #d9230f; font-weight: 600; diff --git a/src/figures.py b/src/figures.py index 565001f..92bc86b 100644 --- a/src/figures.py +++ b/src/figures.py @@ -161,7 +161,7 @@ def get_sources_tables(source_path) -> html.Div: style_cell_conditional=[ { "if": {"column_id": ["nom", "organisation"]}, - "minWidth": "350px", + "minWidth": "220px", "textAlign": "left", "overflow": "hidden", "lineHeight": "14px", diff --git a/src/pages/_apropos_shell.py b/src/pages/_apropos_shell.py new file mode 100644 index 0000000..48fd15d --- /dev/null +++ b/src/pages/_apropos_shell.py @@ -0,0 +1,67 @@ +import dash_bootstrap_components as dbc +from dash import Input, Output, State, callback, html + +SECTIONS = [ + {"key": "presentation", "label": "Présentation", "href": "/a-propos/presentation"}, + { + "key": "donnees-brutes", + "label": "Données brutes", + "href": "/a-propos/donnees-brutes", + }, + {"key": "contact", "label": "Contact", "href": "/a-propos/contact"}, + {"key": "contribuer", "label": "Contribuer", "href": "/a-propos/contribuer"}, + {"key": "explorer", "label": "Explorer le projet", "href": "/a-propos/explorer"}, + {"key": "qualite", "label": "Qualité des données", "href": "/a-propos/qualite"}, + {"key": "sources", "label": "Sources de données", "href": "/a-propos/sources"}, + { + "key": "mentions-legales", + "label": "Mentions légales", + "href": "/a-propos/mentions-legales", + }, +] + + +def _nav(active: str): + links = [ + dbc.NavLink(s["label"], href=s["href"], active=(s["key"] == active)) + for s in SECTIONS + ] + return dbc.Nav(links, vertical=True, class_name="account-nav") + + +def apropos_shell(active: str, contenu): + sidebar = dbc.Col( + html.Div([html.H5("À propos", className="mb-3"), _nav(active)]), + md=3, + className="d-none d-md-block", + ) + mobile = html.Div( + [ + dbc.Button( + "☰ Sections", + id="apropos-offcanvas-open", + color="secondary", + outline=True, + className="mb-3", + ), + dbc.Offcanvas( + _nav(active), + id="apropos-offcanvas", + title="À propos", + is_open=False, + ), + ], + className="d-md-none", + ) + content = dbc.Col([mobile, contenu], md=9) + return dbc.Container(dbc.Row([sidebar, content]), className="py-4") + + +@callback( + Output("apropos-offcanvas", "is_open"), + Input("apropos-offcanvas-open", "n_clicks"), + State("apropos-offcanvas", "is_open"), + prevent_initial_call=True, +) +def _toggle_apropos_offcanvas(_n, is_open): + return not is_open diff --git a/src/pages/a-propos.py b/src/pages/a-propos.py index 2e69d49..0610df9 100644 --- a/src/pages/a-propos.py +++ b/src/pages/a-propos.py @@ -1,12 +1,7 @@ -import os +from dash import Input, Output, callback, dcc, html, register_page -from dash import dcc, html, register_page - -from src.figures import get_sources_tables from src.utils.seo import META_CONTENT -NAME = "À propos" - register_page( __name__, path="/a-propos", @@ -17,201 +12,29 @@ register_page( order=5, ) -layout = html.Div( - className="container", - children=[ - html.H2(NAME), - html.Div( - className="a-propos-container", - children=[ - # Main Content Column - html.Div( - className="a-propos-content", - children=[ - dcc.Markdown( - """Outil d'exploration libre et gratuit des données de marchés publics, développé par Colin Maudry. +_HASH_MAP = { + "#donnees-brutes": "/a-propos/donnees-brutes", + "#api-privee": "/a-propos/api-privee", + "#contact": "/a-propos/contact", + "#contribuer": "/a-propos/contribuer", + "#explorer": "/a-propos/explorer", + "#qualite-exhausitivite": "/a-propos/qualite", + "#sources": "/a-propos/sources", + "#mentions-legales": "/a-propos/mentions-legales", + "#publication": "/a-propos/mentions-legales", + "#audience": "/a-propos/mentions-legales", + "#attributions": "/a-propos/mentions-legales", + "#liste_marches": "/a-propos/mentions-legales", +} -Ce projet vise à démocratiser l'accès aux données des marchés publics et à un outil performant et gratuit. Si vous le trouvez utile -j'aimerais beaucoup échanger avec vous pour comprendre vos cas d'usages et vos besoins. Cet outil ne peut rester performant que si je comprends les problèmes qu'il peut aider à résoudre. Ce projet ne peut rester gratuit que grâce au financement du développement de nouvelles fonctionnalités. -En effet, le potentiel des données d'attribution de marchés et des données qui peuvent les enrichir est très loin d'être exploité par -les fonctionnalités actuelles de decp.info. Il est ainsi possible de rajouter +def layout(**_): + return html.Div(dcc.Location(id="apropos-redirect-loc")) -- de nombreuses visualisations de données (cartes, graphiques, tableaux) sur des thématiques variées (vivacité de la concurrence, secteurs d'activité, insertion par l'activité économique (IAE), distance acheteur-titulaire...) -- des alertes par email si des marchés correspondant à certains critères -- ...et toutes les fonctionnalités auxquelles vous pourrez penser -""" - ), - html.H4("Consommer les données brutes", id="donnees-brutes"), - dcc.Markdown( - """ -Vous pouvez consommer les données qui alimentent decp.info -- en les téléchargeant [sur data.gouv.fr](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire) (Parquet, CSV), pensez à lire la description du jeu de données -- en interrogeant l'[API REST ouverte](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire#user-content-api-rest) -""" - ), - html.H4("API privée", id="api-privee"), - dcc.Markdown( - """ -Une API HTTP est disponible pour accéder aux mêmes données par programme. -Documentation interactive : [Swagger UI](/api/v1/swagger). - -L'accès se fait sur token. Pour en obtenir un, contactez -[colin@maudry.com](mailto:colin@maudry.com). -""" - ), - html.H4("Contact", id="contact"), - dcc.Markdown( - """ -- Email : [colin@colmo.tech](mailto:colin@colmo.tech) -- Bluesky : [@col1m.bsky.social](https://bsky.app/profile/col1m.bsky.social) -- Mastodon : [col1m@mamot.fr](https://mamot.fr/@col1m) -- LinkedIn : [colinmaudry](https://www.linkedin.com/in/colinmaudry/) -""" - ), - html.H4("Pour contribuer", id="contribuer"), - dcc.Markdown( - """ -- via l'achat d'une prestation de service (devis, prestation, facture), vous pouvez financer le développement de [fonctionnalités prévues](https://github.com/ColinMaudry/decp.info/issues), ou d'autres ! -- ma société accepte aussi les dons (pas de réduction d'impôt possible) -- écrivez-moi et on discute ! -""" - ), - html.H4("Pour explorer le projet", id="explorer"), - dcc.Markdown( - """ -- ✉️ [inscription à la liste de diffusion](https://6254d9a3.sibforms.com/serve/MUIFAEonUVkoSVrdgey18CTgLyI16xw4yeu-M-YOUzhWE_AgfQfbgkyT7GvA_RYLro9MfuRqkzQxSvu7-uzbMSv2a2ZQPsliM7wtiiqIL8kR2zOvl6m11fb5qjcOxMAYsLiY_YBi3P7NY95CTJ8vRY4CpsDclF2iLooOElKkTgIgi5nePe7zAIrgiYM5v2EuALlGJZMEG9vBP-Cu) (annonces des mises à jour et évènements, maximum une fois par mois) -- 💾 [données consolidées en Open Data](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire/) -- 🗞️ [mon blog](https://colin.maudry.com) -- 📔 [wiki du projet](https://github.com/ColinMaudry/decp-processing/wiki) -- 🚰 code source - - [de decp.info](https://github.com/ColinMaudry/decp.info) - - [du traitement des données](https://github.com/ColinMaudry/decp-processing) -""" - ), - html.H4( - "Qualité et exhaustivité des données", - id="qualite-exhausitivite", - ), - dcc.Markdown( - """Les données visibles sur ce site proviennent exclusivement de la publication de données ouvertes par les acheteurs publics ou en leur nom, régie par [l'arrêté du 22 décembre 2022](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000046850496). Leur qualité est donc principalement liée à la qualité de leur saisie par les agents publics, parfois peu aidé·es par la qualité des outils à leur disposition. Je pense que l'analyse de marchés individuels et le comptage de marchés sur des critères autres que financiers sont plutôt fiables. En revanche, certains montants de marché estimés à des valeurs farfelues ([1 euro](https://decp.info/marches/432766947000192025S01301), [1 milliard](https://decp.info/marches/2459004280001320210000000271)) faussent les calculs par aggrégation (sommes, moyennes, médianes) et donc la production de statistiques financières fiables. Acheteurs, acheteuses : s'il vous plaît, essayez d'estimer les montants des marchés publics attribués de manière plus précise. - -Quant à l'exhaustivité, je consolide toutes les sources de données exploitables que j'ai pu identifier (voir [ci-dessous](/bin.usr-is-merged/)). Je tiens à souligner la belle continuité de la publication par la DGFiP des données des marchés publics remontées via le [protocole PES](https://www.collectivites-locales.gouv.fr/finances-locales/le-protocole-dechange-standard-pes). Merci à leurs équipes.""" - ), - html.H4("Sources de données ", id="sources"), - get_sources_tables(os.getenv("SOURCE_STATS_CSV_PATH")), - html.H4("Mentions légales", id="mentions-legales"), - html.H5("Publication", id="publication"), - dcc.Markdown( - """ -Site Web développé et édité par [SAS Colmo](https://annuaire-entreprises.data.gouv.fr/entreprise/colmo-989393350), 989 393 350 RCS Rennes au capital de 3 000 euros. - -Siège social : 1 carrefour Jouaust, 35000 Rennes - -Hébergement : serveur situé en France et administré par Scaleway, 8 rue de la Ville l’Evêque, 75008 Paris -""" - ), - html.H5("Suivi d'audience", id="audience"), - dcc.Markdown( - """ -Ce site dépose un petit fichier texte (un « cookie ») sur votre ordinateur lorsque vous le consultez ([Wikipédia](https://fr.wikipedia.org/wiki/Cookie_(informatique))). Cela me permet de mesurer le nombre de visites, de distinguer les nouveaux visiteurs des utilisateurs réguliers et ainsi de communiquer sur l'impact de decp.info. - -**Ce site n’affiche pas de bannière de consentement aux cookies, pourquoi ?** - -C’est vrai, vous n’avez pas eu à cliquer sur un bloc qui recouvre la moitié de la page pour dire que vous êtes d’accord avec le dépôt de cookies. - -Rien d’exceptionnel, je respecte simplement la loi, qui dit que certains outils de suivi d’audience, correctement configurés pour respecter la vie privée, sont exemptés d’autorisation préalable. - -J’utilise pour cela [Matomo](https://matomo.org/), un outil [libre](https://matomo.org/free-software/), paramétré pour être en conformité avec [la recommandation « Cookies »](https://www.cnil.fr/fr/solutions-pour-les-cookies-de-mesure-daudience) de la CNIL. Cela signifie que votre adresse IP, par exemple, est anonymisée avant d’être enregistrée. Il m’est donc impossible d’associer vos visites sur ce site à votre personne. - -J'enregistre également les données suivantes, de manière anonyme, afin de mieux comprendre comment vous utilisez le site et l'améliorer : - -- recherches sur la page d'accueil -- filtres appliqués aux données -""" - ), - html.H5("Attributions", id="attributions"), - dcc.Markdown(""" - Les polices de caractères sont distribuées par [Bunny fonts](https://fonts.bunny.net), une alternative européenne et qualitative à Google Fonts. - - - la police de caractère [Inter](https://fonts.bunny.net/family/inter), principale police de ce site, a été créée par The Inter Project Authors ([source](https://github.com/rsms/inter)) - - la police de caractère [Fira Code](https://fonts.bunny.net/family/fira-code), la police à largeure fixe, a été créée par The Fira Code Project Authors (https://github.com/tonsky/FiraCode) - """), - html.H4( - "Liste des marchés par département", id="liste_marches" - ), - dcc.Markdown( - """ - - [Marchés par département](/departements) - """ - ), - ], - ), - # Table of Contents Column - html.Div( - className="a-propos-toc", - children=[ - html.Div( - [ - html.A( - "Consommer les données brutes", - href="#donnees-brutes", - className="toc-link", - ), - html.A( - "API privée", - href="#api-privee", - className="toc-link", - ), - html.A( - "Contact", href="#contact", className="toc-link" - ), - html.A( - "Pour contribuer", - href="#contribuer", - className="toc-link", - ), - html.A( - "Pour explorer le projet", - href="#explorer", - className="toc-link", - ), - html.A( - "Qualité et exhaustivité des données", - href="#qualite-exhausitivite", - className="toc-link", - ), - html.A( - "Sources de données", - href="#sources", - className="toc-link", - ), - html.A( - "Mentions légales", - href="#mentions-legales", - className="toc-link", - ), - html.A( - "Publication", - href="#publication", - className="toc-link toc-level-2", - ), - html.A( - "Suivi d'audience", - href="#audience", - className="toc-link toc-level-2", - ), - html.A( - "Attributions", - href="#attributions", - className="toc-link toc-level-2", - ), - ] - ), - ], - ), - ], - ), - ], +@callback( + Output("apropos-redirect-loc", "href"), + Input("apropos-redirect-loc", "hash"), ) +def _redirect(hash_val): + return _HASH_MAP.get(hash_val or "", "/a-propos/presentation") diff --git a/src/pages/a_propos/__init__.py b/src/pages/a_propos/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/a_propos/contact.py b/src/pages/a_propos/contact.py new file mode 100644 index 0000000..2da12a8 --- /dev/null +++ b/src/pages/a_propos/contact.py @@ -0,0 +1,29 @@ +from dash import dcc, html, register_page + +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/contact", + title="Contact | À propos | decp.info", + description="Contactez Colin Maudry, développeur de decp.info.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Contact"), + dcc.Markdown( + """ +- Email : [colin@colmo.tech](mailto:colin@colmo.tech) +- Bluesky : [@col1m.bsky.social](https://bsky.app/profile/col1m.bsky.social) +- Mastodon : [col1m@mamot.fr](https://mamot.fr/@col1m) +- LinkedIn : [colinmaudry](https://www.linkedin.com/in/colinmaudry/) +""" + ), + ] + ) + return apropos_shell("contact", contenu) diff --git a/src/pages/a_propos/contribuer.py b/src/pages/a_propos/contribuer.py new file mode 100644 index 0000000..55c564b --- /dev/null +++ b/src/pages/a_propos/contribuer.py @@ -0,0 +1,28 @@ +from dash import dcc, html, register_page + +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/contribuer", + title="Contribuer | À propos | decp.info", + description="Comment contribuer au projet decp.info.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Pour contribuer"), + dcc.Markdown( + """ +- via l'achat d'une prestation de service (devis, prestation, facture), vous pouvez financer le développement de [fonctionnalités prévues](https://github.com/ColinMaudry/decp.info/issues), ou d'autres ! +- ma société accepte aussi les dons (pas de réduction d'impôt possible) +- écrivez-moi et on discute ! +""" + ), + ] + ) + return apropos_shell("contribuer", contenu) diff --git a/src/pages/a_propos/donnees_brutes.py b/src/pages/a_propos/donnees_brutes.py new file mode 100644 index 0000000..cfa2e2e --- /dev/null +++ b/src/pages/a_propos/donnees_brutes.py @@ -0,0 +1,28 @@ +from dash import dcc, html, register_page + +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/donnees-brutes", + title="Données brutes | À propos | decp.info", + description="Téléchargez ou interrogez les données brutes qui alimentent decp.info.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Consommer les données brutes"), + dcc.Markdown( + """ +Vous pouvez consommer les données qui alimentent decp.info en les téléchargeant [sur data.gouv.fr](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire) (Parquet, CSV), pensez à lire la description du jeu de données + +Une API REST tabulaire (JSON) est également disponible par abonnement mensuel pour accéder aux mêmes données et alimenter une application. +Documentation interactive : [Swagger UI](/api/v1/swagger). Si cela vous intéresse, [contactez-moi](/a-propos/contact).""" + ), + ] + ) + return apropos_shell("donnees-brutes", contenu) diff --git a/src/pages/a_propos/explorer.py b/src/pages/a_propos/explorer.py new file mode 100644 index 0000000..923f29b --- /dev/null +++ b/src/pages/a_propos/explorer.py @@ -0,0 +1,32 @@ +from dash import dcc, html, register_page + +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/explorer", + title="Explorer le projet | À propos | decp.info", + description="Ressources pour explorer le projet decp.info : données, code source, blog.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Pour explorer le projet"), + dcc.Markdown( + """ +- ✉️ [inscription à la liste de diffusion](https://6254d9a3.sibforms.com/serve/MUIFAEonUVkoSVrdgey18CTgLyI16xw4yeu-M-YOUzhWE_AgfQfbgkyT7GvA_RYLro9MfuRqkzQxSvu7-uzbMSv2a2ZQPsliM7wtiiqIL8kR2zOvl6m11fb5qjcOxMAYsLiY_YBi3P7NY95CTJ8vRY4CpsDclF2iLooOElKkTgIgi5nePe7zAIrgiYM5v2EuALlGJZMEG9vBP-Cu) (annonces des mises à jour et évènements, maximum une fois par mois) +- 💾 [données consolidées en Open Data](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire/) +- 🗞️ [mon blog](https://colin.maudry.com) +- 📔 [wiki du projet](https://github.com/ColinMaudry/decp-processing/wiki) +- 🚰 code source + - [de decp.info](https://github.com/ColinMaudry/decp.info) + - [du traitement des données](https://github.com/ColinMaudry/decp-processing) +""" + ), + ] + ) + return apropos_shell("explorer", contenu) diff --git a/src/pages/a_propos/mentions_legales.py b/src/pages/a_propos/mentions_legales.py new file mode 100644 index 0000000..151662e --- /dev/null +++ b/src/pages/a_propos/mentions_legales.py @@ -0,0 +1,61 @@ +from dash import dcc, html, register_page + +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/mentions-legales", + title="Mentions légales | À propos | decp.info", + description="Mentions légales de decp.info : éditeur, hébergement, suivi d'audience, attributions.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Mentions légales"), + html.H4("Publication", id="publication"), + dcc.Markdown( + """ +Site Web développé et édité par [SAS Colmo](https://annuaire-entreprises.data.gouv.fr/entreprise/colmo-989393350), 989 393 350 RCS Rennes au capital de 3 000 euros. + +Siège social : 1 carrefour Jouaust, 35000 Rennes + +Hébergement : serveur situé en France et administré par Scaleway, 8 rue de la Ville l'Evêque, 75008 Paris +""" + ), + html.H4("Suivi d'audience", id="audience"), + dcc.Markdown( + """ +Ce site dépose un petit fichier texte (un « cookie ») sur votre ordinateur lorsque vous le consultez ([Wikipédia](https://fr.wikipedia.org/wiki/Cookie_(informatique))). Cela me permet de mesurer le nombre de visites, de distinguer les nouveaux visiteurs des utilisateurs réguliers et ainsi de communiquer sur l'impact de decp.info. + +**Ce site n'affiche pas de bannière de consentement aux cookies, pourquoi ?** + +C'est vrai, vous n'avez pas eu à cliquer sur un bloc qui recouvre la moitié de la page pour dire que vous êtes d'accord avec le dépôt de cookies. + +Rien d'exceptionnel, je respecte simplement la loi, qui dit que certains outils de suivi d'audience, correctement configurés pour respecter la vie privée, sont exemptés d'autorisation préalable. + +J'utilise pour cela [Matomo](https://matomo.org/), un outil [libre](https://matomo.org/free-software/), paramétré pour être en conformité avec [la recommandation « Cookies »](https://www.cnil.fr/fr/solutions-pour-les-cookies-de-mesure-daudience) de la CNIL. Cela signifie que votre adresse IP, par exemple, est anonymisée avant d'être enregistrée. Il m'est donc impossible d'associer vos visites sur ce site à votre personne. + +J'enregistre également les données suivantes, de manière anonyme, afin de mieux comprendre comment vous utilisez le site et l'améliorer : + +- recherches sur la page d'accueil +- filtres appliqués aux données +""" + ), + html.H4("Attributions", id="attributions"), + dcc.Markdown( + """ +Les polices de caractères sont distribuées par [Bunny fonts](https://fonts.bunny.net), une alternative européenne et qualitative à Google Fonts. + +- la police de caractère [Inter](https://fonts.bunny.net/family/inter), principale police de ce site, a été créée par The Inter Project Authors ([source](https://github.com/rsms/inter)) +- la police de caractère [Fira Code](https://fonts.bunny.net/family/fira-code), la police à largeure fixe, a été créée par The Fira Code Project Authors (https://github.com/tonsky/FiraCode) +""" + ), + html.H4("Marchés par département", id="liste_marches"), + dcc.Markdown("- [Marchés par département](/departements)"), + ] + ) + return apropos_shell("mentions-legales", contenu) diff --git a/src/pages/a_propos/presentation.py b/src/pages/a_propos/presentation.py new file mode 100644 index 0000000..03914e6 --- /dev/null +++ b/src/pages/a_propos/presentation.py @@ -0,0 +1,35 @@ +from dash import dcc, html, register_page + +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/presentation", + title="Présentation | À propos | decp.info", + description="En savoir plus sur decp.info, l'outil d'exploration des données essentielles de la commande publique.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Présentation"), + dcc.Markdown( + """Outil d'exploration libre et gratuit des données de marchés publics, développé par Colin Maudry. + +Ce projet vise à démocratiser l'accès aux données des marchés publics et à un outil performant et gratuit. Si vous le trouvez utile +j'aimerais beaucoup échanger avec vous pour comprendre vos cas d'usages et vos besoins. Cet outil ne peut rester performant que si je comprends les problèmes qu'il peut aider à résoudre. Ce projet ne peut rester gratuit que grâce au financement du développement de nouvelles fonctionnalités. + +En effet, le potentiel des données d'attribution de marchés et des données qui peuvent les enrichir est très loin d'être exploité par +les fonctionnalités actuelles de decp.info. Il est ainsi possible de rajouter + +- de nombreuses visualisations de données (cartes, graphiques, tableaux) sur des thématiques variées (vivacité de la concurrence, secteurs d'activité, insertion par l'activité économique (IAE), distance acheteur-titulaire...) +- des alertes par email si des marchés correspondant à certains critères +- ...et toutes les fonctionnalités auxquelles vous pourrez penser +""" + ), + ] + ) + return apropos_shell("presentation", contenu) diff --git a/src/pages/a_propos/qualite.py b/src/pages/a_propos/qualite.py new file mode 100644 index 0000000..2ee6ac7 --- /dev/null +++ b/src/pages/a_propos/qualite.py @@ -0,0 +1,33 @@ +from dash import dcc, html, register_page + +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/qualite", + title="Qualité des données | À propos | decp.info", + description="Informations sur la qualité et l'exhaustivité des données de marchés publics sur decp.info.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Qualité et exhaustivité des données"), + dcc.Markdown( + """Les données visibles sur ce site proviennent exclusivement de la publication de données + ouvertes par les acheteurs publics ou en leur nom, régie par + [l'arrêté du 22 décembre 2022](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000046850496). Leur + qualité est donc principalement liée à la qualité de leur saisie par les agents publics, parfois + peu aidé·es par la qualité des outils à leur disposition. + +Je pense que l'analyse de marchés +individuels et le comptage de marchés sur des critères autres que financiers sont plutôt fiables. En revanche, certains montants de marché estimés à des valeurs farfelues ([1 euro](https://decp.info/marches/432766947000192025S01301), [1 milliard](https://decp.info/marches/2459004280001320210000000271)) faussent les calculs par aggrégation (sommes, moyennes, médianes) et donc la production de statistiques financières fiables. Acheteurs, acheteuses : s'il vous plaît, essayez d'estimer les montants des marchés publics attribués de manière plus précise. + +Quant à l'exhaustivité, je consolide toutes les sources de données exploitables que j'ai pu identifier (voir [Sources de données](/a-propos/sources)). Je tiens à souligner la belle continuité de la publication par la DGFiP des données des marchés publics remontées via le [protocole PES](https://www.collectivites-locales.gouv.fr/finances-locales/le-protocole-dechange-standard-pes). Merci à leurs équipes.""" + ), + ] + ) + return apropos_shell("qualite", contenu) diff --git a/src/pages/a_propos/sources.py b/src/pages/a_propos/sources.py new file mode 100644 index 0000000..bcf58eb --- /dev/null +++ b/src/pages/a_propos/sources.py @@ -0,0 +1,25 @@ +import os + +from dash import html, register_page + +from src.figures import get_sources_tables +from src.pages._apropos_shell import apropos_shell +from src.utils.seo import META_CONTENT + +register_page( + __name__, + path="/a-propos/sources", + title="Sources de données | À propos | decp.info", + description="Sources de données utilisées par decp.info pour consolider les marchés publics français.", + image_url=META_CONTENT["image_url"], +) + + +def layout(**_): + contenu = html.Div( + [ + html.H2("Sources de données"), + get_sources_tables(os.getenv("SOURCE_STATS_CSV_PATH")), + ] + ) + return apropos_shell("sources", contenu)