Browse Source

added danbooru2 api emulation; PLEASE REGENERATE

pull/2/head
asiekierka 6 years ago
parent
commit
3812c30a07
4 changed files with 177 additions and 30 deletions
  1. 53
    29
      app.js
  2. 2
    0
      config-default.json
  3. 10
    1
      imagedb.js
  4. 112
    0
      module-danbooru.js

+ 53
- 29
app.js View File

@@ -44,6 +44,7 @@ function error(req,res,text,codeO) {
}

function parse(req,res,next) { if(req.params[0]) req.params = req.params[0].split("/"); else req.params = [""]; next(); }
function logConnection(req, res, next) { console.log(req.path); next(); }

// Configure
var config = fs.existsSync("./config.json") ? require('./config.json') : defaultConfig;
@@ -172,6 +173,14 @@ function handleQuery(entry,images,allImages) {
return images;
}
function handleSearch(req, res, query) {
getSearchTable(req, query, function(table) {
getImageTable(req,table,req.query,function(images) {
var mlen = Math.min(config.maxSearchLength,images.length);
listImages(req,res,images,req.query,mlen,{ajaxFetching: false, isSearch: true, subtitle: mlen+" results found."});
}, config.maxSearchLength);
});
}
function getSearchTable(req, query, callback) {
var stack = [];
cacheDB.exists("search:"+query,function(err,exists) {
if(!exists)
@@ -195,13 +204,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,{ajaxFetching: false, isSearch: true, subtitle: Math.min(1000,result.length)+" results found."},1000);
callback(result);
});
});
else { // Found cached!
console.log("Loading from cache!");
cacheDB.get("search:"+query,function(err,result) {
listImages(req,res,result,req.query,{ajaxFetching: false, isSearch: true, subtitle: Math.min(1000,result.length)+" results found."},1000);
callback(result);
});
}
});
@@ -292,10 +301,8 @@ app.get("/random*", parse, function(req,res) {
});

// Image listing
function listImages(req,res,images1,options,defConfig,maxVal) {
function getImageTable(req,images1,options,callback,maxVal) {
var start = parseInt(options["start"]) || 0;
var mode = options["mode"] || "";
var noHeader = false;
var images1a, data;
var maxValue = options["length"] || maxVal || config.pageSize;
if(maxValue > config.maxPageSize) maxValue = config.maxPageSize;
@@ -303,32 +310,43 @@ function listImages(req,res,images1,options,defConfig,maxVal) {
if(!_(req.cookies.showHidden).isUndefined() || req.query["hidden"] == true) images1a = images1;
else images1a = _.difference(images1,hiddenImages);
imageDB.range(images1a,start,maxValue,function(images2) {
var conf = _.defaults({images: images2, position: start, maxpos: images1.length, req: req}, defConfig || {isSearch: false});
console.log(options);
if(options["mobile"] == 'true') conf.mobile = true;
if(mode=="json") {
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"))
conf.subtitle = _.capitalize(options["subtitle1"])+": "+options["subtitle2"];
else if(!_.isString(conf.subtitle)) { // Create custom subtitle
if(start > 0 && (start % config.pageSize) == 0) { // page 2+
conf.subtitle = "Page " + ((start / config.pageSize)+1);
} else { // page 1
conf.subtitle = "Now with " + conf.maxpos + " images!";
}
}
var imagesLi = makeRawTemplate("images-li",conf,"raw",true);
conf.imagesLi = imagesLi;
if(mode == "append") data = conf.imagesLi;
else data = makeTemplate("images",conf,mode,noHeader);
res.send(data);
}
callback(images2);
});
});
}

