|
|
|
import { promisify } from "util";
|
|
|
|
import spawn from "async-spawner";
|
|
|
|
import FormData from "form-data";
|
|
|
|
import axios from "axios";
|
|
|
|
import tough from "tough-cookie";
|
|
|
|
import fs from "fs";
|
|
|
|
import axiosCookieJarSupport from "axios-cookiejar-support";
|
|
|
|
import * as path from "path";
|
|
|
|
|
|
|
|
import { LocationData, toCityCoordinates } from "./location";
|
|
|
|
import months from "./months";
|
|
|
|
|
|
|
|
axiosCookieJarSupport(axios);
|
|
|
|
|
|
|
|
const SM_URL =
|
|
|
|
"https://www.um.poznan.pl/mim/forms/sm_zgloszenia.html?instance=poznan_sm";
|
|
|
|
|
|
|
|
const headers = {
|
|
|
|
Accept:
|
|
|
|
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
|
|
|
Host: "www.um.poznan.pl",
|
|
|
|
Origin: "https://www.um.poznan.pl",
|
|
|
|
Referer:
|
|
|
|
"https://www.um.poznan.pl/mim/forms/sm_zgloszenia.html?instance=poznan_sm",
|
|
|
|
"User-Agent":
|
|
|
|
"Mozilla/5.0 (X11; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0",
|
|
|
|
};
|
|
|
|
|
|
|
|
const minimal_data = {
|
|
|
|
lhs: "eurzad",
|
|
|
|
instance: "poznan_sm",
|
|
|
|
};
|
|
|
|
|
|
|
|
function formatTimestamp(timestamp: Date) {
|
|
|
|
const date_str = `${timestamp.getDate()} ${
|
|
|
|
months[timestamp.getMonth()]
|
|
|
|
} ${timestamp.getFullYear()}`;
|
|
|
|
const time = `${timestamp.getHours()}:${
|
|
|
|
timestamp.getMinutes() < 10 ? "0" : ""
|
|
|
|
}${timestamp.getMinutes()}`;
|
|
|
|
return [date_str, time];
|
|
|
|
}
|
|
|
|
|
|
|
|
type ContactDetails = {
|
|
|
|
email: string;
|
|
|
|
imie_nazwisko: string;
|
|
|
|
adres: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
export async function submit(
|
|
|
|
location: LocationData,
|
|
|
|
reason: string,
|
|
|
|
photos: Array<string>,
|
|
|
|
timestamp: Date,
|
|
|
|
contact_details: ContactDetails,
|
|
|
|
plate: string
|
|
|
|
) {
|
|
|
|
if (location.address.includes("\n")) {
|
|
|
|
throw new Error("no newlines allowed in address");
|
|
|
|
}
|
|
|
|
const { x, y } = toCityCoordinates(location.coordinates);
|
|
|
|
|
|
|
|
const jar = new tough.CookieJar();
|
|
|
|
|
|
|
|
const transport = axios.create({
|
|
|
|
withCredentials: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
await transport.get(SM_URL, {
|
|
|
|
headers,
|
|
|
|
jar,
|
|
|
|
});
|
|
|
|
|
|
|
|
const subject = `Nieprawidłowo zaparkowany samochód - ${location.address}`;
|
|
|
|
|
|
|
|
const [date_str, hour] = formatTimestamp(timestamp);
|
|
|
|
|
|
|
|
const body = `Samochód ${
|
|
|
|
reason || ""
|
|
|
|
}. Numer rejestracyjny samochodu: ${plate} Zdjęci${
|
|
|
|
photos.length === 1 ? "e" : "a"
|
|
|
|
} wykonane ${date_str} o godz. ${hour} w pobliżu ul. ${
|
|
|
|
location.address
|
|
|
|
}. Wnoszę o ukaranie.
|
|
|
|
`;
|
|
|
|
|
|
|
|
const main_data = {
|
|
|
|
...minimal_data,
|
|
|
|
srs: "EPSG:2177",
|
|
|
|
uz_process_personal_data_agreement: "Y",
|
|
|
|
uz_kategoria: 86808,
|
|
|
|
uz_temat: subject,
|
|
|
|
uz_tresc: body,
|
|
|
|
uz_email: contact_details.email,
|
|
|
|
uz_odpowiedz: "tak",
|
|
|
|
uz_imie_nazwisko: contact_details.imie_nazwisko,
|
|
|
|
uz_adres: contact_details.adres,
|
|
|
|
};
|
|
|
|
|
|
|
|
const forms = [
|
|
|
|
{
|
|
|
|
...main_data,
|
|
|
|
source: "sm_zgloszenia_step1",
|
|
|
|
goto_sm_zgloszenia_step1_1: "",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
source: "sm_zgloszenia_step1_1",
|
|
|
|
x,
|
|
|
|
y,
|
|
|
|
lon: x,
|
|
|
|
lat: y,
|
|
|
|
srs: "EPSG:2177",
|
|
|
|
id_ulica_city: "Poznań",
|
|
|
|
srs_id: "EPSG:2177",
|
|
|
|
id_ulica_street_lookup: "Limanowskiego",
|
|
|
|
goto_sm_zgloszenia_step1: "",
|
|
|
|
},
|
|
|
|
{ ...main_data, goto_sm_zgloszenia_step1_2: "" },
|
|
|
|
...photos.map((file_path) => ({
|
|
|
|
...minimal_data,
|
|
|
|
source: "sm_zgloszenia_step1_2",
|
|
|
|
goto_sm_zgloszenia_step1_2: "",
|
|
|
|
uz_file: {
|
|
|
|
path: file_path,
|
|
|
|
filename: "photo1.jpg",
|
|
|
|
contentType: "image/jpeg",
|
|
|
|
},
|
|
|
|
})),
|
|
|
|
{
|
|
|
|
...minimal_data,
|
|
|
|
source: "sm_zgloszenia_step1_2",
|
|
|
|
goto_sm_zgloszenia_step1: "",
|
|
|
|
},
|
|
|
|
{ ...main_data, source: "sm_zgloszenia_step1", goto_summary: "" },
|
|
|
|
];
|
|
|
|
|
|
|
|
for (let form of forms) {
|
|
|
|
const formData = new FormData();
|
|
|
|
for (let [key, value] of Object.entries(form)) {
|
|
|
|
if (value.path) {
|
|
|
|
formData.append(key, fs.createReadStream(value.path), {
|
|
|
|
filename: value.filename,
|
|
|
|
contentType: value.contentType,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
formData.append(key, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const response = await transport.post(SM_URL, formData, {
|
|
|
|
headers: { ...headers, ...formData.getHeaders() },
|
|
|
|
jar,
|
|
|
|
});
|
|
|
|
console.log(response.request._headers);
|
|
|
|
}
|
|
|
|
const session_id = (jar as any).store.idx["www.um.poznan.pl"]["/mim"]
|
|
|
|
.JSESSIONID.value;
|
|
|
|
|
|
|
|
const response = await spawn("curl", [
|
|
|
|
"https://www.um.poznan.pl/mim/forms/sm_zgloszenia.html?instance=poznan_sm",
|
|
|
|
"-H",
|
|
|
|
`User-Agent: ${headers["User-Agent"]}`,
|
|
|
|
"-H",
|
|
|
|
`Accept: ${headers.Accept}`,
|
|
|
|
"-H",
|
|
|
|
"Accept-Language: en-US,en;q=0.5",
|
|
|
|
"--compressed",
|
|
|
|
"-H",
|
|
|
|
"Content-Type: application/x-www-form-urlencoded",
|
|
|
|
"-H",
|
|
|
|
`Origin: ${headers.Origin}`,
|
|
|
|
"-H",
|
|
|
|
"DNT: 1",
|
|
|
|
"-H",
|
|
|
|
"Connection: keep-alive",
|
|
|
|
"-H",
|
|
|
|
`Referer: ${headers.Referer}`,
|
|
|
|
"-H",
|
|
|
|
`Cookie: mim_cookie_test=enabled; JSESSIONID=${session_id}`,
|
|
|
|
"-H",
|
|
|
|
"Upgrade-Insecure-Requests: 1",
|
|
|
|
"--data",
|
|
|
|
`action=save&source=summary&instance=poznan_sm&x=${x}&y=${y}&lon=${x}&lat=${y}&srs=EPSG%3A2177&goto_thanks=`,
|
|
|
|
]);
|
|
|
|
const matches = response.match(
|
|
|
|
/<li>Numer: <strong>([0-9]+)<\/strong><\/li>/
|
|
|
|
);
|
|
|
|
if (matches === null) {
|
|
|
|
throw new Error("Could not extract submission number");
|
|
|
|
}
|
|
|
|
return matches[1];
|
|
|
|
}
|