Browse Source

init commit

Jake 10 years ago
commit
f088c17a8b
14 changed files with 241 additions and 0 deletions
  1. 3 0
      .gitignore
  2. 21 0
      LICENSE
  3. 61 0
      app.js
  4. 9 0
      bin/www
  5. 18 0
      package.json
  6. 8 0
      public/stylesheets/style.css
  7. 36 0
      routes/avatars.js
  8. 10 0
      routes/index.js
  9. 9 0
      routes/users.js
  10. 48 0
      skins.js
  11. 0 0
      skins/.gitkeep
  12. 6 0
      views/error.jade
  13. 5 0
      views/index.jade
  14. 7 0
      views/layout.jade

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+*.png
+*.log
+node_modules/

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Jake0oo0
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 61 - 0
app.js

@@ -0,0 +1,61 @@
+var express = require('express');
+var path = require('path');
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var cookieParser = require('cookie-parser');
+var bodyParser = require('body-parser');
+
+var routes = require('./routes/index');
+var users = require('./routes/users');
+var avatars = require('./routes/avatars')
+
+var app = express();
+
+// view engine setup
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'jade');
+
+// uncomment after placing your favicon in /public
+//app.use(favicon(__dirname + '/public/favicon.ico'));
+app.use(logger('dev'));
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: false }));
+app.use(cookieParser());
+app.use(express.static(path.join(__dirname, 'public')));
+
+app.use('/', routes);
+app.use('/users', users);
+app.use('/avatars', avatars)
+
+// catch 404 and forward to error handler
+app.use(function(req, res, next) {
+    var err = new Error('Not Found');
+    err.status = 404;
+    next(err);
+});
+
+// error handlers
+
+// development error handler
+// will print stacktrace
+if (app.get('env') === 'development') {
+    app.use(function(err, req, res, next) {
+        res.status(err.status || 500);
+        res.render('error', {
+            message: err.message,
+            error: err
+        });
+    });
+}
+
+// production error handler
+// no stacktraces leaked to user
+app.use(function(err, req, res, next) {
+    res.status(err.status || 500);
+    res.render('error', {
+        message: err.message,
+        error: {}
+    });
+});
+
+module.exports = app;

+ 9 - 0
bin/www

@@ -0,0 +1,9 @@
+#!/usr/bin/env node
+var debug = require('debug')('crafatar');
+var app = require('../app');
+
+app.set('port', process.env.PORT || 3000);
+
+var server = app.listen(app.get('port'), function() {
+  debug('Express server listening on port ' + server.address().port);
+});

+ 18 - 0
package.json

@@ -0,0 +1,18 @@
+{
+  "name": "crafatar",
+  "version": "0.0.0",
+  "private": true,
+  "scripts": {
+    "start": "node ./bin/www"
+  },
+  "dependencies": {
+    "express": "~4.9.0",
+    "body-parser": "~1.8.1",
+    "cookie-parser": "~1.3.3",
+    "morgan": "~1.3.0",
+    "serve-favicon": "~2.1.3",
+    "debug": "~2.0.0",
+    "jade": "~1.6.0",
+    "node-imagemagick": "0.1.3"
+  }
+}

+ 8 - 0
public/stylesheets/style.css

@@ -0,0 +1,8 @@
+body {
+  padding: 50px;
+  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
+}
+
+a {
+  color: #00B7FF;
+}

+ 36 - 0
routes/avatars.js

@@ -0,0 +1,36 @@
+var express = require('express');
+var router = express.Router();
+var skins = require('../skins');
+var fs = require('fs')
+
+/* GET home page. */
+router.get('/:uuid', function(req, res) {
+  //res.render('index', { title: 'Express' });
+  //res.send("uuid is set to " + req.param("uuid"));
+  uuid = req.param('uuid')
+  var filename = 'skins/' + uuid + ".png";
+  if (fs.existsSync(filename)) {
+      fs.readFile(filename, function(err, data) {
+      res.writeHead(200, {'Content-Type': 'image/jpeg'});
+      res.end(data);
+    });
+  } else {
+    skins.get_profile(uuid, function(profile) {
+    	var skinurl = skins.skin_url(profile);
+    	if (skinurl) {
+    		skins.skin_file(skinurl, filename, function() {
+    			skins.extract_face(filename, filename, function() {
+    				fs.readFile(filename, function(err, data) {
+              res.writeHead(200, {'Content-Type': 'image/jpeg'});
+              res.end(data);
+            });
+    			});
+    		});
+    	} else {
+    		res.send("No skin found.");
+    	}
+    });
+  }
+});
+
+module.exports = router;

+ 10 - 0
routes/index.js

@@ -0,0 +1,10 @@
+var express = require('express');
+var router = express.Router();
+
+/* GET home page. */
+router.get('/', function(req, res) {
+  res.render('index', { title: 'Crafatar' });
+});
+
+
+module.exports = router;

+ 9 - 0
routes/users.js

@@ -0,0 +1,9 @@
+var express = require('express');
+var router = express.Router();
+
+/* GET users listing. */
+router.get('/', function(req, res) {
+  res.send('respond with a resource');
+});
+
+module.exports = router;

+ 48 - 0
skins.js

@@ -0,0 +1,48 @@
+var http = require('http');
+var https = require('https');
+var fs = require('fs');
+var imagemagick = require('imagemagick');
+
+module.exports = {
+  get_profile: function(uuid, callback) {
+    https.get("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid, function(res) {
+     res.on('data', function(d) {
+       var profile = JSON.parse(d);
+       if (profile.error) throw profile.error;
+       callback(profile);
+     });
+   });
+  },
+
+  skin_url: function(profile) {
+    var url = null;
+    if (profile && profile.properties) {
+      profile.properties.forEach(function(prop) {
+        if (prop.name == 'textures') {
+          var json = Buffer(prop.value, 'base64').toString();
+          var props = JSON.parse(json);
+          url = props.textures.SKIN.url;
+        }
+      });
+    }
+    return url;
+  },
+
+  skin_file: function(url, filename, callback) {
+    var file = fs.createWriteStream(filename);
+    http.get(url, function(res) {
+      res.on('data', function(data) {
+        file.write(data);
+      }).on('end', function() {
+        file.end();
+        callback();
+      });
+    });
+  },
+  extract_face: function(infile, outfile, callback) {
+    imagemagick.convert([infile, '-crop', '8x8+8+8', outfile], function(err, stdout) {
+      if (err) throw err;
+      callback();
+    });
+  }
+};

+ 0 - 0
skins/.gitkeep


+ 6 - 0
views/error.jade

@@ -0,0 +1,6 @@
+extends layout
+
+block content
+  h1= message
+  h2= error.status
+  pre #{error.stack}

+ 5 - 0
views/index.jade

@@ -0,0 +1,5 @@
+extends layout
+
+block content
+  h1= title
+  p Welcome to #{title}

+ 7 - 0
views/layout.jade

@@ -0,0 +1,7 @@
+doctype html
+html
+  head
+    title= title
+    link(rel='stylesheet', href='/stylesheets/style.css')
+  body
+    block content