removeddit/static/thread.js

387 lines
12 KiB
JavaScript
Raw Normal View History

"use strict";
var app = (function(){
return {
loadPage: function() {
// Just fucking crach if the user is retarded
if(_.isUndefined(Reddit.threadID) || _.isUndefined(Reddit.subreddit)) {
Status.error("Missing necessary parts of the URL");
return;
}
Status.loading("Loading thread...");
Reddit.fetchToken()
.then(function(){
return Promise.all([
fetch(URLs.thread, Reddit.init)
.then(Fetch2.json)
.then(ThreadHTML.createThread),
fetch(URLs.pushshiftIDs)
.then(Fetch2.json)
.then(_.property("data"))
])
})
.then(function(results) {
var thread = results[0];
Comments.allIDs = results[1];
Status.loading("Loading comments from reddit...");
HandleIDs.normal(thread);
console.log("After normal", Comments.ids.length);
return HandleIDs.morechildren();
})
.then(function(){
console.log("After morechildren", Comments.ids.length);
return Promise.all(_.map(_.uniq(Comments.countinuethread), function(id) {
return fetch(URLs.thread+"/_/"+id.split("_")[1], Reddit.init)
.then(Fetch2.json)
}));
}).then(function(smallerThreads){
_.forEach(smallerThreads, function(thread){
HandleIDs.normal(thread);
})
console.log("After continueThisThread", Comments.ids.length);
console.log("Total", Comments.ids.length);
console.log("Unique", _.uniq(Comments.ids).length);
Status.loading("Getting removed comments...");
HandleIDs.removed();
console.log("Removed", Comments.removed.length);
ThreadHTML.createCommentInfo(Comments.removed.length);
return Fetch2.multiple(URLs.format(URLs.pushshiftComments, Comments.removed), null, "data");
})
.then(function(removedComments){
Status.loading("Generating comments...");
return Comments.generate(removedComments);
})
.then(function(){
Status.success();
});
}
}})()
// ------------------------------------------------------------------------------
// ----------------------- Store and genrates comments --------------------------
// ------------------------------------------------------------------------------
var Comments = (function() {
var totalComments;
var lookup = {};
var toBeCreated = [];
var getParentComments = function(toLookup){
var newCommentsToLookup = [];
var commentsToFetch = [];
_.forEach(toLookup, function(id){
var parentID = lookup[id].parent_id.split("_")[1];
if(parentID === Reddit.threadID) {} // Has no parent (is parent of thread)
else if(_.includes(Comments.toBeCreated, parentID)) {} // Parent already exists, do nothing
else if(_.includes(newCommentsToLookup, parentID)) {} // Parent already exists (this iteration)
else if(_.has(lookup, parentID)) {
newCommentsToLookup.push(parentID);
} else{
commentsToFetch.push(parentID);
}
Comments.toBeCreated.push(id);
});
return new Promise(function(resolve, reject){
if(_.uniq(commentsToFetch).length !== 0) {
fetch(URLs.singleComments + _.join(_.map(_.uniq(commentsToFetch),function(comments){
return "t1_" + comments;
})), Reddit.init)
.then(Fetch2.json)
.then(function(json){
_.forEach(json.data.children, function(comment) {
lookup[comment.data.id] = comment.data;
newCommentsToLookup.push(comment.data.id);
});
})
.then(function(){
resolve();
});
} else {
resolve();
}
})
.then(function(){
if(newCommentsToLookup.length !== 0) {
return getParentComments(newCommentsToLookup)
}
});
};
return {
ids: [], // The comments we found
morechildren: [],
countinuethread: [],
allIDs: [], // All the comments that we were suppose to find
removed: [],
deleted: [],
toBeCreated: toBeCreated,
lookup: lookup,
getTotalComments: function() { return totalComments; },
setTotalComments: function(total) { totalComments = total; },
getRoot: function() {
2017-11-01 23:27:27 +00:00
if(Reddit.permalink !== undefined && Reddit.permalink === "") {
return Reddit.threadID;
}
if(Reddit.permalink === undefined) {
return Reddit.threadID;
}
if(_.has(Comments.lookup, Reddit.permalink)) {
return Comments.lookup[Reddit.permalink].parent_id.split("_")[1];
}
return "";
},
generate: function(removedComments) {
removedComments.forEach(function(comment){
if(_.includes(Comments.deleted, comment.id)) {
comment["deleted"] = true;
} else {
comment["removed"] = true;
}
Comments.lookup[comment.id] = comment;
});
Comments.removed = _.map(removedComments, function(comment){
return comment.id;
});
return getParentComments(Comments.removed)
.then(function(){
//console.log("Removed length", Comments.removed.length)
//console.log("ToBeCreated", Comments.toBeCreated);
ThreadHTML.createCommentSection();
ThreadHTML.createComments();
})
}
}})()
// ------------------------------------------------------------------------------
// ----------------- Handle comments from different requests --------------------
// ------------------------------------------------------------------------------
var HandleIDs = (function(){
var normal = function(thread){
return _.flatten(_.map(thread[1].data.children, Extract.normal))
};
var morechildren = function(){
return Promise.all(_.map(_.uniq(Comments.morechildren), function(idArray){
return Fetch2.multiple(URLs.format(URLs.moreChildren, idArray), Reddit.init);
}))
.then(function(responseArrays){
Comments.morechildren.length = 0;
_.forEach(responseArrays, function(responseArray){
_.forEach(responseArray, function(response){
_.forEach(response.jquery[10][3][0], function(comment){
Extract.normal(comment);
})
});
});
}).then(function(){
if(Comments.morechildren.length !== 0) {
return morechildren();
}
});
};
var removed = function(){
Comments.removed = _.difference(Comments.allIDs, Comments.ids);
Comments.ids.forEach(function(id){
if(! _.has(Comments.lookup, id)) {
return;
}
if(Comments.lookup[id].body === "[removed]") {
Comments.removed.push(id);
} else if (Comments.lookup[id].body === "[deleted]"){
Comments.removed.push(id);
Comments.deleted.push(id);
}
});
Comments.removed = _.uniq(Comments.removed);
};
return {
normal: normal,
morechildren: morechildren,
removed: removed
};
})()
// ------------------------------------------------------------------------------
// ----------------------- Extract ID from comments -----------------------------
// ------------------------------------------------------------------------------
var Extract = (function(){
var normal = function(comment){
var data = comment.data;
if(comment.kind == "more") { // "Show more"-comment
if(data.id === "_") { // = "continue this thread" comment
Comments.countinuethread.push(data.parent_id);
} else if(data.children.length < data.count){ // "Load more"-comment (that is missing some of its children)
Comments.morechildren.push(data.children);
}
Comments.ids.push.apply(Comments.ids, data.children);
} else { // Normal comment
if(data.replies) {
data.replies.data.children.forEach(function(child){
normal(child);
});
delete data.replies;
}
Comments.ids.push(data.id);
Comments.lookup[data.id] = data;
}
};
return {
normal: normal
};
})()
// ------------------------------------------------------------------------------
// ---------------------------- Generating HTML ---------------------------------
// ------------------------------------------------------------------------------
var ThreadHTML = (function(){
var mainDiv = document.getElementById("main");
// I actually haven't found a better way of doing this...
// Imgur has image-links with no indication that they are actually images
var imageHosts = ["i.redd.it", "flickr.com", "i.imgur.com", "imgur.com", "m.imgur.com"];
var createThread = function(data) {
var thread = data[0].data.children[0].data;
Comments.setTotalComments(thread.num_comments);
document.title = thread.title+" : "+thread.subreddit;
var threadDiv = document.createElement("div");
threadDiv.innerHTML = ' \
<div id="thread"> \
<div id="thread-score-box"> \
<div class="vote upvote"></div> \
<div id="thread-score">'+Format.prettyScore(thread.score)+'</div> \
<div class="vote downvote"></div> \
</div> \
<div id="thumbnail"></div> \
<div id="thread-content"> \
'+(thread.link_flair_text !== null ? '<span class="link-flair">'+thread.link_flair_text+'</span>' : '') +
'<a id="thread-title" href="'+thread.url+'">'+thread.title+'</a> \
<span id="domain">('+thread.domain+')</span> \
<div id="thread-info"> \
submitted <span id="thread-time">'+Format.prettyDate(thread.created_utc)+'</span> by \
<a id="thread-author" class="user-link" href="https://www.reddit.com/user/'+thread.author+'">'+thread.author+'</a> to \
<a id="subreddit-link" class="user-link" href="https://reddit.com/r/'+thread.subreddit+'">/r/'+thread.subreddit+'</a> \
</div>' +
(thread.selftext !== '' ? '<div id="thread-selftext" class="user-text">'+Format.parse(thread.selftext)+'</div>':'') +
'<div id="total-comments"><a class="grey-link" href="https://www.reddit.com'+thread.permalink+'"><b>'+thread.num_comments+' comments</b></a></div>' +
(thread.media !== null ? HTML.parse(thread.media_embed.content) : '') +
(_.includes(imageHosts, thread.domain) && _.has(thread, "preview") ? '<a href="'+thread.url+'"><img id="thread-image" src="'+thread.preview.images[0].source.url+'"></a>' : '') +
'</div> \
</div> \
';
mainDiv.appendChild(threadDiv);
return data;
};
var createCommentInfo = function(totalRemovedComments){
var div = document.createElement("div");
div.innerHTML = ' \
<div id="comment-info"> \
removed comments: '+totalRemovedComments+'/'+Comments.getTotalComments()+' ('+(100 * totalRemovedComments / Comments.getTotalComments()).toFixed(1)+'%) \
</div> \
<div id="comment-sort">sorted by: top</div> \
';
mainDiv.appendChild(div);
};
var createCommentSection = function(){
var div = document.createElement("div");
div.id = Comments.getRoot();
mainDiv.appendChild(div);
};
var createComments = function(){
var commentsToCreate = _.sortBy(_.uniq(Comments.toBeCreated), function(id) {
return Comments.lookup[id].score;
});
2017-11-01 23:27:27 +00:00
var createdComments = [Comments.getRoot()];
var didSomething = false;
while(commentsToCreate.length > 0) {
didSomething = false;
for(var i = commentsToCreate.length - 1; i >= 0; i--) {
var id = commentsToCreate[i];
var parentID = Comments.lookup[id].parent_id.split("_")[1];
if(_.includes(createdComments, parentID)) {
document.getElementById(parentID).appendChild(createComment(Comments.lookup[id]));
createdComments.push(id);
commentsToCreate.splice(i, 1);
didSomething = true;
}
}
// Fail safe (parents missing for the rest of the comments, shouldn't happend but oh well :D)
if(!didSomething) {
console.error("Didn't generate all comments correctly");
break;
}
}
};
var createComment = function(comment){
var isRemoved = _.has(comment,"removed");
var isDeleted = _.has(comment,"deleted");
// Sorry
var commentCss = "comment-" + (isRemoved ? "removed" : (isDeleted ? "deleted" : (comment.depth % 2 == 0 ? "even" : "odd")));
var commentDiv = document.createElement("div");
commentDiv.id = comment.id;
commentDiv.className = "comment " + commentCss;
commentDiv.innerHTML = ' \
<div class="comment-head"> \
<a href="javascript:void(0)" class="user-link">[]</a> \
<a href="https://www.reddit.com/user/'+comment.author+'" class="user-link comment-author">'+comment.author+(isDeleted ? " (deleted by user)" : "")+'</a> \
<span class="comment-score">'+Format.prettyScore(comment.score)+' point'+((comment.score == 1) ? '': 's')+'</span> \
<span class="comment-time">'+Format.prettyDate(comment.created_utc)+'</span> \
</div> \
<div class="comment-body">'+(comment.body === "[removed]" && isRemoved ? "<p>[likely removed by automoderator]</p>" : Format.parse(comment.body))+'</div> \
<div class="comment-links"> \
<a href="/r/'+Reddit.subreddit+'/comments/'+Reddit.threadID+'/_/'+comment.id+'/">permalink</a> \
</div>';
return commentDiv;
};
return {
createThread: createThread,
createCommentInfo: createCommentInfo,
createCommentSection: createCommentSection,
createComments: createComments
}
})()
app.loadPage()