hometify/server/db/mysql/repository/HouseRepository.ts

119 lines
3.8 KiB
TypeScript

import { Op, sequelize, House } from "../../../db/mysql/db.config";
export class HouseRepository {
public async findAll(): Promise<string[]> {
return await House.findAll();
}
public async filterHouseByTitleAndExactPriceAndRoomsAndBaths(houseCandidates: any): Promise<string[]> {
const mergedHouses: any[] = [];
for (let i = 0; i < houseCandidates.length; i++) {
const houseCandidate = houseCandidates[i];
const sanitizedTitle = houseCandidate.title.replace(/'/g, "\\'");
const matchingHouses = await House.findAll({
where: {
[Op.and]: [
{ price: houseCandidate.rawPrice },
{ rooms: houseCandidate.rooms },
{ area: houseCandidate.area },
{ baths: houseCandidate.baths },
sequelize.literal(`MATCH(title) AGAINST('${sanitizedTitle}' IN NATURAL LANGUAGE MODE)`)
]
}
});
const resultHouse = this.mergeHouseProperties(matchingHouses);
if (matchingHouses.length > 0) {
mergedHouses.push(resultHouse);
houseCandidates = houseCandidates.filter((candidate: any) => {
return !matchingHouses.some((matchedHouse: any) => {
return (
candidate.rawPrice === matchedHouse.price &&
candidate.rooms === matchedHouse.rooms &&
candidate.area === matchedHouse.area &&
candidate.baths === matchedHouse.baths
);
});
});
i = -1;
}
}
return mergedHouses;
}
private mergeHouseProperties(houses: any[]): any {
if (!Array.isArray(houses)) {
throw new Error("El parámetro 'houses' debe ser un array.");
}
const mergedHouse = {
//id: this.getLongestString(houses.map(h => h.id)) || Math.floor(Math.random() * 100000000).toString().padStart(8, '0'),
title: this.getLongestString(houses.map(h => h.title)),
url: this.joinByComma(houses.map(h => h.url)),
neighborhood: this.getLongestString(houses.map(h => h.neighborhood)),
area: houses[0]?.area || 0,
rooms: houses[0]?.rooms || 0,
price: houses[0]?.price || 0,
description: this.getLongestString(houses.map(h => h.description)),
pic: this.joinByComma(houses.map(h => h.pic)),
baths: houses[0]?.baths || 0,
level: this.getLongestString(houses.map(h => h.level)),
phone: this.joinByComma(houses.map(h => h.phone))
};
return mergedHouse;
}
private getLongestString(strings: string[]): string {
const preSelectedString = strings
.filter(str => str && !str.startsWith('<a href='))
.reduce((longest, current) => current && current.length > longest.length ? current : longest, "");
const alternativeString = strings.reduce((longest, current) => current && current.length > longest.length ? current : longest, "");
return preSelectedString !== "" ? preSelectedString : this.parseLinks(alternativeString);
}
private joinByComma(items: string[]): string {
return items.filter(Boolean).join(', ');
}
private parseLinks(htmlString: string): string {
const anchorTagRegex = /<a href="\/comprar\/(.*?)18.*?"[^>]*>(.*?)<\/a>/g;
let match;
let result = "";
while ((match = anchorTagRegex.exec(htmlString)) !== null) {
const urlPart = match[1];
const innerText = match[2].trim();
if (!innerText) {
result= this.snakeToSpaceCase(urlPart);
} else {
result = innerText;
}
}
return result;
}
private snakeToSpaceCase(snakeCaseString: string): string {
let spaceCaseString = snakeCaseString.replace(/[_-]/g, ' ');
spaceCaseString = spaceCaseString.split(' ').map(word => {
return word.charAt(0).toUpperCase() + word.slice(1);
}).join(' ');
return spaceCaseString;
}
}