@atmosx/event-product-parser 3.0.1 → 3.0.3

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.
@@ -20,7 +20,7 @@
20
20
  import { TypeAttributes } from "../@types/types.attributes";
21
21
  import { TypeStanzaCompiled } from "../@types/types.compiled"
22
22
  import { TypeEvent } from "../@types/type.event";
23
- import { eventsOffshore } from "../@dictionaries/dictionaries.eventsOffshore";
23
+ import { eventsMatchText } from "../@dictionaries/dictionaries.eventsMatchText";
24
24
  import { ugcExtract } from "../@parsers/@ugc/ugc.extract";
25
25
  import { properties } from "../@building/building.properties";
26
26
  import { getEventHeader } from "../@building/building.headers";
@@ -41,11 +41,13 @@ export const ugc = async (stanza: TypeStanzaCompiled): Promise<void> => {
41
41
  if (ugc != null ) {
42
42
  const props = properties({ message, attributes, ugc: ugc })
43
43
  const issued = new Date(attributes.issue)
44
- const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1000)
44
+ const expires = new Date(ugc.expires)
45
45
  const header = getEventHeader({properties: props, getType: stanza.getType })
46
- let event = Object.keys(eventsOffshore).find(event => message.toLowerCase().includes(event.toLowerCase()));
46
+ let event = Object.keys(eventsMatchText).find(event => message.toLowerCase().includes(event.toLowerCase()));
47
+ let isStatement = false;
47
48
  if (!event) {
48
49
  event = stanza.getType.type.split(`-`).map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `)
50
+ isStatement = true;
49
51
  }
50
52
  processed.push({
51
53
  type: `Feature`,
@@ -56,9 +58,9 @@ export const ugc = async (stanza: TypeStanzaCompiled): Promise<void> => {
56
58
  properties: {
57
59
  event: event,
58
60
  parent: event,
59
- status: `Issued`,
61
+ status: isStatement ? `Statement` : `Issued`,
60
62
  issued: (!isNaN(issued.getTime())) ? issued.toISOString() : new Date().toISOString(),
61
- expires: (!isNaN(expires.getTime())) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1000).toISOString(),
63
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1000).toISOString() : (!isNaN(expires.getTime())) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1000).toISOString(),
62
64
  ...props,
63
65
  metadata: {
64
66
  ms: performance.now() - tick,
@@ -24,6 +24,9 @@ import { updateWebhooks } from "./manager.updateWebhooks";
24
24
 
25
25
  export const rmEvent = (event: TypeEvent): void => {
26
26
  const getEvent = bootstrap.cache.events.features.find(f => f?.properties?.metadata?.tracking === event?.properties?.metadata?.tracking);
27
+ const cachedStatus = event.properties.status;
28
+ event.properties.expires = new Date().toISOString();
29
+ event.properties.status = `Expired`;
27
30
  if (getEvent) {
28
31
  setEventEmit({
29
32
  event: `onEventStatus`,
@@ -34,7 +37,7 @@ export const rmEvent = (event: TypeEvent): void => {
34
37
  message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
35
38
  })
36
39
  setEventEmit({ event: `onExpiredProduct`, metadata: event })
37
- updateWebhooks(event)
40
+ if (cachedStatus != `Statement`) updateWebhooks(event)
38
41
  bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
39
42
  bootstrap.cache.hashes = bootstrap.cache.hashes.filter(hash => hash.tracking !== event.properties.metadata.tracking);
40
43
  }
@@ -0,0 +1,35 @@
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 { getFormattedTime } from "../@modules/@utilities/utilities.getFormattedTime";
21
+ import { TypeEvent } from "../@types/type.event";
22
+ import { bootstrap } from "../bootstrap"
23
+ import { rmEvent } from "./manager.rmEvent";
24
+
25
+
26
+ export const updateEvents = async (selectedEvent?: TypeEvent): Promise<void> => {
27
+ const events = bootstrap.cache.events.features;
28
+ async function update(evt: TypeEvent) {
29
+ if (new Date(evt.properties.expires) < new Date()) {
30
+ rmEvent(evt);
31
+ }
32
+ }
33
+ if (!selectedEvent) { await Promise.all(events.map(async (evt) => { await update(evt) })) }
34
+ if (selectedEvent) { await update(selectedEvent) }
35
+ }
@@ -32,10 +32,11 @@ interface CreateWebhookOptions {
32
32
  export const createWebhook = async (options: CreateWebhookOptions): Promise<void> => {
33
33
  const event = options.event.properties;
34
34
  const settings = options.webhook;
35
+
35
36
  let body = [
36
37
  event.locations ? `**Locations**: ${event.locations.slice(0,100)}` : null,
37
38
  event.issued ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime()/1000)}:R>` : null,
38
- event.expires ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime()/1000)}:R>` : null,
39
+ event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime()/1000)}:R>` : null,
39
40
  (() => {
40
41
  const val = event.parameters.estimated_wind_gusts ?? null
41
42
  const th = event.parameters.wind_threat ?? null
@@ -50,6 +51,20 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
50
51
  event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
51
52
  event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
52
53
  event.parameters.tornado_threat ? `**Tornado Threat**: ${event.parameters.tornado_threat}` : null,
54
+ event.spc_parameters.spc_max_tornado ? `**Max Tornado Threat**: ${event.spc_parameters.spc_max_tornado}` : null,
55
+ event.spc_parameters.spc_max_hail ? `**Max Hail Threat**: ${event.spc_parameters.spc_max_hail}` : null,
56
+ event.spc_parameters.spc_max_wind ? `**Max Wind Threat**: ${event.spc_parameters.spc_max_wind}` : null,
57
+ event.spc_parameters.spc_watch_issuance ? `**Watch Issuance**: ${event.spc_parameters.spc_watch_issuance}%` : null,
58
+ event.watch_parameters.watch_number ? `**Watch Number**: ${event.watch_parameters.watch_number}` : null,
59
+ event.watch_parameters.strong_tornadoes_probability ? `**Strong Tornadoes Probability**: ${event.watch_parameters.strong_tornadoes_probability}%` : null,
60
+ event.watch_parameters.additional_tornadoes_probability ? `**Additional Tornadoes Probability**: ${event.watch_parameters.additional_tornadoes_probability}%` : null,
61
+ event.watch_parameters.combined_hail_wind_probability ? `**Combined Hail/Wind Probability**: ${event.watch_parameters.combined_hail_wind_probability}%` : null,
62
+ event.watch_parameters.severe_hail_probability ? `**Severe Hail Probability**: ${event.watch_parameters.severe_hail_probability}%` : null,
63
+ event.watch_parameters.hail_2in_probability ? `**Hail ≥2in Probability**: ${event.watch_parameters.hail_2in_probability}%` : null,
64
+ event.watch_parameters.max_hail_in ? `**Max Hail Inches**: ${event.watch_parameters.max_hail_in}` : null,
65
+ event.watch_parameters.severe_wind_probability ? `**Severe Wind Probability**: ${event.watch_parameters.severe_wind_probability}%` : null,
66
+ event.watch_parameters.max_wind_surface ? `**Max Surface Wind**: ${event.watch_parameters.max_wind_surface}` : null,
67
+ event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
53
68
  (event.parameters.tags?.length > 0) ? `**Tags**: ${event.parameters.tags.join(', ')}` : null,
54
69
  (() => {
55
70
  const val = event.geocode?.office?.name ?? `N/A`
@@ -57,8 +72,6 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
57
72
  return (val || th) ? `**Sender**: ${val} ${th ? `(${th})` : ''}` : null;
58
73
  })(),
59
74
  event.metadata?.tracking ? `**Tracking**: ${event.metadata.tracking}` : null,
60
- event.metadata?.vtec?.vtec ? `**VTEC**: ${event.metadata.vtec?.vtec}` : null,
61
- event.metadata?.filtered_proximity != null ? `**Currently in polygon (Node)**: ${event.metadata.filtered_proximity ? 'Yes' : 'No'}` : null,
62
75
  (() => {
63
76
  const desc = (event.description || '').split('\n').map(l => l.trim()).filter(Boolean).join('\n');
64
77
  return desc ? '```' + '\n' + desc + '\n' + '```' : null;
@@ -86,10 +99,12 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
86
99
  content: settings.message ?? "",
87
100
  embeds: [embed]
88
101
  }));
89
- form.append("file", Buffer.from(JSON.stringify({ type: "FeatureCollection", features: [(getCleanedEvent(options.event))] }, null, 2)), {
90
- filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
91
- contentType: "application/json"
92
- });
102
+ if (settings.upload) {
103
+ form.append("file", Buffer.from(JSON.stringify((getCleanedEvent(event)), null, 2)), {
104
+ filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
105
+ contentType: "application/json"
106
+ });
107
+ }
93
108
  await createHttp({
94
109
  url: settings.webhook,
95
110
  timeout: 2000,
@@ -38,6 +38,7 @@ export type TypeEvent = {
38
38
  is_updated?: boolean
39
39
  is_expired?: boolean
40
40
  is_test?: boolean
41
+ is_statement?: boolean
41
42
  }
42
43
  metadata: {
43
44
  ms: number
@@ -21,6 +21,7 @@ export type TypeWebhook = {
21
21
  webhook: string
22
22
  title: string
23
23
  message: string
24
+ upload: boolean
24
25
  rate: number
25
26
  events: string[]
26
27
  }
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.1`,
24
+ version: `3.0.3`,
25
25
  isReady: true,
26
26
  ratelimits: {},
27
27
  session_xmpp: null,
package/src/index.ts CHANGED
@@ -23,7 +23,7 @@ import { getEventGeometry } from "./@building/building.geometry";
23
23
  import { getCleanedEvent } from "./@building/building.clean"
24
24
  import { setEventEmit } from './@modules/@utilities/utilities.setEventEmit';
25
25
  import { setWarning } from './@modules/@utilities/utilities.setWarning';
26
- import { listener } from "./@core/core.listener"
26
+ import { createListener } from "./@core/core.createListener"
27
27
  import { startService } from "./@core/core.start"
28
28
  import { stopService } from "./@core/core.stop"
29
29
  import { setEasTone } from './@modules/@eas/eas.setEasTone';
@@ -31,12 +31,13 @@ import { setNode } from "./@core/core.setNode"
31
31
  import { getEvents } from "./@core/core.getEvents"
32
32
  import { getNodes } from "./@core/core.getNodes"
33
33
  import { getRandomEvent } from './@core/core.getRandomEvent';
34
+ import { clearEvents } from './@core/core.clearEvents';
34
35
 
35
36
  export class Manager {
36
37
  constructor(settings: TypeSettings) { this.trycatch(); startService(settings) }
37
38
 
38
39
  on(event: string, callback: () => void) {
39
- listener(event, callback)
40
+ createListener(event, callback)
40
41
  }
41
42
 
42
43
  trycatch() {
@@ -62,8 +63,8 @@ export class Manager {
62
63
  export default Manager;
63
64
  export type { TypeEvent } from './@types/type.event';
64
65
  export {
65
- setSettings, getEventGeometry,
66
- getCleanedEvent, stopService,
66
+ setSettings, getEventGeometry,
67
+ getCleanedEvent, stopService, clearEvents,
67
68
  startService, setNode, getRandomEvent,
68
69
  getEvents, getNodes, setEasTone
69
70
  }
package/test.js CHANGED
@@ -34,6 +34,7 @@ const NOAAWeatherWireService = new Manager({
34
34
  webhook: "https://discord.com/api/webhooks/XXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
35
35
  title: "AtmosphericX - (Severe Weather Events)",
36
36
  message: `<@user_id>`,
37
+ upload: true,
37
38
  events: [`Severe Thunderstorm Warning`, `Radar Indicated Tornado Warning`],
38
39
  rate: 1,
39
40
  },
@@ -41,6 +42,7 @@ const NOAAWeatherWireService = new Manager({
41
42
  webhook: "https://discord.com/api/webhooks/XXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
42
43
  title: "AtmosphericX - (All Events)",
43
44
  message: `<@user_id>`,
45
+ upload: false,
44
46
  events: [],
45
47
  rate: 5,
46
48
  }