Skip to content

Commit

Permalink
Tour save and fetch routes added, tour plan generation optimized.
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnasSalman committed Dec 20, 2020
1 parent 75fcfec commit 8564035
Show file tree
Hide file tree
Showing 7 changed files with 392 additions and 55 deletions.
7 changes: 5 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ var Resources = require('./classes/Resources')

const ResourceUpdates = new Resources()

//'0 */10 * * * *' 10 minutes
//'00 00 00 * * *' midnight

const updateFuelPrices = new CronJob('00 00 00 * * *', async () => {
try{
await ResourceUpdates.updatePetrolPrice()
Expand All @@ -44,9 +47,9 @@ app.use(passport.initialize());
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(express.json({limit: '50mb'}));
app.use(express.urlencoded({limit: '50mb', extended: false}));
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(cors());
app.use(express.static(path.join(__dirname, 'public')));
Expand Down
188 changes: 176 additions & 12 deletions classes/Hotel.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,190 @@
const hotelSearch = require('../models/hotel')
const Booking = require('../models/booking')

class Hotel{
constructor() {


class Hotel{
constructor(lat, lng, dateFrom, dateTo) {
this.lat = lat
this.lng = lng
this.dateFrom = dateFrom
this.dateTo = dateTo
}

async searchHotel(){
const hotels = await hotelSearch.find().getNearbyHotels(33.906528,73.393692,15000)
async searchOneRoom(distanceFromCenter, guests, priceLowerLimit, priceUpperLimit){
const hotels = await hotelSearch.find().getNearbyHotels(this.lat, this.lng, distanceFromCenter)
const hotelIdArray = hotels.map((hotelObject)=>(
hotelObject._id
))
const available = await Booking.find({
guestlimit: {$gt: 2},
price: {$gte: 0, $lte: 10000},
// bookings: {
// $not: {
// $elemMatch: {from: {$lt: req.query.to.substring(0,10)}, to: {$gt: req.query.from.substring(0,10)}}
// }
// }
guestlimit: {$gt: parseInt(guests)-1},
price: {$gte: priceLowerLimit, $lte: priceUpperLimit},
bookings: {
$not: {
$elemMatch: {from: {$lt: this.dateFrom.substring(0,10)}, to: {$gt: this.dateTo.substring(0,10)}}
}
}
}).where('hotelid').in(hotelIdArray).exec();
return {leength: available.length}
return {length: available}
}

async getBestRoomOptions(priceBudgetPerNight, distanceFromCenter, guests )
{
const hotels = await hotelSearch.find().getNearbyHotels(this.lat, this.lng, distanceFromCenter)
const hotelIdArray = hotels.map((hotelObject)=>(
hotelObject._id
))
let resultsFound = false
let round = 1
let dividedGuests = [guests]
let matchedRooms = []

// Find room search type combinations according to guests
while(resultsFound!==true){
const rooms = []
for (const guestAmount of dividedGuests){
const available = await Booking.find({
guestlimit: {$gt: parseInt(guestAmount)-1},
bookings: {
$not: {
$elemMatch: {from: {$lt: this.dateFrom.substring(0,10)}, to: {$gt: this.dateTo.substring(0,10)}}
}
},
price: {$gte: 0, $lte: priceBudgetPerNight},
}).where('hotelid').in(hotelIdArray).sort({guest: 1, price: -1}).exec();
if (available.length>0){
rooms.push(available)
}
}
if(rooms.length<round){
round+=1
while(dividedGuests.length){
dividedGuests.pop()
}
for (let i = 0; i < round; i++){
if(i===round-1){
dividedGuests.push(guests - dividedGuests.reduce(function(a, b){return a + b;}, 0))
}
else{
dividedGuests.push(Math.round(guests/round))
}
}
console.log(dividedGuests)
}
else{
matchedRooms = rooms
resultsFound = true
}
if(round === guests){
resultsFound = true
}
}

// Combinations of rooms according to the number of guests
let roomPackages = []
hotelIdArray.forEach((hotelId)=>{
const roomPackage = []
for(let i = 0; i < matchedRooms.length; i++){
for(let matchedRoom of matchedRooms[i]){
if(matchedRoom.hotelid === hotelId.toString() && !roomPackage.find((roomElement)=>roomElement._id.toString()===matchedRoom._id.toString())){
roomPackage.push(matchedRoom)
break
}
}
}
if(roomPackage.length===matchedRooms.length){
roomPackages.push(roomPackage)
}
})
console.log(roomPackages)

// If no rooms with given budget
if(roomPackages.find(roomPackage => roomPackage.length === 0)){
roomPackages = await this.getCheapestRoomOptions(distanceFromCenter, guests)
}

// If still no cheapest rooms
if(roomPackages.find(roomPackage => roomPackage.length === 0)){
roomPackages = []
}

return roomPackages
}

async getCheapestRoomOptions(distanceFromCenter, guests){
const hotels = await hotelSearch.find().getNearbyHotels(this.lat, this.lng, distanceFromCenter)
const hotelIdArray = hotels.map((hotelObject)=>(
hotelObject._id
))
let resultsFound = false
let round = 1
let dividedGuests = [guests]
let matchedRooms = []

// Find room search type combinations according to guests
while(resultsFound!==true){
const rooms = []
for (const guestAmount of dividedGuests){
const available = await Booking.find({
guestlimit: {$gt: parseInt(guestAmount)-1},
bookings: {
$not: {
$elemMatch: {from: {$lt: this.dateFrom.substring(0,10)}, to: {$gt: this.dateTo.substring(0,10)}}
}
}
}).where('hotelid').in(hotelIdArray).sort({price: 1}).exec();
if (available.length>0){
rooms.push(available)
}
}
if(rooms.length<round){
round+=1
while(dividedGuests.length){
dividedGuests.pop()
}
for (let i = 0; i < round; i++){
if(i===round-1){
dividedGuests.push(guests - dividedGuests.reduce(function(a, b){return a + b;}, 0))
}
else{
dividedGuests.push(Math.round(guests/round))
}
}
console.log(dividedGuests)
}
else{
matchedRooms = rooms
resultsFound = true
}
if(round === guests){
resultsFound = true
}
}

// Combinations of rooms according to the number of guests
const roomPackages = []
hotelIdArray.forEach((hotelId)=>{
const roomPackage = []
for(let i = 0; i < matchedRooms.length; i++){
for(let matchedRoom of matchedRooms[i]){
if(matchedRoom.hotelid === hotelId.toString() && !roomPackage.find((roomElement)=>roomElement._id.toString()===matchedRoom._id.toString())){
roomPackage.push(matchedRoom)
break
}
}
}
if(roomPackage.length===matchedRooms.length){
roomPackages.push(roomPackage)
}
})

return roomPackages

}

async findHotelDetailsById(id){
const hotel = await hotelSearch.findById(id).exec()
return hotel
}
}

Expand Down
16 changes: 8 additions & 8 deletions classes/Interests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ const availableInterests = {
searchQuery: 'sightseeing',
searchType: 'tourist_attraction',
validTypes: ['tourist_attraction'],
invalidTypes: [],
invalidTypes: ['travel_agency'],
},
hiking: {
searchQuery: 'hiking trails',
searchType: '',
validTypes: ['point_of_interest', 'park'],
invalidTypes: ['tourist_attraction']
invalidTypes: ['tourist_attraction', 'travel_agency']
},
shopping: {
searchQuery: 'shopping mall',
searchType: 'shopping_mall',
validTypes: ['shopping_mall'],
validTypes: ['shopping_mall', 'travel_agency'],
invalidTypes: [],
},
boating: {
Expand All @@ -28,32 +28,32 @@ const availableInterests = {
historical: {
searchQuery: 'historical',
searchType: '',
validTypes: ['point_of_interest'],
validTypes: ['point_of_interest', 'travel_agency'],
invalidTypes: [],
},
entertainment: {
searchQuery: 'entertainment',
searchType: '',
validTypes: ['point_of_interest'],
invalidTypes: [],
invalidTypes: ['travel_agency'],
},
wildlife: {
searchQuery: 'zoo',
searchType: '',
validTypes: ['zoo'],
invalidTypes: [],
invalidTypes: ['travel_agency'],
},
museums: {
searchQuery: 'museums',
searchType: 'museum',
validTypes: ['museum'],
invalidTypes: [],
invalidTypes: ['travel_agency'],
},
lakes: {
searchQuery: 'lakes',
searchType: '',
validTypes: ['natural_feature', 'park'],
invalidTypes: []
invalidTypes: ['travel_agency']
}
}

Expand Down
23 changes: 19 additions & 4 deletions classes/Resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Resources{

constructor() {
}

// /html/body/div[2]/div[4]/div/div/div/div[2]/div/div[1]/table/tbody/tr[3]/td[2]
async updatePetrolPrice () {
const browser = await puppeteer.launch()
const page = await browser.newPage()
Expand All @@ -14,12 +14,27 @@ class Resources{
const [el] = await page.$x('/html/body/div[2]/div[4]/div/div/div/div[2]/div/div[1]/table/tbody/tr[2]/td[2]')
const src = await el.getProperty('textContent')
const srcText = await src.jsonValue()

const [el2] = await page.$x('/html/body/div[2]/div[4]/div/div/div/div[2]/div/div[1]/table/tbody/tr[3]/td[2]')
const src2 = await el2.getProperty('textContent')
const srcText2 = await src2.jsonValue()

await ResourceConstants.updateOne( { resourceName : 'petrolPrice'}, {resourceName: 'petrolPrice', value : srcText, updatedAt: new Date() }, { upsert : true })
await ResourceConstants.updateOne( { resourceName : 'dieselPrice'}, {resourceName: 'dieselPrice', value : srcText2, updatedAt: new Date() }, { upsert : true })

await browser.close()
}

async getPetrolPrices () {
const price = await ResourceConstants.findOne({ resourceName: 'petrolPrice' }, 'value').exec();
return parseFloat(price.value)

async getFuelPrices (fuelType) {
if(fuelType==='diesel'){
const price = await ResourceConstants.findOne({ resourceName: 'petrolPrice' }, 'value').exec();
return parseFloat(price.value);
}
else {
const price = await ResourceConstants.findOne({ resourceName: 'dieselPrice' }, 'value').exec();
return parseFloat(price.value)
}
}
}

Expand Down
38 changes: 38 additions & 0 deletions models/tour.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var Tour = new Schema({
tour:{},
dateSchedule:{},
totalTourDistance:{},
public: {
type: 'Boolean'
},
cities: {},
title: {
type: 'String'
},
description: {
type: 'String'
},
user: {},
ratings: [],
geometry: {
coordinates: { type: [Number], index: '2dsphere'}
}

});

Tour.query.getNearbyTours = function(lat, lng, distance){
return this.find({'geometry.coordinates': {
$near: {
$geometry: {
type: "Point",
coordinates: [lng, lat]
},
$maxDistance: distance
}
}})
}

module.exports = mongoose.model('Tour', Tour);
1 change: 1 addition & 0 deletions routes/bookings.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ router.get('/findrooms', async (req, res)=>{
}
}, function(err, rooms){
if(err){
console.log('entered')
res.send(err);
} else {
res.json(rooms);
Expand Down
Loading

0 comments on commit 8564035

Please sign in to comment.