Skip to content

Instantly share code, notes, and snippets.

@jimarnold
Created March 31, 2022 20:59
Show Gist options
  • Save jimarnold/ee00c36733adeddb0836dcc0e9a933fe to your computer and use it in GitHub Desktop.
Save jimarnold/ee00c36733adeddb0836dcc0e9a933fe to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
require('@babel/register');
require('@babel/polyfill');
const DB = require('../server/db').default;
const USER_REPO_PATH = './user_repositories/koliva';
const Taxonomy = require('../src/data/taxonomy').default,
Attributes = require('../src/data/attributes').default,
Values = require('../src/data/values').default,
CONFIG = require('../config.js').default;
const db = {
taxonomy: DB.forPath(CONFIG.DB_PATH().TAXONOMY),
attributes: DB.forPath(CONFIG.DB_PATH().ATTRIBUTES),
values: DB.forPath(CONFIG.DB_PATH().VALUES)
};
const loadAll = async (callback) => {
let res = {};
db.taxonomy.all().then(function(data) {
res.taxonomy = Taxonomy.create(data);
db.attributes.all().then(function(data) {
res.attributes = Attributes.create(data);
db.values.all().then(function(data) {
res.values = Values.create(data);
callback(res);
});
});
});
}
const fetchChildrenAttributeIds = (attributes, attributeId) =>
attributes
.children(attributeId)
.splice(0, 0, attributeId)
.toArray();
const boolCompare = (a, b, fn) => fn(b) - fn(a);
const COLOR_ATTRIBUTE_IDS = attributes => fetchChildrenAttributeIds(attributes, COLOR);
const MATERIAL_ATTRIBUTE_IDS = attributes => fetchChildrenAttributeIds(attributes, MATERIAL);
const STYLE_ATTRIBUTE_IDS = attributes => fetchChildrenAttributeIds(attributes, STYLE);
const CRAFT_TYPE = 20;
const COLOR = 1;
const MATERIAL = 5;
const STYLE = 583;
const YES_NO_CAN_BE_PERSONALIZED = 344;
const YES_NO = 10;
const HOLIDAY = 4;
const OCCASION = 3;
const RECIPIENT = 342;
const ROOM = 349;
const ART_SUBJECT = 515;
const SEASON = 475;
const YES_NO_SEXY = 394;
const YES_NO_ART_YARN = 281;
const is = attributeId => (a, b) => boolCompare(a, b, x => x === attributeId);
const craftTypeIsTheOnlyRequiredAttribute = (a, b, attributes, taxoNodeHasSingleRequiredAttribute) =>
boolCompare(
a,
b,
x => taxoNodeHasSingleRequiredAttribute && x === CRAFT_TYPE
);
const isColor = (a, b, attributes) =>
boolCompare(a, b, x => COLOR_ATTRIBUTE_IDS(attributes).includes(x));
const isASizeMeasurementOrDecimalAttr = (a, b, attributes) =>
boolCompare(a, b, x => ['measurement', 'decimal'].includes(attributes.userInputType(x)));
const hasSizeInTheName = (a, b, attributes) =>
boolCompare(
a,
b,
x =>
attributes
.name(x)
.toLowerCase()
.indexOf('size') > -1
);
const canBePersonalized = (a, b) => boolCompare(a, b, x => x === YES_NO_CAN_BE_PERSONALIZED);
const hasThemeInTheName = (a, b, attributes) =>
boolCompare(
a,
b,
x =>
attributes
.name(x)
.toLowerCase()
.indexOf('theme') > -1
);
const hasGraphicInTheName = (a, b, attributes) =>
boolCompare(
a,
b,
x =>
attributes
.name(x)
.toLowerCase()
.indexOf('graphic') > -1
);
const isAMaterial = (a, b, attributes) =>
boolCompare(a, b, x => MATERIAL_ATTRIBUTE_IDS(attributes).includes(x));
const isAStyleAttribute = (a, b, attributes) =>
boolCompare(a, b, x => STYLE_ATTRIBUTE_IDS(attributes).includes(x));
const isYesNo = (a, b, attributes) =>
boolCompare(
a,
b,
x => attributes.parent(x) !== undefined && attributes.parent(x).get('id') === YES_NO
);
const EQUAL = 0;
const sortAvsOrder = (attributes, hasSingleRequiredAttribute, a, b) => {
let rules = [
craftTypeIsTheOnlyRequiredAttribute,
isAMaterial,
isColor,
hasSizeInTheName,
isASizeMeasurementOrDecimalAttr,
isYesNo,
null, // indicator to de-prioritize the reset of the rules
isAStyleAttribute,
is(OCCASION),
is(HOLIDAY),
is(RECIPIENT),
is(ROOM),
is(ART_SUBJECT),
is(SEASON),
hasThemeInTheName,
hasGraphicInTheName,
is(YES_NO_SEXY),
is(YES_NO_ART_YARN),
canBePersonalized
];
let prioritize = true;
let factor = 1;
while (rules.length > 0) {
const rule = rules.shift();
//console.log('Evaluating rule ' + rule.toString() + ' for a=' + a.attribute() + ' compared to b=' + b.attribute());
if (rule === null) {
prioritize = false;
continue;
}
factor = prioritize ? 1 : -1;
const result = factor * rule(a, b, attributes);
if (result !== EQUAL) {
//console.log('Result was ' + result);
return result;
}
}
//console.log('Nodes considered equal');
return EQUAL;
};
const getNewAvsOrder = (hierarchies, node, hasSingleRequiredAttribute) => {
return hierarchies.taxonomy
.avsOrder(node)
.sort(sortAvsOrder.bind(this, hierarchies.attributes, hasSingleRequiredAttribute))
.toArray();
};
const updateAvsOrder = hierarchies => {
const taxonomy = hierarchies.taxonomy;
taxonomy.data.forEach(n => {
//console.log(`Processing node ${n.get('id')}`);
if (taxonomy.isSellerNode(n)) {
const requiredAVSes = taxonomy.hydratedAttributeValueSets(n)
.filter(avs => avs.get('isRequired'))
.map(avs => avs.attribute());
const hasSingleRequiredAttribute = requiredAVSes.size === 1;
// const order = avses
// .sort(sortAvs.bind(this, hierarchies, id, attributeNodeCounts, scaledAttributes))
// .map(a => a.attribute())
// .toArray();
// const line = taxonomy.nodeName(n) + ' (' + id + ') Order=[' + order.join(', ') + ']\n';
// lines += line;
const newNode = n.set('avsOrder', getNewAvsOrder(hierarchies, n, hasSingleRequiredAttribute));
//const db = DB.forUser({ repoPath: USER_REPO_PATH }, 'TAXONOMY');
const id = n.get('id');
//db.write(id, newNode);
// db.taxonomy.write(id, newNode).done();
}
});
//fs.writeFile('output.txt', lines);
};
loadAll(updateAvsOrder);
const IDs = {
MATERIAL,
YES_NO_ADJUSTABLE: 186,
OCCASION,
YES_NO_ART_YARN,
YES_NO_CAN_BE_PERSONALIZED
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment