@atmosx/event-product-parser 3.0.46 → 3.0.48

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.
@@ -35,7 +35,6 @@ export const importShapefiles = async (): Promise<void> => {
35
35
  .get().count;
36
36
  if (tShapefiles === 0) {
37
37
  await setSleep({timeout: 1e3});
38
- setWarning({ message: `Shapefiles are currently building, please DO NOT close your terminal. The shapefiles will not finish and will remain incomplete. If you do mess up, you will need to delete ${settings.Database} and restart the application.` })
39
38
  for (const shapefile of dict_shapefiles) {
40
39
  const response = await fetch(shapefile.link);
41
40
  const arrayBuff = await response.arrayBuffer();
@@ -56,7 +55,7 @@ export const importShapefiles = async (): Promise<void> => {
56
55
  filepath,
57
56
  filepath,
58
57
  );
59
- setWarning({ message: `Importing ${features.length} features from ${shapefile.name}_${shapefile.id}` })
58
+ setWarning({ message: `Importing ${features.length} features from ${shapefile.name}_${shapefile.id} for Shapefiles` })
60
59
  const insert = bootstrap.database
61
60
  .prepare(`INSERT OR REPLACE INTO shapefiles (id, location, geometry) VALUES (?, ?, ?)`)
62
61
  const transaction = bootstrap.database.transaction((entries: any[]) => {
@@ -84,10 +83,8 @@ export const importShapefiles = async (): Promise<void> => {
84
83
  })
85
84
  fs.unlinkSync(`${filepath}.shp`)
86
85
  fs.unlinkSync(`${filepath}.dbf`)
87
- setWarning({ message: `Cleaned up temporary files for ${shapefile.name}_${shapefile.id}` })
88
86
  transaction(features)
89
87
  }
90
- setWarning({ message: `Shapefiles have finished compiling, you can now continue and close this terminal` })
91
88
  fs.rm(resolve(__dirname, '../../shapefiles'), { recursive: true, force: true }, () => {});
92
89
  }
93
90
  } catch (error) {
@@ -17,10 +17,7 @@
17
17
 
18
18
  */
19
19
 
20
- import request from 'request'
21
-
22
20
  interface CreateHttpOptions {
23
- proxy?: string
24
21
  url: string
25
22
  headers?: any
26
23
  timeout?: number
@@ -30,56 +27,44 @@ interface CreateHttpOptions {
30
27
  }
31
28
 
32
29
  export const createHttp = async (options: CreateHttpOptions): Promise<any> => {
33
- return new Promise((resolve, reject) => {
34
- const requestOptions = {
35
- url: options.url ?? `https://api.weather.gov/alerts/active`,
36
- headers: options.headers ?? {
37
- "User-Agent": "AtmosphericX",
38
- "Accept": "application/geo+json, text/plain, */*; q=0.9",
39
- "Accept-Language": "en-US,en;q=0.9"
40
- },
41
- method: options.method ?? `GET`,
42
- timeout: options.timeout ?? 10e3,
43
- proxy: options.proxy ?? null,
44
- maxRedirects: 1,
45
- };
46
- if (options.formData) {
47
- requestOptions['formData'] = options.formData;
48
- } else if (options.body) {
49
- requestOptions['body'] = options.body;
50
- }
51
-
52
- request(requestOptions, (error, response, body) => {
53
- if (error) {
54
- return resolve({
55
- error: true,
56
- options: requestOptions,
57
- status: -1,
58
- message: error.message ?? `Unknown Error`
59
- })
60
- }
61
- if (response.statusCode < 200 || response.statusCode >= 300) {
62
- return resolve({
63
- error: true,
64
- options: requestOptions,
65
- status: response.statusCode ?? -1,
66
- message: `HTTP Status Code ${response.statusCode ?? `Unknown Status Code`} (${body})`
67
- })
68
- }
69
- if (body == undefined || body == null) {
70
- return resolve({
71
- error: true,
72
- options: requestOptions,
73
- status: response.statusCode ?? -1,
74
- message: `Empty Response Body`
75
- })
76
- }
77
- resolve({
78
- error: false,
79
- options: requestOptions,
80
- status: response.statusCode ?? -1,
81
- message: body
82
- })
83
- })
84
- })
30
+ const requestOptions: RequestInit = {
31
+ method: options.method ?? "GET",
32
+ headers: options.headers ?? {
33
+ "User-Agent": "AtmosphericX",
34
+ "Accept": "application/geo+json, text/plain, */*; q=0.9",
35
+ "Accept-Language": "en-US,en;q=0.9",
36
+ },
37
+ signal: AbortSignal.timeout(options.timeout ?? 10_000),
38
+ redirect: "follow"
39
+ };
40
+
41
+
42
+ const returnHttp = function(error: boolean,status: number, message: string) {
43
+ return { error: error, options: requestOptions, status, message };
44
+ }
45
+
46
+ if (options?.formData) {
47
+ requestOptions.body = options.formData;
48
+ } else if (options?.body != undefined) {
49
+ requestOptions.body =
50
+ options.body instanceof FormData
51
+ ? options.body
52
+ : typeof options.body === "string"
53
+ ? options.body
54
+ : JSON.stringify(options.body);
55
+ }
56
+
57
+ try {
58
+ const response = await fetch(
59
+ options?.url ?? `https://api.weather.gov/alerts/active`,
60
+ requestOptions
61
+ )
62
+ const body = await response.text();
63
+ if (!response.ok) {
64
+ return returnHttp(true, response.status, `HTTP Status Code ${response.status} (${response.statusText})`)
65
+ }
66
+ return returnHttp(false, response.status, body)
67
+ } catch (error) {
68
+ return returnHttp(true, 500, `Internal Server Error: ${error}`)
69
+ }
85
70
  }
@@ -52,6 +52,7 @@ export const setCronSchedule = async (): Promise<void> => {
52
52
  };
53
53
  walk(settings.GlobalSettings.ArchiveSettings.TextDirectory)
54
54
  walk(settings.GlobalSettings.ArchiveSettings.EasDirectory)
55
+ walk(settings.GlobalSettings.ArchiveSettings.EventDirectory)
55
56
 
56
57
 
57
58
 
@@ -67,7 +68,7 @@ export const setCronSchedule = async (): Promise<void> => {
67
68
  }
68
69
  })
69
70
  if (response.error) {
70
- return setEventEmit({
71
+ return setEventEmit({
71
72
  event: `onServiceStatus`,
72
73
  metadata: {
73
74
  type: "fetch-api",
@@ -50,7 +50,7 @@ export const xReconnect = async (interval: number): Promise<void> => {
50
50
  },
51
51
  type: `reconnect`,
52
52
  error: true
53
- },
53
+ }, message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${bootstrap.cache.tReconnects})`,
54
54
  })
55
55
  await bootstrap.session_xmpp.stop().catch(() => {});
56
56
  await bootstrap.session_xmpp.start().catch(() => {});
@@ -54,7 +54,5 @@ export const getEmebed = (event: TypeEvent): string => {
54
54
  line(`**Sender:**`, event?.properties?.geocode?.office?.name ? `${event?.properties?.geocode?.office?.name} (${event?.properties?.geocode?.office?.office})` : event?.properties?.geocode?.office?.office),
55
55
  line(`**Tracking:**`, event?.properties?.metadata?.tracking),
56
56
  line(`**Logs:**`, event?.properties?.metadata?.history?.length > 0 ? event?.properties?.metadata?.history.length : null),
57
- line(``, event?.properties?.metadata?.attachments?.length > 0 ? `**Attachments:** ${event?.properties?.metadata?.attachments.map(attachment => `[Attachment #${event?.properties?.metadata?.attachments.indexOf(attachment) + 1}](${attachment})`).join(' | ')}` : null),
58
- line(``, event?.properties?.description ? '```' + '\n' + event?.properties?.description.split('\n').map(l => l.trim()).filter(Boolean).join('\n') + '\n' + '```' : null, !isExpired),
59
57
  ].filter(Boolean).join('\n');
60
58
  }
@@ -63,7 +63,7 @@ export type TypeEvent = {
63
63
  issued: string
64
64
  status: string
65
65
  }[]
66
- attachments?: string[]
66
+ attachments?: { name: string; link: string }[]
67
67
  raw: string
68
68
  }
69
69
  } & BaseTypeEventProperties
@@ -27,6 +27,6 @@ export type TypeListener = {
27
27
  message: string
28
28
  }
29
29
  uploads?: {
30
- file?: boolean, eas?: boolean
30
+ file?: boolean, eas?: boolean, event?: boolean
31
31
  }
32
32
  }
@@ -21,6 +21,7 @@ import { TypeAttributes } from "./type.attributes";
21
21
 
22
22
  export type TypeEventProperties = {
23
23
  locations: string
24
+ locations_array: string[]
24
25
  description: string
25
26
  attributes?: TypeAttributes
26
27
  geocode: {
@@ -48,6 +48,11 @@ export type TypeSettings = {
48
48
  CallbackInterval: number
49
49
  EventsEndpoint: string
50
50
  }
51
+ BroadcastifySettings: {
52
+ BroadcastifyAttachments: boolean
53
+ BroadcastifyDatabase: string
54
+ BroadcastifyTags: string[]
55
+ },
51
56
  GlobalSettings: {
52
57
  EventManagement: boolean
53
58
  BetterEventNames: boolean
@@ -69,7 +74,8 @@ export type TypeSettings = {
69
74
  IgnoreTestProducts: boolean
70
75
  },
71
76
  ArchiveSettings: {
72
- TTL: number,
77
+ TTL: number
78
+ EventDirectory: string
73
79
  TextDirectory: string
74
80
  EasDirectory: string
75
81
  EasToneout: string
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.46`,
24
+ version: `3.0.48`,
25
25
  isReady: true,
26
26
  ratelimits: {},
27
27
  session_xmpp: null,
@@ -72,6 +72,11 @@ export const bootstrap = {
72
72
  CallbackInterval: 15,
73
73
  EventsEndpoint: `https://api.weather.gov/alerts/active`,
74
74
  },
75
+ BroadcastifySettings: {
76
+ BroadcastifyAttachments: true,
77
+ BroadcastifyDatabase: `https://scriptkitty.cafe/ftp/@atmosphericx/assets/broadcastify.json`,
78
+ BroadcastifyTags: [`Ham`, `Air`, `Fire`, `Public Safety`, `Weather`, `EMS`, `Police`, `Rail`]
79
+ },
75
80
  ListenerSettings: [],
76
81
  GlobalSettings: {
77
82
  EventManagement: true,
@@ -94,6 +99,7 @@ export const bootstrap = {
94
99
  },
95
100
  ArchiveSettings: {
96
101
  TTL: 60,
102
+ EventDirectory: null,
97
103
  TextDirectory: null,
98
104
  EasDirectory: null,
99
105
  EasToneout: null
package/test.js CHANGED
@@ -1,6 +1,6 @@
1
- const { Manager, setSettings, getSettings, getListener } = require(`../dist/cjs/index.cjs`)
1
+ const { Manager } = require(`../dist/cjs/index.cjs`)
2
2
 
3
- const NOAAWeatherWireService = new Manager({
3
+ const Client = new Manager({
4
4
  Database: `shapefiles.db`,
5
5
  EnableWireService: false,
6
6
  EnableJournal: true,
@@ -29,6 +29,10 @@ const NOAAWeatherWireService = new Manager({
29
29
  CallbackInterval: 30,
30
30
  EventsEndpoint: `https://api.weather.gov/alerts/active`,
31
31
  },
32
+ BroadcastifySettings: {
33
+ BroadcastifyAttachments: true,
34
+ BroadcastifyTags: [`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`]
35
+ },
32
36
  ListenerSettings: [
33
37
  {
34
38
  events: [`*Thunderstorm Warning*`, `* Watch`],
@@ -41,15 +45,18 @@ const NOAAWeatherWireService = new Manager({
41
45
  },
42
46
  uploads: {
43
47
  eas: true,
44
- file: true
48
+ file: true,
49
+ event: true
45
50
  }
46
51
  }
47
52
  ],
48
53
  GlobalSettings: {
54
+ EventManagement: true,
49
55
  BetterEventNames: true,
50
56
  DisableGeometryParsing: false,
51
57
  UseShapefileCoordinates: true,
52
58
  SPCWatchesOnly: true,
59
+ ShapefileSkipPoints: 0,
53
60
  NodeTTL: 60,
54
61
  NodeMinDistance: 120,
55
62
  EventFiltering: {
@@ -83,9 +90,10 @@ const NOAAWeatherWireService = new Manager({
83
90
  },
84
91
  ArchiveSettings: {
85
92
  TTL: 600,
93
+ EventDirectory: `Storage/EventProducts`,
86
94
  TextDirectory: `Storage/TextProducts`,
87
95
  EasDirectory: `Storage/EasScenarios`,
88
96
  EasToneout: `tone.wav`,
89
97
  }
90
98
  }
91
- })
99
+ })