diff --git a/package.json b/package.json
index cd2b4573..47f2ec6f 100644
--- a/package.json
+++ b/package.json
@@ -22,15 +22,17 @@
"babel-preset-stage-0": "^6.5.0",
"co": "^4.4.0",
"instagram-node": "^0.5.1",
- "koa-bodyparser": "^2.0.1",
+ "koa": "^2.0.0-alpha.3",
+ "koa-bodyparser": "^3.0.0",
+ "koa-compose": "^3.1.0",
"koa-conditional-get": "^1.0.2",
+ "koa-convert": "^1.2.0",
"koa-etag": "^2.0.0",
"koa-helmet": "^1.0.0",
"koa-logger": "^1.2.2",
"koa-prerender": "^1.0.3",
- "koa-route": "^2.4.0",
+ "koa-route": "^3.1.0",
"koa-static": "^2.0.0",
- "koa": "^1.2.0",
"mz": "^2.3.1",
"promised-mongo": "git+https://git@github.com/tmshv/promised-mongo",
"sitemap": "^1.5.0",
diff --git a/src/core/collective.js b/src/core/collective.js
index f103d8d4..f8ff67de 100644
--- a/src/core/collective.js
+++ b/src/core/collective.js
@@ -1,7 +1,7 @@
import {c} from '../core/db';
-export function* getCollective(query={}, show={}) {
- let data = yield c('collective').find(query, show);
+export async function getCollective(query={}, show={}) {
+ let data = await c('collective').find(query, show);
if (!data) {
return null;
}
diff --git a/src/core/schedule.js b/src/core/schedule.js
index 9bad62c9..ca8dbae8 100644
--- a/src/core/schedule.js
+++ b/src/core/schedule.js
@@ -6,8 +6,8 @@ import {populate, scheduleDate} from '../models/schedule';
import {shortifyName} from '../models/collective';
import {courses} from '../models/course';
-export function* getSchedule(period, semester) {
- let data = yield c('schedules').findOne({
+export async function getSchedule(period, semester) {
+ let data = await c('schedules').findOne({
period: period,
semester: semester
});
@@ -15,8 +15,8 @@ export function* getSchedule(period, semester) {
return null;
}
-export function* getScheduleList() {
- let list = yield c('schedules')
+export async function getScheduleList() {
+ let list = await c('schedules')
.find({}, {period: 1, semester: 1})
.toArray();
return list
@@ -28,8 +28,8 @@ export function* getScheduleList() {
});
}
-export function* populateSchedule(schedule) {
- let collective = yield getCollective({}, {id: 1, name: 1});
+export async function populateSchedule(schedule) {
+ let collective = await getCollective({}, {id: 1, name: 1});
let collective_dict = collective.reduce((dict, i) => {
dict[i.id] = i.name;
return dict;
diff --git a/src/middlewares/ensureServiceAuth.js b/src/middlewares/ensureServiceAuth.js
new file mode 100644
index 00000000..e83a83c8
--- /dev/null
+++ b/src/middlewares/ensureServiceAuth.js
@@ -0,0 +1,14 @@
+import {checkAuth} from '../core/service';
+
+export function ensureServiceAuth() {
+ return async (ctx, next) => {
+ let service = ctx.request.headers['x-service-name'];
+ let token = ctx.request.headers['x-service-token'];
+
+ if (!checkAuth(service, token)) {
+ ctx.status = 401;
+ } else {
+ await next();
+ }
+ };
+}
diff --git a/src/routes/404.js b/src/routes/404.js
index 8f706ce0..bddf1507 100644
--- a/src/routes/404.js
+++ b/src/routes/404.js
@@ -1,26 +1,26 @@
import {index, accepts} from './';
export default function () {
- return function *(next) {
- yield next;
+ return async(ctx) => {
+ if (ctx.status != 404) return;
- if (404 != this.status) return;
+ ctx.status = 404;
+ ctx.body = 'lol found';
- this.status = 404;
- yield accepts({
+ await accepts({
'text/html': index(),
-
- 'text/plain': function *() {
- this.type = 'text/plain';
- this.body = 'Page not found';
+ 'text/plain': async ctx => {
+ ctx.type = 'text/plain';
+ ctx.body = 'Page not found';
},
- 'application/json': function *() {
- this.type = 'application/json';
- this.body = {
+ 'application/json': async ctx => {
+ ctx.type = 'application/json';
+ ctx.body = {
+ error: 404,
message: 'Not Found'
};
}
- });
+ })(ctx);
};
};
\ No newline at end of file
diff --git a/src/routes/api/feed.js b/src/routes/api/feed.js
new file mode 100644
index 00000000..9e9839a5
--- /dev/null
+++ b/src/routes/api/feed.js
@@ -0,0 +1,15 @@
+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/api/index.js b/src/routes/api/index.js
new file mode 100644
index 00000000..0a031397
--- /dev/null
+++ b/src/routes/api/index.js
@@ -0,0 +1,8 @@
+import {add as feedAdd} from './feed';
+import compose from 'koa-compose';
+
+export default function () {
+ return compose([
+ feedAdd()
+ ]);
+};
diff --git a/src/routes/articles.js b/src/routes/articles.js
index 48880d8d..0af181b1 100644
--- a/src/routes/articles.js
+++ b/src/routes/articles.js
@@ -1,38 +1,28 @@
import route from 'koa-route';
import {c} from '../core/db';
import {accepts, index} from './';
-import {sortBy} from '../utils/sort';
-export default function (app) {
+async function exists(ctx, id) {
+ let i = await article(id);
+ return i ? true : false;
+}
- function* exists(id) {
- let i = yield c('events').findOne({id: id});
- if (!i) {
- i = yield c('timeline').findOne({id: id});
- }
- return i ? true : false;
+async function article(id){
+ let i = await c('events').findOne({id: id});
+ if (!i) {
+ i = await c('timeline').findOne({id: id});
}
+ return i;
+}
- app.use(route.get('/article/:id', accepts({
- //'text/html': function* (id){
- // let test = yield exists(id);
- // if(test){
- // return yield index();
- // }else{
- // this.status = 404;
- // return yield index();
- // }
- //},
+export default function () {
+ return route.get('/article/:id', accepts({
'text/html': index(exists),
'text/plain': index(exists),
- 'application/json': function* (id) {
- let i = yield c('events').findOne({id: id});
- if (!i) {
- i = yield c('timeline').findOne({id: id});
- }
-
- if (!i) this.status = 404;
- else this.body = i;
+ 'application/json': async (ctx, id) => {
+ let i = await article(id);
+ if (!i) ctx.status = 404;
+ else ctx.body = i;
}
- })));
+ }))
};
diff --git a/src/routes/documents.js b/src/routes/documents.js
index c9094f26..b5de9a82 100644
--- a/src/routes/documents.js
+++ b/src/routes/documents.js
@@ -1,68 +1,73 @@
+import compose from 'koa-compose';
import route from 'koa-route';
import {index, json, accepts} from './';
import {c} from '../core/db';
-function* exists(id) {
- let i = yield c('documents').findOne({id: id});
+async function exists(ctx, id) {
+ let i = await c('documents').findOne({id: id});
return i ? true : false;
}
-export default function (app) {
- [
- [
- '/documents',
- json(function *() {
- let query = {};
- this.body = yield c('documents')
- .find(query)
- .toArray();
- })
- ],
- [
- '/documents/type/:type',
- function *(type) {
- let types = {
- 'document': ['documents', {type: 'document'}, populateDocPreview],
- 'award': ['documents', {type: 'award'}, populateDocPreview]
- };
-
- if (type in types) {
- let [collection, query, mapFn] = types[type];
-
- let docs = yield c(collection)
- .find(query)
- .toArray();
-
- if (mapFn) docs = yield docs.map(mapFn);
-
- this.body = docs;
- } else {
- this.status = 404;
- }
- }
- ],
- [
- '/documents/:id',
- accepts({
- 'text/html': index(exists),
- 'text/plain': index(exists),
- 'application/json': function* (id) {
- let i = yield c('documents').findOne({id: id});
- if (!i) this.status = 404;
- else {
- i = yield populateDocPreview(i);
- this.body = i;
- }
- }
- })
- ]
- ].forEach(item => {
- let [path, fn] = item;
- app.use(route.get(path, fn));
- });
+export default function () {
+ return compose([
+ documents(),
+ document(),
+ type()
+ ]);
};
-function* populateDocPreview(doc) {
- doc.preview = yield c('images').findOne({_id: doc.preview});
+function documents() {
+ return route.get('/documents', json(
+ async(ctx) => {
+ let query = {};
+ ctx.body = await c('documents')
+ .find(query)
+ .toArray();
+ }
+ ));
+}
+
+function document() {
+ return route.get('/documents/:id', accepts({
+ 'text/html': index(exists),
+ 'text/plain': index(exists),
+ 'application/json': async(ctx, id) => {
+ let i = await c('documents').findOne({id: id});
+ if (!i) ctx.status = 404;
+ else {
+ i = await populateDocPreview(i);
+ ctx.body = i;
+ }
+ }
+ }));
+}
+
+function type() {
+ return route.get('/documents/type/:type', async(ctx, type) => {
+ let types = {
+ 'document': ['documents', {type: 'document'}, populateDocPreview],
+ 'award': ['documents', {type: 'award'}, populateDocPreview]
+ };
+
+ if (type in types) {
+ let [collection, query, mapFn] = types[type];
+
+ let docs = await c(collection)
+ .find(query)
+ .toArray();
+
+ if (mapFn) docs = await Promise.all(
+ docs.map(mapFn)
+ );
+
+ ctx.body = docs;
+ } else {
+ ctx.status = 404;
+ }
+ });
+}
+
+async function populateDocPreview(doc) {
+ doc.preview = await c('images').findOne({_id: doc.preview});
return doc;
}
diff --git a/src/routes/events.js b/src/routes/events.js
index a2dc83f4..9c350f21 100644
--- a/src/routes/events.js
+++ b/src/routes/events.js
@@ -3,34 +3,34 @@ import {c} from '../core/db';
import {json} from './';
import {sortBy} from '../utils/sort';
-export default function (app) {
- let sortByDate = sortBy(
- i => (new Date(i.date))
- .getTime()
- );
+let sortByDate = sortBy(
+ i => (new Date(i.date))
+ .getTime()
+);
- app.use(route.get('/events/:page?', json(
- function *() {
- let limit = parseInt(this.query['limit']) || 10;
- let skip = parseInt(this.query['skip']) || 0;
+export default function () {
+ return route.get('/events/:page?', json(
+ async(ctx) => {
+ let limit = parseInt(ctx.query['limit']) || 10;
+ let skip = parseInt(ctx.query['skip']) || 0;
let query = {};
- let documents = yield c('events')
+ let documents = await c('events')
.find(query)
.sort({date: -1})
.skip(skip)
.limit(limit)
.toArray();
- let total = yield c('events')
+ let total = await c('events')
.find(query).count();
- this.body = {
+ ctx.body = {
skip: skip,
limit: limit,
total: total,
data: documents
};
}
- )));
+ ));
};
diff --git a/src/routes/gallery.js b/src/routes/gallery.js
index 261ee6d6..714e814b 100644
--- a/src/routes/gallery.js
+++ b/src/routes/gallery.js
@@ -1,33 +1,14 @@
import co from 'co';
+import compose from 'koa-compose';
import route from 'koa-route';
import {c} from '../core/db';
import {json} from './';
-export default function (app) {
- app.use(route.get('/gallery', json(
- function *() {
- let query = {};
- let fields = ['_id', 'id', 'title', 'date'];
- //.reduce((f, i) => {
- // f[i] = 1;
- // return f;
- //}, {});
-
- let albums = yield c('albums')
- .find(query)
- .toArray();
-
- //albums = albums.map(i => {
- // return fields.reduce((a, key)=> {
- // a[key] = i[key];
- // return a;
- // }, {});
- //});
-
- albums = yield albums.map(processAlbum);
- this.body = albums;
- }
- )));
+export default function () {
+ return compose([
+ gallery(),
+ album()
+ ]);
//app.use(route.get('/gallery/:year', json(
// function *(year) {
@@ -45,28 +26,46 @@ export default function (app) {
// this.body = albums;
// }
//)));
+};
- app.use(route.get('/album/:id', json(
- function *(id) {
- //year = parseInt(year);
- //course = '/' + course;
- //album = '/' + album;
- //let start = new Date(year, 0, 1);
- //let end = new Date(year, 11, 31);
- //let query = {
- // date: {$gte: start, $lt: end},
- // course_uri: course,
- // uri: album
- //};
+function gallery(){
+ return route.get('/gallery', json(
+ async(ctx) => {
+ let query = {};
+ let fields = ['_id', 'id', 'title', 'date'];
+ //.reduce((f, i) => {
+ // f[i] = 1;
+ // return f;
+ //}, {});
- let record = yield c('albums').findOne({
+ let albums = await c('albums')
+ .find(query)
+ .toArray();
+
+ //albums = albums.map(i => {
+ // return fields.reduce((a, key)=> {
+ // a[key] = i[key];
+ // return a;
+ // }, {});
+ //});
+
+ albums = await Promise.all(albums.map(processAlbum));
+ ctx.body = albums;
+ }
+ ));
+}
+
+function album(){
+ return route.get('/album/:id', json(
+ async(ctx, id) => {
+ let record = await c('albums').findOne({
id: id
});
- record = yield processAlbum(record);
- this.body = record;
+ record = await processAlbum(record);
+ ctx.body = record;
}
- )));
-};
+ ));
+}
let processAlbum = album => co(function *() {
//album.url = `/gallery/{year}{course}{album}`
diff --git a/src/routes/index.js b/src/routes/index.js
index 00cbacad..cf12a5fd 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -1,5 +1,6 @@
import fs from 'mz/fs';
import route from 'koa-route';
+import compose from 'koa-compose';
import {map, assign} from '../utils/common';
import config from '../config';
@@ -16,19 +17,19 @@ import articles from './articles';
let main = () => route.get('/', index());
-export function routes(app){
- app.use(main());
-
- sitemap(app);
- schedule(app);
- news(app);
- gallery(app);
- documents(app);
- events(app);
- articles(app);
- teachers(app);
-
- app.use(error404());
+export function routes(){
+ return compose([
+ main(),
+ sitemap(),
+ schedule(),
+ news(),
+ gallery(),
+ documents(),
+ teachers(),
+ events(),
+ articles(),
+ error404()
+ ]);
}
export function queryObject() {
@@ -36,9 +37,9 @@ export function queryObject() {
let toFalse = map(false, i => i === 'false');
const processors = [toTrue, toFalse];
- return function *(next) {
- let query = this.query;
- this.query = Object.keys(query)
+ return async (ctx, next) => {
+ let query = ctx.query;
+ ctx.query = Object.keys(query)
.reduce((query, key) => assign(
query,
key,
@@ -46,23 +47,22 @@ export function queryObject() {
.reduce((value, fn) => fn(value), query[key])
), query);
- yield next;
+ await next();
}
}
-export function accepts(routes, def) {
- return function *() {
- let req = this.request;
+export function accepts(routes) {
+ return async function (ctx) {
+ let request = ctx.request;
let types = Object.keys(routes)
- .filter(type => req.accepts(type));
+ .filter(type => request.accepts(type));
if (types.length) {
- let type = types[0];
- yield routes[type].apply(this, arguments);
- } else if (def) {
- yield def;
+ let fn = routes[types[0]];
+
+ await fn.apply(ctx, arguments);
} else {
- this.status = 406;
+ ctx.status = 406;
}
};
}
@@ -70,21 +70,21 @@ export function accepts(routes, def) {
export function index(fn) {
let filename = config['defaultIndex'];
- return function *() {
+ return async function (ctx){
let test = true;
- if(fn) test = yield fn.apply(this, arguments);
+ if (fn) test = await fn.apply(ctx, arguments);
- if(!test) {
- this.status = 404;
- }
+ if (!test) ctx.status = 404;
- this.type = 'text/html';
- this.body = fs.createReadStream(filename);
+ ctx.type = 'text/html';
+ ctx.body = fs.createReadStream(filename);
}
}
-export const json = fn => accepts({
- 'text/html': index(),
- 'text/plain': index(),
- 'application/json': fn
-});
+export function json(fn){
+ return accepts({
+ 'text/html': index(),
+ 'text/plain': index(),
+ 'application/json': fn
+ });
+}
diff --git a/src/routes/news.js b/src/routes/news.js
index 6315573d..3b8e31c3 100644
--- a/src/routes/news.js
+++ b/src/routes/news.js
@@ -1,32 +1,38 @@
+import compose from 'koa-compose';
import route from 'koa-route';
-import {accepts, index} from './';
+import {accepts} from './';
import {c} from '../core/db';
import {sortBy} from '../utils/sort';
-export default function (app) {
- let sortNewsByDate = sortBy(
- i => (new Date(i.date))
- .getTime()
- );
+const sortNewsByDate = sortBy(
+ i => (new Date(i.date))
+ .getTime()
+);
- app.use(route.get('/news', accepts({
- 'text/html': function *() {
- this.redirect('/');
- },
- 'text/plain': function *() {
- this.redirect('/');
- },
- 'application/json': function *() {
- let limit = parseInt(this.query['limit']) || 10;
- let skip = parseInt(this.query['skip']) || 0;
+const redirect = async ctx => ctx.redirect('/');
+
+export default function () {
+ return compose([
+ news(),
+ pinned()
+ ]);
+};
+
+function news() {
+ return route.get('/news', accepts({
+ 'text/html': redirect,
+ 'text/plain': redirect,
+ 'application/json': async ctx => {
+ let limit = parseInt(ctx.query['limit']) || 10;
+ let skip = parseInt(ctx.query['skip']) || 0;
let query = {};
- if (this.query.type) query.type = this.query.type;
+ if (ctx.query.type) query.type = ctx.query.type;
let pinned = [];
if(skip == 0) {
const now = new Date();
- pinned = yield c('timeline')
+ pinned = await c('timeline')
.find({until: {$gte: now}})
.toArray()
.then(i => i.sort(sortNewsByDate));
@@ -35,7 +41,7 @@ export default function (app) {
let sid = id => id + '';
let pinnedIds = pinned.map(p => sid(p['_id']));
- let posts = yield c('timeline')
+ let posts = await c('timeline')
.find(query)
.sort({date: -1})
.skip(skip)
@@ -45,23 +51,21 @@ export default function (app) {
i => pinnedIds.indexOf(sid(i['_id'])) < 0
));
- this.body = pinned.concat(posts);
+ ctx.body = pinned.concat(posts);
}
- })));
+ }));
+}
- app.use(route.get('/news/pinned', accepts({
- 'text/html': function *() {
- this.redirect('/');
- },
- 'text/plain': function *() {
- this.redirect('/');
- },
- 'application/json': function *() {
+function pinned(){
+ return route.get('/news/pinned', accepts({
+ 'text/html': redirect,
+ 'text/plain': redirect,
+ 'application/json': async ctx => {
let now = new Date();
- this.body = yield c('timeline')
+ ctx.body = await c('timeline')
.find({until: {$gte: now}})
.toArray()
.then(i => i.sort(sortNewsByDate));
}
- })));
-};
+ }));
+}
diff --git a/src/routes/schedule.js b/src/routes/schedule.js
index d624a308..25ff01fa 100644
--- a/src/routes/schedule.js
+++ b/src/routes/schedule.js
@@ -1,38 +1,45 @@
+import compose from 'koa-compose';
+import co from 'co';
import route from 'koa-route';
import {json} from './';
import {getSchedule, getScheduleList, populateSchedule} from '../core/schedule';
-export default function (app) {
- app.use(
- route.get('/schedule/list', json(
- function *() {
- this.type = 'application/json';
- let data = yield getScheduleList();
- if (!data) this.status = 404;
- else this.body = data;
- }
- ))
- );
-
- app.use(
- route.get('/schedule/:period?/:semester?', json(
- function *(period, semester) {
- this.type = 'application/json';
-
- let data = yield getSchedule(period, semester);
- if (!data) {
- this.status = 404;
- return;
- }
-
- let doPopulate = this.query.populate || false;
- if (doPopulate) {
- data.schedule = yield populateSchedule(data.schedule);
- }
-
- this.body = data;
- }
- ))
- );
+export default function () {
+ return compose([
+ list(),
+ schedule()
+ ]);
};
+
+function list() {
+ return route.get('/schedule/list', json(
+ async(ctx) => {
+ ctx.type = 'application/json';
+ let data = await getScheduleList();
+ if (!data) ctx.status = 404;
+ else ctx.body = data;
+ }
+ ))
+}
+
+function schedule() {
+ return route.get('/schedule/:period?/:semester?', json(
+ async(ctx, period, semester) => {
+ ctx.type = 'application/json';
+
+ let data = await getSchedule(period, semester);
+ if (!data) {
+ ctx.status = 404;
+ return;
+ }
+
+ let doPopulate = ctx.query.populate || false;
+ if (doPopulate) {
+ data.schedule = await populateSchedule(data.schedule);
+ }
+
+ ctx.body = data;
+ }
+ ))
+}
\ No newline at end of file
diff --git a/src/routes/sitemap.js b/src/routes/sitemap.js
index b30f5cbe..73d0916d 100644
--- a/src/routes/sitemap.js
+++ b/src/routes/sitemap.js
@@ -5,41 +5,39 @@ import {c} from '../core/db';
import {homeUrl, sitemapCacheTime} from '../config';
import menu from '../models/menu';
-export default function (app) {
- app.use(route.get('/sitemap.xml', function *() {
- let urls = yield [
+export default function () {
+ return route.get('/sitemap.xml', async ctx => {
+ let urls = await Promise.all([
getMenuUrls(),
getGalleryUrls(),
getTeacherUrls(),
getEventsUrls(),
getNewsUrls()
- ];
+ ]);
urls = urls.reduce((urls, i) => urls.concat(i));
- let sm = sitemap.createSitemap({
+ let map = sitemap.createSitemap({
hostname: homeUrl,
cacheTime: sitemapCacheTime,
urls: urls
});
- this.set('Content-Type', 'application/xml');
- this.body = yield new Promise(resolve => sm.toXML(resolve));
- }));
+ ctx.set('Content-Type', 'application/xml');
+ ctx.body = map.toString();
+ })
};
-function *getMenuUrls() {
+async function getMenuUrls(frequency='daily') {
return menu
.filter(i => 'url' in i)
- .map(function (item) {
- return {
- url: item.url,
- changefreq: 'daily'
- }
- });
+ .map(i => ({
+ url: i.url,
+ changefreq: frequency
+ }));
}
-function *getGalleryUrls() {
- let docs = yield c('albums')
+async function getGalleryUrls() {
+ let docs = await c('albums')
.find({})
.toArray();
@@ -51,8 +49,8 @@ function *getGalleryUrls() {
});
}
-function *getTeacherUrls() {
- let docs = yield c('collective')
+async function getTeacherUrls() {
+ let docs = await c('collective')
.find({})
.toArray();
@@ -64,8 +62,8 @@ function *getTeacherUrls() {
});
}
-function *getEventsUrls() {
- let docs = yield c('events')
+async function getEventsUrls() {
+ let docs = await c('events')
.find({})
.toArray();
@@ -77,8 +75,8 @@ function *getEventsUrls() {
});
}
-function *getNewsUrls() {
- let docs = yield c('timeline')
+async function getNewsUrls() {
+ let docs = await c('timeline')
.find({type: 'post'})
.toArray();
diff --git a/src/routes/teachers.js b/src/routes/teachers.js
index 97668a3f..8cfac548 100644
--- a/src/routes/teachers.js
+++ b/src/routes/teachers.js
@@ -1,4 +1,5 @@
import co from 'co';
+import compose from 'koa-compose';
import route from 'koa-route';
import {index, json} from './';
import {sortByPattern} from '../utils/sort';
@@ -7,42 +8,55 @@ import {c} from '../core/db';
let split = d => s => s.split(d);
let toArray = split(',');
-export default function (app) {
- app.use(route.get('/collective', index()));
-
- app.use(route.get('/teacher/list', json(
- function *() {
- this.type = 'application/json';
- let pattern = toArray(this.query.sort || '');
-
- let data = yield c('collective').find();
- if (!data) {
- this.status = 404;
- return;
- }
-
- let collective = yield data
- .map(processProfile);
-
- this.body = sortByPattern(collective, pattern, i => i.id);
- }
- )));
-
- app.use(route.get('/teacher/:id', json(
- function *(id) {
- this.type = 'application/json';
-
- let data = yield c('collective').findOne({id: id});
- if (!data) {
- this.status = 404;
- return;
- }
-
- this.body = yield processProfile(data);
- }
- )))
+export default function () {
+ return compose([
+ collective(),
+ list(),
+ teacher()
+ ]);
};
+function collective() {
+ return route.get('/collective', index());
+}
+
+function list() {
+ return route.get('/teacher/list', json(
+ async(ctx) => {
+ ctx.type = 'application/json';
+ let pattern = toArray(ctx.query.sort || '');
+
+ let data = await c('collective').find();
+ if (!data) {
+ ctx.status = 404;
+ return;
+ }
+
+ let collective = await Promise.all(
+ data.map(processProfile)
+ );
+
+ ctx.body = sortByPattern(collective, pattern, i => i.id);
+ }
+ ));
+}
+
+function teacher() {
+ return route.get('/teacher/:id', json(
+ async (ctx, id) => {
+ ctx.type = 'application/json';
+
+ let data = await c('collective').findOne({id: id});
+ if (!data) {
+ ctx.status = 404;
+ return;
+ }
+
+ ctx.body = await processProfile(data);
+ }
+ ))
+}
+
let processProfile = profile => co(function *() {
let imageId = profile.picture;
profile.picture = yield c('images').findOne({_id: imageId});
diff --git a/src/server.js b/src/server.js
index 490324ec..1acbfb63 100644
--- a/src/server.js
+++ b/src/server.js
@@ -1,7 +1,8 @@
import path from 'path';
-import koa from 'koa';
+import Koa from 'koa';
import serve from 'koa-static';
import logger from 'koa-logger';
+import convert from 'koa-convert';
import conditional from 'koa-conditional-get';
import etag from 'koa-etag';
import prerender from 'koa-prerender';
@@ -11,40 +12,42 @@ 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 './routes/api';
import {redirect} from './routes/redirect';
const dirPublic = path.join(__dirname, '../public');
const dirTemplates = path.join(__dirname, 'templates');
export function server(){
- const app = koa();
+ const $ = convert;
+
+ const app = new Koa();
app.proxy = true;
app.use(bodyParser());
- app.use(logger());
- // api(app);
- app.use(conditional());
- app.use(etag());
+ app.use($(logger()));
+ app.use(api());
+ app.use($(conditional()));
+ app.use($(etag()));
app.use(prerenderRmFragment());
- app.use(prerender(config.prerender));
- app.use(serve(dirPublic));
- app.use(serve(dirTemplates));
- app.use(redirect(redirectionTable));
- app.use(helmet());
+ app.use($(prerender(config.prerender)));
+ app.use($(serve(dirPublic)));
+ app.use($(serve(dirTemplates)));
+ app.use($(redirect(redirectionTable)));
+ app.use($(helmet()));
app.use(queryObject());
- routes(app);
+ app.use(routes());
return app;
}
function prerenderRmFragment(){
- return function *(next) {
- yield* next;
+ return async (ctx, next) => {
+ await next();
try {
- let xp = this.response.header['x-prerender'] == 'true';
- if (xp) this.body = this.body.replace('', '');
+ let xp = ctx.response.header['x-prerender'] == 'true';
+ if (xp) ctx.body = ctx.body.replace('', '');
} catch (e) {
}
}