Skip to content
This repository has been archived by the owner on Jan 27, 2021. It is now read-only.

Commit

Permalink
refactor: refactor script
Browse files Browse the repository at this point in the history
  • Loading branch information
EYHN committed Feb 11, 2018
1 parent 0e25c80 commit 9e1df84
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 143 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ live2d:
## https://github.com/EYHN/hexo-helper-live2d
live2d:
enable: true
jsPath: local # 'local'(1)||'jsdelivr'(2)||'unpkg'(3)||{Your own path, String}(4)
hashLevel: soft # 'soft'(1)||'dep'(2)||'none'(3)
scriptFrom: local # 'local'(1)||'jsdelivr'(2)||'unpkg'(3)||{Your own path, String}(4)
model:
use: live2d-widget-model-miku # {npm-module name}(1)||{folder name in live2d_models/}(2)||{Your own path, String}(3)
```
Expand Down
218 changes: 77 additions & 141 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,176 +5,112 @@

'use strict'

const crypto = require('crypto'),
fs = require('hexo-fs'),
_ = require('lodash'),
path = require('path'),
UglifyJS = require("uglify-js"),
url = require('url'),
pkgInfo = require('./package'),
onSiteRootPath = '/live2dw/',
onSiteJsPath = `${onSiteRootPath}lib/`,
onSiteModelPath = `${onSiteRootPath}assets/`,
coreJsList = require('live2d-widget/lib/manifest'),
coreJsName = coreJsList['main.js'],
coreJssPath = path.dirname(require.resolve('live2d-widget/lib/manifest')),
coreJsDepVer = pkgInfo.dependencies['live2d-widget'],
defaultConfig = require('live2d-widget/src/config/defaultConfig');

let fileArr = new Array(),
config = _.defaultsDeep({}, hexo.config.live2d, hexo.theme.config.live2d, defaultConfig);
const fs = require('hexo-fs');
const _ = require('lodash');
const path = require('path');
const url = require('url');
const colors = require('colors');

const buildGeneratorsFromManifest = require('./lib/buildGeneratorsFromManifest');
const getFileMD5 = require('./lib/getFileMD5');
const getNodeModulePath = require('./lib/getNodeModulePath');
const loadModelFrom = require('./lib/loadModelFrom');

const defaultConfig = _.merge({},
{
enable: false,
scriptFrom: 'local'
})

// using default options
let config = _.defaultsDeep({}, hexo.config.live2d, hexo.theme.config.live2d, defaultConfig);

// Check if enabled
if(_.hasIn(config, 'enable')){
if(!config.enable){
return;
}
_.unset(config, 'enable');
if (!config.enable) {
return;
}

function addFile(sourcePath, distPath, fileArr){
fileArr.push({
path: distPath,
data: () => fs.createReadStream(sourcePath),
});
}
const generators = [];

function localModelProcessor(localFolder, siteDir = onSiteModelPath){
let lsDir = fs.readdirSync(localFolder),
modelJsonName;
for(let item of lsDir){
let currLocal = path.resolve(localFolder, item);
if(fs.statSync(currLocal).isDirectory()){
modelJsonName = modelJsonName || localModelProcessor(currLocal, url.resolve(siteDir, `${item}/`));
// Cannot be modelJsonName || localModelProcessor,
// because localModelProcessor must be excuted.
}else{
addFile(currLocal, url.resolve(siteDir, item), fileArr);
if(item.endsWith('.model.json')){
modelJsonName = url.resolve(siteDir, item);
}
}
}
return modelJsonName;
}
const manifest = require('live2d-widget/lib/manifest');
const mainfestPath = require.resolve('live2d-widget/lib/manifest');
const coreScriptName = manifest['main.js'];
const pkgInfo = require('./package');
const coreJsDepVer = pkgInfo.dependencies['live2d-widget'];

const onSiteRootPath = '/live2dw/';
const onSiteJsPath = `${onSiteRootPath}lib/`;
const onSiteModelPath = `${onSiteRootPath}assets/`;

function localJsProcessor(){
for(let f of Object.keys(coreJsList)){
addFile(path.resolve(coreJssPath, coreJsList[f]), url.resolve(onSiteJsPath, coreJsPath[f]), fileArr);
}
return url.resolve(onSiteJsPath, coreJsName);
}
let scriptURL;

function getFileMD5(filePath){
const rs = fs.readFileSync(filePath),
hash = crypto.createHash('md5');
return (hash.update(rs).digest('hex'));
}

function getJsPath(){
let useHash;
if(_.hasIn(config, 'hashLevel')){
switch(config.hashLevel){
case 'soft':
useHash = `?${getFileMD5(path.resolve(coreJssPath, coreJsName))}`;
break;
case 'dep':
useHash = `?${coreJsDepVer}`;
break;
case 'none':
useHash = '';
break;
default:
useHash = `?${getFileMD5(path.resolve(coreJssPath, coreJsName))}`;
}
}else{
useHash = `?${getFileMD5(path.resolve(coreJssPath, coreJsName))}`;
}
if(_.hasIn(config, 'jsPath')){
// a. have user modified config.jsPath
switch(config.jsPath){
case 'local':
// a.1 is local
// use local(1)
return `${localJsProcessor()}${useHash}`;
case 'jsdelivr':
// a.2 is jsdelivr online CDN
// use jsdelivr(2)
return `https://cdn.jsdelivr.net/npm/live2d-widget@${coreJsDepVer}/lib/${coreJsName}${useHash}`;
case 'unpkg':
// a.3 is unpkg online CDN
// use unpkg(3)
return `https://unpkg.com/live2d-widget@${coreJsDepVer}/lib/${coreJsName}${useHash}`;
default:
// a.4 is custom url or path, etc.
// use custom(4), let it go~
return `${config.jsPath}${useHash}`;
}
_.unset(config, 'jsPath');
}else{
// b. don't have user modified config.jsPath
switch (config.scriptFrom) {
case 'local':
// a.1 is local
// use local(1)
return `${localJsProcessor()}${useHash}`;
}
const scriptGenerators = buildGeneratorsFromManifest(manifest, path.dirname(mainfestPath), onSiteJsPath)
const useHash = getFileMD5(path.resolve(path.dirname(mainfestPath), coreScriptName));
generators.push(...scriptGenerators);
scriptURL = `${url.resolve(onSiteJsPath, coreScriptName)}?${useHash}`;
break;
case 'jsdelivr':
// a.2 is jsdelivr online CDN
// use jsdelivr(2)
scriptURL = `https://cdn.jsdelivr.net/npm/live2d-widget@${coreJsDepVer}/lib/${coreScriptName}`;
break;
case 'unpkg':
// a.3 is unpkg online CDN
// use unpkg(3)
scriptURL = `https://unpkg.com/live2d-widget@${coreJsDepVer}/lib/${coreScriptName}`;
break;
default:
scriptURL = config.scriptFrom;
break;
}

