Merge pull request #1831 from snicker/develop

data exporting support, supports exporting task history via csv
This commit is contained in:
Tyler Renelle
2013-11-15 17:25:46 -08:00
8 changed files with 101 additions and 4 deletions
+2 -1
View File
@@ -42,7 +42,8 @@
"validator": "~1.5.1",
"nodemailer": "~0.5.2",
"grunt-cli": "~0.1.9",
"paypal-ipn": "~1.0.1"
"paypal-ipn": "~1.0.1",
"express-csv": "~0.6.0"
},
"private": true,
"subdomain": "habitrpg",
+13
View File
@@ -31,6 +31,7 @@ window.habitrpg = angular.module('habitrpg',
.when('/options/groups/guilds', '/options/groups/guilds/public')
.when('/options/inventory', '/options/inventory/inventory')
.when('/options/inventory/stable', '/options/inventory/stable/pets')
.when('/options/settings', '/options/settings/settings')
// redirect states that don't match
.otherwise("/tasks");
@@ -161,6 +162,18 @@ window.habitrpg = angular.module('habitrpg',
controller: 'SettingsCtrl',
templateUrl: "partials/options.settings.html"
})
.state('options.settings.settings', {
url: "/settings",
templateUrl: "partials/options.settings.settings.html"
})
.state('options.settings.api', {
url: "/api",
templateUrl: "partials/options.settings.api.html"
})
.state('options.settings.export', {
url: "/export",
templateUrl: "partials/options.settings.export.html"
})
// Options > Settings
.state('options.admin', {
+15 -1
View File
@@ -13,6 +13,7 @@ var api = module.exports;
var NO_TOKEN_OR_UID = { err: "You must include a token and uid (user id) in your request"};
var NO_USER_FOUND = {err: "No user found."};
var NO_SESSION_FOUND = { err: "You must be logged in." };
/*
beforeEach auth interceptor
@@ -40,6 +41,19 @@ api.auth = function(req, res, next) {
});
};
api.authWithSession = function(req, res, next) { //[todo] there is probably a more elegant way of doing this...
var uid;
uid = req.session.userId;
if (!(req.session && req.session.userId)) {
return res.json(401, NO_SESSION_FOUND);
}
return User.findOne({_id: uid,}, function(err, user) {
if (err) return res.json(500, {err: err});
if (_.isEmpty(user)) return res.json(401, NO_USER_FOUND);
res.locals.user = user;
return next();
});
};
api.registerUser = function(req, res, next) {
var confirmPassword, e, email, password, username, _ref;
@@ -263,4 +277,4 @@ api.setupPassport = function(router) {
// if (req.isAuthenticated()) { return next(); }
// res.redirect('/login')
// }
};
};
+27
View File
@@ -0,0 +1,27 @@
var _ = require('lodash');
var csv = require('express-csv');
var nconf = require('nconf');
var moment = require('moment');
var dataexport = module.exports;
/*
------------------------------------------------------------------------
Data export
------------------------------------------------------------------------
*/
dataexport.history = function(req, res) {
var user = res.locals.user;
var output = [
["Task Name", "Task ID", "Task Type", "Date", "Value"]
];
_.each(user.tasks, function(task) {
_.each(task.history, function(history) {
output.push(
[task.text, task.id, task.type, moment(history.date).format("MM-DD-YYYY HH:mm:ss"), history.value]
);
});
});
return res.csv(output);
}
+4
View File
@@ -4,6 +4,7 @@ var user = require('../controllers/user');
var groups = require('../controllers/groups');
var auth = require('../controllers/auth');
var challenges = require('../controllers/challenges');
var dataexport = require('../controllers/dataexport');
var nconf = require('nconf');
/*
@@ -25,6 +26,9 @@ router.get('/status', function(req, res) {
});
});
/* Data export */
router.get('/export/history',auth.auth,dataexport.history); //[todo] encode data output options in the data controller and use these to build routes
/* Scoring*/
router.post('/user/task/:id/:direction', auth.auth, cron, user.scoreTask);
router.post('/user/tasks/:id/:direction', auth.auth, cron, user.scoreTask);
+10
View File
@@ -0,0 +1,10 @@
var express = require('express');
var router = new express.Router();
var dataexport = require('../controllers/dataexport');
var auth = require('../controllers/auth');
var nconf = require('nconf');
/* Data export */
router.get('/history.csv',auth.authWithSession,dataexport.history); //[todo] encode data output options in the data controller and use these to build routes
module.exports = router;
+1
View File
@@ -114,6 +114,7 @@ if ("development" === app.get("env")) {
app.use(require('./routes/pages').middleware);
app.use(require('./routes/auth').middleware);
app.use('/api/v1', require('./routes/api').middleware);
app.use('/export', require('./routes/dataexport').middleware);
app.use(require('./controllers/deprecated').middleware);
server = http.createServer(app).listen(app.get("port"), function() {
return console.log("Express server listening on port " + app.get("port"));
+29 -2
View File
@@ -1,6 +1,22 @@
script(type='text/ng-template', id='partials/options.settings.html')
script(id='partials/options.settings.html', type="text/ng-template")
ul.nav.nav-tabs
li(ng-class="{ active: $state.includes('options.settings.settings') }")
a(ui-sref='options.settings.settings')
| Settings
li(ng-class="{ active: $state.includes('options.settings.api') }")
a(ui-sref='options.settings.api')
| API
li(ng-class="{ active: $state.includes('options.settings.export') }")
a(ui-sref='options.settings.export')
| Data Export
.tab-content
.tab-pane.active
div(ui-view)
script(type='text/ng-template', id='partials/options.settings.settings.html')
.row-fluid
.personal-options.span6.border-right
.personal-options.span6
h2 Settings
h4 Custom Day Start
.option-group.option-short
@@ -36,6 +52,9 @@ script(type='text/ng-template', id='partials/options.settings.html')
a.btn.btn-danger(ng-click='modals.reset = true', tooltip='Resets your entire account (dangerous).') Reset
a.btn.btn-danger(ng-click='modals.restore = true', tooltip='Restores attributes to your character.') Restore
a.btn.btn-danger(ng-click='modals.delete = true', tooltip='Delete your account.') Delete
script(type='text/ng-template', id='partials/options.settings.api.html')
.row.fluid
.span6
h2 API
small Copy these for use in third party applications.
@@ -45,3 +64,11 @@ script(type='text/ng-template', id='partials/options.settings.html')
pre.prettyprint {{user.apiToken}}
h6 QR Code
img(src='https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=%7Baddress%3A%22https%3A%2F%2Fhabitrpg.com%22%2Cuser%3A%22{{user.id}}%22%2Ckey%3A%22{{user.apiToken}}%22%7D,&choe=UTF-8&chld=L', alt='qrcode')
script(id='partials/options.settings.export.html', type="text/ng-template")
.row.fluid
.span6
h2 Data Export
small Here are a few options for saving your Habit data.
h4 Habit History
a(href="/export/history.csv") Export History (CSV)