@atmosx/event-product-parser 3.0.6 → 3.0.7

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.
Files changed (181) hide show
  1. package/.github/docs/docs-functions.md +2 -2
  2. package/.github/docs/docs-general-configurations.md +2 -12
  3. package/.github/docs/docs-integrations.md +4 -3
  4. package/.github/docs/docs-listeners.md +1 -1
  5. package/.github/docs/docs-source-configuration.md +1 -1
  6. package/.github/docs/docs-technical.md +1 -1
  7. package/{.github/README.md → README.md} +15 -9
  8. package/dist/cjs/index.cjs +24073 -7018
  9. package/dist/esm/index.mjs +24035 -6983
  10. package/package.json +56 -47
  11. package/pnpm-workspace.yaml +4 -0
  12. package/src/bootstrap.ts +64 -48
  13. package/src/{@building → building}/CreateEvent.ts +22 -24
  14. package/src/{@building → building}/GetCleanedEvent.ts +2 -2
  15. package/src/{@building → building}/GetEventAttachments.ts +14 -12
  16. package/src/building/GetEventDirection.ts +28 -0
  17. package/src/{@building → building}/GetEventEnhancedName.ts +5 -8
  18. package/src/{@building → building}/GetEventGeometry.ts +19 -13
  19. package/src/{@building → building}/GetEventHeader.ts +13 -13
  20. package/src/{@building → building}/GetEventNodes.ts +21 -19
  21. package/src/{@building → building}/GetEventOffice.ts +13 -13
  22. package/src/building/GetEventProperties.ts +105 -0
  23. package/src/{@building → building}/GetEventSignature.ts +9 -9
  24. package/src/{@building → building}/GetEventTags.ts +3 -3
  25. package/src/building/GetEventTheme.ts +26 -0
  26. package/src/building/GetEventTracking.ts +64 -0
  27. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  28. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  29. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  30. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  31. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  32. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  33. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  34. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +17 -10
  35. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  36. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  37. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  38. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  39. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  40. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  41. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  42. package/src/{@modules/@utilities/SetWarning.ts → components/database/CreateQuery.ts} +18 -13
  43. package/src/{@modules/@database → components/database}/GetCachedEvents.ts +18 -15
  44. package/src/components/database/ImportBoundaries.ts +168 -0
  45. package/src/{@modules/@database → components/database}/ImportBroadcastify.ts +14 -24
  46. package/src/components/database/ImportCities.ts +87 -0
  47. package/src/{@modules/@database → components/database}/ImportShapefiles.ts +23 -26
  48. package/src/{@modules/@database → components/database}/ImportStanza.ts +15 -19
  49. package/src/components/database/InitializeDatabase.ts +71 -0
  50. package/src/components/images/GenerateGraphic.ts +234 -0
  51. package/src/components/images/components/CreateRectangle.ts +22 -0
  52. package/src/components/images/components/CreateText.ts +22 -0
  53. package/src/components/images/modules/CreateSVG.ts +37 -0
  54. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  55. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  56. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  57. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  58. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  59. package/src/components/images/modules/GetSVGPath.ts +53 -0
  60. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  61. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  62. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  63. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  64. package/src/{@modules/@utilities → components/utilities}/GetFormattedTime.ts +2 -2
  65. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  66. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  67. package/src/{@modules/@utilities → components/utilities}/GetShapeNearestPoint.ts +24 -19
  68. package/src/components/utilities/GetUnionPolygon.ts +36 -0
  69. package/src/components/utilities/QueueManager.ts +70 -0
  70. package/src/{@modules/@utilities → components/utilities}/SetCronSchedule.ts +29 -25
  71. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +12 -12
  72. package/src/components/utilities/SetEventEmit.ts +42 -0
  73. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  74. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  75. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  76. package/src/components/utilities/SetWarning.ts +47 -0
  77. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  78. package/src/{@core/CreateListener.ts → components/xmpp/ErrorXMPP.ts} +8 -5
  79. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  80. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  81. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  82. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +25 -25
  83. package/src/{@core → core}/ClearEvents.ts +9 -9
  84. package/src/{@core → core}/GetEvents.ts +4 -4
  85. package/src/{@core → core}/GetNodes.ts +4 -4
  86. package/src/{@core → core}/GetRandomEvent.ts +4 -4
  87. package/src/{@core → core}/GetVersion.ts +4 -4
  88. package/src/{@core → core}/ManualEvent.ts +23 -24
  89. package/src/{@core → core}/QueryStanza.ts +12 -11
  90. package/src/core/SetNode.ts +87 -0
  91. package/src/{@core → core}/StartService.ts +21 -20
  92. package/src/{@core → core}/StopService.ts +10 -10
  93. package/src/{@enums → enums}/AWIPS.ts +2 -2
  94. package/src/{@enums → enums}/Actions.ts +2 -2
  95. package/src/{@enums → enums}/Cancellation.ts +2 -2
  96. package/src/{@enums → enums}/Causes.ts +2 -2
  97. package/src/{@enums → enums}/Correlations.ts +2 -2
  98. package/src/{@enums → enums}/Enhanced.ts +2 -2
  99. package/src/{@enums → enums}/Events.ts +2 -2
  100. package/src/{@enums → enums}/Expressions.ts +3 -3
  101. package/src/{@enums → enums}/GlobalFilter.ts +2 -2
  102. package/src/{@enums → enums}/Hail.ts +2 -2
  103. package/src/{@enums → enums}/ICAO.ts +2 -2
  104. package/src/{@enums → enums}/Matches.ts +8 -3
  105. package/src/{@enums → enums}/Products.ts +2 -2
  106. package/src/{@enums → enums}/Records.ts +2 -2
  107. package/src/{@enums → enums}/Severity.ts +2 -2
  108. package/src/{@enums → enums}/Shapefiles.ts +2 -2
  109. package/src/{@enums → enums}/States.ts +68 -4
  110. package/src/{@enums → enums}/Status.ts +2 -2
  111. package/src/{@enums → enums}/Strings.ts +2 -2
  112. package/src/{@enums → enums}/Tags.ts +9 -4
  113. package/src/{@enums → enums}/Testing.ts +2 -2
  114. package/src/enums/Themes.ts +70 -0
  115. package/src/events/ParseAPI.ts +129 -0
  116. package/src/{@events → events}/ParseText.ts +24 -22
  117. package/src/{@events → events}/ParseUGC.ts +27 -26
  118. package/src/{@events → events}/ParseVTEC.ts +38 -37
  119. package/src/index.ts +57 -37
  120. package/src/manager/MakeEvents.ts +110 -0
  121. package/src/manager/RemoveEvent.ts +74 -0
  122. package/src/{@manager → manager}/SetHash.ts +18 -13
  123. package/src/{@manager → manager}/UpdateEvents.ts +12 -12
  124. package/src/{@manager → manager}/UpdateNode.ts +14 -14
  125. package/src/{@building → manager}/ValidateEvents.ts +47 -57
  126. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +11 -11
  127. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  128. package/src/{@parsers/@text → parsers/text}/GetEmbededText.ts +7 -6
  129. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  130. package/src/{@parsers/@text → parsers/text}/GetStringText.ts +9 -9
  131. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  132. package/src/parsers/ugc/GetCache.ts +24 -0
  133. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  134. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  135. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  136. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  137. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  138. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  139. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  140. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  141. package/src/parsers/vtec/VTECExtract.ts +49 -0
  142. package/src/{@types → static}/Attributes.ts +2 -3
  143. package/src/{@types → static}/Event.ts +8 -7
  144. package/src/{@types → static}/Properties.ts +7 -3
  145. package/src/{@types → static}/Stanza.ts +2 -2
  146. package/src/tasks/CreateTasks.ts +123 -0
  147. package/src/tasks/TaskGenerateJSON.ts +34 -0
  148. package/src/tasks/TaskGenerateText.ts +34 -0
  149. package/src/tasks/TaskSendNTFY.ts +97 -0
  150. package/src/tasks/TaskSendWebhook.ts +107 -0
  151. package/src/{@types → types}/Actions.ts +3 -3
  152. package/src/{@types → types}/HVTEC.ts +6 -6
  153. package/src/{@types → types}/Hash.ts +5 -5
  154. package/src/types/Nodes.ts +29 -0
  155. package/src/{@types → types}/Settings.ts +16 -8
  156. package/src/{@types → types}/StanzaCompiled.ts +15 -15
  157. package/src/{@types → types}/UGC.ts +5 -5
  158. package/src/{@modules/@utilities/GetSettings.ts → types/VTEC.ts} +12 -7
  159. package/tools/build.js +47 -0
  160. package/tsconfig.json +28 -1
  161. package/src/@building/GetEventProperties.ts +0 -96
  162. package/src/@building/GetEventTracking.ts +0 -68
  163. package/src/@core/SetNode.ts +0 -81
  164. package/src/@events/ParseAPI.ts +0 -117
  165. package/src/@manager/CreateActions.ts +0 -213
  166. package/src/@manager/MakeEvent.ts +0 -99
  167. package/src/@manager/RemoveEvent.ts +0 -70
  168. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  169. package/src/@modules/@eas/GenerateEASMessage.ts +0 -144
  170. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  171. package/src/@modules/@utilities/SetListener.ts +0 -30
  172. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  173. package/src/@modules/@xmpp/ErrorXMPP.ts +0 -27
  174. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  175. package/src/@parsers/@pvtec/VTECExtract.ts +0 -49
  176. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  177. package/src/@parsers/@text/GetXML.ts +0 -61
  178. package/src/@parsers/@ugc/GetCache.ts +0 -24
  179. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  180. package/src/@types/VTEC.ts +0 -30
  181. package/tsup.config.ts +0 -16
