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 c2b7050..c7dd323 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);
diff --git a/views/index.jade b/views/index.jade
index 5cf2440..7b33bfb 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,65 @@ 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.
+ | 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.
+ | 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 +150,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 +170,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")