nyx_server
Version:
Node内容发布
319 lines (290 loc) • 12 kB
JavaScript
/* global Buffer */
/* global global */
/*****************************************************************
碎片
******************************************************************/
var _ = require('lodash');
var Promise = require('bluebird');
var ejs = require("ejs");
var path = require("path");
var uriresource = require("./utils/UriResource");
var chipFn = require("./EmptyContext");
var fs = require('fs');
var publishUtil = require("./utils/PublishUtil");
var config = require("../config/default-config");
var EmptyContext = require("./EmptyContext");
var PermissionError = require("./exception/PermissionError");
var PermissionConstant = require("./PermissionConstant");
var nyxsdk = require("./api/project");
var jwt = require('jsonwebtoken');
var Cert_Token = "1OTzi54b7C549J4roOPsKuNUzNW93dMI1Vt2m5MYRYsEQuwIKXRYyMNy1ArKOAYoKqbZkc0jENKjJ4ZSCYom2bmeS2qYWQ7A2KeAp3DoOfNeKfxcaKbaoq2bmZUsMVD3jwXPWwjEFjuZr4aorbKhg4nK5XMquGUH5ij98cUSFHVD9xrf9WEykssdJlL7wK5sZXxJjC3D6r8iDIiUz2j1qW5qigxPT7tFVfPdZZF20V95Gdd7g9m0ZastvwBe8jXW";
var certuser = 'yhstyg';
function Chip(basePath, project) {
this.basePath = basePath;
var packageInfo = require(path.join(basePath, "./package.json"));
var main = path.join(basePath, packageInfo.main);
this._chip = require(main);
this._templateFile = path.join(basePath, packageInfo.template);
this._distTemplateFile = path.join(basePath, config.DIST_DIR, packageInfo.template);
this._name = packageInfo.name;
this._project = project;
this._ui = packageInfo.ui; //碎片编辑页面
this.single = packageInfo.single || false;
this.config = packageInfo;
}
Chip.prototype.getName = function () {
return this._name;
};
module.exports.Chip = Chip;
/************************
* 碎片函数
************************/
function hasPromission(chip , permissionType , permission){
var context = this.log ? this : EmptyContext;
var apiFun = chip._chip["hasPermission"];
var data = {};
if (apiFun && _.isFunction(apiFun)) {
return apiFun.bind(context)(permissionType , permission);
}else{
return true;
}
}
function getContent(chip, mode) {
var templatePath = chip._templateFile;
if (mode == "publist_preview") {
templatePath = chip._distTemplateFile;
}
return new Promise(function (resolve, reject) {
fs.readFile(templatePath, { encoding: 'utf8', flag: 'r' }, function (err, content) {
if (err) {
reject(err);
} else {
resolve(content);
}
});
});
}
function getResourceData(path) {
var context = this.log ? this : EmptyContext;
var log = context.log;
return new Promise(function (resolve, reject) {
fs.exists(path, function (exists) {
if (!exists) {
var content = "文件 " + path + " 不存在";
log.info(content);
resolve(null);
} else {
fs.readFile(path, 'utf-8', function (err, data) {
if (err) {
var content = "文件 " + path + "读取错误!";
log.info(content);
resolve(null);
} else {
resolve(data);
}
});
}
});
});
}
function getDefaultContent(chip) {
var context = this.log ? this : EmptyContext;
var defaultContentPath = path.join(chip.basePath, "__default_render.html");
return getResourceData.bind(context)(defaultContentPath).then(function (content) {
if (!content) {
return "<div>没有默认渲染页面</div>";
}
return content;
});
}
/**
* 得到碎片数据,当id为空时则使用默认数据。
*/
function getData(chip, params) {
var context = this.log ? this : EmptyContext;
var log = context.log;
if (!params.id || params.id=='__') { //没有指定id
log.info("碎片没有指定实例id,使用静态数据");
var defaultDataPath = path.join(chip.basePath, "__default_data.json");
return getResourceData.bind(context)(defaultDataPath).then(function (data) {
return JSON.parse(data);
});
} else {
log.info("装载碎片内容");
return nyxsdk.getChipData(params.id , params.templateDataId).then(function(data){
return chip._chip.getData.bind(context)(data||{});
});
}
}
/**
* 预览碎片
*/
function preview(chip, params, mode) {
var context = this.log ? this : EmptyContext;
var log = context.log;
log.info("预览碎片,碎片名称 : ", chip._name, "mode : ", mode);
var hasPermission = hasPromission.bind(context)(chip , PermissionConstant.CHIP_PREVIEW , chip._name+"."+params.id);
if(!hasPermission){
return Promise.reject(new PermissionError("未授权使用预览."));
}
return Promise.resolve(getData.bind(context)(chip, params)).then(function (template_data) {
if (template_data) {
return getContent.bind(context)(chip, mode).then(function (template_content) {
template_content = template_content.replace(/<[%]{1,2}|[%]{1,2}>/ig
, function (match, offset, input) {
return match.replace(/%/g, global.nxyConfig.ejs_delimiter);
});
var template = ejs.compile(template_content, { 'delimiter': global.nxyConfig.ejs_delimiter });
var ret = template(template_data);
var content = uriresource.transformUrl(ret, chip.basePath);
if (mode == 'edit') {
content = content.replace(/(<[^\/\-\%\?\#][^>]*[^-]{2}>)/g, function (match, block, offset, input) {
return match.replace(">", " " + global.nxyConfig.noeditAttr + ">");
});
} else if (mode == 'publish' && params.ssi && !params.bindTemplateId) { //ssi方式使用include,
var publishUrl = chip._chip.getPublishUrl(params.id, chip._project.config, chip.config);
content = "<!--#include virtual=\"" + publishUrl + "\"-->";
}
return content;
});
} else {
return getDefaultContent.bind(context)(chip);
}
}).then(function (result) {
log.info("完成碎片预览");
return result;
});
}
module.exports.preview = preview;
function publish(chip, params) {
var mode = "publist_preview";
var context = this.log ? this : EmptyContext;
var log = context.log;
log.info("发布碎片 : ", chip._name, "id : ", params.id);
var _hasPermission = hasPromission.bind(context)(chip , PermissionConstant.CHIP_PUBLISH , chip._name+"."+params.id);
if(!_hasPermission){
return Promise.reject(new PermissionError("未授权使用碎片发布."));
}
return preview(chip, params , mode).then(function (content) {
// //获取发布地址
var publishUrl = chip._chip.getPublishUrl(params.id, chip._project.config, chip.config);
var domain = chip._chip.getDomain(params.id, chip._project.config, chip.config , params);
//分发内容
var allPromise = [];
var _publish = function (content, domain, publishUrl) {
return publishUtil.sendFile(new Buffer(content), chip._name
, [ { fname: 'fe.cid', fvalue: domain }
, { fname: 'fe.filepath', fvalue: publishUrl }
, { fname: 'fe.syncflag', fvalue: '1' }
, {fname :'username' ,fvalue: certuser}
, {fname :'token' ,fvalue: getWebToken(domain , publishUrl , Cert_Token)}
])
.then(function () {
var pubUrl = domain + publishUrl;
log.info("publish url : " + pubUrl);
return nyxsdk.setChipPubUrl(params.id , undefined , pubUrl).then(function(){
return pubUrl;
});
}).catch(function (err) {
console.log(err);
throw err;
});
};
if (_.isArray(domain)) {
domain.forEach(function (domain) {
var promise = _publish(content, domain, publishUrl);
allPromise.push(promise);
});
} else {
var promise = _publish(content, domain, publishUrl);
allPromise.push(promise);
}
return Promise.all(allPromise);
}).then(function (result) {
log.info("完成碎片发布");
return result;
});
}
module.exports.publish = publish;
function getWebToken(cid , filepath , cert){
var time = (new Date()).getTime();
var token = jwt.sign({ 'fe.cid': cid , 'fe.filepath': filepath , 'time':time}, cert , { algorithm: 'HS256' });
return token;
}
/**
* 调动chip的ui
* @param id
*/
function ui(chip, uiname, id, params) {
var context = this.log ? this : EmptyContext;
var log = context.log;
log.info("执行碎片UI");
var _hasPermission = hasPromission.bind(context)(chip , PermissionConstant.CHIP_UI , chip._name+"."+uiname+"."+id);
if(!_hasPermission){
return Promise.reject(new PermissionError("未授权使用碎片UI."));
}
//var _data = nyxsdk.getChipData(id , params.templateDataId) ||{};
params.id = id;
var _data = getData.bind(this)(chip , params);
return Promise.resolve(_data).then(function (data) {
var uibasePath = chip._ui.base || ".";
var uitemplate = path.join(chip.basePath, uibasePath, uiname + ".ejs");
return new Promise(function (resolve, reject) {
fs.readFile(uitemplate, { encoding: 'utf8', flag: 'r' }, function (err, content) {
if (err) {
reject(err);
} else {
try {
var template = ejs.compile(content);
var retContent = template({data:data});
retContent = uriresource.transformUrl(retContent, chip.basePath + "/" + uibasePath);
resolve(retContent);
} catch (err) {
reject(err);
}
}
});
});
}).then(function (result) {
log.info("完成碎片UI处理");
return result;
});
}
module.exports.ui = ui;
function api(chip, apiname, params) {
var context = this.log ? this : EmptyContext;
var log = context.log;
log.info("调用碎片API");
var _hasPermission = hasPromission.bind(context)(chip , PermissionConstant.CHIP_UI , chip._name+"."+apiname);
if(!_hasPermission){
return Promise.reject(new PermissionError("未授权使用碎片API."));
}
var data = {};
var config = chip.config;
var apiList = config.exportApi;
if (typeof apiList == 'undefined' || apiList.indexOf(apiname) < 0) { //如果没有暴漏相应的api则不许调用
return Promise.resolve({ message: "非法调用" });
}
var apiFun = chip._chip[apiname];
if (apiFun && _.isFunction(apiFun)) {
data = apiFun(params);
}
return Promise.resolve(data).then(function (result) {
log.info("完成碎片API调用");
return result;
});
}
module.exports.api = api;
/**
* 编辑碎片
* @param id 数据id,可以是null,如果是null则是新建数据
* @param param 数据配置信息
*/
function edit(chip, id, params) {
var templateId = params.templateId;
var editData = params.editData;
console.log(id , templateId , editData);
var chipType = chip._project.name+"."+chip._name;
return nyxsdk.updateChipData(id , templateId , editData ,chipType);
}
module.exports.edit = edit;