Basic support for debug info.

Returning status of each source as part of vehicle model.
This commit is contained in:
Selim Mustafaev 2021-01-02 19:33:51 +03:00
parent d1ebe4b2f4
commit 5de45af0e5
5 changed files with 149 additions and 74 deletions

13
.vscode/launch.json vendored
View File

@ -4,6 +4,19 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "Launch via NPM",
"request": "launch",
"runtimeArgs": [
"run",
"server"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "pwa-node"
},
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",

View File

@ -2,6 +2,7 @@ const crypto = require('crypto');
const fetch = require('node-fetch'); const fetch = require('node-fetch');
const Vehicle = require('../models/vehicle'); const Vehicle = require('../models/vehicle');
const PubNub = require('pubnub'); const PubNub = require('pubnub');
const { SSL_OP_SSLEAY_080_CLIENT_DH_BUG } = require('constants');
const baseUrl = 'https://avtocod.ru/api/v3'; const baseUrl = 'https://avtocod.ru/api/v3';
let deviceToken = crypto.createHash('sha256').update(Date.now().toString()).digest().toString('hex'); let deviceToken = crypto.createHash('sha256').update(Date.now().toString()).digest().toString('hex');
@ -74,28 +75,38 @@ function waitForReport(pubnubConfig, channel) {
class AvtocodProvider { class AvtocodProvider {
static async getReport(number) { static async getReport(number) {
let url = `${baseUrl}/auto/generate?number=${encodeURIComponent(number)}&device_token=${deviceToken}`; try {
let resp = await getJson(url); let url = `${baseUrl}/auto/generate?number=${encodeURIComponent(number)}&device_token=${deviceToken}`;
let resp = await getJson(url);
let html = await getPage(resp.report_uri); let html = await getPage(resp.report_uri);
let result = html.match(/<meta name="app-version-hash" content="(.*?)" \/>/); let result = html.match(/<meta name="app-version-hash" content="(.*?)" \/>/);
if(result == null) { if(result == null) {
throw Error('Error getting api version hash'); throw Error('Error getting api version hash');
} }
let hash = result[1]; let hash = result[1];
result = html.match(/value:(.*report_container.*)/); result = html.match(/value:(.*report_container.*)/);
if(result == null) { if(result == null) {
throw Error('Error getting report data'); throw Error('Error getting report data');
}
let mainData = JSON.parse(result[1]);
let report = decryptReport(mainData.report_container.report, hash);
if(report == null) {
report = await waitForReport(mainData.pubnub, mainData.report_container.channel);
}
let vehicle = Vehicle.fromAvtocod(report);
console.log('Avtocod found vehicle: ', vehicle?.brand?.name?.original);
return vehicle;
} catch(ex) {
ex.debugInfo = {
autocod: {
fields: 0n,
error: ex.message
}
}
throw ex;
} }
let mainData = JSON.parse(result[1]);
let report = decryptReport(mainData.report_container.report, hash);
if(report == null) {
report = await waitForReport(mainData.pubnub, mainData.report_container.channel);
}
let vehicle = Vehicle.fromAvtocod(report);
console.log('Avtocod found vehicle: ', vehicle?.brand?.name?.original);
return vehicle;
} }
} }

View File

@ -54,62 +54,87 @@ class Vin01Provider {
} }
static async getReport(number, token) { static async getReport(number, token) {
let vin = await Vin01Provider.getVin(number, token); try {
console.log('vin01 found VIN: ', vin); let vin = await Vin01Provider.getVin(number, token);
console.log('vin01 found VIN: ', vin);
let checks = [Vin01Provider.runCheck('base', vin, token), Vin01Provider.runCheck('history', vin, token)]; let checks = [Vin01Provider.runCheck('base', vin, token), Vin01Provider.runCheck('history', vin, token)];
let [base, history] = (await Promise.allSettled(checks)).map(Vin01Provider.checkErrors); let [base, history] = (await Promise.allSettled(checks)).map(Vin01Provider.checkErrors);
if(base.status == 'rejected' && history.status == 'rejected') { if(base.status == 'rejected' && history.status == 'rejected') {
console.log('Vin01 base error: ', base.reason); console.log('Vin01 base error: ', base.reason);
console.log('Vin01 history error: ', history.reason); console.log('Vin01 history error: ', history.reason);
let vehicle = new Vehicle(); let vehicle = new Vehicle();
vehicle.vin1 = Utils.cyrillicToLatin(vin); vehicle.vin1 = Utils.cyrillicToLatin(vin);
return vehicle; vehicle.debugInfo = {
} else if(base.status == 'rejected') { vin01vin: { fields: 0n, error: null },
console.log('vin01 found history'); vin01history: { fields: 0n, error: history.reason },
let vehicle = Vehicle.fromVin01History(history.value); vin01base: { fields: 0n, error: base.reason }
vehicle.number = number; }
return vehicle; return vehicle;
} else if(history.status == 'rejected') { } else if(base.status == 'rejected') {
console.log('vin01 found base info'); console.log('vin01 found history');
let vehicle = Vehicle.fromVin01Base(base.value); let vehicle = Vehicle.fromVin01History(history.value);
vehicle.number = number; vehicle.number = number;
return vehicle; Object.assign(vehicle.debugInfo, {
} else { vin01vin: { fields: 0n, error: null },
// Both history and base reports were successfully received, merge them in one report vin01base: { fields: 0n, error: base.reason }
let baseVehicle = Vehicle.fromVin01Base(base.value); });
let historyVehicle = Vehicle.fromVin01History(history.value); return vehicle;
} else if(history.status == 'rejected') {
console.log('vin01 found base info');
let vehicle = Vehicle.fromVin01Base(base.value);
vehicle.number = number;
Object.assign(vehicle.debugInfo, {
vin01vin: { fields: 0n, error: null },
vin01history: { fields: 0n, error: history.reason }
});
return vehicle;
} else {
// Both history and base reports were successfully received, merge them in one report
let baseVehicle = Vehicle.fromVin01Base(base.value);
let historyVehicle = Vehicle.fromVin01History(history.value);
historyVehicle.brand.name.normalized = baseVehicle.brand.name.normalized; historyVehicle.brand.name.normalized = baseVehicle.brand.name.normalized;
historyVehicle.model = baseVehicle.model; historyVehicle.model = baseVehicle.model;
for(let period of historyVehicle.ownershipPeriods) { for(let period of historyVehicle.ownershipPeriods) {
let basePeriod = baseVehicle.ownershipPeriods.find(p => p.from == period.from); let basePeriod = baseVehicle.ownershipPeriods.find(p => p.from == period.from);
if(basePeriod) { if(basePeriod) {
period.region = basePeriod.region; period.region = basePeriod.region;
period.registrationRegion = basePeriod.registrationRegion; period.registrationRegion = basePeriod.registrationRegion;
period.locality = basePeriod.locality; period.locality = basePeriod.locality;
if(basePeriod.street) { if(basePeriod.street) {
period.street = basePeriod.street; period.street = basePeriod.street;
} }
if(basePeriod.building) { if(basePeriod.building) {
period.building = basePeriod.building; period.building = basePeriod.building;
} }
if(basePeriod.inn) { if(basePeriod.inn) {
period.inn = basePeriod.inn; period.inn = basePeriod.inn;
} }
if(basePeriod.code) { if(basePeriod.code) {
period.code = basePeriod.code; period.code = basePeriod.code;
}
} }
} }
}
historyVehicle.number = number; Object.assign(historyVehicle.debugInfo, { vin01vin: { fields: 0n, error: null } });
return historyVehicle; Object.assign(historyVehicle.debugInfo, baseVehicle.debugInfo);
historyVehicle.number = number;
return historyVehicle;
}
} catch(ex) {
ex.debugInfo = {
vin01vin: { fields: 0n, error: ex.message },
vin01history: { fields: 0n, error: 'Not applicable' },
vin01base: { fields: 0n, error: 'Not applicable' }
}
throw ex;
} }
} }
} }

