Commits

Linh Tran committed f86cc57

initial commit"

Comments (0)

Files changed (5)

+var mysql = require('mysql'),
+    Client = require('mysql').Client,
+    DATABASE = 'motorlite',
+    TABLE = 'profile';
+
+client = new Client();
+
+/**
+ * Connect to MySQL database
+ */
+function connect(callback) {
+    client = mysql.createClient({
+        user: 'root',
+        password : 'root',
+    });
+
+    client.query("USE " + DATABASE, function(err, results) {
+        if (err) {
+            client.end();
+            callback(err);
+        }
+        
+        console.log("Successfully connected to the database");
+    })
+}
+
+/**
+ * Create the object to hold sql interaction method
+ */
+function setup(options, callback) {
+    var db = {
+        getAll: function(callback) {
+            connect(callback);
+            client.query("SELECT * FROM " + TABLE, function (err, results, fields) {
+                if (err) {
+                    callback(err);
+                }
+
+                // console.log(results);
+                callback(null, results);
+                client.end();
+            });
+        },
+
+        getTop: function(limit, callback) {
+            connect(callback);
+            client.query("SELECT * FROM " + TABLE + " ORDER BY win DESC,lose ASC, best_time ASC " +
+                        "LIMIT ?", [limit], function(err, results) {
+                if (err) {
+                    console.log(err);
+                    callback(err);
+                }
+
+                callback(null, results);
+                client.end();
+            });
+        },
+
+        getOne: function(id, callback){
+            connect(callback);
+            // Get the profile and its ranking
+            client.query("SET @rank := 0");
+            client.query("SELECT * FROM " +
+                         "(SELECT *, @rank := @rank + 1 AS rank FROM " +
+                         TABLE + " ORDER BY win DESC,best_time ASC) as result WHERE id = ?", [id], function(err, result) {
+                if (err) {
+                    console.log(err);
+                    callback(err);
+                }
+
+                // console.log(result);
+                callback(null, result);
+                client.end();
+            });
+        },
+
+        createNew: function(profile, callback) {
+            connect(callback);
+            client.query("INSERT INTO " + TABLE + " SET " +
+                        "name = ?, win = ?, lose = ?, best_time = ?", 
+                        [profile.name, profile.win, profile.lose, profile.best_time], function(err, info) {
+                            if (err) {
+                                callback(err);
+                            }
+
+                            // console.log(info.insertId);
+                            callback(null, info.insertId);
+                            client.end();
+                        });
+        },
+
+        update: function(id, profile, callback) {
+            connect(callback);
+            client.query("UPDATE " + TABLE + " SET " +
+                        "name = ?, win = ?, lose = ?, best_time = ? " +
+                        "where id = ?", [profile.name, profile.win, profile.lose, profile.best_time, id], function(err, info) {
+                if (err) {
+                    callback(err);
+                }
+
+                // console.log(info.affectedRows);
+                callback(null, info.affectedRows);
+                client.end();
+            })
+        },
+
+        delete: function(id, callback) {
+            connect(callback);
+            client.query("DELETE FROM " + TABLE +
+                        " WHERE id = ?", [id], function(err, info) {
+                if (err) {
+                    callback(err);
+                }
+
+                // console.log(info.affectedRows);
+                callback(null, info.affectedRows);
+                client.end();
+            });
+        }
+
+    };
+
+    callback(null, db);
+}
+
+exports.setup = setup;
+var journey = require('journey');
+
+// Endcoding helper
+var base64 = {
+    encode: function(unencoded) {
+        return new Buffer(unencoded || '').toString('base64');
+    },
+
+    decode: function(encoded) {
+        return new Buffer(encoded || '', 'base64').toString('utf8');
+    }
+};
+
+// Authentication helper
+var auth = {
+    username: 'admin',
+    password: 'password',
+    basicAuth: function(request, body, callback) {
+        var realm = "Authorization Required",
+            authorization = request.headers.authorization;
+
+        if (!authorization) {
+            return callback(new journey.NotAuthorized("Authorization header is required"));
+        }
+
+        var parts = authorization.split(" ")
+            scheme = parts[0],
+            credentials = base64.decode(parts[1]).split(":");
+            
+        // console.log(credentials);
+
+        if (scheme !== "Basic") {
+            return callback(new journey.NotAuthorized("Authorization scheme must be basic"));
+        } else if (!credentials[0] && !credentials[1]) {
+            return callback(new journey.NotAuthorized("Both username and password are required"));
+        } else if (credentials[0] !== auth.username || credentials[1] !== auth.password) {
+            // console.log(credentials[0] + ':' + credentials[1]);
+            return callback(new journey.NotAuthorized("Invalid username and password"));
+        }
+
+        callback(null);
+    }
+};
+
+exports.base64 = base64;
+exports.auth = auth;
+var util = require('util'),
+    http = require('http'),
+    winston = require('winston'),
+    service = require('./router'),
+    database = require('./database'),
+    helpers = require('./helpers');
+
+exports.createServer = function(port, db) {
+    var router = service.createRouter(db);
+
+    var server = http.createServer(function(request, response) {
+        var body = '';
+
+        winston.info('Incoming Request', {url: request.url});
+
+        request.on('data', function(chunk) {
+            body += chunk;
+        });
+
+        request.on('end', function() {
+            // Dispatch the request to the service
+            var emitter = router.handle(request, body, function (route) {
+                response.writeHead(route.status, route.headers);
+                response.end(route.body);
+            });
+
+            emitter.on('log', function (info) {
+                winston.info('Request completed', info);
+            })
+        });
+    });
+
+    if (port) {
+        server.listen(port);
+    }
+
+    return server;
+};
+
+exports.start = function(options, callback) {
+    database.setup(options, function (err, db) {
+        if (err) {
+            return callback(err);
+        }
+
+        // If -a is in the argument use HTTP Basic Auth
+        if (options.basicAuth) {
+            util.puts('Configuring HTTP Basic Auth. Base64 Encoded Username/Password: ' + helpers.base64.encode(helpers.auth.username + ':' + helpers.auth.password));
+            // util.puts(helpers.auth.username+":"+helpers.auth.password);
+        }
+
+        callback(null, exports.createServer(options.port, db));
+    });
+}
+
+var journey = require('journey'),
+    helpers = require('./helpers');
+
+/**
+ * Creates the RESTful router for the webservice
+ */
+ exports.createRouter = function(resource) {
+     var router = new (journey.Router) ({
+         strick: false,
+         strickUrls: false,
+         api: 'basic',
+         filter: helpers.auth.basicAuth
+     });
+
+     router.path('/profiles', function() {
+         // Authentication: Add a filter() method to perfrom HTTP Basic Auth
+         this.filter(function() {
+             // GET to /profiles lists all profiles
+             this.get().bind(function(res) {
+                 /* res.send(501, {}, {action: 'list'}); */
+                 resource.getAll(function (err, profiles) {
+                     if (err) {
+                         return res.send(500, {}, {error: err.error});
+                     }
+
+                     res.send(200, {}, {profiles: profiles});
+                 });
+             });
+
+             // GET to /profiles/top/:limit to show a number of top profiles
+             this.get(/\/top\/(\d+)$/).bind(function(res, limit) {
+                 resource.getTop(limit, function (err, profiles) {
+                     if (err) {
+                         return res.send(500, {}, {error: err.error});
+                     }
+
+                     res.send(200, {}, {profiles: profiles});
+                 });
+             });
+
+             // GET to /profiles/:id shows the details of a profile
+             this.get(/\/([\w|\d|\-|\_]+)/).bind(function(res, id) {
+                 resource.getOne(id, function(err, profile) {
+                     if (err) {
+                         return res.send(500, {}, {error: err.error});
+                     }
+
+                     res.send(200, {}, {profile: profile});
+                 });
+             });
+
+             // POST to /profiles creates a new profile
+             this.post().bind(function(res, profile) {
+                 // res.send(501, {}, {action: 'create'});
+                 resource.createNew(profile, function(err, id) {
+                     if (err) {
+                         return res.send(500, {}, {error: err.error});
+                     } 
+
+                     res.send(200, {}, {profile_id: id});
+                 });
+             });
+
+             // PUT to /profiles/:id updates an existing profile
+             this.put(/\/([\w|\d|\-|\_]+)/).bind(function(res, id, profile) {
+                 // res.send(501, {}, {action: 'update'});
+                 resource.update(id, profile, function(err, result) {
+                     if (err) {
+                         return res.send(500, {}, {error: err.error});
+                     }
+
+                     if (result != 1) {
+                         return res.send(500, {}, {error: "Couldn't update the profile"});
+                     }
+
+                     res.send(200, {}, {result: result});
+                 })
+             });
+
+             // DELETE to /profiles/ delete a specific profile
+             this.del(/\/([\w|\d|\d\-|\_]+)/).bind(function(res, id) {
+                 // res.send(501, {}, {action: 'delete'});
+                 resource.delete(id, function(err, result) {
+                     if (err) {
+                         return res.send(500, {}, {error: err.error});
+                     }
+
+                     if (result != 1) {
+                         return res.send(500, {}, {error: "Couldn't delete the profile"});
+                     }
+
+                     res.send(200, {}, {result: result});
+                 });
+             });
+         });
+     });
+
+     return router;
+ }
+var server = require('./main'),
+    util = require('util'),
+    path = require('path'),
+    argv = require('optimist').argv;
+
+var help = [
+    "usage: server [options]",
+    "",
+    "Runs the demon profile server",
+    "options:",
+    " -p            Port that you want the home server to run on [8888]",
+    " -s, --setup   Indicates we should configure the database first [false]",
+    " -a, --auth    Show the encoded token for HTTP Basic Auth or not [no]",
+    " -h, --help    You're looking at it right now:D"
+].join('\n');
+
+if (argv.h || argv.help) {
+    return util.puts(help);
+}
+
+var options = {
+    port: argv.p || 8888,
+    basicAuth: argv.a || argv.auth || null
+};
+
+server.start(options, function(err, server) {
+    if (err) {
+        return util.puts('Error starting the profile server: ' + err.message)
+    }
+    util.puts('Profile server is runnning');
+});
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.