function listImages(req,res,images2,options,imageAmount,defConfig) {
var mode = options["mode"] || "";
var noHeader = false;
var conf = _.defaults({images: images2, position: start, maxpos: imageAmount, req: req}, defConfig || {"isSearch": false});
console.log(options);
if(options["mobile"] == 'true') conf.mobile = true;
if(mode=="json") {
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"))
conf.subtitle = _.capitalize(options["subtitle1"])+": "+options["subtitle2"];
else if(!_.isString(conf.subtitle)) { // Create custom subtitle
if(start > 0 && (start % config.pageSize) == 0) { // page 2+
conf.subtitle = "Page " + ((start / config.pageSize)+1);
} else { // page 1
conf.subtitle = "Now with " + conf.maxpos + " images!";
}
}
var imagesLi = makeRawTemplate("images-li",conf,"raw",true);
conf.imagesLi = imagesLi;
if(mode == "append") data = conf.imagesLi;
else data = makeTemplate("images",conf,mode,noHeader);
res.send(data);
}
}

// Load Danbooru API emulation
if(config.api.danbooru) {
eval(fs.readFileSync('module-danbooru.js', 'utf-8'));
}

app.get("/cloud/*", parse, function(req,res) {
if(req.params.length < 1 || !imageDB.isCloudTag(req.params[0])) { error(req,res,"No tag found!",404); return; }
imageDB.getCloud(req.params[0], function(cloudData) {
@@ -342,9 +360,15 @@ app.get("/*", function(req,res) {
var p = qs.unescape(req.path).split("/");
console.log("Request: " + JSON.stringify(p));
if(p.length>0 && (p[1] == "tag" || p[1] == "author" || p[1] == "uploader")) imageDB.imagesBy(p[1],p[2],function(images) {
listImages(req,res,images,_(req.query).extend({"subtitle1": p[1], "subtitle2": p[2]}));
getImageTable(req,images,req.query,function(images2) {
listImages(req,res,images2,_(req.query).extend({"subtitle1": p[1], "subtitle2": p[2]}), images.length);
});
});
else imageDB.images(function(images) {
getImageTable(req,images,req.query,function(images2) {
listImages(req,res,images2,req.query,images.length);
});
});
else imageDB.images(function(images) { listImages(req,res,images,req.query); });
});

// Personal boost.io code

+ 2
- 0
config-default.json View File

@@ -11,12 +11,14 @@
"salt": "",
"pageSize": 15,
"maxPageSize": 500,
"maxSearchLength": 500,
"title": "New Booru",
"htmlTitle": "New Booru",
"users": {
"admin": {"pass": "admin", "nick": "admin", "type": "admin" }
},
"api": {
"danbooru": true,
"json": true
},
"frameworks": {

+ 10
- 1
imagedb.js View File

@@ -33,7 +33,7 @@ ImageDB.updateDatabase = function(callback) {
client.set(prefix+"db_version", 2, _.bind(self.updateDatabase, self));
});
}
else if(version == CURRENT_VERSION) { self.log("Latest DB version, nothing to do..."); if(_.isFunction(callback)) callback(); }
if(version == CURRENT_VERSION) { self.log("Latest DB version, nothing to do..."); if(_.isFunction(callback)) callback(false); return; }
});
}

@@ -204,6 +204,7 @@ ImageDB.setSearchData = function(id, data, callback) {
_.bind(self.setTags,self,id,data.tags),
_.bind(self.addField,self,id,"author",data.author),
_.bind(self.addField,self,id,"uploader",data.uploader),
_.bind(client.hset,client,"hashToImage",data.hash,data.id),
_.bind(self.addSize,self,id,"width",data.width),
_.bind(self.addSize,self,id,"height",data.height)
], callback);
@@ -216,10 +217,18 @@ ImageDB.unsetSearchData = function(id, data, callback) {
function(cb) { cb(); },
_.bind(self.delField,self,id,"author",data.author),
_.bind(self.delField,self,id,"uploader",data.uploader),
_.bind(client.hdel,client,"hashToImage",data.hash),
_.bind(self.delSize,self,id,"width"),
_.bind(self.delSize,self,id,"height")
], callback);
}
ImageDB.getByHash = function(hash, callback) {
var self = this;
client.hget("hashToImage", hash, function(err, results){
if(err) callback(err, null);
else self.getWithError(results, callback);
});
}

