Skip to content

Commit

Permalink
added some missing files.
Browse files Browse the repository at this point in the history
  • Loading branch information
cerealbox committed Aug 8, 2015
1 parent 04a249f commit 1c357ce
Show file tree
Hide file tree
Showing 5 changed files with 286 additions and 0 deletions.
32 changes: 32 additions & 0 deletions batch.js
@@ -0,0 +1,32 @@
var Promise = require('promise');

//fun = [1,2,3] -> Promise({1: {}, 2: {}, 3: {}})
module.exports = function batch(fun) {
var batches = {};
var result = null;

return function(ids) {

if (!Object.keys(batches).length) {
result =
Promise.
resolve().
then(function() {
var keys = Object.keys(batches);
batches = {};
return fun(keys);
});
}
ids.forEach(function(id) {
batches[id] = true;
});

return result.then(function(results) {
var prunedResults = {};
ids.forEach(function(id) {
prunedResults[id] = results[id];
});
return prunedResults;
});
};
};
32 changes: 32 additions & 0 deletions cache.js
@@ -0,0 +1,32 @@
var Promise = require('promise');

//fun = [1,2,3] -> Promise({1: {}, 2: {}, 3: {}})
module.exports = function cache(fun) {
var cache = {};

return function(ids) {

var assemble = function(results) {
//put new results in cache:
Object.keys(results).forEach(function(id) {
cache[id] = results[id];
});
//grab cached results:
ids.forEach(function(id) {
results[id] = cache[id];
});

return results;
};

var culledIds = ids.filter(function(id) {
return !cache[id];
});

if (culledIds.length) {
return fun(culledIds).then(assemble);
} else {
return Promise.resolve(assemble({}));
}
};
};
112 changes: 112 additions & 0 deletions rating-service.js
@@ -0,0 +1,112 @@
var Promise = require('promise')
var PouchDB = require('pouchdb')
var ratingsDB = new PouchDB('ratings_db')
var batch = require('./batch')
var cache = require('./cache')

var jlog = function(x) { console.log(JSON.stringify(x, null, 3)) }

// ratings service
function RatingService() {}
RatingService.prototype = {

getRatings: function(userId, titleIds) {
jlog("getRatings(" + userId + ", [" + titleIds + "])")

return ratingsDB.allDocs({
keys: titleIds.map(function(id) {
return userId + "," + id;
}),
include_docs: true
}).then(function(dbResponse) {
var ratings = {}
dbResponse.rows.forEach(function(row) {
ratings[row.key.substr((userId + ",").length)] = row
})
return ratings
});
},

setRatings: function(userId, titlesIdsAndRating) {
jlog("setRatings(" + userId + ", {" + JSON.stringify(titlesIdsAndRating) + "})")

function coerce(rating) {
if (rating > 5)
return 5
else if (rating < 1)
return 1
else
return rating
}

var ids = Object.keys(titlesIdsAndRating)

//test:
// return Promise.resolve({
// 9: {
// doc: {rating: 69}

// },
// 10: {
// doc: {rating: 69}
// }
// })

return ratingsDB.allDocs({
keys: ids.map(function(id) {
return userId + "," + id;
}),
include_docs: true
}).then(function(getResponse) {
//jlog(getResponse)
return ratingsDB.bulkDocs(ids.map(function(id, index) {
// jlog("=============")
// jlog(titlesIdsAndRating[id].userRating)
return {
_id: userId + "," + id,
_rev: (!getResponse.rows[index].error ? getResponse.rows[index].value.rev : undefined),
rating: coerce(titlesIdsAndRating[id].userRating)
};
})).then(function(setResponse) {
var results = {}
getResponse.rows.forEach(function(response, index) {
if (setResponse[index].ok) {
if (getResponse.rows[index].error) {
results[response.key.substr((userId + ",").length)] = {
id: setResponse[index].id,
key: setResponse[index].id,
value: {
rev: setResponse[index].rev
},
doc: {
rating: coerce(titlesIdsAndRating[response.key.substr((userId + ",").length)].userRating),
_id: setResponse[index].id,
_rev: setResponse[index].rev
}
}
} else {
results[response.key.substr((userId + ",").length)] = response
}
} else {
results[response.key.substr((userId + ",").length)] = setResponse[index]
}
})
return results
})
});
}
}

