From 31fe0a40f9bb64cb3d70a8d24c9083f55ec17657 Mon Sep 17 00:00:00 2001 From: jomo Date: Mon, 29 Dec 2014 21:06:30 +0100 Subject: [PATCH 1/3] clean up homepage --- views/index.jade | 77 +++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/views/index.jade b/views/index.jade index 5cf2440..3e03bd8 100644 --- a/views/index.jade +++ b/views/index.jade @@ -27,18 +27,14 @@ block content mark.green id | - a(id="parameters", class="anchor") - a(href="#parameters") - h3 Parameters - a(id="size", class="anchor") - a(href="#size") - h4 size + a(id="avatar-parameters", class="anchor") + a(href="#avatar-parameters") + h3 Avatar Parameters + h4 size p | The size of the image in pixels, #{config.min_size} - #{config.max_size}.
| Default is #{config.default_size}. - a(id="default", class="anchor") - a(href="#default") - h4 default + h4 default p | The image to be served when the id has no skin (404).
| Valid options are @@ -46,60 +42,64 @@ block content | , a(href="/avatars/00000000000000000000000000000000?default=alex") alex | , or a custom URL.
- | The standard value is calculated based on the id (even = alex, odd = steve) - a(id="helm", class="anchor") - a(href="#helm") - h4 helm + | The standard value is calculated based on the UUID (even = alex, odd = steve). Usernames always default to steve. + h4 helm p - | Get an avatar with the "second" (hat) layer applied.
- | The content of this parameter can be anything.
+ | Apply the "second" (hat) layer to the avatar.
+ | The content of this parameter is ignored.
| If you want to get the face only, remove the parameter. a(id="skins", class="anchor") a(href="#skins") h3 Skins p - | You can also get the full skin file from name or id.
+ | You can also get the full skin file of a player.
| Replace mark.green id - | with a Mojang UUID or username to get the related skin. - | The user's skin will be returned, or the default image is served.
+ | with a Mojang UUID or username to get the related skin.
+ | The user's skin is returned, or the default image is served.
| You can use the default parameter here as well. .code | #{domain}/skins/ mark.green id + a(id="skin-parameters", class="anchor") + a(href="#skin-parameters") + h3 Skin Parameters + h4 default + p + | Same as the default for avatars. + a(id="renders", class="anchor") - a(href="renders") + a(href="#renders") h3 3D Renders p - | Crafatar also provides support for 3D renders of Minecraft skins. - | Replace - mark.green id - | with a Mojang UUID or username to get an render for the skin. + | Crafatar also provides support for 3D renders of Minecraft skins.
+ | Replace + mark.green id + | with a Mojang UUID or username to get a render of the skin. + | The head render type returns a render of the skin's head. .code | #{domain}/renders/head/ mark.green id + | The body render returns a render of the entire skin. .code | #{domain}/renders/body/ mark.green id - | The default parameter can also be used here. Using alex or steve will create a - | render with the same parameters. A custom image will not be rendered. A UUID or username - | without a skin, will produce a render based on the input id, or the default parameter. - | Using the helm parameter is also allowed, which will be overlayed onto the head. - | The head render type will return only a render of the skin's head, while the - | body render will return a render of the entire skin. - a(id="#render-parameters", class="#render-anchor") + a(id="render-parameters", class="anchor") a(href="#render-parameters") h3 Render Parameters - a(id="scale", class="anchor") - a(href="#scale") - h4 scale + h4 scale p | The scale factor of the image #{config.min_scale} - #{config.max_scale}.
| Default is #{config.default_scale}. The actual size differs between the type of render. - + h4 helm + p + | Same as the helm for avatars, but it does not stand out (as it does ingame). + h4 default + p + | Same as the default for avatars. a(id="http-headers", class="anchor") a(href="#http-headers") @@ -149,9 +149,12 @@ block content | Images are cached in your browser for #{config.browser_cache_time/60} minutes until a new request to Crafatar is made.
| When you changed your skin you can try clearing your browser cache to see the change faster. + a(id="examples", class="anchor") a(href="#examples") h3 Examples + + h4 Avatars p Jeb's avatar by username, default size .code #{domain}/avatars/jeb_ p Jeb's avatar by UUID, default size @@ -166,14 +169,20 @@ block content | Jeb's avatar, or fall back to a(href="https://i.imgur.com/ozszMZV.png") a custom image .code #{domain}/avatars/853c80ef3c3749fdaa49938b674adae6?default=https%3A%2F%2Fi.imgur.com%2FozszMZV.png + + h4 Skins p Jeb's skin .code #{domain}/skins/853c80ef3c3749fdaa49938b674adae6 p Jeb's skin by username .code #{domain}/skins/jeb_ p Render of Jeb's Head + + h4 Renders .code #{domain}/renders/head/853c80ef3c3749fdaa49938b674adae6 p Render of Jeb's Body, with helmet, by username .code #{domain}/renders/body/jeb_?helm + + .col-md-2.center .sideface.redstone_sheep(title="redstone_sheep") .sideface.Jake0oo0(title="Jake0oo0") From 73ba73b5359beda453f7f8b6d9fe7e96d77c0963 Mon Sep 17 00:00:00 2001 From: jomo Date: Mon, 29 Dec 2014 21:17:52 +0100 Subject: [PATCH 2/3] add note about renders / beta --- views/index.jade | 1 + 1 file changed, 1 insertion(+) diff --git a/views/index.jade b/views/index.jade index 3e03bd8..7b33bfb 100644 --- a/views/index.jade +++ b/views/index.jade @@ -75,6 +75,7 @@ block content h3 3D Renders p | Crafatar also provides support for 3D renders of Minecraft skins.
+ | Please note that this feature is currently beta!
| Replace mark.green id | with a Mojang UUID or username to get a render of the skin. From c80eefd99292d5053d6a5ab44a1659b6b6e9a049 Mon Sep 17 00:00:00 2001 From: jomo Date: Mon, 29 Dec 2014 23:54:33 +0100 Subject: [PATCH 3/3] flush redis before max memory is reached; hotfix for #49 --- modules/cache.js | 12 ++++++ modules/{clean_images.js => cleaner.js} | 52 ++++++++++++++++++++----- modules/config.example.js | 3 +- server.js | 2 +- 4 files changed, 58 insertions(+), 11 deletions(-) rename modules/{clean_images.js => cleaner.js} (50%) diff --git a/modules/cache.js b/modules/cache.js index 885c078..be4665d 100644 --- a/modules/cache.js +++ b/modules/cache.js @@ -51,10 +51,22 @@ function update_file_date(hash) { var exp = {}; +// returns the redis instance exp.get_redis = function() { return redis; }; + +// updates the redis instance's server_info object +// callback contains error, info object +exp.info = function(callback) { + redis.info(function (err, res) { + // parse the info command and store it in redis.server_info + redis.on_info_cmd(err, res); + callback(err, redis.server_info); + }); +}; + // sets the timestamp for +uuid+ and its face file's date to now exp.update_timestamp = function(uuid, hash) { logging.log(uuid + " cache: updating timestamp"); diff --git a/modules/clean_images.js b/modules/cleaner.js similarity index 50% rename from modules/clean_images.js rename to modules/cleaner.js index 1c8e3c2..c1839df 100644 --- a/modules/clean_images.js +++ b/modules/cleaner.js @@ -1,13 +1,35 @@ var logging = require("./logging"); var config = require("./config"); +var cache = require("./cache"); var df = require("node-df"); var fs = require("fs"); +var redis = cache.get_redis(); var exp = {}; +// compares redis' used_memory with cleaning_redis_limit +// callback contains error, true|false +function should_clean_redis(callback) { + cache.info(function(err, info) { + if (err) { + callback(err, false); + } else { + try { + logging.debug(info); + logging.debug("used mem:" + info.used_memory); + var used = parseInt(info.used_memory) / 1024; + logging.log("RedisCleaner: " + used + "KB used"); + callback(err, used >= config.cleaning_redis_limit); + } catch(e) { + callback(e, false); + } + } + }); +} + // uses `df` to get the available fisk space // callback contains error, true|false -function should_clean(callback) { +function should_clean_disk(callback) { df({ file: __dirname + "/../" + config.faces_dir, prefixMultiplier: 'KiB', @@ -18,21 +40,33 @@ function should_clean(callback) { callback(err, false); } else { var available = response[0].available; - console.log("ImageCleaner: " + available + "KB available"); - callback(err, available < config.cleaning_limit); + logging.log("DiskCleaner: " + available + "KB available"); + callback(err, available < config.cleaning_disk_limit); } }); } -// check if disk limit reached -// then delete images +// check if redis limit reached, then flush redis +// check if disk limit reached, then delete images exp.run = function() { - should_clean(function(err, clean) { + should_clean_redis(function(err, clean) { if (err) { - logging.error("Failed to run ImageCleaner"); + logging.error("Failed to run RedisCleaner"); logging.error(err); } else if (clean) { - logging.warn("ImageCleaner: Disk limit reached! Cleaning images now"); + logging.warn("RedisCleaner: Redis limit reached! flushing now"); + redis.flushall(); + } else { + logging.log("RedisCleaner: Nothing to clean"); + } + }); + + should_clean_disk(function(err, clean) { + if (err) { + logging.error("Failed to run DiskCleaner"); + logging.error(err); + } else if (clean) { + logging.warn("DiskCleaner: Disk limit reached! Cleaning images now"); var facesdir = __dirname + "/../" + config.faces_dir; var helmdir = __dirname + "/../" + config.helms_dir; var renderdir = __dirname + "/../" + config.renders_dir; @@ -54,7 +88,7 @@ exp.run = function() { } } } else { - logging.log("ImageCleaner: Nothing to clean"); + logging.log("DiskCleaner: Nothing to clean"); } }); }; diff --git a/modules/config.example.js b/modules/config.example.js index 53c1576..8aded4c 100644 --- a/modules/config.example.js +++ b/modules/config.example.js @@ -5,7 +5,8 @@ var config = { local_cache_time: 1200, // seconds until we will check if the image changed. should be > 60 to prevent mojang 429 response browser_cache_time: 3600, // seconds until browser will request image again cleaning_interval: 1800, // seconds interval: deleting images if disk size at limit - cleaning_limit: 10240, // minumum required available KB on disk to trigger cleaning + cleaning_disk_limit: 10240, // min allowed available KB on disk to trigger cleaning + cleaning_redis_limit: 24576, // max allowed used KB on redis to trigger redis flush cleaning_amount: 50000, // amount of avatar (and their helm) files to clean http_timeout: 1000, // ms until connection to mojang is dropped faces_dir: 'skins/faces/', // directory where faces are kept. should have trailing '/' diff --git a/server.js b/server.js index 531200a..d501c5b 100644 --- a/server.js +++ b/server.js @@ -1,7 +1,7 @@ #!/usr/bin/env node var config = require("./modules/config"); var debug = require("debug")("crafatar"); -var clean = require("./modules/clean_images"); +var clean = require("./modules/cleaner"); var app = require("./app"); app.set("port", process.env.PORT || 3000);