mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-30 19:06:59 -05:00
Level completion counts script
This commit is contained in:
parent
a8c06652ec
commit
624dabd55a
1 changed files with 153 additions and 0 deletions
153
scripts/analytics/mongodb/queries/levelCompletionCounts.js
Normal file
153
scripts/analytics/mongodb/queries/levelCompletionCounts.js
Normal file
|
@ -0,0 +1,153 @@
|
|||
// Level completion counts broken down into free and paid buckets
|
||||
|
||||
// Usage:
|
||||
// mongo <address>:<port>/<database> <script file> -u <username> -p <password>
|
||||
|
||||
// TODO: subscriber is someone who is currently subscribed, not necessarily subscribed when they completed a level
|
||||
|
||||
// Excluded for one reason or another
|
||||
// Some relevant code: https://github.com/codecombat/codecombat/blob/master/app/views/play/CampaignView.coffee#L281-L292
|
||||
var excludedLevels = ['deadly-dungeon-rescue', 'kithgard-brawl', 'cavern-survival', 'kithgard-mastery', 'destroying-angel', 'kithgard-apprentice', 'wild-horses', 'lost-viking', 'forest-flower-grove', 'boulder-woods', 'the-trials'];
|
||||
|
||||
var scriptStartTime = new Date();
|
||||
var startDay = '2015-05-16';
|
||||
var endDay = '2015-06-17';
|
||||
|
||||
log("Dates: " + startDay + " to " + endDay);
|
||||
|
||||
var subscribers = getSubscribers();
|
||||
log("Subscriber count: " + Object.keys(subscribers).length);
|
||||
|
||||
var campaigns = getCampaigns();
|
||||
for (var i = 0; i < campaigns.length; i++) {
|
||||
var campaign = campaigns[i];
|
||||
// if (campaign.slug !== 'mountain') continue;
|
||||
|
||||
function printCampaign(title, prop) {
|
||||
print(title)
|
||||
print("Total\tFree\tSubscribers");
|
||||
for (var j = 0; j < campaign[prop].length; j++) {
|
||||
var levelSlug = campaign[prop][j];
|
||||
if (excludedLevels.indexOf(levelSlug) >= 0) continue;
|
||||
var data = getCompletionCounts([levelSlug], subscribers);
|
||||
if (data[levelSlug]) {
|
||||
var free = data[levelSlug].free.length;
|
||||
var paid = data[levelSlug].paid.length;
|
||||
var total = free + paid;
|
||||
var paidRate = parseInt(paid / total * 100);
|
||||
print(total + "\t" + free + "\t" + paid + "\t\t" + paidRate + "%\t" + levelSlug);
|
||||
}
|
||||
else {
|
||||
print("0\t0\t0\t\t0%\t" + levelSlug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printCampaign(campaign.slug + " (free)", "free");
|
||||
printCampaign(campaign.slug + " (paid)", "paid");
|
||||
printCampaign(campaign.slug + " (replayable)", "replayable");
|
||||
|
||||
// break;
|
||||
}
|
||||
|
||||
log("Script runtime: " + (new Date() - scriptStartTime));
|
||||
|
||||
function log(str) {
|
||||
print(new Date().toISOString() + " " + str);
|
||||
}
|
||||
|
||||
function objectIdWithTimestamp(timestamp) {
|
||||
// Convert string date to Date object (otherwise assume timestamp is a date)
|
||||
if (typeof(timestamp) == 'string') timestamp = new Date(timestamp);
|
||||
// Convert date object to hex seconds since Unix epoch
|
||||
var hexSeconds = Math.floor(timestamp/1000).toString(16);
|
||||
// Create an ObjectId with that hex timestamp
|
||||
var constructedObjectId = ObjectId(hexSeconds + "0000000000000000");
|
||||
return constructedObjectId
|
||||
}
|
||||
|
||||
function getCampaigns() {
|
||||
var campaigns = [];
|
||||
var cursor = db.campaigns.find({}, {slug: 1, levels: 1});
|
||||
var allFree = 0;
|
||||
var allpaid = 0;
|
||||
while (cursor.hasNext()) {
|
||||
var doc = cursor.next();
|
||||
if (doc.slug === 'auditions') continue;
|
||||
var campaign = {slug: doc.slug, free: [], paid: [], replayable: []};
|
||||
for (var levelID in doc.levels) {
|
||||
if (doc.levels[levelID].replayable) {
|
||||
campaign.replayable.push(doc.levels[levelID].slug);
|
||||
}
|
||||
else if (doc.levels[levelID].requiresSubscription) {
|
||||
campaign.paid.push(doc.levels[levelID].slug);
|
||||
}
|
||||
else {
|
||||
campaign.free.push(doc.levels[levelID].slug);
|
||||
}
|
||||
}
|
||||
campaigns.push(campaign);
|
||||
}
|
||||
return campaigns;
|
||||
}
|
||||
|
||||
function getCompletionCounts(levelSlugs, subscribers) {
|
||||
var startObj = objectIdWithTimestamp(ISODate(startDay + "T00:00:00.000Z"));
|
||||
var endObj = objectIdWithTimestamp(ISODate(endDay + "T00:00:00.000Z"))
|
||||
var cursor = db['level.sessions'].find({
|
||||
$and:
|
||||
[
|
||||
{"state.complete": true},
|
||||
{levelID: {$in: levelSlugs}},
|
||||
{_id: {$gte: startObj}},
|
||||
{_id: {$lt: endObj}}
|
||||
]
|
||||
});
|
||||
|
||||
var completionCounts = {};
|
||||
while (cursor.hasNext()) {
|
||||
var myDoc = cursor.next();
|
||||
var userID = myDoc.creator;
|
||||
var levelID = myDoc.levelID;
|
||||
|
||||
if (!completionCounts[levelID]) completionCounts[levelID] = {free: [], paid: []};
|
||||
if (subscribers[userID]) {
|
||||
completionCounts[levelID].paid.push(myDoc._id.valueOf());
|
||||
}
|
||||
else {
|
||||
completionCounts[levelID].free.push(myDoc._id.valueOf());
|
||||
}
|
||||
}
|
||||
|
||||
return completionCounts;
|
||||
}
|
||||
|
||||
function getSubscribers() {
|
||||
var cursor = db['users'].find({
|
||||
$and:
|
||||
[
|
||||
{
|
||||
$or:
|
||||
[
|
||||
{"stripe.sponsorID": {$exists: true}},
|
||||
{$and:
|
||||
[
|
||||
{"stripe.subscriptionID": {$exists: true}},
|
||||
{"stripe.planID": 'basic'}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{permissions: {$ne: ['admin']}},
|
||||
{"stripe.free": {$exists: false}},
|
||||
{"stripe.coupon": {$exists: false}},
|
||||
{"stripe.prepaidCode": {$exists: false}}
|
||||
]
|
||||
});
|
||||
|
||||
var subscribers = {};
|
||||
while (cursor.hasNext()) {
|
||||
subscribers[cursor.next()._id.valueOf()] = true;
|
||||
}
|
||||
return subscribers;
|
||||
}
|
Loading…
Reference in a new issue