Browse Source

configuration refactor, add user tweaking, fix bug

pull/2/head
asiekierka 6 years ago
parent
commit
8b17dee956
9 changed files with 97 additions and 78 deletions
  1. 26
    23
      app.js
  2. 51
    30
      config-default.json
  3. 6
    6
      image.js
  4. 3
    3
      templates/header.html
  5. 3
    3
      templates/images-li.html
  6. 2
    2
      templates/images.html
  7. 4
    9
      templates/main.html
  8. 1
    1
      templates/view.html
  9. 1
    1
      userdb.js

+ 26
- 23
app.js View File

@@ -27,7 +27,7 @@ var app = express();

var defaultConfig = require('./config-default.json')
, defaultImage = { author: "Unknown", source: "/", uploader: "Computer"}
, defaultSiteConfig = { subtitle: null, title: "Website", htmlTitle: null, noAjaxLoad: false, mobile: false}
, defaultSiteConfig = { subtitle: null, mobile: false}
, templateFunctions = {
template: function(name) {
return makeRawTemplate(name,this,true);
@@ -54,6 +54,7 @@ if(!_(config).contains("htmlTitle")) {
else config.htmlTitle = config.title;
}

imageHandler.setConfig(config.images);
imageHandler.express(express,app);

// Image Adding
@@ -159,7 +160,7 @@ function finishUpload(res,fn,thfn,path,metadata, next) {
});
}
app.get("/upload", restrict, parse, function(req,res,next) {
res.send(makeTemplate("upload",{req: req, username: req.session.user, useZepto: false},req.params[0]));
res.send(makeTemplate("upload",{req: req, username: req.session.user, framework: "jQuery"}, req.params[0]));
});

