Cache ADSB/AIS calls
This commit is contained in:
@@ -206,11 +206,11 @@ const navball = computed(() => {
|
|||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<div class="ap-meta flex-r justify-between">
|
<div class="ap-meta flex-r justify-between">
|
||||||
<div class="flex-c">
|
<div class="flex-c">
|
||||||
<span>{{ operator }}</span>
|
<span>{{ operator || 'Unknown Owner' }}</span>
|
||||||
<span>{{ plane.country || 'Unknown Country' }}</span>
|
<span>{{ plane.country || 'Unknown Country' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-c align-x-end">
|
<div class="flex-c align-x-end">
|
||||||
<span>{{ description }}</span>
|
<span>{{ description || 'Unknown Aircraft' }}</span>
|
||||||
<span style="text-transform: capitalize">{{ plane.class || 'Unknown' }} • {{ plane.type || 'Unknown' }}</span>
|
<span style="text-transform: capitalize">{{ plane.class || 'Unknown' }} • {{ plane.type || 'Unknown' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -213,12 +213,12 @@ const compass = computed(() => {
|
|||||||
|
|
||||||
<div class="sp-meta">
|
<div class="sp-meta">
|
||||||
<div class="flex-c">
|
<div class="flex-c">
|
||||||
<span>{{ boat.operator || boat.owner || 'Unknown' }}</span>
|
<span>{{ boat.operator || boat.owner || 'Unknown Owner' }}</span>
|
||||||
<span>{{ boat.country || 'Unknown Country' }}</span>
|
<span>{{ boat.country || 'Unknown Country' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-c align-x-end">
|
<div class="flex-c align-x-end">
|
||||||
<span style="text-transform:capitalize">{{ boat.type || 'Unknown' }}</span>
|
<span style="text-transform:capitalize">{{ boat.type || 'Unknown' }}</span>
|
||||||
<span>{{ boat.ship_type || 'Unknown' }}</span>
|
<span>{{ boat.ship_type || 'Unknown Class' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,17 @@ const CSV_CACHE = resolve(DATA, 'aircraft_db.csv');
|
|||||||
const MAX_HISTORY = 500;
|
const MAX_HISTORY = 500;
|
||||||
const HISTORY_TTL = 1000 * 60 * 60; // 1 hour
|
const HISTORY_TTL = 1000 * 60 * 60; // 1 hour
|
||||||
|
|
||||||
|
const ADSB_TTL = 1000;
|
||||||
const CSV_URL = 'https://s3.opensky-network.org/data-samples/metadata/aircraft-database-complete-2024-06.csv';
|
const CSV_URL = 'https://s3.opensky-network.org/data-samples/metadata/aircraft-database-complete-2024-06.csv';
|
||||||
const MIL_RANGES_URL = ':8080/db-3.14.1708/ranges.js';
|
const MIL_RANGES_URL = ':8080/db-3.14.1708/ranges.js';
|
||||||
|
|
||||||
const MILITARY_OPERATORS = ['air force', 'army', 'navy', 'marine', 'coast guard', 'military', 'defence', 'defense', 'luftwaffe', 'RAF', 'USAF', 'USN', 'USMC'];
|
const MILITARY_OPERATORS = ['air force', 'army', 'navy', 'marine', 'coast guard', 'military', 'defence', 'defense', 'luftwaffe', 'RAF', 'USAF', 'USN', 'USMC'];
|
||||||
const CARGO_OPERATORS = ['fedex', 'ups', 'dhl', 'cargo', 'freight', 'logistic', 'atlas air', 'kalitta', 'air freight'];
|
const CARGO_OPERATORS = ['fedex', 'ups', 'dhl', 'cargo', 'freight', 'logistic', 'atlas air', 'kalitta', 'air freight'];
|
||||||
const PASSENGER_OPERATORS = ['airlines', 'airways', 'air ', 'jet', 'easyjet', 'ryanair', 'delta', 'united', 'american', 'avianca', 'southwest', 'lufthansa', 'emirates', 'british'];
|
const PASSENGER_OPERATORS = ['airlines', 'airways', 'air ', 'jet', 'jetblue', 'easyjet', 'ryanair', 'delta', 'united', 'american', 'avianca', 'southwest', 'lufthansa', 'emirates', 'british'];
|
||||||
const MILITARY_CLASSES = ['H1M', 'H2M', 'L1M', 'L2M', 'L4M', 'A0'];
|
const MILITARY_CLASSES = ['H1M', 'H2M', 'L1M', 'L2M', 'L4M', 'A0'];
|
||||||
|
|
||||||
|
let adsbCache = null;
|
||||||
|
let adsbCacheTs = 0;
|
||||||
const noRecord = [];
|
const noRecord = [];
|
||||||
const history = new Map();
|
const history = new Map();
|
||||||
const milRanges = [];
|
const milRanges = [];
|
||||||
@@ -150,7 +153,7 @@ function isIcaoInMilitaryRange(icao) {
|
|||||||
|
|
||||||
function wordMatch(text, keyword) {
|
function wordMatch(text, keyword) {
|
||||||
if (!text) return false;
|
if (!text) return false;
|
||||||
const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/gi, '\\$&');
|
||||||
return new RegExp(`(?<![\\w])${escaped}(?![\\w])`, 'i').test(text);
|
return new RegExp(`(?<![\\w])${escaped}(?![\\w])`, 'i').test(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +203,6 @@ async function scrapeHexDatabase(icao) {
|
|||||||
|
|
||||||
const cells = row.find('td');
|
const cells = row.find('td');
|
||||||
return {
|
return {
|
||||||
country: $(cells[0]).text().trim() || null,
|
|
||||||
registration: $(cells[1]).text().trim() || null,
|
registration: $(cells[1]).text().trim() || null,
|
||||||
aircraft: $(cells[2]).text().trim() || null,
|
aircraft: $(cells[2]).text().trim() || null,
|
||||||
operator: $(cells[3]).text().trim() || null,
|
operator: $(cells[3]).text().trim() || null,
|
||||||
@@ -288,6 +290,7 @@ export async function enrichAircraft(a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getADSB() {
|
export async function getADSB() {
|
||||||
|
if (adsbCache && Date.now() - adsbCacheTs < ADSB_TTL) return adsbCache;
|
||||||
const { ADSB_URL } = cfg();
|
const { ADSB_URL } = cfg();
|
||||||
if (!ADSB_URL) return [];
|
if (!ADSB_URL) return [];
|
||||||
const r = await fetchWithTimeout(`${ADSB_URL}:8080/data/aircraft.json`);
|
const r = await fetchWithTimeout(`${ADSB_URL}:8080/data/aircraft.json`);
|
||||||
@@ -304,11 +307,13 @@ export async function getADSB() {
|
|||||||
if (trail.length > MAX_HISTORY) trail.shift();
|
if (trail.length > MAX_HISTORY) trail.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(aircraft.map(async a => {
|
adsbCache = await Promise.all(aircraft.map(async a => {
|
||||||
a = await enrichAircraft(a);
|
a = await enrichAircraft(a);
|
||||||
a.icon = getIcon(a);
|
a.icon = getIcon(a);
|
||||||
return a;
|
return a;
|
||||||
}));
|
}));
|
||||||
|
adsbCacheTs = Date.now();
|
||||||
|
return adsbCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getADSBHistory(icao) {
|
export async function getADSBHistory(icao) {
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ const SENDER_TYPE = {
|
|||||||
12: 'AtoN', 13: 'SART/EPIRB'
|
12: 'AtoN', 13: 'SART/EPIRB'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let aisCache = null;
|
||||||
|
let aisCacheTs = 0;
|
||||||
|
const AIS_TTL = 1000;
|
||||||
|
|
||||||
function decodeMsgTypes(raw) {
|
function decodeMsgTypes(raw) {
|
||||||
const types = [];
|
const types = [];
|
||||||
for (let i = 0; i < 32; i++) {
|
for (let i = 0; i < 32; i++) {
|
||||||
@@ -38,6 +42,7 @@ function decodeFlags(flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getAIS() {
|
export async function getAIS() {
|
||||||
|
if (aisCache && Date.now() - aisCacheTs < AIS_TTL) return aisCache;
|
||||||
const {ADSB_URL} = cfg();
|
const {ADSB_URL} = cfg();
|
||||||
if (!ADSB_URL) return {data: []};
|
if (!ADSB_URL) return {data: []};
|
||||||
const r = await fetch(`${ADSB_URL}:9990/api/ships_array.json`);
|
const r = await fetch(`${ADSB_URL}:9990/api/ships_array.json`);
|
||||||
@@ -45,7 +50,7 @@ export async function getAIS() {
|
|||||||
|
|
||||||
const staticMap = new Map(staticRows.map(row => [row[0], row]));
|
const staticMap = new Map(staticRows.map(row => [row[0], row]));
|
||||||
|
|
||||||
return dynamic.map(row => {
|
aisCache = dynamic.map(row => {
|
||||||
const [mmsi, lat, lon, distance, bearing, heading,
|
const [mmsi, lat, lon, distance, bearing, heading,
|
||||||
cog, speed, status, rrsi, ppm, count, msg_type,
|
cog, speed, status, rrsi, ppm, count, msg_type,
|
||||||
last_signal, last_group, group_mask, flags, altitude,
|
last_signal, last_group, group_mask, flags, altitude,
|
||||||
@@ -79,4 +84,6 @@ export async function getAIS() {
|
|||||||
status
|
status
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
aisCacheTs = Date.now();
|
||||||
|
return aisCache;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user