2025-09-03 17:18:21 +02:00
{% extends 'base.html.twig' %}
{% block title %} Évolution des scores de décrépitude - Wiki OSM {% endblock %}
{% block body %}
<div class="container mt-4">
{% include 'admin/_wiki_navigation.html.twig' %}
<h1>Évolution des scores de décrépitude</h1>
<p class="lead">
Cette page montre l'évolution des scores de décrépitude des pages wiki OpenStreetMap en français par rapport aux versions anglaises.
<a href="https://forum.openstreetmap.fr/t/fabriquer-un-outil-de-qualite-pour-le-wiki-osm/36814">
Venez discuter QualiWiki sur le forum
</a>
</p>
{% if not json_exists %}
<div class="alert alert-warning">
<h4 class="alert-heading">Données manquantes</h4>
<p>Le fichier JSON contenant les données de décrépitude n'existe pas. Vous pouvez le générer en exécutant le script Python suivant :</p>
<pre class="bg-light p-3 rounded"><code>cd {{ app .request .server .get ( 'DOCUMENT_ROOT' ) | replace ( { '/public' : '' } ) }} /wiki_compare
python3 wiki_compare.py</code></pre>
<p>Ce script va analyser les pages wiki et générer les fichiers nécessaires, y compris le fichier <code>outdated_pages.json</code> et l'histogramme.</p>
</div>
{% else %}
{% if last_updated %}
<div class="alert alert-info">
<p>Dernière mise à jour des données : {{ last_updated | date ( 'd/m/Y H:i:s' ) }} </p>
</div>
{% endif %}
{% if histogram_exists %}
<div class="card mb-4">
<div class="card-header">
<h2>Histogramme des scores de décrépitude</h2>
</div>
<div class="card-body text-center">
<img src=" {{ asset ( 'wiki_compare/staleness_histogram.png' ) }} " alt="Histogramme des scores de décrépitude" class="img-fluid">
</div>
</div>
{% endif %}
<div class="card mb-4">
<div class="card-header">
<h2>Évolution des scores de décrépitude</h2>
</div>
<div class="card-body">
<p>Le score de décrépitude est calculé en prenant en compte plusieurs facteurs :</p>
<ul>
<li>La différence de date entre les versions anglaise et française (20%)</li>
<li>La différence de nombre de mots entre les versions (50%)</li>
<li>La différence de nombre de sections entre les versions (15%)</li>
<li>La différence de nombre de liens entre les versions (15%)</li>
</ul>
<p>Plus le score est élevé, plus la page française est considérée comme "décrépite" par rapport à sa version anglaise.</p>
<canvas id="decrepitudeChart" height="300"></canvas>
</div>
</div>
<div class="card mb-4">
<div class="card-header bg-warning text-dark">
<h2>Pages régulières avec les scores de décrépitude les plus élevés</h2>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Clé</th>
<th>Raison</th>
<th>Différence de mots</th>
<th>Différence de sections</th>
<th>Différence de liens</th>
<th>Score de décrépitude</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for page in regular_pages | slice ( 0 , 2 0 ) %}
<tr>
2025-09-05 15:58:26 +02:00
<td><strong> {{ page .title }} </strong></td>
<td>
{# {{ page.reason }}#}
</td>
2025-09-03 17:18:21 +02:00
<td class="text-center">
2025-09-08 10:20:51 +02:00
{% if page .word_diff is defined %}
{% if page .word_diff > 0 %}
<span class="badge bg-danger"> {{ page .word_diff }} </span>
{% elseif page .word_diff < 0 %}
<span class="badge bg-success"> {{ page .word_diff }} </span>
{% else %}
<span class="badge bg-secondary">0</span>
{% endif %}
2025-09-03 17:18:21 +02:00
{% else %}
2025-09-08 10:20:51 +02:00
<span class="badge bg-secondary">N/A</span>
2025-09-03 17:18:21 +02:00
{% endif %}
</td>
<td class="text-center">
2025-09-08 10:20:51 +02:00
{% if page .section_diff is defined %}
{% if page .section_diff > 0 %}
<span class="badge bg-danger"> {{ page .section_diff }} </span>
{% elseif page .section_diff < 0 %}
<span class="badge bg-success"> {{ page .section_diff }} </span>
{% else %}
<span class="badge bg-secondary">0</span>
{% endif %}
2025-09-03 17:18:21 +02:00
{% else %}
2025-09-08 10:20:51 +02:00
<span class="badge bg-secondary">N/A</span>
2025-09-03 17:18:21 +02:00
{% endif %}
</td>
<td class="text-center">
2025-09-08 10:20:51 +02:00
{% if page .link_diff is defined %}
{% if page .link_diff > 0 %}
<span class="badge bg-danger"> {{ page .link_diff }} </span>
{% elseif page .link_diff < 0 %}
<span class="badge bg-success"> {{ page .link_diff }} </span>
{% else %}
<span class="badge bg-secondary">0</span>
{% endif %}
2025-09-03 17:18:21 +02:00
{% else %}
2025-09-08 10:20:51 +02:00
<span class="badge bg-secondary">N/A</span>
2025-09-03 17:18:21 +02:00
{% endif %}
</td>
<td class="text-center">
2025-09-08 10:20:51 +02:00
{% if page .staleness_score is defined %}
<div class="progress" style="height: 20px;">
{% set score_class = page .staleness_score > 7 0 ? 'bg-danger' : ( page .staleness_score > 4 0 ? 'bg-warning' : 'bg-success' ) %}
<div class="progress-bar {{ score_class }} " role="progressbar"
style="width: {{ page .staleness_score }} %;"
aria-valuenow=" {{ page .staleness_score }} "
aria-valuemin="0"
aria-valuemax="100">
{{ page .staleness_score }}
</div>
2025-09-03 17:18:21 +02:00
</div>
2025-09-08 10:20:51 +02:00
{% else %}
<span class="badge bg-secondary">N/A</span>
{% endif %}
2025-09-03 17:18:21 +02:00
</td>
<td class="text-center">
<div class="btn-group" role="group">
2025-09-08 10:20:51 +02:00
{% if page .url is defined and page .url %}
<a href=" {{ page .url }} " target="_blank"
class="btn btn-sm btn-outline-primary" title="Version anglaise">
<i class="bi bi-translate"></i> EN
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-translate"></i> EN (URL manquante)
</button>
{% endif %}
2025-09-05 15:58:26 +02:00
{% if page .fr_page is defined and page .fr_page %}
{% if page .fr_page .url is defined %}
<a href=" {{ page .fr_page .url }} " target="_blank"
class="btn btn-sm btn-outline-info" title="Version française">
<i class="bi bi-translate"></i> FR
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-translate"></i> FR (URL manquante)
</button>
{% endif %}
{% if page .key is defined %}
<a href=" {{ path ( 'app_admin_wiki_compare' , { 'key' : page .key } ) }} "
class="btn btn-sm btn-outline-secondary"
title="Comparer les versions">
<i class="bi bi-arrows-angle-expand"></i> Comparer
</a>
{% elseif page .title is defined %}
<a href=" {{ path ( 'app_admin_wiki_compare' , { 'key' : page .title } ) }} "
class="btn btn-sm btn-outline-secondary"
title="Comparer les versions">
<i class="bi bi-arrows-angle-expand"></i> Comparer
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-arrows-angle-expand"></i> Comparer
</button>
{% endif %}
2025-09-03 17:18:21 +02:00
{% else %}
2025-09-05 15:58:26 +02:00
{% if page .key is defined %}
<a href=" {{ path ( 'app_admin_wiki_create_french' , { 'key' : page .key } ) }} "
class="btn btn-sm btn-success"
title="Créer une traduction française">
<i class="bi bi-plus-circle"></i> Traduire
</a>
{% elseif page .title is defined %}
<a href=" {{ path ( 'app_admin_wiki_create_french' , { 'key' : page .title } ) }} "
class="btn btn-sm btn-success"
title="Créer une traduction française">
<i class="bi bi-plus-circle"></i> Traduire
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-plus-circle"></i> Clé manquante
</button>
{% endif %}
2025-09-03 17:18:21 +02:00
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% if specific_pages | length > 0 %}
<div class="card mb-4">
<div class="card-header bg-primary text-white">
<h2>Pages spécifiques avec scores de décrépitude ( {{ specific_pages | length }} )</h2>
</div>
<div class="card-body">
<p>Ces pages wiki sont des pages spécifiques qui ont été sélectionnées pour une comparaison particulière.</p>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Titre</th>
<th>Raison</th>
<th>Score de décrépitude</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for page in specific_pages %}
<tr>
<td>
<div class="d-flex align-items-center">
2025-09-08 10:20:51 +02:00
{% if page .description_img_url is defined and page .description_img_url %}
2025-09-03 17:18:21 +02:00
<div class="me-3">
2025-09-08 10:20:51 +02:00
<img src=" {{ page .description_img_url }} "
2025-09-05 15:58:26 +02:00
alt=" {% if page .key is defined %} {{ page .key }} {% elseif page .title is defined %} {{ page .title }} {% else %} Image {% endif %} "
2025-09-03 17:18:21 +02:00
style="max-width: 80px; max-height: 60px; object-fit: contain;">
</div>
{% endif %}
<div>
2025-09-05 15:58:26 +02:00
<strong> {{ page .title }} </strong>
2025-09-03 17:18:21 +02:00
</div>
</div>
</td>
<td>
2025-09-05 15:58:26 +02:00
{# {{ page.reason }}#}
2025-09-03 17:18:21 +02:00
</td>
<td>
2025-09-08 10:20:51 +02:00
{% if page .staleness_score is defined %}
<div class="progress" style="height: 20px;">
{% set score_class = page .staleness_score > 7 0 ? 'bg-danger' : ( page .staleness_score > 4 0 ? 'bg-warning' : 'bg-success' ) %}
<div class="progress-bar {{ score_class }} " role="progressbar"
style="width: {{ page .staleness_score }} %;"
aria-valuenow=" {{ page .staleness_score }} "
aria-valuemin="0"
aria-valuemax="100">
{{ page .staleness_score }}
</div>
2025-09-03 17:18:21 +02:00
</div>
2025-09-08 10:20:51 +02:00
{% else %}
<span class="badge bg-secondary">N/A</span>
{% endif %}
2025-09-03 17:18:21 +02:00
</td>
<td class="text-center">
<div class="btn-group" role="group">
2025-09-08 10:20:51 +02:00
{% if page .url is defined and page .url %}
<a href=" {{ page .url }} " target="_blank"
class="btn btn-sm btn-outline-primary" title="Version anglaise">
<i class="bi bi-translate"></i> EN
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-translate"></i> EN (URL manquante)
</button>
{% endif %}
2025-09-05 15:58:26 +02:00
{% if page .fr_page is defined and page .fr_page %}
{% if page .fr_page .url is defined %}
<a href=" {{ page .fr_page .url }} " target="_blank"
class="btn btn-sm btn-outline-info" title="Version française">
<i class="bi bi-translate"></i> FR
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-translate"></i> FR (URL manquante)
</button>
{% endif %}
{% if page .key is defined %}
<a href=" {{ path ( 'app_admin_wiki_compare' , { 'key' : page .key } ) }} "
class="btn btn-sm btn-outline-secondary"
title="Comparer les versions">
<i class="bi bi-arrows-angle-expand"></i> Comparer
</a>
{% elseif page .title is defined %}
<a href=" {{ path ( 'app_admin_wiki_compare' , { 'key' : page .title } ) }} "
class="btn btn-sm btn-outline-secondary"
title="Comparer les versions">
<i class="bi bi-arrows-angle-expand"></i> Comparer
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-arrows-angle-expand"></i> Comparer
</button>
{% endif %}
2025-09-03 17:18:21 +02:00
{% else %}
2025-09-05 15:58:26 +02:00
{% if page .key is defined %}
<a href=" {{ path ( 'app_admin_wiki_create_french' , { 'key' : page .key } ) }} "
class="btn btn-sm btn-success"
title="Créer une traduction française">
<i class="bi bi-plus-circle"></i> Traduire
</a>
{% elseif page .title is defined %}
<a href=" {{ path ( 'app_admin_wiki_create_french' , { 'key' : page .title } ) }} "
class="btn btn-sm btn-success"
title="Créer une traduction française">
<i class="bi bi-plus-circle"></i> Traduire
</a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" disabled>
<i class="bi bi-plus-circle"></i> Clé manquante
</button>
{% endif %}
2025-09-03 17:18:21 +02:00
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
{% endif %}
</div>
{% endblock %}
{% block javascripts %}
{{ parent ( ) }}
{% if json_exists %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Collect data for the chart
const labels = [];
const scores = [];
const colors = [];
{% for page in regular_pages | slice ( 0 , 2 0 ) %}
2025-09-05 15:58:26 +02:00
{% if page .key is defined %}
labels.push(" {{ page .key }} ");
{% elseif page .title is defined %}
labels.push(" {{ page .title }} ");
{% else %}
labels.push("Page sans clé");
{% endif %}
2025-09-08 10:20:51 +02:00
{% if page .staleness_score is defined %}
scores.push( {{ page .staleness_score }} );
2025-09-03 17:18:21 +02:00
2025-09-08 10:20:51 +02:00
// Set color based on score
{% if page .staleness_score > 8 0 %}
colors.push('rgba(220, 53, 69, 0.7)'); // danger (red)
{% elseif page .staleness_score > 6 0 %}
colors.push('rgba(232, 113, 55, 0.7)'); // dark orange
{% elseif page .staleness_score > 4 0 %}
colors.push('rgba(255, 153, 0, 0.7)'); // orange
{% elseif page .staleness_score > 2 0 %}
colors.push('rgba(255, 193, 7, 0.7)'); // warning (yellow)
{% elseif page .staleness_score > 1 0 %}
colors.push('rgba(140, 195, 38, 0.7)'); // light green
{% else %}
colors.push('rgba(25, 135, 84, 0.7)'); // success (green)
{% endif %}
2025-09-03 17:18:21 +02:00
{% else %}
2025-09-08 10:20:51 +02:00
scores.push(0);
colors.push('rgba(108, 117, 125, 0.7)'); // secondary (gray)
2025-09-03 17:18:21 +02:00
{% endif %}
{% endfor %}
// Sort data by score (descending)
const indices = Array.from(Array(scores.length).keys())
.sort((a, b) => scores[b] - scores[a]);
const sortedLabels = indices.map(i => labels[i]);
const sortedScores = indices.map(i => scores[i]);
const sortedColors = indices.map(i => colors[i]);
// Create the chart
const ctx = document.getElementById('decrepitudeChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: sortedLabels,
datasets: [ {
label: 'Score de décrépitude',
data: sortedScores,
backgroundColor: sortedColors,
borderColor: sortedColors.map(c => c.replace('0.7', '1')),
borderWidth: 1
}]
},
options: {
indexAxis: 'y',
responsive: true,
plugins: {
legend: {
display: false
},
tooltip: {
callbacks: {
label: function (context) {
return `Score: $ { context.raw}`;
}
}
}
},
scales: {
x: {
beginAtZero: true,
max: 100,
title: {
display: true,
text: 'Score de décrépitude (0-100)'
}
}
}
}
});
});
</script>
{% endif %}
{% endblock %}