Skip to content

Commit

Permalink
Update CHANGELOG
Browse files Browse the repository at this point in the history
  • Loading branch information
ingalls committed Jun 13, 2024
1 parent 1bddbeb commit d919910
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 90 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

## Version History

### v2.5.0

- :rocket: Store internal token to minimize login calls

### v2.4.2

- :bug: Squash a couple bugs related to agency filtering
Expand Down
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

218 changes: 128 additions & 90 deletions task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,26 @@ import { FeatureCollection } from 'geojson';
import ETL, { Event, SchemaType, handler as internal, local, env } from '@tak-ps/etl';
import { parse } from 'csv-parse/sync'

const Env = Type.Object({
Username: Type.String({ description: 'Active911 Username' }),
Password: Type.String({ description: 'Active911 Password' }),
Token: Type.String({ description: 'Internal Active911 Token to avoid repeated login attempts' }),
Agencies: Type.Array(Type.Object({
AgencyId: Type.String()
})),
DEBUG: Type.Boolean({ description: 'Print ADSBX results in logs', default: false })
});

export default class Task extends ETL {
async schema(type: SchemaType = SchemaType.Input): Promise<TSchema> {
if (type === SchemaType.Input) {
return Type.Object({
Username: Type.String({ description: 'Active911 Username' }),
Password: Type.String({ description: 'Active911 Password' }),
Agencies: Type.Array(Type.Object({
AgencyId: Type.String()
})),
DEBUG: Type.Boolean({ description: 'Print ADSBX results in logs', default: false })
})
return Env;
} else {
return Type.Object({});
}
}

async control(): Promise<void> {
const layer = await this.fetchLayer();

async controlLogin(layer: any): Promise<Number[]> {

Check warning on line 26 in task.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check failure on line 26 in task.ts

View workflow job for this annotation

GitHub Actions / test

Don't use `Number` as a type. Use number instead
const loginForm = new FormData();
loginForm.append('operation', 'login');
loginForm.append('post_data', JSON.stringify({
Expand All @@ -42,99 +43,136 @@ export default class Task extends ETL {
.replace(/\)$/, '')
).message;

const fc: FeatureCollection = {
type: 'FeatureCollection',
features: []
};
await this.fetch(`/api/connection/${layer.connection}/layer/${layer.id}`, 'PATCH', {
environment: {
...layer.environment,
Token: login.jwt
}
});

layer.environment.Token = login.jwt;

return login.agencies.map((a: { id: number }) => {
return a.id;
});
}

async control(): Promise<void> {
const layer = await this.fetchLayer();

let filteredAgencies: Number[] = [];

Check failure on line 63 in task.ts

View workflow job for this annotation

GitHub Actions / test

Don't use `Number` as a type. Use number instead
if (layer.environment.Agencies && Array.isArray(layer.environment.Agencies) && layer.environment.Agencies.length) {
const ids = new Set();
layer.environment.Agencies.forEach((a) => { ids.add(parseInt(a.AgencyId)) });
filteredAgencies = login.agencies.filter((a: { id: number }) => {
return ids.has(a.id);
}).map((a: { id: number }) => {
return a.id;
});
} else {
filteredAgencies = login.agencies.map((a: { id: number }) => {
return a.id;
if (!layer.environment.Token || !Array.isArray(layer.environment.Agencies) || !layer.environment.Agencies.length) {
filteredAgencies = await this.controlLogin(layer);
}

if (Array.isArray(layer.environment.Agencies) && layer.environment.Agencies.length) {
filteredAgencies = layer.environment.Agencies.map((a) => {
return a.AgencyId;
});
}

for (const agency of filteredAgencies) {
const agencyForm = new FormData();
agencyForm.append('operation', 'get_archived_alerts_csv');
agencyForm.append('auth', login.jwt);
agencyForm.append('post_data', JSON.stringify({
agency_id: agency,
from_date: moment().subtract(6, 'hours').unix() * 1000,
to_date: moment().unix() * 1000
}));

const alerts = JSON.parse((await (await fetch("https://interface.active911.com/interface/interface.ajax.php", {
referrer: "https://interface.active911.com/interface/",
method: "POST",
body: agencyForm
})).text())
.trim()
.replace(/^\(/, '')
.replace(/\)$/, '')
).message;

const parsed = parse(alerts, { columns: true });

for (const p of parsed) {
if (p.place.trim().length) {
const coords = p.place
.trim()
.split(',')
.map((c: string) => { return Number(c) })
.slice(0, 2);

if (coords.length === 2 && !isNaN(coords[0]) && !isNaN(coords[1])) {
fc.features.push({
id: `active911-${p.id}-staging`,
type: 'Feature',
properties: {
callsign: `Staging: ${p.description}`,
time: moment(p.send).toISOString(),
remarks: `Groups: ${p.units}\n Author: ${p.source}\n ${p.details}`
},
geometry: {
type: 'Point',
coordinates: [coords[1], coords[0]]
}
});
}
}
const fc: FeatureCollection = {
type: 'FeatureCollection',
features: []
};

if (Number(p.lon) === 0 || Number(p.lat) === 0) {
let errs: Error[] = [];

Check failure on line 79 in task.ts

View workflow job for this annotation

GitHub Actions / test

'errs' is never reassigned. Use 'const' instead
for (const agency of filteredAgencies) {
try {
const agencyForm = new FormData();
agencyForm.append('operation', 'get_archived_alerts_csv');
agencyForm.append('auth', String(layer.environment.Token));
agencyForm.append('post_data', JSON.stringify({
agency_id: agency,
from_date: moment().subtract(6, 'hours').unix() * 1000,
to_date: moment().unix() * 1000
}));

const alerts_res = await fetch("https://interface.active911.com/interface/interface.ajax.php", {
referrer: "https://interface.active911.com/interface/",
method: "POST",
body: agencyForm
})

if (!alerts_res.ok) {
console.error(await alerts_res.text())
await this.fetch(`/api/connection/${layer.connection}/layer/${layer.id}`, 'PATCH', {
environment: {
...layer.environment,
Token: undefined
}
});

await this.controlLogin(layer)
continue;
}

fc.features.push({
id: `active911-${p.id}`,
type: 'Feature',
properties: {
callsign: `${p.description}`,
time: moment(p.send).toISOString(),
remarks: `
Groups: ${p.units}
Author: ${p.source}
${p.details}
`
},
geometry: {
type: 'Point',
coordinates: [Number(p.lon), Number(p.lat)]
const alerts = JSON.parse(
(await alerts_res.text())
.trim()
.replace(/^\(/, '')
.replace(/\)$/, '')
).message;

const parsed = parse(alerts, { columns: true });

for (const p of parsed) {
if (p.place.trim().length) {
const coords = p.place
.trim()
.split(',')
.map((c: string) => { return Number(c) })
.slice(0, 2);

if (coords.length === 2 && !isNaN(coords[0]) && !isNaN(coords[1])) {
fc.features.push({
id: `active911-${p.id}-staging`,
type: 'Feature',
properties: {
callsign: `Staging: ${p.description}`,
time: moment(p.send).toISOString(),
remarks: `Groups: ${p.units}\n Author: ${p.source}\n ${p.details}`
},
geometry: {
type: 'Point',
coordinates: [coords[1], coords[0]]
}
});
}
}

if (Number(p.lon) === 0 || Number(p.lat) === 0) {
continue;
}
});
}

fc.features.push({
id: `active911-${p.id}`,
type: 'Feature',
properties: {
callsign: `${p.description}`,
time: moment(p.send).toISOString(),
remarks: `
Groups: ${p.units}
Author: ${p.source}
${p.details}
`
},
geometry: {
type: 'Point',
coordinates: [Number(p.lon), Number(p.lat)]
}
});
}
} catch(err) {
errs.push(err);
}
}

await this.submit(fc);

if (errs.length) {
throw new Error(JSON.stringify(errs));
}
}
}

Expand Down

0 comments on commit d919910

Please sign in to comment.