-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 516783e
Showing
13 changed files
with
6,247 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# EditorConfig is awesome: http://EditorConfig.org | ||
|
||
# top-most EditorConfig file | ||
root = true | ||
|
||
# Unix-style newlines with a newline ending every file | ||
[*] | ||
end_of_line = lf | ||
insert_final_newline = true | ||
|
||
# Matches multiple files with brace expansion notation | ||
# Set default charset | ||
[*.{js,py}] | ||
charset = utf-8 | ||
|
||
# 4 space indentation | ||
[*.py] | ||
indent_style = space | ||
indent_size = 4 | ||
|
||
# Tab indentation (no size specified) | ||
[Makefile] | ||
indent_style = tab | ||
|
||
# Indentation override for all JS under lib directory | ||
[*.js] | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
# Matches the exact files either package.json or .travis.yml | ||
[{package.json,.travis.yml}] | ||
indent_style = space | ||
indent_size = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"extends": "standard", | ||
"env": { | ||
"node": true | ||
}, | ||
"overrides": [ | ||
{ | ||
"files": "**.*.test.js", | ||
"env": { | ||
"jest": true | ||
}, | ||
"plugins": [ | ||
"jest" | ||
], | ||
"rules": { | ||
"jest/no-disabled-tests": "warn", | ||
"jest/no-focused-tests": "error", | ||
"jest/no-identical-title": "error", | ||
"jest/prefer-to-have-length": "warn", | ||
"jest/valid-expect": "error" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
node_modules/ | ||
logs/*.log | ||
.nyc_output/ | ||
coverage/ | ||
*.log | ||
*.dll | ||
config.yml | ||
config.json | ||
config.ini |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
language: node_js | ||
node_js: | ||
- "14" | ||
before_install: | ||
- "sudo npm i -g yarn" | ||
install: | ||
- "yarn" | ||
script: | ||
- "yarn test" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
extends: ['@commitlint/config-conventional'] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
log_level: verbose | ||
mysql: | ||
host: localhost | ||
port: 3306 | ||
user: root | ||
password: | ||
database: hitokoto | ||
charset: utf8mb4 | ||
workdir: ../sentences-bundle |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const preStart = require('./src/prestart') | ||
|
||
// 初始化程序 | ||
preStart.Run() | ||
|
||
// 预先执行一次检测 | ||
require('./src/check').checkUpdate() | ||
|
||
// 启动定时任务 | ||
require('./src/cron') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"name": "hitokoto-sentence-generator", | ||
"version": "1.0.0", | ||
"description": "一言句子集生成器", | ||
"main": "core.js", | ||
"engines": { | ||
"node": ">=12" | ||
}, | ||
"scripts": { | ||
"start": "node core.js", | ||
"test": "jest" | ||
}, | ||
"repository": "https://github.com/hitokoto-osc/hitokoto-sentence-generator", | ||
"author": "a632079 <a632079@qq.com>", | ||
"license": "MIT", | ||
"private": true, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged", | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"eslint --fix" | ||
] | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "^8.3.5", | ||
"@commitlint/config-conventional": "^8.3.4", | ||
"eslint": "^4.16.0", | ||
"eslint-config-standard": "^11.0.0-beta.0", | ||
"eslint-plugin-import": "^2.8.0", | ||
"eslint-plugin-jest": "^23.11.0", | ||
"eslint-plugin-node": "^5.2.1", | ||
"eslint-plugin-promise": "^3.6.0", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"husky": "^4.2.0", | ||
"jest": "^26.0.1", | ||
"lint-staged": "^10.0.1" | ||
}, | ||
"dependencies": { | ||
"async": "^3.2.0", | ||
"axios": "^0.18.1", | ||
"colors": "^1.4.0", | ||
"cron": "^1.3.0", | ||
"diff": "^4.0.2", | ||
"lodash": "^4.17.15", | ||
"mysql2": "^2.1.0", | ||
"nconf": "^0.10.0", | ||
"nconf-yaml": "^1.0.2", | ||
"node-schedule": "^1.3.2", | ||
"semver": "^7.3.2", | ||
"simple-git": "^2.4.0", | ||
"uuid": "^3.2.1", | ||
"winston": "^2.4.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
'use strict' | ||
const database = require('./database') | ||
const winston = require('winston') | ||
const nconf = require('nconf') | ||
const diff = require('diff') | ||
const _ = require('lodash') | ||
const semver = require('semver') | ||
const colors = require('colors/safe') | ||
|
||
const fs = require('fs') | ||
const path = require('path') | ||
|
||
const workdir = path.join(__dirname, '../', nconf.get('workdir')) | ||
console.log(workdir) | ||
const git = require('simple-git/promise')(workdir) | ||
/** | ||
* .catch(e => { | ||
console.error(colors.red(e.stack)) | ||
winston.error('无法初始化 GIT 工作目录,程序结束。') | ||
process.exit(1) | ||
}) | ||
*/ | ||
|
||
// 缓存记录 | ||
let sentenceCount = 0 | ||
let currentCategoriesList = [] | ||
|
||
// 检测版控文件是否存在 | ||
let versionData | ||
const versionFile = path.join(workdir, './version.json') | ||
const categoriesData = {} | ||
if (fs.existsSync(versionFile)) { | ||
versionData = JSON.parse(fs.readFileSync(versionFile, { encoding: 'utf8' })) | ||
// 读取分类列表 | ||
currentCategoriesList = JSON.parse(fs.readFileSync(path.join(workdir, versionData.categories.path))) | ||
// 迭代读取句子分类数据 | ||
for (const category of currentCategoriesList) { | ||
categoriesData[category.key] = JSON.parse(fs.readFileSync(path.join(workdir, category.path))) | ||
} | ||
} else { | ||
versionData = { | ||
protocol_version: nconf.get('version'), | ||
bundle_version: '1.0.0', | ||
updated_at: 0, | ||
categories: { | ||
path: './categories.json', | ||
timestamp: 0 | ||
}, | ||
sentences: [] | ||
} | ||
} | ||
|
||
async function checkUpdate () { | ||
try { | ||
winston.verbose('开始执行同步句子操作...') | ||
let isUpdate = false | ||
const conn = await database.getConnection() | ||
// 获得一言分类列表 | ||
let [rows] = await conn.query('SELECT * FROM `hitokoto_categories`') | ||
if (currentCategoriesList.length === 0 || diff.diffArrays(currentCategoriesList, rows).length > 1) { | ||
currentCategoriesList = rows | ||
currentCategoriesList.map(v => { | ||
v.path = `./sentences/${v.key}.json` | ||
return v | ||
}) | ||
isUpdate = true | ||
// 更新数据 | ||
fs.writeFileSync(path.join(workdir, versionData.categories.path), JSON.stringify(currentCategoriesList)) | ||
versionData.categories.timestamp = Date.now() | ||
fs.writeFileSync(path.join(workdir, './version.json'), JSON.stringify(versionData)) | ||
} | ||
|
||
// 获得一言句子集合 | ||
[rows] = await conn.query('SELECT * FROM `hitokoto_sentence`') | ||
if (rows.length !== sentenceCount) { // TODO: 寻找更经济、全面的比对算法。尽管如果碰巧删除的句子数目与新增句子数目相等时此规则将不合预期忽略掉变化,但目前这是最经济的做法。 | ||
// 建立数据集缓存 | ||
const tmp = {} | ||
for (const sentence of rows) { | ||
sentence.length = sentence.hitokoto.length | ||
if (!tmp[sentence.type]) { | ||
tmp[sentence.type] = [sentence] | ||
} else { | ||
tmp[sentence.type].push(sentence) | ||
} | ||
} | ||
// 按分类比对更新 | ||
for (const category of currentCategoriesList) { | ||
const {key} = category | ||
if (!categoriesData[key] || categoriesData[key].length === 0 || diff.diffArrays(categoriesData[key], tmp[key]).length > 1) { | ||
isUpdate = true | ||
categoriesData[key] = tmp[key] | ||
let categoryVersion = _.find(versionData.sentences, { key }) | ||
if (!categoryVersion) { | ||
categoryVersion = { | ||
name: category.name, | ||
key: category.key, | ||
path: `./sentences/${key}.json`, | ||
timestamp: Date.now() | ||
} | ||
versionData.sentences.push(categoryVersion) | ||
} else { | ||
categoryVersion.timestamp = Date.now() | ||
} | ||
if (!fs.existsSync(path.join(workdir, categoryVersion.path, '../'))) { | ||
fs.mkdirSync(path.join(workdir, categoryVersion.path, '../')) | ||
} | ||
fs.writeFileSync(path.join(workdir, categoryVersion.path), JSON.stringify(tmp[key])) | ||
fs.writeFileSync(path.join(versionFile), JSON.stringify(versionData)) | ||
} | ||
} | ||
} | ||
winston.verbose('文件生成完毕,开始发布 GIT 版本。') | ||
// 调用 Git,生成新的版本号 | ||
if (isUpdate) { | ||
versionData.bundle_version = semver.inc(versionData.bundle_version, 'patch') | ||
versionData.updated_at = Date.now() | ||
fs.writeFileSync(path.join(versionFile), JSON.stringify(versionData)) | ||
|
||
// GIT 操作 | ||
await git.add('*') | ||
await git.commit(`build(auto): v${versionData.bundle_version}`) | ||
await git.addAnnotatedTag(`v${versionData.bundle_version}`, `v${versionData.bundle_version}. Auto released by hitokoto-sentence-generator.`) | ||
await Promise.all([ | ||
git.push(), | ||
git.pushTags() | ||
]) | ||
} | ||
winston.verbose('更新操作执行完毕。') | ||
} catch (e) { | ||
console.error(colors.red(e.stack)) | ||
winston.error('执行同步操作时发生错误!') | ||
} | ||
} | ||
|
||
module.exports = { | ||
checkUpdate | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
'use strict' | ||
const schedule = require('node-schedule') | ||
const {checkUpdate} = require('./check') | ||
|
||
schedule.scheduleJob('checkSentencesUpdates', '1 * * * *', checkUpdate) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const mysql = require('mysql2/promise') | ||
const nconf = require('nconf') | ||
const winston = require('winston') | ||
const colors = require('colors/safe') | ||
|
||
let pool = null | ||
|
||
async function createConnectionsPool () { | ||
if (!nconf.get('mysql')) { | ||
winston.error('数据库配置不存在,程序结束。') | ||
process.exit(1) | ||
} | ||
try { | ||
pool = await mysql.createPool({ | ||
host: nconf.get('mysql:host') || 'localhost', | ||
user: nconf.get('mysql:user') || 'root', | ||
password: nconf.get('mysql:password') || null, | ||
port: nconf.get('mysql:port') || 3306, | ||
charset: nconf.get('mysql:charset') || 'utf8mb4', | ||
database: nconf.get('mysql:database') || null | ||
}) | ||
await pool.query('SELECT 1') | ||
} catch (e) { | ||
console.error(colors.red(e.stack)) | ||
winston.error('与数据库建立连接时发生错误,程序结束。') | ||
process.exit(1) | ||
} | ||
} | ||
|
||
async function getConnection () { | ||
if (!pool) { | ||
await createConnectionsPool() | ||
} | ||
return pool | ||
} | ||
|
||
module.exports = { | ||
getConnection | ||
} |
Oops, something went wrong.