// Searching
@@ -193,13 +194,13 @@ function handleSearch(req, res, query) {
if(stack.length > 1) { error(req,res,"Something quite bad happened! "+JSON.stringify(stack)); return; }
var result = stack.pop();
cacheDB.set("search:"+query,result,60,null);
listImages(req,res,result,req.query,{noAjaxLoad: true, isSearch: true, subtitle: Math.min(1000,result.length)+" results found."},1000);
listImages(req,res,result,req.query,{ajaxFetching: false, isSearch: true, subtitle: Math.min(1000,result.length)+" results found."},1000);
});
});
else { // Found cached!
console.log("Loading from cache!");
cacheDB.get("search:"+query,function(err,result) {
listImages(req,res,result,req.query,{noAjaxLoad: true, isSearch: true, subtitle: Math.min(1000,result.length)+" results found."},1000);
listImages(req,res,result,req.query,{ajaxFetching: false, isSearch: true, subtitle: Math.min(1000,result.length)+" results found."},1000);
});
}
});
@@ -280,6 +281,7 @@ function getImagesTagged(tags,next) {
}
app.get("/random*", parse, function(req,res) {
imageDB.images(function(images) {
if(images.length == 0) { error(req, res, "No images!", 404); return; }
imageDB.get(images[_.random(images.length-1)], function(randomImage) {
if(req.query["mode"] == "json") {
res.json(randomImage);
@@ -296,7 +298,7 @@ function listImages(req,res,images1,options,defConfig,maxVal) {
var images1a, data;
var maxValue = options["length"] || maxVal || config.pageSize;
if(maxValue > config.maxPageSize) maxValue = config.maxPageSize;
getImagesTagged(config.hiddenTags,function(hiddenImages) {
getImagesTagged(config.tags.hidden,function(hiddenImages) {
if(!_(req.cookies.showHidden).isUndefined() || req.query["hidden"] == true) images1a = images1;
else images1a = _.difference(images1,hiddenImages);
imageDB.range(images1a,start,maxValue,function(images2) {
@@ -304,7 +306,7 @@ function listImages(req,res,images1,options,defConfig,maxVal) {
console.log(options);
if(options["mobile"] == 'true') conf.mobile = true;
if(mode=="json") {
if(config.allowJson == false) { error(req, res, "JSON not allowed!", 403); return; }
if(config.api.json == false) { error(req, res, "JSON not allowed!", 403); return; }
res.json({position: start, length: images2.length, results: images2});
} else {
if(_(options).has("subtitle2"))
@@ -357,27 +359,26 @@ if(config.salt == defaultConfig.salt || config.salt.length < 16) {
}

console.log("Connecting to database...")
var client = redis.createClient();
var client = redis.createClient(config.database.port, config.database.host);
if(config.database.password != "")
client.auth(config.database.password);
imageDB.connect(client);
cacheDB.connect(client);
userDB.connect(client, config.salt);
imageHandler.setMode(config.optimize);

userDB.exists("admin", function(err, exists) {
if(!err && !exists) {
console.log("Creating default users...");
_.each(config.defaultUsers, function(value,key) {
console.log("[+] "+key);
userDB.addUser({user: key, pass: userDB.hash(value), nick: key, type: "admin"});
});
}
else if(err) { console.log("Error checking userDB! " + err.message); }
console.log("(Re)Creating users...");
_.each(config.users, function(value,key) {
console.log("[+] "+key);
var user = {user: key, nick: key, type: "admin"};
if(_.isString(value)) user.pass = userDB.hash(value);
else { user.pass = userDB.hash(value.pass); user.nick = value.nick || user.nick; user.type = value.type || user.type; }
userDB.addUser(user, function() {});
});

function start() {
imageDB.updateDatabase(function() {
app.listen(config.port);
console.log("Working on port " + config.port);
app.listen(config.server.port);
console.log("Working on port " + config.server.port);
});
}

@@ -421,7 +422,9 @@ if(argv.t || argv.thumb) {
});
}

process.on("uncaughtException", function(err) {
console.log("Uncaught exception! Please report to author");
console.log(err);
});
if(!(argv.d || argv.debug)) {
process.on("uncaughtException", function(err) {
console.log("Uncaught exception! Please report to author");
console.log(err);
});
}

+ 51
- 30
config-default.json View File

@@ -1,34 +1,55 @@
{ "port": 8080, "pageSize": 15, "maxPageSize": 500, "title": "Booru", "htmlTitle": "Booru",
"noAjaxURL": false,
"allowJson": true,
"useLazyLoad": true,
"socialButtons": true,
"showClouds": true,
"showRandom": true,
{
"server": {
"port": 8080
},
"database": {
"host": "localhost",
"port": 6379,
"password": ""
},
"salt": "",
"defaultUsers": {
"admin": "admin"
"pageSize": 15,
"maxPageSize": 500,
"title": "New Booru",
"htmlTitle": "New Booru",
"users": {
"admin": {"pass": "admin", "nick": "admin", "type": "admin" }
},
"api": {
"json": true
},
"frameworks": {
"zeptoJS": "/static/js/zepto.min.js",
"jQuery": "/static/js/jquery-1.9.1.min.js"
},
"framework": "jQuery",
"ajaxFetching": true,
"lazyLoading": true,
"ui": {
"socialButtons": true,
"showClouds": true,
"showRandom": true
},
"images": {
"optimizationEngines": [
{"name": "pngout", "format": "png", "notes": "Likely the best option for PNG",
"enabled": false,
"path": "/usr/bin/pngout '$FILE'"},
{"name": "pngcrush", "format": "png",
"enabled": false,
"path": "/usr/bin/pngcrush '$FILE' '$FILE'"},
{"name": "jpegrescan", "format": "jpg", "notes": "Just install Perl and File::Slurp",
"enabled": false,
"path": "tools/jpegrescan '$FILE' '$FILE'"},
{"name": "gifsicle", "format": "gif",
"enabled": false,
"path": "/usr/bin/gifsicle --careful '$FILE' -o '$FILE'"}
],
"optimizationThreads": 1,
"optimize": "all"
},
"optimizationEngines": [
{"name": "pngout", "format": "png", "notes": "Likely the best option for PNG",
"enabled": false,
"path": "/usr/bin/pngout '$FILE'"},
{"name": "pngcrush", "format": "png",
"enabled": false,
"path": "/usr/bin/pngcrush '$FILE' '$FILE'"},
{"name": "jpegrescan", "format": "jpg", "notes": "Just install Perl and File::Slurp",
"enabled": false,
"path": "tools/jpegrescan '$FILE' '$FILE'"},
{"name": "gifsicle", "format": "gif",
"enabled": false,
"path": "/usr/bin/gifsicle --careful '$FILE' -o '$FILE'"}
],
"optimizationThreads": 1,
"optimize": "all",
"spoilerTags": ["spoiler"],
"hiddenTags": ["hidden"],
"useZepto": false,
"style": {
"bgcolor": "#fff"
"tags": {
"spoiler": ["spoiler"],
"hidden": ["hidden"]
}
}

+ 6
- 6
image.js View File

@@ -2,15 +2,15 @@ var _ = require('underscore')
, fs = require('fs')
, mkdirp = require('mkdirp')
, im = require('imagemagick')
, config = require('./config.json')
, child = require('child_process')
, async = require('async')
, util = require('./util.js');

var thumbW = 300, thumbH = 300;

var optimizeMode = "all";
exports.setMode = function(mode) { optimizeMode = mode; }
var config = {};

exports.setConfig = function(c) { config = c; }

exports.resize = function(src,dest,w,h,cb,grav) {
var cnf = { srcPath: src, dstPath: dest,
@@ -35,7 +35,7 @@ var optqueue = async.queue(function (task, callback) {
}, config.optimizationThreads || 1);

exports.optimize = function(path,data) {
if(optimizeMode == "none" || !fs.existsSync(path)) return;
if(config.optimize == "none" || !fs.existsSync(path)) return;
var oldfilesize = util.filesize(path);
var format = (data.format || util.fileExt(path)).toLowerCase();
if(format=="jpeg") format="jpg";
@@ -56,7 +56,7 @@ exports.handle = function(src,destName,w1,h1,grav,options) {
if(_.isString(dest2x) && (w>thumbW || h>thumbH))
self.resize(src,dest2x,thumbW*2,thumbH*2,function(err) {
if(err) throw err;
if(optimizeMode == "all" || optimizeMode == "thumbs" || optimizeMode == "thumbnails") {
if(config.optimize == "all" || config.optimize == "thumbnails") {
self.optimize(dest,{format: util.fileExt(src)});
self.optimize(dest2x,{format: util.fileExt(src)});
}
@@ -66,7 +66,7 @@ exports.handle = function(src,destName,w1,h1,grav,options) {
else if(_.isFunction(options.callback)) options.callback();
};
this.resize(src,dest,thumbW,thumbH,t2,grav);
if(options.optimizeSrc && optimizeMode == "all" && _(src).startsWith("./img")) self.optimize(src,{format: util.fileExt(src)});
if(options.optimizeSrc && config.optimize == "all" && _(src).startsWith("./img")) self.optimize(src,{format: util.fileExt(src)});
}

// Create missing directories (just in case)

+ 3
- 3
templates/header.html View File

@@ -3,11 +3,11 @@
<a class="normal" href="/"><h1><% if(_.isString(htmlTitle)) { print(htmlTitle); } else { print(title); } %></h1></a>
<% if(_.isString(subtitle)){ print('<h4>'+subtitle+'</h4>'); } %>
<%
if(showClouds) {
if(ui.showClouds) {
print('<a href="/cloud/tag">All tags</a> | <a href="/cloud/author">All authors</a>');
if(showRandom) { print(' | '); }
if(ui.showRandom) { print(' | '); }
}
if(showRandom) {
if(ui.showRandom) {
print('<a href="/random"><b>Random</b></a>');
}
if(req) {

+ 3
- 3
templates/images-li.html View File

@@ -1,16 +1,16 @@
<% _.each(images, function(img) {
if(img == null) return;
print('<li class="span4"><a href="/image/'+img.id+'/" class="thumbnail thumbnail-300">');
var imgloc = _.some(spoilerTags,function(val) {
var imgloc = _.some(tags.spoiler,function(val) {
if(_(img.tags).contains(val)) return true;
})?'/static/img/spoiler.png':'/img/thumb/'+img.filename;
var imgtitle = img.name;
if(useLazyLoad) {
if(lazyLoading) {
print('<img class="lazy to-scriptize" src="/static/img/white.png" data-original="'+imgloc+'"');
print(' title="'+imgtitle+'"><noscript>');
}
print('<img src="'+imgloc+'" class="to-scriptize" title="'+imgtitle+'">');
if(useLazyLoad) {
if(lazyLoading) {
print('</noscript>');
}
print('</a></li>');

+ 2
- 2
templates/images.html View File

@@ -25,7 +25,7 @@
<script type="text/javascript">
function scriptize() {
<%
if(useLazyLoad) {
if(lazyLoading) {
print("$('img.lazy').show().lazyload();");
}
%>
@@ -50,7 +50,7 @@ function pageLoad() {
var maxpos = <%= maxpos %>;
var pageSize = <%= pageSize %>;
var isUpdating = false;
var noAjaxLoad = <%= noAjaxLoad %>;
var noAjaxLoad = <%= !ajaxFetching %>;
var update = function() {
if(isUpdating || noAjaxLoad) return;
if(position+pageSize < maxpos && $(window).scrollTop() >= ($(document).height() - $(window).height() - 300)) {

+ 4
- 9
templates/main.html View File

@@ -11,18 +11,13 @@ a.social:hover { opacity: 0.7; }
.thumbnail { background-color: #FFF; }
.thumbnail-300 { width: 300px; height: 300px !important; }
h1 { color: #222; }
<% if(useLazyLoad) {
print(".lazy { display: none; }");
} %>
.lazy { display: none; }
<%= skin.css %>
</style>
</head>
<body>
<script src="<%
if(useZepto) print("/static/js/zepto.min.js");
else print("/static/js/jquery-1.9.1.min.js");
%>"></script>
<% if(useLazyLoad) {
<script src="<%= frameworks[framework] %>"></script>
<% if(lazyLoading) {
print('<script src="/static/js/jquery.lazyload.min.js"></script>');
} %>
<script src="/static/js/bootstrap.min.js"></script>
@@ -30,7 +25,7 @@ h1 { color: #222; }
<div class="container" id="page-inject"><%= page %></div>
<script>
function fixURLs() {
<% if(noAjaxURL) { print('return;'); } %>
<% if(!ajaxFetching) { print('return;'); } %>
$("a").each(function(idx) {
if(!$(this).hasClass("no-ajax"))
$(this).click(changeView);

+ 1
- 1
templates/view.html View File

@@ -15,7 +15,7 @@ Tags: <%
Author: <a href="/author/<%= image.author %>/"><%= image.author %></a> (<a class="no-ajax" href="<%= image.source %>">Source</a>)<br>
Uploaded by <a href="/uploader/<%= image.uploader %>/"><%= image.uploader %></a>
<% if(req.session.user) print('[<a href="/edit/'+image.id+'/">edit</a>]'); %>
<% if(socialButtons)
<% if(ui.socialButtons)
print("<br><br>"+template("social-buttons"));
%>
</div>

+ 1
- 1
userdb.js View File

@@ -30,7 +30,7 @@ UserDB.addUser = function(data,callback) {
else if(data.pass == null) callback(new Error("Invalid password!"));
else this.exists(data.user, function(err, does) {
if(err) callback(err);
else if(does) callback(new Error("User exists!"));
//else if(does) callback(new Error("User exists!")); * We overwrite users for now. HACK! TODO!
else async.series([
_.bind(client.set,client,"user:"+data.user,JSON.stringify(data)),
_.bind(client.sadd,client,"users",data.user)

Loading…
Cancel
Save