remove all logging noise
This commit is contained in:
@@ -1,11 +1,8 @@
|
||||
const { allMarketAlertsByRequest } = require("../helpers/db/dbHelper");
|
||||
|
||||
const getRealEstates = async (req, res) => {
|
||||
console.log("Enter get realestates");
|
||||
const request = req.params["request_id"];
|
||||
console.log(req.params["request_id"]);
|
||||
const realEstates = await allMarketAlertsByRequest(request);
|
||||
console.log(realEstates);
|
||||
|
||||
const title = "Ovo su nekretnine koje smo pronašli za vas";
|
||||
res.render("realEstates", { realEstates, title });
|
||||
|
||||
@@ -198,8 +198,6 @@ const sendBulkEmail = async marketAlerts => {
|
||||
ReplacementTemplateData: repData
|
||||
});
|
||||
}
|
||||
console.log("AWS EMAIL : Bulk email replacement data:");
|
||||
console.log(destinations);
|
||||
|
||||
var params = {
|
||||
Destinations: destinations,
|
||||
@@ -214,8 +212,6 @@ const sendBulkEmail = async marketAlerts => {
|
||||
.sendBulkTemplatedEmail(params)
|
||||
.promise();
|
||||
const awsResult = await sendPromise;
|
||||
console.log("AWS SES bulk email response");
|
||||
console.log(awsResult);
|
||||
} catch (e) {
|
||||
console.log("Could not send bulk email", e);
|
||||
}
|
||||
|
||||
@@ -1,375 +1,364 @@
|
||||
const fetch = require('node-fetch');
|
||||
const cheerio = require('cheerio');
|
||||
const { allRERequest, findPointInsideBoundingBox } = require('../db/dbHelper');
|
||||
const { getRealEstateTypeEnum } = require('../enums');
|
||||
const { getRegion, getMunicipality } = require('../codes')
|
||||
const fetch = require("node-fetch");
|
||||
const cheerio = require("cheerio");
|
||||
const { allRERequest, findPointInsideBoundingBox } = require("../db/dbHelper");
|
||||
const { getRealEstateTypeEnum } = require("../enums");
|
||||
const { getRegion, getMunicipality } = require("../codes");
|
||||
const Promise = require("bluebird");
|
||||
|
||||
module.exports = class OlxCrawler {
|
||||
//TODO figure best way to handle paging
|
||||
constructor(hrefs = []) {
|
||||
this.hrefs = hrefs;
|
||||
}
|
||||
//TODO figure best way to handle paging
|
||||
constructor(hrefs = []) {
|
||||
this.hrefs = hrefs;
|
||||
}
|
||||
|
||||
async indexPages(urls) {
|
||||
const indexers = [];
|
||||
async indexPages(urls) {
|
||||
const indexers = [];
|
||||
|
||||
urls.forEach(url => {
|
||||
indexers.push(new Indexer(url));
|
||||
});
|
||||
urls.forEach(url => {
|
||||
indexers.push(new Indexer(url));
|
||||
});
|
||||
|
||||
return Promise.map(indexers, function (indexer) {
|
||||
return indexer.indexWithPagination();
|
||||
}).then(async (results) => {
|
||||
return results
|
||||
})
|
||||
}
|
||||
return Promise.map(indexers, function(indexer) {
|
||||
return indexer.indexWithPagination();
|
||||
}).then(async results => {
|
||||
return results;
|
||||
});
|
||||
}
|
||||
|
||||
async crawl() {
|
||||
console.log("OLX CRAWLER: start crawl");
|
||||
async crawl() {
|
||||
const filteredResults = [];
|
||||
const realestateRequests = await allRERequest();
|
||||
const urls = this.createRequestUrls(realestateRequests);
|
||||
let results = await this.indexPages(
|
||||
urls,
|
||||
this.fromPage,
|
||||
this.toPage,
|
||||
this.maxResults
|
||||
);
|
||||
const flatResults = results.flat();
|
||||
if (flatResults) {
|
||||
for (const finalResult of flatResults) {
|
||||
if (null !== finalResult) {
|
||||
if (
|
||||
finalResult.lat !== undefined &&
|
||||
finalResult.lat !== null &&
|
||||
finalResult.lat !== ""
|
||||
) {
|
||||
const pointInsideBoundingBox = await findPointInsideBoundingBox(
|
||||
[finalResult.lng, finalResult.lat],
|
||||
finalResult.email,
|
||||
finalResult.uuid
|
||||
);
|
||||
|
||||
const filteredResults = [];
|
||||
const realestateRequests = await allRERequest();
|
||||
console.log("OLX CRAWLER: found " + realestateRequests.length + "subscribed RealEstateRequests");
|
||||
const urls = this.createRequestUrls(realestateRequests);
|
||||
let results = await this.indexPages(urls, this.fromPage, this.toPage, this.maxResults);
|
||||
console.log("Final crawler results");
|
||||
const flatResults = results.flat();
|
||||
console.log(flatResults);
|
||||
if (flatResults) {
|
||||
console.log(flatResults.length);
|
||||
|
||||
for (const finalResult of flatResults) {
|
||||
|
||||
if (null !== finalResult) {
|
||||
if (finalResult.lat !== undefined && finalResult.lat !== null && finalResult.lat !== "") {
|
||||
const pointInsideBoundingBox = await findPointInsideBoundingBox([finalResult.lng, finalResult.lat], finalResult.email, finalResult.uuid);
|
||||
|
||||
|
||||
if (pointInsideBoundingBox[0].length !== 0) {
|
||||
finalResult.hasLocation = true
|
||||
filteredResults.push(finalResult);
|
||||
} else {
|
||||
finalResult.hasLocation = false
|
||||
filteredResults.push(finalResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pointInsideBoundingBox[0].length !== 0) {
|
||||
finalResult.hasLocation = true;
|
||||
filteredResults.push(finalResult);
|
||||
} else {
|
||||
finalResult.hasLocation = false;
|
||||
filteredResults.push(finalResult);
|
||||
}
|
||||
|
||||
console.log("OLX CRAWLER: number of olx crawler results, after geo location filtering: " + filteredResults.length);
|
||||
return filteredResults;
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
return filteredResults;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
createRequestUrls(realestateRequests) {
|
||||
const urls = [];
|
||||
|
||||
for (const request of realestateRequests) {
|
||||
const realsestateType =
|
||||
"kategorija=" +
|
||||
getRealEstateTypeEnum(request.realEstateType).olxCategory;
|
||||
const region = "kanton=" + getRegion(request.region).olxid;
|
||||
const municipality =
|
||||
"grad%5B%5D=" +
|
||||
getMunicipality(request.region, request.municipality).olxid;
|
||||
const sizeMin = "kvadrata_min=" + request.sizeMin;
|
||||
const sizeMax = "kvadrata_max=" + request.sizeMax;
|
||||
const priceMin = "od=" + request.priceMin;
|
||||
const priceMax = "do=" + request.priceMax;
|
||||
|
||||
const olxUrl = {
|
||||
url: `https://www.olx.ba/pretraga?${realsestateType}&id=2&stanje=0&vrstapregleda=tabela&sort_order=desc&${region}&${municipality}&${priceMin}&${priceMax}&vrsta=samoprodaja&${sizeMin}&${sizeMax}&stranica=`,
|
||||
email: request.email,
|
||||
uuid: request.uniqueId,
|
||||
hrefs: this.hrefs
|
||||
};
|
||||
urls.push(olxUrl);
|
||||
}
|
||||
|
||||
createRequestUrls(realestateRequests) {
|
||||
const urls = []
|
||||
|
||||
for (const request of realestateRequests) {
|
||||
const realsestateType = "kategorija=" + getRealEstateTypeEnum(request.realEstateType).olxCategory;
|
||||
const region = "kanton=" + getRegion(request.region).olxid;
|
||||
const municipality = "grad%5B%5D=" + getMunicipality(request.region, request.municipality).olxid;
|
||||
const sizeMin = "kvadrata_min=" + request.sizeMin;
|
||||
const sizeMax = "kvadrata_max=" + request.sizeMax;
|
||||
const priceMin = "od=" + request.priceMin;
|
||||
const priceMax = "do=" + request.priceMax;
|
||||
|
||||
const olxUrl = {
|
||||
url: `https://www.olx.ba/pretraga?${realsestateType}&id=2&stanje=0&vrstapregleda=tabela&sort_order=desc&${region}&${municipality}&${priceMin}&${priceMax}&vrsta=samoprodaja&${sizeMin}&${sizeMax}&stranica=`,
|
||||
email: request.email,
|
||||
uuid: request.uniqueId,
|
||||
hrefs: this.hrefs
|
||||
}
|
||||
console.log(olxUrl.url);
|
||||
urls.push(olxUrl);
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Indexer {
|
||||
/**
|
||||
*
|
||||
* @param {String|Array} olxUrl single or array of objects containing url email and uuid
|
||||
* @param {Array} hrefResutls array contaning urls from crawler results
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String|Array} olxUrl single or array of objects containing url email and uuid
|
||||
* @param {Array} hrefResutls array contaning urls from crawler results
|
||||
*/
|
||||
constructor(olxUrl, hrefResutls) {
|
||||
this.olxUrl = olxUrl;
|
||||
this.hrefResutls = hrefResutls;
|
||||
}
|
||||
|
||||
constructor(olxUrl, hrefResutls) {
|
||||
this.olxUrl = olxUrl;
|
||||
this.hrefResutls = hrefResutls;
|
||||
}
|
||||
async indexWithPagination(pageNumber = 1) {
|
||||
const pageNr = this.olxUrl.url.match(/\d+$/);
|
||||
const indexers = this.prepareIndexers(pageNumber ? [pageNumber] : pageNr);
|
||||
|
||||
async indexWithPagination(pageNumber = 1) {
|
||||
try {
|
||||
return Promise.map(indexers.indexers, function(indexer) {
|
||||
return indexer.indexPage(pageNumber);
|
||||
}).then(async results => {
|
||||
let hasResults = false;
|
||||
|
||||
console.log("This is olxUrl:" + this.olxUrl.url);
|
||||
const pageNr = this.olxUrl.url.match(/\d+$/);
|
||||
const indexers = this.prepareIndexers(pageNumber ? [pageNumber] : pageNr);
|
||||
results.forEach(result => {
|
||||
if (!hasResults) {
|
||||
hasResults = result.hasResults;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
if (!hasResults) {
|
||||
const singlePageIndexers = this.prepareHrefIndexers(results);
|
||||
if (singlePageIndexers.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Promise.map(indexers.indexers, function (indexer) {
|
||||
return indexer.indexPage(pageNumber);
|
||||
}).then(async (results) => {
|
||||
let hasResults = false;
|
||||
|
||||
results.forEach(result => {
|
||||
if (!hasResults) {
|
||||
console.log("No results detected")
|
||||
hasResults = result.hasResults
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasResults) {
|
||||
console.log("HAS NO MORE RESULTS, stop the paging, there are some results and they should contain only HREFS");
|
||||
console.log(results.length);
|
||||
const singlePageIndexers = this.prepareHrefIndexers(results);
|
||||
if (singlePageIndexers.length === 0) {
|
||||
console.log("THERE IS NOT EVEN SINGLE RESULT");
|
||||
return []
|
||||
}
|
||||
|
||||
return Promise.map(singlePageIndexers, function (indexer) {
|
||||
return indexer.indexSingle();
|
||||
}).then(async (results) => {
|
||||
console.log("SinglePageMethod in HAS NO RESULTS, MarketAralms");
|
||||
console.log(results.length);
|
||||
return results;
|
||||
});
|
||||
|
||||
} else {
|
||||
console.log("HAS MORE RESULTS, should only contain HREFS");
|
||||
console.log(results.length);
|
||||
const newResults = await this.indexWithPagination(results[0].pageNumber + 5);
|
||||
const singlePageIndexers = this.prepareHrefIndexers(results);
|
||||
|
||||
const newerResults = await Promise.map(singlePageIndexers, function (indexer) {
|
||||
return indexer.indexSingle();
|
||||
}).then(async (results) => {
|
||||
console.log("SinglePageMethod HAS RESULTS, should contain MarketAlerts only");
|
||||
console.log(results.length);
|
||||
return results;
|
||||
});
|
||||
|
||||
Array.prototype.push.apply(newResults, newerResults);
|
||||
return newResults;
|
||||
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Error has accured", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
prepareIndexers(pageNr) {
|
||||
|
||||
console.log("Entering prepareIndexers : page nr - " + pageNr);
|
||||
const indexers = [];
|
||||
let lastPageNumber;
|
||||
if (pageNr) {
|
||||
for (let index = Number(pageNr[0]); index <= Number(pageNr[0]) + 5; index++) {
|
||||
lastPageNumber = index;
|
||||
const newOlxUrl = {
|
||||
url: this.olxUrl.url.replace(/\d+$/, "") + index,
|
||||
email: this.olxUrl.email,
|
||||
uuid: this.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
}
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
|
||||
}
|
||||
return Promise.map(singlePageIndexers, function(indexer) {
|
||||
return indexer.indexSingle();
|
||||
}).then(async results => {
|
||||
return results;
|
||||
});
|
||||
} else {
|
||||
for (let index = 1; index <= 5; index++) {
|
||||
lastPageNumber = index;
|
||||
const newOlxUrl = {
|
||||
url: this.olxUrl.url + index,
|
||||
email: this.olxUrl.email,
|
||||
uuid: this.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
}
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
}
|
||||
const newResults = await this.indexWithPagination(
|
||||
results[0].pageNumber + 5
|
||||
);
|
||||
const singlePageIndexers = this.prepareHrefIndexers(results);
|
||||
|
||||
const newerResults = await Promise.map(singlePageIndexers, function(
|
||||
indexer
|
||||
) {
|
||||
return indexer.indexSingle();
|
||||
}).then(async results => {
|
||||
return results;
|
||||
});
|
||||
|
||||
Array.prototype.push.apply(newResults, newerResults);
|
||||
return newResults;
|
||||
}
|
||||
return {
|
||||
indexers: indexers,
|
||||
lastPageNumber: lastPageNumber
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Error has accured", e);
|
||||
}
|
||||
}
|
||||
|
||||
prepareIndexers(pageNr) {
|
||||
const indexers = [];
|
||||
let lastPageNumber;
|
||||
if (pageNr) {
|
||||
for (
|
||||
let index = Number(pageNr[0]);
|
||||
index <= Number(pageNr[0]) + 5;
|
||||
index++
|
||||
) {
|
||||
lastPageNumber = index;
|
||||
const newOlxUrl = {
|
||||
url: this.olxUrl.url.replace(/\d+$/, "") + index,
|
||||
email: this.olxUrl.email,
|
||||
uuid: this.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
};
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
}
|
||||
} else {
|
||||
for (let index = 1; index <= 5; index++) {
|
||||
lastPageNumber = index;
|
||||
const newOlxUrl = {
|
||||
url: this.olxUrl.url + index,
|
||||
email: this.olxUrl.email,
|
||||
uuid: this.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
};
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
}
|
||||
}
|
||||
return {
|
||||
indexers: indexers,
|
||||
lastPageNumber: lastPageNumber
|
||||
};
|
||||
}
|
||||
|
||||
prepareHrefIndexers(results) {
|
||||
const indexers = []
|
||||
prepareHrefIndexers(results) {
|
||||
const indexers = [];
|
||||
|
||||
if (!Array.isArray(results)) {
|
||||
results.hrefs.forEach(href => {
|
||||
const newOlxUrl = {
|
||||
url: href,
|
||||
email: results.olxUrl.email,
|
||||
uuid: results.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
}
|
||||
if (!Array.isArray(results)) {
|
||||
results.hrefs.forEach(href => {
|
||||
const newOlxUrl = {
|
||||
url: href,
|
||||
email: results.olxUrl.email,
|
||||
uuid: results.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
};
|
||||
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
results.forEach(result => {
|
||||
|
||||
if (result !== null && result.hasOwnProperty('hrefs')) {
|
||||
result.hrefs.forEach(href => {
|
||||
const newOlxUrl = {
|
||||
url: href,
|
||||
email: result.olxUrl.email,
|
||||
uuid: result.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
}
|
||||
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return indexers;
|
||||
}
|
||||
|
||||
async indexPage(pageNumber) {
|
||||
console.log("Page number in index page, max page number :")
|
||||
console.log(pageNumber);
|
||||
|
||||
try {
|
||||
|
||||
console.log("Indexing page: " + this.olxUrl.url);
|
||||
const res = await fetch(this.olxUrl.url);
|
||||
const body = await res.text();
|
||||
const $ = cheerio.load(body);
|
||||
const hrefs = [];
|
||||
let hasResults = false
|
||||
|
||||
$('#rezultatipretrage').find('.listitem').each((i, elem) => {
|
||||
hasResults = true
|
||||
const href = $(elem).find('a').first().attr('href');
|
||||
hrefs.push(href);
|
||||
});
|
||||
|
||||
console.log("this is hrefs for olxUrl" + this.olxUrl.url);
|
||||
console.log("NUMBER OF HREFS " + hrefs.length);
|
||||
|
||||
return {
|
||||
hrefs: hrefs,
|
||||
hasResults: hasResults,
|
||||
pageNumber: pageNumber,
|
||||
olxUrl: this.olxUrl
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Exception caught:' + e);
|
||||
}
|
||||
}
|
||||
|
||||
async indexSingle() {
|
||||
try {
|
||||
console.log("Index single");
|
||||
console.log(this.olxUrl.url);
|
||||
|
||||
if (this.olxUrl.url === undefined) {
|
||||
return {}
|
||||
}
|
||||
|
||||
// if (global.hrefs) {
|
||||
|
||||
if (this.olxUrl.hrefs[this.olxUrl.uuid] && this.olxUrl.hrefs[this.olxUrl.uuid].includes(this.olxUrl.url)) {
|
||||
|
||||
console.log("We found duplicate URL");
|
||||
return null
|
||||
}
|
||||
// }
|
||||
|
||||
const res = await fetch(this.olxUrl.url);
|
||||
const body = await res.text();
|
||||
const $ = cheerio.load(body);
|
||||
|
||||
const title = $('#naslovartikla').text().trim();
|
||||
const realEstateType = $('#artikal_glavni_div > div.artikal_lijevo > div:nth-child(3) > div > span:nth-child(3) > a > span').text();
|
||||
|
||||
const price = $('#pc > p:nth-child(2)').text();
|
||||
const size = $('#dodatnapolja1 > div:nth-child(1) > div.df2').text();
|
||||
const rooms = $('#dodatnapolja1 > div:nth-child(2) > div.df2').text();
|
||||
const address = $('#dodatnapolja1 > div:nth-child(5) > div.df2').text();
|
||||
const gardenSize = $('#dodatnapolja1 > div:nth-child(6) > div.df2').text();
|
||||
const location = $('#artikal_glavni_div > div.artikal_lijevo > div.op.pop.mobile-lokacija').attr('data-content');
|
||||
|
||||
const time = $('time').attr('datetime');
|
||||
const olxId = $('#artikal_glavni_div > div.artikal_lijevo > div:nth-child(15) > div:nth-child(4) > div.df2').text();
|
||||
|
||||
const descriptions = $('.artikal_detaljniopis_tekst');
|
||||
const latLngRe = /LatLng\(([0-9]+\.[0-9]+)\,\s+([0-9]+\.[0-9]+)\)/g;
|
||||
const imgRe = /href":("[^"]*")/g;
|
||||
const matches = latLngRe.exec(body);
|
||||
let lng = '',
|
||||
lat = '';
|
||||
const parsePrice = (price) => parseFloat(price.replace(".", ""))
|
||||
|
||||
if (matches && matches.length >= 3) {
|
||||
lat = matches[1];
|
||||
lng = matches[2];
|
||||
}
|
||||
|
||||
const parsedPrice = parsePrice(price);
|
||||
|
||||
const locationArray = location.split(",");
|
||||
const region = locationArray[0];
|
||||
const municipality = locationArray[1];
|
||||
|
||||
const data = {
|
||||
realEstateType: this.getCategoryId(realEstateType),
|
||||
email: this.olxUrl.email,
|
||||
uuid: this.olxUrl.uuid,
|
||||
olxId: olxId,
|
||||
url: this.olxUrl.url,
|
||||
title,
|
||||
price: isNaN(parsedPrice) ? 0 : parsedPrice,
|
||||
size: parseFloat(size),
|
||||
gardenSize: isNaN(parseFloat(gardenSize)) ? 0 : parseFloat(gardenSize),
|
||||
address,
|
||||
region,
|
||||
municipality,
|
||||
time,
|
||||
shortDescription: descriptions.first().text(),
|
||||
longDescription: descriptions.last().text(),
|
||||
lat,
|
||||
lng,
|
||||
loc: [parseFloat(lat), parseFloat(lng)],
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
});
|
||||
} else {
|
||||
results.forEach(result => {
|
||||
if (result !== null && result.hasOwnProperty("hrefs")) {
|
||||
result.hrefs.forEach(href => {
|
||||
const newOlxUrl = {
|
||||
url: href,
|
||||
email: result.olxUrl.email,
|
||||
uuid: result.olxUrl.uuid,
|
||||
hrefs: this.olxUrl.hrefs
|
||||
};
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error('Exception caught: ' + e.message);
|
||||
indexers.push(new Indexer(newOlxUrl));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return indexers;
|
||||
}
|
||||
|
||||
async indexPage(pageNumber) {
|
||||
try {
|
||||
const res = await fetch(this.olxUrl.url);
|
||||
const body = await res.text();
|
||||
const $ = cheerio.load(body);
|
||||
const hrefs = [];
|
||||
let hasResults = false;
|
||||
|
||||
$("#rezultatipretrage")
|
||||
.find(".listitem")
|
||||
.each((i, elem) => {
|
||||
hasResults = true;
|
||||
const href = $(elem)
|
||||
.find("a")
|
||||
.first()
|
||||
.attr("href");
|
||||
hrefs.push(href);
|
||||
});
|
||||
return {
|
||||
hrefs: hrefs,
|
||||
hasResults: hasResults,
|
||||
pageNumber: pageNumber,
|
||||
olxUrl: this.olxUrl
|
||||
};
|
||||
} catch (e) {
|
||||
console.error("Exception caught:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
async indexSingle() {
|
||||
try {
|
||||
if (this.olxUrl.url === undefined) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// if (global.hrefs) {
|
||||
|
||||
if (
|
||||
this.olxUrl.hrefs[this.olxUrl.uuid] &&
|
||||
this.olxUrl.hrefs[this.olxUrl.uuid].includes(this.olxUrl.url)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
// }
|
||||
|
||||
const res = await fetch(this.olxUrl.url);
|
||||
const body = await res.text();
|
||||
const $ = cheerio.load(body);
|
||||
|
||||
const title = $("#naslovartikla")
|
||||
.text()
|
||||
.trim();
|
||||
const realEstateType = $(
|
||||
"#artikal_glavni_div > div.artikal_lijevo > div:nth-child(3) > div > span:nth-child(3) > a > span"
|
||||
).text();
|
||||
|
||||
const price = $("#pc > p:nth-child(2)").text();
|
||||
const size = $("#dodatnapolja1 > div:nth-child(1) > div.df2").text();
|
||||
const rooms = $("#dodatnapolja1 > div:nth-child(2) > div.df2").text();
|
||||
const address = $("#dodatnapolja1 > div:nth-child(5) > div.df2").text();
|
||||
const gardenSize = $(
|
||||
"#dodatnapolja1 > div:nth-child(6) > div.df2"
|
||||
).text();
|
||||
const location = $(
|
||||
"#artikal_glavni_div > div.artikal_lijevo > div.op.pop.mobile-lokacija"
|
||||
).attr("data-content");
|
||||
|
||||
const time = $("time").attr("datetime");
|
||||
const olxId = $(
|
||||
"#artikal_glavni_div > div.artikal_lijevo > div:nth-child(15) > div:nth-child(4) > div.df2"
|
||||
).text();
|
||||
|
||||
const descriptions = $(".artikal_detaljniopis_tekst");
|
||||
const latLngRe = /LatLng\(([0-9]+\.[0-9]+)\,\s+([0-9]+\.[0-9]+)\)/g;
|
||||
const imgRe = /href":("[^"]*")/g;
|
||||
const matches = latLngRe.exec(body);
|
||||
let lng = "",
|
||||
lat = "";
|
||||
const parsePrice = price => parseFloat(price.replace(".", ""));
|
||||
|
||||
if (matches && matches.length >= 3) {
|
||||
lat = matches[1];
|
||||
lng = matches[2];
|
||||
}
|
||||
|
||||
const parsedPrice = parsePrice(price);
|
||||
|
||||
const locationArray = location.split(",");
|
||||
const region = locationArray[0];
|
||||
const municipality = locationArray[1];
|
||||
|
||||
const data = {
|
||||
realEstateType: this.getCategoryId(realEstateType),
|
||||
email: this.olxUrl.email,
|
||||
uuid: this.olxUrl.uuid,
|
||||
olxId: olxId,
|
||||
url: this.olxUrl.url,
|
||||
title,
|
||||
price: isNaN(parsedPrice) ? 0 : parsedPrice,
|
||||
size: parseFloat(size),
|
||||
gardenSize: isNaN(parseFloat(gardenSize)) ? 0 : parseFloat(gardenSize),
|
||||
address,
|
||||
region,
|
||||
municipality,
|
||||
time,
|
||||
shortDescription: descriptions.first().text(),
|
||||
longDescription: descriptions.last().text(),
|
||||
lat,
|
||||
lng,
|
||||
loc: [parseFloat(lat), parseFloat(lng)]
|
||||
};
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error("Exception caught: " + e.message);
|
||||
}
|
||||
|
||||
getCategoryId(category) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (category) {
|
||||
case 'Stanovi':
|
||||
return 'stan';
|
||||
getCategoryId(category) {
|
||||
switch (category) {
|
||||
case "Stanovi":
|
||||
return "stan";
|
||||
|
||||
case 'Vikendice':
|
||||
return 'vikendica'
|
||||
case "Vikendice":
|
||||
return "vikendica";
|
||||
|
||||
case 'Kuće':
|
||||
return 'kuca';
|
||||
case "Kuće":
|
||||
return "kuca";
|
||||
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ const db = require("../models/index");
|
||||
const { allMarketAlerts } = require("../helpers/db/dbHelper");
|
||||
|
||||
async function crawlAll() {
|
||||
console.log("CRAWLER SERVICE: crawlAll");
|
||||
|
||||
try {
|
||||
const marketAlertsFromDb = await allMarketAlerts(true);
|
||||
const hrefs = [];
|
||||
@@ -18,8 +16,6 @@ async function crawlAll() {
|
||||
hrefs[marketAlert.request].push(marketAlert.url);
|
||||
});
|
||||
|
||||
console.log("CRAWLER SERVICE: GLOBAL HREFS");
|
||||
console.log(hrefs);
|
||||
const olxCrawler = new OlxCrawler(hrefs);
|
||||
|
||||
const crawlers = [olxCrawler];
|
||||
@@ -30,11 +26,6 @@ async function crawlAll() {
|
||||
try {
|
||||
const marketAlertsFromDb = await allMarketAlerts(false, true);
|
||||
|
||||
console.log(
|
||||
"CRAWLER SERVICE: number of existing MarketAlerts from db: " +
|
||||
marketAlertsFromDb.length
|
||||
);
|
||||
|
||||
const marketAlerts = [];
|
||||
const mergedResults = [].concat.apply([], results);
|
||||
|
||||
@@ -56,9 +47,6 @@ async function crawlAll() {
|
||||
hasLocation: result.hasLocation
|
||||
});
|
||||
}
|
||||
console.log(
|
||||
"CRAWLER SERVICE: Number of crawler results: " + marketAlerts.length
|
||||
);
|
||||
|
||||
try {
|
||||
const filteredMarketAlerts = marketAlerts.filter(
|
||||
@@ -67,10 +55,6 @@ async function crawlAll() {
|
||||
return elem.url === url && elem.request === request;
|
||||
})
|
||||
);
|
||||
console.log(
|
||||
"CRAWLER SERVICE: Number of new crawler results: " +
|
||||
filteredMarketAlerts.length
|
||||
);
|
||||
|
||||
await db.MarketAlert.bulkCreate(filteredMarketAlerts);
|
||||
} catch (e) {
|
||||
|
||||
@@ -8,15 +8,9 @@ const {
|
||||
async function processNotifications() {
|
||||
try {
|
||||
const marketAlerts = await allMarketAlerts(false, false);
|
||||
console.log(marketAlerts.length);
|
||||
await createMarketAlertEmailTemplate();
|
||||
if (marketAlerts.length > 0) {
|
||||
console.log(
|
||||
"NOTIFICATION SERVICE: Number of new alerts: " + marketAlerts.length
|
||||
);
|
||||
await sendBulkEmail(marketAlerts);
|
||||
} else {
|
||||
console.log("NOTIFICATION SERVICE: No new alerts");
|
||||
}
|
||||
|
||||
await db.MarketAlert.update(
|
||||
|
||||
@@ -1,389 +1,430 @@
|
||||
<!DOCTYPE>
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://code.jquery.com/jquery-3.4.0.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<select name="kanton" id="kanton" class="drop-select" onchange="pronadji_gradove()">
|
||||
<option value="">Iz svih lokacija</option>
|
||||
|
||||
<option value="" disabled="">Federacija BiH</option>
|
||||
<option value="9"> Sarajevo</option>
|
||||
<option value="3"> Tuzlanski</option>
|
||||
<option value="4"> Zeničko-Dobojski</option>
|
||||
<option value="1"> Unsko-Sanski</option>
|
||||
<option value="2"> Posavski</option>
|
||||
<option value="5"> Bosansko-podrinjski</option>
|
||||
<option value="6"> Srednjobosanski</option>
|
||||
<option value="7"> Hercegovačko-Neretvanski</option>
|
||||
<option value="8"> Zapadno-Hercegovački</option>
|
||||
<option value="10"> Livanjski</option>
|
||||
|
||||
<option value="" disabled="">Republika Srpska</option>
|
||||
<option value="14"> Banjalučka</option>
|
||||
<option value="15"> Dobojsko-Bijeljinska</option>
|
||||
<option value="16"> Sarajevsko-Zvornička</option>
|
||||
<option value="17"> Trebinjsko-Fočanska</option>
|
||||
|
||||
<option value="12">Disktrikt Brčko</option>
|
||||
</select>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="unskosanski" id="unskosanski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="75">Bihać</option>
|
||||
<option value="373">Bosanska Krupa</option>
|
||||
<option value="504">Bosanski Petrovac</option>
|
||||
<option value="374">Bužim</option>
|
||||
<option value="857">Cazin</option>
|
||||
<option value="2362">Ključ</option>
|
||||
<option value="3738">Sanski Most</option>
|
||||
<option value="5122">Velika Kladuša</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="posavski" id="posavski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="6144">Domaljevac</option>
|
||||
<option value="424">Odžak</option>
|
||||
<option value="3252">Orašje</option>
|
||||
<option value="540">Šamac</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="tuzlanski" id="tuzlanski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="2">Banovići</option>
|
||||
<option value="1090">Doboj-Istok</option>
|
||||
<option value="1854">Gradačac</option>
|
||||
<option value="1826">Gračanica</option>
|
||||
<option value="2129">Kalesija</option>
|
||||
<option value="2319">Kladanj</option>
|
||||
<option value="2840">Lukavac</option>
|
||||
<option value="5699">Sapna</option>
|
||||
<option value="4391">Srebrenik</option>
|
||||
<option value="5010">Teočak</option>
|
||||
<option value="4944">Tuzla</option>
|
||||
<option value="2801">Čelić</option>
|
||||
<option value="5774">Živinice</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="zenickodobojski" id="zenickodobojski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="704">Breza</option>
|
||||
<option value="1122">Doboj-Jug</option>
|
||||
<option value="2022">Kakanj</option>
|
||||
<option value="2941">Maglaj</option>
|
||||
<option value="1925">Olovo</option>
|
||||
<option value="4594">Tešanj</option>
|
||||
<option value="1087">Usora</option>
|
||||
<option value="5037">Vareš</option>
|
||||
<option value="5171">Visoko</option>
|
||||
<option value="5548">Zavidovići</option>
|
||||
<option value="4571">Zenica</option>
|
||||
<option value="2940">Žepče</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="bosanskopodrinjski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="1289">Foča</option>
|
||||
<option value="1588">Goražde</option>
|
||||
<option value="3546">Pale</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="srednjobosanski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="732">Bugojno</option>
|
||||
<option value="810">Busovača</option>
|
||||
<option value="4151">Dobretići</option>
|
||||
<option value="1160">Donji Vakuf</option>
|
||||
<option value="1407">Fojnica</option>
|
||||
<option value="1775">Gornji Vakuf - Uskoplje</option>
|
||||
<option value="1960">Jajce</option>
|
||||
<option value="2237">Kiseljak</option>
|
||||
<option value="2608">Kreševo</option>
|
||||
<option value="3477">Novi Travnik</option>
|
||||
<option value="4678">Travnik</option>
|
||||
<option value="5422">Vitez</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="hercegovackoneretvanski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="3017">Grad Mostar</option>
|
||||
<option value="1930">Jablanica</option>
|
||||
<option value="2169">Konjic</option>
|
||||
<option value="3111">Neum</option>
|
||||
<option value="3421">Prozor</option>
|
||||
<option value="4769">Ravno</option>
|
||||
<option value="4439">Stolac</option>
|
||||
<option value="947">Čapljina</option>
|
||||
<option value="1009">Čitluk</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="zapadnohercegovacki" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="1892">Grude</option>
|
||||
<option value="2905">Ljubuški</option>
|
||||
<option value="3268">Posušje</option>
|
||||
<option value="2708">Široki Brijeg</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="sarajevo" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="3817">Hadžići</option>
|
||||
<option value="3879">Ilidža</option>
|
||||
<option value="3892">Ilijaš</option>
|
||||
<option value="3812">Sarajevo - Centar</option>
|
||||
<option value="3969">Sarajevo-Novi Grad</option>
|
||||
<option value="5896">Sarajevo-Novo Sarajevo</option>
|
||||
<option value="4048">Sarajevo-Stari Grad</option>
|
||||
<option value="4063">Trnovo</option>
|
||||
<option value="4126">Vogošća</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="livanjski" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="560">Bosansko Grahovo</option>
|
||||
<option value="4640">Drvar</option>
|
||||
<option value="1533">Glamoč</option>
|
||||
<option value="2635">Kupres</option>
|
||||
<option value="2741">Livno</option>
|
||||
<option value="1228">Tomislavgrad</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="grad11" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="645">distriktbrcko</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="banjalučka" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="21">Banja Luka</option>
|
||||
<option value="305">Gradiška</option>
|
||||
<option value="4662">Istočni Drvar</option>
|
||||
<option value="1965">Jezero</option>
|
||||
<option value="4147">Kneževo</option>
|
||||
<option value="6142">Kostajnica</option>
|
||||
<option value="2574">Kotor Varoš</option>
|
||||
<option value="244">Kozarska Dubica</option>
|
||||
<option value="382">Krupa na uni</option>
|
||||
<option value="2654">Kupres </option>
|
||||
<option value="2671">Laktaši</option>
|
||||
<option value="3073">Mrkonjić Grad</option>
|
||||
<option value="444">Novi Grad</option>
|
||||
<option value="3737">Oštra Luka</option>
|
||||
<option value="515">Petrovac</option>
|
||||
<option value="3287">Prijedor</option>
|
||||
<option value="3358">Prnjavor</option>
|
||||
<option value="2365">Ribnik</option>
|
||||
<option value="4271">Srbac</option>
|
||||
<option value="979">Čelinac</option>
|
||||
<option value="4509">Šipovo</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="dobojskobijeljinska" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="123">Bijeljina</option>
|
||||
<option value="421">Bosanski Brod</option>
|
||||
<option value="1030">Derventa</option>
|
||||
<option value="1088">Doboj</option>
|
||||
<option value="3254">Donji Žabar</option>
|
||||
<option value="2800">Lopare</option>
|
||||
<option value="6029">Lukavac</option>
|
||||
<option value="2996">Modriča</option>
|
||||
<option value="1856">Pelagićevo</option>
|
||||
<option value="1827">Petrovo</option>
|
||||
<option value="1148">Stanari</option>
|
||||
<option value="4549">Teslić</option>
|
||||
<option value="4636">Tešanj</option>
|
||||
<option value="4692">Travnik</option>
|
||||
<option value="4966">Tuzla</option>
|
||||
<option value="5009">Ugljevik</option>
|
||||
<option value="3197">Vukosavlje</option>
|
||||
<option value="539">Šamac</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="sarajevskozvornicka" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="595">Bratunac</option>
|
||||
<option value="1904">Han Pijesak</option>
|
||||
<option value="3947">Ilijaš</option>
|
||||
<option value="4049">Istočni Stari Grad</option>
|
||||
<option value="3880">Kasindo</option>
|
||||
<option value="2325">Kladanj</option>
|
||||
<option value="3971">Lukavica</option>
|
||||
<option value="6143">Milići</option>
|
||||
<option value="3221">Olovo</option>
|
||||
<option value="2128">Osmaci</option>
|
||||
<option value="3978">Pale</option>
|
||||
<option value="3529">Rogatica</option>
|
||||
<option value="3648">Rudo</option>
|
||||
<option value="6069">Sarajevo-Novi Grad</option>
|
||||
<option value="4183">Sokolac</option>
|
||||
<option value="4310">Srebrenica</option>
|
||||
<option value="4067">Trnovo</option>
|
||||
<option value="1593">Ustiprača</option>
|
||||
<option value="5259">Višegrad</option>
|
||||
<option value="5456">Vlasenica</option>
|
||||
<option value="5684">Zvornik</option>
|
||||
<option value="4475">Šekovići</option>
|
||||
<option value="1906">Žepa</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height:40px;">
|
||||
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="trebinjskofocanska" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="4441">Berkovići</option>
|
||||
<option value="183">Bileća</option>
|
||||
<option value="1287">Foča</option>
|
||||
<option value="1462">Gacko</option>
|
||||
<option value="3038">Istočni Mostar</option>
|
||||
<option value="2164">Kalinovik</option>
|
||||
<option value="2884">Ljubinje</option>
|
||||
<option value="3138">Nevesinje</option>
|
||||
<option value="4766">Trebinje</option>
|
||||
<option value="911">Čajniče</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
const stavi_grad = () => {};
|
||||
const gradovi = [
|
||||
{"ime":" Sarajevo","id":"sarajevo"},
|
||||
{"ime":" Unsko-sanski","id":"unskosanski"},
|
||||
{"ime":" Posavski","id":"posavski"},
|
||||
{"ime":" Tuzlanski","id":"tuzlanski"},
|
||||
{"ime":" Zeničko-dobojski","id":"zenickodobojski"},
|
||||
{"ime":" Bosansko-podrinjski","id":"bosanskopodrinjski"},
|
||||
{"ime":" Srednjobosanski","id":"srednjobosanski"},
|
||||
{"ime":" Hercegovačko-neretvanski","id":"hercegovackoneretvanski"},
|
||||
{"ime":" Zapadno-hercegovački","id":"zapadnohercegovacki"},
|
||||
{"ime":" Livanjski","id":"livanjski"},
|
||||
{"ime":" Banjalučka","id":"banjalučka"},
|
||||
{"ime":" Dobojsko-Bijeljinska","id":"dobojskobijeljinska"},
|
||||
{"ime":" Sarajevsko-Zvornička","id":"sarajevskozvornicka"},
|
||||
{"ime":" Trebinjsko-Fočanska","id":"trebinjskofocanska"},
|
||||
{"ime":"Distrikt Brčko","id":"distriktbrcko"},
|
||||
];
|
||||
|
||||
for (let grad of gradovi) {
|
||||
const mjesta = [];
|
||||
$('#' + grad.id).children().each( function() {
|
||||
const mjesto = $(this).text();
|
||||
mjesta.push( {
|
||||
ime: mjesto,
|
||||
id: mjesto.toLowerCase().replace(/[^a-z]/g,''),
|
||||
olxid: $(this).val()
|
||||
});
|
||||
});
|
||||
grad.mjesta = mjesta;
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(gradovi));
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!DOCTYPE >
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://code.jquery.com/jquery-3.4.0.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<select
|
||||
name="kanton"
|
||||
id="kanton"
|
||||
class="drop-select"
|
||||
onchange="pronadji_gradove()"
|
||||
>
|
||||
<option value="">Iz svih lokacija</option>
|
||||
|
||||
<option value="" disabled="">Federacija BiH</option>
|
||||
<option value="9"> Sarajevo</option>
|
||||
<option value="3"> Tuzlanski</option>
|
||||
<option value="4"> Zeničko-Dobojski</option>
|
||||
<option value="1"> Unsko-Sanski</option>
|
||||
<option value="2"> Posavski</option>
|
||||
<option value="5"> Bosansko-podrinjski</option>
|
||||
<option value="6"> Srednjobosanski</option>
|
||||
<option value="7"> Hercegovačko-Neretvanski</option>
|
||||
<option value="8"> Zapadno-Hercegovački</option>
|
||||
<option value="10"> Livanjski</option>
|
||||
|
||||
<option value="" disabled="">Republika Srpska</option>
|
||||
<option value="14"> Banjalučka</option>
|
||||
<option value="15"> Dobojsko-Bijeljinska</option>
|
||||
<option value="16"> Sarajevsko-Zvornička</option>
|
||||
<option value="17"> Trebinjsko-Fočanska</option>
|
||||
|
||||
<option value="12">Disktrikt Brčko</option>
|
||||
</select>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name="unskosanski"
|
||||
id="unskosanski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="75">Bihać</option>
|
||||
<option value="373">Bosanska Krupa</option>
|
||||
<option value="504">Bosanski Petrovac</option>
|
||||
<option value="374">Bužim</option>
|
||||
<option value="857">Cazin</option>
|
||||
<option value="2362">Ključ</option>
|
||||
<option value="3738">Sanski Most</option>
|
||||
<option value="5122">Velika Kladuša</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name="posavski"
|
||||
id="posavski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="6144">Domaljevac</option>
|
||||
<option value="424">Odžak</option>
|
||||
<option value="3252">Orašje</option>
|
||||
<option value="540">Šamac</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name="tuzlanski"
|
||||
id="tuzlanski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="2">Banovići</option>
|
||||
<option value="1090">Doboj-Istok</option>
|
||||
<option value="1854">Gradačac</option>
|
||||
<option value="1826">Gračanica</option>
|
||||
<option value="2129">Kalesija</option>
|
||||
<option value="2319">Kladanj</option>
|
||||
<option value="2840">Lukavac</option>
|
||||
<option value="5699">Sapna</option>
|
||||
<option value="4391">Srebrenik</option>
|
||||
<option value="5010">Teočak</option>
|
||||
<option value="4944">Tuzla</option>
|
||||
<option value="2801">Čelić</option>
|
||||
<option value="5774">Živinice</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name="zenickodobojski"
|
||||
id="zenickodobojski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="704">Breza</option>
|
||||
<option value="1122">Doboj-Jug</option>
|
||||
<option value="2022">Kakanj</option>
|
||||
<option value="2941">Maglaj</option>
|
||||
<option value="1925">Olovo</option>
|
||||
<option value="4594">Tešanj</option>
|
||||
<option value="1087">Usora</option>
|
||||
<option value="5037">Vareš</option>
|
||||
<option value="5171">Visoko</option>
|
||||
<option value="5548">Zavidovići</option>
|
||||
<option value="4571">Zenica</option>
|
||||
<option value="2940">Žepče</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="bosanskopodrinjski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="1289">Foča</option>
|
||||
<option value="1588">Goražde</option>
|
||||
<option value="3546">Pale</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="srednjobosanski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="732">Bugojno</option>
|
||||
<option value="810">Busovača</option>
|
||||
<option value="4151">Dobretići</option>
|
||||
<option value="1160">Donji Vakuf</option>
|
||||
<option value="1407">Fojnica</option>
|
||||
<option value="1775">Gornji Vakuf - Uskoplje</option>
|
||||
<option value="1960">Jajce</option>
|
||||
<option value="2237">Kiseljak</option>
|
||||
<option value="2608">Kreševo</option>
|
||||
<option value="3477">Novi Travnik</option>
|
||||
<option value="4678">Travnik</option>
|
||||
<option value="5422">Vitez</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="hercegovackoneretvanski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="3017">Grad Mostar</option>
|
||||
<option value="1930">Jablanica</option>
|
||||
<option value="2169">Konjic</option>
|
||||
<option value="3111">Neum</option>
|
||||
<option value="3421">Prozor</option>
|
||||
<option value="4769">Ravno</option>
|
||||
<option value="4439">Stolac</option>
|
||||
<option value="947">Čapljina</option>
|
||||
<option value="1009">Čitluk</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="zapadnohercegovacki"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="1892">Grude</option>
|
||||
<option value="2905">Ljubuški</option>
|
||||
<option value="3268">Posušje</option>
|
||||
<option value="2708">Široki Brijeg</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="sarajevo"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="3817">Hadžići</option>
|
||||
<option value="3879">Ilidža</option>
|
||||
<option value="3892">Ilijaš</option>
|
||||
<option value="3812">Sarajevo - Centar</option>
|
||||
<option value="3969">Sarajevo-Novi Grad</option>
|
||||
<option value="5896">Sarajevo-Novo Sarajevo</option>
|
||||
<option value="4048">Sarajevo-Stari Grad</option>
|
||||
<option value="4063">Trnovo</option>
|
||||
<option value="4126">Vogošća</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="livanjski"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="560">Bosansko Grahovo</option>
|
||||
<option value="4640">Drvar</option>
|
||||
<option value="1533">Glamoč</option>
|
||||
<option value="2635">Kupres</option>
|
||||
<option value="2741">Livno</option>
|
||||
<option value="1228">Tomislavgrad</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select name="" id="grad11" class="drop-select" onchange="stavi_grad()">
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="645">distriktbrcko</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="banjalučka"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="21">Banja Luka</option>
|
||||
<option value="305">Gradiška</option>
|
||||
<option value="4662">Istočni Drvar</option>
|
||||
<option value="1965">Jezero</option>
|
||||
<option value="4147">Kneževo</option>
|
||||
<option value="6142">Kostajnica</option>
|
||||
<option value="2574">Kotor Varoš</option>
|
||||
<option value="244">Kozarska Dubica</option>
|
||||
<option value="382">Krupa na uni</option>
|
||||
<option value="2654">Kupres </option>
|
||||
<option value="2671">Laktaši</option>
|
||||
<option value="3073">Mrkonjić Grad</option>
|
||||
<option value="444">Novi Grad</option>
|
||||
<option value="3737">Oštra Luka</option>
|
||||
<option value="515">Petrovac</option>
|
||||
<option value="3287">Prijedor</option>
|
||||
<option value="3358">Prnjavor</option>
|
||||
<option value="2365">Ribnik</option>
|
||||
<option value="4271">Srbac</option>
|
||||
<option value="979">Čelinac</option>
|
||||
<option value="4509">Šipovo</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="dobojskobijeljinska"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="123">Bijeljina</option>
|
||||
<option value="421">Bosanski Brod</option>
|
||||
<option value="1030">Derventa</option>
|
||||
<option value="1088">Doboj</option>
|
||||
<option value="3254">Donji Žabar</option>
|
||||
<option value="2800">Lopare</option>
|
||||
<option value="6029">Lukavac</option>
|
||||
<option value="2996">Modriča</option>
|
||||
<option value="1856">Pelagićevo</option>
|
||||
<option value="1827">Petrovo</option>
|
||||
<option value="1148">Stanari</option>
|
||||
<option value="4549">Teslić</option>
|
||||
<option value="4636">Tešanj</option>
|
||||
<option value="4692">Travnik</option>
|
||||
<option value="4966">Tuzla</option>
|
||||
<option value="5009">Ugljevik</option>
|
||||
<option value="3197">Vukosavlje</option>
|
||||
<option value="539">Šamac</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="sarajevskozvornicka"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="595">Bratunac</option>
|
||||
<option value="1904">Han Pijesak</option>
|
||||
<option value="3947">Ilijaš</option>
|
||||
<option value="4049">Istočni Stari Grad</option>
|
||||
<option value="3880">Kasindo</option>
|
||||
<option value="2325">Kladanj</option>
|
||||
<option value="3971">Lukavica</option>
|
||||
<option value="6143">Milići</option>
|
||||
<option value="3221">Olovo</option>
|
||||
<option value="2128">Osmaci</option>
|
||||
<option value="3978">Pale</option>
|
||||
<option value="3529">Rogatica</option>
|
||||
<option value="3648">Rudo</option>
|
||||
<option value="6069">Sarajevo-Novi Grad</option>
|
||||
<option value="4183">Sokolac</option>
|
||||
<option value="4310">Srebrenica</option>
|
||||
<option value="4067">Trnovo</option>
|
||||
<option value="1593">Ustiprača</option>
|
||||
<option value="5259">Višegrad</option>
|
||||
<option value="5456">Vlasenica</option>
|
||||
<option value="5684">Zvornik</option>
|
||||
<option value="4475">Šekovići</option>
|
||||
<option value="1906">Žepa</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="height:40px;">
|
||||
<span class="drop-container" style="width: 168px;">
|
||||
<span class="drop-label">Mjesto</span><span class="drop-arrow"></span>
|
||||
<select
|
||||
name=""
|
||||
id="trebinjskofocanska"
|
||||
class="drop-select"
|
||||
onchange="stavi_grad()"
|
||||
>
|
||||
<option value="0">Mjesto</option>
|
||||
<option value="4441">Berkovići</option>
|
||||
<option value="183">Bileća</option>
|
||||
<option value="1287">Foča</option>
|
||||
<option value="1462">Gacko</option>
|
||||
<option value="3038">Istočni Mostar</option>
|
||||
<option value="2164">Kalinovik</option>
|
||||
<option value="2884">Ljubinje</option>
|
||||
<option value="3138">Nevesinje</option>
|
||||
<option value="4766">Trebinje</option>
|
||||
<option value="911">Čajniče</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const stavi_grad = () => {};
|
||||
const gradovi = [
|
||||
{ ime: " Sarajevo", id: "sarajevo" },
|
||||
{ ime: " Unsko-sanski", id: "unskosanski" },
|
||||
{ ime: " Posavski", id: "posavski" },
|
||||
{ ime: " Tuzlanski", id: "tuzlanski" },
|
||||
{ ime: " Zeničko-dobojski", id: "zenickodobojski" },
|
||||
{ ime: " Bosansko-podrinjski", id: "bosanskopodrinjski" },
|
||||
{ ime: " Srednjobosanski", id: "srednjobosanski" },
|
||||
{ ime: " Hercegovačko-neretvanski", id: "hercegovackoneretvanski" },
|
||||
{ ime: " Zapadno-hercegovački", id: "zapadnohercegovacki" },
|
||||
{ ime: " Livanjski", id: "livanjski" },
|
||||
{ ime: " Banjalučka", id: "banjalučka" },
|
||||
{ ime: " Dobojsko-Bijeljinska", id: "dobojskobijeljinska" },
|
||||
{ ime: " Sarajevsko-Zvornička", id: "sarajevskozvornicka" },
|
||||
{ ime: " Trebinjsko-Fočanska", id: "trebinjskofocanska" },
|
||||
{ ime: "Distrikt Brčko", id: "distriktbrcko" }
|
||||
];
|
||||
|
||||
for (let grad of gradovi) {
|
||||
const mjesta = [];
|
||||
$("#" + grad.id)
|
||||
.children()
|
||||
.each(function() {
|
||||
const mjesto = $(this).text();
|
||||
mjesta.push({
|
||||
ime: mjesto,
|
||||
id: mjesto.toLowerCase().replace(/[^a-z]/g, ""),
|
||||
olxid: $(this).val()
|
||||
});
|
||||
});
|
||||
grad.mjesta = mjesta;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user