Compare commits

..

1 Commits

Author SHA1 Message Date
Sabe Jones
2d61b81cbe 4.13.0 2017-12-05 19:27:50 +00:00
3393 changed files with 88551 additions and 151373 deletions

View File

@@ -1,6 +1,10 @@
{
"presets": ["es2015"],
"plugins": [
"transform-es2015-modules-commonjs",
"syntax-object-rest-spread",
"transform-object-rest-spread",
["transform-async-to-module-method", {
"module": "bluebird",
"method": "coroutine"
}]
]
}

View File

@@ -10,5 +10,12 @@ apidoc_build/
content_cache/
node_modules/
# Old migrations, disabled
migrations/archive/*
# Not linted
website/client-old/
test/client-old/spec/**/*
# Temporarilly disabled. These should be removed when the linting errors are fixed TODO
migrations/*
scripts/*
website/common/browserify.js
Gruntfile.js

View File

@@ -1,7 +1,7 @@
[//]: # (Note: See http://habitica.wikia.com/wiki/Using_Your_Local_Install_to_Modify_Habitica%27s_Website_and_API for more info)
[//]: # (Put Issue # here, if applicable. This will automatically close the issue if your PR is merged in)
Fixes put_#_and_issue_numer_here
[//]: # (Put Issue # or URL here, if applicable. This will automatically close the issue if your PR is merged in)
Fixes put_issue_url_here
### Changes
[//]: # (Describe the changes that were made in detail here. Include pictures if necessary)

1
.gitignore vendored
View File

@@ -39,7 +39,6 @@ dist-client
test/client/unit/coverage
test/client/e2e/reports
test/client-old/spec/mocks/translations.js
yarn.lock
# Elastic Beanstalk Files
.elasticbeanstalk/*

View File

@@ -4,7 +4,6 @@ node_modules/**
.bower-registry/**
website/client-old/**
website/client/**
website/client/store/**
website/views/**
website/build/**
dist/**
@@ -17,4 +16,3 @@ CHANGELOG.md
newrelic_agent.log
*.swp
*.swx
website/raw_sprites/**

2
.nvmrc
View File

@@ -1 +1 @@
10
6

View File

@@ -1,30 +1,37 @@
language: node_js
node_js:
- '10'
- '6'
sudo: required
dist: precise
services:
- mongodb
cache:
directories:
- 'node_modules'
addons:
chrome: stable
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
before_install:
- $CXX --version
- npm install -g npm@5
- if [ $REQUIRES_SERVER ]; then sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10; echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list; sudo apt-get update; sudo apt-get install mongodb-org-server; fi
install:
- npm install &> npm.install.log || (cat npm.install.log; false)
before_script:
- npm run test:build
- cp config.json.example config.json
- sleep 5
- sleep 15
script:
- npm run $TEST
- if [ $COVERAGE ]; then ./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js; fi
env:
global:
- CXX=g++-4.8
- DISABLE_REQUEST_LOGGING=true
matrix:
- TEST="lint"
- TEST="test:api:unit" REQUIRES_SERVER=true COVERAGE=true
- TEST="test:api-v3:integration" REQUIRES_SERVER=true COVERAGE=true
- TEST="test:api-v4:integration" REQUIRES_SERVER=true COVERAGE=true
- TEST="test:api-v3" REQUIRES_SERVER=true COVERAGE=true
- TEST="test:sanity"
- TEST="test:content" COVERAGE=true
- TEST="test:common" COVERAGE=true
- TEST="client:unit" COVERAGE=true
- TEST="apidoc"

View File

@@ -1,29 +1,21 @@
FROM node:10
ENV ADMIN_EMAIL admin@habitica.com
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
ENV AMAZON_PAYMENTS_SELLER_ID AMQ3SB4SG5E91
ENV AMPLITUDE_KEY e8d4c24b3d6ef3ee73eeba715023dd43
ENV BASE_URL https://habitica.com
ENV FACEBOOK_KEY 128307497299777
ENV GA_ID UA-33510635-1
ENV GOOGLE_CLIENT_ID 1035232791481-32vtplgnjnd1aufv3mcu1lthf31795fq.apps.googleusercontent.com
ENV NODE_ENV production
ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
# Install global packages
RUN npm install -g gulp-cli mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
WORKDIR /usr/src/habitrpg
RUN git clone --branch release https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN npm install
RUN gulp build:prod --force
# Create Build dir
RUN mkdir -p ./website/build
# Start Habitica
EXPOSE 3000
CMD ["node", "./website/transpiled-babel/index.js"]
FROM node:boron
# Upgrade NPM to v5 (Yarn is needed because of this bug https://github.com/npm/npm/issues/16807)
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
RUN yarn global add npm@5
# Install global packages
RUN npm install -g gulp mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
WORKDIR /usr/src/habitrpg
RUN git clone https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN cp config.json.example config.json
RUN npm install
# Create Build dir
RUN mkdir -p ./website/build
# Start Habitica
EXPOSE 3000
CMD ["npm", "start"]

View File

@@ -1,18 +0,0 @@
FROM node:10
# Install global packages
RUN npm install -g gulp-cli mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
WORKDIR /usr/src/habitrpg
RUN git clone https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN cp config.json.example config.json
RUN npm install
# Create Build dir
RUN mkdir -p ./website/build
# Start Habitica
EXPOSE 3000
CMD ["npm", "start"]

32
Dockerfile-Production Normal file
View File

@@ -0,0 +1,32 @@
FROM node:boron
ENV ADMIN_EMAIL admin@habitica.com
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
ENV AMAZON_PAYMENTS_SELLER_ID AMQ3SB4SG5E91
ENV AMPLITUDE_KEY e8d4c24b3d6ef3ee73eeba715023dd43
ENV BASE_URL https://habitica.com
ENV FACEBOOK_KEY 128307497299777
ENV GA_ID UA-33510635-1
ENV GOOGLE_CLIENT_ID 1035232791481-32vtplgnjnd1aufv3mcu1lthf31795fq.apps.googleusercontent.com
ENV NODE_ENV production
ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
# Upgrade NPM to v5 (Yarn is needed because of this bug https://github.com/npm/npm/issues/16807)
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
RUN yarn global add npm@5
# Install global packages
RUN npm install -g gulp mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
WORKDIR /usr/src/habitrpg
RUN git clone --branch v4.11.0 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN npm install
RUN gulp build:prod --force
# Create Build dir
RUN mkdir -p ./website/build
# Start Habitica
EXPOSE 3000
CMD ["node", "./website/transpiled-babel/index.js"]

View File

@@ -1,8 +1,6 @@
Habitica [![Build Status](https://travis-ci.org/HabitRPG/habitica.svg?branch=develop)](https://travis-ci.org/HabitRPG/habitica) [![Code Climate](https://codeclimate.com/github/HabitRPG/habitrpg.svg)](https://codeclimate.com/github/HabitRPG/habitrpg) [![Coverage Status](https://coveralls.io/repos/github/HabitRPG/habitica/badge.svg?branch=develop)](https://coveralls.io/github/HabitRPG/habitica?branch=develop) [![Bountysource](https://api.bountysource.com/badge/tracker?tracker_id=68393)](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Open Source Helpers](https://www.codetriage.com/habitrpg/habitica/badges/users.svg)](https://www.codetriage.com/habitrpg/habitica)
Habitica [![Build Status](https://travis-ci.org/HabitRPG/habitica.svg?branch=develop)](https://travis-ci.org/HabitRPG/habitica) [![Code Climate](https://codeclimate.com/github/HabitRPG/habitrpg.svg)](https://codeclimate.com/github/HabitRPG/habitrpg) [![Coverage Status](https://coveralls.io/repos/github/HabitRPG/habitica/badge.svg?branch=develop)](https://coveralls.io/github/HabitRPG/habitica?branch=develop) [![Bountysource](https://api.bountysource.com/badge/tracker?tracker_id=68393)](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE)
===============
[![Greenkeeper badge](https://badges.greenkeeper.io/HabitRPG/habitica.svg)](https://greenkeeper.io/)
[Habitica](https://habitica.com) is an open source habit building program which treats your life like a Role Playing Game. Level up as you succeed, lose HP as you fail, earn money to buy weapons and armor.
We need more programmers! Your assistance will be greatly appreciated.
@@ -10,3 +8,4 @@ We need more programmers! Your assistance will be greatly appreciated.
For an introduction to the technologies used and how the software is organized, refer to [Guidance for Blacksmiths](http://habitica.wikia.com/wiki/Guidance_for_Blacksmiths).
To set up a local install of Habitica for development and testing on various platforms, see [Setting up Habitica Locally](http://habitica.wikia.com/wiki/Setting_up_Habitica_Locally).

View File

@@ -16,7 +16,5 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.hostname = "habitrpg"
config.vm.network "forwarded_port", guest: 3000, host: 3000, auto_correct: true
config.vm.usable_port_range = (3000..3050)
config.vm.network "forwarded_port", guest: 8080, host: 8080, auto_correct: true
config.vm.usable_port_range = (8080..8130)
config.vm.provision :shell, :path => "vagrant_scripts/vagrant.sh"
end

View File

@@ -1,81 +1,106 @@
{
"ADMIN_EMAIL": "you@example.com",
"AMAZON_PAYMENTS_CLIENT_ID": "CLIENT_ID",
"AMAZON_PAYMENTS_MODE": "sandbox",
"AMAZON_PAYMENTS_MWS_KEY": "MWS_KEY",
"AMAZON_PAYMENTS_MWS_SECRET": "MWS_SECRET",
"AMAZON_PAYMENTS_SELLER_ID": "SELLER_ID",
"AMPLITUDE_KEY": "AMPLITUDE_KEY",
"AMPLITUDE_SECRET": "AMPLITUDE_SECRET",
"BASE_URL": "http://localhost:3000",
"CRON_SAFE_MODE": "false",
"CRON_SEMI_SAFE_MODE": "false",
"DISABLE_REQUEST_LOGGING": "true",
"EMAILS_COMMUNITY_MANAGER_EMAIL": "admin@habitica.com",
"EMAILS_PRESS_ENQUIRY_EMAIL": "admin@habitica.com",
"EMAILS_TECH_ASSISTANCE_EMAIL": "admin@habitica.com",
"EMAIL_SERVER_AUTH_PASSWORD": "password",
"EMAIL_SERVER_AUTH_USER": "user",
"EMAIL_SERVER_URL": "http://example.com",
"ENABLE_CONSOLE_LOGS_IN_PROD": "false",
"ENABLE_CONSOLE_LOGS_IN_TEST": "false",
"FACEBOOK_KEY": "123456789012345",
"FACEBOOK_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"FLAG_REPORT_EMAIL": "email@example.com, email2@example.com",
"GA_ID": "GA_ID",
"GOOGLE_CLIENT_ID": "123456789012345",
"GOOGLE_CLIENT_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"IAP_GOOGLE_KEYDIR": "/path/to/google/public/key/dir/",
"IGNORE_REDIRECT": "true",
"ITUNES_SHARED_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"LOGGLY_CLIENT_TOKEN": "token",
"LOGGLY_SUBDOMAIN": "example-subdomain",
"LOGGLY_TOKEN": "example-token",
"MAINTENANCE_MODE": "false",
"NODE_DB_URI": "mongodb://localhost/habitrpg",
"NODE_ENV": "development",
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
"PAYPAL_BILLING_PLANS_basic_12mo": "basic_12mo",
"PAYPAL_BILLING_PLANS_basic_3mo": "basic_3mo",
"PAYPAL_BILLING_PLANS_basic_6mo": "basic_6mo",
"PAYPAL_BILLING_PLANS_basic_earned": "basic_earned",
"PAYPAL_BILLING_PLANS_google_6mo": "google_6mo",
"PAYPAL_CLIENT_ID": "client_id",
"PAYPAL_CLIENT_SECRET": "client_secret",
"PAYPAL_EXPERIENCE_PROFILE_ID": "xp_profile_id",
"PAYPAL_MODE": "sandbox",
"PLAY_API_ACCESS_TOKEN": "aaaabbbbccccddddeeeeffff00001111",
"PLAY_API_CLIENT_ID": "aaaabbbbccccddddeeeeffff00001111",
"PLAY_API_CLIENT_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"PLAY_API_REFRESH_TOKEN": "aaaabbbbccccddddeeeeffff00001111",
"PORT": 3000,
"PUSH_CONFIGS_APN_ENABLED": "false",
"PUSH_CONFIGS_APN_KEY": "xxxxxxxxxx",
"PUSH_CONFIGS_APN_KEY_ID": "xxxxxxxxxx",
"PUSH_CONFIGS_APN_TEAM_ID": "aaabbbcccd",
"PUSH_CONFIGS_FCM_SERVER_API_KEY": "aaabbbcccd",
"S3_ACCESS_KEY_ID": "accessKeyId",
"S3_BUCKET": "bucket",
"S3_SECRET_ACCESS_KEY": "secretAccessKey",
"SESSION_SECRET": "YOUR SECRET HERE",
"SESSION_SECRET_IV": "12345678912345678912345678912345",
"SESSION_SECRET_KEY": "1234567891234567891234567891234567891234567891234567891234567891",
"SITE_HTTP_AUTH_ENABLED": "false",
"SITE_HTTP_AUTH_PASSWORD": "password",
"SITE_HTTP_AUTH_USERNAME": "admin",
"SLACK_FLAGGING_FOOTER_LINK": "https://habitrpg.github.io/flag-o-rama/",
"SLACK_FLAGGING_URL": "https://hooks.slack.com/services/id/id/id",
"SLACK_SUBSCRIPTIONS_URL": "https://hooks.slack.com/services/id/id/id",
"SLACK_URL": "https://hooks.slack.com/services/some-url",
"SMTP_HOST": "example.com",
"SMTP_PASS": "password",
"SMTP_PORT": 587,
"SMTP_SERVICE": "Gmail",
"SMTP_TLS": "true",
"SMTP_USER": "user@example.com",
"STRIPE_API_KEY": "aaaabbbbccccddddeeeeffff00001111",
"STRIPE_PUB_KEY": "22223333444455556666777788889999",
"TEST_DB_URI": "mongodb://localhost/habitrpg_test",
"TRANSIFEX_SLACK_CHANNEL": "transifex",
"WEB_CONCURRENCY": 1
"PORT":3000,
"ENABLE_CONSOLE_LOGS_IN_PROD":"false",
"IP":"0.0.0.0",
"WEB_CONCURRENCY":1,
"BASE_URL":"http://localhost:3000",
"FACEBOOK_KEY":"123456789012345",
"FACEBOOK_SECRET":"aaaabbbbccccddddeeeeffff00001111",
"GOOGLE_CLIENT_ID":"123456789012345",
"GOOGLE_CLIENT_SECRET":"aaaabbbbccccddddeeeeffff00001111",
"PLAY_API": {
"CLIENT_ID": "aaaabbbbccccddddeeeeffff00001111",
"CLIENT_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"ACCESS_TOKEN":"aaaabbbbccccddddeeeeffff00001111",
"REFRESH_TOKEN":"aaaabbbbccccddddeeeeffff00001111"
},
"NODE_DB_URI":"mongodb://localhost/habitrpg",
"TEST_DB_URI":"mongodb://localhost/habitrpg_test",
"NODE_ENV":"development",
"ENABLE_CONSOLE_LOGS_IN_TEST": false,
"CRON_SAFE_MODE":"false",
"CRON_SEMI_SAFE_MODE":"false",
"MAINTENANCE_MODE": "false",
"SESSION_SECRET":"YOUR SECRET HERE",
"ADMIN_EMAIL": "you@example.com",
"SMTP_USER":"user@example.com",
"SMTP_PASS":"password",
"SMTP_SERVICE":"Gmail",
"SMTP_HOST":"example.com",
"SMTP_PORT": 587,
"SMTP_TLS": true,
"STRIPE_API_KEY":"aaaabbbbccccddddeeeeffff00001111",
"STRIPE_PUB_KEY":"22223333444455556666777788889999",
"NEW_RELIC_LICENSE_KEY":"NEW_RELIC_LICENSE_KEY",
"NEW_RELIC_NO_CONFIG_FILE":"true",
"NEW_RELIC_APPLICATION_ID":"NEW_RELIC_APPLICATION_ID",
"NEW_RELIC_API_KEY":"NEW_RELIC_API_KEY",
"GA_ID": "GA_ID",
"AMPLITUDE_KEY": "AMPLITUDE_KEY",
"AMAZON_PAYMENTS": {
"SELLER_ID": "SELLER_ID",
"CLIENT_ID": "CLIENT_ID",
"MWS_KEY": "",
"MWS_SECRET": ""
},
"FLAG_REPORT_EMAIL": "email@mod.com,email2@mod.com",
"EMAIL_SERVER": {
"url": "http://example.com",
"authUser": "user",
"authPassword": "password"
},
"S3":{
"bucket":"bucket",
"accessKeyId":"accessKeyId",
"secretAccessKey":"secretAccessKey"
},
"SLACK_URL": "https://hooks.slack.com/services/some-url",
"TRANSIFEX_SLACK_CHANNEL": "transifex",
"PAYPAL":{
"billing_plans": {
"basic_earned":"basic_earned",
"basic_3mo":"basic_3mo",
"basic_6mo":"basic_6mo",
"google_6mo":"google_6mo",
"basic_12mo":"basic_12mo"
},
"mode":"sandbox",
"client_id":"client_id",
"client_secret":"client_secret",
"experience_profile_id": ""
},
"IAP_GOOGLE_KEYDIR": "/path/to/google/public/key/dir/",
"LOGGLY_TOKEN": "token",
"LOGGLY_ACCOUNT": "account",
"PUSH_CONFIGS": {
"GCM_SERVER_API_KEY": "",
"APN_ENABLED": "false",
"FCM_SERVER_API_KEY": ""
},
"SITE_HTTP_AUTH": {
"ENABLED": "false",
"USERNAME": "admin",
"PASSWORD": "password"
},
"PUSHER": {
"ENABLED": "false",
"APP_ID": "appId",
"KEY": "key",
"SECRET": "secret"
},
"SLACK": {
"FLAGGING_URL": "https://hooks.slack.com/services/id/id/id",
"FLAGGING_FOOTER_LINK": "https://habitrpg.github.io/flag-o-rama/",
"SUBSCRIPTIONS_URL": "https://hooks.slack.com/services/id/id/id"
},
"ITUNES_SHARED_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"EMAILS" : {
"COMMUNITY_MANAGER_EMAIL" : "leslie@habitica.com",
"TECH_ASSISTANCE_EMAIL" : "admin@habitica.com",
"PRESS_ENQUIRY_EMAIL" : "leslie@habitica.com"
},
"LOGGLY" : {
"TOKEN" : "example-token",
"SUBDOMAIN" : "exmaple-subdomain"
}
}

View File

@@ -1,100 +0,0 @@
import max from 'lodash/max';
import mean from 'lodash/mean';
import monk from 'monk';
import round from 'lodash/round';
import sum from 'lodash/sum';
/*
* Output data on subscribers' task histories, formatted for CSV.
* User ID,Count of Dailies,Count of Habits,Total History Size,Max History Size,Mean History Size,Median History Size
*/
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
let dbUsers = monk(connectionString).get('users', { castIds: false });
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
function usersReport () {
let allHistoryLengths = [];
console.info('User ID,Count of Dailies,Count of Habits,Total History Size,Max History Size,Mean History Size,Median History Size');
dbUsers.find(
{
$and:
[
{'purchased.plan.planId': {$ne:null}},
{'purchased.plan.planId': {$ne:''}},
],
$or:
[
{'purchased.plan.dateTerminated': null},
{'purchased.plan.dateTerminated': ''},
{'purchased.plan.dateTerminated': {$gt:new Date()}},
],
},
{
fields: {_id: 1},
}
).each((user, {close, pause, resume}) => {
let historyLengths = [];
let habitCount = 0;
let dailyCount = 0;
pause();
return dbTasks.find(
{
userId: user._id,
$or:
[
{type: 'habit'},
{type: 'daily'},
],
},
{
fields: {
type: 1,
history: 1,
},
}
).each((task) => {
if (task.type === 'habit') {
habitCount++;
}
if (task.type === 'daily') {
dailyCount++;
}
if (task.history.length > 0) {
allHistoryLengths.push(task.history.length);
historyLengths.push(task.history.length);
}
}).then(() => {
const totalHistory = sum(historyLengths);
const maxHistory = historyLengths.length > 0 ? max(historyLengths) : 0;
const meanHistory = historyLengths.length > 0 ? round(mean(historyLengths)) : 0;
const medianHistory = historyLengths.length > 0 ? median(historyLengths) : 0;
console.info(`${user._id},${dailyCount},${habitCount},${totalHistory},${maxHistory},${meanHistory},${medianHistory}`);
resume();
});
}).then(() => {
console.info(`Total Subscriber History Entries: ${sum(allHistoryLengths)}`);
console.info(`Largest History Size: ${max(allHistoryLengths)}`);
console.info(`Mean History Size: ${round(mean(allHistoryLengths))}`);
console.info(`Median History Size: ${median(allHistoryLengths)}`);
return process.exit(0);
});
}
function median(values) { // https://gist.github.com/caseyjustus/1166258
values.sort( function(a,b) {return a - b;} );
var half = Math.floor(values.length/2);
if (values.length % 2) {
return values[half];
}
else {
return (values[half-1] + values[half]) / 2.0;
}
}
module.exports = usersReport;

