@@ -1,9 +1,11 @@
// searchspring springboard
// controller of the spring
// manages sites and watches 1 site file structure (git branch) for autobuilding
// manages github and s3 connection for sites (site objects have push/pull/etc)
// queue for site publishing
// * includes css injection / browser reload / js linting and concat
// manages github and s3 connection for site

// queue for site publishing?

// * includes css injection / browser reload

/*
@@ -28,11 +30,10 @@ High Level TODO
|- make themes per/module
a. put site functions in site module (class)
b. put module funtions in mod module (class)
|- pass in user, module, s3w, and git
|- pass in user
2. tie together s3 releases with tagging
|- should be easy with new class functionality from 1a,b
3. update UI
a. main menu dropdown
@@ -162,7 +163,7 @@ function springboard() {
},
sites_repo: "git@github.com:korgon/searchspring-sites.git",
log_http: true,
recent_sites: "none",
recent_sites: [],
}
var s3; // used for putting files to s3
var sites = {}; // object containing all site objects
@@ -205,6 +206,10 @@ function springboard() {

loadModules().then(function() {
return repoInit();
}).then(function() {
// commit work done on site (just in case)
// this prevents git error on loadSites due to master checkout
return commitWork();
}).then(function() {
return self.loadSites();
}).then(function() {
@@ -244,7 +249,7 @@ function springboard() {
if (sites[asite]) {
return sites[asite];
} else {
return { 'error': true, message: 'site ' + asite + ' not found.' };
return { error: true, message: 'site ' + asite + ' not found.' };
}
}

@@ -260,7 +265,7 @@ function springboard() {
// better error handling for git repos

stopWatch();

logit.log('syncing repository', 'updating local copy of repository');
git.checkout('master', function(err) {
if (err) return reject({ error: true, message: err.message });
}).pull('origin', 'master', function (err) {
@@ -314,6 +319,9 @@ function springboard() {
}
if (folders) console.log('\n');
logit.log('load complete', total + ' sites loaded', 'blue');
if(sites[options.current_site]) {
self.watchSite(options.current_site);
}
return resolve(sites);
});
});
@@ -408,23 +416,36 @@ function springboard() {
if (sites[thesite]) {
site = sites[thesite];
options.current_site = site.name;

// recent sites
var recents = options.recent_sites.indexOf(site.name);
if (recents != -1) {
options.recent_sites.splice(recents, 1);
}
var max_number_of_recents = 3
if (options.recent_sites.push(site.name) > max_number_of_recents) {
options.recent_sites.shift();
}

writeConfig();
stopWatch();
logit.log('watching site', 'now watching for changes on ' + site.name, 'warn');
site.checkout().then(function() {
return site.pull()
}).then(function() {
console.log('gulping!');
console.log(site);
// start gulping
watchScss();
watchHtml();
watchJSON();
watchJs();
return resolve(site);
}).catch(function(err) {
console.error(err);
return reject(err);
git.checkout(site.branch, function(err) {
if (err) return reject({ error: true, site: self.name, action: 'checkout', status: 'failed', message: err });
}).clean().then(function() {
self.pullSite().then(function() {
console.log('gulping!');
console.log(site);
// start gulping
watchScss();
watchHtml();
watchJSON();
watchJs();
logit.log('watching site', 'now watching for changes on ' + site.name, 'warn');
return resolve(site);
}).catch(function(err) {
console.error(err);
return reject(err);
});
});
}
else {
@@ -437,35 +458,31 @@ function springboard() {
return site;
}

// * * * * * * * * * * * */

// GIT REPOSITORY functions

// * * * * * * * * * * * */

