Compare commits

...

381 Commits

Author SHA1 Message Date
Sabe Jones
d125b8d2f8 4.41.0 2018-05-01 21:32:06 +00:00
Sabe Jones
451e08ce1c chore(i18n): update locales 2018-05-01 21:31:34 +00:00
SabreCat
16b5b8b8c7 chore(sprites): compile 2018-05-01 21:25:58 +00:00
SabreCat
30a717148e chore(event): end Spring Fling 2018-05-01 21:25:45 +00:00
SabreCat
bcf9670dbe feat(content): Armoire and backgrounds May 2018 2018-05-01 20:55:16 +00:00
Sabe Jones
3722452b51 4.40.1 2018-04-30 20:45:38 +00:00
Sabe Jones
d6b5d275da chore(i18n): update locales 2018-04-30 20:45:27 +00:00
SabreCat
72073386ec chore(news): Bailey 2018-04-30 20:41:31 +00:00
Sabe Jones
8b2019c292 4.40.0 2018-04-24 18:45:51 +00:00
Sabe Jones
9ab70ca276 chore(i18n): update locales 2018-04-24 18:44:30 +00:00
SabreCat
d51aa25470 chore(sprites): compile 2018-04-24 18:38:56 +00:00
SabreCat
0b2c1e6d2e fix(pixels): Better alignment for Squirrel mounts
Also (1) updates an artist credit to a new usename, and (2) corrects a typo in migration comments
2018-04-24 18:37:33 +00:00
SabreCat
58ee6e9703 feat(content): Subscriber Mystery Items 2018/04 2018-04-24 18:36:19 +00:00
Keith Holliday
0044778497 4.39.2 2018-04-24 08:16:35 -05:00
Matteo Pagliazzi
46d6590fec chat: use _id instead of id when finding doc (#10278) 2018-04-24 15:10:20 +02:00
Keith Holliday
b10f056a73 4.39.1 2018-04-23 21:04:03 -05:00
Keith Holliday
eeb890466a Converted date to timestamp (#10276)
* Converted date to timestamp

* Added existence check

* Updated test to include timestamp
2018-04-23 21:03:24 -05:00
Sabe Jones
3b35a0a203 4.39.0 2018-04-23 17:21:12 +00:00
Sabe Jones
d787ad43d3 chore(i18n): update locales 2018-04-23 17:20:54 +00:00
Keith Holliday
7d7fe6047c Move Chat to Model (#9703)
* Began moving group chat to separate model

* Fixed lint issue

* Updated delete chat with new model

* Updated flag chat to support model

* Updated like chat to use model

* Fixed duplicate code and chat messages

* Added note about concat chat

* Updated clear flags to user new model

* Updated more chat checks when loading get group

* Fixed spell test and back save

* Moved get chat to json method

* Updated flagging with new chat model

* Added missing await

* Fixed chat user styles. Fixed spell group test

* Added new model to quest chat and group plan chat

* Removed extra timestamps. Added limit check for group plans

* Updated tests

* Synced id fields

* Fixed id creation

* Add meta and fixed tests

* Fixed group quest accept test

* Updated puppeteer

* Added migration

* Export vars

* Updated comments
2018-04-23 12:17:16 -05:00
Sabe Jones
0ec1a91774 4.38.0 2018-04-19 19:29:33 +00:00
Sabe Jones
adf3281bef chore(i18n): update locales 2018-04-19 19:28:43 +00:00
SabreCat
ea86b35833 chore(news): Bailey 2018-04-19 19:25:45 +00:00
Alys
ade14edcd7 add partial documentation for dueDate parameter in /api/v3/tasks/user and related code 2018-04-18 23:22:11 +10:00
Sabe Jones
3a1888739a Merge branch 'release' into develop 2018-04-17 20:07:12 +00:00
Sabe Jones
3b54ce4949 4.37.2 2018-04-17 20:06:46 +00:00
Sabe Jones
4a8aaf7389 chore(i18n): update locales 2018-04-17 19:55:10 +00:00
SabreCat
45eec47b7f chore(news): Bailey
Also disable some costly analytics
2018-04-17 19:52:36 +00:00
Keith Holliday
4b9af8aa86 Added analytics to front. Fixed group plan tracking (#10262) 2018-04-17 12:43:52 -05:00
SabreCat
631bbcb786 Merge branch 'fix-hippocrite' into develop 2018-04-17 01:37:20 +00:00
Matteo Pagliazzi
76a10d6cf9 start removing inbox from some routes (#10259) 2018-04-16 18:43:09 +02:00
Keith Holliday
a1c9ebd661 Prevent dropdown from closing when clicking search (#10252) 2018-04-15 19:18:40 -05:00
SabreCat
9f06d78db6 Revert "moving developer-only strings to api messages (#10188)"
This reverts commit a42cb0e3ab. Testing hypothesis that this was causing Staging to break.
2018-04-15 17:09:15 +00:00
Alys
ac98aa9271 replace Lemoness's email address with admin in sample config file
This is for consistency with the production server and to ensure
that contributors' screenshots in PRs match what will be seen
in production.
2018-04-15 13:34:42 +10:00
negue
455f7ac59b round priority on update too (#10186)
* round priority on update too

* move the fix to Task sanitizeTransform

* refactor the task.priority parsing
2018-04-14 16:16:25 +02:00
negue
a42cb0e3ab moving developer-only strings to api messages (#10188)
* move translatable string to apiMessages

* use apiMessages instead of res.t for groupIdRequired / keepOrRemove

* move pageMustBeNumber to apiMessages

* change apimessages

* move missingKeyParam to apiMessages

* move more strings to apiMessages

* fix lint

* revert lodash imports to fix tests

* fix webhook test

* fix test

* rollback key change of `keepOrRemove`

* remove unneeded `req.language` param

*  extract more messages from i18n

* add missing `missingTypeParam` message
2018-04-14 16:13:13 +02:00
Alys
d05d2fb9d7 removed a slur that has legit uses - TRIGGER / CONTENT WARNING: slurs, swearwords, assault, etc 2018-04-14 21:51:06 +10:00
negue
6c4c5b4697 always check for the quantity not (#10251) 2018-04-13 21:04:08 +02:00
Keith Holliday
5da87640e4 Apple pay tests (#10248)
* Added more tests for verifyGemPurchase

* Added more tests for subscribe

* Added user is subscribed check

* Reverted gulp task

* Added existence check
2018-04-13 12:41:41 -05:00
Kip Raske
fa044ffb44 Feature/sortable reward area (#9930)
* Client POC

We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable

* Ah that ref was being used after all, changing back

* Scaffold out a new callback for when we drag these things

Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start

* Firefox caching is the problem: don't actually need the wrapper div

So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on

* Scaffolding out our API call to save the sort order

The endpoint doesn't exist yet so we will need to add that

* Ok we are now calling our API endpoint to reorder these things

Of course it doesn't exist yet so you get a 404 when you try, but that
is ok

* Defining api endpoint, a work in progress

In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.

* Switching to using the pinned item UUID

This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same

* I thought this would fix our server/client mismatch but it is not it

Something is really wrong with my logic somewhere, maybe I need to
update the db step?

* Moving this logic to the "user" rather than "tasks" and key off path

Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?

* This client code caused quite a lot of problems if you dragged fast

We don't really need it it seems, so off it goes

* Updating markup and CSS so it actually looks good.

Everything is working horray!!

I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@

* Cleaning up my comments in the API section user.js

I had a lot of TODOS that are mostly done now

* Fixing a spacing code standards thing

* Turns out we never use type, so we should remove this from the API call

* Adding pinnedItemsOrder into the user schema

And disabling my call in the frontend before I do any more damage

* Halfway to using pinnedItemsOrder

This isn't working yet but it is not going to break it horribly like it
was before.

* Hooking up inAppRewards to always produce sorted information

It is suspicially working right now even though I have not added the
seasonal stuff logic yet...

* Updating the comments in user.js in movedPinnedItem

It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing

* Cleaning up code standards kinds of things

* Yay, this fixes the popover issue

I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too

* ** Partial Work ** Starting tests on api call for draggable items

Doesn't work, doesn't compile so don't include in PR!

* Test failing still...

This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items

* Okay have the first test passing

Need to clean up my linter problems though

* Planning out the next two tests and fixing my format problems

* 2nd Test case written, this time with the "more" odd case

* Making sure that we didn't mess with pinned items

* Huh... this test doesn't give me the expected result

Drat, I guess I found a bug

* Throw an error when we put garbage in our api call.

Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?

* Cleaning up the multitude of linting problems thanks gulp :)

* Writing tests for inAppRewards.js, but something is wrong

* Fixing my linting errors in inAppRewards tests

These tests still do not run though, so they may fail and I would not
know

* Applying Negue's fixes to inAppRewards.js test

It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 15:22:06 +02:00
Tyler Nychka
5449652bd2 pinned items fixes #10012 (#10216)
* Don't unpin non-gear items

Assumes that multiple of bundles, quests, eggs, potions can be bought

* Added tests

* Changed type checking and made variables global

* Lint fix
2018-04-13 15:19:44 +02:00
Philip Karpiak
c12ae9ea25 Fix #10202 - Send DELETE request when detaching social auth (#10207) 2018-04-13 15:16:49 +02:00
greenkeeper[bot]
734a300b92 fix(package): update sass-loader to version 7.0.0 (#10250) 2018-04-13 15:15:08 +02:00
negue
1109ae308d convert buyQuest (gold) to the purchase refactoring / check quantity to be a number (#10244) 2018-04-13 15:14:51 +02:00
negue
8f1d241e83 if a pet is still hatchable show the hatchable - icon instead of the "you already own the mount"-icon (#10243) 2018-04-13 15:13:42 +02:00
Matteo Pagliazzi
acbca4d1dc upgrade deps 2018-04-12 21:55:24 +02:00
Matteo Pagliazzi
1ea9be8aa2 Preparatory Work for Smaller user doc (WIP) (#10245)
* protect all paths in user.pre(save using this.isDirectSelected to see if a field is available

* fix linting

* authWithHeaders: specify user fields to exclude instead of the ones to include, add comments, doc and improve test

* add more options to unit helper generateReq and add tests for excluding fields in authWithHeaders
2018-04-12 21:17:47 +02:00
Sabe Jones
ace02893e5 4.37.1 2018-04-12 18:38:18 +00:00
Sabe Jones
1c3e043fac chore(i18n): update locales 2018-04-12 18:37:36 +00:00
Matteo Pagliazzi
71c9e7a685 Tasks Modal: add setter for repeatsOn (#10247)
* fix for 10236, add setter to repeatsOn

* remove console.log
2018-04-12 13:30:56 -05:00
Sabe Jones
fa945c7689 Merge branch 'release' into develop 2018-04-11 01:38:10 +00:00
Sabe Jones
c54ce96033 4.37.0 2018-04-11 01:37:46 +00:00
Sabe Jones
85c4e93763 chore(i18n): update locales 2018-04-11 01:37:27 +00:00
SabreCat
25e5e78373 chore(sprites): compile 2018-04-11 01:33:15 +00:00
SabreCat
06181d0a1a feat(content): Squirrel Pet Quest 2018-04-11 01:32:49 +00:00
Matteo Pagliazzi
d5a8259fdb fix members modals (#10240) 2018-04-10 13:27:06 +02:00
Isaac Lim
9db7141853 Added meta image for social media sharing (#10193)
* Add meta image for social media sharing

* Meta Image in Images

* Update index.html
2018-04-09 08:34:12 +02:00
Brian Fenton
ec2a1927a0 adding name attribute to radio inputs so browser inforces selecting a single item from the named set (#10236) 2018-04-09 08:31:33 +02:00
Matteo Pagliazzi
1c1b0f00ad reorganize payments files (#10235) 2018-04-08 16:27:03 +02:00
Alys
fb4d3e44d3 improve code and tests for banned words and slurs (#10211)
* remove removePunctuationFromString function from test code

It's not needed now that the test banned words don't contain underscores.

* prevent tests accidentally throwing messageGroupChatSpam

This commit makes the user for most tests have contributor tiers so
that the user can't trigger the messageGroupChatSpam error message
(for posting messages too quickly).

This is useful when some of the tests fail due to broken code
because that makes more messages be posted than expected. If the user
doesn't have tiers, the messageGroupChatSpam error message would be
triggered, which gives misleading information about the test failure.

* add tests for banned swear and slur words posted in mixed case

* allow banned word error message to show bad words in the same case the user typed them

* stop using randomly-chosen real banned words in tests

The test modified in this commit had been using real banned words,
which meant that those words were being displayed to the contributors
when the test failed.

NB the 'check all banned words are matched' test also uses the real
banned words but the test failure messages don't show the words.

* improve translatability of bannedWordUsed error message
2018-04-08 15:31:37 +02:00
Alys
37fd062cf9 increase Hourglasses and gemCapExtra promptly when multi-month subscription renews - fixes #4819 (#10147)
* allow Hourglasses and gemCapExtra to increase promptly after a multi-month subscription has renewed

* fix existing Hourglass and Gem Cap tests that were wrong

The scenario originally used for these two tests was a six-month recurring
subscription (you can tell that from the starting offset having a non-zero value).
For recurring subscriptions, we do NOT want to increase the consecutive month
benefits as soon as the sixth month starts because the user has already been
given a full six months' benefits in advance and they might cancel the
subscription before it renews later in the sixth month.
Therefore we want to give the extra benefits at the beginning of the seventh
month (ideally we'd give them mid-month in the sixth month when the renewal
happens but we don't have support for tracking renewal dates).
So, the two changed tests were actually not correct for the case
where the offset started as non-zero.

These tests are correct for one-month recurring subscriptions (when the offset
is never set to anything above zero). The user isn't meant to get any consecutive
month benefits until a multiple of 3 months has been reached.

* add tests for one-month recurring subscription before 3x months are reached

* add tests for 3-, 6-, and 12-month recurring subscriptions

The 3-month tests are the most thorough, stepping through the
expected start and end values of consecutive data for a 7-month
range.

The 6-month tests are a bit less thorough since the same code is
used for all multi-month periods.
The discount Google subscription code is used to ensure we keep
support for it.

The 12-month tests are less thorough still, since again the same
code is used.

I'm about to try some more tests with `useFakeTimers`, which should
be a better way to test the code since they won't rely on me having
set the initial values correctly for each test. :) But I wanted to
work through these cases manually first to ensure my understanding
of how the values should change does actually match the code.

* add tests for 1-, 3-, 6-, and 12-month recurring subscriptions using clock changes to simulate passing months

Also fixed the clock call in an unrelated test because it was forming
the date incorrectly (`unix()` can't be used to create a date).

Also changed email@email.email to email@example.com because
email@email.email is potentially a real email address.

* add tests for 3-month gift subscriptions - no extra consecutive benefits given

* add tests for consecutive benefits for 6-month recurring subscription that has incorrect consecutive month data because it started before issue #4819 was fixed

* fix lint errors

* remove outdated subscription tests
2018-04-08 15:26:25 +02:00
Matteo Pagliazzi
485c3c5c46 disable failing test 2018-04-08 14:58:51 +02:00
negue
5007393f24 enable hair style edit during intro (#10227) 2018-04-08 14:52:26 +02:00
Alys
e111ac730c enable translated pet names in hatching success message (#10231) 2018-04-08 14:50:36 +02:00
Philip Karpiak
e7c78eabce Wrap creator icon + text in @click event (#10221)
Perviously only clicking the icon would activate tabs in the creator, which was confusing
2018-04-06 12:56:33 -05:00
Philip Karpiak
5da7699548 Add tooltip to character buff icon (#10156)
* Add tooltip to character buff icon

* Add tooltips for task streak, challenge and broken challenge

* Add tooltips for task menu and due date

* Challenge icon tooltip displays the challenge short name
2018-04-06 12:53:39 -05:00
Keith Holliday
f42955a0ba Added initial account banned modal (#9868)
* Added initial account banned modal

* Fixed check for non logged in user
2018-04-06 08:33:38 -05:00
Sabe Jones
4d67df4da6 4.36.0 2018-04-05 21:09:10 +00:00
Sabe Jones
ab7459f4f3 chore(i18n): update locales 2018-04-05 21:08:53 +00:00
SabreCat
469db7c0e2 Merge branch 'develop' into release 2018-04-05 21:04:11 +00:00
SabreCat
952e813b30 feat(event): avatar customizations 2018-04-05 21:03:57 +00:00
Matteo Pagliazzi
f04d05fee1 fix likes appearing immediately in chat 2018-04-05 20:54:20 +02:00
SabreCat
6d9aa43c07 fix(purchasing): typo "substract" 2018-04-03 20:30:54 +00:00
Sabe Jones
f527221079 Merge branch 'release' into develop 2018-04-03 18:49:37 +00:00
Sabe Jones
d9b852e1ea 4.35.1 2018-04-03 18:49:14 +00:00
Sabe Jones
a1207c1d8d chore(i18n): update locales 2018-04-03 18:48:56 +00:00
SabreCat
f4fb90013d feat(event): enable Shiny Seeds
Plus Bailey news and fix for bulk purchasing transformation items
2018-04-03 18:42:24 +00:00
negue
73a7c0eebc antidote display and functionality (#10199)
* update antidote display and functionality - fixes #9758 and #10160

update antidote display and functionality - fixes #9758 and #10160

update antidote display and functionality - fixes #9758 and #10160

update antidote display and functionality - fixes #9758 and #10160

* clean up / refactor

* prevent unpin of all items which don't have a pinType

* remove the double boolean casting / fix lint
2018-04-03 17:35:56 +00:00
SabreCat
1819398f41 Revert "feat(event): April Foolery 2018"
This reverts commit f7b9ca124d.
2018-04-03 17:19:14 +00:00
Keith Holliday
ab14312368 Group plan landing page (#10222)
* Updated task page styles

* Added initial page styles

* Added login and payments

* Updated more styles

* Added white header

* Added group plan overview modal

* Updated copy

* Fixed location

* Style updates

* Added analytics

* More style updates

* Added locales

* Removed duplicate key
2018-04-03 11:26:08 -05:00
Sabe Jones
690d3e3fd2 Merge branch 'release' into develop 2018-04-03 00:55:28 +00:00
Sabe Jones
36f9a4918f 4.35.0 2018-04-03 00:55:06 +00:00
Sabe Jones
a4b5e27614 chore(i18n): update locales 2018-04-03 00:45:59 +00:00
SabreCat
0abfe86296 chore(sprites): compile 2018-04-03 00:41:49 +00:00
SabreCat
e11c777325 feat(content): Armoire and Backgrounds 4/18 2018-04-03 00:41:22 +00:00
Keith Holliday
63a04f36c9 Added guilds to allowed banned words 2018-04-02 17:36:57 -05:00
Keith Holliday
e58af6e3ea Replaced siena with admin 2018-04-02 17:35:26 -05:00
Keith Holliday
6ba28b5757 Added fix for chat revoke creation test (#10218) 2018-04-02 19:11:30 +02:00
Keith Holliday
ed607d2bae Fixed challenge count check (#10215) 2018-04-01 16:54:32 -05:00
Keith Holliday
1f7fc594e5 Added supression support for pet/mount modals and added mount modal (#9882)
* Added supression support for pet/mount modals and added mount modal

* Moved create animal

* Fixed raise pet logic

* Added suppresion for stable hatch modal

* Fixed click paw and added growl

* Fixed confirm. Fixed mount name

* Suppresed confirmation
2018-04-01 14:43:18 -05:00
Alys
45d0a4fac2 add a second test swear word and slur - TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc 2018-04-01 19:58:23 +10:00
Sabe Jones
e50bc189aa Merge branch 'release' into develop 2018-04-01 03:55:40 +00:00
Sabe Jones
95f8867bf8 4.34.2 2018-04-01 03:01:04 +00:00
SabreCat
4968b291f7 chore(news): Bailey 2018-04-01 02:59:54 +00:00
SabreCat
f7b9ca124d feat(event): April Foolery 2018 2018-04-01 02:55:04 +00:00
Philip Karpiak
4623bcd877 Force menu links to have white color on :hover (#10200)
This is mostly to fix the contact form link under the Help menu inheriting the wrong color on hover due to missing href attribute
2018-03-31 13:48:41 +02:00
Alys
4a368a1128 supply the correct type and path for featured Magic Hatching Potions - fixes #10135 (#10204) 2018-03-31 13:46:51 +02:00
Alys
bec8cb01e0 prevents a user who has had their chat privileges revoked from creating a public guild (#10205) 2018-03-31 13:46:14 +02:00
negue
f3c041a561 antidote display and functionality (#10199)
* update antidote display and functionality - fixes #9758 and #10160

update antidote display and functionality - fixes #9758 and #10160

update antidote display and functionality - fixes #9758 and #10160

update antidote display and functionality - fixes #9758 and #10160

* clean up / refactor

* prevent unpin of all items which don't have a pinType

* remove the double boolean casting / fix lint
2018-03-31 13:39:26 +02:00
Mateus Etto
c21726ec61 No Ethereal Surge on Mages (#10121)
* problem location identified (breaks code)

* problem identification notes

* Add class checking to ES (does not yet notify user)

* Add error message

* Add .gitattributes

Attempting to fix line ending disaster

* package stuff

so I can see what's broken

* add reminder and hopefully fix gitattributes

* Fix lint errors

* Redo surge fail notifs

* exterminate rogue comment, fix gitattributes

* Remove unused import 

As per @paglias' request.

* fix(lint): remove extraneous expression

* Delete .gitattributes

* Fix skill key surge -> mpheal

* Show notification only when there are mages in party

* Fix notification being too big and appearing outside the notification div

* Remove unused code

* Only show the notification on parties with 2 or more mages

The caster is a mage, so certainly at least 1 mage will be counted.

* Automated test: mpheal does not heal other mages

* Fix lint error

* Fix typo in test description

* Increase performance of test

* Using target instead of requestion partyMembers again

* Rename variable 'party' to 'partyMembers'

* Update strings in English

* spell -> Skill
2018-03-31 13:34:39 +02:00
Alys
df69208caa prevent a user with no chat privileges from inviting any player to a guild or party (#10194)
This is because they could use private group chat messages to bypass
the restriction on talking to other players.
2018-03-31 13:29:08 +02:00
negue
08d07cdd67 split profile and profileStats (#10185) 2018-03-31 13:22:17 +02:00
Philip Karpiak
a309e48183 Remove Like action from inbox chat messages (#10181)
There is no API endpoint for this action and seems rather useless for private messages anyway
2018-03-31 13:20:41 +02:00
Clay Smith
70c539cc81 (fixes #9978) Remove Leader dropdown from groupFormModal (#10176) 2018-03-31 13:17:10 +02:00
negue
11f136ac89 Purchase API Refactoring: Armoire (#10153)
* convert armoire

* fix armoire tests

* fix lint
2018-03-31 13:10:37 +02:00
negue
567d5f74ba Purchase API Refactoring: Health Potion (#10152)
* convert buyHealthPotion

* fix health potion tests

* fix lint
2018-03-31 13:09:16 +02:00
Alys
338781f57b improves rounding for boss hp and player pending damage - partial fix for #8368 (#9749)
* improves rounding for boss hp and player pending damage

* use floor filter function for user's pending damage for party page and tavern boss
2018-03-31 12:57:37 +02:00
Matteo Pagliazzi
bd07f3cd38 disable test failing on travis 2018-03-31 12:20:11 +02:00
Alys
0b735abd44 remove underscores from test swear words and slurs - TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc
This is because real words don't contain them and the test words should mimic real words.
2018-03-31 18:06:04 +10:00
Alys
a88cdaf1fc Revert "Move notification snackbars when resting bar is shown (#10177)" (#10203)
This reverts commit 64e86bad91
because the console was showing errors like this:

[Vue warn]: Error in render: "TypeError: this.user is null"
found in
---> <App> at website/client/app.vue
       <Root>
2018-03-31 15:15:13 +10:00
Neel Mehta
7cae5f1a37 fix featured quests label under butterfly (#10197) 2018-03-30 15:39:33 -05:00
Neel Mehta
e453330535 Make modal overlay transparent, not solid purple (#10191) 2018-03-30 15:38:22 -05:00
Philip Karpiak
b1e5fcdeaf Focus title input of task modal when shown (#10182) 2018-03-30 15:35:59 -05:00
Philip Karpiak
10e0848a5c Use margin offsets for group plan header (#10180)
So there are no whitespaces around the header
2018-03-30 15:34:46 -05:00
Philip Karpiak
64e86bad91 Move notification snackbars when resting bar is shown (#10177)
Allows top-most notification to still be shown
2018-03-30 15:34:06 -05:00
Gabriel Siedler
21cf5d2321 fixes #10173 - Task page search bar only searches task titles, not No… (#10175)
* fixes #10173 - Task page search bar only searches task titles, not Notes (#10173)

* Fixing unit test: Test expect task to have note, but it has notes.
2018-03-30 15:30:15 -05:00
Matteo Pagliazzi
a6106a801b try fix for test 2018-03-30 19:31:35 +02:00
Matteo Pagliazzi
769405ff34 google subs: make sure the subs can be cancelled if they return a 410 from google (#10201) 2018-03-30 19:24:51 +02:00
Sabe Jones
a0803796b2 Merge branch 'release' into develop 2018-03-30 17:03:39 +00:00
Sabe Jones
cb418882f3 4.34.1 2018-03-30 17:03:13 +00:00
Sabe Jones
b17a09ac17 chore(i18n): update locales 2018-03-30 16:58:55 +00:00
Sabe Jones
88bb4f6a72 Revert "Revert "Adding the ability for admins to revoke/reinstate chat privileges and block/unblock users from the profile page. (#10082)""
This reverts commit fed2d3fb19.
2018-03-30 16:57:21 +00:00
SabreCat
ae0c440846 chore(news): Bailey 2018-03-30 16:55:51 +00:00
Keith Holliday
2f69f4039e Made challenge paging optional 2018-03-30 11:34:00 -05:00
Matteo Pagliazzi
10370ea1dc fix wording on admin tools 2018-03-30 18:27:20 +02:00
Sabe Jones
0d65e5219e 4.34.0 2018-03-30 01:20:25 +00:00
Sabe Jones
fed2d3fb19 Revert "Adding the ability for admins to revoke/reinstate chat privileges and block/unblock users from the profile page. (#10082)"
This reverts commit e4b13eecd1.
2018-03-30 01:20:18 +00:00
Sabe Jones
6ec50ed0c1 chore(i18n): update locales 2018-03-30 01:18:27 +00:00
SabreCat
6f1a551d76 chore(news): Bailey 2018-03-30 01:12:38 +00:00
SabreCat
bed97f0610 feat(community): update Community Guidelines 2018-03-30 00:26:07 +00:00
Sabe Jones
f86f98f4a6 Merge branch 'release' into develop 2018-03-28 21:33:04 +00:00
Sabe Jones
0e442a0076 4.33.2 2018-03-28 21:32:03 +00:00
Sabe Jones
89f047b15b chore(i18n): update locales 2018-03-28 21:30:38 +00:00
Travis Husman
e64bc2e39a Fixing issue with pull request when task is changed to monthly but that start date isn't updated. 2018-03-28 21:00:17 +00:00
SabreCat
3b3fcbdfce fix(sound): correct element nesting 2018-03-28 20:47:31 +00:00
Neel Mehta
558dd2e4bf fix hippo-crite scroll image size 2018-03-27 23:04:34 -04:00
SabreCat
7914a959b3 fix(test): add flags to expected public fields 2018-03-27 21:50:55 +00:00
SabreCat
8a27524fa0 fix(members): include classSelected flag in public fields 2018-03-27 21:21:11 +00:00
Matteo Pagliazzi
a64fed97ac try to fix failing tests 2018-03-27 15:54:00 +02:00
Keith Holliday
e937d1722e Contact form links (#10187)
* Added links to contact form

* Fixed encoding link. Added link to tavern. Updated copy

* Converted link to cookie link

* Updated domain format

* Updated links

* Added apikey to cookie
2018-03-26 14:02:32 -05:00
greenkeeper[bot]
f537e8142f chore(package): update eslint-plugin-mocha to version 5.0.0 (#10174) 2018-03-24 18:34:32 +01:00
Travis
e4b13eecd1 Adding the ability for admins to revoke/reinstate chat privileges and block/unblock users from the profile page. (#10082)
* Adding the ability for admins to revoke/reinstate chat privileges and block/unblock users from the profile page.

fixes #10073

* Updating fix to dynamically load user blocked and chat revoked state for admins.

* Fixing pr according to comments.
2018-03-24 11:18:52 -05:00
Travis
b5872a9577 Give MasterClasser Acheivement on completion of any of the series quests, not just the final. (#10086)
* Adding check to give master classer acheivement on any master classer series quest completion

fixes #9461

* Fixing concat bug by assigning the variable after concatenation.

* Fixing retry query.
2018-03-24 11:18:33 -05:00
Travis
48fa78bef2 Quest completion modal acknowledge on close (#10089)
* Change quest completion modal to only close on user acknowledge of clicking ok or 'x'
and update 'x' to acknowledge the quest completion.

* Removing check on header-close.

* Removing unused variable.
2018-03-24 11:18:13 -05:00
Travis
781256c917 fix: fix quest shop to not use string addition when buying quests (#10120)
* fix: fix quest shop to not use string addition when buying quests

fixes #10115

* Fixing quest purchase quantity interpretted as a string on the server side.

* Adjusting pull-request according to comments.

* Updating according to PR comments.
2018-03-24 11:17:23 -05:00
Mark Kuba
dcd680c293 Fix/mana bar unselected class - fix: #10026 (#10126)
* Update getClass() for users who have not yet selected a class

* Added tests for members.getClass()

* fix linter errors

* Update test

* Update import in test to point to correct module

* use hasClass() getter where appropriate

* Fix linter error
2018-03-24 11:15:40 -05:00
Philip Karpiak
ec6f53bb1b Wrap attribute cell value text (#10161)
When they become floating point or have more than 3 charcters they wrap to the next line. This change prevents that.
2018-03-24 11:12:26 -05:00
jack
9834afee4a fixes #9880 - uneven sizes and spacing in the action buttons of the user modal. (#10163) 2018-03-24 11:09:56 -05:00
Dexx Mandele
9b279563ea Prettify background overview (#10078)
* Bring buy bg set button in line with title

* Make background sets pretty

* Add checkbox to filter backgrounds

* Review: replace background filter checkbox with toggle

* Remove dashed line from toggle-switch label

* Test: add comma to make es-lint happy

* Move toggle tooltip into toggle-switch template

* Make toggle-switch label optional

* Review: Remove toggle-switch margin
2018-03-24 11:07:37 -05:00
Sabe Jones
347fe69667 Merge branch 'release' into develop 2018-03-24 02:51:25 +00:00
Sabe Jones
552cf70abd 4.33.1 2018-03-24 02:51:01 +00:00
Sabe Jones
01c8ef9382 chore(i18n): update locales 2018-03-24 02:48:23 +00:00
Keith Holliday
298a6a743c Added paging (#10150)
* Added paging

* Escaped regex

* Fixed challenge side effect tests
2018-03-23 14:13:08 -05:00
Matteo Pagliazzi
fa17ab7c17 avoid errors when trying to call createTasks with no tasks (#10170) 2018-03-23 17:15:50 +01:00
Matteo Pagliazzi
0f339d8d3e Docker: yarn is not necessary anymore 2018-03-23 16:20:00 +01:00
Keith Holliday
99852fcd89 Stringified mem report (#10167)
* Stringified mem report

* Passed info
2018-03-23 10:19:24 -05:00
Matteo Pagliazzi
ca3d044aa1 upgrade deps 2018-03-23 16:01:51 +01:00
greenkeeper[bot]
b338e65dc9 chore(package): update karma-webpack to version 3.0.0 (#10151) 2018-03-23 16:00:18 +01:00
greenkeeper[bot]
1475c93962 chore(package): update eslint-friendly-formatter to version 4.0.0 (#10168) 2018-03-23 15:58:40 +01:00
Sabe Jones
ddec458364 4.33.0 2018-03-22 19:58:55 +00:00
Sabe Jones
bfe74a8dcb chore(i18n): update locales 2018-03-22 19:57:57 +00:00
SabreCat
13d9da404d chore(sprites): compile 2018-03-22 19:51:21 +00:00
SabreCat
85e0af0c0e feat(content): Mystery Items 2018/03 2018-03-22 19:50:47 +00:00
SabreCat
a2e5548b1c Merge branch 'develop' into release 2018-03-22 18:53:40 +00:00
negue
36dabad2c9 fix seasonal shop (#10164) 2018-03-22 13:50:58 -05:00
Keith Holliday
25b9e6f330 Added memwatch for memory leak detection (#10166) 2018-03-22 12:44:45 -05:00
Keith Holliday
d0a786554c Removed balance check test (#10159)
* Removed balance check test

* Removed balance check in common

* Removed gem logic and added achievement to tests
2018-03-21 11:53:47 -05:00
Alys
de79e0e3c3 add swear word - TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc 2018-03-21 19:19:13 +10:00
Sabe Jones
0e74d25ede Merge branch 'release' into develop 2018-03-20 23:12:23 +00:00
Sabe Jones
bde8b76da7 4.32.1 2018-03-20 23:11:49 +00:00
Sabe Jones
4235be4b43 chore(i18n): update locales 2018-03-20 23:11:37 +00:00
Sabe Jones
3af7f89d10 Merge branch 'release' into develop 2018-03-20 22:57:52 +00:00
Sabe Jones
396362d27e 4.32.0 2018-03-20 22:57:28 +00:00
SabreCat
972efb1878 fix(seasonal-shop): remove quest
it was breaking the API. Wut? Just use canBuy logic and Quest Shop for now
2018-03-20 22:49:54 +00:00
SabreCat
6c18d19d95 fix(test): extra curly 2018-03-20 21:56:55 +00:00
SabreCat
9b8bdb90d8 chore(sprites): compile 2018-03-20 21:31:04 +00:00
SabreCat
a84ea8b1b7 feat(event): Spring Fling 2018 2018-03-20 21:30:43 +00:00
Matteo Pagliazzi
480a839bc5 update package-lock 2018-03-18 16:36:36 +01:00
greenkeeper[bot]
df9c54fe20 chore(package): update http-proxy-middleware to version 0.18.0 (#10131) 2018-03-18 16:33:33 +01:00
greenkeeper[bot]
8dbab1a976 chore(package): update sinon-chai to version 3.0.0 (#10096) 2018-03-18 16:33:19 +01:00
greenkeeper[bot]
df6088bc6d fix(package): update url-loader to version 1.0.0 (#10088) 2018-03-18 16:31:03 +01:00
greenkeeper[bot]
f0ff3a4eb6 fix(package): update html-webpack-plugin to version 3.0.0 (#10070) 2018-03-18 16:29:25 +01:00
greenkeeper[bot]
786e4419da chore(package): update eslint-loader to version 2.0.0 (#10056) 2018-03-18 16:28:20 +01:00
Chris Wang
fff4ea3ad3 Added popover stats to costume equipment on profile stats - fixes #9280 (#10136)
* Added popover stats to costume equipment on the stats page of a profile (#9280)

* Changed popover position to bottom for equip and costume items.

* Fixed indent on line 160

* Changed escaped double quotes to single quotes for readability
2018-03-18 16:24:41 +01:00
kartik adur
e18e89bc10 Task page - task filters v2 (#10053)
* update column.vue, getters/task.js, getters/user.js and add unittests and helpers

* add vue-test-utils pkg + unit test for column.vue

* add unit test column.vue

* update unit tests

* fix linting errors
2018-03-18 16:23:58 +01:00
Matteo Pagliazzi
68ea28305d fix linting issues 2018-03-17 22:36:17 +01:00
Travis
242b3508a1 Update Staff list in the tavern to make staff names clickable to pull up staff profiles. (#10107)
* Update Staff list in the tavern to make staff names clickable to pull up staff profiles.

fixes #9290

* Addressing PR comments.
2018-03-17 22:29:52 +01:00
Travis
8c316d939f Updated get challenges api to return challenges sorted by which challenges include the habitica_official category (#10079)
and removed sorting on the official flag of the challenges object.

fixes #9955
2018-03-17 22:26:24 +01:00
Travis
45eb19e992 Update the API to prevent the user from leaving a group if they are the only member and have a quest active. (#10091)
* Update the API to prevent the user from leaving a group if they are the only member and have a quest active.

fixes #10068

* fixing api doc
2018-03-17 22:26:07 +01:00
Travis
3ad0ffcaec Escaping regex characters from user input before searching for groups. (#10092)
fixes #9953
2018-03-17 22:25:50 +01:00
Travis
fef8929dd9 Fixes start date updating the repeat on day for dailies repeated monthly (#10095)
fixes # 9200
2018-03-17 22:25:34 +01:00
Travis
911f894750 Fixing edit profile page so blurb can be editted after reload. (#10097)
fixes #10032
2018-03-17 22:25:17 +01:00
Travis
d4e2f5ac9e fix: Fixing xml data export 500 error. (#10114)
* fix: Fixing xml data export 500 error.

fixes #10100

* Removing outdated comment.

* Making xml data export test pass consistently.
2018-03-17 22:24:40 +01:00
Mahendran Nadesan
e43749bed1 Stats over 3 digits overlap (fixes #10033) (#10133)
* Formatted stats

* small changes

* Fixed issues as per comments
2018-03-17 22:23:55 +01:00
Sarah Boo
8be29e27d0 Hide "Delete Completed" To-Dos button on Challenge or Group Task Board - fixes #9935 (#10128)
* only show delete to-dos for user's task page

* remove stray spaces
2018-03-17 22:22:12 +01:00
Mark Kuba
301668fe22 fix: you are already in group message - fixes #10119 (#10122)
* add youAreAlreadyInGroup message

* add test for youAreAlreadyInGroup message

* update youAreAlreadyInGroup message
2018-03-17 22:21:16 +01:00
Gene Vityugov
767f3ebe12 Add space in profile modal to make it consistent with other text (#10103) 2018-03-17 22:19:58 +01:00
EthanEFung
25e6f8e26e Add Completion Text to Older Quests #10066 (#10081) 2018-03-17 22:18:54 +01:00
Dmitry Torba
1c6608d071 fix flower avatar in chat #10015 (#10040) 2018-03-17 22:17:47 +01:00
Toivo Mattila
d2b160438c Added margin to buttons on Settings-page (#10034)
* Added margin to buttons on Settings-page

* Added bottom margin for 'Enable Class System' button
2018-03-17 22:16:55 +01:00
Александр
37d70f089c Removes video from presskit.zip (#10013)
* presskit without video

* Boss/ update pics

* Logo/ change broken pics

* updated broken files

* Delete Level Up.PNG

* Add files via upload

* update outdated icons

* update party

* upload updated presskit
2018-03-17 22:15:40 +01:00
Julius Jung
04b4912d59 Fix password reset when querying for emails with upcase characters (fixes #9059) (#9707)
* downcase updating an email to be consistent with creating

* add tests to ensure downcase of email for create/update

* create migration to downcase existing User objects

* delete 'only'

* change gmail to example

* add trailing comma from lint error

* search for emails with at least one capital letter

* fix query in order to search for any email with at least one capital letter

* batch process effected users with at least one capital in email

* update script for batch process effected users
2018-03-17 22:13:54 +01:00
Zack Sunderland
b9a6d9ceec Allow Un-subscribed Users to Claim Mystery Items (#9270)
Remove restriction on mystery/special inventory items that prevents
non-subscribed users from seeing the items. Organize the imports on the
page.

Resolves: Issue #9228
2018-03-17 22:13:31 +01:00
negue
2a97915477 Purchase API Refactoring: Market Gear (#10010)
* convert buyGear to buyMarketGearOperation + tests

* move NotImplementedError
2018-03-17 21:56:19 +01:00
Alys
29a9deaeb8 prevent lint indent warning on multi-line reduce function (#10145) 2018-03-17 21:13:55 +01:00
negue
0fcc1f2080 correct position of pets in the profile overview - fixes #10104 (#10144) 2018-03-17 21:13:35 +01:00
negue
9287098e70 fix #10116 (#10143) 2018-03-17 21:13:12 +01:00
negue
1812f63812 raise coverage for user api calls (#10099)
* user integration tests

* fix lint
2018-03-17 21:12:53 +01:00
negue
3d4107db3e checkout of the Inn - banner (#9835)
* show resting banner

* resume damage

* replace colors by variables

* remove indentation
2018-03-17 21:12:25 +01:00
Sabe Jones
67e750a81c 4.31.1 2018-03-15 21:19:44 +00:00
Keith Holliday
7fe62a731b Fixed gem amount on master key (#10140)
* Fixed gem amount on master key

* fix(news): update Bailey text
2018-03-15 16:19:11 -05:00
Sabe Jones
3c224fe353 Merge branch 'release' into develop 2018-03-15 19:10:56 +00:00
Sabe Jones
bb6f465ac8 4.31.0 2018-03-15 19:10:37 +00:00
Sabe Jones
a2a79e4607 chore(i18n): update locales 2018-03-15 19:07:38 +00:00
SabreCat
5125cc5f59 chore(news): Bailey 2018-03-15 19:04:00 +00:00
Matteo Pagliazzi
cb42a31c43 Node 8 (WIP) (#9946)
* start upgrade to node 8

* upgrade travis

* improve travis

* Remove bluebird, babel (except for modules) from server (WIP) (#9947)

* remove bluebird, babel from server (except for modules)

* fixes

* fix path

* fix path

* fix export

* fix export

* fix test

* fix tests

* remove plugin for transform-object-rest-spread since it is supported in node8

* babel: correct syntax rest spread

* remove bluebird

* update migrations archive readme

* fix package-lock.json

* fix typo

* add package-loc
2018-03-15 19:59:36 +01:00
Alys
b1b1e512f5 adjust word order in mod slack flag message (#10137) 2018-03-15 19:27:59 +01:00
Alys
5ba09c45df adjust comments and word lists in slurs and banned words. TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc 2018-03-15 20:53:48 +10:00
Matteo Pagliazzi
70dec611e3 Make Kafka dep optional (#10129)
* Made kafka optional

* make kafka optional
2018-03-14 18:21:39 +01:00
Keith Holliday
2195464772 Flag comment (#9991)
* Added initial chat flag comment form

* Added user comment to slack message

* Updated copy and styles

* Fixed comma

* Updated admin messaging
2018-03-14 07:41:13 -05:00
Sabe Jones
b662f8bdff Merge branch 'release' into develop 2018-03-13 21:00:00 +00:00
Sabe Jones
0e6d6336c6 4.30.0 2018-03-13 20:59:13 +00:00
Sabe Jones
d8078adacd chore(i18n): update locales 2018-03-13 20:58:43 +00:00
SabreCat
a88800df78 chore(sprites): compile 2018-03-13 20:54:54 +00:00
SabreCat
42e0095bbd feat(content): spring Hatching Potions 2018-03-13 20:54:27 +00:00
Sabe Jones
ee1aa653f0 fix(groups): Guild badge fencepost errors 2018-03-12 14:43:39 -05:00
SabreCat
8d1b1ff794 chore(npm): update package lock 2018-03-09 21:22:25 +00:00
SabreCat
70500d7c98 Merge branch 'release' into develop 2018-03-09 21:18:56 +00:00
Travis
35849ebdd7 Fixing items sort by number in the market. (#10108)
fixes #10093
2018-03-09 15:17:26 -06:00
Matteo Pagliazzi
1332fd68b0 Mongoose 5 (#9870)
* mongoose 5: remove unused autoinc, remove promise option (it uses native promises now)

* remove mongodb package

* remove mongoskin

* migrate migration away from mongoskin

* fix mongoose hooks

* fix _updateUserWithRetries

* try without next

* remove init

* update sinon

* fix some integration tests

* fix remaining tests

* fix error message

* fix error message

* fix error message

* another fix

* fix mongoose options

* remove greenkeeper exception
2018-03-09 15:13:58 -06:00
Travis
f9a47b1420 Update user pinned items on purchases. (#10085)
fixes #10049
2018-03-09 15:11:42 -06:00
Sabe Jones
090c571f3e 4.29.8 2018-03-09 21:04:14 +00:00
Dexx Mandele
07b3824c4c Stop market background from covering sign (#10067) 2018-03-09 14:59:45 -06:00
Sabe Jones
1bf3736198 chore(i18n): update locales 2018-03-09 20:58:12 +00:00
Travis
92fa6805eb fix: Quest collected items displayed multiple times. (#10111)
fixes #10065
2018-03-09 14:56:59 -06:00
SabreCat
d5efa7b2b0 fix(event): clean up more Valentine's content 2018-03-09 20:45:12 +00:00
Dexx Mandele
f64b34318f Set warrior as default for the choose class pop-up (#10084) 2018-03-09 14:40:53 -06:00
Sabe Jones
5e13a9c503 4.29.7 2018-03-09 03:31:53 +00:00
Sabe Jones
b27aec855c chore(event): end Cupid Potions 2018-03-09 03:31:39 +00:00
Sabe Jones
fe61c0f29e Merge branch 'release' into develop 2018-03-08 21:43:35 +00:00
Sabe Jones
2db3ac7bd3 4.29.6 2018-03-08 21:42:52 +00:00
SabreCat
201ec0e865 fix(world-boss): add achievement badge, correct mount positioning 2018-03-08 21:37:17 +00:00
Sabe Jones
a0253cf289 chore(i18n): update locales 2018-03-08 19:41:22 +00:00
SabreCat
5256569bac fix(world-boss): remove notification 2018-03-08 19:37:27 +00:00
Sabe Jones
5f0b957dc2 fix(logging): only start Stackimpact in prod (#10112) 2018-03-08 13:12:45 -06:00
Sabe Jones
16524d4464 4.29.5 2018-03-08 18:39:00 +00:00
SabreCat
63a11c6c28 chore(event): end Valentines/Dysheartener 2018-03-08 18:37:32 +00:00
Sabe Jones
37650ca674 Merge branch 'release' into develop 2018-03-08 00:30:37 +00:00
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
b4dab2e13c Merge branch 'release' into develop 2018-03-07 22:53:09 +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
b827b17481 Don't include seasonal class gear in classless category (#10047)
* fix(market): don't include seasonal class gear in classless category

* refactor(shops): use standard indexOf check
2018-03-06 11:03:49 -06:00
Sabe Jones
27ef187e66 Merge branch 'release' into develop 2018-03-05 20:59:17 +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
Keith Holliday
9c9b67aa9d Keys kennel fixes (#9848)
* Show keys to pets immediately

* Ensured keys to pets dissapear after use

* Added resdirect to stable after purchase

* Added mount check and updated keys to mounts and to both

* Added api calls

* Added check for beastmaster progress

* Added mount check for release mounts. Added pets and mount check to release both

* Added actions

* Added catch to common tests

* Added beast count and reload

* Removed extra console log
2018-03-02 15:30:11 -06:00
Keith Holliday
7cff331800 Removed uri for client side oauth (#10058)
* Removed uri for client side oauth

* Fixed lint
2018-03-02 14:07:15 -07:00
Keith Holliday
e7bc505b88 Modal popup fixes (#10080)
* Added validation for modal stack

* Lint fixes
2018-03-02 12:43:22 -07: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
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
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
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
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
1689 changed files with 65371 additions and 51112 deletions

View File

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

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/*

View File

@@ -4,6 +4,7 @@ node_modules/**
.bower-registry/**
website/client-old/**
website/client/**
website/client/store/**
website/views/**
website/build/**
dist/**

2
.nvmrc
View File

@@ -1 +1 @@
6
8

View File

@@ -1,13 +1,13 @@
language: node_js
node_js:
- '6'
- '8'
services:
- mongodb
cache:
directories:
- 'node_modules'
before_install:
- npm install -g npm@5
addons:
chrome: stable
before_script:
- npm run test:build
- cp config.json.example config.json
@@ -25,4 +25,5 @@ env:
- TEST="test:sanity"
- TEST="test:content" COVERAGE=true
- TEST="test:common" COVERAGE=true
- TEST="client:unit" COVERAGE=true
- TEST="apidoc"

View File

@@ -1,10 +1,7 @@
FROM node:boron
FROM node:8
# Upgrade NPM to v5 (Yarn is needed because of this bug https://github.com/npm/npm/issues/16807)
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
RUN yarn global add npm@5
# Install global packages
RUN npm install -g gulp mocha
RUN npm install -g gulp-cli mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg

View File

@@ -1,4 +1,4 @@
FROM node:boron
FROM node:8
ENV ADMIN_EMAIL admin@habitica.com
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
@@ -11,16 +11,13 @@ ENV GOOGLE_CLIENT_ID 1035232791481-32vtplgnjnd1aufv3mcu1lthf31795fq.apps.googleu
ENV NODE_ENV production
ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
# Upgrade NPM to v5 (Yarn is needed because of this bug https://github.com/npm/npm/issues/16807)
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
RUN yarn global add npm@5
# Install global packages
RUN npm install -g gulp-cli mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
WORKDIR /usr/src/habitrpg
RUN git clone --branch v4.26.2 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN git clone --branch v4.40.1 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN npm install
RUN gulp build:prod --force

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.

View File

@@ -98,12 +98,20 @@
},
"ITUNES_SHARED_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"EMAILS" : {
"COMMUNITY_MANAGER_EMAIL" : "leslie@habitica.com",
"COMMUNITY_MANAGER_EMAIL" : "admin@habitica.com",
"TECH_ASSISTANCE_EMAIL" : "admin@habitica.com",
"PRESS_ENQUIRY_EMAIL" : "leslie@habitica.com"
"PRESS_ENQUIRY_EMAIL" : "admin@habitica.com"
},
"LOGGLY" : {
"TOKEN" : "example-token",
"SUBDOMAIN" : "exmaple-subdomain"
}
},
"KAFKA": {
"GROUP_ID": "",
"CLOUDKARAFKA_BROKERS": "",
"CLOUDKARAFKA_USERNAME": "",
"CLOUDKARAFKA_PASSWORD": "",
"CLOUDKARAFKA_TOPIC_PREFIX": ""
},
"STACK_IMPACT_KEY": "aaaabbbbccccddddeeeeffffgggg111100002222"
}

View File

@@ -26,7 +26,6 @@ let improveRepl = (context) => {
const mongooseOptions = !isProd ? {} : {
keepAlive: 1,
connectTimeoutMS: 30000,
useMongoClient: true,
};
mongoose.connect(
nconf.get('NODE_DB_URI'),

View File

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

7
migrations/.eslintrc Normal file
View File

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

View File

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

View File

@@ -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 }
}
);
});

View File

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

View File

@@ -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);
}
})

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
}
)
})

View File

@@ -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});
})

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);
}
}
})

View File

@@ -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);
}
})

View File

@@ -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);
}
})

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);
}
})

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);
}
}
})
})

View File

@@ -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);
}
}
})

View File

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

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}
)

View File

@@ -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 }
})

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} )

View File

@@ -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);
}
})

View File

@@ -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}});
});

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!");
});

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);
}
});

View File

@@ -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}});
});

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}});
});

View File

@@ -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)} });
});

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}});
});

View File

@@ -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}
})
})

View File

@@ -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}
)

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}});
});

View File

@@ -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} });
});

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);
});

View File

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

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}});
});

View File

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

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!");
})
});
});

View File

@@ -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');
})
});

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');
})
});

View File

@@ -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}});
});

View File

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

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})

View File

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

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);
});*/

View File

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

View File

@@ -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}
);
});

View File

@@ -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}});
});

View File

@@ -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');
});

View File

@@ -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);
}

View File

@@ -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);
}

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}
);

View File

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

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}
)

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});

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}
)

View File

@@ -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}
);

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);
}

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}
)

View File

@@ -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);
}

View File

@@ -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);
}

View File

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

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})

View File

@@ -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);
}

View File

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

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);
}

View File

@@ -1,5 +0,0 @@
db.users.update(
{},
{$set:{'items.mounts.Gryphon-RoyalPurple':true}},
{multi:true}
);

View File

@@ -1,5 +0,0 @@
db.users.update(
{'items.pets.Wolf-Veteran':{$ne:null}},
{$set:{'items.pets.Tiger-Veteran':5}},
{multi:true}
);

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}
);

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();

View File

@@ -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();

View File

@@ -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);
});

View File

@@ -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);
});
});
});

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);
}

View File

@@ -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();

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);
}

View File

@@ -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);
}

View File

@@ -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);
}

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);
}

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);
}

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);
}

View File

@@ -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;
});

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);
}

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);
}

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);
}

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);
}

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);
}

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);
}

View File

@@ -1,74 +0,0 @@
var migrationName = '20161122_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
/*
* Yearly Turkey Day award. Turkey pet, Turkey mount, Gilded Turkey pet, Gilded Turkey mount
*/
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-10-31')} // 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 = {
'migration': 1,
'items.mounts': 1,
'items.pets': 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 (user.items.pets['Turkey-Gilded']) {
set = {'migration':migrationName, 'items.mounts.Turkey-Gilded':true};
} else 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);
}

View File

@@ -1,73 +0,0 @@
var migrationName = '20161230_nye_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
/*
* Yearly New Year's party hat award
*/
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-11-30')} // Remove after first run
};
// 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_nye2015 !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.head_special_nye2016':false};
} else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') {
set = {'migration':migrationName, 'items.gear.owned.head_special_nye2015':false};
} else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') {
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);
}

View File

@@ -1,113 +0,0 @@
var migrationName = '20170120_missing_incentive.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 missing Royal Purple Hatching Potion to users with 55+ check-ins
* Reduce users with impossible check-in counts to a reasonable number
*/
import monk from 'monk';
import common from '../website/common';
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers(lastId) {
// specify a query to limit the affected users (empty for all users):
var query = {
'loginIncentives': {$gt:54},
'migration': {$ne: migrationName},
};
if (lastId) {
query._id = {
$gt: lastId
}
}
dbUsers.find(query, {
sort: {_id: 1},
limit: 250,
fields: [] // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch(function (err) {
console.log(err);
return exiting(1, 'ERROR! ' + err);
});
}
var progressCount = 1000;
var count = 0;
function updateUsers (users) {
if (!users || users.length === 0) {
console.warn('All appropriate users found and modified.');
displayData();
return;
}
var userPromises = users.map(updateUser);
var lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(function () {
processUsers(lastUser._id);
});
}
function updateUser (user) {
count++;
var language = user.preferences.language || 'en';
var set = {'migration': migrationName};
var inc = {'items.hatchingPotions.RoyalPurple': 1};
if (user.loginIncentives > 58) {
set = {'migration': migrationName, 'loginIncentives': 58};
}
var push = {
'notifications': {
'type': 'LOGIN_INCENTIVE',
'data': {
'nextRewardAt': 60,
'rewardKey': [
'Pet_HatchingPotion_Purple',
],
'rewardText': common.i18n.t('potion', {potionType: common.i18n.t('hatchingPotionRoyalPurple', language)}, language),
'reward': [
{
'premium': true,
'key': 'RoyalPurple',
'limited': true,
'value': 2,
}
],
'message': common.i18n.t('unlockedCheckInReward', language),
},
'id': common.uuid(),
}
};
dbUsers.update({_id: user._id}, {$set:set, $push:push, $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);
}
module.exports = processUsers;

View File

@@ -1,109 +0,0 @@
var migrationName = '20170131_habit_birthday.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 2017 party robes if user has 2016 robes, 2016 robes if they have the 2015 robes,
* 2015 robes if they have the 2014 robes, and 2014 robes otherwise. Also cake!
*/
var monk = require('monk');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers(lastId) {
// specify a query to limit the affected users (empty for all users):
var query = {
'migration':{$ne:migrationName},
'auth.timestamps.loggedin':{$gt:new Date('2017-01-24')}, // remove after first run to cover remaining users
};
if (lastId) {
query._id = {
$gt: lastId
}
}
dbUsers.find(query, {
sort: {_id: 1},
limit: 250,
fields: [ // specify fields we are interested in to limit retrieved data (empty if we're not reading data)
'items.gear.owned'
],
})
.then(updateUsers)
.catch(function (err) {
console.log(err);
return exiting(1, 'ERROR! ' + err);
});
}
var progressCount = 1000;
var count = 0;
function updateUsers (users) {
if (!users || users.length === 0) {
console.warn('All appropriate users found and modified.');
displayData();
return;
}
var userPromises = users.map(updateUser);
var lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(function () {
processUsers(lastUser._id);
});
}
function updateUser (user) {
count++;
var set = {'migration':migrationName};
if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('armor_special_birthday2016')) {
set['items.gear.owned.armor_special_birthday2017'] = false;
} else if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('armor_special_birthday2015')) {
set['items.gear.owned.armor_special_birthday2016'] = false;
} else if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('armor_special_birthday')) {
set['items.gear.owned.armor_special_birthday2015'] = false;
} else {
set['items.gear.owned.armor_special_birthday'] = false;
}
var inc = {
'items.food.Cake_Skeleton':1,
'items.food.Cake_Base':1,
'items.food.Cake_CottonCandyBlue':1,
'items.food.Cake_CottonCandyPink':1,
'items.food.Cake_Shade':1,
'items.food.Cake_White':1,
'items.food.Cake_Golden':1,
'items.food.Cake_Zombie':1,
'items.food.Cake_Desert':1,
'items.food.Cake_Red':1,
'achievements.habitBirthdays':1
};
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);
}
module.exports = processUsers;

View File

@@ -1,88 +0,0 @@
var migrationName = '20170418_subscriber_jackalopes.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 Jackalope pet to all current subscribers
*/
var monk = require('monk');
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = monk(connectionString).get('users', { castIds: false });
var now = new Date();
function processUsers(lastId) {
// specify a query to limit the affected users (empty for all users):
var query = {
'purchased.plan.customerId': {$type: 2},
$or: [
{'purchased.plan.dateTerminated': null},
{'purchased.plan.dateTerminated': {$exists: false}},
{'purchased.plan.dateTerminated': {$gt: now}},
]
};
if (lastId) {
query._id = {
$gt: lastId
}
}
dbUsers.find(query, {
sort: {_id: 1},
limit: 250,
fields: [] // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch(function (err) {
console.log(err);
return exiting(1, 'ERROR! ' + err);
});
}
var progressCount = 1000;
var count = 0;
function updateUsers (users) {
if (!users || users.length === 0) {
console.warn('All appropriate users found and modified.');
displayData();
return;
}
var userPromises = users.map(updateUser);
var lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(function () {
processUsers(lastUser._id);
});
}
function updateUser (user) {
count++;
var set = {'items.pets.Jackalope-RoyalPurple': 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);
}
module.exports = processUsers;

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