add fontsync pull and push
This commit is contained in:
@@ -92,3 +92,5 @@ sh build.sh
|
||||
23. 2016-2-25 增加字形导出svg和png功能.
|
||||
|
||||
24. 2016-3-7 将path的布尔操作库替换成paper.js的路径库.
|
||||
|
||||
25. 2016-3-20 增加字体同步的拉取和推送,增加自动更新同步版本.
|
||||
|
||||
@@ -40,5 +40,6 @@ module.exports = exports = {
|
||||
help: 'Help',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
fontinfo: 'Font Info'
|
||||
fontinfo: 'Font Info',
|
||||
syncfromserver: 'Sync Font From Server'
|
||||
};
|
||||
|
||||
@@ -40,5 +40,6 @@ module.exports = exports = {
|
||||
help: '帮助',
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
fontinfo: '字体信息'
|
||||
fontinfo: '字体信息',
|
||||
syncfromserver: '从服务器同步字体'
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* "fontName": "fonteditor", // 字体名称
|
||||
* "hasNew": 1, // 如果有新数据则标记为1, 同时设置fontType, timestamp, ttf字段
|
||||
* "timestamp": 12345678, // 新纪录时间戳,unix timestamp 精确到毫秒
|
||||
* "fontType": "ttf", // 新纪录类型
|
||||
* "fontType": "ttf", // 新纪录类型,默认为ttf字体
|
||||
* "ttf": base64str // 新纪录的base64字体数据
|
||||
* }
|
||||
* }
|
||||
@@ -54,8 +54,10 @@
|
||||
*
|
||||
* @author mengke01(kekee000@gmail.com)
|
||||
*/
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
|
||||
define('SYNC_FILE', __DIR__ . '/list.md'); // 同步的文件
|
||||
define('FONT_ROOT', __DIR__); // 同步字体的基础目录
|
||||
define('SYNC_FILE', FONT_ROOT . '/list.md'); // 同步的文件
|
||||
|
||||
|
||||
|
||||
@@ -69,9 +71,13 @@ define('SYNC_FILE', __DIR__ . '/list.md'); // 同步的文件
|
||||
function jsonp($status, $data = null, $statusInfo = null) {
|
||||
$callback = $_GET['callback'];
|
||||
$json = array(
|
||||
'status' => $status,
|
||||
'data' => $data,
|
||||
'status' => $status
|
||||
);
|
||||
|
||||
if (!empty($data)) {
|
||||
$json['data'] = $data;
|
||||
}
|
||||
|
||||
if (!empty($statusInfo)) {
|
||||
$json['statusInfo'] = $statusInfo;
|
||||
}
|
||||
@@ -85,7 +91,14 @@ function jsonp($status, $data = null, $statusInfo = null) {
|
||||
* @return number
|
||||
*/
|
||||
function getTimestamp() {
|
||||
return intval(microtime(true) * 1000);
|
||||
return floor(microtime(true) * 1000);
|
||||
}
|
||||
|
||||
function getFontPath() {
|
||||
// 根据具体情况设置fontpath
|
||||
// $fontpath = FONT_ROOT . dirname($_SERVER["REQUEST_URI"]);
|
||||
// return preg_replace('/\\\+/', '/', $fontpath);
|
||||
return FONT_ROOT;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,6 +147,8 @@ function getSyncRecord() {
|
||||
|
||||
/**
|
||||
* 保存同步的记录
|
||||
*
|
||||
* @param array $data 同步的记录列表
|
||||
*/
|
||||
function saveSyncRecord($data) {
|
||||
file_put_contents(SYNC_FILE, json_encode($data));
|
||||
@@ -152,9 +167,10 @@ function doPush() {
|
||||
|
||||
$ret = array(); // 记录成功的类型
|
||||
|
||||
$fontPath = getFontPath();
|
||||
foreach (explode(',', $fontType) as $type) {
|
||||
if (!empty($_POST[$type])) {
|
||||
writeBase64File($_POST[$type], "${fontName}.${type}");
|
||||
writeBase64File($_POST[$type], "${fontPath}/${fontName}.${type}");
|
||||
$ret[] = $type;
|
||||
}
|
||||
}
|
||||
@@ -162,7 +178,7 @@ function doPush() {
|
||||
// 保存同步记录
|
||||
$timestamp = getTimestamp();
|
||||
$recordList = getSyncRecord();
|
||||
$recordList[$fontName] = array(
|
||||
$recordList["${fontPath}/${fontName}"] = array(
|
||||
'user' => $_COOKIE['FONT_USER'],
|
||||
'timestamp' => $timestamp,
|
||||
'fontType' => $ret[0],
|
||||
@@ -189,34 +205,35 @@ function doPush() {
|
||||
*/
|
||||
function doPull() {
|
||||
$fontName = $_GET['fontName'];
|
||||
$fontType = $_GET['fontType'];
|
||||
$timestamp = empty($_GET['timestamp']) ? 0 : intval($_GET['timestamp']);
|
||||
$fontType = $_GET['fontType']; // 默认拉取的为ttf字体
|
||||
$timestamp = empty($_GET['timestamp']) ? 0 : floor($_GET['timestamp']);
|
||||
if (empty($fontName)) {
|
||||
jsonp(1, null, 'missing font field fontName!');
|
||||
return;
|
||||
}
|
||||
|
||||
$fontPath = getFontPath();
|
||||
$recordList = getSyncRecord();
|
||||
if (!empty($recordList[$fontName])) {
|
||||
$record = $recordList[$fontName];
|
||||
//var_dump($record);
|
||||
// 最后一次提交不是当前用户,或者强制拉取
|
||||
if (
|
||||
($record['user'] != $_COOKIE['FONT_USER'] && $record['timestamp'] > $timestamp)
|
||||
|| -1 === $timestamp
|
||||
) {
|
||||
if (!empty($recordList["${fontPath}/${fontName}"])) {
|
||||
$record = $recordList["${fontPath}/${fontName}"];
|
||||
}
|
||||
else {
|
||||
$record = array();
|
||||
}
|
||||
|
||||
$fontFile = "${fontName}.${fontType}";
|
||||
if (file_exists($fontFile)) {
|
||||
$data = array(
|
||||
'fontName' => $fontName,
|
||||
'hasNew' => 1,
|
||||
'timestamp' => $record['timestamp'],
|
||||
'fontType' => $fontType,
|
||||
);
|
||||
$data[$fontType] = readBase64File($fontFile);
|
||||
jsonp(0, $data);
|
||||
return;
|
||||
}
|
||||
// 最后一次提交大于当前记录时间
|
||||
if (-1 == $timestamp || $record['timestamp'] > $timestamp) {
|
||||
$fontFile = "${fontPath}/${fontName}.${fontType}";
|
||||
if (file_exists($fontFile)) {
|
||||
$data = array(
|
||||
'fontName' => $fontName,
|
||||
'hasNew' => 1,
|
||||
'timestamp' => empty($record['timestamp']) ? getTimestamp() : $record['timestamp'],
|
||||
'fontType' => $fontType,
|
||||
);
|
||||
$data[$fontType] = readBase64File($fontFile);
|
||||
jsonp(0, $data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"cicons":{"user":"3e60a8b0712c80d976fb3e917c658d4f","timestamp":1458308845195,"fontType":"ttf"}}
|
||||
{"D:\\fonteditor\\demo\\sync\/fonteditor":{"user":"3e60a8b0712c80d976fb3e917c658d4f","timestamp":1458479047942,"fontType":"ttf"}}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -31,6 +31,7 @@
|
||||
<li data-disabled="1" data-action="import" title="${lang.import_font_title}"><a>${lang.import_font}</a></li>
|
||||
<li data-action="add-online"><a>${lang.onlinefont}</a></li>
|
||||
<li data-action="add-url"><a>${lang.fonturl}</a></li>
|
||||
<li data-action="sync-from-server"><a>${lang.syncfromserver}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<i class="split"></i>
|
||||
|
||||
1
list.md
Normal file
1
list.md
Normal file
@@ -0,0 +1 @@
|
||||
{"D:\/fonteditor\/fonteditor\/demo\/sync\/fonteditor":{"user":"3e60a8b0712c80d976fb3e917c658d4f","timestamp":1458405187581,"fontType":"ttf"}}
|
||||
@@ -48,17 +48,31 @@ define(
|
||||
}, 20);
|
||||
|
||||
// 延迟同步函数
|
||||
var fontDelaySync = lang.debounce(function (projectId, ttf, syncConfig) {
|
||||
var fontDelaySync = lang.debounce(function (options) {
|
||||
program.loading.show(i18n.lang.msg_syncing, 4000);
|
||||
program.sync.addTask(projectId, ttf, syncConfig).then(function (data) {
|
||||
if (data.newData) {
|
||||
program.sync.addTask(options).then(function (data) {
|
||||
if (options.newProject && data.newData) {
|
||||
actions['new']({
|
||||
ttf: data.newData,
|
||||
config: {
|
||||
sync: options.config
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (options.type === 'push' && data.newData) {
|
||||
program.ttfManager.ttf.set(data.newData);
|
||||
program.ttfManager.fireChange(true);
|
||||
program.project.update(options.projectId, data.newData).then(function () {
|
||||
program.ttfManager.setState('saved');
|
||||
});
|
||||
}
|
||||
|
||||
program.loading.show(i18n.lang.msg_sync_success, 400);
|
||||
}, function (data) {
|
||||
console.warn(data.reason);
|
||||
if (options.newProject && data.status === 500) {
|
||||
alert(i18n.lang.msg_error_sync_font);
|
||||
}
|
||||
|
||||
data.reason && console.warn(data.reason);
|
||||
});
|
||||
}, 500);
|
||||
|
||||
@@ -84,14 +98,15 @@ define(
|
||||
}
|
||||
},
|
||||
|
||||
'new': function () {
|
||||
'new': function (options) {
|
||||
if (program.ttfManager.isChanged() && !window.confirm(i18n.lang.msg_confirm_save_proj)) {
|
||||
return;
|
||||
}
|
||||
program.ttfManager.set(getEmptyttfObject());
|
||||
program.ttfManager.set((options && options.ttf) || getEmptyttfObject());
|
||||
program.data.projectId = null;
|
||||
|
||||
// 建立项目 提示保存
|
||||
actions.save();
|
||||
actions.save(options);
|
||||
},
|
||||
|
||||
'open': function () {
|
||||
@@ -124,11 +139,32 @@ define(
|
||||
}
|
||||
},
|
||||
|
||||
'sync': function (projectId, ttf, syncConfig) {
|
||||
fontDelaySync(program.data.projectId, ttf, syncConfig);
|
||||
'sync-from-server': function () {
|
||||
var SettingSync = settingSupport.sync;
|
||||
// 从服务器同步字体
|
||||
!new SettingSync({
|
||||
onChange: function (setting) {
|
||||
setting.timestamp = -1; // 配置强制拉取
|
||||
fontDelaySync({
|
||||
type: 'pull',
|
||||
newProject: true,
|
||||
config: setting
|
||||
});
|
||||
}
|
||||
}).show({});
|
||||
},
|
||||
|
||||
'save': function () {
|
||||
'sync': function (projectId, ttf, config) {
|
||||
// 推送字体
|
||||
fontDelaySync({
|
||||
type: 'push',
|
||||
projectId: projectId,
|
||||
ttf: ttf,
|
||||
config: config
|
||||
});
|
||||
},
|
||||
|
||||
'save': function (options) {
|
||||
if (program.ttfManager.get()) {
|
||||
// 已经保存过的项目
|
||||
var projectId = program.data.projectId;
|
||||
@@ -151,8 +187,12 @@ define(
|
||||
var name = program.ttfManager.get().name.fontFamily || '';
|
||||
if ((name = window.prompt(i18n.lang.msg_input_proj_name, name))) {
|
||||
name = string.encodeHTML(name);
|
||||
program.project.add(name, program.ttfManager.get())
|
||||
.then(function (id) {
|
||||
options = options || {};
|
||||
program.project.add(
|
||||
name,
|
||||
options.ttf || program.ttfManager.get(),
|
||||
options.config
|
||||
).then(function (id) {
|
||||
program.data.projectId = id;
|
||||
program.ttfManager.setState('new');
|
||||
program.projectViewer.show(program.project.items(), id);
|
||||
|
||||
@@ -40,7 +40,12 @@ define(
|
||||
preview_title: 'Preview {%=fontFormat%} Format Font',
|
||||
preview_first_step: 'Step 1: Use `{%=fontFamily%}` as font-face.',
|
||||
preview_second_step: 'Step 2:Define css styles with `{%=fontFamily%}`.',
|
||||
preview_third_step: 'Step 3:Set font unicode to icons on web page.'
|
||||
preview_third_step: 'Step 3:Set font unicode to icons on web page.',
|
||||
|
||||
msg_error_sync_font: 'Get sync font error!',
|
||||
msg_error_sync_font_address: 'Font sync address not available!',
|
||||
msg_has_new_font_version: 'Font `${fontName}` has new version, update now?',
|
||||
msg_error_sync_font_version: 'Sync new font version error!'
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -41,7 +41,12 @@ define(
|
||||
preview_title: '预览{%=fontFormat%}格式字体',
|
||||
preview_first_step: '第一步:使用font-face声明字体',
|
||||
preview_second_step: '第二步:定义使用{%=fontFamily%}的样式',
|
||||
preview_third_step: '第三步:挑选相应图标并获取字体编码,应用于页面'
|
||||
preview_third_step: '第三步:挑选相应图标并获取字体编码,应用于页面',
|
||||
|
||||
msg_error_sync_font: '无法获取同步字体!',
|
||||
msg_error_sync_font_address: '字体同步地址不可用!',
|
||||
msg_has_new_font_version: '字体`${fontName}`有新版本,是否同步新版本?',
|
||||
msg_error_sync_font_version: '同步新版本出错!'
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -29,6 +29,15 @@ define(
|
||||
|
||||
var project = {
|
||||
|
||||
/**
|
||||
* 获取新项目的编号
|
||||
*
|
||||
* @return {string} 编号
|
||||
*/
|
||||
getId: function () {
|
||||
return ('' + Date.now());
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取现有项目列表
|
||||
*
|
||||
@@ -47,17 +56,23 @@ define(
|
||||
*
|
||||
* @param {string} name 项目名称
|
||||
* @param {Object} ttf ttfObject
|
||||
* @param {Object} config 当前的项目配置
|
||||
*
|
||||
* @return {Array} 现有项目列表
|
||||
*/
|
||||
add: function (name, ttf) {
|
||||
add: function (name, ttf, config) {
|
||||
var list = this.items();
|
||||
|
||||
var id = '' + Date.now();
|
||||
list.push({
|
||||
var id = (config && config.id) || this.getId();
|
||||
var item = {
|
||||
name: name,
|
||||
id: id
|
||||
});
|
||||
};
|
||||
// 设置当前项目的配置
|
||||
if (config) {
|
||||
item.config = config;
|
||||
}
|
||||
|
||||
list.push(item);
|
||||
storage.setItem('project-list', JSON.stringify(list));
|
||||
|
||||
if (projectDataStore) {
|
||||
@@ -71,7 +86,7 @@ define(
|
||||
|
||||
return resolver.promise();
|
||||
}
|
||||
|
||||
// 不支持 datastore 则使用localstorate存储
|
||||
storage.setItem(id, JSON.stringify(ttf));
|
||||
return Resolver.resolved(id);
|
||||
},
|
||||
@@ -81,9 +96,15 @@ define(
|
||||
*
|
||||
* @param {string} id 编号
|
||||
* @param {Object} ttf ttf对象
|
||||
* @param {Object} config 当前的项目配置
|
||||
*
|
||||
* @return {string} 项目编号
|
||||
*/
|
||||
update: function (id, ttf) {
|
||||
update: function (id, ttf, config) {
|
||||
// 设置当前项目的配置
|
||||
if (config) {
|
||||
this.updateConfig(id, config);
|
||||
}
|
||||
|
||||
if (projectDataStore) {
|
||||
var resolver = new Resolver();
|
||||
@@ -97,6 +118,7 @@ define(
|
||||
return resolver.promise();
|
||||
}
|
||||
|
||||
// 不支持 datastore 则使用localstorate存储
|
||||
storage.setItem(id, JSON.stringify(ttf));
|
||||
return Resolver.resolved(id);
|
||||
},
|
||||
|
||||
@@ -8,6 +8,7 @@ define(
|
||||
function (require) {
|
||||
var i18n = require('../i18n/i18n');
|
||||
var Resolver = require('common/promise');
|
||||
var string = require('common/string');
|
||||
var project = require('./project');
|
||||
var writettf = require('./util/writettf');
|
||||
var ttf2woff = require('fonteditor-core/ttf/ttf2woff');
|
||||
@@ -16,7 +17,6 @@ define(
|
||||
var loader = require('./loader');
|
||||
var bytes2base64 = require('fonteditor-core/ttf/util/bytes2base64');
|
||||
var base642bytes = require('fonteditor-core/ttf/util/base642bytes');
|
||||
|
||||
var SyncForm = require('./SyncForm');
|
||||
|
||||
var DEFAULT_FONTTYPE = 'ttf'; // 同步默认的字体类型
|
||||
@@ -58,9 +58,10 @@ define(
|
||||
function checkSync(syncConfig) {
|
||||
var data = {
|
||||
action: 'pull',
|
||||
encode: 'base64',
|
||||
fontName: syncConfig.name,
|
||||
fontType: DEFAULT_FONTTYPE, // 暂时只接收ttf类型的字体
|
||||
timestamp: syncConfig.timestamp || '',
|
||||
timestamp: syncConfig.timestamp || 0
|
||||
};
|
||||
|
||||
var resolver = new Resolver();
|
||||
@@ -84,7 +85,7 @@ define(
|
||||
resolver.resolve({});
|
||||
}
|
||||
else {
|
||||
alert('同步地址不可用!');
|
||||
alert(i18n.lang.msg_error_sync_font_address);
|
||||
setSyncStatus(syncConfig.url, 0x1);
|
||||
resolver.reject({
|
||||
status: 404,
|
||||
@@ -183,13 +184,22 @@ define(
|
||||
|
||||
/**
|
||||
* 添加一个任务
|
||||
* @param {Object} projectId 项目编号或者同步选项
|
||||
* @param {?Object} ttf 字体对象
|
||||
* @param {?Object} syncConfig 同步选项
|
||||
*
|
||||
* @param {Object} options 任务参数
|
||||
* @param {string} options.type 同步类型,push or pull
|
||||
* @param {string} options.projectId 项目编号或者同步选项
|
||||
* @param {?Object} options.ttf 字体对象
|
||||
* @param {?Object} options.config 同步选项
|
||||
*
|
||||
* @return {Object} Promise对象
|
||||
*/
|
||||
exports.addTask = function (projectId, ttf, syncConfig) {
|
||||
exports.addTask = function (options) {
|
||||
var syncType = options.type || 'push';
|
||||
var projectId = options.projectId;
|
||||
var ttf = options.ttf;
|
||||
var syncConfig = options.config;
|
||||
options = null;
|
||||
|
||||
if (!syncConfig) {
|
||||
syncConfig = project.getConfig(projectId).sync;
|
||||
}
|
||||
@@ -202,28 +212,38 @@ define(
|
||||
|
||||
var resolver = new Resolver();
|
||||
checkSync(syncConfig).then(function (data) {
|
||||
if (data.hasNew && window.confirm('字体`' + data.fontName + '`有新版本,是否同步新版本?')) {
|
||||
if (data.hasNew && window.confirm(string.format(i18n.lang.msg_has_new_font_version, data.fontName))) {
|
||||
if (data.fontType === DEFAULT_FONTTYPE && data[data.fontType]) {
|
||||
// 解析后台传送过来的ttf字形
|
||||
var ttfBuffer = new Int8Array(base642bytes(data[data.fontType])).buffer;
|
||||
loader.load(ttfBuffer, {
|
||||
type: 'ttf',
|
||||
success: function (ttfObject) {
|
||||
syncConfig.timestamp = data.timestamp || 0;
|
||||
resolver.resolve({
|
||||
timestamp: data.timestamp,
|
||||
newData: ttfObject
|
||||
});
|
||||
},
|
||||
error: function () {
|
||||
alert('同步新版本出错!');
|
||||
alert(i18n.lang.msg_error_sync_font_version);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
alert('同步新版本出错!');
|
||||
alert(i18n.lang.msg_error_sync_font_version);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 拉取模式下用户取消或者没有新数据,则返回
|
||||
if (syncType === 'pull') {
|
||||
resolver.reject({
|
||||
status: data.hasNew ? 200 : 500
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前推送的ttf,如果没有,则从本地存储中获取
|
||||
if (!ttf) {
|
||||
project.get(projectId).then(function (data) {
|
||||
|
||||
Reference in New Issue
Block a user