@@ -1,213 +0,0 @@
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
- }
@@ -1,99 +0,0 @@
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 { TypeSettings } from "../@types/Settings";
22
- import { EnumGlobalFilter } from "../@enums/GlobalFilter";
23
- import { bootstrap } from "../bootstrap"
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";
29
-
30
- export const MakeEvent = async (event: TypeEvent): Promise<void> => {
31
- const settings = bootstrap.settings as TypeSettings;
32
- const features = bootstrap.cache.events.features;
33
-
34
- const getHash = event.properties.metadata.hash;
35
- const getTracking = event.properties.metadata.tracking;
36
- const isEntry = bootstrap.cache.hashes?.find(hash => hash.tracking === getTracking)
37
- const isHashed = isEntry?.hashes?.includes(getHash) ?? false;
38
- const getFeature = features.find(feature => feature.properties.metadata.tracking === getTracking);
39
-
40
- if (isHashed || event.properties.status_metadata.is_expired) return
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
- }
60
-
61
- if (settings.GlobalSettings.EventManagement) {
62
- if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
63
- if (getFeature) {
64
- const getIndex = features.indexOf(getFeature);
65
- const cHistory = getFeature?.properties?.metadata?.history ?? [];
66
- const cLocations = getFeature?.properties?.locations?.split(";").map((l: string) => l.trim()) ?? [];
67
- const cUgc = getFeature?.properties?.geocode?.ugc ?? [];
68
-
69
- const iHistory = event.properties?.metadata?.history ?? [];
70
- const iLocations = event.properties?.locations?.split(";").map((l: string) => l.trim()) ?? [];
71
- const iUgc = event.properties?.geocode?.ugc ?? [];
72
-
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);
74
- const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join('; ');
75
- const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
76
-
77
- bootstrap.cache.events.features[getIndex] = {
78
- ...event,
79
- properties: {
80
- ...event.properties,
81
- metadata: {
82
- ...event?.properties?.metadata,
83
- history: mHistory
84
- },
85
- locations: mLocations,
86
- geocode: {
87
- ...event?.properties?.geocode,
88
- ugc: mUgc
89
- },
90
- }
91
- };
92
- await CreateActions(bootstrap.cache.events.features[getIndex])
93
- } else {
94
- features.push(event)
95
- await CreateActions(event)
96
- }
97
- }
98
- }
99
- }
@@ -1,70 +0,0 @@
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
- }
@@ -1,59 +0,0 @@
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
-
21
- import { TypeSettings } from "../../@types/Settings"
22
- import { bootstrap } from "../../bootstrap"
23
- import { SetWarning } from '../@utilities/SetWarning'
24
- import { ImportShapefiles } from './ImportShapefiles'
25
- import { ImportBroadcastify } from "./ImportBroadcastify"
26
- import { existsSync, writeFileSync } from "fs"
27
- import sqlite3 from 'better-sqlite3'
28
-
29
- export const InitializeDatabase = async (): Promise<void> => {
30
- const settings = bootstrap.settings as TypeSettings;
31
- try {
32
- if (!existsSync(settings.Database)) {
33
- writeFileSync(settings.Database, '')
34
- SetWarning({ message: `Creating new database at ${settings.Database}` })
35
- }
36
- bootstrap.database = new sqlite3(settings.Database);
37
- bootstrap.database
38
- .prepare(`CREATE TABLE IF NOT EXISTS stanzas ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, issued TEXT, stanza TEXT )`)
39
- .run();
40
- bootstrap.database
41
- .prepare(`CREATE TABLE IF NOT EXISTS shapefiles (id TEXT PRIMARY KEY, location TEXT, geometry TEXT)`)
42
- .run();
43
- const isNeedingShapefiles = bootstrap.database
44
- .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='shapefiles';`)
45
- .get();
46
- const isNeedingBroadcastify = bootstrap.database
47
- .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='broadcastify';`)
48
- .get();
49
-
50
- if (!isNeedingShapefiles || !isNeedingBroadcastify) {
51
- SetWarning({message: `Required database tables are currently building, please ${bootstrap.ansi_colors.RED}DO NOT${bootstrap.ansi_colors.RESET} close your terminal. The building will not finish and will remain incomplete. If you do mess up, you will need to delete ${settings.Database} and restart the application.` })
52
- await ImportBroadcastify();
53
- await ImportShapefiles();
54
- SetWarning({ message: `Building has completed, you can now continue or close the terminal`})
55
- }
56
- } catch (error) {
57
- SetWarning({ message: `An error occurred while initializing the database: ${error.message}` })
58
- }
59
- }
@@ -1,144 +0,0 @@
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 { bootstrap } from "../../bootstrap";
22
- import { SetWarning } from "../@utilities/SetWarning";
23
- import { GetWavPCM16 } from "./GetWavPCM16";
24
- import { GetSampledPCM16 } from "./GetSampledPCM16";
25
- import { SetRadioEffect } from "./SetRadioEffect";
26
- import { SetSameHeader } from "./SetSameHeader";
27
- import { SetAttentionTone } from "./SetAttentionTone";
28
- import { GetMergedPCM16 } from "./GetMergedPCM16";
29
- import { SetNoise } from "./SetNoise";
30
- import { GetPCM16 } from "./GetPCM16";
31
- import { GetTTS } from "./GetTTS";
32
- import { GetCleanDescription } from "./GetCleanDescription";
33
- import { SetDebug } from "../@utilities/SetDebug";
34
- import { join } from 'path'
35
- import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs'
36
- import { execSync } from 'child_process'
37
- import { platform } from 'os'
38
-
39
-
40
- interface GenerateEASMessageOptions {
41
- message: string
42
- header: string
43
- title: string
44
- }
45
-
46
- export const GenerateEASMessage = async (options: GenerateEASMessageOptions): Promise<string> => {
47
- const tick = performance.now()
48
- const settings = bootstrap.settings as TypeSettings;
49
- const directory = settings.GlobalSettings.ArchiveSettings.EasDirectory;
50
- const prefix = settings.GlobalSettings.ArchiveSettings.EasToneout;
51
- let message = options.message;
52
- let header = options.header;
53
- let title = (options.title ?? `${Math.random().toString(36).substring(2, 15)}-${header.replace(/[^a-zA-Z0-9]/g, '')}`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
54
- if (!message || !header) {
55
- SetWarning({
56
- title: `EAS`,
57
- message: `Message and header are required to generate an EAS tone.`
58
- })
59
- return null;
60
- }
61
- let buffTTS: Buffer;
62
- let buffRadio: any;
63
- let buffFull: any[] = [];
64
-
65
- if (!existsSync(directory)) {
66
- mkdirSync(directory, { recursive: true });
67
- }
68
- const tmpTTS = join(directory, `/${title}-tts.wav`)
69
- const outTTS = join(directory, `/${title}.wav`)
70
- const vPlatform = platform();
71
-
72
- if (vPlatform === 'darwin') {
73
- SetWarning({
74
- title: `EAS`,
75
- message: `EAS tone generation is not supported on macOS.`
76
- });
77
- return null
78
- }
79
-
80
-
81
- await new Promise<void>((resolve, reject) => {
82
- const tMsg = GetCleanDescription(message)
83
- GetTTS(tMsg, tmpTTS).then(() => {
84
- resolve();
85
- });
86
- });
87
- if (!existsSync(tmpTTS)) {
88
- return null;
89
- }
90
- buffTTS = readFileSync(tmpTTS);
91
- const vWav = GetWavPCM16(buffTTS);
92
- const vSamples = GetSampledPCM16(vWav.samples, vWav.sampleRate, 8000)
93
- const vRadio = SetRadioEffect(vSamples, 8000)
94
-
95
- if (existsSync(prefix)) {
96
- let tBuffer = readFileSync(prefix);
97
- let tWav = GetWavPCM16(tBuffer);
98
-
99
- if (tWav == null) {
100
- try {
101
- const converted = join(directory, `/${title}-tts-fixed.wav`)
102
- execSync(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: 'ignore' })
103
- if (existsSync(converted)) {
104
- tBuffer = readFileSync(converted)
105
- tWav = GetWavPCM16(tBuffer)
106
- try { unlinkSync(converted) } catch {}
107
- }
108
- } catch (e) {}
109
- }
110
-
111
- if (tWav == null) {
112
- SetWarning({ title: `EAS`, message: `Intro tone isn't a valid .WAV file or isn't in PCM 16-bit format. Converted attempt failed; please convert it then try again.` })
113
- return null;
114
- }
115
-
116
- const tSamples = (tWav.sampleRate != 8000 ? GetSampledPCM16(tWav.samples, tWav.sampleRate, 8000) : tWav.samples)
117
- buffRadio = SetRadioEffect(tSamples, 8000)
118
- }
119
-
120
- buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8000))] : [];
121
- buffFull.push(
122
- SetSameHeader(header, 3, 8000, {
123
- preMarkSec: 1.1,
124
- gapSec: 0.5,
125
- }),
126
- new Int16Array(Math.floor(0.5 * 8000)),
127
- SetAttentionTone(8, 8000),
128
- new Int16Array(Math.floor(0.5 * 8000)),
129
- vRadio
130
- )
131
- for (let i = 0; i < 3; i++) {
132
- buffFull.push(SetSameHeader(header, 1, 8000, { preMarkSec: 0.5, gapSec: 0.1 }))
133
- buffFull.push(new Int16Array(Math.floor(0.5 * 8000)));
134
- }
135
- const aSamples = GetMergedPCM16(buffFull);
136
- const aFinal = SetNoise(aSamples, 0.002);
137
- const aBuffer = GetPCM16(Array.from(aFinal).map(v => ({ value: v })), 8000);
138
- writeFileSync(outTTS, aBuffer)
139
- try{ unlinkSync(tmpTTS) } catch {}
140
- SetDebug({ title: `GenerateEASMessage`, message: `${Math.round(performance.now() - tick)}ms` })
141
- return outTTS;
142
- }
143
-
144
-
@@ -1,41 +0,0 @@
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 { bootstrap } from "../../bootstrap"
21
- import { SetTimeoutAction } from "./SetTimeoutAction";
22
- import { SetWarning } from "./SetWarning";
23
-
24
- interface SetEventEmitOptions {
25
- event: string
26
- metadata: any
27
- message?: string
28
- limited?: boolean
29
- }
30
-
31
- export const SetEventEmit = (options: SetEventEmitOptions): void => {
32
- if (options.limited) {
33
- const isTimeout = SetTimeoutAction({ identifier: `event.${options.event}`, addTime: true, max: 1, interval: 1 })
34
- if (isTimeout.limited) return;
35
- }
36
- bootstrap.listener.emit(options.event, options.metadata)
37
- if (options.event != `log`) { bootstrap.listener.emit(`*`, {event: options.event, data: options.metadata}) }
38
- if (options.message) {
39
- SetWarning({ message: options.message })
40
- }
41
- }
@@ -1,30 +0,0 @@
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 { bootstrap } from "../../bootstrap"
21
-
22
- interface SetListenerOptions {
23
- event: string,
24
- callback: () => void
25
- }
26
-
27
- export const SetListener = (options: SetListenerOptions): (() => void) => {
28
- bootstrap.listener.on(options.event, options.callback)
29
- return () => { void bootstrap.listener.off(options.event, options.callback) };
30
- }