self.commitSite = function(message, status) {
// promisified
return new Promise(function(resolve, reject) {
if (options.current_site == 'none' || options.current_site == '') return resolve(true);
// must use tempsite because this function can run when no site/sites objects are populated (initial load)
var tempsite = {};

// check if a site is assigned, if not assign the current site (on initial load only)
if (site.siteid === undefined) {
tempsite.name = options.current_site;
if (message === undefined) message = options.user.name + '@springboard >>> AUTOCOMMITED >>> ' + tempsite.name;
} else {
tempsite = site;
if (status === undefined) status == 'commited';
site.setStatus({ gitstatus: status });
if (message === undefined) message = options.user.name + '@springboard >>> COMMITED >>> ' + tempsite.name;
}
if (message === undefined) message = options.user.name + '@springboard >>> COMMITED >>> ' + site.name;
if (status === undefined) status == 'commited';

git.add([sites_dir + '/' + tempsite.name, sites_dir + '/.thumbs'], function(err, data) {
site.setStatus({ gitstatus: status });

git.add([sites_dir + '/' + site.name], function(err, data) {
if (err) return reject(err);
}).commit(message, function(err) {
if (err) {
// apparently its an error when there is nothing to commit
// best way to handle this for now...
logit.log('commit', tempsite.name.bold + ' no changes to commit');
return resolve( { site: tempsite.name, action: 'commit', status: 'nothing to commit' } );
logit.log('commit', site.name.bold + ' no changes to commit');
return resolve( { site: site.name, action: 'commit', status: 'nothing to commit' } );
}
logit.log('commit', message, 'pass');
return resolve( { site: tempsite.name, action: 'commit', status: 'success' } );
return resolve( { site: site.name, action: 'commit', status: 'success' } );
});
});
}
@@ -592,7 +609,6 @@ function springboard() {
return resolve(true);
});
} else {
logit.log('syncing repository', 'updating local copy of repository');
git._baseDir = sites_dir;
return resolve(true);
}
@@ -603,6 +619,22 @@ function springboard() {
});
}

// used to commit work uncommited by error or mistake
// this runs only on load
function commitWork() {
// promisified
return new Promise(function(resolve, reject) {
if (!options.current_site) return resolve(true);

sites[options.current_site] = new website({ name: options.current_site, directory: sites_dir + '/' + options.current_site }, options.user);
site = sites[options.current_site];
var message = options.user.name + '@springboard >>> AUTOCOMMITED >>> ' + site.name;
self.commitSite(message, 'commited').then(function() {
return resolve(true);
});
});
}

// to be used on site creation ONLY for now...
function mergeSite(message) {
// promisified
@@ -620,35 +652,12 @@ function springboard() {
if (err) return reject(err);
}).then(function() {
logit.log('merged', site.name + ' >>> ' + 'master', 'warn');
return resolve(true);
});
});
});
}

// // commit current site to prevent loss of work / errors
// function commitCurrent() {
// // promisified
// return new Promise(function(resolve, reject) {
// if (options.current_site != "none") {
// var cs = options.current_site;
// sites[cs] = new website({ name: cs, directory: sites_dir + '/' + cs }, options.user, git, s3);
// var message = options.user.name + '@springboard >>> AUTOCOMMITED >>> ' + tempsite.name;
// console.log('comcur?');
// sites[cs].commit(message).then(function(resp) {
// if (resp.error) {
// // apparently its an error when there is nothing to commit
// // best way to handle this for now...
// logit.log('commit', tempsite.name.bold + ' no changes to commit');
// } else {
// logit.log('commit', message, 'pass');
// }
// return(resolve);
// });
// }
// return(resolve);
// });
// }

