Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update service for hs leaderboards #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 0 additions & 44 deletions proxy/bots.js

This file was deleted.

4 changes: 2 additions & 2 deletions proxy/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
"id" : "id"
}
},
"supported_courses": [1838, 1906, 3067, 3150, 3149, 3124, 8290],
"supported_courses": [1],
"supported_days": [0, 7, 1]
}
}
24 changes: 0 additions & 24 deletions proxy/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ const users = config.get('table_users');
const getFirstArg = (r) => { return r[0]; }

module.exports = {
addNonFakeUser: function (userId) {
return db.query(`
REPLACE INTO ${users.name} VALUES (?)
`, [userId]);
},

updateRating: function (courseId, profileId, exp) {
return db.query(`
INSERT INTO ${submissions.name}
Expand All @@ -36,24 +30,6 @@ module.exports = {
), NOW()`, [courseId, profileId, exp, courseId, profileId]);
},

/**
* @param courseId {number} - id of a course
* @param count {number} - max number of users you want to get
* @param {number} [delta] - if set period in days for which you want get top
* @return - array of top users like [{profile_id, exp, submissions.fields.timestamp }]
*/
getTopForCourse: function (courseId, count, delta) {
delta = delta ? `AND ${submissions.fields.timestamp} >= DATE_SUB (NOW(), INTERVAL ${SqlString.escape(delta)} DAY)` : '';

return db.query(`
SELECT ${submissions.fields.profileId}, sum(${submissions.fields.exp}) as ${submissions.fields.exp}
FROM ${submissions.name}
WHERE ${submissions.fields.courseId} = ? ${delta}
GROUP BY ${submissions.fields.profileId}
ORDER BY ${submissions.fields.exp} DESC
LIMIT ?`, [courseId, count]).then(getFirstArg);
},

/**
* @param courseId {number} - id of a course
* @param start {number} - starting users rank, if 0 you get top users
Expand Down
121 changes: 6 additions & 115 deletions proxy/handlers.js
Original file line number Diff line number Diff line change
@@ -1,122 +1,13 @@
const
db = require('./db'),
handlers = require('./handlers'),
https = require('https');

// Make api request
// Returns promise with response
function apiCall(endpoint, bearer) {
return new Promise((resolve, reject) => {
let headers = {'Authorization': 'Bearer ' + bearer};
let options = {host: 'stepik.org', path: endpoint, method: 'GET', headers: headers};

let req = https.request(options, res => {
res.setEncoding('utf-8');

let responseString = '';

res.on('data', data => {
responseString += data;
});

res.on('end', () => {
resolve(JSON.parse(responseString));
});
});

req.end();
});
}


function isFakeEmail(email) {
return /adaptive_\d+_(android|ios)_[A-Za-z0-9_]+@stepik\.org/.test(email)
}

// Get id by token
// Returns promise with id
function resolveToken(token) {
return new Promise((resolve, reject) => {
apiCall('/api/stepics/1', token).then(result => {
if (result["users"][0]["is_guest"] != undefined && !result["users"][0]["is_guest"]) {
resolve(result["users"][0]["id"]);
} else {
reject();
}
});
});
}

// Get email by token and id
// Returns promise with emails
function resolveEmail(id, token) {
return new Promise((resolve, reject) => {
apiCall('/api/email-addresses?user=' + id, token).then(result => {
let emails = []
result["email-addresses"].forEach(a => {
emails.push(a["email"]);
});
resolve(emails);
})
.catch(err => reject(err));
});
}

//
function deanonymizeUserById(userId, token) {
return new Promise((resolve, reject) => {
resolveEmail(userId, token).then(emails => {
if (emails.length == 0) {
resolve({status: false, msg: 'has no emails'})
} else {
var hasRealEmail = false
for (var i = 0; i < emails.length; i++) {
if (!isFakeEmail(emails[i])) {
hasRealEmail = true;

db.addNonFakeUser(userId)
.then(_ => resolve({status: true, msg: ''}))
.catch(err => reject(err));
break;
}
}

if (!hasRealEmail) {
resolve({status: false, msg: 'fake email'})
}
}
}).catch(err => reject(err));
});
}
db = require('./db');

module.exports = {
putRating: function(course, rating, token) {
return new Promise((resolve, reject) => {
resolveToken(token)
.then(userId => {
deanonymizeUserById(userId, token)
.then(r => {
if (r.status) {
console.log('[OK] User deanonymized, user id = ' + userId)
}
})
.catch(err => { console.log('[FAIL] Error while user deanonymization. ' + err) })

return db.updateRating(course, userId, rating);
})
.then(_ => resolve())
.catch(err => reject(err));
});
putRating: function(course, rating, userId) {
return db.updateRating(course, userId, rating);
},
restoreRating: function(course, token) {
return new Promise((resolve, reject) => {
resolveToken(token)
.then(userId => {
return db.getUserExpAndStreak(course, userId);
})
.then(result => resolve({exp: result.exp, streak: 0}))
.catch(err => reject(err));
});
restoreRating: function(course, userId) {
let result = db.getUserExpAndStreak(course, userId);
return {exp: result.exp, streak: 0}
},
getRating: function(course, top, delta, user) {
let ratingCnt = 0;
Expand Down
6 changes: 1 addition & 5 deletions proxy/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ const app = express(),
server = require('http').createServer(app),
bodyParser = require('body-parser'),
db = require('./db'),
config = require('config'),
bots = require('./bots');
config = require('config');

app.use(bodyParser.json());
app.use('/', require('./routes'));
Expand All @@ -31,10 +30,7 @@ let rebuildCaches = () => {

setInterval(() => rebuildCaches(), 10 * 60 * 1000);

setInterval(bots.addBots, bots.BOTS_ADD_INTERVAL * 1000);

server.listen(PORT, () => {
console.log(`Server started on port ${PORT}...`);
bots.addBots();
rebuildCaches();
});