forked from grahamjenson/hapiger
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit with most of a service written
- Loading branch information
0 parents
commit 560e067
Showing
3,576 changed files
with
700,497 additions
and
0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<img src="./assets/hapiger300x200.png" align="right" alt="HapiGER logo" /> | ||
|
||
Providing good recommendations can get greater user engagement and provide an opportunity to add value that would otherwise not exist. The main reason why many applications don't provide recommendations is the perceived difficulty in either implementing a custom engine or using an off-the-shelf engine. | ||
|
||
Good Enough Recommendations (**GER**) is an attempt to reduce this difficulty by providing a recommendation engine that is scalable, easily usable and easy to integrate. HapiGER is an HTTP wrapper around GER implemented using the Hapi.js framework. | ||
|
||
Posts about (or related to) GER: | ||
|
||
1. Demo Movie Recommendations Site: [Yeah, Nah](http://yeahnah.maori.geek.nz/) | ||
1. Overall description and motivation of GER: [Good Enough Recommendations with GER](http://maori.geek.nz/post/good_enough_recomendations_with_ger) | ||
2. How GER works [GER's Anatomy: How to Generate Good Enough Recommendations](http://www.maori.geek.nz/post/how_ger_generates_recommendations_the_anatomy_of_a_recommendations_engine) | ||
2. Testing frameworks being used to test GER: [Testing Javascript with Mocha, Chai, and Sinon](http://www.maori.geek.nz/post/introduction_to_testing_node_js_with_mocha_chai_and_sinon) | ||
3. Bootstrap function for dumping data into GER: [Streaming directly into Postgres with Hapi.js and pg-copy-stream](http://www.maori.geek.nz/post/streaming_directly_into_postgres_with_hapi_js_and_pg_copy_stream) | ||
4. [Postgres Upsert (Update or Insert) in GER using Knex.js](http://www.maori.geek.nz/post/postgres_upsert_update_or_insert_in_ger_using_knex_js) | ||
|
||
#Quick Start Guide | ||
|
||
To install hapiger | ||
|
||
``` | ||
npm install -g hapiger | ||
``` | ||
|
||
To start hapiger | ||
|
||
``` | ||
hapiger | ||
``` | ||
|
||
To create an event: | ||
|
||
``` | ||
curl -X POST 'http://localhost:7890/default/event' -d '{person: "p1", action: "likes", thing: "x-men"}' | ||
``` | ||
|
||
The `default` namespace is initialized on startup | ||
|
||
To get recommendations for a user | ||
|
||
``` | ||
curl -X GET 'http://localhost:7890/default/recommendations?person=p1&action=likes' | ||
``` | ||
|
||
To compact the database | ||
|
||
``` | ||
curl -X POST 'http://localhost:7890/default/compact' | ||
``` | ||
|
||
#Namespace | ||
|
||
Namespaces are exclusive places to store events and query for recommendations | ||
|
||
To create a custom namespace | ||
|
||
``` | ||
curl -X POST 'http://localhost:7890/namespace/movies' | ||
``` | ||
|
||
|
||
Then you can add events | ||
|
||
``` | ||
curl -X POST 'http://localhost:7890/movies/event' -d '{person: "p1", action: "likes", thing: "x-men"}' | ||
``` | ||
|
||
|
||
A namespace also has an individual GER configuration which can be set by passing a payload, e.g. | ||
|
||
``` | ||
curl -X POST 'http://localhost:7890/namespace' -d '{name: "movies", options: {crowd_weight: 1}}' | ||
``` | ||
|
||
Delete a namespace (and all its events) with | ||
|
||
``` | ||
curl -X DELETE 'http://localhost:7890/namespace/movies' | ||
``` |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/usr/bin/env node | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
bb = require 'bluebird' | ||
|
||
environment = {} | ||
environment.logging_options = { | ||
reporters: [{ | ||
reporter: require('good-console'), | ||
args: [{ log: '*', response: '*' }] | ||
}] | ||
} | ||
process.env.PORT=4567 | ||
|
||
console.log "ENV", process.env.NODE_ENV | ||
switch process.env.NODE_ENV | ||
when "test" | ||
|
||
process.env.PORT = 3000 | ||
bb.Promise.longStackTraces() | ||
when "production" | ||
else | ||
console.log "ENV", "forcing development" | ||
bb.Promise.longStackTraces() | ||
#AMD | ||
if (typeof define != 'undefined' && define.amd) | ||
define([], -> return environment) | ||
#Node | ||
else if (typeof module != 'undefined' && module.exports) | ||
module.exports = environment; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#Setup the environment variables | ||
environment = require './config/environment' | ||
|
||
#PROMISES LIBRARY | ||
bb = require 'bluebird' | ||
|
||
# HAPI STACK | ||
Hapi = require 'hapi' | ||
Joi = require 'joi' | ||
|
||
# GER | ||
g = require 'ger' | ||
knex = g.knex # postgres client | ||
r = g.r #rethink client | ||
|
||
#ESMs | ||
PsqlESM = g.PsqlESM | ||
MemESM = g.MemESM | ||
RethinkDBESM = g.RethinkDBESM | ||
|
||
Utils = {} | ||
|
||
Utils.handle_error = (logger, err, reply) -> | ||
if err.isBoom | ||
logger.log(['error'], err) | ||
reply(err) | ||
else | ||
console.log "Unhandled Error", err, err.stack | ||
logger.log(['error'], {error: "#{err}", stack: err.stack}) | ||
reply({error: "An unexpected error occurred"}).code(500) | ||
|
||
|
||
class HapiGER | ||
|
||
initialize: () -> | ||
bb.try( => @init_server()) | ||
.then( => @setup_server()) | ||
.then( => @add_server_methods()) | ||
.then( => @add_server_routes()) | ||
|
||
init_server: (esm = 'mem') -> | ||
#SETUP SERVER | ||
@_server = new Hapi.Server() | ||
@_server.connection({ port: process.env.PORT }); | ||
@_esm = MemESM | ||
@info = @_server.info | ||
(new @_esm('default')).initialize() #add the default namespace | ||
|
||
create_namespace: (namespace) -> | ||
(new @_esm(namespace)).initialize() | ||
|
||
setup_server: -> | ||
@load_server_plugin('good', environment.logging_options) | ||
|
||
add_server_routes: -> | ||
@load_server_plugin('./lib/the_hapi_ger', {ESM : @_esm, ESM_OPTIONS : {}}) | ||
|
||
add_server_methods: -> | ||
|
||
|
||
server_method: (method, args = []) -> | ||
d = bb.defer() | ||
@_server.methods[method].apply(@, args.concat((err, result) -> | ||
if (err) | ||
d.reject(err) | ||
else | ||
d.resolve(result) | ||
)) | ||
d.promise | ||
|
||
|
||
start: -> | ||
@start_server() | ||
|
||
stop: -> | ||
@stop_server() | ||
|
||
|
||
|
||
load_server_plugin: (plugin, options = {}) -> | ||
d = bb.defer() | ||
@_server.register({register: require(plugin), options: options}, (err) -> | ||
if (err) | ||
d.reject(err) | ||
else | ||
d.resolve() | ||
) | ||
d.promise | ||
|
||
start_server: -> | ||
d = bb.defer() | ||
@_server.start( => | ||
d.resolve(@) | ||
) | ||
d.promise | ||
|
||
stop_server: -> | ||
d = bb.defer() | ||
@_server.stop( -> | ||
d.resolve() | ||
) | ||
d.promise | ||
|
||
|
||
|
||
|
||
|
||
|
||
#AMD | ||
if (typeof define != 'undefined' && define.amd) | ||
define([], -> return HapiGER) | ||
#Node | ||
else if (typeof module != 'undefined' && module.exports) | ||
module.exports = HapiGER; | ||
else | ||
#not being required | ||
hapiger = new HapiGER() | ||
hapiger.initialize() | ||
.then( -> hapiger.start()) | ||
.catch((e) -> console.log "ERROR"; console.log e.stack) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
bb = require 'bluebird' | ||
|
||
class NS | ||
constructor: (@name, @options = {}) -> | ||
|
||
NS.find = (name) -> | ||
#returns the object with GER options | ||
options = {} | ||
bb.try( => new NS(name, options)) | ||
|
||
#AMD | ||
if (typeof define != 'undefined' && define.amd) | ||
define([], -> return NS) | ||
#Node | ||
else if (typeof module != 'undefined' && module.exports) | ||
module.exports = NS; |
Oops, something went wrong.