2014-03-03 16:35:21 -05:00
"use strict" ;
var async = require ( 'async' ) ,
2014-09-29 17:51:18 -04:00
fs = require ( 'fs' ) ,
path = require ( 'path' ) ,
2015-04-16 11:30:53 +02:00
nconf = require ( 'nconf' ) ,
2014-03-03 16:35:21 -05:00
2014-03-13 23:43:36 -04:00
user = require ( '../user' ) ,
categories = require ( '../categories' ) ,
2015-03-25 15:42:15 -04:00
privileges = require ( '../privileges' ) ,
2014-10-07 16:21:12 -04:00
posts = require ( '../posts' ) ,
2014-03-13 23:43:36 -04:00
topics = require ( '../topics' ) ,
meta = require ( '../meta' ) ,
db = require ( '../database' ) ,
events = require ( '../events' ) ,
languages = require ( '../languages' ) ,
plugins = require ( '../plugins' ) ,
widgets = require ( '../widgets' ) ,
groups = require ( '../groups' ) ,
2014-03-13 14:08:58 -04:00
validator = require ( 'validator' ) ;
2014-03-12 17:34:59 -04:00
2014-03-03 16:35:21 -05:00
var adminController = {
categories : { } ,
2014-08-17 19:26:24 -04:00
tags : { } ,
2014-10-07 16:21:12 -04:00
flags : { } ,
2014-03-03 16:35:21 -05:00
topics : { } ,
groups : { } ,
2014-09-25 13:12:51 -04:00
appearance : { } ,
2014-09-28 20:22:04 -04:00
extend : {
widgets : { }
} ,
2014-03-03 16:35:21 -05:00
events : { } ,
2014-10-03 16:31:53 -04:00
logs : { } ,
2014-03-03 16:35:21 -05:00
database : { } ,
2015-04-20 18:23:09 -04:00
postCache : { } ,
2014-03-03 16:35:21 -05:00
plugins : { } ,
languages : { } ,
settings : { } ,
2014-03-12 17:34:59 -04:00
logger : { } ,
2014-03-17 10:37:11 -04:00
sounds : { } ,
2015-02-26 14:10:41 -05:00
homepage : { } ,
2015-02-25 14:50:45 -05:00
navigation : { } ,
2014-09-29 17:51:18 -04:00
themes : { } ,
2014-03-12 17:59:29 -04:00
users : require ( './admin/users' ) ,
uploads : require ( './admin/uploads' )
2014-03-03 16:35:21 -05:00
} ;
adminController . home = function ( req , res , next ) {
2014-07-14 14:28:19 -04:00
async . parallel ( {
stats : function ( next ) {
getStats ( next ) ;
} ,
notices : function ( next ) {
var notices = [
2014-11-17 14:07:34 -05:00
{ done : ! meta . reloadRequired , doneText : 'Reload not required' , notDoneText : 'Reload required' } ,
2014-07-14 14:28:19 -04:00
{ done : plugins . hasListeners ( 'action:email.send' ) , doneText : 'Emailer Installed' , notDoneText : 'Emailer not installed' } ,
{ done : plugins . hasListeners ( 'filter:search.query' ) , doneText : 'Search Plugin Installed' , notDoneText : 'Search Plugin not installed' }
] ;
plugins . fireHook ( 'filter:admin.notices' , notices , next ) ;
}
} , function ( err , results ) {
2014-07-01 16:30:06 -04:00
if ( err ) {
return next ( err ) ;
}
2014-09-28 21:20:34 -04:00
res . render ( 'admin/general/dashboard' , {
2015-04-16 11:30:53 +02:00
version : nconf . get ( 'version' ) ,
2014-07-14 14:28:19 -04:00
notices : results . notices ,
2014-09-27 16:06:01 -04:00
stats : results . stats
2014-07-01 16:30:06 -04:00
} ) ;
2014-03-09 20:05:14 -04:00
} ) ;
2014-03-03 16:35:21 -05:00
} ;
2014-07-01 16:30:06 -04:00
function getStats ( callback ) {
async . parallel ( [
function ( next ) {
2014-10-13 15:06:21 -04:00
getStatsForSet ( 'ip:recent' , 'uniqueIPCount' , next ) ;
2014-07-01 16:30:06 -04:00
} ,
function ( next ) {
2014-10-13 15:06:21 -04:00
getStatsForSet ( 'users:joindate' , 'userCount' , next ) ;
2014-07-01 16:30:06 -04:00
} ,
function ( next ) {
2014-10-13 15:06:21 -04:00
getStatsForSet ( 'posts:pid' , 'postCount' , next ) ;
2014-07-01 16:30:06 -04:00
} ,
function ( next ) {
2014-10-13 15:06:21 -04:00
getStatsForSet ( 'topics:tid' , 'topicCount' , next ) ;
2014-07-01 16:30:06 -04:00
}
] , function ( err , results ) {
if ( err ) {
return callback ( err ) ;
}
results [ 0 ] . name = 'Unique Visitors' ;
results [ 1 ] . name = 'Users' ;
results [ 2 ] . name = 'Posts' ;
results [ 3 ] . name = 'Topics' ;
callback ( null , results ) ;
} ) ;
}
2014-10-13 15:06:21 -04:00
function getStatsForSet ( set , field , callback ) {
2014-07-01 16:30:06 -04:00
var terms = {
day : 86400000 ,
week : 604800000 ,
month : 2592000000
} ;
2014-10-13 15:06:21 -04:00
2014-07-01 16:30:06 -04:00
var now = Date . now ( ) ;
async . parallel ( {
day : function ( next ) {
db . sortedSetCount ( set , now - terms . day , now , next ) ;
} ,
week : function ( next ) {
db . sortedSetCount ( set , now - terms . week , now , next ) ;
} ,
month : function ( next ) {
db . sortedSetCount ( set , now - terms . month , now , next ) ;
} ,
alltime : function ( next ) {
2015-02-03 18:13:34 -05:00
getGlobalField ( field , next ) ;
2014-07-01 16:30:06 -04:00
}
} , callback ) ;
}
2015-02-03 18:13:34 -05:00
function getGlobalField ( field , callback ) {
db . getObjectField ( 'global' , field , function ( err , count ) {
callback ( err , parseInt ( count , 10 ) || 0 ) ;
} ) ;
}
2014-12-29 15:52:00 -05:00
adminController . categories . get = function ( req , res , next ) {
2015-03-25 15:42:15 -04:00
async . parallel ( {
2015-03-25 17:21:38 -04:00
category : async . apply ( categories . getCategories , [ req . params . category _id ] , req . user . uid ) ,
2015-03-25 15:42:15 -04:00
privileges : async . apply ( privileges . categories . list , req . params . category _id )
} , function ( err , data ) {
2014-12-29 21:37:55 -05:00
if ( err ) {
return next ( err ) ;
}
2015-04-06 16:17:29 -04:00
2015-04-01 18:22:55 +03:00
plugins . fireHook ( 'filter:admin.category.get' , { req : req , res : res , category : data . category [ 0 ] , privileges : data . privileges } , function ( err , data ) {
2015-04-01 15:11:15 +03:00
if ( err ) {
return next ( err ) ;
}
2015-04-06 16:17:29 -04:00
2015-04-01 18:22:55 +03:00
res . render ( 'admin/manage/category' , {
category : data . category ,
privileges : data . privileges
} ) ;
} ) ;
2014-12-29 21:37:55 -05:00
} ) ;
2014-12-29 21:20:43 -05:00
} ;
adminController . categories . getAll = function ( req , res , next ) {
2015-04-01 00:23:57 -04:00
var active = [ ] ,
2014-12-29 15:52:00 -05:00
disabled = [ ] ;
2014-03-13 14:08:58 -04:00
2015-04-06 16:17:29 -04:00
async . waterfall ( [
function ( next ) {
db . getSortedSetRange ( 'categories:cid' , 0 , - 1 , next ) ;
} ,
function ( cids , next ) {
categories . getCategoriesData ( cids , next ) ;
} ,
function ( categories , next ) {
plugins . fireHook ( 'filter:admin.categories.get' , { req : req , res : res , categories : categories } , next ) ;
}
] , function ( err , data ) {
2014-08-22 19:10:26 -04:00
if ( err ) {
return next ( err ) ;
}
2015-04-06 16:17:29 -04:00
data . categories . filter ( Boolean ) . forEach ( function ( category ) {
( category . disabled ? disabled : active ) . push ( category ) ;
} ) ;
res . render ( 'admin/manage/categories' , {
active : active ,
disabled : disabled
2014-09-17 16:07:26 -04:00
} ) ;
2014-03-03 16:35:21 -05:00
} ) ;
2014-12-29 15:52:00 -05:00
} ;
2014-03-03 16:35:21 -05:00
2014-08-17 19:26:24 -04:00
adminController . tags . get = function ( req , res , next ) {
2014-11-13 14:36:44 -05:00
topics . getTags ( 0 , 199 , function ( err , tags ) {
2014-08-17 19:26:24 -04:00
if ( err ) {
return next ( err ) ;
}
2014-09-28 21:20:34 -04:00
res . render ( 'admin/manage/tags' , { tags : tags } ) ;
2014-08-17 19:26:24 -04:00
} ) ;
} ;
2014-10-07 16:21:12 -04:00
adminController . flags . get = function ( req , res , next ) {
2015-02-19 15:56:04 -05:00
function done ( err , posts ) {
2014-10-07 16:21:12 -04:00
if ( err ) {
return next ( err ) ;
}
2015-03-31 23:40:58 -04:00
res . render ( 'admin/manage/flags' , { posts : posts , next : stop + 1 , byUsername : byUsername } ) ;
2015-02-19 15:56:04 -05:00
}
2015-04-01 00:23:57 -04:00
2015-02-19 15:56:04 -05:00
var sortBy = req . query . sortBy || 'count' ;
var byUsername = req . query . byUsername || '' ;
var start = 0 ;
2015-03-31 23:40:58 -04:00
var stop = 19 ;
2015-02-19 15:56:04 -05:00
if ( byUsername ) {
2015-04-01 00:23:57 -04:00
posts . getUserFlags ( byUsername , sortBy , req . uid , start , stop , done ) ;
2015-02-19 15:56:04 -05:00
} else {
var set = sortBy === 'count' ? 'posts:flags:count' : 'posts:flagged' ;
2015-04-01 00:23:57 -04:00
posts . getFlags ( set , req . uid , start , stop , done ) ;
2015-03-31 23:40:58 -04:00
}
2014-10-07 16:21:12 -04:00
} ;
2014-03-03 16:35:21 -05:00
adminController . database . get = function ( req , res , next ) {
2015-05-08 15:36:06 -04:00
async . parallel ( {
redis : function ( next ) {
if ( nconf . get ( 'redis' ) ) {
var rdb = require ( '../database/redis' ) ;
var cxn = rdb . connect ( ) ;
rdb . info ( cxn , next ) ;
} else {
next ( ) ;
}
} ,
mongo : function ( next ) {
if ( nconf . get ( 'mongo' ) ) {
var mdb = require ( '../database/mongo' ) ;
mdb . info ( mdb . client , next ) ;
} else {
next ( ) ;
}
}
} , function ( err , results ) {
if ( err ) {
return next ( err ) ;
}
res . render ( 'admin/advanced/database' , results ) ;
2014-03-03 16:35:21 -05:00
} ) ;
} ;
adminController . events . get = function ( req , res , next ) {
2015-02-01 19:11:58 -05:00
events . getEvents ( 0 , 19 , function ( err , events ) {
if ( err || ! events ) {
2014-03-03 16:35:21 -05:00
return next ( err ) ;
}
2014-03-13 14:08:58 -04:00
2014-09-28 21:09:40 -04:00
res . render ( 'admin/advanced/events' , {
2015-02-01 19:11:58 -05:00
events : events ,
next : 20
2014-03-09 20:05:14 -04:00
} ) ;
2014-03-03 16:35:21 -05:00
} ) ;
} ;
2014-10-03 16:31:53 -04:00
adminController . logs . get = function ( req , res , next ) {
2014-11-24 12:20:28 -05:00
meta . logs . get ( function ( err , logs ) {
2014-10-11 16:30:07 -04:00
res . render ( 'admin/advanced/logs' , {
2014-11-24 12:20:28 -05:00
data : validator . escape ( logs )
2014-10-03 16:31:53 -04:00
} ) ;
} ) ;
} ;
2015-04-20 18:23:09 -04:00
adminController . postCache . get = function ( req , res , next ) {
var cache = require ( '../posts/cache' ) ;
var avgPostSize = 0 ;
var percentFull = 0 ;
if ( cache . itemCount > 0 ) {
avgPostSize = parseInt ( ( cache . length / cache . itemCount ) , 10 ) ;
percentFull = ( ( cache . length / cache . max ) * 100 ) . toFixed ( 2 ) ;
}
res . render ( 'admin/advanced/post-cache' , {
cache : {
length : cache . length ,
max : cache . max ,
itemCount : cache . itemCount ,
percentFull : percentFull ,
avgPostSize : avgPostSize
}
} ) ;
} ;
2014-03-03 16:35:21 -05:00
adminController . plugins . get = function ( req , res , next ) {
2014-04-22 21:02:58 -04:00
plugins . getAll ( function ( err , plugins ) {
2014-03-03 16:35:21 -05:00
if ( err || ! Array . isArray ( plugins ) ) {
plugins = [ ] ;
}
2014-09-28 21:09:40 -04:00
res . render ( 'admin/extend/plugins' , {
2014-03-09 20:05:14 -04:00
plugins : plugins
} ) ;
2014-10-08 12:18:32 -04:00
} ) ;
2014-03-03 16:35:21 -05:00
} ;
adminController . languages . get = function ( req , res , next ) {
languages . list ( function ( err , languages ) {
2015-04-08 11:54:38 -04:00
if ( err ) {
return next ( err ) ;
}
languages . forEach ( function ( language ) {
language . selected = language . code === meta . config . defaultLang ;
} ) ;
2014-09-28 21:09:40 -04:00
res . render ( 'admin/general/languages' , {
2014-03-09 20:05:14 -04:00
languages : languages
} ) ;
2014-03-03 16:35:21 -05:00
} ) ;
} ;
2015-02-25 14:50:45 -05:00
adminController . sounds . get = function ( req , res , next ) {
meta . sounds . getFiles ( function ( err , sounds ) {
sounds = Object . keys ( sounds ) . map ( function ( name ) {
return {
name : name
} ;
} ) ;
res . render ( 'admin/general/sounds' , {
sounds : sounds
} ) ;
} ) ;
} ;
adminController . navigation . get = function ( req , res , next ) {
2015-02-25 17:22:41 -05:00
require ( '../navigation/admin' ) . getAdmin ( function ( err , data ) {
2015-02-25 14:50:45 -05:00
if ( err ) {
return next ( err ) ;
}
2015-03-31 23:40:58 -04:00
2015-02-25 14:50:45 -05:00
res . render ( 'admin/general/navigation' , data ) ;
} ) ;
} ;
2015-02-26 14:10:41 -05:00
adminController . homepage . get = function ( req , res , next ) {
2015-02-27 15:09:09 -05:00
plugins . fireHook ( 'filter:homepage.get' , { routes : [
{
route : 'categories' ,
name : 'Categories'
} ,
{
route : 'recent' ,
name : 'Recent'
} ,
{
route : 'popular' ,
name : 'Popular'
}
] } , function ( err , data ) {
res . render ( 'admin/general/homepage' , data ) ;
} ) ;
2015-02-26 14:10:41 -05:00
} ;
2014-03-03 16:35:21 -05:00
adminController . settings . get = function ( req , res , next ) {
2014-09-24 14:47:58 -04:00
var term = req . params . term ? req . params . term : 'general' ;
2014-11-18 14:54:54 -05:00
res . render ( 'admin/settings/' + term ) ;
2014-03-03 16:35:21 -05:00
} ;
adminController . logger . get = function ( req , res , next ) {
2014-09-28 21:09:40 -04:00
res . render ( 'admin/development/logger' , { } ) ;
2014-03-03 16:35:21 -05:00
} ;
2014-09-25 13:12:51 -04:00
adminController . appearance . get = function ( req , res , next ) {
var term = req . params . term ? req . params . term : 'themes' ;
2014-09-28 20:22:04 -04:00
res . render ( 'admin/appearance/' + term , { } ) ;
2014-09-25 13:12:51 -04:00
} ;
2014-09-28 20:22:04 -04:00
adminController . extend . widgets = function ( req , res , next ) {
2014-03-03 16:35:21 -05:00
async . parallel ( {
areas : function ( next ) {
2014-03-31 12:27:24 -04:00
var defaultAreas = [
{ name : 'Global Sidebar' , template : 'global' , location : 'sidebar' } ,
2014-05-28 16:30:16 -04:00
{ name : 'Global Header' , template : 'global' , location : 'header' } ,
2014-03-31 12:27:24 -04:00
{ name : 'Global Footer' , template : 'global' , location : 'footer' } ,
2015-01-11 18:04:35 -05:00
{ name : 'Group Page (Left)' , template : 'groups/details.tpl' , location : 'left' } ,
{ name : 'Group Page (Right)' , template : 'groups/details.tpl' , location : 'right' }
2014-03-31 12:27:24 -04:00
] ;
plugins . fireHook ( 'filter:widgets.getAreas' , defaultAreas , next ) ;
2014-03-03 16:35:21 -05:00
} ,
widgets : function ( next ) {
plugins . fireHook ( 'filter:widgets.getWidgets' , [ ] , next ) ;
}
} , function ( err , widgetData ) {
2014-11-04 17:57:31 -05:00
if ( err ) {
return next ( err ) ;
}
2014-06-16 14:08:42 -04:00
widgetData . areas . push ( { name : 'Draft Zone' , template : 'global' , location : 'drafts' } ) ;
2014-03-31 16:19:57 -04:00
2014-03-03 16:35:21 -05:00
async . each ( widgetData . areas , function ( area , next ) {
widgets . getArea ( area . template , area . location , function ( err , areaData ) {
area . data = areaData ;
next ( err ) ;
} ) ;
} , function ( err ) {
2014-11-04 17:57:31 -05:00
if ( err ) {
return next ( err ) ;
}
2014-03-03 16:35:21 -05:00
for ( var w in widgetData . widgets ) {
if ( widgetData . widgets . hasOwnProperty ( w ) ) {
2014-04-16 21:02:25 -04:00
// if this gets anymore complicated, it needs to be a template
2014-10-31 02:10:40 -04:00
widgetData . widgets [ w ] . content += "<br /><label>Title:</label><input type=\"text\" class=\"form-control\" name=\"title\" placeholder=\"Title (only shown on some containers)\" /><br /><label>Container:</label><textarea rows=\"4\" class=\"form-control container-html\" name=\"container\" placeholder=\"Drag and drop a container or enter HTML here.\"></textarea><div class=\"checkbox\"><label><input name=\"hide-guests\" type=\"checkbox\"> Hide from anonymous users?</label></div><div class=\"checkbox\"><label><input name=\"hide-registered\" type=\"checkbox\"> Hide from registered users?</input></label></div>" ;
2014-03-03 16:35:21 -05:00
}
}
2014-06-11 16:42:07 -04:00
var templates = [ ] ,
list = { } , index = 0 ;
widgetData . areas . forEach ( function ( area ) {
if ( typeof list [ area . template ] === 'undefined' ) {
list [ area . template ] = index ;
templates . push ( {
template : area . template ,
areas : [ ]
} ) ;
index ++ ;
}
templates [ list [ area . template ] ] . areas . push ( {
name : area . name ,
location : area . location
} ) ;
} ) ;
2014-09-28 20:22:04 -04:00
res . render ( 'admin/extend/widgets' , {
2014-06-11 16:42:07 -04:00
templates : templates ,
2014-03-03 16:35:21 -05:00
areas : widgetData . areas ,
2014-09-25 12:41:16 -04:00
widgets : widgetData . widgets
2014-03-09 20:05:14 -04:00
} ) ;
2014-03-03 16:35:21 -05:00
} ) ;
} ) ;
2014-09-28 20:22:04 -04:00
} ;
2015-02-19 14:20:13 -05:00
adminController . extend . rewards = function ( req , res , next ) {
require ( '../rewards/admin' ) . get ( function ( err , data ) {
if ( err ) {
return next ( err ) ;
}
2015-03-31 23:40:58 -04:00
2015-02-19 14:20:13 -05:00
res . render ( 'admin/extend/rewards' , data ) ;
} ) ;
} ;
2014-03-03 16:35:21 -05:00
adminController . groups . get = function ( req , res , next ) {
2014-03-19 10:27:02 -04:00
groups . list ( {
expand : true ,
2015-02-23 15:43:32 -05:00
truncateUserList : true ,
2015-02-26 11:09:14 -05:00
isAdmin : true ,
showSystemGroups : true
2014-03-19 10:27:02 -04:00
} , function ( err , groups ) {
2014-06-12 18:53:58 -04:00
groups = groups . filter ( function ( group ) {
2015-02-26 11:09:14 -05:00
return group . name !== 'registered-users' && group . name !== 'guests' && group . name . indexOf ( ':privileges:' ) === - 1 ;
2014-06-12 18:53:58 -04:00
} ) ;
2014-09-28 21:09:40 -04:00
res . render ( 'admin/manage/groups' , {
2014-03-09 20:05:14 -04:00
groups : groups ,
yourid : req . user . uid
} ) ;
2014-03-03 16:35:21 -05:00
} ) ;
} ;
2014-09-29 17:51:18 -04:00
adminController . themes . get = function ( req , res , next ) {
var themeDir = path . join ( _ _dirname , '../../node_modules/' + req . params . theme ) ;
fs . exists ( themeDir , function ( exists ) {
if ( exists ) {
var themeConfig = require ( path . join ( themeDir , 'theme.json' ) ) ,
screenshotPath = path . join ( themeDir , themeConfig . screenshot ) ;
if ( themeConfig . screenshot && fs . existsSync ( screenshotPath ) ) {
2014-11-04 17:34:01 -05:00
res . sendFile ( screenshotPath ) ;
2014-09-29 17:51:18 -04:00
} else {
2014-11-04 17:34:01 -05:00
res . sendFile ( path . join ( _ _dirname , '../../public/images/themes/default.png' ) ) ;
2014-09-29 17:51:18 -04:00
}
} else {
return next ( ) ;
}
} ) ;
2014-10-08 12:18:32 -04:00
} ;
2014-09-29 17:51:18 -04:00
2014-04-10 20:31:57 +01:00
module . exports = adminController ;