ImageDB.regenerate = function(id, callback) {
var self = this;

+ 112
- 0
module-danbooru.js View File

@@ -0,0 +1,112 @@
// Danbooru API emulation
// fits inside app.js

function toDanbooruFormat(item) {
var isQuestionable = ( _.intersection(item.tags, config.tags.spoiler).length > 0)
, isExplicit = ( _.intersection(item.tags, config.tags.hidden).length > 0);

return{"approver_id": null,
"created_at": "1970-01-01T00:00:00+00:00",
"down_score": 0,
"fav_count": 0,
"fav_string": "",
"file_ext": item.format,
"file_size": util.filesize("./img/src/"+item.filename), // TODO: Index this!
"has_children": false,
"id": item.id,
"image_height": item.height,
"image_width": item.width,
"is_banned": false,
"is_deleted": false,
"is_flagged": false,
"is_note_locked": false,
"is_pending": false,
"is_rating_locked": isQuestionable || isExplicit,
"is_status_locked": false,
"last_commented_at": null,
"last_noted_at": null,
"md5": item.hash,
"parent_id": null,
"pixiv_id": 0,
"pool_string":"",
"rating": (isExplicit ? "e" : (isQuestionable ? "q" : "s")),
"score": 0,
"source": item.source,
"tag_count": item.tags.length,
"tag_count_artist": ((_.isString(item.author) && item.author != "") ? 1 : 0),
"tag_count_character": 0,
"tag_count_copyright": 0,
"tag_count_general": item.tags.length,
"tag_string": item.tags.join(" "),
"up_score": 0,
"updated_at": "1970-01-01T00:00:00+00:00",
"uploader_id": 1, // TODO: Make a real uploader ID!
"uploader_name": item.uploader,
"has_large": false,
"tag_string_artist": item.author,
"tag_string_character": "",
"tag_string_copyright": "",
"tag_string_general": item.tags.join(" "),
"file_url": "/img/src/"+item.filename,
"large_file_url": "/img/src/"+item.filename,
"preview_file_url": "/img/thumb/"+item.filename
};
}

// Effing Anime boxes on iPad...
app.get("/data/*", parse, function(req,res) {
if(req.params[0].indexOf(".") > 0) {
var md5 = req.params[0].split(".")[0];
imageDB.getByHash(md5, function(err, image) {
if(image != null) {
res.redirect("/img/src/"+image.filename);
} else res.send(404, "Not found!");
});
} else res.send(404, "Not found!");
});
app.get("/ssd/data/preview/*", parse, function(req,res) {
if(req.params[0].indexOf(".") > 0) {
var md5 = req.params[0].split(".")[0];
imageDB.getByHash(md5, function(err, image) {
if(image != null) {
res.redirect("/img/thumb/"+image.filename);
} else res.send(404, "Not found!");
});
} else res.send(404, "Not found!");
});

function sendDanbooruTable(req, res, images, options) {
getImageTable(req,images,options,function(images2) {
async.map(images2, function(item, callback) {
callback(null, toDanbooruFormat(item));
}, function(err, results) {
res.json(results);
});
});
}
app.get("/posts.json", function(req,res) {
imageDB.images(function(images) {
var onePageSize = (_.isNumber(req.query["limit"]) ? Math.min(config.maxPageSize,req.query["limit"]) : config.pageSize);
var pageNumber = (req.query["page"] || 1)-1;
var options = {
"length": onePageSize,
"start": pageNumber*onePageSize
};
var tags = [];
if(_.isString(req.query["tags"]) && req.query["tags"] != "*" && req.query["tags"] != "") {
var oldTags = req.query["tags"].split(" ");
_.each(oldTags, function(tag) {
if(tag != "" && !(_.startsWith(tag,"rating"))) {
tags.push(tag);
}
});
}
if(tags.length > 0) {
var query = queryParser.parse(tags.join(" "));
if(options["start"] > 0) res.json([])
else getSearchTable(req, query, function(result) {
sendDanbooruTable(req, res, result, {"start": 0, "length": result.length});
});
} else sendDanbooruTable(req, res, images, options);
});
});

Loading…
Cancel
Save