function getModelJsonPath(){
if(_.hasIn(config, 'model.use')){
// a. have user modified config.model.use
try{
// a.1 is a npm-module(1)
let tryModulePath = path.dirname(require.resolve(`${config.model.use}/package`));
let modelPath = path.resolve(tryModulePath, './assets/');
return localModelProcessor(modelPath);
}catch(e){
let tryFolderPath = path.resolve(hexo.base_dir, path.join('./live2d_models/', config.model.use));
fs.exists(tryFolderPath, function(exists){
if(exists){
// a.2 founded in live2d_models/
let modelPath = path.resolve(tryFolderPath, './assets/');
return localModelProcessor(modelPath);
}else{
// a.3 is custom url or path, etc.
// use custom(3), let it go~
return config.model.use;
}
})
}
_.unset(config, 'model.use');
}else{
// b. don't have user modified config.model.use
// use default
return defaultConfig.model.jsonPath;
if (config.model.use) {
// try './live2d_models/%config.model.use%' or './%config.model.use%'
const modelInHexoBaseDir = [
path.resolve(hexo.base_dir, './live2d_models/', config.model.use),
path.resolve(hexo.base_dir, config.model.use)]
.reduce((p, path) => {
if (!p && fs.existsSync(path))
return path;
else
return p;
}, undefined);
const modelPath = modelInHexoBaseDir || getNodeModulePath(config.model.use);
const { generators: modelGenerators, jsonUrl: modelJsonUrl, packageInfo } = loadModelFrom(modelPath, onSiteModelPath);
generators.push(...modelGenerators);
config = _.set(config, 'model.jsonPath', modelJsonUrl);
if (packageInfo) {
console.log(`${colors.green('hexo-helper-live2d'.toUpperCase())} Load model ${packageInfo.name || config.model.use}@${packageInfo.version || 'unknown'} at '${modelPath}'`);
}
}

config.model.jsonPath = getModelJsonPath();

/**
* Deprecated version support
* since 3.0
* Don't manually add live2d tag into your site template
*/

hexo.extend.helper.register('live2d', function(){
console.warn('hexo-helper-live2d: live2d tag was deprecated since 3.0. See #36. PLEASE REMOVE live2d TAG IN YOUR TEMPLATE FILE.');
hexo.extend.helper.register('live2d', function () {
console.warn(`${colors.green('hexo-helper-live2d'.toUpperCase())} live2d tag was deprecated since 3.0. See #36. PLEASE REMOVE live2d TAG IN YOUR TEMPLATE FILE.`);
});

// injector borrowed form here:
// https://github.com/Troy-Yang/hexo-lazyload-image/blob/master/lib/addscripts.js
hexo.extend.filter.register('after_render:html', function(htmlContent){
let scriptToInject =`
L2Dwidget.init(${JSON.stringify(config)});
`;
let contentToInject = `<script src="${getJsPath()}"></script><script>${UglifyJS.minify(scriptToInject).code}</script>`
if(/<\/body>/gi.test(htmlContent)){
hexo.extend.filter.register('after_render:html', function (htmlContent) {
let scriptToInject = `L2Dwidget.init(${JSON.stringify(config)});`;
let contentToInject = `<script src="${scriptURL}"></script><script>${scriptToInject}</script>`
if (/<\/body>/gi.test(htmlContent)) {
let lastIndex = htmlContent.lastIndexOf('</body>');
_.sp
htmlContent = `${htmlContent.substring(0, lastIndex)}${contentToInject}${htmlContent.substring(lastIndex, htmlContent.length)}`;
}
return htmlContent;
});

hexo.extend.generator.register('live2d', function (locals) {
return fileArr;
return generators;
});
10 changes: 10 additions & 0 deletions lib/buildGenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict'

const fs = require('hexo-fs');

module.exports = function buildGenerator(sourcePath, distPath) {
return {
path: distPath,
data: () => fs.createReadStream(sourcePath),
};
}
12 changes: 12 additions & 0 deletions lib/buildGeneratorsFromManifest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'

const path = require('path');
const url = require('url');
const buildGenerator = require('./buildGenerator');

module.exports = function buildGeneratorsFromManifest(manifest, dirname, distPath) {
const files = Object.keys(manifest).map(key => path.resolve(dirname, manifest[key]));
return files.map((file) => {
return buildGenerator(file, url.resolve(distPath, path.basename(file)))
});
}
10 changes: 10 additions & 0 deletions lib/getFileMD5.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict'

const fs = require('hexo-fs');
const crypto = require('crypto');

module.exports = function getFileMD5(filePath) {
const rs = fs.readFileSync(filePath),
hash = crypto.createHash('md5');
return (hash.update(rs).digest('hex'));
}
7 changes: 7 additions & 0 deletions lib/getNodeModulePath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

const path = require('path');

module.exports = function getNodeModulePath(packageName) {
return path.dirname(require.resolve(packageName + '/package.json'));
}
17 changes: 17 additions & 0 deletions lib/listFiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict'

const fs = require('hexo-fs');
const path = require('path');

module.exports = function listFiles(dir) {
const lsDir = fs.readdirSync(dir);
const files = [];
for (const filename of lsDir) {
const pathname = path.join(dir, filename);
if (fs.statSync(pathname).isDirectory()) {
files.push(...listFiles(pathname));
}
else files.push(pathname);
}
return files;
}
30 changes: 30 additions & 0 deletions lib/loadModelFrom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const path = require('path');
'use strict'

const url = require('url');
const fs = require('fs');
const buildGenerator = require('./buildGenerator');
const listFiles = require('./listFiles');

module.exports = function loadModelFrom(modelPath, modelrootUrl) {
const packageFile = path.resolve(modelPath, 'package.json');
const packageInfo = fs.existsSync(packageFile) && require(packageFile);
const assetsDir = path.resolve(modelPath, './assets/');
const modelFiles = listFiles(assetsDir);
const modelGenerators = modelFiles.map(file => {
return buildGenerator(file, url.resolve(modelrootUrl, path.relative(assetsDir, file)))
});
// find the model.json from model files
const modelJsonUrl = modelGenerators.reduce((p, generator) => {
if (!p && generator.path.endsWith('.model.json')) {
return generator.path;
} else {
return p;
}
}, undefined);
return {
generators: modelGenerators,
jsonUrl: modelJsonUrl,
packageInfo
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"live2d-widget-model-wanko": "^1.0.2"
},
"dependencies": {
"colors": "^1.1.2",
"hexo-fs": "^0.2.2",
"live2d-widget": "3.x",
"lodash": "^4.17.4",
Expand Down

0 comments on commit 9e1df84

Please sign in to comment.