Bottom link bug
[4Free-FSE.git] / Thread-Rebuilder.user.js
blobfe91591864b60d3eec4bc61da0367dc4258b3aba
1 // ==UserScript==
2 // @name Thread Rebuilder
3 // @namespace http://tampermonkey.net/
4 // @version 0.3.2
5 // @description try to take over the world!
6 // @author You
7 // @match https://boards.4chan.org/*/thread/*
8 // @match http://boards.4chan.org/*/thread/*
9 // @grant GM_xmlhttpRequest
10 // @updateURL https://github.com/ECHibiki/4chan-UserScripts/raw/master/Thread-Rebuilder.user.js
11 // @downloadURL https://github.com/ECHibiki/4chan-UserScripts/raw/master/Thread-Rebuilder.user.js
12 // ==/UserScript==
14 var board = "qa";
15 var threadData = [['Comment'], ['Image URLs'], ['Image Names'] ,['Post No.']];
16 var semaphore = 1;
17 var semaphore_posts = 1;
18 var timeListen;
20 //1) CREATE INTERFACE
22 var enhance4ChanX = function(){
24 var qrWindow = document.getElementById("qr");
26 if(document.getElementById("qrRebuilder") !== null) qrWindow.removeChild(document.getElementById("qrRebuilder"));
27 //document.getElementById("dump-button").click();
29 //console.log(document.getElementById("qr").getElementsByTagName("TEXTAREA")[0]);
30 var dList = document.getElementById("dump-list");
31 var filenamecontainer = document.getElementById("qr-filename-container");
32 var BGImg = "";
33 var oldBGImg = "";
36 var observer = new MutationObserver(function(mutate){
37 BGImg = dList.firstChild.style.backgroundImage;
38 if(BGImg !== oldBGImg && imgURL !== ""){
39 console.log("CHANGED");
40 dList.firstChild.style.backgroundImage = "url(" + imgURL + ")";
41 console.log("CHANGED");
42 oldBGImg = dList.firstChild.style.backgroundImage;
43 console.log("CHANGED");
44 console.log(imgURL);
46 else if (imgURL == ""){
49 });
50 observer.observe(dList , {attributes: true,subtree:true, childList: true, characterData: true });*/
52 if(document.getElementById("qr-filerm") !== null)
53 document.getElementById("qr-filerm").addEventListener("click", function(){imgURL = "";});
54 else return;
56 var qrTable = document.createElement("TABLE");
57 qrTable.setAttribute("id", "qrRebuilder");
58 qrTable.setAttribute("style", "text-align:center");
59 qrWindow.appendChild(qrTable);
61 var instructionRow = document.createElement("TR");
62 var topRowNodes = [document.createElement("BR"),
63 document.createTextNode("Insert the thread number of the post to rebuild"),
64 document.createElement("BR"),
65 document.createTextNode("Must be in the 4chan archives"),
66 document.createElement("BR"),
68 topRowNodes.forEach(
69 function(node){
70 instructionRow.appendChild(node);
71 });
72 qrTable.appendChild(instructionRow);
74 var threadRow = document.createElement("TR");
75 var secondRowNodes = [
76 document.createTextNode("Thread: "),
77 document.createElement("INPUT"),
78 document.createElement("INPUT"),
80 secondRowNodes.forEach(
81 function(node){
82 threadRow.appendChild(node);
83 });
84 qrTable.appendChild(threadRow);
86 secondRowNodes[1].setAttribute("ID", "threadInput");
87 secondRowNodes[1].setAttribute("style", "width:44.9%");
89 secondRowNodes[2].setAttribute("ID", "threadButton");
90 secondRowNodes[2].setAttribute("type", "button");
91 secondRowNodes[2].setAttribute("value", "Set Rebuild Queue");
92 secondRowNodes[2].addEventListener("click", function(){
93 //console.log("exce");
94 getThread(secondRowNodes[1].value);
95 //wait until done
96 postID = setInterval(postRoutine, 1000);
97 if(timeListen === undefined) timeListen = setInterval(timeListenerFunction, 1000);
98 });
102 var len = 0;
103 var i = 0;
105 var postID = "";
106 var postRoutine = function(){
107 if(semaphore == 0){
108 semaphore--;
109 len = threadData[0].length;
110 //console.log(len);
111 fillID = setInterval(fillRoutine, 10);
112 stopRoutine();
115 var stopRoutine = function(){
116 //console.log("Post Ends");
117 clearInterval(postID);
120 var fillID = "";
121 var fillRoutine = function(){
122 //console.log(semaphore_posts + " " + i);
123 if(i >= len) {semaphore_posts = 0 ; stopFillRoutine();}
124 else if(semaphore_posts == 1){
125 semaphore_posts--;
126 createPost(threadData[0][i], threadData[1][i], threadData[2][i]);
127 i++;
131 var stopFillRoutine = function(){
132 //console.log("Fill Ends");
133 clearInterval(fillID);
136 //2) GET ARCHIVED THREAD
137 var getThread = function(threadNo){
138 threadData = [[], [], [], []];
140 URL = "https://a.4cdn.org/" + board + "/thread/" + threadNo + ".json";
141 //console.log(URL);
142 var xhr = new GM_xmlhttpRequest(({
143 method: "GET",
144 url: URL,
145 responseType : "json",
146 onload: function(data){
147 data = data.response;
148 //console.log(data);
149 if(data == undefined){
150 alert("Invalid Thread ID: " + threadNo + ".\n4chan Archive ");
151 //draw from desu instead
153 else{
154 var len = data["posts"].length;
155 for(var i = 1 ; i < len ; i++){
156 var comment = data["posts"][i]["com"];
157 if(comment !== undefined)
158 threadData[0].push(comment);
159 else
160 threadData[0].push(-1);
162 var filename = "" + data["posts"][i]["tim"] + data["posts"][i]["ext"];
163 if(filename !== undefined && filename.indexOf("undefined") == -1)
164 threadData[1].push("https://i.4cdn.org/" + board + "/" + filename);
165 else threadData[1].push(-1);
167 threadData[2].push(data["posts"][i]["filename"]);
169 threadData[3].push(data["posts"][i]["no"]);
172 //console.log(threadData);
173 semaphore--;
175 }));
178 //3) RIP POSTS AND IMAGES
179 var createPost = function(text, imageURL, imageName){
180 //console.log("url: " + imageURL);
181 if(imageURL != -1){
182 var xhr = new GM_xmlhttpRequest(({
183 method: "GET",
184 url: imageURL,
185 responseType : "arraybuffer",
186 onload: function(response)
188 var blob;
189 var ext = ".jpg";
190 if(imageURL.indexOf(".jpg") > -1){
191 blob = new Blob([response.response], {type:"image/jpeg"});
192 ext = ".jpg";
194 else if(imageURL.indexOf(".png") > -1){
195 blob = new Blob([response.response], {type:"image/png"});
196 ext = ".png";
198 else if(imageURL.indexOf(".gif") > -1){
199 blob = new Blob([response.response], {type:"image/gif"});
200 ext = ".gif";
202 else if(imageURL.indexOf(".webm") > -1){
203 blob = new Blob([response.response], {type:"video/webm"});
204 ext = ".webm";
207 var name = imageName + ext;
209 //console.log("----------------");
210 //console.log("Blob: "); //console.log(blob);
211 //console.log("MIME: " + blob.type);
212 //console.log("Name: " + name);
214 //SEND RESULTING RESPONSE TO 4CHANX FILES === QRSetFile
215 var detail = {file:blob, name:name};
216 if (typeof cloneInto === 'function') {
217 detail = cloneInto(detail , document.defaultView);
219 //console.log("Detail: ");//console.log(detail);
220 document.dispatchEvent(new CustomEvent('QRSetFile', {bubbles:true, detail}));
222 if(text !== "" && text !== undefined && text !== -1) createPostComment(text);
224 document.getElementById("add-post").click();
225 semaphore_posts++;
227 }));
229 else{
230 createPostComment(text);
231 document.getElementById("add-post").click();
232 semaphore_posts++;
236 //4) CREATE POST QUEUE
237 var createPostComment = function(text){
238 //console.log("text-Before: " + text);
240 text = text.replace(/<a href="\/[a-zA-Z]+\/" class="quotelink">&gt;&gt;&gt;/g, ">>>");
242 var quote_regex = /<a href="#p[0-9]+" class="quotelink">&gt;&gt;[0-9]+/g;
243 var find = text.match(quote_regex);
244 if(find){
245 find.forEach(function(match){
246 //console.log("---==");
247 var index_start = text.indexOf(match);
248 var match_len = match.length;
249 var index_len = index_start + match_len;
250 var first_quote = match.indexOf('"');
251 var second_quote = match.indexOf('"', first_quote + 1);
252 var post_no = match.substring(first_quote + 3, second_quote);
254 match = ">>" + post_no;
256 text = text.substr(0, index_start) + match + text.substr(index_len);
260 text = text.replace(/<span class="quote">&gt;/g, ">");
261 text = text.replace(/<br>/g, "\n");
262 text = text.replace(/&#039;/g, "'");
263 text = text.replace(/<\/a>/g, "");
264 text = text.replace(/<wbr>/g, "");
265 text = text.replace(/<\/span>/g, "");
267 //console.log("text-After: " + text);
268 //if(text.match(/^>>[0-9]+$/g)) document.getElementById("qr").getElementsByTagName("TEXTAREA")[0].value = text + "\n" + Math.floor(Math.random() * 1000).toString(62)/*.replace(/[^a-z]+/g, '')*/;
269 //else
270 document.getElementById("qr").getElementsByTagName("TEXTAREA")[0].value = text;
273 var checked = false;
274 var timeListenerFunction = function(){
276 var time = document.getElementById("qr-filename-container").nextSibling.value.replace(/[a-zA-Z]+/g, "");
277 if(time <= 5){
278 checked = false;
279 console.log(time + "A");
281 else if(time > 5){
282 checked = true;
283 console.log(time + "B");
288 window.onload = function(){
289 //console.log(document.links);
290 var len = document.links.length;
291 for(var i = 0 ; i < len ; i++){
292 document.links[i].addEventListener("click", enhance4ChanX);
295 //ENHANCE DUMP TABS (COVER, 482PX - 482PX)
296 //DUMP LIST MAX-HEIGHT TO 490
298 document.getElementById("fourchanx-css").textContent += ".qr-preview { height: 482px; width: 482px; background-size: cover;}";
299 //document.getElementById("fourchanx-css").textContent += "#qr { min-width:490px;}";
300 document.getElementById("fourchanx-css").textContent += "#dump-list { min-height: 400px; width: 509px;}";