Comparing version 0.1.3 to 0.3.1
[ | ||
"бандл", | ||
"десктопных", | ||
"десктопной", | ||
"закоммиченное", | ||
"конфига", | ||
"маппинга", | ||
"минимизатором", | ||
"шаблонизатор", | ||
"шаблонизаторы", | ||
"разработческий", | ||
"рендеринга", | ||
"чекаута", | ||
"чекаутом" | ||
] | ||
"масква" | ||
] |
327
bin/cli.js
#!/usr/bin/env node | ||
var fs = require('fs'), | ||
pth = require('path'), | ||
request = require('request'), | ||
chalk = require('chalk'), | ||
isutf8 = require('isutf8'), | ||
Q = require('q'), | ||
program = require('commander'), | ||
yaspeller = require('../lib/yaspeller'), | ||
program = require('commander'), | ||
xml2js = require('xml2js'), | ||
printDebug = require('../lib/print_debug'), | ||
FILENAME_DICTIONARY = '.yaspeller.dictionary.json', | ||
FILE_EXTENSIONS = ['wiki', 'md', 'txt', 'text', 'html', 'htm', 'json', 'js', 'css', 'xml', 'svg'], | ||
isDir = function(path) { | ||
return fs.statSync(path).isDirectory(); | ||
}, | ||
dictionary = []; | ||
dictionary; | ||
if(fs.existsSync(FILENAME_DICTIONARY)) { | ||
dictionary = JSON.parse(fs.readFileSync(FILENAME_DICTIONARY, 'utf-8')); | ||
} | ||
function getDictionary(filename) { | ||
var dict; | ||
function printErrors(resource, words) { | ||
var bufWords = delDuplicates(words); | ||
printDebug('get/check dictionary: ' + filename); | ||
if(fs.existsSync(filename)) { | ||
try { | ||
dict = fs.readFileSync(filename); | ||
if(!isutf8(dict)) { | ||
console.error(filename + ': is not utf-8'); | ||
process.exit(1); | ||
} | ||
bufWords = markRuEnSymbols(bufWords); | ||
if(bufWords.length) { | ||
console.log('Resource: ' + resource); | ||
console.log('typos: ' + bufWords.join(', ') + '\n'); | ||
dictionary = JSON.parse(dict.toString('utf-8')); | ||
printDebug('use dictionary: ' + filename); | ||
} catch(e) { | ||
console.error(filename + ': error parsing JSON'); | ||
process.exit(1); | ||
} | ||
} | ||
} | ||
function firstUpperCase(word) { | ||
return word.substr(0, 1).toUpperCase() + word.substr(1); | ||
return dict || []; | ||
} | ||
function delDuplicates(ar) { | ||
var props = {}, | ||
result = []; | ||
function getTypos(data) { | ||
var buf = []; | ||
data.forEach(function(el) { | ||
var find = false; | ||
// ERROR_UNKNOWN_WORD: Слова нет в словаре | ||
if(el.code === 1) { | ||
dictionary.some(function(el2) { | ||
if(el2 === el.word) { | ||
find = true; | ||
} | ||
ar.forEach(function(el) { | ||
if(props[el]) { | ||
props[el]++; | ||
} else { | ||
props[el] = 1; | ||
return find; | ||
}); | ||
} | ||
if(!find) { | ||
buf.push(el.word); | ||
} | ||
}); | ||
Object.keys(props).forEach(function(key) { | ||
if(props[key] > 1) { | ||
result.push(key + ' (' + props[key] + ')'); | ||
} else { | ||
result.push(key); | ||
var obj = {}; | ||
buf.forEach(function(word) { | ||
if(!obj[word]) { | ||
obj[word] = { | ||
count: 0, | ||
comment: [] | ||
}; | ||
if(word.search(/[a-z]/i) > -1 && word.search(/[а-яё]/i) > -1) { | ||
obj[word].comment = [ | ||
chalk.red('en: ' + word.replace(/[а-яё]/gi, '*')), | ||
chalk.green('ru: ' + word.replace(/[a-z]/gi, '*')) | ||
]; | ||
} | ||
} | ||
obj[word].count++; | ||
}); | ||
return result.sort(); | ||
} | ||
var typos = []; | ||
Object.keys(obj).forEach(function(w) { | ||
var comment = [], | ||
item = obj[w]; | ||
if(item.count > 1) { | ||
comment.push(chalk.cyan('count: ' + item.count)); | ||
} | ||
function markRuEnSymbols(words) { | ||
var result = []; | ||
words.forEach(function(el) { | ||
if(el.search(/[a-z]/i) !== -1 && el.search(/[а-яё]/i) !== -1) { | ||
result.push(el + ' (en: ' + el.replace(/[а-яё]/gi, '*') + ', ru: ' + el.replace(/[a-z]/gi, '*') + ')'); | ||
} else { | ||
result.push(el); | ||
if(item.comment.length) { | ||
comment = comment.concat(item.comment); | ||
} | ||
typos.push(w + (comment.length ? ' (' + comment.join(', ') + ')' : '')); | ||
}); | ||
return result; | ||
return typos; | ||
} | ||
function getWords(data) { | ||
var res = []; | ||
function getRepeatWords(data) { | ||
var words = []; | ||
data.forEach(function(el) { | ||
var word = firstUpperCase(el.word); | ||
var find = false; | ||
dictionary.forEach(function(el2) { | ||
var dword = firstUpperCase(el2); | ||
if(dword === word) { | ||
find = true; | ||
} | ||
}); | ||
if(!find) { | ||
res.push(el.word); | ||
// ERROR_REPEAT_WORD: Повтор слова | ||
if(el.code === 2) { | ||
words.push(el.word); | ||
} | ||
}); | ||
return res; | ||
return words; | ||
} | ||
function checkText(text, resource, options) { | ||
// Если в тексте нет русских символов, то проверять не нужно | ||
if(!text || (options.lang === 'ru' && text.search(/[а-яё]/i) === -1)) { | ||
return; | ||
} | ||
yaspeller.checkText(text, options.lang, options.options, options.format, function(error, data) { | ||
var words = getWords(data); | ||
printErrors(resource, words); | ||
function getCapitalisation(data) { | ||
var words = []; | ||
data.forEach(function(el) { | ||
// ERROR_CAPITALIZATION: Неверное употребление прописных и строчных букв | ||
if(el.code === 3) { | ||
words.push(el.word); | ||
} | ||
}); | ||
} | ||
function checkFile(file, options) { | ||
var text = fs.readFileSync(file, 'utf-8'); | ||
checkText(text, file, options); | ||
return words; | ||
} | ||
function checkUrl(url, options) { | ||
request.get(url, function(error, response, text) { | ||
checkText(text, url, options); | ||
function hasManyErrors(data) { | ||
var hasErrors = false; | ||
data.some(function(el) { | ||
// ERROR_TOO_MANY_ERRORS: Текст содержит слишком много ошибок | ||
if(el.code === 4) { | ||
hasErrors = true; | ||
return true; | ||
} | ||
return false; | ||
}); | ||
return hasErrors; | ||
} | ||
function checkDir(dir, options) { | ||
var files = findFiles(Array.isArray(dir) ? dir : [dir]); | ||
files.forEach(function(file) { | ||
checkFile(file, options); | ||
}); | ||
function getTextError(title, words) { | ||
var SEPARATOR = '\n-----'; | ||
return chalk.cyan(title + ': ' + words.length + SEPARATOR + '\n') + words.join('\n') + chalk.cyan(SEPARATOR); | ||
} | ||
function findFiles(files) { | ||
var res = [], | ||
regExp = new RegExp('\.(' + FILE_EXTENSIONS.join('|') + ')$', 'i'), | ||
find = function (path) { | ||
var files = fs.readdirSync(path); | ||
files.forEach(function (el) { | ||
var file = pth.join(path, el); | ||
if (isDir(file)) { | ||
find(file); | ||
} else if (file.search(regExp) !== -1) { | ||
res.push(file); | ||
} | ||
}); | ||
}; | ||
function buildResource(err, data) { | ||
if(err) { | ||
console.error(chalk.red(data)); | ||
} else { | ||
var typos = getTypos(data.data), | ||
repeatWords = getRepeatWords(data.data), | ||
capitalization = getCapitalisation(data.data), | ||
textErrors = []; | ||
files.forEach(function (el) { | ||
if(isDir(el)) { | ||
find(el); | ||
} else { | ||
res.push(el); | ||
if(hasManyErrors(data.data)) { | ||
textErrors.push(chalk.red('Too many errors')); | ||
} | ||
}); | ||
return res; | ||
} | ||
if(repeatWords.length) { | ||
textErrors.push(getTextError('Repeat words', repeatWords)); | ||
} | ||
function checkSitemap(url, options) { | ||
request.get(url, function(error, response, xml) { | ||
var parser = new xml2js.Parser(); | ||
parser.parseString(xml, function (err, result) { | ||
result.urlset.url.forEach(function(el) { | ||
el.loc.forEach(function(url) { | ||
checkUrl(url, options); | ||
}); | ||
}); | ||
}); | ||
}); | ||
if(capitalization.length) { | ||
textErrors.push(getTextError('Capitalization', capitalization)); | ||
} | ||
if(typos.length) { | ||
textErrors.push(getTextError('Typos', typos)); | ||
} | ||
if(textErrors.length) { | ||
console.error(chalk.red.bold('[ERR]'), data.resource); | ||
console.error(textErrors.join('\n') + '\n'); | ||
} else { | ||
console.log(chalk.bold.green('[OK]'), data.resource); | ||
} | ||
} | ||
} | ||
program | ||
.version(JSON.parse(fs.readFileSync(__dirname + '/../package.json')).version) | ||
.usage('[options] <file-or-directory-or-link>') | ||
.version(require('../package.json').version) | ||
.usage('[options] <file-or-directory-or-link...>') | ||
.option('-l, --lang <s>', 'Langs: ru, en, tr. Default: "en,ru"') | ||
.option('-d, --debug', 'Debug mode') | ||
.option('-di, --dictionary <s>', 'json file for own dictionary') | ||
.option('-f, --format <s>', 'Formats: plain or html. Default: plain') | ||
.parse(process.argv); | ||
var resource = process.argv[2], | ||
timeA = Date.now(), | ||
opt = {format: 'html', lang: 'ru'}; | ||
var startTime = Date.now(), | ||
settings = {}; | ||
if(!resource) { | ||
if(program.lang) { | ||
settings.lang = program.lang; | ||
} | ||
if(program.format) { | ||
settings.format = program.format; | ||
} | ||
if(!program.args.length) { | ||
program.help(); | ||
} | ||
if(resource.search(/^https?:/) !== -1) { | ||
if(resource.search(/sitemap\.xml$/) !== -1) { | ||
checkSitemap(resource, opt); | ||
} else { | ||
checkUrl(resource, opt); | ||
} | ||
} else { | ||
if(fs.existsSync(resource)) { | ||
if(isDir(resource)) { | ||
checkDir(resource, opt); | ||
var hasErrors = false, | ||
onNext = function(data) { | ||
data.forEach(function(el) { | ||
if(el[0]) { | ||
hasErrors = true; | ||
} | ||
buildResource(el[0], el[1]); | ||
}); | ||
}; | ||
yaspeller.setDebug(program.debug); | ||
dictionary = getDictionary(program.dictionary || FILENAME_DICTIONARY); | ||
var queries = []; | ||
program.args.forEach(function(resource) { | ||
queries.push(Q.Promise(function(resolve) { | ||
if(resource.search(/^https?:/) > -1) { | ||
if(resource.search(/sitemap\.xml$/) > -1) { | ||
yaspeller.checkSitemap(resource, function(err, data) { | ||
onNext(err, data); | ||
resolve(); | ||
}, settings); | ||
} else { | ||
yaspeller.checkUrl(resource, function(err, data) { | ||
onNext([[err, data]]); | ||
resolve(); | ||
}, settings); | ||
} | ||
} else { | ||
checkFile(resource, opt); | ||
if(fs.existsSync(resource)) { | ||
if(fs.statSync(resource).isDirectory()) { | ||
yaspeller.checkDir(resource, function(err, data) { | ||
onNext(err, data); | ||
resolve(); | ||
}, settings); | ||
} else { | ||
yaspeller.checkFile(resource, function(err, data) { | ||
onNext([[err, data]]); | ||
resolve(); | ||
}, settings); | ||
} | ||
} else { | ||
onNext([[true, Error(resource + ': is not exists')]]); | ||
resolve(); | ||
} | ||
} | ||
} else { | ||
console.log(resource + ': No such file or directory'); | ||
} | ||
} | ||
})); | ||
}); | ||
Q.all(queries).then(function() { | ||
console.log(chalk.magenta('Build finished: ' + ((+new Date() - startTime) / 1000) + ' sec.')); | ||
process.exit(hasErrors ? 1 : 0); | ||
}); |
@@ -1,20 +0,69 @@ | ||
var http = require('http'), | ||
qs = require('querystring'), | ||
request = require('request'); | ||
/* jshint maxlen: 300 */ | ||
var request = require('request'), | ||
pth = require('path'), | ||
fs = require('fs'), | ||
isutf8 = require('isutf8'), | ||
Q = require('q'), | ||
printDebug = require('./print_debug'), | ||
xml2js = require('xml2js'), | ||
settings = null, | ||
isDebug = false, | ||
fileExtensions; | ||
var FILENAME_SETTINGS = 'yaspeller.json', | ||
YASPELLER_API_URL = 'http://speller.yandex.net/services/spellservice.json/checkText'; | ||
function getExtension(file) { | ||
var buf = file.split('.'); | ||
return buf[buf.length - 1]; | ||
} | ||
function isDir(dir) { | ||
return fs.statSync(dir).isDirectory(); | ||
} | ||
function getFormat(format, ext) { | ||
if(!format || format === 'auto') { | ||
var exts = getSettings().fileExtensions; | ||
if(exts[ext] && exts[ext].format) { | ||
return exts[ext].format; | ||
} else { | ||
return 'plain'; | ||
} | ||
} | ||
return format; | ||
} | ||
function getSettings() { | ||
if(!settings) { | ||
settings = JSON.parse(fs.readFileSync(FILENAME_SETTINGS)); | ||
} | ||
return settings; | ||
} | ||
/*function getFileExtensions() { | ||
if(!fileExtensions) { | ||
fileExtensions = Object.keys(getSettings().fileExtensions); | ||
} | ||
return fileExtensions; | ||
}*/ | ||
function getOptions(options) { | ||
var result = 0, | ||
standartOptions = { | ||
IGNORE_UPPERCASE: 1, // Пропускать слова, написанные заглавными буквами, например, "ВПК" | ||
IGNORE_DIGITS: 2, //Пропускать слова с цифрами, например, "авп17х4534" | ||
IGNORE_URLS: 4, // Пропускать интернет-адреса, почтовые адреса и имена файлов | ||
FIND_REPEAT_WORDS: 8, // Подсвечивать повторы слов, идущие подряд. Например, "я полетел на на Кипр" | ||
IGNORE_LATIN: 16, // Пропускать слова, написанные латиницей, например, "madrid" | ||
NO_SUGGEST: 32, // Только проверять текст, не выдавая вариантов для замены | ||
FLAG_LATIN: 128, // Отмечать слова, написанные латиницей, как ошибочные | ||
BY_WORDS: 256, // Не использовать словарное окружение (контекст) при проверке. Опция полезна в случаях, когда на вход сервиса передается список отдельных слов | ||
IGNORE_CAPITALIZATION: 512, // Игнорировать неверное употребление ПРОПИСНЫХ/строчных букв, например, в слове "москва" | ||
IGNORE_ROMAN_NUMERALS: 2048 // Игнорировать римские цифры ("I, II, III, ...") | ||
}; | ||
IGNORE_UPPERCASE: 1, | ||
IGNORE_DIGITS: 2, | ||
IGNORE_URLS: 4, | ||
FIND_REPEAT_WORDS: 8, | ||
IGNORE_LATIN: 16, | ||
NO_SUGGEST: 32, | ||
FLAG_LATIN: 128, | ||
BY_WORDS: 256, | ||
IGNORE_CAPITALIZATION: 512, | ||
IGNORE_ROMAN_NUMERALS: 2048 | ||
}; | ||
Object.keys(options || {}).forEach(function(key) { | ||
@@ -25,3 +74,3 @@ if(standartOptions[key] && options[key]) { | ||
}); | ||
return result; | ||
@@ -31,29 +80,85 @@ } | ||
function prepareText(text, format) { | ||
text = text.replace(/<\/?[^>]+>/g, ' '); | ||
text = text.replace(/\s+/g, ' '); | ||
text = ('' + text).trim(); | ||
return text; | ||
var buf = text.trim(); | ||
if(format === 'html') { | ||
buf = buf.replace(/<\/?[^>]+>/g, ' '); // strip html tags | ||
} | ||
return buf.replace(/\r\n/g, '\n') // fix Windows | ||
.replace(/\r/g, '\n') // fix MacOS | ||
.replace(/\s+\n/g, '\n') // trailling spaces | ||
.replace(/\s+/g, ' ') // repeat spaces | ||
.replace(/\n+/g, '\n') | ||
.trim(); | ||
} | ||
function checkText(text, lang, options, format, callback) { | ||
var bufText; | ||
function findFiles(dir) { | ||
var res = [], | ||
regExp = new RegExp('\\.(' + fileExtensions.join('|') + ')$', 'i'), | ||
find = function(path) { | ||
var files = fs.readdirSync(path); | ||
files.forEach(function(el) { | ||
var file = pth.join(path, el); | ||
if(isDir(file)) { | ||
find(file); | ||
} else if(file.search(regExp) !== -1) { | ||
res.push(file); | ||
} | ||
}); | ||
}; | ||
if(isDir(dir)) { | ||
find(dir); | ||
} else { | ||
res.push(dir); | ||
} | ||
return res; | ||
} | ||
/** | ||
* Check text for typos | ||
* | ||
* @param {string} text | ||
* @param {Function} callback | ||
* @tutorial settings | ||
* @param {Object} [settings] Настройки | ||
* @param {string} [settings.format] Формат текста: plain или html | ||
* @param {string|Array} [settings.lang] Языки проверки: ru – русский, uk – украинский, en – английский | ||
* @param {Object} [settings.options] Опции | ||
* @param {boolean} [settings.options.IGNORE_UPPERCASE] Пропускать слова, написанные заглавными буквами, например, "ВПК" | ||
* @param {boolean} [settings.options.IGNORE_DIGITS] Пропускать слова с цифрами, например, "авп17х4534" | ||
* @param {boolean} [settings.options.IGNORE_URLS] Пропускать интернет-адреса, почтовые адреса и имена файлов | ||
* @param {boolean} [settings.options.FIND_REPEAT_WORDS] Подсвечивать повторы слов, идущие подряд. Например, "я полетел на на Кипр" | ||
* @param {boolean} [settings.options.IGNORE_LATIN] Пропускать слова, написанные латиницей, например, "madrid" | ||
* @param {boolean} [settings.options.NO_SUGGEST] Только проверять текст, не выдавая вариантов для замены | ||
* @param {boolean} [settings.options.FLAG_LATIN] Отмечать слова, написанные латиницей, как ошибочные | ||
* @param {boolean} [settings.options.BY_WORDS] Не использовать словарное окружение (контекст) при проверке. Опция полезна в случаях, когда на вход сервиса передается список отдельных слов | ||
* @param {boolean} [settings.options.IGNORE_CAPITALIZATION] Игнорировать неверное употребление ПРОПИСНЫХ/строчных букв, например, в слове "москва" | ||
* @param {boolean} [settings.options.IGNORE_ROMAN_NUMERALS] Игнорировать римские цифры ("I, II, III, ...") | ||
*/ | ||
function checkText(text, callback, settings) { | ||
settings = settings || {}; | ||
var bufText, | ||
format = settings.format, | ||
options = settings.options, | ||
lang = settings.lang; | ||
if(Array.isArray(text)) { | ||
bufText = []; | ||
text.forEach(function(el) { | ||
var t = prepareText(text, format); | ||
if(t) { | ||
bufText.push(t); | ||
} | ||
bufText.push(prepareText(el, format)); | ||
}); | ||
bufText = bufText.join('\n'); | ||
} else { | ||
bufText = prepareText(text, format); | ||
} | ||
if(Array.isArray(lang)) { | ||
lang = lang.join(','); | ||
} | ||
request.post('http://speller.yandex.net/services/spellservice.json/checkText', { | ||
request.post(YASPELLER_API_URL, { | ||
form: { | ||
@@ -65,7 +170,7 @@ format: format || 'plain', | ||
} | ||
}, function (error, response, body) { | ||
}, function(error, response, body) { | ||
if(!error && response.statusCode === 200) { | ||
callback(false, JSON.parse(body)); | ||
} else { | ||
callback(true, response.statusCode); | ||
callback(true, Error('API returns status code is ' + response.statusCode)); | ||
} | ||
@@ -75,4 +180,206 @@ }); | ||
/** | ||
* Check text in file on typos | ||
* | ||
* @param {string} file | ||
* @param {Function} callback | ||
* @param {Object} [settings] See {@tutorial options} | ||
*/ | ||
function checkFile(file, callback, settings) { | ||
settings = settings || {}; | ||
if(isDebug) { | ||
printDebug('get: ' + file); | ||
} | ||
if(fs.existsSync(file)) { | ||
if(fs.statSync(file).isFile()) { | ||
var buf = fs.readFileSync(file); | ||
if(isutf8(buf)) { | ||
settings.format = getFormat(settings.format, getExtension(file, settings.format)); | ||
if(isDebug) { | ||
printDebug('post text -> api: ' + file); | ||
} | ||
checkText(buf.toString(), function(err, data) { | ||
callback(err, !err ? {resource: file, data: data} : data); | ||
}, settings); | ||
} else { | ||
callback(true, Error(file + ': is not utf-8')); | ||
} | ||
} else { | ||
callback(true, Error(file + ': is not file')); | ||
} | ||
} else { | ||
callback(true, Error(file + ': is not exists')); | ||
} | ||
} | ||
/** | ||
* Check text on link for typos | ||
* | ||
* @param {string} url | ||
* @param {Function} callback | ||
* @param {Object} [settings] See {@tutorial settings} | ||
*/ | ||
function checkUrl(url, callback, settings) { | ||
if(isDebug) { | ||
printDebug('get: ' + url); | ||
} | ||
request.get(url, function(error, response, text) { | ||
if(error || response.statusCode !== 200) { | ||
callback(true, Error(url + ': returns status code is ' + response.statusCode)); | ||
return; | ||
} | ||
checkText(text, function(err, data) { | ||
callback(err, {resource: url, data: data}); | ||
}, settings); | ||
}); | ||
} | ||
/** | ||
* Check text in files in folders on typos | ||
* | ||
* @param {string} dir | ||
* @param {Function} callback | ||
* @param {Object} [settings] See {@tutorial settings} | ||
*/ | ||
function checkDir(dir, callback, settings) { | ||
if(!fs.existsSync(dir)) { | ||
callback([[true, Error(dir + ': file or directory is not exists')]]); | ||
return; | ||
} | ||
var files = findFiles(dir), | ||
queries = []; | ||
files.forEach(function(file) { | ||
queries.push(Q.Promise(function(resolve) { | ||
checkFile(file, function(err, data) { | ||
resolve([err, data]); | ||
}, settings); | ||
})); | ||
}); | ||
Q.all(queries).done(function(data) { | ||
callback(data); | ||
}); | ||
} | ||
/** | ||
* Check text on pages of sitemap.xml | ||
* | ||
* @param {string} url | ||
* @param {Function} callback | ||
* @param {Object} [settings] See {@tutorial settings} | ||
*/ | ||
function checkSitemap(url, callback, settings) { | ||
var queries = [], | ||
results = []; | ||
if(isDebug) { | ||
printDebug('get: ' + url); | ||
} | ||
request.get(url, function(error, response, xml) { | ||
if(error || response.statusCode !== 200) { | ||
results.push([true, Error(url + ': returns status code is ' + response.statusCode)]); | ||
callback(results); | ||
return; | ||
} | ||
var parser = new xml2js.Parser(); | ||
parser.parseString(xml, function(err, result) { | ||
if(err) { | ||
results.push([true, Error(url + ': error parsing xml')]); | ||
callback(results); | ||
return; | ||
} | ||
if(result && result.urlset && Array.isArray(result.urlset.url)) { | ||
result.urlset.url.forEach(function(el) { | ||
el.loc.forEach(function(url) { | ||
queries.push(Q.Promise(function(resolve) { | ||
checkUrl(url, function(err, data) { | ||
resolve([err, data]); | ||
}, settings); | ||
})); | ||
}); | ||
}); | ||
} | ||
Q.all(queries).done(function(data) { | ||
callback(data); | ||
}); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Check text on pages of sitemap.xml | ||
* | ||
* @param {string} url | ||
* @param {Function} callback | ||
* @param {Object} [settings] See {@tutorial settings} | ||
*/ | ||
function checkSitemap(url, callback, settings) { | ||
var queries = [], | ||
results = []; | ||
if(isDebug) { | ||
printDebug('get: ' + url); | ||
} | ||
request.get(url, function(error, response, xml) { | ||
if(error || response.statusCode !== 200) { | ||
results.push([true, Error(url + ': returns status code is ' + response.statusCode)]); | ||
callback(results); | ||
return; | ||
} | ||
var parser = new xml2js.Parser(); | ||
parser.parseString(xml, function(err, result) { | ||
if(err) { | ||
results.push([true, result]); | ||
callback(results); | ||
return; | ||
} | ||
if(result && result.urlset && Array.isArray(result.urlset.url)) { | ||
result.urlset.url.forEach(function(el) { | ||
el.loc.forEach(function(url) { | ||
queries.push(Q.Promise(function(resolve) { | ||
checkUrl(url, function(err, data) { | ||
resolve([err, data]); | ||
}, settings); | ||
})); | ||
}); | ||
}); | ||
} | ||
Q.all(queries).done(function(data) { | ||
callback(data); | ||
}); | ||
}); | ||
}); | ||
} | ||
module.exports = { | ||
checkText: checkText | ||
setDebug: function(val) { | ||
isDebug = val; | ||
}, | ||
setFileExtensions: function(exts) { | ||
fileExtensions = exts; | ||
}, | ||
getSettings: getSettings, | ||
checkText: checkText, | ||
checkFile: checkFile, | ||
checkDir: checkDir, | ||
checkUrl: checkUrl, | ||
checkSitemap: checkSitemap | ||
}; |
{ | ||
"author": { | ||
"name": "Denis Seleznev", | ||
"email": "hcodes@yandex.ru", | ||
"url": "https://github.com/hcodes" | ||
}, | ||
"name": "yaspeller", | ||
"main": "index.js", | ||
"description": "Проверка опечаток в текстах, в файлах и на сайтах", | ||
"version": "0.1.3", | ||
"homepage": "https://github.com/hcodes/yaspeller", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/hcodes/yaspeller.git" | ||
}, | ||
"keywords": [ | ||
"typos", "text", "опечатки", "текст", "Яндекс.Спеллер", "Yandex.Speller" | ||
], | ||
"dependencies": { | ||
"commander": "~1.3", | ||
"request": "~2.47", | ||
"xml2js": "~0.4" | ||
}, | ||
"devDependencies": {}, | ||
"optionalDependencies": {}, | ||
"engines": { | ||
"node": "*" | ||
}, | ||
"bin": { | ||
"yaspeller": "./bin/cli.js" | ||
} | ||
"author": { | ||
"name": "Denis Seleznev", | ||
"email": "hcodes@yandex.ru", | ||
"url": "https://github.com/hcodes" | ||
}, | ||
"name": "yaspeller", | ||
"main": "index.js", | ||
"description": "Проверка опечаток в текстах, в файлах и на сайтах", | ||
"version": "0.3.1", | ||
"license": "MIT", | ||
"homepage": "https://github.com/hcodes/yaspeller", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/hcodes/yaspeller.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/hcodes/yaspeller/issues" | ||
}, | ||
"keywords": [ | ||
"typos", "text", "опечатки", "текст", "Яндекс.Спеллер", "Yandex.Speller" | ||
], | ||
"dependencies": { | ||
"commander": "~2.5", | ||
"request": "~2.x", | ||
"isutf8": "~1.0", | ||
"xml2js": "~0.4", | ||
"chalk": "0.5.1", | ||
"q": "~1.1.2" | ||
}, | ||
"devDependencies": { | ||
"mocha": "2.0.x", | ||
"chai": "1.x", | ||
"istanbul": "0.3.x", | ||
"jscs": "1.8.x", | ||
"jshint": "2.x" | ||
}, | ||
"optionalDependencies": {}, | ||
"engines": { | ||
"node": "*" | ||
}, | ||
"scripts": { | ||
"test": "npm run-script jshint && npm run-script check-style && npm run-script unit-test-coverage", | ||
"jscs": "./node_modules/.bin/jscs .", | ||
"jshint": "./node_modules/.bin/jshint .", | ||
"unit-test": "./node_modules/.bin/mocha -u bdd -R spec --recursive test", | ||
"unit-test-coverage": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- -u bdd -R spec --recursive test" | ||
}, | ||
"bin": { | ||
"yaspeller": "./bin/cli.js" | ||
} | ||
} |
yaspeller | ||
========= | ||
[![NPM version](https://badge.fury.io/js/yaspeller.svg)](http://badge.fury.io/js/yaspeller) | ||
[![Build Status](https://travis-ci.org/hcodes/yaspeller.png?branch=master)](https://travis-ci.org/hcodes/yaspeller) | ||
[![Coverage Status](https://coveralls.io/repos/hcodes/yaspeller/badge.png?branch=master)](https://coveralls.io/r/hcodes/yaspeller) | ||
[![Dependency Status](https://gemnasium.com/hcodes/yaspeller.svg)](https://gemnasium.com/hcodes/yaspeller) | ||
Средство поиска опечаток в текстах, в файлах и на сайтах. | ||
@@ -4,0 +9,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
29518
23
0
739
0
20
6
5
3
+ Addedchalk@0.5.1
+ Addedisutf8@~1.0
+ Addedq@~1.1.2
+ Addedajv@6.12.6(transitive)
+ Addedansi-regex@0.2.1(transitive)
+ Addedansi-styles@1.1.0(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@1.0.0(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedaws-sign2@0.7.0(transitive)
+ Addedaws4@1.13.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedchalk@0.5.1(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcommander@2.5.1(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@2.3.3(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhas-ansi@0.1.0(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedisutf8@1.0.11(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedoauth-sign@0.9.0(transitive)
+ Addedperformance-now@2.1.0(transitive)
+ Addedpsl@1.9.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedq@1.1.2(transitive)
+ Addedqs@6.5.3(transitive)
+ Addedrequest@2.88.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedstrip-ansi@0.3.0(transitive)
+ Addedsupports-color@0.2.0(transitive)
+ Addedtough-cookie@2.5.0(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedverror@1.10.0(transitive)
- Removedasn1@0.1.11(transitive)
- Removedassert-plus@0.1.5(transitive)
- Removedasync@0.9.2(transitive)
- Removedaws-sign2@0.5.0(transitive)
- Removedbl@0.9.5(transitive)
- Removedboom@0.4.2(transitive)
- Removedcaseless@0.6.0(transitive)
- Removedcombined-stream@0.0.7(transitive)
- Removedcommander@1.3.2(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removedcryptiles@0.2.2(transitive)
- Removedctype@0.5.3(transitive)
- Removeddelayed-stream@0.0.5(transitive)
- Removedforever-agent@0.5.2(transitive)
- Removedform-data@0.1.4(transitive)
- Removedhawk@1.1.1(transitive)
- Removedhoek@0.9.1(transitive)
- Removedhttp-signature@0.10.1(transitive)
- Removedinherits@2.0.4(transitive)
- Removedisarray@0.0.1(transitive)
- Removedkeypress@0.1.0(transitive)
- Removedmime@1.2.11(transitive)
- Removedmime-types@1.0.2(transitive)
- Removednode-uuid@1.4.8(transitive)
- Removedoauth-sign@0.4.0(transitive)
- Removedqs@2.3.3(transitive)
- Removedreadable-stream@1.0.34(transitive)
- Removedrequest@2.47.0(transitive)
- Removedsntp@0.2.4(transitive)
- Removedstring_decoder@0.10.31(transitive)
- Removedstringstream@0.0.6(transitive)
- Removedtldts@6.1.47(transitive)
- Removedtldts-core@6.1.47(transitive)
- Removedtough-cookie@5.0.0(transitive)
- Removedtunnel-agent@0.4.3(transitive)
Updatedcommander@~2.5
Updatedrequest@~2.x