以下来自我最新的源码中选取的内容. [By the way, nimrod is a cool language!]
[1.] 缓存层
import {equal} from '../common-util';
import client from './client';
const TIME_LOCK = 600;
function to_imagelock (task_id) {
return `imagelocks._${task_id}`;
}
export function set_imagelock(task_id, userid, basename, f) {
let key = to_imagelock(task_id);
client
.multi([
['hmset', key, 'userid', userid, 'basename', basename],
['expire', key, TIME_LOCK]
])
.exec((err, replies) => {
if (err)
f(err, null);
else if (equal(replies[0], 'OK') && equal(replies[1], 1))
f(null, true);
else
f(null, false);
});
}
export function get_imagelock(task_id, f) {
client.hgetall(to_imagelock(task_id), f);
}
export function del_imagelock(task_id, f) {
client.del(to_imagelock(task_id), f);
}
[2.] 数据层
import * as queries from './task-queries';
import {query, connect} from './client';
import {format, rollback} from './db-util';
import {equal, not_equal} from '../common-util';
const TIME = 24 * 60 * 60 * 1000;
export function get_published_tasks(pubber_name, f) {
query(queries.get_published_tasks, [pubber_name], f);
}
export function get_random_tasks(userid, f) {
let random = Math.floor(Math.random() * 1e9);
function get_gte_tasks(f) {
query(format(queries.get_gte_tasks, [random, userid, 3]), f);
}
function get_lt_tasks(n, f) {
query(format(queries.get_lt_tasks, [random, userid, n]), f);
}
get_gte_tasks((_err, gtes) => {
let n;
if (_err)
f(_err, null);
else if ((n = (3 - gtes.length)) > 0)
get_lt_tasks(n, (err, lts) => {
if (err)
f(err, gtes);
else
f(err, gtes.concat(lts));
});
else
f(null, gtes);
});
}
export function set_task(pubber_id, pubber_name, keyword, f) {
query(
format(queries.set_task, [pubber_id, pubber_name, keyword]),
(err, reply) => {
if (err)
f(err, null, null);
else if (equal(reply.affectedRows, 1))
f(null, true, reply.insertId);
else
f(null, false, null);
}
);
}
// ...
[3.] 控制层
import {bad_request, server_error, send} from './server-util';
import {equal, not_equal, escape_input, escape_id} from '../common-util';
import {exists_user_by_userid} from '../dataset/user';
import {get_published_tasks, get_locked_tasks, get_finished_tasks, get_random_tasks,
set_task, modify_task_to_locked, modify_task_to_finished} from '../dataset/task';
import {set_imagelock, get_imagelock, del_imagelock} from '../memory/imagelock';
import conf from './conf';
import fs from 'fs';
import path from 'path';
const image_mimes = [
'image/gif',
'image/jpeg',
'image/png',
'image/svg+xml',
'image/tiff'
];
export function* show_published_tasks(ynext, next, req, res) {
let [err, tasks] = yield get_published_tasks(req.params.username, ynext);
if (err)
server_error(res);
else {
send(res, 200, 'OK', {'content-type':'application/json'}, tasks);
yield* next;
}
}
export function* create_task(ynext, next, req, res) {
let keyword = escape_input(req.body.keyword);
if (equal(keyword, ''))
bad_request(res);
else {
let [err, affected] = yield set_task(
req.session.userid,
req.session.username,
keyword,
ynext
);
if (err)
server_error(res);
else if (equal(affected, false))
bad_request(res);
else {
send(res, 201, 'Created');
yield* next;
}
}
}
// ...
[4.] 服务层
//@ •·→¸﹋ ﹌ ﹊ ˊ︽︾︿﹀︹︺︷︸︵︶﹄﹃︼︻〖【〗】«»‹›「」『』
import {auth_user, is_user, join, login, logout} from './controler/user/auth';
import {create_task, lock_task, push_task, save_image, accept_task_push,
show_random_tasks, show_published_tasks,
show_finished_tasks, show_locked_tasks} from './controler/task';
import {create_fans, destroy_fans} from './controler/fans';
import {create_follower, destroy_follower} from './controler/follower';
import {is_media, show_media_and_comments, show_some_medias} from './controler/media';
import {is_comment, create_comment, validate_comment, update_comment, destroy_comment} from './controler/comment';
import {index_space} from './controler/space';
import * as cparser from './cookie-parser';
import conf from './conf';
import * as rocore from 'rocore';
import http from 'http';
import formidable from 'formidable';
let server = http.createServer();
let app = rocore.createApplication();
app
.on('found', (route, req, res) => {
req.cookies = cparser.parse(req.headers.cookie);
let incoming = new formidable.IncomingForm();
let body = {};
incoming.keepExtensions = conf.incoming.keepExtensions;
incoming.uploadDir = conf.incoming.uploadDir;
incoming.multiples = conf.incoming.multiples;
incoming.maxFieldsSize = conf.incoming.maxFieldsSize;
incoming
.on('file', (name, file) => {
if (!(body[name] instanceof Array)) {
body[name] = [];
}
body[name].push(file);
})
.on('field', (name, value) => { body[name] = value; })
.on('end', () => {
req.body = body;
req.method = (req.body.__method || req.method).toLowerCase();
app.exec(route, req, res);
})
.parse(req);
})
.on('notfound', (req, res) => {
res.writeHead(404);
res.end('404 not found');
})
.post ('/join', join)
.post ('/login', login)
.get ('/logout', auth_user, logout)
.post ('/users/:username/fans', auth_user, is_user, create_fans)
.delete('/users/:username/fans', auth_user, is_user, destroy_fans)
.post ('/users/:username/followers', auth_user, is_user, create_follower)
.delete('/users/:username/followers', auth_user, is_user, destroy_follower)
.get ('/tasks/randoms', auth_user, show_random_tasks)
.post ('/tasks', auth_user, create_task)
.put ('/tasks/:task_id/locked', auth_user, lock_task)
.put ('/tasks/:task_id/pushed', auth_user, push_task)
.put ('/tasks/:task_id/accepted', auth_user, save_image, accept_task_push)
.get ('/users/:username/tasks/published', auth_user, is_user, show_published_tasks)
.get ('/users/:username/tasks/finished', auth_user, is_user, show_finished_tasks)
.get ('/users/:username/tasks/locked', auth_user, is_user, show_locked_tasks)
.post ('/users/:username/medias/:media_id/comments', auth_user, is_media, create_comment)
.put ('/users/:username/medias/:media_id/comments/:comment_id', auth_user, is_comment, update_comment)
.delete('/users/:username/medias/:media_id/comments/:comment_id', auth_user, is_comment, destroy_comment)
.get ('/users/:username/medias/:media_id', auth_user, is_media, show_media_and_comments)
.get ('/users/:username/medias', auth_user, is_user, show_some_medias)
.get ('/users/:username', auth_user, is_user, index_space)
// ...
;
server
.on('request', (req, res) => { app.match(req, res); })
.on('error', (error) => { console.log('Server Nodejs %s', error); })
.on('listening', () => { console.log('Server Nodejs online listening %s %d', conf.hostname, conf.port); })
.listen(conf.port, conf.hostname)
;
[5.] 安装层、编译层
var traceur = require('traceur');
var rocore = require('rocore');
var fs = require('fs');
var path = require('path');
var source = '/home/king/box-fork/dist';
var target = '/home/king/box-fork-compile';
rocore.readSync([source], 0, function (type, pathname) {
var newPath = path.join(target, pathname.replace(new RegExp('^' + source.replace(/\//g,'\/').replace(/\\/g,'\\')), ''));
if (type === 'file') {
if (path.extname(pathname) !== '.js') {
console.log('copy %s %s', pathname, newPath);
fs.writeFileSync(newPath, fs.readFileSync(pathname));
return;
}
console.log('traceur %s %s', pathname, newPath);
var src = fs.readFileSync(pathname, {encoding:'utf8'});
var options = {};
var compiled = traceur.compile(src, options);
fs.writeFileSync(newPath, compiled, {encoding:'utf8'});
}
if (type === 'directory') {
console.log('mkdir %s', newPath);
fs.mkdirSync(newPath);
}
});
// ...