1
0
Fork 0
mirror of synced 2024-06-14 00:04:45 +12:00
bulk-downloader-for-reddit/script.py

739 lines
25 KiB
Python
Raw Normal View History

2018-07-10 07:58:11 +12:00
#!/usr/bin/env python
"""
This program downloads imgur, gfycat and direct image and video links of
saved posts from a reddit account. It is written in Python 3.
"""
import argparse
import logging
2018-07-10 07:58:11 +12:00
import os
import sys
import time
import webbrowser
from io import StringIO
2018-07-10 07:58:11 +12:00
from pathlib import Path, PurePath
from src.downloaders.Direct import Direct
from src.downloaders.Erome import Erome
from src.downloaders.Gfycat import Gfycat
from src.downloaders.Imgur import Imgur
from src.downloaders.redgifs import Redgifs
from src.downloaders.selfPost import SelfPost
from src.downloaders.gifDeliveryNetwork import GifDeliveryNetwork
from src.errors import *
2018-07-10 07:58:11 +12:00
from src.parser import LinkDesigner
from src.searcher import getPosts
from src.utils import (GLOBAL, createLogFile, jsonFile, nameCorrector,
2018-07-10 07:58:11 +12:00
printToFile)
__author__ = "Ali Parlakci"
__license__ = "GPL"
2019-04-10 05:45:22 +12:00
__version__ = "1.6.5"
2018-07-10 07:58:11 +12:00
__maintainer__ = "Ali Parlakci"
__email__ = "parlakciali@gmail.com"
def getConfig(configFileName):
"""Read credentials from config.json file"""
keys = ['imgur_client_id',
'imgur_client_secret']
if os.path.exists(configFileName):
FILE = jsonFile(configFileName)
content = FILE.read()
if "reddit_refresh_token" in content:
if content["reddit_refresh_token"] == "":
FILE.delete("reddit_refresh_token")
2018-07-30 22:36:27 +12:00
if not all(False if content.get(key,"") == "" else True for key in keys):
print(
"Go to this URL and fill the form: " \
"https://api.imgur.com/oauth2/addclient\n" \
"Enter the client id and client secret here:"
)
webbrowser.open("https://api.imgur.com/oauth2/addclient",new=2)
2018-07-10 07:58:11 +12:00
for key in keys:
try:
if content[key] == "":
raise KeyError
except KeyError:
FILE.add({key:input(" "+key+": ")})
2018-07-10 07:58:11 +12:00
return jsonFile(configFileName).read()
else:
FILE = jsonFile(configFileName)
configDictionary = {}
print(
"Go to this URL and fill the form: " \
"https://api.imgur.com/oauth2/addclient\n" \
"Enter the client id and client secret here:"
)
webbrowser.open("https://api.imgur.com/oauth2/addclient",new=2)
2018-07-10 07:58:11 +12:00
for key in keys:
configDictionary[key] = input(" "+key+": ")
2018-07-10 07:58:11 +12:00
FILE.add(configDictionary)
return FILE.read()
def parseArguments(arguments=[]):
"""Initialize argparse and add arguments"""
parser = argparse.ArgumentParser(allow_abbrev=False,
description="This program downloads " \
"media from reddit " \
"posts")
2018-07-25 22:40:06 +12:00
parser.add_argument("--directory","-d",
2018-07-10 07:58:11 +12:00
help="Specifies the directory where posts will be " \
"downloaded to",
metavar="DIRECTORY")
2018-07-26 20:15:13 +12:00
parser.add_argument("--NoDownload",
2018-07-26 20:59:29 +12:00
help="Just gets the posts and stores them in a file" \
2018-07-26 20:15:13 +12:00
" for downloading later",
action="store_true",
default=False)
parser.add_argument("--verbose","-v",
help="Verbose Mode",
action="store_true",
default=False)
parser.add_argument("--quit","-q",
2018-07-26 20:59:29 +12:00
help="Auto quit afer the process finishes",
2018-07-26 20:15:13 +12:00
action="store_true",
default=False)
2018-07-10 07:58:11 +12:00
parser.add_argument("--link","-l",
help="Get posts from link",
metavar="link")
parser.add_argument("--saved",
action="store_true",
help="Triggers saved mode")
parser.add_argument("--submitted",
action="store_true",
help="Gets posts of --user")
parser.add_argument("--upvoted",
action="store_true",
help="Gets upvoted posts of --user")
parser.add_argument("--log",
2018-07-12 08:24:15 +12:00
help="Takes a log file which created by itself " \
"(json files), reads posts and tries downloadin" \
"g them again.",
2018-07-10 07:58:11 +12:00
# type=argparse.FileType('r'),
metavar="LOG FILE")
parser.add_argument("--subreddit",
nargs="+",
help="Triggers subreddit mode and takes subreddit's " \
"name without r/. use \"frontpage\" for frontpage",
metavar="SUBREDDIT",
type=str)
parser.add_argument("--multireddit",
help="Triggers multireddit mode and takes "\
"multireddit's name without m/",
metavar="MULTIREDDIT",
type=str)
parser.add_argument("--user",
help="reddit username if needed. use \"me\" for " \
"current user",
required="--multireddit" in sys.argv or \
"--submitted" in sys.argv,
metavar="redditor",
type=str)
parser.add_argument("--search",
help="Searches for given query in given subreddits",
metavar="query",
type=str)
parser.add_argument("--sort",
help="Either hot, top, new, controversial, rising " \
"or relevance default: hot",
choices=[
"hot","top","new","controversial","rising",
"relevance"
],
metavar="SORT TYPE",
type=str)
parser.add_argument("--limit",
help="default: unlimited",
metavar="Limit",
type=int)
parser.add_argument("--time",
help="Either hour, day, week, month, year or all." \
" default: all",
choices=["all","hour","day","week","month","year"],
metavar="TIME_LIMIT",
type=str)
if arguments == []:
return parser.parse_args()
else:
return parser.parse_args(arguments)
def checkConflicts():
"""Check if command-line arguments are given correcly,
if not, raise errors
"""
if GLOBAL.arguments.user is None:
user = 0
else:
user = 1
2018-08-09 18:26:01 +12:00
search = 1 if GLOBAL.arguments.search else 0
modes = [
2018-08-09 18:26:01 +12:00
"saved","subreddit","submitted","log","link","upvoted","multireddit"
]
2018-07-12 04:25:24 +12:00
2018-07-12 07:18:54 +12:00
values = {
x: 0 if getattr(GLOBAL.arguments,x) is None or \
getattr(GLOBAL.arguments,x) is False \
else 1 \
for x in modes
}
2018-07-10 07:58:11 +12:00
2018-07-12 04:25:24 +12:00
if not sum(values[x] for x in values) == 1:
2018-07-12 04:57:38 +12:00
raise ProgramModeError("Invalid program mode")
2018-07-10 07:58:11 +12:00
2018-08-09 18:26:01 +12:00
if search+values["saved"] == 2:
2018-07-12 04:57:38 +12:00
raise SearchModeError("You cannot search in your saved posts")
2018-07-10 07:58:11 +12:00
2018-08-09 18:26:01 +12:00
if search+values["submitted"] == 2:
2018-07-12 04:57:38 +12:00
raise SearchModeError("You cannot search in submitted posts")
2018-07-10 07:58:11 +12:00
2018-08-09 18:26:01 +12:00
if search+values["upvoted"] == 2:
2018-07-12 04:57:38 +12:00
raise SearchModeError("You cannot search in upvoted posts")
2018-07-10 07:58:11 +12:00
2018-08-09 18:26:01 +12:00
if search+values["log"] == 2:
raise SearchModeError("You cannot search in log files")
2018-07-12 04:25:24 +12:00
if values["upvoted"]+values["submitted"] == 1 and user == 0:
2018-07-12 04:57:38 +12:00
raise RedditorNameError("No redditor name given")
2018-07-10 07:58:11 +12:00
2018-07-12 03:59:17 +12:00
class PromptUser:
2018-07-12 03:40:40 +12:00
@staticmethod
def chooseFrom(choices):
print()
choicesByIndex = list(str(x) for x in range(len(choices)+1))
for i in range(len(choices)):
print("{indent}[{order}] {mode}".format(
indent=" "*4,order=i+1,mode=choices[i]
))
print(" "*4+"[0] exit\n")
choice = input("> ")
while not choice.lower() in choices+choicesByIndex+["exit"]:
2018-07-12 03:40:40 +12:00
print("Invalid input\n")
programModeIndex = input("> ")
2018-07-13 07:00:43 +12:00
if choice == "0" or choice == "exit":
2018-07-12 22:00:02 +12:00
sys.exit()
2018-07-12 03:40:40 +12:00
elif choice in choicesByIndex:
return choices[int(choice)-1]
else:
return choice
def __init__(self):
2018-07-12 03:56:39 +12:00
print("select program mode:")
2018-07-12 03:40:40 +12:00
programModes = [
"search","subreddit","multireddit",
"submitted","upvoted","saved","log"
]
programMode = self.chooseFrom(programModes)
if programMode == "search":
2018-07-12 08:27:16 +12:00
GLOBAL.arguments.search = input("\nquery: ")
GLOBAL.arguments.subreddit = input("\nsubreddit: ")
2018-07-12 03:40:40 +12:00
2018-07-12 03:56:39 +12:00
print("\nselect sort type:")
2018-07-12 03:40:40 +12:00
sortTypes = [
"relevance","top","new"
]
sortType = self.chooseFrom(sortTypes)
GLOBAL.arguments.sort = sortType
2018-07-12 03:56:39 +12:00
print("\nselect time filter:")
2018-07-12 03:40:40 +12:00
timeFilters = [
"hour","day","week","month","year","all"
]
timeFilter = self.chooseFrom(timeFilters)
GLOBAL.arguments.time = timeFilter
if programMode == "subreddit":
2018-07-13 07:00:43 +12:00
2019-01-28 01:59:24 +13:00
subredditInput = input("(type frontpage for all subscribed subreddits,\n" \
" use plus to seperate multi subreddits:" \
" pics+funny+me_irl etc.)\n\n" \
"subreddit: ")
2018-07-13 07:00:43 +12:00
GLOBAL.arguments.subreddit = subredditInput
2019-01-28 01:59:24 +13:00
# while not (subredditInput == "" or subredditInput.lower() == "frontpage"):
# subredditInput = input("subreddit: ")
# GLOBAL.arguments.subreddit += "+" + subredditInput
2018-07-13 07:00:43 +12:00
2018-07-12 03:40:40 +12:00
if " " in GLOBAL.arguments.subreddit:
GLOBAL.arguments.subreddit = "+".join(GLOBAL.arguments.subreddit.split())
2018-07-13 07:00:43 +12:00
# DELETE THE PLUS (+) AT THE END
2019-01-28 03:05:31 +13:00
if not subredditInput.lower() == "frontpage" \
and GLOBAL.arguments.subreddit[-1] == "+":
2018-07-24 07:57:54 +12:00
GLOBAL.arguments.subreddit = GLOBAL.arguments.subreddit[:-1]
2018-07-13 07:00:43 +12:00
2018-07-12 03:56:39 +12:00
print("\nselect sort type:")
2018-07-12 03:40:40 +12:00
sortTypes = [
"hot","top","new","rising","controversial"
]
sortType = self.chooseFrom(sortTypes)
GLOBAL.arguments.sort = sortType
if sortType in ["top","controversial"]:
2018-07-12 03:56:39 +12:00
print("\nselect time filter:")
2018-07-12 03:40:40 +12:00
timeFilters = [
"hour","day","week","month","year","all"
]
timeFilter = self.chooseFrom(timeFilters)
GLOBAL.arguments.time = timeFilter
else:
GLOBAL.arguments.time = "all"
2018-07-12 06:25:45 +12:00
elif programMode == "multireddit":
2019-01-28 01:59:24 +13:00
GLOBAL.arguments.user = input("\nmultireddit owner: ")
GLOBAL.arguments.multireddit = input("\nmultireddit: ")
2018-07-12 03:40:40 +12:00
2018-07-12 03:56:39 +12:00
print("\nselect sort type:")
2018-07-12 03:40:40 +12:00
sortTypes = [
"hot","top","new","rising","controversial"
]
sortType = self.chooseFrom(sortTypes)
GLOBAL.arguments.sort = sortType
if sortType in ["top","controversial"]:
2018-07-12 03:56:39 +12:00
print("\nselect time filter:")
2018-07-12 03:40:40 +12:00
timeFilters = [
"hour","day","week","month","year","all"
]
timeFilter = self.chooseFrom(timeFilters)
GLOBAL.arguments.time = timeFilter
else:
GLOBAL.arguments.time = "all"
elif programMode == "submitted":
GLOBAL.arguments.submitted = True
2018-07-12 08:27:16 +12:00
GLOBAL.arguments.user = input("\nredditor: ")
2018-07-12 06:25:45 +12:00
print("\nselect sort type:")
sortTypes = [
"hot","top","new","controversial"
]
sortType = self.chooseFrom(sortTypes)
GLOBAL.arguments.sort = sortType
if sortType == "top":
print("\nselect time filter:")
timeFilters = [
"hour","day","week","month","year","all"
]
timeFilter = self.chooseFrom(timeFilters)
GLOBAL.arguments.time = timeFilter
else:
GLOBAL.arguments.time = "all"
2018-07-12 03:40:40 +12:00
elif programMode == "upvoted":
GLOBAL.arguments.upvoted = True
2018-07-12 08:27:16 +12:00
GLOBAL.arguments.user = input("\nredditor: ")
2018-07-12 03:40:40 +12:00
elif programMode == "saved":
GLOBAL.arguments.saved = True
elif programMode == "log":
2018-07-12 06:25:45 +12:00
while True:
2018-07-12 08:27:16 +12:00
GLOBAL.arguments.log = input("\nlog file directory:")
2018-07-12 06:25:45 +12:00
if Path(GLOBAL.arguments.log ).is_file():
break
while True:
try:
2018-07-20 22:01:21 +12:00
GLOBAL.arguments.limit = int(input("\nlimit (0 for none): "))
if GLOBAL.arguments.limit == 0:
GLOBAL.arguments.limit = None
2018-07-12 06:25:45 +12:00
break
except ValueError:
pass
2018-07-12 03:40:40 +12:00
2018-07-12 03:56:39 +12:00
def prepareAttributes():
ATTRIBUTES = {}
if GLOBAL.arguments.user is not None:
ATTRIBUTES["user"] = GLOBAL.arguments.user
if GLOBAL.arguments.search is not None:
ATTRIBUTES["search"] = GLOBAL.arguments.search
if GLOBAL.arguments.sort == "hot" or \
GLOBAL.arguments.sort == "controversial" or \
GLOBAL.arguments.sort == "rising":
GLOBAL.arguments.sort = "relevance"
if GLOBAL.arguments.sort is not None:
ATTRIBUTES["sort"] = GLOBAL.arguments.sort
else:
if GLOBAL.arguments.submitted:
ATTRIBUTES["sort"] = "new"
else:
ATTRIBUTES["sort"] = "hot"
if GLOBAL.arguments.time is not None:
ATTRIBUTES["time"] = GLOBAL.arguments.time
else:
ATTRIBUTES["time"] = "all"
if GLOBAL.arguments.link is not None:
GLOBAL.arguments.link = GLOBAL.arguments.link.strip("\"")
2018-08-09 09:17:04 +12:00
ATTRIBUTES = LinkDesigner(GLOBAL.arguments.link)
2018-07-12 03:56:39 +12:00
if GLOBAL.arguments.search is not None:
ATTRIBUTES["search"] = GLOBAL.arguments.search
if GLOBAL.arguments.sort is not None:
ATTRIBUTES["sort"] = GLOBAL.arguments.sort
if GLOBAL.arguments.time is not None:
ATTRIBUTES["time"] = GLOBAL.arguments.time
elif GLOBAL.arguments.subreddit is not None:
if type(GLOBAL.arguments.subreddit) == list:
GLOBAL.arguments.subreddit = "+".join(GLOBAL.arguments.subreddit)
ATTRIBUTES["subreddit"] = GLOBAL.arguments.subreddit
elif GLOBAL.arguments.multireddit is not None:
ATTRIBUTES["multireddit"] = GLOBAL.arguments.multireddit
2018-07-12 03:56:39 +12:00
elif GLOBAL.arguments.saved is True:
ATTRIBUTES["saved"] = True
elif GLOBAL.arguments.upvoted is True:
ATTRIBUTES["upvoted"] = True
elif GLOBAL.arguments.submitted is not None:
ATTRIBUTES["submitted"] = True
if GLOBAL.arguments.sort == "rising":
2018-08-09 09:17:04 +12:00
raise InvalidSortingType("Invalid sorting type has given")
2018-07-12 03:56:39 +12:00
ATTRIBUTES["limit"] = GLOBAL.arguments.limit
return ATTRIBUTES
def postFromLog(fileName):
"""Analyze a log file and return a list of dictionaries containing
submissions
"""
if Path.is_file(Path(fileName)):
content = jsonFile(fileName).read()
else:
print("File not found")
2018-07-12 22:00:02 +12:00
sys.exit()
2018-07-12 03:56:39 +12:00
try:
del content["HEADER"]
except KeyError:
pass
posts = []
for post in content:
if not content[post][-1]['postType'] == None:
posts.append(content[post][-1])
return posts
2018-07-25 03:55:33 +12:00
def isPostExists(POST):
2018-07-10 07:58:11 +12:00
"""Figure out a file's name and checks if the file already exists"""
title = nameCorrector(POST['postTitle'])
PATH = GLOBAL.directory / POST["postSubreddit"]
2018-07-24 21:44:53 +12:00
2018-07-10 12:12:24 +12:00
possibleExtensions = [".jpg",".png",".mp4",".gif",".webm",".md"]
2018-07-10 07:58:11 +12:00
"""If you change the filenames, don't forget to add them here.
Please don't remove existing ones
"""
2018-07-24 21:44:53 +12:00
for extension in possibleExtensions:
OLD_FILE_PATH = PATH / (
title
+ "_" + POST['postId']
+ extension
)
FILE_PATH = PATH / (
2018-07-25 03:55:33 +12:00
POST["postSubmitter"]
+ "_" + title
2018-07-24 21:44:53 +12:00
+ "_" + POST['postId']
+ extension
)
SHORT_FILE_PATH = PATH / (POST['postId']+extension)
2018-07-24 22:17:14 +12:00
if OLD_FILE_PATH.exists() or \
FILE_PATH.exists() or \
SHORT_FILE_PATH.exists():
2018-07-24 21:44:53 +12:00
return True
2018-07-24 22:17:14 +12:00
2018-07-10 07:58:11 +12:00
else:
return False
2018-07-24 07:57:54 +12:00
def downloadPost(SUBMISSION):
"""Download directory is declared here for each file"""
2018-07-24 07:06:33 +12:00
directory = GLOBAL.directory / SUBMISSION['postSubreddit']
2018-07-10 07:58:11 +12:00
2018-07-24 07:06:33 +12:00
global lastRequestTime
2018-07-23 02:25:30 +12:00
2018-07-24 08:16:56 +12:00
downloaders = {
"imgur":Imgur,"gfycat":Gfycat,"erome":Erome,"direct":Direct,"self":SelfPost,
"redgifs":Redgifs, "gifdeliverynetwork": GifDeliveryNetwork
2018-07-24 08:16:56 +12:00
}
2018-07-10 07:58:11 +12:00
2018-07-25 21:24:50 +12:00
print()
2018-07-24 07:57:54 +12:00
if SUBMISSION['postType'] in downloaders:
2018-07-10 07:58:11 +12:00
2018-07-24 07:06:33 +12:00
if SUBMISSION['postType'] == "imgur":
2018-07-10 07:58:11 +12:00
2018-07-25 18:27:41 +12:00
while int(time.time() - lastRequestTime) <= 2:
2018-07-10 07:58:11 +12:00
pass
2018-07-24 07:06:33 +12:00
2018-07-10 07:58:11 +12:00
credit = Imgur.get_credits()
IMGUR_RESET_TIME = credit['UserReset']-time.time()
USER_RESET = ("after " \
2018-07-24 07:06:33 +12:00
+ str(int(IMGUR_RESET_TIME/60)) \
+ " Minutes " \
+ str(int(IMGUR_RESET_TIME%60)) \
+ " Seconds")
2018-07-26 20:08:37 +12:00
2018-07-25 21:24:50 +12:00
if credit['ClientRemaining'] < 25 or credit['UserRemaining'] < 25:
2018-07-26 20:08:37 +12:00
printCredit = {"noPrint":False}
else:
printCredit = {"noPrint":True}
print(
"==> Client: {} - User: {} - Reset {}\n".format(
credit['ClientRemaining'],
credit['UserRemaining'],
USER_RESET
),end="",**printCredit
)
2018-07-10 07:58:11 +12:00
if not (credit['UserRemaining'] == 0 or \
credit['ClientRemaining'] == 0):
"""This block of code is needed for API workaround
2018-07-10 07:58:11 +12:00
"""
2018-07-25 18:27:41 +12:00
while int(time.time() - lastRequestTime) <= 2:
2018-07-10 07:58:11 +12:00
pass
2018-07-24 07:06:33 +12:00
lastRequestTime = time.time()
2018-07-10 07:58:11 +12:00
else:
if credit['UserRemaining'] == 0:
KEYWORD = "user"
elif credit['ClientRemaining'] == 0:
KEYWORD = "client"
2018-07-24 07:06:33 +12:00
raise ImgurLimitError('{} LIMIT EXCEEDED\n'.format(KEYWORD.upper()))
2018-07-10 07:58:11 +12:00
2018-07-24 07:06:33 +12:00
downloaders[SUBMISSION['postType']] (directory,SUBMISSION)
2018-07-10 07:58:11 +12:00
2018-07-24 07:06:33 +12:00
else:
raise NoSuitablePost
return None
def download(submissions):
"""Analyze list of submissions and call the right function
to download each one, catch errors, update the log files
"""
subsLenght = len(submissions)
global lastRequestTime
lastRequestTime = 0
downloadedCount = subsLenght
duplicates = 0
FAILED_FILE = createLogFile("FAILED")
2018-07-10 07:58:11 +12:00
2018-07-24 07:06:33 +12:00
for i in range(subsLenght):
print(f"\n({i+1}/{subsLenght}) {submissions[i]['postId']} r/{submissions[i]['postSubreddit']}",
2018-08-04 19:22:41 +12:00
end="")
print(f" {submissions[i]['postType'].upper()}",end="",noPrint=True)
2018-07-10 07:58:11 +12:00
2018-07-25 03:55:33 +12:00
if isPostExists(submissions[i]):
2018-08-18 23:51:20 +12:00
print(f"\n" \
f"{submissions[i]['postSubmitter']}_"
f"{nameCorrector(submissions[i]['postTitle'])}")
2018-08-16 06:46:27 +12:00
print("It already exists")
2018-07-24 07:06:33 +12:00
duplicates += 1
downloadedCount -= 1
continue
try:
2018-07-24 07:57:54 +12:00
downloadPost(submissions[i])
2018-07-10 10:30:50 +12:00
2018-07-24 07:06:33 +12:00
except FileAlreadyExistsError:
print("It already exists")
duplicates += 1
downloadedCount -= 1
2018-07-10 10:30:50 +12:00
2018-07-24 07:06:33 +12:00
except ImgurLoginError:
print(
"Imgur login failed. \nQuitting the program "\
"as unexpected errors might occur."
)
sys.exit()
2018-07-10 10:30:50 +12:00
2018-07-24 07:06:33 +12:00
except ImgurLimitError as exception:
2018-07-25 04:27:52 +12:00
FAILED_FILE.add({int(i+1):[
"{class_name}: {info}".format(
class_name=exception.__class__.__name__,info=str(exception)
),
submissions[i]
]})
2018-07-24 07:06:33 +12:00
downloadedCount -= 1
2018-07-10 10:30:50 +12:00
2018-07-24 07:06:33 +12:00
except NotADownloadableLinkError as exception:
2018-07-25 04:27:52 +12:00
print(
"{class_name}: {info}".format(
class_name=exception.__class__.__name__,info=str(exception)
)
)
FAILED_FILE.add({int(i+1):[
"{class_name}: {info}".format(
class_name=exception.__class__.__name__,info=str(exception)
),
submissions[i]
]})
2018-07-24 07:06:33 +12:00
downloadedCount -= 1
except NoSuitablePost:
2018-07-10 07:58:11 +12:00
print("No match found, skipping...")
downloadedCount -= 1
2018-07-24 07:06:33 +12:00
except Exception as exception:
# raise exception
2018-07-25 04:27:52 +12:00
print(
"{class_name}: {info}".format(
class_name=exception.__class__.__name__,info=str(exception)
)
)
FAILED_FILE.add({int(i+1):[
"{class_name}: {info}".format(
class_name=exception.__class__.__name__,info=str(exception)
),
submissions[i]
]})
2018-07-24 07:06:33 +12:00
downloadedCount -= 1
2018-07-10 07:58:11 +12:00
if duplicates:
2018-08-24 01:41:07 +12:00
print(f"\nThere {'were' if duplicates > 1 else 'was'} " \
f"{duplicates} duplicate{'s' if duplicates > 1 else ''}")
2018-07-10 07:58:11 +12:00
if downloadedCount == 0:
2018-08-24 01:41:07 +12:00
print("Nothing downloaded :(")
2018-07-10 07:58:11 +12:00
else:
2018-08-24 01:41:07 +12:00
print(f"Total of {downloadedCount} " \
f"link{'s' if downloadedCount > 1 else ''} downloaded!")
2018-07-10 07:58:11 +12:00
def main():
2018-08-18 06:25:01 +12:00
2018-08-18 23:51:20 +12:00
VanillaPrint(
2019-01-28 01:59:24 +13:00
f"\nBulk Downloader for Reddit v{__version__}\n" \
f"Written by Ali PARLAKCI parlakciali@gmail.com\n\n" \
f"https://github.com/aliparlakci/bulk-downloader-for-reddit/"
2018-08-18 23:51:20 +12:00
)
2018-07-12 03:40:40 +12:00
GLOBAL.arguments = parseArguments()
2018-07-10 07:58:11 +12:00
if GLOBAL.arguments.directory is not None:
2018-08-29 01:24:14 +12:00
GLOBAL.directory = Path(GLOBAL.arguments.directory.strip())
2018-07-10 07:58:11 +12:00
else:
2019-01-28 01:59:24 +13:00
GLOBAL.directory = Path(input("\ndownload directory: ").strip())
2018-07-12 03:40:40 +12:00
2018-07-26 19:08:57 +12:00
print("\n"," ".join(sys.argv),"\n",noPrint=True)
2018-08-18 23:51:20 +12:00
print(f"Bulk Downloader for Reddit v{__version__}\n",noPrint=True
)
2018-07-12 04:31:32 +12:00
2018-07-12 04:57:38 +12:00
try:
2018-07-12 03:56:39 +12:00
checkConflicts()
2018-07-12 04:57:38 +12:00
except ProgramModeError as err:
PromptUser()
2018-07-10 07:58:11 +12:00
2019-04-10 05:31:42 +12:00
if not Path(GLOBAL.defaultConfigDirectory).is_dir():
os.makedirs(GLOBAL.defaultConfigDirectory)
2019-02-24 22:28:40 +13:00
2019-04-09 07:09:52 +12:00
if Path("config.json").exists():
GLOBAL.configDirectory = Path("config.json")
else:
GLOBAL.configDirectory = GLOBAL.defaultConfigDirectory / "config.json"
2019-02-24 22:28:40 +13:00
GLOBAL.config = getConfig(GLOBAL.configDirectory)
2018-07-10 07:58:11 +12:00
if GLOBAL.arguments.log is not None:
logDir = Path(GLOBAL.arguments.log)
download(postFromLog(logDir))
2018-07-12 22:00:02 +12:00
sys.exit()
2018-08-11 04:50:52 +12:00
try:
POSTS = getPosts(prepareAttributes())
except Exception as exc:
logging.error(sys.exc_info()[0].__name__,
exc_info=full_exc_info(sys.exc_info()))
print(log_stream.getvalue(),noPrint=True)
print(exc)
sys.exit()
2018-07-10 07:58:11 +12:00
if POSTS is None:
print("I could not find any posts in that URL")
2018-07-12 22:00:02 +12:00
sys.exit()
2018-07-10 07:58:11 +12:00
if GLOBAL.arguments.NoDownload:
2018-07-12 22:00:02 +12:00
sys.exit()
2018-07-10 07:58:11 +12:00
else:
download(POSTS)
if __name__ == "__main__":
log_stream = StringIO()
logging.basicConfig(stream=log_stream, level=logging.INFO)
2018-07-10 07:58:11 +12:00
try:
VanillaPrint = print
print = printToFile
GLOBAL.RUN_TIME = time.time()
main()
2018-07-24 07:06:33 +12:00
2018-07-10 07:58:11 +12:00
except KeyboardInterrupt:
if GLOBAL.directory is None:
GLOBAL.directory = Path(".\\")
2018-07-24 07:06:33 +12:00
except Exception as exception:
2018-07-22 06:50:54 +12:00
if GLOBAL.directory is None:
GLOBAL.directory = Path(".\\")
logging.error(sys.exc_info()[0].__name__,
exc_info=full_exc_info(sys.exc_info()))
print(log_stream.getvalue())
2018-07-26 20:15:13 +12:00
if not GLOBAL.arguments.quit: input("\nPress enter to quit\n")