diff --git a/src/Controller/WikiController.php b/src/Controller/WikiController.php index b753f3a0..1ca8d11d 100644 --- a/src/Controller/WikiController.php +++ b/src/Controller/WikiController.php @@ -9,6 +9,175 @@ use Symfony\Component\HttpFoundation\Request; class WikiController extends AbstractController { + #[Route('/admin/wiki/missing-translations', name: 'app_admin_wiki_missing_translations')] + public function missingTranslations(): Response + { + $csvFile = $this->getParameter('kernel.project_dir') . '/wiki_compare/wiki_pages.csv'; + + if (!file_exists($csvFile)) { + $this->addFlash('error', 'Le fichier wiki_pages.csv n\'existe pas.'); + return $this->redirectToRoute('app_admin_wiki'); + } + + $csvData = array_map('str_getcsv', file($csvFile)); + $headers = array_shift($csvData); + + $wikiPages = []; + + // Process CSV data + foreach ($csvData as $row) { + $page = array_combine($headers, $row); + $wikiPages[$page['key']][$page['language']] = $page; + } + + // Find French pages without English translations + $frenchOnlyPages = []; + foreach ($wikiPages as $key => $languages) { + if (isset($languages['fr']) && !isset($languages['en'])) { + $frenchOnlyPages[$key] = $languages['fr']; + } + } + + // Sort by key + ksort($frenchOnlyPages); + + return $this->render('admin/wiki_missing_translations.html.twig', [ + 'french_only_pages' => $frenchOnlyPages + ]); + } + #[Route('/admin/wiki/suspicious-deletions', name: 'app_admin_wiki_suspicious_deletions')] + public function suspiciousDeletions(): Response + { + $csvFile = $this->getParameter('kernel.project_dir') . '/wiki_compare/wiki_pages.csv'; + $jsonFile = $this->getParameter('kernel.project_dir') . '/wiki_compare/outdated_pages.json'; + + if (!file_exists($csvFile) || !file_exists($jsonFile)) { + $this->addFlash('error', 'Les fichiers nécessaires n\'existent pas.'); + return $this->redirectToRoute('app_admin_wiki'); + } + + // Load CSV data + $csvData = array_map('str_getcsv', file($csvFile)); + $headers = array_shift($csvData); + + // Process CSV data to find French pages + $frenchPages = []; + foreach ($csvData as $row) { + $page = array_combine($headers, $row); + if ($page['language'] === 'fr') { + $frenchPages[$page['key']] = $page; + } + } + + // Load JSON data + $jsonData = json_decode(file_get_contents($jsonFile), true); + + // Find pages with suspicious deletions + $suspiciousPages = []; + foreach ($jsonData as $page) { + if (isset($page['fr_page']) && isset($page['en_page'])) { + // Calculate deletion percentage + $enWordCount = (int)$page['en_page']['word_count']; + $frWordCount = (int)$page['fr_page']['word_count']; + $wordDiff = $enWordCount - $frWordCount; + + // If English has more words and the difference is significant (>30%) + if ($wordDiff > 0 && $frWordCount > 0 && ($wordDiff / $enWordCount) > 0.3) { + $page['deletion_percentage'] = round(($wordDiff / $enWordCount) * 100, 2); + $suspiciousPages[] = $page; + } + } + } + + // Sort by deletion percentage (highest first) + usort($suspiciousPages, function($a, $b) { + return $b['deletion_percentage'] <=> $a['deletion_percentage']; + }); + + return $this->render('admin/wiki_suspicious_deletions.html.twig', [ + 'suspicious_pages' => $suspiciousPages + ]); + } + #[Route('/admin/wiki/tag-proposals', name: 'app_admin_wiki_tag_proposals')] + public function tagProposals(): Response + { + // URL of the OSM wiki page that lists tag proposals + $url = 'https://wiki.openstreetmap.org/wiki/Proposed_features'; + + try { + $html = file_get_contents($url); + + if ($html === false) { + throw new \Exception('Failed to fetch the tag proposals page'); + } + + // Create a DOM parser + $dom = new \DOMDocument(); + @$dom->loadHTML($html); + $xpath = new \DOMXPath($dom); + + // Find the table with proposals + $tables = $xpath->query("//table[contains(@class, 'wikitable')]"); + $proposals = []; + + if ($tables->length > 0) { + // Get the first table which contains the active proposals + $table = $tables->item(0); + $rows = $xpath->query(".//tr", $table); + + // Skip the header row + for ($i = 1; $i < $rows->length; $i++) { + $row = $rows->item($i); + $cells = $xpath->query(".//td", $row); + + if ($cells->length >= 4) { + $proposal = [ + 'feature' => $xpath->query(".//a", $cells->item(0))->item(0)->textContent, + 'url' => 'https://wiki.openstreetmap.org' . $xpath->query(".//a", $cells->item(0))->item(0)->getAttribute('href'), + 'description' => $cells->item(1)->textContent, + 'proposer' => $cells->item(2)->textContent, + 'status' => $cells->item(3)->textContent, + ]; + + $proposals[] = $proposal; + } + } + } + + return $this->render('admin/wiki_tag_proposals.html.twig', [ + 'proposals' => $proposals + ]); + + } catch (\Exception $e) { + $this->addFlash('error', 'Erreur lors de la récupération des propositions de tags : ' . $e->getMessage()); + return $this->redirectToRoute('app_admin_wiki'); + } + } + + #[Route('/admin/wiki/random-suggestion', name: 'app_admin_wiki_random_suggestion')] + public function randomSuggestion(): Response + { + $jsonFile = $this->getParameter('kernel.project_dir') . '/wiki_compare/outdated_pages.json'; + + if (!file_exists($jsonFile)) { + $this->addFlash('error', 'Le fichier outdated_pages.json n\'existe pas.'); + return $this->redirectToRoute('app_admin_wiki'); + } + + $jsonData = json_decode(file_get_contents($jsonFile), true); + + if (empty($jsonData)) { + $this->addFlash('error', 'Aucune page à améliorer n\'a été trouvée.'); + return $this->redirectToRoute('app_admin_wiki'); + } + + // Select a random page from the outdated pages + $randomPage = $jsonData[array_rand($jsonData)]; + + return $this->render('admin/wiki_random_suggestion.html.twig', [ + 'page' => $randomPage + ]); + } #[Route('/admin/wiki', name: 'app_admin_wiki')] public function index(): Response diff --git a/templates/admin/_wiki_navigation.html.twig b/templates/admin/_wiki_navigation.html.twig new file mode 100644 index 00000000..6ebd4e6b --- /dev/null +++ b/templates/admin/_wiki_navigation.html.twig @@ -0,0 +1,37 @@ + \ No newline at end of file diff --git a/templates/admin/wiki.html.twig b/templates/admin/wiki.html.twig index e804a3be..3a730f97 100644 --- a/templates/admin/wiki.html.twig +++ b/templates/admin/wiki.html.twig @@ -4,6 +4,8 @@ {% block body %}
+ {% include 'admin/_wiki_navigation.html.twig' %} +

Pages Wiki OpenStreetMap

Comparaison des pages wiki en français et en anglais pour les clés OSM les plus utilisées.

diff --git a/templates/admin/wiki_compare.html.twig b/templates/admin/wiki_compare.html.twig index 79ce7b0a..04d2d5f0 100644 --- a/templates/admin/wiki_compare.html.twig +++ b/templates/admin/wiki_compare.html.twig @@ -8,14 +8,29 @@ transform: none !important; box-shadow: none !important; } + .title-level-1 { + font-weight: bold; + } .title-level-2 { padding-left: 1.5rem; } .title-level-3 { padding-left: 2.8rem; } + .title-level-4 { + padding-left: 4rem; + } + .title-level-5 { + padding-left: 5.2rem; + } + .title-level-6 { + padding-left: 6.4rem; + font-size: 0.9rem; + }
+ {% include 'admin/_wiki_navigation.html.twig' %} +

Comparaison Wiki OpenStreetMap - {{ key }}

Comparaison détaillée des pages wiki en français et en anglais pour la clé OSM "{{ key }}".

@@ -118,22 +133,20 @@ {{ en_page.sections }} sections
-{#

Sections communes ({{ detailed_comparison.section_comparison.common|length }})

#} -{# #} - -

Sections uniquement en anglais ({{ detailed_comparison.section_comparison.en_only|length }})

-
-{#

Sections communes ({{ detailed_comparison.section_comparison.common|length }})

#} -{# #} - -

Sections uniquement en français ({{ detailed_comparison.section_comparison.fr_only|length }})

-