mirror of
https://github.com/gurnec/removeddit.git
synced 2026-03-11 08:54:27 +00:00
Init commit
This commit is contained in:
commit
fef01747d8
19 changed files with 5054 additions and 0 deletions
116
Unsaved Document 1
Normal file
116
Unsaved Document 1
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
[
|
||||
{
|
||||
'data':{
|
||||
'before':None,
|
||||
'after':None,
|
||||
'children':[
|
||||
{
|
||||
'data':{
|
||||
'created_utc':1502406327.0,
|
||||
'created':1502435127.0,
|
||||
'subreddit_id':'t5_3njjl',
|
||||
'banned_at_utc':None,
|
||||
'collapsed_reason':None,
|
||||
'author_flair_text':None,
|
||||
'stickied':False,
|
||||
'subreddit_type':'public',
|
||||
'score_hidden':False,
|
||||
'edited':False,
|
||||
'banned_by':None,
|
||||
'replies':'',
|
||||
'score':1,
|
||||
'report_reasons':None,
|
||||
'approved_at_utc':None,
|
||||
'ups':1,
|
||||
'link_id':'t3_6sx4fk',
|
||||
'collapsed':False,
|
||||
'saved':False,
|
||||
'num_reports':None,
|
||||
'depth':0,
|
||||
'subreddit_name_prefixed':'r/TestForApp',
|
||||
'can_gild':True,
|
||||
'parent_id':'t3_6sx4fk',
|
||||
'is_submitter':True,
|
||||
'can_mod_post':False,
|
||||
'body':'asdsad',
|
||||
'archived':False,
|
||||
'removal_reason':None,
|
||||
'author':'Jubbeart',
|
||||
'mod_reports':[
|
||||
|
||||
],
|
||||
'approved_by':None,
|
||||
'downs':0,
|
||||
'controversiality':0,
|
||||
'name':'t1_dlg744z',
|
||||
'subreddit':'TestForApp',
|
||||
'likes':None,
|
||||
'distinguished':None,
|
||||
'body_html':'<div class="md"><p>asdsad</p>\n</div>',
|
||||
'user_reports':[
|
||||
|
||||
],
|
||||
'id':'dlg744z',
|
||||
'gilded':0,
|
||||
'author_flair_css_class':None
|
||||
},
|
||||
'kind':'t1'
|
||||
},
|
||||
{
|
||||
'data':{
|
||||
'created_utc':1502406332.0,
|
||||
'created':1502435132.0,
|
||||
'subreddit_id':'t5_3njjl',
|
||||
'banned_at_utc':None,
|
||||
'collapsed_reason':None,
|
||||
'author_flair_text':None,
|
||||
'stickied':False,
|
||||
'subreddit_type':'public',
|
||||
'score_hidden':False,
|
||||
'edited':False,
|
||||
'banned_by':None,
|
||||
'replies':'',
|
||||
'score':1,
|
||||
'report_reasons':None,
|
||||
'approved_at_utc':None,
|
||||
'ups':1,
|
||||
'link_id':'t3_6sx4fk',
|
||||
'collapsed':False,
|
||||
'saved':False,
|
||||
'num_reports':None,
|
||||
'depth':0,
|
||||
'subreddit_name_prefixed':'r/TestForApp',
|
||||
'can_gild':True,
|
||||
'parent_id':'t3_6sx4fk',
|
||||
'is_submitter':True,
|
||||
'can_mod_post':False,
|
||||
'body':'asdasdas1123123123\n',
|
||||
'archived':False,
|
||||
'removal_reason':None,
|
||||
'author':'Jubbeart',
|
||||
'mod_reports':[
|
||||
|
||||
],
|
||||
'approved_by':None,
|
||||
'downs':0,
|
||||
'controversiality':0,
|
||||
'name':'t1_dlg749h',
|
||||
'subreddit':'TestForApp',
|
||||
'likes':None,
|
||||
'distinguished':None,
|
||||
'body_html':'<div class="md"><p>asdasdas1123123123</p>\n</div>',
|
||||
'user_reports':[
|
||||
|
||||
],
|
||||
'id':'dlg749h',
|
||||
'gilded':0,
|
||||
'author_flair_css_class':None
|
||||
},
|
||||
'kind':'t1'
|
||||
}
|
||||
],
|
||||
'modhash':''
|
||||
},
|
||||
'kind':'Listing'
|
||||
}
|
||||
]
|
||||
47
Unsaved Document 2
Normal file
47
Unsaved Document 2
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
'created_utc':1502406327.0,
|
||||
'created':1502435127.0,
|
||||
'subreddit_id':'t5_3njjl',
|
||||
'banned_at_utc':None,
|
||||
'collapsed_reason':None,
|
||||
'author_flair_text':None,
|
||||
'stickied':False,
|
||||
'subreddit_type':'public',
|
||||
'score_hidden':False,
|
||||
'edited':False,
|
||||
'banned_by':None,
|
||||
'replies':'',
|
||||
'score':1,
|
||||
'report_reasons':None,
|
||||
'approved_at_utc':None,
|
||||
'ups':1,
|
||||
'link_id':'t3_6sx4fk',
|
||||
'collapsed':False,
|
||||
'saved':False,
|
||||
'num_reports':None,
|
||||
'depth':0,
|
||||
'subreddit_name_prefixed':'r/TestForApp',
|
||||
'can_gild':True,
|
||||
'parent_id':'t3_6sx4fk',
|
||||
'is_submitter':True,
|
||||
'can_mod_post':False,
|
||||
'body':'asdsad',
|
||||
'archived':False,
|
||||
'removal_reason':None,
|
||||
'author':'Jubbeart',
|
||||
'mod_reports':[
|
||||
|
||||
],
|
||||
'approved_by':None,
|
||||
'downs':0,
|
||||
'controversiality':0,
|
||||
'name':'t1_dlg744z',
|
||||
'subreddit':'TestForApp',
|
||||
'likes':None,
|
||||
'distinguished':None,
|
||||
'body_html':'<div class="md"><p>asdsad</p>\n</div>',
|
||||
'user_reports':[
|
||||
|
||||
],
|
||||
'id':'dlg744z',
|
||||
'gilded':0,
|
||||
'author_flair_css_class':None
|
||||
47
Unsaved Document 3
Normal file
47
Unsaved Document 3
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
'created_utc':1502406332.0,
|
||||
'created':1502435132.0,
|
||||
'subreddit_id':'t5_3njjl',
|
||||
'banned_at_utc':None,
|
||||
'collapsed_reason':None,
|
||||
'author_flair_text':None,
|
||||
'stickied':False,
|
||||
'subreddit_type':'public',
|
||||
'score_hidden':False,
|
||||
'edited':False,
|
||||
'banned_by':None,
|
||||
'replies':'',
|
||||
'score':1,
|
||||
'report_reasons':None,
|
||||
'approved_at_utc':None,
|
||||
'ups':1,
|
||||
'link_id':'t3_6sx4fk',
|
||||
'collapsed':False,
|
||||
'saved':False,
|
||||
'num_reports':None,
|
||||
'depth':0,
|
||||
'subreddit_name_prefixed':'r/TestForApp',
|
||||
'can_gild':True,
|
||||
'parent_id':'t3_6sx4fk',
|
||||
'is_submitter':True,
|
||||
'can_mod_post':False,
|
||||
'body':'asdasdas1123123123\n',
|
||||
'archived':False,
|
||||
'removal_reason':None,
|
||||
'author':'Jubbeart',
|
||||
'mod_reports':[
|
||||
|
||||
],
|
||||
'approved_by':None,
|
||||
'downs':0,
|
||||
'controversiality':0,
|
||||
'name':'t1_dlg749h',
|
||||
'subreddit':'TestForApp',
|
||||
'likes':None,
|
||||
'distinguished':None,
|
||||
'body_html':'<div class="md"><p>asdasdas1123123123</p>\n</div>',
|
||||
'user_reports':[
|
||||
|
||||
],
|
||||
'id':'dlg749h',
|
||||
'gilded':0,
|
||||
'author_flair_css_class':None
|
||||
BIN
__pycache__/app.cpython-35.pyc
Normal file
BIN
__pycache__/app.cpython-35.pyc
Normal file
Binary file not shown.
BIN
__pycache__/devapp.cpython-35.pyc
Normal file
BIN
__pycache__/devapp.cpython-35.pyc
Normal file
Binary file not shown.
86
app.py
Normal file
86
app.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
from flask import Flask, abort, request, render_template
|
||||
import urllib.parse
|
||||
import requests
|
||||
import requests.auth
|
||||
import datetime
|
||||
|
||||
import json
|
||||
|
||||
APP_NAME = 'TEST'
|
||||
USERNAME = 'Jubbeart'
|
||||
VERSION = '0.1'
|
||||
|
||||
CLIENT_ID = ''
|
||||
CLIENT_SECRET = ''
|
||||
USER_AGENT = 'Javascript:{}:v{} (by /u/{})'.format(APP_NAME, VERSION, USERNAME)
|
||||
|
||||
TOKEN_URL = 'https://www.reddit.com/api/v1/access_token'
|
||||
API_URL = 'https://oauth.reddit.com/'
|
||||
COMMENT_IDS_URL = 'https://api.pushshift.io/reddit/submission/comment_ids/{}'
|
||||
COMMENTS_URL = 'https://api.pushshift.io/reddit/comment/search?ids={}'
|
||||
|
||||
FILTER_BODY = [
|
||||
'title', 'author', 'num_comments',
|
||||
'subreddit', 'score', 'upvote_ratio',
|
||||
'created_utc', 'locked', 'link_flair_text',
|
||||
'is_self', 'url', 'selftext_html',
|
||||
'id'
|
||||
]
|
||||
|
||||
FILTER_COMMENT = [
|
||||
'score', 'author', 'created_utc',
|
||||
'body_html', 'id', 'controversiality',
|
||||
|
||||
'collapsed_reason', 'collapsed',
|
||||
]
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/')
|
||||
def homepage():
|
||||
return render_template('frontpage.html')
|
||||
|
||||
|
||||
@app.route('/r/<string:subreddit>/comments/<path:thread_id>')
|
||||
def thread(subreddit, thread_id):
|
||||
thread_id = thread_id.split('/')[0]
|
||||
comment_ids = requests.get(COMMENT_IDS_URL.format(thread_id)).json()["data"]
|
||||
token = get_token()
|
||||
|
||||
return render_template(
|
||||
'thread.html',
|
||||
token=token,
|
||||
comment_ids=comment_ids,
|
||||
thread_id=thread_id,
|
||||
subreddit=subreddit
|
||||
)
|
||||
|
||||
@app.route('/comments/')
|
||||
def comments():
|
||||
ids = None
|
||||
|
||||
try:
|
||||
ids = request.args.get('c')
|
||||
except:
|
||||
return ''
|
||||
|
||||
if ids:
|
||||
return requests.get(COMMENTS_URL.format(ids)).content
|
||||
else:
|
||||
return ''
|
||||
|
||||
|
||||
def get_token(old_token=None):
|
||||
post_data = {'grant_type': 'client_credentials'}
|
||||
headers = {'User-Agent': USER_AGENT}
|
||||
client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
|
||||
response = requests.post(
|
||||
TOKEN_URL,
|
||||
auth=client_auth,
|
||||
data=post_data,
|
||||
headers=headers
|
||||
)
|
||||
return response.json()['access_token']
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, port=65010)
|
||||
0
attributestosave
Normal file
0
attributestosave
Normal file
2
devapp.py
Normal file
2
devapp.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from app import create_app
|
||||
app = create_app()
|
||||
17
front-page
Normal file
17
front-page
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
fun image
|
||||
|
||||
#About
|
||||
|
||||
this site was inspired by Go1dfish's ceddit.com but it not meant as a replace for Reddit.
|
||||
|
||||
#TODO
|
||||
|
||||
#Thanks To:
|
||||
bold(Jason) href=blog - making all this possible
|
||||
/r/redditdev
|
||||
markdown-shit
|
||||
|
||||
#Links & Contact
|
||||
Feedback, questions: removeddit [at] gmail.com
|
||||
Source code: github@
|
||||
|
||||
105
old_code
Normal file
105
old_code
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
function get_comments(json) {
|
||||
var comments = [];
|
||||
var comments_json = json[1].data.children;
|
||||
|
||||
for(var i = 0; i < comments_json.length; i++) {
|
||||
get_comment_data(comments_json[i], comments);
|
||||
}
|
||||
|
||||
return comments;
|
||||
}
|
||||
|
||||
|
||||
var stripped_comment_tags = ["author_flair_css_class", "approved_by",
|
||||
"approved_at_utc", "archived", "author_flair_text",
|
||||
"body_html", "banned_at_utc", "banned_by",
|
||||
"can_gild", "can_mod_post", "created", "collapsed", "collapsed_reason",
|
||||
"downs", "distinguished", "gilded",
|
||||
"edited", "likes", "link_id", "name", "mod_reports", "num_reports",
|
||||
"removal_reason", "report_reasons",
|
||||
"saved", "subreddit", "subreddit_type", "subreddit_name_prefixed", "subreddit_id",
|
||||
"ups", "user_reports"];
|
||||
|
||||
|
||||
|
||||
|
||||
// Strips unnecessary tags from comment, adds to comment array
|
||||
// Do this recursivly to all replies
|
||||
// Params comment:JSON object, comments: array
|
||||
function get_comment_data(comment, comments) {
|
||||
if(comment.kind !== "t1") {
|
||||
alert(comment.kind);
|
||||
return;
|
||||
}
|
||||
|
||||
var comment_data = comment.data;
|
||||
|
||||
for(var i = 0; i < stripped_comment_tags.length; i++) {
|
||||
delete comment_data[stripped_comment_tags[i]];
|
||||
}
|
||||
|
||||
if(comment_data.replies) {
|
||||
for(var i = 0; i < comment_data.replies.data.children.length; i++) {
|
||||
get_comment_data(comment_data.replies.data.children[i], comments);
|
||||
}
|
||||
}
|
||||
|
||||
if(comment_data.parent_id.indexOf("_") !== -1) {
|
||||
comment_data.parent_id = comment_data.parent_id.split("_")[1];
|
||||
}
|
||||
|
||||
delete comment_data["replies"];
|
||||
comments.push(comment_data);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
old_code:
|
||||
|
||||
|
||||
"""headers = {'Authorization': 'bearer ' + token, 'User-Agent': USER_AGENT}
|
||||
url = API_URL + THREAD_PATH.format(subreddit, thread_id)
|
||||
|
||||
response = requests.get(url, headers=headers)
|
||||
thread_json = None
|
||||
|
||||
try:
|
||||
thread_json = response.json()
|
||||
except:
|
||||
return 'Error parsing the thread'
|
||||
|
||||
thread = {
|
||||
'body': get_thread_body(thread_json),
|
||||
'comments': get_thread_comments(thread_json)
|
||||
}
|
||||
|
||||
return str(get_thread_comments(thread_json))
|
||||
#return str(get_thread_comments(thread_json)) + '/' + str(thread['body']['num_comments'])
|
||||
|
||||
def get_thread_body(thread_json):
|
||||
body_json = thread_json[0]['data']['children'][0]['data']
|
||||
filtered_body = {k:v for k,v in body_json.items() if k in FILTER_BODY}
|
||||
return filtered_body
|
||||
|
||||
def get_thread_comments(thread_json):
|
||||
comments_json = thread_json[1]['data']['children']
|
||||
filtered_comments = []
|
||||
|
||||
for comment_json in comments_json:
|
||||
comment_data = get_comment_data(comment_json)
|
||||
filtered_comments.append(comment_data)
|
||||
|
||||
return filtered_comments
|
||||
|
||||
def get_comment_data(comment):
|
||||
comment_data = comment['data']
|
||||
filtered_comment = {k:v for k,v in comment_data.items() if k in FILTER_COMMENT}
|
||||
filtered_comment['replies'] = []
|
||||
|
||||
if comment_data['replies']:
|
||||
for child_comment in comment_data['replies']['data']['children']:
|
||||
filtered_comment['replies'].append(get_comment_data(child_comment))
|
||||
|
||||
return filtered_comment
|
||||
"""
|
||||
0
static/functions.js
Normal file
0
static/functions.js
Normal file
411
static/script.js
Normal file
411
static/script.js
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
"use strict";
|
||||
|
||||
const markdown = SnuOwnd.getParser();
|
||||
|
||||
const thread_url = `https://oauth.reddit.com/r/${subreddit}/comments/${thread_id}`;
|
||||
const morechildren_url = `https://oauth.reddit.com/api/morechildren?link_id=t3_${thread_id}&children=`;
|
||||
const single_comment_url = `https://oauth.reddit.com/r/${subreddit}/api/info/?id=t1_`;
|
||||
const removed_comments_url = "/comments/?c=";
|
||||
|
||||
const main_div = document.getElementById("main");
|
||||
|
||||
const loading_comments = document.getElementById("loading-comments");
|
||||
|
||||
const comment_ids = new Set();
|
||||
const comment_lookup = new Map();
|
||||
const comments_to_generate = [];
|
||||
const comments_to_generate_ids = new Set();
|
||||
let ajax_calls_left = 0;
|
||||
let total_comments;
|
||||
|
||||
get(thread_url, response => {
|
||||
const json = JSON.parse(response);
|
||||
//generate_thread(json[0].data.children[0].data);
|
||||
//get_comment_ids(json[1].data.children);
|
||||
});
|
||||
|
||||
function generate_thread(thread) {
|
||||
const thread_div = document.createElement("div");
|
||||
thread_div.id = "thread";
|
||||
|
||||
const thread_string = `
|
||||
<div id="thread-score-box">
|
||||
<div class="vote upvote"></div>
|
||||
<div id="thread-score">${pretty_score(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">${pretty_date(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" href="https://reddit.com/r/${subreddit}">/r/${subreddit}</a>
|
||||
</div>
|
||||
${thread.selftext !== '' ? '<div id="thread-selftext" class="user-text">'+markdown.render(thread.selftext)+'</div>':''}
|
||||
</div>
|
||||
`;
|
||||
|
||||
thread_div.innerHTML = thread_string;
|
||||
main_div.insertBefore(thread_div, loading_comments);
|
||||
total_comments = thread.num_comments;
|
||||
}
|
||||
|
||||
function get_comment_ids(comments) {
|
||||
comments.forEach(comment => extract_id_from_comment(comment));
|
||||
|
||||
if(ajax_calls_left == 0) {
|
||||
get_all_comment_ids();
|
||||
}
|
||||
}
|
||||
|
||||
function extract_id_from_comment(comment) {
|
||||
// "Show more"-comments
|
||||
if(comment.kind == "more") {
|
||||
const children = comment.data.children;
|
||||
|
||||
// Some "show more"-comments were missing, need to do more ajax-calls
|
||||
if(children.length < comment.data.count){
|
||||
ajax_calls_left++;
|
||||
get(morechildren_url + children.join(), response => handle_show_more_comments(JSON.parse(response)));
|
||||
}
|
||||
|
||||
if(children.length > 0) {
|
||||
comment_ids.add(...children);
|
||||
}
|
||||
}
|
||||
// Normal comment
|
||||
else {
|
||||
const data = comment.data;
|
||||
|
||||
if(data.replies) {
|
||||
data.replies.data.children.forEach(child => extract_id_from_comment(child));
|
||||
}
|
||||
|
||||
delete data.replies;
|
||||
comment_lookup.set(data.id, data);
|
||||
comment_ids.add(data.id);
|
||||
}
|
||||
}
|
||||
|
||||
function handle_show_more_comments(comments) {
|
||||
|
||||
comments.jquery[14][3][0].forEach(comment => {
|
||||
if(comment.kind == "more") {
|
||||
let children = comment.data.children;
|
||||
|
||||
if(children.length < comment.data.count) {
|
||||
ajax_calls_left++;
|
||||
get(morechildren_url + children.join, response => handle_show_more_comments(JSON.parse(response)));
|
||||
}
|
||||
|
||||
comment_ids.add(...children);
|
||||
} else {
|
||||
comment_ids.add(comment.data.id);
|
||||
comment_lookup.set(comment.data.id, comment.data);
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
for(var i = 0, len = comments.length; i < len; i++){
|
||||
if(comments[i].kind == "more") {
|
||||
var children = comments[i].data.children;
|
||||
|
||||
if(children.length < comments[i].data.count) {
|
||||
ajax_calls_left++;
|
||||
get(morechildren_url + thread_id + "&children=" + children.join(), function(data){
|
||||
handle_show_more_comments(JSON.parse(data))
|
||||
});
|
||||
}
|
||||
|
||||
add_id(children);
|
||||
|
||||
} else {
|
||||
add_id(comments[i].data.id);
|
||||
comment_lookup[comments[i].data.id] = comments[i].data;
|
||||
}
|
||||
}
|
||||
*/
|
||||
ajax_calls_left--;
|
||||
|
||||
if(ajax_calls_left == 0) {
|
||||
get_all_comment_ids();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_all_comment_ids() {
|
||||
const ids_diff = new Set([...all_ids].filter(x => !comment_ids.has(x)));
|
||||
console.log(all_ids);
|
||||
console.log(comment_ids);
|
||||
console.log(ids_diff);
|
||||
|
||||
if(ids_diff.size > 100) {
|
||||
alert("very many removal, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
get(removed_comments_url + [...ids_diff].join(), response => create_comments(JSON.parse(response).data));
|
||||
}
|
||||
|
||||
function create_comments(comments) {
|
||||
create_comment_info(comments.length);
|
||||
|
||||
comments.forEach(comment => {
|
||||
comment["removed"] = true;
|
||||
comments_to_generate.push(comment);
|
||||
comments_to_generate_ids.add(comment.id);
|
||||
comment_lookup.set(comment.id, comment);
|
||||
});
|
||||
|
||||
//create_parent_comments();
|
||||
|
||||
/*
|
||||
for(var i = 0; i < comments.length; i++) {
|
||||
comment = create_comment(comments[i], true);
|
||||
comment_section.appendChild(comment);
|
||||
comment_lookup[comments[i].id] = comments[i];
|
||||
}
|
||||
*/
|
||||
//add_parent_comments();
|
||||
|
||||
}
|
||||
|
||||
function create_parent_comments() {
|
||||
let done = true;
|
||||
let parent_id;
|
||||
let comment;
|
||||
|
||||
for(let i = comments_to_generate.length - 1; i >= 0; i--) {
|
||||
//console.log(comments[i]);
|
||||
comment = comments_to_generate[i];
|
||||
|
||||
parent_id = comment_lookup.get(comment.id).parent_id.split("_")[1];
|
||||
|
||||
// Done with this comment
|
||||
if(parent_id == thread_id || comments_to_generate_ids.has(parent_id)) { }
|
||||
// comment exists in lookup but hasnt been added to the queue yet
|
||||
else if(comment_lookup.has(parent_id)) {
|
||||
comments_to_generate.push(comment);
|
||||
comments_to_generate_ids.add(comment.id);
|
||||
done = false;
|
||||
}
|
||||
// parent comment doesn't exists
|
||||
else {
|
||||
get(single_comment_url + parent_id, response => {
|
||||
let new_comment = JSON.parse(data).data.children[0].data;
|
||||
|
||||
comments_to_generate.push(new_comment);
|
||||
comments_to_generate_ids.add(new_comment.id);
|
||||
create_parent_comments();
|
||||
console.log(parent_id, " created via /api/info ???");
|
||||
});
|
||||
done = false;
|
||||
console.log(i, " doesn't exist");
|
||||
}
|
||||
|
||||
console.log(i);
|
||||
}
|
||||
|
||||
if(!done) {
|
||||
create_parent_comments();
|
||||
} else {
|
||||
generate_comments();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function generate_comments() {
|
||||
const comment_section = document.createElement("div");
|
||||
comment_section.id = "comments";
|
||||
main_div.insertBefore(comment_section, loading_comments);
|
||||
|
||||
sort_comments();
|
||||
comments_to_generate.forEach(comment => {
|
||||
comment_section.appendChild(create_comment(comment));
|
||||
});
|
||||
}
|
||||
|
||||
function create_comment(comment) {
|
||||
const comment_div = document.createElement("div");
|
||||
comment_div.className = "comment " + (comment.hasOwnProperty("removed") ? "comment-removed" : "");
|
||||
comment_div.id = comment.id;
|
||||
|
||||
const comment_html = `
|
||||
<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}</a>
|
||||
<span class="comment-score">${comment.score} point${(comment.score == 1) ? '': 's'}</span>
|
||||
<span class="comment-time">${pretty_date(comment.created_utc) }</span>
|
||||
</div>
|
||||
<div class="comment-body">${markdown.render(comment.body)}</div>
|
||||
<div class="comment-links">
|
||||
<a href="https://todo.com">permalink</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
comment_div.innerHTML = comment_html;
|
||||
return comment_div;
|
||||
}
|
||||
|
||||
/*function create_parent_comments() {
|
||||
var comment_section = document.getElementById("comments");
|
||||
var comments = comment_section.children;
|
||||
var parent_id;
|
||||
var comment;
|
||||
var created_comments = [];
|
||||
var done = true;
|
||||
|
||||
for(var i = comments.length - 1; i >= 0; i--) {
|
||||
//console.log(comments[i]);
|
||||
|
||||
parent_id = comment_lookup[comments[i].id].parent_id;
|
||||
|
||||
if(parent_id.includes("_")) {
|
||||
parent_id = parent_id.split("_")[1];
|
||||
}
|
||||
|
||||
// Done with this comment
|
||||
if(parent_id == thread_id) {
|
||||
//console.log(i, "done");
|
||||
}
|
||||
// Check if parent already exists
|
||||
else if(comments_on_display.has(parent_id)) {
|
||||
document.getElementById(parent_id).appendChild(comments[i]);
|
||||
//console.log(i, "comment already exists");
|
||||
done = false;
|
||||
}
|
||||
// comment_data exists but parent comment hasn't been created yet
|
||||
else if(comment_lookup.hasOwnProperty(parent_id)) {
|
||||
//created_comments.push(create_comment(comments_data[parent_id]));
|
||||
comment_section.appendChild(create_comment(comment_lookup[parent_id], false));
|
||||
//console.log(i, " comment data exists");
|
||||
//done = false;
|
||||
}
|
||||
// parent comment doesn't exists
|
||||
else {
|
||||
get(single_comment_url + parent_id, function(data){
|
||||
var comment = create_comment(JSON.parse(data).data.children[0].data, false);
|
||||
comment_section.appendChild();
|
||||
add_parent_comments();
|
||||
console.log(parent_id, " created via /api/info ???");
|
||||
});
|
||||
|
||||
console.log(i, " doesn't exist");
|
||||
}
|
||||
}
|
||||
|
||||
if(!done) {
|
||||
add_parent_comments();
|
||||
} else {
|
||||
fix_background_color();
|
||||
sort_comments();
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
function create_comment_info(removed_comments) {
|
||||
const comment_info = document.createElement("div");
|
||||
comment_info.innerHTML = `
|
||||
<div id="comment-info">
|
||||
removed comments: ${removed_comments}/${total_comments} (${ (100 * removed_comments / total_comments).toFixed(1)}%)
|
||||
</div>
|
||||
<div id="comment-sort">sorted by: top</div>
|
||||
`;
|
||||
|
||||
main_div.insertBefore(comment_info, loading_comments);
|
||||
}
|
||||
|
||||
function fix_background_color(root = document.getElementById("comments"), depth = 0) {
|
||||
var comments = document.getElementById("comments").children;
|
||||
|
||||
|
||||
|
||||
for(var i = 0, len = comments.length; i < len; i++) {
|
||||
//if(!comments.
|
||||
|
||||
//comments.
|
||||
}
|
||||
|
||||
}
|
||||
//https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement
|
||||
function sort_comments() {
|
||||
comments_to_generate.sort(function(a, b) {
|
||||
if(a.score == b.score) {
|
||||
return 0;
|
||||
}
|
||||
return a.score < b.score ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------- Other less interesting functions ------------------------
|
||||
|
||||
function get(url, callback) {
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
callback(this.responseText);
|
||||
} else if (this.readyState == 4) {
|
||||
alert(this.status + " error: " + this.responseText);
|
||||
// Error handle
|
||||
}
|
||||
}
|
||||
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.setRequestHeader("Authorization", "bearer " + token);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function add_id(id) {
|
||||
if(id instanceof Array) {
|
||||
comment_ids.add(...id);
|
||||
} else {
|
||||
comment_ids.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
// UTC -> "Reddit time format"
|
||||
function pretty_date(created_utc) {
|
||||
const current_utc = Math.floor((new Date()).getTime() / 1000);
|
||||
const second_diff = current_utc - created_utc;
|
||||
const day_diff = Math.floor(second_diff / 86400);
|
||||
|
||||
if(day_diff < 0)
|
||||
return '';
|
||||
|
||||
if(day_diff == 0) {
|
||||
if(second_diff < 10)
|
||||
return "just now";
|
||||
if(second_diff < 60)
|
||||
return second_diff + " seconds ago";
|
||||
if(second_diff < 120)
|
||||
return "a minute ago";
|
||||
if(second_diff < 3600)
|
||||
return Math.floor(second_diff / 60) + " minutes ago";
|
||||
if(second_diff < 7200)
|
||||
return "an hour ago";
|
||||
if(second_diff < 86400)
|
||||
return Math.floor(second_diff / 3600) + " hours ago";
|
||||
}
|
||||
if(day_diff == 1)
|
||||
return "Yesterday";
|
||||
if(day_diff < 7)
|
||||
return day_diff + " days ago";
|
||||
if(day_diff < 31)
|
||||
return Math.floor(day_diff / 7) + " weeks ago";
|
||||
if(day_diff < 365)
|
||||
return Math.floor(day_diff / 30) + " months ago";
|
||||
return Math.floor(day_diff / 365) + " years ago";
|
||||
}
|
||||
|
||||
function pretty_score(score) {
|
||||
if(score >= 10000) {
|
||||
return (score / 1000).toFixed(1) + "k";
|
||||
} else {
|
||||
return score;
|
||||
}
|
||||
}
|
||||
3950
static/snuownd.js
Normal file
3950
static/snuownd.js
Normal file
File diff suppressed because it is too large
Load diff
225
static/style.css
Normal file
225
static/style.css
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
body {
|
||||
background-color: #262626;
|
||||
margin: 0;
|
||||
font-family: verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 5px 0;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
#thread-selftext p:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
#thread-selftext p:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
a {
|
||||
cursor: auto;
|
||||
color: #8cb3d9;
|
||||
}
|
||||
|
||||
a:link, a:visited, a:hover, a:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
.user-text {
|
||||
color: #ddd;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-link {
|
||||
color: #6a98af;
|
||||
|
||||
}
|
||||
/*
|
||||
.user-link:hover {
|
||||
text-decoration: underline;
|
||||
}*/
|
||||
|
||||
|
||||
#header {
|
||||
background-color: #181818;
|
||||
padding: 20px 10px 10px;
|
||||
}
|
||||
|
||||
#header a {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
#header a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header-title {
|
||||
margin: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#main {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
#thread {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
||||
.thumbnail {
|
||||
background-color: black;
|
||||
float: left;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
#thread-score-box {
|
||||
margin: 0 7px;
|
||||
}
|
||||
|
||||
.vote {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAcCAMAAADC4sagAAABFFBMVEUjJCQiIiIjIyMkIiIkJCQlJSUlJicmJiYnIyEnJycnKCsoKCgpLC8rIyErKyssMDUvLy8wJCAwMDAxMTEyMjI0NDQ2NjY3JR83Nzc5OTk7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NGRkZISEhKSkpKV2tLS0tMTExOTk5PT09QYHdSUlJTU1NVVVVWVlZXV1dXaINYWFhaWlpabYlbW1tecpBgYGBhYWFid5dkZGRle5xlfJ1pgKRrhKhshKlshapuLhZwirFyjbV0j7h4lL97mcZ9MBR/nsyCo9OOMxGcNQ+eNg+kNw6sOA2vOAy0OQy7Ogq/OwrBOwrDPAnLPQjPPQfTPgfbPwXjQQTrQgPzQwLKxGgxAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlJREFUOMu9lF1TwjAQRTcMvmeQOi1QPmxFBQTxW1ERUUFEUVRU/P//w9yGmBTFyZPnpXNmbju76W6IJM8Uw49rLa6Tz4mpq/mCqY3Gvqnj6XQ61lp0mGd8favCwx2tow8wUlpwGWOZrNJKjXO+UVc6fJcMZzV7IswSOU/qej0l0rwyq33wphhAM1kWkcy70GB7mUfUNqG9V02PyPMTMs2Wig5RaTctwzxVXyPqvJh0VkJBIKJ4huncCRAvHOEZyGKegO4a6UDrIdLGCT4C6/QDsE7fA+v0HdAadWqk0SH9D3sgXkm4uJIDYKTFnwwXd3kMrNOnwDp9BmzS5QuTshN1iDRwfkxV9VJTJXLzSWYM+NzEEjWvFE2oGvCE7/2yDeL8riWzM8xmorRazLlNI2rdgNb3ZYLF1Es/t8VE7X6/39Yqlt4tLLwhiLq3XVNLfumP24fo3Opm+wLGCVa252Y8tQAAAABJRU5ErkJggg==);
|
||||
background-repeat: no-repeat;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 15px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.upvote {
|
||||
background-position: -15px 0px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.downvote {
|
||||
background-position: -15px -14px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
#thread-score {
|
||||
color: #646464;
|
||||
float: left;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
#thread-content {
|
||||
flex: 1;
|
||||
float: left;
|
||||
margin-left: 3px;
|
||||
max-width: 840px;
|
||||
}
|
||||
|
||||
.link-flair {
|
||||
color: #c8c8c8;
|
||||
background-color: #404040;
|
||||
margin-right: 5px;
|
||||
border: 1px solid #4d4d4d;
|
||||
border-radius: 2px;
|
||||
padding: 0 2px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#thread-title {
|
||||
color: #a6a6a6;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#thread-title:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#domain {
|
||||
color: #888;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#thread-info {
|
||||
color: #828282;
|
||||
font-size: 10px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
#thread-selftext {
|
||||
border: 1px solid #666;
|
||||
border-radius: 7px;
|
||||
margin: 5px 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
#comment-info {
|
||||
color: red;
|
||||
margin-top: 10px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px dotted #808080;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#comment-sort {
|
||||
color: #808080;
|
||||
font-size: 12px;
|
||||
margin: 5px 0 10px;
|
||||
}
|
||||
|
||||
.comment {
|
||||
margin: 0 8px 8px 0;
|
||||
padding: 5px 8px 5px /*14px*/ 30px;
|
||||
border: 1px solid #333;
|
||||
border-radius: 3px;
|
||||
color: #ddd;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.comment-head {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.comment-author {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.comment-score {
|
||||
color: #b4b4b4;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.comment-time {
|
||||
color: #828282;
|
||||
}
|
||||
|
||||
.comment-body {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.comment-links {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.comment-links a {
|
||||
color: #828282;
|
||||
font-weight: bold;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.comment-removed {
|
||||
background-color: #633636;
|
||||
}
|
||||
|
||||
.comment-odd {
|
||||
background-color: #121212;
|
||||
}
|
||||
|
||||
.comment-even {
|
||||
background-color: #161616;
|
||||
}
|
||||
6
templates/footer.html
Normal file
6
templates/footer.html
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<div id="debug"></div>
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
7
templates/frontpage.html
Normal file
7
templates/frontpage.html
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "main.html" %}
|
||||
{% block body %}
|
||||
|
||||
frontpage
|
||||
|
||||
{% endblock %}
|
||||
|
||||
15
templates/header.html
Normal file
15
templates/header.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<title></title>
|
||||
<meta charset="utf-8">
|
||||
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet">
|
||||
<link rel="shotcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header id="header">
|
||||
<a href="https://jubbeart.com"><h1 id="header-title">Removeddit [beta]</h1></a>
|
||||
</header>
|
||||
<div id="main">
|
||||
4
templates/main.html
Normal file
4
templates/main.html
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{% include "header.html" %}
|
||||
{% block body%}
|
||||
{% endblock %}
|
||||
{% include "footer.html" %}
|
||||
16
templates/thread.html
Normal file
16
templates/thread.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{% extends "main.html" %}
|
||||
{% block body %}
|
||||
<div id="loading-comments" class="loading-comments"></div>
|
||||
<!-- https://rawgit.com/ -->
|
||||
<script src="{{ url_for('static', filename='snuownd.js') }}"></script>
|
||||
<script src="https://cdn.rawgit.com/showdownjs/showdown/1.7.2/dist/showdown.min.js"></script>
|
||||
<script src="{{ url_for('static', filename='functions.js') }}"></script>
|
||||
<script>
|
||||
const thread_id = "{{ thread_id }}";
|
||||
const token = "{{ token }}";
|
||||
const subreddit = "{{ subreddit }}";
|
||||
const all_ids = new Set({{ comment_ids|safe }});
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='script.js')}}"></script>
|
||||
{% endblock %}
|
||||
|
||||
Loading…
Reference in a new issue