From aea2b8ff2532fe9bd07c2566f3031e7604e37028 Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Wed, 23 Mar 2016 19:38:59 +0300 Subject: [PATCH] data api with io --- package.json | 3 +- src/api/feed.js | 21 +++++++++++ src/{routes => }/api/index.js | 0 src/bin/www.js | 12 ------- src/client/app.js | 4 +-- src/client/components/Timeline.js | 26 ++++++-------- src/core/collective.js | 2 +- src/core/db.js | 60 ++++++++++--------------------- src/data/Data.js | 14 ++++++++ src/data/Feed.js | 34 ++++++++++++++++++ src/data/index.js | 5 +++ src/index.js | 21 +++++++++++ src/io.js | 24 +++++++++++++ src/models/collective.js | 2 +- src/models/menu.js | 2 +- src/routes/api/feed.js | 15 -------- src/routes/teachers.js | 2 +- src/server.js | 9 ++--- 18 files changed, 162 insertions(+), 94 deletions(-) create mode 100644 src/api/feed.js rename src/{routes => }/api/index.js (100%) delete mode 100644 src/bin/www.js create mode 100644 src/data/Data.js create mode 100644 src/data/Feed.js create mode 100644 src/data/index.js create mode 100644 src/index.js create mode 100644 src/io.js delete mode 100644 src/routes/api/feed.js diff --git a/package.json b/package.json index 47f2ec6f..7ad7c69e 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,10 @@ "koa-prerender": "^1.0.3", "koa-route": "^3.1.0", "koa-static": "^2.0.0", + "mongodb": "^2.1.11", "mz": "^2.3.1", - "promised-mongo": "git+https://git@github.com/tmshv/promised-mongo", "sitemap": "^1.5.0", + "socket.io": "^1.4.5", "thunkify": "^2.1.2" }, "devDependencies": { diff --git a/src/api/feed.js b/src/api/feed.js new file mode 100644 index 00000000..f309f2ce --- /dev/null +++ b/src/api/feed.js @@ -0,0 +1,21 @@ +import {put} from 'koa-route'; +import compose from 'koa-compose'; +import {ensureServiceAuth} from '../middlewares/ensureServiceAuth'; + +import data from '../data'; + +export function add() { + return put('/api/v1/feed', compose([ + ensureServiceAuth(), + async(ctx) => { + let post = ctx.request.body; + + try { + ctx.body = await data.feed.add(post); + } catch (e) { + ctx.status = 400; + ctx.body = e; + } + } + ])); +} diff --git a/src/routes/api/index.js b/src/api/index.js similarity index 100% rename from src/routes/api/index.js rename to src/api/index.js diff --git a/src/bin/www.js b/src/bin/www.js deleted file mode 100644 index 9cbba666..00000000 --- a/src/bin/www.js +++ /dev/null @@ -1,12 +0,0 @@ -require('babel-core/register'); -require('babel-polyfill'); - -var config = require("../config").default; -var db = require("../core/db"); -var server = require("../server").server; - -db.init(config.db.uri) - .then(function () { - var app = server(); - app.listen(config.port); - }); diff --git a/src/client/app.js b/src/client/app.js index 5812f461..44935daa 100644 --- a/src/client/app.js +++ b/src/client/app.js @@ -43,7 +43,7 @@ import UppercaseFirst from './filters/UppercaseFirst'; import Bytes from './filters/Bytes'; import Ext from './filters/Ext'; -// import IOService from './services/io'; +import IOService from './services/io'; import MenuService from './services/menu'; import API from './services/api'; @@ -225,7 +225,7 @@ app.run(($location, $rootScope, $http) => { [ API, - // IOService, + IOService, MenuService, RemoveHashtags, RemoveNewline, diff --git a/src/client/components/Timeline.js b/src/client/components/Timeline.js index 8eb49e5c..391d55cc 100644 --- a/src/client/components/Timeline.js +++ b/src/client/components/Timeline.js @@ -27,14 +27,13 @@ function postText(post){ export default function(app) { app.component('timeline', { template: template, - controller: function($timeout, usSpinnerService, api){ + controller: function($timeout, usSpinnerService, api, io){ let skip = 0; let limit = 10; this.feed = []; this.timelineUpdating = false; usSpinnerService.stop('timelineMore'); - //usSpinnerService.spin("timelineMore"); function toInstagram(post){ //var author_id = personByInstagram(team.team, post.data.author); @@ -68,7 +67,6 @@ export default function(app) { else return post; }); - //skip++; skip += limit; this.feed = this.feed.concat(feed2); this.showFooter = this.feed && this.feed.length; @@ -77,18 +75,16 @@ export default function(app) { this.loadNext(); - // io.on('post', params => { - //let posts = params instanceof Array ? params : [params]; - // - //let feed2 = posts.map(post => { - // if(post.type == 'instagram') return toInstagram(post); - // else return post; - //}); + io.on('feed', feed => { + // console.log(feed); - //this.$apply(() => { - // this.feed = feed2.concat(this.feed); - //}); - // }); + feed = feed instanceof Array ? feed : [feed]; + feed = feed.map(i => i.type === 'instagram' ? toInstagram(i) : i); + + $timeout(()=>{ + this.feed = feed.concat(this.feed); + }, 0); + }); } }); -}; \ No newline at end of file +}; diff --git a/src/core/collective.js b/src/core/collective.js index f8ff67de..8956ad1b 100644 --- a/src/core/collective.js +++ b/src/core/collective.js @@ -1,7 +1,7 @@ import {c} from '../core/db'; export async function getCollective(query={}, show={}) { - let data = await c('collective').find(query, show); + let data = await c('collective').find(query, show).toArray(); if (!data) { return null; } diff --git a/src/core/db.js b/src/core/db.js index ab09b3de..73a85352 100644 --- a/src/core/db.js +++ b/src/core/db.js @@ -1,46 +1,24 @@ -/** - * Created by tmshv on 22/11/14. - */ +import {MongoClient, ObjectId} from 'mongodb'; +import co from 'co'; -var mongo = require("promised-mongo"); -var ObjectId = mongo.ObjectId; +export var db; -var client = null; +export function connect(uri){ + return co(function*() { + db = yield MongoClient.connect(uri); + return db; + }) +} -module.exports = { - init: function (uri) { - //noinspection JSUnresolvedFunction - return new Promise(function (resolve) { - client = mongo(uri); - resolve(); - }); - }, +export function collection(name){ + return db.collection(name); +} - close: function () { - client.close(); - }, +export const c = collection; - get db() { - return client; - }, - - c: function(name){ - return client.collection(name); - }, - - id: function(i) { - if(typeof i === "string"){ - return ObjectId(i); - } - - else if(i instanceof ObjectId) { - return i; - } - - else if(i instanceof Object) { - return "_id" in i ? ObjectId(i._id) : null; - } - - return null; - } -}; \ No newline at end of file +export function id(i){ + if(typeof i === 'string')return ObjectId(i); + else if(i instanceof ObjectId) return i; + else if(i instanceof Object) return '_id' in i ? ObjectId(i._id) : null; + return null; +} diff --git a/src/data/Data.js b/src/data/Data.js new file mode 100644 index 00000000..fa34d210 --- /dev/null +++ b/src/data/Data.js @@ -0,0 +1,14 @@ +import {EventEmitter} from 'events'; +import {collection} from '../core/db'; + +export default class Data extends EventEmitter { + constructor(storeName) { + super(); + this.name = storeName; + this.store = collection(storeName); + } + + update(document){ + this.emit('update', document); + } +} diff --git a/src/data/Feed.js b/src/data/Feed.js new file mode 100644 index 00000000..e13ad962 --- /dev/null +++ b/src/data/Feed.js @@ -0,0 +1,34 @@ +import Data from './Data'; + +export default class Feed extends Data { + constructor() { + super('timeline'); + } + + add(post) { + let add = async(post) => { + const id = post.id; + const type = post.type; + const query = {id: id, type: type}; + + await this.store.update(query, post, {upsert: true}); + + let document = await this.store.find(query).limit(1).toArray(); + document = document[0]; + // post._id = `schachlo-${Date.now()}`; + // let document = post; + + this.update(document); + return document; + }; + return add(post); + } + + read(id) { + + } + + portion() { + + } +} diff --git a/src/data/index.js b/src/data/index.js new file mode 100644 index 00000000..535d122a --- /dev/null +++ b/src/data/index.js @@ -0,0 +1,5 @@ +import Feed from './Feed'; + +export default { + feed: new Feed() +}; diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..f96ee64e --- /dev/null +++ b/src/index.js @@ -0,0 +1,21 @@ +require('babel-core/register'); +require('babel-polyfill'); + +var config = require('./config').default; +var db = require('./core/db'); + +db.connect(config.db.uri) + .then(function () { + var server = require('./server').default; + var io = require('./io').default; + + var app = server(); + io(app); + app.listen(config.port); + }) + .catch(function(e){ + console.error(e.stack); + }) + .then(function(){ + console.log(`Start listening ${config.port}`); + }); diff --git a/src/io.js b/src/io.js new file mode 100644 index 00000000..fcede465 --- /dev/null +++ b/src/io.js @@ -0,0 +1,24 @@ +import socketIO from 'socket.io'; +import data from './data'; + +export default function(server) { + let io = socketIO(server); + io.on('connection', socket => { + console.log('a user connected'); + + socket.emit('feed', { + type: 'test', + id: 1, + message: 'hello world' + }); + + // socket.on('my other event', function (data) { + // console.log(data); + // }); + }); + + data.feed.on('update', i => { + console.log(`io feed update ${JSON.stringify(i, null, '\t')}`); + io.emit('feed', i); + }); +} diff --git a/src/models/collective.js b/src/models/collective.js index d0331a7e..54ea159f 100644 --- a/src/models/collective.js +++ b/src/models/collective.js @@ -6,4 +6,4 @@ export function shortifyName(name) { export function splitName(name) { return /(.+)\s(.+)\s(.+)/.exec(name); -} \ No newline at end of file +} diff --git a/src/models/menu.js b/src/models/menu.js index 9aaab874..bd68cdf6 100644 --- a/src/models/menu.js +++ b/src/models/menu.js @@ -33,4 +33,4 @@ export default [ "url": "/documents", "color": "yellow" } -] \ No newline at end of file +]; diff --git a/src/routes/api/feed.js b/src/routes/api/feed.js deleted file mode 100644 index 9e9839a5..00000000 --- a/src/routes/api/feed.js +++ /dev/null @@ -1,15 +0,0 @@ -import {put} from 'koa-route'; -import compose from 'koa-compose'; -import {ensureServiceAuth} from '../../middlewares/ensureServiceAuth'; - -export function add() { - return put('/api/v1/feed', compose([ - ensureServiceAuth(), - async ctx => { - let post = ctx.body; - ctx.body = { - pong: post - }; - } - ])); -} diff --git a/src/routes/teachers.js b/src/routes/teachers.js index 8cfac548..37f0e125 100644 --- a/src/routes/teachers.js +++ b/src/routes/teachers.js @@ -26,7 +26,7 @@ function list() { ctx.type = 'application/json'; let pattern = toArray(ctx.query.sort || ''); - let data = await c('collective').find(); + let data = await c('collective').find().toArray(); if (!data) { ctx.status = 404; return; diff --git a/src/server.js b/src/server.js index 1acbfb63..bca8eb58 100644 --- a/src/server.js +++ b/src/server.js @@ -1,4 +1,5 @@ import path from 'path'; +import {Server} from 'http'; import Koa from 'koa'; import serve from 'koa-static'; import logger from 'koa-logger'; @@ -12,13 +13,13 @@ import bodyParser from 'koa-bodyparser'; import config from './config'; import {redirectionTable} from './config'; import {routes, queryObject} from './routes'; -import api from './routes/api'; +import api from './api'; import {redirect} from './routes/redirect'; const dirPublic = path.join(__dirname, '../public'); const dirTemplates = path.join(__dirname, 'templates'); -export function server(){ +export default function(){ const $ = convert; const app = new Koa(); @@ -37,8 +38,8 @@ export function server(){ app.use($(helmet())); app.use(queryObject()); app.use(routes()); - - return app; + + return Server(app.callback()); } function prerenderRmFragment(){