// ==UserScript==
// @name Danbooru-Image-Adder
// @namespace http://tampermonkey.net/
// @version 0.5
// @description Add images to posts
// @author ECHibiki /qa/
// @match http://boards.4chan.org/*
// @match https://boards.4chan.org/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
var numberOfPosts;
var pageNo;
var JSONPage;
var JSONTag;
var pagesLoaded = 0;
var smallestTag;
var loopPage = 0;
var loopOne = false;
var setPostAndPage = function(){
numberOfPosts = Math.floor(Math.random() * 100 % 20);
console.log("Post No: " + numberOfPosts);
pageNo = Math.floor(Math.random() * 100 % ((smallestTag / 20) / 2));
console.log("Page No: " + pageNo);
loopPage = pageNo;
};
var enhance4ChanX = function(){
if(document.getElementById("qrImages") !== null) qrWindow.removeChild(document.getElementById("qrImages"));
document.getElementById("dump-button").click();
var qrWindow = document.getElementById("qr");
var qrTable = document.createElement("TABLE");
qrTable.setAttribute("id", "qrImages");
qrTable.setAttribute("style", "text-align:center");
qrWindow.appendChild(qrTable);
qrWindow.appendChild(document.createElement("BR"));
var instructionRow = document.createElement("TR");
var topRowNodes = [document.createElement("BR"),
document.createTextNode("Insert Tags to search from danbooru bellow."),
document.createElement("BR"),
document.createTextNode("PLEASE PUT order:__ TAGS ON THE FIRST SLOT."),
document.createElement("BR"),
document.createTextNode("PUT rating:s IF YOU DON'T WANT NSFW IMAGES"),
];
topRowNodes.forEach(
function(node){
instructionRow.appendChild(node);
});
qrTable.appendChild(instructionRow);
var tagRow = document.createElement("TR");
var secondRowNodes = [
document.createTextNode("Tags: "),
document.createElement("INPUT"),
document.createElement("INPUT"),
];
secondRowNodes.forEach(
function(node){
tagRow.appendChild(node);
});
qrTable.appendChild(tagRow);
var breakRow = document.createElement("TR");
breakRow.setAttribute("style", "margin:0px;");
//var line = document.createTextNode("t\n");
// breakRow.appendChild(line);
qrTable.appendChild(breakRow);
var autoCompleteRow = document.createElement("TR");
autoCompleteRow.setAttribute("ID", "acr");
autoCompleteRow.setAttribute("style", "margin:5px;");
qrTable.appendChild(autoCompleteRow);
secondRowNodes[1].setAttribute("ID", "tags");
var oldVal = "";
var tags = "";
var tagNode = document.getElementById("tags");
var rightMost;
var leftMost;
setInterval(
function(){
tags = tagNode.value;
if(oldVal !== tags){
console.log("change observed");
var cursorPos = tagNode.selectionStart - 1;
var currentTag = (function(){
var currentChar = tags.charAt(cursorPos);
var i = 0;
rightMost = cursorPos;
while(currentChar != " " && currentChar != "" && currentChar !== undefined){
i++;
currentChar = tags.charAt(cursorPos + i);
if(currentChar != " " && currentChar != "") rightMost = cursorPos + i;
console.log(" cC: " + currentChar + " cP: " + cursorPos + " t: " + tags + " i: " + i);
}
rightMost += 1;
console.log("RIGHT: " + rightMost);
currentChar = tags.charAt(cursorPos);
i = 0;
leftMost = cursorPos;
while(currentChar != " " && currentChar != "" && currentChar !== undefined){
i++;
currentChar = tags.charAt(cursorPos - i);
if(currentChar != " " && currentChar != "") leftMost = cursorPos - i;
console.log(" cC: " + currentChar + " cP: " + cursorPos + " t: " + tags + " i: " + i);
}
console.log("LEFT: " + leftMost);
return tags.substring(leftMost, rightMost);
})();
console.log(currentTag);
console.log("https://danbooru.donmai.us/tags.json?search[name_matches]=" + currentTag + "*&search[order]=count");
var xhr = new GM_xmlhttpRequest(({
method: "GET",
url: "https://danbooru.donmai.us/tags.json?search[name_matches]=" + currentTag + "*&search[order]=count",
responseType : "json",
onload: function(data){
data = data.response;
var tagArray = tags.split(" ");
while (autoCompleteRow.hasChildNodes()) {
autoCompleteRow.removeChild(autoCompleteRow.lastChild);
}
for (var i = 0 ; i < 5 ; i++){
console.log(data["" + i]);
var a = document.createElement("A");
a.setAttribute("style", "padding:5px;padding-top:0px;font-size:15px;font-weight:bold;border:1px solid black;");
var tagText = data["" + i]["name"];
if(tagText == "") break;
var aTxt = document.createTextNode(data[i]["name"]);
autoCompleteRow.appendChild(a);
a.appendChild(aTxt);
a.addEventListener("click", function(evt){
console.log(tagArray);
tagArray[tagArray.indexOf(currentTag)] = this.textContent;
console.log(tagArray);
console.log(this.textContent);
secondRowNodes[1].value = tagArray.join(" ");
console.log(secondRowNodes[1].textContent);
});
}
}}));
}
oldVal = tagNode.value;
},
1);
secondRowNodes[2].setAttribute("ID", "imageButton");
secondRowNodes[2].setAttribute("type", "button");
secondRowNodes[2].setAttribute("value", "Set Image");
secondRowNodes[2].addEventListener("click", function(){
console.log("exce");
var tags = document.getElementById("tags").value;
console.log("tags: " + tags);
tags = tags.split(" ");
var xhr = new GM_xmlhttpRequest(({
method: "GET",
url: "https://danbooru.donmai.us/tags.json?search[name]=" + tags.join() + "&search[order]=count",
responseType : "json",
onload: function(data)
{
data = data.response;
JSONTag = data;
console.log(data);
if(data.length == 0){
alert("All tags incorrect");
return;
}
//tag size
smallestTag = parseInt(data[data.length-1]["post_count"]);
if(data.length == 0){
alert("Tag " + data[data.length-1]["name"] + "too small");
return;
}
setPostAndPage();
loopOne = false;
//GET AND SAVE JSON OF GIVEN PAGE USING TAG NUMBER 1 AND 2 TO
makeRequest(tags, JSONTag);
//SCAN PAGE FOR TAGS GOING UPWARDS
//IF PAST POST 20 SAVE THE NEXT PAGE
//IF A MATCH CHECK FILESIZE
//IF LESS THAN 4MB USE FULL ELSE USE SAMPLE SIZE
}}));
}
);
};
var numberOfItterations;
var timeout = 0;
var setImageFromDanbooru = function(err, data, tags){
if (err != null) {
console.log('Something went wrong: ' + err);
alert("Danbooru Server Did Not Perform request -- Error: " + err);
pageNo = 1;
numberOfPosts = 0;
}
else {
if(data == ""){
console.log("MISS");
smallestTag /= 2;
setPostAndPage();
makeRequest(tags, JSONTag);
return;
}
JSONPage = data;
if(JSONPage.length < 20){
numberOfPosts = Math.floor(Math.random() * 100 % JSONPage.length);
if(pageNo == 0)
console.log("SMALL RESULTS: Image number " + numberOfPosts + " out of " + JSONPage.length);
}
while(JSONPage["" + numberOfPosts] !== undefined){
var endURL = JSONPage["" + numberOfPosts].file_url;
var URL = "https://danbooru.donmai.us" + endURL;
console.log("URL: " + URL);
console.log("PageNo: " +pageNo);
console.log("PostNo: " +numberOfPosts);
var fail = false;
if(endURL === undefined ||
endURL.indexOf(".mp4") > -1 || endURL.indexOf(".webm") > -1 || endURL.indexOf(".swf") > -1 || endURL.indexOf(".zip") > -1){
numberOfPosts++;
console.log("Condition: 1");
if(numberOfPosts == 20){
numberOfPosts = 0;
pageNo++;
pagesLoaded++;
if(pagesLoaded > 20) return;
makeRequest(tags, JSONTag);
return;
}
continue;
}
else{
console.log("Condition: 2");
tags.forEach(function(tag){
if(tag.indexOf("order:") > -1);
else if(tag.indexOf("rating:") > -1){
console.log(tag.charAt(7));
if(tag.charAt(7) !== JSONPage["" + numberOfPosts]["rating"]){
fail = true;
return;
}
}
else if(JSONPage["" + numberOfPosts]["tag_string"].indexOf(tag) == -1){
fail = true;
return;
}
});
}
if(fail){
console.log("Condition: 3");
numberOfPosts++;
if(numberOfPosts == 20){
numberOfPosts = 0;
pageNo++;
var now = Date.now();
if(!loopOne){
timeout = Date.now();
loopOne = true;
}
if (pageNo > (smallestTag / 20) / 2){
pageNo = 0;
}
else if(loopPage == pageNo){
alert("Failed to find " + tags);
loopOne = false;
return;
}
else if(Date.now() > timeout + 5000){
alert("Timeout on " + tags);
loopOne = false;
return;
}
makeRequest(tags, JSONTag);
return;
}
continue;
}
else{
if(JSONPage["" + numberOfPosts].file_size >= 4000000){
var endURL = JSONPage["" + numberOfPosts].large_file_url;
var URL = "https://danbooru.donmai.us" + endURL;
console.log("URL: " + URL);
console.log("PageNo: " +pageNo);
console.log("PostNo: " +numberOfPosts);
console.log("Condition: 4");
}
var xhr = new GM_xmlhttpRequest(({
method: "GET",
url: URL,
responseType : "arraybuffer",
onload: function(response)
{
var blob;
if(endURL.indexOf(".jpg") > -1)
blob = new Blob([response.response], {type:"image/jpeg"});
else if(endURL.indexOf(".png") > -1)
blob = new Blob([response.response], {type:"image/png"});
else if(endURL.indexOf(".gif") > -1)
blob = new Blob([response.response], {type:"image/gif"});
var name = endURL.replace(/(data|cached)/g, "");
name = name.replace(/\//g, "");
console.log("----------------");
console.log("Blob: " + blob);
console.log("MIME: " + blob.type);
console.log("Name: " + name);
//SEND RESULTING RESPONSE TO 4CHANX FILES === QRSetFile
var detail = {file:blob, name:name};
if (typeof cloneInto === 'function') {
detail = cloneInto(detail , document.defaultView);
}
console.log("Detail: " +detail);
document.getElementById("dump-list").firstChild.click();
document.dispatchEvent(new CustomEvent('QRSetFile', {bubbles:true, detail}));
//document.getElementById("url-button").click();
numberOfPosts++;
if(numberOfPosts == 20){
numberOfPosts = 0;
pageNo++;
}
}
}));
//break condition
return;
}
}
}
};
var getJSON = function(url, callback, extra) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status == 200) {
callback(null, xhr.response, extra);
} else {
callback(status);
}
};
xhr.send();
};
window.onload = function(){
console.log(document.links);
var len = document.links.length;
for(var i = 0 ; i < len ; i++){
document.links[i].addEventListener("click", enhance4ChanX);
}
document.getElementById("fourchanx-css").textContent += ".qr-preview { height: 250px; width: 250px; background-size: auto;}";
};
function makeRequest(tags, data){
console.log("PageNo: " + pageNo + " PostNo: " + numberOfPosts + "\nhttps://danbooru.donmai.us/posts.json?page=" + pageNo + "&utf8=%E2%9C%93&tags=" + tags[0] + "+" + data[data.length-1]["name"]);
getJSON("https://danbooru.donmai.us/posts.json?page=" + pageNo + "&utf8=%E2%9C%93&tags=" + tags[0] + "+" + data[data.length-1]["name"], setImageFromDanbooru, tags);
}
/*
I(CREATING THE POSTS)
1) DO JSON SEARCH FOR TAGS:
search[name]=TAG1,TAG2...TAGn &&&&&& search[order]=count
2) PICK THE SMALLEST ONE AND DIVIDE BY 20 SUBTRACT 1(LAST PAGE MAY HAVE EMPTY SLOTS)
3) GENERATE A RANDOM NUMBER BETWEEN 0 AND FINAL_PAGE-1
4) ITTERATE THROUGH POSTS WITH TAGS UNTIL:
A) IT TIMESOUT
B) IT GOES FROM START TO END AND NOT FOUND
5) DO A 4CHANX CreateNotification*** (TODO)
II(AUTO COMPLETE)
1) ON FIELD CHANGE READ THE CURSOR LEFT AND DO A search[name_matches]=n* & search[order]=count
2) PHONE STYLED AUTO COMPLETE
3) CLICK ON THE GIVEN ITEM TO ADD
4) GETS PLACED IN THE GIVEN FIELD
III(CHECKBOXES)
1) CHECKS FOR RATINGS
2) DROPDOWN FOR ORDER
3)*** (TODO)
*/