mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
complete preening and enable for challenges too
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
MAX_LEVEL,
|
||||
MAX_STAT_POINTS,
|
||||
} from './constants';
|
||||
import preenUserHistory from './preenUserHistory';
|
||||
import { preenHistory, preenUserHistory } from './preenUserHistory';
|
||||
import * as statHelpers from './statHelpers';
|
||||
|
||||
var $w, _, api, content, i18n, moment, sortOrder,
|
||||
@@ -32,6 +32,8 @@ api.maxHealth = MAX_HEALTH;
|
||||
api.tnl = statHelpers.toNextLevel;
|
||||
api.diminishingReturns = statHelpers.diminishingReturns;
|
||||
|
||||
api.preenHistory = preenHistory;
|
||||
|
||||
$w = api.$w = function(s) {
|
||||
return s.split(' ');
|
||||
};
|
||||
|
||||
@@ -1,68 +1,69 @@
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
/*
|
||||
Preen history for users and tasks. This code runs only on the server.
|
||||
// Aggregate entries
|
||||
function _aggregate (history, aggregateBy) {
|
||||
return _.chain(history)
|
||||
.groupBy(entry => { // group entries by aggregateBy
|
||||
return moment(entry.date).format(aggregateBy);
|
||||
})
|
||||
.sortBy((entry, key) => key) // sort by date
|
||||
.reverse() // sort from most to least recent
|
||||
.map(entries => {
|
||||
return {
|
||||
date: Number(entries[0].date),
|
||||
value: _.reduce(entries, (previousValue, entry) => {
|
||||
return previousValue + entry.value;
|
||||
}, 0) / entries.length,
|
||||
};
|
||||
})
|
||||
.value();
|
||||
}
|
||||
|
||||
Free users:
|
||||
- 1 value for each day of the past 60 days (no compression)
|
||||
- 1 value each month for the previous 10 months
|
||||
- 1 value each year for the previous years
|
||||
/* Preen an array of history entries
|
||||
|
||||
Subscribers:
|
||||
- 1 value for each day of the past 365 days (no compression)
|
||||
- 1 value each month for the previous 12 months
|
||||
- 1 value each year for the previous years
|
||||
Free users:
|
||||
- 1 value for each day of the past 60 days (no compression)
|
||||
- 1 value each month for the previous 10 months
|
||||
- 1 value each year for the previous years
|
||||
|
||||
Subscribers and challenges:
|
||||
- 1 value for each day of the past 365 days (no compression)
|
||||
- 1 value each month for the previous 12 months
|
||||
- 1 value each year for the previous years
|
||||
*/
|
||||
export function preenHistory (history, isSubscribed, timezoneOffset) {
|
||||
history = _.filter(history, historyEntry => Boolean(historyEntry)); // Filter missing entries
|
||||
let now = timezoneOffset ? moment().zone(timezoneOffset) : moment();
|
||||
// Date after which to begin compressing data
|
||||
let cutOff = now.subtract(isSubscribed ? 365 : 60, 'days').startOf('day');
|
||||
|
||||
|
||||
function _preenHistory (history, isSubscribed) {
|
||||
history = _.filter(history, historyEntry => return Boolean(historyEntry)); // Filter missing entries
|
||||
let newHistory = [];
|
||||
|
||||
// Steps
|
||||
// Take first 365 or 60 entries and keep them unmodified - only if of consecutive days? In the long term we want history to be continuous not with big jumps
|
||||
// Group the rest by month and keep 10 or 12
|
||||
// Group the rest by year
|
||||
|
||||
function _preen (amount, groupBy) {
|
||||
let groups = _.chain(history).groupBy(h => {
|
||||
return moment(h.date).format(groupBy);
|
||||
}).sortBy((h, k) => {
|
||||
return k;
|
||||
}).value();
|
||||
groups = groups.slice(-amount);
|
||||
groups.pop();
|
||||
|
||||
return _.each(groups, group => {
|
||||
newHistory.push({
|
||||
date: moment(group[0].date).toDate(),
|
||||
value: _.reduce(group, (m, obj) => {
|
||||
return m + obj.value;
|
||||
}, 0) / group.length,
|
||||
// Keep uncompressed entries (modifies history)
|
||||
let newHistory = _.remove(history, entry => {
|
||||
return moment(entry.date).isSameOrAfter(cutOff);
|
||||
});
|
||||
|
||||
// Date after which to begin compressing data by year
|
||||
let monthsCutOff = cutOff.subtract(isSubscribed ? 12 : 10, 'months').startOf('day');
|
||||
let aggregateByMonth = _.remove(history, entry => {
|
||||
return moment(entry.date).isSameOrAfter(monthsCutOff);
|
||||
});
|
||||
}
|
||||
|
||||
_preen(50, 'YYYY');
|
||||
_preen(moment().format('MM'), 'YYYYMM');
|
||||
|
||||
let thisMonth = moment().format('YYYYMM');
|
||||
newHistory = newHistory.concat(_.filter(history, h => {
|
||||
return moment(h.date).format('YYYYMM') === thisMonth;
|
||||
}));
|
||||
// Aggregate remaining entries by month and year
|
||||
newHistory.push(..._aggregate(aggregateByMonth, 'YYYYMM'));
|
||||
newHistory.push(..._aggregate(history, 'YYYY'));
|
||||
|
||||
return newHistory;
|
||||
}
|
||||
|
||||
export default function (user) {
|
||||
// Preen history for users and tasks. This code runs only on the server.
|
||||
export function preenUserHistory (user) {
|
||||
let isSubscribed = user.purchased && user.purchased.plan && user.purchased.plan.customerId;
|
||||
let minHistoryLength = isSubscribed ? 365 : 60;
|
||||
|
||||
_.each(user.habits.concat(user.dailys), (task, index) => {
|
||||
if (task.history && task.history.length > minHistoryLength) {
|
||||
task.history = _preenHistory(task.history, isSubscribed);
|
||||
user.markModified(`user.${task.type}s.${index}.history`);
|
||||
task.history = preenHistory(task.history, isSubscribed);
|
||||
if (user.markModified) user.markModified(`${task.type}s.${index}.history`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -72,12 +73,12 @@ export default function (user) {
|
||||
});
|
||||
|
||||
if (user.history.exp.length > minHistoryLength) {
|
||||
user.history.exp = _preenHistory(user.history.exp, isSubscribed);
|
||||
user.markModified('user.history.exp');
|
||||
user.history.exp = preenHistory(user.history.exp, isSubscribed);
|
||||
user.markModified('history.exp');
|
||||
}
|
||||
|
||||
if (user.history.todos.length > minHistoryLength) {
|
||||
user.history.todos = _preenHistory(user.history.todos, isSubscribed);
|
||||
user.markModified('user.history.todos');
|
||||
user.history.todos = preenHistory(user.history.todos, isSubscribed);
|
||||
user.markModified('history.todos');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preenUserHistory from '../../common/script/preenUserHistory'; // eslint-disable-line no-unused-vars
|
||||
import preenUserHistory from '../../common/script/preenUserHistory';
|
||||
|
||||
describe('preenUserHistory', () => {
|
||||
describe('preen tasks history', () => {
|
||||
|
||||
@@ -135,8 +135,14 @@ api.score = function(req, res, next) {
|
||||
}
|
||||
|
||||
t.value += delta;
|
||||
if (t.type == 'habit' || t.type == 'daily')
|
||||
if (t.type == 'habit' || t.type == 'daily') {
|
||||
t.history.push({value: t.value, date: +new Date});
|
||||
if (t.history.length > 365) {
|
||||
var tIndex = chal[`${t.type}`].indexOf(t);
|
||||
t.history = shared.preenHistory(t.history, true); // true means the challenge will retain as much entries as a subscribed user
|
||||
chal.markModified(`${t.type}s.${tIndex}.history`); // Setting habits/dailys as modified because we don't know the index of the task
|
||||
}
|
||||
}
|
||||
chal.save();
|
||||
clearMemory();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user