@atmosx/event-product-parser 3.0.3 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +1 -1
- package/.github/README.md +163 -0
- package/.github/SUPPORTED_EVENTS.md +370 -0
- package/.github/docs/docs-functions.md +30 -0
- package/.github/docs/docs-general-configurations.md +209 -0
- package/.github/docs/docs-integrations.md +37 -0
- package/.github/docs/docs-listeners.md +28 -0
- package/.github/docs/docs-source-configuration.md +218 -0
- package/.github/docs/docs-technical.md +50 -0
- package/.github/logo.png +0 -0
- package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
- package/.github/samples/SAMPLE_GEOJSON.json +204 -0
- package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +119 -0
- package/dist/cjs/index.cjs +4681 -13425
- package/dist/esm/index.mjs +3163 -11909
- package/package.json +4 -8
- package/src/@building/{building.create.ts → CreateEvent.ts} +25 -11
- package/src/@building/{building.clean.ts → GetCleanedEvent.ts} +2 -2
- package/src/@building/GetEventAttachments.ts +86 -0
- package/src/@building/{building.enhance.ts → GetEventEnhancedName.ts} +11 -12
- package/src/@building/{building.geometry.ts → GetEventGeometry.ts} +7 -7
- package/src/@building/{building.headers.ts → GetEventHeader.ts} +3 -3
- package/src/@building/{building.polygon.ts → GetEventNodes.ts} +13 -11
- package/src/@building/{building.office.ts → GetEventOffice.ts} +6 -6
- package/src/@building/GetEventProperties.ts +96 -0
- package/src/@building/{building.signature.ts → GetEventSignature.ts} +14 -15
- package/src/@building/{building.tags.ts → GetEventTags.ts} +9 -4
- package/src/@building/{building.tracking.ts → GetEventTracking.ts} +15 -15
- package/src/@building/{building.validate.ts → ValidateEvents.ts} +67 -60
- package/src/@core/{core.clearEvents.ts → ClearEvents.ts} +3 -4
- package/src/@core/{core.createListener.ts → CreateListener.ts} +3 -3
- package/src/@core/{core.getEvents.ts → GetEvents.ts} +1 -2
- package/src/@core/{core.getNodes.ts → GetNodes.ts} +1 -2
- package/src/@core/{core.getRandomEvent.ts → GetRandomEvent.ts} +1 -2
- package/src/@core/{core.getVersion.ts → GetVersion.ts} +1 -2
- package/src/@core/ManualEvent.ts +56 -0
- package/src/@core/QueryStanza.ts +39 -0
- package/src/@core/{core.setNode.ts → SetNode.ts} +8 -8
- package/src/@core/{core.start.ts → StartService.ts} +21 -21
- package/src/@core/{core.stop.ts → StopService.ts} +1 -1
- package/src/@enums/AWIPS.ts +366 -0
- package/src/{@dictionaries/dictionaries.eventActions.ts → @enums/Actions.ts} +1 -1
- package/src/{@dictionaries/dictionaries.eventCancelMessages.ts → @enums/Cancellation.ts} +2 -1
- package/src/{@dictionaries/dictionaries.eventCauses.ts → @enums/Causes.ts} +1 -1
- package/src/{@dictionaries/dictionaries.statusCorrelationText.ts → @enums/Correlations.ts} +1 -1
- package/src/@enums/Enhanced.ts +70 -0
- package/src/{@dictionaries/dictionaries.eventTypes.ts → @enums/Events.ts} +1 -1
- package/src/{@dictionaries/dictionaries.regExp.ts → @enums/Expressions.ts} +2 -1
- package/src/@enums/GlobalFilter.ts +24 -0
- package/src/{@dictionaries/dictionaries.hailStrings.ts → @enums/Hail.ts} +7 -2
- package/src/{@dictionaries/dictionaries.officeICAOs.ts → @enums/ICAO.ts} +3 -1
- package/src/@enums/Matches.ts +55 -0
- package/src/{@dictionaries/dictionaries.eventProducts.ts → @enums/Products.ts} +1 -1
- package/src/{@dictionaries/dictionaries.eventRecords.ts → @enums/Records.ts} +1 -1
- package/src/{@dictionaries/dictionaries.eventSeverity.ts → @enums/Severity.ts} +1 -1
- package/src/{@dictionaries/dictionaries.shapefileLinks.ts → @enums/Shapefiles.ts} +1 -1
- package/src/@enums/States.ts +72 -0
- package/src/{@dictionaries/dictionaries.eventStatus.ts → @enums/Status.ts} +1 -1
- package/src/@enums/Strings.ts +22 -0
- package/src/@enums/Tags.ts +167 -0
- package/src/{@dictionaries/dictionaries.testSignatures.ts → @enums/Testing.ts} +3 -2
- package/src/@events/{events.api.ts → ParseAPI.ts} +42 -38
- package/src/@events/{events.text.ts → ParseText.ts} +25 -18
- package/src/@events/{events.ugc.ts → ParseUGC.ts} +28 -19
- package/src/@events/{events.vtec.ts → ParseVTEC.ts} +21 -21
- package/src/@manager/CreateActions.ts +213 -0
- package/src/@manager/{manager.mkEvent.ts → MakeEvent.ts} +34 -30
- package/src/@manager/RemoveEvent.ts +70 -0
- package/src/@manager/{manager.setHash.ts → SetHash.ts} +8 -9
- package/src/@manager/{manager.updateEvents.ts → UpdateEvents.ts} +9 -9
- package/src/@manager/{manager.updateNodes.ts → UpdateNode.ts} +24 -17
- package/src/@modules/@database/{database.cache.ts → GetCachedEvents.ts} +10 -8
- package/src/@modules/@database/ImportBroadcastify.ts +70 -0
- package/src/@modules/@database/{database.shapefiles.ts → ImportShapefiles.ts} +17 -20
- package/src/@modules/@database/{database.stanza.ts → ImportStanza.ts} +5 -6
- package/src/@modules/@database/{database.init.ts → InitializeDatabase.ts} +25 -11
- package/src/@modules/@eas/GenerateEASMessage.ts +144 -0
- package/src/@modules/@eas/GetCleanDescription.ts +91 -0
- package/src/@modules/@eas/{eas.getFloatPCM16.ts → GetFloatPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.getMergedPCM16.ts → GetMergedPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.getPCM16.ts → GetPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.getPCMToFloat.ts → GetPCMToFloat.ts} +1 -1
- package/src/@modules/@eas/{eas.getSampledPCM16.ts → GetSampledPCM16.ts} +1 -1
- package/src/@modules/@eas/GetTTS.ts +54 -0
- package/src/@modules/@eas/{eas.getWavPCM16.ts → GetWavPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.setAFSK.ts → SetAFSK.ts} +1 -2
- package/src/@modules/@eas/{eas.setAsciiToBits.ts → SetAsciiToBits.ts} +1 -2
- package/src/@modules/@eas/{eas.setAttentionTone.ts → SetAttentionTone.ts} +1 -1
- package/src/@modules/@eas/{eas.setNoise.ts → SetNoise.ts} +6 -5
- package/src/@modules/@eas/{eas.setRadioEffect.ts → SetRadioEffect.ts} +6 -5
- package/src/@modules/@eas/{eas.setSameHeader.ts → SetSameHeader.ts} +7 -8
- package/src/@modules/@stanza/{stanza.getAwipsType.ts → GetAwipsType.ts} +11 -9
- package/src/@modules/@stanza/{stanza.validate.ts → ValidateStanza.ts} +9 -9
- package/src/@modules/@utilities/CreateHttp.ts +83 -0
- package/src/@modules/@utilities/{utilities.getFormattedTime.ts → GetFormattedTime.ts} +1 -1
- package/src/@modules/@utilities/GetLatestIssuance.ts +32 -0
- package/src/@modules/@utilities/GetMatched.ts +33 -0
- package/src/@modules/@utilities/{utilities.getSettings.ts → GetSettings.ts} +2 -2
- package/src/@modules/@utilities/{utilities.getShapeNearestPoint.ts → GetShapeNearestPoint.ts} +1 -1
- package/src/@modules/@utilities/{utilities.setCronSchedule.ts → SetCronSchedule.ts} +41 -12
- package/src/{@types/types.webhook.ts → @modules/@utilities/SetDebug.ts} +16 -6
- package/src/@modules/@utilities/{utilities.setEventEmit.ts → SetEventEmit.ts} +5 -5
- package/src/@modules/@utilities/{utilities.setListener.ts → SetListener.ts} +1 -1
- package/src/@modules/@utilities/{utilities.setSettings.ts → SetSettings.ts} +2 -2
- package/src/@modules/@utilities/{utilities.setSleep.ts → SetSleep.ts} +1 -1
- package/src/@modules/@utilities/{utilities.setTimeoutAction.ts → SetTimeoutAction.ts} +8 -3
- package/src/@modules/@utilities/{utilities.setWarning.ts → SetWarning.ts} +4 -4
- package/src/@modules/@xmpp/{xmpp.xDeploy.ts → DeployXMPP.ts} +13 -14
- package/src/@modules/@xmpp/{xmpp.xError.ts → ErrorXMPP.ts} +1 -3
- package/src/@modules/@xmpp/{xmpp.xOffline.ts → OfflineXMPP.ts} +3 -4
- package/src/@modules/@xmpp/{xmpp.xOnline.ts → OnlineXMPP.ts} +6 -5
- package/src/@modules/@xmpp/{xmpp.xReconnect.ts → ReconnectXMPP.ts} +8 -8
- package/src/@modules/@xmpp/{xmpp.xStanza.ts → StanzaXMPP.ts} +11 -11
- package/src/@parsers/@hvtec/{hvtec.extract.ts → HVExtract.ts} +10 -10
- package/src/@parsers/@pvtec/{pvtec.expires.ts → GetExpiry.ts} +1 -1
- package/src/@parsers/@pvtec/{pvtec.extract.ts → VTECExtract.ts} +17 -17
- package/src/@parsers/@text/{text.getDescriptionFromProduct.ts → GetDescriptionFromProduct.ts} +12 -5
- package/src/@parsers/@text/GetEmbededText.ts +56 -0
- package/src/@parsers/@text/{text.getPolygonFromProduct.ts → GetPolygonFromProduct.ts} +31 -10
- package/src/@parsers/@text/GetStringText.ts +58 -0
- package/src/@parsers/@text/{text.getTextFromProduct.ts → GetTextFromProduct.ts} +1 -1
- package/src/@parsers/@text/{text.getXML.ts → GetXML.ts} +1 -1
- package/src/@parsers/@ugc/GetCache.ts +24 -0
- package/src/@parsers/@ugc/{ugc.expiry.ts → GetExpiry.ts} +1 -1
- package/src/@parsers/@ugc/{ugc.locations.ts → GetLocations.ts} +35 -7
- package/src/@parsers/@ugc/{ugc.header.ts → GetUGCHeader.ts} +3 -3
- package/src/@parsers/@ugc/{ugc.coordinates.ts → GetZonePolygon.ts} +4 -3
- package/src/@parsers/@ugc/SetCache.ts +28 -0
- package/src/@parsers/@ugc/{ugc.extract.ts → UGCExtract.ts} +6 -6
- package/src/@types/Actions.ts +37 -0
- package/src/@types/{type.event.ts → Event.ts} +7 -5
- package/src/@types/{type.properties.ts → Properties.ts} +11 -8
- package/src/@types/{types.settings.ts → Settings.ts} +31 -7
- package/src/@types/{types.compiled.ts → StanzaCompiled.ts} +2 -1
- package/src/bootstrap.ts +33 -9
- package/src/index.ts +28 -26
- package/tsup.config.ts +1 -1
- package/README.md +0 -339
- package/dist/index.d.mts +0 -239
- package/dist/index.d.ts +0 -239
- package/src/@building/building.properties.ts +0 -89
- package/src/@dictionaries/dictionaries.betterEventNames.ts +0 -99
- package/src/@dictionaries/dictionaries.eventAwipAbreviations.ts +0 -364
- package/src/@dictionaries/dictionaries.eventTags.ts +0 -93
- package/src/@dictionaries/dictionaries.eventsMatchText.ts +0 -36
- package/src/@dictionaries/dictionaries.transcribedMessageReplacements.ts +0 -68
- package/src/@manager/manager.rmEvent.ts +0 -49
- package/src/@manager/manager.updateWebhooks.ts +0 -50
- package/src/@modules/@eas/eas.setEasTone.ts +0 -137
- package/src/@modules/@utilities/utilities.createHttp.ts +0 -85
- package/src/@modules/@utilities/utilities.createWebhook.ts +0 -115
- package/test.js +0 -91
- /package/{CODE_OF_CONDUCT.md → .github/CODE_OF_CONDUCT.md} +0 -0
- /package/{LICENSE → .github/LICENSE} +0 -0
- /package/{SECURITY.md → .github/SECURITY.md} +0 -0
- /package/src/@parsers/@ugc/{ugc.zones.ts → GetZones.ts} +0 -0
- /package/src/@types/{types.attributes.ts → Attributes.ts} +0 -0
- /package/src/@types/{types.hvtec.ts → HVTEC.ts} +0 -0
- /package/src/@types/{types.hash.ts → Hash.ts} +0 -0
- /package/src/@types/{types.stanza.ts → Stanza.ts} +0 -0
- /package/src/@types/{types.ugc.ts → UGC.ts} +0 -0
- /package/src/@types/{types.pvtec.ts → VTEC.ts} +0 -0
|
@@ -17,21 +17,20 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeAttributes } from "../@types/
|
|
21
|
-
import { TypeStanzaCompiled } from "../@types/
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { ugcExtract } from "../@parsers/@ugc/
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
20
|
+
import { TypeAttributes } from "../@types/Attributes";
|
|
21
|
+
import { TypeStanzaCompiled } from "../@types/StanzaCompiled"
|
|
22
|
+
import { TypePVTEC } from "../@types/VTEC";
|
|
23
|
+
import { TypeHVTEC } from "../@types/HVTEC";
|
|
24
|
+
import { bootstrap } from "../bootstrap";
|
|
25
|
+
import { VTECExtract } from "../@parsers/@pvtec/VTECExtract";
|
|
26
|
+
import { HVExtract } from "../@parsers/@hvtec/HVExtract";
|
|
27
|
+
import { ugcExtract } from "../@parsers/@ugc/UGCExtract";
|
|
28
|
+
import { GetEventProperties } from "../@building/GetEventProperties";
|
|
29
|
+
import { GetEventHeader } from "../@building/GetEventHeader";
|
|
30
|
+
import { GetEventTracking } from "../@building/GetEventTracking";
|
|
31
|
+
import { SetDebug } from "../@modules/@utilities/SetDebug";
|
|
32
32
|
|
|
33
|
-
export const
|
|
34
|
-
let processed: TypeEvent[] = [];
|
|
33
|
+
export const ParseVTEC = async (stanza: TypeStanzaCompiled): Promise<void> => {
|
|
35
34
|
const getMessages = stanza?.message
|
|
36
35
|
?.split(/(?=\$\$)/g)
|
|
37
36
|
?.map(message => message.trim())
|
|
@@ -40,17 +39,17 @@ export const vtec = async (stanza: TypeStanzaCompiled): Promise<void> => {
|
|
|
40
39
|
for (const message of getMessages) {
|
|
41
40
|
const tick = performance.now();
|
|
42
41
|
const attributes = stanza?.attributes as TypeAttributes
|
|
43
|
-
const pVtec =
|
|
44
|
-
const hVtec =
|
|
42
|
+
const pVtec = VTECExtract(message) as TypePVTEC[];
|
|
43
|
+
const hVtec = HVExtract(message) as TypeHVTEC[];
|
|
45
44
|
const ugc = await ugcExtract(message)
|
|
46
45
|
if (pVtec != null && ugc != null ) {
|
|
47
46
|
for (const pv of pVtec) {
|
|
48
47
|
const vtec = pv;
|
|
49
|
-
const props =
|
|
50
|
-
const header =
|
|
48
|
+
const props = GetEventProperties({ message, attributes, ugc, pVtec: vtec })
|
|
49
|
+
const header = GetEventHeader({properties: props, getType: stanza.getType, vtec: vtec})
|
|
51
50
|
const issued = new Date(attributes.issue)?? new Date()
|
|
52
51
|
const expires = new Date(vtec.expires)
|
|
53
|
-
processed.push({
|
|
52
|
+
bootstrap.cache.processed.push({
|
|
54
53
|
type: `Feature`,
|
|
55
54
|
geometry: {
|
|
56
55
|
type: `Point`,
|
|
@@ -66,10 +65,11 @@ export const vtec = async (stanza: TypeStanzaCompiled): Promise<void> => {
|
|
|
66
65
|
metadata: {
|
|
67
66
|
ms: performance.now() - tick,
|
|
68
67
|
source: `events.vtec`,
|
|
69
|
-
tracking:
|
|
68
|
+
tracking: GetEventTracking({ type: `VTEC`, stanza, attributes, properties: props, vtec }),
|
|
70
69
|
header: header,
|
|
71
70
|
vtec: pv,
|
|
72
71
|
hvtec: hVtec,
|
|
72
|
+
raw: message,
|
|
73
73
|
history: [
|
|
74
74
|
{
|
|
75
75
|
description: props.description,
|
|
@@ -80,8 +80,8 @@ export const vtec = async (stanza: TypeStanzaCompiled): Promise<void> => {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
})
|
|
83
|
+
SetDebug({ title: `ParseVTEC`, message: `${Math.round(performance.now() - tick)}ms` })
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
|
-
validateEvents(processed)
|
|
87
87
|
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
|
|
12
|
+
Discord: https://atmosphericx-discord.scriptkitty.cafe
|
|
13
|
+
Ko-Fi: https://ko-fi.com/k3yomi
|
|
14
|
+
Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
|
|
15
|
+
|
|
16
|
+
Internal Package: @atmosx/event-product-parser
|
|
17
|
+
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { TypeSettings } from "../@types/Settings";
|
|
21
|
+
import { TypeEvent } from "../@types/Event";
|
|
22
|
+
import { TypeActions } from "../@types/Actions";
|
|
23
|
+
import { bootstrap } from "../bootstrap"
|
|
24
|
+
import { GenerateEASMessage } from "../@modules/@eas/GenerateEASMessage"
|
|
25
|
+
import { SetTimeoutAction } from "../@modules/@utilities/SetTimeoutAction";
|
|
26
|
+
import { GetEmebedText } from "../@parsers/@text/GetEmbededText";
|
|
27
|
+
import { GetStringText } from "../@parsers/@text/GetStringText";
|
|
28
|
+
import { GetCleanedEvent } from "../@building/GetCleanedEvent"
|
|
29
|
+
import { CreateHttp } from "../@modules/@utilities/CreateHttp";
|
|
30
|
+
import { SetDebug } from "../@modules/@utilities/SetDebug";
|
|
31
|
+
import { GetMatched } from "../@modules/@utilities/GetMatched";
|
|
32
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync } from "fs";
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
export const CreateActions = async (event: TypeEvent): Promise<void> => {
|
|
36
|
+
const tick = performance.now()
|
|
37
|
+
const settings = bootstrap.settings as TypeSettings;
|
|
38
|
+
const notifyServer = settings.NotifyServer;
|
|
39
|
+
const actions = settings.ActionSettings as TypeActions[];
|
|
40
|
+
const properties = event.properties;
|
|
41
|
+
const hasActions = Array.isArray(actions) && actions.length > 0;
|
|
42
|
+
if (!hasActions) {
|
|
43
|
+
SetDebug({ title: `CreateActions`, message: `${Math.round(performance.now() - tick)}ms` });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const metadata = {
|
|
47
|
+
text: null,
|
|
48
|
+
eas: null,
|
|
49
|
+
json: null,
|
|
50
|
+
name: properties.event,
|
|
51
|
+
status: properties.status,
|
|
52
|
+
description: properties.description,
|
|
53
|
+
tracking: properties.metadata.tracking,
|
|
54
|
+
header: properties.metadata.header,
|
|
55
|
+
raw: properties.metadata.raw,
|
|
56
|
+
expired: properties.status_metadata.is_expired,
|
|
57
|
+
attachments: properties.metadata.attachments
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const action of actions) {
|
|
61
|
+
const events = action?.Events;
|
|
62
|
+
const webhook = action?.Webhook;
|
|
63
|
+
const notify = action?.NotificationServer;
|
|
64
|
+
const uploads = action?.Uploads
|
|
65
|
+
const isMatched = GetMatched(events ?? [], metadata.name)
|
|
66
|
+
|
|
67
|
+
if (events?.length == 0 || isMatched) {
|
|
68
|
+
if (uploads?.EAS) {
|
|
69
|
+
metadata.eas = await GenerateEASMessage({
|
|
70
|
+
title: `${metadata.name}_${metadata.status}_${metadata.tracking}`,
|
|
71
|
+
message: metadata.description,
|
|
72
|
+
header: metadata.header
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (uploads?.TEXT) {
|
|
77
|
+
const fDestination = settings.GlobalSettings.ArchiveSettings.TextDirectory;
|
|
78
|
+
if (fDestination) {
|
|
79
|
+
const file = (`${fDestination}/${metadata.name}_${metadata.tracking}.txt`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
|
|
80
|
+
if (!existsSync(fDestination)) { mkdirSync(fDestination, { recursive: true }); }
|
|
81
|
+
if (existsSync(file)) {
|
|
82
|
+
appendFileSync(file, `${(`\n`).repeat(10)}${metadata.raw}`);
|
|
83
|
+
} else {
|
|
84
|
+
writeFileSync(file, metadata.raw);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
metadata.text = metadata.raw;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (uploads?.JSON) {
|
|
91
|
+
const eDestination = settings.GlobalSettings.ArchiveSettings.JSONDirectory;
|
|
92
|
+
if (eDestination) {
|
|
93
|
+
const file = (`${eDestination}/${metadata.name}_${metadata.tracking}.json`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
|
|
94
|
+
if (!existsSync(eDestination)) { mkdirSync(eDestination, { recursive: true }); }
|
|
95
|
+
writeFileSync(file, JSON.stringify(GetCleanedEvent(event), null, 2));
|
|
96
|
+
}
|
|
97
|
+
metadata.json = JSON.stringify(GetCleanedEvent(event), null, 2);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (notifyServer?.Enabled && notify?.Enabled && notify?.Topic) {
|
|
101
|
+
let buttons = [];
|
|
102
|
+
const auth = notifyServer?.Credentials?.Username && notifyServer?.Credentials?.Password ? { username: notifyServer?.Credentials?.Username, password: notifyServer?.Credentials?.Password } : undefined;
|
|
103
|
+
if (notifyServer?.MediaStorage?.EAS) {
|
|
104
|
+
if (metadata.eas) {
|
|
105
|
+
buttons.push({
|
|
106
|
+
"action": "view",
|
|
107
|
+
"label": "Listen",
|
|
108
|
+
"url": `${notifyServer?.MediaStorage?.EAS}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav`,
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (metadata.json) {
|
|
113
|
+
buttons.push({
|
|
114
|
+
"action": "view",
|
|
115
|
+
"label": "View JSON",
|
|
116
|
+
"url": `${notifyServer?.MediaStorage?.JSON}/${metadata.name}_${metadata.tracking}.json`,
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
if (metadata.text) {
|
|
120
|
+
buttons.push({
|
|
121
|
+
"action": "view",
|
|
122
|
+
"label": "View Text",
|
|
123
|
+
"url": `${notifyServer?.MediaStorage?.TEXT}/${metadata.name}_${metadata.tracking}.txt`,
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
if (metadata.attachments?.length > 0 && metadata.attachments.find(a => a.name === "Image: Graphic")) {
|
|
127
|
+
buttons.push({
|
|
128
|
+
"action": "view",
|
|
129
|
+
"label": "View Image",
|
|
130
|
+
"url": metadata.attachments.find(a => a.name === "Image: Graphic").link,
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
await CreateHttp({
|
|
134
|
+
url: `${notifyServer?.Server?.replace(/\/$/, "")}/${notify.Topic}`,
|
|
135
|
+
timeout: 15_000,
|
|
136
|
+
method: "PUT",
|
|
137
|
+
...(auth && { auth }),
|
|
138
|
+
headers: {
|
|
139
|
+
"Title": `${metadata.name} (${metadata.status})`,
|
|
140
|
+
"Tags": properties.parameters.tags?.join(",") ?? "N/A",
|
|
141
|
+
"Priority": notify?.Priority ?? "5",
|
|
142
|
+
... (buttons.length > 0 && { "Actions": JSON.stringify(buttons) }),
|
|
143
|
+
},
|
|
144
|
+
body: GetStringText(event)
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (webhook?.Enabled && webhook?.Destination) {
|
|
149
|
+
const isRatelimited = SetTimeoutAction({ identifier: webhook.Destination, interval: (webhook.Ratelimit ?? 2) * 2, max: (webhook.Ratelimit ?? 2), addTime: true })
|
|
150
|
+
const form = new FormData();
|
|
151
|
+
const embed = {
|
|
152
|
+
title: `${metadata.name} (${metadata.status})`,
|
|
153
|
+
description: GetEmebedText(event),
|
|
154
|
+
fields: [],
|
|
155
|
+
color: 16711680,
|
|
156
|
+
timestamp: new Date().toISOString(),
|
|
157
|
+
footer: { text: webhook.Title ?? `AtmosphericX` }
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (isRatelimited.limited) { return }
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if (metadata.description && !metadata.expired) {
|
|
164
|
+
if (metadata.description.length > 900) {
|
|
165
|
+
metadata.description = metadata.description.substring(0, 900) + "\n\n[Message truncated due to length]";
|
|
166
|
+
}
|
|
167
|
+
embed.fields.push({
|
|
168
|
+
name: "Description",
|
|
169
|
+
value: metadata.description ? '```' + '\n' + metadata.description.split('\n').map(l => l.trim()).filter(Boolean).join('\n') + '\n' + '```' : ""
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
if (metadata.attachments?.length > 0) {
|
|
175
|
+
metadata.attachments = metadata.attachments.slice(0, 5);
|
|
176
|
+
embed.fields.push({
|
|
177
|
+
name: "Attachments",
|
|
178
|
+
value: metadata.attachments.map(attachment => `- [${attachment.name.length > 45 ? attachment.name.substring(0, 45) + '...' : attachment.name}](${attachment.link})`).join('\n')
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (uploads?.TEXT) {
|
|
183
|
+
form.append("fUpload", new Blob([Buffer.from(metadata.text)], {type: "application/text"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.txt`)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (uploads?.JSON) {
|
|
187
|
+
form.append("fUpload2", new Blob([Buffer.from(metadata.json)], {type: "application/json"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.json`)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (uploads?.EAS) {
|
|
191
|
+
if (metadata.eas) {
|
|
192
|
+
const file = readFileSync(metadata.eas)
|
|
193
|
+
form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties.event}_${properties.status}_${properties.metadata.tracking}_eas.mp3`)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
form.append("payload_json", JSON.stringify({
|
|
198
|
+
username: webhook.Title ?? "AtmosphericX",
|
|
199
|
+
content: webhook.Message ?? "",
|
|
200
|
+
embeds: [embed]
|
|
201
|
+
}));
|
|
202
|
+
|
|
203
|
+
await CreateHttp({
|
|
204
|
+
url: webhook.Destination,
|
|
205
|
+
timeout: 15e3,
|
|
206
|
+
method: `POST`,
|
|
207
|
+
body: form
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
SetDebug({ title: `CreateActions`, message: `${Math.round(performance.now() - tick)}ms` })
|
|
213
|
+
}
|
|
@@ -17,44 +17,47 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
20
|
+
import { TypeEvent } from "../@types/Event";
|
|
21
|
+
import { TypeSettings } from "../@types/Settings";
|
|
22
|
+
import { EnumGlobalFilter } from "../@enums/GlobalFilter";
|
|
22
23
|
import { bootstrap } from "../bootstrap"
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
24
|
+
import { SetHash } from "./SetHash";
|
|
25
|
+
import { CreateActions } from "./CreateActions";
|
|
26
|
+
import { UpdateNode } from "./UpdateNode";
|
|
27
|
+
import { SetEventEmit } from "../@modules/@utilities/SetEventEmit";
|
|
28
|
+
import { SetTimeoutAction } from "../@modules/@utilities/SetTimeoutAction";
|
|
27
29
|
|
|
28
|
-
export const
|
|
30
|
+
export const MakeEvent = async (event: TypeEvent): Promise<void> => {
|
|
29
31
|
const settings = bootstrap.settings as TypeSettings;
|
|
30
32
|
const features = bootstrap.cache.events.features;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (const f of features) {
|
|
34
|
-
const key = f?.properties?.metadata?.tracking;
|
|
35
|
-
if (!key) continue;
|
|
36
|
-
map.set(key, f);
|
|
37
|
-
}
|
|
38
|
-
|
|
33
|
+
|
|
39
34
|
const getHash = event.properties.metadata.hash;
|
|
40
35
|
const getTracking = event.properties.metadata.tracking;
|
|
41
36
|
const isEntry = bootstrap.cache.hashes?.find(hash => hash.tracking === getTracking)
|
|
42
37
|
const isHashed = isEntry?.hashes?.includes(getHash) ?? false;
|
|
43
|
-
const getFeature =
|
|
44
|
-
|
|
38
|
+
const getFeature = features.find(feature => feature.properties.metadata.tracking === getTracking);
|
|
39
|
+
|
|
45
40
|
if (isHashed || event.properties.status_metadata.is_expired) return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
SetHash(event, isEntry)
|
|
42
|
+
|
|
43
|
+
await UpdateNode(event);
|
|
44
|
+
const isNodeFiltering = settings.GlobalSettings.EventFiltering.NodeLocationFiltering
|
|
45
|
+
if (isNodeFiltering && !event.properties.metadata.filtered_proximity && !EnumGlobalFilter.includes(event.properties.event.toLowerCase())) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const isRatelimited = SetTimeoutAction({ identifier: getTracking, interval: 1, max: 1, addTime: true })
|
|
50
|
+
if (!isRatelimited.limited) {
|
|
51
|
+
SetEventEmit({
|
|
52
|
+
event: `onEventStatus`,
|
|
53
|
+
metadata: {
|
|
54
|
+
type: getFeature ? `Updated` : `New`,
|
|
55
|
+
event: event
|
|
56
|
+
},
|
|
57
|
+
message: `[${getFeature ? 'Updated' : 'New'}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
|
|
58
|
+
})
|
|
59
|
+
}
|
|
49
60
|
|
|
50
|
-
setEventEmit({
|
|
51
|
-
event: `onEventStatus`,
|
|
52
|
-
metadata: {
|
|
53
|
-
type: getFeature ? `Updated` : `New`,
|
|
54
|
-
event: event
|
|
55
|
-
},
|
|
56
|
-
message: `[${getFeature ? 'Updated' : 'New'}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
|
|
57
|
-
})
|
|
58
61
|
if (settings.GlobalSettings.EventManagement) {
|
|
59
62
|
if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
|
|
60
63
|
if (getFeature) {
|
|
@@ -67,7 +70,7 @@ export const mkEvent = async (event: TypeEvent): Promise<void> => {
|
|
|
67
70
|
const iLocations = event.properties?.locations?.split(";").map((l: string) => l.trim()) ?? [];
|
|
68
71
|
const iUgc = event.properties?.geocode?.ugc ?? [];
|
|
69
72
|
|
|
70
|
-
const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i);
|
|
73
|
+
const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i).filter((v, i, a) => a.findIndex(h => h.description === v.description && h.issued === v.issued) === i);
|
|
71
74
|
const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join('; ');
|
|
72
75
|
const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
|
|
73
76
|
|
|
@@ -86,10 +89,11 @@ export const mkEvent = async (event: TypeEvent): Promise<void> => {
|
|
|
86
89
|
},
|
|
87
90
|
}
|
|
88
91
|
};
|
|
92
|
+
await CreateActions(bootstrap.cache.events.features[getIndex])
|
|
89
93
|
} else {
|
|
90
94
|
features.push(event)
|
|
95
|
+
await CreateActions(event)
|
|
91
96
|
}
|
|
92
97
|
}
|
|
93
98
|
}
|
|
94
|
-
updateWebhooks(event)
|
|
95
99
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
|
|
12
|
+
Discord: https://atmosphericx-discord.scriptkitty.cafe
|
|
13
|
+
Ko-Fi: https://ko-fi.com/k3yomi
|
|
14
|
+
Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
|
|
15
|
+
|
|
16
|
+
Internal Package: @atmosx/event-product-parser
|
|
17
|
+
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { TypeEvent } from "../@types/Event";
|
|
21
|
+
import { EnumStrings } from "../@enums/Strings";
|
|
22
|
+
import { bootstrap } from "../bootstrap"
|
|
23
|
+
import { SetEventEmit } from "../@modules/@utilities/SetEventEmit";
|
|
24
|
+
import { SetTimeoutAction } from "../@modules/@utilities/SetTimeoutAction";
|
|
25
|
+
import { CreateActions } from "./CreateActions";
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
export const RemoveEvent = async (event: TypeEvent, isTimeBasedExpiration: boolean):Promise<void> => {
|
|
29
|
+
const gTracking = event.properties.metadata.tracking;
|
|
30
|
+
const isTrackingEventLogged = bootstrap.cache.events.features
|
|
31
|
+
.find(f => f?.properties?.metadata?.tracking === gTracking);
|
|
32
|
+
const isStatement = event.properties.status_metadata.is_statement;
|
|
33
|
+
|
|
34
|
+
if (isTrackingEventLogged) {
|
|
35
|
+
event.properties.expires = new Date().toISOString();
|
|
36
|
+
event.properties.status = `Expired`;
|
|
37
|
+
event.properties.status_metadata.is_expired = true;
|
|
38
|
+
|
|
39
|
+
const description = isTimeBasedExpiration ? EnumStrings.cancellation
|
|
40
|
+
.replace(`{SENDER}`, event.properties.geocode.office.name)
|
|
41
|
+
.replace(`{EVENT}`, event.properties.event) : event.properties.description
|
|
42
|
+
event.properties.description = description;
|
|
43
|
+
event.properties.metadata.raw = isTimeBasedExpiration ? description : event.properties.metadata.raw;
|
|
44
|
+
event.properties.metadata.history.push({
|
|
45
|
+
description: isTimeBasedExpiration ? description : event.properties.description,
|
|
46
|
+
issued: event.properties.expires,
|
|
47
|
+
status: event.properties.status
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
bootstrap.cache.events.features
|
|
51
|
+
.splice(bootstrap.cache.events.features.indexOf(isTrackingEventLogged), 1);
|
|
52
|
+
bootstrap.cache.hashes = bootstrap.cache.hashes
|
|
53
|
+
.filter(hash => hash.tracking !== gTracking);
|
|
54
|
+
|
|
55
|
+
if (!isStatement) {
|
|
56
|
+
SetEventEmit({
|
|
57
|
+
event: `onEventStatus`,
|
|
58
|
+
metadata: { type: `Removed`, event: event },
|
|
59
|
+
message: `[Removed] ${event.properties.event} (${event.properties.status}) (${gTracking})`
|
|
60
|
+
})
|
|
61
|
+
await CreateActions(event)
|
|
62
|
+
}
|
|
63
|
+
SetTimeoutAction({ identifier: gTracking, expire: true })
|
|
64
|
+
}
|
|
65
|
+
SetEventEmit({
|
|
66
|
+
event: `onEventCache`,
|
|
67
|
+
metadata: bootstrap.cache.events,
|
|
68
|
+
limited: true
|
|
69
|
+
})
|
|
70
|
+
}
|
|
@@ -17,21 +17,20 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeEvent } from "../@types/
|
|
21
|
-
import { TypeHash } from "../@types/
|
|
20
|
+
import { TypeEvent } from "../@types/Event";
|
|
21
|
+
import { TypeHash } from "../@types/Hash"
|
|
22
22
|
import { bootstrap } from "../bootstrap"
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (entry) {
|
|
27
|
-
entry.hashes.push(event.properties.metadata.hash);
|
|
28
|
-
entry.expires = event.properties.expires;
|
|
29
|
-
} else {
|
|
24
|
+
export const SetHash = (event: TypeEvent, entry: TypeHash): void => {
|
|
25
|
+
if (!entry) {
|
|
30
26
|
bootstrap.cache.hashes.push({
|
|
31
27
|
tracking: event.properties.metadata.tracking,
|
|
32
28
|
hashes: [event.properties.metadata.hash],
|
|
33
29
|
expires: event.properties.expires
|
|
34
30
|
});
|
|
31
|
+
return;
|
|
35
32
|
}
|
|
36
|
-
|
|
33
|
+
|
|
34
|
+
entry.hashes.push(event.properties.metadata.hash);
|
|
35
|
+
entry.expires = event.properties.expires;
|
|
37
36
|
}
|
|
@@ -17,19 +17,19 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
import { TypeEvent } from "../@types/type.event";
|
|
20
|
+
import { TypeEvent } from "../@types/Event";
|
|
22
21
|
import { bootstrap } from "../bootstrap"
|
|
23
|
-
import {
|
|
22
|
+
import { SetEventEmit } from "../@modules/@utilities/SetEventEmit";
|
|
23
|
+
import { RemoveEvent } from "./RemoveEvent";
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
export const updateEvents = async (selectedEvent?: TypeEvent): Promise<void> => {
|
|
25
|
+
export const UpdateEvents = async (selectedEvent?: TypeEvent): Promise<void> => {
|
|
27
26
|
const events = bootstrap.cache.events.features;
|
|
28
|
-
async function update(
|
|
29
|
-
if (new Date(
|
|
30
|
-
|
|
27
|
+
async function update(event: TypeEvent) {
|
|
28
|
+
if (new Date(event.properties.expires) < new Date()) {
|
|
29
|
+
SetEventEmit({ event: `onExpiredProduct`, metadata: event })
|
|
30
|
+
await RemoveEvent(event, true)
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
if (!selectedEvent) { await Promise.all(events.map(async (
|
|
33
|
+
if (!selectedEvent) { await Promise.all(events.map(async (event) => { await update(event) })) }
|
|
34
34
|
if (selectedEvent) { await update(selectedEvent) }
|
|
35
35
|
}
|
|
@@ -17,34 +17,41 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
import { setEventEmit } from "../@modules/@utilities/utilities.setEventEmit";
|
|
22
|
-
import { TypeEvent } from "../@types/type.event";
|
|
20
|
+
import { TypeEvent } from "../@types/Event";
|
|
23
21
|
import { bootstrap } from "../bootstrap"
|
|
22
|
+
import { GetEventNodes } from "../@building/GetEventNodes";
|
|
23
|
+
import { SetEventEmit } from "../@modules/@utilities/SetEventEmit";
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
export const updateNode = async (selectedEvent?: TypeEvent): Promise<void> => {
|
|
25
|
+
export const UpdateNode = async (selectedEvent?: TypeEvent): Promise<void> => {
|
|
27
26
|
const events = bootstrap.cache.events.features;
|
|
28
27
|
const ttl = bootstrap.settings.GlobalSettings.NodeTTL * 1e3;
|
|
29
28
|
let total = 0;
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
const TTLEvents = selectedEvent ? [selectedEvent] : events.filter((evt) => {
|
|
32
31
|
const lastUpdate = evt?.properties?.metadata?.updated ?? null;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
return lastUpdate == null || (Date.now() - lastUpdate) >= ttl;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (TTLEvents.length === 0) return;
|
|
36
|
+
|
|
37
|
+
async function update(evt: TypeEvent) {
|
|
38
|
+
const node = await GetEventNodes(evt);
|
|
37
39
|
if (node.nodes.length > 0) {
|
|
38
|
-
total
|
|
40
|
+
total++;
|
|
39
41
|
}
|
|
40
|
-
evt.properties.metadata.nodes = node.nodes
|
|
41
|
-
evt.properties.metadata.filtered_proximity = node.filtered
|
|
42
|
-
evt.properties.metadata.updated = node.updated
|
|
42
|
+
evt.properties.metadata.nodes = node.nodes;
|
|
43
|
+
evt.properties.metadata.filtered_proximity = node.filtered;
|
|
44
|
+
evt.properties.metadata.updated = node.updated;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const concurrency = 4;
|
|
48
|
+
for (let index = 0; index < TTLEvents.length; index += concurrency) {
|
|
49
|
+
const batch = TTLEvents.slice(index, index + concurrency);
|
|
50
|
+
await Promise.all(batch.map((evt) => update(evt)));
|
|
43
51
|
}
|
|
44
|
-
|
|
45
|
-
if (selectedEvent) { await update(selectedEvent) }
|
|
52
|
+
|
|
46
53
|
if (total > 0) {
|
|
47
|
-
|
|
54
|
+
SetEventEmit({
|
|
48
55
|
event: `onNodeUpdate`,
|
|
49
56
|
metadata: {
|
|
50
57
|
type: `global-update`,
|
|
@@ -17,19 +17,20 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeSettings } from "../../@types/
|
|
20
|
+
import { TypeSettings } from "../../@types/Settings"
|
|
21
21
|
import { bootstrap } from '../../bootstrap'
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
22
|
+
import { SetWarning } from '../@utilities/SetWarning';
|
|
23
|
+
import { CreateEvent } from '../../@building/CreateEvent';
|
|
24
|
+
import { ValidateEvents } from "../../@building/ValidateEvents";
|
|
24
25
|
|
|
25
|
-
export const
|
|
26
|
+
export const GetCachedEvents = async (): Promise<void> => {
|
|
26
27
|
try {
|
|
27
28
|
const settings = bootstrap.settings as TypeSettings;
|
|
28
29
|
const tick = performance.now();
|
|
29
30
|
if (settings.NOAAWeatherWireServiceSettings.CacheSettings.Enabled) {
|
|
30
31
|
const max = settings.NOAAWeatherWireServiceSettings.CacheSettings.MaxRetentionHistory ?? 500;
|
|
31
32
|
const get = await bootstrap.database.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(max) as { rowid: number; stanza: string }[];
|
|
32
|
-
|
|
33
|
+
SetWarning({ message: `Fetched ${get.length} cached stanzas from the database in ${Math.floor(performance.now() - tick)} ms` })
|
|
33
34
|
let events = get.map((row) => JSON.parse(row.stanza))
|
|
34
35
|
.filter(stanza => {
|
|
35
36
|
if (!stanza) { return }
|
|
@@ -39,10 +40,11 @@ export const getCachedEvents = async (): Promise<void> => {
|
|
|
39
40
|
return !isSkippable
|
|
40
41
|
});
|
|
41
42
|
events = events.sort((a, b) => b.issued - a.issued)
|
|
42
|
-
await Promise.all(events.map(event =>
|
|
43
|
-
|
|
43
|
+
await Promise.all(events.map(event => CreateEvent(event, true)))
|
|
44
|
+
SetWarning({ message: `Processed ${events.length} cached stanzas in ${Math.floor(performance.now() - tick)} ms` })
|
|
45
|
+
await ValidateEvents(bootstrap.cache.processed)
|
|
44
46
|
}
|
|
45
47
|
} catch (error) {
|
|
46
|
-
|
|
48
|
+
SetWarning({ message: `An error occurred while fetching cached stanzas: ${error.message} -> ${error.stack}` })
|
|
47
49
|
}
|
|
48
50
|
}
|