| from warnings import filterwarnings | |
| from random import randint | |
| from time import sleep | |
| import argparse | |
| import requests | |
| import json | |
| import sys | |
| import os | |
| import re | |
| filterwarnings('ignore') | |
| def chunks(l, n): | |
| """Yield successive n-sized chunks from l.""" | |
| for i in range(0, len(l), n): | |
| yield l[i:i+n] | |
| #https://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python/312464#312464 | |
| def natural_sort(l): | |
| convert = lambda text: int(text) if text.isdigit() else text.lower() | |
| alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] | |
| return sorted(l, key = alphanum_key) | |
| #https://stackoverflow.com/questions/4836710/does-python-have-a-built-in-function-for-string-natural-sort/4836734#4836734 | |
| def has_numbers(input_string): | |
| return any(char.isdigit() for char in input_string) | |
| #https://stackoverflow.com/questions/19859282/check-if-a-string-contains-a-number/19859308#19859308 | |
| def is_installed(module): | |
| try: | |
| __import__(module) | |
| except ImportError: | |
| return False | |
| return True | |
| parser = argparse.ArgumentParser(description='Dump a folder to a thread') | |
| parser.add_argument('-f','--folder', help='Folder to upload images from', type=str, required=True) | |
| parser.add_argument('-u','--url', help='URL of thread', required=True) | |
| parser.add_argument('-d','--delay', help='Delay between posting', type=int, required=True) | |
| parser.add_argument('-i','--images', help='Number of images to post', type=int) | |
| parser.add_argument('-n','--name', help='Name to post with', type=str, default='') | |
| parser.add_argument('-e','--email', help='Email to post with', type=str, default='') | |
| parser.add_argument('-p','--progress', help="Post with dump progress? (default y)", choices=('y', 'n'), default='y') | |
| #https://stackoverflow.com/questions/9234258/in-python-argparse-is-it-possible-to-have-paired-no-something-something-arg | |
| args = vars(parser.parse_args()) | |
| delay = args['delay'] | |
| DIRECTORY = args['folder'] | |
| filelist = [] | |
| for file in os.listdir(DIRECTORY): | |
| if os.path.splitext(file)[1].lower() in ('.jpg', '.jpeg', '.png', '.gif', '.webm', '.mp4'): | |
| filelist.append(os.path.join(DIRECTORY, file)) | |
| #I stole this from stackoverflow somewhere, I can't find the link | |
| if len(args['url'].split('/')) == 6: | |
| spliturl = args['url'].split('/') | |
| if has_numbers(spliturl[5]) and '.html' in args['url']: | |
| url = '{}//{}'.format(spliturl[0], spliturl[2]) | |
| board = spliturl[3] | |
| thread = spliturl[5].split('.')[0] | |
| else: | |
| sys.exit('\nBad URL. --u/--url should be the URL of a thread.\nExample: https://8ch.net/b/res/1.html') | |
| else: | |
| sys.exit('\nBad URL. --u/--url should be the URL of a thread.\nExample: https://8ch.net/b/res/1.html') | |
| boardindex = requests.get('{}/{}/index.html'.format(url, board)) | |
| if args['images'] == None: | |
| if is_installed('bs4') == True: | |
| from bs4 import BeautifulSoup | |
| soup = BeautifulSoup(boardindex.text) | |
| script_tag = str(soup.find_all('script')[1]) | |
| print('-i/--images not specified. Defaulting to the maximum number of allowed images on this board.') | |
| maxfiles = int(re.search('var max_images=[1-5]', script_tag).group(0).split('=')[1]) | |
| elif is_installed('bs4') == False: | |
| sys.exit('Unable to automatically detect the maximum number of images per post, please specify -i/--images') | |
| else: | |
| if args['images'] >= 1 and args['images'] <= 5: | |
| maxfiles = args['images'] | |
| else: | |
| sys.exit('-i/--images must be between 1 and 5') | |
| filelist = natural_sort(filelist) | |
| total = len(filelist) | |
| chunked_list = list(chunks(filelist, maxfiles)) | |
| r = requests.get('{}/settings.php?board={}'.format(url, board)) | |
| j = json.loads(r.text) | |
| if j['max_newlines'] != 0: | |
| max_newlines = j['max_newlines'] | |
| else: | |
| max_newlines = 100 | |
| data = { | |
| 'board' : board, | |
| 'thread' : thread, | |
| 'name' : args['name'], | |
| 'email' : args['email'], | |
| 'subject' : '', | |
| 'body' : '', | |
| 'embed' : '', | |
| 'dx' : '', | |
| 'dy' : '', | |
| 'dz' : '', | |
| 'password' : 'ayylmao', | |
| 'json_response' : '1', | |
| 'post' : 'New Reply', | |
| } | |
| headers = { | |
| 'referer' : '', | |
| 'user-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0', | |
| 'accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | |
| 'accept-language' : 'en-US,en;q=0.5', | |
| 'cache-control' : 'max-age=0', | |
| } | |
| headers['referer'] = '{}/{}/'.format(url, board) | |
| progress = maxfiles | |
| #csgrad.jpg | |
| for i in range(len(chunked_list)): | |
| number_of_files = len(chunked_list[i]) | |
| status = '' | |
| while 'redirect' not in status: | |
| for x in range(len(chunked_list[i])): | |
| l = natural_sort(chunked_list[i]) | |
| if number_of_files == 1: | |
| files = { | |
| 'file': open(l[0], 'rb'), | |
| } | |
| if number_of_files == 2: | |
| files = { | |
| 'file2': open(l[0], 'rb'), | |
| 'file': open(l[1], 'rb'), | |
| } | |
| if number_of_files == 3: | |
| files = { | |
| 'file3': open(l[0], 'rb'), | |
| 'file2': open(l[1], 'rb'), | |
| 'file': open(l[2], 'rb'), | |
| } | |
| if number_of_files == 4: | |
| files = { | |
| 'file3': open(l[0], 'rb'), | |
| 'file2': open(l[1], 'rb'), | |
| 'file5': open(l[2], 'rb'), | |
| 'file': open(l[3], 'rb'), | |
| } | |
| if number_of_files == 5: | |
| files = { | |
| 'file3': open(l[0], 'rb'), | |
| 'file2': open(l[1], 'rb'), | |
| 'file': open(l[3], 'rb'), | |
| 'file5': open(l[2], 'rb'), | |
| 'file4': open(l[4], 'rb'), | |
| } | |
| newlines = '\n' * randint(1, max_newlines) | |
| if progress > total: | |
| progress = total | |
| if args['progress'] == 'y': | |
| data['body'] = str(progress) + '/' + str(total) + newlines | |
| else: | |
| data['body'] = newlines | |
| status = requests.post(url + '/post.php', data=data, headers=headers, files=files).text | |
| print(status) | |
| if 'already exists' in status: | |
| status = 'redirect' | |
| del files | |
| print(str(progress) + '/' + str(total) + ' - Waiting ' + str(delay) + ' seconds...') | |
| sleep(delay) | |
| progress += number_of_files |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment