mirror of
https://github.com/HackPlan/RootPanel.git
synced 2026-01-12 22:27:09 +08:00
Fixbugs, Add tests, Admin dashboard
This commit is contained in:
14
bower.json
14
bower.json
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "rootpanel",
|
||||
"dependencies": {
|
||||
"bootstrap": "~3.3.1",
|
||||
"jquery-cookie": "~1.4.1",
|
||||
"underscore": "~1.7.0",
|
||||
"jquery": "~2.1.2",
|
||||
"backbone": "~1.1.2",
|
||||
"moment": "~2.9.0",
|
||||
"bootstrap": "3.3.1",
|
||||
"jquery-cookie": "1.4.1",
|
||||
"underscore": "1.7.0",
|
||||
"jquery": "2.1.2",
|
||||
"backbone": "1.1.2",
|
||||
"moment": "2.9.0",
|
||||
"jquery-tmpl": "git://github.com/jquery/jquery-tmpl.git#b504c8afba",
|
||||
"q": "~1.2.0"
|
||||
"q": "1.2.0"
|
||||
},
|
||||
"overrides": {
|
||||
"jquery-tmpl": {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
_ = require 'lodash'
|
||||
Q = require 'q'
|
||||
|
||||
{Component} = root
|
||||
|
||||
###
|
||||
Class: Billing Plan, Managed by {BillingManager}.
|
||||
###
|
||||
|
||||
@@ -241,11 +241,15 @@ Account.register = ({username, email, password}) ->
|
||||
preferences:
|
||||
avatar_url: avatar_url
|
||||
|
||||
root.hooks.executeHooks('account.before_register',
|
||||
root.hooks.executeHooks 'account.before_register',
|
||||
execute: 'filter'
|
||||
params: [account]
|
||||
).then ->
|
||||
.then ->
|
||||
account.save()
|
||||
.tap ->
|
||||
root.hooks.executeHooks 'account.after_register',
|
||||
execute: 'action'
|
||||
params: [account]
|
||||
|
||||
###
|
||||
Public: Create token for this account.
|
||||
@@ -397,6 +401,11 @@ Account::joinGroup = (group) ->
|
||||
$addToSet:
|
||||
groups: group
|
||||
|
||||
Account::leaveGroup = (group) ->
|
||||
@update
|
||||
$pull:
|
||||
groups: group
|
||||
|
||||
###
|
||||
Public: Set email.
|
||||
|
||||
|
||||
@@ -111,8 +111,7 @@ Component::setStatus = (status) ->
|
||||
Return {Promise}.
|
||||
###
|
||||
Component::destroy = ->
|
||||
@populate().then =>
|
||||
@provider.destroyComponent @
|
||||
@provider.destroyComponent @
|
||||
|
||||
###
|
||||
Public: Check has specified member.
|
||||
|
||||
@@ -10,9 +10,23 @@ class Plugin
|
||||
name: null
|
||||
# Public: {String}
|
||||
path: null
|
||||
# Public: {Object}
|
||||
config: {}
|
||||
# Public: {Array} or {String}
|
||||
dependencies: []
|
||||
|
||||
@create: ({PluginClass, name, path, config}) ->
|
||||
instance = new PluginClass()
|
||||
|
||||
_.extend instance,
|
||||
name: name
|
||||
path: path
|
||||
config: config
|
||||
|
||||
instance.injector = new InjectorHelpers instance
|
||||
|
||||
return instance
|
||||
|
||||
###
|
||||
Public: Constructor.
|
||||
|
||||
@@ -21,6 +35,12 @@ class Plugin
|
||||
###
|
||||
constructor: (@injector) ->
|
||||
|
||||
###
|
||||
Public: Resolve path based on plugin directory.
|
||||
###
|
||||
resolve: ->
|
||||
return root.resolve 'plugins', @name, arguments...
|
||||
|
||||
###
|
||||
Public: Get translator of plugin.
|
||||
|
||||
@@ -33,20 +53,8 @@ class Plugin
|
||||
###
|
||||
Class: Private injector of {Plugin}.
|
||||
###
|
||||
class Injector
|
||||
###
|
||||
Public: Constructor.
|
||||
|
||||
###
|
||||
constructor: ->
|
||||
|
||||
###
|
||||
Public: Get owner plugin.
|
||||
|
||||
Return {Plugin}.
|
||||
###
|
||||
plugin: ->
|
||||
return @owner
|
||||
class InjectorHelpers
|
||||
constructor: (@plugin) ->
|
||||
|
||||
router: (path) ->
|
||||
router = new Router()
|
||||
@@ -55,7 +63,7 @@ class Injector
|
||||
root.routers.push
|
||||
path: path
|
||||
router: router
|
||||
plugin: @owner
|
||||
plugin: @plugin
|
||||
|
||||
return router
|
||||
|
||||
@@ -64,42 +72,42 @@ class Injector
|
||||
###
|
||||
hook: (path, options) ->
|
||||
return root.hooks.register path, _.extend options,
|
||||
plugin: @owner
|
||||
plugin: @plugin
|
||||
|
||||
###
|
||||
Public: Register a view, proxy of {ViewRegistry::register}.
|
||||
###
|
||||
view: (view, options) ->
|
||||
return root.views.register view, _.extend options,
|
||||
plugin: @owner
|
||||
plugin: @plugin
|
||||
|
||||
###
|
||||
Public: Register a widget, proxy of {WidgetRegistry::register}.
|
||||
###
|
||||
widget: (view, options) ->
|
||||
return root.widgets.register view, _.extend options,
|
||||
plugin: @owner
|
||||
plugin: @plugin
|
||||
|
||||
###
|
||||
Public: Register a component, proxy of {ComponentRegistry::register}.
|
||||
###
|
||||
component: (name, options) ->
|
||||
return root.components.register name, _.extend options,
|
||||
plugin: @owner
|
||||
plugin: @plugin
|
||||
|
||||
###
|
||||
Public: Register a coupon type, proxy of {CouponTypeRegistry::register}.
|
||||
###
|
||||
couponType: (name, options) ->
|
||||
return root.couponTypes.register name, _.extend options,
|
||||
plugin: @owner
|
||||
plugin: @plugin
|
||||
|
||||
###
|
||||
Public: Register a payment provider, proxy of {PaymentProviderRegistry::register}.
|
||||
###
|
||||
paymentProvider: (name, options) ->
|
||||
return root.paymentProviders.register name, _.extend options,
|
||||
plugin: @owner
|
||||
plugin: @plugin
|
||||
|
||||
###
|
||||
Manager: Plugin manager,
|
||||
@@ -126,16 +134,11 @@ module.exports = class PluginManager
|
||||
if @plugins[name]
|
||||
throw new Error "Plugin `#{name}` already exists"
|
||||
|
||||
Plugin = require path
|
||||
|
||||
injector = new Injector()
|
||||
plugin = new Plugin injector, config
|
||||
|
||||
injector.owner = plugin
|
||||
|
||||
@plugins[name] = _.extend plugin,
|
||||
@plugins[name] = plugin = Plugin.create
|
||||
name: name
|
||||
path: path
|
||||
config: config
|
||||
PluginClass: require path
|
||||
|
||||
plugin.activate()
|
||||
|
||||
@@ -166,6 +169,12 @@ module.exports = class PluginManager
|
||||
|
||||
return {
|
||||
routers: filter root.routers
|
||||
hooks: filter root.hooks.getHooksAsArray()
|
||||
views: filter root.views.getExpansionsAsArray()
|
||||
widgets: filter root.widgets.getWidgetsAsArray()
|
||||
components: filter root.components.all()
|
||||
couponTypes: filter root.couponTypes.all()
|
||||
paymentProviders: filter root.paymentProviders.all()
|
||||
}
|
||||
|
||||
PluginManager.Plugin = Plugin
|
||||
|
||||
@@ -9,8 +9,10 @@ module.exports = class HookRegistry
|
||||
constructor: ->
|
||||
@hooks =
|
||||
account:
|
||||
# filter: (account) -> Promise
|
||||
# action: (account) -> Promise
|
||||
before_register: []
|
||||
# action: (account) -> Promise
|
||||
after_register: []
|
||||
|
||||
###
|
||||
Public: Register a hook.
|
||||
@@ -38,13 +40,13 @@ module.exports = class HookRegistry
|
||||
|
||||
Return {Array}.
|
||||
###
|
||||
applyHooks: (path, {execute, pluck, req, payload} = {}) ->
|
||||
applyHooks: (path, {execute, pluck, req, params} = {}) ->
|
||||
return _.compact @getHooks(path).map (hook) ->
|
||||
if execute
|
||||
return hook[execute].call
|
||||
return hook[execute].apply
|
||||
req: req
|
||||
plugin: hook.plugin
|
||||
, payload
|
||||
, params
|
||||
|
||||
else if pluck
|
||||
return hook[pluck]
|
||||
@@ -63,6 +65,9 @@ module.exports = class HookRegistry
|
||||
Q.all @applyHooks arguments...
|
||||
|
||||
getHooks: (path, {array, object} = {}) ->
|
||||
unless path
|
||||
return @hooks
|
||||
|
||||
words = path.split '.'
|
||||
last = words.pop()
|
||||
|
||||
@@ -78,3 +83,26 @@ module.exports = class HookRegistry
|
||||
ref[last] ?= {}
|
||||
|
||||
return ref[last]
|
||||
|
||||
getHooksAsArray: (path) ->
|
||||
if path
|
||||
currentPaths = path.split '.'
|
||||
else
|
||||
currentPaths = []
|
||||
|
||||
result = []
|
||||
|
||||
iterator = (hooks) ->
|
||||
for k, v of hooks
|
||||
if _.isArray v
|
||||
for hook in v
|
||||
result.push _.extend {}, hook,
|
||||
path: [currentPaths..., k].join '.'
|
||||
else if _.isObject v
|
||||
currentPaths.push k
|
||||
iterator v
|
||||
currentPaths.pop()
|
||||
|
||||
iterator @getHooks path
|
||||
|
||||
return result
|
||||
|
||||
@@ -84,3 +84,8 @@ module.exports = class ViewRegistry
|
||||
fs.read(filename).then (source) ->
|
||||
return jade.compile extendSource(source.toString()),
|
||||
filename: filename
|
||||
|
||||
getExpansionsAsArray: ->
|
||||
return _.flatten _.map @viewExtends, (expansion, view) ->
|
||||
return _.extend {}, expansion,
|
||||
view: view
|
||||
|
||||
@@ -158,3 +158,8 @@ module.exports = class WidgetRegistry
|
||||
|
||||
.then (result) ->
|
||||
return _.compact result
|
||||
|
||||
getWidgetsAsArray: ->
|
||||
return _.flatten _.map @widgets, (widget, view) ->
|
||||
return _.extend {}, widget,
|
||||
view: view
|
||||
|
||||
@@ -34,7 +34,18 @@ router.get '/', (req, res, next) ->
|
||||
|
||||
Response {Component}.
|
||||
###
|
||||
router.post '/:type', (req, res) ->
|
||||
router.post '/:type', (req, res, next) ->
|
||||
{account, params: {type}, body: {name, options}} = req
|
||||
|
||||
unless type in root.billing.availableComponents(account)
|
||||
next new Error 'component_not_available'
|
||||
|
||||
root.components.byName(type).create account, root.servers.master(),
|
||||
name: name
|
||||
options: options
|
||||
.done (component) ->
|
||||
res.send component
|
||||
, next
|
||||
|
||||
###
|
||||
Router: PATCH /components/:id
|
||||
@@ -46,6 +57,9 @@ router.patch '/:id', (req, res) ->
|
||||
###
|
||||
Router: DELETE /components/:id
|
||||
###
|
||||
router.delete '/:id', (req, res) ->
|
||||
router.delete '/:id', (req, res, next) ->
|
||||
req.component.destroy().done ->
|
||||
res.sendStatus 204
|
||||
, next
|
||||
|
||||
router.all '/:id/actions/:action', (req, res) ->
|
||||
|
||||
@@ -157,7 +157,7 @@ module.exports = class ServerManager
|
||||
constructor: (@config) ->
|
||||
@servers = {}
|
||||
|
||||
for name, options of @config
|
||||
for name, options of @config.servers
|
||||
@servers[name] = new ServerNode _.extend options,
|
||||
name: name
|
||||
|
||||
@@ -180,5 +180,5 @@ module.exports = class ServerManager
|
||||
return @servers[name]
|
||||
|
||||
master: ->
|
||||
return _.findWhere @servers,
|
||||
return _.findWhere @all(),
|
||||
master: true
|
||||
|
||||
21
core/test/manager/billing.test.coffee
Normal file
21
core/test/manager/billing.test.coffee
Normal file
@@ -0,0 +1,21 @@
|
||||
{createAccount} = helpers
|
||||
|
||||
describe 'manager.billing', ->
|
||||
describe 'addMember and removeMember', ->
|
||||
account = null
|
||||
plan = null
|
||||
|
||||
before ->
|
||||
plan = root.billing.byName 'sample'
|
||||
createAccount().then (result) ->
|
||||
account = result
|
||||
|
||||
it '::addMember', ->
|
||||
plan.addMember account
|
||||
|
||||
it '::hasMember', ->
|
||||
plan.hasMember(account).should.be.true
|
||||
|
||||
it '::removeMember', ->
|
||||
plan.removeMember(account).then ->
|
||||
plan.hasMember(account).should.be.false
|
||||
@@ -1,5 +1,7 @@
|
||||
{createAccount, randomAccount} = helpers
|
||||
|
||||
describe 'model.account', ->
|
||||
Account = require '../../model/account'
|
||||
{Account} = root
|
||||
|
||||
describe '.register', ->
|
||||
it 'should success', ->
|
||||
@@ -39,3 +41,14 @@ describe 'model.account', ->
|
||||
_.findWhere(account.tokens,
|
||||
code: code
|
||||
).type.should.be.equal 'full_access'
|
||||
|
||||
describe '::inGroup, ::joinGroup, ::leaveGroup', ->
|
||||
it 'should success', ->
|
||||
createAccount().then (account) ->
|
||||
account.joinGroup('test').then ->
|
||||
account.inGroup('test').should.be.true
|
||||
account.inGroup('root').should.be.false
|
||||
.then ->
|
||||
account.leaveGroup 'test'
|
||||
.then ->
|
||||
account.inGroup('test').should.be.false
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{createAccount} = helpers
|
||||
|
||||
describe 'model.component', ->
|
||||
Component = require '../../model/component'
|
||||
{Component} = root
|
||||
|
||||
describe '.createComponent', ->
|
||||
it 'should success', ->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
describe 'model.coupon-code', ->
|
||||
CouponCode = require '../../model/coupon-code'
|
||||
{CouponCode} = root
|
||||
|
||||
describe '.createCoupons', ->
|
||||
it 'should success', ->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
describe 'model.financials', ->
|
||||
Account = require '../../model/account'
|
||||
Financials = require '../../model/financials'
|
||||
{createAccount} = helpers
|
||||
|
||||
describe 'model.financials', ->
|
||||
{Account, Financials} = root
|
||||
{PaymentProvider} = require root.resolve 'core/registry/payment-provider'
|
||||
provider = new PaymentProvider name: 'taobao'
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{createAccount} = helpers
|
||||
|
||||
describe 'model.notification', ->
|
||||
Notification = require '../../model/notification'
|
||||
{Notification} = root
|
||||
|
||||
describe '::isGroupNotice', ->
|
||||
it 'return true', ->
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{createAccount} = helpers
|
||||
|
||||
describe 'model.security-log', ->
|
||||
SecurityLog = require '../../model/security-log'
|
||||
{Token} = require '../../model/account'
|
||||
{SecurityLog, Account: {Token}} = root
|
||||
|
||||
describe '.createLog', ->
|
||||
it 'should success', ->
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{createAccount, createAdmin, createTicket} = helpers
|
||||
|
||||
describe 'model.ticket', ->
|
||||
Ticket = require '../../model/ticket'
|
||||
{Ticket} = root
|
||||
|
||||
describe '.createTicket', ->
|
||||
it 'should success', ->
|
||||
|
||||
35
core/test/registry/component.test.coffee
Normal file
35
core/test/registry/component.test.coffee
Normal file
@@ -0,0 +1,35 @@
|
||||
{createAccount} = helpers
|
||||
|
||||
describe 'registry.component', ->
|
||||
{Component} = root
|
||||
|
||||
describe 'ComponentProvider', ->
|
||||
describe 'create and destroyComponent', ->
|
||||
initializeCount = 0
|
||||
destroyCount = 0
|
||||
|
||||
before ->
|
||||
root.components.register 'mock',
|
||||
plugin:
|
||||
name: 'mock'
|
||||
|
||||
initialize: (component) ->
|
||||
initializeCount++
|
||||
|
||||
destroy: (component) ->
|
||||
destroyCount++
|
||||
|
||||
it 'should success', ->
|
||||
provider = root.components.byName 'mock.mock'
|
||||
|
||||
createAccount().then (account) ->
|
||||
provider.create account, root.servers.master(),
|
||||
name: 'test'
|
||||
.then (component) ->
|
||||
initializeCount.should.be.equal 1
|
||||
component.type.should.be.equal 'mock.mock'
|
||||
|
||||
provider.destroyComponent(component).then ->
|
||||
destroyCount.should.be.equal 1
|
||||
Component.findById(component._id).then (component) ->
|
||||
expect(component).to.not.exists
|
||||
@@ -1,3 +1,5 @@
|
||||
{createAgent, randomAccount} = helpers
|
||||
|
||||
describe 'router.account', ->
|
||||
agent = createAgent
|
||||
baseUrl: '/account'
|
||||
|
||||
1
core/test/router/component.test.coffee
Normal file
1
core/test/router/component.test.coffee
Normal file
@@ -0,0 +1 @@
|
||||
describe 'router.component', ->
|
||||
@@ -1,3 +1,5 @@
|
||||
{createLoggedAgent} = helpers
|
||||
|
||||
describe 'router.tickets', ->
|
||||
agent = createLoggedAgent
|
||||
baseUrl: '/tickets'
|
||||
|
||||
@@ -2,31 +2,3 @@
|
||||
h1
|
||||
| RootPanel
|
||||
small= root.package.version
|
||||
|
||||
.row
|
||||
header 付费方案
|
||||
|
||||
for plan in root.billing.all()
|
||||
.col-md-3
|
||||
.panel.panel-success
|
||||
.panel-heading
|
||||
strong= plan.name
|
||||
.panel-body
|
||||
p join_freely: #{plan.join_freely}
|
||||
p components: #{_.keys(plan.components).join()}
|
||||
p billing: #{_.keys(plan.billing).join()}
|
||||
p 用户数量:0
|
||||
|
||||
.row
|
||||
header 已加载的插件
|
||||
|
||||
for plugin in root.plugins.all()
|
||||
- registered = root.plugins.getRegisteredExtends(plugin)
|
||||
|
||||
.col-md-3
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
strong= plugin.name
|
||||
.panel-body
|
||||
p dependencies: #{_.keys(plugin.dependencies).join()}
|
||||
p routes: #{_.pluck(registered.routers, 'path').join()}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
.row
|
||||
header 付费方案
|
||||
|
||||
for plan in root.billing.all()
|
||||
.col-md-3
|
||||
.panel.panel-success
|
||||
.panel-heading
|
||||
strong= plan.name
|
||||
.panel-body
|
||||
p join_freely: #{plan.join_freely}
|
||||
p components: #{_.keys(plan.components).join()}
|
||||
p billing: #{_.keys(plan.billing).join()}
|
||||
p 用户数量:0
|
||||
|
||||
.row
|
||||
header 已加载的插件
|
||||
|
||||
for plugin in root.plugins.all()
|
||||
- registered = root.plugins.getRegisteredExtends(plugin)
|
||||
|
||||
.col-md-6
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
strong= plugin.name
|
||||
.panel-body
|
||||
p dependencies: #{_.keys(plugin.dependencies).join()}
|
||||
p routes: #{_.pluck(registered.routers, 'path').join()}
|
||||
p hooks: #{_.pluck(registered.hooks, 'path').join()}
|
||||
p views: #{_.pluck(registered.views, 'view').join()}
|
||||
p widgets: #{_.pluck(registered.widgets, 'view').join()}
|
||||
p components: #{_.pluck(registered.components, 'name').join()}
|
||||
p couponTypes: #{_.pluck(registered.couponTypes, 'name').join()}
|
||||
p paymentProviders: #{_.pluck(registered.paymentProviders, 'name').join()}
|
||||
|
||||
108
package.json
108
package.json
@@ -19,67 +19,67 @@
|
||||
"scripts": {
|
||||
"prepushlish": "bower install && gulp build",
|
||||
"start": "coffee app.coffee",
|
||||
"test": "mocha --compilers coffee:coffee-script/register --require test/env --recursive core/test",
|
||||
"test": "mocha --compilers coffee:coffee-script/register --require test/init --recursive core/test",
|
||||
"docker-build": "docker build -t=jysperm/rootpanel .",
|
||||
"docker-create": "docker run --name rootpanel -P -v `pwd`:/rootpanel -i -t jysperm/rootpanel",
|
||||
"docker-create": "docker run --name rootpanel -P jysperm/rootpanel",
|
||||
"docker-start": "docker start -i -a rootpanel"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^0.9.0",
|
||||
"async-q": "^0.2.2",
|
||||
"body-parser": "^1.9.3",
|
||||
"bower": "^1.3.12",
|
||||
"bunyan-mongo": "^0.1.0",
|
||||
"coffee-script": "^1.8.0",
|
||||
"connect-redis": "^2.1.0",
|
||||
"cookie-parser": "^1.3.3",
|
||||
"counter-cache": "^0.1.0",
|
||||
"csrf": "^2.0.2",
|
||||
"deepmerge": "^0.2.7",
|
||||
"express": "^4.10.4",
|
||||
"express-bunyan-logger": "^1.1.0",
|
||||
"express-session": "^1.9.2",
|
||||
"insight": "^0.5.3",
|
||||
"jade": "^1.9.2",
|
||||
"json-stable-stringify": "^1.0.0",
|
||||
"lodash": "^3.6.0",
|
||||
"mabolo": "^0.3.1",
|
||||
"markdown": "^0.5.0",
|
||||
"moment-timezone": "^0.2.5",
|
||||
"mongodb": "^2.0.7",
|
||||
"morgan": "^1.5.0",
|
||||
"mysql": "^2.5.3",
|
||||
"negotiator": "^0.4.9",
|
||||
"nodemailer": "^1.3.0",
|
||||
"q": "^1.2.0",
|
||||
"q-io": "^1.12.0",
|
||||
"redis": "^0.12.1",
|
||||
"request": "^2.55.0",
|
||||
"semver": "^4.1.0",
|
||||
"ssh2": "^0.3.6",
|
||||
"underscore": "^1.7.0",
|
||||
"validator": "^3.37.0",
|
||||
"ioredis": "^1.3.6"
|
||||
"async": "0.9.0",
|
||||
"async-q": "0.2.2",
|
||||
"body-parser": "1.9.3",
|
||||
"bower": "1.3.12",
|
||||
"bunyan-mongo": "0.1.0",
|
||||
"coffee-script": "1.8.0",
|
||||
"connect-redis": "2.1.0",
|
||||
"cookie-parser": "1.3.3",
|
||||
"counter-cache": "0.1.0",
|
||||
"csrf": "2.0.2",
|
||||
"deepmerge": "0.2.7",
|
||||
"express": "4.10.4",
|
||||
"express-bunyan-logger": "1.1.0",
|
||||
"express-session": "1.9.2",
|
||||
"insight": "0.5.3",
|
||||
"jade": "1.9.2",
|
||||
"json-stable-stringify": "1.0.0",
|
||||
"lodash": "3.6.0",
|
||||
"mabolo": "0.3.2",
|
||||
"markdown": "0.5.0",
|
||||
"moment-timezone": "0.2.5",
|
||||
"mongodb": "2.0.7",
|
||||
"morgan": "1.5.0",
|
||||
"mysql": "2.5.3",
|
||||
"negotiator": "0.4.9",
|
||||
"nodemailer": "1.3.0",
|
||||
"q": "1.2.0",
|
||||
"q-io": "1.12.0",
|
||||
"redis": "0.12.1",
|
||||
"request": "2.55.0",
|
||||
"semver": "4.1.0",
|
||||
"ssh2": "0.3.6",
|
||||
"underscore": "1.7.0",
|
||||
"validator": "3.37.0",
|
||||
"ioredis": "1.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^1.10.0",
|
||||
"chai": "1.10.0",
|
||||
"coffee-coverage": "0.4.2",
|
||||
"del": "^1.1.1",
|
||||
"gulp": "^3.8.11",
|
||||
"gulp-coffee": "^2.3.1",
|
||||
"gulp-concat": "^2.5.2",
|
||||
"gulp-debug": "^2.0.1",
|
||||
"gulp-filter": "^2.0.2",
|
||||
"gulp-less": "^3.0.3",
|
||||
"gulp-minify-css": "^1.1.0",
|
||||
"gulp-order": "^1.1.1",
|
||||
"del": "1.1.1",
|
||||
"gulp": "3.8.11",
|
||||
"gulp-coffee": "2.3.1",
|
||||
"gulp-concat": "2.5.2",
|
||||
"gulp-debug": "2.0.1",
|
||||
"gulp-filter": "2.0.2",
|
||||
"gulp-less": "3.0.3",
|
||||
"gulp-minify-css": "1.1.0",
|
||||
"gulp-order": "1.1.1",
|
||||
"gulp-rsync": "0.0.5",
|
||||
"gulp-shell": "^0.4.1",
|
||||
"gulp-uglify": "^1.2.0",
|
||||
"main-bower-files": "^2.7.0",
|
||||
"mocha": "^2.0.1",
|
||||
"mocha-reporter-cov-summary": "^0.1.0",
|
||||
"run-sequence": "^1.1.0",
|
||||
"supertest": "^0.15.0"
|
||||
"gulp-shell": "0.4.1",
|
||||
"gulp-uglify": "1.2.0",
|
||||
"main-bower-files": "2.7.0",
|
||||
"mocha": "2.0.1",
|
||||
"mocha-reporter-cov-summary": "0.1.0",
|
||||
"run-sequence": "1.1.0",
|
||||
"supertest": "0.15.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{Account, CouponCode} = root
|
||||
|
||||
module.exports = class Builtin extends root.Plugin
|
||||
activate: ->
|
||||
@injector.couponType 'cash', new CashCoupon()
|
||||
@@ -5,6 +7,12 @@ module.exports = class Builtin extends root.Plugin
|
||||
@injector.router('/').get '/', (req, res) ->
|
||||
res.redirect '/panel/'
|
||||
|
||||
@injector.hook 'account.after_register',
|
||||
action: (account) ->
|
||||
Account.count().then (count) ->
|
||||
if count == 1
|
||||
account.joinGroup 'root'
|
||||
|
||||
class CashCoupon
|
||||
validate: (account, coupon) ->
|
||||
apply_log = _.find coupon.apply_log, (log) ->
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
validator = require 'validator'
|
||||
|
||||
module.exports = class Linux
|
||||
constructor: (@injector, {@monitor_cycle}) ->
|
||||
{requireAuthenticate} = root.middleware
|
||||
{requireAuthenticate} = root.middleware
|
||||
|
||||
module.exports = class Linux extends root.Plugin
|
||||
activate: ->
|
||||
@injector.view 'layout',
|
||||
filename: __dirname + '/view/layout'
|
||||
locals: linux: @
|
||||
filename: @resolve 'view/layout'
|
||||
locals:
|
||||
linux: @
|
||||
|
||||
@injector.router('/public/monitor').get '/node?', requireAuthenticate, (req, res) =>
|
||||
server = @getLinuxServer req.params.node
|
||||
|
||||
Q.all([
|
||||
server.system()
|
||||
server.getStorageUsages()
|
||||
server.getProcessList()
|
||||
server.getMemoryUsages()
|
||||
]).then ([system, storage, processes, memory]) ->
|
||||
res.render __dirname + '/view/monitor',
|
||||
Q.all
|
||||
system: server.system()
|
||||
storage: server.getStorageUsages()
|
||||
processes: server.getProcessList()
|
||||
memory: server.getMemoryUsages()
|
||||
.then (statistics) ->
|
||||
res.render @resolve('view/monitor'),
|
||||
system: system
|
||||
storage: storage
|
||||
processes: processes
|
||||
@@ -50,12 +51,12 @@ module.exports = class Linux
|
||||
repeating:
|
||||
every: 'linux'
|
||||
generator: (account, component) ->
|
||||
root.views.render __dirname + '/view/widget'
|
||||
root.views.render @resolve 'view/widget'
|
||||
|
||||
if @monitor_cycle
|
||||
if @config.monitor_cycle
|
||||
@monitors = root.servers.all().map ({name}) =>
|
||||
return new LinuxMonitoring @getLinuxServer(name),
|
||||
monitor_cycle: @monitor_cycle
|
||||
monitor_cycle: @config.monitor_cycle
|
||||
|
||||
getLinuxServer: (node) ->
|
||||
if node
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"name": "rootpanel-linux",
|
||||
"version": "0.1.0"
|
||||
"version": "0.9.0"
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ module.exports =
|
||||
arrears_above: 0
|
||||
|
||||
plans:
|
||||
all:
|
||||
sample:
|
||||
name: 'plans.sample.name'
|
||||
description: 'plans.sample.description'
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ expect = chai.expect
|
||||
|
||||
methods = ['get', 'post', 'delete', 'put', 'patch', 'head', 'options']
|
||||
|
||||
module.exports = createAgent = (agent_options) ->
|
||||
module.exports = (agent_options) ->
|
||||
if _.isNumber config.web.listen
|
||||
prefix = "http://127.0.0.1:#{config.web.listen}"
|
||||
else
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
request = require 'request'
|
||||
chai = require 'chai'
|
||||
_ = require 'lodash'
|
||||
Q = require 'q'
|
||||
|
||||
utils = require '../core/utils'
|
||||
createAgent = require './agent'
|
||||
@@ -55,12 +54,6 @@ createLoggedAgent = (options) ->
|
||||
return agent
|
||||
|
||||
module.exports = {
|
||||
_
|
||||
Q
|
||||
chai
|
||||
utils
|
||||
expect
|
||||
|
||||
ifEnabled
|
||||
unlessTravis
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
process.env.NODE_ENV = 'test'
|
||||
|
||||
chai = require 'chai'
|
||||
_ = require 'lodash'
|
||||
Q = require 'q'
|
||||
|
||||
Root = require '../core'
|
||||
snippet = require './snippet'
|
||||
|
||||
global.config = require '../sample/core.config.coffee'
|
||||
global.helpers = require './helpers'
|
||||
global.root = new Root config
|
||||
|
||||
root.start()
|
||||
|
||||
_.extend global, snippet
|
||||
_.extend global,
|
||||
expect: chai.expect
|
||||
Q: Q
|
||||
_: _
|
||||
|
||||
chai.should()
|
||||
chai.config.includeStack = true
|
||||
|
||||
Q.longStackSupport = true
|
||||
Reference in New Issue
Block a user