@atmosx/event-product-parser 3.0.622 → 3.1.0

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 (199) hide show
  1. package/.github/CHANGELOGS.md +52 -0
  2. package/.github/CODE_OF_CONDUCT.md +24 -1
  3. package/.github/CONTRIBUTING.md +22 -3
  4. package/.github/FUNDING.yaml +3 -0
  5. package/.github/LICENSE +24 -1
  6. package/.github/SECURITY.md +25 -6
  7. package/.github/docs/chapters/general-configurations.md +109 -0
  8. package/.github/docs/chapters/sources-and-attributes.md +219 -0
  9. package/README.md +56 -148
  10. package/dist/{cjs/index.cjs → index.cjs} +4486 -1471
  11. package/package.json +13 -8
  12. package/pnpm-workspace.yaml +1 -0
  13. package/src/bootstrap.ts +66 -51
  14. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  15. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  16. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  17. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  18. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  19. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  20. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  21. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +15 -8
  22. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  23. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  24. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  25. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  26. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  27. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  28. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  29. package/src/components/database/CreateQuery.ts +39 -0
  30. package/src/components/database/InitializeDatabase.ts +71 -0
  31. package/src/components/database/imports/Boundaires.ts +168 -0
  32. package/src/{@modules/@database/ImportBroadcastify.ts → components/database/imports/Broadcastify.ts} +15 -25
  33. package/src/components/database/imports/Census.ts +87 -0
  34. package/src/{@modules/@database/ImportShapefiles.ts → components/database/imports/Shapefiles.ts} +18 -21
  35. package/src/{@modules/@database/ImportStanza.ts → components/database/imports/Stanza.ts} +15 -19
  36. package/src/components/events/CreateEvents.ts +88 -0
  37. package/src/components/events/FilterEvents.ts +149 -0
  38. package/src/{@building/CreateEvent.ts → components/events/ProcessStanza.ts} +22 -22
  39. package/src/components/events/RemoveEvents.ts +74 -0
  40. package/src/{@building → components/events/components}/GetCleanedEvent.ts +2 -2
  41. package/src/{@building → components/events/components}/GetEventAttachments.ts +14 -12
  42. package/src/components/events/components/GetEventDirection.ts +28 -0
  43. package/src/{@building → components/events/components}/GetEventEnhancedName.ts +5 -6
  44. package/src/{@building → components/events/components}/GetEventGeometry.ts +19 -13
  45. package/src/{@building → components/events/components}/GetEventHeader.ts +13 -13
  46. package/src/components/events/components/GetEventMerged.ts +51 -0
  47. package/src/{@building → components/events/components}/GetEventNodes.ts +20 -18
  48. package/src/{@building → components/events/components}/GetEventOffice.ts +13 -13
  49. package/src/components/events/components/GetEventPopulation.ts +58 -0
  50. package/src/components/events/components/GetEventProperties.ts +106 -0
  51. package/src/{@building → components/events/components}/GetEventSignature.ts +9 -9
  52. package/src/{@building → components/events/components}/GetEventTags.ts +3 -3
  53. package/src/{@core/CreateListener.ts → components/events/components/GetEventTheme.ts} +8 -6
  54. package/src/components/events/components/GetEventTracking.ts +64 -0
  55. package/src/{@modules/@database → components/events/utilities}/GetCachedEvents.ts +18 -14
  56. package/src/{@manager → components/events/utilities}/SetHash.ts +18 -13
  57. package/src/{@manager → components/events/utilities}/UpdateEvents.ts +12 -12
  58. package/src/{@manager → components/events/utilities}/UpdateNode.ts +14 -14
  59. package/src/{@parsers/@text → components/formatting}/GetEmbededText.ts +12 -6
  60. package/src/{@parsers/@text → components/formatting}/GetStringText.ts +13 -9
  61. package/src/{@modules/@utilities → components/geometry}/GetShapeNearestPoint.ts +24 -19
  62. package/src/components/geometry/GetUnionPolygon.ts +36 -0
  63. package/src/components/images/GenerateGraphic.ts +242 -0
  64. package/src/components/images/components/CreateRectangle.ts +22 -0
  65. package/src/components/images/components/CreateText.ts +22 -0
  66. package/src/components/images/modules/CreateSVG.ts +37 -0
  67. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  68. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  69. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  70. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  71. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  72. package/src/components/images/modules/GetSVGPath.ts +53 -0
  73. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  74. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  75. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  76. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  77. package/src/components/utilities/EmitThread.ts +97 -0
  78. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  79. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  80. package/src/{@modules/@utilities → components/utilities}/QueueManager.ts +7 -8
  81. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +13 -13
  82. package/src/components/utilities/SetEventEmit.ts +42 -0
  83. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  84. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  85. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  86. package/src/components/utilities/SetWarning.ts +47 -0
  87. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  88. package/src/{@modules/@xmpp → components/xmpp}/ErrorXMPP.ts +6 -6
  89. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  90. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  91. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  92. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +26 -26
  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 +4 -3
  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 +8 -3
  113. package/src/{@enums → enums}/Testing.ts +2 -2
  114. package/src/enums/Themes.ts +70 -0
  115. package/src/events/ParseAPI.ts +133 -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 +37 -36
  119. package/src/{@core → exports}/ClearEvents.ts +9 -9
  120. package/src/{@core → exports}/GetEvents.ts +4 -4
  121. package/src/exports/GetNearestCity.ts +45 -0
  122. package/src/{@core → exports}/GetNodes.ts +4 -4
  123. package/src/{@core → exports}/GetRandomEvent.ts +4 -4
  124. package/src/{@core → exports}/GetVersion.ts +4 -4
  125. package/src/{@core → exports}/ManualEvent.ts +24 -24
  126. package/src/{@core → exports}/QueryStanza.ts +12 -11
  127. package/src/exports/SetNode.ts +100 -0
  128. package/src/{@core → exports}/StartService.ts +22 -21
  129. package/src/{@core → exports}/StopService.ts +10 -10
  130. package/src/index.ts +55 -37
  131. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +7 -7
  132. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  133. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  134. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  135. package/src/parsers/ugc/GetCache.ts +24 -0
  136. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  137. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  138. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  139. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  140. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  141. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  142. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  143. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  144. package/src/{@parsers/@pvtec → parsers/vtec}/VTECExtract.ts +17 -17
  145. package/src/tasks/CreateTasks.ts +116 -0
  146. package/src/{@tasks → tasks}/TaskGenerateJSON.ts +10 -11
  147. package/src/{@tasks → tasks}/TaskGenerateText.ts +11 -12
  148. package/src/tasks/TaskSendNTFY.ts +96 -0
  149. package/src/tasks/TaskSendWebhook.ts +107 -0
  150. package/src/{@types → types/event}/Attributes.ts +2 -3
  151. package/src/{@types → types/event}/Event.ts +8 -7
  152. package/src/{@types → types/event}/HVTEC.ts +2 -2
  153. package/src/{@types → types/event}/Properties.ts +17 -4
  154. package/src/{@types → types/event}/Stanza.ts +2 -2
  155. package/src/{@types → types/event}/VTEC.ts +8 -8
  156. package/src/{@types → types/standard}/Actions.ts +3 -3
  157. package/src/{@types → types/standard}/Hash.ts +5 -5
  158. package/src/{@modules/@utilities/GetSettings.ts → types/standard/Nodes.ts} +15 -7
  159. package/src/{@types → types/standard}/Settings.ts +19 -12
  160. package/src/{@types → types/standard}/StanzaCompiled.ts +15 -15
  161. package/src/{@types → types/standard}/UGC.ts +5 -5
  162. package/tools/build.js +2 -15
  163. package/tsconfig.json +29 -17
  164. package/.github/SUPPORTED_EVENTS.md +0 -370
  165. package/.github/docs/docs-functions.md +0 -30
  166. package/.github/docs/docs-general-configurations.md +0 -209
  167. package/.github/docs/docs-integrations.md +0 -37
  168. package/.github/docs/docs-listeners.md +0 -28
  169. package/.github/docs/docs-source-configuration.md +0 -218
  170. package/.github/docs/docs-technical.md +0 -50
  171. package/.github/logo.png +0 -0
  172. package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
  173. package/.github/samples/SAMPLE_GEOJSON.json +0 -204
  174. package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +0 -119
  175. package/dist/esm/index.mjs +0 -22298
  176. package/src/@building/GetEventProperties.ts +0 -101
  177. package/src/@building/GetEventTracking.ts +0 -68
  178. package/src/@core/SetNode.ts +0 -87
  179. package/src/@events/ParseAPI.ts +0 -122
  180. package/src/@manager/MakeEvents.ts +0 -109
  181. package/src/@manager/RemoveEvent.ts +0 -70
  182. package/src/@manager/ValidateEvents.ts +0 -141
  183. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  184. package/src/@modules/@eas/GenerateEASMessage.ts +0 -152
  185. package/src/@modules/@utilities/GetFormattedTime.ts +0 -43
  186. package/src/@modules/@utilities/SetCronSchedule.ts +0 -94
  187. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  188. package/src/@modules/@utilities/SetListener.ts +0 -30
  189. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  190. package/src/@modules/@utilities/SetWarning.ts +0 -34
  191. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  192. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  193. package/src/@parsers/@text/GetXML.ts +0 -61
  194. package/src/@parsers/@ugc/GetCache.ts +0 -24
  195. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  196. package/src/@tasks/CreateTasks.ts +0 -110
  197. package/src/@tasks/TaskGenerateAudio.ts +0 -35
  198. package/src/@tasks/TaskSendNTFY.ts +0 -93
  199. package/src/@tasks/TaskSendWebhook.ts +0 -101