View File

@ -61,6 +61,13 @@ class Vehicle {
v.addedDate = Date.now(); v.addedDate = Date.now();
v.events = []; v.events = [];
v.debugInfo = {
autocod: {
fields: 0n,
error: null
}
};
return v; return v;
} }
@ -97,6 +104,13 @@ class Vehicle {
v.addedDate = Date.now(); v.addedDate = Date.now();
v.events = []; v.events = [];
v.debugInfo = {
vin01history: {
fields: 0n,
error: null
}
};
return v; return v;
} }
@ -151,6 +165,13 @@ class Vehicle {
v.addedDate = Date.now(); v.addedDate = Date.now();
v.events = []; v.events = [];
v.debugInfo = {
vin01base: {
fields: 0n,
error: null
}
};
return v; return v;
} }
} }

View File

@ -45,8 +45,10 @@ router.post('/check', async (req, res) => {
throw Error(autocod.reason); throw Error(autocod.reason);
} else if(vin01.status == 'rejected') { } else if(vin01.status == 'rejected') {
vehicle = autocod.value; vehicle = autocod.value;
Object.assign(vehicle.debugInfo, vin01.reason.debugInfo);
} else if(autocod.status == 'rejected') { } else if(autocod.status == 'rejected') {
vehicle = vin01.value; vehicle = vin01.value;
Object.assign(vehicle.debugInfo, autocod.reason.debugInfo);
if(!vehicle.brand.name.normalized) { if(!vehicle.brand.name.normalized) {
throw Error(autocod.reason); throw Error(autocod.reason);
} }
@ -58,11 +60,14 @@ router.post('/check', async (req, res) => {
vehicle.color = vin01.value.color; vehicle.color = vin01.value.color;
vehicle.ownershipPeriods = vin01.value.ownershipPeriods; vehicle.ownershipPeriods = vin01.value.ownershipPeriods;
} }
Object.assign(vehicle.debugInfo, vin01.value.debugInfo);
} }
if(nomerogram.status == 'fulfilled') { if(nomerogram.status == 'fulfilled') {
vehicle.ads = nomerogram.value; vehicle.ads = nomerogram.value;
Object.assign(vehicle.debugInfo, { fields: 0n, error: null });
} else { } else {
Object.assign(vehicle.debugInfo, nomerogram.reason.debugInfo);
console.error('nomerogram error: ', nomerogram.reason); console.error('nomerogram error: ', nomerogram.reason);
} }