add & clean up documentation

also a small improvement for URL error logging, variable naming, and argument joining
This commit is contained in:
jomo 2015-03-01 18:57:57 +01:00
parent 912b1b2ba7
commit abaf3f77aa
7 changed files with 81 additions and 56 deletions

View File

@ -64,7 +64,7 @@ exp.get_redis = function() {
// updates the redis instance's server_info object
// callback contains error, info object
// callback: error, info object
exp.info = function(callback) {
redis.info(function (err, res) {
@ -95,7 +95,7 @@ exp.info = function(callback) {
// sets the timestamp for +userId+ and its face file's (+hash+) date to the current time
// if +temp+ is true, the timestamp is set so that the record will be outdated after 60 seconds
// these 60 seconds match the duration of Mojang's rate limit ban
// +callback+ contains error
// callback: error
exp.update_timestamp = function(rid, userId, hash, temp, callback) {
logging.log(rid + "cache: updating timestamp");
sub = temp ? (config.local_cache_time - 60) : 0;
@ -143,7 +143,7 @@ exp.remove_hash = function(rid, userId) {
// get a details object for +userId+
// {skin: "0123456789abcdef", cape: "gs1gds1g5d1g5ds1", time: 1414881524512}
// +callback+ contains error, details
// callback: error, details
// details is null when userId not cached
exp.get_details = function(userId, callback) {
// get userId in lower case if not null

View File

@ -8,7 +8,7 @@ var redis = cache.get_redis();
var exp = {};
// compares redis' used_memory with cleaning_redis_limit
// callback contains error, true|false
// callback: error, true|false
function should_clean_redis(callback) {
cache.info(function(err, info) {
if (err) {
@ -28,7 +28,7 @@ function should_clean_redis(callback) {
}
// uses `df` to get the available fisk space
// callback contains error, true|false
// callback: error, true|false
function should_clean_disk(callback) {
df({
file: __dirname + "/../" + config.faces_dir,

View File

@ -15,11 +15,15 @@ function get_hash(url) {
return hash_pattern.exec(url)[0].toLowerCase();
}
function store_skin(rid, userId, profile, details, callback) {
// gets the skin for +userId+ with +profile+
// uses +cache_details+ to determine if the skin needs to be downloaded or can be taken from cache
// face and face+helm images are extracted and stored to files
// callback: error, skin hash
function store_skin(rid, userId, profile, cache_details, callback) {
networking.get_skin_url(rid, userId, profile, function(err, url) {
if (!err && url) {
var skin_hash = get_hash(url);
if (details && details.skin === skin_hash) {
if (cache_details && cache_details.skin === skin_hash) {
cache.update_timestamp(rid, userId, skin_hash, false, function(err) {
callback(err, skin_hash);
});
@ -60,11 +64,15 @@ function store_skin(rid, userId, profile, details, callback) {
});
}
function store_cape(rid, userId, profile, details, callback) {
// gets the cape for +userId+ with +profile+
// uses +cache_details+ to determine if the cape needs to be downloaded or can be taken from cache
// the cape - if downloaded - is stored to file
// callback: error, cape hash
function store_cape(rid, userId, profile, cache_details, callback) {
networking.get_cape_url(rid, userId, profile, function(err, url) {
if (!err && url) {
var cape_hash = get_hash(url);
if (details && details.cape === cape_hash) {
if (cache_details && cache_details.cape === cape_hash) {
cache.update_timestamp(rid, userId, cape_hash, false, function(err) {
callback(err, cape_hash);
});
@ -120,7 +128,10 @@ function callback_for(userId, type, err, hash) {
}
}
// returns true if any object in +arr+ has +value+ as +property+
// returns true if any object in +arr+ has a +property+ that matches +value+
//
// deep_property_check([{foo: "bar"}, {foo: "baz"}], "foo", "baz");
//
function deep_property_check(arr, property, value) {
for (var i = 0; i < arr.length; i++) {
if (arr[i][property] === value) {
@ -131,10 +142,10 @@ function deep_property_check(arr, property, value) {
}
// downloads the images for +userId+ while checking the cache
// status based on +details+. +type+ specifies which
// status based on +cache_details+. +type+ specifies which
// image type should be called back on
// +callback+ contains error, image hash
function store_images(rid, userId, details, type, callback) {
// callback: error, image hash
function store_images(rid, userId, cache_details, type, callback) {
var is_uuid = userId.length > 16;
var new_hash = {
rid: rid,
@ -160,7 +171,7 @@ function store_images(rid, userId, details, type, callback) {
}
} else {
// no error and we have a profile (if it's a uuid)
store_skin(rid, userId, profile, details, function(err, skin_hash) {
store_skin(rid, userId, profile, cache_details, function(err, skin_hash) {
if (err && !skin_hash) {
// an error occured, not caching. we can try in 60 seconds
callback_for(userId, "skin", err, null);
@ -170,7 +181,7 @@ function store_images(rid, userId, details, type, callback) {
});
}
});
store_cape(rid, userId, profile, details, function(err, cape_hash) {
store_cape(rid, userId, profile, cache_details, function(err, cape_hash) {
if (err && !cape_hash) {
// an error occured, not caching. we can try in 60 seconds
callback_for(userId, "cape", (err || cache_err), cape_hash);
@ -197,7 +208,7 @@ exp.id_valid = function(userId) {
};
// decides whether to get a +type+ image for +userId+ from disk or to download it
// callback contains error, status, hash
// callback: error, status, hash
// the status gives information about how the image was received
// -1: "error"
// 0: "none" - cached as null
@ -205,32 +216,32 @@ exp.id_valid = function(userId) {
// 2: "downloaded" - profile downloaded, skin downloaded from mojang servers
// 3: "checked" - profile re-downloaded (was too old), but it has either not changed or has no skin
exp.get_image_hash = function(rid, userId, type, callback) {
cache.get_details(userId, function(err, details) {
var cached_hash = (details !== null) ? (type === "skin" ? details.skin : details.cape) : null;
cache.get_details(userId, function(err, cache_details) {
var cached_hash = (cache_details !== null) ? (type === "skin" ? cache_details.skin : cache_details.cape) : null;
if (err) {
callback(err, -1, null);
} else {
if (details && details[type] !== undefined && details.time + config.local_cache_time * 1000 >= new Date().getTime()) {
if (cache_details && cache_details[type] !== undefined && cache_details.time + config.local_cache_time * 1000 >= new Date().getTime()) {
// use cached image
logging.log(rid + "userId cached & recently updated");
callback(null, (cached_hash ? 1 : 0), cached_hash);
} else {
// download image
if (details) {
if (cache_details) {
logging.log(rid + "userId cached, but too old");
} else {
logging.log(rid + "userId not cached");
}
store_images(rid, userId, details, type, function(err, new_hash) {
store_images(rid, userId, cache_details, type, function(err, new_hash) {
if (err) {
// we might have a cached hash although an error occured
// (e.g. Mojang servers not reachable, using outdated hash)
cache.update_timestamp(rid, userId, cached_hash, true, function(err2) {
callback(err2 || err, -1, details && cached_hash);
callback(err2 || err, -1, cache_details && cached_hash);
});
} else {
var status = details && (cached_hash === new_hash) ? 3 : 2;
logging.debug(rid + "cached hash: " + (details && cached_hash));
var status = cache_details && (cached_hash === new_hash) ? 3 : 2;
logging.debug(rid + "cached hash: " + (cache_details && cached_hash));
logging.log(rid + "new hash: " + new_hash);
callback(null, status, new_hash);
}
@ -242,7 +253,7 @@ exp.get_image_hash = function(rid, userId, type, callback) {
// handles requests for +userId+ avatars with +size+
// callback contains error, status, image buffer, skin hash
// callback: error, status, image buffer, skin hash
// image is the user's face+helm when helm is true, or the face otherwise
// for status, see get_image_hash
exp.get_avatar = function(rid, userId, helm, size, callback) {
@ -271,7 +282,7 @@ exp.get_avatar = function(rid, userId, helm, size, callback) {
};
// handles requests for +userId+ skins
// callback contains error, skin hash, image buffer
// callback: error, skin hash, image buffer
exp.get_skin = function(rid, userId, callback) {
exp.get_image_hash(rid, userId, "skin", function(err, status, skin_hash) {
var skinpath = __dirname + "/../" + config.skins_dir + skin_hash + ".png";
@ -290,13 +301,16 @@ exp.get_skin = function(rid, userId, callback) {
});
};
// helper method used for file names
// possible returned names based on +helm+ and +body+ are:
// body, bodyhelm, head, headhelm
function get_type(helm, body) {
var text = body ? "body" : "head";
return helm ? text + "helm" : text;
}
// handles creations of 3D renders
// callback contains error, skin hash, image buffer
// callback: error, skin hash, image buffer
exp.get_render = function(rid, userId, scale, helm, body, callback) {
exp.get_skin(rid, userId, function(err, skin_hash, img) {
if (!skin_hash) {
@ -335,7 +349,7 @@ exp.get_render = function(rid, userId, scale, helm, body, callback) {
};
// handles requests for +userId+ capes
// callback contains error, cape hash, image buffer
// callback: error, cape hash, image buffer
exp.get_cape = function(rid, userId, callback) {
exp.get_image_hash(rid, userId, "cape", function(err, status, cape_hash) {
if (!cape_hash) {

View File

@ -3,23 +3,23 @@ var config = require("./config");
var exp = {};
function split_args(args) {
var text = "";
// returns all values in the +args+ object separated by " "
function join_args(args) {
var values = [];
for (var i = 0, l = args.length; i < l; i++) {
if (i > 0) {
text += " " + args[i];
} else {
text += args[i];
}
values.push(args[i]);
}
return text;
return values.join(" ");
}
// prints +args+ to +logger+ (defaults to `console.log`)
// the +level+ and a timestamp is prepended to each line of log
// the timestamp can be disabled in the config
function log(level, args, logger) {
logger = logger || console.log;
var time = config.log_time ? new Date().toISOString() + " " : "";
var clid = (cluster.worker && cluster.worker.id || "M");
var lines = split_args(args).split("\n");
var lines = join_args(args).split("\n");
for (var i = 0, l = lines.length; i < l; i++) {
logger(time + clid + " " + level + ": " + lines[i]);
}
@ -42,4 +42,4 @@ if (config.debug_enabled || process.env.DEBUG === "true") {
exp.debug = function(){};
}
module.exports = exp;
module.exports = exp;

View File

@ -12,36 +12,39 @@ var mojang_urls = [skins_url, capes_url];
var exp = {};
function extract_url(profile, property) {
// extracts the +type+ [SKIN|CAPE] URL
// from the nested & encoded +profile+ object
// returns the URL or null if not present
function extract_url(profile, type) {
var url = null;
if (profile && profile.properties) {
profile.properties.forEach(function(prop) {
if (prop.name === "textures") {
var json = new Buffer(prop.value, "base64").toString();
var props = JSON.parse(json);
url = props && props.textures && props.textures[property] && props.textures[property].url || null;
url = props && props.textures && props.textures[type] && props.textures[type].url || null;
}
});
}
return url;
}
// exracts the skin url of a +profile+ object
// returns null when no url found (user has no skin)
// exracts the skin URL of a +profile+ object
// returns null when no URL found (user has no skin)
exp.extract_skin_url = function(profile) {
return extract_url(profile, 'SKIN');
};
// exracts the cape url of a +profile+ object
// returns null when no url found (user has no cape)
// exracts the cape URL of a +profile+ object
// returns null when no URL found (user has no cape)
exp.extract_cape_url = function(profile) {
return extract_url(profile, 'CAPE');
};
// makes a GET request to the +url+
// +options+ hash includes these options:
// performs a GET request to the +url+
// +options+ object includes these options:
// encoding (string), default is to return a buffer
// +callback+ contains the body, response,
// callback: the body, response,
// and error buffer. get_from helper method is available
exp.get_from_options = function(rid, url, options, callback) {
request.get({
@ -55,7 +58,9 @@ exp.get_from_options = function(rid, url, options, callback) {
}, function(error, response, body) {
// log url + code + description
var code = response && response.statusCode;
if (!error) {
if (error) {
logging.error(url, error);
} else {
var logfunc = code && code < 405 ? logging.log : logging.warn;
logfunc(rid + url + " " + code + " " + http_code[code]);
}
@ -65,7 +70,6 @@ exp.get_from_options = function(rid, url, options, callback) {
// response received successfully
callback(body, response, null);
} else if (error) {
logging.error(error);
callback(body || null, response, error);
} else if (code === 404 || code === 204) {
// page does not exist
@ -115,7 +119,7 @@ exp.get_uuid_url = function(profile, type, callback) {
};
// make a request to sessionserver for +uuid+
// +callback+ contains error, profile
// callback: error, profile
exp.get_profile = function(rid, uuid, callback) {
if (!uuid) {
callback(null, null);
@ -142,6 +146,8 @@ exp.get_cape_url = function(rid, userId, profile, callback) {
});
};
// helper method that calls `get_username_url` or `get_uuid_url` based on the +usedId+
// +userId+ is used for usernames, while +profile+ is used for UUIDs
function get_url(rid, userId, profile, type, callback) {
if (userId.length <= 16) {
//username
@ -155,6 +161,9 @@ function get_url(rid, userId, profile, type, callback) {
}
}
// download the +tex_hash+ image from the texture server
// and save it in the +outpath+ file
// callback: error, response, image buffer
exp.save_texture = function(rid, tex_hash, outpath, callback) {
if (tex_hash) {
var textureurl = textures_url + tex_hash;

View File

@ -128,7 +128,7 @@ exp.draw_body = function(rid, skin_canvas, model_ctx, scale) {
// sets up the necessary components to draw the skin model
// uses the +img+ skin with options of drawing
// the +helm+ and the +body+
// callback contains error, image buffer
// callback: error, image buffer
exp.draw_model = function(rid, img, scale, helm, body, callback) {
var image = new Image();
@ -169,7 +169,7 @@ exp.draw_model = function(rid, img, scale, helm, body, callback) {
};
// helper method to open a render from +renderpath+
// callback contains error, image buffer
// callback: error, image buffer
exp.open_render = function(rid, renderpath, callback) {
fs.readFile(renderpath, function (err, buf) {
if (err) {

View File

@ -6,7 +6,7 @@ var exp = {};
// extracts the face from an image +buffer+
// result is saved to a file called +outname+
// +callback+ contains error
// callback: error
exp.extract_face = function(buffer, outname, callback) {
lwip.open(buffer, "png", function(err, image) {
if (err) {
@ -28,7 +28,7 @@ exp.extract_face = function(buffer, outname, callback) {
// extracts the helm from an image +buffer+ and lays it over a +facefile+
// +facefile+ is the filename of an image produced by extract_face
// result is saved to a file called +outname+
// +callback+ contains error
// callback: error
exp.extract_helm = function(rid, facefile, buffer, outname, callback) {
lwip.open(buffer, "png", function(err, skin_img) {
if (err) {
@ -69,7 +69,7 @@ exp.extract_helm = function(rid, facefile, buffer, outname, callback) {
};
// resizes the image file +inname+ to +size+ by +size+ pixels
// +callback+ contains error, image buffer
// callback: error, image buffer
exp.resize_img = function(inname, size, callback) {
lwip.open(inname, function(err, image) {
if (err) {
@ -105,7 +105,7 @@ exp.default_skin = function(uuid) {
};
// helper method for opening a skin file from +skinpath+
// callback contains error, image buffer
// callback: error, image buffer
exp.open_skin = function(rid, skinpath, callback) {
fs.readFile(skinpath, function(err, buf) {
if (err) {
@ -117,6 +117,8 @@ exp.open_skin = function(rid, skinpath, callback) {
});
};
// write the image +buffer+ to the +outpath+ file
// callback: error
exp.save_image = function(buffer, outpath, callback) {
lwip.open(buffer, "png", function(err, image) {
if (err) {