function loadModules() {
// promisified
return new Promise(function(resolve, reject) {
@@ -759,8 +768,11 @@ function springboard() {

function watchScss() {
// scss task compile to css (with sourcemaps) and sync with browser
var watchlist = [site.directory + '/scss/**/*.scss'];
console.log(watchlist);

gulp.task('scss', function() {
gulp.src(site.directory + '/scss/**/*.scss')
gulp.src(watchlist)
.pipe(sourcemaps.init())
.pipe(sass({
sourceComments: 'map',
@@ -775,6 +787,11 @@ function springboard() {
.pipe(reload({stream: true})).on('error', gutil.log)
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(site.directory + '/css/'))
.pipe(gcb(function() {
console.log('scss watch!');
site.setStatus({ gitstatus: 'uncommited' });
logit.log('scss', 'compiled scss file > css file');
}));
});

// css task to minify css
@@ -784,27 +801,31 @@ function springboard() {
.pipe(minify())
.pipe(gulp.dest(site.directory + '/css/'))
.pipe(gcb(function() {
console.log('css watch!');
site.setStatus({ gitstatus: 'uncommited' });
logit.log('scss', 'compiled scss file');
logit.log('css', 'minified css file');
}));
});

// watch for scss file changes
if (eye_of_sauron) {
// stop the watch in the rare case that it should ever exist
eye_of_sauron.end();
// start the watch again
eye_of_sauron = gulp.watch([site.directory + '/scss/**/*.scss'], ['scss', 'css']);
} else {
eye_of_sauron = gulp.watch([site.directory + '/scss/**/*.scss'], ['scss', 'css']);
}
// start the watch again
eye_of_sauron = gulp.watch(watchlist, ['scss', 'css']);
eye_of_sauron.on('change', function(event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
}

function watchHtml() {
// html task to reload browser on change
var watchlist = [site.directory + '/**/*.html'];
gulp.task('html', function() {
gulp.src(site.directory + '/**/*.html')
gulp.src(watchlist)
.pipe(gcb(function() {
console.log('html watch!');
site.setStatus({ gitstatus: 'uncommited' });
reload();
}));
@@ -814,11 +835,12 @@ function springboard() {
if (eye_of_horus) {
// stop the watch in the rare case that it should ever exist
eye_of_horus.end();
// start the watch again
eye_of_horus = gulp.watch([site.directory + '/*.html'], ['html']);
} else {
eye_of_horus = gulp.watch([site.directory + '/*.html'], ['html']);
}
// start the watch again
eye_of_horus = gulp.watch(watchlist, ['html']);
eye_of_horus.on('change', function(event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
}

function watchJSON() {
@@ -844,11 +866,9 @@ function springboard() {
if (eye_of_saturn) {
// stop the watch in the rare case that it should ever exist
eye_of_saturn.end();
// start the watch again
eye_of_saturn = gulp.watch(watchlist, ['rendernj']);
} else {
eye_of_saturn = gulp.watch(watchlist, ['rendernj']);
}
// start the watch again
eye_of_saturn = gulp.watch(watchlist, ['rendernj']);
}

function watchJs() {
@@ -864,6 +884,7 @@ function springboard() {
.pipe(concat(site.name + '.js'))
.pipe(gulp.dest(site.directory + '/js'))
.pipe(gcb(function(){
console.log('js watch!');
site.setStatus({ gitstatus: 'uncommited' });
}));
});
@@ -893,11 +914,9 @@ function springboard() {
if (all_seeing_eye) {
// stop the watch
all_seeing_eye.end();
// start the watch again
all_seeing_eye = gulp.watch(watchlist, ['lintjs']);
} else {
all_seeing_eye = gulp.watch(watchlist, ['lintjs']);
}
// start the watch again
all_seeing_eye = gulp.watch(watchlist, ['lintjs']);
}

function startBrowserSync() {
@@ -1,10 +1,6 @@
// site "class"

// * upload to s3
// * push to git
// * pull from git
// * tag versions
// * module/plugin management?
// module/plugin management

// strictness!
"use strict";
@@ -26,18 +22,16 @@ object prototype
}
functions:
checkoutSite
commit
push
publish (live/mockup)
pullrequest
rerender (allmodules)
installModule
installPlugin
installTheme
removeModule
removePlugin
removeTheme
updateModule
updatePlugin
updateTheme
@@ -73,22 +67,18 @@ var lwip = require('lwip');

// placeholders for passed in objects (dependency injection)
var user;
var git;
var s3;

// the object properties that should be written to file (sitename.json)
var export_options = ['name', 'siteid', 'backend', 'status', 'gitstatus', 'cart'];
var export_options = ['name', 'siteid', 'backend', 'status', 'gitstatus', 'cart', 'default_html'];

// modules object
var modules = {};

// construction
module.exports = website;
// pass in options object, user object and git and s3 dependencies
function website(options, luuser, di_git, di_s3) {
user = luuser;
git = di_git;
s3 = di_s3;
// pass in options object, user object
function website(options, louser) {
user = louser;

this.valid = true;

@@ -102,6 +92,7 @@ function website(options, luuser, di_git, di_s3) {
this.getConfig();
}
else {
this.default_html = this.name + '.html';
this.saveConfig();
}
}
@@ -165,101 +156,6 @@ website.prototype.setStatus = function(newstatus) {
return;
}




// * * * * * * * * * * * */

// GIT REPOSITORY functions

// * * * * * * * * * * * */

website.prototype.checkout = function() {
// promisified
var self = this;
return new Promise(function(resolve, reject) {
git.checkout(self.branch, function(err) {
if (err) return reject({ error: true, site: self.name, action: 'checkout', status: 'failed', message: err });
}).clean().then(function() {
return resolve({ error: null, site: self.name, action: 'checkout', status: 'success' });
});
});
}
website.prototype.pull = function() {
// promisified
var self = this;
return new Promise(function(resolve, reject) {
git.pull('origin', 'site/' + self.name, function(err) {
if (err) return reject({ error: true, site: self.name, action: 'pull', status: 'failed', message: err });
// reload site config to match new pull from repo
self.getConfig();
return resolve({ error: null, site: self.name, action: 'pull', status: 'success' })
});
});
}

website.prototype.commit = function(message, status) {
// promisified
var self = this;
return new Promise(function(resolve, reject) {
if (status === undefined) status == 'commited';

self.setStatus({ gitstatus: status });
var gitmessage = user.name + '@springboard >>> COMMITED >>> ' + self.name;

if (message !== undefined) {
gitmessage += ' >>> ' + message;
}

git.add([self.directory], function(err, data) {
if (err) return reject({ error: true, site: self.name, action: 'commit', status: 'failed', message: err });
}).commit(gitmessage, function(err) {
if (err) {
// apparently its an error when there is nothing to commit
// best way to handle this for now...
// TBD... find a better way
return resolve({ error: null, site: self.name, action: 'commit', status: 'warning', message: 'nothing to commit' });
}
return resolve({ error: null, site: self.name, action: 'commit', status: 'success' });
});
});
}

website.prototype.push = function(message, status) {
// promisified
var self = this;
return new Promise(function(resolve, reject) {
self.commit(message, status).then(function() {
if (self.status == 'new') {
git.pushUp('origin', self.branch, function(err) {
if (err) {
return reject({ error: true, site: self.name, action: 'push', status: 'failed', message: err });
}
return resolve({ error: null, site: self.name, action: 'push', status: 'success' })
});
} else {
git.push('origin', self.branch, function(err) {
if (err) return reject({ error: true, site: self.name, action: 'push', status: 'failed', message: err });
return resolve({ error: null, site: self.name, action: 'push', status: 'success' })
});
}
});
});
}

website.prototype.pullRequest = function() {
// promisified
var self = this;
return new Promise(function(resolve, reject) {
if (true) {
return resolve({ error: null, site: self.name, action: 'pullRequest', status: 'success' });
} else {
return reject({ error: true, site: self.name, action: 'pullRequest', status: 'failed' });
}
});
}


website.prototype.appendHistory = function(username, message) {
console.log('re-writing the books...');
}
@@ -150,15 +150,10 @@ function sb() {

self.pushSite = function() {
$('#loading').fadeIn(300);
$.get('/api/sites/commit/', function(data) {

$.get('/api/sites/push/', function(data) {
if (data.site !== undefined) {
$.get('/api/sites/push/', function(data) {
if (data.site !== undefined) {
$('#loading').fadeOut(300);
} else {
console.log('error: ' + data.error);
}
});
$('#loading').fadeOut(300);
} else {
console.log('error: ' + data.error);
}
@@ -287,7 +282,7 @@ function sb() {

},{"jquery":2}],2:[function(require,module,exports){
/*!
* jQuery JavaScript Library v2.1.3
* jQuery JavaScript Library v2.1.4
* http://jquery.com/
*
* Includes Sizzle.js
@@ -297,7 +292,7 @@ function sb() {
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2014-12-18T15:11Z
* Date: 2015-04-28T16:01Z
*/

(function( global, factory ) {
@@ -355,7 +350,7 @@ var
// Use the correct document accordingly with window argument (sandbox)
document = window.document,

version = "2.1.3",
version = "2.1.4",

// Define a local copy of jQuery
jQuery = function( selector, context ) {
@@ -819,7 +814,12 @@ jQuery.each("Boolean Number String Function Array Date RegExp Object Error".spli
});

function isArraylike( obj ) {
var length = obj.length,

// Support: iOS 8.2 (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = "length" in obj && obj.length,
type = jQuery.type( obj );

if ( type === "function" || jQuery.isWindow( obj ) ) {

Large diffs are not rendered by default.

@@ -1,30 +1,34 @@
// springboard
// http service

var jade = require('jade');
jade = require('jade');

var view_dir = __dirname + '/../views/';

// must pass in the springboard dependency
module.exports = function(springboard) {
return {
editor: function*() {
var site = springboard.getSite(this.params.site);
var sites = springboard.getSites();

var site = springboard.watching();
// redirect if no sites
if (site.error) {
if (Object.keys(sites).length == 0 || site === undefined) {
this.status = 307;
this.redirect('/gallery');
this.redirect('/sites');
this.body = 'Redirecting to sites. There is no site to edit...';
return;
}
this.body = jade.renderFile(view_dir + 'editor.jade', {pretty:true, sites: sites, site: site});
},
editSite: function*() {
var site = springboard.watching();
if (site.default_html) {
this.redirect('/sites/' + site.name + '/' + site.default_html);
} else {
yield springboard.watchSite(site.name);
this.body = jade.renderFile(view_dir + 'editor.jade', {pretty:true, sites: sites, site: site});
this.body = jade.renderFile(view_dir + 'edit_site.jade', {pretty:true, site: site});
}
},
gallery: function*() {
var site = springboard.watching();
var sites = springboard.getSites();
this.body = jade.renderFile(view_dir + 'gallery.jade', {pretty:true, sites: sites});
}
@@ -93,7 +93,20 @@ module.exports = function(springboard) {
}
},

mergeit: function*() {
pull: function*() {
try {
var data = yield springboard.pullSite();
this.response.type = 'json';
this.response.body = data;
}
catch(err) {
console.log(err);
this.response.type = 'json';
this.response.body = { error: true, message: 'site could not be pushed' };
}
},

merge: function*() {
try {
// var data = yield springboard.mergeSite();
var data = { message: 'not really merged dude...' };
@@ -0,0 +1,2 @@
h1.site= site.name
h2 No HTML file set to default.
@@ -12,5 +12,5 @@ block header

block body
#frame
-var site_url = 'http://localhost:1338/sites/' + site.name + '/' + site.name + '.html';
-var site_url = 'http://localhost:1338/sites/' + site.name;
iframe#frameview(name='frameview', src=site_url, onLoad='sb.updateUrl()')
@@ -16,8 +16,8 @@ block body
ul
each site in sites
li
-var site_url = '/sites/' + site.name + '/' + site.name + '.html';
a(href="/edit/" + site.name)
-var site_url = '/sites/' + site.name + '/' + site.name;
a(onclick="sb.viewSite('" + site.name + "')")
span= site.name
if site.status == 'mockup'
img(src="/sites/thumbs/" + site.name + "/" + site.name + '.png')
@@ -26,7 +26,7 @@ block headerextend
ul.sitechoices
-var show_images = true;
each site in sites
-var site_url = '/sites/' + site.name + '/' + site.name + '.html';
-var site_url = '/sites/' + site.name;
li
a(onclick="sb.switchSite('" + site.name + "', '" + site_url + "')")
.shade