Adding information from GitHub.
This commit is contained in:
		@@ -11,6 +11,7 @@ export default class Information {
 | 
			
		||||
        Log.debug(`Creating information for ${items.length} items...`)
 | 
			
		||||
        for (const itemNode of items) {
 | 
			
		||||
            const item = new Item(itemNode);
 | 
			
		||||
            item.extractAsyncData();
 | 
			
		||||
            item.refreshData();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								src/Item.js
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/Item.js
									
									
									
									
									
								
							@@ -1,4 +1,5 @@
 | 
			
		||||
import ItemHTML from './ItemHTML.js';
 | 
			
		||||
import Locations from './Locations.js';
 | 
			
		||||
 | 
			
		||||
export default class Item {
 | 
			
		||||
 | 
			
		||||
@@ -14,14 +15,13 @@ export default class Item {
 | 
			
		||||
        this._node = htmlNode;
 | 
			
		||||
 | 
			
		||||
        this.name = this._extractName();
 | 
			
		||||
 | 
			
		||||
        this.locationName = this._extractLocationName();
 | 
			
		||||
        //this.location = this._extractLocation();
 | 
			
		||||
 | 
			
		||||
        this.price = this._extractPrice();
 | 
			
		||||
        this.meters = this._extractMeters();
 | 
			
		||||
        this.priceMeter = this._extractPriceMeter();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this.additionalInfo = this._extractAdditionalInfo();
 | 
			
		||||
        this.hasGarage = this._extractGarage();
 | 
			
		||||
        this.hasLift = this._extractLift();
 | 
			
		||||
@@ -33,6 +33,11 @@ export default class Item {
 | 
			
		||||
        return this._node.nextElementSibling;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async extractAsyncData() {
 | 
			
		||||
        this.location = await this._extractLocation();
 | 
			
		||||
        this.refreshData();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    refreshData() {
 | 
			
		||||
        this.removeData();
 | 
			
		||||
        this.addData();
 | 
			
		||||
@@ -85,9 +90,20 @@ export default class Item {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _extractLocationName() {
 | 
			
		||||
        return this.name
 | 
			
		||||
        if (this.name.lastIndexOf(',') != -1) {
 | 
			
		||||
            return this.name
 | 
			
		||||
            .substring(this.name.lastIndexOf(','), this.name.length)
 | 
			
		||||
            .replaceAll('.', '').replaceAll(',', '');
 | 
			
		||||
            .replaceAll('\n', '').replaceAll('.', '')
 | 
			
		||||
            .replaceAll(',', '').replaceAll(' ', '');
 | 
			
		||||
        }
 | 
			
		||||
        return this.name
 | 
			
		||||
            .substring(this.name.lastIndexOf(' en ') + ' en '.length, this.name.length)
 | 
			
		||||
            .replaceAll('\n', '').replaceAll('.', '')
 | 
			
		||||
            .replaceAll(' ', '');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _extractLocation() {
 | 
			
		||||
        return Locations.get(this.locationName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _extractPrice() {
 | 
			
		||||
@@ -96,10 +112,16 @@ export default class Item {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _extractMeters() {
 | 
			
		||||
        let metersText = this._node.querySelector(Item.METERS_SELECTOR).textContent;
 | 
			
		||||
        if (!metersText.includes('m²')) {
 | 
			
		||||
        let metersNode = this._node.querySelector(Item.METERS_SELECTOR);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        let metersText;
 | 
			
		||||
        if (!metersNode || !metersNode.textContent.includes('m²')) {
 | 
			
		||||
            metersText = this._node.querySelector(Item.ROOM_SELECTOR).textContent;
 | 
			
		||||
        } else {
 | 
			
		||||
            metersText = metersNode.textContent;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Number(metersText
 | 
			
		||||
            .replace('m²', '')
 | 
			
		||||
            .replaceAll('.', '')
 | 
			
		||||
@@ -115,6 +137,7 @@ export default class Item {
 | 
			
		||||
        if (!additionalInfo) {
 | 
			
		||||
            additionalInfo = this._node.querySelector(Item.METERS_SELECTOR);
 | 
			
		||||
        }
 | 
			
		||||
        if (!additionalInfo) return null;
 | 
			
		||||
        return additionalInfo.textContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										115
									
								
								src/ItemHTML.js
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								src/ItemHTML.js
									
									
									
									
									
								
							@@ -43,20 +43,37 @@ export default class ItemHTML {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static createInformation(item) {
 | 
			
		||||
        return `
 | 
			
		||||
        <div class='${this.CONTAINER_CLASS_NAME} ${this.ITEM_STATE_CLASS_NAME(item)}'>
 | 
			
		||||
            <div class='${this.INFORMATION_CONTAINER_CLASS_NAME}'>
 | 
			
		||||
                ${this._createPercentagePriceHTML(item)}
 | 
			
		||||
                ${this._createPriceHTML(item)}
 | 
			
		||||
                ${this._createPriceMeterHTML(item)}
 | 
			
		||||
                ${this._createGarageHTML(item)}
 | 
			
		||||
                ${this._createLiftHTML(item)}
 | 
			
		||||
                ${this._createExteriorHTML(item)}
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class='${this.INFORMATION_CONTAINER_CLASS_NAME}'>
 | 
			
		||||
                ${this._createLocationInformation(item)}
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>`
 | 
			
		||||
        let html = `<div class='${this.CONTAINER_CLASS_NAME} ${this.ITEM_STATE_CLASS_NAME(item)}'>`;
 | 
			
		||||
        html += `<div class='${this.INFORMATION_CONTAINER_CLASS_NAME}'>`;
 | 
			
		||||
        html += this._createPercentagePriceHTML(item);
 | 
			
		||||
        html += this._createPriceHTML(item);
 | 
			
		||||
        html += this._createPriceMeterHTML(item);
 | 
			
		||||
        html += this._createGarageHTML(item);
 | 
			
		||||
        html += this._createLiftHTML(item);
 | 
			
		||||
        html += this._createExteriorHTML(item);
 | 
			
		||||
        html += `</div>`;
 | 
			
		||||
 | 
			
		||||
        html += `<div class='${this.INFORMATION_CONTAINER_CLASS_NAME}'>`;
 | 
			
		||||
        html += this._createLocationName(item);
 | 
			
		||||
 | 
			
		||||
        if (item.location && item.location.name) {
 | 
			
		||||
            html += this._createLocationTrain(item);
 | 
			
		||||
            html += this._createLocationBus(item);
 | 
			
		||||
            html += this._createLocationGym(item);
 | 
			
		||||
            html += this._createLocationPool(item);
 | 
			
		||||
            html += this._createLocationSupermarket(item);
 | 
			
		||||
            html += this._createLocationSmoke(item);
 | 
			
		||||
            html += this._createLocationPharmacy(item);
 | 
			
		||||
        } else if (item.location && item.location.errorMessage) {
 | 
			
		||||
            html += this._createError(item.location.errorMessage);
 | 
			
		||||
        } else {
 | 
			
		||||
            html += this._createNeutral(`Cargando datos...`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        html += `</div>`;
 | 
			
		||||
        html += `</div>`;
 | 
			
		||||
 | 
			
		||||
        return html;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createPercentagePriceHTML(item) {
 | 
			
		||||
@@ -162,10 +179,78 @@ export default class ItemHTML {
 | 
			
		||||
        return this._createMissing('Exterior');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationInformation(item) {
 | 
			
		||||
    static _createLocationName(item) {
 | 
			
		||||
        return this._createNeutral(item.locationName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationTrain(item) {
 | 
			
		||||
        if (!Preferences.get('train')) return ``;
 | 
			
		||||
 | 
			
		||||
        if (item.location?.train) {
 | 
			
		||||
            return this._createSuccess('Tren');
 | 
			
		||||
        }
 | 
			
		||||
        return this._createError('Tren');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationBus(item) {
 | 
			
		||||
        if (!Preferences.get('bus')) return ``;
 | 
			
		||||
 | 
			
		||||
        if (item.location?.bus) {
 | 
			
		||||
            return this._createSuccess('Bus');
 | 
			
		||||
        }
 | 
			
		||||
        return this._createError('Bus');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationGym(item) {
 | 
			
		||||
        if (!Preferences.get('gym')) return ``;
 | 
			
		||||
 | 
			
		||||
        if (item.location?.gym) {
 | 
			
		||||
            return this._createSuccess('Gimnasio');
 | 
			
		||||
        }
 | 
			
		||||
        return this._createError('Gimnasio');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationPool(item) {
 | 
			
		||||
        if (!Preferences.get('pool')) return ``;
 | 
			
		||||
 | 
			
		||||
        if (item.location?.pool) {
 | 
			
		||||
            return this._createSuccess('Piscina');
 | 
			
		||||
        }
 | 
			
		||||
        return this._createError('Piscina');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationSupermarket(item) {
 | 
			
		||||
        if (!Preferences.get('supermarket')) return ``;
 | 
			
		||||
 | 
			
		||||
        let html = `<div>`;
 | 
			
		||||
        if (item.location?.supermarkets.length) {
 | 
			
		||||
            html += this._createSuccess(`${item.location.supermarkets.length} supermercados`);
 | 
			
		||||
        } else {
 | 
			
		||||
            html += this._createError('Supermercado');
 | 
			
		||||
        }
 | 
			
		||||
        html += `</div>`;
 | 
			
		||||
 | 
			
		||||
        return html;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationSmoke(item) {
 | 
			
		||||
        if (!Preferences.get('smoke')) return ``;
 | 
			
		||||
 | 
			
		||||
        if (item.location?.smoke) {
 | 
			
		||||
            return this._createSuccess('Estanco');
 | 
			
		||||
        }
 | 
			
		||||
        return this._createError('Estanco');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _createLocationPharmacy(item) {
 | 
			
		||||
        if (!Preferences.get('pharmacy')) return ``;
 | 
			
		||||
 | 
			
		||||
        if (item.location?.pharmacy) {
 | 
			
		||||
            return this._createSuccess('Farmacia');
 | 
			
		||||
        }
 | 
			
		||||
        return this._createError('Farmacia');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _shouldCheckExterior(item) {
 | 
			
		||||
        return Preferences.get('exterior')
 | 
			
		||||
            && !item.isHouse();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,29 @@
 | 
			
		||||
import Supermarket from "./Supermarket.js";
 | 
			
		||||
 | 
			
		||||
export default class Location {
 | 
			
		||||
 | 
			
		||||
    static fromRaw(raw) {
 | 
			
		||||
        const location = new Location();
 | 
			
		||||
        location.name = raw.name;
 | 
			
		||||
        location.train = raw.train;
 | 
			
		||||
        location.bus = raw.bus;
 | 
			
		||||
 | 
			
		||||
        location.gym = raw.gym;
 | 
			
		||||
        location.pool = raw.pool;
 | 
			
		||||
 | 
			
		||||
        location.smoke = raw.smoke;
 | 
			
		||||
        location.pharmacy = raw.pharmacy;
 | 
			
		||||
        location.supermarkets = [];
 | 
			
		||||
        for (const rawSupermarket of raw.supermarkets) {
 | 
			
		||||
            const supermarket = new Supermarket();
 | 
			
		||||
            supermarket.name = rawSupermarket.type;
 | 
			
		||||
            supermarket.url = rawSupermarket.url;
 | 
			
		||||
            location.supermarkets.push(supermarket);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return location;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    name;
 | 
			
		||||
    
 | 
			
		||||
    train;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +1,18 @@
 | 
			
		||||
import Location from './Location.js';
 | 
			
		||||
import Supermarket from './Supermarket.js';
 | 
			
		||||
import Log from './Log.js';
 | 
			
		||||
 | 
			
		||||
export default class Locations {
 | 
			
		||||
 | 
			
		||||
    static get ZARAGOZA() {
 | 
			
		||||
        const location = new Location();
 | 
			
		||||
        location.name = 'Zaragoza';
 | 
			
		||||
    static async get(name) {
 | 
			
		||||
        const response = await fetch(`https://raw.githubusercontent.com/Midefos/idealista-enhancer/main/locations/${name}.json`);
 | 
			
		||||
        Log.debug(`Requested location '${name}'`);
 | 
			
		||||
 | 
			
		||||
        location.bus = true;
 | 
			
		||||
        location.train = true;
 | 
			
		||||
 | 
			
		||||
        location.pool = true;
 | 
			
		||||
        location.gym = true;
 | 
			
		||||
 | 
			
		||||
        location.supermarkets = [
 | 
			
		||||
            Supermarket.DIA('https://goo.gl/maps/NLCXd7GdYWS2wgBMA')
 | 
			
		||||
        ];
 | 
			
		||||
        location.smoke = true;
 | 
			
		||||
 | 
			
		||||
        return location;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static get BIELSA() {
 | 
			
		||||
        const location = new Location();
 | 
			
		||||
        location.name = 'Bielsa';
 | 
			
		||||
 | 
			
		||||
        location.bus = true;
 | 
			
		||||
        location.train = false;
 | 
			
		||||
 | 
			
		||||
        location.pool = false;
 | 
			
		||||
        location.gym = true;
 | 
			
		||||
 | 
			
		||||
        location.supermarkets = [
 | 
			
		||||
            Supermarket.SPAR('https://goo.gl/maps/KGhqH8SwMJrcwPse8')
 | 
			
		||||
        ];
 | 
			
		||||
        location.smoke = true;
 | 
			
		||||
 | 
			
		||||
        return location;
 | 
			
		||||
        if (response.status == 404) {
 | 
			
		||||
            Log.debug(`Missing information for location: '${name}'`);
 | 
			
		||||
            return { errorMessage: 'Datos no disponibles...' };
 | 
			
		||||
        }
 | 
			
		||||
        const data = await response.json();
 | 
			
		||||
        return Location.fromRaw(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -22,7 +22,6 @@ export default class Styles {
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            margin-top: -10px;
 | 
			
		||||
            margin-bottom: 10px;
 | 
			
		||||
            padding: 10px 0;	
 | 
			
		||||
 | 
			
		||||
            background-color: white;
 | 
			
		||||
            box-shadow: 0 3px 6px rgba(225, 245, 110, 0.16), 0 3px 6px rgba(225, 245, 110, 0.23);
 | 
			
		||||
@@ -35,8 +34,14 @@ export default class Styles {
 | 
			
		||||
            justify-content: space-around;
 | 
			
		||||
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            padding: 0.5rem 0;
 | 
			
		||||
            border-bottom: 1px solid gray;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .${ItemHTML.INFORMATION_CONTAINER_CLASS_NAME}:last-of-type {
 | 
			
		||||
            border-bottom: none;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        .${ItemHTML.INFORMATION_CLASS_NAME} {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
 
 | 
			
		||||
@@ -3,45 +3,4 @@ export default class Supermarket {
 | 
			
		||||
    name;
 | 
			
		||||
    url;
 | 
			
		||||
 | 
			
		||||
    constructor(name, url) {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
        this.url = url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static DIA(url) {
 | 
			
		||||
        return new Supermarket('Dia', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static MERCADONA(url) {
 | 
			
		||||
        return new Supermarket('Mercadona', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static LIDL(url) {
 | 
			
		||||
        return new Supermarket('Lidl', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static CARREFOUR(url) {
 | 
			
		||||
        return new Supermarket('Carrefour', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static SPAR(url) {
 | 
			
		||||
        return new Supermarket('Spar', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static EROSKI(url) {
 | 
			
		||||
        return new Supermarket('Eroski', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static SUMA(url) {
 | 
			
		||||
        return new Supermarket('Suma', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static SIMPLY(url) {
 | 
			
		||||
        return new Supermarket('Simply', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static CUSTOM(url) {
 | 
			
		||||
        return new Supermarket('Custom', url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user