View File

@@ -1,48 +0,0 @@
import monk from 'monk';
import nconf from 'nconf';
/*
* Output data on users who completed all the To-Do tasks in the 2018 Back-to-School Challenge.
* User ID,Profile Name
*/
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
const CHALLENGE_ID = '0acb1d56-1660-41a4-af80-9259f080b62b';
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
let dbTasks = monk(CONNECTION_STRING).get('tasks', { castIds: false });
function usersReport() {
console.info('User ID,Profile Name');
let userCount = 0;
dbUsers.find(
{challenges: CHALLENGE_ID},
{fields:
{_id: 1, 'profile.name': 1}
},
).each((user, {close, pause, resume}) => {
pause();
userCount++;
let completedTodos = 0;
return dbTasks.find(
{
userId: user._id,
'challenge.id': CHALLENGE_ID,
type: 'todo',
},
{fields: {completed: 1}}
).each((task) => {
if (task.completed) completedTodos++;
}).then(() => {
if (completedTodos >= 7) {
console.info(`${user._id},${user.profile.name}`);
}
resume();
});
}).then(() => {
console.info(`${userCount} users reviewed`);
return process.exit(0);
});
}
module.exports = usersReport;

View File

@@ -1,14 +1,3 @@
version: "3"
services:
client:
environment:
- NODE_ENV=development
volumes:
- '.:/usr/src/habitrpg'
server:
environment:
- NODE_ENV=development
volumes:
- '.:/usr/src/habitrpg'
web:
volumes:
- '.:/usr/src/habitrpg'

View File

@@ -1,36 +1,13 @@
version: "3"
services:
web:
build: .
ports:
- "3000:3000"
links:
- mongo
environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
client:
build: .
networks:
- habitica
environment:
- BASE_URL=http://server:3000
ports:
- "8080:8080"
command: ["npm", "run", "client:dev"]
depends_on:
- server
server:
build: .
ports:
- "3000:3000"
networks:
- habitica
environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
depends_on:
- mongo
mongo:
image: mongo:3.4
ports:
- "27017:27017"
networks:
- habitica
networks:
habitica:
driver: bridge
mongo:
image: mongo
ports:
- "27017:27017"

View File

@@ -8,7 +8,7 @@ gulp.task('apidoc:clean', (done) => {
clean(APIDOC_DEST_PATH, done);
});
gulp.task('apidoc', gulp.series('apidoc:clean', (done) => {
gulp.task('apidoc', ['apidoc:clean'], (done) => {
let result = apidoc.createDoc({
src: APIDOC_SRC_PATH,
dest: APIDOC_DEST_PATH,
@@ -19,8 +19,8 @@ gulp.task('apidoc', gulp.series('apidoc:clean', (done) => {
} else {
done();
}
}));
});
gulp.task('apidoc:watch', gulp.series('apidoc', (done) => {
return gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, gulp.series('apidoc', done));
}));
gulp.task('apidoc:watch', ['apidoc'], () => {
return gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, ['apidoc']);
});

View File

@@ -2,6 +2,12 @@ import gulp from 'gulp';
import babel from 'gulp-babel';
import webpackProductionBuild from '../webpack/build';
gulp.task('build', () => {
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
gulp.start('build:prod');
}
});
gulp.task('build:src', () => {
return gulp.src('website/server/**/*.js')
.pipe(babel())
@@ -14,30 +20,18 @@ gulp.task('build:common', () => {
.pipe(gulp.dest('website/common/transpiled-babel/'));
});
gulp.task('build:server', gulp.series('build:src', 'build:common', done => done()));
gulp.task('build:server', ['build:src', 'build:common']);
// Client Production Build
gulp.task('build:client', (done) => {
webpackProductionBuild((err, output) => {
if (err) return done(err);
console.log(output); // eslint-disable-line no-console
done();
});
});
gulp.task('build:prod', gulp.series(
gulp.task('build:prod', [
'build:server',
'build:client',
'apidoc',
done => done()
));
let buildArgs = [];
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
buildArgs.push('build:prod');
}
gulp.task('build', gulp.series(buildArgs, (done) => {
done();
}));
]);

View File

@@ -1,4 +1,5 @@
import mongoose from 'mongoose';
import autoinc from 'mongoose-id-autoinc';
import logger from '../website/server/libs/logger';
import nconf from 'nconf';
import repl from 'repl';
@@ -24,22 +25,23 @@ let improveRepl = (context) => {
const isProd = nconf.get('NODE_ENV') === 'production';
const mongooseOptions = !isProd ? {} : {
keepAlive: 1,
connectTimeoutMS: 30000,
replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
};
mongoose.connect(
nconf.get('NODE_DB_URI'),
mongooseOptions,
(err) => {
if (err) throw err;
logger.info('Connected with Mongoose');
}
autoinc.init(
mongoose.connect(
nconf.get('NODE_DB_URI'),
mongooseOptions,
(err) => {
if (err) throw err;
logger.info('Connected with Mongoose');
}
)
);
};
gulp.task('console', (done) => {
gulp.task('console', () => {
improveRepl(repl.start({
prompt: 'Habitica > ',
}).context);
done();
});

View File

@@ -7,7 +7,6 @@ import mergeStream from 'merge-stream';
import {basename} from 'path';
import {sync} from 'glob';
import {each} from 'lodash';
import vinylBuffer from 'vinyl-buffer';
// https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248
const MAX_SPRITESHEET_SIZE = 1024 * 1024 * 3;
@@ -105,7 +104,6 @@ function createSpritesStream (name, src) {
}));
let imgStream = spriteData.img
.pipe(vinylBuffer())
.pipe(imagemin())
.pipe(gulp.dest(IMG_DIST_PATH));
@@ -119,6 +117,8 @@ function createSpritesStream (name, src) {
return stream;
}
gulp.task('sprites:compile', ['sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions']);
gulp.task('sprites:main', () => {
let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
return createSpritesStream('main', mainSrc);
@@ -133,7 +133,7 @@ gulp.task('sprites:clean', (done) => {
clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done);
});
gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprites:largeSprites', (done) => {
gulp.task('sprites:checkCompiledDimensions', ['sprites:main', 'sprites:largeSprites'], () => {
console.log('Verifiying that images do not exceed max dimensions'); // eslint-disable-line no-console
let numberOfSheetsThatAreTooBig = 0;
@@ -159,7 +159,4 @@ gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprite
} else {
console.log('All images are within the correct dimensions'); // eslint-disable-line no-console
}
done();
}));
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions', done => done()));
});

