Skip to content

Instantly share code, notes, and snippets.

@yeppiidev
Created October 14, 2022 14:20
Show Gist options
  • Save yeppiidev/2c07b9543464da5cb25be51e08fa8c2a to your computer and use it in GitHub Desktop.
Save yeppiidev/2c07b9543464da5cb25be51e08fa8c2a to your computer and use it in GitHub Desktop.
A simple Reddit Image Fetcher Program
# Copyright (c) 2022, yeppiidev
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
import os
import re
import argparse
import urllib.request
import requests
from tqdm import tqdm
class DownloadProgressBar(tqdm):
def update_to(self, b=1, bsize=1, tsize=None):
if tsize is not None:
self.total = tsize
self.update(b * bsize - self.n)
req_headers = {'User-agent': 'UHaveNeverSeenThisBrowserBefore 4.0'}
req_post_limit = '50'
def filter_fname(fname):
pat = re.compile(r'[^a-zA-Z\_0-9]+')
answer = re.sub(pat, '', fname.replace(' ', '_'))
return answer
def get_subreddit_posts_dict(subreddit):
req = requests.get(f'https://api.reddit.com/r/{subreddit}/top.json?limit={req_post_limit}', headers=req_headers)
return req.json()
def get_random_sub_posts_dict():
return get_subreddit_posts_dict('random')
def get_download_image(url, ftitle):
output_path = f'images/{ftitle}.png'
with DownloadProgressBar(unit='B', unit_scale=True,
miniters=1, desc=url.split('/')[-1]) as t:
urllib.request.urlretrieve(url, filename=output_path, reporthook=t.update_to)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='RFA (RedditFetchAll) v1.1')
subparser = parser.add_subparsers(dest='command')
fetch_sub = subparser.add_parser('fetch')
fetch_random = subparser.add_parser('fetch_random')
fetch_random.add_argument('--download-images', type=bool, required=False, dest='frnd_dl_img')
fetch_sub.add_argument('--subreddit', type=str, required=True)
fetch_sub.add_argument('--download-images', type=bool, required=False, dest='fsub_dl_img')
args = parser.parse_args()
if not os.path.isdir('images'):
os.mkdir('images')
if args.command == 'fetch':
print(f'Fetching images from subreddit: {args.subreddit}')
if args.fsub_dl_img:
sub_dict = get_subreddit_posts_dict(args.subreddit)
sub_name = args.subreddit
print(f'Fetching images from a {sub_name} subreddit...')
for post in sub_dict['data']['children']:
data = post['data']
if data['domain'] == 'i.redd.it':
print(f'-> Downloading "{data["title"]}" (r/{data["subreddit"]})')
get_download_image(data['url'], filter_fname(data['title']))
else:
print(f'-! Skipping "{data["title"]}" (r/{data["subreddit"]}) [not an image]')
elif args.command == 'fetch_random':
if args.frnd_dl_img:
print('Fetching images from a random subreddit...')
rnd_sub_dict = get_random_sub_posts_dict()
for post in rnd_sub_dict['data']['children']:
data = post['data']
if data['domain'] == 'i.redd.it':
print(f'-> Downloading "{data["title"]}" (r/{data["subreddit"]})')
get_download_image(data['url'], filter_fname(data['title']))
else:
print(f'-! Skipping "{data["title"]}" (r/{data["subreddit"]}) [not an image]')
else:
print('Fetching posts from a random subreddit...')
else:
print('error: no sub-command specified. \nrun "rfa --help" to see a list of available commands.')
requests==2.28.1
tqdm==4.64.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment