The device detection data file contains meta data that can provide additional information about the various records in the data model.This example shows how to access this data and display the values available.
To help navigate the data, it's useful to have an understanding of the types of records that are present:
The example will output each component in turn, with a list of the properties associated with each component. Some of the possible values for each property are also displayed. There are too many profiles to display, so we just list the number of profiles for each component.
Finally, the evidence keys that are accepted by device detection are listed. These are the keys that, when added to the evidence collection in flow data, could have some impact on the result returned by device detection.
const path = require('path');
const require51 = (requestedPackage) => {
try {
return require(path.join(__dirname, '/../../../node_modules/', requestedPackage));
} catch (e) {
return require(path.join(__dirname, '/../../../../', requestedPackage));
}
};
require51('fiftyone.devicedetection.onpremise').DeviceDetectionOnPremisePipelineBuilder;
const LITE_V_4_1_HASH = '51Degrees-LiteV4.1.hash';
const truncateToNl = function (string) {
const lines = string.split('\n');
let result = '';
let i = 0;
for (; i < lines.length; i++) {
if (lines[i]) {
result = lines[i];
break;
}
}
if (i < lines.length) {
result += ' ...';
}
return result;
};
const outputProperties = function (component, output) {
const properties = component.getProperties();
for (const property of properties) {
output.write(`\x1b[31mProperty - ${property.name}\x1b[89m\x1b[0m\n`);
output.write(
`[Category: ${property.category}](${property.type} - ${property.description})\n`);
if (property.category.toLowerCase() !== 'device metrics') {
let valuesStr = 'Possible values: ';
const values = property.getValues();
let count = 0;
for (const value of values) {
valuesStr += truncateToNl(value.getName());
const description = value.getDescription();
if (description) {
valuesStr += `(${description})`;
}
valuesStr += ',';
if (++count >= 20) {
break;
}
}
if (property.getNumberOfValues() > 20) {
valuesStr += ` + ${property.getNumberOfValues() - 20} more ...`;
}
output.write(valuesStr);
output.write('\n');
}
}
};
const outputComponents = function (engine, output) {
const components = engine.components;
for (const value of Object.values(components)) {
output.write(`\x1b[34mComponent - ${value.name}\x1b[89m\x1b[0m\n`);
outputProperties(value, output);
output.write('\n');
}
};
const outputProfileDetails = async function (engine, output) {
const groups = {};
let count = 0;
output.write('\n');
const profiles = engine.profiles();
for (const profile of profiles) {
if (!groups[profile.component.name]) {
groups[profile.component.name] = 1;
} else {
groups[profile.component.name]++;
}
if (++count % 1000 === 0) {
output.write(`Load ${count} profiles\r`);
}
}
output.write(`Load completed: ${count} profiles\n`);
output.write('Profile count:\n');
for (const [key, value] of Object.entries(groups)) {
output.write(`${key} Profiles: ${value}\n`);
}
};
const outputEvidenceKeyDetails = async function (engine, output) {
output.write('\n');
output.write('Accepted evidence keys:\n');
for (const evidence of engine.evidenceKeyFilter.list) {
output.write(`\t${evidence}\n`);
}
};
const run = async function (dataFile, output) {
dataFile,
performanceProfile: 'LowMemory',
shareUsage: false,
autoUpdate: false,
updateOnStart: false,
fileSystemWatcher: false
}).build();
const device = pipeline.getElement('device');
await outputComponents(device, output);
await outputProfileDetails(device, output);
await outputEvidenceKeyDetails(device, output);
};
if (process.env.JEST_WORKER_ID === undefined) {
const args = process.argv.slice(2);
const dataFile = args.length > 0 ? args[0] :
ExampleUtils.
findFile(LITE_V_4_1_HASH);
if (dataFile !== undefined) {
run(dataFile, process.stdout);
} else {
console.error('Failed to find a device detection ' +
'data file. Make sure the device-detection-data ' +
'submodule has been updated by running ' +
'`git submodule update --recursive`. By default, the \'lite\' file ' +
'included with this code will be used. A different file can be ' +
'specified by supplying the full path as a command line argument');
}
};
module.exports = {
run
};