View File

@@ -3,7 +3,7 @@ import nodemon from 'gulp-nodemon';
let pkg = require('../package.json');
gulp.task('nodemon', (done) => {
gulp.task('nodemon', () => {
nodemon({
script: pkg.main,
ignore: [
@@ -12,5 +12,4 @@ gulp.task('nodemon', (done) => {
'common/dist/script/content/*',
],
});
done();
});

View File

@@ -4,6 +4,7 @@ import {
import mongoose from 'mongoose';
import { exec } from 'child_process';
import gulp from 'gulp';
import runSequence from 'run-sequence';
import os from 'os';
import nconf from 'nconf';
@@ -38,23 +39,23 @@ let testBin = (string, additionalEnvVariables = '') => {
}
};
gulp.task('test:nodemon', gulp.series(function setupNodemon (done) {
gulp.task('test:nodemon', () => {
process.env.PORT = TEST_SERVER_PORT; // eslint-disable-line no-process-env
process.env.NODE_DB_URI = TEST_DB_URI; // eslint-disable-line no-process-env
done();
}, 'nodemon'));
runSequence('nodemon');
});
gulp.task('test:prepare:mongo', (cb) => {
mongoose.connect(TEST_DB_URI, (err) => {
if (err) return cb(`Unable to connect to mongo database. Are you sure it's running? \n\n${err}`);
mongoose.connection.dropDatabase((err2) => {
if (err2) return cb(err2);
mongoose.connection.close(cb);
});
mongoose.connection.db.dropDatabase();
mongoose.connection.close();
cb();
});
});
gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', (done) => {
gulp.task('test:prepare:server', ['test:prepare:mongo'], () => {
if (!server) {
server = exec(testBin('node ./website/server/index.js', `NODE_DB_URI=${TEST_DB_URI} PORT=${TEST_SERVER_PORT}`), (error, stdout, stderr) => {
if (error) {
@@ -63,18 +64,16 @@ gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', (done) => {
if (stderr) {
console.error(stderr); // eslint-disable-line no-console
}
done();
});
}
}));
});
gulp.task('test:prepare:build', gulp.series('build', done => done()));
gulp.task('test:prepare:build', ['build']);
gulp.task('test:prepare', gulp.series(
gulp.task('test:prepare', [
'test:prepare:build',
'test:prepare:mongo',
done => done()
));
]);
gulp.task('test:sanity', (cb) => {
let runner = exec(
@@ -89,7 +88,7 @@ gulp.task('test:sanity', (cb) => {
pipe(runner);
});
gulp.task('test:common', gulp.series('test:prepare:build', (cb) => {
gulp.task('test:common', ['test:prepare:build'], (cb) => {
let runner = exec(
testBin(COMMON_TEST_COMMAND),
(err) => {
@@ -100,17 +99,17 @@ gulp.task('test:common', gulp.series('test:prepare:build', (cb) => {
}
);
pipe(runner);
}));
});
gulp.task('test:common:clean', (cb) => {
pipe(exec(testBin(COMMON_TEST_COMMAND), () => cb()));
});
gulp.task('test:common:watch', gulp.series('test:common:clean', () => {
return gulp.watch(['common/script/**/*', 'test/common/**/*'], gulp.series('test:common:clean', done => done()));
}));
gulp.task('test:common:watch', ['test:common:clean'], () => {
gulp.watch(['common/script/**/*', 'test/common/**/*'], ['test:common:clean']);
});
gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => {
gulp.task('test:common:safe', ['test:prepare:build'], (cb) => {
let runner = exec(
testBin(COMMON_TEST_COMMAND),
(err, stdout) => { // eslint-disable-line handle-callback-err
@@ -124,9 +123,9 @@ gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => {
}
);
pipe(runner);
}));
});
gulp.task('test:content', gulp.series('test:prepare:build', (cb) => {
gulp.task('test:content', ['test:prepare:build'], (cb) => {
let runner = exec(
testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS,
@@ -138,17 +137,17 @@ gulp.task('test:content', gulp.series('test:prepare:build', (cb) => {
}
);
pipe(runner);
}));
});
gulp.task('test:content:clean', (cb) => {
pipe(exec(testBin(CONTENT_TEST_COMMAND), CONTENT_OPTIONS, () => cb()));
});
gulp.task('test:content:watch', gulp.series('test:content:clean', () => {
return gulp.watch(['common/script/content/**', 'test/**'], gulp.series('test:content:clean', done => done()));
}));
gulp.task('test:content:watch', ['test:content:clean'], () => {
gulp.watch(['common/script/content/**', 'test/**'], ['test:content:clean']);
});
gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
gulp.task('test:content:safe', ['test:prepare:build'], (cb) => {
let runner = exec(
testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS,
@@ -163,11 +162,11 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
}
);
pipe(runner);
}));
});
gulp.task('test:api:unit', (done) => {
gulp.task('test:api-v3:unit', (done) => {
let runner = exec(
testBin('istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-unit --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/unit --recursive --require ./test/helpers/start-server'),
(err) => {
if (err) {
process.exit(1);
@@ -179,13 +178,13 @@ gulp.task('test:api:unit', (done) => {
pipe(runner);
});
gulp.task('test:api:unit:watch', () => {
return gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done()));
gulp.task('test:api-v3:unit:watch', () => {
gulp.watch(['website/server/libs/*', 'test/api/v3/unit/**/*', 'website/server/controllers/**/*'], ['test:api-v3:unit']);
});
gulp.task('test:api-v3:integration', (done) => {
let runner = exec(
testBin('istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
{maxBuffer: 500 * 1024},
(err) => {
if (err) {
@@ -199,10 +198,8 @@ gulp.task('test:api-v3:integration', (done) => {
});
gulp.task('test:api-v3:integration:watch', () => {
return gulp.watch([
'website/server/controllers/api-v3/**/*', 'common/script/ops/*', 'website/server/libs/*.js',
'test/api/v3/integration/**/*',
], gulp.series('test:api-v3:integration', done => done()));
gulp.watch(['website/server/controllers/api-v3/**/*', 'common/script/ops/*', 'website/server/libs/*.js',
'test/api/v3/integration/**/*'], ['test:api-v3:integration']);
});
gulp.task('test:api-v3:integration:separate-server', (done) => {
@@ -215,43 +212,21 @@ gulp.task('test:api-v3:integration:separate-server', (done) => {
pipe(runner);
});
gulp.task('test:api-v4:integration', (done) => {
let runner = exec(
testBin('istanbul cover --dir coverage/api-v4-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
{maxBuffer: 500 * 1024},
(err) => {
if (err) {
process.exit(1);
}
done();
}
gulp.task('test', (done) => {
runSequence(
'test:sanity',
'test:content',
'test:common',
'test:api-v3:unit',
'test:api-v3:integration',
done
);
pipe(runner);
});
gulp.task('test:api-v4:integration:separate-server', (done) => {
let runner = exec(
testBin('mocha test/api/v4 --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
{maxBuffer: 500 * 1024},
(err) => done(err)
gulp.task('test:api-v3', (done) => {
runSequence(
'test:api-v3:unit',
'test:api-v3:integration',
done
);
pipe(runner);
});
gulp.task('test', gulp.series(
'test:sanity',
'test:content',
'test:common',
'test:api:unit',
'test:api-v3:integration',
'test:api-v4:integration',
done => done()
));
gulp.task('test:api-v3', gulp.series(
'test:api:unit',
'test:api-v3:integration',
done => done()
));

View File

@@ -93,7 +93,9 @@ const malformedStringExceptions = {
feedPet: true,
};
gulp.task('transifex:missingFiles', (done) => {
gulp.task('transifex', ['transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings']);
gulp.task('transifex:missingFiles', () => {
let missingStrings = [];
eachTranslationFile(ALL_LANGUAGES, (error) => {
@@ -107,10 +109,9 @@ gulp.task('transifex:missingFiles', (done) => {
let formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:missingStrings', (done) => {
gulp.task('transifex:missingStrings', () => {
let missingStrings = [];
eachTranslationString(ALL_LANGUAGES, (language, filename, key, englishString, translationString) => {
@@ -125,10 +126,9 @@ gulp.task('transifex:missingStrings', (done) => {
let formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:malformedStrings', (done) => {
gulp.task('transifex:malformedStrings', () => {
let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
let interpolationRegex = /<%= [a-zA-Z]* %>/g;
let stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex);
@@ -170,11 +170,4 @@ gulp.task('transifex:malformedStrings', (done) => {
let formattedMessage = formatMessageForPosting(message, stringsWithIncorrectNumberOfInterpolations);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task(
'transifex',
gulp.series('transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings'),
(done) => done()
);

View File

@@ -2,6 +2,7 @@ import { exec } from 'child_process';
import psTree from 'ps-tree';
import nconf from 'nconf';
import net from 'net';
import Bluebird from 'bluebird';
import { post } from 'superagent';
import { sync as glob } from 'glob';
import Mocha from 'mocha';
@@ -44,7 +45,7 @@ export function kill (proc) {
* before failing.
*/
export function awaitPort (port, max = 60) {
return new Promise((rej, res) => {
return new Bluebird((rej, res) => {
let socket;
let timeout;
let interval;

View File

@@ -8,12 +8,10 @@
require('babel-register');
const gulp = require('gulp');
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
require('./gulp/gulp-build'); // eslint-disable-line global-require
} else {
require('glob').sync('./gulp/gulp-*').forEach(require); // eslint-disable-line global-require
require('gulp').task('default', gulp.series('test')); // eslint-disable-line global-require
require('gulp').task('default', ['test']); // eslint-disable-line global-require
}

View File

@@ -1,7 +0,0 @@
{
"root": false,
"rules": {
"no-console": 0,
"no-use-before-define": ["error", { "functions": false }]
}
}

View File

@@ -0,0 +1,5 @@
db.users.update(
{ lastCron: { $exists: false} },
{ $set: { lastCron: +new Date } },
{ multi: true }
);

View File

@@ -0,0 +1,15 @@
db.users.find({ completedIds: { $exists: true } }).forEach(function(user) {
var newTodoIds = user.todoIds;
user.completedIds.forEach(function(value) {
if (newTodoIds.indexOf(value) === -1) {
newTodoIds.push(value)
}
});
db.users.update(
{ _id: user._id },
{
$set: { todoIds: newTodoIds },
$unset: { completedIds: 1 }
}
);
});

View File

@@ -0,0 +1,5 @@
db.users.update(
{preferences:{$exists:false}},
{$set:{preferences:{gender: 'm', armorSet: 'v1'}}},
{multi:true}
)

View File

@@ -7,14 +7,14 @@
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
let habits = 0,
dailies = 0,
todos = 0,
registered = { $or: [{ 'auth.local': { $exists: true } }, { 'auth.facebook': { $exists: true} }]};
var habits = 0,
dailies = 0,
todos = 0,
registered = { $or: [ { 'auth.local': { $exists: true } }, { 'auth.facebook': { $exists: true} } ]};
db.user.find(registered).forEach(function (u) {
// TODO this isn't working??
habits += _.where(u.tasks, {type: 'habit'}).length;
dailies += _.where(u.tasks, {type: 'daily'}).length;
todos += _.where(u.tasks, {type: 'todo'}).length;
});
db.user.find(registered).forEach(function(u){
//TODO this isn't working??
habits += _.where(u.tasks, {type:'habit'}).length;
dailies += _.where(u.tasks, {type:'daily'}).length;
todos += _.where(u.tasks, {type:'todo'}).length;
})

View File

@@ -0,0 +1,102 @@
// %mongo server:27017/dbname underscore.js my_commands.js
// %mongo server:27017/dbname underscore.js --shell
//db.users.find({'auth.facebook.email': 'tylerrenelle@gmail.com'}).forEach(function(user){
db.users.find().forEach(function(user){
if (!user._id) {
print("User has null _id");
return; // need to figure out how to delete these buggers if they don't have an id to delete from
}
if (!!user.idLists) {
print("User " + user._id + " has already been migrated")
return
}
if (user._id.indexOf("$") === 0) {
print("User id starts with $ (" + user._id + ")")
return;
}
// even though we're clobbering user later, sometimes these are undefined and crash the script
// this saves us some ternaries
user.stats = user.stats || {};
user.items = user.items || {};
user.preferences = user.preferences || {};
user.notifications = user.notifications || {};
user.flags = user.flags || {};
user.habitIds = user.habitIds || [];
user.dailyIds = user.dailyIds || [];
user.todoIds = user.todoIds || [];
user.rewardIds = user.rewardIds|| [];
_.each(user.tasks, function(task, key){
if (!task.type) {
delete user.tasks[key];
// idList will take care of itself on page-load
return
}
if (key == '$spec') {
print("$spec was found: " + user._id);
return
}
if (key.indexOf("$_") === 0) {
var newKey = key.replace("$_", ''),
index = user[task.type + "Ids"].indexOf(key)
user[task.type + "Ids"][index] = newKey;
task.id = newKey
user.tasks[newKey] = task
// TODO make sure this is ok, that we're not deleting the original
// Otherwise use lodash.cloneDeep
delete user.tasks[key]
}
});
// New user schema has public and private paths, so we can setup proper access control with racer
// Note 'public' and 'private' are reserved words
var newUser = {
auth: user.auth, // we need this top-level due to derby-auth
apiToken: user.preferences.api_token || null, // set on update, we need derby.uuid()
preferences: {
armorSet: user.preferences.armorSet || 'v1',
gender: user.preferences.gender || 'm'
},
balance: user.balance || 2,
lastCron: user.lastCron || +new Date,
history: user.history || [],
stats: {
gp: user.stats.money || 0,
hp: user.stats.hp || 50,
exp: user.stats.exp || 0,
lvl: user.stats.lvl || 1
},
items: {
armor: user.items.armor || 0,
weapon: user.items.weapon || 0
},
tasks: user.tasks || {},
idLists: {
habit: user.habitIds || [],
daily: user.dailyIds || [],
todo: user.todoIds || [],
reward: user.rewardIds || []
},
flags: {
partyEnabled: false,
itemsEnabled: user.items.itemsEnabled || false,
kickstarter: user.notifications.kickstarter || 'show',
ads: user.flags.ads || null // null because it's set on registration
},
party: {
current: null,
invitation: null
}
};
try {
db.users.update({_id:user._id}, newUser);
} catch(e) {
print(e);
}
})

View File

@@ -0,0 +1,19 @@
// move idList back to root-level, is what's causing the sort bug - see https://github.com/codeparty/racer/pull/73
// We could just delete user.idLists, since it's re-created on refresh. However, users's first refresh will scare them
// since everything will dissappear - second refresh will bring everything back.
db.users.find().forEach(function(user){
if (!user.idLists) return;
db.users.update(
{_id:user._id},
{
$set:{
'habitIds':user.idLists.habit,
'dailyIds':user.idLists.daily,
'todoIds':user.idLists.todo,
'rewardIds':user.idLists.reward
}
//$unset:{idLists:true} // run this after the code has been pushed
}
)
})

View File

@@ -0,0 +1,20 @@
db.users.update(
{items:{$exists:0}},
{$set:{items:{weapon: 0, armor: 0, head: 0, shield: 0 }}},
{multi:true}
);
db.users.find().forEach(function(user){
var updates = {
// I'm not racist, these were just the defaults before ;)
'preferences.skin': 'white',
'preferences.hair': 'blond',
'items.head': user.items.armor,
'items.shield': user.items.armor,
}
db.users.update({_id:user._id}, {$set:updates});
})

View File

@@ -0,0 +1,39 @@
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130307_normalize_algo_values.js
/**
* Make sure people aren't overflowing their exp with the new system
*/
db.users.find().forEach(function(user){
function oldTnl(level) {
return (Math.pow(level,2)*10)+(level*10)+80
}
function newTnl(level) {
var value = 0;
if (level >= 100) {
value = 0
} else {
value = Math.round(((Math.pow(level,2)*0.25)+(10 * level) + 139.75)/10)*10; // round to nearest 10
}
return value
}
var newTnl = newTnl(user.stats.lvl);
if (user.stats.exp > newTnl) {
var percent = user.stats.exp / oldTnl(user.stats.lvl);
percent = (percent>1) ? 1 : percent;
user.stats.exp = newTnl * percent;
try {
db.users.update(
{_id:user._id},
{$set: {'stats.exp': user.stats.exp}},
{multi:true}
);
} catch(e) {
print(e);
}
}
})

View File

@@ -0,0 +1,47 @@
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130307_normalize_algo_values.js
/**
* Users were experiencing a lot of extreme Exp multiplication (https://github.com/lefnire/habitrpg/issues/594).
* This sets things straight, and in preparation for another algorithm overhaul
*/
db.users.find().forEach(function(user){
if (user.stats.exp >= 3580) {
user.stats.exp = 0;
}
if (user.stats.lvl > 100) {
user.stats.lvl = 100;
}
_.each(user.tasks, function(task, key){
// remove corrupt tasks
if (!task) {
delete user.tasks[key];
return;
}
// Fix busted values
if (task.value > 21.27) {
task.value = 21.27;
}
else if (task.value < -47.27) {
task.value = -47.27;
}
});
try {
db.users.update(
{_id:user._id},
{$set:
{
'stats.lvl': user.stats.lvl,
'stats.exp': user.stats.exp,
'tasks' : user.tasks
}
},
{multi:true}
);
} catch(e) {
print(e);
}
})

View File

@@ -0,0 +1,28 @@
/**
* Remove duff histories for dailies
*/
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130307_remove_duff_histories.js
db.users.find().forEach(function(user){
_.each(user.tasks, function(task, key){
if (task.type === "daily") {
// remove busted history entries
task.history = _.filter(task.history, function(h){return !!h.value})
}
});
try {
db.users.update(
{_id:user._id},
{$set:
{
'tasks' : user.tasks
}
},
{multi:true}
);
} catch(e) {
print(e);
}
})

View File

@@ -0,0 +1,98 @@
/**
* Migrate old pets to new system
*/
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130326_migrate_pets.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mapping = {
bearcub: {name:'BearCub', modifier: 'Base'},
cactus: {name:'Cactus', modifier:'Base'},
dragon: {name:'Dragon', modifier:'Base'},
flyingpig: {name:'FlyingPig', modifier:'Base'},
fox: {name:'Fox', modifier:'Base'},
lioncub: {name:'LionCub', modifier:'Base'},
pandacub: {name:'PandaCub', modifier:'Base'},
tigercub: {name:'TigerCub', modifier:'Base'},
wolfBorder: {name:'Wolf', modifier:'Base'},
wolfDesert: {name:'Wolf', modifier:'Desert'},
wolfGolden: {name:'Wolf', modifier:'Golden'},
wolfRed: {name:'Wolf', modifier:'Red'},
wolfShade: {name:'Wolf', modifier:'Shade'},
wolfSkeleton: {name:'Wolf', modifier:'Skeleton'},
wolfVeteran: {name:'Wolf', modifier:'Veteran'},
wolfWhite: {name:'Wolf', modifier:'White'},
wolfZombie: {name:'Wolf', modifier:'Zombie'}
}
/**
== Old Style ==
pet: Object
icon: "Pet-Wolf-White.png"
index: 14
name: "wolfWhite"
text: "White Wolf"
value: 3
pets: Object
bearcub: true
cactus: true
== New Style ==
currentPet: Object
modifier: "Red"
name: "Wolf"
notes: "Find some Hatching Powder to sprinkle on this egg, and one day it will hatch into a loyal pet."
str: "Wolf-Red"
text: "Wolf"
value: 3
pets: Array
0: "PandaCub-Base"
1: "Wolf-Base"
*/
db.users.find().forEach(function(user){
if (!user.items || (!user.items.pets && !user.items.pet)) return;
// migrate items.pet to items.currentPet
if (!!user.items.pet) {
var mapped = mapping[user.items.pet.name];
delete user.items.pet;
user.items.currentPet = {
modifier: mapped.modifier,
name: mapped.name,
str: mapped.name + "-" + mapped.modifier,
text: '' // FIXME?
}
}
// migrate items.pets
if (!!user.items.pets) {
var newPets = [];
_.each(user.items.pets, function(val, key){
if (_.isNumber(key)) {
newPets.push(val)
//FIXME why is this happening? seems the user gets migrated already...
//throw "Error: User appears already migrated, this shouldn't be happening!"
} else {
newPets.push(mapping[key].name + "-" + mapping[key].modifier);
}
});
user.items.pets = newPets;
}
try {
db.users.update(
{_id:user._id},
{$set:
{ 'items' : user.items }
}
);
} catch(e) {
print(e);
}
})

View File

@@ -0,0 +1,110 @@
/**
* Applies backer tokens & items (this file will be updated periodically
*/
// mongo habitrpg ./node_modules/underscore/underscore.js migrations/20130327_apply_tokens.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mapping = [
{
tier: 1,
tokens: 0,
users: []
},
{
tier: 5,
tokens: 20,
users: []
},
{
tier: 10,
tokens: 50,
users: []
},
{
tier: 15,
tokens: 100,
users: []
},
{
tier: 30,
tokens: 150,
users: []
},
{
tier: 45,
tokens: 170,
users: []
},
{
tier: 60,
tokens: 200,
users: []
},
{
tier: 70,
tokens: 240,
users: []
},
{
tier: 80,
tokens: 240,
users: []
},
{
tier: 90,
tokens: 280,
users: []
},
{
tier: 300,
tokens: 500,
users: []
},
{
tier: 800,
tokens: 500,
users: []
}
];
db.users.find().forEach(function(user){
if (!user._id) return;
var possibleUserIds = [user._id];
if (!!user.local) {
if (!!user.local.username) possibleUserIds.push(user.local.username);
if (!!user.local.email) possibleUserIds.push(user.local.email);
}
_.each(mapping, function(tier){
var userInTier = !_.isEmpty(_.intersection(tier.users, possibleUserIds));
if (userInTier) {
var tokenInc = 0,
backer = user.backer || {};
if (!backer.tokensApplied) {
tokenInc = tier.tokens;
backer.tokensApplied = true;
}
backer.tier = tier.tier;
try {
db.users.update(
{_id:user._id},
{
$set: { backer: backer, 'flags.ads': 'hide' },
$inc: { balance: (tokenInc/4) }
}
);
} catch(e) {
print(e);
}
}
})
})

View File

@@ -0,0 +1,22 @@
/**
* For users who already have max gear, they earned the achievement
*/
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130503_max_gear_achievement.js
db.users.find().forEach(function(user){
var items = user.items;
if (!items) { return; }
if ( parseInt(items.armor) == 5 &&
parseInt(items.head) == 5 &&
parseInt(items.shield) == 5 &&
parseInt(items.weapon) == 6) {
try {
db.users.update(
{_id:user._id},
{$set: {'achievements.ultimateGear':true}}
);
} catch(e) {
print(e);
}
}
})

View File

@@ -4,8 +4,9 @@
* mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130507_fix_broken_tags.js
*/
db.users.find().forEach(function (user) {
if (!_.isArray(user.tags)) {
db.users.update({_id: user._id}, {$set: {tags: []}});
}
});
db.users.find().forEach(function(user){
if(!_.isArray(user.tags)) {
db.users.update({_id:user._id}, {$set:{tags:[]}});
}
})

View File

@@ -0,0 +1 @@
db.users.update({'backer.tier':{$gte:80}}, {$push:{'items.pets':'Wolf-Cerberus'}}, {multi:true});

View File

@@ -13,28 +13,29 @@
// https://github.com/lodash/lodash/wiki/Changelog#v400
// since our primary subscription will first hit parties now, we *definitely* need an index there
db.parties.ensureIndex({ members: 1}, {background: true});
db.parties.ensureIndex( { 'members': 1}, {background: true} );
db.parties.find().forEach(function (party) {
if (!party.members) {
return db.parties.remove({_id: party._id});
}
db.parties.find().forEach(function(party){
// Find all members
db.users.find({_id: {$in: party.members} }, {_id: 1, party: 1}).forEach(function (user) {
// user somehow is subscribed to this party in the background, but they're it's not their primary party
if (user.party && user.party.current !== party._id) {
let i = party.members.indexOf(user._id);
party.members.splice(i, 1);
if(!party.members) {
return db.parties.remove({_id:party._id});
}
// if after we remove the user, the party is empty - delete this party
if (_.isEmpty(party.members)) {
db.parties.remove({_id: party._id});
// Find all members
db.users.find( {_id: {$in:party.members} }, {_id:1,party:1} ).forEach(function(user){
// user somehow is subscribed to this party in the background, but they're it's not their primary party
if (user.party && user.party.current !== party._id) {
var i = party.members.indexOf(user._id);
party.members.splice(i, 1);
}
// else just set it
} else {
db.parties.update({_id: party._id}, {$set: {members: party.members}});
}
});
});
// if after we remove the user, the party is empty - delete this party
if (_.isEmpty(party.members)) {
db.parties.remove({_id:party._id});
// else just set it
} else {
db.parties.update({_id:party._id}, {$set:{members:party.members}});
}
})
})

View File

@@ -15,34 +15,34 @@
* 5) subscribe everyone to habitrpg (be sure to set that for default user too!)
*/
db.parties.renameCollection('groups', true);
// db.parties.dropCollection(); // doesn't seem to do this step during rename...
// db.parties.ensureIndex( { 'members': 1, 'background': 1} );
db.parties.renameCollection('groups',true);
//db.parties.dropCollection(); // doesn't seem to do this step during rename...
//db.parties.ensureIndex( { 'members': 1, 'background': 1} );
db.groups.update({}, {$set: {type: 'party'}}, {multi: true});
db.groups.update({}, {$set:{type:'party'}}, {multi:true});
// migrate invitation mechanisms
//migrate invitation mechanisms
db.users.update(
{},
{
$remove: {party: 1},
$set: {invitations: {party: null, guilds: []}},
},
{multi: 1}
{},
{
$remove:{party:1},
$set:{invitations:{party:null,guilds:[]}}
},
{multi:1}
);
tavern = db.tavern.findOne();
db.tavern.drop();
// TODO make as a callback of previous, or make sure group.type is still 'guild' for habitrpg in the end
//TODO make as a callback of previous, or make sure group.type is still 'guild' for habitrpg in the end
db.groups.insert({
_id: 'habitrpg',
leader: '9',
type: 'guild',
name: 'HabitRPG',
chat: tavern.messages,
info: {
blurb: '',
websites: [],
},
_id: "habitrpg",
leader: '9',
type: 'guild',
name: "HabitRPG",
chat: tavern.messages,
info: {
blurb: '',
websites: []
}
});

View File

@@ -0,0 +1,31 @@
//mongo habitrpg ./node_modules/lodash/lodash.js migrations/20130602_survey_rewards.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var members = []
members = _.uniq(members);
var query = {
_id: {$exists:1},
$or:[
{_id: {$in: members}},
//{'profile.name': {$in: members}},
{'auth.facebook.name': {$in: members}},
{'auth.local.username': {$in: members}},
{'auth.local.email': {$in: members}}
]
};
print(db.users.count(query));
db.users.update(query,
{
$set: { 'achievements.helpedHabit': true },
$inc: { balance: 2.5 }
},
{multi:true}
)

View File

@@ -0,0 +1,9 @@
//mongo habitrpg migrations/20130612_survey_rewards_individual.js
var query = {_id: ""};
db.users.update(query,
{
$set: { 'achievements.helpedHabit': true },
$inc: { balance: 2.5 }
})

View File

@@ -0,0 +1,4 @@
db.users.ensureIndex( { _id: 1, apiToken: 1 }, {background: true} )
db.groups.ensureIndex( { members: 1 }, {background: true} )
db.groups.ensureIndex( { type: 1 }, {background: true} )
db.groups.ensureIndex( { type: 1, privacy: 1 }, {background: true} )

View File

@@ -0,0 +1,16 @@
//mongo habitrpg ./node_modules/lodash/lodash.js migrations/20130908_cleanup_corrupt_tags.js
// Racer was notorious for adding duplicates, randomly deleting documents, etc. Once we pull the plug on old.habit,
// run this migration to cleanup all the corruption
db.users.find().forEach(function(user){
user.tags = _.filter(user.tags, (function(t) {
return !!t ? t.id : false;
}));
try {
db.users.update({_id:user._id}, {$set:{tags:user.tags}});
} catch(e) {
print(e);
}
})

View File

@@ -1,4 +1,4 @@
// mongo habitrpg ./node_modules/lodash/lodash.js migrations/20130908_cleanup_derby_corruption.js
//mongo habitrpg ./node_modules/lodash/lodash.js migrations/20130908_cleanup_derby_corruption.js
// Racer was notorious for adding duplicates, randomly deleting documents, etc. Once we pull the plug on old.habit,
// run this migration to cleanup all the corruption
@@ -9,48 +9,49 @@
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
db.users.find().forEach(function (user) {
db.users.find().forEach(function(user){
// remove corrupt tasks, which will either be null-value or no id
user.tasks = _.reduce(user.tasks, function (m, task, k) {
user.tasks = _.reduce(user.tasks, function(m,task,k) {
if (!task || !task.id) return m;
if (isNaN(Number(task.value))) task.value = 0;
if (isNaN(+task.value)) task.value = 0;
m[k] = task;
return m;
}, {});
// fix NaN stats
_.each(user.stats, function (v, k) {
if (!v || isNaN(Number(v))) user.stats[k] = 0;
_.each(user.stats, function(v,k) {
if (!v || isNaN(+v)) user.stats[k] = 0;
return true;
});
// remove duplicates, restore ghost tasks
['habit', 'daily', 'todo', 'reward'].forEach(function (type) {
let idList = user[`${type }Ids`];
let taskIds = _.pluck(_.where(user.tasks, {type}), 'id');
let union = _.union(idList, taskIds);
let preened = _.filter(union, function (id) {
['habit', 'daily', 'todo', 'reward'].forEach(function(type) {
var idList = user[type + "Ids"];
var taskIds = _.pluck(_.where(user.tasks, {type: type}), 'id');
var union = _.union(idList, taskIds);
var preened = _.filter(union, function(id) {
return id && _.contains(taskIds, id);
});
if (!_.isEqual(idList, preened)) {
user[`${type }Ids`] = preened;
user[type + "Ids"] = preened;
}
});
// temporarily remove broken eggs. we'll need to write a migration script to grant gems for and remove these instead
if (user.items && user.items.eggs) {
user.items.eggs = _.filter(user.items.eggs, function (egg) {
user.items.eggs = _.filter(user.items.eggs,function(egg){
if (_.isString(egg)) {
user.balance += 0.75; // give them 3 gems for each broken egg
} else {
return true;
}
});
})
}
try {
db.users.update({_id: user._id}, user);
} catch (e) {
db.users.update({_id:user._id}, user);
} catch(e) {
print(e);
}
});
})

View File

@@ -8,7 +8,7 @@
* If we experience any troubles with removed staging users, come back to a snapshot and restore accounts. This will
* give a peak into possible conflict accounts:
*/
/* db.users.count({
/*db.users.count({
"auth.local": {$exists: false},
"auth.facebook": {$exists: false},
"history.exp.5": {$exists: 1},
@@ -22,9 +22,9 @@
* in we'll be using localStorage anyway instead of creating a new database record
*/
db.users.remove({
// Un-registered users
'auth.local': {$exists: false},
'auth.facebook': {$exists: false},
// Un-registered users
"auth.local": {$exists: false},
"auth.facebook": {$exists: false}
});
/**
@@ -32,6 +32,6 @@ db.users.remove({
* Another vestige of Racer. Empty parties shouldn't be being created anymore in the new site
*/
db.groups.remove({
type: 'party',
$where: 'return this.members.length === 0',
'type': 'party',
$where: "return this.members.length === 0"
});

View File

@@ -0,0 +1,5 @@
db.users.find().forEach(function(user){
if (!user.purchased) user.purchased = {hair: {}, skin: {}};
user.purchased.ads = user.flags && !!user.flags.ads;
db.users.update({_id:user._id}, {$set:{'purchased': user.purchased, 'flags.newStuff': true}, $unset: {'flags.ads':1}});
});

View File

@@ -0,0 +1,12 @@
// node .migrations/20131022_restore_ads.js
var mongo = require('mongoskin');
var _ = require('lodash');
var dbBackup = mongo.db('localhost:27017/habitrpg?auto_reconnect');
var dbLive = mongo.db('localhost:27017/habitrpg2?auto_reconnect');
var count = 89474;
dbBackup.collection('users').findEach({$or: [{'flags.ads':'show'}, {'flags.ads': null}]}, {batchSize:10}, function(err, item) {
if (err) return console.error({err:err});
if (!item || !item._id) return console.error('blank user');
dbLive.collection('users').update({_id:item._id}, {$set:{'purchased.ads':false}, $unset: {'flags.ads': 1}});
if (--count <= 0) console.log("DONE!");
});

View File

@@ -3,7 +3,7 @@
// TODO it might be better we just find() and save() all user objects using mongoose, and rely on our defined pre('save')
// and default values to "migrate" users. This way we can make sure those parts are working properly too
// @see http://stackoverflow.com/questions/14867697/mongoose-full-collection-scan
// Also, what do we think of a Mongoose Migration module? something like https://github.com/madhums/mongoose-migrate
//Also, what do we think of a Mongoose Migration module? something like https://github.com/madhums/mongoose-migrate
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
@@ -11,27 +11,28 @@
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
db.users.find().forEach(function (user) {
db.users.find().forEach(function(user){
// Add invites to groups
// -------------------------
if (user.invitations) {
if (user.invitations.party) {
db.groups.update({_id: user.invitations.party.id}, {$addToSet: {invites: user._id}});
if(user.invitations){
if(user.invitations.party){
db.groups.update({_id: user.invitations.party.id}, {$addToSet:{invites:user._id}});
}
if (user.invitations.guilds) {
_.each(user.invitations.guilds, function (guild) {
db.groups.update({_id: guild.id}, {$addToSet: {invites: user._id}});
if(user.invitations.guilds){
_.each(user.invitations.guilds, function(guild){
db.groups.update({_id: guild.id}, {$addToSet:{invites:user._id}});
});
}
}
// Cleanup broken tags
// -------------------------
_.each(user.tasks, function (task) {
_.each(task.tags, function (val, key) {
_.each(user.tags, function (tag) {
if (key === tag.id) delete task.tags[key];
_.each(user.tasks, function(task){
_.each(task.tags, function(val, key){
_.each(user.tags, function(tag){
if(key == tag.id) delete task.tags[key];
});
});
});
@@ -39,25 +40,25 @@ db.users.find().forEach(function (user) {
// Fix corrupt dates
// -------------------------
user.lastCron = new Date(user.lastCron);
if (user.lastCron === 'Invalid Date') user.lastCron = new Date();
if (user.lastCron == 'Invalid Date') user.lastCron = new Date();
if (user.auth) { // what to do with !auth?
_.defaults(user.auth, {timestamps: {created: undefined, loggedin: undefined}});
_.defaults(user.auth, {timestamps: {created:undefined, loggedin: undefined}});
_.defaults(user.auth.timestamps, {created: new Date(user.lastCron), loggedin: new Date(user.lastCron)});
}
// Fix missing history
// -------------------------
_.defaults(user, {history: {}});
_.defaults(user.history, {exp: [], todos: []});
_.defaults(user, {history:{}});
_.defaults(user.history,{exp:[], todos:[]});
// Add username
// -------------------------
if (!user.profile) user.profile = {name: undefined};
if (!user.profile) user.profile = {name:undefined};
if (_.isEmpty(user.profile.name) && user.auth) {
let fb = user.auth.facebook;
var fb = user.auth.facebook;
user.profile.name =
user.auth.local && user.auth.local.username ||
fb && (fb.displayName || fb.name || fb.username || fb.first_name && `${fb.first_name } ${ fb.last_name}`) ||
(user.auth.local && user.auth.local.username) ||
(fb && (fb.displayName || fb.name || fb.username || (fb.first_name && fb.first_name + ' ' + fb.last_name))) ||
'Anonymous';
}
@@ -70,62 +71,62 @@ db.users.find().forEach(function (user) {
print(user._id);
}
} else {
_.each(['habit', 'daily', 'todo', 'reward'], function (type) {
_.each(['habit', 'daily', 'todo', 'reward'], function(type) {
// we use _.transform instead of a simple _.where in order to maintain sort-order
user[`${type }s`] = _.reduce(user[`${type }Ids`], function (m, tid) {
let task = user.tasks[tid],
user[type + "s"] = _.reduce(user[type + "Ids"], function(m, tid) {
var task = user.tasks[tid],
newTask = {};
if (!task) return m; // remove null tasks
// Cleanup tasks for TaskSchema
newTask._id = newTask.id = task.id;
newTask.text = _.isString(task.text) ? task.text : '';
newTask.text = (_.isString(task.text)) ? task.text : '';
if (_.isString(task.notes)) newTask.notes = task.notes;
newTask.tags = _.isObject(task.tags) ? task.tags : {};
newTask.type = _.isString(task.type) ? task.type : 'habit';
newTask.value = _.isNumber(task.value) ? task.value : 0;
newTask.priority = _.isString(task.priority) ? task.priority : '!';
newTask.tags = (_.isObject(task.tags)) ? task.tags : {};
newTask.type = (_.isString(task.type)) ? task.type : 'habit';
newTask.value = (_.isNumber(task.value)) ? task.value : 0;
newTask.priority = (_.isString(task.priority)) ? task.priority : '!';
switch (newTask.type) {
case 'habit':
newTask.up = _.isBoolean(task.up) ? task.up : true;
newTask.down = _.isBoolean(task.down) ? task.down : true;
newTask.history = _.isArray(task.history) ? task.history : [];
newTask.up = (_.isBoolean(task.up)) ? task.up : true;
newTask.down = (_.isBoolean(task.down)) ? task.down : true;
newTask.history = (_.isArray(task.history)) ? task.history : [];
break;
case 'daily':
newTask.repeat = _.isObject(task.repeat) ? task.repeat : {m: 1, t: 1, w: 1, th: 1, f: 1, s: 1, su: 1};
newTask.streak = _.isNumber(task.streak) ? task.streak : 0;
newTask.completed = _.isBoolean(task.completed) ? task.completed : false;
newTask.history = _.isArray(task.history) ? task.history : [];
newTask.repeat = (_.isObject(task.repeat)) ? task.repeat : {m:1, t:1, w:1, th:1, f:1, s:1, su:1};
newTask.streak = (_.isNumber(task.streak)) ? task.streak : 0;
newTask.completed = (_.isBoolean(task.completed)) ? task.completed : false;
newTask.history = (_.isArray(task.history)) ? task.history : [];
break;
case 'todo':
newTask.completed = _.isBoolean(task.completed) ? task.completed : false;
newTask.completed = (_.isBoolean(task.completed)) ? task.completed : false;
break;
}
m.push(newTask);
return m;
}, []);
delete user[`${type }Ids`];
delete user[type + 'Ids'];
});
delete user.tasks;
}
try {
db.users.update({_id: user._id}, user);
} catch (e) {
db.users.update({_id:user._id}, user);
} catch(e) {
print(e);
}
});
// Remove old groups.*.challenges, they're not compatible with the new system, set member counts
// -------------------------
db.groups.find().forEach(function (group) {
db.groups.update({_id: group._id}, {
$set: {memberCount: _.size(group.members)},
$pull: {challenges: 1},
});
db.groups.find().forEach(function(group){
db.groups.update({_id:group._id}, {
$set:{memberCount: _.size(group.members)},
$pull:{challenges:1}
})
});
// HabitRPG => Tavern
// -------------------------
db.groups.update({_id: 'habitrpg'}, {$set: {name: 'Tavern'}});
db.groups.update({_id:'habitrpg'}, {$set:{name:'Tavern'}});

View File

@@ -0,0 +1,25 @@
// mongo habitrpg ./node_modules/lodash/lodash.js ./migrations/20131028_task_subdocs_tags_invites.js
db.challenges.find().forEach(function(chal){
_.each(chal.habits.concat(chal.dailys).concat(chal.todos).concat(chal.rewards), function(task){
task.id = task.id || task._id;
})
try {
db.challenges.update({_id:chal._id}, chal);
db.groups.update({_id:chal.group}, {$addToSet:{challenges:chal._id}})
} catch(e) {
print(e);
}
});
db.users.find().forEach(function(user){
_.each(user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards), function(task){
task.id = task.id || task._id;
})
try {
db.users.update({_id:user._id}, user);
} catch(e) {
print(e);
}
});

View File

@@ -0,0 +1,7 @@
db.users.find({},{todos:1}).forEach(function(user){
_.each(user.todos, function(task){
if (moment(task.date).toDate() == 'Invalid Date')
task.date = moment().format('MM/DD/YYYY');
})
db.users.update({_id:user._id}, {$set:{todos: user.todos}});
});

View File

@@ -5,8 +5,8 @@
* schemas became more strict. See conversation at https://github.com/HabitRPG/habitrpg/issues/1712 ,
* this restores task tags, streaks, due-dates, values
*/
let mongo = require('mongoskin');
let _ = require('lodash');
var mongo = require('mongoskin');
var _ = require('lodash');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
@@ -14,47 +14,47 @@ let _ = require('lodash');
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
let backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
let liveUsers = mongo.db('localhost:27017/habitrpg_new?auto_reconnect').collection('users');
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('localhost:27017/habitrpg_new?auto_reconnect').collection('users');
backupUsers.count(function (err, count) {
backupUsers.count(function(err, count){
if (err) return console.error(err);
backupUsers.findEach({}, {batchSize: 250}, function (err, before) {
backupUsers.findEach({}, {batchSize:250}, function(err, before){
if (err) return console.error(err);
if (!before) return console.log('!before');
liveUsers.findOne({_id: before._id}, function (err, after) {
liveUsers.findById(before._id, function(err, after){
if (err) return console.error(err);
if (!after) {
count--;
return console.log(`${before._id } deleted?`);
return console.log(before._id + ' deleted?');
}
if (before._id === '9') console.log('lefnire processed');
_.each(before.tasks, function (tBefore) {
let tAfter = _.find(after[`${tBefore.type}s`], {id: tBefore.id});
if (before._id == '9') console.log('lefnire processed');
_.each(before.tasks, function(tBefore){
var tAfter = _.find(after[tBefore.type+'s'], {id:tBefore.id});
if (!tAfter) return; // task has been deleted since launch
// Restore deleted tags
if (!_.isEmpty(tBefore.tags) && _.isEmpty(tAfter.tags))
tAfter.tags = tBefore.tags;
// Except tags which are no longer available on the updated user
_.each(tAfter.tags, function (v, k) { // value is true, key is tag.id
if (!_.find(after.tags, {id: k})) delete tAfter.tags[k];
});
_.each(tAfter.tags, function(v,k){ //value is true, key is tag.id
if (!_.find(after.tags,{id:k})) delete tAfter.tags[k];
})
// Restore deleted streaks
if (Number(tBefore.streak) > tAfter.streak)
tAfter.streak = Number(tBefore.streak);
if (+tBefore.streak > tAfter.streak)
tAfter.streak = +tBefore.streak;
if (Boolean(tBefore.date) && !tAfter.date)
if (!!tBefore.date && !tAfter.date)
tAfter.date = tBefore.date;
// Restore deleted values
if (Number(tBefore.value) != 0 && tAfter.value === 0)
tAfter.value = Number(tBefore.value);
});
if (+tBefore.value != 0 && tAfter.value == 0)
tAfter.value = +tBefore.value;
})
after._v++;
liveUsers.update({_id: after._id}, after);
if (--count <= 0) console.log('DONE!');
});
liveUsers.update({_id:after._id}, after);
if (--count <= 0) console.log("DONE!");
})
});
});

View File

@@ -0,0 +1,21 @@
function deleteId(h){
delete h._id;
}
db.users.find({},{habits:1,dailys:1,history:1}).forEach(function(user){
if (user.history) {
_.each(['todos','exp'], function(type){
if (user.history[type]) {
_.each(user.history.exp, deleteId);
}
})
} else {
user.history = {exp:[],todos:[]};
}
_.each(['habits', 'dailys'], function(type){
_.each(user[type].history, deleteId);
});
db.users.update({_id:user._id}, {$set:{history: user.history, habits: user.habits, dailys: user.dailys}});
});

View File

@@ -1,9 +1,9 @@
db.users.find({
$or: [
{'backer.admin': {$exists: 1}},
{'backer.contributor': {$exists: 1}},
],
}, {backer: 1}).forEach(function (user) {
{'backer.admin':{$exists:1}},
{'backer.contributor':{$exists:1}}
]
},{backer:1}).forEach(function(user){
user.contributor = {};
user.contributor.admin = user.backer.admin;
delete user.backer.admin;
@@ -14,5 +14,5 @@ db.users.find({
delete user.backer.contributor;
}
db.users.update({_id: user._id}, {$set: {backer: user.backer, contributor: user.contributor}});
db.users.update({_id:user._id}, {$set:{backer:user.backer, contributor:user.contributor}});
});

View File

@@ -0,0 +1,4 @@
// Increase everyone's gems per their contribution level
db.users.find({'contributor.level':{$gt:0}},{contributor:1, balance:1}).forEach(function(user){
db.users.update({_id:user._id}, {$inc: {balance: (user.contributor.level * .5)} });
});

View File

@@ -1,11 +1,10 @@
db.users.find(
{$where: 'Array.isArray(this.items.pets) || Array.isArray(this.items.eggs) || Array.isArray(this.items.hatchingPotions)'},
{backer: 1, items: 1}
).forEach(function (user) {
{$where: "Array.isArray(this.items.pets) || Array.isArray(this.items.eggs) || Array.isArray(this.items.hatchingPotions)"},
{backer: 1, items:1}
).forEach(function(user){
if (_.isArray(user.items.pets)) {
user.items.pets = _.reduce(user.items.pets, function (m, v) {
m[v] = 5; return m;
}, {});
user.items.pets = _.reduce(user.items.pets, function(m,v){ m[v] = 5; return m;}, {});
}
if (!_.isString(user.items.currentPet)) {
@@ -13,7 +12,7 @@ db.users.find(
}
if (_.isArray(user.items.eggs)) {
user.items.eggs = _.reduce(user.items.eggs, function (m, v) {
user.items.eggs = _.reduce(user.items.eggs, function(m,v){
if (!m[v.name]) m[v.name] = 0;
m[v.name]++;
return m;
@@ -21,7 +20,7 @@ db.users.find(
}
if (_.isArray(user.items.hatchingPotions)) {
user.items.hatchingPotions = _.reduce(user.items.hatchingPotions, function (m, v) {
user.items.hatchingPotions = _.reduce(user.items.hatchingPotions, function(m,v){
if (!m[v]) m[v] = 0;
m[v]++;
return m;
@@ -36,5 +35,5 @@ db.users.find(
user.items.mounts['LionCub-Ethereal'] = true;
}
db.users.update({_id: user._id}, {$set: {items: user.items}});
db.users.update({_id:user._id}, {$set:{items:user.items}});
});

View File

@@ -0,0 +1,15 @@
// This migration has already been run in the past. It's vital to fix these users presently, but we need to find
// out why task values are ever getting in as NaN. My guess is API PUT /tasks/:tid routes
db.users.find({},{habits:1,dailys:1,todos:1,rewards:1}).forEach(function(user){
_.each(['habits','dailys','todos','rewards'], function(type){
_.each(user[type], function(task){
task.value = +task.value;
if (_.isNaN(task.value)) {
task.value = 0;
print(user._id);
}
})
})
db.users.update({_id:user._id}, {$set:{habits: user.habits, dailys: user.dailys, todos: user.todos, rewards: user.rewards}});
});

View File

@@ -0,0 +1,14 @@
// Migrate all users websites to the profile blurb field
db.users.find({'profile.websites':{$exists: true}}).forEach(function(user){
db.users.update({_id: user._id}, {
$set: {"profile.blurb": user.profile.blurb + '\n * ' + user.profile.websites.join('\n * ')},
$unset: {'profile.websites': 1}
})
})
db.groups.find({'websites.0':{$exists: true}}).forEach(function(group){
db.groups.update({_id: group._id}, {
$set: {"description": group.description + '\n * ' + group.websites.join('\n * ')},
$unset: {websites: 1}
})
})

View File

@@ -0,0 +1,10 @@
//Add defaults to show gears in all users
db.users.update(
{},
{$set:{
'preferences.showWeapon': true,
'preferences.showShield': true,
'preferences.showArmor': true,
}},
{multi:true}
)

View File

@@ -0,0 +1,18 @@
// TODO figure out why this is happening in the first place
db.users.find({},{habits:1, dailys:1, todos:1, rewards:1}).forEach(function(user){
_.each(user.habits, function(task){
task.type = 'habit';
})
_.each(user.dailys, function(task){
task.type = 'daily';
})
_.each(user.todos, function(task){
task.type = 'todo';
})
_.each(user.rewards, function(task){
task.type = 'reward';
})
db.users.update({_id:user._id}, {$set:{habits: user.habits, dailys: user.dailys, todos: user.todos, rewards: user.rewards}});
});

View File

@@ -0,0 +1,12 @@
// once and for all!
db.users.find({'items.pets':{$exists:1}},{'items.pets':1}).forEach(function(user){
_.reduce(user.items.pets, function(m,v,k){
if (!k.indexOf('undefined')) m.push(k);
return m;
}, []).forEach(function(key){
delete user.items.pets[key];
})
db.users.update({_id:user._id}, { $set:{'items.pets':user.items.pets} });
});

View File

@@ -0,0 +1,13 @@
// Cleanup broken tags
// -------------------------
db.users.find().forEach(function(user){
var tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
_.each(tasks, function(task){
_.each(task.tags, function(value, key){ //value is true, key is tag.id
if (!_.find(user.tags,{id:key})) delete task.tags[key];
});
});
db.users.update({_id:user._id}, user);
});

View File

@@ -0,0 +1,8 @@
//Add default to randomize party members list
db.users.update(
{},
{$set:{
'party.order': 'random',
}},
{multi:true}
)

View File

@@ -0,0 +1,5 @@
db.users.find({'preferences.dayStart':{$exists:1}},{'preferences.dayStart':1}).forEach(function(user){
var dayStart = +user.preferences.dayStart;
dayStart = (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) ? 0 : dayStart;
db.users.update({_id:user._id}, {$set:{'preferences.dayStart':dayStart}});
});

View File

@@ -0,0 +1 @@
db.users.update({},{$set:{'items.pets.Turkey-Base':5, 'flags.newStuff':true}}, {multi:true});

View File

@@ -0,0 +1,38 @@
// node .migrations/20131127_restore_dayStart.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('localhost:27017/habitrpg_new?auto_reconnect').collection('users');
var query = {'preferences.dayStart':{$exists:1,$ne:0}};
var select = {'preferences.dayStart': 1};
backupUsers.count(query, function(err, count){
if (err) return console.error(err);
backupUsers.findEach(query, select, {batchSize:20}, function(err, before){
if (err) return console.error(err);
if (!before) { count--; return console.log('!before'); }
liveUsers.findById(before._id, function(err, after){
if (err) return console.error(err);
if (!after) { count--; return console.log(before._id + ' deleted?'); }
var dayStart = +before.preferences.dayStart;
if (after.preferences.dayStart == 0 && dayStart != 0){
dayStart = (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) ? 0 : dayStart;
} else {
dayStart = after.preferences.dayStart;
}
liveUsers.update({_id:after._id}, {$inc:{_v:1}, $set:{'preferences.dayStart':dayStart}});
if (--count <= 0) console.log("DONE!");
})
});
});

View File

@@ -1,20 +1,20 @@
let query = {
$or: [
var query = {
'$or': [
{'items.gear.owned.weapon_special_0': true},
{'items.gear.owned.armor_special_0': true},
{'items.gear.owned.head_special_0': true},
{'items.gear.owned.shield_special_0': true},
],
{'items.gear.owned.shield_special_0': true}
]
};
db.users.find(query, {'items.gear.owned': 1, backer: 1}).forEach(function (user) {
let owned = user.items.gear.owned;
let tier = user.backer && user.backer.tier || 0;
db.users.find(query, {'items.gear.owned':1,backer:1}).forEach(function(user){
var owned = user.items.gear.owned;
var tier = (user.backer && user.backer.tier) || 0;
if (tier < 70) delete owned.weapon_special_0;
if (tier < 45) delete owned.armor_special_0;
if (tier < 45) delete owned.head_special_0;
if (tier < 45) delete owned.shield_special_0;
db.users.update({_id: user._id}, {$set: {'items.gear.owned': owned}});
db.users.update({_id:user._id}, {$set:{'items.gear.owned':owned}});
});

View File

@@ -0,0 +1,51 @@
// node .migrations/20131221_restore_NaN_history.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* After the classes migration, users lost some history entries
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('localhost:27017/habitrpg?auto_reconnect').collection('users');
function filterNaNs(h) {
return h && _.isNumber(+h.value) && !_.isNaN(+h.value);
}
var fields = {history:1,habits:1,dailys:1,migration:1};
var count = 0;
liveUsers.findEach({migration: {$ne:'20131221_restore_NaN_history'}}, fields, {batchSize:500}, function(err, after){
if (!after) err = '!after';
if (err) {count++;return console.error(err);}
backupUsers.findById(after._id, fields, function(err, before){
if (err) {count++;return console.error(err);}
_.each(['todos','exp'],function(type){
if (!_.isEmpty(after.history[type]))
after.history[type] = _.filter(after.history[type], filterNaNs);
if (before && !_.isEmpty(before.history[type]))
after.history[type] = before.history[type].concat(after.history[type]);
})
_.each(['habits','dailys'], function(type){
_.each(after[type], function(t){
t.history = _.filter(t.history, filterNaNs);
var found = before && _.find(before[type],{id:t.id});
if (found && found.history) t.history = found.history.concat(t.history);
})
})
liveUsers.update({_id:after._id}, {$set:{history:after.history, dailys:after.dailys, habits:after.habits, migration:'20131221_restore_NaN_history'}, $inc:{_v:1}});
//if (--count <= 0) console.log("DONE! " + after._id);
if (++count%1000 == 0) console.log(count);
if (after._id == '9') console.log('lefnire processed');
})
});

View File

@@ -0,0 +1,38 @@
// node .migrations/20131225_restore_streaks.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* After the classes migration, users lost some history entries
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('lefnire:mAdn3s5s@charlotte.mongohq.com:10015/habitrpg_large?auto_reconnect').collection('users');
var fields = {dailys:1,migration:1};
var count = 0;
liveUsers.findEach({migration: {$ne:'20131225_restore_streaks'}}, fields, {batchSize:250}, function(err, after){
if (!after) err = '!after';
if (err) {count++;return console.error(err);}
backupUsers.findById(after._id, fields, function(err, before){
if (!before) err = '!before';
if (err) {count++;return console.error(err);}
_.each(before.dailys,function(d){
var found = _.find(after.dailys,{id: d.id});
if (found && !found.streak) found.streak = d.streak;
})
liveUsers.update({_id:after._id}, {$set:{dailys:after.dailys, migration:'20131225_restore_streaks'}, $inc:{_v:1}});
//if (--count <= 0) console.log("DONE! " + after._id);
if (++count%1000 == 0) console.log(count);
if (after._id == '9') console.log('lefnire processed');
})
});

View File

@@ -0,0 +1,8 @@
db.users.find({},{todos:1,dailys:1,rewards:1,habits:1}).forEach(function(user){
_.each(user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards), function(t){
t.dateCreated = t.created || new Date;
delete t.created;
if (t.type == 'todo' && t.completed) t.dateCompleted = new Date;
})
db.users.update({_id:user._id}, {$set:{habits:user.habits,dailys:user.dailys,todos:user.todos,rewards:user.rewards}});
});

View File

@@ -0,0 +1 @@
db.users.update({},{$set:{'achievements.habitBirthday':true}},{multi:1})

View File

@@ -0,0 +1,12 @@
db.users.update({},{$set:{
'items.food.Cake_Skeleton':1,
'items.food.Cake_Base':1,
'items.food.Cake_CottonCandyBlue':1,
'items.food.Cake_CottonCandyPink':1,
'items.food.Cake_Shade':1,
'items.food.Cake_White':1,
'items.food.Cake_Golden':1,
'items.food.Cake_Zombie':1,
'items.food.Cake_Desert':1,
'items.food.Cake_Red':1
}},{multi:1})

View File

@@ -0,0 +1,3 @@
db.challenges.find({},{members:1}).forEach(function(chal){
db.challenges.update({_id:chal._id}, {$set:{memberCount:chal.members.length}});
});

View File

@@ -0,0 +1,14 @@
db.users.update(
{
'purchased.plan.dateCreated':{$gte:new Date('2014-02-22'),$lt:new Date('2014-02-29')},
'items.gear.owned.armor_mystery_201402':null,
'items.gear.owned.head_mystery_201402': null,
'items.gear.owned.back_mystery_201402': null,
'purchased.plan.mysteryItems':{$nin:['armor_mystery_201402','head_mystery_201402','back_mystery_201402']}
},
//{_id:1,'purchased.plan':1,'items.gear.owned':1}
{$push: {'purchased.plan.mysteryItems':{$each:['armor_mystery_201402','head_mystery_201402','back_mystery_201402']}}},
{multi:true}
)/*.forEach(function(user){
printjson(user);
});*/

View File

@@ -0,0 +1 @@
db.users.update({'backer.tier':{$gt:69}},{$set:{'items.mounts.LionCub-Ethereal':true}},{multi:1})

View File

@@ -0,0 +1,11 @@
//mongo habitrpg node_modules/lodash/lodash.js ./migrations/20140712_wiped_quest_membership.js
db.groups.find({type:'party','quest.key':{$ne:null},'quest.active':true},{quest:1}).forEach(function(group){
var activeMembers = _.reduce(group.quest.members, function(m,v,k){
if (v===true) m.push(k); return m;
},[]);
db.users.update(
{_id:{$in: activeMembers}},
{$set:{'party.quest.key':group.quest.key,'party.quest.completed':null}},
{multi:true}
);
});

View File

@@ -0,0 +1,13 @@
var _ = require('lodash');
db.users.find({}).forEach(function(user){
var newNewMessages = {};
_.each(user.newMessages, function(val, key){
if(key != "undefined"){
newNewMessages[key] = val;
};
});
db.users.update({_id: user._id}, {$set: {'newMessages': newNewMessages}});
});

View File

@@ -1,9 +1,9 @@
// node .migrations/20140823_remove_undefined_and_false_notifications.js
let migrationName = '20140823_remove_undefined_and_false_notifications';
var migrationName = '20140823_remove_undefined_and_false_notifications';
let authorName = 'Alys'; // in case script author needs to know when their ...
let authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; // ... own data is done
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
@@ -15,8 +15,8 @@ let authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; // ... own data is done
* https://github.com/HabitRPG/habitrpg/pull/3907
*/
let mongo = require('mongoskin');
let _ = require('lodash');
var mongo = require('mongoskin');
var _ = require('lodash');
// XXX @lefnire, choose wisely:
// var liveUsers = mongo.db('lefnire:mAdn3s5s@charlotte.mongohq.com:10015/habitrpg_large?auto_reconnect').collection('users');
@@ -26,28 +26,26 @@ let _ = require('lodash');
// var liveUsers = mongo.db('localhost:27017/habitrpg?auto_reconnect').collection('users');
let fields = {migration: 1, newMessages: 1};
let progressCount = 1000;
var fields = {migration:1,newMessages:1};
var progressCount = 1000;
// var progressCount = 1;
let count = 0;
liveUsers.findEach({migration: {$ne: migrationName}}, fields, {batchSize: 250}, function (err, user) {
var count = 0;
liveUsers.findEach({migration: {$ne:migrationName}}, fields, {batchSize:250}, function(err, user){
count++;
if (!user) err = '!user';
if (err) {
return console.error(err);
}
if (err) {return console.error(err);}
let newNewMessages = {};
_.each(user.newMessages, function (val, key) {
var newNewMessages = {};
_.each(user.newMessages,function(val,key){
// console.log(key + " " + val.name);
if (key != 'undefined' && val.value) {
if(key != "undefined" && val['value']){
newNewMessages[key] = val;
}
});
})
liveUsers.update({_id: user._id}, {$set: {newMessages: newNewMessages, migration: migrationName}, $inc: {_v: 1}});
liveUsers.update({_id:user._id}, {$set:{newMessages:newNewMessages, migration:migrationName}, $inc:{_v:1}});
if (count % progressCount === 0) console.log(`${count } ${ user._id}`);
if (user._id === '9') console.log('lefnire processed');
if (user._id === authorUuid) console.log(`${authorName } processed`);
if (count%progressCount == 0) console.log(count + ' ' + user._id);
if (user._id == '9') console.log('lefnire processed');
if (user._id == authorUuid) console.log(authorName + ' processed');
});

View File

@@ -0,0 +1,81 @@
// node .migrations/20140829_change_headAccessory_to_eyewear.js
var migrationName = '20140829_change_headAccessory_to_eyewear';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* https://github.com/HabitRPG/habitrpg/issues/3645
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var liveUsers = mongo.db('localhost:27017/habitrpg2?auto_reconnect').collection('users');
var fields = {'migration':1,
'items.gear.costume.headAccessory':1,
'items.gear.equipped.headAccessory':1,
'items.gear.owned.headAccessory_special_wondercon_black':1,
'items.gear.owned.headAccessory_special_wondercon_red':1,
'items.gear.owned.headAccessory_special_summerRogue':1,
'items.gear.owned.headAccessory_special_summerWarrior':1
};
var progressCount = 1000;
var count = 0;
liveUsers.findEach({ $and: [
{ migration: {$ne:migrationName} },
{ $or: [
{'items.gear.owned.headAccessory_special_summerRogue': {'$exists':true}},
{'items.gear.owned.headAccessory_special_summerWarrior':{'$exists':true}},
{'items.gear.owned.headAccessory_special_wondercon_red':{'$exists':true}},
{'items.gear.owned.headAccessory_special_wondercon_black':{'$exists':true}}
]}
]}, fields, {batchSize:250}, function(err, user){
count++;
if (!user) err = '!user';
if (err) {return console.error(err);}
var set = {'migration': migrationName};
var unset = {};
var oldToNew = {
'headAccessory_special_summerRogue': 'eyewear_special_summerRogue',
'headAccessory_special_summerWarrior': 'eyewear_special_summerWarrior',
'headAccessory_special_wondercon_red': 'eyewear_special_wondercon_red',
'headAccessory_special_wondercon_black':'eyewear_special_wondercon_black'
};
// items.gear.costume, items.gear.equipped:
_.each(['costume','equipped'],function(type){
_.each(oldToNew,function(newName,oldName){
if (user.items.gear[type].headAccessory === oldName) {
unset['items.gear.'+type+'.headAccessory'] = "";
set['items.gear.'+type+'.eyewear'] = newName;
}
});
});
// items.gear.owned:
_.each(oldToNew,function(newName,oldName){
if (oldName in user.items.gear.owned) {
unset['items.gear.owned.'+oldName] = "";
set['items.gear.owned.'+newName] = user.items.gear.owned[oldName];
}
});
//console.log(JSON.stringify(user, null, " "));
//console.log("set: " + JSON.stringify(set, null, " "));
//console.log("unset: " + JSON.stringify(unset, null, " "));
liveUsers.update({_id:user._id}, {$set:set, $unset:unset, $inc:{_v:1}});
if (count%progressCount == 0) console.log(count + ' ' + user._id);
if (user._id == '9') console.log('lefnire processed');
if (user._id == authorUuid) console.log(authorName + ' processed');
});

View File

@@ -0,0 +1,131 @@
// IMPORTANT:
//
// run like this to capture all output:
//
// node 20140831_increase_gems_for_previous_contributions.js > 20140831_increase_gems_for_previous_contributions_output.txt
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var migrationName = '20140831_increase_gems_for_previous_contributions';
/**
* https://github.com/HabitRPG/habitrpg/issues/3933
* Increase Number of Gems for Contributors
* author: Alys (d904bd62-da08-416b-a816-ba797c9ee265)
*
* Increase everyone's gems per their contribution level.
* Originally they were given 2 gems per tier.
* Now they are given 3 gems per tier for tiers 1,2,3
* and 4 gems per tier for tiers 4,5,6,7
* So that means an EXTRA 1 for tier 1,
* 2 for tier 2,
* 3 for tier 3,
* 5 for tier 4,
* 7 for tier 5,
* 9 for tier 6,
* 11 for tier 7,
* 11 for tier 8 (moderators = tier 7 + admin privileges),
* none for tier 9 (staff)
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db('localhost:27017/habitrpg?auto_reconnect').collection('users');
var query = {
'contributor.level': {$gt: 0, $lt: 9},
'migration': {$ne: migrationName}
};
var fields = {
'migration':1,
'contributor.level':1,
'balance':1
};
var userResults = {}; // each key is a UUID, each value is a string
// describing what changed for that user
console.warn('Updating users...');
var progressCount = 50;
var count = 0;
dbUsers.findEach(query, fields, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All users found. Fetching final balances...');
return fetchFinalBalances();
}
count++;
var set = {'migration': migrationName};
var tier = user.contributor.level;
var extraGems = tier; // tiers 1,2,3
if (tier > 3) { extraGems = 3 + (tier - 3) * 2; }
if (tier == 8) { extraGems = 11; }
var extraBalance = extraGems / 4;
set['balance'] = user.balance + extraBalance;
// Capture current state of user:
userResults[user._id] =
user._id + ' ' + ':\n' +
' contrib tier : ' + tier + '\n' +
' balance before : ' + user.balance + '\n' +
' balance (gems) added : ' + extraBalance + ' (' +
extraGems + ')' + '\n' +
' expected balance after: ' + (user.balance + extraBalance) + '\n';
// Update user:
dbUsers.update({_id:user._id}, {$set:set, $inc:{_v:1}});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
});
function fetchFinalBalances() {
var query = {_id: {$in: Object.keys(userResults)}};
var fields = {
'balance':1,
};
var count1 = 0;
dbUsers.findEach(query, fields, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All final balances found.');
return displayData();
}
count1++;
userResults[user._id] = userResults[user._id] +
user._id + ' ' + ':\n' +
' actual balance after : ' + user.balance + '\n';
if (count1%progressCount == 0) console.warn(count1 + ' ' + user._id);
});
}
function displayData() {
_.each(userResults, function(text, uuid) {
console.log(text); // text contains uuid
});
console.log('\n' + count +
' users processed (should be roughly 335 according to the Hall)\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}

View File

@@ -0,0 +1,79 @@
var migrationName = '20140914_upgrade_admin_contrib_tiers';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/**
* https://github.com/HabitRPG/habitrpg/issues/3801
* Convert Tier 8 contributors to Tier 9 (staff) (all current Tier 8s are admins).
* Convert Tier 7 contributors with admin flag to Tier 8 (moderators).
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db('localhost:27017/habitrpg?auto_reconnect').collection('users');
var query =
{ 'contributor.level':{$gte:7}, 'contributor.admin':true, 'migration': {$ne: migrationName} };
var fields = {'migration':1,
'contributor.admin':1,
'contributor.level':1,
'auth.local.username':1,
'profile.name':1,
};
var userResults = {}; // each key is a UUID, each value is a username;
// contains only the users changed
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var set = {'migration': migrationName};
var inc = {'contributor.level':1, _v:1};
userResults[user._id] = user.profile.name;
dbUsers.update({_id:user._id}, {$set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.log('users modified:');
_.each(userResults, function(name, uuid) {
console.log(name);
});
console.warn('\n' + count +
' users processed (should be 11 according to the Hall)\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}

View File

@@ -0,0 +1,18 @@
db.users.update(
{},
{
$inc: {
'items.food.Candy_Base':1,
'items.food.Candy_CottonCandyBlue':1,
'items.food.Candy_CottonCandyPink':1,
'items.food.Candy_Desert':1,
'items.food.Candy_Golden':1,
'items.food.Candy_Red':1,
'items.food.Candy_Shade':1,
'items.food.Candy_Skeleton':1,
'items.food.Candy_White':1,
'items.food.Candy_Zombie':1
}
},
{multi:1}
);

View File

@@ -0,0 +1 @@
db.users.update({_id:'9'},{$set:{'items.pets.JackOLantern-Base':5, 'flags.newStuff':true}}, {multi:true});

View File

@@ -6,15 +6,15 @@
// require moment, lodash
db.users.find(
{'purchased.plan.customerId': {$ne: null}},
{_id: 1, 'purchased.plan': 1}
).forEach(function (user) {
let p = user.purchased.plan,
latestMonth = p.dateTerminated || new Date(), // their last sub date, or on-going (now)
count = moment(latestMonth).diff(p.dateCreated, 'months');
{'purchased.plan.customerId':{$ne:null}},
{_id:1, 'purchased.plan':1}
).forEach(function(user){
var p = user.purchased.plan
, latestMonth = p.dateTerminated || new Date() // their last sub date, or on-going (now)
, count = moment(latestMonth).diff(p.dateCreated, 'months');
db.users.update({_id: user._id}, {$set: {
'purchased.plan.consecutive.count': count,
'purchased.plan.consecutive.gemCapExtra': _.min([Math.floor(count / 3) * 5, 25]),
'purchased.plan.consecutive.trinkets': Math.floor(count / 3),
'purchased.plan.consecutive.gemCapExtra': _.min([ Math.floor(count/3)*5, 25 ]),
'purchased.plan.consecutive.trinkets': Math.floor(count/3)
}});
});

View File

@@ -0,0 +1,11 @@
db.users.update(
{'items.pets.Turkey-Base':{$ne:null}},
{$set:{'items.mounts.Turkey-Base':true}},
{multi:1}
)
db.users.update(
{'items.pets.Turkey-Base':null},
{$set:{'items.pets.Turkey-Base':5}},
{multi:1}
)

View File

@@ -0,0 +1,4 @@
db.users.update({'purchased.plan.consecutive.count':NaN}, {$set:{'purchased.plan.consecutive.count':0}}, {multi:1});
db.users.update({'purchased.plan.consecutive.offset':NaN}, {$set:{'purchased.plan.consecutive.offset':0}}, {multi:1});
db.users.update({'purchased.plan.consecutive.gemCapExtra':NaN}, {$set:{'purchased.plan.consecutive.gemCapExtra':0}}, {multi:1});
db.users.update({'purchased.plan.consecutive.trinkets':NaN}, {$set:{'purchased.plan.consecutive.trinkets':0}}, {multi:1});

View File

@@ -0,0 +1,11 @@
db.users.update(
{'items.gear.owned.head_special_nye':{$ne:null}},
{$set:{'items.gear.owned.head_special_nye2014':false}},
{multi:1}
)
db.users.update(
{'items.gear.owned.head_special_nye':null},
{$set:{'items.gear.owned.head_special_nye':false}},
{multi:1}
)

View File

@@ -0,0 +1,8 @@
db.users.update(
{'purchased.plan.customerId':{$ne:null}, 'purchased.plan.dateUpdated':null},
{
$set: {'purchased.plan.dateUpdated': new Date('12/01/2014')},
$unset: {'purchased.plan.datedUpdated':''}
},
{multi:true}
);

View File

@@ -0,0 +1,88 @@
var migrationName = '20150124_mountmaster_fix.js';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/**
* https://github.com/HabitRPG/habitrpg/pull/4374#issuecomment-71038795
* Convert false to null for mounts that used to be owned.
*/
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
var query = {
'items.mounts':{$exists:true}
};
var fields = {
'items.mounts':1
};
var animals = [ "Wolf-Base", "Wolf-White", "Wolf-Desert", "Wolf-Red", "Wolf-Shade", "Wolf-Skeleton", "Wolf-Zombie", "Wolf-CottonCandyPink", "Wolf-CottonCandyBlue", "Wolf-Golden", "TigerCub-Base", "TigerCub-White", "TigerCub-Desert", "TigerCub-Red", "TigerCub-Shade", "TigerCub-Skeleton", "TigerCub-Zombie", "TigerCub-CottonCandyPink", "TigerCub-CottonCandyBlue", "TigerCub-Golden", "PandaCub-Base", "PandaCub-White", "PandaCub-Desert", "PandaCub-Red", "PandaCub-Shade", "PandaCub-Skeleton", "PandaCub-Zombie", "PandaCub-CottonCandyPink", "PandaCub-CottonCandyBlue", "PandaCub-Golden", "LionCub-Base", "LionCub-White", "LionCub-Desert", "LionCub-Red", "LionCub-Shade", "LionCub-Skeleton", "LionCub-Zombie", "LionCub-CottonCandyPink", "LionCub-CottonCandyBlue", "LionCub-Golden", "Fox-Base", "Fox-White", "Fox-Desert", "Fox-Red", "Fox-Shade", "Fox-Skeleton", "Fox-Zombie", "Fox-CottonCandyPink", "Fox-CottonCandyBlue", "Fox-Golden", "FlyingPig-Base", "FlyingPig-White", "FlyingPig-Desert", "FlyingPig-Red", "FlyingPig-Shade", "FlyingPig-Skeleton", "FlyingPig-Zombie", "FlyingPig-CottonCandyPink", "FlyingPig-CottonCandyBlue", "FlyingPig-Golden", "Dragon-Base", "Dragon-White", "Dragon-Desert", "Dragon-Red", "Dragon-Shade", "Dragon-Skeleton", "Dragon-Zombie", "Dragon-CottonCandyPink", "Dragon-CottonCandyBlue", "Dragon-Golden", "Cactus-Base", "Cactus-White", "Cactus-Desert", "Cactus-Red", "Cactus-Shade", "Cactus-Skeleton", "Cactus-Zombie", "Cactus-CottonCandyPink", "Cactus-CottonCandyBlue", "Cactus-Golden", "BearCub-Base", "BearCub-White", "BearCub-Desert", "BearCub-Red", "BearCub-Shade", "BearCub-Skeleton", "BearCub-Zombie", "BearCub-CottonCandyPink", "BearCub-CottonCandyBlue", "BearCub-Golden" ]; // all Gen1 mounts
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var mounts = user.items.mounts;
var changed = false;
for(var a in animals) {
if(mounts[animals[a]] == false) {
mounts[animals[a]] = null;
changed = true;
}
}
if (changed) {
dbUsers.update(
{ _id: user._id},
{
$set: { "migration": migrationName,
"items.mounts" : mounts
}
}
);
}
// var set = {'migration': migrationName};
// var inc = {'xyz':1, _v:1};
// dbUsers.update({_id:user._id}, {$set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}

View File

@@ -0,0 +1,36 @@
db.users.update(
{'items.gear.owned.armor_special_birthday':{$ne:null}},
{$set:{'items.gear.owned.armor_special_birthday2015':false}},
{multi:1}
)
db.users.update(
{'items.gear.owned.armor_special_birthday':null},
{$set:{'items.gear.owned.armor_special_birthday':false}},
{multi:1}
)
db.users.update({},{$inc:{
'items.food.Cake_Skeleton':1,
'items.food.Cake_Base':1,
'items.food.Cake_CottonCandyBlue':1,
'items.food.Cake_CottonCandyPink':1,
'items.food.Cake_Shade':1,
'items.food.Cake_White':1,
'items.food.Cake_Golden':1,
'items.food.Cake_Zombie':1,
'items.food.Cake_Desert':1,
'items.food.Cake_Red':1
}},{multi:1})
db.users.update(
{'achievements.habitBirthday':true},
{$set:{'achievements.habitBirthdays':1}},
{multi:1}
)
db.users.update(
{},
{$inc:{'achievements.habitBirthdays':1}},
{multi:1}
)

View File

@@ -0,0 +1,78 @@
var migrationName = '20150131_birthday_goodies_fix__one_birthday__1';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* remove new birthday robes and second achievement from people who shouldn't have them
*/
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
// 'auth.timestamps.created':{$gt:new Date('2014-02-01')},
var query = {
'achievements.habitBirthdays':1,
'auth.timestamps.loggedin':{$gt:new Date('2014-12-20')}
};
// '_id': 'c03e41bd-501f-438c-9553-a7afdf52a08c',
// 'achievements.habitBirthday':{$exists:false},
// 'items.gear.owned.armor_special_birthday2015':1
var fields = {
// 'auth.timestamps.created':1,
// 'achievements.habitBirthday':1,
// 'achievements.habitBirthdays':1,
'items.gear.owned.armor_special_birthday2015':1,
// 'items.gear.owned.armor_special':1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var unset = {'items.gear.owned.armor_special_birthday2015': 1};
// var set = {'migration':migrationName, 'achievements.habitBirthdays':1 };
// var inc = {'xyz':1, _v:1};
dbUsers.update({_id:user._id}, {$unset:unset}); // , $inc:inc});
// dbUsers.update({_id:user._id}, {$unset:unset, $set:set});
// console.warn(user.auth.timestamps.created);
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}

View File

@@ -0,0 +1,112 @@
var migrationName = '20150201_convert_creation_date_from_string_to_object__no_date_recent_signup';
//// var migrationName = '20150201_convert_creation_date_from_string_to_object';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* For users that have no value for auth.timestamps.created, assign them
* a recent value.
*
* NOTE:
* Before this script was used as described above, it was first used to
* find all users that have a auth.timestamps.created field that is a string
* rather than a date object and set it to be a date object. The code used
* for this has been commented out with four slashes: ////
*
* https://github.com/HabitRPG/habitrpg/issues/4601#issuecomment-72339846
*/
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var moment = require('moment');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
var uuidArrayRecent=[ // recent users with no creation dates
'1a0d4b75-73ed-4937-974d-d504d6398884',
'1c7ebe27-1250-4f95-ba10-965580adbfd7',
'5f972121-4a6d-411c-95e9-7093d3e89b66',
'ae85818a-e336-4ccd-945e-c15cef975102',
'ba273976-d9fc-466c-975f-38559d34a824',
];
var query = {
'_id':{$in: uuidArrayRecent}
//// 'auth':{$exists:true},
//// 'auth.timestamps':{$exists:true},
//// 'auth.timestamps.created':{$not: {$lt:new Date('2018-01-01')}}
};
var fields = {
'_id':1,
'auth.timestamps.created':1
};
// 'achievements.habitBirthdays':1
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
//// var oldDate = user.auth.timestamps.created;
//// var newDate = moment(oldDate).toDate();
var oldDate = 'none';
var newDate = moment('2015-01-11').toDate();
console.warn(user._id + ' == ' + oldDate + ' == ' + newDate);
//// var set = { 'migration': migrationName,
//// 'auth.timestamps.created': newDate,
//// 'achievements.habitBirthdays': 2,
//// 'items.gear.owned.head_special_nye':true,
//// 'items.gear.owned.head_special_nye2014':true,
//// 'items.gear.owned.armor_special_birthday':true,
//// 'items.gear.owned.armor_special_birthday2015':true,
//// };
var set = { 'migration': migrationName,
'auth.timestamps.created': newDate,
'achievements.habitBirthdays': 1,
'items.gear.owned.armor_special_birthday':true,
};
// var unset = {'items.gear.owned.armor_special_birthday2015': 1};
// var inc = {'xyz':1, _v:1};
dbUsers.update({_id:user._id}, {$set:set});
// dbUsers.update({_id:user._id}, {$unset:unset, $set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}

View File

@@ -0,0 +1,7 @@
db.users.update({
'flags.recaptureEmailsPhase': {
$gt: 0
}
},{$inc:{
'flags.recaptureEmailsPhase':1
}},{multi:1})

View File

@@ -0,0 +1,10 @@
db.users.update({},{$set:{
'flags.tour.intro':-2,
//'flags.tour.classes':-2,
'flags.tour.stats':-2,
'flags.tour.tavern':-2,
'flags.tour.party':-2,
'flags.tour.guilds':-2,
'flags.tour.challenges':-2,
'flags.tour.market':-2
}},{multi:1})

View File

@@ -0,0 +1,64 @@
var migrationName = '20150224_force_resting_in_inn';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* force all active players to rest in the inn due to massive server fail
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
var query = {
'auth.timestamps.loggedin':{$gt:new Date('2015-02-22')}
};
var fields = {
'preferences.sleep':1,
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var set = {'migration':migrationName, 'preferences.sleep':1 };
dbUsers.update({_id:user._id}, {$set:set});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}

Some files were not shown because too many files have changed in this diff Show More