require("dotenv").config(); const { APP_PORT } = require("./app/config/appConfig"); const welcome = require("./app/controllers/welcome").getWelcome; const { getRealEstateTypes, postRealEstateTypes } = require("./app/controllers/realEstateTypes"); const { getRegion, postRegion } = require("./app/controllers/regions"); const { getMunicipality, postMunicipality } = require("./app/controllers/municipalities"); const { getSize, postSize } = require("./app/controllers/sizes"); const { getGardenSize, postGardenSize } = require("./app/controllers/gardenSizes"); const { getPrice, postPrice } = require("./app/controllers/prices"); const { getQueryReview, postQueryReview } = require("./app/controllers/queryReview"); const { getQuerySubmit, postQuerySubmit } = require("./app/controllers/querySubmit"); const { getGoAgain } = require("./app/controllers/goAgain"); const { getNeighborhood, postNeighborhood } = require("./app/controllers/neighborhoodMap"); const { getUnsubscribe } = require("./app/controllers/unsubscribe"); const { getRealEstates } = require("./app/controllers/realEstates"); const { redirect } = require("./app/controllers/redirect"); const schedule = require("node-schedule"); const crawlAll = require("./app/services/crawlerService"); const processNotifications = require("./app/services/notificationService"); let express = require("express"); const path = require("path"); const bodyParser = require("body-parser"); const MarketAlert = require("./app/models/marketalert"); const sendNotification = require("./app/lib/sendNotification"); const scrapTheItems = require("./app/lib/scrapTheItems"); const sequelize = require("./app/models/index").sequelize; const Twocheckout = require("2checkout-node"); const layout = require("express-layout"); const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.set("views", path.join(__dirname, "/app/views")); app.set("view engine", "ejs"); app.use(layout()); const compression = require("compression"); app.use(compression()); app.get("/api/sendnotifications", async (req, res) => { let marketAlerts = await MarketAlert.findAll(); let lastDateUpdate = await Promise.all( marketAlerts .map(marketAlert => { const { id, email, olx_url, last_date } = marketAlert.dataValues; return { id, email, olx_url, last_date }; }) .map(sendNotification) ); lastDateUpdate = lastDateUpdate.filter(Boolean(dateUpdate)); lastDateUpdate.length && lastDateUpdate.forEach(dateUpdate => MarketAlert.update( { last_date: dateUpdate.date }, { where: { id: dateUpdate.id } } ) ); }); app.get("/api/items/:url", async (req, res) => { let url = "https://www.olx.ba/pretraga?" + req.params.url + "&sort_order=desc&sort_po=datum"; let appts = await scrapTheItems(url); res.json({ last_date: appts[0] && appts[0].date, items: appts }); }); app.post("/api/marketalerts", (req, res) => { const { email, last_date, olx_url } = req.body; console.log(email, last_date, olx_url); sequelize.sync().then(() => { MarketAlert.create({ olx_url, last_date, email }) .then(() => { res.json({ message: "Market Alert Created!" }); }) .catch(e => console.error(e)); }); }); app.post("/api/payforalert", (req, res) => { let tco = new Twocheckout({ sellerId: "901402692", privateKey: "A28DCE5F-9292-405C-8161-F84D8BB83AFC", sandbox: true }); let params = { merchantOrderId: "123", token: req.body.token, currency: "USD", total: "2.00", billingAddr: { name: "Testing Tester", addrLine1: "123 Test St", city: "Sarajevo", state: "BiH", zipCode: "71000", country: "BiH", email: req.body.email, phoneNumber: "5555555555" } }; tco.checkout.authorize(params, function(error, data) { if (error) { res.send(error.message); } else { res.send(data.response.responseMsg); } }); }); app.get("/", welcome); app.get("/vrstanekretnine/:request_id", getRealEstateTypes); app.get("/vrstanekretnine", getRealEstateTypes); app.post("/vrstanekretnine/:request_id", postRealEstateTypes); app.post("/vrstanekretnine", postRealEstateTypes); app.get("/grad/:request_id", getRegion); app.post("/grad/:request_id", postRegion); app.get("/mjesto/:request_id", getMunicipality); app.post("/mjesto/:request_id", postMunicipality); app.get("/naselje/:request_id/:municipality", getNeighborhood); app.post("/naselje/:request_id/:municipality", postNeighborhood); app.get("/povrsina/:request_id", getSize); app.post("/povrsina/:request_id", postSize); app.get("/okucnica/:request_id", getGardenSize); app.post("/okucnica/:request_id", postGardenSize); app.get("/cijena/:request_id", getPrice); app.post("/cijena/:request_id", postPrice); app.get("/pregled/:request_id", getQueryReview); app.post("/pregled/:request_id", postQueryReview); app.get("/posalji/:request_id", getQuerySubmit); app.post("/posalji/:request_id", postQuerySubmit); app.get("/odjava/:request_id", getUnsubscribe); app.get("/ponovo", getGoAgain); app.get("/nekretnine/:request_id", getRealEstates); app.get("/redirect/:id", redirect); app.use("/assets", express.static("./app/public")); app.listen(APP_PORT, () => console.log(`Example app listening on port ${APP_PORT}!`) ); var rule = new schedule.RecurrenceRule(); rule.seccond = 1; schedule.scheduleJob(rule, async function() { console.log(new Date(), "Crawler service started"); await crawlAll(); console.log( new Date(), "Crawler service finished, starting Notification service" ); await processNotifications(); console.log(new Date(), "Notification service finished"); }); /** * Add flat method to Array */ Object.defineProperty(Array.prototype, "flat", { value: function(depth = 1) { return this.reduce(function(flat, toFlatten) { return flat.concat( Array.isArray(toFlatten) && depth > 1 ? toFlatten.flat(depth - 1) : toFlatten ); }, []); } });