Fix events stuff with awful hacks

This commit is contained in:
Jonathan Cremin 2015-08-08 20:37:49 +01:00
parent b48a4e92e1
commit ab49c181e7
8 changed files with 60 additions and 52 deletions

View file

@ -129,6 +129,7 @@ app.use(auth);
app.use(route.get('/user', user.get)); app.use(route.get('/user', user.get));
app.use(route.get('/user/token', user.token)); app.use(route.get('/user/token', user.token));
app.use(route.get('/token', user.token));
app.use(route.get('/user/transaction', user.transaction)); app.use(route.get('/user/transaction', user.transaction));
app.use(route.post('/user/settings', user.settings)); app.use(route.post('/user/settings', user.settings));
app.use(route.get('/file', file.list)); app.use(route.get('/file', file.list));

View file

@ -15,7 +15,7 @@ const debug = debugname('hostr-api:file');
const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379'; const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379';
const fileHost = process.env.FILE_HOST || 'https://localhost:4040'; const fileHost = process.env.FILE_HOST || 'http://localhost:4040';
const storePath = process.env.STORE_PATH || path.join(process.env.HOME, '.hostr', 'uploads'); const storePath = process.env.STORE_PATH || path.join(process.env.HOME, '.hostr', 'uploads');
@ -105,7 +105,7 @@ export function* post(next) {
percentComplete = Math.floor(receivedSize * 100 / expectedSize); percentComplete = Math.floor(receivedSize * 100 / expectedSize);
if (percentComplete > lastPercent && lastTick < Date.now() - 1000) { if (percentComplete > lastPercent && lastTick < Date.now() - 1000) {
const progressEvent = `{type: 'file-progress', data: {id: ${fileId}, complete: ${percentComplete}}}`; const progressEvent = `{"type": "file-progress", "data": {"id": "${fileId}", "complete": ${percentComplete}}}`;
this.redis.publish('/file/' + fileId, progressEvent); this.redis.publish('/file/' + fileId, progressEvent);
this.redis.publish('/user/' + this.user.id, progressEvent); this.redis.publish('/user/' + this.user.id, progressEvent);
lastTick = Date.now(); lastTick = Date.now();
@ -116,10 +116,10 @@ export function* post(next) {
}); });
// Fire an event to let the frontend map the GUID it sent to the real ID. Allows immediate linking to the file // Fire an event to let the frontend map the GUID it sent to the real ID. Allows immediate linking to the file
let acceptedEvent = `{type: 'file-accepted', data: {id: ${fileId}, guid: ${tempGuid}, href: ${fileHost}/${fileId}}}`; let acceptedEvent = `{"type": "file-accepted", "data": {"id": "${fileId}", "guid": "${tempGuid}", "href": "${fileHost}/${fileId}"}}`;
this.redis.publish('/user/' + this.user.id, acceptedEvent); this.redis.publish('/user/' + this.user.id, acceptedEvent);
// Fire final upload progress event so users know it's now processing // Fire final upload progress event so users know it's now processing
const completeEvent = `{type: 'file-progress', data: {id: ${fileId}, complete: 100}}`; const completeEvent = `{"type": "file-progress", "data": {"id": "${fileId}", "complete": 100}}`;
this.redis.publish('/file/' + fileId, completeEvent); this.redis.publish('/file/' + fileId, completeEvent);
this.redis.publish('/user/' + this.user.id, completeEvent); this.redis.publish('/user/' + this.user.id, completeEvent);
@ -160,7 +160,7 @@ export function* post(next) {
yield Files.updateOne({_id: fileId}, {$set: dbFile}); yield Files.updateOne({_id: fileId}, {$set: dbFile});
// Fire upload complete event // Fire upload complete event
const addedEvent = `{type: 'file-added', data: ${formattedFile}}`; const addedEvent = `{"type": "file-added", "data": ${JSON.stringify(formattedFile)}}`;
this.redis.publish('/file/' + fileId, addedEvent); this.redis.publish('/file/' + fileId, addedEvent);
this.redis.publish('/user/' + this.user.id, addedEvent); this.redis.publish('/user/' + this.user.id, addedEvent);
this.status = 201; this.status = 201;
@ -246,14 +246,14 @@ export function* del(id) {
export function* events() { export function* events() {
const pubsub = redis.connect(redisUrl); const pubsub = redis.connect(redisUrl);
pubsub.on('ready', function() { pubsub.on('ready', () => {
pubsub.subscribe(this.path); pubsub.subscribe(this.path);
}.bind(this)); });
pubsub.on('message', function(channel, message) { pubsub.on('message', (channel, message) => {
this.websocket.send(message); this.websocket.send(message);
}.bind(this)); });
this.on('close', function() { this.websocket.on('close', function() {
pubsub.quit(); pubsub.quit();
}); });
} }

View file

@ -4,7 +4,7 @@ import co from 'co';
import passwords from 'passwords'; import passwords from 'passwords';
import debugname from 'debug'; import debugname from 'debug';
const debug = debugname('hostr-api:file'); const debug = debugname('hostr-api:user');
const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379'; const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379';
@ -57,10 +57,10 @@ export function* settings() {
export function* events() { export function* events() {
const pubsub = redis.connect(redisUrl); const pubsub = redis.connect(redisUrl);
pubsub.on('message', function(channel, message) { pubsub.on('message', (channel, message) => {
this.websocket.send(message); this.websocket.send(message);
}.bind(this)); });
pubsub.on('ready', function () { pubsub.on('ready', () => {
this.websocket.on('message', co.wrap(function* (message) { this.websocket.on('message', co.wrap(function* (message) {
let json; let json;
try{ try{
@ -76,9 +76,9 @@ export function* events() {
} else { } else {
this.websocket.send('Invalid authentication token.'); this.websocket.send('Invalid authentication token.');
} }
})); }.bind(this)));
}.bind(this)); });
this.on('close', function() { this.websocket.on('close', () => {
debug('Socket closed'); debug('Socket closed');
pubsub.quit(); pubsub.quit();
}); });

38
app.js
View file

@ -1,7 +1,14 @@
import koa from 'koa'; import koa from 'koa';
import mount from 'koa-mount'; import mount from 'koa-mount';
import route from 'koa-route';
import websockify from 'koa-websocket';
import redis from 'redis-url';
import coRedis from 'co-redis';
import co from 'co';
import spdy from 'spdy'; import spdy from 'spdy';
import api from './api/app'; import api from './api/app';
import { events as fileEvents } from './api/routes/file';
import { events as userEvents } from './api/routes/user';
import web from './web/app'; import web from './web/app';
import { init as storageInit } from './lib/storage'; import { init as storageInit } from './lib/storage';
@ -10,26 +17,37 @@ const debug = debugname('hostr');
storageInit(); storageInit();
const app = koa(); const app = websockify(koa());
app.keys = [process.env.KEYS || 'INSECURE']; app.keys = [process.env.KEYS || 'INSECURE'];
const redisUrl = process.env.REDIS_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379';
let coRedisConn = {};
co(function*() {
coRedisConn = coRedis(redis.connect(redisUrl));
coRedisConn.on('error', function (err) {
debug('Redis error ' + err);
});
}).catch(function(err) {
console.error(err);
});
app.ws.use(function*(next) {
this.redis = coRedisConn;
yield next;
});
app.ws.use(route.all('/api/user', userEvents));
app.ws.use(route.all('/api/file/:id', fileEvents));
app.use(mount('/api', api)); app.use(mount('/api', api));
app.use(mount('/', web)); app.use(mount('/', web));
if (!module.parent) { if (!module.parent) {
if (process.env.LOCALHOST_KEY) {
spdy.createServer({
key: process.env.LOCALHOST_KEY,
cert: process.env.LOCALHOST_CRT
}, app.callback()).listen(4040, function() {
debug('Koa SPDY server listening on port ' + (process.env.PORT || 4040));
});
} else {
app.listen(process.env.PORT || 4040, function() { app.listen(process.env.PORT || 4040, function() {
debug('Koa HTTP server listening on port ' + (process.env.PORT || 4040)); debug('Koa HTTP server listening on port ' + (process.env.PORT || 4040));
}); });
}
} }
module.exports = app; module.exports = app;

View file

@ -17,13 +17,13 @@
"jspm": "jspm install", "jspm": "jspm install",
"start": "npm run build && node -r 'babel/register' app.js", "start": "npm run build && node -r 'babel/register' app.js",
"test": "mongo hostr test/fixtures/mongo-user.js test/fixtures/mongo-file.js && mocha -r babel/register test/api test/web", "test": "mongo hostr test/fixtures/mongo-user.js test/fixtures/mongo-file.js && mocha -r babel/register test/api test/web",
"watch": "nodemon -x \"node -r 'babel/register'\" -i web/public/ app.js", "watch": "nodemon -x \"node -r 'babel/register'\" app.js",
"watch-js": "babel -D -w -m system -d web/public/build web/public/src", "watch-js": "babel -D -w -m system -d web/public/build web/public/src",
"watch-sass": "node-sass -w -r -o web/public/styles/ web/public/styles/" "watch-sass": "node-sass -w -r -o web/public/styles/ web/public/styles/"
}, },
"dependencies": { "dependencies": {
"aws-sdk": "~2.1.42", "aws-sdk": "~2.1.44",
"babel": "~5.8.20", "babel": "~5.8.21",
"basic-auth": "~1.0.3", "basic-auth": "~1.0.3",
"co": "~4.6.0", "co": "~4.6.0",
"co-busboy": "~1.3.0", "co-busboy": "~1.3.0",
@ -61,13 +61,13 @@
"redis-url": "~1.2.1", "redis-url": "~1.2.1",
"s3-upload-stream": "^1.0.7", "s3-upload-stream": "^1.0.7",
"spdy": "~1.32.4", "spdy": "~1.32.4",
"stripe": "~3.6.0", "stripe": "^3.7.0",
"supertest": "~1.0.1", "supertest": "~1.0.1",
"swig": "^1.4.2", "swig": "^1.4.2",
"virustotal.js": "~0.3.1" "virustotal.js": "~0.3.1"
}, },
"devDependencies": { "devDependencies": {
"eslint": "~1.0.0", "eslint": "~1.1.0",
"istanbul": "^0.3.17", "istanbul": "^0.3.17",
"mocha": "~2.2.5", "mocha": "~2.2.5",
"nodemon": "~1.4.0", "nodemon": "~1.4.0",

View file

@ -1,5 +1,4 @@
import path from 'path'; import path from 'path';
import spdy from 'spdy';
import koa from 'koa'; import koa from 'koa';
import route from 'koa-route'; import route from 'koa-route';
import views from 'koa-views'; import views from 'koa-views';
@ -153,18 +152,9 @@ app.use(route.get('/updaters/mac/changelog', function() {
})); }));
if (!module.parent) { if (!module.parent) {
if (process.env.LOCALHOST_KEY) {
spdy.createServer({
key: process.env.LOCALHOST_KEY,
cert: process.env.LOCALHOST_CRT
}, app.callback()).listen(4041, function() {
debug('Koa SPDY server listening on port ' + (process.env.PORT || 4041));
});
} else {
app.listen(process.env.PORT || 4041, function() { app.listen(process.env.PORT || 4041, function() {
debug('Koa HTTP server listening on port ' + (process.env.PORT || 4041)); debug('Koa HTTP server listening on port ' + (process.env.PORT || 4041));
}); });
}
} }
export default app; export default app;

View file

@ -22,7 +22,7 @@ var app = angular.module('hostr', [
app.factory('FileService', ['$resource', '$cacheFactory', FileService.factory]); app.factory('FileService', ['$resource', '$cacheFactory', FileService.factory]);
app.factory('UserService', ['$resource', UserService.factory]); app.factory('UserService', ['$resource', UserService.factory]);
app.factory('EventService', ['$rootScope', ReconnectingWebSocket, EventService.factory]); app.factory('EventService', ['$rootScope', 'WebSocket', EventService.factory]);
app.factory('TransactionService', ['$resource', '$cacheFactory', TransactionService.factory]); app.factory('TransactionService', ['$resource', '$cacheFactory', TransactionService.factory]);
app.factory('SettingService', ['$http', SettingService.factory]); app.factory('SettingService', ['$http', SettingService.factory]);
@ -38,7 +38,6 @@ app.directive('searchShortcut', ['$document', searchShortcut]);
app.directive('stripeSubscribe', ['$http', stripeSubscribe]); app.directive('stripeSubscribe', ['$http', stripeSubscribe]);
app.config(['$routeProvider', '$locationProvider', '$httpProvider', '$tooltipProvider', function($routeProvider, $locationProvider, $httpProvider, $tooltipProvider) { app.config(['$routeProvider', '$locationProvider', '$httpProvider', '$tooltipProvider', function($routeProvider, $locationProvider, $httpProvider, $tooltipProvider) {
$tooltipProvider.defaults.template = '/jspm_packages/npm/angular-strap@2.1.2/src/tooltip/tooltip.tpl.html'; $tooltipProvider.defaults.template = '/jspm_packages/npm/angular-strap@2.1.2/src/tooltip/tooltip.tpl.html';
if (typeof window.user !== 'undefined') { if (typeof window.user !== 'undefined') {

View file

@ -1,5 +1,5 @@
export class FilesController { export class FilesController {
constructor($scope, UserService, files) { constructor($scope, UserService, EventService, files) {
$scope.$root.user = UserService.get(); $scope.$root.user = UserService.get();
files.$promise.then(function() { files.$promise.then(function() {
$scope.$root.loadingView = false; $scope.$root.loadingView = false;
@ -22,7 +22,7 @@ export class FilesController {
}; };
} }
} }
FilesController.$inject = ['$scope', 'UserService', 'files']; FilesController.$inject = ['$scope', 'UserService', 'EventService', 'files'];
export class FileController { export class FileController {
constructor ($scope, $rootScope, $routeParams, ReconnectingWebSocket, file) { constructor ($scope, $rootScope, $routeParams, ReconnectingWebSocket, file) {