mirror of
https://github.com/HabitRPG/habitica.git
synced 2026-05-10 02:28:44 -05:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4fa689d9af |
@@ -1,12 +1,6 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"node": true
|
||||
}
|
||||
}
|
||||
]
|
||||
"plugins": [
|
||||
"transform-es2015-modules-commonjs",
|
||||
"syntax-object-rest-spread",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1 +1,2 @@
|
||||
https://github.com/heroku/heroku-buildpack-nodejs.git
|
||||
https://github.com/heroku/heroku-buildpack-nodejs.git
|
||||
https://github.com/stomita/heroku-buildpack-phantomjs.git
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
node_modules
|
||||
.git
|
||||
website
|
||||
|
||||
@@ -3,14 +3,11 @@ coverage/
|
||||
database_reports/
|
||||
website/build/
|
||||
website/transpiled-babel/
|
||||
# Has its own linter
|
||||
website/client/
|
||||
website/common/transpiled-babel/
|
||||
dist/
|
||||
dist-client/
|
||||
apidoc_build/
|
||||
content_cache/
|
||||
i18n_cache/
|
||||
node_modules/
|
||||
|
||||
# Old migrations, disabled
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true,
|
||||
},
|
||||
"extends": [
|
||||
"habitrpg",
|
||||
"habitrpg/esnext"
|
||||
],
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'habitrpg/lib/node'
|
||||
],
|
||||
}
|
||||
@@ -8,8 +8,13 @@
|
||||
|
||||
# Requesting a feature
|
||||
|
||||
Habitica uses [this Google form](https://docs.google.com/forms/d/e/1FAIpQLScPhrwq_7P1C6PTrI3lbvTsvqGyTNnGzp1ugi1Ml0PFee_p5g/viewform?usp=sf_link) to track feature requests. Please post there rather than creating an issue.
|
||||
Habitica uses [Trello](https://trello.com/b/EpoYEYod/habitica) to track feature requests. [Read more](https://trello.com/c/odmhIqyW/440-read-first-table-of-contents).
|
||||
|
||||
# Contributing Code
|
||||
|
||||
See [Contributing to Habitica](http://habitica.fandom.com/wiki/Contributing_to_Habitica#Coders_.28Web_.26_Mobile.29)
|
||||
|
||||
## Issue Triage [](https://www.codetriage.com/habitrpg/habitica)
|
||||
|
||||
You can triage issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to habitrpg on CodeTriage](https://www.codetriage.com/habitrpg/habitica).
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[//]: # (Note: See http://habitica.fandom.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_number_here
|
||||
Fixes put_#_and_issue_numer_here
|
||||
|
||||
### Changes
|
||||
[//]: # (Describe the changes that were made in detail here. Include pictures if necessary)
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
name: Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run lint-no-fix
|
||||
apidoc:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run apidoc
|
||||
sanity:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run test:sanity
|
||||
|
||||
common:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run test:common
|
||||
content:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run test:content
|
||||
|
||||
api-unit:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
mongodb-version: [4.2]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
|
||||
uses: supercharge/mongodb-github-action@1.3.0
|
||||
with:
|
||||
mongodb-version: ${{ matrix.mongodb-version }}
|
||||
mongodb-replica-set: rs
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run test:api:unit
|
||||
env:
|
||||
REQUIRES_SERVER=true: true
|
||||
api-v3-integration:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
mongodb-version: [4.2]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
|
||||
uses: supercharge/mongodb-github-action@1.3.0
|
||||
with:
|
||||
mongodb-version: ${{ matrix.mongodb-version }}
|
||||
mongodb-replica-set: rs
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run test:api-v3:integration
|
||||
env:
|
||||
REQUIRES_SERVER=true: true
|
||||
api-v4-integration:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
mongodb-version: [4.2]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
|
||||
uses: supercharge/mongodb-github-action@1.3.0
|
||||
with:
|
||||
mongodb-version: ${{ matrix.mongodb-version }}
|
||||
mongodb-replica-set: rs
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run test:api-v4:integration
|
||||
env:
|
||||
REQUIRES_SERVER=true: true
|
||||
|
||||
client-unit:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cp config.json.example config.json
|
||||
- name: npm install
|
||||
run: |
|
||||
npm ci
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: test
|
||||
- run: npm run test:unit
|
||||
working-directory: ./website/client
|
||||
+10
-11
@@ -1,16 +1,22 @@
|
||||
.DS_Store
|
||||
website/client-old/gen
|
||||
website/client-old/common
|
||||
website/client-old/apidoc
|
||||
website/build
|
||||
website/client-old/js/habitrpg-shared.js*
|
||||
website/client-old/css/habitrpg-shared.css
|
||||
website/transpiled-babel/
|
||||
website/common/transpiled-babel/
|
||||
node_modules
|
||||
content_cache
|
||||
i18n_cache
|
||||
apidoc_build
|
||||
*.swp
|
||||
.idea*
|
||||
config.json
|
||||
npm-debug.log*
|
||||
lib
|
||||
website/client-old/bower_components
|
||||
website/client-old/new-stuff.html
|
||||
newrelic_agent.log
|
||||
.bower-tmp
|
||||
.bower-registry
|
||||
@@ -21,13 +27,15 @@ TODO
|
||||
*.log
|
||||
src/*/*.map
|
||||
src/*/*/*.map
|
||||
test/*.js
|
||||
test/*.map
|
||||
website/client-old/docs
|
||||
*.sublime-workspace
|
||||
coverage
|
||||
coverage.html
|
||||
common/dist/scripts/*
|
||||
dist
|
||||
dist-client
|
||||
website/client/dist
|
||||
test/client/unit/coverage
|
||||
test/client/e2e/reports
|
||||
test/client-old/spec/mocks/translations.js
|
||||
@@ -38,12 +46,3 @@ yarn.lock
|
||||
.elasticbeanstalk/*
|
||||
!.elasticbeanstalk/*.cfg.yml
|
||||
!.elasticbeanstalk/*.global.yml
|
||||
|
||||
/.vscode
|
||||
|
||||
# webstorm fake webpack for path intellisense
|
||||
webpack.webstorm.config
|
||||
|
||||
# mongodb replica set for local dev
|
||||
mongodb-*.tgz
|
||||
/mongodb-data
|
||||
|
||||
+11
-3
@@ -1,12 +1,20 @@
|
||||
node_modules/**
|
||||
content_cache
|
||||
content_cache/**
|
||||
.bower-cache/**
|
||||
.bower-tmp/**
|
||||
.bower-registry/**
|
||||
website/client-old/**
|
||||
website/client/**
|
||||
website/client/store/**
|
||||
website/views/**
|
||||
website/build/**
|
||||
dist/**
|
||||
test/**
|
||||
.git/**
|
||||
Gruntfile.js
|
||||
CHANGELOG.md
|
||||
.idea*
|
||||
*.log
|
||||
newrelic_agent.log
|
||||
*.swp
|
||||
*.swx
|
||||
website/raw_sprites/**
|
||||
content_cache/**
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- '12'
|
||||
services:
|
||||
- mongodb
|
||||
cache:
|
||||
directories:
|
||||
- 'node_modules'
|
||||
addons:
|
||||
chrome: stable
|
||||
before_script:
|
||||
- npm run test:build
|
||||
- cp config.json.example config.json
|
||||
- sleep 5
|
||||
script:
|
||||
- npm run $TEST
|
||||
env:
|
||||
global:
|
||||
- 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:sanity"
|
||||
- TEST="test:content" COVERAGE=true
|
||||
- TEST="test:common" COVERAGE=true
|
||||
- TEST="client:unit" COVERAGE=true
|
||||
- TEST="apidoc"
|
||||
+6
-5
@@ -1,7 +1,6 @@
|
||||
FROM node:14
|
||||
FROM node:12
|
||||
|
||||
ENV ADMIN_EMAIL admin@habitica.com
|
||||
ENV EMAILS_COMMUNITY_MANAGER_EMAIL admin@habitica.com
|
||||
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
|
||||
ENV AMAZON_PAYMENTS_SELLER_ID AMQ3SB4SG5E91
|
||||
ENV AMPLITUDE_KEY e8d4c24b3d6ef3ee73eeba715023dd43
|
||||
@@ -12,7 +11,6 @@ ENV GOOGLE_CLIENT_ID 1035232791481-32vtplgnjnd1aufv3mcu1lthf31795fq.apps.googleu
|
||||
ENV LOGGLY_CLIENT_TOKEN ab5663bf-241f-4d14-8783-7d80db77089a
|
||||
ENV NODE_ENV production
|
||||
ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
|
||||
ENV APPLE_AUTH_CLIENT_ID 9Q9SMRMCNN.com.habitrpg.ios.Habitica
|
||||
|
||||
# Install global packages
|
||||
RUN npm install -g gulp-cli mocha
|
||||
@@ -21,9 +19,12 @@ RUN npm install -g gulp-cli mocha
|
||||
RUN mkdir -p /usr/src/habitrpg
|
||||
WORKDIR /usr/src/habitrpg
|
||||
RUN git clone --branch release --depth 1 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
||||
RUN npm set unsafe-perm true
|
||||
RUN npm install
|
||||
RUN gulp build:prod --force
|
||||
|
||||
# Create Build dir
|
||||
RUN mkdir -p ./website/build
|
||||
|
||||
# Start Habitica
|
||||
EXPOSE 80 8080 36612
|
||||
EXPOSE 3000
|
||||
CMD ["node", "./website/transpiled-babel/index.js"]
|
||||
|
||||
+5
-14
@@ -1,14 +1,5 @@
|
||||
FROM node:14
|
||||
|
||||
# Install global packages
|
||||
RUN npm install -g gulp-cli mocha
|
||||
|
||||
# Copy package.json and package-lock.json into image, then install
|
||||
# dependencies.
|
||||
WORKDIR /usr/src/habitica
|
||||
COPY ["package.json", "package-lock.json", "./"]
|
||||
RUN npm install
|
||||
|
||||
# Copy the remaining source files in.
|
||||
COPY . /usr/src/habitica
|
||||
RUN npm run postinstall
|
||||
FROM node:12
|
||||
WORKDIR /code
|
||||
COPY package*.json /code/
|
||||
RUN npm install
|
||||
RUN npm install -g gulp-cli mocha
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
* Code is GPL v3 licensed:
|
||||
This Source Code is subject to the terms of the GNU General Public License, v. 3.0.
|
||||
If a copy of the GPL was not distributed with this file, you can obtain one at http://www.gnu.org/licenses/gpl-3.0.txt
|
||||
If a copy of the GPL was not distributed with this file, You can obtain one at http://www.gnu.org/licenses/gpl-3.0.txt
|
||||
|
||||
* Assets and content designed for Mozilla BrowserQuest are licensed under CC-BY-SA 3.0:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Habitica  [](https://codeclimate.com/github/HabitRPG/habitrpg) [](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE)
|
||||
Habitica [](https://travis-ci.org/HabitRPG/habitica) [](https://codeclimate.com/github/HabitRPG/habitrpg) [](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE) [](https://www.codetriage.com/habitrpg/habitica)
|
||||
===============
|
||||
|
||||
[](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. The wiki pages below and the additional pages they link to will tell you how to get started on contributing code and where you can go to seek further help or ask questions:
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# Vagrant #
|
||||
|
||||
Vagrant is a system to create reproducible and portable development
|
||||
environments. Because of the variety of systems used for Habitica
|
||||
development and the various issues developers may encounter setting up
|
||||
Habitica on them, vagrant provides a single development enviroment with
|
||||
minimal dependencies on the developer's local platform. It can be used
|
||||
on a variety of systems including Windows, Mac OS X, and Linux.
|
||||
|
||||
Instructions for using the Habitica Vagrant environment are in
|
||||
[Setting up Habitica Locally](http://habitica.fandom.com/wiki/Setting_up_Habitica_Locally).
|
||||
@@ -0,0 +1,22 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
config.vm.provider "virtualbox" do |v|
|
||||
v.memory = 4096
|
||||
v.cpus = 1
|
||||
v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/vagrant", "1"]
|
||||
end
|
||||
config.vm.box = "thepeopleseason/habitrpg"
|
||||
config.ssh.forward_agent = true
|
||||
|
||||
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
|
||||
@@ -2,10 +2,6 @@
|
||||
"name": "Habitica V3 API Documentation",
|
||||
"title": "Habitica",
|
||||
"url": "https://habitica.com",
|
||||
"header": {
|
||||
"title": "Introduction",
|
||||
"filename": "apidoc/header.md"
|
||||
},
|
||||
"template": {
|
||||
"withCompare": false
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Introduction
|
||||
|
||||
This webpage includes the documentation for version 3 of the [Habitica](https://habitica.com) API.
|
||||
|
||||
If you're developing a 3rd party tool that uses the Habitica API you should read the [Guidance for Comrades](https://habitica.fandom.com/wiki/Guidance_for_Comrades) and in particular the section called [Rules for Third-Party Tools](https://habitica.fandom.com/wiki/Guidance_for_Comrades#Rules_for_Third-Party_Tools) which includes suggestions on how to best use the API and the rules to follow when interacting with it.
|
||||
+3
-15
@@ -32,9 +32,7 @@
|
||||
"LOGGLY_SUBDOMAIN": "example-subdomain",
|
||||
"LOGGLY_TOKEN": "example-token",
|
||||
"MAINTENANCE_MODE": "false",
|
||||
"NODE_DB_URI": "mongodb://localhost:27017/habitica-dev?replicaSet=rs",
|
||||
"TEST_DB_URI": "mongodb://localhost:27017/habitica-test?replicaSet=rs",
|
||||
"MONGODB_POOL_SIZE": "10",
|
||||
"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",
|
||||
@@ -71,19 +69,9 @@
|
||||
"SLACK_URL": "https://hooks.slack.com/services/some-url",
|
||||
"STRIPE_API_KEY": "aaaabbbbccccddddeeeeffff00001111",
|
||||
"STRIPE_PUB_KEY": "22223333444455556666777788889999",
|
||||
"STRIPE_WEBHOOKS_ENDPOINT_SECRET": "111111",
|
||||
"TEST_DB_URI": "mongodb://localhost/habitrpg_test",
|
||||
"TRANSIFEX_SLACK_CHANNEL": "transifex",
|
||||
"WEB_CONCURRENCY": 1,
|
||||
"SKIP_SSL_CHECK_KEY": "key",
|
||||
"ENABLE_STACKDRIVER_TRACING": "false",
|
||||
"APPLE_AUTH_PRIVATE_KEY": "",
|
||||
"APPLE_TEAM_ID": "",
|
||||
"APPLE_AUTH_CLIENT_ID": "",
|
||||
"APPLE_AUTH_KEY_ID": "",
|
||||
"BLOCKED_IPS": "",
|
||||
"LOG_AMPLITUDE_EVENTS": "false",
|
||||
"RATE_LIMITER_ENABLED": "false",
|
||||
"REDIS_HOST": "aaabbbcccdddeeefff",
|
||||
"REDIS_PORT": "1234",
|
||||
"REDIS_PASSWORD": "12345678"
|
||||
"ENABLE_STACKDRIVER_TRACING": "false"
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@ services:
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- .:/usr/src/habitica
|
||||
- /usr/src/habitica/node_modules
|
||||
- /usr/src/habitica/website/client/node_modules
|
||||
- .:/code
|
||||
- /code/node_modules
|
||||
server:
|
||||
build:
|
||||
context: .
|
||||
@@ -33,10 +32,10 @@ services:
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- .:/usr/src/habitica
|
||||
- /usr/src/habitica/node_modules
|
||||
- .:/code
|
||||
- /code/node_modules
|
||||
mongo:
|
||||
image: mongo:3.6
|
||||
image: mongo:3.4
|
||||
networks:
|
||||
- habitica
|
||||
ports:
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ services:
|
||||
- mongo
|
||||
|
||||
mongo:
|
||||
image: mongo:3.6
|
||||
image: mongo:3.4
|
||||
ports:
|
||||
- "27017:27017"
|
||||
networks:
|
||||
|
||||
+6
-4
@@ -4,12 +4,12 @@ import apidoc from 'apidoc';
|
||||
|
||||
const APIDOC_DEST_PATH = './apidoc_build';
|
||||
const APIDOC_SRC_PATH = './website/server';
|
||||
gulp.task('apidoc:clean', done => {
|
||||
gulp.task('apidoc:clean', (done) => {
|
||||
clean(APIDOC_DEST_PATH, done);
|
||||
});
|
||||
|
||||
gulp.task('apidoc', gulp.series('apidoc:clean', done => {
|
||||
const result = apidoc.createDoc({
|
||||
gulp.task('apidoc', gulp.series('apidoc:clean', (done) => {
|
||||
let result = apidoc.createDoc({
|
||||
src: APIDOC_SRC_PATH,
|
||||
dest: APIDOC_DEST_PATH,
|
||||
});
|
||||
@@ -21,4 +21,6 @@ gulp.task('apidoc', gulp.series('apidoc:clean', done => {
|
||||
}
|
||||
}));
|
||||
|
||||
gulp.task('apidoc:watch', gulp.series('apidoc', done => gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, gulp.series('apidoc', done))));
|
||||
gulp.task('apidoc:watch', gulp.series('apidoc', (done) => {
|
||||
return gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, gulp.series('apidoc', done));
|
||||
}));
|
||||
|
||||
+30
-86
@@ -1,99 +1,43 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import gulp from 'gulp';
|
||||
import path from 'path';
|
||||
import babel from 'gulp-babel';
|
||||
import os from 'os';
|
||||
import fs from 'fs';
|
||||
import spawn from 'cross-spawn'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
import clean from 'rimraf';
|
||||
import webpackProductionBuild from '../webpack/build';
|
||||
|
||||
gulp.task('build:babel:server', () => gulp.src('website/server/**/*.js')
|
||||
.pipe(babel())
|
||||
.pipe(gulp.dest('website/transpiled-babel/')));
|
||||
|
||||
gulp.task('build:babel:common', () => gulp.src('website/common/script/**/*.js')
|
||||
.pipe(babel())
|
||||
.pipe(gulp.dest('website/common/transpiled-babel/')));
|
||||
|
||||
gulp.task('build:babel', gulp.parallel('build:babel:server', 'build:babel:common', done => done()));
|
||||
|
||||
gulp.task('build:cache', gulp.parallel(
|
||||
'cache:content',
|
||||
'cache:i18n',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
gulp.task('build:prod', gulp.series(
|
||||
'build:babel',
|
||||
'apidoc',
|
||||
'build:cache',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
// Due to this issue https://github.com/vkarpov15/run-rs/issues/45
|
||||
// When used on windows `run-rs` must first be run without the `--keep` option
|
||||
// in order to be setup correctly, afterwards it can be used.
|
||||
|
||||
const MONGO_PATH = path.join(__dirname, '/../mongodb-data/');
|
||||
|
||||
gulp.task('build:prepare-mongo', async () => {
|
||||
if (fs.existsSync(MONGO_PATH)) {
|
||||
// console.log('MongoDB data folder exists, skipping setup.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (os.platform() !== 'win32') {
|
||||
// console.log('Not on Windows, skipping MongoDB setup.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('MongoDB data folder is missing, setting up.'); // eslint-disable-line no-console
|
||||
|
||||
// use run-rs without --keep, kill it as soon as the replica set starts
|
||||
const runRsProcess = spawn('run-rs', ['-v', '4.2.8', '-l', 'ubuntu1804', '--dbpath', 'mongodb-data', '--number', '1', '--quiet']);
|
||||
|
||||
for await (const chunk of runRsProcess.stdout) {
|
||||
const stringChunk = chunk.toString();
|
||||
console.log(stringChunk); // eslint-disable-line no-console
|
||||
// kills the process after the replica set is setup
|
||||
if (stringChunk.includes('Started replica set')) {
|
||||
console.log('MongoDB setup correctly.'); // eslint-disable-line no-console
|
||||
runRsProcess.kill();
|
||||
}
|
||||
}
|
||||
|
||||
let error = '';
|
||||
for await (const chunk of runRsProcess.stderr) {
|
||||
const stringChunk = chunk.toString();
|
||||
error += stringChunk;
|
||||
}
|
||||
|
||||
const exitCode = await new Promise(resolve => {
|
||||
runRsProcess.on('close', resolve);
|
||||
});
|
||||
|
||||
if (exitCode || error.length > 0) {
|
||||
// remove any leftover files
|
||||
clean.sync(MONGO_PATH);
|
||||
|
||||
throw new Error(`Error running run-rs: ${error}`);
|
||||
}
|
||||
gulp.task('build:src', () => {
|
||||
return gulp.src('website/server/**/*.js')
|
||||
.pipe(babel())
|
||||
.pipe(gulp.dest('website/transpiled-babel/'));
|
||||
});
|
||||
|
||||
gulp.task('build:dev', gulp.series(
|
||||
'build:prepare-mongo',
|
||||
done => done(),
|
||||
gulp.task('build:common', () => {
|
||||
return gulp.src('website/common/script/**/*.js')
|
||||
.pipe(babel())
|
||||
.pipe(gulp.dest('website/common/transpiled-babel/'));
|
||||
});
|
||||
|
||||
gulp.task('build:server', gulp.series('build:src', 'build:common', done => done()));
|
||||
|
||||
// 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(
|
||||
'build:server',
|
||||
'build:client',
|
||||
'apidoc',
|
||||
done => done()
|
||||
));
|
||||
|
||||
const buildArgs = [];
|
||||
let buildArgs = [];
|
||||
|
||||
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
|
||||
buildArgs.push('build:prod');
|
||||
} else if (process.env.NODE_ENV !== 'test') { // eslint-disable-line no-process-env
|
||||
buildArgs.push('build:dev');
|
||||
}
|
||||
|
||||
gulp.task('build', gulp.series(buildArgs, done => {
|
||||
gulp.task('build', gulp.series(buildArgs, (done) => {
|
||||
done();
|
||||
}));
|
||||
}));
|
||||
@@ -1,63 +0,0 @@
|
||||
import gulp from 'gulp';
|
||||
import fs from 'fs';
|
||||
|
||||
// TODO parallelize, use gulp file helpers
|
||||
gulp.task('cache:content', done => {
|
||||
// Requiring at runtime because these files access `common`
|
||||
// code which in production works only if transpiled so after
|
||||
// gulp build:babel:common has run
|
||||
const { CONTENT_CACHE_PATH, getLocalizedContentResponse } = require('../website/server/libs/content'); // eslint-disable-line global-require
|
||||
const { langCodes } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
|
||||
|
||||
try {
|
||||
// create the cache folder (if it doesn't exist)
|
||||
try {
|
||||
fs.mkdirSync(CONTENT_CACHE_PATH);
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err;
|
||||
}
|
||||
|
||||
// clone the content for each language and save
|
||||
// localize it
|
||||
// save the result
|
||||
langCodes.forEach(langCode => {
|
||||
fs.writeFileSync(
|
||||
`${CONTENT_CACHE_PATH}${langCode}.json`,
|
||||
getLocalizedContentResponse(langCode),
|
||||
'utf8',
|
||||
);
|
||||
});
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('cache:i18n', done => {
|
||||
// Requiring at runtime because these files access `common`
|
||||
// code which in production works only if transpiled so after
|
||||
// gulp build:babel:common has run
|
||||
const { BROWSER_SCRIPT_CACHE_PATH, geti18nBrowserScript } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
|
||||
const { langCodes } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
|
||||
|
||||
try {
|
||||
// create the cache folder (if it doesn't exist)
|
||||
try {
|
||||
fs.mkdirSync(BROWSER_SCRIPT_CACHE_PATH);
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err;
|
||||
}
|
||||
|
||||
// create and save the i18n browser script for each language
|
||||
langCodes.forEach(languageCode => {
|
||||
fs.writeFileSync(
|
||||
`${BROWSER_SCRIPT_CACHE_PATH}${languageCode}.js`,
|
||||
geti18nBrowserScript(languageCode),
|
||||
'utf8',
|
||||
);
|
||||
});
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
+23
-32
@@ -1,52 +1,43 @@
|
||||
import mongoose from 'mongoose';
|
||||
import nconf from 'nconf';
|
||||
import repl from 'repl';
|
||||
import gulp from 'gulp';
|
||||
import logger from '../website/server/libs/logger';
|
||||
import {
|
||||
getDevelopmentConnectionUrl,
|
||||
getDefaultConnectionOptions,
|
||||
} from '../website/server/libs/mongodb';
|
||||
import logger from '../website/server/libs/logger';
|
||||
import nconf from 'nconf';
|
||||
import repl from 'repl';
|
||||
import gulp from 'gulp';
|
||||
|
||||
// Add additional properties to the repl's context
|
||||
const improveRepl = context => {
|
||||
let improveRepl = (context) => {
|
||||
// Let "exit" and "quit" terminate the console
|
||||
['exit', 'quit'].forEach(term => {
|
||||
Object.defineProperty(context, term, {
|
||||
get () { // eslint-disable-line getter-return
|
||||
process.exit();
|
||||
},
|
||||
});
|
||||
['exit', 'quit'].forEach((term) => {
|
||||
Object.defineProperty(context, term, { get () {
|
||||
process.exit();
|
||||
}});
|
||||
});
|
||||
|
||||
// "clear" clears the screen
|
||||
Object.defineProperty(context, 'clear', {
|
||||
get () { // eslint-disable-line getter-return
|
||||
process.stdout.write('\u001B[2J\u001B[0;0f');
|
||||
},
|
||||
});
|
||||
Object.defineProperty(context, 'clear', { get () {
|
||||
process.stdout.write('\u001B[2J\u001B[0;0f');
|
||||
}});
|
||||
|
||||
context.Challenge = require('../website/server/models/challenge').model; // eslint-disable-line global-require
|
||||
context.Group = require('../website/server/models/group').model; // eslint-disable-line global-require
|
||||
context.User = require('../website/server/models/user').model; // eslint-disable-line global-require
|
||||
|
||||
const IS_PROD = nconf.get('NODE_ENV') === 'production';
|
||||
const NODE_DB_URI = nconf.get('NODE_DB_URI');
|
||||
|
||||
const mongooseOptions = getDefaultConnectionOptions();
|
||||
const connectionUrl = IS_PROD ? NODE_DB_URI : getDevelopmentConnectionUrl(NODE_DB_URI);
|
||||
context.Group = require('../website/server/models/group').model; // eslint-disable-line global-require
|
||||
context.User = require('../website/server/models/user').model; // eslint-disable-line global-require
|
||||
|
||||
const isProd = nconf.get('NODE_ENV') === 'production';
|
||||
const mongooseOptions = !isProd ? {} : {
|
||||
keepAlive: 1,
|
||||
connectTimeoutMS: 30000,
|
||||
};
|
||||
mongoose.connect(
|
||||
connectionUrl,
|
||||
nconf.get('NODE_DB_URI'),
|
||||
mongooseOptions,
|
||||
err => {
|
||||
(err) => {
|
||||
if (err) throw err;
|
||||
logger.info('Connected with Mongoose');
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
gulp.task('console', done => {
|
||||
gulp.task('console', (done) => {
|
||||
improveRepl(repl.start({
|
||||
prompt: 'Habitica > ',
|
||||
}).context);
|
||||
|
||||
+39
-38
@@ -4,29 +4,29 @@ import spritesmith from 'gulp.spritesmith';
|
||||
import clean from 'rimraf';
|
||||
import sizeOf from 'image-size';
|
||||
import mergeStream from 'merge-stream';
|
||||
import { basename } from 'path';
|
||||
import { sync } from 'glob';
|
||||
import { each } from 'lodash';
|
||||
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;
|
||||
|
||||
const IMG_DIST_PATH = 'website/client/src/assets/images/sprites/';
|
||||
const CSS_DIST_PATH = 'website/client/src/assets/css/sprites/';
|
||||
const IMG_DIST_PATH = 'website/client/assets/images/sprites/';
|
||||
const CSS_DIST_PATH = 'website/client/assets/css/sprites/';
|
||||
|
||||
function checkForSpecialTreatment (name) {
|
||||
const regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame|^eyewear_special_\w+HalfMoon/;
|
||||
let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame|^eyewear_special_\w+HalfMoon/;
|
||||
return name.match(regex) || name === 'head_0';
|
||||
}
|
||||
|
||||
function calculateImgDimensions (img, addPadding) {
|
||||
let dims = sizeOf(img);
|
||||
|
||||
const requiresSpecialTreatment = checkForSpecialTreatment(img);
|
||||
let requiresSpecialTreatment = checkForSpecialTreatment(img);
|
||||
if (requiresSpecialTreatment) {
|
||||
const newWidth = dims.width < 90 ? 90 : dims.width;
|
||||
const newHeight = dims.height < 90 ? 90 : dims.height;
|
||||
let newWidth = dims.width < 90 ? 90 : dims.width;
|
||||
let newHeight = dims.height < 90 ? 90 : dims.height;
|
||||
dims = {
|
||||
width: newWidth,
|
||||
height: newHeight,
|
||||
@@ -41,17 +41,17 @@ function calculateImgDimensions (img, addPadding) {
|
||||
|
||||
if (!dims.width || !dims.height) console.error('MISSING DIMENSIONS:', dims); // eslint-disable-line no-console
|
||||
|
||||
const totalPixelSize = dims.width * dims.height + padding;
|
||||
let totalPixelSize = dims.width * dims.height + padding;
|
||||
|
||||
return totalPixelSize;
|
||||
}
|
||||
|
||||
function calculateSpritesheetsSrcIndicies (src) {
|
||||
let totalPixels = 0;
|
||||
const slices = [0];
|
||||
let slices = [0];
|
||||
|
||||
each(src, (img, index) => {
|
||||
const imageSize = calculateImgDimensions(img, true);
|
||||
let imageSize = calculateImgDimensions(img, true);
|
||||
totalPixels += imageSize;
|
||||
|
||||
if (totalPixels > MAX_SPRITESHEET_SIZE) {
|
||||
@@ -64,35 +64,37 @@ function calculateSpritesheetsSrcIndicies (src) {
|
||||
}
|
||||
|
||||
function cssVarMap (sprite) {
|
||||
// For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class,
|
||||
// which works as a 60x60 image pointing at the proper part of the 90x90 sprite.
|
||||
// For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class, which works as a
|
||||
// 60x60 image pointing at the proper part of the 90x90 sprite.
|
||||
// We set up the custom info here, and the template makes use of it.
|
||||
const requiresSpecialTreatment = checkForSpecialTreatment(sprite.name);
|
||||
let requiresSpecialTreatment = checkForSpecialTreatment(sprite.name);
|
||||
if (requiresSpecialTreatment) {
|
||||
sprite.custom = {
|
||||
px: {
|
||||
offsetX: `-${sprite.x + 25}px`,
|
||||
offsetY: `-${sprite.y + 15}px`,
|
||||
offsetX: `-${ sprite.x + 25 }px`,
|
||||
offsetY: `-${ sprite.y + 15 }px`,
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
},
|
||||
};
|
||||
}
|
||||
if (sprite.name.indexOf('shirt') !== -1) sprite.custom.px.offsetY = `-${sprite.y + 35}px`; // even more for shirts
|
||||
if (sprite.name.indexOf('shirt') !== -1)
|
||||
sprite.custom.px.offsetY = `-${ sprite.y + 35 }px`; // even more for shirts
|
||||
if (sprite.name.indexOf('hair_base') !== -1) {
|
||||
const styleArray = sprite.name.split('_').slice(2, 3);
|
||||
if (Number(styleArray[0]) > 14) sprite.custom.px.offsetY = `-${sprite.y}px`; // don't crop updos
|
||||
let styleArray = sprite.name.split('_').slice(2, 3);
|
||||
if (Number(styleArray[0]) > 14)
|
||||
sprite.custom.px.offsetY = `-${ sprite.y }px`; // don't crop updos
|
||||
}
|
||||
}
|
||||
|
||||
function createSpritesStream (name, src) {
|
||||
const spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src);
|
||||
const stream = mergeStream();
|
||||
let spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src);
|
||||
let stream = mergeStream();
|
||||
|
||||
each(spritesheetSliceIndicies, (start, index) => {
|
||||
const slicedSrc = src.slice(start, spritesheetSliceIndicies[index + 1]);
|
||||
let slicedSrc = src.slice(start, spritesheetSliceIndicies[index + 1]);
|
||||
|
||||
const spriteData = gulp.src(slicedSrc)
|
||||
let spriteData = gulp.src(slicedSrc)
|
||||
.pipe(spritesmith({
|
||||
imgName: `spritesmith-${name}-${index}.png`,
|
||||
cssName: `spritesmith-${name}-${index}.css`,
|
||||
@@ -102,12 +104,12 @@ function createSpritesStream (name, src) {
|
||||
cssVarMap,
|
||||
}));
|
||||
|
||||
const imgStream = spriteData.img
|
||||
let imgStream = spriteData.img
|
||||
.pipe(vinylBuffer())
|
||||
.pipe(imagemin())
|
||||
.pipe(gulp.dest(IMG_DIST_PATH));
|
||||
|
||||
const cssStream = spriteData.css
|
||||
let cssStream = spriteData.css
|
||||
.pipe(gulp.dest(CSS_DIST_PATH));
|
||||
|
||||
stream.add(imgStream);
|
||||
@@ -118,32 +120,32 @@ function createSpritesStream (name, src) {
|
||||
}
|
||||
|
||||
gulp.task('sprites:main', () => {
|
||||
const mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
|
||||
let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
|
||||
return createSpritesStream('main', mainSrc);
|
||||
});
|
||||
|
||||
gulp.task('sprites:largeSprites', () => {
|
||||
const largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png');
|
||||
let largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png');
|
||||
return createSpritesStream('largeSprites', largeSrc);
|
||||
});
|
||||
|
||||
gulp.task('sprites:clean', done => {
|
||||
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', gulp.series('sprites:main', 'sprites:largeSprites', (done) => {
|
||||
console.log('Verifiying that images do not exceed max dimensions'); // eslint-disable-line no-console
|
||||
|
||||
let numberOfSheetsThatAreTooBig = 0;
|
||||
|
||||
const distSpritesheets = sync(`${IMG_DIST_PATH}*.png`);
|
||||
let distSpritesheets = sync(`${IMG_DIST_PATH}*.png`);
|
||||
|
||||
each(distSpritesheets, img => {
|
||||
const spriteSize = calculateImgDimensions(img);
|
||||
each(distSpritesheets, (img) => {
|
||||
let spriteSize = calculateImgDimensions(img);
|
||||
|
||||
if (spriteSize > MAX_SPRITESHEET_SIZE) {
|
||||
numberOfSheetsThatAreTooBig += 1;
|
||||
const name = basename(img, '.png');
|
||||
numberOfSheetsThatAreTooBig++;
|
||||
let name = basename(img, '.png');
|
||||
console.error(`WARNING: ${name} might be too big - ${spriteSize} > ${MAX_SPRITESHEET_SIZE}`); // eslint-disable-line no-console
|
||||
}
|
||||
});
|
||||
@@ -153,12 +155,11 @@ gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprite
|
||||
console.error( // eslint-disable-line no-console
|
||||
`${numberOfSheetsThatAreTooBig} sheets might too big for mobile Safari to be able to handle
|
||||
them, but there is a margin of error in these calculations so it is probably okay. Mention
|
||||
this to an admin so they can test a staging site on mobile Safari after your PR is merged.`,
|
||||
);
|
||||
this to an admin so they can test a staging site on mobile Safari after your PR is merged.`);
|
||||
} 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:checkCompiledDimensions', done => done()));
|
||||
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions', done => done()));
|
||||
|
||||
+7
-2
@@ -1,11 +1,16 @@
|
||||
import gulp from 'gulp';
|
||||
import nodemon from 'gulp-nodemon';
|
||||
|
||||
import pkg from '../package.json';
|
||||
let pkg = require('../package.json');
|
||||
|
||||
gulp.task('nodemon', done => {
|
||||
gulp.task('nodemon', (done) => {
|
||||
nodemon({
|
||||
script: pkg.main,
|
||||
ignore: [
|
||||
'website/client-old/*',
|
||||
'website/views/*',
|
||||
'common/dist/script/content/*',
|
||||
],
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
+151
-93
@@ -1,74 +1,60 @@
|
||||
import mongoose from 'mongoose';
|
||||
import { exec } from 'child_process';
|
||||
import gulp from 'gulp';
|
||||
import os from 'os';
|
||||
import nconf from 'nconf';
|
||||
import { pipe } from './taskHelper';
|
||||
import {
|
||||
getDevelopmentConnectionUrl,
|
||||
getDefaultConnectionOptions,
|
||||
} from '../website/server/libs/mongodb';
|
||||
pipe,
|
||||
} from './taskHelper';
|
||||
import mongoose from 'mongoose';
|
||||
import { exec } from 'child_process';
|
||||
import gulp from 'gulp';
|
||||
import os from 'os';
|
||||
import nconf from 'nconf';
|
||||
|
||||
// TODO rewrite
|
||||
|
||||
const TEST_SERVER_PORT = 3003;
|
||||
const TEST_SERVER_PORT = 3003;
|
||||
let server;
|
||||
|
||||
const TEST_DB_URI = nconf.get('TEST_DB_URI');
|
||||
const TEST_DB_URI = nconf.get('TEST_DB_URI');
|
||||
|
||||
const SANITY_TEST_COMMAND = 'npm run test:sanity';
|
||||
const COMMON_TEST_COMMAND = 'npm run test:common';
|
||||
const CONTENT_TEST_COMMAND = 'npm run test:content';
|
||||
const LIMIT_MAX_BUFFER_OPTIONS = { maxBuffer: 1024 * 500 };
|
||||
const CONTENT_OPTIONS = {maxBuffer: 1024 * 500};
|
||||
|
||||
/* Helper method for reporting test summary */
|
||||
const testResults = [];
|
||||
const testCount = (stdout, regexp) => {
|
||||
const match = stdout.match(regexp);
|
||||
return parseInt(match && (match[1] || 0), 10);
|
||||
/* Helper methods for reporting test summary */
|
||||
let testResults = [];
|
||||
let testCount = (stdout, regexp) => {
|
||||
let match = stdout.match(regexp);
|
||||
return parseInt(match && match[1] || 0, 10);
|
||||
};
|
||||
|
||||
/* Helper methods to correctly run child test processes */
|
||||
const testBin = (string, additionalEnvVariables = '') => {
|
||||
let testBin = (string, additionalEnvVariables = '') => {
|
||||
if (os.platform() === 'win32') {
|
||||
if (additionalEnvVariables !== '') {
|
||||
additionalEnvVariables = additionalEnvVariables.split(' ').join('&&set '); // eslint-disable-line no-param-reassign
|
||||
additionalEnvVariables = `set ${additionalEnvVariables}&&`; // eslint-disable-line no-param-reassign
|
||||
additionalEnvVariables = additionalEnvVariables.split(' ').join('&&set ');
|
||||
additionalEnvVariables = `set ${additionalEnvVariables}&&`;
|
||||
}
|
||||
return `set NODE_ENV=test&&${additionalEnvVariables}${string}`;
|
||||
} else {
|
||||
return `NODE_ENV=test ${additionalEnvVariables} ${string}`;
|
||||
}
|
||||
return `NODE_ENV=test ${additionalEnvVariables} ${string}`;
|
||||
};
|
||||
|
||||
function runInChildProcess (command, options = {}, envVariables = '') {
|
||||
return done => pipe(exec(testBin(command, envVariables), options, done));
|
||||
}
|
||||
|
||||
function integrationTestCommand (testDir, coverageDir) {
|
||||
return `istanbul cover --dir coverage/${coverageDir} --report lcovonly node_modules/mocha/bin/_mocha -- ${testDir} --recursive --require ./test/helpers/start-server`;
|
||||
}
|
||||
|
||||
/* Test task definitions */
|
||||
gulp.task('test:nodemon', gulp.series(done => {
|
||||
gulp.task('test:nodemon', gulp.series(function setupNodemon (done) {
|
||||
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'));
|
||||
|
||||
gulp.task('test:prepare:mongo', cb => {
|
||||
const mongooseOptions = getDefaultConnectionOptions();
|
||||
const connectionUrl = getDevelopmentConnectionUrl(TEST_DB_URI);
|
||||
|
||||
mongoose.connect(connectionUrl, mongooseOptions, err => {
|
||||
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}`);
|
||||
return mongoose.connection.dropDatabase(err2 => {
|
||||
mongoose.connection.dropDatabase((err2) => {
|
||||
if (err2) return cb(err2);
|
||||
return mongoose.connection.close(cb);
|
||||
mongoose.connection.close(cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', done => {
|
||||
gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', (done) => {
|
||||
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) {
|
||||
@@ -87,21 +73,45 @@ gulp.task('test:prepare:build', gulp.series('build', done => done()));
|
||||
gulp.task('test:prepare', gulp.series(
|
||||
'test:prepare:build',
|
||||
'test:prepare:mongo',
|
||||
done => done(),
|
||||
done => done()
|
||||
));
|
||||
|
||||
gulp.task('test:sanity', runInChildProcess(SANITY_TEST_COMMAND));
|
||||
gulp.task('test:sanity', (cb) => {
|
||||
let runner = exec(
|
||||
testBin(SANITY_TEST_COMMAND),
|
||||
(err) => {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
cb();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:common', gulp.series('test:prepare:build', runInChildProcess(COMMON_TEST_COMMAND)));
|
||||
gulp.task('test:common', gulp.series('test:prepare:build', (cb) => {
|
||||
let runner = exec(
|
||||
testBin(COMMON_TEST_COMMAND),
|
||||
(err) => {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
cb();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
}));
|
||||
|
||||
gulp.task('test:common:clean', cb => {
|
||||
gulp.task('test:common:clean', (cb) => {
|
||||
pipe(exec(testBin(COMMON_TEST_COMMAND), () => cb()));
|
||||
});
|
||||
|
||||
gulp.task('test:common:watch', gulp.series('test:common:clean', () => gulp.watch(['common/script/**/*', 'test/common/**/*'], gulp.series('test:common:clean', done => done()))));
|
||||
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:safe', gulp.series('test:prepare:build', cb => {
|
||||
const runner = exec(
|
||||
gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => {
|
||||
let runner = exec(
|
||||
testBin(COMMON_TEST_COMMAND),
|
||||
(err, stdout) => { // eslint-disable-line handle-callback-err
|
||||
testResults.push({
|
||||
@@ -111,25 +121,38 @@ gulp.task('test:common:safe', gulp.series('test:prepare:build', cb => {
|
||||
pend: testCount(stdout, /(\d+) pending/),
|
||||
});
|
||||
cb();
|
||||
},
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
}));
|
||||
|
||||
gulp.task('test:content', gulp.series('test:prepare:build',
|
||||
runInChildProcess(CONTENT_TEST_COMMAND, LIMIT_MAX_BUFFER_OPTIONS)));
|
||||
gulp.task('test:content', gulp.series('test:prepare:build', (cb) => {
|
||||
let runner = exec(
|
||||
testBin(CONTENT_TEST_COMMAND),
|
||||
CONTENT_OPTIONS,
|
||||
(err) => {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
cb();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
}));
|
||||
|
||||
gulp.task('test:content:clean', cb => {
|
||||
pipe(exec(testBin(CONTENT_TEST_COMMAND), LIMIT_MAX_BUFFER_OPTIONS, () => cb()));
|
||||
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', () => gulp.watch(['common/script/content/**', 'test/**'], gulp.series('test:content:clean', done => done()))));
|
||||
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:safe', gulp.series('test:prepare:build', cb => {
|
||||
const runner = exec(
|
||||
gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
|
||||
let runner = exec(
|
||||
testBin(CONTENT_TEST_COMMAND),
|
||||
LIMIT_MAX_BUFFER_OPTIONS,
|
||||
(err, stdout) => { // eslint-disable-line handle-callback-err
|
||||
CONTENT_OPTIONS,
|
||||
(err, stdout) => { // eslint-disable-line handle-callback-err
|
||||
testResults.push({
|
||||
suite: 'Content Specs\t',
|
||||
pass: testCount(stdout, /(\d+) passing/),
|
||||
@@ -137,63 +160,98 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', cb => {
|
||||
pend: testCount(stdout, /(\d+) pending/),
|
||||
});
|
||||
cb();
|
||||
},
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
}));
|
||||
|
||||
gulp.task('test:api:unit:run',
|
||||
runInChildProcess(integrationTestCommand('test/api/unit', 'coverage/api-unit')));
|
||||
gulp.task('test:api: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'),
|
||||
(err) => {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit:run', done => done())));
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:api-v3:integration', gulp.series('test:prepare:mongo',
|
||||
runInChildProcess(
|
||||
integrationTestCommand('test/api/v3/integration', 'coverage/api-v3-integration'),
|
||||
LIMIT_MAX_BUFFER_OPTIONS,
|
||||
)));
|
||||
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:integration:watch', () => 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.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'),
|
||||
{maxBuffer: 500 * 1024},
|
||||
(err) => {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
gulp.task('test:api-v3:integration:separate-server', runInChildProcess(
|
||||
'mocha test/api/v3/integration --recursive --require ./test/helpers/start-server',
|
||||
LIMIT_MAX_BUFFER_OPTIONS,
|
||||
'LOAD_SERVER=0',
|
||||
));
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:api-v4:integration', gulp.series('test:prepare:mongo',
|
||||
runInChildProcess(
|
||||
integrationTestCommand('test/api/v4', 'api-v4-integration'),
|
||||
LIMIT_MAX_BUFFER_OPTIONS,
|
||||
)));
|
||||
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.task('test:api-v4:integration:separate-server', runInChildProcess(
|
||||
'mocha test/api/v4 --recursive --require ./test/helpers/start-server',
|
||||
LIMIT_MAX_BUFFER_OPTIONS,
|
||||
'LOAD_SERVER=0',
|
||||
));
|
||||
gulp.task('test:api-v3:integration:separate-server', (done) => {
|
||||
let runner = exec(
|
||||
testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
|
||||
{maxBuffer: 500 * 1024},
|
||||
(err) => done(err)
|
||||
);
|
||||
|
||||
gulp.task('test:api:unit', gulp.series(
|
||||
'test:prepare:mongo',
|
||||
'test:api:unit:run',
|
||||
done => 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();
|
||||
}
|
||||
);
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test', gulp.series(
|
||||
'test:sanity',
|
||||
'test:content',
|
||||
'test:common',
|
||||
'test:api:unit:run',
|
||||
'test:api:unit',
|
||||
'test:api-v3:integration',
|
||||
'test:api-v4:integration',
|
||||
done => done(),
|
||||
done => done()
|
||||
));
|
||||
|
||||
gulp.task('test:api-v3', gulp.series(
|
||||
'test:api:unit',
|
||||
'test:api-v3:integration',
|
||||
done => done(),
|
||||
done => done()
|
||||
));
|
||||
|
||||
+48
-51
@@ -1,6 +1,6 @@
|
||||
import fs from 'fs';
|
||||
import _ from 'lodash';
|
||||
import gulp from 'gulp';
|
||||
import fs from 'fs';
|
||||
import _ from 'lodash';
|
||||
import gulp from 'gulp';
|
||||
import { postToSlack, conf } from './taskHelper';
|
||||
|
||||
const SLACK_CONFIG = {
|
||||
@@ -12,8 +12,9 @@ const SLACK_CONFIG = {
|
||||
const LOCALES = './website/common/locales/';
|
||||
const ENGLISH_LOCALE = `${LOCALES}en/`;
|
||||
|
||||
|
||||
function getArrayOfLanguages () {
|
||||
const languages = fs.readdirSync(LOCALES);
|
||||
let languages = fs.readdirSync(LOCALES);
|
||||
languages.shift(); // Remove README.md from array of languages
|
||||
|
||||
return languages;
|
||||
@@ -22,16 +23,18 @@ function getArrayOfLanguages () {
|
||||
const ALL_LANGUAGES = getArrayOfLanguages();
|
||||
|
||||
function stripOutNonJsonFiles (collection) {
|
||||
const onlyJson = _.filter(collection, file => file.match(/[a-zA-Z]*\.json/));
|
||||
let onlyJson = _.filter(collection, (file) => {
|
||||
return file.match(/[a-zA-Z]*\.json/);
|
||||
});
|
||||
|
||||
return onlyJson;
|
||||
}
|
||||
|
||||
function eachTranslationFile (languages, cb) {
|
||||
const jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
|
||||
let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
|
||||
|
||||
_.each(languages, lang => {
|
||||
_.each(jsonFiles, filename => {
|
||||
_.each(languages, (lang) => {
|
||||
_.each(jsonFiles, (filename) => {
|
||||
let parsedTranslationFile;
|
||||
try {
|
||||
const translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
|
||||
@@ -40,10 +43,10 @@ function eachTranslationFile (languages, cb) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
const englishFile = fs.readFileSync(ENGLISH_LOCALE + filename);
|
||||
const parsedEnglishFile = JSON.parse(englishFile);
|
||||
let englishFile = fs.readFileSync(ENGLISH_LOCALE + filename);
|
||||
let parsedEnglishFile = JSON.parse(englishFile);
|
||||
|
||||
return cb(null, lang, filename, parsedEnglishFile, parsedTranslationFile);
|
||||
cb(null, lang, filename, parsedEnglishFile, parsedTranslationFile);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -68,9 +71,9 @@ function formatMessageForPosting (msg, items) {
|
||||
}
|
||||
|
||||
function getStringsWith (json, interpolationRegex) {
|
||||
const strings = {};
|
||||
let strings = {};
|
||||
|
||||
_.each(json, fileName => {
|
||||
_.each(json, (fileName) => {
|
||||
const rawFile = fs.readFileSync(ENGLISH_LOCALE + fileName);
|
||||
const parsedJson = JSON.parse(rawFile);
|
||||
|
||||
@@ -90,69 +93,66 @@ const malformedStringExceptions = {
|
||||
feedPet: true,
|
||||
};
|
||||
|
||||
gulp.task('transifex:missingFiles', done => {
|
||||
const missingStrings = [];
|
||||
gulp.task('transifex:missingFiles', (done) => {
|
||||
let missingStrings = [];
|
||||
|
||||
eachTranslationFile(ALL_LANGUAGES, error => {
|
||||
eachTranslationFile(ALL_LANGUAGES, (error) => {
|
||||
if (error) {
|
||||
missingStrings.push(error.path);
|
||||
}
|
||||
});
|
||||
|
||||
if (!_.isEmpty(missingStrings)) {
|
||||
const message = 'the following files were missing from the translations folder';
|
||||
const formattedMessage = formatMessageForPosting(message, missingStrings);
|
||||
let message = 'the following files were missing from the translations folder';
|
||||
let formattedMessage = formatMessageForPosting(message, missingStrings);
|
||||
postToSlack(formattedMessage, SLACK_CONFIG);
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('transifex:missingStrings', done => {
|
||||
const missingStrings = [];
|
||||
gulp.task('transifex:missingStrings', (done) => {
|
||||
let missingStrings = [];
|
||||
|
||||
eachTranslationString(ALL_LANGUAGES, (lang, filename, key, englishString, translationString) => {
|
||||
eachTranslationString(ALL_LANGUAGES, (language, filename, key, englishString, translationString) => {
|
||||
if (!translationString) {
|
||||
const errorString = `${lang} - ${filename} - ${key} - ${englishString}`;
|
||||
let errorString = `${language} - ${filename} - ${key} - ${englishString}`;
|
||||
missingStrings.push(errorString);
|
||||
}
|
||||
});
|
||||
|
||||
if (!_.isEmpty(missingStrings)) {
|
||||
const message = 'The following strings are not translated';
|
||||
const formattedMessage = formatMessageForPosting(message, missingStrings);
|
||||
let message = 'The following strings are not translated';
|
||||
let formattedMessage = formatMessageForPosting(message, missingStrings);
|
||||
postToSlack(formattedMessage, SLACK_CONFIG);
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('transifex:malformedStrings', done => {
|
||||
const jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
|
||||
const interpolationRegex = /<%= [a-zA-Z]* %>/g;
|
||||
const stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex);
|
||||
gulp.task('transifex:malformedStrings', (done) => {
|
||||
let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
|
||||
let interpolationRegex = /<%= [a-zA-Z]* %>/g;
|
||||
let stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex);
|
||||
|
||||
const stringsWithMalformedInterpolations = [];
|
||||
const stringsWithIncorrectNumberOfInterpolations = [];
|
||||
let stringsWithMalformedInterpolations = [];
|
||||
let stringsWithIncorrectNumberOfInterpolations = [];
|
||||
|
||||
_.each(ALL_LANGUAGES, lang => {
|
||||
_.each(ALL_LANGUAGES, (lang) => {
|
||||
_.each(stringsToLookFor, (strings, filename) => {
|
||||
const translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
|
||||
const parsedTranslationFile = JSON.parse(translationFile);
|
||||
let translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
|
||||
let parsedTranslationFile = JSON.parse(translationFile);
|
||||
|
||||
_.each(strings, (value, key) => { // eslint-disable-line max-nested-callbacks
|
||||
const translationString = parsedTranslationFile[key];
|
||||
let translationString = parsedTranslationFile[key];
|
||||
if (!translationString) return;
|
||||
|
||||
const englishOccurences = stringsToLookFor[filename][key];
|
||||
const translationOccurences = translationString.match(interpolationRegex);
|
||||
let englishOccurences = stringsToLookFor[filename][key];
|
||||
let translationOccurences = translationString.match(interpolationRegex);
|
||||
|
||||
if (!translationOccurences) {
|
||||
const malformedString = `${lang} - ${filename} - ${key} - ${translationString}`;
|
||||
let malformedString = `${lang} - ${filename} - ${key} - ${translationString}`;
|
||||
stringsWithMalformedInterpolations.push(malformedString);
|
||||
} else if (
|
||||
englishOccurences.length !== translationOccurences.length
|
||||
&& !malformedStringExceptions[key]
|
||||
) {
|
||||
const missingInterpolationString = `${lang} - ${filename} - ${key} - ${translationString}`;
|
||||
} else if (englishOccurences.length !== translationOccurences.length && !malformedStringExceptions[key]) {
|
||||
let missingInterpolationString = `${lang} - ${filename} - ${key} - ${translationString}`;
|
||||
stringsWithIncorrectNumberOfInterpolations.push(missingInterpolationString);
|
||||
}
|
||||
});
|
||||
@@ -160,17 +160,14 @@ gulp.task('transifex:malformedStrings', done => {
|
||||
});
|
||||
|
||||
if (!_.isEmpty(stringsWithMalformedInterpolations)) {
|
||||
const message = 'The following strings have malformed or missing interpolations';
|
||||
const formattedMessage = formatMessageForPosting(message, stringsWithMalformedInterpolations);
|
||||
let message = 'The following strings have malformed or missing interpolations';
|
||||
let formattedMessage = formatMessageForPosting(message, stringsWithMalformedInterpolations);
|
||||
postToSlack(formattedMessage, SLACK_CONFIG);
|
||||
}
|
||||
|
||||
if (!_.isEmpty(stringsWithIncorrectNumberOfInterpolations)) {
|
||||
const message = 'The following strings have a different number of string interpolations';
|
||||
const formattedMessage = formatMessageForPosting(
|
||||
message,
|
||||
stringsWithIncorrectNumberOfInterpolations,
|
||||
);
|
||||
let message = 'The following strings have a different number of string interpolations';
|
||||
let formattedMessage = formatMessageForPosting(message, stringsWithIncorrectNumberOfInterpolations);
|
||||
postToSlack(formattedMessage, SLACK_CONFIG);
|
||||
}
|
||||
done();
|
||||
@@ -179,5 +176,5 @@ gulp.task('transifex:malformedStrings', done => {
|
||||
gulp.task(
|
||||
'transifex',
|
||||
gulp.series('transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings'),
|
||||
done => done(),
|
||||
);
|
||||
(done) => done()
|
||||
);
|
||||
+23
-22
@@ -1,11 +1,11 @@
|
||||
import { exec } from 'child_process';
|
||||
import psTree from 'ps-tree';
|
||||
import nconf from 'nconf';
|
||||
import net from 'net';
|
||||
import { post } from 'superagent';
|
||||
import { sync as glob } from 'glob';
|
||||
import Mocha from 'mocha'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
import { resolve } from 'path';
|
||||
import { exec } from 'child_process';
|
||||
import psTree from 'ps-tree';
|
||||
import nconf from 'nconf';
|
||||
import net from 'net';
|
||||
import { post } from 'superagent';
|
||||
import { sync as glob } from 'glob';
|
||||
import Mocha from 'mocha';
|
||||
import { resolve } from 'path';
|
||||
|
||||
/*
|
||||
* Get access to configruable values
|
||||
@@ -19,15 +19,15 @@ export const conf = nconf;
|
||||
* its tasks.
|
||||
*/
|
||||
export function kill (proc) {
|
||||
const killProcess = pid => {
|
||||
let killProcess = (pid) => {
|
||||
psTree(pid, (_, pids) => {
|
||||
if (pids.length) {
|
||||
pids.forEach(kill); return;
|
||||
}
|
||||
try {
|
||||
exec(/^win/.test(process.platform)
|
||||
? `taskkill /PID ${pid} /T /F`
|
||||
: `kill -9 ${pid}`);
|
||||
exec(/^win/.test(process.platform) ?
|
||||
`taskkill /PID ${pid} /T /F` :
|
||||
`kill -9 ${pid}`);
|
||||
} catch (e) {
|
||||
console.log(e); // eslint-disable-line no-console
|
||||
}
|
||||
@@ -46,15 +46,16 @@ export function kill (proc) {
|
||||
export function awaitPort (port, max = 60) {
|
||||
return new Promise((rej, res) => {
|
||||
let socket;
|
||||
let timeout;
|
||||
let interval;
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
timeout = setTimeout(() => {
|
||||
clearInterval(interval);
|
||||
rej(`Timed out after ${max} seconds`);
|
||||
}, max * 1000);
|
||||
|
||||
interval = setInterval(() => {
|
||||
socket = net.connect({ port }, () => {
|
||||
socket = net.connect({port}, () => {
|
||||
clearInterval(interval);
|
||||
clearTimeout(timeout);
|
||||
socket.destroy();
|
||||
@@ -70,10 +71,10 @@ export function awaitPort (port, max = 60) {
|
||||
* Pipe the child's stdin and stderr to the parent process.
|
||||
*/
|
||||
export function pipe (child) {
|
||||
child.stdout.on('data', data => {
|
||||
child.stdout.on('data', (data) => {
|
||||
process.stdout.write(data);
|
||||
});
|
||||
child.stderr.on('data', data => {
|
||||
child.stderr.on('data', (data) => {
|
||||
process.stderr.write(data);
|
||||
});
|
||||
}
|
||||
@@ -82,7 +83,7 @@ export function pipe (child) {
|
||||
* Post request to notify configured slack channel
|
||||
*/
|
||||
export function postToSlack (msg, config = {}) {
|
||||
const slackUrl = nconf.get('SLACK_URL');
|
||||
let slackUrl = nconf.get('SLACK_URL');
|
||||
|
||||
if (!slackUrl) {
|
||||
console.error('No slack post url specified. Your message was:'); // eslint-disable-line no-console
|
||||
@@ -98,7 +99,7 @@ export function postToSlack (msg, config = {}) {
|
||||
text: msg,
|
||||
icon_emoji: `:${config.emoji || 'gulp'}:`, // eslint-disable-line camelcase
|
||||
})
|
||||
.end(err => {
|
||||
.end((err) => {
|
||||
if (err) console.error('Unable to post to slack', err); // eslint-disable-line no-console
|
||||
});
|
||||
}
|
||||
@@ -106,15 +107,15 @@ export function postToSlack (msg, config = {}) {
|
||||
export function runMochaTests (files, server, cb) {
|
||||
require('../test/helpers/globals.helper'); // eslint-disable-line global-require
|
||||
|
||||
const mocha = new Mocha({ reporter: 'spec' });
|
||||
const tests = glob(files);
|
||||
let mocha = new Mocha({reporter: 'spec'});
|
||||
let tests = glob(files);
|
||||
|
||||
tests.forEach(test => {
|
||||
tests.forEach((test) => {
|
||||
delete require.cache[resolve(test)];
|
||||
mocha.addFile(test);
|
||||
});
|
||||
|
||||
mocha.run(numberOfFailures => {
|
||||
mocha.run((numberOfFailures) => {
|
||||
if (!process.env.RUN_INTEGRATION_TEST_FOREVER) { // eslint-disable-line no-process-env
|
||||
if (server) kill(server);
|
||||
process.exit(numberOfFailures);
|
||||
|
||||
+2
-11
@@ -6,23 +6,14 @@
|
||||
* directory, and it will automatically be included.
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-commonjs */
|
||||
require('@babel/register');
|
||||
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-cache'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-build'); // eslint-disable-line global-require
|
||||
} else {
|
||||
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-cache'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-build'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-console'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-sprites'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-start'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-tests'); // eslint-disable-line global-require
|
||||
require('./gulp/gulp-transifex-test'); // eslint-disable-line global-require
|
||||
require('glob').sync('./gulp/gulp-*').forEach(require); // eslint-disable-line global-require
|
||||
require('gulp').task('default', gulp.series('test')); // eslint-disable-line global-require
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"root": false,
|
||||
"rules": {
|
||||
"no-console": 0,
|
||||
"no-use-before-define": ["error", { "functions": false }]
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
module.exports = {
|
||||
root: false,
|
||||
rules: {
|
||||
'no-console': 0,
|
||||
'no-use-before-define': ['error', { functions: false }]
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20191022_pet_color_achievements';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
let set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets) {
|
||||
const pets = user.items.pets;
|
||||
if (pets['Wolf-Zombie'] > 0
|
||||
&& pets['TigerCub-Zombie'] > 0
|
||||
&& pets['PandaCub-Zombie'] > 0
|
||||
&& pets['LionCub-Zombie'] > 0
|
||||
&& pets['Fox-Zombie'] > 0
|
||||
&& pets['FlyingPig-Zombie'] > 0
|
||||
&& pets['Dragon-Zombie'] > 0
|
||||
&& pets['Cactus-Zombie'] > 0
|
||||
&& pets['BearCub-Zombie'] > 0) {
|
||||
set['achievements.monsterMagus'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (user && user.items && user.items.mounts) {
|
||||
const mounts = user.items.mounts;
|
||||
if (mounts['Wolf-Zombie']
|
||||
&& mounts['TigerCub-Zombie']
|
||||
&& mounts['PandaCub-Zombie']
|
||||
&& mounts['LionCub-Zombie']
|
||||
&& mounts['Fox-Zombie']
|
||||
&& mounts['FlyingPig-Zombie']
|
||||
&& mounts['Dragon-Zombie']
|
||||
&& mounts['Cactus-Zombie']
|
||||
&& mounts['BearCub-Zombie'] ) {
|
||||
set['achievements.undeadUndertaker'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2019-10-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Award Habitoween ladder items to participants in this month's Habitoween festivities
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const MIGRATION_NAME = '20191031_habitoween_ladder'; // Update when running in future years
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
const inc = {
|
||||
'items.food.Candy_Skeleton': 1,
|
||||
'items.food.Candy_Base': 1,
|
||||
'items.food.Candy_CottonCandyBlue': 1,
|
||||
'items.food.Candy_CottonCandyPink': 1,
|
||||
'items.food.Candy_Shade': 1,
|
||||
'items.food.Candy_White': 1,
|
||||
'items.food.Candy_Golden': 1,
|
||||
'items.food.Candy_Zombie': 1,
|
||||
'items.food.Candy_Desert': 1,
|
||||
'items.food.Candy_Red': 1,
|
||||
};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Glow']) {
|
||||
set['items.mounts.JackOLantern-Glow'] = true;
|
||||
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Ghost']) {
|
||||
set['items.pets.JackOLantern-Glow'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Ghost']) {
|
||||
set['items.mounts.JackOLantern-Ghost'] = true;
|
||||
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Base']) {
|
||||
set['items.pets.JackOLantern-Ghost'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Base']) {
|
||||
set['items.mounts.JackOLantern-Base'] = true;
|
||||
} else {
|
||||
set['items.pets.JackOLantern-Base'] = 5;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-10-01')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Award Onboarding Achievements for existing users
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = '20191218_onboarding_achievements';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count += 1;
|
||||
|
||||
const set = {};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
const hasPet = Object.keys(user.items.pets).find(petKey => {
|
||||
const pet = user.items.pets[petKey];
|
||||
|
||||
if (pet >= 5) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (hasPet) {
|
||||
set['achievements.hatchedPet'] = true;
|
||||
}
|
||||
|
||||
const hasFedPet = Object.keys(user.items.pets).find(petKey => {
|
||||
const pet = user.items.pets[petKey];
|
||||
|
||||
if (pet > 5) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (hasFedPet) {
|
||||
set['achievements.fedPet'] = true;
|
||||
}
|
||||
|
||||
const hasGear = Object.keys(user.items.gear.owned).find(gearKey => {
|
||||
const gear = user.items.gear.owned[gearKey];
|
||||
|
||||
if (gear === true && gearKey.indexOf('_special_') === -1) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (hasGear) {
|
||||
set['achievements.purchasedEquipment'] = true;
|
||||
}
|
||||
|
||||
if (user.tasksOrder) {
|
||||
const hasTask = Object.keys(user.tasksOrder).find(tasksOrderType => {
|
||||
const order = user.tasksOrder[tasksOrderType];
|
||||
|
||||
if (order && order.length > 0) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (hasTask) {
|
||||
set['achievements.createdTask'] = true;
|
||||
}
|
||||
|
||||
const hasExperience = user.stats && user.stats.exp && user.stats.exp > 0;
|
||||
if (hasTask && hasExperience) {
|
||||
set['achievements.completedTask'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
return User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () { // eslint-disable-line import/no-commonjs
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
stats: 1,
|
||||
items: 1,
|
||||
achievements: 1,
|
||||
tasksOrder: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(100)
|
||||
.sort({ _id: 1 })
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,126 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20191127_harvest_feast';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
let inc;
|
||||
let push;
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (typeof user.items.gear.owned.head_special_turkeyHelmGilded !== 'undefined') {
|
||||
inc = {
|
||||
'items.food.Pie_Base': 1,
|
||||
'items.food.Pie_CottonCandyBlue': 1,
|
||||
'items.food.Pie_CottonCandyPink': 1,
|
||||
'items.food.Pie_Desert': 1,
|
||||
'items.food.Pie_Golden': 1,
|
||||
'items.food.Pie_Red': 1,
|
||||
'items.food.Pie_Shade': 1,
|
||||
'items.food.Pie_Skeleton': 1,
|
||||
'items.food.Pie_Zombie': 1,
|
||||
'items.food.Pie_White': 1,
|
||||
}
|
||||
} else if (typeof user.items.gear.owned.armor_special_turkeyArmorBase !== 'undefined') {
|
||||
set['items.gear.owned.head_special_turkeyHelmGilded'] = false;
|
||||
set['items.gear.owned.armor_special_turkeyArmorGilded'] = false;
|
||||
set['items.gear.owned.back_special_turkeyTailGilded'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_turkeyHelmGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.armor_special_turkeyArmorGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.back_special_turkeyTailGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (user.items && user.items.mounts && user.items.mounts['Turkey-Gilded']) {
|
||||
set['items.gear.owned.head_special_turkeyHelmBase'] = false;
|
||||
set['items.gear.owned.armor_special_turkeyArmorBase'] = false;
|
||||
set['items.gear.owned.back_special_turkeyTailBase'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_turkeyHelmBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.armor_special_turkeyArmorBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.back_special_turkeyTailBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (user.items && user.items.pets && user.items.pets['Turkey-Gilded']) {
|
||||
set['items.mounts.Turkey-Gilded'] = true;
|
||||
} else if (user.items && user.items.mounts && user.items.mounts['Turkey-Base']) {
|
||||
set['items.pets.Turkey-Gilded'] = 5;
|
||||
} else if (user.items && user.items.pets && user.items.pets['Turkey-Base']) {
|
||||
set['items.mounts.Turkey-Base'] = true;
|
||||
} else {
|
||||
set['items.pets.Turkey-Base'] = 5;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
if (inc) {
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
|
||||
} else if (push) {
|
||||
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
|
||||
} else {
|
||||
return await User.update({_id: user._id}, {$set: set}).exec();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-11-01')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20191210_pet_color_achievements';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
let set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets) {
|
||||
const pets = user.items.pets;
|
||||
if (pets['Wolf-White'] > 0
|
||||
&& pets['TigerCub-White'] > 0
|
||||
&& pets['PandaCub-White'] > 0
|
||||
&& pets['LionCub-White'] > 0
|
||||
&& pets['Fox-White'] > 0
|
||||
&& pets['FlyingPig-White'] > 0
|
||||
&& pets['Dragon-White'] > 0
|
||||
&& pets['Cactus-White'] > 0
|
||||
&& pets['BearCub-White'] > 0) {
|
||||
set['achievements.primedForPainting'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (user && user.items && user.items.mounts) {
|
||||
const mounts = user.items.mounts;
|
||||
if (mounts['Wolf-White']
|
||||
&& mounts['TigerCub-White']
|
||||
&& mounts['PandaCub-White']
|
||||
&& mounts['LionCub-White']
|
||||
&& mounts['Fox-White']
|
||||
&& mounts['FlyingPig-White']
|
||||
&& mounts['Dragon-White']
|
||||
&& mounts['Cactus-White']
|
||||
&& mounts['BearCub-White'] ) {
|
||||
set['achievements.pearlyPro'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2019-12-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,118 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20191231_nye';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {'flags.newStuff': true};
|
||||
let push;
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (typeof user.items.gear.owned.head_special_nye2018 !== 'undefined') {
|
||||
set['items.gear.owned.head_special_nye2019'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_nye2019',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (typeof user.items.gear.owned.head_special_nye2017 !== 'undefined') {
|
||||
set['items.gear.owned.head_special_nye2018'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_nye2018',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (typeof user.items.gear.owned.head_special_nye2016 !== 'undefined') {
|
||||
set['items.gear.owned.head_special_nye2017'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_nye2017',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (typeof user.items.gear.owned.head_special_nye2015 !== 'undefined') {
|
||||
set['items.gear.owned.head_special_nye2016'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_nye2016',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') {
|
||||
set['items.gear.owned.head_special_nye2015'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_nye2015',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') {
|
||||
set['items.gear.owned.head_special_nye2014'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_nye2014',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else {
|
||||
set['items.gear.owned.head_special_nye'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_nye',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,91 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200131_habit_birthday';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const 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,
|
||||
'achievements.habitBirthdays': 1,
|
||||
};
|
||||
const set = {};
|
||||
let push;
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (typeof user.items.gear.owned.armor_special_birthday2019 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2020'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2020', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2018 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2019'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2019', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2017 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2018'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2018', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2016 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2017'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2017', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2015 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2016'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2016', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2015'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2015', _id: uuid()}};
|
||||
} else {
|
||||
set['items.gear.owned.armor_special_birthday'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday', _id: uuid()}};
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set, $push: push}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-01-15')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,69 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200402_webhooks_add_protocol';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.webhooks && user.webhooks.length > 0) {
|
||||
user.webhooks.forEach(webhook => {
|
||||
// Make sure the protocol is set and valid
|
||||
if (webhook.url.startsWith('ftp')) {
|
||||
webhook.url = webhook.url.replace('ftp', 'https');
|
||||
}
|
||||
|
||||
if (!webhook.url.startsWith('http://') && !webhook.url.startsWith('https://')) {
|
||||
// the default in got 9 was https
|
||||
// see https://github.com/sindresorhus/got/commit/92bc8082137d7d085750359bbd76c801e213d7d2#diff-0730bb7c2e8f9ea2438b52e419dd86c9L111
|
||||
webhook.url = `https://${webhook.url}`;
|
||||
}
|
||||
});
|
||||
|
||||
set.webhooks = user.webhooks;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
webhooks: { $exists: true, $not: { $size: 0 } },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
webhooks: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,63 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200402_webhooks_reenable';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.webhooks && user.webhooks.length > 0) {
|
||||
user.webhooks.forEach(webhook => {
|
||||
// Re-enable webhooks disabled because of too many failures
|
||||
if (webhook.enabled === false && webhook.lastFailureAt === null) {
|
||||
webhook.enabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
set.webhooks = user.webhooks;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
webhooks: { $exists: true, $not: { $size: 0 } },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
webhooks: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200721_summer_splash_orcas';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
let set;
|
||||
|
||||
if (user && user.items && user.items.pets && typeof user.items.pets['Orca-Base'] !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME };
|
||||
} else if (user && user.items && user.items.mounts && typeof user.items.mounts['Orca-Base'] !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.pets.Orca-Base': 5 };
|
||||
} else {
|
||||
set = { migration: MIGRATION_NAME, 'items.mounts.Orca-Base': true };
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2020-06-21')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200731_naming_day';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
let set;
|
||||
let push;
|
||||
const inc = {
|
||||
'items.food.Cake_Base': 1,
|
||||
'items.food.Cake_CottonCandyBlue': 1,
|
||||
'items.food.Cake_CottonCandyPink': 1,
|
||||
'items.food.Cake_Desert': 1,
|
||||
'items.food.Cake_Golden': 1,
|
||||
'items.food.Cake_Red': 1,
|
||||
'items.food.Cake_Shade': 1,
|
||||
'items.food.Cake_Skeleton': 1,
|
||||
'items.food.Cake_White': 1,
|
||||
'items.food.Cake_Zombie': 1,
|
||||
'achievements.habiticaDays': 1,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.back_special_namingDay2020 !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME };
|
||||
} else if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.body_special_namingDay2018 !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.gear.owned.back_special_namingDay2020': false };
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.back_special_namingDay2020', _id: uuid() }};
|
||||
} else if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.head_special_namingDay2017 !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.gear.owned.body_special_namingDay2018': false };
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.body_special_namingDay2018', _id: uuid() }};
|
||||
} else if (user && user.items && user.items.pets && typeof user.items.pets['Gryphon-RoyalPurple'] !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.gear.owned.head_special_namingDay2017': false };
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.head_special_namingDay2017', _id: uuid() }};
|
||||
} else if (user && user.items && user.items.mounts && typeof user.items.mounts['Gryphon-RoyalPurple'] !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.pets.Gryphon-RoyalPurple': 5 };
|
||||
} else {
|
||||
set = { migration: MIGRATION_NAME, 'items.mounts.Gryphon-RoyalPurple': true };
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
if (push) {
|
||||
return await User.update({ _id: user._id }, { $set: set, $inc: inc, $push: push }).exec();
|
||||
} else {
|
||||
return await User.update({ _id: user._id }, { $set: set, $inc: inc }).exec();
|
||||
}
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2020-07-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200818_pet_color_achievements';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets) {
|
||||
const pets = user.items.pets;
|
||||
if (pets['Wolf-Golden'] > 0
|
||||
&& pets['TigerCub-Golden'] > 0
|
||||
&& pets['PandaCub-Golden'] > 0
|
||||
&& pets['LionCub-Golden'] > 0
|
||||
&& pets['Fox-Golden'] > 0
|
||||
&& pets['FlyingPig-Golden'] > 0
|
||||
&& pets['Dragon-Golden'] > 0
|
||||
&& pets['Cactus-Golden'] > 0
|
||||
&& pets['BearCub-Golden'] > 0) {
|
||||
set['achievements.goodAsGold'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (user && user.items && user.items.mounts) {
|
||||
const mounts = user.items.mounts;
|
||||
if (mounts['Wolf-Golden']
|
||||
&& mounts['TigerCub-Golden']
|
||||
&& mounts['PandaCub-Golden']
|
||||
&& mounts['LionCub-Golden']
|
||||
&& mounts['Fox-Golden']
|
||||
&& mounts['FlyingPig-Golden']
|
||||
&& mounts['Dragon-Golden']
|
||||
&& mounts['Cactus-Golden']
|
||||
&& mounts['BearCub-Golden'] ) {
|
||||
set['achievements.allThatGlitters'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2020-08-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20201020_pet_color_achievements';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets) {
|
||||
const pets = user.items.pets;
|
||||
if (pets['Wolf-Golden'] > 0
|
||||
&& pets['TigerCub-Skeleton'] > 0
|
||||
&& pets['PandaCub-Skeleton'] > 0
|
||||
&& pets['LionCub-Skeleton'] > 0
|
||||
&& pets['Fox-Skeleton'] > 0
|
||||
&& pets['FlyingPig-Skeleton'] > 0
|
||||
&& pets['Dragon-Skeleton'] > 0
|
||||
&& pets['Cactus-Skeleton'] > 0
|
||||
&& pets['BearCub-Skeleton'] > 0) {
|
||||
set['achievements.boneCollector'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (user && user.items && user.items.mounts) {
|
||||
const mounts = user.items.mounts;
|
||||
if (mounts['Wolf-Skeleton']
|
||||
&& mounts['TigerCub-Skeleton']
|
||||
&& mounts['PandaCub-Skeleton']
|
||||
&& mounts['LionCub-Skeleton']
|
||||
&& mounts['Fox-Skeleton']
|
||||
&& mounts['FlyingPig-Skeleton']
|
||||
&& mounts['Dragon-Skeleton']
|
||||
&& mounts['Cactus-Skeleton']
|
||||
&& mounts['BearCub-Skeleton'] ) {
|
||||
set['achievements.skeletonCrew'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2020-10-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Award Habitoween ladder items to participants in this month's Habitoween festivities
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const MIGRATION_NAME = '20201029_habitoween_ladder'; // Update when running in future years
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
const inc = {
|
||||
'items.food.Candy_Skeleton': 1,
|
||||
'items.food.Candy_Base': 1,
|
||||
'items.food.Candy_CottonCandyBlue': 1,
|
||||
'items.food.Candy_CottonCandyPink': 1,
|
||||
'items.food.Candy_Shade': 1,
|
||||
'items.food.Candy_White': 1,
|
||||
'items.food.Candy_Golden': 1,
|
||||
'items.food.Candy_Zombie': 1,
|
||||
'items.food.Candy_Desert': 1,
|
||||
'items.food.Candy_Red': 1,
|
||||
};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Glow']) {
|
||||
set['items.pets.JackOLantern-RoyalPurple'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Glow']) {
|
||||
set['items.mounts.JackOLantern-Glow'] = true;
|
||||
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Ghost']) {
|
||||
set['items.pets.JackOLantern-Glow'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Ghost']) {
|
||||
set['items.mounts.JackOLantern-Ghost'] = true;
|
||||
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Base']) {
|
||||
set['items.pets.JackOLantern-Ghost'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Base']) {
|
||||
set['items.mounts.JackOLantern-Base'] = true;
|
||||
} else {
|
||||
set['items.pets.JackOLantern-Base'] = 5;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2020-10-01')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Fix JackOLantern-Base for users that signed up recently
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const MIGRATION_NAME = '20201102_fix_habitoween'; // Update when running in future years
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
set['items.pets.JackOLantern-Base'] = 5;
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.created': {$gt: new Date('2020-10-26')},
|
||||
'items.pets.JackOLantern-Base': true,
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* All web users should be enrolled in the Drop Cap AB Test
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const MIGRATION_NAME = '20201103_drop_cap_ab_tweaks';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
const testGroup = Math.random();
|
||||
// Enroll 100% of users, splitting them 50/50
|
||||
const value = testGroup <= 0.50 ? 'drop-cap-notif-enabled' : 'drop-cap-notif-disabled';
|
||||
set['_ABtests.dropCapNotif'] = value;
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
return await User.update({_id: user._id}, {$set: set}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2020-10-10')},
|
||||
'_ABtests.dropCapNotif': 'drop-cap-notif-not-enrolled',
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
_ABtests: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20201124_pet_color_achievements';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets) {
|
||||
const pets = user.items.pets;
|
||||
if (pets['Wolf-Red'] > 0
|
||||
&& pets['TigerCub-Red'] > 0
|
||||
&& pets['PandaCub-Red'] > 0
|
||||
&& pets['LionCub-Red'] > 0
|
||||
&& pets['Fox-Red'] > 0
|
||||
&& pets['FlyingPig-Red'] > 0
|
||||
&& pets['Dragon-Red'] > 0
|
||||
&& pets['Cactus-Red'] > 0
|
||||
&& pets['BearCub-Red'] > 0) {
|
||||
set['achievements.seeingRed'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (user && user.items && user.items.mounts) {
|
||||
const mounts = user.items.mounts;
|
||||
if (mounts['Wolf-Red']
|
||||
&& mounts['TigerCub-Red']
|
||||
&& mounts['PandaCub-Red']
|
||||
&& mounts['LionCub-Red']
|
||||
&& mounts['Fox-Red']
|
||||
&& mounts['FlyingPig-Red']
|
||||
&& mounts['Dragon-Red']
|
||||
&& mounts['Cactus-Red']
|
||||
&& mounts['BearCub-Red'] ) {
|
||||
set['achievements.redLetterDay'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2020-11-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,126 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20201126_harvest_feast';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
let inc;
|
||||
let push;
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (typeof user.items.gear.owned.head_special_turkeyHelmGilded !== 'undefined') {
|
||||
inc = {
|
||||
'items.food.Pie_Base': 1,
|
||||
'items.food.Pie_CottonCandyBlue': 1,
|
||||
'items.food.Pie_CottonCandyPink': 1,
|
||||
'items.food.Pie_Desert': 1,
|
||||
'items.food.Pie_Golden': 1,
|
||||
'items.food.Pie_Red': 1,
|
||||
'items.food.Pie_Shade': 1,
|
||||
'items.food.Pie_Skeleton': 1,
|
||||
'items.food.Pie_Zombie': 1,
|
||||
'items.food.Pie_White': 1,
|
||||
}
|
||||
} else if (typeof user.items.gear.owned.armor_special_turkeyArmorBase !== 'undefined') {
|
||||
set['items.gear.owned.head_special_turkeyHelmGilded'] = false;
|
||||
set['items.gear.owned.armor_special_turkeyArmorGilded'] = false;
|
||||
set['items.gear.owned.back_special_turkeyTailGilded'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_turkeyHelmGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.armor_special_turkeyArmorGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.back_special_turkeyTailGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (user.items && user.items.mounts && user.items.mounts['Turkey-Gilded']) {
|
||||
set['items.gear.owned.head_special_turkeyHelmBase'] = false;
|
||||
set['items.gear.owned.armor_special_turkeyArmorBase'] = false;
|
||||
set['items.gear.owned.back_special_turkeyTailBase'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_turkeyHelmBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.armor_special_turkeyArmorBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.back_special_turkeyTailBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (user.items && user.items.pets && user.items.pets['Turkey-Gilded']) {
|
||||
set['items.mounts.Turkey-Gilded'] = true;
|
||||
} else if (user.items && user.items.mounts && user.items.mounts['Turkey-Base']) {
|
||||
set['items.pets.Turkey-Gilded'] = 5;
|
||||
} else if (user.items && user.items.pets && user.items.pets['Turkey-Base']) {
|
||||
set['items.mounts.Turkey-Base'] = true;
|
||||
} else {
|
||||
set['items.pets.Turkey-Base'] = 5;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
if (inc) {
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
|
||||
} else if (push) {
|
||||
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
|
||||
} else {
|
||||
return await User.update({_id: user._id}, {$set: set}).exec();
|
||||
}
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-11-01')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,110 @@
|
||||
import monk from 'monk';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const migrationName = 'mystery-items-201808.js'; // Update per month
|
||||
const authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Award this month's mystery items to subscribers
|
||||
*/
|
||||
const MYSTERY_ITEMS = ['armor_mystery_201810', 'head_mystery_201810'];
|
||||
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
|
||||
|
||||
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
|
||||
let UserNotification = require('../../website/server/models/userNotification').model;
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
let query = {
|
||||
migration: {$ne: migrationName},
|
||||
'purchased.plan.customerId': { $ne: null },
|
||||
$or: [
|
||||
{ 'purchased.plan.dateTerminated': { $gte: new Date() } },
|
||||
{ 'purchased.plan.dateTerminated': { $exists: false } },
|
||||
{ 'purchased.plan.dateTerminated': { $eq: null } },
|
||||
],
|
||||
};
|
||||
|
||||
if (lastId) {
|
||||
query._id = {
|
||||
$gt: lastId,
|
||||
};
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
fields: [
|
||||
], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return;
|
||||
}
|
||||
|
||||
let userPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(() => {
|
||||
processUsers(lastUser._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const addToSet = {
|
||||
'purchased.plan.mysteryItems': {
|
||||
$each: MYSTERY_ITEMS,
|
||||
},
|
||||
};
|
||||
const push = {
|
||||
notifications: (new UserNotification({
|
||||
type: 'NEW_MYSTERY_ITEMS',
|
||||
data: {
|
||||
MYSTERY_ITEMS,
|
||||
},
|
||||
})).toJSON(),
|
||||
};
|
||||
|
||||
dbUsers.update({_id: user._id}, {$addToSet: addToSet, $push: push});
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } 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);
|
||||
}
|
||||
|
||||
module.exports = processUsers;
|
||||
@@ -1,93 +0,0 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
const request = require('superagent');
|
||||
const last = require('lodash/last');
|
||||
const AWS = require('aws-sdk');
|
||||
|
||||
const config = require('../config');
|
||||
|
||||
const S3_DIRECTORY = 'mobileApp/images'; // config.S3.SPRITES_DIRECTORY;
|
||||
|
||||
AWS.config.update({
|
||||
accessKeyId: config.S3.accessKeyId,
|
||||
secretAccessKey: config.S3.secretAccessKey,
|
||||
// region: config.get('S3_REGION'),
|
||||
});
|
||||
|
||||
const BUCKET_NAME = config.S3.bucket;
|
||||
const s3 = new AWS.S3();
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/22210077/2601552
|
||||
function uploadFile (buffer, fileName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
s3.putObject({
|
||||
Body: buffer,
|
||||
Key: fileName,
|
||||
Bucket: BUCKET_NAME,
|
||||
}, error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
// console.info(`${fileName} uploaded to ${BUCKET_NAME} successfully.`);
|
||||
resolve(fileName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFileName (file) {
|
||||
const piecesOfPath = file.split('/');
|
||||
const name = last(piecesOfPath);
|
||||
const fullName = S3_DIRECTORY + name;
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
function getFileFromUrl (url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.get(url).end((err, res) => {
|
||||
if (err) return reject(err);
|
||||
const file = res.body;
|
||||
return resolve(file);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let commit = '78f94e365c72cc58f66857d5941105638db7d35c';
|
||||
commit = 'df0dbaba636c9ce424cc7040f7bd7fc1aa311015';
|
||||
const gihuburl = `https://api.github.com/repos/HabitRPG/habitica/commits/${commit}`;
|
||||
|
||||
|
||||
let currentIndex = 0;
|
||||
|
||||
function uploadToS3 (start, end, filesUrls) {
|
||||
const urls = filesUrls.slice(start, end);
|
||||
|
||||
if (urls.length === 0) {
|
||||
console.log('done');
|
||||
return;
|
||||
}
|
||||
|
||||
const promises = urls.map(fullUrl => getFileFromUrl(fullUrl)
|
||||
.then(buffer => uploadFile(buffer, getFileName(fullUrl))));
|
||||
console.log(promises.length);
|
||||
|
||||
Promise.all(promises)
|
||||
.then(() => {
|
||||
currentIndex += 50;
|
||||
uploadToS3(currentIndex, currentIndex + 50, filesUrls);
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
request.get(gihuburl)
|
||||
.end((err, res) => {
|
||||
console.log(err);
|
||||
const { files } = res.body;
|
||||
|
||||
let filesUrls = [''];
|
||||
filesUrls = files.map(file => file.raw_url);
|
||||
|
||||
uploadToS3(currentIndex, currentIndex + 50, filesUrls);
|
||||
});
|
||||
@@ -2,15 +2,15 @@ import { model as Challenges } from '../../website/server/models/challenge';
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
async function syncChallengeToMembers (challenges) {
|
||||
const challengSyncPromises = challenges.map(async challenge => {
|
||||
const users = await User.find({
|
||||
let challengSyncPromises = challenges.map(async (challenge) => {
|
||||
let users = await User.find({
|
||||
// _id: '',
|
||||
challenges: challenge._id,
|
||||
}).exec();
|
||||
|
||||
const promises = [];
|
||||
users.forEach(user => {
|
||||
promises.push(challenge.syncTasksToUser(user));
|
||||
let promises = [];
|
||||
users.forEach((user) => {
|
||||
promises.push(challenge.syncToUser(user));
|
||||
promises.push(challenge.save());
|
||||
promises.push(user.save());
|
||||
});
|
||||
@@ -18,11 +18,11 @@ async function syncChallengeToMembers (challenges) {
|
||||
return Promise.all(promises);
|
||||
});
|
||||
|
||||
return Promise.all(challengSyncPromises);
|
||||
return await Promise.all(challengSyncPromises);
|
||||
}
|
||||
|
||||
async function syncChallenges (lastChallengeDate) {
|
||||
const query = {
|
||||
let query = {
|
||||
// _id: '',
|
||||
};
|
||||
|
||||
@@ -30,16 +30,16 @@ async function syncChallenges (lastChallengeDate) {
|
||||
query.createdOn = { $lte: lastChallengeDate };
|
||||
}
|
||||
|
||||
const challengesFound = await Challenges.find(query)
|
||||
let challengesFound = await Challenges.find(query)
|
||||
.limit(10)
|
||||
.sort('-createdAt')
|
||||
.exec();
|
||||
|
||||
const syncedChallenges = await syncChallengeToMembers(challengesFound)
|
||||
let syncedChallenges = await syncChallengeToMembers(challengesFound)
|
||||
.catch(reason => console.error(reason));
|
||||
const lastChallenge = challengesFound[challengesFound.length - 1];
|
||||
let lastChallenge = challengesFound[challengesFound.length - 1];
|
||||
if (lastChallenge) syncChallenges(lastChallenge.createdAt);
|
||||
return syncedChallenges;
|
||||
}
|
||||
|
||||
export default syncChallenges;
|
||||
module.exports = syncChallenges;
|
||||
|
||||
@@ -1 +1 @@
|
||||
db.users.update({ _id: { $in: [''] } }, { $inc: { balance: 0.5 } }, { multi: true });
|
||||
db.users.update({_id: {$in: ['']}}, {$inc: {balance: 0.5}}, {multi: true});
|
||||
@@ -1,14 +1,11 @@
|
||||
// mongo habitrpg ./node_modules/moment/moment.js ./migrations/cancelSubscription.js
|
||||
|
||||
// For some reason people often to contact me to cancel their sub,
|
||||
// rather than do it online. Even when I point them to
|
||||
// For some reason people often to contact me to cancel their sub, rather than do it online. Even when I point them to
|
||||
// the FAQ (http://goo.gl/1uoPGQ) they insist...
|
||||
|
||||
db.users.update(
|
||||
{ _id: '' },
|
||||
{
|
||||
$set: {
|
||||
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
|
||||
},
|
||||
},
|
||||
);
|
||||
{_id: ''},
|
||||
{$set: {
|
||||
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
|
||||
}}
|
||||
);
|
||||
@@ -1,7 +1,8 @@
|
||||
// Give contrib.level 7+ free subscription for life
|
||||
db.users.update(
|
||||
|
||||
{
|
||||
'contributor.level': { $gte: 7 },
|
||||
'contributor.level': {$gte: 7},
|
||||
'purchased.plan.customerId': null,
|
||||
},
|
||||
|
||||
@@ -17,6 +18,6 @@ db.users.update(
|
||||
},
|
||||
},
|
||||
|
||||
{ multi: true },
|
||||
{multi: true}
|
||||
|
||||
);
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
// mongo habitrpg ./node_modules/moment/moment.js ./migrations/current_period_end.js
|
||||
db.users.update(
|
||||
{ _id: '' },
|
||||
{ $set: { 'purchased.plan.dateTerminated': moment().add({ days: 7 }).toDate() } },
|
||||
);
|
||||
{_id: ''},
|
||||
{$set: {'purchased.plan.dateTerminated': moment().add({days: 7}).toDate()}}
|
||||
);
|
||||
@@ -32,57 +32,45 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// CONFIGURATION:
|
||||
// - Change the uuid below to be the user's uuid.
|
||||
// - Change ALL instances of "todos" to "habits"/"dailys"/"rewards" as
|
||||
// needed. Do not miss any of them!
|
||||
|
||||
const uuid = '30fb2640-7121-4968-ace5-f385e60ea6c5';
|
||||
|
||||
let uuid = '30fb2640-7121-4968-ace5-f385e60ea6c5';
|
||||
|
||||
db.users.aggregate([
|
||||
{
|
||||
$match: {
|
||||
_id: uuid,
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 0, todos: 1,
|
||||
},
|
||||
},
|
||||
{ $unwind: '$todos' },
|
||||
{
|
||||
$group: {
|
||||
_id: { taskid: '$todos.id' },
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
count: { $gt: 1 },
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
'_id.taskid': 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: { taskid: '$todos.id' },
|
||||
troublesomeIds: { $addToSet: '$_id.taskid' },
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 0,
|
||||
troublesomeIds: 1,
|
||||
},
|
||||
},
|
||||
]).forEach(data => {
|
||||
{$match: {
|
||||
_id: uuid,
|
||||
}},
|
||||
{$project: {
|
||||
_id: 0, todos: 1,
|
||||
}},
|
||||
{$unwind: '$todos'},
|
||||
{$group: {
|
||||
_id: { taskid: '$todos.id' },
|
||||
count: { $sum: 1 },
|
||||
}},
|
||||
{$match: {
|
||||
count: { $gt: 1 },
|
||||
}},
|
||||
{$project: {
|
||||
'_id.taskid': 1,
|
||||
}},
|
||||
{$group: {
|
||||
_id: { taskid: '$todos.id' },
|
||||
troublesomeIds: { $addToSet: '$_id.taskid' },
|
||||
}},
|
||||
{$project: {
|
||||
_id: 0,
|
||||
troublesomeIds: 1,
|
||||
}},
|
||||
]).forEach((data) => {
|
||||
// print( "\n" ); printjson(data);
|
||||
data.troublesomeIds.forEach(taskid => {
|
||||
print(`non-unique task: ${taskid}`); // eslint-disable-line no-restricted-globals
|
||||
data.troublesomeIds.forEach((taskid) => {
|
||||
print(`non-unique task: ${ taskid}`);
|
||||
db.users.update({
|
||||
_id: uuid,
|
||||
todos: { $elemMatch: { id: taskid } },
|
||||
@@ -93,7 +81,8 @@ db.users.aggregate([
|
||||
});
|
||||
|
||||
db.users.update(
|
||||
{ _id: uuid },
|
||||
{ $pull: { todos: { id: 'de666' } } },
|
||||
{ multi: false },
|
||||
{_id: uuid},
|
||||
{$pull: { todos: { id: 'de666' } } },
|
||||
{multi: false }
|
||||
);
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const oldId = '';
|
||||
const newId = '';
|
||||
const newUser = db.users.findOne({ _id: newId });
|
||||
let oldId = '';
|
||||
let newId = '';
|
||||
let newUser = db.users.findOne({_id: newId});
|
||||
|
||||
db.users.update({ _id: oldId }, { $set: { auth: newUser.auth } });
|
||||
db.users.update({_id: oldId}, {$set: {auth: newUser.auth}});
|
||||
|
||||
// remove the auth on the new user (which is a template account).
|
||||
// The account will be preened automatically later,
|
||||
// remove the auth on the new user (which is a template account). The account will be preened automatically later,
|
||||
// this allows us to keep the account around a few days in case there was a mistake
|
||||
db.users.update({ _id: newId }, { $unset: { auth: 1 } });
|
||||
db.users.update({_id: newId}, {$unset: {auth: 1}});
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Past in the text of a unique habit here to find the user, then you can restore their UUID
|
||||
*/
|
||||
|
||||
db.users.find().forEach(user => {
|
||||
db.users.find().forEach((user) => {
|
||||
user.tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
|
||||
const found = _.some(user.tasks, { text: '' });
|
||||
if (found) printjson({ id: user._id, auth: user.auth });
|
||||
});
|
||||
let found = _.some(user.tasks, {text: ''});
|
||||
if (found) printjson({id: user._id, auth: user.auth});
|
||||
});
|
||||
@@ -1,34 +1,32 @@
|
||||
// mongo habitrpg ./node_modules/moment/moment.js ./migrations/freeMonth.js
|
||||
|
||||
db.users.update(
|
||||
{ _id: '' },
|
||||
{
|
||||
$set: {
|
||||
'purchased.plan.customerId': 'temporary',
|
||||
'purchased.plan.paymentMethod': 'Stripe',
|
||||
'purchased.plan.planId': 'basic_earned',
|
||||
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
|
||||
},
|
||||
},
|
||||
{_id: ''},
|
||||
{$set: {
|
||||
'purchased.plan.customerId': 'temporary',
|
||||
'purchased.plan.paymentMethod': 'Stripe',
|
||||
'purchased.plan.planId': 'basic_earned',
|
||||
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
|
||||
}}
|
||||
);
|
||||
// var m = 12;
|
||||
// db.users.update(
|
||||
// {_id:''},
|
||||
// {$set:{'purchased.plan':{
|
||||
// planId: 'basic_'+m+'mo',
|
||||
// paymentMethod: 'Paypal',
|
||||
// customerId: 'Gift',
|
||||
// dateCreated: new Date(),
|
||||
// dateTerminated: moment().add('month',m).toDate(),
|
||||
// dateUpdated: new Date(),
|
||||
// extraMonths: 0,
|
||||
// gemsBought: 0,
|
||||
// mysteryItems: [],
|
||||
// consecutive: {
|
||||
// count: 0,
|
||||
// offset: m,
|
||||
// gemCapExtra: m/3*5,
|
||||
// trinkets: m/3
|
||||
// }
|
||||
// planId: 'basic_'+m+'mo',
|
||||
// paymentMethod: 'Paypal',
|
||||
// customerId: 'Gift',
|
||||
// dateCreated: new Date(),
|
||||
// dateTerminated: moment().add('month',m).toDate(),
|
||||
// dateUpdated: new Date(),
|
||||
// extraMonths: 0,
|
||||
// gemsBought: 0,
|
||||
// mysteryItems: [],
|
||||
// consecutive: {
|
||||
// count: 0,
|
||||
// offset: m,
|
||||
// gemCapExtra: m/3*5,
|
||||
// trinkets: m/3
|
||||
// }
|
||||
// }}}
|
||||
// )
|
||||
// )
|
||||
@@ -1,5 +1,5 @@
|
||||
db.users.update(
|
||||
{},
|
||||
{ $inc: { 'achievements.habiticaDays': 1 } },
|
||||
{ multi: 1 },
|
||||
{$inc: {'achievements.habiticaDays': 1}},
|
||||
{multi: 1}
|
||||
);
|
||||
|
||||
@@ -1 +1 @@
|
||||
db.users.update({ _id: '' }, { $inc: { balance: 5 } });
|
||||
db.users.update({_id: ''}, {$inc: {balance: 5}});
|
||||
@@ -13,7 +13,7 @@ import { model as Group } from '../../website/server/models/group';
|
||||
|
||||
// @TODO: this should probably be a GroupManager library method
|
||||
async function addUnlimitedSubscription (groupId, dateTerminated) {
|
||||
const group = await Group.findOne({ _id: groupId });
|
||||
let group = await Group.findOne({_id: groupId});
|
||||
|
||||
group.purchased.plan.customerId = 'group-unlimited';
|
||||
group.purchased.plan.dateCreated = new Date();
|
||||
@@ -22,7 +22,7 @@ async function addUnlimitedSubscription (groupId, dateTerminated) {
|
||||
group.purchased.plan.planId = 'group_monthly';
|
||||
group.purchased.plan.dateTerminated = null;
|
||||
if (dateTerminated) {
|
||||
const dateToEnd = moment(dateTerminated).toDate();
|
||||
let dateToEnd = moment(dateTerminated).toDate();
|
||||
group.purchased.plan.dateTerminated = dateToEnd;
|
||||
}
|
||||
// group.purchased.plan.owner = ObjectId();
|
||||
@@ -31,12 +31,12 @@ async function addUnlimitedSubscription (groupId, dateTerminated) {
|
||||
return group.save();
|
||||
}
|
||||
|
||||
export default async function addUnlimitedSubscriptionCreator () {
|
||||
const groupId = process.argv[2];
|
||||
module.exports = async function addUnlimitedSubscriptionCreator () {
|
||||
let groupId = process.argv[2];
|
||||
|
||||
if (!groupId) throw Error('Group ID is required');
|
||||
|
||||
const dateTerminated = process.argv[3];
|
||||
let dateTerminated = process.argv[3];
|
||||
|
||||
await addUnlimitedSubscription(groupId, dateTerminated);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,9 +3,9 @@ import { model as User } from '../../website/server/models/user';
|
||||
|
||||
// @TODO: this should probably be a GroupManager library method
|
||||
async function createGroup (name, privacy, type, leaderId) {
|
||||
const user = await User.findOne({ _id: leaderId });
|
||||
let user = await User.findOne({_id: leaderId});
|
||||
|
||||
const group = new Group({
|
||||
let group = new Group({
|
||||
name,
|
||||
privacy,
|
||||
type,
|
||||
@@ -17,11 +17,13 @@ async function createGroup (name, privacy, type, leaderId) {
|
||||
return Promise.all([group.save(), user.save()]);
|
||||
}
|
||||
|
||||
export default async function groupCreator () {
|
||||
const name = process.argv[2];
|
||||
const privacy = process.argv[3];
|
||||
const type = process.argv[4];
|
||||
const leaderId = process.argv[5];
|
||||
module.exports = async function groupCreator () {
|
||||
let name = process.argv[2];
|
||||
let privacy = process.argv[3];
|
||||
let type = process.argv[4];
|
||||
let leaderId = process.argv[5];
|
||||
|
||||
await createGroup(name, privacy, type, leaderId);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,43 +1,44 @@
|
||||
/* let migrationName = 'Jackalopes for Unlimited Subscribers'; */
|
||||
|
||||
/*
|
||||
* This migration will find users with unlimited subscriptions who are also eligible
|
||||
* for Jackalope mounts, and award them
|
||||
* This migration will find users with unlimited subscriptions who are also eligible for Jackalope mounts, and award them
|
||||
*/
|
||||
|
||||
import { model as Group } from '../../website/server/models/group';
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
async function handOutJackalopes () {
|
||||
const promises = [];
|
||||
const cursor = User.find({
|
||||
let promises = [];
|
||||
let cursor = User.find({
|
||||
'purchased.plan.customerId': 'habitrpg',
|
||||
}).cursor();
|
||||
|
||||
cursor.on('data', async user => {
|
||||
console.log(`User: ${user._id}`);
|
||||
cursor.on('data', async (user) => {
|
||||
console.log(`User: ${ user._id}`);
|
||||
|
||||
let groupList = [];
|
||||
if (user.party._id) groupList.push(user.party._id);
|
||||
groupList = groupList.concat(user.guilds);
|
||||
|
||||
const subscribedGroup = await Group.findOne({
|
||||
_id: { $in: groupList },
|
||||
'purchased.plan.planId': 'group_monthly',
|
||||
'purchased.plan.dateTerminated': null,
|
||||
},
|
||||
{ _id: 1 });
|
||||
let subscribedGroup =
|
||||
await Group.findOne({
|
||||
_id: {$in: groupList},
|
||||
'purchased.plan.planId': 'group_monthly',
|
||||
'purchased.plan.dateTerminated': null,
|
||||
},
|
||||
{_id: 1}
|
||||
);
|
||||
|
||||
if (subscribedGroup) {
|
||||
User.update({ _id: user._id }, { $set: { 'items.mounts.Jackalope-RoyalPurple': true } }).exec();
|
||||
User.update({_id: user._id}, {$set: {'items.mounts.Jackalope-RoyalPurple': true}}).exec();
|
||||
promises.push(user.save());
|
||||
}
|
||||
});
|
||||
|
||||
cursor.on('close', async () => {
|
||||
console.log('done');
|
||||
return Promise.all(promises);
|
||||
return await Promise.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
export default handOutJackalopes;
|
||||
module.exports = handOutJackalopes;
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
// @authorName = 'TheHollidayInn'; // in case script author needs to know when their ...
|
||||
// @authorUuid = ''; // ... own data is done
|
||||
|
||||
|
||||
/*
|
||||
* This migration moves chat off of groups and into their own model
|
||||
*/
|
||||
|
||||
import { model as Group } from '../../website/server/models/group';
|
||||
import { chatModel as Chat } from '../../website/server/models/message';
|
||||
import { model as Chat } from '../../website/server/models/chat';
|
||||
|
||||
async function moveGroupChatToModel (skip = 0) {
|
||||
const groups = await Group.find({})
|
||||
@@ -37,8 +38,9 @@ async function moveGroupChatToModel (skip = 0) {
|
||||
return chatpromises;
|
||||
});
|
||||
|
||||
|
||||
const reducedPromises = promises.reduce((acc, curr) => {
|
||||
acc = acc.concat(curr); // eslint-disable-line no-param-reassign
|
||||
acc = acc.concat(curr);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
@@ -47,4 +49,4 @@ async function moveGroupChatToModel (skip = 0) {
|
||||
moveGroupChatToModel(skip + 50);
|
||||
}
|
||||
|
||||
export default moveGroupChatToModel;
|
||||
module.exports = moveGroupChatToModel;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import monk from 'monk'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
import monk from 'monk';
|
||||
import nconf from 'nconf';
|
||||
import stripePayments from '../../website/server/libs/payments/stripe';
|
||||
|
||||
@@ -12,8 +12,8 @@ import stripePayments from '../../website/server/libs/payments/stripe';
|
||||
|
||||
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
|
||||
|
||||
const dbGroups = monk(CONNECTION_STRING).get('groups', { castIds: false });
|
||||
const dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
|
||||
let dbGroups = monk(CONNECTION_STRING).get('groups', { castIds: false });
|
||||
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
|
||||
|
||||
async function fixGroupPlanMembers () {
|
||||
console.info('Group ID, Customer ID, Plan ID, Quantity, Recorded Member Count, Actual Member Count');
|
||||
@@ -24,15 +24,15 @@ async function fixGroupPlanMembers () {
|
||||
{
|
||||
$and:
|
||||
[
|
||||
{ 'purchased.plan.planId': { $ne: null } },
|
||||
{ 'purchased.plan.planId': { $ne: '' } },
|
||||
{ 'purchased.plan.customerId': { $ne: 'cus_9f0DV4g7WHRzpM' } }, // Demo groups
|
||||
{ 'purchased.plan.customerId': { $ne: 'cus_9maalqDOFTrvqx' } },
|
||||
{'purchased.plan.planId': {$ne: null}},
|
||||
{'purchased.plan.planId': {$ne: ''}},
|
||||
{'purchased.plan.customerId': {$ne: 'cus_9f0DV4g7WHRzpM'}}, // Demo groups
|
||||
{'purchased.plan.customerId': {$ne: 'cus_9maalqDOFTrvqx'}},
|
||||
],
|
||||
$or:
|
||||
[
|
||||
{ 'purchased.plan.dateTerminated': null },
|
||||
{ 'purchased.plan.dateTerminated': '' },
|
||||
{'purchased.plan.dateTerminated': null},
|
||||
{'purchased.plan.dateTerminated': ''},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -40,19 +40,19 @@ async function fixGroupPlanMembers () {
|
||||
memberCount: 1,
|
||||
'purchased.plan': 1,
|
||||
},
|
||||
},
|
||||
).each(async (group, { close, pause, resume }) => { // eslint-disable-line no-unused-vars
|
||||
}
|
||||
).each(async (group, {close, pause, resume}) => { // eslint-disable-line no-unused-vars
|
||||
pause();
|
||||
groupPlanCount += 1;
|
||||
groupPlanCount++;
|
||||
|
||||
const canonicalMemberCount = await dbUsers.countDocuments(
|
||||
const canonicalMemberCount = await dbUsers.count(
|
||||
{
|
||||
$or:
|
||||
[
|
||||
{ 'party._id': group._id },
|
||||
{ guilds: group._id },
|
||||
{'party._id': group._id},
|
||||
{guilds: group._id},
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
const incorrectMemberCount = group.memberCount !== canonicalMemberCount;
|
||||
|
||||
@@ -73,24 +73,24 @@ async function fixGroupPlanMembers () {
|
||||
$set: {
|
||||
memberCount: canonicalMemberCount,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!groupUpdate) return;
|
||||
|
||||
fixedGroupCount += 1;
|
||||
fixedGroupCount++;
|
||||
if (group.purchased.plan.paymentMethod === 'Stripe') {
|
||||
await stripePayments.chargeForAdditionalGroupMember(group);
|
||||
await dbGroups.update(
|
||||
{ _id: group._id },
|
||||
{ $set: { 'purchased.plan.quantity': canonicalMemberCount + 2 } },
|
||||
{_id: group._id},
|
||||
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}}
|
||||
);
|
||||
}
|
||||
|
||||
if (incorrectQuantity) {
|
||||
await dbGroups.update(
|
||||
{ _id: group._id },
|
||||
{ $set: { 'purchased.plan.quantity': canonicalMemberCount + 2 } },
|
||||
{_id: group._id},
|
||||
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ async function fixGroupPlanMembers () {
|
||||
}).then(() => {
|
||||
console.info(`Fixed ${fixedGroupCount} out of ${groupPlanCount} active Group Plans`);
|
||||
return process.exit(0);
|
||||
}).catch(err => {
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
return process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
export default fixGroupPlanMembers;
|
||||
module.exports = fixGroupPlanMembers;
|
||||
|
||||
@@ -5,27 +5,29 @@ let authorUuid = ''; // ... own data is done
|
||||
*/
|
||||
|
||||
/*
|
||||
* This migrations will iterate through all groups with a group plan
|
||||
* a subscription and resync the free subscription to all members
|
||||
* This migrations will iterate through all groups with a group plan a subscription and resync the free
|
||||
* subscription to all members
|
||||
*/
|
||||
|
||||
import { model as Group } from '../../website/server/models/group';
|
||||
import payments from '../../website/server/libs/payments/payments';
|
||||
import * as payments from '../../website/server/libs/payments';
|
||||
|
||||
async function updateGroupsWithGroupPlans () {
|
||||
const cursor = Group.find({
|
||||
let cursor = Group.find({
|
||||
'purchased.plan.planId': 'group_monthly',
|
||||
'purchased.plan.dateTerminated': null,
|
||||
}).cursor();
|
||||
|
||||
const promises = [];
|
||||
let promises = [];
|
||||
|
||||
cursor.on('data', group => {
|
||||
cursor.on('data', (group) => {
|
||||
promises.push(payments.addSubscriptionToGroupUsers(group));
|
||||
promises.push(group.save());
|
||||
});
|
||||
|
||||
cursor.on('close', async () => Promise.all(promises));
|
||||
cursor.on('close', async () => {
|
||||
return await Promise.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
export default updateGroupsWithGroupPlans;
|
||||
module.exports = updateGroupsWithGroupPlans;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
require('@babel/register'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
require('babel-register');
|
||||
|
||||
// This file must use ES5, everything required can be in ES6
|
||||
|
||||
@@ -18,13 +17,12 @@ function setUpServer () {
|
||||
setUpServer();
|
||||
|
||||
// Replace this with your migration
|
||||
const processUsers = require().default;
|
||||
|
||||
const processUsers = require('');
|
||||
processUsers()
|
||||
.then(() => {
|
||||
.then(function success () {
|
||||
process.exit(0);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch(function failure (err) {
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
+24
-29
@@ -1,21 +1,19 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
/* let migrationName = 'new_stuff.js'; */
|
||||
const authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
let authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
|
||||
/*
|
||||
* set the newStuff flag in all user accounts so they see a Bailey message
|
||||
*/
|
||||
|
||||
const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
let monk = require('monk');
|
||||
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
let dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
const query = {
|
||||
'flags.newStuff': { $ne: true },
|
||||
let query = {
|
||||
'flags.newStuff': {$ne: true},
|
||||
};
|
||||
|
||||
if (lastId) {
|
||||
@@ -25,31 +23,29 @@ function processUsers (lastId) {
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
// specify fields we are interested in to limit retrieved data
|
||||
// (empty if we're not reading data):
|
||||
fields: [],
|
||||
fields: [], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const userPromises = users.map(updateUser);
|
||||
const lastUser = users[users.length - 1];
|
||||
let userPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(() => {
|
||||
@@ -58,31 +54,30 @@ function updateUsers (users) {
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
const set = { 'flags.newStuff': true };
|
||||
let set = {'flags.newStuff': true};
|
||||
|
||||
dbUsers.update({ _id: user._id }, { $set: set });
|
||||
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 (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
console.warn(`\n${ count } users processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
const migrationName = 'restock_armoire.js';
|
||||
const authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
let migrationName = 'restock_armoire.js';
|
||||
let authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Remove flag stating that the Enchanted Armoire is empty, for when new equipment is added
|
||||
*/
|
||||
|
||||
const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
let monk = require('monk');
|
||||
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
let dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
const query = {
|
||||
let query = {
|
||||
'flags.armoireEmpty': true,
|
||||
};
|
||||
|
||||
@@ -25,31 +23,29 @@ function processUsers (lastId) {
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
// specify fields we are interested in to limit retrieved data
|
||||
// (empty if we're not reading data):
|
||||
fields: [],
|
||||
fields: [], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const userPromises = users.map(updateUser);
|
||||
const lastUser = users[users.length - 1];
|
||||
let userPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(() => {
|
||||
@@ -58,31 +54,30 @@ function updateUsers (users) {
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
const set = { migration: migrationName, 'flags.armoireEmpty': false };
|
||||
let set = {migration: migrationName, 'flags.armoireEmpty': false};
|
||||
|
||||
dbUsers.update({ _id: user._id }, { $set: set });
|
||||
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 (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
console.warn(`\n${ count } users processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
const migrationName = 'restock_armoire_for_users_that_need_it.js';
|
||||
const authorName = 'Alys (ALittleYellowSpider)'; // in case script author needs to know when their ...
|
||||
const authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is done
|
||||
let migrationName = 'restock_armoire_for_users_that_need_it.js';
|
||||
let authorName = 'Alys (ALittleYellowSpider)'; // in case script author needs to know when their ...
|
||||
let authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Remove flag stating that the Enchanted Armoire is empty,
|
||||
@@ -19,16 +18,16 @@ const authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is do
|
||||
*
|
||||
*/
|
||||
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
|
||||
const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
let monk = require('monk');
|
||||
let dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
const query = {
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2016-01-04') },
|
||||
let query = {
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2016-01-04')},
|
||||
// '_id': authorUuid // FOR TESTING
|
||||
};
|
||||
|
||||
@@ -36,7 +35,7 @@ function processUsers (lastId) {
|
||||
/* let fields = {
|
||||
'flags.armoireEmpty': 1,
|
||||
'items.gear.owned': 1,
|
||||
}; */
|
||||
};*/
|
||||
|
||||
if (lastId) {
|
||||
query._id = {
|
||||
@@ -45,34 +44,32 @@ function processUsers (lastId) {
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
// specify fields we are interested in to limit retrieved data
|
||||
// (empty if we're not reading data):
|
||||
fields: {
|
||||
'flags.armoireEmpty': 1,
|
||||
'items.gear.owned': 1,
|
||||
},
|
||||
}, // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const userPromises = users.map(updateUser);
|
||||
const lastUser = users[users.length - 1];
|
||||
let userPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(() => {
|
||||
@@ -81,68 +78,19 @@ function updateUsers (users) {
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
let set = {migration: migrationName, 'flags.armoireEmpty': false};
|
||||
|
||||
const set = { migration: migrationName, 'flags.armoireEmpty': false };
|
||||
|
||||
if (user.flags.armoireEmpty) {
|
||||
// this user believes their armoire has no more items in it
|
||||
if (
|
||||
user.items.gear.owned.weapon_armoire_barristerGavel
|
||||
&& user.items.gear.owned.armor_armoire_barristerRobes
|
||||
&& user.items.gear.owned.head_armoire_jesterCap
|
||||
&& user.items.gear.owned.armor_armoire_jesterCostume
|
||||
&& user.items.gear.owned.head_armoire_barristerWig
|
||||
&& user.items.gear.owned.weapon_armoire_jesterBaton
|
||||
&& user.items.gear.owned.weapon_armoire_lunarSceptre
|
||||
&& user.items.gear.owned.armor_armoire_gladiatorArmor
|
||||
&& user.items.gear.owned.weapon_armoire_basicCrossbow
|
||||
&& user.items.gear.owned.head_armoire_gladiatorHelm
|
||||
&& user.items.gear.owned.armor_armoire_lunarArmor
|
||||
&& user.items.gear.owned.head_armoire_redHairbow
|
||||
&& user.items.gear.owned.head_armoire_violetFloppyHat
|
||||
&& user.items.gear.owned.head_armoire_rancherHat
|
||||
&& user.items.gear.owned.shield_armoire_gladiatorShield
|
||||
&& user.items.gear.owned.head_armoire_blueHairbow
|
||||
&& user.items.gear.owned.weapon_armoire_mythmakerSword
|
||||
&& user.items.gear.owned.head_armoire_royalCrown
|
||||
&& user.items.gear.owned.head_armoire_hornedIronHelm
|
||||
&& user.items.gear.owned.weapon_armoire_rancherLasso
|
||||
&& user.items.gear.owned.armor_armoire_rancherRobes
|
||||
&& user.items.gear.owned.armor_armoire_hornedIronArmor
|
||||
&& user.items.gear.owned.armor_armoire_goldenToga
|
||||
&& user.items.gear.owned.weapon_armoire_ironCrook
|
||||
&& user.items.gear.owned.head_armoire_goldenLaurels
|
||||
&& user.items.gear.owned.head_armoire_redFloppyHat
|
||||
&& user.items.gear.owned.armor_armoire_plagueDoctorOvercoat
|
||||
&& user.items.gear.owned.head_armoire_plagueDoctorHat
|
||||
&& user.items.gear.owned.weapon_armoire_goldWingStaff
|
||||
&& user.items.gear.owned.head_armoire_yellowHairbow
|
||||
&& user.items.gear.owned.eyewear_armoire_plagueDoctorMask
|
||||
&& user.items.gear.owned.head_armoire_blackCat
|
||||
&& user.items.gear.owned.weapon_armoire_batWand
|
||||
&& user.items.gear.owned.head_armoire_orangeCat
|
||||
&& user.items.gear.owned.shield_armoire_midnightShield
|
||||
&& user.items.gear.owned.armor_armoire_royalRobes
|
||||
&& user.items.gear.owned.head_armoire_blueFloppyHat
|
||||
&& user.items.gear.owned.shield_armoire_royalCane
|
||||
&& user.items.gear.owned.weapon_armoire_shepherdsCrook
|
||||
&& user.items.gear.owned.armor_armoire_shepherdRobes
|
||||
&& user.items.gear.owned.head_armoire_shepherdHeaddress
|
||||
&& user.items.gear.owned.weapon_armoire_blueLongbow
|
||||
&& user.items.gear.owned.weapon_armoire_crystalCrescentStaff
|
||||
&& user.items.gear.owned.head_armoire_crystalCrescentHat
|
||||
&& user.items.gear.owned.armor_armoire_dragonTamerArmor
|
||||
&& user.items.gear.owned.head_armoire_dragonTamerHelm
|
||||
&& user.items.gear.owned.armor_armoire_crystalCrescentRobes
|
||||
&& user.items.gear.owned.shield_armoire_dragonTamerShield
|
||||
&& user.items.gear.owned.weapon_armoire_glowingSpear
|
||||
) {
|
||||
if (user.items.gear.owned.weapon_armoire_barristerGavel && user.items.gear.owned.armor_armoire_barristerRobes && user.items.gear.owned.head_armoire_jesterCap && user.items.gear.owned.armor_armoire_jesterCostume && user.items.gear.owned.head_armoire_barristerWig && user.items.gear.owned.weapon_armoire_jesterBaton && user.items.gear.owned.weapon_armoire_lunarSceptre && user.items.gear.owned.armor_armoire_gladiatorArmor && user.items.gear.owned.weapon_armoire_basicCrossbow && user.items.gear.owned.head_armoire_gladiatorHelm && user.items.gear.owned.armor_armoire_lunarArmor && user.items.gear.owned.head_armoire_redHairbow && user.items.gear.owned.head_armoire_violetFloppyHat && user.items.gear.owned.head_armoire_rancherHat && user.items.gear.owned.shield_armoire_gladiatorShield && user.items.gear.owned.head_armoire_blueHairbow && user.items.gear.owned.weapon_armoire_mythmakerSword && user.items.gear.owned.head_armoire_royalCrown && user.items.gear.owned.head_armoire_hornedIronHelm && user.items.gear.owned.weapon_armoire_rancherLasso && user.items.gear.owned.armor_armoire_rancherRobes && user.items.gear.owned.armor_armoire_hornedIronArmor && user.items.gear.owned.armor_armoire_goldenToga && user.items.gear.owned.weapon_armoire_ironCrook && user.items.gear.owned.head_armoire_goldenLaurels && user.items.gear.owned.head_armoire_redFloppyHat && user.items.gear.owned.armor_armoire_plagueDoctorOvercoat && user.items.gear.owned.head_armoire_plagueDoctorHat && user.items.gear.owned.weapon_armoire_goldWingStaff && user.items.gear.owned.head_armoire_yellowHairbow && user.items.gear.owned.eyewear_armoire_plagueDoctorMask && user.items.gear.owned.head_armoire_blackCat && user.items.gear.owned.weapon_armoire_batWand && user.items.gear.owned.head_armoire_orangeCat && user.items.gear.owned.shield_armoire_midnightShield && user.items.gear.owned.armor_armoire_royalRobes && user.items.gear.owned.head_armoire_blueFloppyHat && user.items.gear.owned.shield_armoire_royalCane && user.items.gear.owned.weapon_armoire_shepherdsCrook && user.items.gear.owned.armor_armoire_shepherdRobes && user.items.gear.owned.head_armoire_shepherdHeaddress && user.items.gear.owned.weapon_armoire_blueLongbow && user.items.gear.owned.weapon_armoire_crystalCrescentStaff && user.items.gear.owned.head_armoire_crystalCrescentHat && user.items.gear.owned.armor_armoire_dragonTamerArmor && user.items.gear.owned.head_armoire_dragonTamerHelm && user.items.gear.owned.armor_armoire_crystalCrescentRobes && user.items.gear.owned.shield_armoire_dragonTamerShield && user.items.gear.owned.weapon_armoire_glowingSpear) {
|
||||
// this user does have all the armoire items so we don't change the flag
|
||||
// console.log("don't change: " + user._id); // FOR TESTING
|
||||
} else {
|
||||
// console.log("change: " + user._id); // FOR TESTING
|
||||
dbUsers.update({ _id: user._id }, { $set: set });
|
||||
dbUsers.update({_id: user._id}, {$set: set});
|
||||
}
|
||||
} else {
|
||||
// this user already has armoire marked as containing items to be bought
|
||||
@@ -150,25 +98,24 @@ function updateUser (user) {
|
||||
// console.log("DON'T CHANGE: " + user._id); // FOR TESTING
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName} processed`);
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
console.warn(`\n${ count } users processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
/* let migrationName = 'restore_profile_data.js'; */
|
||||
const authorName = 'ThehollidayInn'; // in case script author needs to know when their ...
|
||||
const authorUuid = ''; // ... own data is done
|
||||
let authorName = 'ThehollidayInn'; // in case script author needs to know when their ...
|
||||
let authorUuid = ''; // ... own data is done
|
||||
|
||||
/*
|
||||
* Check if users have empty profile data in new database and update it with old database info
|
||||
*/
|
||||
|
||||
const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
let monk = require('monk');
|
||||
let connectionString = ''; // FOR TEST DATABASE
|
||||
let dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
const connectionString = ''; // FOR TEST DATABASE
|
||||
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
const monk2 = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const oldDbConnectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
const olDbUsers = monk2(oldDbConnectionString).get('users', { castIds: false });
|
||||
let monk2 = require('monk');
|
||||
let oldDbConnectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
let olDbUsers = monk2(oldDbConnectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
const query = {
|
||||
let query = {
|
||||
// 'profile.name': 'profile name not found',
|
||||
'profile.blurb': null,
|
||||
// 'auth.timestamps.loggedin': {$gt: new Date('11/30/2016')},
|
||||
@@ -32,47 +29,49 @@ function processUsers (lastId) {
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
fields: ['_id', 'profile', 'auth.timestamps.loggedin'], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
setTimeout(displayData, 300000);
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const userPaymentPromises = users.map(updateUser);
|
||||
const lastUser = users[users.length - 1];
|
||||
let userPaymentPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPaymentPromises)
|
||||
.then(() => processUsers(lastUser._id));
|
||||
.then(() => {
|
||||
return processUsers(lastUser._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
if (!user.profile.name || user.profile.name === 'profile name not found' || !user.profile.imageUrl || !user.profile.blurb) {
|
||||
return olDbUsers.findOne({ _id: user._id }, '_id profile')
|
||||
.then(oldUserData => {
|
||||
if (!oldUserData) return null;
|
||||
return olDbUsers.findOne({_id: user._id}, '_id profile')
|
||||
.then((oldUserData) => {
|
||||
if (!oldUserData) return;
|
||||
// specify user data to change:
|
||||
const set = {};
|
||||
let set = {};
|
||||
|
||||
if (oldUserData.profile.name === 'profile name not found') return null;
|
||||
if (oldUserData.profile.name === 'profile name not found') return;
|
||||
|
||||
const userNeedsProfileName = !user.profile.name || user.profile.name === 'profile name not found';
|
||||
let userNeedsProfileName = !user.profile.name || user.profile.name === 'profile name not found';
|
||||
if (userNeedsProfileName && oldUserData.profile.name) {
|
||||
set['profile.name'] = oldUserData.profile.name;
|
||||
}
|
||||
@@ -87,38 +86,34 @@ function updateUser (user) {
|
||||
|
||||
if (Object.keys(set).length !== 0 && set.constructor === Object) {
|
||||
console.log(set);
|
||||
return dbUsers.update({ _id: user._id }, { $set: set });
|
||||
return dbUsers.update({_id: user._id}, {$set: set});
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName} processed`);
|
||||
|
||||
return null;
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
console.warn(`\n${ count } users processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
|
||||
processUsers();
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
let request = require('superagent');
|
||||
let last = require('lodash/last');
|
||||
let AWS = require('aws-sdk');
|
||||
|
||||
let config = require('../config');
|
||||
const S3_DIRECTORY = 'mobileApp/images'; // config.S3.SPRITES_DIRECTORY;
|
||||
|
||||
AWS.config.update({
|
||||
accessKeyId: config.S3.accessKeyId,
|
||||
secretAccessKey: config.S3.secretAccessKey,
|
||||
// region: config.get('S3_REGION'),
|
||||
});
|
||||
|
||||
let BUCKET_NAME = config.S3.bucket;
|
||||
let s3 = new AWS.S3();
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/22210077/2601552
|
||||
function uploadFile (buffer, fileName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
s3.putObject({
|
||||
Body: buffer,
|
||||
Key: fileName,
|
||||
Bucket: BUCKET_NAME,
|
||||
}, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
// console.info(`${fileName} uploaded to ${BUCKET_NAME} succesfully.`);
|
||||
resolve(fileName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFileName (file) {
|
||||
let piecesOfPath = file.split('/');
|
||||
let name = last(piecesOfPath);
|
||||
let fullName = S3_DIRECTORY + name;
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
function getFileFromUrl (url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.get(url).end((err, res) => {
|
||||
if (err) return reject(err);
|
||||
let file = res.body;
|
||||
resolve(file);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let commit = '78f94e365c72cc58f66857d5941105638db7d35c';
|
||||
commit = 'df0dbaba636c9ce424cc7040f7bd7fc1aa311015';
|
||||
let gihuburl = `https://api.github.com/repos/HabitRPG/habitica/commits/${commit}`;
|
||||
|
||||
|
||||
let currentIndex = 0;
|
||||
|
||||
function uploadToS3 (start, end, filesUrls) {
|
||||
let urls = filesUrls.slice(start, end);
|
||||
|
||||
if (urls.length === 0) {
|
||||
console.log('done');
|
||||
return;
|
||||
}
|
||||
|
||||
let promises = urls.map(fullUrl => {
|
||||
return getFileFromUrl(fullUrl)
|
||||
.then((buffer) => {
|
||||
return uploadFile(buffer, getFileName(fullUrl));
|
||||
});
|
||||
});
|
||||
console.log(promises.length);
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(() => {
|
||||
currentIndex += 50;
|
||||
uploadToS3(currentIndex, currentIndex + 50, filesUrls);
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
request.get(gihuburl)
|
||||
.end((err, res) => {
|
||||
console.log(err);
|
||||
let files = res.body.files;
|
||||
|
||||
let filesUrls = [''];
|
||||
filesUrls = files.map(file => {
|
||||
return file.raw_url;
|
||||
});
|
||||
|
||||
uploadToS3(currentIndex, currentIndex + 50, filesUrls);
|
||||
});
|
||||
@@ -1,23 +1,21 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
// const migrationName = 'habits-one-history-entry-per-day';
|
||||
// const authorName = 'paglias'; // in case script author needs to know when their ...
|
||||
// const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Iterates over all habits and condense multiple history entries for the same day into a single one
|
||||
* Iterates over all habits and condense multiple history entries for the same day into a single entry
|
||||
*/
|
||||
|
||||
const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
const monk = require('monk');
|
||||
const _ = require('lodash');
|
||||
const moment = require('moment');
|
||||
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||
|
||||
function processChallengeHabits (lastId) {
|
||||
const query = {
|
||||
'challenge.id': { $exists: true },
|
||||
userId: { $exists: false },
|
||||
let query = {
|
||||
'challenge.id': {$exists: true},
|
||||
userId: {$exists: false},
|
||||
type: 'habit',
|
||||
};
|
||||
|
||||
@@ -28,35 +26,37 @@ function processChallengeHabits (lastId) {
|
||||
}
|
||||
|
||||
dbTasks.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 500,
|
||||
})
|
||||
.then(updateChallengeHabits)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateChallengeHabits (habits) {
|
||||
if (!habits || habits.length === 0) {
|
||||
console.warn('All appropriate challenge habits found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const habitsPromises = habits.map(updateChallengeHabit);
|
||||
const lastHabit = habits[habits.length - 1];
|
||||
let habitsPromises = habits.map(updateChallengeHabit);
|
||||
let lastHabit = habits[habits.length - 1];
|
||||
|
||||
return Promise.all(habitsPromises)
|
||||
.then(() => processChallengeHabits(lastHabit._id));
|
||||
.then(() => {
|
||||
return processChallengeHabits(lastHabit._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateChallengeHabit (habit) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
if (habit && habit.history && habit.history.length > 0) {
|
||||
// First remove missing entries
|
||||
@@ -76,12 +76,13 @@ function updateChallengeHabit (habit) {
|
||||
entry.scoreDirection = entry.value > previousValue ? 'up' : 'down';
|
||||
}
|
||||
})
|
||||
// group entries by aggregateBy
|
||||
.groupBy(entry => moment(entry.date).format('YYYYMMDD'))
|
||||
.groupBy(entry => { // group entries by aggregateBy
|
||||
return moment(entry.date).format('YYYYMMDD');
|
||||
})
|
||||
.toPairs() // [key, entry]
|
||||
.sortBy(([key]) => key) // sort by date
|
||||
.map(keyEntryPair => {
|
||||
const entries = keyEntryPair[1]; // 1 is entry, 0 is key
|
||||
let entries = keyEntryPair[1]; // 1 is entry, 0 is key
|
||||
let scoredUp = 0;
|
||||
let scoredDown = 0;
|
||||
|
||||
@@ -106,34 +107,32 @@ function updateChallengeHabit (habit) {
|
||||
})
|
||||
.value();
|
||||
|
||||
return dbTasks.update({ _id: habit._id }, {
|
||||
$set: { history: habit.history },
|
||||
return dbTasks.update({_id: habit._id}, {
|
||||
$set: {history: habit.history},
|
||||
});
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} habits processed`);
|
||||
return null;
|
||||
if (count % progressCount === 0) console.warn(`${count } habits processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} tasks processed\n`);
|
||||
console.warn(`\n${ count } tasks processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
export default processChallengeHabits;
|
||||
module.exports = processChallengeHabits;
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
const migrationName = 'habits-one-history-entry-per-day';
|
||||
const authorName = 'paglias'; // in case script author needs to know when their ...
|
||||
const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Iterates over all habits and condense multiple history entries for the same day into a single one
|
||||
* Iterates over all habits and condense multiple history entries for the same day into a single entry
|
||||
*/
|
||||
|
||||
const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
const monk = require('monk');
|
||||
const _ = require('lodash');
|
||||
const moment = require('moment');
|
||||
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers (lastId) {
|
||||
const query = {
|
||||
migration: { $ne: migrationName },
|
||||
let query = {
|
||||
migration: {$ne: migrationName},
|
||||
};
|
||||
|
||||
if (lastId) {
|
||||
@@ -27,32 +25,34 @@ function processUsers (lastId) {
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 50, // just 50 users per time since we have to process all their habits as well
|
||||
fields: ['_id', 'preferences.timezoneOffset', 'preferences.dayStart'],
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users and their tasks found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const usersPromises = users.map(updateUser);
|
||||
const lastUser = users[users.length - 1];
|
||||
let usersPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(usersPromises)
|
||||
.then(() => processUsers(lastUser._id));
|
||||
.then(() => {
|
||||
return processUsers(lastUser._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateHabit (habit, timezoneOffset, dayStart) {
|
||||
@@ -82,7 +82,7 @@ function updateHabit (habit, timezoneOffset, dayStart) {
|
||||
.toPairs() // [key, entry]
|
||||
.sortBy(([key]) => key) // sort by date
|
||||
.map(keyEntryPair => {
|
||||
const entries = keyEntryPair[1]; // 1 is entry, 0 is key
|
||||
let entries = keyEntryPair[1]; // 1 is entry, 0 is key
|
||||
let scoredUp = 0;
|
||||
let scoredDown = 0;
|
||||
|
||||
@@ -107,56 +107,57 @@ function updateHabit (habit, timezoneOffset, dayStart) {
|
||||
})
|
||||
.value();
|
||||
|
||||
return dbTasks.update({ _id: habit._id }, {
|
||||
$set: { history: habit.history },
|
||||
return dbTasks.update({_id: habit._id}, {
|
||||
$set: {history: habit.history},
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
const { timezoneOffset } = user.preferences;
|
||||
const { dayStart } = user.preferences;
|
||||
const timezoneOffset = user.preferences.timezoneOffset;
|
||||
const dayStart = user.preferences.dayStart;
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName} being processed`);
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } being processed`);
|
||||
|
||||
return dbTasks.find({
|
||||
type: 'habit',
|
||||
userId: user._id,
|
||||
})
|
||||
.then(habits => Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart))))
|
||||
.then(() => dbUsers.update({ _id: user._id }, {
|
||||
$set: { migration: migrationName },
|
||||
}))
|
||||
.catch(err => {
|
||||
.then(habits => {
|
||||
return Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart)));
|
||||
})
|
||||
.then(() => {
|
||||
return dbUsers.update({_id: user._id}, {
|
||||
$set: {migration: migrationName},
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} tasks processed\n`);
|
||||
console.warn(`\n${ count } tasks processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
export default processUsers;
|
||||
module.exports = processUsers;
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// @migrationName = 'RewardsMigrationFlipNegativeCostsValues';
|
||||
// @authorName = 'hamboomger';
|
||||
// @authorUuid = '80b61b73-2278-4947-b713-a10112cfe7f5';
|
||||
|
||||
/*
|
||||
* For each reward with negative cost, make it positive
|
||||
* by assigning it an absolute value of itself
|
||||
*/
|
||||
|
||||
import { Task } from '../../website/server/models/task';
|
||||
|
||||
async function flipNegativeCostsValues () {
|
||||
const query = {
|
||||
type: 'reward',
|
||||
value: { $lt: 0 },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
value: 1,
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const rewards = await Task
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (rewards.length === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
const promises = rewards.map(reward => {
|
||||
const positiveValue = Math.abs(reward.value);
|
||||
return Task.update({ _id: reward._id }, { $set: { value: positiveValue } }).exec();
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await Promise.all(promises);
|
||||
|
||||
query._id = {
|
||||
$gt: rewards[rewards.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
console.log('All rewards with negative values were updated, migration finished');
|
||||
}
|
||||
|
||||
export default flipNegativeCostsValues;
|
||||
@@ -1,19 +1,18 @@
|
||||
import monk from 'monk'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
/* let migrationName = 'tasks-set-everyX'; */
|
||||
const authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
let authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Iterates over all tasks and sets invalid everyX values
|
||||
* (less than 0 or more than 9999 or not an int) field to 0
|
||||
* Iterates over all tasks and sets invalid everyX values (less than 0 or more than 9999 or not an int) field to 0
|
||||
*/
|
||||
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true';
|
||||
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||
let monk = require('monk');
|
||||
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true';
|
||||
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||
|
||||
function processTasks (lastId) {
|
||||
// specify a query to limit the affected tasks (empty for all tasks):
|
||||
const query = {
|
||||
let query = {
|
||||
type: 'daily',
|
||||
everyX: {
|
||||
$not: {
|
||||
@@ -31,63 +30,64 @@ function processTasks (lastId) {
|
||||
}
|
||||
|
||||
dbTasks.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
fields: [],
|
||||
})
|
||||
.then(updateTasks)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateTasks (tasks) {
|
||||
if (!tasks || tasks.length === 0) {
|
||||
console.warn('All appropriate tasks found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const taskPromises = tasks.map(updatetask);
|
||||
const lasttask = tasks[tasks.length - 1];
|
||||
let taskPromises = tasks.map(updatetask);
|
||||
let lasttask = tasks[tasks.length - 1];
|
||||
|
||||
return Promise.all(taskPromises)
|
||||
.then(() => processTasks(lasttask._id));
|
||||
.then(() => {
|
||||
return processTasks(lasttask._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updatetask (task) {
|
||||
count += 1;
|
||||
const set = { everyX: 0 };
|
||||
count++;
|
||||
let set = {everyX: 0};
|
||||
|
||||
dbTasks.update({ _id: task._id }, { $set: set });
|
||||
dbTasks.update({_id: task._id}, {$set: set});
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${task._id}`);
|
||||
if (task._id === authorUuid) console.warn(`${authorName} processed`);
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ task._id}`);
|
||||
if (task._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} tasks processed\n`);
|
||||
console.warn(`\n${ count } tasks processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
export default processTasks;
|
||||
module.exports = processTasks;
|
||||
|
||||
@@ -1,31 +1,28 @@
|
||||
/* let migrationName = 'tasks-set-yesterdaily'; */
|
||||
// ... own data is done
|
||||
let authorName = 'TheHollidayInn'; // in case script author needs to know when their ...
|
||||
let authorUuid = ''; // ... own data is done
|
||||
|
||||
/*
|
||||
* Iterates over all tasks and sets the yseterDaily field to True
|
||||
*/
|
||||
|
||||
import monk from 'monk'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
import monk from 'monk';
|
||||
|
||||
const authorName = 'TheHollidayInn'; // in case script author needs to know when their ...
|
||||
const authorUuid = '';
|
||||
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
@@ -33,37 +30,39 @@ function exiting (code, msg) {
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} tasks processed\n`);
|
||||
console.warn(`\n${ count } tasks processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function updatetask (task) {
|
||||
count += 1;
|
||||
const set = { yesterDaily: true };
|
||||
count++;
|
||||
let set = {yesterDaily: true};
|
||||
|
||||
dbTasks.update({ _id: task._id }, { $set: set });
|
||||
dbTasks.update({_id: task._id}, {$set: set});
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${task._id}`);
|
||||
if (task._id === authorUuid) console.warn(`${authorName} processed`);
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ task._id}`);
|
||||
if (task._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function updateTasks (tasks) {
|
||||
if (!tasks || tasks.length === 0) {
|
||||
console.warn('All appropriate tasks found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const taskPromises = tasks.map(updatetask);
|
||||
const lasttask = tasks[tasks.length - 1];
|
||||
let taskPromises = tasks.map(updatetask);
|
||||
let lasttask = tasks[tasks.length - 1];
|
||||
|
||||
return Promise.all(taskPromises)
|
||||
.then(() => processTasks(lasttask._id)); // eslint-disable-line no-use-before-define
|
||||
.then(() => {
|
||||
return processTasks(lasttask._id); // eslint-disable-line no-use-before-define
|
||||
});
|
||||
}
|
||||
|
||||
function processTasks (lastId) {
|
||||
// specify a query to limit the affected tasks (empty for all tasks):
|
||||
const query = {
|
||||
let query = {
|
||||
yesterDaily: false,
|
||||
};
|
||||
|
||||
@@ -74,18 +73,16 @@ function processTasks (lastId) {
|
||||
}
|
||||
|
||||
dbTasks.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
// specify fields we are interested in to limit retrieved data
|
||||
// (empty if we're not reading data):
|
||||
fields: [
|
||||
fields: [ // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
],
|
||||
})
|
||||
.then(updateTasks)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
export default processTasks;
|
||||
module.exports = processTasks;
|
||||
|
||||
@@ -8,30 +8,29 @@ let authorUuid = ''; // ... own data is done
|
||||
* This migraition will copy user data from prod to test
|
||||
*/
|
||||
|
||||
import monk from 'monk'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const monk = require('monk');
|
||||
const connectionString = '';
|
||||
const Users = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
export default async function accountTransfer () {
|
||||
module.exports = async function accountTransfer () {
|
||||
const fromAccountId = '';
|
||||
const toAccountId = '';
|
||||
|
||||
const fromAccount = await Users.findOne({ _id: fromAccountId });
|
||||
const toAccount = await Users.findOne({ _id: toAccountId });
|
||||
const fromAccount = await Users.findOne({_id: fromAccountId});
|
||||
const toAccount = await Users.findOne({_id: toAccountId});
|
||||
|
||||
const newMounts = { ...fromAccount.items.mounts, ...toAccount.items.mounts };
|
||||
const newPets = { ...fromAccount.items.pets, ...toAccount.items.pets };
|
||||
const newBackgrounds = { ...fromAccount.purchased.background, ...toAccount.purchased.background };
|
||||
const newMounts = Object.assign({}, fromAccount.items.mounts, toAccount.items.mounts);
|
||||
const newPets = Object.assign({}, fromAccount.items.pets, toAccount.items.pets);
|
||||
const newBackgrounds = Object.assign({}, fromAccount.purchased.background, toAccount.purchased.background);
|
||||
|
||||
await Users.update({ _id: toAccountId }, {
|
||||
await Users.update({_id: toAccountId}, {
|
||||
$set: {
|
||||
'items.pets': newPets,
|
||||
'items.mounts': newMounts,
|
||||
'purchased.background': newBackgrounds,
|
||||
},
|
||||
})
|
||||
.then(result => {
|
||||
.then((result) => {
|
||||
console.log(result);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,8 +8,7 @@ const authorUuid = ''; // ... own data is done
|
||||
* This migraition will copy user data from prod to test
|
||||
*/
|
||||
|
||||
import monk from 'monk'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const monk = require('monk');
|
||||
const connectionString = 'mongodb://localhost/new-habit';
|
||||
const Users = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
@@ -20,17 +19,15 @@ function getAchievementUpdate (newUser, oldUser) {
|
||||
const oldAchievements = oldUser.achievements;
|
||||
const newAchievements = newUser.achievements;
|
||||
|
||||
const achievementsUpdate = { ...newAchievements };
|
||||
let achievementsUpdate = Object.assign({}, newAchievements);
|
||||
|
||||
// ultimateGearSets
|
||||
if (!achievementsUpdate.ultimateGearSets && oldAchievements.ultimateGearSets) {
|
||||
achievementsUpdate.ultimateGearSets = oldAchievements.ultimateGearSets;
|
||||
} else if (oldAchievements.ultimateGearSets) {
|
||||
Object.keys(oldAchievements.ultimateGearSets).forEach(index => {
|
||||
if (oldAchievements.ultimateGearSets[index]) {
|
||||
achievementsUpdate.ultimateGearSets[index] = true;
|
||||
}
|
||||
});
|
||||
for (let index in oldAchievements.ultimateGearSets) {
|
||||
if (oldAchievements.ultimateGearSets[index]) achievementsUpdate.ultimateGearSets[index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// challenges
|
||||
@@ -40,57 +37,57 @@ function getAchievementUpdate (newUser, oldUser) {
|
||||
|
||||
// Quests
|
||||
if (!achievementsUpdate.quests) achievementsUpdate.quests = {};
|
||||
Object.keys(oldAchievements.quests).forEach(index => {
|
||||
for (let index in oldAchievements.quests) {
|
||||
if (!achievementsUpdate.quests[index]) {
|
||||
achievementsUpdate.quests[index] = oldAchievements.quests[index];
|
||||
} else {
|
||||
achievementsUpdate.quests[index] += oldAchievements.quests[index];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Rebirth level
|
||||
if (achievementsUpdate.rebirthLevel) {
|
||||
achievementsUpdate.rebirthLevel = Math.max(
|
||||
achievementsUpdate.rebirthLevel, oldAchievements.rebirthLevel,
|
||||
);
|
||||
achievementsUpdate.rebirthLevel = Math.max(achievementsUpdate.rebirthLevel, oldAchievements.rebirthLevel);
|
||||
} else if (oldAchievements.rebirthLevel) {
|
||||
achievementsUpdate.rebirthLevel = oldAchievements.rebirthLevel;
|
||||
}
|
||||
|
||||
// All others
|
||||
const indexsToIgnore = ['ultimateGearSets', 'challenges', 'quests', 'rebirthLevel'];
|
||||
Object.keys(oldAchievements).forEach(index => {
|
||||
if (indexsToIgnore.indexOf(index) !== -1) return;
|
||||
for (let index in oldAchievements) {
|
||||
if (indexsToIgnore.indexOf(index) !== -1) continue; // eslint-disable-line no-continue
|
||||
|
||||
if (!achievementsUpdate[index]) {
|
||||
if (!achievementsUpdate[index]) {
|
||||
achievementsUpdate[index] = oldAchievements[index];
|
||||
return;
|
||||
continue; // eslint-disable-line no-continue
|
||||
}
|
||||
|
||||
if (Number.isInteger(oldAchievements[index])) {
|
||||
achievementsUpdate[index] += oldAchievements[index];
|
||||
} else if (oldAchievements[index] === true) achievementsUpdate[index] = true;
|
||||
});
|
||||
}
|
||||
|
||||
return achievementsUpdate;
|
||||
}
|
||||
|
||||
export default async function achievementRestore () {
|
||||
module.exports = async function achievementRestore () {
|
||||
const userIds = [
|
||||
];
|
||||
|
||||
await Promise.all(userIds.map(userId => (async () => {
|
||||
const oldUser = await UsersOld.findOne({ _id: userId }, 'achievements');
|
||||
const newUser = await Users.findOne({ _id: userId }, 'achievements');
|
||||
/* eslint-disable no-await-in-loop */
|
||||
for (let index in userIds) {
|
||||
const userId = userIds[index];
|
||||
const oldUser = await UsersOld.findOne({_id: userId}, 'achievements');
|
||||
const newUser = await Users.findOne({_id: userId}, 'achievements');
|
||||
const achievementUpdate = getAchievementUpdate(newUser, oldUser);
|
||||
await Users.update(
|
||||
{ _id: userId },
|
||||
{_id: userId},
|
||||
{
|
||||
$set: {
|
||||
achievements: achievementUpdate,
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
console.log(`Updated ${userId}`);
|
||||
})()));
|
||||
}
|
||||
/* eslint-enable no-await-in-loop */
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,37 +1,33 @@
|
||||
/* eslint-disable no-console */
|
||||
import moment from 'moment';
|
||||
import nconf from 'nconf';
|
||||
import { sendTxn } from '../../website/server/libs/email';
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
import moment from 'moment';
|
||||
import nconf from 'nconf';
|
||||
const BASE_URL = nconf.get('BASE_URL');
|
||||
const EMAIL_SLUG = 'mandrill-email-slug'; // Set email template to send
|
||||
const MIGRATION_NAME = 'bulk-email';
|
||||
|
||||
const progressCount = 250;
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
if (count % progressCount === 0) {
|
||||
console.warn(`${count} ${user._id}`);
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
}
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
await sendTxn(
|
||||
sendTxn(
|
||||
user,
|
||||
EMAIL_SLUG,
|
||||
[{ name: 'BASE_URL', content: BASE_URL }], // Add variables from template
|
||||
[{name: 'BASE_URL', content: BASE_URL}] // Add variables from template
|
||||
);
|
||||
|
||||
return User.update({ _id: user._id }, { $set: { migration: MIGRATION_NAME } }).exec();
|
||||
return await User.update({_id: user._id}, {$set: {migration: MIGRATION_NAME}}).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: moment().subtract(2, 'weeks').toDate() }, // customize or remove to target different populations
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: moment().subtract(2, 'weeks').toDate()}, // customize or remove to target different populations
|
||||
};
|
||||
|
||||
const fields = {
|
||||
@@ -45,7 +41,7 @@ export default async function processUsers () {
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
@@ -62,4 +58,4 @@ export default async function processUsers () {
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
import each from 'lodash/each';
|
||||
import keys from 'lodash/keys';
|
||||
import content from '../../website/common/script/content/index';
|
||||
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = 'full-gear';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
/*
|
||||
* Award users every extant pet and mount
|
||||
*/
|
||||
|
||||
async function updateUser (user) {
|
||||
count += 1;
|
||||
|
||||
const set = {};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
each(keys(content.gear.flat), gearItem => {
|
||||
set[`items.gear.owned.${gearItem}`] = true;
|
||||
});
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.local.lowerCaseUsername': 'olson1',
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = 'full-stable';
|
||||
import each from 'lodash/each';
|
||||
import keys from 'lodash/keys';
|
||||
import content from '../../website/common/script/content/index';
|
||||
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = 'full-stable';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
@@ -15,49 +14,46 @@ let count = 0;
|
||||
*/
|
||||
|
||||
async function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
each(keys(content.pets), pet => {
|
||||
each(keys(content.pets), (pet) => {
|
||||
set[`items.pets.${pet}`] = 5;
|
||||
});
|
||||
each(keys(content.premiumPets), pet => {
|
||||
each(keys(content.premiumPets), (pet) => {
|
||||
set[`items.pets.${pet}`] = 5;
|
||||
});
|
||||
each(keys(content.questPets), pet => {
|
||||
each(keys(content.questPets), (pet) => {
|
||||
set[`items.pets.${pet}`] = 5;
|
||||
});
|
||||
each(keys(content.specialPets), pet => {
|
||||
each(keys(content.specialPets), (pet) => {
|
||||
set[`items.pets.${pet}`] = 5;
|
||||
});
|
||||
each(keys(content.wackyPets), pet => {
|
||||
set[`items.pets.${pet}`] = 5;
|
||||
});
|
||||
each(keys(content.mounts), mount => {
|
||||
each(keys(content.mounts), (mount) => {
|
||||
set[`items.mounts.${mount}`] = true;
|
||||
});
|
||||
each(keys(content.premiumMounts), mount => {
|
||||
each(keys(content.premiumMounts), (mount) => {
|
||||
set[`items.mounts.${mount}`] = true;
|
||||
});
|
||||
each(keys(content.questMounts), mount => {
|
||||
each(keys(content.questMounts), (mount) => {
|
||||
set[`items.mounts.${mount}`] = true;
|
||||
});
|
||||
each(keys(content.specialMounts), mount => {
|
||||
each(keys(content.specialMounts), (mount) => {
|
||||
set[`items.mounts.${mount}`] = true;
|
||||
});
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return User.update({ _id: user._id }, { $set: set }).exec();
|
||||
return await User.update({_id: user._id}, {$set: set}).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.local.username': 'SabreTest',
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.local.username': 'olson22',
|
||||
};
|
||||
|
||||
const fields = {
|
||||
@@ -68,7 +64,7 @@ export default async function processUsers () {
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
@@ -85,4 +81,4 @@ export default async function processUsers () {
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = 'mystery_items_201909';
|
||||
const MYSTERY_ITEMS = ['armor_mystery_201909', 'head_mystery_201909'];
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
import { model as UserNotification } from '../../website/server/models/userNotification';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const addToSet = {
|
||||
'purchased.plan.mysteryItems': {
|
||||
$each: MYSTERY_ITEMS,
|
||||
},
|
||||
};
|
||||
const push = {
|
||||
notifications: (new UserNotification({
|
||||
type: 'NEW_MYSTERY_ITEMS',
|
||||
data: {
|
||||
MYSTERY_ITEMS,
|
||||
},
|
||||
})).toJSON(),
|
||||
};
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({_id: user._id}, {$set: set, $push: push, $addToSet: addToSet}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'purchased.plan.customerId': { $ne: null },
|
||||
$or: [
|
||||
{ 'purchased.plan.dateTerminated': { $gte: new Date() } },
|
||||
{ 'purchased.plan.dateTerminated': { $exists: false } },
|
||||
{ 'purchased.plan.dateTerminated': { $eq: null } },
|
||||
],
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
+15
-28
@@ -1,15 +1,14 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20190314_pi_day';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = '20200314_pi_day';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count *= 1;
|
||||
count++;
|
||||
|
||||
const inc = {
|
||||
'items.food.Pie_Skeleton': 1,
|
||||
@@ -24,37 +23,25 @@ async function updateUser (user) {
|
||||
'items.food.Pie_Red': 1,
|
||||
};
|
||||
const set = {};
|
||||
let push;
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (typeof user.items.gear.owned.head_special_piDay !== 'undefined') {
|
||||
push = false;
|
||||
} else {
|
||||
set['items.gear.owned.head_special_piDay'] = false;
|
||||
set['items.gear.owned.shield_special_piDay'] = false;
|
||||
push = [
|
||||
{ type: 'marketGear', path: 'gear.flat.head_special_piDay', _id: uuid() },
|
||||
{ type: 'marketGear', path: 'gear.flat.shield_special_piDay', _id: uuid() },
|
||||
];
|
||||
}
|
||||
set['items.gear.owned.head_special_piDay'] = false;
|
||||
set['items.gear.owned.shield_special_piDay'] = false;
|
||||
const push = [
|
||||
{type: 'marketGear', path: 'gear.flat.head_special_piDay', _id: uuid()},
|
||||
{type: 'marketGear', path: 'gear.flat.shield_special_piDay', _id: uuid()},
|
||||
];
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
if (push) {
|
||||
return User
|
||||
.update({ _id: user._id }, { $inc: inc, $set: set, $push: { pinnedItems: { $each: push } } })
|
||||
.exec();
|
||||
}
|
||||
return User
|
||||
.update({ _id: user._id }, { $inc: inc, $set: set })
|
||||
.exec();
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set, $push: {pinnedItems: {$each: push}}}).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2020-02-15') },
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-02-15')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
@@ -66,7 +53,7 @@ export default async function processUsers () {
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
@@ -83,4 +70,4 @@ export default async function processUsers () {
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import monk from 'monk'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const migrationName = 'remove-social-users-extra-data.js';
|
||||
const authorName = 'paglias'; // in case script author needs to know when their ...
|
||||
const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is done
|
||||
@@ -9,12 +7,13 @@ const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is do
|
||||
*/
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
|
||||
const monk = require('monk');
|
||||
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
const query = {
|
||||
migration: { $ne: migrationName },
|
||||
let query = {
|
||||
migration: {$ne: migrationName},
|
||||
$or: [
|
||||
{ 'auth.facebook.id': { $exists: true } },
|
||||
{ 'auth.google.id': { $exists: true } },
|
||||
@@ -28,28 +27,28 @@ function processUsers (lastId) {
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: { _id: 1 },
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${err}`);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
const progressCount = 1000;
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const userPromises = users.map(updateUser);
|
||||
const lastUser = users[users.length - 1];
|
||||
let userPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(() => {
|
||||
@@ -58,7 +57,7 @@ function updateUsers (users) {
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count *= 1;
|
||||
count++;
|
||||
|
||||
const isFacebook = user.auth.facebook && user.auth.facebook.id;
|
||||
const isGoogle = user.auth.google && user.auth.google.id;
|
||||
@@ -83,29 +82,28 @@ function updateUser (user) {
|
||||
_id: user._id,
|
||||
}, update);
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName} processed`);
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
console.warn(`\n${ count } users processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
// 0 = success
|
||||
code = code || 0; // eslint-disable-line no-param-reassign
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!'; // eslint-disable-line no-param-reassign
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
export default processUsers;
|
||||
module.exports = processUsers;
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = 'tag-challenge-field-string2bool';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
tags: {
|
||||
$elemMatch: {
|
||||
challenge: {
|
||||
$exists: true,
|
||||
$type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const users = await User.find(query)
|
||||
.sort({ _id: 1 })
|
||||
.limit(250)
|
||||
.select({ _id: 1, tags: 1 })
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
}
|
||||
|
||||
async function updateUser (user) {
|
||||
count += 1;
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
let requiresUpdate = false;
|
||||
|
||||
if (user && user.tags) {
|
||||
user.tags.forEach(tag => {
|
||||
if (tag && typeof tag.challenge === 'string') {
|
||||
requiresUpdate = true;
|
||||
if (tag.challenge === 'true') {
|
||||
tag.challenge = true;
|
||||
} else if (tag.challenge === 'false') {
|
||||
tag.challenge = false;
|
||||
} else {
|
||||
tag.challenge = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (requiresUpdate) {
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
tags: user.tags,
|
||||
};
|
||||
return User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20181203_take_this';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = '20181203_take_this';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count += 1;
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
let push;
|
||||
@@ -20,35 +19,36 @@ async function updateUser (user) {
|
||||
push = false;
|
||||
} else if (typeof user.items.gear.owned.body_special_takeThis !== 'undefined') {
|
||||
set['items.gear.owned.back_special_takeThis'] = false;
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.back_special_takeThis', _id: uuid() } };
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.back_special_takeThis', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.head_special_takeThis !== 'undefined') {
|
||||
set['items.gear.owned.body_special_takeThis'] = false;
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.body_special_takeThis', _id: uuid() } };
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.body_special_takeThis', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_takeThis !== 'undefined') {
|
||||
set['items.gear.owned.head_special_takeThis'] = false;
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.head_special_takeThis', _id: uuid() } };
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_takeThis', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_takeThis'] = false;
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.armor_special_takeThis', _id: uuid() } };
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_takeThis', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
|
||||
set['items.gear.owned.weapon_special_takeThis'] = false;
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.weapon_special_takeThis', _id: uuid() } };
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.weapon_special_takeThis', _id: uuid()}};
|
||||
} else {
|
||||
set['items.gear.owned.shield_special_takeThis'] = false;
|
||||
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.shield_special_takeThis', _id: uuid() } };
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.shield_special_takeThis', _id: uuid()}};
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
if (push) {
|
||||
return User.update({ _id: user._id }, { $set: set, $push: push }).exec();
|
||||
return await User.update({_id: user._id}, {$set: set, $push: push}).exec();
|
||||
} else {
|
||||
return await User.update({_id: user._id}, {$set: set}).exec();
|
||||
}
|
||||
return User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
challenges: '00708425-d477-41a5-bf27-6270466e7976',
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ export default async function processUsers () {
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
@@ -78,4 +78,4 @@ export default async function processUsers () {
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
/*
|
||||
let migrationName = 'UserFromProdToTest';
|
||||
let authorName = 'TheHollidayInn'; // in case script author needs to know when their ...
|
||||
@@ -9,24 +8,22 @@ let authorUuid = ''; // ... own data is done
|
||||
* This migraition will copy user data from prod to test
|
||||
*/
|
||||
|
||||
let monk = require('monk');
|
||||
let testConnectionSting = ''; // FOR TEST DATABASE
|
||||
let usersTest = monk(testConnectionSting).get('users', { castIds: false });
|
||||
let groupsTest = monk(testConnectionSting).get('groups', { castIds: false });
|
||||
let challengesTest = monk(testConnectionSting).get('challenges', { castIds: false });
|
||||
let tasksTest = monk(testConnectionSting).get('tasks', { castIds: false });
|
||||
|
||||
let monk2 = require('monk');
|
||||
let liveConnectString = ''; // FOR TEST DATABASE
|
||||
let userLive = monk2(liveConnectString).get('users', { castIds: false });
|
||||
let groupsLive = monk2(liveConnectString).get('groups', { castIds: false });
|
||||
let challengesLive = monk2(liveConnectString).get('challenges', { castIds: false });
|
||||
let tasksLive = monk2(liveConnectString).get('tasks', { castIds: false });
|
||||
|
||||
import uniq from 'lodash/uniq';
|
||||
|
||||
const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const testConnectionSting = ''; // FOR TEST DATABASE
|
||||
const usersTest = monk(testConnectionSting).get('users', { castIds: false });
|
||||
const groupsTest = monk(testConnectionSting).get('groups', { castIds: false });
|
||||
const challengesTest = monk(testConnectionSting).get('challenges', { castIds: false });
|
||||
const tasksTest = monk(testConnectionSting).get('tasks', { castIds: false });
|
||||
|
||||
const monk2 = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const liveConnectString = ''; // FOR TEST DATABASE
|
||||
const userLive = monk2(liveConnectString).get('users', { castIds: false });
|
||||
const groupsLive = monk2(liveConnectString).get('groups', { castIds: false });
|
||||
const challengesLive = monk2(liveConnectString).get('challenges', { castIds: false });
|
||||
const tasksLive = monk2(liveConnectString).get('tasks', { castIds: false });
|
||||
|
||||
// Variabls for updating
|
||||
/*
|
||||
let userIds = [
|
||||
@@ -39,11 +36,11 @@ let challengeIds = [];
|
||||
let tasksIds = [];
|
||||
|
||||
async function processUsers () {
|
||||
const userPromises = [];
|
||||
let userPromises = [];
|
||||
// {_id: {$in: userIds}}
|
||||
|
||||
return userLive.find({ guilds: 'b0764d64-8276-45a1-afa5-5ca9a5c64ca0' })
|
||||
.each(user => {
|
||||
return userLive.find({guilds: 'b0764d64-8276-45a1-afa5-5ca9a5c64ca0'})
|
||||
.each((user) => {
|
||||
if (user.guilds.length > 0) groupIds = groupIds.concat(user.guilds);
|
||||
if (user.party._id) groupIds.push(user.party._id);
|
||||
if (user.challenges.length > 0) challengeIds = challengeIds.concat(user.challenges);
|
||||
@@ -52,56 +49,64 @@ async function processUsers () {
|
||||
if (user.tasksOrder.dailys.length > 0) tasksIds = tasksIds.concat(user.tasksOrder.dailys);
|
||||
if (user.tasksOrder.habits.length > 0) tasksIds = tasksIds.concat(user.tasksOrder.habits);
|
||||
|
||||
const userPromise = usersTest.update({ _id: user._id }, user, { upsert: true });
|
||||
let userPromise = usersTest.update({_id: user._id}, user, {upsert: true});
|
||||
userPromises.push(userPromise);
|
||||
}).then(() => Promise.all(userPromises))
|
||||
}).then(() => {
|
||||
return Promise.all(userPromises);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('Done User');
|
||||
});
|
||||
}
|
||||
|
||||
function processGroups () {
|
||||
const promises = [];
|
||||
const groupsToQuery = uniq(groupIds);
|
||||
return groupsLive.find({ _id: { $in: groupsToQuery } })
|
||||
.each(group => {
|
||||
const promise = groupsTest.update({ _id: group._id }, group, { upsert: true });
|
||||
let promises = [];
|
||||
let groupsToQuery = uniq(groupIds);
|
||||
return groupsLive.find({_id: {$in: groupsToQuery}})
|
||||
.each((group) => {
|
||||
let promise = groupsTest.update({_id: group._id}, group, {upsert: true});
|
||||
promises.push(promise);
|
||||
}).then(() => Promise.all(promises))
|
||||
}).then(() => {
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('Done Group');
|
||||
});
|
||||
}
|
||||
|
||||
function processChallenges () {
|
||||
const promises = [];
|
||||
const challengesToQuery = uniq(challengeIds);
|
||||
return challengesLive.find({ _id: { $in: challengesToQuery } })
|
||||
.each(challenge => {
|
||||
const promise = challengesTest.update({ _id: challenge._id }, challenge, { upsert: true });
|
||||
let promises = [];
|
||||
let challengesToQuery = uniq(challengeIds);
|
||||
return challengesLive.find({_id: {$in: challengesToQuery}})
|
||||
.each((challenge) => {
|
||||
let promise = challengesTest.update({_id: challenge._id}, challenge, {upsert: true});
|
||||
promises.push(promise);
|
||||
}).then(() => Promise.all(promises))
|
||||
}).then(() => {
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('Done Challenge');
|
||||
});
|
||||
}
|
||||
|
||||
function processTasks () {
|
||||
const promises = [];
|
||||
const tasksToQuery = uniq(tasksIds);
|
||||
return tasksLive.find({ _id: { $in: tasksToQuery } })
|
||||
.each(task => {
|
||||
const promise = tasksTest.update({ _id: task._id }, task, { upsert: true });
|
||||
let promises = [];
|
||||
let tasksToQuery = uniq(tasksIds);
|
||||
return tasksLive.find({_id: {$in: tasksToQuery}})
|
||||
.each((task) => {
|
||||
let promise = tasksTest.update({_id: task._id}, task, {upsert: true});
|
||||
promises.push(promise);
|
||||
}).then(() => Promise.all(promises))
|
||||
}).then(() => {
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('Done Tasks');
|
||||
});
|
||||
}
|
||||
|
||||
export default async function prodToTest () {
|
||||
module.exports = async function prodToTest () {
|
||||
await processUsers();
|
||||
await processGroups();
|
||||
await processChallenges();
|
||||
await processTasks();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
const { MongoClient } = require('mongodb'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
'use strict';
|
||||
|
||||
const MongoClient = require('mongodb').MongoClient;
|
||||
const logger = require('./logger');
|
||||
|
||||
let dbConnection;
|
||||
@@ -16,7 +17,7 @@ function connectToDb (dbUri) {
|
||||
|
||||
logger.success(`Connected to ${dbUri}`);
|
||||
|
||||
return resolve(database);
|
||||
resolve(database);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
const chalk = require('chalk'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
'use strict';
|
||||
|
||||
const chalk = require('chalk');
|
||||
|
||||
function loggerGenerator (type, color) {
|
||||
return function logger () {
|
||||
const args = Array
|
||||
.from(arguments) // eslint-disable-line prefer-rest-params
|
||||
.map(arg => chalk[color](arg));
|
||||
let args = Array.from(arguments).map(arg => chalk[color](arg));
|
||||
console[type].apply(null, args);
|
||||
};
|
||||
}
|
||||
|
||||
+10
-10
@@ -1,30 +1,30 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
const logger = require('./logger');
|
||||
'use strict';
|
||||
|
||||
let logger = require('./logger');
|
||||
|
||||
class Timer {
|
||||
constructor (options = {}) {
|
||||
const warningThreshold = options.minutesWarningThreshold || 10;
|
||||
constructor (options) {
|
||||
options = options || {};
|
||||
let warningThreshold = options.minutesWarningThreshold || 10;
|
||||
|
||||
this.count = 0;
|
||||
this._minutesWarningThreshold = warningThreshold * 60;
|
||||
|
||||
if (!options.disableAutoStart) this.start();
|
||||
}
|
||||
|
||||
start () {
|
||||
this._internalTimer = setInterval(() => {
|
||||
this.count *= 1;
|
||||
this.count++;
|
||||
|
||||
const shouldWarn = this._minutesWarningThreshold < this.count;
|
||||
const logStyle = shouldWarn ? 'error' : 'warn';
|
||||
const dangerMessage = shouldWarn ? 'DANGER: ' : '';
|
||||
let shouldWarn = this._minutesWarningThreshold < this.count;
|
||||
let logStyle = shouldWarn ? 'error' : 'warn';
|
||||
let dangerMessage = shouldWarn ? 'DANGER: ' : '';
|
||||
|
||||
if (this.count % 30 === 0) {
|
||||
logger[logStyle](`${dangerMessage}Process has been running for`, this.count / 60, 'minutes');
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
stop () {
|
||||
if (!this._internalTimer) {
|
||||
throw new Error('Timer has not started');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
'use strict';
|
||||
|
||||
function unique (array) {
|
||||
return Array.from(new Set(array));
|
||||
}
|
||||
|
||||
Generated
+19720
-6291
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user