updated voting and scoring to give more "power" to admins

This commit is contained in:
Sacha Greif 2012-09-26 06:51:38 +09:00
parent 205f59c562
commit eda774aea1
5 changed files with 30 additions and 15 deletions

View file

@ -30,7 +30,6 @@ Template.footer.rendered = function(){
} }
document.title = getSetting("title"); document.title = getSetting("title");
if(Meteor.user() && !Meteor.user().loading && !Meteor.user().createdAt){ if(Meteor.user() && !Meteor.user().loading && !Meteor.user().createdAt){
throwError("Due to the Auth API update, please log out and then create a new account. Sorry!") throwError("Due to the Auth API update, please log out and then create a new account. Sorry!")
} }

View file

@ -41,7 +41,7 @@
| <a href="/posts/{{_id}}/edit" class="edit-link goto-edit">Edit</a> | <a href="/posts/{{_id}}/edit" class="edit-link goto-edit">Edit</a>
{{/if}} {{/if}}
{{#if is_admin}} {{#if is_admin}}
| score: {{short_score}}, votes: {{votes}} | votes: {{votes}}, baseScore: {{baseScore}}, score: {{short_score}}
{{/if}} {{/if}}
</p> </p>
</div> </div>

View file

@ -37,4 +37,14 @@ sessionSetObject=function(name, value){
sessionGetObject=function(name){ sessionGetObject=function(name){
return JSON.parse(Session.get(name)); return JSON.parse(Session.get(name));
}
// returns how much "power" a user's votes have
getVotesPower = function(userId){
var user=Meteor.users.findOne(userId);
if(user.isAdmin){
return 5;
}else{
return 1;
}
} }

View file

@ -20,36 +20,36 @@
var upvote = function(collection, id) { var upvote = function(collection, id) {
return prepareVote.call(this, collection, id, function(userId) { return prepareVote.call(this, collection, id, function(userId) {
var votePower=getVotesPower(userId);
var query = {_id: id, upvoters: {$ne: userId}}; var query = {_id: id, upvoters: {$ne: userId}};
var update = {$push: {upvoters: userId}, $inc: {votes: 1}}; var update = {$push: {upvoters: userId}, $inc: {votes: 1}, $inc: {baseScore: votePower}};
collection.update(query, update); collection.update(query, update);
}); });
}; };
var downvote = function(collection, id) { var downvote = function(collection, id) {
return prepareVote.call(this, collection, id, function(userId) { return prepareVote.call(this, collection, id, function(userId) {
var votePower=getVotesPower(userId);
var query = {_id: id, downvoters: {$ne: userId}}; var query = {_id: id, downvoters: {$ne: userId}};
var update = {$push: {downvoters: userId}, $inc: {votes: -1}}; var update = {$push: {downvoters: userId}, $inc: {votes: -1}, $inc: {baseScore: -votePower}};
collection.update(query, update); collection.update(query, update);
}); });
}; };
var cancelUpvote = function(collection, id) { var cancelUpvote = function(collection, id) {
return prepareVote.call(this, collection, id, function(userId) { return prepareVote.call(this, collection, id, function(userId) {
var votePower=getVotesPower(userId);
var query = {_id: id, upvoters: userId}; var query = {_id: id, upvoters: userId};
var update = {$pull: {upvoters: userId}, $inc: {votes: -1}}; var update = {$pull: {upvoters: userId}, $inc: {votes: -1}, $inc: {baseScore: -votePower}};
collection.update(query, update); collection.update(query, update);
}); });
}; };
var cancelDownvote = function(collection, id) { var cancelDownvote = function(collection, id) {
return prepareVote.call(this, collection, id, function(userId) { return prepareVote.call(this, collection, id, function(userId) {
var votePower=getVotesPower(userId);
var query = {_id: id, downvoters: userId}; var query = {_id: id, downvoters: userId};
var update = {$pull: {downvoters: userId}, $inc: {votes: 1}}; var update = {$pull: {downvoters: userId}, $inc: {votes: 1}, $inc: {baseScore: -votePower}};
collection.update(query, update); collection.update(query, update);
}); });
}; };

View file

@ -7,16 +7,22 @@ var Scoring = {
if(isNaN(object.score)){ if(isNaN(object.score)){
object.score=0; object.score=0;
} }
if(typeof object.votes === 'undefined'){
// just count the number of votes for now object.votes=0;
var baseScore = object.votes; }
// use baseScore if defined, if not just use the number of votes
// note: for transition period, also use votes if there are more votes than baseScore
var baseScore = (typeof object.baseScore === 'undefined' || object.votes>object.baseScore) ? object.votes : object.baseScore;
// now multiply by 'age' exponentiated // now multiply by 'age' exponentiated
// FIXME: timezones <-- set by server or is getTime() ok? // FIXME: timezones <-- set by server or is getTime() ok?
var ageInHours = (new Date().getTime() - object.submitted) / (60 * 60 * 1000); var ageInHours = (new Date().getTime() - object.submitted) / (60 * 60 * 1000);
object.score = baseScore * Math.pow(ageInHours + 2, -0.1375); // Bindle algorithm
// object.score = baseScore * Math.pow(ageInHours + 2, -0.1375);
// HN algorithm (same as Bindle)
object.score = (baseScore) / Math.pow(ageInHours + 2, 1.3);
}, },
// rerun all the scoring -- TODO: should we check to see if the score has // rerun all the scoring -- TODO: should we check to see if the score has
@ -37,6 +43,6 @@ var Scoring = {
// tick every second // tick every second
Meteor.Cron = new Cron(1000); Meteor.Cron = new Cron(1000);
// update scores every 10 seconds // update scores every 10 seconds
Meteor.Cron.addJob(30, function() { Meteor.Cron.addJob(10, function() {
Scoring.updateScores(); Scoring.updateScores();
}) })