Skip to content

Instantly share code, notes, and snippets.

@SheinH
Created November 26, 2019 07:17
Show Gist options
  • Select an option

  • Save SheinH/c2a16c8b60d017bc1083a75e7dd5aa97 to your computer and use it in GitHub Desktop.

Select an option

Save SheinH/c2a16c8b60d017bc1083a75e7dd5aa97 to your computer and use it in GitHub Desktop.
PRAW starter pack
import csv
import statistics
import sys
import os
from collections import defaultdict
from typing import List
import praw
import xdg
from praw import Reddit
from praw.models import ListingGenerator
from praw.models import MoreComments
from praw.models import Redditor
from praw.models import Submission
import prawcore
from prawcore.exceptions import Forbidden
def make_reddit() -> Reddit:
base = os.path.join(xdg.XDG_CONFIG_HOME, 'redditaccounts')
if not os.path.exists(base):
os.makedirs(base)
accs = [x.name for x in os.scandir(base) if not x.name.startswith('.') and x.is_file()]
print(f'Available accounts: {str.join(", ", accs)}')
name = input("Account name: ") if len(sys.argv) < 2 else sys.argv[1]
path = os.path.join(base, name)
with open(path, 'r') as file:
lines: list[str] = file.readlines()
lines = [l.strip() for l in lines]
r: Reddit = praw.Reddit(client_id=lines[0],
client_secret=lines[1],
user_agent=lines[2],
username=lines[3],
password=lines[4])
return r
r: Reddit = make_reddit()
def get_contributors(s: str) -> List[Redditor]:
sr = sub(s)
return list(n for n in sr.contributor(limit=6000000))
def nuke(item):
if isinstance(item, Redditor):
for x in item.new(limit=1e5):
try:
x.mod.remove()
except Forbidden as e:
pass
return
tree = None
if isinstance(item, Submission):
tree = item.comments
else:
item.refresh()
tree = item.replies
item.mod.remove()
for x in tree.list():
try:
x.mod.remove()
except:
pass
def get_comments(subname, limit=1e5, replace=False):
submissions: ListingGenerator = sub(subname).new(limit=limit)
visited = set()
posts = []
comments = []
for s in submissions:
if s not in visited:
posts.append(s)
else:
continue
if replace:
s.comments.replace_more(limit=replace)
for c in s.comments.list():
if isinstance(c, MoreComments):
continue
comments.append(c)
return posts, comments
def validate(u: str) -> bool:
u: Redditor = user(u)
try:
fn = u.fullname
except:
return False
try:
val: bool = getattr(u, 'is_suspended', False)
return not val
except:
return False
def is_active(u: str, time='week') -> bool:
if not validate(u):
return False
u: Redditor = user(u)
listings = u.top(time_filter=time)
listings.limit = 10
top = [t for t in listings]
return len(top) > 1
def sub_data(subname: str, limit=1e5, replace_more=False):
submissions: ListingGenerator = sub(subname).new(limit=limit)
map = defaultdict(lambda: [0, 0, 0, 0])
visited = set()
for s in submissions:
if s not in visited:
visited.add(s)
else:
continue
if s.author:
arr = map[s.author.name]
arr[0] += s.score
arr[1] += 1
if replace_more:
s.comments.replace_more(limit=None)
for c in s.comments.list():
if isinstance(c, MoreComments):
continue
if c not in visited:
visited.add(c)
else:
continue
if not c.author:
continue
arr2 = map[c.author.name]
arr2[2] += c.score
arr2[3] += 1
return map
def get_zscores(data: dict):
pkarma = [x[0] for x in data.values()]
ckarma = [x[2] for x in data.values()]
pstd = statistics.stdev(pkarma)
pavg = statistics.mean(pkarma)
cstd = statistics.stdev(ckarma)
cavg = statistics.mean(ckarma)
for x in data.values():
pz = (x[0] - pavg) / pstd
cz = (x[2] - cavg) / cstd
zs = (pz + cz) / 2
x.append(zs)
def pretty_print(res):
w = len(res[0])
arr = [0] * w
for i in range(w):
arr[i] = len(max(res, key=lambda x: len(x[i]))[i])
print(arr)
for row in res:
st = row[0] + ':'
st = st.ljust(arr[0] + 1)
for x in range(1, w):
e = row[x]
e = e.rjust(arr[x] + 1)
st += e
print(st)
def scan_user(name):
res = user_history(name)
res = map(lambda x: map(lambda y: str(y)), x)
pretty_print(res)
def user_history(name):
if isinstance(name, str):
name = user(name)
posts = name.submissions.new(limit=1e4)
comments = name.comments.new(limit=1e4)
d = defaultdict(lambda: [0, 0, 0, 0])
for x in posts:
arr = d[x.subreddit.display_name]
arr[0] += x.score - 1
arr[1] += 1
for x in comments:
arr = d[x.subreddit.display_name]
arr[2] += x.score - 1
arr[3] += 1
return sort_by_rank(d)
def sort_by_rank(d):
arr = [[key] + value for key, value in d.items()]
s1 = sorted(arr, key=lambda x: x[1])
s2 = sorted(arr, key=lambda x: x[4])
rankdict = defaultdict(lambda: 0)
for i in range(len(s1)):
v1 = s1[i]
v2 = s2[i]
rankdict[v1[0]] += i + 1
rankdict[v2[0]] += i + 1
arr.sort(key=lambda x: rankdict[x[0]], reverse=True)
return arr
def scan_sub(subname: str, limit=1000):
data = sub_data(subname, limit)
get_zscores(data)
data = [[x] + y for x, y in data.items()]
data.sort(key=lambda x: x[5], reverse=True)
file = csv.writer(open(f'{subname}_{today.strftime("%Y_%m_%d")}.csv', 'w'))
file.writerow(['Username', 'Post Karma', '# Posts', 'Comment Karma', '# Comments', 'Z Score'])
for value in data:
file.writerow([str(x) for x in value])
sub = r.subreddit
user = r.redditor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment