version change
[4Free-FSE.git] / Thread-Rebuilder.user.js
blob9f09da2bf3f8e45e752db3429fbf2ba7a5407555
1 // ==UserScript==
2 // @name         Thread Rebuilder
3 // @namespace    http://tampermonkey.net/
4 // @version      0.3
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 imgURL = "";
20 //1) CREATE INTERFACE
22 var enhance4ChanX = function(){
24     if(document.getElementById("qrRebuilder") !== null) qrWindow.removeChild(document.getElementById("qrImages"));
25     document.getElementById("dump-button").click();
26     
27     console.log(document.getElementById("qr").getElementsByTagName("TEXTAREA")[0]);
28     var dList = document.getElementById("dump-list");
29     var filenamecontainer = document.getElementById("qr-filename-container");
30     var BGImg = "";
31     var oldBGImg = "";
33     /*
34     var observer = new MutationObserver(function(mutate){
35         BGImg = dList.firstChild.style.backgroundImage;
36         if(BGImg !== oldBGImg && imgURL !== ""){
37             console.log("CHANGED");
38             dList.firstChild.style.backgroundImage = "url(" + imgURL + ")";
39             console.log("CHANGED");
40             oldBGImg = dList.firstChild.style.backgroundImage;
41             console.log("CHANGED");
42             console.log(imgURL);
43         }
44         else if (imgURL == ""){
46         }
47     });
48     observer.observe(dList , {attributes: true,subtree:true, childList: true, characterData: true });*/
50     document.getElementById("qr-filerm").addEventListener("click", function(){imgURL = "";});
54     var qrWindow = document.getElementById("qr");
56     var qrTable = document.createElement("TABLE");
57     qrTable.setAttribute("id", "qrRebuilder");
58     qrTable.setAttribute("style", "text-align:center");
59     qrWindow.appendChild(qrTable);
60     qrWindow.appendChild(document.createElement("BR"));
62     var instructionRow = document.createElement("TR");        
63     var topRowNodes = [document.createElement("BR"),
64                        document.createTextNode("Insert the thread number of the post to rebuild"),
65                        document.createElement("BR"),
66                        document.createTextNode("Must be in the 4chan archives"),
67                        document.createElement("BR"),
68                       ];
69     topRowNodes.forEach(
70         function(node){
71             instructionRow.appendChild(node);
72         });
73     qrTable.appendChild(instructionRow);
75     var threadRow = document.createElement("TR");
76     var secondRowNodes = [
77         document.createTextNode("Thread: "),
78         document.createElement("INPUT"),
79         document.createElement("INPUT"),
80     ];
81     secondRowNodes.forEach(
82         function(node){
83             threadRow.appendChild(node);
84         });
85     qrTable.appendChild(threadRow);
86     
87     secondRowNodes[1].setAttribute("ID", "threadInput");
88     secondRowNodes[1].setAttribute("style", "width:44.9%");
89     
90     secondRowNodes[2].setAttribute("ID", "threadButton");
91     secondRowNodes[2].setAttribute("type", "button");
92     secondRowNodes[2].setAttribute("value", "Set Rebuild Queue");
93     secondRowNodes[2].addEventListener("click", function(){
94         console.log("exce");
95         getThread(secondRowNodes[1].value);
96         //wait until done
97         postID = setInterval(postRoutine, 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();
113     }
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++;
128     }
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) alert("Invalid Thread ID: " + threadNo + ".\n4chan Archive Only");
150             else{
151                 var len = data["posts"].length;
152                 for(var i = 1 ; i < len ; i++){
153                     var comment = data["posts"][i]["com"];
154                     if(comment !== undefined)
155                         threadData[0].push(comment);
156                     else 
157                         threadData[0].push(-1);
158                     
159                     var filename = "" + data["posts"][i]["tim"] + data["posts"][i]["ext"];
160                     if(filename !== undefined && filename.indexOf("undefined") == -1)
161                        threadData[1].push("https://i.4cdn.org/" + board + "/" + filename);
162                     else  threadData[1].push(-1);
163                     
164                     threadData[2].push(data["posts"][i]["filename"]);
165                     
166                     threadData[3].push(data["posts"][i]["no"]);
167                 }
168             }
169             console.log(threadData);
170             semaphore--;
171         }
172     }));
175 //3) RIP POSTS AND IMAGES
176 var createPost = function(text, imageURL, imageName){
177     console.log("url: " + imageURL);
178     if(imageURL != -1){
179         var xhr = new GM_xmlhttpRequest(({
180             method: "GET", 
181             url: imageURL, 
182             responseType : "arraybuffer",
183             onload: function(response)
184             {            
185                 var blob;
186                 var ext = ".jpg";
187                 if(imageURL.indexOf(".jpg") > -1){
188                     blob = new Blob([response.response], {type:"image/jpeg"});
189                     ext = ".jpg";
190                 }
191                 else if(imageURL.indexOf(".png") > -1){
192                     blob = new Blob([response.response], {type:"image/png"});
193                     ext = ".png";
194                 }
195                 else if(imageURL.indexOf(".gif") > -1){
196                     blob = new Blob([response.response], {type:"image/gif"});
197                     ext = ".gif";
198                 }
199                 else if(imageURL.indexOf(".webm") > -1){
200                     blob = new Blob([response.response], {type:"video/webm"});
201                     ext = ".webm";
202                 }
204                 var name = imageName + ext;
206                 console.log("----------------");
207                 console.log("Blob: "); console.log(blob);
208                 console.log("MIME: " + blob.type);
209                 console.log("Name: " + name);
211                 //SEND RESULTING RESPONSE TO 4CHANX FILES === QRSetFile
212                 var detail = {file:blob, name:name};
213                 if (typeof cloneInto === 'function') {
214                     detail  = cloneInto(detail , document.defaultView);
215                 }
216                 console.log("Detail: ");console.log(detail);
217                 document.dispatchEvent(new CustomEvent('QRSetFile', {bubbles:true, detail}));
219                 if(text !== "" && text !== undefined && text !== -1) createPostComment(text);
220                 
221                 document.getElementById("add-post").click();
222                 semaphore_posts++;
223             }
224         }));
225     }
226     else{
227         createPostComment(text);
228         document.getElementById("add-post").click();
229         semaphore_posts++;
230     }
233 //4) CREATE POST QUEUE
234 var createPostComment = function(text){
235     console.log("text-Before: " + text);
236     
237     text = text.replace(/<a href="\/[a-zA-Z]+\/" class="quotelink">&gt;&gt;&gt;/g, ">>>");
238     text = text.replace(/<a href="#p[0-9]+" class="quotelink">&gt;&gt;/g, ">>");
239     text = text.replace(/<span class="quote">&gt;/g, ">");
240     text = text.replace(/<br>/g, "\n");
241     text = text.replace(/&#039;/g, "'");
242     text = text.replace(/<\/a>/g, "");
243     text = text.replace(/<wbr>/g, "");
244     text = text.replace(/<\/span>/g, "");
245     
246     console.log("text-After: " + text);
247     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, '')*/;
248     else document.getElementById("qr").getElementsByTagName("TEXTAREA")[0].value = text;
252 window.onload = function(){
253     console.log(document.links);
254     var len = document.links.length;
255     for(var i = 0 ; i < len ; i++){
256         document.links[i].addEventListener("click", enhance4ChanX);
257     }
259     //ENHANCE DUMP TABS (COVER, 482PX - 482PX)
260     //DUMP LIST MAX-HEIGHT TO 490
262     document.getElementById("fourchanx-css").textContent += ".qr-preview { height: 482px; width: 482px; background-size: cover;}";
263     //document.getElementById("fourchanx-css").textContent += "#qr { min-width:490px;}";
264     document.getElementById("fourchanx-css").textContent += "#dump-list { min-height: 400px; width: 509px;}";