feature(cloudcmd) lib/client -> client

Move lib/client and lib/server one level upper
This commit is contained in:
coderaiser 2016-12-13 17:56:05 +02:00
parent 8326475a9f
commit b71ec29db6
48 changed files with 286 additions and 255 deletions

262
common/cloudfunc.js Normal file
View file

@ -0,0 +1,262 @@
(function(global) {
'use strict';
var rendy;
if (typeof module === 'object' && module.exports) {
rendy = require('rendy');
module.exports = new CloudFuncProto();
} else {
rendy = window.rendy;
global.CloudFunc = new CloudFuncProto();
}
function CloudFuncProto() {
var CloudFunc = this,
Entity = new entityProto(),
FS;
/* КОНСТАНТЫ (общие для клиента и сервера)*/
/* название программы */
this.NAME = 'Cloud Commander';
/* если в ссылке будет эта строка - в браузере js отключен */
this.FS = FS = '/fs';
this.apiURL = '/api/v1';
this.MAX_FILE_SIZE = 500 * 1024;
this.Entity = Entity;
function entityProto() {
var Entities = {
' ': ' ',
'&lt;' : '<',
'&gt;' : '>'
};
this.encode = function(str) {
Object.keys(Entities).forEach(function(code) {
var char = Entities[code],
reg = RegExp(char, 'g');
str = str.replace(reg, code);
});
return str;
};
this.decode = function(str) {
Object.keys(Entities).forEach(function(code) {
var char = Entities[code],
reg = RegExp(code, 'g');
str = str.replace(reg, char);
});
return str;
};
}
this.formatMsg = function(msg, name, status) {
if (!status)
status = 'ok';
if (name)
name = '("' + name + '")';
else
name = '';
msg = msg + ': ' + status + name;
return msg;
};
/** Функция возвращает заголовок веб страницы
* @pPath
*/
this.getTitle = function(pPath) {
if (!CloudFunc.Path)
CloudFunc.Path = '/';
return CloudFunc.NAME + ' - ' + (pPath || CloudFunc.Path);
};
/** Функция получает адреса каждого каталога в пути
* возвращаеться массив каталогов
* @param url - адрес каталога
*/
function getPathLink(url, prefix, template) {
var namesRaw, names, length,
pathHTML = '',
path = '/';
if (!url)
throw Error('url could not be empty!');
if (!template)
throw Error('template could not be empty!');
namesRaw = url.split('/')
.slice(1, -1),
names = [].concat('/', namesRaw),
length = names.length - 1;
names.forEach(function(name, index) {
var slash = '',
isLast = index === length;
if (index)
path += name + '/';
if (index && isLast) {
pathHTML += name + '/';
} else {
if (index)
slash = '/';
pathHTML += rendy(template, {
path: path,
name: name,
slash: slash,
prefix: prefix
});
}
});
return pathHTML;
}
/**
* Функция строит таблицу файлв из JSON-информации о файлах
* @param params - информация о файлах
*
*/
this.buildFromJSON = function(params) {
var file, i, n, type, attribute, size, date, owner, mode,
dotDot, link, dataName,
linkResult,
prefix = params.prefix,
template = params.template,
templateFile = template.file,
templateLink = template.link,
json = params.data,
files = json.files,
path = json.path,
/*
* Строим путь каталога в котором мы находимся
* со всеми подкаталогами
*/
htmlPath = getPathLink(path, prefix, template.pathLink),
fileTable = rendy(template.path, {
link : prefix + FS + path,
fullPath : path,
path : htmlPath
}),
header = rendy(templateFile, {
tag : 'div',
attribute : '',
className : 'fm-header',
type : '',
name : 'name',
size : 'size',
date : 'date',
owner : 'owner',
mode : 'mode'
});
fileTable += header;
/* сохраняем путь */
CloudFunc.Path = path;
fileTable += '<ul data-name="js-files" class="files">';
/* Если мы не в корне */
if (path !== '/') {
/* убираем последний слеш и каталог в котором мы сейчас находимся*/
dotDot = path.substr(path, path.lastIndexOf('/'));
dotDot = dotDot.substr(dotDot, dotDot.lastIndexOf('/'));
/* Если предыдущий каталог корневой */
if (dotDot === '')
dotDot = '/';
link = prefix + FS + dotDot;
linkResult = rendy(template.link, {
link : link,
title : '..',
name : '..'
});
dataName = 'data-name="js-file-.." ',
attribute = 'draggable="true" ' + dataName,
/* Сохраняем путь к каталогу верхнего уровня*/
fileTable += rendy(template.file, {
tag : 'li',
attribute : attribute,
className : '',
type : 'directory',
name : linkResult,
size : '&lt;dir&gt;',
date : '--.--.----',
owner : '.',
mode : '--- --- ---'
});
}
n = files.length;
for (i = 0; i < n; i++) {
file = files[i];
link = prefix + FS + path + file.name;
if (file.size === 'dir') {
type = 'directory';
attribute = '';
size = '&lt;dir&gt;';
} else {
type = 'text-file';
attribute = 'target="_blank" ';
size = file.size;
}
date = file.date || '--.--.----';
owner = file.owner || 'root';
mode = file.mode;
linkResult = rendy(templateLink, {
link : link,
title : file.name,
name : Entity.encode(file.name),
attribute : attribute
});
dataName = 'data-name="js-file-' + file.name + '" ';
attribute = 'draggable="true" ' + dataName;
fileTable += rendy(templateFile, {
tag : 'li',
attribute : attribute,
className : '',
/* Если папка - выводим пиктограмму папки *
* В противоположном случае - файла */
type : type,
name : linkResult,
size : size,
date : date,
owner : owner,
mode : mode
});
}
fileTable += '</ul>';
return fileTable;
};
}
})(this);

