diff --git a/.mailmap b/.mailmap index 7568df6..b1dcabc 100644 --- a/.mailmap +++ b/.mailmap @@ -1,5 +1,5 @@ jysperm -jysperm +jysperm lyd600lty kanakin kanakin diff --git a/app.coffee b/app.coffee index 076ab2b..d271378 100644 --- a/app.coffee +++ b/app.coffee @@ -1,172 +1,153 @@ -connect = require 'connect' -nodemailer = require 'nodemailer' -path = require 'path' -harp = require 'harp' -fs = require 'fs' -morgan = require 'morgan' -moment = require 'moment-timezone' -redis = require 'redis' -express = require 'express' -{MongoClient} = require 'mongodb' -session = require 'express-session' -crypto = require 'crypto' -csrf = require('csrf')() -RedisStore = require('connect-redis')(session) +#!/usr/bin/env coffee -global.app = express() +global.app = exports -config = null +app.libs = + bodyParser: require 'body-parser' + cookieParser: require 'cookie-parser' + depd: require 'depd' + express: require 'express' + fs: require 'fs' + middlewareInjector: require 'middleware-injector' + mongoose: require 'mongoose' + morgan: require 'morgan' + nodemailer: require 'nodemailer' + path: require 'path' -exports.checkEnvironment = -> - config_file_path = path.join __dirname, 'config.coffee' - session_key_path = path.join __dirname, 'session.key' +{cookieParser, bodyParser, depd, express, fs, nodemailer, path} = exports.libs - unless fs.existsSync config_file_path - default_config_file_path = path.join __dirname, './sample/rpvhost.config.coffee' - fs.writeFileSync config_file_path, fs.readFileSync default_config_file_path - console.log '[Warning] Copy sample config file to ./config.coffee' +app.package = require './package' +app.deprecate = depd 'rootpanel' + +do -> + config_path = path.join __dirname, 'config.coffee' + + unless fs.existsSync config_path + default_config_path = path.join __dirname, './sample/core.config.coffee' + fs.writeFileSync config_file_path, fs.readFileSync default_config_path + app.deprecate 'config.coffee not found, copy sample config to ./config.coffee' fs.chmodSync config_file_path, 0o750 - config = require './config' +config = require './config' +do -> if fs.existsSync config.web.listen fs.unlinkSync config.web.listen + session_key_path = path.join __dirname, 'session.key' + unless fs.existsSync session_key_path fs.writeFileSync session_key_path, crypto.randomBytes(48).toString('hex') -exports.loadCoreTemplates = -> - app.template_data = {} +app.config = config +app.db = require './db' +app.templates = require './templates' +app.i18n = require './core/i18n' +app.utils = require './core/utils' +app.cache = require './core/cache' +app.config = require './config' +app.package = require './package.json' +app.billing = require './core/billing' +app.pluggable = require './core/pluggable' +app.middleware = require './core/middleware' +app.notification = require './core/notification' +app.authenticator = require './core/authenticator' - for filename in fs.readdirSync "#{__dirname}/core/template" - template_name = path.basename filename, path.extname(filename) - app.template_data[template_name] = fs.readFileSync "#{__dirname}/core/template/#{filename}" +app.mailer = nodemailer.createTransport config.email.account +app.express = express() -exports.run = -> - exports.checkEnvironment() - exports.loadCoreTemplates() +app.redis = redis.createClient 6379, '127.0.0.1', + auth_pass: config.redis.password - {user, password, host, name} = config.mongodb +app.models = + Account: require './core/model/account' + BalanceLog: require './core/model/balance_log' + CouponCode: require './core/model/coupon_code' + Notification: require './core/model/notification' + SecurityLog: require './core/model/security_log' + Ticket: require './core/model/ticket' - if user and password - mongodb_uri = "mongodb://#{user}:#{password}@#{host}/#{name}" - else - mongodb_uri = "mongodb://#{host}/#{name}" +app.use bodyParser.json() +app.use morgan 'dev' +app.use cookieParser() +app.use middlewareInjector - MongoClient.connect mongodb_uri, (err, db) -> - throw err if err - app.db = db +app.use session + store: new RedisStore + client: app.redis - app.redis = redis.createClient 6379, '127.0.0.1', - auth_pass: config.redis.password - - app.mailer = nodemailer.createTransport config.email.account - - app.models = - mAccount: require './core/model/account' - mBalanceLog: require './core/model/balance_log' - mCouponCode: require './core/model/coupon_code' - mNotification: require './core/model/notification' - mSecurityLog: require './core/model/security_log' - mTicket: require './core/model/ticket' - - app.i18n = require './core/i18n' - app.utils = require './core/utils' - app.cache = require './core/cache' - app.config = require './config' - app.package = require './package.json' - app.billing = require './core/billing' - app.pluggable = require './core/pluggable' - app.middleware = require './core/middleware' - app.notification = require './core/notification' - app.authenticator = require './core/authenticator' - - app.use connect.json() - app.use connect.urlencoded() - app.use morgan('dev') - app.use require('cookie-parser')() - - app.use require 'middleware-injector' - - app.use session - store: new RedisStore - client: app.redis - - resave: true - saveUninitialized: true - secret: fs.readFileSync(path.join __dirname, 'session.key').toString() - - app.use (req, res, next) -> - unless req.session.csrf_secret - csrf.secret (err, secret) -> - req.session.csrf_secret = secret - req.session.csrf_token = csrf.create secret - next() + resave: true + saveUninitialized: true + secret: fs.readFileSync(path.join __dirname, 'session.key').toString() +app.use (req, res, next) -> + unless req.session.csrf_secret + csrf.secret (err, secret) -> + req.session.csrf_secret = secret + req.session.csrf_token = csrf.create secret next() - app.use (req, res, next) -> - unless req.method == 'GET' - unless csrf.verify req.session.csrf_secret, req.body.csrf_token - return res.status(403).send - error: 'invalid_csrf_token' + next() - next() +app.use (req, res, next) -> + unless req.method == 'GET' + unless csrf.verify req.session.csrf_secret, req.body.csrf_token + return res.status(403).send + error: 'invalid_csrf_token' - app.use (req, res, next) -> - req.res = res + next() - res.language = req.cookies.language ? config.i18n.default_language - res.timezone = req.cookies.timezone ? config.i18n.default_timezone +app.use (req, res, next) -> + req.res = res - res.locals = - config: config - app: app - req: req - res: res + res.language = req.cookies.language ? config.i18n.default_language + res.timezone = req.cookies.timezone ? config.i18n.default_timezone - t: app.i18n.getTranslator req + res.locals = + config: config + app: app + req: req + res: res - selectHook: (name) -> - return app.pluggable.selectHook req.account, name + t: app.i18n.getTranslator req - moment: -> - return moment.apply(@, arguments).locale(res.language).tz(res.timezone) + selectHook: (name) -> + return app.pluggable.selectHook req.account, name - res.t = res.locals.t - res.moment = res.locals.moment + moment: -> + return moment.apply(@, arguments).locale(res.language).tz(res.timezone) - res.locals.config.web.name = res.t app.config.web.t_name + res.t = res.locals.t + res.moment = res.locals.moment - next() + res.locals.config.web.name = res.t app.config.web.t_name - app.use app.middleware.accountInfo + next() - app.set 'views', path.join(__dirname, 'core/view') - app.set 'view engine', 'jade' +app.use app.middleware.accountInfo - app.get '/locale/:language?', app.i18n.downloadLocales +app.set 'views', path.join(__dirname, 'core/view') +app.set 'view engine', 'jade' - app.use '/account', require './core/router/account' - app.use '/billing', require './core/router/billing' - app.use '/ticket', require './core/router/ticket' - app.use '/admin', require './core/router/admin' - app.use '/panel', require './core/router/panel' +app.get '/locale/:language?', app.i18n.downloadLocales - app.pluggable.initializePlugins() +app.use '/account', require './core/router/account' +app.use '/billing', require './core/router/billing' +app.use '/ticket', require './core/router/ticket' +app.use '/admin', require './core/router/admin' +app.use '/panel', require './core/router/panel' - app.get '/', (req, res) -> - unless res.headerSent - res.redirect '/panel/' +app.pluggable.initializePlugins() - app.use harp.mount './core/static' +app.get '/', (req, res) -> + unless res.headerSent + res.redirect '/panel/' - app.billing.run() +app.use harp.mount './core/static' - app.listen config.web.listen, -> - fs.chmodSync config.web.listen, 0o770 - console.log "RootPanel start at #{config.web.listen}" +app.billing.run() -unless module.parent - exports.run() +app.listen config.web.listen, -> + fs.chmodSync config.web.listen, 0o770 + console.log "RootPanel start at #{config.web.listen}" diff --git a/core/cache.coffee b/core/cache.coffee index 643e89a..5f9e28f 100644 --- a/core/cache.coffee +++ b/core/cache.coffee @@ -1,5 +1,6 @@ stringify = require 'json-stable-stringify' -CounterCache = require('counter-cache') +CounterCache = require 'counter-cache' +_ = require 'underscore' config = require '../config' @@ -24,8 +25,13 @@ exports.try = (key, options, setter, callback) -> key = exports.hashKey key, options.param + if _.isEmpty options.param + original_setter = setter + setter = (param, callback) -> + original_setter callback + redis.get key, (err, value) -> - if value != undefined + if value != undefined and value != null if options.is_json value = JSON.parse value diff --git a/core/db.coffee b/core/db.coffee new file mode 100644 index 0000000..b3328eb --- /dev/null +++ b/core/db.coffee @@ -0,0 +1,13 @@ +{config} = app +{mongoose} = app.libs + +{user, password, host, name} = config.mongodb + +if user and password + mongodb_uri = "mongodb://#{user}:#{password}@#{host}/#{name}" +else + mongodb_uri = "mongodb://#{host}/#{name}" + +module.exports = mongoose.createConnection mongodb_uri + +exports.mongodb_uri = mongodb_uri diff --git a/core/tempaltes.coffee b/core/tempaltes.coffee new file mode 100644 index 0000000..e06fcc2 --- /dev/null +++ b/core/tempaltes.coffee @@ -0,0 +1,7 @@ +template_data = {} + +for filename in fs.readdirSync "#{__dirname}/core/template" + template_name = path.basename filename, path.extname(filename) + template_data[template_name] = fs.readFileSync("#{__dirname}/template/#{filename}").toSting() + +module.exports = template_data diff --git a/package.json b/package.json index e54d78a..f5ca01a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ } ], "scripts": { - "start": "node start.js" + "start": "coffee app.coffee", + "test": "./node_modules/.bin/mocha --compilers coffee:coffee-script/register --require test/support/env core/test plugin/*/test" }, "bin": { "rp-fix-permissions": "./bin/rp-fix-permissions.coffee", @@ -28,7 +29,6 @@ "negotiator": "^0.4.8", "async": "^0.9.0", "coffee-script": "^1.7.1", - "connect": "^2.17.3", "express": "^4.8.4", "harp": "^0.13.0", "jade": "^1.3.1", @@ -48,6 +48,14 @@ "csrf": "^2.0.1", "connect-redis": "^2.0.1", "express-session": "^1.8.2", - "morgan": "^1.3.2" + "morgan": "^1.3.2", + "mongoose": "^3.8.17", + "depd": "^1.0.0", + "body-parser": "^1.9.0" + }, + "devDependencies": { + "mocha": "^1.21.5", + "chai": "^1.9.2", + "deepmerge": "^0.2.7" } } diff --git a/plugin/linux/index.coffee b/plugin/linux/index.coffee index f0149e4..9123cb9 100644 --- a/plugin/linux/index.coffee +++ b/plugin/linux/index.coffee @@ -58,12 +58,20 @@ exports.registerServiceHook 'disable', app.get '/public/monitor', requireAuthenticate, (req, res) -> async.parallel - resources_usage: wrapAsync linux.getResourceUsageByAccounts + resources_usage: (callback) -> + linux.getResourceUsageByAccounts (result) -> + console.log result + callback null, result system: wrapAsync linux.getSystemInfo storage: wrapAsync linux.getStorageInfo process_list: wrapAsync linux.getProcessList + memory: wrapAsync linux.getMemoryInfo + x: (callback) -> + callback null, 'test' , (err, result) -> + console.log arguments + exports.render 'monitor', req, result, (html) -> res.send html diff --git a/plugin/linux/linux.coffee b/plugin/linux/linux.coffee index a5e2bb3..a9b9f60 100644 --- a/plugin/linux/linux.coffee +++ b/plugin/linux/linux.coffee @@ -249,6 +249,7 @@ exports.getResourceUsageByAccounts = (callback) -> command: cache.SETEX 20 is_json: true , (callback) -> + console.log 'getResourceUsageByAccounts' async.parallel storage_quota: wrapAsync exports.getStorageQuota process_list: wrapAsync exports.getProcessList diff --git a/plugin/linux/locale/zh_CN.json b/plugin/linux/locale/zh_CN.json index 6293d6a..dc64453 100644 --- a/plugin/linux/locale/zh_CN.json +++ b/plugin/linux/locale/zh_CN.json @@ -7,5 +7,10 @@ "hour_memory": "一小时内存占用", "storage": "储存空间", "month_transfer": "月流量" + }, + "monitor": { + "system": "操作系统", + "system_info": "系统信息", + "cpu": "CPU" } } diff --git a/plugin/linux/test/linux.coffee b/plugin/linux/test/linux.coffee new file mode 100644 index 0000000..92be856 --- /dev/null +++ b/plugin/linux/test/linux.coffee @@ -0,0 +1,14 @@ +console.log '1' + +application.run -> + console.log '2' + linux = require '../linux' + + describe 'linux', -> + console.log '3' + describe 'getPasswdMap', -> + it 'should an object', (done) -> + linux.getPasswdMap (passwd_map) -> + console.log passwd_map + passwd_map.should.an 'object' + done() diff --git a/plugin/linux/view/monitor.jade b/plugin/linux/view/monitor.jade index a441bbe..bec7661 100644 --- a/plugin/linux/view/monitor.jade +++ b/plugin/linux/view/monitor.jade @@ -1,10 +1,9 @@ extends ../../../core/view/layout -prepend head - title 服务器状态 | #{t('app.name')} +prepend header + title #{t('server_monitor')} | #{t('app.name')} -append head - link(rel='stylesheet', href='/style/panel.css') +append header link(rel='stylesheet', href='/plugin/linux/style/monitor.css') block content @@ -33,10 +32,10 @@ block content td #{(system.uptime / 3600).toFixed(1)} hours tr td Loadavg - td= system.loadavg + td= system.loadavg.join(', ') tr td Address - td= system.address + td= system.address.join(', ') .col-md-8 .panel.panel-default @@ -106,7 +105,7 @@ block content th TIME th COMMAND tbody - for process in last_plist + for process in process_list tr td= process.user td= process.pid diff --git a/start.js b/start.js deleted file mode 100644 index 59bf065..0000000 --- a/start.js +++ /dev/null @@ -1,2 +0,0 @@ -require('coffee-script/register'); -require('./app.coffee').run(); diff --git a/test/support/env.coffee b/test/support/env.coffee new file mode 100644 index 0000000..0493c66 --- /dev/null +++ b/test/support/env.coffee @@ -0,0 +1,5 @@ +process.env.NODE_ENV = 'test' + +require("chai").should() + +global.application = require '../../../app'