module.exports = new RatingService()

// module.exports.getRatings(1, [3,4,5]).then(jlog, jlog)
// module.exports.getRatings(1, [1,2,3]).then(jlog, jlog)

// //example:
// module.exports.getRatings(1, [11]).then(jlog)
// module.exports.getRatings(1, [11]).then(function(x) {
// jlog(x)
// module.exports.getRatings(1, [11]).then(jlog)
// module.exports.getRatings(1, [11]).then(jlog)
// })
// jlog("-----------------------------------")
74 changes: 74 additions & 0 deletions recommendation-service.js
@@ -0,0 +1,74 @@
var Promise = require('promise')

var PouchDB = require('pouchdb')
var recommendationsDB = new PouchDB('recommendations_db')

var log = console.log.bind(console)
var jlog = function(x) { console.log(JSON.stringify(x, null, 3)) }

// genrelist service
function RecommendationsService() {}
RecommendationsService.prototype = {
getGenreList: function(userId) {
var self = this
if (self.cache) {
return Promise.resolve(self.cache)
} else {
return recommendationsDB.get((userId || 'all').toString())
.then(function(response) {
self.cache = response.recommendations
return response.recommendations
})
}
},
addTitleToGenreList: function(userId, genreIndex, titles) {

return recommendationsDB.get(userId)
.then(function(response) {
var titlesLength = response.recommendations[genreIndex].titles.push(titles);
return recommendationsDB.put({
_id: userId,
_rev: response._rev,
recommendations: response.recommendations
}).then(function(a) {
return [
{
path: ['genrelist', genreIndex, 'titles', titlesLength - 1],
value: titles
},
{
path: ['genrelist', genreIndex, 'titles', 'length'],
value: titlesLength
}
];
});
});
},

//@TODO: untested.
//[].splice(index, howMany, replce, replce, replce) takes unlimited number of the final argument
spliceTitleFromGenreList: function(userId, a, b, c) {
return recommendationsDB.get(userId)
.then(function(response) {
var titlesLength = response.recommendations[genreIndex].titles.splice(a, b, c);
return recommendationsDB.put({
_id: userId,
_rev: response._rev,
recommendations: response.recommendations
}).then(function() {
return [
{
path: ['genrelist', genreIndex, 'titles', titlesLength - 1],
value: titles
},
{
path: ['genrelist', genreIndex, 'titles', 'length'],
value: titlesLength
}
];
});
});
}
}

module.exports = new RecommendationsService()
36 changes: 36 additions & 0 deletions title-service.js
@@ -0,0 +1,36 @@
var PouchDB = require('pouchdb')
var titlesDB = new PouchDB('titles_db')
var batch = require('./batch')
var cache = require('./cache')

var jlog = function(x) { console.log(JSON.stringify(x, null, 3)) }

// titles service
function TitleService() {}
TitleService.prototype = {
getTitles: function(titleIds) {
jlog("getTitles([" + titleIds + "])")

return titlesDB.allDocs({
keys: titleIds,
include_docs: true
}).then(function(dbResponse) {
var titles = {}
dbResponse.rows.forEach(function (row) {
titles[row.key] = row
})
return titles
})
}
}

module.exports = new TitleService()

//example:
// module.exports.getTitles([12]).then(jlog)
// module.exports.getTitles([12]).then(function(x) {
// jlog(x)
// module.exports.getTitles([13]).then(jlog)
// module.exports.getTitles([12,13]).then(jlog)
// })
// jlog("-----------------------------------")

0 comments on commit 1c357ce

Please sign in to comment.