@atmosx/event-product-parser 3.0.53 → 3.0.55

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.
@@ -22,8 +22,8 @@ import { TypeListener } from "../@types/type.listener";
22
22
  import { bootstrap } from "../bootstrap"
23
23
  import { setEasTone } from "../@modules/@eas/eas.setEasTone"
24
24
  import { setTimeoutAction } from "../@modules/@utilities/utilities.setTimeoutAction";
25
- import { getEmebed } from "../@parsers/@text/text.getEmbed";
26
- import { getRaw } from "../@parsers/@text/text.getRaw";
25
+ import { getEmebedText } from "../@parsers/@text/text.getEmbedText";
26
+ import { getStringText } from "../@parsers/@text/text.getStringText";
27
27
  import { getCleanedEvent } from "../@building/building.clean"
28
28
  import { createHttp } from "../@modules/@utilities/utilities.createHttp";
29
29
  import { setDebug } from "../@modules/@utilities/utilities.setDebug";
@@ -50,13 +50,14 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
50
50
  }
51
51
 
52
52
  for (const listener of listeners) {
53
- const events = listener?.events;
54
- const webhook = listener?.webhook;
55
- const uploads = listener?.uploads
53
+ const events = listener?.Events;
54
+ const webhook = listener?.Webhook;
55
+ const notify = listener?.NotificationServer;
56
+ const uploads = listener?.Uploads
56
57
  const isMatched = getMatched(events ?? [], metadata.name)
57
58
 
58
59
  if (events?.length == 0 || isMatched) {
59
- if (uploads?.eas) {
60
+ if (uploads?.EAS) {
60
61
  metadata.eas = await setEasTone({
61
62
  title: `${metadata.name}_${metadata.status}_${metadata.tracking}`,
62
63
  message: metadata.description,
@@ -64,13 +65,13 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
64
65
  });
65
66
  }
66
67
 
67
- if (uploads?.file) {
68
+ if (uploads?.File) {
68
69
  const fDestination = settings.GlobalSettings.ArchiveSettings.TextDirectory;
69
70
  if (fDestination) {
70
- const file = (`${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
71
+ const file = (`${fDestination}/${metadata.name}_${metadata.tracking}.txt`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
71
72
  if (!existsSync(fDestination)) { mkdirSync(fDestination, { recursive: true }); }
72
73
  if (existsSync(file)) {
73
- appendFileSync(file, metadata.raw);
74
+ appendFileSync(file, `${(`\n`).repeat(10)}${metadata.raw}`);
74
75
  } else {
75
76
  writeFileSync(file, metadata.raw);
76
77
  }
@@ -78,50 +79,49 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
78
79
  metadata.file = metadata.raw;
79
80
  }
80
81
 
81
- if (uploads?.event) {
82
+ if (uploads?.JSON) {
82
83
  const eDestination = settings.GlobalSettings.ArchiveSettings.EventDirectory;
83
84
  if (eDestination) {
84
- const file = (`${eDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.json`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
85
+ const file = (`${eDestination}/${metadata.name}_${metadata.tracking}.json`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
85
86
  if (!existsSync(eDestination)) { mkdirSync(eDestination, { recursive: true }); }
86
87
  writeFileSync(file, JSON.stringify(getCleanedEvent(event), null, 2));
87
88
  }
88
89
  metadata.json = JSON.stringify(getCleanedEvent(event), null, 2);
89
90
  }
90
91
 
91
- if (settings.NotifyServer.Enabled && listener?.notify?.enabled && listener?.notify?.topic) {
92
- const auth = settings.NotifyServer.Credentials?.Username && settings.NotifyServer.Credentials?.Password
93
- ? {
94
- username: settings.NotifyServer.Credentials.Username,
95
- password: settings.NotifyServer.Credentials.Password
96
- }
97
- : undefined;
98
- const attachment = metadata.eas && settings.NotifyServer.Attachments ? `${settings.NotifyServer.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : null;
99
- await createHttp({
100
- url: `${settings.NotifyServer.Server.replace(/\/$/, "")}/${listener?.notify?.topic}`,
101
- timeout: 15_000,
102
- method: "POST",
103
- ...(auth && { auth }),
104
- headers: {
105
- "Title": `${metadata.name} (${metadata.status})`,
106
- "Tags": properties.parameters.tags?.join(",") ?? "N/A",
107
- ... (attachment && { "Attach": attachment }),
108
- "Priority": "max",
109
- "Sound": "siren",
110
- },
111
- body: getRaw(event)
112
- })
92
+ if (settings?.NotifyServer?.Enabled && notify?.Enabled && notify?.Topic) {
93
+ const server = settings?.NotifyServer;
94
+ const auth = server?.Credentials?.Username && server?.Credentials?.Password ? { username: settings?.NotifyServer?.Credentials?.Username, password: server?.Credentials?.Password } : undefined;
95
+ const attachment = metadata.eas && server?.Attachments ? `${server?.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : undefined;
96
+ const isRatelimited = setTimeoutAction({ identifier: metadata.tracking + `notify.server`, interval: 1, max: 1, addTime: true })
97
+ if (!isRatelimited.limited) {
98
+ await createHttp({
99
+ url: `${server?.Server?.replace(/\/$/, "")}/${listener?.NotificationServer?.Topic}`,
100
+ timeout: 15_000,
101
+ method: "POST",
102
+ ...(auth && { auth }),
103
+ headers: {
104
+ "Title": `${metadata.name} (${metadata.status})`,
105
+ "Tags": properties.parameters.tags?.join(",") ?? "N/A",
106
+ "Expires": new Date(properties.expires).getTime(),
107
+ "Priority": notify?.Priority ? notify.Priority.toString() : "5",
108
+ ... (attachment && { "Attach": attachment }),
109
+ },
110
+ body: getStringText(event)
111
+ })
112
+ }
113
113
  }
114
114
 
115
- if (webhook?.enabled && webhook?.destination) {
116
- const isRatelimited = setTimeoutAction({ identifier: webhook.destination, interval: (webhook.ratelimit ?? 2) * 2, max: (webhook.ratelimit ?? 2), addTime: true })
115
+ if (webhook?.Enabled && webhook?.Destination) {
116
+ const isRatelimited = setTimeoutAction({ identifier: webhook.Destination, interval: (webhook.Ratelimit ?? 2) * 2, max: (webhook.Ratelimit ?? 2), addTime: true })
117
117
  const form = new FormData();
118
118
  const embed = {
119
119
  title: `${metadata.name} (${metadata.status})`,
120
- description: getEmebed(event),
120
+ description: getEmebedText(event),
121
121
  fields: [],
122
122
  color: 16711680,
123
123
  timestamp: new Date().toISOString(),
124
- footer: { text: webhook.title ?? `AtmosphericX` }
124
+ footer: { text: webhook.Title ?? `AtmosphericX` }
125
125
  };
126
126
 
127
127
  if (isRatelimited.limited) { return }
@@ -146,15 +146,15 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
146
146
  });
147
147
  }
148
148
 
149
- if (uploads?.file) {
149
+ if (uploads?.File) {
150
150
  form.append("fUpload", new Blob([Buffer.from(metadata.file)], {type: "application/text"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.txt`)
151
151
  }
152
152
 
153
- if (uploads?.event) {
153
+ if (uploads?.JSON) {
154
154
  form.append("fUpload2", new Blob([Buffer.from(metadata.json)], {type: "application/json"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.json`)
155
155
  }
156
156
 
157
- if (uploads?.eas) {
157
+ if (uploads?.EAS) {
158
158
  if (metadata.eas) {
159
159
  const file = readFileSync(metadata.eas)
160
160
  form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties.event}_${properties.status}_${properties.metadata.tracking}_eas.mp3`)
@@ -162,13 +162,13 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
162
162
  }
163
163
 
164
164
  form.append("payload_json", JSON.stringify({
165
- username: webhook.title ?? "AtmosphericX",
166
- content: webhook.message ?? "",
165
+ username: webhook.Title ?? "AtmosphericX",
166
+ content: webhook.Message ?? "",
167
167
  embeds: [embed]
168
168
  }));
169
169
 
170
170
  await createHttp({
171
- url: webhook.destination,
171
+ url: webhook.Destination,
172
172
  timeout: 15e3,
173
173
  method: `POST`,
174
174
  body: form
@@ -41,6 +41,7 @@ export const setTimeoutAction = (options: SetTimeoutActionOptions): SetTimeoutAc
41
41
  }
42
42
  if (options?.expire) {
43
43
  delete bootstrap.ratelimits[options?.identifier];
44
+ return { limited: false };
44
45
  }
45
46
  if (target?.length > 0) {
46
47
  bootstrap.ratelimits[options?.identifier] = target.filter((ts: number) => Date.now() - ts < options?.interval * 1000);
@@ -19,7 +19,7 @@
19
19
 
20
20
  import { TypeEvent } from "../../@types/type.event"
21
21
 
22
- export const getEmebed = (event: TypeEvent): string => {
22
+ export const getEmebedText = (event: TypeEvent): string => {
23
23
  const line = (label: string, value: unknown, condition = true) => condition && value ? `${label} ${value}` : null;
24
24
  const isStatement = event.properties.status_metadata.is_statement;
25
25
  const isExpired = event.properties.status_metadata.is_expired;
@@ -19,7 +19,7 @@
19
19
 
20
20
  import { TypeEvent } from "../../@types/type.event"
21
21
 
22
- export const getRaw = (event: TypeEvent): string => {
22
+ export const getStringText = (event: TypeEvent): string => {
23
23
  const line = (label: string, value: unknown, condition = true) => condition && value ? `${label} ${value}` : null;
24
24
  const isStatement = event.properties.status_metadata.is_statement;
25
25
  const isExpired = event.properties.status_metadata.is_expired;
@@ -18,20 +18,21 @@
18
18
  */
19
19
 
20
20
  export type TypeListener = {
21
- events: string[]
22
- webhook?: {
23
- enabled: boolean
24
- destination: string
25
- ratelimit: number
26
- title: string
27
- message: string
21
+ Events: string[]
22
+ Webhook?: {
23
+ Enabled: boolean
24
+ Destination: string
25
+ Ratelimit: number
26
+ Title: string
27
+ Message: string
28
28
  }
29
- notify?: {
30
- enabled: boolean
31
- topic: string
29
+ NotificationServer?: {
30
+ Enabled: boolean
31
+ Topic: string
32
+ Priority?: 1 | 2 | 3 | 4 | 5 | void
32
33
  }
33
- uploads?: {
34
- file?: boolean, eas?: boolean, event?: boolean
34
+ Uploads?: {
35
+ File?: boolean, EAS?: boolean, JSON?: boolean
35
36
  }
36
37
 
37
38
  }
package/src/bootstrap.ts CHANGED
@@ -21,7 +21,7 @@ import path from 'path'
21
21
  import { EventEmitter } from 'node:events';
22
22
 
23
23
  export const bootstrap = {
24
- version: `3.0.53`,
24
+ version: `3.0.55`,
25
25
  isReady: true,
26
26
  ratelimits: {},
27
27
  session_xmpp: null,
package/testing/init.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { Manager } = require(`../dist/cjs/index.cjs`)
2
2
 
3
3
  const Client = new Manager({
4
- Database: `shapefiles.db`,
4
+ Database: `event-product-parser.db`,
5
5
  EnableWireService: false,
6
6
  EnableJournal: true,
7
7
  EnableDebugging: false,
@@ -17,8 +17,8 @@ const Client = new Manager({
17
17
  },
18
18
  CacheSettings: {
19
19
  Enabled: true,
20
- MaxDatabaseHistory: 5000,
21
- MaxRetentionHistory: 555,
20
+ MaxDatabaseHistory: 50000,
21
+ MaxRetentionHistory: 1500,
22
22
  },
23
23
  StanzaSettings: {
24
24
  DisableUGC: false,
@@ -32,12 +32,13 @@ const Client = new Manager({
32
32
  },
33
33
  BroadcastifySettings: {
34
34
  BroadcastifyAttachments: true,
35
+ BroadcastifyDatabase: `https://scriptkitty.cafe/ftp/@atmosphericx/assets/broadcastify.json`,
35
36
  BroadcastifyTags: [`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`]
36
37
  },
37
38
  NotifyServer: {
38
39
  Enabled: false,
39
- Server: "https://ntfy.domainname.com",
40
- Attachments: "https://domainname.com/Storage/EasScenarios",
40
+ Server: "https://ntfy.scriptkitty.cafe",
41
+ Attachments: "https://scriptkitty.cafe/ftp/@bucket/EAS/encoded",
41
42
  Credentials: {
42
43
  Username: "username",
43
44
  Password: "password"
@@ -45,22 +46,16 @@ const Client = new Manager({
45
46
  },
46
47
  ListenerSettings: [
47
48
  {
48
- events: [`*Thunderstorm Warning*`, `* Watch`],
49
- webhook: {
50
- enabled: true,
51
- destination: "https://discord.com/api/XXXXXXXXXX/XXXXXXXXXXX",
52
- title: "AtmosphericX - (Thunderstorm Warnings and Watches)",
53
- message: "<@&XXXXXXXXXXXXXXXXXXXXX>",
54
- ratelimit: 1
49
+ Events: ["*Extreme Heat Warning*"],
50
+ NotificationServer: {
51
+ Enabled: false,
52
+ Topic: "heat-warnings",
53
+ Priority: 5
55
54
  },
56
- notify: {
57
- enabled: false,
58
- topic: "thunderstorm_events",
59
- },
60
- uploads: {
61
- eas: true,
62
- file: true,
63
- event: true
55
+ Uploads: {
56
+ EAS: true,
57
+ File: true,
58
+ JSON: true
64
59
  }
65
60
  }
66
61
  ],
@@ -72,35 +67,25 @@ const Client = new Manager({
72
67
  SPCWatchesOnly: true,
73
68
  ShapefileSkipPoints: 0,
74
69
  NodeTTL: 60,
75
- NodeMinDistance: 120,
70
+ NodeMinDistance: 125,
76
71
  EventFiltering: {
77
72
  ListeningEvents: [
78
- "*Severe Thunderstorm Warning*",
79
- "*Blizzard*", "*Ice Storm*", "*Winter Storm*", "*Snow Squall*",
80
- "Tornado Emergency", "*Tornado Warning*",
81
- "Special Weather Statement", "Marine Weather Statement",
82
- "*Tsunami*", "*Hurricane*", "*Tropical Storm*", "*Special Marine*",
83
- "*Flash Flood Warning*", "*Flash Flood Watch*", "*Flash Flood Advisory*",
84
- "Mesoscale Discussion",
85
- "*Storm Prediction Center*",
86
- "PDS Tornado Watch", "Tornado Watch", "Severe Thunderstorm Watch", "Flash Flood Watch", "PDS Severe Thunderstorm Watch",
87
- "*Administrative*", "National Weather Service Policy",
88
- "Fire Weather Warning", "Fire Weather Watch", "Fire Weather Advisory",
73
+ "*Warning*"
89
74
  ],
90
- ListeningICAO: [`KLOT`],
75
+ ListeningICAO: [],
76
+ ListeningUGC: [],
77
+ ListeningStates: [],
91
78
  IgnoredICAO: [],
92
79
  IgnoredEvents: [],
93
- ListeningUGC: [`WIC001`],
94
- ListeningStates: [`MO`, `IA`],
95
80
  NodeLocationFiltering: false,
96
81
  IgnoreTestProducts: true,
97
82
  },
98
83
  ArchiveSettings: {
99
- TTL: 600,
100
- EventDirectory: `Storage/EventProducts`,
101
- TextDirectory: `Storage/TextProducts`,
102
- EasDirectory: `Storage/EasScenarios`,
103
- EasToneout: `tone.wav`,
84
+ TTL: 30,
85
+ EventDirectory: `@bucket/ParsedProducts`,
86
+ TextDirectory: `@bucket/RawTextProducts`,
87
+ EasDirectory: `@bucket/EAS`,
88
+ EasToneout: `eas-toneout.wav`,
104
89
  }
105
90
  }
106
- })
91
+ })