Skip to content

Instantly share code, notes, and snippets.

@firehawk895
Created March 12, 2016 08:17
Show Gist options
  • Save firehawk895/464b16cbc11fb02719fe to your computer and use it in GitHub Desktop.
Save firehawk895/464b16cbc11fb02719fe to your computer and use it in GitHub Desktop.
The Express Gist
/**
* TODO: switch to schema based validation
*/
var express = require('express');
global.mod = function (file){
return require ("./" + file)
}
global.__base = __dirname + '/';
var path = require('path');
var fs = require('fs')
var morgan = require('morgan');
var bodyParser = require('body-parser');
var cors = require('cors');
var request = require('request')
var qbchat = require('./Chat/qbchat');
var passport = require('passport');
var BearerStrategy = require('passport-http-bearer').Strategy;
var user = require('./routes/user');
var matches = require('./routes/matches');
var facilities = require('./routes/facilities');
var sports = require('./routes/sports');
var events = require('./routes/events');
var chats = require('./routes/chats');
var config = require('./config.js');
var customUtils = require('./utils.js');
//kardo sab import, node only uses it once
var constants = require('./constants');
var UserModel = require('./models/User');
var MatchModel = require('./models/Match');
var EventModel = require('./models/Event');
var RequestModel = require('./requests/Request');
var dbUtils = require('./dbUtils');
var EventSystem = require('./events/events');
var requests = require('./requests/requests');
//var recommendations = require('./recommendations/recommendations');
//----------------------------- Start Extended Validators --------------------------------------
var validator = require('validator');
validator.extend('isTimeInFuture', function (time) {
console.log(time)
if (!time)
return false
var date = new Date()
var currentTime = date.getTime()
console.log(currentTime)
if (validator.isInt(time) && parseInt(time) > (currentTime / 1000))
return true
else
return false
});
validator.extend('isValidLatLong', function (latOrLong) {
var regex = /^-?([1-8]?[1-9]|[1-9]0)\.{1}\d{1,6}/
return latOrLong.match(regex) ? true : false
})
validator.extend('isImage', function (mimetype) {
return mimetype.match(/^image/)
})
//---------------------------- End Extended Validators -----------------------------------------
var oio = require('orchestrate');
oio.ApiEndPoint = config.db.region;
var db = oio(config.db.key);
var app = express();
//qbchat.init();
//qbchat.createSession(function (err, session) {
// if (session) {
// console.log("Quickblox Session created");
// }
// else if (err) console.log(err)
// }
//);
function failure() {
return false;
}
// app.use(favicon(__dirname + '/public/favicon.ico'));
// create a write stream (in append mode)
var accessLogStream = fs.createWriteStream(__dirname + '/access.log', {flags: 'a'})
var corsOptions = {
origin: '*',
credentials: true
};
app.use(morgan(':remote-addr - [:date[clf]] - :method :url :status - :response-time ms', {stream: accessLogStream}))
app.use(morgan('dev'))
app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(passport.initialize());
/**
* Its better to use JWT (JSON Web Token)
* so as to save these extra calls to the database
* caching queries above the layer of orchestrate would be
* the awesome way to go.
*/
passport.use(new BearerStrategy({},
function (token, done) {
db.newGraphReader()
.get()
.from('tokens', token)
.related('hasUser')
.then(function (result) {
user = result.body;
if (user.count === 1) {
return done(null, user);
} else {
console.log("token has no user");
return done(null, false);
}
//console.log(result);
})
.fail(function (err) {
console.log("Token invalid or expired");
return done(null, false);
});
}
));
// view engine setup
//app.set('views', path.join(__dirname, 'views'));
//app.set('view engine', 'jade');
//app.use('/public', express.static(path.join(__dirname, 'public')));
app.use('/user', user);
app.use('/matches', matches);
app.use('/facilities', facilities);
app.use('/sports', sports);
app.use('/events', events);
app.use('/chats', chats);
app.all('/ping', function (req, res) {
res.send('Pong')
});
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
//// will print stacktrace
//if (app.get('env') === 'development') {
// app.use(function (err, req, res, next) {
// res.status(err.status || 500);
// res.send(err);
// });
//}
//
//// production error handler
//// no stacktraces leaked to user
//app.use(function (err, req, res, next) {
// res.status(err.status || 500);
// res.send(err);
//});
// error handlers
// development error handler
// will print stacktrace
//if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
console.log(err)
res.status(err.status || 500);
res.json({
errors: [err.message],
errorObj: err
});
});
//}
// production error handler
// no stacktraces leaked to user
//app.use(function(err, req, res, next) {
// res.status(err.status || 500);
// res.render('error', {
// message: err.message,
// error: {}
// });
//});
module.exports = app;
//kardo sab import, node only uses it once
var config = require(__base + 'config.js');
var oio = require('orchestrate');
oio.ApiEndPoint = config.db.region;
var db = oio(config.db.key);
var customUtils = require('../utils.js');
var constants = require('../constants');
var qbchat = require('../Chat/qbchat');
var UserModel = require('../models/User');
var MatchModel = require('../models/Match');
//var EventModel = require(__base + 'models/Event');
var RequestModel = require('../requests/Request');
var dbUtils = require('../dbUtils');
var EventSystem = require('../events/events');
console.log("yay")
function checkEventParticipationPromise(eventId, userId) {
var checkEventParticipationPromise =
db.newSearchBuilder()
.query(dbUtils.createGetOneOnOneGraphRelationQuery('events', eventId, 'participants', 'users', userId))
return checkEventParticipationPromise
}
/**
* get featured matches
* @returns {SearchBuilder} promise
*/
function getFeaturedEventsPromise() {
/**
* TODO: Red alert! can't put this outside! how!
* no idea why in the world if this is outside the method this doesnt work
*/
var MatchModel = require(__base + 'models/Match');
var queries = []
queries.push("value.isFeatured:true")
console.log("sup")
queries.push(MatchModel.createIsDiscoverableQuery())
console.log("never made it here")
var finalQuery = dbUtils.queryJoiner(queries)
var featuredMatches = db.newSearchBuilder()
.collection("events")
.query(finalQuery)
return featuredMatches
}
module.exports = {
checkEventParticipationPromise : checkEventParticipationPromise,
getFeaturedEventsPromise : getFeaturedEventsPromise
}
//kardo sab import, node only uses it once
var config = require(__base + 'config.js');
var oio = require('orchestrate');
oio.ApiEndPoint = config.db.region;
var db = oio(config.db.key);
var customUtils = require('../utils.js');
var constants = require('../constants');
var qbchat = require('../Chat/qbchat');
var UserModel = require('../models/User');
var EventModel = require('../models/Event');
var RequestModel = require('../requests/Request');
var dbUtils = require('../dbUtils');
var EventSystem = require('../events/events');
var date = new Date()
/**
* LUCENE query generators ------------------------------------->
*/
/**
* generete the lucene query for min and max skill rating
*
* Lucene reference:
* Your queries can contain as many as ten different buckets in a single Range Aggregate.
* Each bucket can have numerical min and max values, separated by a tilde character (~).
* An asterisk may be used to designate a particular range bucket as boundless.
* For example, the range *~-10 would mean "all values less than negative ten" and
* the range 100~* would communicate "all values greater than or equal to one hundred".
*
* Ya that shit didn't work so I used the range [minRating TO 5] etc. -_- :*
* @param minRating
* @param maxRating
*/
function createSkillRatingQuery(minRating, maxRating) {
var skillQuery = "value.skill_level_min:[" + minRating + " TO 5] AND " + "value.skill_level_max:[1 TO " + maxRating + "]"
return skillQuery
}
function connectFacilityToMatch(matchId, facilityId) {
dbUtils.createGraphRelation('matches', matchId, 'facilities', facilityId, constants.graphRelations.matches.hostedFacility)
dbUtils.createGraphRelation('facilities', facilityId, 'matches', matchId, constants.graphRelations.matches.hasMatches)
}
/**
* get results having playing_time that are past the current time
* and whose results matches/events are discoverable
* @returns {string}
*/
function createIsDiscoverableQuery() {
var currentUnixTime = Math.round(date.getTime() / 1000)
var query = "value.playing_time: " + currentUnixTime + "~*" //this means greater than equalto
//https://orchestrate.io/docs/apiref#search
//matches that are not discoverable for any reason are set to isDiscoverable: false
query = query + " AND value.isDiscoverable:true"
return query
}
/**
* Note : For lucene you can use filed grouping:
* Field Grouping
* Lucene supports using parentheses to group multiple clauses to a single field.
* To search for a title that contains both the word "return" and the phrase "pink panther" use the query:
* title:(+return +"pink panther")
*
* createSportsQuery can be updated this way
*/
/**
* Crate a lucene OR query with the array of sports provided
* @param sportsArray
* @returns {string}
*/
function createSportsQuery(sportsArray) {
return dbUtils.createFieldORQuery(sportsArray, "value.sports")
}
/**
* Crate a lucene OR query with the array of gender provided
* @param genderArray
* @returns {*}
*/
function createGenderQuery(genderArray) {
return dbUtils.createFieldORQuery(genderArray, "value.gender")
}
/**
* assuming the field type is time
*/
function createOnlyFutureTypeQuery() {
var currentUnixTime = Math.round(date.getTime() / 1000);
//this means greater than equalto
return "value.time: " + currentUnixTime + "~*"
}
/**
* check if a user is participating in a match
* @param matchId
* @param userId
* @returns {SearchBuilder}
*/
function checkMatchParticipationPromise(matchId, userId) {
var checkMatchParticipation =
db.newSearchBuilder()
.query(dbUtils.createGetOneOnOneGraphRelationQuery('matches', matchId, constants.graphRelations.matches.participants, 'users', userId))
return checkMatchParticipation
}
function incrementMatchesPlayed(userId) {
db.get("users", userId)
.then(function (result) {
var matchesPlayed = result.body.matchesPlayed;
db.merge("users", userId, {
matchesPlayed: matchesPlayed + 1
})
})
}
/**
* inject the distance between the match and the user in km
* @param results orchestrate response of matches
* @param usersLat lat coordinates of the user
* @param usersLong long coordinates of the user
*/
var insertDistance = function (results, usersLat, usersLong) {
var newResults = results.body.results.map(function (aResult) {
aResult["value"]["distance"] = customUtils.getDistanceFromLatLonInKm(
aResult["value"]["location"]["lat"],
aResult["value"]["location"]["long"],
usersLat,
usersLong
)
return aResult;
//console.log(aResult["value"]["distance"])
})
console.log(newResults)
results.body.results = newResults
return results
}
/**
* update the connections of all users when a new player
* joins the match
* @param userId
* @param matchId
*/
function updateMatchConnections(userId, matchId) {
/**
* get all the players of the match
* let playerList = the players of the match except the player in userId
* create connections of userId to the playerList if no existing connection exists
* create connections of each player in playerList to the userId if no existing connection exists
*/
db.newGraphReader()
.get()
.from('matches', matchId)
.related(constants.graphRelations.matches.participants)
.then(function (results) {
//get all the players of the match
var playerList = results.body.results.map(function (oneUser) {
return oneUser.path.key;
})
//let players = the players of the match except the player in userId
var index = playerList.indexOf(userId)
if (index > -1) {
playerList.splice(index, 1);
}
playerList.forEach(function (playerId) {
dbUtils.createGraphRelation('users', userId, 'users', playerId, constants.graphRelations.users.connections)
dbUtils.createGraphRelation('users', playerId, 'users', userId, constants.graphRelations.users.connections)
})
})
}
/**
* create the chat room for a match
* @param hostUserQbId
* @param matchId
*/
function createChatRoomForMatch(hostUserQbId, matchId) {
/**
* format of match dialog title:
* <matchRoom>:::matchId
* format of user dialog title:
* <connectionRoom>:::user1id:::user2Id
*/
//TODO: this should be abstracted out into a Chat model that hides this implementation
qbchat.createRoom(2, constants.chats.matchRoom + ":::" + matchId, function (err, newRoom) {
if (err) {
console.log("error creating the room")
console.log(err);
}
else {
console.log("bro add ho gaya bro")
console.log(hostUserQbId)
qbchat.addUserToRoom(newRoom._id, [hostUserQbId], function (err, result) {
if (err) {
console.log("error making the dude join the room")
console.log(err);
} else {
console.log("bro add ho gaya bro")
db.merge('matches', matchId, {"qbId": newRoom._id})
.then(function (result) {
//chatObj["id"] = date.getTime() + "@1";
//chatObj["channelName"] = payload["title"];
//chatObj["channelId"] = newRoom._id;
//notify.emit('wordForChat', chatObj);
})
.fail(function (err) {
console.log(err.body.message);
});
}
})
}
});
}
/**
* takes a json payload and inserts flags:
* hasMale, hasFemale, hasCustomGender
* @param payload
* @param gender
* @returns {*}
*/
function updateGenderInPayload(payload, gender) {
if (gender == "male")
payload["hasMale"] = true
else if (gender == "female")
payload["hasFemale"] = true
else {
payload["hasCustomGender"] = true
}
return payload
}
function getFacilityOfMatchPromise(matchId) {
return dbUtils.getGraphResultsPromise('matches', matchId, constants.graphRelations.matches.hostedFacility)
}
function getMatchPromise(matchId) {
return db.get('matches', matchId)
}
function getFacilityPromise(facilityId) {
return db.get('facilities', facilityId)
}
/**
* get the promise that gets the participants of the matches
* @param matchId
*/
function getMatchParticipantsPromise(matchId) {
return dbUtils.getGraphResultsPromise('matches', matchId, constants.graphRelations.matches.participants)
}
function getMatchHistoryPromise(userId) {
return dbUtils.getGraphResultsPromise('users', userId, constants.graphRelations.users.playsMatches)
}
function removeFromMatch(userId, matchId) {
//decrease slots_filled of the given match
//remove from chat channel
return kew.all([
dbUtils.deleteGraphRelation('matches', matchId, 'users', userId, constants.graphRelations.matches.participants),
dbUtils.deleteGraphRelation('users', userId, 'matches', matchId, constants.graphRelations.users.playsMatches)
])
}
module.exports = {
getMatchParticipantsPromise : getMatchParticipantsPromise,
createSportsQuery : createSportsQuery,
getMatchHistoryPromise : getMatchHistoryPromise,
createOnlyFutureTypeQuery : createOnlyFutureTypeQuery,
connectFacilityToMatch : connectFacilityToMatch,
checkMatchParticipationPromise:checkMatchParticipationPromise,
updateGenderInPayload:updateGenderInPayload,
updateMatchConnections:updateMatchConnections,
createIsDiscoverableQuery:createIsDiscoverableQuery,
createGenderQuery:createGenderQuery,
createChatRoomForMatch:createChatRoomForMatch,
removeFromMatch:removeFromMatch,
createSkillRatingQuery:createSkillRatingQuery,
insertDistance:insertDistance
}
var express = require('express');
var router = express.Router();
var passport = require('passport');
//var config = require('../models/Match.js');
var matchValidation = require('../validations/Match.js');
var kew = require('kew')
//kardo sab import, node only uses it once
var config = require(__base + 'config.js');
var oio = require('orchestrate');
oio.ApiEndPoint = config.db.region;
var db = oio(config.db.key);
var customUtils = require(__base + 'utils.js');
var constants = require(__base + 'constants');
var qbchat = require(__base + 'Chat/qbchat');
var UserModel = require(__base + 'models/User');
var EventModel = require('../models/Event');
console.log("Event model")
console.log(EventModel)
var RequestModel = require(__base + 'requests/Request');
var dbUtils = require(__base + 'dbUtils');
var EventSystem = require(__base + 'events/events');
var MatchModel = require('../models/Match.js')
router.get('/', [passport.authenticate('bearer', {session: false}), function (req, res) {
//... kuch kuch code
promises.push(EventModel.getFeaturedEventsPromise())
//..kuch kuch code
}])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment