diff --git a/app/css/app.css b/app/css/app.css
index bfd83b1..0042991 100644
--- a/app/css/app.css
+++ b/app/css/app.css
@@ -165,6 +165,7 @@ buttons {
padding-bottom: 5px;
border-bottom:1px solid #e0c0e0;
padding-right: 16px;
+ cursor:pointer;
}
#sidedrawer .entry:after {
diff --git a/app/index.html b/app/index.html
index b26ff82..b634bec 100644
--- a/app/index.html
+++ b/app/index.html
@@ -13,10 +13,12 @@
+
+
diff --git a/app/js/app.js b/app/js/app.js
index 231d40b..32cf4df 100644
--- a/app/js/app.js
+++ b/app/js/app.js
@@ -15,7 +15,10 @@ $.fn.pressEnter = function (fn) {
});
};
-(function () {
+var Keeper = (function () {
+
+ var self = this;
+
console.log('GO!');
var $list = $('#listContainer');
var displayList = function (obj) {
@@ -28,12 +31,37 @@ $.fn.pressEnter = function (fn) {
getRecipe(this.id);
});
}, displayPage = function (obj) {
- var $bodyContents = $('#bodyContents');
+ var $bodyContents = $('#bodyContents');
- if (obj.reduced.length > 0) {
- $bodyContents.empty();
- $bodyContents.append(obj.reduced);
+ if (obj.reduced.length > 0) {
+ var vdata = {
+ data: {
+ _id: obj._id,
+ _rev: obj._rev,
+ title: obj.title,
+ reduced: obj.reduced,
+ url:obj.url
}
+ };
+
+ var redoData = {
+ _id: obj._id,
+ _rev: obj._rev,
+ url: obj.url
+ };
+
+
+ var html = new EJS({url: 'partials/view.ejs'}).render(vdata);
+
+ $bodyContents.empty();
+ $bodyContents.append(html);
+
+ $('#redo').on('click', function () {
+ self.trigger('redo', redoData);
+
+ });
+
+ }
}, getRecipe = function (id) {
console.log('get recipe');
var url = '/entry/' + id;
@@ -124,10 +152,40 @@ $.fn.pressEnter = function (fn) {
}
});
},
- start = function () {
+ redo = function (d) {
+ console.log('redooing');
+ var url = '/redo';
- getList();
- };
+ $.ajax({
+ type: 'POST',
+ url: url,
+ data: d,
+ dataType: 'json',
+
+ timeout: 10000,
+
+ //contentType: ('application/json'),
+ headers: {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
+ 'Access-Control-Allow-Headers': 'Content-Type'
+
+ },
+ success: function () {
+ // console.log(data);
+ // displayList(data);
+ },
+ error: function (xhr, type) {
+ console.log('ajax error');
+ console.log(xhr);
+ console.log(type);
+ }
+ });
+ },
+ start = function () {
+
+ getList();
+ };
$('#newurl').pressEnter(function () {
var url = $(this).val();
@@ -146,5 +204,14 @@ $.fn.pressEnter = function (fn) {
getList();
});
+
+
+ this.bind('redo', function (data) {
+ redo(data);
+ });
start();
-})();
+});
+
+MicroEvent.mixin(Keeper);
+
+var keeper = new Keeper();
diff --git a/app/libs/microevent.js b/app/libs/microevent.js
new file mode 100644
index 0000000..e9cdb5c
--- /dev/null
+++ b/app/libs/microevent.js
@@ -0,0 +1,55 @@
+/**
+ * MicroEvent - to make any js object an event emitter (server or browser)
+ *
+ * - pure javascript - server compatible, browser compatible
+ * - dont rely on the browser doms
+ * - super simple - you get it immediatly, no mistery, no magic involved
+ *
+ * - create a MicroEventDebug with goodies to debug
+ * - make it safer to use
+ */
+
+var MicroEvent = function(){};
+MicroEvent.prototype = {
+ bind : function(event, fct){
+ this._events = this._events || {};
+ this._events[event] = this._events[event] || [];
+ this._events[event].push(fct);
+ },
+ unbind : function(event, fct){
+ this._events = this._events || {};
+ if( event in this._events === false ) return;
+ this._events[event].splice(this._events[event].indexOf(fct), 1);
+ },
+ trigger : function(event /* , args... */){
+ this._events = this._events || {};
+ if( event in this._events === false ) return;
+ for(var i = 0; i < this._events[event].length; i++){
+ this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
+ }
+ }
+};
+
+/**
+ * mixin will delegate all MicroEvent.js function in the destination object
+ *
+ * - require('MicroEvent').mixin(Foobar) will make Foobar able to use MicroEvent
+ *
+ * @param {Object} the object which will support MicroEvent
+ */
+MicroEvent.mixin = function(destObject){
+ var props = ['bind', 'unbind', 'trigger'];
+ for(var i = 0; i < props.length; i ++){
+ if( typeof destObject === 'function' ){
+ destObject.prototype[props[i]] = MicroEvent.prototype[props[i]];
+ }else{
+ destObject[props[i]] = MicroEvent.prototype[props[i]];
+ }
+ }
+ return destObject;
+}
+
+// export in common js
+if( typeof module !== "undefined" && ('exports' in module)){
+ module.exports = MicroEvent;
+}
diff --git a/app/partials/view.ejs b/app/partials/view.ejs
new file mode 100644
index 0000000..82bdd85
--- /dev/null
+++ b/app/partials/view.ejs
@@ -0,0 +1,19 @@
+
+
+
<%=data.title%>
+
+ Redo
+ <%=link_to('Link',data.url) %>
+
+
+
+
+
+
+ <%=data.reduced%>
+
+
+
+<%=data._id%>
+<%=data._rev%>
+
diff --git a/package.json b/package.json
index db48a7a..27171ca 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,8 @@
"nano": "^6.2.0",
"require-dir": "^0.3.0",
"serve-favicon": "^2.3.0",
- "string": "^3.3.1"
+ "string": "^3.3.1",
+ "url": "^0.11.0"
},
"devDependencies": {
"del": "^2.2.0",
diff --git a/server/keeper.js b/server/keeper.js
index 8b064b2..10e0422 100644
--- a/server/keeper.js
+++ b/server/keeper.js
@@ -8,6 +8,7 @@ var jsonfile = require('jsonfile'), fs = require('fs'), STRING = require('string
var zlib = require("zlib");
var log4js = require('log4js');
var logger = log4js.getLogger();
+var URL = require('url');
var router = express.Router();
@@ -49,14 +50,39 @@ function insertBookmark(obj) {
logger.debug('Insert done..');
}
+function updateBookmark(obj,_id, _rev) {
+ logger.debug('Updating couch...');
+ var _obj = obj;
+ _obj._id = _id;
+ _obj._rev = _rev;
+ logger.info(util.inspect(_obj));
+
+ dbCouch.insert(_obj, function(err, body,header) {
+ if (err) {
+ logger.error('Error updating into couch');
+ return;
+ }
+ });
+ logger.debug('Update done..');
+}
var doInsertBookmark = (obj) =>{
// logger.info('sendSocket: ' + JSON.stringify(obj));
insertBookmark(obj);
};
-var doGetBookmark = (url) =>{
+var doUpdateBookmark = (obj, _id, _rev) =>{
+ // logger.info('sendSocket: ' + JSON.stringify(obj));
+ updateBookmark(obj,_id, _rev);
+};
+
+var doGetBookmark = (obj) =>{
// logger.info('sendSocket: ' + JSON.stringify(obj));
- genericGrab(url);
+ genericGrab(obj);
+};
+
+var doGetBookmarkRedo = (obj) =>{
+ // logger.info('sendSocket: ' + JSON.stringify(obj));
+ genericGrab(obj);
};
var doGetBookmarkRes = (url,res) =>{
@@ -67,25 +93,28 @@ var doGetBookmarkRes = (url,res) =>{
// Events
busEmitter.on('saveBookmarkData', doInsertBookmark);
+busEmitter.on('updateBookmarkData', doUpdateBookmark);
busEmitter.on('getBookmark', doGetBookmark);
busEmitter.on('getBookmarkRes', doGetBookmarkRes);
-function processBody(body, url) {
+busEmitter.on('getBookmarkRedo', doGetBookmarkRedo);
+function processBody(body, url, _id, _rev) {
+
+ var obj, tdihbody, i, urlObj, urlPrefix;
var $ = cheerio.load(body);
var title = $('TITLE').text();
// try to find a body to grab
- var i = 0;
+ i = 0;
while (($(generics[i]).length == 0) && (i < generics.length)) {
i++;
}
logger.debug(i);
- var tdihbody;
- var obj = {};
+ obj = {};
if (i < generics.length) {
tdihbody = $(generics[i]);
logger.debug(tdihbody.length);
@@ -100,34 +129,53 @@ function processBody(body, url) {
logger.debug(title);
}
- try
- {
- tdihbody.find('IMG').each(function(i, elem) {
- //fruits[i] = $(this).text();
- var s = 'http://image.silvrtree.co.uk/900,fit/' + $(this).attr("src");
+ urlObj = URL.parse(url);
+ urlPrefix = urlObj.protocol + '//' + urlObj.host + '/';
+ try {
+ tdihbody.find('IMG').each(function (i, elem) {
+ let s, src = $(this).attr("src");
+
+ if (!STRING(src).startsWith('http')) {
+ src = urlPrefix + STRING(src).stripLeft('/').s;
+ }
+ s = 'http://image.silvrtree.co.uk/900,fit/' + src;
$(this).attr("src", s);
});
}
- catch(e)
- {
+ catch (e) {
logger.error(e);
}
-
obj.url = url;
obj.html = $.html();
obj.reduced = STRING(tdihbody.html()).trim().s;
obj.title = STRING(title).collapseWhitespace().s;
- busEmitter.emit("saveBookmarkData", obj);
+ if (_id !== null )
+ {
+ busEmitter.emit("updateBookmarkData", obj, _id, _rev);
+ }
+ else
+ {
+ busEmitter.emit("saveBookmarkData", obj);
+ }
+
return obj;
}
-function genericGrab(url,res) {
+function genericGrab(obj,res) {
+
+ var url = obj.url;
+ var _id = obj._id || null;
+ var _ver = obj._rev || null;
+
logger.info(url);
+ logger.info(_id);
+ logger.info(_ver);
+
request(url, function (err, resp, body) {
if (err)
throw err;
@@ -155,7 +203,7 @@ function genericGrab(url,res) {
}
else
{
- var b = processBody(body,url);
+ var b = processBody(body,url, _id, _ver);
if (res != null)
{
res.render('grabbed');
@@ -164,7 +212,7 @@ function genericGrab(url,res) {
} else
{
- var b = processBody(body,url);
+ var b = processBody(body,url, _id, _ver);
if (res != null)
{
res.render('grabbed',{data:b});
@@ -206,8 +254,11 @@ router.get('/entry/:id', function (req, res) {
if (!err) {
var outJSON = {};
+ outJSON._id = body._id;
+ outJSON._rev = body._rev;
outJSON.title = body.title;
outJSON.reduced = body.reduced;
+ outJSON.url = body.url;
//logger.debug(util.inspect(body));
res.writeHead(200, {"ContentType": "application/json"});
res.end(JSON.stringify(outJSON));
@@ -228,7 +279,7 @@ router.post('/add', function (req, res) {
if (t.hasOwnProperty('url')) {
var url = JSON.parse(t.url.toString());
logger.debug(url);
- busEmitter.emit("getBookmark", url);
+ busEmitter.emit("getBookmark", t);
}
else {
logger.error('No data block!');
@@ -238,6 +289,26 @@ router.post('/add', function (req, res) {
});
+router.post('/redo', function (req, res) {
+ logger.debug('redoing entry..');
+
+ var t = req.body;
+ console.log(t);
+ if (t.hasOwnProperty('url')) {
+ var url = t.url.toString();
+ logger.debug(url);
+ busEmitter.emit("getBookmark", t);
+ }
+ else {
+ logger.error('No data block!');
+ }
+ res.writeHead(200, {"ContentType": "application/json"});
+ res.end(JSON.stringify({adding: url}));
+
+});
+
+
+
router.get('/new', function (req, res) {
logger.debug('Save new');
busEmitter.emit("getBookmarkRes", req.query.url ,res);