mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-05-26 07:31:50 +00:00
add preen_history to user cron (see
https://github.com/HabitRPG/habitrpg/issues/1492), to cut back on user object sizes (and hopefully angular performance) dramatically. Start writing tests, but they're not complete. @djuretic could you take a peak at this? My brain is melting
This commit is contained in:
parent
f0cc17bfaf
commit
5482a83a00
3 changed files with 177 additions and 2 deletions
73
dist/habitrpg-shared.js
vendored
73
dist/habitrpg-shared.js
vendored
|
|
@ -8131,7 +8131,7 @@ if(typeof module != 'undefined' && module.exports){
|
|||
|
||||
},{}],5:[function(require,module,exports){
|
||||
(function() {
|
||||
var HP, XP, hatchingPotions, helpers, items, moment, obj, pets, randomDrop, updateStats, _, _ref,
|
||||
var HP, XP, hatchingPotions, helpers, items, moment, obj, pets, preenHistory, randomDrop, updateStats, _, _ref,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
moment = require('moment');
|
||||
|
|
@ -8675,9 +8675,74 @@ if(typeof module != 'undefined' && module.exports){
|
|||
value: expTally
|
||||
});
|
||||
paths["history"] = true;
|
||||
obj.preenUserHistory(user);
|
||||
return user;
|
||||
};
|
||||
|
||||
/*
|
||||
Preen history for users with > 7 history entries
|
||||
This takes an infinite array of single day entries [day day day day day...], and turns it into a condensed array
|
||||
of averages, condensing more the further back in time we go. Eg, 7 entries each for last 7 days; 1 entry each week
|
||||
of this month; 1 entry for each month of this year; 1 entry per previous year: [day*7 week*4 month*12 year*infinite]
|
||||
*/
|
||||
|
||||
|
||||
preenHistory = function(history) {
|
||||
var newHistory, preen, thisMonth;
|
||||
history = _.filter(history, function(h) {
|
||||
return !!h;
|
||||
});
|
||||
newHistory = [];
|
||||
preen = function(amount, groupBy) {
|
||||
var groups;
|
||||
groups = _.chain(history).groupBy(function(h) {
|
||||
return moment(h.date).format(groupBy);
|
||||
}).sortBy(function(h, k) {
|
||||
return k;
|
||||
}).value();
|
||||
groups = groups.slice(-amount);
|
||||
groups.pop();
|
||||
return _.each(groups, function(group) {
|
||||
newHistory.push({
|
||||
date: moment(group[0].date).toDate(),
|
||||
value: _.reduce(group, (function(m, obj) {
|
||||
return m + obj.value;
|
||||
}), 0) / group.length
|
||||
});
|
||||
return true;
|
||||
});
|
||||
};
|
||||
preen(50, "YYYY");
|
||||
preen(moment().format('MM'), "YYYYMM");
|
||||
thisMonth = moment().format('YYYYMM');
|
||||
newHistory = newHistory.concat(_.filter(history, function(h) {
|
||||
return moment(h.date).format('YYYYMM') === thisMonth;
|
||||
}));
|
||||
return newHistory;
|
||||
};
|
||||
|
||||
obj.preenUserHistory = function(user) {
|
||||
var minHistLen;
|
||||
minHistLen = 7;
|
||||
_.each(user.habits.concat(user.dailys), function(task) {
|
||||
var _ref1;
|
||||
if (((_ref1 = task.history) != null ? _ref1.length : void 0) > minHistLen) {
|
||||
task.history = preenHistory(task.history);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
_.defaults(user.history, {
|
||||
todos: [],
|
||||
exp: []
|
||||
});
|
||||
if (user.history.exp.length > minHistLen) {
|
||||
user.history.exp = preenHistory(user.history.exp);
|
||||
}
|
||||
if (user.history.todos.length > minHistLen) {
|
||||
return user.history.todos = preenHistory(user.history.todos);
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
|
||||
|
|
@ -8866,7 +8931,11 @@ var process=require("__browserify_process");(function() {
|
|||
weapon: 0,
|
||||
armor: 0,
|
||||
head: 0,
|
||||
shield: 0
|
||||
shield: 0,
|
||||
lastDrop: {
|
||||
date: +(new Date),
|
||||
count: 0
|
||||
}
|
||||
},
|
||||
preferences: {
|
||||
gender: 'm',
|
||||
|
|
|
|||
|
|
@ -436,4 +436,56 @@ obj.cron = (user, options={}) ->
|
|||
expTally += obj.tnl(lvl)
|
||||
(user.history.exp ?= []).push { date: now, value: expTally }
|
||||
paths["history"] = true
|
||||
obj.preenUserHistory(user) # we can probably start removing paths[...] stuff, no longer used by our app
|
||||
user
|
||||
|
||||
###
|
||||
Preen history for users with > 7 history entries
|
||||
This takes an infinite array of single day entries [day day day day day...], and turns it into a condensed array
|
||||
of averages, condensing more the further back in time we go. Eg, 7 entries each for last 7 days; 1 entry each week
|
||||
of this month; 1 entry for each month of this year; 1 entry per previous year: [day*7 week*4 month*12 year*infinite]
|
||||
###
|
||||
preenHistory = (history) ->
|
||||
history = _.filter(history, (h) -> !!h) # discard nulls (corrupted somehow)
|
||||
newHistory = []
|
||||
preen = (amount, groupBy) ->
|
||||
groups = _.chain(history)
|
||||
.groupBy((h) -> moment(h.date).format groupBy) # get date groupings to average against
|
||||
.sortBy((h, k) -> k) # sort by date
|
||||
.value() # turn into an array
|
||||
groups = groups.slice(-amount)
|
||||
groups.pop() # get rid of "this week", "this month", etc (except for case of days)
|
||||
_.each groups, (group) ->
|
||||
newHistory.push
|
||||
date: moment(group[0].date).toDate()
|
||||
#date: moment(group[0].date).format('MM/DD/YYYY') # Use this one when testing
|
||||
value: _.reduce(group, ((m, obj) -> m + obj.value), 0) / group.length # average
|
||||
true
|
||||
|
||||
# Keep the last:
|
||||
preen 50, "YYYY" # 50 years (habit will toootally be around that long!)
|
||||
preen moment().format('MM'), "YYYYMM" # last MM months (eg, if today is 05, keep the last 5 months)
|
||||
|
||||
# Then keep all days of this month. Note, the extra logic is to account for Habits, which can be counted multiple times per day
|
||||
# FIXME I'd rather keep 1-entry/week of this month, then last 'd' days in this week. However, I'm having issues where the 1st starts mid week
|
||||
thisMonth = moment().format('YYYYMM')
|
||||
newHistory = newHistory.concat _.filter(history, (h)-> moment(h.date).format('YYYYMM') is thisMonth)
|
||||
#preen Math.ceil(moment().format('D')/7), "YYYYww" # last __ weeks (# weeks so far this month)
|
||||
#newHistory = newHistory.concat(history.slice -moment().format('D')) # each day of this week
|
||||
|
||||
newHistory
|
||||
|
||||
# Registered users with some history
|
||||
obj.preenUserHistory = (user) ->
|
||||
minHistLen = 7
|
||||
_.each user.habits.concat(user.dailys), (task) ->
|
||||
task.history = preenHistory(task.history) if task.history?.length > minHistLen
|
||||
true
|
||||
|
||||
_.defaults user.history, {todos:[], exp: []}
|
||||
user.history.exp = preenHistory(user.history.exp) if user.history.exp.length > minHistLen
|
||||
user.history.todos = preenHistory(user.history.todos) if user.history.todos.length > minHistLen
|
||||
#user.markModified('history')
|
||||
#user.markModified('habits')
|
||||
#user.markModified('dailys')
|
||||
|
||||
|
|
|
|||
|
|
@ -221,6 +221,60 @@ describe 'Cron', ->
|
|||
afterTasks = after.habits.concat(after.dailys).concat(after.todos).concat(after.rewards)
|
||||
expect(beforeTasks).to.eql afterTasks
|
||||
|
||||
it.only 'should preen user history', ->
|
||||
{before,after} = beforeAfter({daysAgo:1})
|
||||
history = [
|
||||
# Last year should be condensed to one entry, avg: 1
|
||||
{date:'09/01/2012', value: 0}
|
||||
{date:'10/01/2012', value: 0}
|
||||
{date:'11/01/2012', value: 2}
|
||||
{date:'12/01/2012', value: 2}
|
||||
|
||||
# Each month of this year should be condensed to 1/mo, averages follow
|
||||
{date:'01/01/2013', value: 1} #2
|
||||
{date:'01/15/2013', value: 3}
|
||||
|
||||
{date:'02/01/2013', value: 2} #3
|
||||
{date:'02/15/2013', value: 4}
|
||||
|
||||
{date:'03/01/2013', value: 3} #4
|
||||
{date:'03/15/2013', value: 5}
|
||||
|
||||
{date:'04/01/2013', value: 4} #5
|
||||
{date:'04/15/2013', value: 6}
|
||||
|
||||
{date:'05/01/2013', value: 5} #6
|
||||
{date:'05/15/2013', value: 7}
|
||||
|
||||
{date:'06/01/2013', value: 6} #7
|
||||
{date:'06/15/2013', value: 8}
|
||||
|
||||
{date:'07/01/2013', value: 7} #8
|
||||
{date:'07/15/2013', value: 9}
|
||||
|
||||
{date:'08/01/2013', value: 8} #9
|
||||
{date:'08/15/2013', value: 10}
|
||||
|
||||
{date:'09/01/2013', value: 9} #10
|
||||
{date:'09/15/2013', value: 11}
|
||||
|
||||
{date:'010/01/2013', value: 10} #11
|
||||
{date:'010/15/2013', value: 12}
|
||||
|
||||
# This month should condense each week
|
||||
{date:'011/01/2013', value: 12}
|
||||
{date:'011/02/2013', value: 13}
|
||||
{date:'011/03/2013', value: 14}
|
||||
{date:'011/04/2013', value: 15}
|
||||
]
|
||||
after.history = {exp: _.cloneDeep(history), todos: _.cloneDeep(history)}
|
||||
after.habits[0].history = _.cloneDeep(history)
|
||||
algos.cron(after)
|
||||
console.log after.habits[0].history
|
||||
# _.each [after.history.exp, after.history.todos, after.habits[0].history], (arr) ->
|
||||
# expect(arr.length).to.be 15
|
||||
# expect(arr).to.eql [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
||||
|
||||
describe 'Todos', ->
|
||||
it '1 day missed', ->
|
||||
{before,after} = beforeAfter({daysAgo:1})
|
||||
|
|
|
|||
Loading…
Reference in a new issue