332
common/util.js Normal file
View file

@ -0,0 +1,332 @@
(function(scope) {
'use strict';
var exec,
rendy,
jonny,
Scope = scope.window ? window : global;
if (typeof module === 'object' && module.exports) {
exec = require('execon');
rendy = require('rendy');
jonny = require('jonny');
module.exports = new UtilProto(exec);
} else if (!Scope.Util) {
exec = window.exec;
rendy = window.rendy;
jonny = window.jonny;
Scope.Util = new UtilProto(exec);
}
function UtilProto(exec) {
var Util = this;
this.check = new checkProto();
function checkProto() {
/**
* Check is all arguments with names present
*
* @param name
* @param arg
*/
function check(args, names) {
var msg = '',
name = '',
template = '{{ name }} coud not be empty!',
indexOf = Array.prototype.indexOf,
lenNames = names.length,
lenArgs = args.length,
lessArgs = lenArgs < lenNames,
emptyIndex = indexOf.call(args),
isEmpty = ~emptyIndex && emptyIndex <= lenNames - 1;
if (lessArgs || isEmpty) {
if (lessArgs)
name = names[lenNames - 1];
else
name = names[emptyIndex];
msg = rendy(template, {
name: name
});
throw Error(msg);
}
return check;
}
check.check = check;
/**
* Check is type of arg with name is equal to type
*
* @param name
* @param arg
* @param type
*/
check.type = function(name, arg, type) {
var is = Util.type(arg) === type;
if (!is)
throw Error(name + ' should be ' + type);
return check;
};
return check;
}
/**
* Copy properties from from to to
*
* @param from
* @param to
*/
this.copyObj = function(to, from) {
if (!from) {
from = to;
to = {};
}
if (to)
Object.keys(from).forEach(function(name) {
to[name] = from[name];
});
return to;
};
/**
* copy objFrom properties to target
*
* @target
* @objFrom
*/
this.extend = function(target, objFrom) {
var obj,
keys,
proto,
isFunc = Util.type.function(objFrom),
isArray = Util.type.array(objFrom),
isObj = Util.type.object(target),
ret = isObj ? target : {};
if (isArray)
objFrom.forEach(function(item) {
ret = Util.extend(target, item);
});
else if (objFrom) {
obj = isFunc ? new objFrom() : objFrom;
keys = Object.keys(obj);
if (!keys.length) {
proto = Object.getPrototypeOf(objFrom);
keys = Object.keys(proto);
}
keys.forEach(function(name) {
ret[name] = obj[name];
});
}
return ret;
};
/**
* extend proto
*
* @obj
*/
this.extendProto = function(obj) {
var ret, F = function() {};
F.prototype = Util.extend({}, obj);
ret = new F();
return ret;
};
this.json = jonny;
this.escapeRegExp = function(str) {
var isStr = Util.type.string(str);
if (isStr)
str = str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
return str;
};
/**
* get regexp from wild card
*/
this.getRegExp = function(wildcard) {
var regExp;
if (!wildcard)
wildcard = '*';
wildcard = '^' + wildcard /* search from start of line */
.replace('.', '\\.')
.replace('*', '.*')
.replace('?', '.?');
wildcard += '$'; /* search to end of line */
regExp = new RegExp(wildcard);
return regExp;
};
this.type = new TypeProto();
function TypeProto() {
/**
* get type of variable
*
* @param variable
*/
function type(variable) {
var regExp = /\s([a-zA-Z]+)/,
str = {}.toString.call(variable),
typeBig = str.match(regExp)[1],
result = typeBig.toLowerCase();
return result;
}
/**
* functions check is variable is type of name
*
* @param variable
*/
function typeOf(name, variable) {
return type(variable) === name;
}
function typeOfSimple(name, variable) {
return typeof variable === name;
}
['null', 'arrayBuffer', 'file', 'array', 'object']
.forEach(function(name) {
type[name] = typeOf.bind(null, name);
});
['string', 'undefined', 'boolean', 'number', 'function']
.forEach(function(name) {
type[name] = typeOfSimple.bind(null, name);
});
return type;
}
this.exec = exec;
/**
* function gets file extension
*
* @param pFileName
* @return Ext
*/
this.getExt = function(name) {
var ret = '',
dot,
isStr = Util.type.string(name);
if (isStr) {
dot = name.lastIndexOf('.');
if (~dot)
ret = name.substr(dot);
}
return ret;
};
/**
* get values from Object Array name properties
* or
* @pObj
*/
this.getNamesFromObjArray = function(arr) {
var ret = [];
if (!Array.isArray(arr))
throw Error('arr should be array!');
ret = arr.map(function(item) {
return item.name;
});
return ret;
};
/**
* find object by name in arrray
*
* @param array
* @param name
*/
this.findObjByNameInArr = function(array, name) {
var ret;
if (!Array.isArray(array))
throw Error('array should be array!');
if (typeof name !== 'string')
throw Error('name should be string!');
array.some(function(item) {
var is = item.name === name,
isArray = Array.isArray(item);
if (is)
ret = item;
else if (isArray)
item.some(function(item) {
is = item.name === name;
if (is)
ret = item.data;
return is;
});
return is;
});
return ret;
};
/**
* start timer
* @param name
*/
this.time = function(name) {
var console = Scope.console;
Util.exec.ifExist(console, 'time', [name]);
return this;
};
/**
* stop timer
* @param name
*/
this.timeEnd = function(name) {
var console = Scope.console;
Util.exec.ifExist(console, 'timeEnd', [name]);
return this;
};
}
})(this);