Fix merge conflicts

v1.18.x
Peter Jaszkowiak 8 years ago
commit a8add6477c

@ -32,6 +32,7 @@
"no-prototype-builtins": "off",
"new-cap": "off",
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
"import/no-unresolved": "error",
// ES6
"prefer-rest-params": "off",
@ -43,7 +44,6 @@
"vars-on-top": "off",
// TODO
"import/no-unresolved": "off",
"import/no-extraneous-dependencies": "off",
"import/no-dynamic-require": "off",
"import/newline-after-import": "off",

@ -19,6 +19,12 @@
'use strict';
if (require.main !== module) {
require.main.require = function (path) {
return require(path);
};
}
var nconf = require('nconf');
nconf.argv().env('__');

@ -7,6 +7,7 @@ var path = require('path');
var fork = require('child_process').fork;
var async = require('async');
var logrotate = require('logrotate-stream');
var file = require('./src/file');
var pkg = require('./package.json');
@ -23,6 +24,7 @@ var workers = [];
var Loader = {
timesStarted: 0,
};
var appPath = path.join(__dirname, 'app.js');
Loader.init = function (callback) {
if (silent) {
@ -114,7 +116,7 @@ function forkWorker(index, isPrimary) {
process.env.isCluster = ports.length > 1;
process.env.port = ports[index];
var worker = fork('app.js', args, {
var worker = fork(appPath, args, {
silent: silent,
env: process.env,
});

111
nodebb

@ -2,16 +2,25 @@
'use strict';
var cproc;
var args;
var fs;
var path;
var request;
var semver;
var prompt;
var async;
try {
require('colors');
var cproc = require('child_process');
var args = require('minimist')(process.argv.slice(2));
var fs = require('fs');
var path = require('path');
var request = require('request');
var semver = require('semver');
var prompt = require('prompt');
var async = require('async');
cproc = require('child_process');
args = require('minimist')(process.argv.slice(2));
fs = require('fs');
path = require('path');
request = require('request');
semver = require('semver');
prompt = require('prompt');
async = require('async');
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND') {
process.stdout.write('NodeBB could not be started because it\'s dependencies have not been installed.\n');
@ -23,13 +32,16 @@ try {
}
}
var loaderPath = path.join(__dirname, 'loader.js');
var appPath = path.join(__dirname, 'app.js');
if (args.dev) {
process.env.NODE_ENV = 'development';
}
function getRunningPid(callback) {
fs.readFile(__dirname + '/pidfile', {
encoding: 'utf-8'
fs.readFile(path.join(__dirname, 'pidfile'), {
encoding: 'utf-8',
}, function (err, pid) {
if (err) {
return callback(err);
@ -38,7 +50,7 @@ function getRunningPid(callback) {
try {
process.kill(parseInt(pid, 10), 0);
callback(null, parseInt(pid, 10));
} catch(e) {
} catch (e) {
callback(e);
}
});
@ -52,28 +64,29 @@ function getCurrentVersion(callback) {
try {
pkg = JSON.parse(pkg);
return callback(null, pkg.version);
} catch(err) {
} catch (err) {
return callback(err);
}
});
}
function fork(args) {
return cproc.fork('app.js', args, {
return cproc.fork(appPath, args, {
cwd: __dirname,
silent: false
silent: false,
});
}
function getInstalledPlugins(callback) {
async.parallel({
files: async.apply(fs.readdir, path.join(__dirname, 'node_modules')),
deps: async.apply(fs.readFile, path.join(__dirname, 'package.json'), { encoding: 'utf-8' })
deps: async.apply(fs.readFile, path.join(__dirname, 'package.json'), { encoding: 'utf-8' }),
}, function (err, payload) {
if (err) {
return callback(err);
}
var isNbbModule = /^nodebb-(?:plugin|theme|widget|rewards)-[\w\-]+$/,
moduleName, isGitRepo;
var isNbbModule = /^nodebb-(?:plugin|theme|widget|rewards)-[\w-]+$/;
var moduleName;
var isGitRepo;
payload.files = payload.files.filter(function (file) {
return isNbbModule.test(file);
@ -98,7 +111,7 @@ function getInstalledPlugins(callback) {
try {
fs.accessSync(path.join(__dirname, 'node_modules/' + moduleName, '.git'));
isGitRepo = true;
} catch(e) {
} catch (e) {
isGitRepo = false;
}
@ -144,7 +157,7 @@ function checkPlugins(standalone, callback) {
async.waterfall([
async.apply(async.parallel, {
plugins: async.apply(getInstalledPlugins),
version: async.apply(getCurrentVersion)
version: async.apply(getCurrentVersion),
}),
function (payload, next) {
var toCheck = Object.keys(payload.plugins);
@ -157,7 +170,7 @@ function checkPlugins(standalone, callback) {
request({
method: 'GET',
url: 'https://packages.nodebb.org/api/v1/suggest?version=' + payload.version + '&package[]=' + toCheck.join('&package[]='),
json: true
json: true,
}, function (err, res, body) {
if (err) {
process.stdout.write('error'.red + '\n'.reset);
@ -169,25 +182,25 @@ function checkPlugins(standalone, callback) {
body = [body];
}
var current, suggested,
upgradable = body.map(function (suggestObj) {
current = payload.plugins[suggestObj.package];
suggested = suggestObj.version;
if (suggestObj.code === 'match-found' && semver.gt(suggested, current)) {
return {
name: suggestObj.package,
current: current,
suggested: suggested
};
} else {
return null;
}
}).filter(Boolean);
var current;
var suggested;
var upgradable = body.map(function (suggestObj) {
current = payload.plugins[suggestObj.package];
suggested = suggestObj.version;
if (suggestObj.code === 'match-found' && semver.gt(suggested, current)) {
return {
name: suggestObj.package,
current: current,
suggested: suggested,
};
}
return null;
}).filter(Boolean);
next(null, upgradable);
});
}
},
], callback);
}
function upgradePlugins(callback) {
@ -199,7 +212,7 @@ function upgradePlugins(callback) {
checkPlugins(standalone, function (err, found) {
if (err) {
process.stdout.write('\Warning'.yellow + ': An unexpected error occured when attempting to verify plugin upgradability\n'.reset);
process.stdout.write('Warning'.yellow + ': An unexpected error occured when attempting to verify plugin upgradability\n'.reset);
return callback(err);
}
@ -223,7 +236,7 @@ function upgradePlugins(callback) {
prompt.get({
name: 'upgrade',
description: 'Proceed with upgrade (y|n)?'.reset,
type: 'string'
type: 'string',
}, function (err, result) {
if (err) {
return callback(err);
@ -279,8 +292,8 @@ var commands = {
process.stdout.write(' "' + './nodebb restart'.yellow + '" to restart NodeBB\n\n'.reset);
// Spawn a new NodeBB process
cproc.fork(__dirname + '/loader.js', {
env: process.env
cproc.fork(loaderPath, {
env: process.env,
});
},
},
@ -320,7 +333,7 @@ var commands = {
process.stdout.write('\n\n'.reset);
cproc.spawn('tail', ['-F', './logs/output.log'], {
cwd: __dirname,
stdio: 'inherit'
stdio: 'inherit',
});
},
},
@ -333,12 +346,12 @@ var commands = {
process.stdout.write('\n\n'.reset);
// Spawn a new NodeBB process
cproc.fork(__dirname + '/loader.js', {
env: process.env
cproc.fork(loaderPath, {
env: process.env,
});
cproc.spawn('tail', ['-F', './logs/output.log'], {
cwd: __dirname,
stdio: 'inherit'
stdio: 'inherit',
});
},
},
@ -347,14 +360,14 @@ var commands = {
usage: 'Usage: ' + './nodebb dev'.yellow,
handler: function () {
process.env.NODE_ENV = 'development';
cproc.fork(__dirname + '/loader.js', ['--no-daemon', '--no-silent'], {
env: process.env
cproc.fork(loaderPath, ['--no-daemon', '--no-silent'], {
env: process.env,
});
},
},
build: {
description: 'Compile static assets (CSS, Javascript, etc)',
usage: 'Usage: ' + './nodebb build'.yellow + ' [js,clientCSS,acpCSS,tpl,lang]'.red + '\n' +
usage: 'Usage: ' + './nodebb build'.yellow + ' [js,clientCSS,acpCSS,tpl,lang]'.red + '\n' +
' e.g. ' + './nodebb build js,tpl'.yellow + '\tbuilds JS and templates\n' +
' ' + './nodebb build'.yellow + '\t\tbuilds all targets\n',
handler: function () {
@ -422,7 +435,7 @@ var commands = {
var upgradeProc = fork(arr);
upgradeProc.on('close', next);
}
},
], function (err) {
if (err) {
process.stdout.write('\nError'.red + ': ' + err.message + '\n');
@ -430,7 +443,7 @@ var commands = {
var message = 'NodeBB Upgrade Complete!';
// some consoles will return undefined/zero columns, so just use 2 spaces in upgrade script if we can't get our column count
var columns = process.stdout.columns;
var spaces = columns ? new Array(Math.floor(columns / 2) - (message.length / 2) + 1).join(' ') : " ";
var spaces = columns ? new Array(Math.floor(columns / 2) - (message.length / 2) + 1).join(' ') : ' ';
process.stdout.write('OK\n'.green);
process.stdout.write('\n' + spaces + message.green.bold + '\n\n'.reset);

@ -11,7 +11,7 @@
"main": "app.js",
"scripts": {
"start": "node loader.js",
"lint": "eslint --cache .",
"lint": "eslint --cache ./nodebb .",
"pretest": "npm run lint",
"test": "istanbul cover node_modules/mocha/bin/_mocha -- -R dot",
"coveralls": "istanbul cover _mocha --report lcovonly -- -R dot && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"

@ -61,7 +61,7 @@
"reputation": "Hírnév",
"read_more": "tovább olvas",
"more": "Több",
"posted_ago_by_guest": "Vendég hozzászólás %1",
"posted_ago_by_guest": "%1 vendég hozzászólás",
"posted_ago_by": "%2 hozzászólás %1",
"posted_ago": "%1 hozzászólás",
"posted_in": "hozzászólt itt: %1",
@ -103,5 +103,5 @@
"cookies.message": "A weboldal sütiket használ, a legjobb weboldalas élmény érdekében.",
"cookies.accept": "Értem!",
"cookies.learn_more": "Tudnivalók",
"edited": "Edited"
"edited": "Szerkesztett"
}

@ -4,7 +4,7 @@
"week": "Hét",
"month": "Hónap",
"year": "Év",
"alltime": "Minden idők",
"alltime": "Bármikor",
"no_recent_topics": "Nincs friss témakör.",
"no_popular_topics": "Nincs népszerű témakör.",
"there-is-a-new-topic": "Van egy új témakör.",

@ -103,5 +103,5 @@
"cookies.message": "Deze website gebruikt cookies om je ervan te verzekeren dat je de beste ervaring krijgt tijdens het gebruik van onze website.",
"cookies.accept": "Begrepen",
"cookies.learn_more": "Meer",
"edited": "Edited"
"edited": "Bewerkt"
}

@ -27,7 +27,7 @@
"details.disableJoinRequests": "Groepsverzoeken uitschakelen",
"details.grant": "Toekennen/herroepen van eigendom",
"details.kick": "Kick",
"details.kick_confirm": "Are you sure you want to remove this member from the group?",
"details.kick_confirm": "Weet u zeker dat u de gebruiker wilt verwijderen uit de groep?",
"details.owner_options": "Groepsadministratie",
"details.group_name": "Groepsnaam",
"details.member_count": "Ledentelling",
@ -54,5 +54,5 @@
"upload-group-cover": "Upload groepscover",
"bulk-invite-instructions": "Vul een lijst is met gebruikersnamen gescheiden met komma's om deze uit te nodigen voor deze groep",
"bulk-invite": "Massa uitnodiging",
"remove_group_cover_confirm": "Are you sure you want to remove the cover picture?"
"remove_group_cover_confirm": "Weet u zeker dat u de cover foto wilt verwijderen?"
}

@ -13,7 +13,7 @@
"chat.contacts": "Contacten",
"chat.message-history": "Berichtengeschiedenis",
"chat.pop-out": "Chatvenster opbrengen bij chat",
"chat.minimize": "Minimize",
"chat.minimize": "Verkleinen",
"chat.maximize": "Maximaliseren",
"chat.seven_days": "7 dagen",
"chat.thirty_days": "30 dagen",

@ -10,14 +10,14 @@
"return_to": "Terug naar %1",
"new_notification": "Nieuwe notificatie",
"you_have_unread_notifications": "Je hebt nieuwe notificaties.",
"all": "All",
"topics": "Topics",
"replies": "Replies",
"all": "Alles",
"topics": "Onderwerpen",
"replies": "Antwoorden",
"chat": "Chats",
"follows": "Follows",
"follows": "Volgt",
"upvote": "Upvotes",
"new-flags": "New Flags",
"my-flags": "Flags assigned to me",
"new-flags": "Nieuwe markeringen",
"my-flags": "Markeringen toegewezen aan mij",
"bans": "Bans",
"new_message_from": "Nieuw bericht van <strong>%1</strong>",
"upvoted_your_post_in": "<strong>%1</strong> heeft voor een bericht gestemd in <strong>%2</strong>.",
@ -28,9 +28,9 @@
"user_flagged_post_in": "<strong>%1</strong> rapporteerde een bericht in <strong>%2</strong>",
"user_flagged_post_in_dual": "<strong>%1</strong> en <strong>%2</strong> rapporteerde een bericht in <strong>%3</strong>",
"user_flagged_post_in_multiple": "<strong>%1</strong> en %2 andere rapporteede een bericht in <strong>%3</strong>",
"user_flagged_user": "<strong>%1</strong> flagged a user profile (%2)",
"user_flagged_user_dual": "<strong>%1</strong> and <strong>%2</strong> flagged a user profile (%3)",
"user_flagged_user_multiple": "<strong>%1</strong> and %2 others flagged a user profile (%3)",
"user_flagged_user": "<strong>%1</strong> markeerde een gebruikersprofiel (%2)",
"user_flagged_user_dual": "<strong>%1</strong> en <strong>%2</strong> markeerden een gebruikersprofiel (%3)",
"user_flagged_user_multiple": "<strong>%1</strong> en %2 anderen markeerde een gebruikersprofiel (%3)",
"user_posted_to": "<strong>%1</strong> heeft een reactie geplaatst in <strong>%2</strong>",
"user_posted_to_dual": "<strong>%1</strong> en <strong>%2</strong> hebben een reactie geplaatst in: <strong>%3</strong>",
"user_posted_to_multiple": "<strong>%1</strong> en %2 hebben een reactie geplaatst in: <strong>%3</strong>",
@ -40,7 +40,7 @@
"user_started_following_you_multiple": "<strong%1>%1</strong> en %2 andere volgen jou nu.",
"new_register": "<strong>%1</strong> heeft een registratie verzoek aangevraagd.",
"new_register_multiple": "Er is/zijn <strong>%1</strong> registratieverzoek(en) die wacht(en) op goedkeuring.",
"flag_assigned_to_you": "<strong>Flag %1</strong> has been assigned to you",
"flag_assigned_to_you": "<strong>Flag %1</strong> is aan u toegewezen",
"email-confirmed": "E-mailadres bevestigd",
"email-confirmed-message": "Bedankt voor het bevestigen van je e-mailadres. Je account is nu volledig geactiveerd.",
"email-confirm-error-message": "Er was een probleem met het bevestigen van dit e-mailadres. Misschien is de code niet goed ingevoerd of was de beschikbare tijd inmiddels verstreken.",

@ -6,7 +6,7 @@
"popular-month": "De populaire onderwerpen van deze maand",
"popular-alltime": "De populaire onderwerpen",
"recent": "Recente onderwerpen",
"flagged-content": "Flagged Content",
"flagged-content": "Gemarkeerde content",
"ip-blacklist": "IP zwarte lijst",
"users/online": "Online Gebruikers",
"users/latest": "Meest recente gebruikers",
@ -27,7 +27,7 @@
"group": "%1's groep",
"chats": "Chats",
"chat": "Chatten met %1",
"flags": "Flags",
"flags": "Markeringen",
"flag-details": "Flag %1 Details",
"account/edit": "\"%1\" aanpassen",
"account/edit/password": "Wachtwoord van \"%1\" aanpassen",

@ -12,55 +12,55 @@
"ext-link": "外部链接",
"upload-image": "上传图片",
"delete-image": "移除",
"category-image": "块图片",
"parent-category": "父块",
"optional-parent-category": "(可选)父块",
"category-image": "块图片",
"parent-category": "父块",
"optional-parent-category": "(可选)父块",
"parent-category-none": "(无)",
"copy-settings": "复制设置",
"optional-clone-settings": "(可选) 从块复制设置",
"purge": "删除块",
"optional-clone-settings": "(可选) 从块复制设置",
"purge": "删除块",
"enable": "启用",
"disable": "禁用",
"edit": "编辑",
"select-category": "选择块",
"set-parent-category": "设置父块",
"select-category": "选择块",
"set-parent-category": "设置父块",
"privileges.description": "您可以在此部分中配置此块的访问控制权限。 可以根据每个用户或每个组授予权限。 您可以通过在下面的表格中搜索,将新用户添加到此表中。",
"privileges.description": "您可以在此部分中配置此块的访问控制权限。 可以根据每个用户或每个组授予权限。 您可以通过在下面的表格中搜索,将新用户添加到此表中。",
"privileges.warning": "<strong>注意</strong>:权限设置会立即生效。 调整这些设置后,无需保存。",
"privileges.section-viewing": "查看权限",
"privileges.section-posting": "发帖权限",
"privileges.section-moderation": "审核权限",
"privileges.section-user": "用户",
"privileges.search-user": "添加用户",
"privileges.no-users": "此块中没有用户特定的权限。",
"privileges.no-users": "此块中没有用户特定的权限。",
"privileges.section-group": "群组",
"privileges.group-private": "这个群组是私密的",
"privileges.search-group": "添加群组",
"privileges.copy-to-children": "复制到子版块",
"privileges.copy-from-category": "从块复制",
"privileges.copy-from-category": "从块复制",
"privileges.inherit": "如果 <code>registered-users</code> 组被授予特定权限,所有其他组都会收到<strong>隐式权限</strong>,即使它们未被明确定义/检查。 将显示此隐式权限,因为所有用户都是 <code>registered-users</code> 群组的一部分,因此无需显式授予其他组的权限。",
"analytics.back": "返回块列表",
"analytics.title": "“%1”块的统计",
"analytics.pageviews-hourly": "<strong>图1</strong> &ndash; 此块的每小时页面浏览量</small>",
"analytics.pageviews-daily": "<strong>图2</strong> &ndash; 此块的每日页面浏览量</small>",
"analytics.topics-daily": "<strong>图3</strong> &ndash; 每日在此块中创建的主题</small>",
"analytics.posts-daily": "<strong>图4</strong> &ndash; 每日在此块中每日发布的帖子</small>",
"analytics.back": "返回块列表",
"analytics.title": "“%1”块的统计",
"analytics.pageviews-hourly": "<strong>图1</strong> &ndash; 此块的每小时页面浏览量</small>",
"analytics.pageviews-daily": "<strong>图2</strong> &ndash; 此块的每日页面浏览量</small>",
"analytics.topics-daily": "<strong>图3</strong> &ndash; 每日在此块中创建的主题</small>",
"analytics.posts-daily": "<strong>图4</strong> &ndash; 每日在此块中每日发布的帖子</small>",
"alert.created": "创建",
"alert.create-success": "块创建成功!",
"alert.none-active": "您没有有效的块。",
"alert.create": "创建一个块",
"alert.create-success": "块创建成功!",
"alert.none-active": "您没有有效的块。",
"alert.create": "创建一个块",
"alert.confirm-moderate": "<strong>您确定要将审核权限授予此群组吗?</strong>此群组是公开的,任何用户都可以随意加入。",
"alert.confirm-purge": "<p class =“lead”>您确定要清除此块“%1”吗</p> <h5> <strong class =“text-danger”>警告!</strong> 板块将被清除!</h5> <p class =“help-block”>清除板块将删除所有主题和帖子,并从数据库中删除板块。 如果您想<em>暂时</em>移除板块,请使用停用板块。</p>",
"alert.purge-success": "块已删除!",
"alert.confirm-purge": "<p class =“lead”>您确定要清除此块“%1”吗</p> <h5> <strong class =“text-danger”>警告!</strong> 版块将被清除!</h5> <p class =“help-block”>清除版块将删除所有主题和帖子,并从数据库中删除版块。 如果您想<em>暂时</em>移除版块,请使用停用版块。</p>",
"alert.purge-success": "块已删除!",
"alert.copy-success": "设置已复制!",
"alert.set-parent-category": "设置父块",
"alert.updated": "块已更新",
"alert.updated-success": "块ID %1 成功更新。",
"alert.upload-image": "上传块图片",
"alert.set-parent-category": "设置父块",
"alert.updated": "块已更新",
"alert.updated-success": "块ID %1 成功更新。",
"alert.upload-image": "上传块图片",
"alert.find-user": "查找用户",
"alert.user-search": "在这里查找用户…",
"alert.find-group": "查找群组",

@ -3,7 +3,7 @@
"enable": "在主题和帖子使用分页替代无限滚动浏览。",
"topics": "话题分页",
"posts-per-page": "每页帖子数",
"categories": "块分页",
"categories": "块分页",
"topics-per-page": "每页主题数",
"initial-num-load": "最初加载未读,最新,热门的话题"
}

@ -6,21 +6,21 @@
"sorting.most-votes": "最多投票",
"sorting.topic-default": "默认主题排序",
"restrictions": "发帖限制",
"restrictions.seconds-between": "发帖间隔",
"restrictions.seconds-between-new": "对于新用户的发帖间隔",
"restrictions.seconds-between": "发帖间隔(单位:秒)",
"restrictions.seconds-between-new": "对于新用户的发帖间隔(单位:秒)",
"restrictions.rep-threshold": "取消发帖限制所需的声望值",
"restrictions.seconds-defore-new": "见习时间",
"restrictions.seconds-edit-after": "用户在发布后允许编辑帖子的秒数。 (0为禁用) ",
"restrictions.seconds-delete-after": "允许在发布后删除帖子的秒数。 (0为禁用) ",
"restrictions.seconds-defore-new": "见习时间(单位:秒)",
"restrictions.seconds-edit-after": "用户在发布后允许编辑帖子的时间0为禁用单位",
"restrictions.seconds-delete-after": "用户在发布后允许删除帖子的时间0为禁用单位",
"restrictions.replies-no-delete": "在用户被禁止删除自己的主题后的回复数。 (0为禁用) ",
"restrictions.min-title-length": "最小标题长度",
"restrictions.max-title-length": "最大标题长度",
"restrictions.min-post-length": "最小帖子长度",
"restrictions.max-post-length": "最大帖子长度",
"restrictions.days-until-stale": "主题过期时间",
"restrictions.days-until-stale": "主题过期时间(单位:天)",
"restrictions.stale-help": "如果某个主题被视为“过时”,则会向尝试回复该主题的用户显示警告。",
"timestamp": "时间戳",
"timestamp.cut-off": "日期截止日期 (天) ",
"timestamp.cut-off": "日期截止日期(单位:天)",
"timestamp.cut-off-help": "日期&amp;时间将以相对方式 (例如“3小时前” / “5天前”) 显示,并且会依照访客语言时区转换。在某一时刻之后,可以切换该文本以显示本地化日期本身 (例如2016年11月5日15:30) 。<br /> <em> (默认值:<code> 30 </code>或一个月) 。 设置为0可始终显示日期留空以始终显示相对时间。</em>",
"teaser": "预览帖子",
"teaser.last-post": "最后&ndash; 显示最新的帖子,包括原帖,如果没有回复",

@ -38,7 +38,7 @@
"composer.upload-picture": "上传图片",
"composer.upload-file": "上传文件",
"composer.zen_mode": "无干扰模式",
"composer.select_category": "选择一个块",
"composer.select_category": "选择一个块",
"bootbox.ok": "确认",
"bootbox.cancel": "取消",
"bootbox.confirm": "确认",

@ -6,8 +6,8 @@
"titles": "标题",
"titles-posts": "标题和回帖",
"posted-by": "发表",
"in-categories": "在版",
"search-child-categories": "搜索子版",
"in-categories": "在版",
"search-child-categories": "搜索子版",
"has-tags": "有标签",
"reply-count": "回复数",
"at-least": "至少",

@ -48,7 +48,7 @@
"not-watching": "未关注",
"ignoring": "忽略中",
"watching.description": "有新回复时通知我。<br/>在未读主题中显示。",
"not-watching.description": "不要在有新回复时通知我。<br/>如果这个分类未被忽略则在未读主题中显示。",
"not-watching.description": "不要在有新回复时通知我。<br/>如果这个版块未被忽略则在未读主题中显示。",
"ignoring.description": "不要在有新回复时通知我。<br/>不要在未读主题中显示该主题。",
"thread_tools.title": "主题工具",
"thread_tools.markAsUnreadForAll": "标记全部未读",
@ -70,8 +70,8 @@
"post_delete_confirm": "确定删除此帖吗?",
"post_restore_confirm": "确定恢复此帖吗?",
"post_purge_confirm": "确认清除此回帖吗?",
"load_categories": "正在载入块",
"disabled_categories_note": "停用的块为灰色",
"load_categories": "正在载入块",
"disabled_categories_note": "停用的块为灰色",
"confirm_move": "移动",
"confirm_fork": "分割",
"bookmark": "书签",

@ -15,7 +15,7 @@
"recent_topics": "最新主题",
"popular_topics": "热门主题",
"unread_topics": "未读主题",
"categories": "版",
"categories": "版",
"tags": "话题",
"no-users-found": "未找到匹配的用户!"
}

@ -97,6 +97,9 @@
// and the strings of untranslated text in between
var toTranslate = [];
// to store the state of if we're currently in a top-level token for later
var inToken = false;
// split a translator string into an array of tokens
// but don't split by commas inside other translator strings
function split(text) {
@ -141,6 +144,8 @@
// set the last break to our current
// spot since we just broke the string
lastBreak = cursor;
// we're in a token now
inToken = true;
// the current level of nesting of the translation strings
var level = 0;
@ -176,6 +181,8 @@
invalidTextRegex.test(sliced[0])) {
cursor += 1;
lastBreak -= 2;
// no longer in a token
inToken = false;
if (level > 0) {
level -= 1;
} else {
@ -191,18 +198,26 @@
// if we're at the base level, then this is the end
if (level === 0) {
// so grab the name and args
var result = split(str.slice(lastBreak, cursor));
var currentSlice = str.slice(lastBreak, cursor);
var result = split(currentSlice);
var name = result[0];
var args = result.slice(1);
// make a backup based on the raw string of the token
// if there are arguments to the token
var backup = '';
if (args && args.length) {
backup = this.translate('&lsqb;&lsqb;' + currentSlice + '&lsqb;&lsqb;');
}
// add the translation promise to the array
toTranslate.push(this.translateKey(name, args));
toTranslate.push(this.translateKey(name, args, backup));
// skip past the ending brackets
cursor += 2;
// set this as our last break
lastBreak = cursor;
// and we're no longer in a translation string,
// so continue with the main loop
inToken = false;
break;
}
// otherwise we lower the level
@ -219,8 +234,16 @@
cursor += 1;
}
// ending string of source
var last = str.slice(lastBreak);
// if we were mid-token, treat it as invalid
if (inToken) {
last = this.translate('&lsqb;&lsqb;' + last);
}
// add the remaining text after the last translation string
toTranslate.push(str.slice(lastBreak, cursor + 2));
toTranslate.push(last);
// and return a promise for the concatenated translated string
return Promise.all(toTranslate).then(function (translated) {
@ -232,9 +255,10 @@
* Translates a specific key and array of arguments
* @param {string} name - Translation key (ex. 'global:home')
* @param {string[]} args - Arguments for `%1`, `%2`, etc
* @param {string|Promise<string>} backup - Text to use in case the key can't be found
* @returns {Promise<string>}
*/
Translator.prototype.translateKey = function translateKey(name, args) {
Translator.prototype.translateKey = function translateKey(name, args, backup) {
var self = this;
var result = name.split(':', 2);
@ -251,29 +275,27 @@
}
var translation = this.getTranslation(namespace, key);
var argsToTranslate = args.map(function (arg) {
return string(arg).collapseWhitespace().decodeHTMLEntities().escapeHTML().s;
}).map(function (arg) {
return self.translate(arg);
});
// so we can await all promises at once
argsToTranslate.unshift(translation);
return Promise.all(argsToTranslate).then(function (result) {
var translated = result[0];
var translatedArgs = result.slice(1);
return translation.then(function (translated) {
// check if the translation is missing first
if (!translated) {
warn('Missing translation "' + name + '"');
return key;
return backup || key;
}
var out = translated;
translatedArgs.forEach(function (arg, i) {
var escaped = arg.replace(/%/g, '&#37;').replace(/\\,/g, '&#44;');
out = out.replace(new RegExp('%' + (i + 1), 'g'), escaped);
var argsToTranslate = args.map(function (arg) {
return string(arg).collapseWhitespace().decodeHTMLEntities().escapeHTML().s;
}).map(function (arg) {
return self.translate(arg);
});
return Promise.all(argsToTranslate).then(function (translatedArgs) {
var out = translated;
translatedArgs.forEach(function (arg, i) {
var escaped = arg.replace(/%/g, '&#37;').replace(/\\,/g, '&#44;');
out = out.replace(new RegExp('%' + (i + 1), 'g'), escaped);
});
return out;
});
return out;
});
};
@ -281,7 +303,7 @@
* Load translation file (or use a cached version), and optionally return the translation of a certain key
* @param {string} namespace - The file name of the translation namespace
* @param {string} [key] - The key of the specific translation to getJSON
* @returns {Promise<Object|string>}
* @returns {Promise<Object>|Promise<string>}
*/
Translator.prototype.getTranslation = function getTranslation(namespace, key) {
var translation;

@ -1,13 +1,16 @@
'use strict';
(function (module) {
var utils;
var fs;
var XRegExp;
if (typeof window === 'undefined') {
fs = require('fs');
XRegExp = require('xregexp');
(function (factory) {
if (typeof module === 'object' && module.exports) {
var winston = require('winston');
var file = require('../../src/file');
module.exports = factory(require('xregexp'));
module.exports.walk = function (dir, done) {
// DEPRECATED
winston.warn('[deprecated] `utils.walk` is deprecated. Use `file.walk` instead.');
file.walk(dir, done);
};
process.profile = function (operation, start) {
console.log('%s took %d milliseconds', operation, process.elapsedTimeSince(start));
@ -18,11 +21,10 @@
return (diff[0] * 1e3) + (diff[1] / 1e6);
};
} else {
XRegExp = window.XRegExp;
window.utils = factory(window.XRegExp);
}
utils = {
}(function (XRegExp) {
var utils = {
generateUUID: function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0;
@ -31,49 +33,6 @@
});
},
// Adapted from http://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
walk: function (dir, done) {
var results = [];
fs.readdir(dir, function (err, list) {
if (err) {
return done(err);
}
var pending = list.length;
if (!pending) {
return done(null, results);
}
list.forEach(function (file) {
file = dir + '/' + file;
fs.stat(file, function (err, stat) {
if (err) {
return done(err);
}
if (stat && stat.isDirectory()) {
utils.walk(file, function (err, res) {
if (err) {
return done(err);
}
results = results.concat(res);
pending -= 1;
if (!pending) {
done(null, results);
}
});
} else {
results.push(file);
pending -= 1;
if (!pending) {
done(null, results);
}
}
});
});
});
},
invalidUnicodeChars: XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'),
invalidLatinChars: /[^\w\s\d\-_]/g,
trimRegex: /^\s+|\s+$/g,
@ -447,11 +406,6 @@
},
};
module.exports = utils;
if (typeof window !== 'undefined') {
window.utils = module.exports;
}
/* eslint "no-extend-native": "off" */
if (typeof String.prototype.startsWith !== 'function') {
String.prototype.startsWith = function (prefix) {
@ -474,13 +428,5 @@
};
}
if (typeof String.prototype.rtrim !== 'function') {
String.prototype.rtrim = function () {
return this.replace(/\s+$/g, '');
};
}
}(typeof module === 'undefined' ? {
module: {
exports: {},
},
} : module));
return utils;
}));

@ -6,8 +6,8 @@ var async = require('async');
var sanitizeHTML = require('sanitize-html');
var nconf = require('nconf');
var utils = require('../../public/src/utils');
var Translator = require('../../public/src/modules/translator').Translator;
var file = require('../file');
var Translator = require('../translator').Translator;
function filterDirectories(directories) {
return directories.map(function (dir) {
@ -24,7 +24,7 @@ function filterDirectories(directories) {
}
function getAdminNamespaces(callback) {
utils.walk(path.resolve(nconf.get('views_dir'), 'admin'), function (err, directories) {
file.walk(path.resolve(nconf.get('views_dir'), 'admin'), function (err, directories) {
if (err) {
return callback(err);
}

@ -4,7 +4,7 @@
var async = require('async');
var db = require('./database');
var utils = require('../public/src/utils');
var utils = require('./utils');
var DEFAULT_BATCH_SIZE = 100;

@ -6,7 +6,7 @@ var db = require('../database');
var groups = require('../groups');
var plugins = require('../plugins');
var privileges = require('../privileges');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Categories) {
Categories.create = function (data, callback) {

@ -5,8 +5,8 @@ var async = require('async');
var db = require('../database');
var meta = require('../meta');
var utils = require('../../public/src/utils');
var translator = require('../../public/src/modules/translator');
var utils = require('../utils');
var translator = require('../translator');
var plugins = require('../plugins');
module.exports = function (Categories) {

@ -9,7 +9,7 @@ var user = require('../../user');
var groups = require('../../groups');
var plugins = require('../../plugins');
var meta = require('../../meta');
var utils = require('../../../public/src/utils');
var utils = require('../../utils');
var helpers = {};

@ -6,7 +6,7 @@ var categories = require('../../categories');
var privileges = require('../../privileges');
var analytics = require('../../analytics');
var plugins = require('../../plugins');
var translator = require('../../../public/src/modules/translator');
var translator = require('../../translator');
var categoriesController = {};

@ -24,13 +24,13 @@ settingsController.get = function (req, res, next) {
function renderEmail(req, res, next) {
var fs = require('fs');
var path = require('path');
var utils = require('../../../public/src/utils');
var file = require('../../file');
var emailsPath = path.join(nconf.get('views_dir'), 'emails');
async.waterfall([
function (next) {
utils.walk(emailsPath, next);
file.walk(emailsPath, next);
},
function (emails, next) {
async.map(emails, function (email, next) {

@ -12,7 +12,7 @@ var categories = require('../categories');
var privileges = require('../privileges');
var plugins = require('../plugins');
var widgets = require('../widgets');
var translator = require('../../public/src/modules/translator');
var translator = require('../translator');
var apiController = module.exports;

@ -11,7 +11,7 @@ var db = require('../database');
var meta = require('../meta');
var user = require('../user');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var Password = require('../password');
var sockets = require('../socket.io');

@ -11,7 +11,7 @@ var categories = require('../categories');
var meta = require('../meta');
var pagination = require('../pagination');
var helpers = require('./helpers');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var categoryController = {};

@ -13,7 +13,7 @@ var privileges = require('../privileges');
var plugins = require('../plugins');
var helpers = require('./helpers');
var pagination = require('../pagination');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var topicsController = {};

@ -1,7 +1,7 @@
'use strict';
var async = require('async');
var utils = require('../../../public/src/utils');
var utils = require('../../utils');
module.exports = function (db, module) {
var helpers = module.helpers.mongo;

@ -1,7 +1,7 @@
'use strict';
module.exports = function (redisClient, module) {
var utils = require('../../../public/src/utils');
var utils = require('../../utils');
var helpers = module.helpers.redis;

@ -13,7 +13,7 @@ var url = require('url');
var User = require('./user');
var Plugins = require('./plugins');
var meta = require('./meta');
var translator = require('../public/src/modules/translator');
var translator = require('./translator');
var transports = {
sendmail: nodemailer.createTransport(sendmailTransport()),

@ -7,7 +7,7 @@ var validator = require('validator');
var db = require('./database');
var batch = require('./batch');
var user = require('./user');
var utils = require('../public/src/utils');
var utils = require('./utils');
(function (events) {
events.log = function (data, callback) {

@ -8,9 +8,9 @@ var jimp = require('jimp');
var mkdirp = require('mkdirp');
var mime = require('mime');
var utils = require('../public/src/utils');
var utils = require('./utils');
var file = {};
var file = module.exports;
file.saveFileToLocal = function (filename, folder, tempPath, callback) {
/*
@ -129,4 +129,47 @@ file.typeToExtension = function (type) {
return extension;
};
// Adapted from http://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
file.walk = function (dir, done) {
var results = [];
fs.readdir(dir, function (err, list) {
if (err) {
return done(err);
}
var pending = list.length;
if (!pending) {
return done(null, results);
}
list.forEach(function (filename) {
filename = dir + '/' + filename;
fs.stat(filename, function (err, stat) {
if (err) {
return done(err);
}
if (stat && stat.isDirectory()) {
file.walk(filename, function (err, res) {
if (err) {
return done(err);
}
results = results.concat(res);
pending -= 1;
if (!pending) {
done(null, results);
}
});
} else {
results.push(filename);
pending -= 1;
if (!pending) {
done(null, results);
}
}
});
});
});
};
module.exports = file;

@ -6,7 +6,7 @@ var validator = require('validator');
var user = require('./user');
var db = require('./database');
var plugins = require('./plugins');
var utils = require('../public/src/utils');
var utils = require('./utils');
var Groups = module.exports;

@ -3,7 +3,7 @@
var async = require('async');
var meta = require('../meta');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var db = require('../database');
module.exports = function (Groups) {

@ -5,7 +5,7 @@ var validator = require('validator');
var db = require('../database');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Groups) {
Groups.getGroupsData = function (groupNames, callback) {

@ -2,7 +2,7 @@
var async = require('async');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var db = require('./../database');
module.exports = function (Groups) {

@ -5,7 +5,7 @@ var winston = require('winston');
var _ = require('underscore');
var user = require('../user');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var plugins = require('../plugins');
var notifications = require('../notifications');
var db = require('../database');

@ -4,7 +4,7 @@ var async = require('async');
var winston = require('winston');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var db = require('../database');

@ -6,7 +6,7 @@ var path = require('path');
var prompt = require('prompt');
var winston = require('winston');
var nconf = require('nconf');
var utils = require('../public/src/utils.js');
var utils = require('./utils.js');
var install = {};
var questions = {};

@ -8,7 +8,7 @@ var db = require('./database');
var user = require('./user');
var plugins = require('./plugins');
var meta = require('./meta');
var utils = require('../public/src/utils');
var utils = require('./utils');
var Messaging = module.exports;

@ -5,7 +5,7 @@ var S = require('string');
var db = require('../database');
var user = require('../user');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Messaging) {
Messaging.getMessageField = function (mid, field, callback) {

@ -6,7 +6,7 @@ var os = require('os');
var nconf = require('nconf');
var pubsub = require('./pubsub');
var utils = require('../public/src/utils');
var utils = require('./utils');
(function (Meta) {
Meta.reloadRequired = false;

@ -13,7 +13,6 @@ var clean = require('postcss-clean');
var plugins = require('../plugins');
var db = require('../database');
var file = require('../file');
var utils = require('../../public/src/utils');
module.exports = function (Meta) {
Meta.css = {};
@ -106,7 +105,7 @@ module.exports = function (Meta) {
});
async.each(pluginDirectories, function (directory, next) {
utils.walk(directory, function (err, styleFiles) {
file.walk(directory, function (err, styleFiles) {
if (err) {
return next(err);
}

@ -11,7 +11,6 @@ var uglifyjs = require('uglify-js');
var file = require('../file');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var minifierPath = path.join(__dirname, 'minifier.js');
@ -20,12 +19,12 @@ module.exports = function (Meta) {
target: {},
scripts: {
base: [
'./node_modules/jquery/dist/jquery.js',
'./node_modules/socket.io-client/dist/socket.io.js',
'node_modules/jquery/dist/jquery.js',
'node_modules/socket.io-client/dist/socket.io.js',
'public/vendor/jquery/timeago/jquery.timeago.js',
'public/vendor/jquery/js/jquery.form.min.js',
'public/vendor/visibility/visibility.min.js',
'./node_modules/bootstrap/dist/js/bootstrap.js',
'node_modules/bootstrap/dist/js/bootstrap.js',
'public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js',
'public/vendor/jquery/textcomplete/jquery.textcomplete.js',
'public/vendor/requirejs/require.js',
@ -35,14 +34,14 @@ module.exports = function (Meta) {
'public/vendor/tinycon/tinycon.js',
'public/vendor/xregexp/xregexp.js',
'public/vendor/xregexp/unicode/unicode-base.js',
'./node_modules/templates.js/lib/templates.js',
'node_modules/templates.js/lib/templates.js',
'public/src/utils.js',
'public/src/sockets.js',
'public/src/app.js',
'public/src/ajaxify.js',
'public/src/overrides.js',
'public/src/widgets.js',
'./node_modules/promise-polyfill/promise.js',
'node_modules/promise-polyfill/promise.js',
],
// files listed below are only available client-side, or are bundled in to reduce # of network requests on cold load
@ -84,12 +83,12 @@ module.exports = function (Meta) {
// modules listed below are built (/src/modules) so they can be defined anonymously
modules: {
'Chart.js': './node_modules/chart.js/dist/Chart.min.js',
'mousetrap.js': './node_modules/mousetrap/mousetrap.min.js',
'cropper.js': './node_modules/cropperjs/dist/cropper.min.js',
'Chart.js': 'node_modules/chart.js/dist/Chart.min.js',
'mousetrap.js': 'node_modules/mousetrap/mousetrap.min.js',
'cropper.js': 'node_modules/cropperjs/dist/cropper.min.js',
'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js',
'zxcvbn.js': './node_modules/zxcvbn/dist/zxcvbn.js',
ace: './node_modules/ace-builds/src-min',
'zxcvbn.js': 'node_modules/zxcvbn/dist/zxcvbn.js',
ace: 'node_modules/ace-builds/src-min',
},
},
};
@ -199,7 +198,7 @@ module.exports = function (Meta) {
return next();
}
utils.walk(srcPath, function (err, files) {
file.walk(srcPath, function (err, files) {
if (err) {
return next(err);
}
@ -225,10 +224,10 @@ module.exports = function (Meta) {
function clearModules(callback) {
var builtPaths = moduleDirs.map(function (p) {
return '../../build/public/src/' + p;
return path.join(__dirname, '../../build/public/src', p);
});
async.each(builtPaths, function (builtPath, next) {
rimraf(path.join(__dirname, builtPath), next);
rimraf(builtPath, next);
}, function (err) {
callback(err);
});
@ -325,7 +324,7 @@ module.exports = function (Meta) {
});
async.each(pluginDirectories, function (directory, next) {
utils.walk(directory, function (err, scripts) {
file.walk(directory, function (err, scripts) {
pluginsScripts = pluginsScripts.concat(scripts);
next(err);
});
@ -343,7 +342,7 @@ module.exports = function (Meta) {
}
Meta.js.target[target].scripts = Meta.js.target[target].scripts.map(function (script) {
return path.relative(basePath, script).replace(/\\/g, '/');
return path.resolve(basePath, script).replace(/\\/g, '/');
});
callback();
@ -357,7 +356,7 @@ module.exports = function (Meta) {
};
Meta.js.commitToFile = function (target, callback) {
fs.writeFile(path.join(__dirname, '../../build/public/' + target), Meta.js.target[target].cache, function (err) {
fs.writeFile(path.join(__dirname, '../../build/public', target), Meta.js.target[target].cache, function (err) {
callback(err);
});
};

@ -8,7 +8,6 @@ var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var file = require('../file');
var utils = require('../../public/src/utils');
var Plugins = require('../plugins');
var db = require('../database');
@ -67,7 +66,7 @@ function getTranslationTree(callback) {
async.parallel([
// get core languages and namespaces
function (nxt) {
utils.walk(coreLanguagesPath, function (err, paths) {
file.walk(coreLanguagesPath, function (err, paths) {
if (err) {
return nxt(err);
}
@ -80,7 +79,7 @@ function getTranslationTree(callback) {
function (nxt) {
async.each(plugins, function (pluginData, cb) {
var pathToFolder = path.join(__dirname, '../../node_modules/', pluginData.id, pluginData.languages);
utils.walk(pathToFolder, function (err, paths) {
file.walk(pathToFolder, function (err, paths) {
if (err) {
return cb(err);
}

@ -9,7 +9,7 @@ var fs = require('fs');
var nconf = require('nconf');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var file = require('../file');
var Templates = {};
@ -62,11 +62,11 @@ function preparePaths(baseTemplatesPaths, callback) {
async.parallel({
coreTpls: function (next) {
utils.walk(coreTemplatesPath, next);
file.walk(coreTemplatesPath, next);
},
baseThemes: function (next) {
async.map(baseTemplatesPaths, function (baseTemplatePath, next) {
utils.walk(baseTemplatePath, function (err, paths) {
file.walk(baseTemplatePath, function (err, paths) {
paths = paths.map(function (tpl) {
return {
base: baseTemplatePath,

@ -6,7 +6,7 @@ var validator = require('validator');
var winston = require('winston');
var plugins = require('../plugins');
var translator = require('../../public/src/modules/translator');
var translator = require('../translator');
module.exports = function (middleware) {
middleware.processRender = function (req, res, next) {

@ -3,7 +3,7 @@
var async = require('async');
var plugins = require('../plugins');
var db = require('../database');
var translator = require('../../public/src/modules/translator');
var translator = require('../translator');
var pubsub = require('../pubsub');
var admin = module.exports;

@ -2,7 +2,7 @@
var nconf = require('nconf');
var admin = require('./admin');
var translator = require('../../public/src/modules/translator');
var translator = require('../translator');
var navigation = {};

@ -13,7 +13,7 @@ var groups = require('./groups');
var meta = require('./meta');
var batch = require('./batch');
var plugins = require('./plugins');
var utils = require('../public/src/utils');
var utils = require('./utils');
(function (Notifications) {
Notifications.init = function () {

@ -2,6 +2,7 @@
(function (module) {
var fork = require('child_process').fork;
var path = require('path');
module.hash = function (rounds, password, callback) {
forkChild({ type: 'hash', rounds: rounds, password: password }, callback);
@ -16,7 +17,7 @@
if (global.v8debug || parseInt(process.execArgv.indexOf('--debug'), 10) !== -1) {
forkProcessParams = { execArgv: ['--debug=' + (5859), '--nolazy'] };
}
var child = fork('./bcrypt', [], forkProcessParams);
var child = fork(path.join(__dirname, 'bcrypt'), [], forkProcessParams);
child.on('message', function (msg) {
if (msg.err) {

@ -9,7 +9,6 @@ var express = require('express');
var nconf = require('nconf');
var db = require('./database');
var utils = require('../public/src/utils');
var hotswap = require('./hotswap');
var file = require('./file');
var languages = require('./languages');
@ -176,7 +175,7 @@ var middleware;
if (plugin.templates || plugin.id.startsWith('nodebb-theme-')) {
winston.verbose('[plugins] Loading templates (' + plugin.id + ')');
var templatesPath = path.join(__dirname, '../node_modules', plugin.id, plugin.templates || 'templates');
utils.walk(templatesPath, function (err, pluginTemplates) {
file.walk(templatesPath, function (err, pluginTemplates) {
if (pluginTemplates) {
pluginTemplates.forEach(function (pluginTemplate) {
if (pluginTemplate.endsWith('.tpl')) {

@ -4,7 +4,7 @@ var async = require('async');
var _ = require('underscore');
var db = require('./database');
var utils = require('../public/src/utils');
var utils = require('./utils');
var user = require('./user');
var topics = require('./topics');
var privileges = require('./privileges');

@ -9,7 +9,7 @@ var plugins = require('../plugins');
var user = require('../user');
var topics = require('../topics');
var categories = require('../categories');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Posts) {
Posts.create = function (data, callback) {

@ -11,7 +11,7 @@ var privileges = require('../privileges');
var plugins = require('../plugins');
var cache = require('./cache');
var pubsub = require('../pubsub');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Posts) {
pubsub.on('post:edit', function (pid) {

@ -9,7 +9,7 @@ var S = require('string');
var meta = require('../meta');
var cache = require('./cache');
var plugins = require('../plugins');
var translator = require('../../public/src/modules/translator');
var translator = require('../translator');
var urlRegex = /href="([^"]+)"/g;

@ -9,7 +9,7 @@ var db = require('../database');
var user = require('../user');
var plugins = require('../plugins');
var categories = require('../categories');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Posts) {

@ -4,7 +4,7 @@
var async = require('async');
var topics = require('../topics');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Posts) {
Posts.getPostsFromSet = function (set, start, stop, uid, reverse, callback) {

@ -10,7 +10,7 @@ var categories = require('./categories');
var user = require('./user');
var plugins = require('./plugins');
var privileges = require('./privileges');
var utils = require('../public/src/utils');
var utils = require('./utils');
var search = {};

@ -10,7 +10,7 @@ var topics = require('./topics');
var privileges = require('./privileges');
var meta = require('./meta');
var plugins = require('./plugins');
var utils = require('../public/src/utils');
var utils = require('./utils');
var sitemap = {
maps: {

@ -5,7 +5,7 @@ var async = require('async');
var groups = require('../groups');
var meta = require('../meta');
var user = require('../user');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var groupsController = require('../controllers/groups');
var SocketGroups = {};

@ -7,7 +7,7 @@ var meta = require('../meta');
var notifications = require('../notifications');
var plugins = require('../plugins');
var Messaging = require('../messaging');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var server = require('./');
var user = require('../user');

@ -3,7 +3,7 @@
var async = require('async');
var user = require('../user');
var notifications = require('../notifications');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var SocketNotifs = {};

@ -9,7 +9,7 @@ var topics = require('../topics');
var user = require('../user');
var websockets = require('./index');
var socketHelpers = require('./helpers');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var apiController = require('../controllers/api');

@ -11,7 +11,7 @@ var privileges = require('../../privileges');
var notifications = require('../../notifications');
var plugins = require('../../plugins');
var meta = require('../../meta');
var utils = require('../../../public/src/utils');
var utils = require('../../utils');
module.exports = function (SocketPosts) {
SocketPosts.flag = function (socket, data, callback) {

@ -5,7 +5,7 @@ var async = require('async');
var topics = require('../../topics');
var privileges = require('../../privileges');
var meta = require('../../meta');
var utils = require('../../../public/src/utils');
var utils = require('../../utils');
var social = require('../../social');
module.exports = function (SocketTopics) {

@ -3,7 +3,7 @@
var async = require('async');
var db = require('../../database');
var topics = require('../../topics');
var utils = require('../../../public/src/utils');
var utils = require('../../utils');
module.exports = function (SocketTopics) {
SocketTopics.isTagAllowed = function (socket, data, callback) {

@ -5,7 +5,7 @@ var _ = require('underscore');
var db = require('./database');
var posts = require('./posts');
var utils = require('../public/src/utils');
var utils = require('./utils');
var plugins = require('./plugins');
var user = require('./user');
var categories = require('./categories');

@ -5,7 +5,7 @@ var async = require('async');
var validator = require('validator');
var S = require('string');
var db = require('../database');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var plugins = require('../plugins');
var analytics = require('../analytics');
var user = require('../user');
@ -87,6 +87,10 @@ module.exports = function (Topics) {
], callback);
};
function rtrim(str) {
return str.replace(/\s+$/g, '');
}
Topics.post = function (data, callback) {
var uid = data.uid;
data.title = String(data.title).trim();
@ -101,7 +105,7 @@ module.exports = function (Topics) {
},
function (next) {
if (data.content) {
data.content = data.content.rtrim();
data.content = rtrim(data.content);
}
check(data.content, meta.config.minimumPostLength, meta.config.maximumPostLength, 'content-too-short', 'content-too-long', next);
},
@ -234,7 +238,7 @@ module.exports = function (Topics) {
function (filteredData, next) {
content = filteredData.content || data.content;
if (content) {
content = content.rtrim();
content = rtrim(content);
}
check(content, meta.config.minimumPostLength, meta.config.maximumPostLength, 'content-too-short', 'content-too-long', next);

@ -4,7 +4,7 @@ var validator = require('validator');
var db = require('../database');
var categories = require('../categories');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Topics) {
Topics.getTopicField = function (tid, field, callback) {

@ -7,7 +7,7 @@ var db = require('../database');
var meta = require('../meta');
var _ = require('underscore');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Topics) {

@ -9,7 +9,7 @@ var meta = require('../meta');
var user = require('../user');
var posts = require('../posts');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Topics) {
Topics.getTeasers = function (topics, uid, callback) {

@ -9,7 +9,7 @@ var notifications = require('../notifications');
var categories = require('../categories');
var privileges = require('../privileges');
var meta = require('../meta');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (Topics) {
Topics.getTotalUnread = function (uid, filter, callback) {

@ -0,0 +1,3 @@
'use strict';
module.exports = require('../public/src/modules/translator');

@ -9,8 +9,8 @@ var meta = require('../meta');
var emailer = require('../emailer');
var notifications = require('../notifications');
var groups = require('../groups');
var translator = require('../../public/src/modules/translator');
var utils = require('../../public/src/utils');
var translator = require('../translator');
var utils = require('../utils');
var plugins = require('../plugins');
module.exports = function (User) {

@ -2,7 +2,7 @@
var async = require('async');
var db = require('../database');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var validator = require('validator');
var plugins = require('../plugins');
var groups = require('../groups');

@ -7,7 +7,7 @@ var winston = require('winston');
var db = require('../database');
var plugins = require('../plugins');
var utils = require('../../public/src/utils');
var utils = require('../utils');
module.exports = function (User) {
var iconBackgrounds = ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3',

@ -10,7 +10,7 @@ var user = require('../user');
var topics = require('../topics');
var plugins = require('../plugins');
var emailer = require('../emailer');
var utils = require('../../public/src/utils');
var utils = require('../utils');
(function (Digest) {
Digest.execute = function (interval, callback) {

@ -5,8 +5,8 @@ var async = require('async');
var nconf = require('nconf');
var user = require('../user');
var utils = require('../../public/src/utils');
var translator = require('../../public/src/modules/translator');
var utils = require('../utils');
var translator = require('../translator');
var plugins = require('../plugins');
var db = require('../database');
var meta = require('../meta');

@ -7,8 +7,8 @@ var nconf = require('nconf');
var db = require('./../database');
var meta = require('../meta');
var emailer = require('../emailer');
var translator = require('../../public/src/modules/translator');
var utils = require('../../public/src/utils');
var translator = require('../translator');
var utils = require('../utils');
module.exports = function (User) {

@ -4,7 +4,7 @@
var async = require('async');
var S = require('string');
var utils = require('../../public/src/utils');
var utils = require('../utils');
var meta = require('../meta');
var db = require('../database');
var groups = require('../groups');

@ -5,8 +5,8 @@ var nconf = require('nconf');
var winston = require('winston');
var user = require('../user');
var utils = require('../../public/src/utils');
var translator = require('../../public/src/modules/translator');
var utils = require('../utils');
var translator = require('../translator');
var db = require('../database');
var meta = require('../meta');

@ -0,0 +1,3 @@
'use strict';
module.exports = require('../public/src/utils');

@ -5,7 +5,7 @@ var winston = require('winston');
var templates = require('templates.js');
var plugins = require('../plugins');
var translator = require('../../public/src/modules/translator');
var translator = require('../translator');
var db = require('../database');
var widgets = {};

@ -145,6 +145,27 @@ describe('new Translator(language)', function () {
assert.strictEqual(translated, 'Latest Users');
});
});
it('should use key for unknown keys without arguments', function () {
var translator = Translator.create('en-GB');
return translator.translate('[[unknown:key.without.args]]').then(function (translated) {
assert.strictEqual(translated, 'key.without.args');
});
});
it('should use backup for unknown keys with arguments', function () {
var translator = Translator.create('en-GB');
return translator.translate('[[unknown:key.with.args, arguments are here, derpity, derp]]').then(function (translated) {
assert.strictEqual(translated, '&lsqb;&lsqb;unknown:key.with.args, arguments are here, derpity, derp&lsqb;&lsqb;');
});
});
it('should ignore unclosed tokens', function () {
var translator = Translator.create('en-GB');
return translator.translate('here is some stuff and other things [[abc:xyz, other random stuff should be fine here [[global:home]] and more things [[pages:users/latest]]').then(function (translated) {
assert.strictEqual(translated, 'here is some stuff and other things &lsqb;&lsqb;abc:xyz, other random stuff should be fine here Home and more things Latest Users');
});
});
});
});

Loading…
Cancel
Save