You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

598 lines
16 KiB

// Generated by CoffeeScript 1.6.2
var Backbone, FileModel, Iconv, Model, TaskGroup, balUtil, jschardet, mime, pathUtil, safefs, typeChecker, _ref, _ref1,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__slice = [].slice;
pathUtil = require('path');
balUtil = require('bal-util');
typeChecker = require('typechecker');
TaskGroup = require('taskgroup').TaskGroup;
safefs = require('safefs');
mime = require('mime');
jschardet = null;
Iconv = null;
_ref = require(__dirname + '/../base'), Backbone = _ref.Backbone, Model = _ref.Model;
FileModel = (function(_super) {
__extends(FileModel, _super);
function FileModel() {
_ref1 = FileModel.__super__.constructor.apply(this, arguments);
return _ref1;
}
FileModel.prototype.outDirPath = null;
FileModel.prototype.type = 'file';
FileModel.prototype.stat = null;
FileModel.prototype.data = null;
FileModel.prototype.buffer = null;
FileModel.prototype.meta = null;
FileModel.prototype.defaults = {
id: null,
basename: null,
extension: null,
outExtension: null,
extensions: null,
filename: null,
path: null,
outPath: null,
dirPath: null,
outDirPath: null,
outFilename: null,
relativePath: null,
relativeOutPath: null,
relativeDirPath: null,
relativeOutDirPath: null,
relativeBase: null,
contentType: null,
outContentType: null,
ctime: null,
mtime: null,
exists: null,
encoding: null,
source: null,
content: null,
title: null,
name: null,
date: null,
slug: null,
url: null,
urls: null,
ignored: false,
standalone: false
};
FileModel.prototype.setData = function(data) {
this.data = data;
return this;
};
FileModel.prototype.getData = function() {
return this.data;
};
FileModel.prototype.setBuffer = function(buffer) {
this.buffer = buffer;
return this;
};
FileModel.prototype.getBuffer = function() {
return this.buffer;
};
FileModel.prototype.setStat = function(stat) {
this.stat = stat;
this.set({
ctime: new Date(stat.ctime),
mtime: new Date(stat.mtime)
});
return this;
};
FileModel.prototype.getStat = function() {
return this.stat;
};
FileModel.prototype.getAttributes = function() {
return this.toJSON();
};
FileModel.prototype.getMeta = function() {
var args, _ref2;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (this.meta === null) {
this.meta = new Model();
}
if (args.length) {
return (_ref2 = this.meta).get.apply(_ref2, args);
} else {
return this.meta;
}
};
FileModel.prototype.setMeta = function(attrs) {
this.getMeta().set(attrs);
this.set(attrs);
return this;
};
FileModel.prototype.setMetaDefaults = function(defaults) {
this.getMeta().setDefaults(defaults);
this.setDefaults(defaults);
return this;
};
FileModel.prototype.getContent = function() {
return this.get('content') || this.getBuffer();
};
FileModel.prototype.getOutContent = function() {
return this.getContent();
};
FileModel.prototype.isText = function() {
return this.get('encoding') !== 'binary';
};
FileModel.prototype.isBinary = function() {
return this.get('encoding') === 'binary';
};
FileModel.prototype.setUrl = function(url) {
this.addUrl(url);
this.set({
url: url
});
return this;
};
FileModel.prototype.addUrl = function(url) {
var existingUrl, found, newUrl, urls, _i, _j, _len, _len1;
if (url instanceof Array) {
for (_i = 0, _len = url.length; _i < _len; _i++) {
newUrl = url[_i];
this.addUrl(newUrl);
}
} else if (url) {
found = false;
urls = this.get('urls');
for (_j = 0, _len1 = urls.length; _j < _len1; _j++) {
existingUrl = urls[_j];
if (existingUrl === url) {
found = true;
break;
}
}
if (!found) {
urls.push(url);
}
this.trigger('change:urls', this, urls, {});
this.trigger('change', this, {});
}
return this;
};
FileModel.prototype.removeUrl = function(userUrl) {
var index, url, urls, _i, _len;
urls = this.get('urls');
for (index = _i = 0, _len = urls.length; _i < _len; index = ++_i) {
url = urls[index];
if (url === userUrl) {
urls.splice(index, 1);
break;
}
}
return this;
};
FileModel.prototype.getPath = function(relativePath, parentPath) {
var path, relativeDirPath;
if (/^\./.test(relativePath)) {
relativeDirPath = this.get('relativeDirPath');
path = pathUtil.join(relativeDirPath, relativePath);
} else {
if (parentPath) {
path = pathUtil.join(parentPath, relativePath);
} else {
path = relativePath;
}
}
return path;
};
FileModel.prototype.initialize = function(attrs, opts) {
var data, defaults, detectEncoding, meta, outDirPath, stat;
detectEncoding = opts.detectEncoding, outDirPath = opts.outDirPath, stat = opts.stat, data = opts.data, meta = opts.meta;
if (detectEncoding != null) {
this.detectEncoding = detectEncoding;
}
if (outDirPath) {
this.outDirPath = outDirPath;
}
defaults = {
extensions: [],
urls: [],
id: this.cid
};
if (stat) {
this.setStat(stat);
} else {
defaults.ctime = new Date();
defaults.mtime = new Date();
}
this.set(defaults);
if (attrs.data != null) {
data = attrs.data;
delete attrs.data;
delete this.attributes.data;
}
if (data != null) {
this.setData(data);
}
if (attrs.meta != null) {
this.setMeta(attrs.meta);
delete attrs.meta;
}
if (meta) {
this.setMeta(meta);
}
return FileModel.__super__.initialize.apply(this, arguments);
};
FileModel.prototype.getActionArgs = function(opts, next) {
if (typeChecker.isFunction(opts) && (next != null) === false) {
next = opts;
opts = {};
} else {
opts || (opts = {});
}
next || (next = opts.next || null);
return {
next: next,
opts: opts
};
};
FileModel.prototype.load = function(opts, next) {
var buffer, data, exists, file, filePath, fullPath, tasks, _ref2, _ref3,
_this = this;
if (opts == null) {
opts = {};
}
_ref2 = this.getActionArgs(opts, next), opts = _ref2.opts, next = _ref2.next;
file = this;
exists = (_ref3 = opts.exists) != null ? _ref3 : false;
fullPath = this.get('fullPath');
if (!fullPath) {
filePath = this.get('relativePath') || this.get('fullPath') || this.get('filename');
fullPath = this.get('fullPath') || filePath || null;
file.set({
fullPath: fullPath
});
}
file.log('debug', "Loading the file: " + fullPath);
tasks = new TaskGroup().setConfig({
concurrency: 0
}).once('complete', function(err) {
if (err) {
return next(err);
}
file.log('debug', "Loaded the file: " + fullPath);
return file.parse(function(err) {
if (err) {
return next(err);
}
return file.normalize(function(err) {
if (err) {
return next(err);
}
return next(null, file.buffer);
});
});
});
data = file.getData();
if (data != null) {
buffer = new Buffer(data);
file.setBuffer(buffer);
}
if (opts.stat) {
file.setStat(opts.stat);
}
if (opts.buffer) {
file.setBuffer(opts.buffer);
}
tasks.addTask(function(complete) {
if (fullPath && exists && (opts.stat != null) === false) {
return safefs.stat(fullPath, function(err, fileStat) {
if (err) {
return complete(err);
}
file.setStat(fileStat);
return complete();
});
} else {
return complete();
}
});
tasks.addTask(function(complete) {
if (fullPath && exists && (opts.buffer != null) === false) {
return safefs.readFile(fullPath, function(err, buffer) {
if (err) {
return complete(err);
}
file.setBuffer(buffer);
return complete();
});
} else {
return complete();
}
});
if (fullPath) {
safefs.exists(fullPath, function(_exists) {
exists = _exists;
file.set({
exists: exists
});
return tasks.run();
});
} else {
tasks.run();
}
return this;
};
FileModel.prototype.parse = function(opts, next) {
var buffer, changes, content, encoding, err, fullPath, isText, source, _ref2, _ref3, _ref4;
if (opts == null) {
opts = {};
}
_ref2 = this.getActionArgs(opts, next), opts = _ref2.opts, next = _ref2.next;
buffer = this.getBuffer();
fullPath = this.get('fullPath');
encoding = this.get('encoding') || null;
changes = {};
if ((encoding != null) === false || opts.reencode === true) {
isText = balUtil.isTextSync(fullPath, buffer);
if (isText === true) {
if (this.detectEncoding) {
if (jschardet == null) {
jschardet = require('jschardet');
}
try {
if (Iconv == null) {
Iconv = require('iconv').Iconv;
}
} catch (_error) {
err = _error;
Iconv = null;
}
if (encoding == null) {
encoding = ((_ref3 = jschardet.detect(buffer)) != null ? _ref3.encoding : void 0) || 'utf8';
}
} else {
if (encoding == null) {
encoding = 'utf8';
}
}
if ((_ref4 = encoding.toLowerCase()) !== 'ascii' && _ref4 !== 'utf8' && _ref4 !== 'utf-8') {
if (Iconv != null) {
this.log('info', "Converting encoding " + encoding + " to UTF-8 on " + fullPath);
try {
buffer = new Iconv(encoding, 'utf8').convert(buffer);
} catch (_error) {
err = _error;
this.log('warn', "Encoding conversion failed, therefore we cannot convert the encoding " + encoding + " to UTF-8 on " + fullPath);
}
} else {
this.log('warn', "Iconv did not load, therefore we cannot convert the encoding " + encoding + " to UTF-8 on " + fullPath);
}
}
changes.encoding = encoding;
} else {
encoding = 'binary';
changes.encoding = encoding;
}
}
if (encoding === 'binary') {
content = source = '';
changes.content = content;
changes.source = source;
} else {
source = buffer.toString('utf8');
content = source;
changes.content = content;
changes.source = source;
}
this.set(changes);
next();
return this;
};
FileModel.prototype.normalize = function(opts, next) {
var basename, changes, contentType, date, extension, extensions, filename, fullDirPath, fullPath, mtime, relativeBase, relativeDirPath, relativePath, _ref2;
if (opts == null) {
opts = {};
}
_ref2 = this.getActionArgs(opts, next), opts = _ref2.opts, next = _ref2.next;
changes = {};
basename = this.get('basename');
filename = this.get('filename');
fullPath = this.get('fullPath');
extensions = this.get('extensions');
relativePath = this.get('relativePath');
mtime = this.get('mtime');
date = this.getMeta('date') || null;
if (fullPath) {
changes.filename = filename = pathUtil.basename(fullPath);
changes.outFilename = filename;
}
if (filename) {
if (filename[0] === '.') {
basename = filename.replace(/^(\.[^\.]+)\..*$/, '$1');
} else {
basename = filename.replace(/\..*$/, '');
}
changes.basename = basename;
if ((extensions != null) === false || extensions.length === 0) {
extensions = filename.split(/\./g);
extensions.shift();
}
changes.extensions = extensions;
if (extensions.length) {
extension = extensions[extensions.length - 1];
} else {
extension = null;
}
changes.extension = extension;
changes.outExtension = extension;
}
if (fullPath) {
changes.fullDirPath = fullDirPath = pathUtil.dirname(fullPath) || '';
changes.contentType = contentType = mime.lookup(fullPath);
changes.outContentType = contentType;
}
if (relativePath) {
changes.relativeDirPath = relativeDirPath = pathUtil.dirname(relativePath).replace(/^\.$/, '') || '';
changes.relativeBase = relativeBase = relativeDirPath ? pathUtil.join(relativeDirPath, basename) : basename;
}
if (!date && mtime) {
changes.date = date = mtime;
}
this.set(changes);
next();
return this;
};
FileModel.prototype.contextualize = function(opts, next) {
var changes, filename, meta, name, outDirPath, outPath, relativeBase, relativeDirPath, relativeOutDirPath, relativeOutPath, relativePath, slug, url, _ref2;
if (opts == null) {
opts = {};
}
_ref2 = this.getActionArgs(opts, next), opts = _ref2.opts, next = _ref2.next;
changes = {};
meta = this.getMeta();
relativePath = this.get('relativePath');
relativeDirPath = this.get('relativeDirPath');
relativeBase = this.get('relativeBase');
filename = this.get('filename');
outPath = this.get('outPath');
outDirPath = this.get('outDirPath');
name = meta.get('name') || null;
slug = meta.get('slug') || null;
url = meta.get('url') || null;
if (!url && relativePath) {
url = "/" + relativePath;
this.setUrl(url);
}
if (!slug && relativeBase) {
changes.slug = slug = balUtil.generateSlugSync(relativeBase);
}
if (!name && filename) {
changes.name = name = filename;
}
if (this.outDirPath && relativePath) {
if (relativeDirPath != null) {
changes.relativeOutDirPath = relativeOutDirPath = relativeDirPath;
}
changes.relativeOutPath = relativeOutPath = relativePath;
changes.outPath = outPath = pathUtil.join(this.outDirPath, relativePath);
if (outPath) {
changes.outDirPath = outDirPath = pathUtil.dirname(outPath);
}
}
this.set(changes);
next();
return this;
};
FileModel.prototype.write = function(opts, next) {
var err, file, _ref2, _ref3;
_ref2 = this.getActionArgs(opts, next), opts = _ref2.opts, next = _ref2.next;
file = this;
opts.path || (opts.path = this.get('outPath'));
opts.encoding || (opts.encoding = this.get('encoding'));
opts.content || (opts.content = this.getContent());
opts.type || (opts.type = 'file');
if (!opts.path) {
next();
return this;
}
if ((_ref3 = opts.encoding.toLowerCase()) !== 'ascii' && _ref3 !== 'utf8' && _ref3 !== 'utf-8' && _ref3 !== 'binary') {
if (Iconv != null) {
this.log('info', "Converting encoding UTF-8 to " + opts.encoding + " on " + opts.path);
try {
opts.content = new Iconv('utf8', opts.encoding).convert(opts.content);
} catch (_error) {
err = _error;
this.log('warn', "Encoding conversion failed, therefore we cannot convert the encoding UTF-8 to " + opts.encoding + " on " + opts.path);
}
} else {
this.log('warn', "Iconv did not load, therefore we cannot convert the encoding UTF-8 to " + opts.encoding + " on " + opts.path);
}
}
file.log('debug', "Writing the " + opts.type + ": " + opts.path + " " + opts.encoding);
safefs.writeFile(opts.path, opts.content, function(err) {
if (err) {
return next(err);
}
file.log('debug', "Wrote the " + opts.type + ": " + opts.path + " " + opts.encoding);
return next();
});
return this;
};
FileModel.prototype["delete"] = function(next) {
var file, fileOutPath;
file = this;
fileOutPath = this.get('outPath');
if (!fileOutPath) {
next();
return this;
}
file.log('debug', "Delete the file: " + fileOutPath);
safefs.exists(fileOutPath, function(exists) {
if (!exists) {
return next();
}
return safefs.unlink(fileOutPath, function(err) {
if (err) {
return next(err);
}
file.log('debug', "Deleted the file: " + fileOutPath);
return next();
});
});
return this;
};
return FileModel;
})(Model);
module.exports = FileModel;