Add a couple scripts for resetting user progress and migrating course sessions to hero levels

This commit is contained in:
Nick Winter 2015-11-26 06:54:23 -08:00
parent ac0e21aa39
commit 7a317370b5
3 changed files with 88 additions and 6 deletions

View file

@ -0,0 +1,46 @@
// Migrates course-kithgard-gates-style sessions to normal levels, if the user doesn't already have a session for those
// Usage:
// mongo <address>:<port>/<database> <script file> -u <username> -p <password>
var levelsDone = 0;
var levelsTotal = 0;
migrateCourseSessionsToNormalLevels();
function migrateCourseSessionsToNormalLevels() {
print("Grabbing all course-* levels...");
var courseLevels = db.levels.find({slug: {$regex: /^course-/}}, {original: 1, version: 1, slug: 1});
levelsTotal = courseLevels.count();
courseLevels.forEach(migrateSessionsForCourseLevel);
}
function migrateSessionsForCourseLevel(courseLevel) {
++levelsDone;
if (courseLevel.slug == 'course-defend-orge') return; // Haha
if (courseLevel.slug == 'course-winding-trail') return; // This one we actually keep the course- version
var heroLevel = db.levels.findOne({slug: courseLevel.slug.replace(/^course-/, '')}, {original: 1, version: 1, slug: 1, name: 1});
if (heroLevel)
print("Got", heroLevel.slug, "for", courseLevel.slug);
else {
print("No matching hero level for", courseLevel.slug);
return;
}
var courseSessions = db.level.sessions.find({levelID: courseLevel.slug});
var sessionsTotal = courseSessions.count();
var sessionsDone = 0;
courseSessions.forEach(function(courseSession) {
var heroSession = db.level.sessions.findOne({
creator: courseSession.creator,
level: {original: heroLevel.original + '', majorVersion: heroLevel.version.major}
});
//print("Found hero session", !!heroSession, "for course level", courseLevel.slug, "for user", courseSession.creatorName, 'looking for hero level', heroLevel.original, heroLevel.version.major);
if (heroSession) return; // Already had one
courseSession.levelID = heroLevel.slug;
courseSession.levelName = heroLevel.name;
courseSession.level = {original: heroLevel.original + '', majorVersion: heroLevel.version.major};
db.level.sessions.save(courseSession);
if (!(++sessionsDone % 100)) {
print("Done", sessionsDone, "/", sessionsTotal, "sessions for", courseLevel.slug, "--", levelsDone, "/", levelsTotal, "levels done.");
}
});
}

View file

@ -0,0 +1,34 @@
# Users can do this on their own on the account settings, so this script is for doing big batches of users.
database = require '../server/commons/database'
mongoose = require 'mongoose'
log = require 'winston'
async = require 'async'
### SET UP ###
do (setupLodash = this) ->
GLOBAL._ = require 'lodash'
_.str = require 'underscore.string'
_.mixin _.str.exports()
GLOBAL.tv4 = require('tv4').tv4
database.connect()
UserHandler = require '../server/users/user_handler'
User = require '../server/users/User'
userIDs = [
# Fill in userID strings here
]
User.find _id: {$in: (mongoose.Types.ObjectId(userID) for userID in userIDs)}, (err, users) ->
if users.length isnt userIDs.length
log.info "Only found #{users.length} users out of #{userIDs.length}. Got this right? Quitting conservatively."
process.exit()
log.info "Starting user progress reset for #{users.length} users..."
#async.parallel ((do(user) -> (cb) -> console.log("should reset progress for user: #{user._id}") or cb null) for user in users), (err) ->
async.parallel (((cb) -> UserHandler.constructor.resetProgressForUser(user, cb)) for user in users), (err) ->
log.error err if err?
log.info 'Finished resetting user accounts.' unless err?
process.exit()

View file

@ -705,15 +705,17 @@ UserHandler = class UserHandler extends Handler
return @sendMethodNotAllowed res unless req.method is 'POST'
return @sendForbiddenError res unless userID and userID is req.user?._id + '' # Only you can reset your own progress
return @sendForbiddenError res if req.user?.isAdmin() # Protect admins from resetting their progress
async.parallel [
(cb) -> LevelSession.remove {creator: req.user._id + ''}, cb
(cb) -> EarnedAchievement.remove {user: req.user._id + ''}, cb
(cb) -> UserPollsRecord.remove {user: req.user._id + ''}, cb
(cb) -> req.user.update {points: 0, 'stats.gamesCompleted': 0, 'stats.concepts': {}, 'earned.gems': 0, 'earned.levels': [], 'earned.items': [], 'earned.heroes': [], 'purchased.items': [], 'purchased.heroes': [], spent: 0}, cb
], (err, results) =>
@resetProgressForUser req.user, (err, results) =>
return @sendDatabaseError res, err if err
@sendSuccess res, result: 'success'
resetProgressForUser: (user, cb) ->
async.parallel [
(cb) -> LevelSession.remove {creator: user._id + ''}, cb
(cb) -> EarnedAchievement.remove {user: user._id + ''}, cb
(cb) -> UserPollsRecord.remove {user: user._id + ''}, cb
(cb) -> user.update {points: 0, 'stats.gamesCompleted': 0, 'stats.concepts': {}, 'earned.gems': 0, 'earned.levels': [], 'earned.items': [], 'earned.heroes': [], 'purchased.items': [], 'purchased.heroes': [], spent: 0}, cb
], cb
countEdits = (model, done) ->
statKey = User.statsMapping.edits[model.modelName]