170 lines
5.1 KiB
PHP
170 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use Illuminate\Database\Seeder;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class CtySeeder extends Seeder
|
|
{
|
|
public function run(): void
|
|
{
|
|
$path = storage_path('data/cty_wt_mod.dat.gz');
|
|
if (! file_exists($path)) {
|
|
$path = storage_path('data/cty_wt.dat.gz');
|
|
}
|
|
if (! file_exists($path)) {
|
|
return;
|
|
}
|
|
|
|
DB::table('cty')->truncate();
|
|
|
|
$handle = gzopen($path, 'rb');
|
|
if (! $handle) {
|
|
return;
|
|
}
|
|
|
|
$dxcc = null;
|
|
$current = null;
|
|
$prefixBuffer = '';
|
|
$batch = [];
|
|
$batchSize = 500;
|
|
$source = 'cty_wt.dat';
|
|
$now = now();
|
|
|
|
$flush = function () use (&$batch) {
|
|
if (! $batch) {
|
|
return;
|
|
}
|
|
|
|
DB::table('cty')->upsert(
|
|
$batch,
|
|
['prefix'],
|
|
[
|
|
'country_name',
|
|
'dxcc',
|
|
'cq_zone',
|
|
'itu_zone',
|
|
'continent',
|
|
'latitude',
|
|
'longitude',
|
|
'time_offset',
|
|
'prefix_norm',
|
|
'precise',
|
|
'source',
|
|
'updated_at',
|
|
]
|
|
);
|
|
|
|
$batch = [];
|
|
};
|
|
|
|
$addPrefix = function (string $token, array $current, bool $preciseOverride = false) use (&$batch, $batchSize, $now, $flush) {
|
|
$rawToken = trim($token);
|
|
if ($rawToken === '') {
|
|
return;
|
|
}
|
|
|
|
$precise = $preciseOverride || str_starts_with($rawToken, '=');
|
|
$prefix = $rawToken;
|
|
|
|
$normToken = $rawToken;
|
|
if (str_starts_with($normToken, '=')) {
|
|
$normToken = substr($normToken, 1);
|
|
}
|
|
$normToken = trim($normToken);
|
|
$normToken = preg_split('/[\\(\\[<\\{~]/', $normToken, 2)[0] ?? '';
|
|
$normToken = strtoupper(trim($normToken));
|
|
if ($normToken === '') {
|
|
return;
|
|
}
|
|
$batch[] = [
|
|
'country_name' => $current['country_name'],
|
|
'dxcc' => $current['dxcc'],
|
|
'cq_zone' => $current['cq_zone'],
|
|
'itu_zone' => $current['itu_zone'],
|
|
'continent' => $current['continent'],
|
|
'latitude' => $current['latitude'],
|
|
'longitude' => $current['longitude'],
|
|
'time_offset' => $current['time_offset'],
|
|
'prefix' => $prefix,
|
|
'prefix_norm' => $normToken,
|
|
'precise' => $precise,
|
|
'source' => $current['source'],
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
];
|
|
|
|
if (count($batch) >= $batchSize) {
|
|
$flush();
|
|
}
|
|
};
|
|
|
|
while (($line = gzgets($handle)) !== false) {
|
|
$line = rtrim($line, "\r\n");
|
|
if ($line === '') {
|
|
continue;
|
|
}
|
|
|
|
if (str_starts_with($line, '#')) {
|
|
if (preg_match('/ADIF\\s+(\\d+)/', $line, $match)) {
|
|
$dxcc = (int) $match[1];
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (! preg_match('/^\\s/', $line)) {
|
|
$prefixBuffer = '';
|
|
if (preg_match(
|
|
'/^([^:]+):\\s*([0-9]+):\\s*([0-9]+):\\s*([A-Z]{2}):\\s*([0-9\\.-]+):\\s*([0-9\\.-]+):\\s*([0-9\\.-]+):\\s*([^:]+):/',
|
|
$line,
|
|
$match
|
|
)) {
|
|
$current = [
|
|
'country_name' => trim($match[1]),
|
|
'dxcc' => $dxcc,
|
|
'cq_zone' => (int) $match[2],
|
|
'itu_zone' => (int) $match[3],
|
|
'continent' => trim($match[4]),
|
|
'latitude' => (float) $match[5],
|
|
'longitude' => (float) $match[6],
|
|
'time_offset' => (float) $match[7],
|
|
'source' => $source,
|
|
];
|
|
|
|
$primaryPrefix = trim($match[8]);
|
|
if ($primaryPrefix !== '') {
|
|
$addPrefix($primaryPrefix, $current);
|
|
}
|
|
} else {
|
|
$current = null;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (! $current) {
|
|
continue;
|
|
}
|
|
|
|
$segment = trim($line);
|
|
if ($segment === '') {
|
|
continue;
|
|
}
|
|
|
|
$prefixBuffer .= ' ' . $segment;
|
|
|
|
if (str_contains($segment, ';')) {
|
|
$prefixBuffer = rtrim($prefixBuffer, ';');
|
|
$tokens = array_map('trim', explode(',', $prefixBuffer));
|
|
foreach ($tokens as $token) {
|
|
$addPrefix($token, $current);
|
|
}
|
|
$prefixBuffer = '';
|
|
}
|
|
}
|
|
|
|
$flush();
|
|
gzclose($handle);
|
|
}
|
|
}
|