Compare commits

...

292 Commits

Author SHA1 Message Date
Sabe Jones b5dfa54052 4.29.4 2018-03-08 00:30:20 +00:00
SabreCat 2e7deffb69 fix(user): no more birthday 2018-03-08 00:29:00 +00:00
Sabe Jones 535c41dba8 4.29.3 2018-03-07 22:52:45 +00:00
Sabe Jones 7357fb0528 chore(i18n): update locales 2018-03-07 22:49:33 +00:00
Keith Holliday 49e67fa87c Added stackimpact (#10109) 2018-03-07 16:46:50 -06:00
Sabe Jones b4ca425562 4.29.2 2018-03-06 22:03:34 +00:00
Sabe Jones deba726afa chore(i18n): update locales 2018-03-06 22:00:31 +00:00
SabreCat 2abf0f4900 feat(content): Hug a Bug Quest Bundle 2018-03-06 21:56:01 +00:00
Sabe Jones 0c3b4bba51 4.29.1 2018-03-05 20:58:50 +00:00
Sabe Jones 09948ba319 chore(i18n): update locales 2018-03-05 20:58:16 +00:00
SabreCat da50d2f495 feat(world-boss): third Rage Strike support 2018-03-05 20:46:22 +00:00
Sabe Jones 716393cf91 4.29.0 2018-03-01 23:31:00 +00:00
Sabe Jones fe102aedd3 chore(i18n): update locales 2018-03-01 23:29:59 +00:00
SabreCat cf7fc8d578 Merge branch 'develop' into release 2018-03-01 23:23:57 +00:00
SabreCat b39a5be2d1 chore(sprites): compile 2018-03-01 23:23:36 +00:00
SabreCat 45a1ad501e feat(content): Backgrounds and Armoire 2018/03 2018-03-01 23:23:00 +00:00
Keith Holliday 2959f0afab Removed modify inventory because the Content is causing Garbage Collection issues (#10075) 2018-03-01 08:24:46 -07:00
Sabe Jones 77f8c45e08 fix(world-boss): remove deprecated "recent" field 2018-02-28 15:53:32 +00:00
Sabe Jones bd2fea6e81 Merge branch 'release' into develop 2018-02-28 15:40:28 +00:00
Sabe Jones cb7f85037f 4.28.2 2018-02-28 15:39:45 +00:00
Sabe Jones a9db5310cc chore(i18n): update locales 2018-02-28 15:38:07 +00:00
SabreCat 49af418a29 chore(news): Bailey 2018-02-28 15:33:45 +00:00
Keith Holliday dee81ee6c9 Reversed order to put newest on top (#10059) 2018-02-28 08:17:54 -07:00
Alys 5265e6d321 add swear words - TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc 2018-02-28 19:45:07 +10:00
Matteo Pagliazzi 5e5d73816b fixes #10057 (#10063) 2018-02-27 22:24:31 +01:00
Matteo Pagliazzi 3e723ec4de fixes #9952 (#10062) 2018-02-27 22:02:12 +01:00
Sabe Jones 892ba3b741 Merge branch 'release' into develop 2018-02-27 20:55:34 +00:00
Sabe Jones 48e556fa54 4.28.1 2018-02-27 20:55:11 +00:00
Sabe Jones f687c6f987 chore(i18n): update locales 2018-02-27 20:54:40 +00:00
negue 0b4eafeb28 prevent selling negative items (#10061) 2018-02-27 14:51:10 -06:00
SabreCat cedfc005f8 feat(world-boss): Market Strike support 2018-02-27 20:04:37 +00:00
Keith Holliday be71c5f844 Added kafka queue and initial messages for delete account (#10036)
* Added kafka queue and initial messages for delete account

* Checked for env vars
2018-02-27 09:57:37 -07:00
Keith Holliday 7dcd550209 Updated membercount checks (#10006)
* Updated membercount checks

* Added get member count method

* Updated tests to correctly add users
2018-02-26 13:03:04 -07:00
Keith Holliday 6118336a5d Marked new stuff complete when clicking later (#10043)
* Marked new stuff complete when clicking later

* Moved flag set to action
2018-02-26 12:07:54 -07:00
Alys 01dab33b96 adjust loading screen tip to refer to Tags button by its correct name (not Filters) 2018-02-26 19:40:19 +10:00
Keith Holliday 84dc2f8e3c Fixed sorting and model creation for inboxes (#10039) 2018-02-25 08:04:55 -07:00
greenkeeper[bot] b1bd243892 docs(readme): add Greenkeeper badge (#10050) 2018-02-24 12:46:42 +01:00
Matteo Pagliazzi 67961be575 greenkeeper: exclude mongoose 2018-02-24 12:05:13 +01:00
Gergely Imreh 4b17f62241 task types: add new error messages for invalid task types (#9983)
* `/task/user` `GET` endpoint takes plurals of task types as allowed
  parameters, plus  another custom `completedTodos` type
* `/tasks/group/:groupId` and `/tasks/challenge/:challengeId`
  `GET` endpoints task plurals of task types as allowed parameters
2018-02-23 14:38:18 -06:00
Keith Holliday b850ea9dbf Bulk spell casting (#10007)
* Reorganized spell code

* Added quantity field

* Fixed parameter passing
2018-02-23 11:30:15 -07:00
README Bot 94e615e53e Add CodeTriage badge to habitrpg/habitica (#10028)
Adds a badge showing the number of people helping this repo on CodeTriage.

[![Open Source Helpers](https://www.codetriage.com/habitrpg/habitica/badges/users.svg)](https://www.codetriage.com/habitrpg/habitica)

CodeTriage is an Open Source app that is designed to make contributing to Open Source projects easier. It works by sending subscribers a few open issues in their inbox. If subscribers get busy, there is an algorithm that backs off issue load so they do not get overwhelmed

[Read more about the CodeTriage project](https://www.codetriage.com/what).

Your project was picked by the human, @schneems. They selected it from the projects submitted to https://www.codetriage.com and hand edited the PR. How did your project get added to [CodeTriage](https://www.codetriage.com/what)? Roughly 11 months ago, [chufty](https://github.com/chufty) added this project to CodeTriage in order to start contributing. Since then, 29 people have subscribed to help this repo.

Adding a badge invites people to help contribute to your project. It also lets developers know that others are invested in the longterm success and maintainability of the project.

You can see an example of a CodeTriage badge on these popular OSS READMEs:

- [![](https://www.codetriage.com/rails/rails/badges/users.svg)](https://www.codetriage.com/rails/rails) https://github.com/rails/rails
- [![](https://www.codetriage.com/crystal-lang/crystal/badges/users.svg)](https://www.codetriage.com/crystal-lang/crystal) https://github.com/crystal-lang/crystal

While I am a bot, this PR was manually reviewed and monitored by a human - @schneems. My job is writing commit messages and handling PR logistics.

If you have any questions, you can reply back to this PR and they will be answered by @schneems. If you do not want a badge right now, no worries, close the PR, you will not hear from me again.

Thanks for making your project Open Source! Any feedback is greatly appreciated.
2018-02-23 15:47:09 +01:00
Matteo Pagliazzi 3a1e56cc8e Upgrade server deps (#10017)
* remove unused apn lib and upgrade moment-recur

* upgrade validator

* upgrade got

* request -> got

* fix validation

* fix tests

* upgrade nodemailer

* fix unit tests

* fix webhook tests, upgrade express-validator (using legacy api)

* upgrade js2xmlparser

* update misc packages

* fix linting

* update packages
2018-02-23 15:21:00 +01:00
Sabe Jones cea47e5280 4.28.0 2018-02-22 23:06:53 +00:00
Sabe Jones 9ccb60799e chore(i18n): update locales 2018-02-22 23:04:56 +00:00
SabreCat f86a77608b chore(sprites): compile & cleanup 2018-02-22 22:57:34 +00:00
SabreCat 8b8cee40a7 feat(content): mystery items Feb 2018 2018-02-22 22:56:33 +00:00
SabreCat 9487811d31 fix(world-boss): Tavern layout tweaks 2018-02-22 21:31:57 +00:00
Matteo Pagliazzi d5e4be85e9 Revert "Task page : task filters (#9898)"
This reverts commit 9919faeed8.
2018-02-22 12:28:24 +01:00
Keith Holliday deaf7fee81 Added world boss notification (#10030)
* Added world boss notification

* Updated styles
2018-02-21 14:58:56 -06:00
Sabe Jones 72dc7c01c3 Merge branch 'release' into develop 2018-02-21 17:47:56 +00:00
Sabe Jones 00c830372a 4.27.4 2018-02-21 17:47:28 +00:00
Sabe Jones 199ca03b23 chore(i18n): update locales 2018-02-21 17:45:03 +00:00
SabreCat 84dc1ab546 chore(news): Bailey 2018-02-21 17:35:33 +00:00
Sabe Jones 91df5d1565 4.27.3 2018-02-20 21:41:52 +00:00
Sabe Jones d0a05ad745 fix(lint): disable-line typo 2018-02-20 21:41:33 +00:00
Sabe Jones c991a3e20f fix(lint): disable-line typo 2018-02-20 21:41:11 +00:00
Sabe Jones 93cfd59ea1 chore(i18n): update locales 2018-02-20 21:32:43 +00:00
Sabe Jones 695f53758a Merge branch 'release' into develop 2018-02-20 21:16:43 +00:00
Sabe Jones 416c24d1e2 fix(auth): initialize Hello for social
fixes #9460
2018-02-20 21:15:36 +00:00
SabreCat b0974fc4fc feat(rage-strike): Seasonal Shop modal 2018-02-20 20:05:32 +00:00
negue 8fabadfc67 fix genericPurchase test (#10024) 2018-02-19 20:17:41 +01:00
Matteo Pagliazzi f2e5fdddf1 tests: fix client unit tests 2018-02-19 19:38:20 +01:00
kartik adur 9919faeed8 Task page : task filters (#9898)
* add tasklist getter

* add unit test + refactor for getters

* add task order sorting + update unit tests

* remove direct access to store.state.tasks

* add tag and search filter back to column.vue + unit tests

* add unit test for task order setting function

* add task filters to helper file + modify taskColumn state access to getter

* update column to get values at runtime. TODO set active filter at runtime

* add TaskColumn init state + daily-due-default

* add check for task type daily before set/reset dailyDueView

* remove unused sortBy import in column.vue

* remove unused sortBy

* pr review requested updates

* pr review clean up updates
2018-02-19 19:03:38 +01:00
Josh Sears f592103754 Partial Fix for #8735 ("Failed party invitations do not indicate which invitations failed") (#9939)
* Updated from origin and added invite error fixes

* Update test for capitalization issue

* New error display

Changed app.vue to display error message using error.response.data.message
2018-02-19 19:00:42 +01:00
kartik adur 80e4f5e745 Replace PhantomJS with ChromeHeadless for unit test support (#9972)
* change PhantomJS to ChromeHeadless + travis support

* pr requested updates

* update api-v3 integration beforAll/afterAll
2018-02-19 18:56:48 +01:00
Mike Tung 119f21ddce New PR for margins in stable - fixes #9651 (#9982)
* made style change for pet item class to have more margins.

* made style change for pet item class to have more margins.

* files got added

* encapsulated the items as stated in #9903

* #9903 moved the css to stable -> petitem.vue for better encapsulation.

* saving pngs

* update on files

* updated files as requested in PR!

* Revert "saving pngs"

This reverts commit a38ea664e1.

* made css changes just to pet slot

* #9982 removed redundant css

* #9982 applied scss to mount slots as well.

* #9982 refactored scss to be in one place.

* #9982 changed selector
2018-02-19 18:55:16 +01:00
Mateus Etto 311a898938 Fix attributes box size being too small on Japanese (#9984) 2018-02-19 18:52:07 +01:00
Ignacio Alvarez 1c1b050e2c If message uuid is set as system append as user 'system message' #9985 (#9988) 2018-02-19 18:51:43 +01:00
Keith Holliday faa068f690 Challenge small refactor (#9964)
* Removed challenge group duplication

* Removed duplication of joined challenge

* Moved helpers to challenge library

* Passed group to function

* Fixed group response
2018-02-19 08:15:43 -07:00
Matteo Pagliazzi b619496f8e fix linting 2018-02-17 18:41:49 +01:00
Matteo Pagliazzi 80fe58bc6f Upgrade client deps (#9990)
* upgrade axios

* upgrade axios-progress-bar

* upgrade bootstrap-vue

* fix issues
2018-02-17 18:15:43 +01:00
Matteo Pagliazzi c3c9dd5d35 Merge branch 'upgrade-client-build' into develop 2018-02-17 18:15:02 +01:00
Matteo Pagliazzi 464613a56a Merge branch 'develop' into upgrade-client-build 2018-02-17 18:14:48 +01:00
Matteo Pagliazzi 74ba55c20b Upgrade tests tools and lint migrations and scripts (part 2) (#9998)
* upgrade gulp-babel

* upgrade babel-eslint

* upgrade eslint-friendly-formatter

* start upgrading chai

* start to upgrade eslint

* restore skipped tests

* start to upgrqde monk

* fix linting and remove unused file

* fix mocha notifications, and common tests

* fix unit tests

* start to fix initrgration tests

* more integration tests fixes

* upgrade monk to latest version

* lint /scripts

* migrations: start moving to /archive unused migrations and run eslint with --fix

* lint migrations

* fix more integration tests

* fix test
2018-02-17 18:11:24 +01:00
SabreCat ee087e5eee refactor(rage-strike): consts 2018-02-16 21:36:10 +00:00
SabreCat 95179be346 feat(world-boss): Rage Strike support 2018-02-16 21:18:51 +00:00
negue b0ae0ef4da HOTFIX: purchase marketGear (#9992)
* fix purchase marketGear

* test marketGear purchase in the client
2018-02-16 17:56:05 +01:00
Matteo Pagliazzi dad4f864ff fixes #10001 (#10002) 2018-02-16 17:55:45 +01:00
Keith Holliday f7ffc173b1 Prevented of closing bailey without clicking bottom buttons (#9993) 2018-02-16 09:21:59 -07:00
Keith Holliday ac6a5ae8d2 Registered new funtion as translation (#10005) 2018-02-15 21:25:44 -07:00
Sabe Jones 70fbc83664 Merge branch 'release' into develop 2018-02-16 03:08:22 +00:00
Sabe Jones c3e41cc5e1 4.27.2 2018-02-16 03:07:52 +00:00
Sabe Jones cae0120beb chore(i18n): update locales 2018-02-16 03:01:42 +00:00
SabreCat 10b978da4e fix(spoilers): don't reveal quest boss rewards 2018-02-16 02:56:08 +00:00
SabreCat 5987145b86 fix(phobia): show censored art as needed 2018-02-14 22:35:14 +00:00
Sabe Jones 791d711298 Merge branch 'release' into develop 2018-02-14 21:09:30 +00:00
Sabe Jones ff65c4da78 4.27.1 2018-02-14 20:55:12 +00:00
Sabe Jones 163d56afe9 chore(i18n): update locales 2018-02-14 20:54:50 +00:00
SabreCat 2f46d1bc65 chore(sprites): compile 2018-02-14 20:48:48 +00:00
SabreCat 6ccb841b32 chore(news): Bailey text 2018-02-14 20:47:47 +00:00
Sabe Jones cdcee8d169 World boss client (#9999)
* WIP(world-boss): client components partial

* WIP(world-boss): more client additions

* WIP(world-boss): some beautification

* WIP(world-boss): more Tavern beauty

* fix(world-boss): gradient adjustment

* fix(style): various WB tweaks

* fix(world-boss): better resolution Rage Strike

* fix(world-boss): alignment fixes

* Added world boss modal

* feat(world-boss): add info button

* fix(world-boss): move SVG and tweak padding
2018-02-14 13:43:10 -06:00
Matteo Pagliazzi 16a227109e upgrade to webpack 3 and extract-text-webpack-plugin 2018-02-14 12:14:11 +01:00
Matteo Pagliazzi 8611bd97ae upgrade webpack-dev-middleware 2018-02-14 12:06:30 +01:00
Matteo Pagliazzi 2f3e6b82cf fix svgo options 2018-02-14 12:05:53 +01:00
Matteo Pagliazzi adcd9a53c4 upgrade babel-loader 2018-02-14 11:58:12 +01:00
Matteo Pagliazzi 4a7eb768dc ugrade vue-loader 2018-02-14 11:57:47 +01:00
Matteo Pagliazzi d544a5be6f upgrade svgo-loader 2018-02-14 11:54:36 +01:00
Matteo Pagliazzi 269dac1fe8 upgrade postcss-easy-import 2018-02-14 11:51:01 +01:00
Matteo Pagliazzi bd90ffa6f8 upgrade svg-inline-loader 2018-02-14 11:49:41 +01:00
Matteo Pagliazzi 7c5d35cf77 upgrade url-loader 2018-02-14 11:48:05 +01:00
Matteo Pagliazzi 0049647c08 upgrade autoprefixer 2018-02-14 11:47:29 +01:00
Sabe Jones 7684f9b26a Merge branch 'release' into develop 2018-02-14 02:31:17 +00:00
Sabe Jones fd5ab32c43 4.27.0 2018-02-14 02:30:55 +00:00
Sabe Jones e0933dc0a1 chore(i18n): update locales 2018-02-14 02:29:58 +00:00
Sabe Jones d69e7e66ee World Boss 2018 (Server) (#9995)
* feat(world-boss): barebones API

* fix(world): use Express respond for better JSON

* fix(api): respond with code 200

* feat(content): canonical Dysheartener desc and Rage

* fix(world-boss): enable progress

* WIP(test): world state API

* WIP(test): refactor world boss setup

* WIP(test): better expectations

* fix(test): more expect polishing

* feat(event): server side World Boss

* fix(strings): accidental deletion

* fix(content): include encouragement after Rage

* refactor(world-boss): address comments
2018-02-13 19:21:39 -06:00
Matteo Pagliazzi fa06628361 add new locales 2018-02-13 12:41:47 +01:00
Matteo Pagliazzi 7f1067e1ab chore(i18n): update locales 2018-02-13 12:40:05 +01:00
Matteo Pagliazzi db6644a572 chore(i18n): update locales 2018-02-13 12:35:05 +01:00
Sabe Jones 1e23395c8c Merge branch 'release' into develop 2018-02-12 22:08:03 +00:00
Sabe Jones b7b8faedd6 4.26.3 2018-02-12 22:07:52 +00:00
Sabe Jones 7da0b641dd chore(i18n): update locales 2018-02-12 22:07:00 +00:00
SabreCat 82ff241e39 chore(sprites): compile 2018-02-12 21:58:54 +00:00
SabreCat cf4aaf1618 feat(event): enable Valentines 2018-02-12 21:56:29 +00:00
Keith Holliday 6a67cbba65 Refactored spell code to functions (#9908)
* Refactored spell code to functions

* Fixed party member returns
2018-02-12 09:17:15 -07:00
Keith Holliday 037280601a Refactored group chat flagging (#9907) 2018-02-11 08:35:24 -07:00
Keith Holliday 2687fe1ac9 Added message when there will be no notification for group (#9856)
* Added message when there will be no notification for group

* Added constant and removed extra locale

* Added back message
2018-02-11 08:34:57 -07:00
Sabe Jones 31eeb13598 4.26.2 2018-02-10 11:56:30 +00:00
Sabe Jones 818c201afe chore(i18n): update locales 2018-02-10 11:46:36 +00:00
negue 54153ec299 Refactor Purchase API - Part 1 (#9714)
* move to shops/purchase

* move files to /buy/ instead of /purchase/

* refactor buy.js - add more itemtypes

* revert moving special purchases to buy

* only use buyOp from api-routes

* fix buying potion client-side

* undo import buy instead of purchase

* enable potion bulk purchase - use buyGear as fallback (as before)

* move quantity purchase inside buyHealthPotion

* move quantity purchase inside buyQuest

* move quantity purchase inside buySpecialSpell + add analytics

* remove unused quantity variable - set req.type on specialKeys

* fix `buyKnownKeys` on buy api

* test buy-special-spell if not enough gold

* more buy ops coverage

* fix lint

* buyMysterySet: test for window.confirm, buyQuest: check for Masterclassers unlock

* fix test & lint

* re-create package-lock.json to travis build ?

* use global.window instead of method argument

* add back canOwn checks

* remove buyMysterySet confirm request
2018-02-10 11:14:40 +01:00
Matteo Pagliazzi 7abfd1d510 chore: docker: use correct gulp cli, tests: try to reduce timeouts 2018-02-10 11:14:01 +01:00
Sabe Jones b4cbcb172b Merge branch 'release' into develop 2018-02-10 05:36:49 +00:00
Sabe Jones f78bcc20c9 chore(i18n): update locales 2018-02-10 05:18:40 +00:00
negue 6506f1d44d fix user avatar transformation - change number of buffs owned when you use them - fixes #9795 (#9824)
* refresh not working - show avatar transformation

*  call store-action from mixin, use mixin from app.vue, add user-target in spells-mixin,

* fix avatar tranformation on user - clean up

* move default message

* fix purchase of cards

* fix casting
2018-02-09 17:04:08 -06:00
negue 6cb1ec4ec5 fix draging-info margin - resize draging icon - resize hatching modal (remove unneeded space) (#9775) 2018-02-09 16:48:48 -06:00
negue 723b4f3451 Attributes UI Refactoring (#9887)
* include class bonus in sorting

* wip - show more information in the attributes grid

* attributes tooltip + dialog redesign

* fix stat calculation

* fix spacings

* show class in equip-gear-modal

* fix buy-modal attributes-grid, clean up css

* show attributes popover in profile-stats overview

* add class / purchase type colors to colors.scss - replace colors by variable - clean up

* translate strings
2018-02-09 16:47:38 -06:00
James Hwang 6c677be9d2 Styles inputs in group modal to be consistent with rest of app #9897 (#9924)
* Styles input in group modal to be consistent with rest of app #9897

* Changed checkbox id to accurately describe the element
2018-02-09 16:44:56 -06:00
Александр f49c99ee06 replaced an outdated link //habitrpg.wikia.com (#9954)
* replaced an outdated link //habitrpg.wikia.com

Since http://habitica.wikia.com is the official link. Also, there are still incorrect paths in the footer menu, such as "Go to Social > Challenges" and others, when 'Challenges' is already on the menu bar.

* fix  Party to Guilds _mistake

Here is a simple mistake, because of what does not pass the verification
2018-02-09 16:19:02 -06:00
Alexey Pyltsyn 846feb1902 Make images responsive on features page (#9931) 2018-02-09 16:15:03 -06:00
Sabe Jones da22858ac0 Triumph Theme by anastasiagaskamp (#9323)
* feat(audio): Triumph Theme

* fix(audio): trim silence
2018-02-09 15:57:34 -06:00
SabreCat dafb6df18b feat(analytics): track account delete/reset 2018-02-09 21:36:14 +00:00
Keith Holliday 9017eea0c4 4.26.1 2018-02-09 10:05:12 -06:00
Keith Holliday 92abb19f9c Docker update (#9976)
* Updated docker prod

* Added new gulp cli
2018-02-09 08:59:49 -07:00
Keith Holliday 3bee0446b8 Loaded profile when not cached (#9977) 2018-02-09 08:57:55 -07:00
Matteo Pagliazzi 1ed58c452c Upgrade amplitude stripe amazon-payments cwait (#9962)
* upgrade amplitude stripe amazon-payments cwait

* correctly import cwait
2018-02-09 13:47:52 +01:00
Matteo Pagliazzi f947d3562b Remove user wrapping (#9960)
* remove user wrapping, fixes #9146

* update tests

* fix tests
2018-02-09 13:46:55 +01:00
Matteo Pagliazzi 8e24b0578e upgrade express, passport, ncong and csv-stringify, remove csv package that is only used in super old migrations (#9965) 2018-02-09 13:46:39 +01:00
Matteo Pagliazzi f87d6e3b31 groups: always fetch basic fields (#9975) 2018-02-09 13:46:17 +01:00
Sabe Jones e1e5a6cc34 4.26.0 2018-02-09 00:58:23 +00:00
Sabe Jones 9eb70ee9ba Merge branch 'develop' into release 2018-02-09 00:58:13 +00:00
Sabe Jones 7485300ee9 chore(i18n): update locales 2018-02-09 00:43:01 +00:00
SabreCat 762c202154 feat(content): enable Cupid Potions 2018-02-09 00:35:51 +00:00
Matteo Pagliazzi 7613e50917 remove mongoskin and mongodb packages 2018-02-08 19:10:01 +01:00
Matteo Pagliazzi 4c77434bf0 Upgrade karma and related deps (#9974)
* upgrade karma and karma babel

* upgrade karma-chai

* upgrade karma-coverage

* upgrade karma-mocha

* upgrade karma-mocha-reporter

* upgrade karma-sinon-chai

* upgrade karma-spec-reporter
2018-02-08 19:02:19 +01:00
Matteo Pagliazzi 1ab26a200e Upgrade tests packages (#9973)
* upgrade mochat to v5

* upgrade cross-spawn

* upgrade chalk

* try to fix mongoose

* upgrade shelljs

* upgrade expect.js

* upgrade coveralls

* upgrade cross-env

* upgrade lcov-result-merger

* upgrade image-size
2018-02-08 19:00:49 +01:00
Matteo Pagliazzi b738824f76 fix indentation in app.vue 2018-02-07 18:47:14 +01:00
Sabe Jones 694c440b55 Merge branch 'release' into develop 2018-02-07 02:16:48 +00:00
Sabe Jones 667bb28fe3 4.25.0 2018-02-07 02:16:24 +00:00
Sabe Jones 8993337ad7 chore(i18n): update locales 2018-02-07 02:15:58 +00:00
SabreCat a251a5d089 chore(sprites): compile 2018-02-07 02:04:37 +00:00
SabreCat dcdeec6256 feat(content): Badger Pet Quest 2018-02-07 02:03:30 +00:00
SabreCat 9fd0df9f2f fix(food): add missing text functions to Bare Bones Cake 2018-02-06 20:34:33 +00:00
Matteo Pagliazzi 1061fb0c31 remove async (only used for old migrations) (#9961) 2018-02-06 18:13:13 +01:00
Keith Holliday c14fdd3fed Fixed attribute binding. Removed member url (#9963) 2018-02-06 09:53:43 -07:00
Alys e219ad6bdf adjust slurs / banned words. TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc 2018-02-06 08:40:31 +10:00
Alys 42d7fd0861 fix typo in equipment description (Armorie) 2018-02-06 08:37:39 +10:00
Nathan Sollenberger 7ade91a8b8 Updates notification text for armoire items in shops:genericPurchase. (#9240)
Adjusts column widths for 'drop' type notifications to prevent .text from overlapping .icon-item.
Adds new 'flavorMessage' property to Snackbar notifications, which overrides standard computed message.
Vertically center XP gain icon/amount.
Fixes unrelated typo in i18n key name.
2018-02-05 19:43:30 +01:00
Feywood 7c6dd6a6bd (in)definite articles for food items. Partial fix for https://github.com/HabitRPG/habitica/issues/3571 (#9658)
* testing additional event trigger for sendMessage

* moved keyup event to newmessage

* added keyup event to tavern vue too

* all food items now have version with definite and indefinite article. foodText also adapted in messages json

* modified api.food, and feed, armoire and drop mechanism

* drops now ok, removed dropArticle, corrected feed test

* test correction

* api doc modification for task completion
2018-02-05 19:43:12 +01:00
Jon Lim 9a00779698 Adding support for loading more members for Groups (#9740)
* Adding support for loading more members for Groups

Addresses issue #9720

Member modal component was only loading the maximum limit for queries
made to _getMembersForItem in /members, except with Challenges, which
was able to display a "Load More" button to retrieve another set of
users from the Challenge.

Made a few changes to how the GET request was being made when querying
for more members, added an easier way to know whether or not to display
the Load More button, and extracted some of the actions that were
too tightly coupled with the membersModal.vue.

* Fixes for failing lint tests

* Removing unnecessary async/await usage

* Fixing party view in header section

* Resolving missed conflict

* Adding necessary data for View Party in index header for web client to load party members
2018-02-05 19:42:54 +01:00
Lula Villalobos a61d911c48 Feature - Store Exact Completion Date For Dailies (#9813)
* dailies history date added in scoreTask instead of cron

* fix lint issues

* changes based on feedback. Undo cron code deletion and deleted iteration on scoreTask

* fix lint issues

* add task history entry in cron for dailies that weren't completed

* add history entry after value is fully evaluated
2018-02-05 19:42:20 +01:00
Alexey Pyltsyn fbacb56700 Fixed footer to bottom of page (#9860) 2018-02-05 19:42:01 +01:00
Alexey Pyltsyn 185717e6c3 Fixed a task tag tooltip position (#9910) 2018-02-05 19:41:46 +01:00
Mason Hahn 505dd4969d add contributor info for inbox tier styling (#9911) 2018-02-05 19:41:28 +01:00
Feywood 944e4fe399 collection items shown in quest progress (#9945) 2018-02-05 19:41:11 +01:00
Keith Holliday 804dd087f8 Updated notes on armoire when purchasing (#9891) 2018-02-05 10:27:10 -07:00
Keith Holliday cb1136aadc Added markdown to tag edit fields/popup (#9867) 2018-02-05 09:54:42 -07:00
Keith Holliday 0f4b8f5f30 Added summary field tests (#9883)
* Added summary field tests

* Fixed typo
2018-02-05 09:52:44 -07:00
Keith Holliday 2d612b655d Added copy as todo (#9884) 2018-02-05 09:43:00 -07:00
negue 46877fb20c Purchase Card: fixes (#9803)
* prevent re-showing buy-modal after buying a card / fix class-badge in member-selection

* show notifications on card purchase

* move string to generic.json

* translation param "profileName"
2018-02-05 09:39:42 -07:00
Keith Holliday 38cded2083 4.24.6 2018-02-04 23:03:51 -06:00
Matteo Pagliazzi 65074df668 fix build task 2018-02-04 19:30:30 +01:00
Matteo Pagliazzi b0ab09c352 Upgrade gulp (and gulp deps) (#9950)
* upgrade gulp to v4

* fix imagemin

* fixes
2018-02-04 18:18:10 +01:00
Matteo Pagliazzi 3a60e8de66 Merge branch 'develop' of github.com:HabitRPG/habitrpg into develop 2018-02-04 15:54:35 +01:00
Matteo Pagliazzi 886a96dac9 Merge branch 'release' into develop 2018-02-04 15:53:40 +01:00
Matteo Pagliazzi 20556e2af4 refactor casting spells on the client side (#9949) 2018-02-04 15:51:17 +01:00
Matteo Pagliazzi 3e849ec9a8 Revert "refactor casting spells on the client side (#9921)" (#9948)
This reverts commit 03946e6a87.
2018-02-04 15:50:36 +01:00
Matteo Pagliazzi 03946e6a87 refactor casting spells on the client side (#9921) 2018-02-04 14:47:34 +01:00
Matteo Pagliazzi fdcc69fe4a Merge branch 'upgrade-universal-analytics' into develop 2018-02-04 14:45:31 +01:00
Matteo Pagliazzi 322b6a5e44 Merge branch 'develop' into upgrade-universal-analytics 2018-02-04 14:45:20 +01:00
Matteo Pagliazzi 2243a2f3dc upgrade winston-loggly-bulk (#9942) 2018-02-04 14:40:33 +01:00
Matteo Pagliazzi 59c848add5 upgrade request (#9941) 2018-02-04 14:39:54 +01:00
Matteo Pagliazzi 2d6a1fe709 remove jade, upgrade pug (#9940) 2018-02-04 14:39:46 +01:00
Matteo Pagliazzi fac0338437 Merge branch 'release' into develop 2018-02-04 14:39:30 +01:00
Matteo Pagliazzi e46f30894c fix test timeout 2018-02-04 14:39:16 +01:00
Matteo Pagliazzi 553dc116c5 Merge branch 'release' into develop 2018-02-04 14:21:35 +01:00
Matteo Pagliazzi 2029cd884c notifications: fix tests 2018-02-04 14:20:12 +01:00
Matteo Pagliazzi ab89941ed5 notifications: fix tests 2018-02-04 14:04:41 +01:00
Matteo Pagliazzi 5dc0f5bb9b Merge branch 'release' into develop 2018-02-04 13:41:53 +01:00
Matteo Pagliazzi d46a7ba985 notifications: fix typos and add extra check 2018-02-04 13:40:49 +01:00
Matteo Pagliazzi 86b3228a59 Merge branch 'release' into develop 2018-02-04 13:28:34 +01:00
Matteo Pagliazzi 4efbbd7bac notifications: fixes 2018-02-04 13:28:05 +01:00
Matteo Pagliazzi d39e8a3587 upgrade universal-analytics 2018-02-03 22:40:40 +01:00
Matteo Pagliazzi 8bd3ef6f24 fix mongoose options 2018-02-03 22:17:10 +01:00
Matteo Pagliazzi 6d0917964b fix mongoose options 2018-02-03 22:15:40 +01:00
Sabe Jones d463e2373e Merge branch 'release' into develop 2018-02-02 20:51:24 +00:00
Sabe Jones 2af99d7c65 4.24.5 2018-02-02 19:53:57 +00:00
Keith Holliday 4e01b14874 Removed required fields from user notifications (#9929) 2018-02-02 12:31:52 -07:00
Keith Holliday 944781c2f8 Added p parameter to group party query (#9857) 2018-02-02 11:24:41 -07:00
Keith Holliday 027eed1b25 Reset market on gear purchase (#9855) 2018-02-02 11:22:25 -07:00
Keith Holliday 803f63d991 Added two handed message to weapons (#9839)
* Added two handed message to weapons

* Added two handed message to content api

* Fixed static notes text. Added support for RTL
2018-02-02 11:21:53 -07:00
Keith Holliday 78ad1cd8b0 Added cache for user styles on chat (#9679)
* Added cache for user styles on chat

* Added loading on new message and other minor checks

* Added null checks

* Updated chat tests

* Added costume preference to chat

* Removed single profile cacheing for new chat messages

* Remove owned gear from cache

* Updated stats to only use buffs
2018-02-02 11:18:25 -07:00
Sabe Jones a3ddd0746c 4.24.4 2018-02-02 16:55:55 +00:00
SabreCat 94845ec629 fix(event): remove seasonal pinned items 2018-02-02 16:54:25 +00:00
Sabe Jones 7e63856e64 4.24.3 2018-02-02 16:44:09 +00:00
Matteo Pagliazzi 3727d69d51 Merge branch 'release' into develop 2018-02-02 16:38:27 +01:00
Matteo Pagliazzi 1fbdb7dbd0 Mongoose 4.x (#9928)
* update mongoose to ^4.x

* another fix
2018-02-02 16:37:36 +01:00
Matteo Pagliazzi b430b6ccb6 Revert "Mongoose 4.13 (#9926)" (#9927)
This reverts commit 7859f20a40.
2018-02-02 16:36:54 +01:00
Matteo Pagliazzi 7859f20a40 Mongoose 4.13 (#9926)
* update mongoose to ^4.x

* another fix
2018-02-02 16:35:05 +01:00
Matteo Pagliazzi 389d6f18b4 travis split unit and integration tests (#9925) 2018-02-02 15:07:39 +01:00
Sabe Jones fd1d1da509 Revert "fix(test): update for event"
This reverts commit ede28ac33a.
2018-02-02 12:09:45 +00:00
Matteo Pagliazzi 014b367f56 do not use lodash to find notification 2018-02-02 12:24:43 +01:00
Matteo Pagliazzi 4580b33e43 fix progress bar hidden behind the menu 2018-02-02 09:57:39 +01:00
Sabe Jones 48bcc1e968 4.24.2 2018-02-02 03:35:00 +00:00
Sabe Jones 35368eb6ad chore(i18n): update locales 2018-02-02 03:33:27 +00:00
Sabe Jones 9b337983ed fix(strings): Capital Party, comrade 2018-02-02 03:27:19 +00:00
Sabe Jones cd4951d204 fix(notifs): brevity 2018-02-02 03:19:13 +00:00
Sabe Jones bd83d6f5aa 4.24.1 2018-02-02 01:51:08 +00:00
Sabe Jones 9c241a6159 fix(classes): remove winter preview
Also adds a new index to the Mongo doc and fixes a typo in that file.
2018-02-02 01:49:33 +00:00
Sabe Jones 7a6baeadbd 4.24.0 2018-02-02 00:48:36 +00:00
Sabe Jones 5495acea96 chore(i18n): update locales 2018-02-02 00:46:45 +00:00
SabreCat a3aa2cc175 chore(sprites): compile 2018-02-02 00:33:04 +00:00
SabreCat 8b0d02a16b feat(content): backgrounds and Armoire Feb 2018
Also ends Winter Wonderland event
2018-02-02 00:31:38 +00:00
SabreCat c3c0eb974a Merge branch 'develop' into release 2018-02-02 00:29:58 +00:00
Keith Holliday 56539100e3 Fixed zindex for progress bar (#9922) 2018-02-01 18:12:34 -06:00
SabreCat b706db43e4 Merge branch 'release' into develop 2018-02-01 21:09:57 +00:00
Keith Holliday 3e0a7c70ed Event off fixes (#9918)
* Added removes for all events

* Moved to beforeDestroy
2018-02-01 10:14:21 -07:00
Sabe Jones 6a5bd1b0a5 Merge branch 'release' into develop 2018-01-31 22:23:15 +00:00
Sabe Jones 7f8a9be766 4.23.2 2018-01-31 22:20:51 +00:00
Sabe Jones dbdf679e4a chore(i18n): update locales 2018-01-31 22:20:39 +00:00
SabreCat eb28dfadf9 chore(news): Last Chance Bailey
Also fixes a linting issue with birthday fun.
2018-01-31 22:10:50 +00:00
SabreCat ede28ac33a fix(test): update for event 2018-01-31 22:00:54 +00:00
Matteo Pagliazzi 33b249d078 Notifications v2 and Bailey API (#9716)
* Added initial bailey api

* wip

* implement new panel header

* Fixed lint

* add ability to mark notification as seen

* add notification count, remove top badge from user and add ability to mark multiple notifications as seen

* add support dismissall and mark all as read

* do not dismiss actionable notif

* mark as seen when menu is opened instead of closed

* implement ordering, list of actionable notifications

* add groups messages and fix badges count

* add notifications for received cards

* send card received notification to target not sender

* rename notificaion field

* fix integration tests

* mark cards notifications as read and update tests

* add mystery items notifications

* add unallocated stats points notifications

* fix linting

* simplify code

* refactoring and fixes

* fix dropdown opening

* start splitting notifications into their own component

* add notifications for inbox messages

* fix unit tests

* fix default buttons styles

* add initial bailey support

* add title and tests to new stuff notification

* add notification if a group task needs more work

* add tests and fixes for marking a task as needing more work

* make sure user._v is updated

* remove console.log

* notification: hover status and margins

* start styling notifications, add separate files and basic functionalities

* fix tests

* start adding mystery items notification

* wip card notification

* fix cards text

* initial implementation inbox messages

* initial implementation group messages

* disable inbox notifications until mobile is ready

* wip group chat messages

* finish mystery and card notifications

* add bailey notification and fix a lot of stuff

* start adding guilds and parties invitations

* misc invitation fixes

* fix lint issues

* remove old code and add key to notifications

* fix tests

* remove unused code

* add link for public guilds invite

* starts to implement needs work notification design and feature

* fixes to needs work, add group task approved notification

* finish needs work feature

* lots of fixes

* implement quest notification

* bailey fixes and static page

* routing fixes

* fixes #      this.$store.dispatch(guilds:join, {groupId: group.id, type: party});

* read notifications on click

* chat notifications

* fix tests for chat notifications

* fix chat notification test

* fix tests

* fix tests (again)

* try awaiting

* remove only

* more sleep

* add bailey tests

* fix icons alignment

* fix issue with multiple points notifications

* remove merge code

* fix rejecting guild invitation

* make remove area bigger

* fix error with notifications and add migration

* fix migration

* fix typos

* add cleanup migration too

* notifications empty state, new counter color, fix marking messages as seen in guilds

* fixes

* add image and install correct packages

* fix mongoose version

* update bailey

* typo

* make sure chat is marked as read after other requests
2018-01-31 11:55:39 +01:00
Matteo Pagliazzi a85282763f Upgrade sinonjs (and related libs) (#9914)
* update sinon

* remove errors

* fix unit tests
2018-01-31 10:56:32 +01:00
Sabe Jones ba9d7b3b5e 4.23.1 2018-01-31 00:53:27 +00:00
Sabe Jones 3b794c017a fix(event): update birthday vars and hooks 2018-01-31 00:41:06 +00:00
SabreCat 47dbe4561f fix(test): update for event 2018-01-30 22:22:02 +00:00
Sabe Jones 97135a1ac3 Merge branch 'release' into develop 2018-01-30 21:38:56 +00:00
Sabe Jones a636e15d11 4.23.0 2018-01-30 21:38:34 +00:00
Sabe Jones 3cc15e869e chore(i18n): update locales 2018-01-30 21:38:00 +00:00
SabreCat 88c8b92a68 chore(sprites): compile 2018-01-30 21:26:15 +00:00
SabreCat cee4d7e87b feat(event): Habit Birthday 2018 2018-01-30 21:25:19 +00:00
Matteo Pagliazzi 9488ec2eb0 Merge branch 'release' into develop 2018-01-30 18:56:25 +01:00
Keith Holliday 4fe6c8db64 Clone challenges api (#9684)
* Added clone api

* Added new clone UI

* Fixed challenge clone

* Fixed lint and added mongo toObject

* Removed clone field, fixed type, fixed challenge task query

* Auto selected group

* Accounted for group balance when creating challenge

* Added check for if user is leader of guild

* Added leader existence check

* Added fix for leader and prizecost equal to
2018-01-30 08:23:20 -07:00
Keith Holliday ccf8e0b320 Removed gitattributes 2018-01-29 21:34:18 -06:00
Matteo Pagliazzi 1dc558ddba prevent ex-participants appearing in challenge export file - Fix #9844 (#9846)
* possible fix for 9844

* fix typo in challengeModal file

* remove lines for empty users
2018-01-29 16:23:40 -06:00
Alexey Pyltsyn ae27ae0090 Improved Party page UI (#9892) 2018-01-29 15:44:22 -06:00
Alys 47c2a3a21a prevent "Zero-day streak" giving a 21-day streak achievement + tests - fixes #2578 (#9688)
* prevent "Zero-day streak" giving a 21-day streak achievement - fixes #2578

* add tests for streak achievements

* remove .only from set of tests

* refactor(test): fix linting
2018-01-29 15:43:59 -06:00
Cassidy Pignatello 5d4e1362bb updates Orb of Rebirth description to more accurately list its effects (#9894) 2018-01-29 15:32:21 -06:00
James Hwang 25cecf298f Fixed formatting of modal strings to correctly display message #9818 (#9862) 2018-01-29 15:30:05 -06:00
Alexey Pyltsyn 2de3b63e87 Fixed a community guidelines layout (#9893)
* Fixed a community guidelines layout

* Refactoring: add community guidelines component
2018-01-29 15:18:20 -06:00
John Zhou 7abb8a81a7 Do not show visual buffs on choose class avatars (#9812) 2018-01-29 15:16:49 -06:00
Daniel Reeves 3eb3891899 Update copyright year 2017->2018 (#9889) 2018-01-29 15:14:00 -06:00
Alexey Pyltsyn 4b0ad422f1 Use translatable strings in footer (#9866) 2018-01-29 15:11:30 -06:00
Alexey Pyltsyn 3c603e3bb1 Fixed horizontal scrollbar (#9853) 2018-01-29 15:07:59 -06:00
Nicole Massaro 4ee788f541 Hide stats points allocation on locked or disabled class system (#9826) (#9851) 2018-01-29 15:05:06 -06:00
Sabe Jones 99ab9726b4 Allow user to buy numbered special gear (#9823)
* fix(buy): allow user to buy numbered special gear

* fix(buy): correct content constant
2018-01-29 15:02:55 -06:00
Maru de Vera 23dd402e79 Unpin Regained Items from Enchanted Armoire (#9766) 2018-01-29 15:00:19 -06:00
Irina Brennen 6bd90807f3 Fixing issue with hair bangs, styles and colors not getting the option.active class (#9759) 2018-01-29 14:57:35 -06:00
Alys 563a5845f0 refund gems when deleting a "Public Challenge" (Tavern challenge) (#9752) 2018-01-29 14:56:46 -06:00
Brad Lugo 2e580baf27 Update the docker compose process (#9724)
Since the client side code and server side code run independently, the
docker compose process needed to be updated to reflect this change.
This fix included updating the docker-compose files' versions.
2018-01-29 14:56:08 -06:00
Clement134 44ded25f6d Add .gitattributes file fixes #9717 (#9722)
* chore(gitattributes): add .gitattributes file

*  chore(gitattributes): specify file type for each extension

* fix(presskit): use LF line endings
2018-01-29 14:53:14 -06:00
Alys 70da5940a7 clarify that "Leave" refers to guild/party; fix pluralisation in keep/remove challenge tasks (#9706)
* change "Keep/Remove It" to "Keep/Remove Them" when asking about all challenge tasks while leaving a challenge

* change "Leave" button on groups to "Leave Guild" or "Leave Party"

This is because the button is underneath the challenges so this
clarifies that it is referring to the group, not a challenge.

* change "Keep/Remove Them" to "Keep/Remove Tasks"
2018-01-29 14:52:28 -06:00
Cai Lu 12aa8a78c1 Track sleeping in the inn with analytics (fixes #9561) (#9685)
* Sleep status is tracked by analytics when toggled.

* Modify test: test that analytics is called with 'sleep' event and data passed includes the user's new sleep status
2018-01-29 14:48:24 -06:00
Keith Holliday 94619737e8 Adjusted zindex of navbar to be above snackbars and modals (#9873) 2018-01-29 08:25:07 -07:00
Alys ccc9e6611c adjust terminology in delete To-Dos message; move similar messages together 2018-01-28 12:29:24 +10:00
Keith Holliday 1f1459b0d8 4.22.1 2018-01-27 11:31:59 -06:00
Keith Holliday 6489e74b6b Added tests for new username restrictions (#9900) 2018-01-27 10:30:17 -07:00
Alys c1e264955f describe Login Name limitations on Registration form and Add Local Auth form (#9896)
* describe Login Name limitations on registration form and Add Local Auth form

* adjust text in response to this change: https://github.com/HabitRPG/habitica/pull/9895/commits/c69687f935bc95a94f557ef9950e435622c282ff

* update max length
2018-01-27 09:38:23 -07:00
Alys f302d15bc4 add length and character limitations for login name (username) (#9895)
* update API comments to for `username` restrictions and to use Login Name terminology

We use "login name" rather than "username" in user-visible text
on the website and (usually) when communicating with users because
"username" could be confused with "profile name".
Using it in the docs allows you to search for that term.

* add alphanumeric and length validation for creating new login name (username)

The 'en-US' locale is specified explicitly to ensure we never use
another locale. The point of this change is to limit the character
set to prevent login names being used to send spam in the Welcome
emails, such as Chinese language spam we've had trouble with.

* add error messages for bad login names

* allow login name to also contain hyphens

This is because our automated tests generate user accounts using:
  let username = generateUUID();

* allow login names to be up to 36 characters long because we use UUIDs as login names in our tests

* revert back to using max 20 characters and only a-z, 0-9 for login name.

It's been decided to change the username generation in the tests instead.

* disable test that is failing because it's redundant

Spaces are now prohibited by other code.

We can probably delete this test later. I don't want to delete it
now, but instead give us time to think about that.

* fix typos

* revert to login name restrictions that allow us to keep using our existing test code

I'm really not comfortable changing our test suite in ways that
aren't essential, especially since we're working in a hurry with
a larger chance than normal of breaking things.
The 36 character length is larger than we initially decided but
not so much larger that it's a huge problem.
We can reduce it to 20 when we have more time.

* limit username length to 20 chars

* fix tests
2018-01-27 09:33:56 -07:00
Keith Holliday 8c70c8839b 4.22.0 2018-01-25 17:35:45 -06:00
Keith Holliday 3fcd04fd8a Updated encryption 2018-01-25 17:33:50 -06:00
Sabe Jones d85f18751c chore(i18n): update locales 2018-01-25 23:26:24 +00:00
SabreCat 1390c4eae5 Merge branch 'develop' into release 2018-01-25 23:20:01 +00:00
Sabe Jones 18ade8ca65 Analytics: track challenge and task events (#9885)
* feat(analytics): track challenge and task events

* feat(analytics): add more challenge events
Also tweaks data for better troubleshooting utility

* refactor(analytics): include IDs for challenges/groups

* refactor(analytics): term for award challenge is "close"
2018-01-25 17:14:41 -06:00
Keith Holliday 7b026fa32c Added existence check for lastMessageText (#9886) 2018-01-25 13:46:49 -07:00
Keith Holliday 33698c219f Added existence check for lastMessageText (#9881) 2018-01-25 11:33:37 -07:00
Matteo Pagliazzi b76d731cee fix gold icon alignment 2018-01-25 16:53:53 +01:00
Matteo Pagliazzi 4d1ac51543 upgrade datepicker 2018-01-25 15:13:21 +01:00
Matteo Pagliazzi 3818fbdd3e update boostrap and bootstrap-vue (no breaking changes) 2018-01-24 19:08:07 +01:00
Sabe Jones af245b63d9 Merge branch 'release' into develop 2018-01-24 01:31:27 +00:00
Keith Holliday 51aebb540c Removed display of users personal checklist on challenge tasks (#9837) 2018-01-23 10:55:55 -07:00
Keith Holliday f5d7777b2c Reloaded user data after cancelling subscription (#9836) 2018-01-23 10:28:44 -07:00
Keith Holliday be1ffbd671 Removed promot to leader from challenge member modal (#9831) 2018-01-23 09:58:12 -07:00
Keith Holliday 5640139ef1 Awaited unlink so the UI refreshes removed tasks (#9815) 2018-01-23 09:36:46 -07:00
Keith Holliday 0959499450 Changed width to maxwidth (#9830) 2018-01-22 09:15:55 -07:00
Keith Holliday 90ffe587dd Added analytics to drop (#9792)
* Added analytics to drop

* Updated tracking category
2018-01-22 09:15:23 -07:00
Keith Holliday 38aafb6c7b Added clear completed todos (#9782) 2018-01-22 08:28:42 -07:00
Keith Holliday ecfcf09184 Added more responsive styles to filters (#9820) 2018-01-22 08:20:34 -07:00
Keith Holliday 7083dc7e05 Added resync for completed todos (#9821) 2018-01-22 08:19:47 -07:00
Keith Holliday d4e0417c48 Added challenge tag when challenge task is added to existing challenge (#9833) 2018-01-22 08:19:27 -07:00
Matteo Pagliazzi 6f9db87843 Upgrade travis (#9850)
* upgrade travis

* upgrade travis
2018-01-21 22:47:58 +01:00
Matteo Pagliazzi 46c9038f54 Remove unused packages (#9849)
* remove unused packages

* update lock package

* try with paypal-rest-sdk 1.7.1

* setup nconf
2018-01-21 21:23:25 +01:00
Matteo Pagliazzi de93b47493 add new notifications types 2018-01-20 17:28:50 +01:00
1514 changed files with 61056 additions and 47500 deletions
+2 -9
View File
@@ -10,12 +10,5 @@ apidoc_build/
content_cache/
node_modules/
# Not linted
website/client-old/
test/client-old/spec/**/*
# Temporarilly disabled. These should be removed when the linting errors are fixed TODO
migrations/*
scripts/*
website/common/browserify.js
Gruntfile.js
# Old migrations, disabled
migrations/archive/*
+8 -14
View File
@@ -1,37 +1,31 @@
language: node_js
node_js:
- '6'
sudo: required
dist: precise
services:
- mongodb
cache:
directories:
- 'node_modules'
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
chrome: stable
before_install:
- $CXX --version
- npm install -g npm@5
- if [ $REQUIRES_SERVER ]; then sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10; echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list; sudo apt-get update; sudo apt-get install mongodb-org-server; fi
install:
- npm install &> npm.install.log || (cat npm.install.log; false)
before_script:
- npm run test:build
- cp config.json.example config.json
- sleep 15
- sleep 5
script:
- npm run $TEST
- if [ $COVERAGE ]; then ./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js; fi
env:
global:
- CXX=g++-4.8
- DISABLE_REQUEST_LOGGING=true
matrix:
- TEST="lint"
- TEST="test:api-v3" REQUIRES_SERVER=true COVERAGE=true
- TEST="test:api-v3:unit" REQUIRES_SERVER=true COVERAGE=true
- TEST="test:api-v3: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"
+1 -1
View File
@@ -4,7 +4,7 @@ FROM node:boron
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
RUN yarn global add npm@5
# Install global packages
RUN npm install -g gulp mocha
RUN npm install -g gulp-cli mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
+2 -2
View File
@@ -15,12 +15,12 @@ ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
RUN yarn global add npm@5
# Install global packages
RUN npm install -g gulp mocha
RUN npm install -g gulp-cli mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
WORKDIR /usr/src/habitrpg
RUN git clone --branch v4.20.3 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN git clone --branch v4.29.2 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN npm install
RUN gulp build:prod --force
+3 -1
View File
@@ -1,6 +1,8 @@
Habitica [![Build Status](https://travis-ci.org/HabitRPG/habitica.svg?branch=develop)](https://travis-ci.org/HabitRPG/habitica) [![Code Climate](https://codeclimate.com/github/HabitRPG/habitrpg.svg)](https://codeclimate.com/github/HabitRPG/habitrpg) [![Coverage Status](https://coveralls.io/repos/github/HabitRPG/habitica/badge.svg?branch=develop)](https://coveralls.io/github/HabitRPG/habitica?branch=develop) [![Bountysource](https://api.bountysource.com/badge/tracker?tracker_id=68393)](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE)
Habitica [![Build Status](https://travis-ci.org/HabitRPG/habitica.svg?branch=develop)](https://travis-ci.org/HabitRPG/habitica) [![Code Climate](https://codeclimate.com/github/HabitRPG/habitrpg.svg)](https://codeclimate.com/github/HabitRPG/habitrpg) [![Coverage Status](https://coveralls.io/repos/github/HabitRPG/habitica/badge.svg?branch=develop)](https://coveralls.io/github/HabitRPG/habitica?branch=develop) [![Bountysource](https://api.bountysource.com/badge/tracker?tracker_id=68393)](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Open Source Helpers](https://www.codetriage.com/habitrpg/habitica/badges/users.svg)](https://www.codetriage.com/habitrpg/habitica)
===============
[![Greenkeeper badge](https://badges.greenkeeper.io/HabitRPG/habitica.svg)](https://greenkeeper.io/)
[Habitica](https://habitica.com) is an open source habit building program which treats your life like a Role Playing Game. Level up as you succeed, lose HP as you fail, earn money to buy weapons and armor.
We need more programmers! Your assistance will be greatly appreciated.
+9
View File
@@ -22,6 +22,8 @@
"CRON_SEMI_SAFE_MODE":"false",
"MAINTENANCE_MODE": "false",
"SESSION_SECRET":"YOUR SECRET HERE",
"SESSION_SECRET_KEY": "1234567891234567891234567891234567891234567891234567891234567891",
"SESSION_SECRET_IV": "12345678912345678912345678912345",
"ADMIN_EMAIL": "you@example.com",
"SMTP_USER":"user@example.com",
"SMTP_PASS":"password",
@@ -103,5 +105,12 @@
"LOGGLY" : {
"TOKEN" : "example-token",
"SUBDOMAIN" : "exmaple-subdomain"
},
"KAFKA": {
"GROUP_ID": "",
"CLOUDKARAFKA_BROKERS": "",
"CLOUDKARAFKA_USERNAME": "",
"CLOUDKARAFKA_PASSWORD": "",
"CLOUDKARAFKA_TOPIC_PREFIX": ""
}
}
+10 -3
View File
@@ -1,3 +1,10 @@
web:
volumes:
- '.:/usr/src/habitrpg'
version: "3"
services:
client:
volumes:
- '.:/usr/src/habitrpg'
server:
volumes:
- '.:/usr/src/habitrpg'
+35 -12
View File
@@ -1,13 +1,36 @@
web:
build: .
ports:
- "3000:3000"
links:
- mongo
environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
version: "3"
services:
mongo:
image: mongo
ports:
- "27017:27017"
client:
build: .
networks:
- habitica
environment:
- BASE_URL=http://server:3000
ports:
- "8080:8080"
command: ["npm", "run", "client:dev"]
depends_on:
- server
server:
build: .
ports:
- "3000:3000"
networks:
- habitica
environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
depends_on:
- mongo
mongo:
image: mongo
ports:
- "27017:27017"
networks:
- habitica
networks:
habitica:
driver: bridge
+5 -5
View File
@@ -8,7 +8,7 @@ gulp.task('apidoc:clean', (done) => {
clean(APIDOC_DEST_PATH, done);
});
gulp.task('apidoc', ['apidoc:clean'], (done) => {
gulp.task('apidoc', gulp.series('apidoc:clean', (done) => {
let result = apidoc.createDoc({
src: APIDOC_SRC_PATH,
dest: APIDOC_DEST_PATH,
@@ -19,8 +19,8 @@ gulp.task('apidoc', ['apidoc:clean'], (done) => {
} else {
done();
}
});
}));
gulp.task('apidoc:watch', ['apidoc'], () => {
return gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, ['apidoc']);
});
gulp.task('apidoc:watch', gulp.series('apidoc', (done) => {
return gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, gulp.series('apidoc', done));
}));
+15 -9
View File
@@ -2,12 +2,6 @@ import gulp from 'gulp';
import babel from 'gulp-babel';
import webpackProductionBuild from '../webpack/build';
gulp.task('build', () => {
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
gulp.start('build:prod');
}
});
gulp.task('build:src', () => {
return gulp.src('website/server/**/*.js')
.pipe(babel())
@@ -20,18 +14,30 @@ gulp.task('build:common', () => {
.pipe(gulp.dest('website/common/transpiled-babel/'));
});
gulp.task('build:server', ['build:src', 'build:common']);
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.task('build:prod', gulp.series(
'build:server',
'build:client',
'apidoc',
]);
done => done()
));
let buildArgs = [];
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
buildArgs.push('build:prod');
}
gulp.task('build', gulp.series(buildArgs, (done) => {
done();
}));
+12 -13
View File
@@ -1,5 +1,4 @@
import mongoose from 'mongoose';
import autoinc from 'mongoose-id-autoinc';
import logger from '../website/server/libs/logger';
import nconf from 'nconf';
import repl from 'repl';
@@ -25,23 +24,23 @@ let improveRepl = (context) => {
const isProd = nconf.get('NODE_ENV') === 'production';
const mongooseOptions = !isProd ? {} : {
replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
keepAlive: 1,
connectTimeoutMS: 30000,
useMongoClient: true,
};
autoinc.init(
mongoose.connect(
nconf.get('NODE_DB_URI'),
mongooseOptions,
(err) => {
if (err) throw err;
logger.info('Connected with Mongoose');
}
)
mongoose.connect(
nconf.get('NODE_DB_URI'),
mongooseOptions,
(err) => {
if (err) throw err;
logger.info('Connected with Mongoose');
}
);
};
gulp.task('console', () => {
gulp.task('console', (done) => {
improveRepl(repl.start({
prompt: 'Habitica > ',
}).context);
done();
});
+7 -4
View File
@@ -7,6 +7,7 @@ import mergeStream from 'merge-stream';
import {basename} from 'path';
import {sync} from 'glob';
import {each} from 'lodash';
import vinylBuffer from 'vinyl-buffer';
// https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248
const MAX_SPRITESHEET_SIZE = 1024 * 1024 * 3;
@@ -104,6 +105,7 @@ function createSpritesStream (name, src) {
}));
let imgStream = spriteData.img
.pipe(vinylBuffer())
.pipe(imagemin())
.pipe(gulp.dest(IMG_DIST_PATH));
@@ -117,8 +119,6 @@ function createSpritesStream (name, src) {
return stream;
}
gulp.task('sprites:compile', ['sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions']);
gulp.task('sprites:main', () => {
let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
return createSpritesStream('main', mainSrc);
@@ -133,7 +133,7 @@ gulp.task('sprites:clean', (done) => {
clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done);
});
gulp.task('sprites:checkCompiledDimensions', ['sprites:main', 'sprites:largeSprites'], () => {
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;
@@ -159,4 +159,7 @@ gulp.task('sprites:checkCompiledDimensions', ['sprites:main', 'sprites:largeSpri
} else {
console.log('All images are within the correct dimensions'); // eslint-disable-line no-console
}
});
done();
}));
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions', done => done()));
+2 -1
View File
@@ -3,7 +3,7 @@ import nodemon from 'gulp-nodemon';
let pkg = require('../package.json');
gulp.task('nodemon', () => {
gulp.task('nodemon', (done) => {
nodemon({
script: pkg.main,
ignore: [
@@ -12,4 +12,5 @@ gulp.task('nodemon', () => {
'common/dist/script/content/*',
],
});
done();
});
+46 -47
View File
@@ -4,7 +4,6 @@ import {
import mongoose from 'mongoose';
import { exec } from 'child_process';
import gulp from 'gulp';
import runSequence from 'run-sequence';
import os from 'os';
import nconf from 'nconf';
@@ -39,23 +38,23 @@ let testBin = (string, additionalEnvVariables = '') => {
}
};
gulp.task('test:nodemon', () => {
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
runSequence('nodemon');
});
done();
}, 'nodemon'));
gulp.task('test:prepare:mongo', (cb) => {
mongoose.connect(TEST_DB_URI, (err) => {
if (err) return cb(`Unable to connect to mongo database. Are you sure it's running? \n\n${err}`);
mongoose.connection.db.dropDatabase();
mongoose.connection.close();
cb();
mongoose.connection.dropDatabase((err2) => {
if (err2) return cb(err2);
mongoose.connection.close(cb);
});
});
});
gulp.task('test:prepare:server', ['test:prepare:mongo'], () => {
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) {
@@ -64,16 +63,18 @@ gulp.task('test:prepare:server', ['test:prepare:mongo'], () => {
if (stderr) {
console.error(stderr); // eslint-disable-line no-console
}
done();
});
}
});
}));
gulp.task('test:prepare:build', ['build']);
gulp.task('test:prepare:build', gulp.series('build', done => done()));
gulp.task('test:prepare', [
gulp.task('test:prepare', gulp.series(
'test:prepare:build',
'test:prepare:mongo',
]);
done => done()
));
gulp.task('test:sanity', (cb) => {
let runner = exec(
@@ -88,7 +89,7 @@ gulp.task('test:sanity', (cb) => {
pipe(runner);
});
gulp.task('test:common', ['test:prepare:build'], (cb) => {
gulp.task('test:common', gulp.series('test:prepare:build', (cb) => {
let runner = exec(
testBin(COMMON_TEST_COMMAND),
(err) => {
@@ -99,17 +100,17 @@ gulp.task('test:common', ['test:prepare:build'], (cb) => {
}
);
pipe(runner);
});
}));
gulp.task('test:common:clean', (cb) => {
pipe(exec(testBin(COMMON_TEST_COMMAND), () => cb()));
});
gulp.task('test:common:watch', ['test:common:clean'], () => {
gulp.watch(['common/script/**/*', 'test/common/**/*'], ['test:common:clean']);
});
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', ['test:prepare:build'], (cb) => {
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
@@ -123,9 +124,9 @@ gulp.task('test:common:safe', ['test:prepare:build'], (cb) => {
}
);
pipe(runner);
});
}));
gulp.task('test:content', ['test:prepare:build'], (cb) => {
gulp.task('test:content', gulp.series('test:prepare:build', (cb) => {
let runner = exec(
testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS,
@@ -137,17 +138,17 @@ gulp.task('test:content', ['test:prepare:build'], (cb) => {
}
);
pipe(runner);
});
}));
gulp.task('test:content:clean', (cb) => {
pipe(exec(testBin(CONTENT_TEST_COMMAND), CONTENT_OPTIONS, () => cb()));
});
gulp.task('test:content:watch', ['test:content:clean'], () => {
gulp.watch(['common/script/content/**', 'test/**'], ['test:content:clean']);
});
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', ['test:prepare:build'], (cb) => {
gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
let runner = exec(
testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS,
@@ -162,7 +163,7 @@ gulp.task('test:content:safe', ['test:prepare:build'], (cb) => {
}
);
pipe(runner);
});
}));
gulp.task('test:api-v3:unit', (done) => {
let runner = exec(
@@ -179,7 +180,7 @@ gulp.task('test:api-v3:unit', (done) => {
});
gulp.task('test:api-v3:unit:watch', () => {
gulp.watch(['website/server/libs/*', 'test/api/v3/unit/**/*', 'website/server/controllers/**/*'], ['test:api-v3:unit']);
return gulp.watch(['website/server/libs/*', 'test/api/v3/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api-v3:unit', done => done()));
});
gulp.task('test:api-v3:integration', (done) => {
@@ -198,8 +199,10 @@ gulp.task('test:api-v3:integration', (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/**/*'], ['test:api-v3:integration']);
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-v3:integration:separate-server', (done) => {
@@ -212,21 +215,17 @@ gulp.task('test:api-v3:integration:separate-server', (done) => {
pipe(runner);
});
gulp.task('test', (done) => {
runSequence(
'test:sanity',
'test:content',
'test:common',
'test:api-v3:unit',
'test:api-v3:integration',
done
);
});
gulp.task('test', gulp.series(
'test:sanity',
'test:content',
'test:common',
'test:api-v3:unit',
'test:api-v3:integration',
done => done()
));
gulp.task('test:api-v3', (done) => {
runSequence(
'test:api-v3:unit',
'test:api-v3:integration',
done
);
});
gulp.task('test:api-v3', gulp.series(
'test:api-v3:unit',
'test:api-v3:integration',
done => done()
));
+12 -5
View File
@@ -93,9 +93,7 @@ const malformedStringExceptions = {
feedPet: true,
};
gulp.task('transifex', ['transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings']);
gulp.task('transifex:missingFiles', () => {
gulp.task('transifex:missingFiles', (done) => {
let missingStrings = [];
eachTranslationFile(ALL_LANGUAGES, (error) => {
@@ -109,9 +107,10 @@ gulp.task('transifex:missingFiles', () => {
let formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:missingStrings', () => {
gulp.task('transifex:missingStrings', (done) => {
let missingStrings = [];
eachTranslationString(ALL_LANGUAGES, (language, filename, key, englishString, translationString) => {
@@ -126,9 +125,10 @@ gulp.task('transifex:missingStrings', () => {
let formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:malformedStrings', () => {
gulp.task('transifex:malformedStrings', (done) => {
let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
let interpolationRegex = /<%= [a-zA-Z]* %>/g;
let stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex);
@@ -170,4 +170,11 @@ gulp.task('transifex:malformedStrings', () => {
let formattedMessage = formatMessageForPosting(message, stringsWithIncorrectNumberOfInterpolations);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task(
'transifex',
gulp.series('transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings'),
(done) => done()
);
+3 -1
View File
@@ -8,10 +8,12 @@
require('babel-register');
const gulp = require('gulp');
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
require('./gulp/gulp-build'); // eslint-disable-line global-require
} else {
require('glob').sync('./gulp/gulp-*').forEach(require); // eslint-disable-line global-require
require('gulp').task('default', ['test']); // eslint-disable-line global-require
require('gulp').task('default', gulp.series('test')); // eslint-disable-line global-require
}
+7
View File
@@ -0,0 +1,7 @@
{
"root": false,
"rules": {
"no-console": 0,
"no-use-before-define": ["error", { "functions": false }]
}
}
-5
View File
@@ -1,5 +0,0 @@
db.users.update(
{ lastCron: { $exists: false} },
{ $set: { lastCron: +new Date } },
{ multi: true }
);
@@ -1,15 +0,0 @@
db.users.find({ completedIds: { $exists: true } }).forEach(function(user) {
var newTodoIds = user.todoIds;
user.completedIds.forEach(function(value) {
if (newTodoIds.indexOf(value) === -1) {
newTodoIds.push(value)
}
});
db.users.update(
{ _id: user._id },
{
$set: { todoIds: newTodoIds },
$unset: { completedIds: 1 }
}
);
});
@@ -1,5 +0,0 @@
db.users.update(
{preferences:{$exists:false}},
{$set:{preferences:{gender: 'm', armorSet: 'v1'}}},
{multi:true}
)
@@ -1,102 +0,0 @@
// %mongo server:27017/dbname underscore.js my_commands.js
// %mongo server:27017/dbname underscore.js --shell
//db.users.find({'auth.facebook.email': 'tylerrenelle@gmail.com'}).forEach(function(user){
db.users.find().forEach(function(user){
if (!user._id) {
print("User has null _id");
return; // need to figure out how to delete these buggers if they don't have an id to delete from
}
if (!!user.idLists) {
print("User " + user._id + " has already been migrated")
return
}
if (user._id.indexOf("$") === 0) {
print("User id starts with $ (" + user._id + ")")
return;
}
// even though we're clobbering user later, sometimes these are undefined and crash the script
// this saves us some ternaries
user.stats = user.stats || {};
user.items = user.items || {};
user.preferences = user.preferences || {};
user.notifications = user.notifications || {};
user.flags = user.flags || {};
user.habitIds = user.habitIds || [];
user.dailyIds = user.dailyIds || [];
user.todoIds = user.todoIds || [];
user.rewardIds = user.rewardIds|| [];
_.each(user.tasks, function(task, key){
if (!task.type) {
delete user.tasks[key];
// idList will take care of itself on page-load
return
}
if (key == '$spec') {
print("$spec was found: " + user._id);
return
}
if (key.indexOf("$_") === 0) {
var newKey = key.replace("$_", ''),
index = user[task.type + "Ids"].indexOf(key)
user[task.type + "Ids"][index] = newKey;
task.id = newKey
user.tasks[newKey] = task
// TODO make sure this is ok, that we're not deleting the original
// Otherwise use lodash.cloneDeep
delete user.tasks[key]
}
});
// New user schema has public and private paths, so we can setup proper access control with racer
// Note 'public' and 'private' are reserved words
var newUser = {
auth: user.auth, // we need this top-level due to derby-auth
apiToken: user.preferences.api_token || null, // set on update, we need derby.uuid()
preferences: {
armorSet: user.preferences.armorSet || 'v1',
gender: user.preferences.gender || 'm'
},
balance: user.balance || 2,
lastCron: user.lastCron || +new Date,
history: user.history || [],
stats: {
gp: user.stats.money || 0,
hp: user.stats.hp || 50,
exp: user.stats.exp || 0,
lvl: user.stats.lvl || 1
},
items: {
armor: user.items.armor || 0,
weapon: user.items.weapon || 0
},
tasks: user.tasks || {},
idLists: {
habit: user.habitIds || [],
daily: user.dailyIds || [],
todo: user.todoIds || [],
reward: user.rewardIds || []
},
flags: {
partyEnabled: false,
itemsEnabled: user.items.itemsEnabled || false,
kickstarter: user.notifications.kickstarter || 'show',
ads: user.flags.ads || null // null because it's set on registration
},
party: {
current: null,
invitation: null
}
};
try {
db.users.update({_id:user._id}, newUser);
} catch(e) {
print(e);
}
})
-19
View File
@@ -1,19 +0,0 @@
// move idList back to root-level, is what's causing the sort bug - see https://github.com/codeparty/racer/pull/73
// We could just delete user.idLists, since it's re-created on refresh. However, users's first refresh will scare them
// since everything will dissappear - second refresh will bring everything back.
db.users.find().forEach(function(user){
if (!user.idLists) return;
db.users.update(
{_id:user._id},
{
$set:{
'habitIds':user.idLists.habit,
'dailyIds':user.idLists.daily,
'todoIds':user.idLists.todo,
'rewardIds':user.idLists.reward
}
//$unset:{idLists:true} // run this after the code has been pushed
}
)
})
@@ -1,20 +0,0 @@
db.users.update(
{items:{$exists:0}},
{$set:{items:{weapon: 0, armor: 0, head: 0, shield: 0 }}},
{multi:true}
);
db.users.find().forEach(function(user){
var updates = {
// I'm not racist, these were just the defaults before ;)
'preferences.skin': 'white',
'preferences.hair': 'blond',
'items.head': user.items.armor,
'items.shield': user.items.armor,
}
db.users.update({_id:user._id}, {$set:updates});
})
-39
View File
@@ -1,39 +0,0 @@
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130307_normalize_algo_values.js
/**
* Make sure people aren't overflowing their exp with the new system
*/
db.users.find().forEach(function(user){
function oldTnl(level) {
return (Math.pow(level,2)*10)+(level*10)+80
}
function newTnl(level) {
var value = 0;
if (level >= 100) {
value = 0
} else {
value = Math.round(((Math.pow(level,2)*0.25)+(10 * level) + 139.75)/10)*10; // round to nearest 10
}
return value
}
var newTnl = newTnl(user.stats.lvl);
if (user.stats.exp > newTnl) {
var percent = user.stats.exp / oldTnl(user.stats.lvl);
percent = (percent>1) ? 1 : percent;
user.stats.exp = newTnl * percent;
try {
db.users.update(
{_id:user._id},
{$set: {'stats.exp': user.stats.exp}},
{multi:true}
);
} catch(e) {
print(e);
}
}
})
@@ -1,47 +0,0 @@
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130307_normalize_algo_values.js
/**
* Users were experiencing a lot of extreme Exp multiplication (https://github.com/lefnire/habitrpg/issues/594).
* This sets things straight, and in preparation for another algorithm overhaul
*/
db.users.find().forEach(function(user){
if (user.stats.exp >= 3580) {
user.stats.exp = 0;
}
if (user.stats.lvl > 100) {
user.stats.lvl = 100;
}
_.each(user.tasks, function(task, key){
// remove corrupt tasks
if (!task) {
delete user.tasks[key];
return;
}
// Fix busted values
if (task.value > 21.27) {
task.value = 21.27;
}
else if (task.value < -47.27) {
task.value = -47.27;
}
});
try {
db.users.update(
{_id:user._id},
{$set:
{
'stats.lvl': user.stats.lvl,
'stats.exp': user.stats.exp,
'tasks' : user.tasks
}
},
{multi:true}
);
} catch(e) {
print(e);
}
})
@@ -1,28 +0,0 @@
/**
* Remove duff histories for dailies
*/
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130307_remove_duff_histories.js
db.users.find().forEach(function(user){
_.each(user.tasks, function(task, key){
if (task.type === "daily") {
// remove busted history entries
task.history = _.filter(task.history, function(h){return !!h.value})
}
});
try {
db.users.update(
{_id:user._id},
{$set:
{
'tasks' : user.tasks
}
},
{multi:true}
);
} catch(e) {
print(e);
}
})
-98
View File
@@ -1,98 +0,0 @@
/**
* Migrate old pets to new system
*/
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130326_migrate_pets.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mapping = {
bearcub: {name:'BearCub', modifier: 'Base'},
cactus: {name:'Cactus', modifier:'Base'},
dragon: {name:'Dragon', modifier:'Base'},
flyingpig: {name:'FlyingPig', modifier:'Base'},
fox: {name:'Fox', modifier:'Base'},
lioncub: {name:'LionCub', modifier:'Base'},
pandacub: {name:'PandaCub', modifier:'Base'},
tigercub: {name:'TigerCub', modifier:'Base'},
wolfBorder: {name:'Wolf', modifier:'Base'},
wolfDesert: {name:'Wolf', modifier:'Desert'},
wolfGolden: {name:'Wolf', modifier:'Golden'},
wolfRed: {name:'Wolf', modifier:'Red'},
wolfShade: {name:'Wolf', modifier:'Shade'},
wolfSkeleton: {name:'Wolf', modifier:'Skeleton'},
wolfVeteran: {name:'Wolf', modifier:'Veteran'},
wolfWhite: {name:'Wolf', modifier:'White'},
wolfZombie: {name:'Wolf', modifier:'Zombie'}
}
/**
== Old Style ==
pet: Object
icon: "Pet-Wolf-White.png"
index: 14
name: "wolfWhite"
text: "White Wolf"
value: 3
pets: Object
bearcub: true
cactus: true
== New Style ==
currentPet: Object
modifier: "Red"
name: "Wolf"
notes: "Find some Hatching Powder to sprinkle on this egg, and one day it will hatch into a loyal pet."
str: "Wolf-Red"
text: "Wolf"
value: 3
pets: Array
0: "PandaCub-Base"
1: "Wolf-Base"
*/
db.users.find().forEach(function(user){
if (!user.items || (!user.items.pets && !user.items.pet)) return;
// migrate items.pet to items.currentPet
if (!!user.items.pet) {
var mapped = mapping[user.items.pet.name];
delete user.items.pet;
user.items.currentPet = {
modifier: mapped.modifier,
name: mapped.name,
str: mapped.name + "-" + mapped.modifier,
text: '' // FIXME?
}
}
// migrate items.pets
if (!!user.items.pets) {
var newPets = [];
_.each(user.items.pets, function(val, key){
if (_.isNumber(key)) {
newPets.push(val)
//FIXME why is this happening? seems the user gets migrated already...
//throw "Error: User appears already migrated, this shouldn't be happening!"
} else {
newPets.push(mapping[key].name + "-" + mapping[key].modifier);
}
});
user.items.pets = newPets;
}
try {
db.users.update(
{_id:user._id},
{$set:
{ 'items' : user.items }
}
);
} catch(e) {
print(e);
}
})
-110
View File
@@ -1,110 +0,0 @@
/**
* Applies backer tokens & items (this file will be updated periodically
*/
// mongo habitrpg ./node_modules/underscore/underscore.js migrations/20130327_apply_tokens.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mapping = [
{
tier: 1,
tokens: 0,
users: []
},
{
tier: 5,
tokens: 20,
users: []
},
{
tier: 10,
tokens: 50,
users: []
},
{
tier: 15,
tokens: 100,
users: []
},
{
tier: 30,
tokens: 150,
users: []
},
{
tier: 45,
tokens: 170,
users: []
},
{
tier: 60,
tokens: 200,
users: []
},
{
tier: 70,
tokens: 240,
users: []
},
{
tier: 80,
tokens: 240,
users: []
},
{
tier: 90,
tokens: 280,
users: []
},
{
tier: 300,
tokens: 500,
users: []
},
{
tier: 800,
tokens: 500,
users: []
}
];
db.users.find().forEach(function(user){
if (!user._id) return;
var possibleUserIds = [user._id];
if (!!user.local) {
if (!!user.local.username) possibleUserIds.push(user.local.username);
if (!!user.local.email) possibleUserIds.push(user.local.email);
}
_.each(mapping, function(tier){
var userInTier = !_.isEmpty(_.intersection(tier.users, possibleUserIds));
if (userInTier) {
var tokenInc = 0,
backer = user.backer || {};
if (!backer.tokensApplied) {
tokenInc = tier.tokens;
backer.tokensApplied = true;
}
backer.tier = tier.tier;
try {
db.users.update(
{_id:user._id},
{
$set: { backer: backer, 'flags.ads': 'hide' },
$inc: { balance: (tokenInc/4) }
}
);
} catch(e) {
print(e);
}
}
})
})
@@ -1,22 +0,0 @@
/**
* For users who already have max gear, they earned the achievement
*/
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130503_max_gear_achievement.js
db.users.find().forEach(function(user){
var items = user.items;
if (!items) { return; }
if ( parseInt(items.armor) == 5 &&
parseInt(items.head) == 5 &&
parseInt(items.shield) == 5 &&
parseInt(items.weapon) == 6) {
try {
db.users.update(
{_id:user._id},
{$set: {'achievements.ultimateGear':true}}
);
} catch(e) {
print(e);
}
}
})
-1
View File
@@ -1 +0,0 @@
db.users.update({'backer.tier':{$gte:80}}, {$push:{'items.pets':'Wolf-Cerberus'}}, {multi:true});
-31
View File
@@ -1,31 +0,0 @@
//mongo habitrpg ./node_modules/lodash/lodash.js migrations/20130602_survey_rewards.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var members = []
members = _.uniq(members);
var query = {
_id: {$exists:1},
$or:[
{_id: {$in: members}},
//{'profile.name': {$in: members}},
{'auth.facebook.name': {$in: members}},
{'auth.local.username': {$in: members}},
{'auth.local.email': {$in: members}}
]
};
print(db.users.count(query));
db.users.update(query,
{
$set: { 'achievements.helpedHabit': true },
$inc: { balance: 2.5 }
},
{multi:true}
)
@@ -1,9 +0,0 @@
//mongo habitrpg migrations/20130612_survey_rewards_individual.js
var query = {_id: ""};
db.users.update(query,
{
$set: { 'achievements.helpedHabit': true },
$inc: { balance: 2.5 }
})
-4
View File
@@ -1,4 +0,0 @@
db.users.ensureIndex( { _id: 1, apiToken: 1 }, {background: true} )
db.groups.ensureIndex( { members: 1 }, {background: true} )
db.groups.ensureIndex( { type: 1 }, {background: true} )
db.groups.ensureIndex( { type: 1, privacy: 1 }, {background: true} )
@@ -1,16 +0,0 @@
//mongo habitrpg ./node_modules/lodash/lodash.js migrations/20130908_cleanup_corrupt_tags.js
// Racer was notorious for adding duplicates, randomly deleting documents, etc. Once we pull the plug on old.habit,
// run this migration to cleanup all the corruption
db.users.find().forEach(function(user){
user.tags = _.filter(user.tags, (function(t) {
return !!t ? t.id : false;
}));
try {
db.users.update({_id:user._id}, {$set:{tags:user.tags}});
} catch(e) {
print(e);
}
})
@@ -1,5 +0,0 @@
db.users.find().forEach(function(user){
if (!user.purchased) user.purchased = {hair: {}, skin: {}};
user.purchased.ads = user.flags && !!user.flags.ads;
db.users.update({_id:user._id}, {$set:{'purchased': user.purchased, 'flags.newStuff': true}, $unset: {'flags.ads':1}});
});
-12
View File
@@ -1,12 +0,0 @@
// node .migrations/20131022_restore_ads.js
var mongo = require('mongoskin');
var _ = require('lodash');
var dbBackup = mongo.db('localhost:27017/habitrpg?auto_reconnect');
var dbLive = mongo.db('localhost:27017/habitrpg2?auto_reconnect');
var count = 89474;
dbBackup.collection('users').findEach({$or: [{'flags.ads':'show'}, {'flags.ads': null}]}, {batchSize:10}, function(err, item) {
if (err) return console.error({err:err});
if (!item || !item._id) return console.error('blank user');
dbLive.collection('users').update({_id:item._id}, {$set:{'purchased.ads':false}, $unset: {'flags.ads': 1}});
if (--count <= 0) console.log("DONE!");
});
-25
View File
@@ -1,25 +0,0 @@
// mongo habitrpg ./node_modules/lodash/lodash.js ./migrations/20131028_task_subdocs_tags_invites.js
db.challenges.find().forEach(function(chal){
_.each(chal.habits.concat(chal.dailys).concat(chal.todos).concat(chal.rewards), function(task){
task.id = task.id || task._id;
})
try {
db.challenges.update({_id:chal._id}, chal);
db.groups.update({_id:chal.group}, {$addToSet:{challenges:chal._id}})
} catch(e) {
print(e);
}
});
db.users.find().forEach(function(user){
_.each(user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards), function(task){
task.id = task.id || task._id;
})
try {
db.users.update({_id:user._id}, user);
} catch(e) {
print(e);
}
});
@@ -1,7 +0,0 @@
db.users.find({},{todos:1}).forEach(function(user){
_.each(user.todos, function(task){
if (moment(task.date).toDate() == 'Invalid Date')
task.date = moment().format('MM/DD/YYYY');
})
db.users.update({_id:user._id}, {$set:{todos: user.todos}});
});
-21
View File
@@ -1,21 +0,0 @@
function deleteId(h){
delete h._id;
}
db.users.find({},{habits:1,dailys:1,history:1}).forEach(function(user){
if (user.history) {
_.each(['todos','exp'], function(type){
if (user.history[type]) {
_.each(user.history.exp, deleteId);
}
})
} else {
user.history = {exp:[],todos:[]};
}
_.each(['habits', 'dailys'], function(type){
_.each(user[type].history, deleteId);
});
db.users.update({_id:user._id}, {$set:{history: user.history, habits: user.habits, dailys: user.dailys}});
});
@@ -1,4 +0,0 @@
// Increase everyone's gems per their contribution level
db.users.find({'contributor.level':{$gt:0}},{contributor:1, balance:1}).forEach(function(user){
db.users.update({_id:user._id}, {$inc: {balance: (user.contributor.level * .5)} });
});
-15
View File
@@ -1,15 +0,0 @@
// This migration has already been run in the past. It's vital to fix these users presently, but we need to find
// out why task values are ever getting in as NaN. My guess is API PUT /tasks/:tid routes
db.users.find({},{habits:1,dailys:1,todos:1,rewards:1}).forEach(function(user){
_.each(['habits','dailys','todos','rewards'], function(type){
_.each(user[type], function(task){
task.value = +task.value;
if (_.isNaN(task.value)) {
task.value = 0;
print(user._id);
}
})
})
db.users.update({_id:user._id}, {$set:{habits: user.habits, dailys: user.dailys, todos: user.todos, rewards: user.rewards}});
});
@@ -1,14 +0,0 @@
// Migrate all users websites to the profile blurb field
db.users.find({'profile.websites':{$exists: true}}).forEach(function(user){
db.users.update({_id: user._id}, {
$set: {"profile.blurb": user.profile.blurb + '\n * ' + user.profile.websites.join('\n * ')},
$unset: {'profile.websites': 1}
})
})
db.groups.find({'websites.0':{$exists: true}}).forEach(function(group){
db.groups.update({_id: group._id}, {
$set: {"description": group.description + '\n * ' + group.websites.join('\n * ')},
$unset: {websites: 1}
})
})
@@ -1,10 +0,0 @@
//Add defaults to show gears in all users
db.users.update(
{},
{$set:{
'preferences.showWeapon': true,
'preferences.showShield': true,
'preferences.showArmor': true,
}},
{multi:true}
)
-18
View File
@@ -1,18 +0,0 @@
// TODO figure out why this is happening in the first place
db.users.find({},{habits:1, dailys:1, todos:1, rewards:1}).forEach(function(user){
_.each(user.habits, function(task){
task.type = 'habit';
})
_.each(user.dailys, function(task){
task.type = 'daily';
})
_.each(user.todos, function(task){
task.type = 'todo';
})
_.each(user.rewards, function(task){
task.type = 'reward';
})
db.users.update({_id:user._id}, {$set:{habits: user.habits, dailys: user.dailys, todos: user.todos, rewards: user.rewards}});
});
@@ -1,12 +0,0 @@
// once and for all!
db.users.find({'items.pets':{$exists:1}},{'items.pets':1}).forEach(function(user){
_.reduce(user.items.pets, function(m,v,k){
if (!k.indexOf('undefined')) m.push(k);
return m;
}, []).forEach(function(key){
delete user.items.pets[key];
})
db.users.update({_id:user._id}, { $set:{'items.pets':user.items.pets} });
});
-13
View File
@@ -1,13 +0,0 @@
// Cleanup broken tags
// -------------------------
db.users.find().forEach(function(user){
var tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
_.each(tasks, function(task){
_.each(task.tags, function(value, key){ //value is true, key is tag.id
if (!_.find(user.tags,{id:key})) delete task.tags[key];
});
});
db.users.update({_id:user._id}, user);
});
@@ -1,8 +0,0 @@
//Add default to randomize party members list
db.users.update(
{},
{$set:{
'party.order': 'random',
}},
{multi:true}
)
-5
View File
@@ -1,5 +0,0 @@
db.users.find({'preferences.dayStart':{$exists:1}},{'preferences.dayStart':1}).forEach(function(user){
var dayStart = +user.preferences.dayStart;
dayStart = (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) ? 0 : dayStart;
db.users.update({_id:user._id}, {$set:{'preferences.dayStart':dayStart}});
});
-1
View File
@@ -1 +0,0 @@
db.users.update({},{$set:{'items.pets.Turkey-Base':5, 'flags.newStuff':true}}, {multi:true});
-38
View File
@@ -1,38 +0,0 @@
// node .migrations/20131127_restore_dayStart.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('localhost:27017/habitrpg_new?auto_reconnect').collection('users');
var query = {'preferences.dayStart':{$exists:1,$ne:0}};
var select = {'preferences.dayStart': 1};
backupUsers.count(query, function(err, count){
if (err) return console.error(err);
backupUsers.findEach(query, select, {batchSize:20}, function(err, before){
if (err) return console.error(err);
if (!before) { count--; return console.log('!before'); }
liveUsers.findById(before._id, function(err, after){
if (err) return console.error(err);
if (!after) { count--; return console.log(before._id + ' deleted?'); }
var dayStart = +before.preferences.dayStart;
if (after.preferences.dayStart == 0 && dayStart != 0){
dayStart = (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) ? 0 : dayStart;
} else {
dayStart = after.preferences.dayStart;
}
liveUsers.update({_id:after._id}, {$inc:{_v:1}, $set:{'preferences.dayStart':dayStart}});
if (--count <= 0) console.log("DONE!");
})
});
});
@@ -1,51 +0,0 @@
// node .migrations/20131221_restore_NaN_history.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* After the classes migration, users lost some history entries
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('localhost:27017/habitrpg?auto_reconnect').collection('users');
function filterNaNs(h) {
return h && _.isNumber(+h.value) && !_.isNaN(+h.value);
}
var fields = {history:1,habits:1,dailys:1,migration:1};
var count = 0;
liveUsers.findEach({migration: {$ne:'20131221_restore_NaN_history'}}, fields, {batchSize:500}, function(err, after){
if (!after) err = '!after';
if (err) {count++;return console.error(err);}
backupUsers.findById(after._id, fields, function(err, before){
if (err) {count++;return console.error(err);}
_.each(['todos','exp'],function(type){
if (!_.isEmpty(after.history[type]))
after.history[type] = _.filter(after.history[type], filterNaNs);
if (before && !_.isEmpty(before.history[type]))
after.history[type] = before.history[type].concat(after.history[type]);
})
_.each(['habits','dailys'], function(type){
_.each(after[type], function(t){
t.history = _.filter(t.history, filterNaNs);
var found = before && _.find(before[type],{id:t.id});
if (found && found.history) t.history = found.history.concat(t.history);
})
})
liveUsers.update({_id:after._id}, {$set:{history:after.history, dailys:after.dailys, habits:after.habits, migration:'20131221_restore_NaN_history'}, $inc:{_v:1}});
//if (--count <= 0) console.log("DONE! " + after._id);
if (++count%1000 == 0) console.log(count);
if (after._id == '9') console.log('lefnire processed');
})
});
-38
View File
@@ -1,38 +0,0 @@
// node .migrations/20131225_restore_streaks.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* After the classes migration, users lost some history entries
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('lefnire:mAdn3s5s@charlotte.mongohq.com:10015/habitrpg_large?auto_reconnect').collection('users');
var fields = {dailys:1,migration:1};
var count = 0;
liveUsers.findEach({migration: {$ne:'20131225_restore_streaks'}}, fields, {batchSize:250}, function(err, after){
if (!after) err = '!after';
if (err) {count++;return console.error(err);}
backupUsers.findById(after._id, fields, function(err, before){
if (!before) err = '!before';
if (err) {count++;return console.error(err);}
_.each(before.dailys,function(d){
var found = _.find(after.dailys,{id: d.id});
if (found && !found.streak) found.streak = d.streak;
})
liveUsers.update({_id:after._id}, {$set:{dailys:after.dailys, migration:'20131225_restore_streaks'}, $inc:{_v:1}});
//if (--count <= 0) console.log("DONE! " + after._id);
if (++count%1000 == 0) console.log(count);
if (after._id == '9') console.log('lefnire processed');
})
});
@@ -1,8 +0,0 @@
db.users.find({},{todos:1,dailys:1,rewards:1,habits:1}).forEach(function(user){
_.each(user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards), function(t){
t.dateCreated = t.created || new Date;
delete t.created;
if (t.type == 'todo' && t.completed) t.dateCompleted = new Date;
})
db.users.update({_id:user._id}, {$set:{habits:user.habits,dailys:user.dailys,todos:user.todos,rewards:user.rewards}});
});
-1
View File
@@ -1 +0,0 @@
db.users.update({},{$set:{'achievements.habitBirthday':true}},{multi:1})
-12
View File
@@ -1,12 +0,0 @@
db.users.update({},{$set:{
'items.food.Cake_Skeleton':1,
'items.food.Cake_Base':1,
'items.food.Cake_CottonCandyBlue':1,
'items.food.Cake_CottonCandyPink':1,
'items.food.Cake_Shade':1,
'items.food.Cake_White':1,
'items.food.Cake_Golden':1,
'items.food.Cake_Zombie':1,
'items.food.Cake_Desert':1,
'items.food.Cake_Red':1
}},{multi:1})
@@ -1,3 +0,0 @@
db.challenges.find({},{members:1}).forEach(function(chal){
db.challenges.update({_id:chal._id}, {$set:{memberCount:chal.members.length}});
});
-14
View File
@@ -1,14 +0,0 @@
db.users.update(
{
'purchased.plan.dateCreated':{$gte:new Date('2014-02-22'),$lt:new Date('2014-02-29')},
'items.gear.owned.armor_mystery_201402':null,
'items.gear.owned.head_mystery_201402': null,
'items.gear.owned.back_mystery_201402': null,
'purchased.plan.mysteryItems':{$nin:['armor_mystery_201402','head_mystery_201402','back_mystery_201402']}
},
//{_id:1,'purchased.plan':1,'items.gear.owned':1}
{$push: {'purchased.plan.mysteryItems':{$each:['armor_mystery_201402','head_mystery_201402','back_mystery_201402']}}},
{multi:true}
)/*.forEach(function(user){
printjson(user);
});*/
@@ -1 +0,0 @@
db.users.update({'backer.tier':{$gt:69}},{$set:{'items.mounts.LionCub-Ethereal':true}},{multi:1})
@@ -1,11 +0,0 @@
//mongo habitrpg node_modules/lodash/lodash.js ./migrations/20140712_wiped_quest_membership.js
db.groups.find({type:'party','quest.key':{$ne:null},'quest.active':true},{quest:1}).forEach(function(group){
var activeMembers = _.reduce(group.quest.members, function(m,v,k){
if (v===true) m.push(k); return m;
},[]);
db.users.update(
{_id:{$in: activeMembers}},
{$set:{'party.quest.key':group.quest.key,'party.quest.completed':null}},
{multi:true}
);
});
@@ -1,13 +0,0 @@
var _ = require('lodash');
db.users.find({}).forEach(function(user){
var newNewMessages = {};
_.each(user.newMessages, function(val, key){
if(key != "undefined"){
newNewMessages[key] = val;
};
});
db.users.update({_id: user._id}, {$set: {'newMessages': newNewMessages}});
});
@@ -1,81 +0,0 @@
// node .migrations/20140829_change_headAccessory_to_eyewear.js
var migrationName = '20140829_change_headAccessory_to_eyewear';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* https://github.com/HabitRPG/habitrpg/issues/3645
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var liveUsers = mongo.db('localhost:27017/habitrpg2?auto_reconnect').collection('users');
var fields = {'migration':1,
'items.gear.costume.headAccessory':1,
'items.gear.equipped.headAccessory':1,
'items.gear.owned.headAccessory_special_wondercon_black':1,
'items.gear.owned.headAccessory_special_wondercon_red':1,
'items.gear.owned.headAccessory_special_summerRogue':1,
'items.gear.owned.headAccessory_special_summerWarrior':1
};
var progressCount = 1000;
var count = 0;
liveUsers.findEach({ $and: [
{ migration: {$ne:migrationName} },
{ $or: [
{'items.gear.owned.headAccessory_special_summerRogue': {'$exists':true}},
{'items.gear.owned.headAccessory_special_summerWarrior':{'$exists':true}},
{'items.gear.owned.headAccessory_special_wondercon_red':{'$exists':true}},
{'items.gear.owned.headAccessory_special_wondercon_black':{'$exists':true}}
]}
]}, fields, {batchSize:250}, function(err, user){
count++;
if (!user) err = '!user';
if (err) {return console.error(err);}
var set = {'migration': migrationName};
var unset = {};
var oldToNew = {
'headAccessory_special_summerRogue': 'eyewear_special_summerRogue',
'headAccessory_special_summerWarrior': 'eyewear_special_summerWarrior',
'headAccessory_special_wondercon_red': 'eyewear_special_wondercon_red',
'headAccessory_special_wondercon_black':'eyewear_special_wondercon_black'
};
// items.gear.costume, items.gear.equipped:
_.each(['costume','equipped'],function(type){
_.each(oldToNew,function(newName,oldName){
if (user.items.gear[type].headAccessory === oldName) {
unset['items.gear.'+type+'.headAccessory'] = "";
set['items.gear.'+type+'.eyewear'] = newName;
}
});
});
// items.gear.owned:
_.each(oldToNew,function(newName,oldName){
if (oldName in user.items.gear.owned) {
unset['items.gear.owned.'+oldName] = "";
set['items.gear.owned.'+newName] = user.items.gear.owned[oldName];
}
});
//console.log(JSON.stringify(user, null, " "));
//console.log("set: " + JSON.stringify(set, null, " "));
//console.log("unset: " + JSON.stringify(unset, null, " "));
liveUsers.update({_id:user._id}, {$set:set, $unset:unset, $inc:{_v:1}});
if (count%progressCount == 0) console.log(count + ' ' + user._id);
if (user._id == '9') console.log('lefnire processed');
if (user._id == authorUuid) console.log(authorName + ' processed');
});
@@ -1,131 +0,0 @@
// IMPORTANT:
//
// run like this to capture all output:
//
// node 20140831_increase_gems_for_previous_contributions.js > 20140831_increase_gems_for_previous_contributions_output.txt
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var migrationName = '20140831_increase_gems_for_previous_contributions';
/**
* https://github.com/HabitRPG/habitrpg/issues/3933
* Increase Number of Gems for Contributors
* author: Alys (d904bd62-da08-416b-a816-ba797c9ee265)
*
* Increase everyone's gems per their contribution level.
* Originally they were given 2 gems per tier.
* Now they are given 3 gems per tier for tiers 1,2,3
* and 4 gems per tier for tiers 4,5,6,7
* So that means an EXTRA 1 for tier 1,
* 2 for tier 2,
* 3 for tier 3,
* 5 for tier 4,
* 7 for tier 5,
* 9 for tier 6,
* 11 for tier 7,
* 11 for tier 8 (moderators = tier 7 + admin privileges),
* none for tier 9 (staff)
*/
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db('localhost:27017/habitrpg?auto_reconnect').collection('users');
var query = {
'contributor.level': {$gt: 0, $lt: 9},
'migration': {$ne: migrationName}
};
var fields = {
'migration':1,
'contributor.level':1,
'balance':1
};
var userResults = {}; // each key is a UUID, each value is a string
// describing what changed for that user
console.warn('Updating users...');
var progressCount = 50;
var count = 0;
dbUsers.findEach(query, fields, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All users found. Fetching final balances...');
return fetchFinalBalances();
}
count++;
var set = {'migration': migrationName};
var tier = user.contributor.level;
var extraGems = tier; // tiers 1,2,3
if (tier > 3) { extraGems = 3 + (tier - 3) * 2; }
if (tier == 8) { extraGems = 11; }
var extraBalance = extraGems / 4;
set['balance'] = user.balance + extraBalance;
// Capture current state of user:
userResults[user._id] =
user._id + ' ' + ':\n' +
' contrib tier : ' + tier + '\n' +
' balance before : ' + user.balance + '\n' +
' balance (gems) added : ' + extraBalance + ' (' +
extraGems + ')' + '\n' +
' expected balance after: ' + (user.balance + extraBalance) + '\n';
// Update user:
dbUsers.update({_id:user._id}, {$set:set, $inc:{_v:1}});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
});
function fetchFinalBalances() {
var query = {_id: {$in: Object.keys(userResults)}};
var fields = {
'balance':1,
};
var count1 = 0;
dbUsers.findEach(query, fields, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All final balances found.');
return displayData();
}
count1++;
userResults[user._id] = userResults[user._id] +
user._id + ' ' + ':\n' +
' actual balance after : ' + user.balance + '\n';
if (count1%progressCount == 0) console.warn(count1 + ' ' + user._id);
});
}
function displayData() {
_.each(userResults, function(text, uuid) {
console.log(text); // text contains uuid
});
console.log('\n' + count +
' users processed (should be roughly 335 according to the Hall)\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
@@ -1,79 +0,0 @@
var migrationName = '20140914_upgrade_admin_contrib_tiers';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/**
* https://github.com/HabitRPG/habitrpg/issues/3801
* Convert Tier 8 contributors to Tier 9 (staff) (all current Tier 8s are admins).
* Convert Tier 7 contributors with admin flag to Tier 8 (moderators).
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db('localhost:27017/habitrpg?auto_reconnect').collection('users');
var query =
{ 'contributor.level':{$gte:7}, 'contributor.admin':true, 'migration': {$ne: migrationName} };
var fields = {'migration':1,
'contributor.admin':1,
'contributor.level':1,
'auth.local.username':1,
'profile.name':1,
};
var userResults = {}; // each key is a UUID, each value is a username;
// contains only the users changed
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var set = {'migration': migrationName};
var inc = {'contributor.level':1, _v:1};
userResults[user._id] = user.profile.name;
dbUsers.update({_id:user._id}, {$set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.log('users modified:');
_.each(userResults, function(name, uuid) {
console.log(name);
});
console.warn('\n' + count +
' users processed (should be 11 according to the Hall)\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
-18
View File
@@ -1,18 +0,0 @@
db.users.update(
{},
{
$inc: {
'items.food.Candy_Base':1,
'items.food.Candy_CottonCandyBlue':1,
'items.food.Candy_CottonCandyPink':1,
'items.food.Candy_Desert':1,
'items.food.Candy_Golden':1,
'items.food.Candy_Red':1,
'items.food.Candy_Shade':1,
'items.food.Candy_Skeleton':1,
'items.food.Candy_White':1,
'items.food.Candy_Zombie':1
}
},
{multi:1}
);
-1
View File
@@ -1 +0,0 @@
db.users.update({_id:'9'},{$set:{'items.pets.JackOLantern-Base':5, 'flags.newStuff':true}}, {multi:true});
-11
View File
@@ -1,11 +0,0 @@
db.users.update(
{'items.pets.Turkey-Base':{$ne:null}},
{$set:{'items.mounts.Turkey-Base':true}},
{multi:1}
)
db.users.update(
{'items.pets.Turkey-Base':null},
{$set:{'items.pets.Turkey-Base':5}},
{multi:1}
)
-4
View File
@@ -1,4 +0,0 @@
db.users.update({'purchased.plan.consecutive.count':NaN}, {$set:{'purchased.plan.consecutive.count':0}}, {multi:1});
db.users.update({'purchased.plan.consecutive.offset':NaN}, {$set:{'purchased.plan.consecutive.offset':0}}, {multi:1});
db.users.update({'purchased.plan.consecutive.gemCapExtra':NaN}, {$set:{'purchased.plan.consecutive.gemCapExtra':0}}, {multi:1});
db.users.update({'purchased.plan.consecutive.trinkets':NaN}, {$set:{'purchased.plan.consecutive.trinkets':0}}, {multi:1});
-11
View File
@@ -1,11 +0,0 @@
db.users.update(
{'items.gear.owned.head_special_nye':{$ne:null}},
{$set:{'items.gear.owned.head_special_nye2014':false}},
{multi:1}
)
db.users.update(
{'items.gear.owned.head_special_nye':null},
{$set:{'items.gear.owned.head_special_nye':false}},
{multi:1}
)
@@ -1,8 +0,0 @@
db.users.update(
{'purchased.plan.customerId':{$ne:null}, 'purchased.plan.dateUpdated':null},
{
$set: {'purchased.plan.dateUpdated': new Date('12/01/2014')},
$unset: {'purchased.plan.datedUpdated':''}
},
{multi:true}
);
-88
View File
@@ -1,88 +0,0 @@
var migrationName = '20150124_mountmaster_fix.js';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/**
* https://github.com/HabitRPG/habitrpg/pull/4374#issuecomment-71038795
* Convert false to null for mounts that used to be owned.
*/
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
var query = {
'items.mounts':{$exists:true}
};
var fields = {
'items.mounts':1
};
var animals = [ "Wolf-Base", "Wolf-White", "Wolf-Desert", "Wolf-Red", "Wolf-Shade", "Wolf-Skeleton", "Wolf-Zombie", "Wolf-CottonCandyPink", "Wolf-CottonCandyBlue", "Wolf-Golden", "TigerCub-Base", "TigerCub-White", "TigerCub-Desert", "TigerCub-Red", "TigerCub-Shade", "TigerCub-Skeleton", "TigerCub-Zombie", "TigerCub-CottonCandyPink", "TigerCub-CottonCandyBlue", "TigerCub-Golden", "PandaCub-Base", "PandaCub-White", "PandaCub-Desert", "PandaCub-Red", "PandaCub-Shade", "PandaCub-Skeleton", "PandaCub-Zombie", "PandaCub-CottonCandyPink", "PandaCub-CottonCandyBlue", "PandaCub-Golden", "LionCub-Base", "LionCub-White", "LionCub-Desert", "LionCub-Red", "LionCub-Shade", "LionCub-Skeleton", "LionCub-Zombie", "LionCub-CottonCandyPink", "LionCub-CottonCandyBlue", "LionCub-Golden", "Fox-Base", "Fox-White", "Fox-Desert", "Fox-Red", "Fox-Shade", "Fox-Skeleton", "Fox-Zombie", "Fox-CottonCandyPink", "Fox-CottonCandyBlue", "Fox-Golden", "FlyingPig-Base", "FlyingPig-White", "FlyingPig-Desert", "FlyingPig-Red", "FlyingPig-Shade", "FlyingPig-Skeleton", "FlyingPig-Zombie", "FlyingPig-CottonCandyPink", "FlyingPig-CottonCandyBlue", "FlyingPig-Golden", "Dragon-Base", "Dragon-White", "Dragon-Desert", "Dragon-Red", "Dragon-Shade", "Dragon-Skeleton", "Dragon-Zombie", "Dragon-CottonCandyPink", "Dragon-CottonCandyBlue", "Dragon-Golden", "Cactus-Base", "Cactus-White", "Cactus-Desert", "Cactus-Red", "Cactus-Shade", "Cactus-Skeleton", "Cactus-Zombie", "Cactus-CottonCandyPink", "Cactus-CottonCandyBlue", "Cactus-Golden", "BearCub-Base", "BearCub-White", "BearCub-Desert", "BearCub-Red", "BearCub-Shade", "BearCub-Skeleton", "BearCub-Zombie", "BearCub-CottonCandyPink", "BearCub-CottonCandyBlue", "BearCub-Golden" ]; // all Gen1 mounts
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var mounts = user.items.mounts;
var changed = false;
for(var a in animals) {
if(mounts[animals[a]] == false) {
mounts[animals[a]] = null;
changed = true;
}
}
if (changed) {
dbUsers.update(
{ _id: user._id},
{
$set: { "migration": migrationName,
"items.mounts" : mounts
}
}
);
}
// var set = {'migration': migrationName};
// var inc = {'xyz':1, _v:1};
// dbUsers.update({_id:user._id}, {$set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
-36
View File
@@ -1,36 +0,0 @@
db.users.update(
{'items.gear.owned.armor_special_birthday':{$ne:null}},
{$set:{'items.gear.owned.armor_special_birthday2015':false}},
{multi:1}
)
db.users.update(
{'items.gear.owned.armor_special_birthday':null},
{$set:{'items.gear.owned.armor_special_birthday':false}},
{multi:1}
)
db.users.update({},{$inc:{
'items.food.Cake_Skeleton':1,
'items.food.Cake_Base':1,
'items.food.Cake_CottonCandyBlue':1,
'items.food.Cake_CottonCandyPink':1,
'items.food.Cake_Shade':1,
'items.food.Cake_White':1,
'items.food.Cake_Golden':1,
'items.food.Cake_Zombie':1,
'items.food.Cake_Desert':1,
'items.food.Cake_Red':1
}},{multi:1})
db.users.update(
{'achievements.habitBirthday':true},
{$set:{'achievements.habitBirthdays':1}},
{multi:1}
)
db.users.update(
{},
{$inc:{'achievements.habitBirthdays':1}},
{multi:1}
)
@@ -1,78 +0,0 @@
var migrationName = '20150131_birthday_goodies_fix__one_birthday__1';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* remove new birthday robes and second achievement from people who shouldn't have them
*/
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
// 'auth.timestamps.created':{$gt:new Date('2014-02-01')},
var query = {
'achievements.habitBirthdays':1,
'auth.timestamps.loggedin':{$gt:new Date('2014-12-20')}
};
// '_id': 'c03e41bd-501f-438c-9553-a7afdf52a08c',
// 'achievements.habitBirthday':{$exists:false},
// 'items.gear.owned.armor_special_birthday2015':1
var fields = {
// 'auth.timestamps.created':1,
// 'achievements.habitBirthday':1,
// 'achievements.habitBirthdays':1,
'items.gear.owned.armor_special_birthday2015':1,
// 'items.gear.owned.armor_special':1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var unset = {'items.gear.owned.armor_special_birthday2015': 1};
// var set = {'migration':migrationName, 'achievements.habitBirthdays':1 };
// var inc = {'xyz':1, _v:1};
dbUsers.update({_id:user._id}, {$unset:unset}); // , $inc:inc});
// dbUsers.update({_id:user._id}, {$unset:unset, $set:set});
// console.warn(user.auth.timestamps.created);
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
@@ -1,112 +0,0 @@
var migrationName = '20150201_convert_creation_date_from_string_to_object__no_date_recent_signup';
//// var migrationName = '20150201_convert_creation_date_from_string_to_object';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* For users that have no value for auth.timestamps.created, assign them
* a recent value.
*
* NOTE:
* Before this script was used as described above, it was first used to
* find all users that have a auth.timestamps.created field that is a string
* rather than a date object and set it to be a date object. The code used
* for this has been commented out with four slashes: ////
*
* https://github.com/HabitRPG/habitrpg/issues/4601#issuecomment-72339846
*/
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var moment = require('moment');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
var uuidArrayRecent=[ // recent users with no creation dates
'1a0d4b75-73ed-4937-974d-d504d6398884',
'1c7ebe27-1250-4f95-ba10-965580adbfd7',
'5f972121-4a6d-411c-95e9-7093d3e89b66',
'ae85818a-e336-4ccd-945e-c15cef975102',
'ba273976-d9fc-466c-975f-38559d34a824',
];
var query = {
'_id':{$in: uuidArrayRecent}
//// 'auth':{$exists:true},
//// 'auth.timestamps':{$exists:true},
//// 'auth.timestamps.created':{$not: {$lt:new Date('2018-01-01')}}
};
var fields = {
'_id':1,
'auth.timestamps.created':1
};
// 'achievements.habitBirthdays':1
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
//// var oldDate = user.auth.timestamps.created;
//// var newDate = moment(oldDate).toDate();
var oldDate = 'none';
var newDate = moment('2015-01-11').toDate();
console.warn(user._id + ' == ' + oldDate + ' == ' + newDate);
//// var set = { 'migration': migrationName,
//// 'auth.timestamps.created': newDate,
//// 'achievements.habitBirthdays': 2,
//// 'items.gear.owned.head_special_nye':true,
//// 'items.gear.owned.head_special_nye2014':true,
//// 'items.gear.owned.armor_special_birthday':true,
//// 'items.gear.owned.armor_special_birthday2015':true,
//// };
var set = { 'migration': migrationName,
'auth.timestamps.created': newDate,
'achievements.habitBirthdays': 1,
'items.gear.owned.armor_special_birthday':true,
};
// var unset = {'items.gear.owned.armor_special_birthday2015': 1};
// var inc = {'xyz':1, _v:1};
dbUsers.update({_id:user._id}, {$set:set});
// dbUsers.update({_id:user._id}, {$unset:unset, $set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
@@ -1,7 +0,0 @@
db.users.update({
'flags.recaptureEmailsPhase': {
$gt: 0
}
},{$inc:{
'flags.recaptureEmailsPhase':1
}},{multi:1})
-10
View File
@@ -1,10 +0,0 @@
db.users.update({},{$set:{
'flags.tour.intro':-2,
//'flags.tour.classes':-2,
'flags.tour.stats':-2,
'flags.tour.tavern':-2,
'flags.tour.party':-2,
'flags.tour.guilds':-2,
'flags.tour.challenges':-2,
'flags.tour.market':-2
}},{multi:1})
@@ -1,64 +0,0 @@
var migrationName = '20150224_force_resting_in_inn';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* force all active players to rest in the inn due to massive server fail
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/habitrpg?auto_reconnect').collection('users');
var query = {
'auth.timestamps.loggedin':{$gt:new Date('2015-02-22')}
};
var fields = {
'preferences.sleep':1,
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var set = {'migration':migrationName, 'preferences.sleep':1 };
dbUsers.update({_id:user._id}, {$set:set});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
@@ -1,5 +0,0 @@
db.users.update(
{'achievements.helpedHabit':true},
{$set:{'achievements.habitSurveys':1}},
{multi:1}
)
-138
View File
@@ -1,138 +0,0 @@
// var migrationName = '20150604_ultimateGearSets';
// var authorName = 'Sabe'; // in case script author needs to know when their ...
// var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
var migrationName = '20150620_ultimateGearSets';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* grant the new ultimateGearSets achievement for existing users' collected equipment
*
*
* Changed by Alys on 20150620 to assign false values to
* 'achievements.ultimateGearSets' when true values are not appropriate,
* because of https://github.com/HabitRPG/habitrpg/issues/5427
*
* Minimal changes were made so the code isn't as efficient or clean
* as it could be, but it's (hopefully) one-use-only and minimal changes
* means minimal new testing.
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var dbserver = 'localhost:27017' // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379' // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
var fields = {
'achievements.ultimateGearSets':1,
'items.gear.owned':1
};
// Changes 20150620: All users have to be processed now (non-achievers need
// false values).
var query = {
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
var achievements = {};
var changeUser = false;
// Changes 20150620: 'changeUser' now indicates that the user must have the
// Enchanted Armoire unlocked.
if ( (typeof user.items.gear.owned.weapon_wizard_6 !== 'undefined')
&& (typeof user.items.gear.owned.armor_wizard_5 !== 'undefined')
&& (typeof user.items.gear.owned.head_wizard_5 !== 'undefined')
) {
achievements['wizard'] = true;
changeUser = true;
}
else {
// Changes 20150620: false added for all classes (here and below)
achievements['wizard'] = false;
}
if ( (typeof user.items.gear.owned.weapon_warrior_6 !== 'undefined')
&& (typeof user.items.gear.owned.armor_warrior_5 !== 'undefined')
&& (typeof user.items.gear.owned.head_warrior_5 !== 'undefined')
&& (typeof user.items.gear.owned.shield_warrior_5 !== 'undefined')
) {
achievements['warrior'] = true;
changeUser = true;
}
else {
achievements['warrior'] = false;
}
if ( (typeof user.items.gear.owned.weapon_healer_6 !== 'undefined')
&& (typeof user.items.gear.owned.armor_healer_5 !== 'undefined')
&& (typeof user.items.gear.owned.head_healer_5 !== 'undefined')
&& (typeof user.items.gear.owned.shield_healer_5 !== 'undefined')
) {
achievements['healer'] = true;
changeUser = true;
}
else {
achievements['healer'] = false;
}
if ( (typeof user.items.gear.owned.weapon_rogue_6 !== 'undefined')
&& (typeof user.items.gear.owned.armor_rogue_5 !== 'undefined')
&& (typeof user.items.gear.owned.head_rogue_5 !== 'undefined')
&& (typeof user.items.gear.owned.shield_rogue_6 !== 'undefined')
) {
achievements['rogue'] = true;
changeUser = true;
}
else {
achievements['rogue'] = false;
}
// Changes 20150620: $set is now run for all users.
var set = {'migration':migrationName, 'achievements.ultimateGearSets':achievements};
if (changeUser) { // user has at least one Ultimate Gear achievement
set['flags.armoireEnabled'] = true;
}
dbUsers.update({_id:user._id}, {$set:set});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
if (user._id == '9' ) console.warn('lefnire' + ' processed');
});
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
-5
View File
@@ -1,5 +0,0 @@
db.users.update(
{},
{$set:{'items.mounts.Gryphon-RoyalPurple':true}},
{multi:true}
);
-5
View File
@@ -1,5 +0,0 @@
db.users.update(
{'items.pets.Wolf-Veteran':{$ne:null}},
{$set:{'items.pets.Tiger-Veteran':5}},
{multi:true}
);
-7
View File
@@ -1,7 +0,0 @@
// Run after the Veteran Tiger script, not before!
db.users.update(
{'items.pets.Wolf-Veteran':{$exists:false}},
{$set:{'items.pets.Wolf-Veteran':5}},
{multi:true}
);
-79
View File
@@ -1,79 +0,0 @@
/*
* Make sure leaders are existing users
*/
var mongo = require('mongoskin');
var async = require('async');
var dbserver = 'url';
var dbname = 'dbname';
var countGroups = 0;
var countUsers = 0;
var db = mongo.db(dbserver + '/' + dbname + '?auto_reconnect');
var dbUsers = db.collection('users');
var dbGroups = db.collection('groups');
console.log('Begins work on db');
function findGroups(gt){
var query = {};
if(gt) query._id = {$gt: gt};
console.log(query)
dbGroups.find(query, {
fields: {_id: 1, members: 1, leader: 1},
limit: 10000,
sort: {
_id: 1
}
}).toArray(function(err, groups){
if(err) throw err;
var lastGroup = null;
if(groups.length === 10000){
lastGroup = groups[groups.length - 1];
}
async.eachLimit(groups, 30, function(group, cb1){
countGroups++;
console.log('Group: ', countGroups, group._id);
var members = group.members;
dbUsers.findOne({_id: group.leader}, {fields: {_id: 1}}, function(err, user){
if(err) return cb1(err);
// If leader has deleted account
if(!user && (group._id !== 'habitrpg') && members && members[0]) {
dbGroups.update({
_id: group._id
}, {
$set: {
// Set first user as new leader
leader: members[0]
}
}, {
multi: false
}, function(err, res){
if(err) return cb1(err);
console.log('Updated: ', res);
return cb1();
});
}else{
return cb1();
}
});
}, function(err){
if(err) throw err;
if(lastGroup && lastGroup._id){
findGroups(lastGroup._id);
}
});
});
};
findGroups();
@@ -1,87 +0,0 @@
/*
* Remove deleted accounts from groups
*/
var mongo = require('mongoskin');
var async = require('async');
var dbserver = 'url';
var dbname = 'dbname';
var countGroups = 0;
var countUsers = 0;
var db = mongo.db(dbserver + '/' + dbname + '?auto_reconnect');
var dbUsers = db.collection('users');
var dbGroups = db.collection('groups');
console.log('Begins work on db');
function findGroups(gt){
var query = {};
if(gt) query._id = {$gt: gt};
console.log(query)
dbGroups.find(query, {
fields: {_id: 1, members: 1},
limit: 10000,
sort: {
_id: 1
}
}).toArray(function(err, groups){
if(err) throw err;
var lastGroup = null;
if(groups.length === 10000){
lastGroup = groups[groups.length - 1];
}
async.eachLimit(groups, 3, function(group, cb1){
countGroups++;
console.log('Group: ', countGroups, group._id);
var members = group.members;
// Remove users who deleted their account
async.eachLimit(members, 15, function(member, cb2){
dbUsers.findOne({_id: member}, {fields: {_id: 1}}, function(err, user){
if(err) return cb2(err);
if(!user){
countUsers++;
console.log('User removed n. ', countUsers, 'user id ', member, 'group id ', group._id);
dbGroups.update({
_id: group._id
}, {
$pull: {members: member},
$inc: {memberCount: -1}
}, {
multi: false
}, function(err, res){
if(err) return cb2(err);
console.log('Updated: ', res);
return cb2();
});
}else{
cb2();
}
});
}, function(err){
if(err) return cb1(err);
cb1();
});
}, function(err){
if(err) throw err;
if(lastGroup && lastGroup._id){
findGroups(lastGroup._id);
}
});
});
};
findGroups();
@@ -1,21 +0,0 @@
/*
* Remove empty private groups
*/
var mongo = require('mongoskin');
var dbserver = 'url';
var dbname = 'name';
var db = mongo.db(dbserver + '/' + dbname + '?auto_reconnect');
var dbGroups = db.collection('groups');
console.log('Begins work on db');
dbGroups.findEach({
memberCount: 0,
}, {_id: 1}, function(err, res){
if(err) throw err;
console.log(res);
});
@@ -1,43 +0,0 @@
/*
* Sync groups with Firebase
*/
var mongo = require('mongoskin');
var Firebase = require('Firebase');
var dbserver = 'mongodb://url';
var dbname = 'db';
var db = mongo.db(dbserver + '/' + dbname + '?auto_reconnect');
var dbGroups = db.collection('groups');
var countGroups = 0;
var firebaseRef = new Firebase('https://' + 'firebase-app' + '.firebaseio.com');
// TODO handle sync errors with firebase?
firebaseRef.authWithCustomToken('firebase-secret', function(err, authData){
if(err) throw new Error('Impossible to authenticate Firebase');
console.log('Firebase connected, begins work on db');
dbGroups.findEach({}, {_id: 1, members: 1}, {batchSize: 100}, function(err, group){
if(err) throw err;
if(group._id !== 'habitrpg') return;
countGroups++;
console.log('Group: ', countGroups);
firebaseRef.child('rooms/' + group._id)
.set({
name: group.name
});
group.members.forEach(function(member){
firebaseRef.child('members/' + group._id + '/' + userId)
.set(true);
firebaseRef.child('users/' + member + '/rooms/' + group._id)
.set(true);
});
});
});
-67
View File
@@ -1,67 +0,0 @@
var migrationName = '20151013_jackolanterns.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Jack-O'-Lantern mounts to users who already have the pet version, award pet if they don't
*/
var dbserver = 'localhost:27017'; // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.pets.JackOLantern-Base':1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
// specify user data to change:
var set = {};
if (user.items.pets['JackOLantern-Base']) {
set = {'migration':migrationName, 'items.mounts.JackOLantern-Base':true};
} else {
set = {'migration':migrationName, 'items.pets.JackOLantern-Base':5};
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}
@@ -1,63 +0,0 @@
/*
* Migrate email to lowerCase version and add auth.local.lowerCaseUsername email
*/
var mongo = require('mongoskin');
var async = require('async');
var dbserver = 'url';
var dbname = 'dbname';
var countUsers = 0;
var db = mongo.db(dbserver + '/' + dbname + '?auto_reconnect');
var dbUsers = db.collection('users');
console.log('Begins work on db');
function findUsers(gt){
var query = {};
if(gt) query._id = {$gt: gt};
console.log(query)
dbUsers.find(query, {
fields: {_id: 1, auth: 1},
limit: 10000,
sort: {
_id: 1
}
}).toArray(function(err, users){
if(err) throw err;
var lastUser = null;
if(users.length === 10000){
lastUser = users[users.length - 1];
}
async.eachLimit(users, 20, function(user, cb){
countUsers++;
console.log('User: ', countUsers, user._id);
var update = {
$set: {}
};
if(user.auth && user.auth.local) {
if(user.auth.local.username) update['$set']['auth.local.lowerCaseUsername'] = user.auth.local.username.toLowerCase();
if(user.auth.local.email) update['$set']['auth.local.email'] = user.auth.local.email.toLowerCase();
}
dbUsers.update({
_id: user._id
}, update, cb);
}, function(err){
if(err) throw err;
if(lastUser && lastUser._id){
findUsers(lastUser._id);
}
});
});
};
findUsers();
-63
View File
@@ -1,63 +0,0 @@
var migrationName = '20151105_tutorial_flags_v1';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
/*
* set flags.tutorial.ios and flags.tutorial.main flags to true in preparation
* for the release of a new iOS tutorial
*
*/
// var dbserver = 'localhost:27017' // FOR TEST DATABASE
var dbserver = 'alys:@ds031379-a0.mongolab.com:31379' // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
var fields = {
};
var query = {
'auth.timestamps.loggedin':{$gt:new Date('2015-10-20')}
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
// var set = {'migration':migrationName, 'flags.tutorial.ios':true, 'flags.tutorial.main':true };
var set = {'migration':migrationName, 'flags.tutorial.ios':{} };
dbUsers.update({_id:user._id}, {$set:set});
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);
}
@@ -1,102 +0,0 @@
var migrationName = '20151116_costume_contest.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Costume Contest achievement to 2015 winners
*/
var dbserver = 'localhost:27017'; // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
_id: {
$in: [
'e411dab3-a4ca-414d-bdbd-b6940b3bdeb3',
'35ced5cc-c33a-45c8-93dc-16000ee66fde',
'ab3f0549-7247-4fd5-975b-efcff98c79c3',
'b1261fd2-eb25-46b4-97a9-ae7a0dc8a131',
'1f27893f-3808-4724-9725-f46dab93faca',
'216a0c23-6afd-4a5e-b434-d386a10862a2',
'2d6ef231-50b4-4a22-90e7-45eb97147a2c',
'98b8cf4f-89bd-4b0a-988d-02629a217232',
'c5183dfa-c741-43ce-935e-c6d89b41a030',
'262a7afb-6b57-4d81-88e0-80d2e9f6cbdc',
'33991e0a-de55-4986-ac81-af78491a84de',
'7adf6ada-3c05-4054-b5df-fa7d49d3b9eb',
'235a1cbd-48c5-41b1-afb4-59d2f8645c57',
'b7617a61-188b-4332-bf4d-32268fa77f2b',
'672c1ce0-9f47-44f0-a3f3-8cc3c6c5a9cb',
'd0a3217a-7b92-48d6-b39a-b1b1be96702e',
'5ef910dc-1d22-47d9-aa38-a60132c60679',
'370a44c8-e94a-4a2c-91f2-33166926db1f',
'1b0b3ef3-28bd-4046-a49b-e1c83e281baf',
'75b93321-66b9-49bd-9076-052499c1d2bf',
'd97516e4-81d0-4f60-bf03-95f7330925ab',
'3e13cc79-de38-420d-822e-9e9da309ce6b',
'0e471dc1-ecb0-4388-a891-b873a237d2cf',
'ca3da398-4f73-4304-b838-af3669ed4cbb',
'44cdf105-8bda-4197-9d1a-1bcb83b4dc84',
'5419830c-b837-4573-ae82-4718ab95b7f1',
'ac6fbe37-b0dc-40d8-ba14-77dde66fbfa8',
'8789ba18-a498-46b9-b367-3b929a0acb94',
'52fce1a9-9b0a-4e26-95dc-adc12f52e752',
'21bf71ac-399c-470b-abe0-cc49a03b6a8b',
'f1618ce2-552e-4f23-bc76-e73d63ebedd0',
'4cc0c749-d943-4090-b529-42bc665b7244',
'e259682e-cb5c-4d94-b472-ceedc66d7484',
'fa197a4b-e065-4551-803a-c8a5b9970f9d'
]
}
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
// specify user data to change:
var set = {'migration':migrationName};
var inc = {'achievements.costumeContests':1};
dbUsers.update({_id:user._id}, {$set:set});
dbUsers.update({_id:user._id}, {$inc:inc});
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);
}
@@ -1,64 +0,0 @@
var migrationName = '20151116_costume_contest_to_number.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Change Costume Contest achievement from Boolean to Number, so people can win repeatedly
*/
var dbserver = 'localhost:27017'; // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'achievements.costumeContest':true
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'achievements.costumeContest':1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
// specify user data to change:
var set = {'achievements.costumeContests':1};
dbUsers.update({_id:user._id}, {$set:set});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
});
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);
}
-71
View File
@@ -1,71 +0,0 @@
var migrationName = '20151125_turkey_ladder.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Gilded Turkey pet to Turkey mount owners, Turkey Mount if they only have Turkey Pet,
* and Turkey Pet otherwise
*/
var dbserver = 'localhost:27017'; // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.pets.Turkey-Base': 1,
'items.mounts.Turkey-Base': 1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
// specify user data to change:
var set = {};
if (user.items.mounts['Turkey-Base']) {
set = {'migration':migrationName, 'items.pets.Turkey-Gilded':5};
} else if (user.items.pets['Turkey-Base']) {
set = {'migration':migrationName, 'items.mounts.Turkey-Base':true};
} else {
set = {'migration':migrationName, 'items.pets.Turkey-Base':5};
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}
-70
View File
@@ -1,70 +0,0 @@
var migrationName = '20151229_new_years_hats.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award 2015 party hat if user has 2014 hat, 2014 hat if they have the 2013 hat,
* and 2013 hat otherwise
*/
var dbserver = 'localhost:27017'; // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.gear.owned': 1,
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
// specify user data to change:
var set = {};
if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('head_special_nye2014')) {
set = {'migration':migrationName, 'items.gear.owned.head_special_nye2015':false};
} else if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('head_special_nye')) {
set = {'migration':migrationName, 'items.gear.owned.head_special_nye2014':false};
} else {
set = {'migration':migrationName, 'items.gear.owned.head_special_nye':false};
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}
-82
View File
@@ -1,82 +0,0 @@
var migrationName = '20160521_veteran_ladder.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Gilded Turkey pet to Turkey mount owners, Turkey Mount if they only have Turkey Pet,
* and Turkey Pet otherwise
*/
var dbserver = 'localhost:27017'; // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'auth.timestamps.loggedin':{$gt:new Date('2016-05-01')} // remove when running migration a second time
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'migration': 1,
'items.pets.Wolf-Veteran': 1,
'items.pets.Tiger-Veteran': 1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
return displayData();
}
count++;
// specify user data to change:
var set = {};
if (user.migration !== migrationName) {
if (user.items.pets['Tiger-Veteran']) {
set = {'migration':migrationName, 'items.pets.Lion-Veteran':5};
} else if (user.items.pets['Wolf-Veteran']) {
set = {'migration':migrationName, 'items.pets.Tiger-Veteran':5};
} else {
set = {'migration':migrationName, 'items.pets.Wolf-Veteran':5};
}
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}
@@ -1,84 +0,0 @@
var uuid = require('uuid').v4;
var mongo = require('mongodb').MongoClient;
var _ = require('lodash');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var taskIds = require('checklists-no-id.json').map(function (obj) {
return obj._id;
});
// Fix empty task.checklistt.id
var progressCount = 100;
var count = 0;
function displayData() {
console.warn('\n' + count + ' tasks 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); }
}
}
mongo.connect('db url')
.then(function (db) {
var dbTasks = db.collection('tasks');
// specify a query to limit the affected tasks (empty for all tasks):
var query = {
'_id':{ $in: taskIds },
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'checklist': 1,
};
console.warn('Updating tasks...');
dbTasks.find(query, fields, {batchSize: 250}).toArray(function(err, tasks) {
if (err) { return exiting(1, 'ERROR! ' + err); }
tasks.forEach(function (task) {
var checklist = task.checklist || [];
checklist.forEach(function (item) {
if (!item.id || item.id === "") {
item.id = uuid();
}
});
// specify user data to change:
var set = {
checklist: checklist,
};
//console.log(set);
dbTasks.update({_id: task._id}, {$set: set}, function (err, res) {
if (err) console.error('Error while updating', err);
});
count++;
if (count % progressCount == 0) console.warn(count + ' ' + task._id);
});
if (count === tasks.length) {
console.warn('All appropriate tasks found and modified.');
return displayData();
}
});
})
.catch(function (err) {
throw err;
});
-82
View File
@@ -1,82 +0,0 @@
var migrationName = '20160731_naming_day.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Royal Purple Gryphon pet to Royal Purple Gryphon mount owners, mount to everyone else
*/
var mongo = require('mongoskin');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = mongo.db(connectionString).collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'migration':{$ne:migrationName},
'auth.timestamps.loggedin':{$gt:new Date('2016-07-30')} // Extend timeframe each run of migration
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.mounts': 1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
setTimeout(displayData, 300000);
return;
}
count++;
// specify user data to change:
var set = {};
var inc = {};
inc = {
'achievements.habiticaDays': 1,
'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
};
if (user.items.mounts['Gryphon-RoyalPurple']) {
set = {'migration':migrationName, 'items.pets.Gryphon-RoyalPurple':5};
} else {
set = {'migration':migrationName, 'items.mounts.Gryphon-RoyalPurple':true};
}
dbUsers.update({_id:user._id}, {$set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
});
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);
}
-71
View File
@@ -1,71 +0,0 @@
var migrationName = '20160731_takeThis.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Take This Sword to Take This challenge participants who already own the Shield
* and Take This Shield to the rest of the list
*/
var mongo = require('mongoskin');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = mongo.db(connectionString).collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'migration':{$ne:migrationName},
'auth.timestamps.loggedin':{$gt:new Date('2016-07-30')}, // Extend timeframe each run of migration
'challenges':{$in:['da8859b2-5c6e-4aa5-b8b2-8db93d5de9fc']}
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.gear.owned': 1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
setTimeout(displayData, 300000);
return;
}
count++;
// specify user data to change:
var set = {};
if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.weapon_special_takeThis':false};
} else {
set = {'migration':migrationName, 'items.gear.owned.shield_special_takeThis':false};
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}
-72
View File
@@ -1,72 +0,0 @@
var migrationName = '20160831_takeThis.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Take This Sword to Take This challenge participants who already own the Shield
* and Take This Shield to the rest of the list
*/
var mongo = require('mongoskin');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = mongo.db(connectionString).collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'migration':{$ne:migrationName},
'challenges':{$in:['ee2b3c87-13f0-422a-af3c-309102d4f7e6']}
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.gear.owned': 1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
setTimeout(displayData, 300000);
return;
}
count++;
// specify user data to change:
var set = {};
if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.armor_special_takeThis':false};
} else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.weapon_special_takeThis':false};
} else {
set = {'migration':migrationName, 'items.gear.owned.shield_special_takeThis':false};
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}
-73
View File
@@ -1,73 +0,0 @@
var migrationName = '20161002_takeThis.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Take This ladder items to participants in this month's challenge
*/
var mongo = require('mongoskin');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = mongo.db(connectionString).collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'migration':{$ne:migrationName},
'challenges':{$in:['4bbf63b5-10bc-49f9-8e95-5bd2ac99cd1c']}
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.gear.owned': 1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
setTimeout(displayData, 300000);
return;
}
count++;
// specify user data to change:
var set = {};
if (typeof user.items.gear.owned.armor_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.head_special_takeThis':false};
} else if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.armor_special_takeThis':false};
} else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.weapon_special_takeThis':false};
} else {
set = {'migration':migrationName, 'items.gear.owned.shield_special_takeThis':false};
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}
-86
View File
@@ -1,86 +0,0 @@
var migrationName = '20161030-jackolanterns.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* set the newStuff flag in all user accounts so they see a Bailey message
*/
var mongo = require('mongoskin');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = mongo.db(connectionString).collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'auth.timestamps.loggedin':{$gt:new Date('2016-10-01')} // remove when running migration a second time
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'migration': 1,
'items.pets.JackOLantern-Base': 1,
'items.mounts.JackOLantern-Base': 1,
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
setTimeout(displayData, 300000);
return;
}
count++;
// specify user data to change:
var set = {};
var inc = {};
if (user.migration !== migrationName) {
if (user.items.mounts['JackOLantern-Base']) {
set = {'migration':migrationName, 'items.pets.JackOLantern-Ghost':5};
} else if (user.items.pets['JackOLantern-Base']) {
set = {'migration':migrationName, 'items.mounts.JackOLantern-Base':true};
} else {
set = {'migration':migrationName, 'items.pets.JackOLantern-Base':5};
}
inc = {
'items.food.Candy_Base': 1,
'items.food.Candy_CottonCandyBlue': 1,
'items.food.Candy_CottonCandyPink': 1,
'items.food.Candy_Desert': 1,
'items.food.Candy_Golden': 1,
'items.food.Candy_Red': 1,
'items.food.Candy_Shade': 1,
'items.food.Candy_Skeleton': 1,
'items.food.Candy_White': 1,
'items.food.Candy_Zombie': 1,
}
}
dbUsers.update({_id:user._id}, {$set:set, $inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
});
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);
}
-75
View File
@@ -1,75 +0,0 @@
var migrationName = '20161102_takeThis.js';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award Take This ladder items to participants in this month's challenge
*/
var mongo = require('mongoskin');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = mongo.db(connectionString).collection('users');
// specify a query to limit the affected users (empty for all users):
var query = {
'migration':{$ne:migrationName},
'challenges':{$in:['d1be0965-e909-4d30-82fa-9a0011f885b2']}
};
// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
var fields = {
'items.gear.owned': 1
};
console.warn('Updating users...');
var progressCount = 1000;
var count = 0;
dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
if (err) { return exiting(1, 'ERROR! ' + err); }
if (!user) {
console.warn('All appropriate users found and modified.');
setTimeout(displayData, 300000);
return;
}
count++;
// specify user data to change:
var set = {};
if (typeof user.items.gear.owned.head_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.body_special_takeThis':false};
} else if (typeof user.items.gear.owned.armor_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.head_special_takeThis':false};
} else if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.armor_special_takeThis':false};
} else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.weapon_special_takeThis':false};
} else {
set = {'migration':migrationName, 'items.gear.owned.shield_special_takeThis':false};
}
dbUsers.update({_id:user._id}, {$set:set});
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);
}

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