From 3d9f3c27002daa6062151a7895d2e534b3d7975f Mon Sep 17 00:00:00 2001 From: Aiko Mastboom Date: Sat, 20 Apr 2013 12:32:50 +0200 Subject: [PATCH] added untested /importer --- helpers.js | 58 +++++++++++++++++++++++ importer.js | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++ preview.js | 85 +++++++++------------------------- routes.js | 17 ++++++- 4 files changed, 225 insertions(+), 66 deletions(-) create mode 100644 helpers.js create mode 100644 importer.js diff --git a/helpers.js b/helpers.js new file mode 100644 index 0000000..06d6274 --- /dev/null +++ b/helpers.js @@ -0,0 +1,58 @@ +var when = require('when'); + +function replace(text, marker, getReplacement, once) { + var deferred = when.defer(); + var regExp = new RegExp('', 'gmi'); + var matches = text.match(regExp); + if (matches) { + if (once) { + matches = [matches[0]]; + } + var match_promises = []; + _.forEach(matches, function (result) { + var deferred2 = when.defer(); + match_promises.push(deferred2.promise); + getReplacement(result, function (err, replacement) { + if (err) { + deferred2.reject(err); + } else { + deferred2.resolve({regExp: replacement.regExp || regExp, replacement: replacement.value}) + } + }) + }); + when.all( + match_promises, + function onSuccess(results) { + deferred.resolve(results); + }, + function onFailure(err) { + deferred.reject(err); + } + ); + } else { + deferred.resolve(); + } + return deferred.promise; +} + +function handTextManipulation(text, promises, handler, callback) { + when.all( + promises, + function onSuccess(all_results) { + _.forEach(all_results, function (results) { + _.forEach(results, function (result) { + text = handler( text, result); + }); + }); + return callback(null, text); + }, + function onFailure(err) { + return callback(err); + } + ) +} + +module.exports = { + replace: replace, + handTextManipulation: handTextManipulation +}; diff --git a/importer.js b/importer.js new file mode 100644 index 0000000..d310866 --- /dev/null +++ b/importer.js @@ -0,0 +1,131 @@ +var when = require('when'); +var _ = require('underscore'); +var helpers = require('./helpers.js'); +var fs = require('fs'); + + +module.exports = function (config, mongoInstance) { + + var import_leftovers_tag = 'import_leftovers__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; + var import_leftovers_regexp = new RegExp(import_leftovers_tag); + + var importer = function (doc, options, cb) { + when.any( + helpers.replace(doc, import_leftovers_tag, function getReplacement(result, callback) { + var parts = import_leftovers_regexp.exec(result); + var context = { + collection: parts[1], + name: parts[2], + attribute: parts[3] + }; + return callback(null, { + regExp: new RegExp(result, 'gmi'), + value: context + }); + }, + // there can be only one import_leftovers + true + ), + function onSuccess(leftover) { + handleImportMarkers(doc, options, function handleLeftover(err, remainder) { + if (leftover) { + remainder = remainder.replace(leftover.regExp, ""); + mongoInstance.setMongoAttribute(remainder, leftover.value, function (err,result) { + return cb(err); + }) + } else { + return cb(err); + } + + }); + }, + function onFailure(err) { + return cb(err); + } + ) + }; + + var handleImportMarkers = function (doc, options, callback) { + var promises = replaceMarkers(doc, options); + function handler( text, result) { + return text.replace(result.regExp, result.replacement); + } + helpers.handTextManipulation(doc, + promises, + handler, + callback + ); + }; + + var replaceMarkers = function(doc, options) { + var promises = []; + /* markers: + import__[collection]_[name]_[attribute] + end_import__[collection]_[name]_[attribute] + + moves content between tags into /collection/name/attribute + + + import_file__[filename]__into__[collection]_[name]_[attribute] + + read filename into /collection/name/attribute and process it. + */ + var import_tag = 'import__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)([\\w\\W]*)_end_import_([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; + var import_regexp = new RegExp(import_tag); + + promises.push( + helpers.replace(doc, import_tag, function (result, callback) { + var parts = import_regexp.exec(result); + if (parts[1] != parts[5] + || parts[2] != parts[6] + || parts[3] != parts[7] + ) { + callback(new Error('no closing tag found for import__'+parts[1]+'_'+parts[2]+'_'+parts[3])) + } + var context = { + collection: parts[1], + name: parts[2], + attribute: parts[3] + }; + var sub_doc = parts[4]; + handleImportMarkers(sub_doc, options, function handleLeftover(err, remainder) { + mongoInstance.setMongoAttribute(remainder, context, function (err,attribute_result) { + return callback(err, { + regExp: new RegExp(result, 'gmi'), + value: "" + }); + }); + + }); + }) + ); + + var import_file_tag = 'import_file__(\\w\\W)__into__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; + var import_file_regexp = new RegExp(import_file_tag); + + promises.push( + helpers.replace(doc, import_file_tag, function (result, callback) { + var parts = import_file_regexp.exec(result); + var filename = parts[0]; + var context = { + collection: parts[1], + name: parts[2], + attribute: parts[3] + }; + var sub_doc = fs.readFile(filename, 'utf-8'); + // process with leftover marker support + importer(sub_doc, context, function handleLeftover(err, attribute_result) { + // remove import_file marker from source + return callback(err, { + regExp: new RegExp(result, 'gmi'), + value: "" + }); + }); + }) + ); + }; + + return { + importer: importer + } +}; diff --git a/preview.js b/preview.js index 10f5331..578ac17 100644 --- a/preview.js +++ b/preview.js @@ -3,6 +3,7 @@ var markdown = require('markdown').markdown; var _ = require('underscore'); var less = require('less'); var when = require('when'); +var helpers = require('./helpers.js'); module.exports = function (config, mongodataInstance) { @@ -15,66 +16,21 @@ module.exports = function (config, mongodataInstance) { '\n' + '{{/if}}'; - var getPreviewHTML = function (options, content, callback) { + var getPreviewHTML = function (content ,options, callback) { config.debug && console.log('getPreviewHTML', content); - var html = content; - var promises = replaceMarkers(options, html); - when.all( - promises, - function onSucces(all_results) { - console.log('getPreviewHTML replaceMakers results', all_results); - _.forEach(all_results, function (results) { - _.forEach(results, function (result) { - html = html.replace(result.regExp, result.replacement); - }); - }); - return callback(null, html); - }, - function onFailure(err) { - return callback(err); - } - ) - }; - - var replace = function (html, marker, getReplacement, once) { - var deferred = when.defer(); - var regExp = new RegExp('', 'gmi'); - var matches = html.match(regExp); - if (matches) { - if (once) { - matches = [matches[0]]; - } - var match_promisses = []; - _.forEach(matches, function (result) { - var deferred2 = when.defer(); - match_promisses.push(deferred2.promise); - getReplacement(result, function (err, replacement) { - if (err) { - deferred2.reject(err); - } else { - deferred2.resolve({regExp: replacement.regExp || regExp, replacement: replacement.value}) - } - }) - }); - when.all( - match_promisses, - function onSuccess(results) { - deferred.resolve(results); - }, - function onFailure(err) { - deferred.reject(err); - } - ); - } else { - deferred.resolve(); + var promises = replaceMarkers( content, content); + function handler( text, result) { + return text.replace(result.regExp, result.replacement); } - return deferred.promise; + helpers.handTextManipulation(content, + promises, + handler, + callback + ); }; - var replaceMarkers = function (options, html) { + var replaceMarkers = function (html, options) { - console.log('marker options', options); - var promises = []; /* markers: [type]_[collection]_[name]_[attribute] @@ -97,10 +53,12 @@ module.exports = function (config, mongodataInstance) { style -> contains all type='style' attributes concatenated based on 'order' */ + var promises = []; + var script_tag = 'script_([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var script_regexp = new RegExp(script_tag); promises.push( - replace(html, script_tag, function (result, callback) { + helpers.replace(html, script_tag, function (result, callback) { var parts = script_regexp.exec(result); var context = { collection: parts[1], @@ -116,7 +74,7 @@ module.exports = function (config, mongodataInstance) { var style_tag = 'style_([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var style_regexp = new RegExp(style_tag); promises.push( - replace(html, style_tag, function (result, callback) { + helpers.replace(html, style_tag, function (result, callback) { var parts = style_regexp.exec(result); var context = { collection: parts[1], @@ -132,7 +90,7 @@ module.exports = function (config, mongodataInstance) { var template_tag = 'template_([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)_context_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var template_regexp = new RegExp(template_tag); promises.push( - replace(html, template_tag, function (result, callback) { + helpers.replace(html, template_tag, function (result, callback) { var parts = template_regexp.exec(result); var template = { collection: parts[1], @@ -157,13 +115,13 @@ module.exports = function (config, mongodataInstance) { var rendered = template(context_result); config.debug && console.log('// recurse markers on rendered template'); context.query = {_id: context_result._id}; - getPreviewHTML(context, rendered, function (err, html) { + getPreviewHTML(context, rendered, function (err, preview_html) { if (err) { return callback(err); } return callback(null, { regExp: new RegExp(result, 'gmi'), - value: html + value: preview_html }); }) }); @@ -173,7 +131,7 @@ module.exports = function (config, mongodataInstance) { var markdown_tag = 'markdown_([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var markdown_regexp = new RegExp(markdown_tag); promises.push( - replace(html, markdown_tag, function (result, callback) { + helpers.replace(html, markdown_tag, function (result, callback) { var parts = markdown_regexp.exec(result); var attribute = { collection: parts[1], @@ -195,7 +153,7 @@ module.exports = function (config, mongodataInstance) { var remove_tag = 'remove_([\\w\\W]*)_end_remove'; //var remove_regexp = new RegExp(remove_tag); promises.push( - replace(html, remove_tag, function (result, callback) { + helpers.replace(html, remove_tag, function (result, callback) { return callback(null, { regExp: null, value: "" @@ -208,8 +166,7 @@ module.exports = function (config, mongodataInstance) { return { getPreviewHTML: getPreviewHTML, - _replaceMarkers: replaceMarkers, - replace: replace + _replaceMarkers: replaceMarkers }; }; diff --git a/routes.js b/routes.js index 44e11db..6393574 100644 --- a/routes.js +++ b/routes.js @@ -2,6 +2,8 @@ var sharejs = require('share'); var mongodata = require('./mongodata.js'); var responder = require('./responder.js'); var preview = require('./preview.js'); +var importer = require('./importer.js'); +var fs = require('fs'); module.exports = function (app, config) { @@ -276,7 +278,7 @@ module.exports = function (app, config) { collection: req.params.collection, ext: req.params.ext, query: {name: req.params.name}, - req: { query: req.query, + req: { query: req.query || {}, headers: req.headers } // debug: req.query && req.query.hasOwnProperty('debug') @@ -300,7 +302,7 @@ module.exports = function (app, config) { }; config.debug && console.log('getPreviewContent content', attribute_value); - previewInstance.getPreviewHTML(preview_options, attribute_value, + previewInstance.getPreviewHTML(attribute_value, preview_options, responder(options, res, next) ); } else { @@ -311,5 +313,16 @@ module.exports = function (app, config) { } ); + var importerInstance = importer(config, mongodataInstance); + app.get('/importer/:filename', function importFile(req, res, next) { + config.debug && console.log('/importer/:filename'); + var sub_doc = fs.readFile( req.params.filename, 'utf-8'); + // process with leftover marker support + var options = {}; + importerInstance.importer(sub_doc, options, function handleLeftover(err, result) { + responder(options, res, next); + }); + }); + return server; }; \ No newline at end of file