From 449a29bdab67b6252ce72bc221e8b707cea60e82 Mon Sep 17 00:00:00 2001 From: Sergio Crisostomo Date: Fri, 7 Nov 2014 00:44:19 +0100 Subject: [PATCH 01/10] prepare to re-use hash builds --- core/index.js | 12 +++++++++++- lib/getHashDependencies.js | 20 ++++++++++++++++++++ more/index.js | 11 ++++++++++- views/builder/index.jade | 9 +++++---- 4 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 lib/getHashDependencies.js diff --git a/core/index.js b/core/index.js index f08566e..6eed471 100644 --- a/core/index.js +++ b/core/index.js @@ -10,6 +10,7 @@ var guides = require('../middleware/guides')('core', { var project = 'core'; var versions = require('../package.json')._projects[project].versions; +var getHashDependencies = require('../lib/getHashDependencies')(); var links = versions.slice(1).map(function(version){ return { version: version, @@ -41,13 +42,15 @@ module.exports = function(app){ }); }); - app.get('/core/builder', function(req, res){ + app.get('/core/builder/:hash?', function(req, res){ + var hash = req.params.hash; res.render('builder/index', { title: 'MooTools Core Builder', navigation: 'core', page: 'builder', project: 'Core', site: 'core', + hashDependencies: getHashDependencies(hash), version: versions[0], versions: links, dependencies: require('../builder/dependencies.js')(project, versions[0]) @@ -61,4 +64,11 @@ module.exports = function(app){ app.get('/core/guides', core, guides.index); app.get('/core/guides/:guide', core, guides.article); + // hash build redirect + var regex = /core\/([a-z]+[0-9]+[a-z0-9]*|[0-9]+[a-z]+[a-z0-9]*)$/; + app.get(regex, function(req, res){ + var hash = req.path.match(regex)[1]; + res.redirect('/core/builder/' + hash); + }); + }; diff --git a/lib/getHashDependencies.js b/lib/getHashDependencies.js new file mode 100644 index 0000000..b4b45b0 --- /dev/null +++ b/lib/getHashDependencies.js @@ -0,0 +1,20 @@ +'use strict'; + +function getHashDependencies(){ + + return function(hash){ + if (!hash) return []; + // I leave a dummy here so far with the first example + // on the issue Tim opened on Github + var DB = { 'e8f3003df2d0919c1091b11854a53e9b': + { + date: '1415017941', + deps: 'Core/Core;Core/String;Core/Event;Core/Browser;Core/Class;Core/Element.Style;Core/Element.Event;Core/Element.Delegation;Core/Element.Dimensions;Core/Fx;Core/Fx.CSS;Core/Fx.Tween;Core/Fx.Morph;Core/Fx.Transitions;Core/Request.HTML;Core/Request.JSON;Core/Cookie;Core/DOMReady' + } + }; + var dependencies = DB[hash].deps.split(';'); + return dependencies; + } +} + +module.exports = getHashDependencies; diff --git a/more/index.js b/more/index.js index fa3b957..5dfd6d6 100644 --- a/more/index.js +++ b/more/index.js @@ -28,13 +28,15 @@ module.exports = function(app){ }); }); - app.get('/more/builder', function(req, res){ + app.get('/more/builder/:hash?', function(req, res){ + var hash = req.params.hash; res.render('builder/index', { title: 'MooTools More Builder', navigation: 'more', page: 'builder', project: 'More', site: 'more', + hashDependencies: getHashDependencies(hash), version: lastVersion, dependencies: require('../builder/dependencies.js')(project, lastVersion) }); @@ -47,4 +49,11 @@ module.exports = function(app){ app.get('/more/guides', more, guides.index); app.get('/more/guides/:guide', more, guides.article); + // hash build redirect + var regex = /more\/([a-z]+[0-9]+[a-z0-9]*|[0-9]+[a-z]+[a-z0-9]*)$/; + app.get(regex, function(req, res){ + var hash = req.url.match(regex)[1]; + res.redirect('/more/builder#' + hash); + }); + }; diff --git a/views/builder/index.jade b/views/builder/index.jade index b120c8b..420a0c0 100644 --- a/views/builder/index.jade +++ b/views/builder/index.jade @@ -12,7 +12,7 @@ block main div.header.clearfix h1 Download complete source - form(method="post", action="../builder") + form(method="post", action="/builder") input(hidden, name="project", value="#{project}") .save @@ -40,7 +40,7 @@ block main h3 Choose which modules you want to use - form(method="post", action="../builder") + form(method="post", action="/builder") input(hidden, name="project", value="#{project}") table#builderOptions tr @@ -50,16 +50,17 @@ block main td Description each yaml, module in dependencies + - var file = project + "/" + module; + - var hashRequested = hashDependencies.indexOf(file) != -1; tr td - input(type="checkbox", value="#{project}/#{module}", name="modules[]", data-provides="#{yaml.prov}", data-requires="#{yaml.req}") + input(type="checkbox", value=file, name="modules[]", data-provides="#{yaml.prov}", data-requires="#{yaml.req}", checked=hashRequested) td #{module} td #{yaml.prov} td #{yaml.desc} h2.step Options: - .save label From f9ebb642d2f7fa7448cca42c7f41fa8c47d192b4 Mon Sep 17 00:00:00 2001 From: Tim Wienk Date: Fri, 7 Nov 2014 11:53:03 +0100 Subject: [PATCH 02/10] Untested builderHash load and save functionality. --- middleware/builderHash.js | 62 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 middleware/builderHash.js diff --git a/middleware/builderHash.js b/middleware/builderHash.js new file mode 100644 index 0000000..a1e5896 --- /dev/null +++ b/middleware/builderHash.js @@ -0,0 +1,62 @@ +'use strict'; + +var sqlite3 = require('sqlite3'), + md5 = require('md5'); + +var databasePaths = {}, + databases = {}; + +function getDatabase(project){ + if (!databases[project]) { + var path = databasePaths[project]; + if (path){ + databases[project] = new sqlite3.Database(path, sqlite3.OPEN_READWRITE, function(error){ + if (error) throw error; + }); + } else { + throw Error('No database found for "' + project + '".'); + } + } + return databases[project]; +} + +function loadHash(project, hash, callback){ + getDatabase(project).get('SELECT * FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ + var data = null; + if (row) data = {hash: row.md5, packages: row.packages.split(';')}; + if (callback) callback(data); + }); +} + +function saveHash(project, packages, callback){ + if (packages && packages.length){ + var db = getDatabase(project), + packageString = packages.join(';'), + hash = md5.digest_s(packageString); + + db.get('SELECT COUNT(*) AS count FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ + if (error) throw error; + if (row.count){ + if (callback) callback({hash: hash, packages: packages}); + } else { + var values = {1: hash, 2: packageString, 3: Math.round(Date.now() / 1000)}; + db.run('INSERT INTO hashes (md5, packages, date) VALUES (?, ?, ?)', values, function(error){ + if (error) throw error; + if (callback) callback({hash: hash, packages: packages}); + }); + } + }); + } else { + if (callback) callback(null); + } +} + +module.exports = function(paths){ + for (var key in paths){ + databasePaths[key] = paths[key]; + } + return { + load: loadHash, + save: saveHash + } +} From a37b5d484e401e701364017b40312280829462f4 Mon Sep 17 00:00:00 2001 From: Sergio Crisostomo Date: Sun, 9 Nov 2014 22:05:00 +0100 Subject: [PATCH 03/10] add testing samples --- tests/database/core.db | Bin 0 -> 4096 bytes tests/database/more.db | Bin 0 -> 4096 bytes tests/database/newDatabase.js | 33 +++++++++++++++++++++++++++++++++ tests/database/sampleData.json | 27 +++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 tests/database/core.db create mode 100644 tests/database/more.db create mode 100755 tests/database/newDatabase.js create mode 100755 tests/database/sampleData.json diff --git a/tests/database/core.db b/tests/database/core.db new file mode 100644 index 0000000000000000000000000000000000000000..1947b45e978c2449fd4ece1ea0b2ad5cfc1872f5 GIT binary patch literal 4096 zcmeHJOK;Oa5VljN&;zFmAr45+jY@6mUEBLm50IvbDyUm%B5|zN-fD9( z4AZt$UvJdf4YOTaTxpmo&3xFC?yR{Zf^D%0!&y^`7-q^!7JcGpB9WnfA8tytYwZ#+(x%lv#Lm zc+#9ZI6L6f(bZOb(9M@-0xUrnHbp`9oZeBw4wXuo^v(U0Rdc`E-UG-qRU>Z@?QErU zPg-lMX>V!GTL&Qz5{)RKl-h^wlG5l!1q(qe0L&N-k&OjG)W^c%)O8@Fp**8e!N#pP z>hw2L{;Rt^AEHd6Q?_68UqX->zhK9RG-N2aV!if2Wn6mZtTusxyB6y#&FJf|5 z2nQJ)o}g-x$7eEWcr%7Wfij=l6ddW>0Z-~88BofwB{}#hq!#x*c!SGj@BMTIV-Yg7 z9Z@MH!#)meOqh})RMiI9a0ZP3N{%U@_o!QK?8lMFP_xzT1l!eTB04TfQcAPamwAzL e)dKFK1aNun_NPF9xYw+OQK@SaO59(ict*ki literal 0 HcmV?d00001 diff --git a/tests/database/more.db b/tests/database/more.db new file mode 100644 index 0000000000000000000000000000000000000000..ddb8f9b66c35938c1f28f37dd74a76d8fa80f5ca GIT binary patch literal 4096 zcmeHJ&2G~`5Vn&zH%l03L~HN34f%1gU78+K5H}tP z9tR$R3+vc!-LyqjTMkHG+3T6v_3q5KGdttH-5DjI24OU1iK9=*+WhGYAl9wn=F>j9{}9MeO9+lI$PN{A3i)GOqUtW=TeNCoGP0=>(={ z@?OTYOH=!EWFW(`DJIrpP*$aPmOp2+w0^2ZweOA)FkdK72u`nsuzCX{F>d)K5V}RUJ!8u`cc#w^~atFH^wLNh5 zfbo;mB4QCj^u@3yEPB_%j9D50wrvt19Wx6N4>N-j(|~{ke8r*?#%>agX8YOtyGK(G zqFkd3*blr9;OF3%z}aCbnw&gl4FT2iF=U4i>@TprIY1egg zF#mGA>Cs0_I7R9$xmy%i-4wl&W0;x<(Rw4z%?%OuwIA{?`B4@BRs6%|`Hfb^f0}8E z$iCwK{-5I?5o(}iZC-mViKl860(U{+GgcJm>%$htEU*m%h;YVj?BPJimW@FRM704r ztR&-qa>tai_mXV)=1Iiztm#fh{ Date: Sun, 9 Nov 2014 23:00:53 +0100 Subject: [PATCH 04/10] make builder save and load hash --- builder/index.js | 27 ++++++++++++-- core/index.js | 29 +++++++++------ lib/getHashDependencies.js | 20 ----------- middleware/builderHash.js | 3 +- more/index.js | 20 +++++++++-- package.json | 4 +++ views/builder/index.jade | 12 +++++-- views/css/global.styl | 5 +++ views/js/main.js | 73 ++++++++++++++++++++++++++++++-------- 9 files changed, 138 insertions(+), 55 deletions(-) mode change 100644 => 100755 core/index.js delete mode 100644 lib/getHashDependencies.js diff --git a/builder/index.js b/builder/index.js index 8c113e6..91796af 100644 --- a/builder/index.js +++ b/builder/index.js @@ -7,9 +7,18 @@ var packager = require('mootools-packager'); var getFiles = require('../lib/getFiles'); var projectPath = require('../lib/projectPath'); var bodyParser = require('body-parser'); +var pkgProjects = require('../package.json')._projects; +var hashPath = (function(){ + var pathObject = {}; + var projects = Object.keys(pkgProjects).forEach(function(project){ + pathObject[project] = pkgProjects[project].hashStorage; + }) + return pathObject; +})(); +var builderHash = require('../middleware/builderHash')(hashPath); var copyright = '/* MooTools: the javascript framework. license: MIT-style license. copyright: Copyright (c) 2006-' + new Date().getFullYear() + ' [Valerio Proietti](http://mad4milk.net/).*/ '; -var allVersions = require('../package.json'); + function uglify(source){ var uglifyed = UglifyJS.minify(source, { @@ -24,7 +33,7 @@ function processPost(req, res){ var postData = req.body; var minified = postData.minified; var project = postData.project; - var version = allVersions._projects[project.toLowerCase()].versions[0]; + var version = pkgProjects[project.toLowerCase()].versions[0]; var corePath = projectPath('core', version); var morePath = projectPath('more', version); @@ -62,10 +71,22 @@ function processPost(req, res){ res.end(); } } - +function hash(req, res, next){ + if (!req.query.packages) return res.end(); + builderHash.save(req.query.project, req.query.packages, function(data) { + res.locals.hash = data.hash; + next(); + }); +} module.exports = function(app){ app.use(bodyParser.urlencoded({ extended: true })); app.post('/builder', processPost); + app.get('/builder', hash, function(req, res){ + res.send({ + hash: res.locals.hash, + project: req.query.project + }); + }); }; diff --git a/core/index.js b/core/index.js old mode 100644 new mode 100755 index 6eed471..61bb8c5 --- a/core/index.js +++ b/core/index.js @@ -9,8 +9,8 @@ var guides = require('../middleware/guides')('core', { }); var project = 'core'; -var versions = require('../package.json')._projects[project].versions; -var getHashDependencies = require('../lib/getHashDependencies')(); +var pkgProject = require('../package.json')._projects[project]; +var versions = pkgProject.versions; var links = versions.slice(1).map(function(version){ return { version: version, @@ -23,6 +23,19 @@ var links = versions.slice(1).map(function(version){ }; }); +var builderHash = require('../middleware/builderHash')({ + core: pkgProject.hashStorage +}); + +function hash(req, res, next){ + var hash = req.params.hash; + if (!hash) return next(); + builderHash.load(project, hash, function(data) { + res.locals.hash = data.packages; + next(); + }); +} + module.exports = function(app){ var core = function(req, res, next){ @@ -31,7 +44,6 @@ module.exports = function(app){ }; app.get('/core', core, function(req, res){ - res.render('core/index', { page: "/core", title: "MooTools Core", @@ -42,15 +54,14 @@ module.exports = function(app){ }); }); - app.get('/core/builder/:hash?', function(req, res){ - var hash = req.params.hash; + app.get('/core/builder/:hash?', hash, function(req, res){ res.render('builder/index', { title: 'MooTools Core Builder', navigation: 'core', page: 'builder', project: 'Core', site: 'core', - hashDependencies: getHashDependencies(hash), + hashDependencies: res.locals.hash || [], version: versions[0], versions: links, dependencies: require('../builder/dependencies.js')(project, versions[0]) @@ -65,10 +76,8 @@ module.exports = function(app){ app.get('/core/guides/:guide', core, guides.article); // hash build redirect - var regex = /core\/([a-z]+[0-9]+[a-z0-9]*|[0-9]+[a-z]+[a-z0-9]*)$/; - app.get(regex, function(req, res){ - var hash = req.path.match(regex)[1]; - res.redirect('/core/builder/' + hash); + app.get('/core/:hash', function(req, res){ + res.redirect('/core/builder/' + req.params.hash); }); }; diff --git a/lib/getHashDependencies.js b/lib/getHashDependencies.js deleted file mode 100644 index b4b45b0..0000000 --- a/lib/getHashDependencies.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -function getHashDependencies(){ - - return function(hash){ - if (!hash) return []; - // I leave a dummy here so far with the first example - // on the issue Tim opened on Github - var DB = { 'e8f3003df2d0919c1091b11854a53e9b': - { - date: '1415017941', - deps: 'Core/Core;Core/String;Core/Event;Core/Browser;Core/Class;Core/Element.Style;Core/Element.Event;Core/Element.Delegation;Core/Element.Dimensions;Core/Fx;Core/Fx.CSS;Core/Fx.Tween;Core/Fx.Morph;Core/Fx.Transitions;Core/Request.HTML;Core/Request.JSON;Core/Cookie;Core/DOMReady' - } - }; - var dependencies = DB[hash].deps.split(';'); - return dependencies; - } -} - -module.exports = getHashDependencies; diff --git a/middleware/builderHash.js b/middleware/builderHash.js index a1e5896..cd076b2 100644 --- a/middleware/builderHash.js +++ b/middleware/builderHash.js @@ -31,9 +31,8 @@ function loadHash(project, hash, callback){ function saveHash(project, packages, callback){ if (packages && packages.length){ var db = getDatabase(project), - packageString = packages.join(';'), + packageString = typeof packages == 'string' ? packages : packages.join(';'), hash = md5.digest_s(packageString); - db.get('SELECT COUNT(*) AS count FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ if (error) throw error; if (row.count){ diff --git a/more/index.js b/more/index.js index 5dfd6d6..782f554 100644 --- a/more/index.js +++ b/more/index.js @@ -9,7 +9,21 @@ var guides = require('../middleware/guides')('more', { }); var project = 'more'; -var lastVersion = require('../package.json')._projects[project].versions[0]; +var pkgProject = require('../package.json')._projects[project]; +var lastVersion = pkgProject.versions[0]; + +var builderHash = require('../middleware/builderHash')({ + more: pkgProject.hashStorage +}); + +function hash(req, res, next){ + var hash = req.params.hash; + if (!hash) return next(); + builderHash.load(project, hash, function(data) { + res.locals.hash = data.packages; + next(); + }); +} module.exports = function(app){ @@ -28,7 +42,7 @@ module.exports = function(app){ }); }); - app.get('/more/builder/:hash?', function(req, res){ + app.get('/more/builder/:hash?', hash, function(req, res){ var hash = req.params.hash; res.render('builder/index', { title: 'MooTools More Builder', @@ -36,7 +50,7 @@ module.exports = function(app){ page: 'builder', project: 'More', site: 'more', - hashDependencies: getHashDependencies(hash), + hashDependencies: res.locals.hash || [], version: lastVersion, dependencies: require('../builder/dependencies.js')(project, lastVersion) }); diff --git a/package.json b/package.json index e56f601..f1a796e 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "highlight.js": "7.3", "jade": "0.31", "js-yaml": "^3.2.2", + "md5": "^1.0.0", "mootools-packager": "~0.0.2", "morgan": "~1.3.2", "needle": "~0.6.3", @@ -43,6 +44,7 @@ "semver": "2.0", "serve-favicon": "^2.1.5", "slugify": "0.1", + "sqlite3": "^3.0.2", "stylus": "0.32", "sync-prompt": "^0.4.1", "twitter": "^0.2.13", @@ -60,6 +62,7 @@ "core": { "repository": "https://github.com/mootools/mootools-core", "docsIntro": "Docs/Intro.md", + "hashStorage": "/srv/mootools/core/database/packager.sqlite", "versions": [ "1.5.1", "1.4.5", @@ -70,6 +73,7 @@ "more": { "repository": "https://github.com/mootools/mootools-more", "docsIntro": "Docs/More/More.md", + "hashStorage": "/srv/mootools/more/database/packager.sqlite", "versions": [ "1.5.1", "1.5.0", diff --git a/views/builder/index.jade b/views/builder/index.jade index 420a0c0..5b69404 100644 --- a/views/builder/index.jade +++ b/views/builder/index.jade @@ -40,9 +40,9 @@ block main h3 Choose which modules you want to use - form(method="post", action="/builder") + form#builderOptions(method="post", action="/builder") input(hidden, name="project", value="#{project}") - table#builderOptions + table tr td td File @@ -54,7 +54,7 @@ block main - var hashRequested = hashDependencies.indexOf(file) != -1; tr td - input(type="checkbox", value=file, name="modules[]", data-provides="#{yaml.prov}", data-requires="#{yaml.req}", checked=hashRequested) + input(type="checkbox", value=file, name="modules[]", data-provides="#{yaml.prov}", data-requires="#{yaml.req}", checked=hashRequested, class=hashRequested ? "activeChoice" : "") td #{module} td #{yaml.prov} td #{yaml.desc} @@ -62,6 +62,12 @@ block main h2.step Options: .save + span(id="hashLink") + + label + input(type="checkbox", id="hashOption") + | Save this build and give me a url to it + label input(type="checkbox", name="minified", value="1") diff --git a/views/css/global.styl b/views/css/global.styl index bd9bbe9..07b34fb 100644 --- a/views/css/global.styl +++ b/views/css/global.styl @@ -155,6 +155,11 @@ input[type="checkbox"] height: 1em; position: relative; width: 1em; +#builderOptions table input[type="checkbox"] + &:checked + background #f4f1ed + &.activeChoice:checked + background #7d8aa5 input[type="submit"] background: #F4F1ED; diff --git a/views/js/main.js b/views/js/main.js index 21f635f..ba75d8e 100644 --- a/views/js/main.js +++ b/views/js/main.js @@ -1,11 +1,35 @@ "use strict"; +var global = global || {}; +global.hashRequest = new Request.JSON({ + url: '/builder', + method: 'get', + onComplete: function(res){ + var link = '/' + res.project + '/builder/' + res.hash; + var anchor = new Element('a', { + href: link, + text: 'mootools.net' + link + }); + $('hashLink').empty().adopt(anchor).addClass('visible'); + $('builderOptions').submit(); + } +}); + + window.addEvent('domready', function(){ // download buttons, form submit and source code download document.getElements('a.getFile').addEvent('click', function(e){ e.preventDefault(); - this.getParent('form').submit(); + // check if checkbox for getting hash is checked + if (!$('hashOption').get('checked')) return $('builderOptions').submit(); + + // prepare data and send Request + var project = document.getElement('input[name="project"]').value.toLowerCase(); + var packages = $$('.activeChoice').get('value').reduce(function(a, b){ + return a + b + ';'; + }, ''); + global.hashRequest.send('packages=' + packages + '&project=' + project); }); // to manage dependencies in build table @@ -32,7 +56,9 @@ if (window.matchMedia){ var notReallySelected = selected && selected.classList.contains('not-really'); if (!selected) selected = navigation.querySelector('li'); - if (!navigation || !selected) return; + if (!navigation || !selected){ + return; + } var opened = false; selected.addEventListener('click', function(event){ @@ -76,36 +102,53 @@ if (window.matchMedia){ function customBuilderTable(){ - var checkboxes = document.querySelectorAll('table#builderOptions input[type=checkbox]'); + var checkboxes = $$('form#builderOptions table input[type=checkbox]'); + // in case not builder page if (!checkboxes.length) return; + var providerInput = {}; var requireInput = {}; - for (var i = 0; i < checkboxes.length; i++){ - var data = getData(checkboxes[i]); + checkboxes.each(function(checkbox){ + var data = getData(checkbox); data.provides.forEach(function(code){ - if (code) providerInput[code] = checkboxes[i]; + if (code) providerInput[code] = checkbox; }); data.requires.forEach(function(code){ if (code){ if (!requireInput[code]) requireInput[code] = []; - requireInput[code].push(checkboxes[i]); + requireInput[code].push(checkbox); } }); - checkboxes[i].addEventListener('change', updateModules) - }; - + checkbox.addEvent('change', changedModule); + }); + // in case its a hash URL with pre-selected modules + $$('.activeChoice').set('checked', true).fireEvent('change'); + + // everytime a checkbox changes + function changedModule() { + this.toggleClass('activeChoice', this.checked || !this.hasClass('activeChoice')); + var required = []; + checkboxes.each(function(checkbox){ + if (checkbox.hasClass('activeChoice')) required.append(getData(checkbox).requires); + else checkbox.checked = false; + }); + required.each(addDependency); + } + // trigger update of checked modules/dependencies function updateModules(){ - var action = this.checked ? addDependency : removeDependency; - var modules = getData(this)[this.checked ? 'requires' : 'provides']; + var isWanted = this.checked || this.hasClass('activeChoice'); + var action = isWanted ? addDependency : removeDependency; + var modules = getData(this)[isWanted ? 'requires' : 'provides']; for (var i = 0; i < modules.length; i++) if (modules[i]) action(modules[i]); - } + function addDependency(code){ if (!providerInput[code]) return; providerInput[code].checked = true; updateModules.call(providerInput[code]); } + function removeDependency(code){ if (!requireInput[code]) return; requireInput[code].forEach(function(input){ @@ -113,6 +156,8 @@ function customBuilderTable(){ updateModules.call(input); }); } + + // make array out of data fields function getData(input){ var provides = input.getAttribute('data-provides').split(', '); var requires = input.getAttribute('data-requires').split(', '); @@ -120,7 +165,7 @@ function customBuilderTable(){ } } -// script for older-version select +// script for "choose older version" select global.selectVersion = function(select){ var span = select.getParent().getNext(); span.removeClass('visible'); From 03811912cd73054f369cfb9523913c4f5789aeed Mon Sep 17 00:00:00 2001 From: Sergio Crisostomo Date: Tue, 11 Nov 2014 11:07:44 +0100 Subject: [PATCH 05/10] improvements after review --- builder/index.js | 10 +--- core/index.js | 15 +----- middleware/builderHash.js | 98 +++++++++++++++++++---------------- middleware/hashMiddleware.js | 18 +++++++ more/index.js | 22 ++------ tests/database/newDatabase.js | 25 +++++---- views/js/main.js | 12 ++--- 7 files changed, 95 insertions(+), 105 deletions(-) create mode 100644 middleware/hashMiddleware.js diff --git a/builder/index.js b/builder/index.js index 91796af..00b8f2c 100644 --- a/builder/index.js +++ b/builder/index.js @@ -8,15 +8,7 @@ var getFiles = require('../lib/getFiles'); var projectPath = require('../lib/projectPath'); var bodyParser = require('body-parser'); var pkgProjects = require('../package.json')._projects; - -var hashPath = (function(){ - var pathObject = {}; - var projects = Object.keys(pkgProjects).forEach(function(project){ - pathObject[project] = pkgProjects[project].hashStorage; - }) - return pathObject; -})(); -var builderHash = require('../middleware/builderHash')(hashPath); +var builderHash = require('../middleware/builderHash')(Object.keys(pkgProjects)); var copyright = '/* MooTools: the javascript framework. license: MIT-style license. copyright: Copyright (c) 2006-' + new Date().getFullYear() + ' [Valerio Proietti](http://mad4milk.net/).*/ '; diff --git a/core/index.js b/core/index.js index 61bb8c5..0ccceb0 100755 --- a/core/index.js +++ b/core/index.js @@ -23,18 +23,7 @@ var links = versions.slice(1).map(function(version){ }; }); -var builderHash = require('../middleware/builderHash')({ - core: pkgProject.hashStorage -}); - -function hash(req, res, next){ - var hash = req.params.hash; - if (!hash) return next(); - builderHash.load(project, hash, function(data) { - res.locals.hash = data.packages; - next(); - }); -} +var hashMiddleware = require('../middleware/hashMiddleware')(project); module.exports = function(app){ @@ -54,7 +43,7 @@ module.exports = function(app){ }); }); - app.get('/core/builder/:hash?', hash, function(req, res){ + app.get('/core/builder/:hash?', hashMiddleware, function(req, res){ res.render('builder/index', { title: 'MooTools Core Builder', navigation: 'core', diff --git a/middleware/builderHash.js b/middleware/builderHash.js index cd076b2..03b31bc 100644 --- a/middleware/builderHash.js +++ b/middleware/builderHash.js @@ -1,61 +1,67 @@ 'use strict'; var sqlite3 = require('sqlite3'), - md5 = require('md5'); + md5 = require('md5'), + pkgProjects = require('../package.json')._projects; -var databasePaths = {}, - databases = {}; +function BuilderDatabase(projects){ + this.databasePaths = {}; + this.databases = {}; + this.paths = projects.reduce(function(pathObject, project){ + pathObject[project] = pkgProjects[project].hashStorage; + return pathObject; + }, {}); -function getDatabase(project){ - if (!databases[project]) { - var path = databasePaths[project]; - if (path){ - databases[project] = new sqlite3.Database(path, sqlite3.OPEN_READWRITE, function(error){ - if (error) throw error; - }); - } else { - throw Error('No database found for "' + project + '".'); - } + for (var key in this.paths){ + this.databasePaths[key] = this.paths[key]; } - return databases[project]; -} - -function loadHash(project, hash, callback){ - getDatabase(project).get('SELECT * FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ - var data = null; - if (row) data = {hash: row.md5, packages: row.packages.split(';')}; - if (callback) callback(data); - }); -} -function saveHash(project, packages, callback){ - if (packages && packages.length){ - var db = getDatabase(project), - packageString = typeof packages == 'string' ? packages : packages.join(';'), - hash = md5.digest_s(packageString); - db.get('SELECT COUNT(*) AS count FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ - if (error) throw error; - if (row.count){ - if (callback) callback({hash: hash, packages: packages}); - } else { - var values = {1: hash, 2: packageString, 3: Math.round(Date.now() / 1000)}; - db.run('INSERT INTO hashes (md5, packages, date) VALUES (?, ?, ?)', values, function(error){ + this.getDatabase = function(project){ + if (!this.databases[project]){ + var path = this.databasePaths[project]; + if (path){ + this.databases[project] = new sqlite3.Database(path, sqlite3.OPEN_READWRITE, function(error){ if (error) throw error; - if (callback) callback({hash: hash, packages: packages}); }); + } else { + throw Error('No database found for "' + project + '".'); } - }); - } else { - if (callback) callback(null); + } + return this.databases[project]; } -} -module.exports = function(paths){ - for (var key in paths){ - databasePaths[key] = paths[key]; + this.loadHash = function(project, hash, callback){ + this.getDatabase(project).get('SELECT * FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ + var data = null; + if (row) data = {hash: row.md5, packages: row.packages.split(';')}; + if (callback) callback(data); + }); } - return { - load: loadHash, - save: saveHash + + this.saveHash = function(project, packages, callback){ + if (packages && packages.length){ + var db = this.getDatabase(project), + packageString = typeof packages == 'string' ? packages : packages.join(';'), + hash = md5.digest_s(packageString); + db.get('SELECT COUNT(*) AS count FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ + if (error) throw error; + if (row.count){ + if (callback) callback({hash: hash, packages: packages}); + } else { + var values = {1: hash, 2: packageString, 3: Math.round(Date.now() / 1000)}; + db.run('INSERT INTO hashes (md5, packages, date) VALUES (?, ?, ?)', values, function(error){ + if (error) throw error; + if (callback) callback({hash: hash, packages: packages}); + }); + } + }); + } else { + if (callback) callback(null); + } } } + +module.exports = function(paths){ + var db = new BuilderDatabase(paths); + return {load: db.loadHash.bind(db), save: db.saveHash.bind(db)}; +}; diff --git a/middleware/hashMiddleware.js b/middleware/hashMiddleware.js new file mode 100644 index 0000000..056cebc --- /dev/null +++ b/middleware/hashMiddleware.js @@ -0,0 +1,18 @@ +"use strict"; + +module.exports = function(project){ + + var builderHash = require('../middleware/builderHash')([project]); + + return function(req, res, next){ + var hash = req.params.hash; + if (hash){ + builderHash.load(project, hash, function(data) { + res.locals.hash = data.packages; + next(); + }); + } else { + return next(); + } + } +}; diff --git a/more/index.js b/more/index.js index 782f554..ab4d3b5 100644 --- a/more/index.js +++ b/more/index.js @@ -11,19 +11,7 @@ var guides = require('../middleware/guides')('more', { var project = 'more'; var pkgProject = require('../package.json')._projects[project]; var lastVersion = pkgProject.versions[0]; - -var builderHash = require('../middleware/builderHash')({ - more: pkgProject.hashStorage -}); - -function hash(req, res, next){ - var hash = req.params.hash; - if (!hash) return next(); - builderHash.load(project, hash, function(data) { - res.locals.hash = data.packages; - next(); - }); -} +var hashMiddleware = require('../middleware/hashMiddleware')(project); module.exports = function(app){ @@ -42,7 +30,7 @@ module.exports = function(app){ }); }); - app.get('/more/builder/:hash?', hash, function(req, res){ + app.get('/more/builder/:hash?', hashMiddleware, function(req, res){ var hash = req.params.hash; res.render('builder/index', { title: 'MooTools More Builder', @@ -64,10 +52,8 @@ module.exports = function(app){ app.get('/more/guides/:guide', more, guides.article); // hash build redirect - var regex = /more\/([a-z]+[0-9]+[a-z0-9]*|[0-9]+[a-z]+[a-z0-9]*)$/; - app.get(regex, function(req, res){ - var hash = req.url.match(regex)[1]; - res.redirect('/more/builder#' + hash); + app.get('/more/:hash', function(req, res){ + res.redirect('/more/builder/' + req.params.hash); }); }; diff --git a/tests/database/newDatabase.js b/tests/database/newDatabase.js index 0b5aaa5..8cede77 100755 --- a/tests/database/newDatabase.js +++ b/tests/database/newDatabase.js @@ -5,29 +5,28 @@ var sqlite3 = require('sqlite3').verbose(); var sampleData = require('../tests/database/sampleData.json'); if (!exists){ - console.log('Creating DB file.'); - fs.openSync(file, 'w'); + console.log('Creating DB file.'); + fs.openSync(file, 'w'); } var db = new sqlite3.Database(file); db.serialize(function(){ - if (!exists) db.run("CREATE TABLE hashes (md5, packages, date)"); + if (!exists) db.run("CREATE TABLE hashes (md5, packages, date)"); - if (!exists) sampleData.forEach(function (sample) { - var values = sample; - db.run('INSERT INTO hashes (md5, packages, date) VALUES (?, ?, ?)', values, function(error){ - if (error) throw error; - }); + if (!exists) sampleData.forEach(function (sample) { + var values = sample; + db.run('INSERT INTO hashes (md5, packages, date) VALUES (?, ?, ?)', values, function(error){ + if (error) throw error; + }); + }); - }); - - db.each("SELECT md5, packages, date FROM hashes", function(err, row){ - console.log(row.md5); + db.each("SELECT md5, packages, date FROM hashes", function(err, row){ + console.log(row.md5); console.log(row.packages); console.log(row.date); console.log('.....................'); - }); + }); }); db.close(); diff --git a/views/js/main.js b/views/js/main.js index ba75d8e..2285ef3 100644 --- a/views/js/main.js +++ b/views/js/main.js @@ -2,8 +2,8 @@ var global = global || {}; global.hashRequest = new Request.JSON({ - url: '/builder', - method: 'get', + url: '/builder', + method: 'get', onComplete: function(res){ var link = '/' + res.project + '/builder/' + res.hash; var anchor = new Element('a', { @@ -125,15 +125,15 @@ function customBuilderTable(){ $$('.activeChoice').set('checked', true).fireEvent('change'); // everytime a checkbox changes - function changedModule() { - this.toggleClass('activeChoice', this.checked || !this.hasClass('activeChoice')); + function changedModule() { + this.toggleClass('activeChoice', this.checked || !this.hasClass('activeChoice')); var required = []; checkboxes.each(function(checkbox){ if (checkbox.hasClass('activeChoice')) required.append(getData(checkbox).requires); - else checkbox.checked = false; + else checkbox.checked = false; }); required.each(addDependency); - } + } // trigger update of checked modules/dependencies function updateModules(){ From f9445708a6becc5dcbdb1437597819b309b75eac Mon Sep 17 00:00:00 2001 From: Arian Stolwijk Date: Tue, 11 Nov 2014 14:41:19 +0100 Subject: [PATCH 06/10] Refactored the builder hasher - now it adds the hash link to the download file, as it used to be - improved error handling in the builderHash - use a separate config file for the locations, so you can specify that in dev and production. --- .gitignore | 1 + README.md | 3 +- builder/index.js | 102 ++++++++++++++++------------ config/databases.sample.json | 4 ++ index.js | 17 ++--- middleware/builderHash.js | 120 +++++++++++++++++++-------------- middleware/hashMiddleware.js | 15 +++-- package.json | 2 - tests/database/core.db | Bin 4096 -> 6144 bytes tests/database/newDatabase.js | 5 +- tests/database/sampleData.json | 0 views/builder/index.jade | 17 ++--- views/js/main.js | 28 +------- 13 files changed, 161 insertions(+), 153 deletions(-) create mode 100644 config/databases.sample.json mode change 100755 => 100644 tests/database/newDatabase.js mode change 100755 => 100644 tests/database/sampleData.json diff --git a/.gitignore b/.gitignore index 6afabc1..11a03cd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ *.DS_Store *.tern-port config/api_keys.json +config/databases.json diff --git a/README.md b/README.md index 18bff0d..d261d53 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ To install everything you need to clone the repository and submodules (for the d cd website npm install cp config/api_keys.sample.json config/api_keys.json + cp config/databases.sample.json config/databases.json node build/all node index @@ -28,7 +29,7 @@ To run it, you can either use node directly. node index ``` -Now the website is running on `http://localhost:3000`. +Now the website is running on `http://localhost:3000`. Alternatively use `forever` or use `supervisor`. `supervisor` watches all files, while wrapup/stylus write to the `public` folder. It is advised to use `supervisor --ignore public index`. diff --git a/builder/index.js b/builder/index.js index 00b8f2c..9762d0e 100644 --- a/builder/index.js +++ b/builder/index.js @@ -1,5 +1,6 @@ "use strict"; +var async = require('async'); var path = require('path'); var express = require('express'); var UglifyJS = require('uglify-js'); @@ -8,77 +9,90 @@ var getFiles = require('../lib/getFiles'); var projectPath = require('../lib/projectPath'); var bodyParser = require('body-parser'); var pkgProjects = require('../package.json')._projects; -var builderHash = require('../middleware/builderHash')(Object.keys(pkgProjects)); +var builderHash = require('../middleware/builderHash')(require('../config/databases.json')); var copyright = '/* MooTools: the javascript framework. license: MIT-style license. copyright: Copyright (c) 2006-' + new Date().getFullYear() + ' [Valerio Proietti](http://mad4milk.net/).*/ '; - function uglify(source){ var uglifyed = UglifyJS.minify(source, { fromString : true, mangle: ['sort'] // to assign shorter names to most frequently used variables. }); - return copyright + uglifyed.code; + return uglifyed.code; } -function processPost(req, res){ +function processPost(req, res, next){ var postData = req.body; var minified = postData.minified; var project = postData.project; - var version = pkgProjects[project.toLowerCase()].versions[0]; + var project_ = project.toLowerCase(); - var corePath = projectPath('core', version); - var morePath = projectPath('more', version); + if (!pkgProjects[project_]) { + var e = new Error('This project does not exist'); + e.status = 404; + next(e); + return; + } + var version = pkgProjects[project_].versions[0]; var modules = !postData.modules ? [project + '/*'] : postData.modules; - var packagerOptions = { - name: { - Core: corePath, - More: morePath - }, - noOutput: true, - callback: stream, - removeCoreDependencies: postData.removeCoreDependencies - }; - - if (modules.length) packagerOptions.only = modules; - if (!postData.compat) packagerOptions.strip = ['.*compat']; - - // get all files and send to packager - var sourceFiles = [corePath, morePath].reduce(function(files, folder){ - var folderPath = path.join(__dirname, '/../', folder); - return getFiles(folderPath, files, '.js'); - }, []); - - // compile files - packager(sourceFiles, packagerOptions); - - // callback from packager - function stream(data){ + + function packageFile(cb) { + + var corePath = projectPath('core', version); + var morePath = projectPath('more', version); + + var packagerOptions = { + name: { + Core: corePath, + More: morePath + }, + noOutput: true, + callback: function(data){ + cb(null, data); + }, + removeCoreDependencies: postData.removeCoreDependencies + }; + + if (modules.length) packagerOptions.only = modules; + if (!postData.compat) packagerOptions.strip = ['.*compat']; + + // get all files and send to packager + var sourceFiles = [corePath, morePath].reduce(function(files, folder){ + var folderPath = path.join(__dirname, '/../', folder); + return getFiles(folderPath, files, '.js'); + }, []); + + // compile files + packager(sourceFiles, packagerOptions); + } + + function hash(cb){ + if (!modules || minified) return cb(); + builderHash.save(project_, modules, cb); + } + + async.parallel([packageFile, hash], function(err, results){ + if (err) return next(err); + var filename = ['MooTools-', project, '-', version, (postData.compat ? '-compat' : '') + (minified ? '-compressed' : ''), '.js'].join(''); + var data = results[0]; if (minified) data = uglify(data); + + data = copyright + '\n' + + (results[1] ? '/*\nWeb Build: http://mootools.net/' + project_ + '/builder/' + results[1].hash + '\n*/\n' : '') + + data; + res.setHeader('Content-Type', 'application/javascript'); res.setHeader('Content-Disposition', 'attachment; filename=' + filename); res.write(data); res.end(); - } -} -function hash(req, res, next){ - if (!req.query.packages) return res.end(); - builderHash.save(req.query.project, req.query.packages, function(data) { - res.locals.hash = data.hash; - next(); }); } + module.exports = function(app){ app.use(bodyParser.urlencoded({ extended: true })); app.post('/builder', processPost); - app.get('/builder', hash, function(req, res){ - res.send({ - hash: res.locals.hash, - project: req.query.project - }); - }); }; diff --git a/config/databases.sample.json b/config/databases.sample.json new file mode 100644 index 0000000..f1b3eed --- /dev/null +++ b/config/databases.sample.json @@ -0,0 +1,4 @@ +{ + "core": "tests/database/core.db", + "more": "tests/database/more.db" +} diff --git a/index.js b/index.js index b0805a6..ad38487 100644 --- a/index.js +++ b/index.js @@ -154,17 +154,14 @@ app.use(function(err, req, res, next){ }); }); -app.use(function(err, req, res, next){ - res.status(500); - res.render('errors/500', { - site: 'mootools' +if (app.get('env') != 'development'){ + app.use(function(err, req, res, next){ + res.status(500); + res.render('errors/500', { + site: 'mootools' + }); }); -}); - -// general error handler -app.use(function(err){ - console.error(err); -}); +} // starting server app.listen(app.get('port'), function(){ diff --git a/middleware/builderHash.js b/middleware/builderHash.js index 03b31bc..ce7f78f 100644 --- a/middleware/builderHash.js +++ b/middleware/builderHash.js @@ -1,67 +1,85 @@ -'use strict'; +"use strict"; -var sqlite3 = require('sqlite3'), - md5 = require('md5'), - pkgProjects = require('../package.json')._projects; +var path = require('path'); +var async = require('async'); +var sqlite3 = require('sqlite3'); +var md5 = require('md5'); +var waitForIt = require('../lib/waitForIt'); -function BuilderDatabase(projects){ - this.databasePaths = {}; +function BuilderDatabase(paths){ + this.paths = paths; this.databases = {}; - this.paths = projects.reduce(function(pathObject, project){ - pathObject[project] = pkgProjects[project].hashStorage; - return pathObject; - }, {}); +} - for (var key in this.paths){ - this.databasePaths[key] = this.paths[key]; +BuilderDatabase.prototype.getDatabase = function(project, callback){ + var getDB = this.databases[project]; + if (getDB){ + return getDB.get(callback); + } + var dbPath = path.join(__dirname, '..', this.paths[project]); + if (!path){ + return callback(Error('No database found for "' + project + '".')); } + getDB = waitForIt(function(cb){ + var db = new sqlite3.Database(dbPath, sqlite3.OPEN_READWRITE, function(error){ + if (error) cb(error); + else cb(null, db); + }); + }); + getDB.get(callback); +}; - this.getDatabase = function(project){ - if (!this.databases[project]){ - var path = this.databasePaths[project]; - if (path){ - this.databases[project] = new sqlite3.Database(path, sqlite3.OPEN_READWRITE, function(error){ - if (error) throw error; - }); - } else { - throw Error('No database found for "' + project + '".'); - } - } - return this.databases[project]; +BuilderDatabase.prototype.loadHash = function(project, hash, callback){ + function getResult(row, cb){ + cb(null, row ? {hash: row.md5, packages: row.packages.split(';')} : null); + } + function getHash(db, cb){ + db.get('SELECT * FROM hashes WHERE md5 = ?', {1: hash}, cb); } + async.compose( + getResult, + getHash, + this.getDatabase.bind(this, project) + )(callback); +}; - this.loadHash = function(project, hash, callback){ - this.getDatabase(project).get('SELECT * FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ - var data = null; - if (row) data = {hash: row.md5, packages: row.packages.split(';')}; - if (callback) callback(data); - }); +BuilderDatabase.prototype.saveHash = function(project, packages, callback){ + if (!packages || !packages.length){ + if (callback) callback(null); + return; } - this.saveHash = function(project, packages, callback){ - if (packages && packages.length){ - var db = this.getDatabase(project), - packageString = typeof packages == 'string' ? packages : packages.join(';'), - hash = md5.digest_s(packageString); - db.get('SELECT COUNT(*) AS count FROM hashes WHERE md5 = ?', {1: hash}, function(error, row){ - if (error) throw error; - if (row.count){ - if (callback) callback({hash: hash, packages: packages}); - } else { - var values = {1: hash, 2: packageString, 3: Math.round(Date.now() / 1000)}; - db.run('INSERT INTO hashes (md5, packages, date) VALUES (?, ?, ?)', values, function(error){ - if (error) throw error; - if (callback) callback({hash: hash, packages: packages}); - }); - } - }); + var packageString = typeof packages == 'string' ? packages : packages.join(';'); + var hash = md5.digest_s(packageString); + + function hashCount(db, cb){ + db.get('SELECT COUNT(*) AS count FROM hashes WHERE md5 = ?', {1: hash}, function(err, row){ + cb(err, row && {count: row.count, db: db}); + }); + } + function insertIfNotExisting(res, cb){ + if (res.hash){ + cb(null, {hash: hash, packages: packages}); } else { - if (callback) callback(null); + var values = {1: hash, 2: packageString, 3: Math.round(Date.now() / 1000)}; + res.db.run('INSERT INTO hashes (md5, packages, date) VALUES (?, ?, ?)', values, function(error){ + if (error) cb(error); + else cb(null, {hash: hash, packages: packages}); + }); } } -} + + async.compose( + insertIfNotExisting, + hashCount, + this.getDatabase.bind(this, project) + )(callback); +}; module.exports = function(paths){ - var db = new BuilderDatabase(paths); - return {load: db.loadHash.bind(db), save: db.saveHash.bind(db)}; + var db = new BuilderDatabase(paths); + return { + load: db.loadHash.bind(db), + save: db.saveHash.bind(db) + }; }; diff --git a/middleware/hashMiddleware.js b/middleware/hashMiddleware.js index 056cebc..ea29a8c 100644 --- a/middleware/hashMiddleware.js +++ b/middleware/hashMiddleware.js @@ -1,18 +1,21 @@ "use strict"; -module.exports = function(project){ +var builderHash = require('../middleware/builderHash')(require('../config/databases.json')); - var builderHash = require('../middleware/builderHash')([project]); +module.exports = function(project){ return function(req, res, next){ var hash = req.params.hash; if (hash){ - builderHash.load(project, hash, function(data) { - res.locals.hash = data.packages; - next(); + builderHash.load(project, hash, function(err, data) { + if (err) next(err); + else { + res.locals.hash = data.packages; + next(); + } }); } else { return next(); } - } + }; }; diff --git a/package.json b/package.json index f1a796e..ec65876 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "core": { "repository": "https://github.com/mootools/mootools-core", "docsIntro": "Docs/Intro.md", - "hashStorage": "/srv/mootools/core/database/packager.sqlite", "versions": [ "1.5.1", "1.4.5", @@ -73,7 +72,6 @@ "more": { "repository": "https://github.com/mootools/mootools-more", "docsIntro": "Docs/More/More.md", - "hashStorage": "/srv/mootools/more/database/packager.sqlite", "versions": [ "1.5.1", "1.5.0", diff --git a/tests/database/core.db b/tests/database/core.db index 1947b45e978c2449fd4ece1ea0b2ad5cfc1872f5..beb4f9c76fde6a0c389939ed648f919f95cec086 100644 GIT binary patch literal 6144 zcmeHK&2QsG6t@$nu#{4k3ZWj5QpABpyTLQI=RQU^4FI6jK|mlV+&lC z1?KIES7vAJdwn50uqk?*&`ami;(C3)S+6$d7gp=llvjOYTL(9*_l4RL8_>I1)uInK zDn^!a`L{%(iSnQ2KT`6t1iauqgNjoL2Yilt0{cX29wDNDaqxsBEQlfmE(o7Y+e31BcSrTx-JNt*{}^`qDY@7Yy7JM?PU3Q!-d9SHgpE zP9u#aXWCN&TurGEnEM!WPJmG6;^E7a>BNh(7mU2R*68nd@~xQwOVEK0QII|7w~eqp zqf#dQ@?Lt?@?Nd^03g%Utio=5e>45pJ-uyLaww|6$u`|s{FcA=MT$`-YiX1JPOm~)QQS?qSV+L_@Ju2Cy+5ycoC+_5X+qg!*pBF}X_9bxTq z#1%5LM2H2x2t45Om|8_$PLuLv=seDUh0}RVJ%LLX8;#7EXSg?UeJo5+B+-(EMQ*F} zTF(TANy$nA$j&u0m7O7JeQuS$v462&HpIU<#`%93MC1G)=l^JVzoh)nfg!1&+($|N zSFEqB(z~S@`$zi|L;g3%pmoh4*tQdZM-^6>D=An2SORi|@_B%L0O9(_N__#rM!SR} zh86K(1geT~*66g=R_#3z9|Bp*S#Iy>9NI=<|ELei)4Bi`IYu|-I$`KA!i97> z;K0|ElgJm8MLO`Y)>=xMYL-|0qwL5py4}3@{Z9+eIN`kGgK3hexy?f&QW)HT11Cgt z<+?t?DzniMsuu6~mP|O|4acWIndBY?UrSH%q%YEnQifg4L8g#eJooBDT&aYg&dgyf zB4&;ws)c4);>g2<87U&uZGZ=-d#LD#qJKs`S9D6jpd*eep!blh)%W_b$WZg*p3J(k z$24#S0dglVonE{DDbSC0NascUld&>vbv;5!kmCP_Rers+Vt1^Kr9F+#rRgbFpOe+TDX)JyXkEXeF?{`t+KWy&>wu4m-~uQjR0YhX j5>ZbF8ls3$FG`!9H%%S>tTuh2{f`E%7p|!7ruY8>6ad!~ delta 69 zcmZoLXi%6S&C1EZz`!z5!Jd(GW5N<<9!BQhKmi68Ak{muuy%7VM;`O$-|U<$JS>c@ X3{2ik!i?t`TQ?S#GH!0=t!4rMOD_@p diff --git a/tests/database/newDatabase.js b/tests/database/newDatabase.js old mode 100755 new mode 100644 index 8cede77..fa99735 --- a/tests/database/newDatabase.js +++ b/tests/database/newDatabase.js @@ -1,8 +1,9 @@ var fs = require('fs'); -var file = __dirname + '/../tests/database/test.db'; +var path = require('path'); +var file = path.join(__dirname, 'more.db'); var exists = fs.existsSync(file); var sqlite3 = require('sqlite3').verbose(); -var sampleData = require('../tests/database/sampleData.json'); +var sampleData = require('./sampleData.json'); if (!exists){ console.log('Creating DB file.'); diff --git a/tests/database/sampleData.json b/tests/database/sampleData.json old mode 100755 new mode 100644 diff --git a/views/builder/index.jade b/views/builder/index.jade index 5b69404..06f504c 100644 --- a/views/builder/index.jade +++ b/views/builder/index.jade @@ -6,7 +6,7 @@ block header-logo block header-menu include partials/header-menu - + block main .clearfix.wrapper.builder @@ -28,23 +28,23 @@ block main label input(type="checkbox", name="removeCoreDependencies", value="1") | Remove MooTools Core's dependencies - + label a.button.highlighted.getFile(href='#') span Download MooTools #{project} span.version Ver. #{version} - span.icon.download(aria-hidden='true') + span.icon.download(aria-hidden='true') div.header.clearfix h1 Download your customized version - + h3 Choose which modules you want to use form#builderOptions(method="post", action="/builder") input(hidden, name="project", value="#{project}") table tr - td + td td File td Provides td Description @@ -53,7 +53,7 @@ block main - var file = project + "/" + module; - var hashRequested = hashDependencies.indexOf(file) != -1; tr - td + td input(type="checkbox", value=file, name="modules[]", data-provides="#{yaml.prov}", data-requires="#{yaml.req}", checked=hashRequested, class=hashRequested ? "activeChoice" : "") td #{module} td #{yaml.prov} @@ -64,11 +64,6 @@ block main .save span(id="hashLink") - label - input(type="checkbox", id="hashOption") - | Save this build and give me a url to it - - label input(type="checkbox", name="minified", value="1") | Download minified source code diff --git a/views/js/main.js b/views/js/main.js index 2285ef3..f269f8d 100644 --- a/views/js/main.js +++ b/views/js/main.js @@ -1,35 +1,11 @@ "use strict"; -var global = global || {}; -global.hashRequest = new Request.JSON({ - url: '/builder', - method: 'get', - onComplete: function(res){ - var link = '/' + res.project + '/builder/' + res.hash; - var anchor = new Element('a', { - href: link, - text: 'mootools.net' + link - }); - $('hashLink').empty().adopt(anchor).addClass('visible'); - $('builderOptions').submit(); - } -}); - - window.addEvent('domready', function(){ - + // download buttons, form submit and source code download document.getElements('a.getFile').addEvent('click', function(e){ e.preventDefault(); - // check if checkbox for getting hash is checked - if (!$('hashOption').get('checked')) return $('builderOptions').submit(); - - // prepare data and send Request - var project = document.getElement('input[name="project"]').value.toLowerCase(); - var packages = $$('.activeChoice').get('value').reduce(function(a, b){ - return a + b + ';'; - }, ''); - global.hashRequest.send('packages=' + packages + '&project=' + project); + this.getParent('form').submit(); }); // to manage dependencies in build table From be189617b8b73883d1d6bcc880dbde121ee8e9b1 Mon Sep 17 00:00:00 2001 From: Arian Stolwijk Date: Tue, 11 Nov 2014 14:43:48 +0100 Subject: [PATCH 07/10] Make core/index not executable. --- core/index.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 core/index.js diff --git a/core/index.js b/core/index.js old mode 100755 new mode 100644 From a7ee207cae3eb60459bc3475dc5f667caa1e2422 Mon Sep 17 00:00:00 2001 From: Arian Stolwijk Date: Tue, 11 Nov 2014 14:45:51 +0100 Subject: [PATCH 08/10] Move the BuilderHash from middelware to lib. --- builder/index.js | 2 +- middleware/builderHash.js => lib/BuilderHash.js | 0 middleware/hashMiddleware.js | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename middleware/builderHash.js => lib/BuilderHash.js (100%) diff --git a/builder/index.js b/builder/index.js index 9762d0e..13f1286 100644 --- a/builder/index.js +++ b/builder/index.js @@ -9,7 +9,7 @@ var getFiles = require('../lib/getFiles'); var projectPath = require('../lib/projectPath'); var bodyParser = require('body-parser'); var pkgProjects = require('../package.json')._projects; -var builderHash = require('../middleware/builderHash')(require('../config/databases.json')); +var builderHash = require('../lib/BuilderHash')(require('../config/databases.json')); var copyright = '/* MooTools: the javascript framework. license: MIT-style license. copyright: Copyright (c) 2006-' + new Date().getFullYear() + ' [Valerio Proietti](http://mad4milk.net/).*/ '; function uglify(source){ diff --git a/middleware/builderHash.js b/lib/BuilderHash.js similarity index 100% rename from middleware/builderHash.js rename to lib/BuilderHash.js diff --git a/middleware/hashMiddleware.js b/middleware/hashMiddleware.js index ea29a8c..4dfd4bb 100644 --- a/middleware/hashMiddleware.js +++ b/middleware/hashMiddleware.js @@ -1,6 +1,6 @@ "use strict"; -var builderHash = require('../middleware/builderHash')(require('../config/databases.json')); +var builderHash = require('../lib/BuilderHash')(require('../config/databases.json')); module.exports = function(project){ From cecc92c01b38608c11e8d8d9402165f98324b181 Mon Sep 17 00:00:00 2001 From: Arian Stolwijk Date: Tue, 11 Nov 2014 14:55:39 +0100 Subject: [PATCH 09/10] Rename middleware/buildHash - fix when the hash was not in the database Fix when there are no results for loadHash --- core/index.js | 14 ++++++++------ lib/BuilderHash.js | 8 +++----- .../{hashMiddleware.js => buildHash.js} | 5 ++--- more/index.js | 13 +++++++------ tests/database/more.db | Bin 4096 -> 4096 bytes 5 files changed, 20 insertions(+), 20 deletions(-) rename middleware/{hashMiddleware.js => buildHash.js} (88%) diff --git a/core/index.js b/core/index.js index 0ccceb0..cbb1150 100644 --- a/core/index.js +++ b/core/index.js @@ -1,16 +1,20 @@ "use strict"; -var docs = require('../middleware/docs')('core', { +var project = 'core'; + +var docs = require('../middleware/docs')(project, { title: "MooTools Core Documentation" }); -var guides = require('../middleware/guides')('core', { +var guides = require('../middleware/guides')(project, { title: "MooTools Core Guides" }); -var project = 'core'; +var hash = require('../middleware/buildHash')(project); + var pkgProject = require('../package.json')._projects[project]; var versions = pkgProject.versions; + var links = versions.slice(1).map(function(version){ return { version: version, @@ -23,8 +27,6 @@ var links = versions.slice(1).map(function(version){ }; }); -var hashMiddleware = require('../middleware/hashMiddleware')(project); - module.exports = function(app){ var core = function(req, res, next){ @@ -43,7 +45,7 @@ module.exports = function(app){ }); }); - app.get('/core/builder/:hash?', hashMiddleware, function(req, res){ + app.get('/core/builder/:hash?', hash, function(req, res){ res.render('builder/index', { title: 'MooTools Core Builder', navigation: 'core', diff --git a/lib/BuilderHash.js b/lib/BuilderHash.js index ce7f78f..3e12e45 100644 --- a/lib/BuilderHash.js +++ b/lib/BuilderHash.js @@ -30,14 +30,12 @@ BuilderDatabase.prototype.getDatabase = function(project, callback){ }; BuilderDatabase.prototype.loadHash = function(project, hash, callback){ - function getResult(row, cb){ - cb(null, row ? {hash: row.md5, packages: row.packages.split(';')} : null); - } function getHash(db, cb){ - db.get('SELECT * FROM hashes WHERE md5 = ?', {1: hash}, cb); + db.get('SELECT * FROM hashes WHERE md5 = ?', {1: hash}, function(err, row){ + cb(err, row ? {hash: row.md5, packages: row.packages.split(';')} : null); + }); } async.compose( - getResult, getHash, this.getDatabase.bind(this, project) )(callback); diff --git a/middleware/hashMiddleware.js b/middleware/buildHash.js similarity index 88% rename from middleware/hashMiddleware.js rename to middleware/buildHash.js index 4dfd4bb..dab3873 100644 --- a/middleware/hashMiddleware.js +++ b/middleware/buildHash.js @@ -8,11 +8,10 @@ module.exports = function(project){ var hash = req.params.hash; if (hash){ builderHash.load(project, hash, function(err, data) { - if (err) next(err); - else { + if (data){ res.locals.hash = data.packages; - next(); } + next(err); }); } else { return next(); diff --git a/more/index.js b/more/index.js index ab4d3b5..3c82c26 100644 --- a/more/index.js +++ b/more/index.js @@ -1,17 +1,19 @@ "use strict"; -var docs = require('../middleware/docs')('more', { +var project = 'more'; + +var docs = require('../middleware/docs')(project, { title: "MooTools More Documentation" }); -var guides = require('../middleware/guides')('more', { +var guides = require('../middleware/guides')(project, { title: "MooTools More Guides" }); -var project = 'more'; +var hash = require('../middleware/buildHash')(project); + var pkgProject = require('../package.json')._projects[project]; var lastVersion = pkgProject.versions[0]; -var hashMiddleware = require('../middleware/hashMiddleware')(project); module.exports = function(app){ @@ -30,8 +32,7 @@ module.exports = function(app){ }); }); - app.get('/more/builder/:hash?', hashMiddleware, function(req, res){ - var hash = req.params.hash; + app.get('/more/builder/:hash?', hash, function(req, res){ res.render('builder/index', { title: 'MooTools More Builder', navigation: 'more', diff --git a/tests/database/more.db b/tests/database/more.db index ddb8f9b66c35938c1f28f37dd74a76d8fa80f5ca..819b0f8e6392724d02a9d9231f2565b2ae63040f 100644 GIT binary patch delta 127 zcmZorXi%6S&B#7c#+i|QW5N<{4kpGA3{2jPA2t>~VT_JsWAV*rNwly`wluahHaAX9 zGcrmsF*8mwH#SO2GETHeN=-^m^35+w)dvyQV3tc!VmgAQ=bK*!l?cu+DoISrNi7aZ M5|!EP&9{{i0Bf8l@&Et; delta 33 pcmZorXi%6S&B!)U#+i|AW5N<{Hby3I1}5)~g^o;{z4^8>0sxJt2yy@b From 1ccdd1ef763191bb58ab3fd7ead927fc873a2b4a Mon Sep 17 00:00:00 2001 From: Sergio Crisostomo Date: Tue, 11 Nov 2014 21:11:13 +0100 Subject: [PATCH 10/10] remove unused placeholder span --- views/builder/index.jade | 2 -- 1 file changed, 2 deletions(-) diff --git a/views/builder/index.jade b/views/builder/index.jade index 06f504c..9392639 100644 --- a/views/builder/index.jade +++ b/views/builder/index.jade @@ -62,8 +62,6 @@ block main h2.step Options: .save - span(id="hashLink") - label input(type="checkbox", name="minified", value="1") | Download minified source code