Separating code into files.

Bundling the code with node.
Adding some neccesary files.
This commit is contained in:
2022-07-05 20:09:49 +02:00
parent 62825829e2
commit 73ae583881
8 changed files with 7898 additions and 171 deletions

45
src/Configuration.js Normal file
View File

@ -0,0 +1,45 @@
export default class Configuration {
static NAME = 'midefos-idealista';
static _current;
static init() {
this._current = this._getConfig();
}
static get(key) {
const config = this._getConfig();
return config[key];
}
static save(config) {
window.localStorage.setItem(this.NAME, JSON.stringify(config));
this._current = config;
}
static _getConfig() {
const storageConfig = this._getFromLocalStorage();
if (!storageConfig) return this._default();
return storageConfig;
}
static _getFromLocalStorage() {
const storageConfig = window.localStorage.getItem(this.NAME);
if (!storageConfig) return null;
return JSON.parse(storageConfig);
}
static _default() {
return {
enabled: true,
percentages: true,
garage: false,
exterior: true,
lift: true,
'max-price': 120_000,
'max-price-per-meter': 1_500
}
}
}

71
src/Item.js Normal file
View File

@ -0,0 +1,71 @@
export default class Item {
static NAME_SELECTOR = '.item-link';
static PRICE_SELECTOR = '.item-price';
static ROOM_SELECTOR = '.item-detail-char .item-detail:nth-child(1)';
static METERS_SELECTOR = '.item-detail-char .item-detail:nth-child(2)';
static ADDITIONAL_INFORMATION_SELECTOR = '.item-detail-char .item-detail:nth-child(3)';
constructor(htmlNode) {
this._node = htmlNode;
this.name = this._extractName();
this.price = this._extractPrice();
this.meters = this._extractMeters();
this.priceMeter = this._extractPriceMeter();
this.additionalInfo = this._extractAdditionalInfo();
this.hasLift = this._extractLift();
this.isExterior = this._extractExterior();
}
_extractName() {
return this._node.querySelector(Item.NAME_SELECTOR).textContent;;
}
_extractPrice() {
const priceText = this._node.querySelector(Item.PRICE_SELECTOR).textContent;
return Number(priceText.replace('€', '').replace('.', '').replace(',', ''));
}
_extractMeters() {
let metersText = this._node.querySelector(Item.METERS_SELECTOR).textContent;
if (!metersText.includes('m²')) {
metersText = this._node.querySelector(Item.ROOM_SELECTOR).textContent;
}
return Number(metersText.replace('m²', ''));
}
_extractPriceMeter() {
return Math.round(this.price / this.meters);
}
_extractAdditionalInfo() {
const additionalInfo = this._node.querySelector(Item.ADDITIONAL_INFORMATION_SELECTOR);
if (!additionalInfo) return null;
return additionalInfo.textContent;
}
_extractLift() {
if (!this.additionalInfo) return false;
return this.additionalInfo.includes('con ascensor');
}
_extractExterior() {
if (!this.additionalInfo) return false;
return this.additionalInfo.includes('exterior');
}
isFlat() {
return this.name.includes('Piso');
}
isHouse() {
return this.name.includes('Casa');
}
isGround() {
return this.name.includes('Bajo');
}
}

87
src/ItemHTML.js Normal file
View File

@ -0,0 +1,87 @@
import Configuration from "./Configuration.js";
export default class ItemHTML {
static createInformation(item) {
return `
<div class='midefos-idealista-container'>
${this._createPercentagePriceHTML(item)}
${this._createPriceHTML(item)}
${this._createPriceMeterHTML(item)}
${this._createLiftHTML(item)}
${this._createInteriorHTML(item)}
</div>`
}
static _createPercentagePriceHTML(item) {
if (!Configuration.get('percentages')) return ``;
const twentyPercent = Math.round(item.price * 20 / 100);
const thirtyPercent = Math.round(item.price * 30 / 100);
return `
<span>
<strong>20%:</strong> ${twentyPercent}€ <br>
<strong>30%:</strong> ${thirtyPercent}
</span>`;
}
static _createPriceHTML(item) {
const desiredPrice = Configuration.get('max-price');
const desiredTwentyFivePercentMore = Math.round(desiredPrice * 1.25);
if (item.price <= desiredPrice) {
return `<span class='success'><strong>✓</strong> Precio</span>`;
} else if (item.price <= desiredTwentyFivePercentMore) {
return `<span class='warning'><strong>✓</strong> Precio</span>`;
}
return `<span class='error'><strong>X</strong> Precio</span>`;
}
static _createPriceMeterHTML(item) {
const desiredPricePerMeter = Configuration.get('max-price-per-meter');
const desiredTwentyFivePercentMore = Math.round(desiredPricePerMeter * 1.25);
if (item.priceMeter <= desiredPricePerMeter) {
return `<span class='success'><strong>m²:</strong> ${item.priceMeter}€</span>`;
} else if (item.priceMeter <= desiredTwentyFivePercentMore) {
return `<span class='warning'><strong>m²:</strong> ${item.priceMeter}€</span>`;
}
return `<span class='error'><strong>m²:</strong> ${item.priceMeter}€</span>`;
}
static _createLiftHTML(item) {
if (!Configuration.get('lift')) return ``;
if (!item.additionalInfo) {
if (item.isFlat()) return ``;
return this.__createIndividual('?', 'Ascensor', 'warning');
}
if (item.hasLift) {
return this.__createIndividual('✓', 'Ascensor', 'warning');
}
return this.__createIndividual('X', 'Ascensor', 'error');
}
static _createInteriorHTML(item) {
if (!Configuration.get('exterior')) return ``;
if (!item.additionalInfo) {
if (!item.isFlat()) return ``;
return `<span class='warning'><strong>?</strong> Exterior</span>`
}
if (item.isExterior) {
return `<span class='success'><strong>✓</strong> Exterior</span>`
}
return `<span class='error'><strong>X</strong> Exterior</span>`;
}
static __createIndividual(strongText, infoText, className = '') {
return `<span class='${className}'><strong>${strongText}</strong> ${infoText}</span>`;
}
}