Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules
npm-debug.log
*.pem
package-lock.json
jsconfig.json
File renamed without changes.
26 changes: 26 additions & 0 deletions dictionaries/racist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"en": [
"nigger",
"gook",
"ape",
"coon",
"jigaboo",
"negro",
"sambo",
"sooty",
"teapot",
"cracker",
"gringo",
"gweilo",
"gwailo",
"kwai lo",
"honky",
"redskin",
"white trash",
"slave",
"whitelist",
"white list",
"blacklist",
"black list"
]
}
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ module.exports = async robot => {
}

async function forRepository (context) {
let config = await getConfig(context, 'profanity.yml')
let config = await getConfig(context, 'profanity.yml', null)

if (!config) {
scheduler.stop(context.payload.repository)
Expand Down
25 changes: 23 additions & 2 deletions lib/profanity.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const blacklist = require('../config/blacklist.json')
const Filter = require('./filter')
const schema = require('./schema')

Expand Down Expand Up @@ -27,11 +26,12 @@ module.exports = class Profanity {
getFilter () {
const {
language,
dictionaries,
extraWords,
exemptWords,
placeholder
} = this.config
const list = blacklist[language]
const list = this.getForbiddenWordList(dictionaries, language)

return new Filter({
list: list,
Expand All @@ -41,6 +41,27 @@ module.exports = class Profanity {
})
}

/**
* Get the flattened forbidden words list for the specified dictionaries and language
*
* @param {string[]} dictionaries The list of dictionaries to use
* @param {string} language The language code to use
* @returns {string[]} The flattened list of forbidden words
*/
getForbiddenWordList (dictionaries, language) {
if (!dictionaries || !dictionaries.length || !language) {
return []
}

return Array.from(new Set(dictionaries.reduce((acc, dictName) => {
const dictionary = require('../dictionaries/' + dictName)
if (!dictionary || !dictionary[language]) {
return acc
}
return acc.concat(dictionary[language])
}, [])))
}

async markAndSweep (type) {
const {only} = this.config
if (only && only !== type) {
Expand Down
4 changes: 4 additions & 0 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const fields = {
censor: Joi.boolean()
.description('Set to true to censor issues (defaults to false)'),

dictionaries: Joi.array().items(Joi.string().valid('profanity', 'racist')).min(1).single()
.description('The dictionaries of forbidden words to use'),

placeholder: Joi.string().max(1)
.description('A letter to replace those of a forbidden word'),

Expand Down Expand Up @@ -52,6 +55,7 @@ const fields = {
const schema = Joi.object().keys({
language: fields.language.default('en'),
censor: fields.censor.default(false),
dictionaries: fields.dictionaries.default(['profanity', 'racist']),
placeholder: fields.placeholder.default('*'),
extraWords: fields.extraWords.default([]),
exemptWords: fields.exemptWords.default([]),
Expand Down
45 changes: 33 additions & 12 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions test/schema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const validConfigs = [
[{language: 'en'}],
[{censor: true}],
[{censor: false}],
[{dictionaries: ['profanity']}],
[{dictionaries: ['racist', 'profanity']}],
[{placeholder: '*'}],
[{extraWords: ['duck']}],
[{extraWords: 'duck'}, {extraWords: ['duck']}],
Expand Down Expand Up @@ -44,6 +46,8 @@ const validConfigs = [
const invalidConfigs = [
[{language: 'bananas'}, 'must be one of [de, en, es, fr, it, nl, pt, ru]'],
[{censor: 'nope'}, 'must be a boolean'],
[{dictionaries: ['fake']}, 'must be one of [profanity, racist]'],
[{dictionaries: []}, 'must contain at least 1 items'],
[{placeholder: ''}, 'not allowed to be empty'],
[{placeholder: false}, 'must be a string'],
[{placeholder: ['a', 'b']}, 'must be a string'],
Expand Down Expand Up @@ -72,6 +76,7 @@ describe('schema', () => {
expect(schema.validate({}).value).toEqual({
language: 'en',
censor: false,
dictionaries: ['profanity', 'racist'],
placeholder: '*',
extraWords: [],
exemptWords: [],
Expand Down