@@ -1,64 +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 { SetEventEmit } from "@utilities/SetEventEmit"
23
- import { SetWarning } from "@utilities/SetWarning"
24
-
25
- export const ReconnectXMPP = async (interval: number): Promise<void> => {
26
- const settings = bootstrap.settings as TypeSettings;
27
- const lastStanza = Date.now() - bootstrap.cache.lastStanza
28
- if (interval < 15) {
29
- SetWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` })
30
- interval = 15;
31
- bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
32
- }
33
- const reconnectThreshold = interval * 1e3
34
- if ((!bootstrap.cache.isConnected && !bootstrap.cache.sigHault) || !bootstrap.session_xmpp) {
35
- return;
36
- }
37
- if (lastStanza > reconnectThreshold) {
38
- if (!bootstrap.cache.isReconnecting) {
39
- bootstrap.cache.isReconnecting = true;
40
- bootstrap.cache.isConnected = false;
41
- bootstrap.cache.tReconnects += 1;
42
- try {
43
- SetEventEmit({
44
- event: `onServiceStatus`,
45
- metadata: {
46
- message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${bootstrap.cache.tReconnects})`,
47
- data: {
48
- last_stanza: lastStanza,
49
- nickname: settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname
50
- },
51
- type: `reconnect`,
52
- error: true
53
- }, message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${bootstrap.cache.tReconnects})`,
54
- })
55
- await bootstrap.session_xmpp.stop().catch(() => {});
56
- await bootstrap.session_xmpp.start().catch(() => {});
57
- } catch (error) {
58
- SetWarning({ message: `XMPP Reconnect Failed - ${(error as Error).message}` })
59
- } finally {
60
- bootstrap.cache.isReconnecting = false;
61
- }
62
- }
63
- }
64
- }
@@ -1,53 +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
- export const getPolygonFromProduct = (message: string): number[][] => {
21
- const coordinates: number[][] = [];
22
- const match = message.match(
23
- /LAT\.\.\.LON\s+([\s\S]*?)(?=\n[A-Z]{2,}(?:\.\.\.|:)|\$\$|&&|$)/i
24
- );
25
- if (!match) return coordinates;
26
- const text = match[1];
27
- const values = text.match(/\d{4,8}/g);
28
- if (!values) return coordinates;
29
-
30
- if (values.every(v => v.length === 8)) {
31
- for (const value of values) {
32
- const lat = parseInt(value.slice(0, 4), 10) / 100;
33
- const lon = -parseInt(value.slice(4, 8), 10) / 100;
34
- if (Number.isFinite(lat) && Number.isFinite(lon)) {
35
- coordinates.push([lon, lat]);
36
- }
37
- }
38
- }
39
-
40
- else {
41
- for (let i = 0; i + 1 < values.length; i += 2) {
42
- const lat = parseInt(values[i], 10) / 100;
43
- const lon = -parseInt(values[i + 1], 10) / 100;
44
- if (Number.isFinite(lat) && Number.isFinite(lon)) {
45
- coordinates.push([lon, lat]);
46
- }
47
- }
48
- }
49
- if (coordinates.length > 2) {
50
- coordinates.push([...coordinates[0]]);
51
- }
52
- return coordinates;
53
- };
@@ -1,61 +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
- interface GetXMLOptions {
21
- message: string
22
- targets: string[]
23
- }
24
-
25
- export const GetXML = (options: GetXMLOptions): Record<string, string> => {
26
- const extracted: Record<string, any> = {};
27
- const findValueByKey = (obj: any, searchKey: string) => {
28
- const results = [];
29
- if (obj === null || typeof obj !== 'object') {
30
- return results;
31
- }
32
- const searchKeyLower = searchKey.toLowerCase();
33
- for (const key in obj) {
34
- if (obj.hasOwnProperty(key) && key.toLowerCase() === searchKeyLower) {
35
- results.push(obj[key]);
36
- }
37
- }
38
- if (Array.isArray(obj)) {
39
- for (const item of obj) {
40
- if (item.valueName && item.valueName.toLowerCase() === searchKeyLower && item.value !== undefined) {
41
- results.push(item.value);
42
- }
43
- const nestedResults = findValueByKey(item, searchKey);
44
- results.push(...nestedResults);
45
- }
46
- }
47
- for (const key in obj) {
48
- if (obj.hasOwnProperty(key)) {
49
- const nestedResults = findValueByKey(obj[key], searchKey);
50
- results.push(...nestedResults);
51
- }
52
- }
53
- return results;
54
- };
55
- for (const key of options.targets) {
56
- const values = findValueByKey(options.message, key);
57
- const uniqueValues = [...new Set(values)];
58
- extracted[key] = uniqueValues.length === 0 ? null : (uniqueValues.length === 1 ? uniqueValues[0] : uniqueValues);
59
- }
60
- return extracted;
61
- }
@@ -1,24 +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
- export const getCache = (key: string) => {
23
- return bootstrap.cache.ugc.get(key);
24
- };
@@ -1,111 +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 { union } from "polygon-clipping"
22
-
23
- interface CoordinatesOptions {
24
- zones: string[]
25
- isUnion: boolean
26
- }
27
-
28
- interface CoordinatesResponse {
29
- type: `Polygon` | `MultiPolygon`
30
- coordinates: any[]
31
- }
32
-
33
- export const getZonePolygon = (options: CoordinatesOptions): CoordinatesResponse | null => {
34
- const list = [...new Set(options.zones.map(z => z.trim()))].filter(z => z === 'XX000' ? false : true);
35
- if (list.length === 0) return null;
36
-
37
- const placeholders = list.map(() => "?").join(",");
38
- const rows = bootstrap.database
39
- .prepare(`SELECT geometry FROM shapefiles WHERE id IN (${placeholders})`)
40
- .all(...list);
41
- const polygons: any[] = [];
42
- for (const row of rows) {
43
- if (!row?.geometry) continue;
44
- const geom = JSON.parse(row.geometry);
45
- if (geom?.type === "Polygon") {
46
- polygons.push(geom.coordinates);
47
- }
48
- }
49
-
50
- if (polygons.length === 0) return null;
51
-
52
- if (options.isUnion) {
53
- const unionFn = union as (...polys: any[]) => any;
54
- const mergedCoords = unionFn(...polygons);
55
- if (!mergedCoords || mergedCoords.length === 0) return null;
56
- let maxArea = -1;
57
- let bestPoly: any[] = [];
58
- for (const poly of mergedCoords) {
59
- const outerRing = poly[0];
60
- let area = 0;
61
- for (let i = 0; i < outerRing.length - 1; i++) {
62
- const [x1, y1] = outerRing[i];
63
- const [x2, y2] = outerRing[i + 1];
64
- area += x1 * y2 - x2 * y1;
65
- }
66
- area = Math.abs(area / 2);
67
- if (area > maxArea) {
68
- maxArea = area;
69
- bestPoly = poly;
70
- }
71
- }
72
- if (!bestPoly || bestPoly.length === 0) return null;
73
- const outerRing = bestPoly[0];
74
- const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10) ?? 1);
75
- let skipped = outerRing.filter((_: any, idx: number) => idx % skip === 0);
76
- if (skipped.length < 4) {
77
- skipped = outerRing.slice();
78
- }
79
- const first = skipped[0];
80
- const last = skipped[skipped.length - 1];
81
- if (!first || !last || first[0] !== last[0] || first[1] !== last[1]) {
82
- skipped.push([first[0], first[1]]);
83
- }
84
- return {type: "Polygon", coordinates: [skipped]};
85
- } else {
86
- const multi: any[] = [];
87
- for (const polyCoords of polygons) {
88
- if (Array.isArray(polyCoords) && Array.isArray(polyCoords[0])) {
89
- multi.push(polyCoords);
90
- }
91
- }
92
- if (multi.length === 0) return null;
93
- const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10) ?? 1);
94
- if (skip > 1) {
95
- for (let p = 0; p < multi.length; p++) {
96
- for (let r = 0; r < multi[p].length; r++) {
97
- const ring = multi[p][r];
98
- let reduced = ring.filter((_: any, i: number) => i % skip === 0);
99
- if (reduced.length < 4) reduced = ring.slice();
100
- const first = reduced[0];
101
- const last = reduced[reduced.length - 1];
102
- if ( first && last && (first[0] !== last[0] || first[1] !== last[1])) {
103
- reduced.push([first[0], first[1]]);
104
- }
105
- multi[p][r] = reduced;
106
- }
107
- }
108
- }
109
- return {type: "MultiPolygon", coordinates: multi};
110
- }
111
- }
@@ -1,110 +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
- import { TypeSettings } from "types/Settings"
20
- import { TypeEvent } from "types/Event"
21
- import { TypeActions } from "types/Actions"
22
- import { bootstrap } from "@bootstrap"
23
- import { SetDebug } from "@utilities/SetDebug"
24
- import { GetMatched } from "@utilities/GetMatched"
25
- import { GetStringText } from "@parsers/text/GetStringText"
26
- import { GetCleanedEvent } from "@building/GetCleanedEvent"
27
- import { TaskGenerateAudio } from "@tasks/TaskGenerateAudio"
28
- import { TaskGenerateText } from "@tasks/TaskGenerateText"
29
- import { TaskGenerateJSON } from "@tasks/TaskGenerateJSON"
30
- import { TaskSendNTFY } from "@tasks/TaskSendNTFY"
31
- import { TaskSendWebhook } from "@tasks/TaskSendWebhook"
32
- import { QueueManager } from "@utilities/QueueManager"
33
-
34
- const Webhooks = new QueueManager({ concurrency: 1 });
35
- const NTFY = new QueueManager({ concurrency: 5 });
36
-
37
- export const CreateTasks = async (events: TypeEvent[]): Promise<void> => {
38
- const tick = performance.now()
39
- const settings = bootstrap.settings as TypeSettings;
40
- const { ActionSettings, GlobalSettings, NotifyServer } = settings;
41
- const actions = ActionSettings as TypeActions[];
42
-
43
- for (const event of events) {
44
- const { properties } = event;
45
- const isActioning = Array.isArray(actions) && actions.length > 0;
46
- if (!isActioning) { continue }
47
-
48
- for (const action of actions) {
49
- const { Events, Webhook, NotificationServer, Uploads } = action;
50
- const isValidAction = GetMatched(Events, properties.event)
51
- if ((Events.length == 0 || isValidAction)) {
52
- const a = performance.now();
53
- const [eas, text, json] = await Promise.all([
54
- Uploads?.EAS ? TaskGenerateAudio({
55
- filename: (`${properties.event}_${properties.metadata.tracking}`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim(),
56
- description: properties.description,
57
- header: properties.metadata.header
58
- }).then((result) => { return result; }) : Promise.resolve(null),
59
-
60
- Uploads?.TEXT ? TaskGenerateText({
61
- string: properties.metadata.raw,
62
- directory: GlobalSettings?.ArchiveSettings?.TextDirectory,
63
- filename: (`${properties.event}_${properties.metadata.tracking}.txt`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
64
- }).then((result) => { return result; }) : Promise.resolve(null),
65
-
66
- Uploads?.JSON ? TaskGenerateJSON({
67
- string: JSON.stringify(GetCleanedEvent(event), null, 2),
68
- directory: GlobalSettings?.ArchiveSettings?.JSONDirectory,
69
- filename: (`${properties.event}_${properties.metadata.tracking}.json`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
70
- }).then((result) => { return result; }) : Promise.resolve(null),
71
- ]);
72
-
73
- SetDebug({ title: `Tasks/Generative`, message: `${Math.round(performance.now() - a)}ms` })
74
-
75
- const b = performance.now();
76
- await Promise.all([
77
- NotificationServer?.Enabled && NotifyServer?.Enabled && NotificationServer?.Topic ? NTFY.enqueue(() => TaskSendNTFY({
78
- event: event,
79
- toggles: {
80
- eas: Uploads?.EAS,
81
- json: Uploads?.JSON,
82
- text: Uploads?.TEXT
83
- },
84
- priority: NotificationServer?.Priority ?? 5,
85
- body: GetStringText(event),
86
- topic: NotificationServer?.Topic
87
- })) : Promise.resolve(null),
88
- Webhook?.Enabled && Webhook?.Destination ? Webhooks.enqueue(() => TaskSendWebhook({
89
- event: event,
90
- webhook: {
91
- enabled: Webhook?.Enabled,
92
- destination: Webhook?.Destination,
93
- message: Webhook?.Message,
94
- title: Webhook?.Title,
95
- ratelimit: Webhook?.Ratelimit
96
- },
97
- attachments: {
98
- text: text,
99
- eas: eas,
100
- json: json
101
- }
102
- })) : Promise.resolve(null)
103
- ]);
104
- SetDebug({ title: `Tasks/Send`, message: `${Math.round(performance.now() - b)}ms` })
105
- }
106
- }
107
- SetDebug({ title: `Tasks/CompletedEventTask`, message: `${Math.round(performance.now() - tick)}ms` })
108
- }
109
- SetDebug({ title: `Tasks/Global`, message: `${Math.round(performance.now() - tick)}ms` })
110
- }
@@ -1,35 +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 { GenerateEASMessage } from "@eas/GenerateEASMessage"
21
-
22
- interface TaskGenerateAudioOptions {
23
- filename: string;
24
- description: string;
25
- header: string;
26
- }
27
-
28
- export const TaskGenerateAudio = async function(options: TaskGenerateAudioOptions): Promise<string> {
29
- const { filename, description, header } = options;
30
- return await GenerateEASMessage({
31
- title: filename,
32
- message: description,
33
- header: header
34
- });
35
- }
@@ -1,93 +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 { bootstrap } from "@bootstrap"
22
- import { CreateHttp } from "@utilities/CreateHttp";
23
- import { SetDebug } from "@utilities/SetDebug";
24
- import { SetTimeoutAction } from "@utilities/SetTimeoutAction";
25
-
26
- interface TaskSendNTFYOptions {
27
- event: TypeEvent;
28
- toggles?: {
29
- eas?: boolean;
30
- json?: boolean;
31
- text?: boolean;
32
- },
33
- priority: string | number;
34
- body: string;
35
- topic: string;
36
- }
37
-
38
- export const TaskSendNTFY = async function(options: TaskSendNTFYOptions): Promise<void> {
39
- const { event, toggles, priority, body, topic } = options;
40
- const { properties } = event;
41
-
42
- const configurations = bootstrap.settings.NotifyServer;
43
- const authentication = configurations?.Credentials?.Username && configurations?.Credentials?.Password ? {
44
- username: configurations.Credentials.Username,
45
- password: configurations.Credentials.Password
46
- } : undefined;
47
- const image = properties.metadata.attachments?.find(a => a.name === "Image: Graphic");
48
-
49
- const buttons = [
50
- ...(toggles?.eas && configurations?.MediaStorage?.EAS ? [{
51
- "action": "view",
52
- "label": "Listen",
53
- "url": `${configurations.MediaStorage.EAS}/${properties.event}_${properties.metadata.tracking}.wav`,
54
- }] : []),
55
- ...(toggles?.text && configurations?.MediaStorage?.TEXT ? [{
56
- "action": "view",
57
- "label": "View Text",
58
- "url": `${configurations.MediaStorage.TEXT}/${properties.event}_${properties.metadata.tracking}.txt`,
59
- }] : []),
60
- ...(image ? [{
61
- "action": "view",
62
- "label": "View Image",
63
- "url": image.link,
64
- }] : []),
65
- ];
66
-
67
- const headers = {
68
- "Title": `${properties.event} (${properties.status})`,
69
- "Tags": properties.parameters.tags?.join(",") ?? "N/A",
70
- "Priority": priority ?? "5",
71
- ...(buttons.length > 0 && { "Actions": JSON.stringify(buttons) }),
72
- };
73
-
74
- const post = async (topic: string) => {
75
- const response = await CreateHttp({
76
- url: `${configurations?.Server?.replace(/\/$/, "")}/${topic}`,
77
- timeout: 15_000,
78
- method: "PUT",
79
- ...(authentication && { auth: authentication }),
80
- headers,
81
- body
82
- })
83
- if (response.error) {
84
- SetDebug({ title: `Tasks/NTFY`, message: `Failed to send notification to topic "${topic}": ${response.message}` })
85
- }
86
- }
87
- const topics = [
88
- topic,
89
- ...(properties.metadata.filtered_proximity ? [`${topic}-LOCAL`] : []),
90
- ];
91
-
92
- await Promise.all([...new Set(topics)].map(post));
93
- }
@@ -1,101 +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 { CreateHttp } from "@utilities/CreateHttp";
22
- import { SetTimeoutAction } from "@utilities/SetTimeoutAction";
23
- import { GetEmebedText } from "@parsers/text/GetEmbededText";
24
- import { parentPort } from "worker_threads"
25
- import { readFile } from "fs/promises"
26
-
27
- interface TaskSendWebhook {
28
- event: TypeEvent;
29
- webhook: {
30
- enabled: boolean;
31
- destination: string;
32
- message: string;
33
- title: string;
34
- ratelimit: number;
35
- };
36
- attachments: {
37
- text?: string;
38
- eas?: string;
39
- json?: string;
40
- }
41
- }
42
-
43
- export const TaskSendWebhook = async function(options: TaskSendWebhook): Promise<void> {
44
- const { event, webhook, attachments } = options;
45
- const { properties } = event;
46
- const isRatelimited = SetTimeoutAction({
47
- identifier: webhook.destination,
48
- interval: (webhook.ratelimit ?? 2) * 2,
49
- max: (webhook.ratelimit ?? 2),
50
- addTime: true
51
- })
52
- if (isRatelimited.limited) { return }
53
- const newForm = new FormData();
54
- const newEmbed = {
55
- title: `${properties.event} (${properties.status})`,
56
- description: GetEmebedText(event),
57
- fields: [],
58
- color: 16711680,
59
- timestamp: new Date().toISOString(),
60
- footer: { text: webhook.title ?? `AtmosphericX` }
61
- };
62
- if (properties.description && !properties.status_metadata.is_expired) {
63
- const description = properties.description.length > 900
64
- ? properties.description.substring(0, 900) + "\n\n[Message truncated due to length]"
65
- : properties.description;
66
- newEmbed.fields.push({
67
- name: "Description",
68
- value: description ? '```' + '\n' + description.split('\n').map(l => l.trim()).filter(Boolean).join('\n') + '\n' + '```' : ""
69
- });
70
- }
71
- if (properties.metadata.attachments?.length > 0) {
72
- const attachments = properties.metadata.attachments.slice(0, 5);
73
- newEmbed.fields.push({
74
- name: "Attachments",
75
- value: attachments.map(attachment => `- [${attachment.name.length > 45 ? attachment.name.substring(0, 45) + '...' : attachment.name}](${attachment.link})`).join('\n')
76
- });
77
- }
78
- if (attachments?.text) {
79
- newForm.append("fUpload", new Blob([Buffer.from(attachments.text)], {type: "application/text"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.txt`)
80
- }
81
- if (attachments?.json) {
82
- newForm.append("fUpload2", new Blob([Buffer.from(attachments.json)], {type: "application/json"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.json`)
83
- }
84
- if (attachments?.eas) {
85
- const file = await readFile(attachments.eas);
86
- newForm.append("fUpload3", new Blob([Buffer.from(file)], {type: "application/wav"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.wav`)
87
- }
88
-
89
- newForm.append("payload_json", JSON.stringify({
90
- username: webhook.title ?? `AtmosphericX`,
91
- content: webhook.message ?? "",
92
- embeds: [newEmbed]
93
- }));
94
-
95
- await CreateHttp({
96
- url: webhook.destination,
97
- timeout: 15e3,
98
- method: `POST`,
99
- body: newForm
100
- })
101
- }