Skip to content

Commit

Permalink
lt-check
Browse files Browse the repository at this point in the history
  • Loading branch information
viperehonchuk committed Jul 31, 2021
1 parent 5354bfd commit b21fd90
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"dependencies": {
"axios": "0.21.1",
"chalk": "~4.1.2",
"glob": "~7.1.7",
"html-to-text": "~8.0.0"
},
"engines": {
"node": ">= 14"
},
"license": "MIT",
"name": "webdoky-content",
"private": false,
"repository": "https://github.com/webdoky/content",
"scripts": {
"check": "node scripts/check.js",
"postinstall": "docker pull erikvl87/languagetool"
},
"type": "module",
"version": "1.0.0"
}
25 changes: 25 additions & 0 deletions scripts/check-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import glob from "glob";
import checkFile from "./utils/check-file.js";

async function getAllFiles() {
return new Promise((resolve, reject) => {
glob("files/uk/**/*", { nodir: true }, (err, filePaths) => {
console.debug(filePaths);
if (err) {
reject(err);
return;
}
resolve(filePaths);
});
});
}

export default async function checkAll() {
const allFilePaths = await getAllFiles();
for (let filePath of allFilePaths) {
if (!(await checkFile(filePath))) {
return false;
}
}
return true;
}
27 changes: 27 additions & 0 deletions scripts/check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import checkAll from "./check-all.js";
import checkFile from "./utils/check-file.js";
import {
startLanguageTool,
stopLanguageTool,
waitForLanguageTool,
} from "./utils/language-tool.js";

const [, , targetFile] = process.argv;

async function check() {
let result = true;
try {
await startLanguageTool();
await waitForLanguageTool();
if (!targetFile) {
result = await checkAll();
} else {
result = await checkFile(targetFile);
}
} finally {
await stopLanguageTool();
}
process.exit(result ? 0 : 1);
}

check();
20 changes: 20 additions & 0 deletions scripts/utils/check-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import fs from "fs";

import { convert } from "html-to-text";

import { checkText } from "./language-tool.js";
import printCorrection from "./print-correction.js";

export default async function checkFile(filePath) {
console.debug(`checkFile(${filePath})`);
const html = fs.readFileSync(filePath, "utf8");
const text = convert(html, { ignoreHref: true });
// console.debug(text);
const corrections = await checkText(text);
if(!corrections || corrections.length === 0) {
return true;
}
console.debug(JSON.stringify(corrections, null, 2));
corrections.forEach(printCorrection);
return false;
}
15 changes: 15 additions & 0 deletions scripts/utils/execute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import childProcess from "child_process";

export default async function execute(command) {
console.debug(command);
const statusCode = await new Promise((resolve, reject) => {
const process = childProcess.exec(command);
process.on("error", reject);
process.on("close", resolve);
process.stdout?.on?.("data", (data) => console.debug(data));
process.stderr?.on?.("data", (data) => console.warn(data));
});
if (statusCode) {
throw new Error("Failure");
}
}
64 changes: 64 additions & 0 deletions scripts/utils/language-tool.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import axios from "axios";
import execute from "./execute.js";
import sleep from "./sleep.js";

const START_COMMAND = "docker run -d -p 8010:8010 erikvl87/languagetool";
const STOP_COMMAND =
'docker stop $(docker ps -a -q --filter ancestor=erikvl87/languagetool --format="{{.ID}}")';
const TIMEOUT = 8000;

async function checkLanguageTool() {
try {
const result = await requestLanguageTool({
language: "en-US",
text: "Hello",
});
console.debug(result);
return result.statusText === "OK";
} catch (error) {
return false;
}
}

export async function checkText(text) {
console.debug("checkText(...)");
return (
await requestLanguageTool({
language: "uk-UA",
text,
})
).data.matches;
}

function requestLanguageTool(data) {
const params = new URLSearchParams();
Object.entries(data).forEach(([key, value]) => params.append(key, value));
return axios.post("http://localhost:8010/v2/check", params, {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
}

export function startLanguageTool() {
return execute(START_COMMAND);
}

export function stopLanguageTool() {
return execute(STOP_COMMAND);
}

export function waitForLanguageTool() {
return Promise.race([
new Promise(async (resolve) => {
while (true) {
if (await checkLanguageTool()) {
resolve();
return;
}
await sleep(200);
}
}),
new Promise((resolve, reject) => setTimeout(reject, TIMEOUT)),
]);
}
37 changes: 37 additions & 0 deletions scripts/utils/print-correction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import chalk from "chalk";

export default function printCorrection(correction) {
if (correction.shortMessage) {
console.info(chalk.black.bgYellow(correction.shortMessage));
}
console.info(chalk.yellow(correction.message));
console.info(chalk.gray(correction.rule.description));
const contextStart = correction.context.text.slice(
0,
correction.context.offset
);
const contextEssence = correction.context.text.slice(
correction.context.offset,
correction.context.offset + correction.context.length
);
const contextEnd = correction.context.text.slice(
correction.context.offset + correction.context.length
);
console.info(`${contextStart}${chalk.yellow(contextEssence)}${contextEnd}`);
console.info(
correction.context.text.slice(
correction.context.offset,
correction.context.offset + correction.context.length
)
);
if (correction.replacements && correction.replacements.length > 0) {
console.info(
chalk.green(
correction.replacements
.map((replacement) => `${replacement.value}?`)
.join(" ")
)
);
}
console.info("====================================");
}
6 changes: 6 additions & 0 deletions scripts/utils/sequential-async-map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default async function sequentialAsyncMap(collection, f) {
return collection.reduce(
async (accumulator, item) => [...(await accumulator), await f(item)],
Promise.resolve([])
);
}
3 changes: 3 additions & 0 deletions scripts/utils/sleep.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
Loading

0 comments on commit b21fd90

Please sign in to comment.