Update README.md
[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 = "";
35                 /*
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);
45                         }
46                         else if (imgURL == ""){
48                         }
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"),
67                                                   ];
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"),
79                 ];
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                 });
100         };
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();
113                 }
114         };
115         var stopRoutine = function(){
116                 //console.log("Post Ends");
117                 clearInterval(postID);
118         };
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++;
128                 }
129         };
131         var stopFillRoutine = function(){
132                 //console.log("Fill Ends");
133                 clearInterval(fillID);
134         };
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
152                                 }
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"]);
170                                         }
171                                 }
172                                 //console.log(threadData);
173                                 semaphore--;
174                         }
175                 }));
177         };
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)
187                                 {
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";
193                                         }
194                                         else if(imageURL.indexOf(".png") > -1){
195                                                 blob = new Blob([response.response], {type:"image/png"});
196                                                 ext = ".png";
197                                         }
198                                         else if(imageURL.indexOf(".gif") > -1){
199                                                 blob = new Blob([response.response], {type:"image/gif"});
200                                                 ext = ".gif";
201                                         }
202                                         else if(imageURL.indexOf(".webm") > -1){
203                                                 blob = new Blob([response.response], {type:"video/webm"});
204                                                 ext = ".webm";
205                                         }
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);
218                                         }
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++;
226                                 }
227                         }));
228                 }
229                 else{
230                         createPostComment(text);
231                         document.getElementById("add-post").click();
232                         semaphore_posts++;
233                 }
234         };
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);
257                         });
258                 }
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;
271         };
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");
280                 }
281                 else if(time > 5){
282                         checked = true;
283                         console.log(time + "B");
284                 }
285         };
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);
293                 }
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;}";
302         };