aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bridges/AnfrBridge.php278
1 files changed, 278 insertions, 0 deletions
diff --git a/bridges/AnfrBridge.php b/bridges/AnfrBridge.php
new file mode 100644
index 00000000..391fde77
--- /dev/null
+++ b/bridges/AnfrBridge.php
@@ -0,0 +1,278 @@
+<?php
+
+class AnfrBridge extends BridgeAbstract
+{
+ const NAME = 'ANFR';
+ const URI = 'https://data.anfr.fr/';
+ const DESCRIPTION = 'Fetches data from the French administration "Agence Nationale des Fréquences".';
+ const CACHE_TIMEOUT = 604800; // 7d
+ const MAINTAINER = 'quent1';
+ const PARAMETERS = [
+ 'Données sur les réseaux mobiles' => [
+ 'departement' => [
+ 'name' => 'Département',
+ 'type' => 'list',
+ 'values' => [
+ 'Tous' => null,
+ 'Ain' => '001',
+ 'Aisne' => '002',
+ 'Allier' => '003',
+ 'Alpes-de-Haute-Provence' => '004',
+ 'Hautes-Alpes' => '005',
+ 'Alpes-Maritimes' => '006',
+ 'Ardèche' => '007',
+ 'Ardennes' => '008',
+ 'Ariège' => '009',
+ 'Aube' => '010',
+ 'Aude' => '011',
+ 'Aveyron' => '012',
+ 'Bouches-du-Rhône' => '013',
+ 'Calvados' => '014',
+ 'Cantal' => '015',
+ 'Charente' => '016',
+ 'Charente-Maritime' => '017',
+ 'Cher' => '018',
+ 'Corrèze' => '019',
+ 'Corse-du-Sud' => '02A',
+ 'Haute-Corse' => '02B',
+ 'Côte-d\'Or' => '021',
+ 'Côtes-d\'Armor' => '022',
+ 'Creuse' => '023',
+ 'Dordogne' => '024',
+ 'Doubs' => '025',
+ 'Drôme' => '026',
+ 'Eure' => '027',
+ 'Eure-et-Loir' => '028',
+ 'Finistère' => '029',
+ 'Gard' => '030',
+ 'Haute-Garonne' => '031',
+ 'Gers' => '032',
+ 'Gironde' => '033',
+ 'Hérault' => '034',
+ 'Ille-et-Vilaine' => '035',
+ 'Indre' => '036',
+ 'Indre-et-Loire' => '037',
+ 'Isère' => '038',
+ 'Jura' => '039',
+ 'Landes' => '040',
+ 'Loir-et-Cher' => '041',
+ 'Loire' => '042',
+ 'Haute-Loire' => '043',
+ 'Loire-Atlantique' => '044',
+ 'Loiret' => '045',
+ 'Lot' => '046',
+ 'Lot-et-Garonne' => '047',
+ 'Lozère' => '048',
+ 'Maine-et-Loire' => '049',
+ 'Manche' => '050',
+ 'Marne' => '051',
+ 'Haute-Marne' => '052',
+ 'Mayenne' => '053',
+ 'Meurthe-et-Moselle' => '054',
+ 'Meuse' => '055',
+ 'Morbihan' => '056',
+ 'Moselle' => '057',
+ 'Nièvre' => '058',
+ 'Nord' => '059',
+ 'Oise' => '060',
+ 'Orne' => '061',
+ 'Pas-de-Calais' => '062',
+ 'Puy-de-Dôme' => '063',
+ 'Pyrénées-Atlantiques' => '064',
+ 'Hautes-Pyrénées' => '065',
+ 'Pyrénées-Orientales' => '066',
+ 'Bas-Rhin' => '067',
+ 'Haut-Rhin' => '068',
+ 'Rhône' => '069',
+ 'Haute-Saône' => '070',
+ 'Saône-et-Loire' => '071',
+ 'Sarthe' => '072',
+ 'Savoie' => '073',
+ 'Haute-Savoie' => '074',
+ 'Paris' => '075',
+ 'Seine-Maritime' => '076',
+ 'Seine-et-Marne' => '077',
+ 'Yvelines' => '078',
+ 'Deux-Sèvres' => '079',
+ 'Somme' => '080',
+ 'Tarn' => '081',
+ 'Tarn-et-Garonne' => '082',
+ 'Var' => '083',
+ 'Vaucluse' => '084',
+ 'Vendée' => '085',
+ 'Vienne' => '086',
+ 'Haute-Vienne' => '087',
+ 'Vosges' => '088',
+ 'Yonne' => '089',
+ 'Territoire de Belfort' => '090',
+ 'Essonne' => '091',
+ 'Hauts-de-Seine' => '092',
+ 'Seine-Saint-Denis' => '093',
+ 'Val-de-Marne' => '094',
+ 'Val-d\'Oise' => '095',
+ 'Guadeloupe' => '971',
+ 'Martinique' => '972',
+ 'Guyane' => '973',
+ 'La Réunion' => '974',
+ 'Saint-Pierre-et-Miquelon' => '975',
+ 'Mayotte' => '976',
+ 'Saint-Barthélemy' => '977',
+ 'Saint-Martin' => '978',
+ 'Terres australes et antarctiques françaises' => '984',
+ 'Wallis-et-Futuna' => '986',
+ 'Polynésie française' => '987',
+ 'Nouvelle-Calédonie' => '988',
+ 'Île de Clipperton' => '989'
+ ]
+ ],
+ 'generation' => [
+ 'name' => 'Génération',
+ 'type' => 'list',
+ 'values' => [
+ 'Tous' => null,
+ '2G' => '2G',
+ '3G' => '3G',
+ '4G' => '4G',
+ '5G' => '5G',
+ ]
+ ],
+ 'operateur' => [
+ 'name' => 'Opérateur',
+ 'type' => 'list',
+ 'values' => [
+ 'Tous' => null,
+ 'Bouygues Télécom' => 'BOUYGUES TELECOM',
+ 'Dauphin Télécom' => 'DAUPHIN TELECOM',
+ 'Digiciel' => 'DIGICEL',
+ 'Free Caraïbes' => 'FREE CARAIBES',
+ 'Free Mobile' => 'FREE MOBILE',
+ 'GLOBALTEL' => 'GLOBALTEL',
+ 'Office des postes et télécommunications de Nouvelle Calédonie' => 'Gouv Nelle Calédonie (OPT)',
+ 'Maore Mobile' => 'MAORE MOBILE',
+ 'ONATi' => 'ONATI',
+ 'Orange' => 'ORANGE',
+ 'Outremer Telecom' => 'OUTREMER TELECOM',
+ 'Vodafone polynésie' => 'PMT/VODAPHONE',
+ 'SFR' => 'SFR',
+ 'SPM Télécom' => 'SPM TELECOM',
+ 'Service des Postes et Télécommunications de Polynésie Française' => 'Gouv Nelle Calédonie (OPT)',
+ 'SRR' => 'SRR',
+ 'Station étrangère' => 'Station étrangère',
+ 'Telco OI' => 'TELCO IO',
+ 'United Telecommunication Services Caraïbes' => 'UTS Caraibes',
+ 'Ora Mobile' => 'VITI SAS',
+ 'Zeop' => 'ZEOP'
+ ]
+ ],
+ 'statut' => [
+ 'name' => 'Statut',
+ 'type' => 'list',
+ 'values' => [
+ 'Tous' => null,
+ 'En service' => 'En service',
+ 'Projet approuvé' => 'Projet approuvé',
+ 'Techniquement opérationnel' => 'Techniquement opérationnel',
+ ]
+ ]
+ ]
+ ];
+
+ public function collectData()
+ {
+ $urlParts = [
+ 'id' => 'observatoire_2g_3g_4g',
+ 'resource_id' => '88ef0887-6b0f-4d3f-8545-6d64c8f597da',
+ 'fields' => 'id,adm_lb_nom,sta_nm_dpt,emr_lb_systeme,generation,date_maj,sta_nm_anfr,adr_lb_lieu,adr_lb_add1,adr_lb_add2,adr_lb_add3,adr_nm_cp,statut',
+ 'rows' => 10000
+ ];
+
+ if (!empty($this->getInput('departement'))) {
+ $urlParts['refine.sta_nm_dpt'] = urlencode($this->getInput('departement'));
+ }
+
+ if (!empty($this->getInput('generation'))) {
+ $urlParts['refine.generation'] = $this->getInput('generation');
+ }
+
+ if (!empty($this->getInput('operateur'))) {
+ // http_build_query() already does urlencoding so this call is redundant
+ $urlParts['refine.adm_lb_nom'] = urlencode($this->getInput('operateur'));
+ }
+
+ if (!empty($this->getInput('statut'))) {
+ $urlParts['refine.statut'] = urlencode($this->getInput('statut'));
+ }
+
+ // API seems to not play well with urlencoded data
+ $url = urljoin(static::URI, '/d4c/api/records/1.0/download/?' . urldecode(http_build_query($urlParts)));
+
+ $json = getContents($url);
+ $data = Json::decode($json, false);
+ $records = $data->records;
+ $frequenciesByStation = [];
+ foreach ($records as $record) {
+ if (!isset($frequenciesByStation[$record->fields->sta_nm_anfr])) {
+ $street = sprintf(
+ '%s %s %s',
+ $record->fields->adr_lb_add1 ?? '',
+ $record->fields->adr_lb_add2 ?? '',
+ $record->fields->adr_lb_add3 ?? ''
+ );
+ $frequenciesByStation[$record->fields->sta_nm_anfr] = [
+ 'id' => $record->fields->sta_nm_anfr,
+ 'operator' => $record->fields->adm_lb_nom,
+ 'frequencies' => [],
+ 'lastUpdate' => 0,
+ 'address' => [
+ 'street' => trim($street),
+ 'postCode' => $record->fields->adr_nm_cp,
+ 'city' => $record->fields->adr_lb_lieu
+ ]
+ ];
+ }
+
+ $frequenciesByStation[$record->fields->sta_nm_anfr]['frequencies'][] = [
+ 'generation' => $record->fields->generation,
+ 'frequency' => $record->fields->emr_lb_systeme,
+ 'status' => $record->fields->statut,
+ 'updatedAt' => strtotime($record->fields->date_maj),
+ ];
+
+ $frequenciesByStation[$record->fields->sta_nm_anfr]['lastUpdate'] = max(
+ $frequenciesByStation[$record->fields->sta_nm_anfr]['lastUpdate'],
+ strtotime($record->fields->date_maj)
+ );
+ }
+
+ usort($frequenciesByStation, static fn ($a, $b) => $b['lastUpdate'] <=> $a['lastUpdate']);
+
+ foreach ($frequenciesByStation as $station) {
+ $title = sprintf(
+ '[%s] Mise à jour de la station n°%s à %s (%s)',
+ $station['operator'],
+ $station['id'],
+ $station['address']['city'],
+ $station['address']['postCode']
+ );
+
+ $array_reduce = array_reduce($station['frequencies'], static function ($carry, $frequency) {
+ return sprintf('%s<li>%s : %s</li>', $carry, $frequency['frequency'], $frequency['status']);
+ }, '');
+
+ $content = sprintf(
+ '<h1>Adresse complète</h1><p>%s<br>%s<br>%s</p><h1>Fréquences</h1><p><ul>%s</ul></p>',
+ $station['address']['street'],
+ $station['address']['postCode'],
+ $station['address']['city'],
+ $array_reduce
+ );
+
+ $this->items[] = [
+ 'uid' => $station['id'],
+ 'timestamp' => $station['lastUpdate'],
+ 'title' => $title,
+ 'content' => $content,
+ ];
+ }
+ }
+} \ No newline at end of file