Last active
May 19, 2020 16:12
-
-
Save gavin19/7972e5554def6bd4edc62bed29a92107 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Python subreddit utils.""" | |
import os | |
import sys | |
import argparse | |
import shutil | |
from configparser import ConfigParser | |
from time import sleep | |
from urllib.request import (Request, urlopen, urlretrieve) | |
from zipfile import ZipFile | |
import praw | |
import prawcore | |
class SrUtils: | |
"""Main class.""" | |
def __init__(self): | |
"""Init.""" | |
self.path = sys.path[0] | |
self.reddit = None | |
self.login() | |
def login(self): | |
"""Log in via script app.""" | |
conf = ConfigParser() | |
if os.path.exists('creds.ini'): | |
conf.read('creds.ini', encoding='utf-8') | |
else: | |
raise FileNotFoundError('Config file, creds.ini, was not found.') | |
user = conf.get('creds', 'username') | |
pwd = conf.get('creds', 'password') | |
app_id = conf.get('creds', 'app_id') | |
app_secret = conf.get('creds', 'app_secret') | |
user_agent = conf.get('creds', 'user_agent') | |
self.reddit = praw.Reddit(client_id=app_id, | |
client_secret=app_secret, | |
username=user, | |
password=pwd, | |
user_agent=user_agent) | |
self.parse_args() | |
def parse_args(self): | |
"""Parse the arguments.""" | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--backup', '-b', nargs="*") | |
parser.add_argument('--dupe', '-d', nargs=2) | |
parser.add_argument('--restore', '-r', nargs=2) | |
args = parser.parse_args() | |
if args.backup: | |
self.backup(args.backup) | |
elif args.dupe: | |
self.dupe(args.dupe) | |
elif args.restore: | |
self.restore(args.restore) | |
else: | |
print("No option selected") | |
def backup(self, loc): | |
"""Backup the given sub to a zip.""" | |
source = loc[0] | |
if not os.path.exists('backups'): | |
os.makedirs('backups') | |
if len(loc) < 2: | |
archive_name = source + '.zip' | |
else: | |
archive_name = loc[1] | |
backup_path = os.path.join(self.path, 'backups') | |
if archive_name in os.listdir(backup_path): | |
print(archive_name + ' already exists.') | |
print('If you proceed it will be replaced with a current backup') | |
while True: | |
inp = input("Proceed - y/n: ") | |
if inp not in "YyNn": | |
print("y to proceed or n to exit") | |
else: | |
break | |
if inp.lower() == 'n': | |
print('Exiting...') | |
sleep(2) | |
sys.exit() | |
else: | |
os.remove(os.path.join(backup_path, archive_name)) | |
temp_path = source + '_tmp' | |
if os.path.exists(temp_path): | |
shutil.rmtree(temp_path) | |
os.makedirs(temp_path) | |
os.chdir(temp_path) | |
archive = {} | |
sub = self.reddit.subreddit(source) | |
archive['settings'] = self.get_subreddit_settings() | |
archive['user_flair'] = self.get_user_flair_templates() | |
archive['link_flair'] = self.get_link_flair_templates(sub) | |
stylesheet = self.get_subreddit_stylesheet() | |
archive['css'] = stylesheet.stylesheet | |
images = stylesheet.images | |
if images: | |
archive['imgs'] = self.get_images(images) | |
with open('backup.txt', 'w', encoding='utf-8') as f: | |
f.write(str(archive)) | |
items = os.listdir() | |
with ZipFile(archive_name, 'w') as zip: | |
for item in items: | |
zip.write(item) | |
src = os.path.abspath(archive_name) | |
target = os.path.join(backup_path, archive_name) | |
shutil.move(src, target) | |
os.chdir(self.path) | |
shutil.rmtree(temp_path) | |
print('Backup completed...') | |
@staticmethod | |
def get_subreddit_settings(sub): | |
"""Fetch the subreddit settings.""" | |
settings = sub.mod.settings() | |
return settings | |
@staticmethod | |
def get_user_flair_templates(sub): | |
"""Fetch user flair templates.""" | |
user_flair = [t for t in sub.flair.templates] | |
return user_flair | |
@staticmethod | |
def get_subreddit_stylesheet(sub): | |
"""Fetch the subreddit settings.""" | |
stylesheet = sub.stylesheet() | |
return stylesheet | |
@staticmethod | |
def get_link_flair_templates(sub): | |
"""Get templates from existing/test submission.""" | |
templates = [] | |
id = [s.id for s in sub.hot(limit=1)] | |
if not id: | |
print(""" | |
No posts were found in the target subreddit. | |
At least one post must exist in the subreddit to fetch | |
the link flair templates. | |
If you don't want to backup the templates then you can | |
skip this part, | |
otherwise a test post will be made, the templates fetched, | |
and the post deleted. | |
""") | |
while True: | |
skip = input("Skip this part - y/n: ") | |
if skip not in "YyNn": | |
print("y to skip, n to backup") | |
else: | |
break | |
if skip.lower() == 'n': | |
templates = self.make_test_post(sub.display_name) | |
else: | |
templates = self.make_test_post(sub.display_name) | |
return templates | |
@staticmethod | |
def get_images(imgs): | |
"""Download subreddit stylesheet images.""" | |
count = 1 | |
total = len(imgs) | |
for i in imgs: | |
url = i['url'] | |
ext = '.' + url.split('.')[-1] | |
name = i['name'] + ext | |
urlretrieve(url, name) | |
print(str(count) + ' of ' + str(total) + ' - ' + name) | |
count += 1 | |
sleep(1) | |
@staticmethod | |
def make_test_post(sub): | |
"""Create/delete test post to fetch link flair templates.""" | |
post = sub.submit('Link flair test', url='https://reddit.com/#test') | |
templates = post.flair.choices() | |
post.delete() | |
return templates | |
SrUtils() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment