Skip to content

Commit

Permalink
feat: v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
a632079 committed May 15, 2020
0 parents commit 516783e
Show file tree
Hide file tree
Showing 13 changed files with 6,247 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .editorconfig
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
24 changes: 24 additions & 0 deletions .eslintrc.json
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"
}
}
]
}
9 changes: 9 additions & 0 deletions .gitignore
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
9 changes: 9 additions & 0 deletions .travis.yml
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"
3 changes: 3 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional']
}
9 changes: 9 additions & 0 deletions config.example.yml
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
10 changes: 10 additions & 0 deletions core.js
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')
58 changes: 58 additions & 0 deletions package.json
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"
}
}
137 changes: 137 additions & 0 deletions src/check.js
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
}
5 changes: 5 additions & 0 deletions src/cron.js
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)
39 changes: 39 additions & 0 deletions src/database.js
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
}
Loading

0 comments on commit 516783e

Please sign in to comment.