mirror of
https://github.com/KevinMidboe/bulk-downloader-for-reddit.git
synced 2026-01-26 02:55:36 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43cf0a4d42 | ||
|
|
3693cf46f8 | ||
|
|
04152e8554 | ||
|
|
210238d086 | ||
|
|
90e071354f | ||
|
|
426089d0f3 | ||
|
|
7ae6c6385d | ||
|
|
97d15f9974 | ||
|
|
172cd72dc1 | ||
|
|
af29492951 | ||
|
|
5633b301f3 | ||
|
|
5ed855af28 | ||
|
|
7ccf2fb7f9 | ||
|
|
2297e9ed86 | ||
|
|
401e014059 | ||
|
|
eb31d38c44 | ||
|
|
747fefea14 | ||
|
|
80cc4fade3 | ||
|
|
c26843c7fc | ||
|
|
a14edc9f5a |
42
README.md
42
README.md
@@ -1,7 +1,7 @@
|
|||||||
# Bulk Downloader for Reddit
|
# Bulk Downloader for Reddit
|
||||||
This program downloads imgur, gfycat and direct image and video links of saved posts from a reddit account. It is written in Python 3.
|
Downloads media from reddit posts.
|
||||||
|
|
||||||
**PLEASE** post any issue you have with the script to [Issues](https://github.com/aliparlakci/bulk-downloader-for-reddit/issues) tab. Since I don't have any testers or contributers I need your feedback.
|
## [Download the latest release](https://github.com/aliparlakci/bulk-downloader-for-reddit/releases/latest)
|
||||||
|
|
||||||
## What it can do
|
## What it can do
|
||||||
- Can get posts from: frontpage, subreddits, multireddits, redditor's submissions, upvoted and saved posts; search results or just plain reddit links
|
- Can get posts from: frontpage, subreddits, multireddits, redditor's submissions, upvoted and saved posts; search results or just plain reddit links
|
||||||
@@ -13,34 +13,17 @@ This program downloads imgur, gfycat and direct image and video links of saved p
|
|||||||
- Saves a reusable copy of posts' details that are found so that they can be re-downloaded again
|
- Saves a reusable copy of posts' details that are found so that they can be re-downloaded again
|
||||||
- Logs failed ones in a file to so that you can try to download them later
|
- Logs failed ones in a file to so that you can try to download them later
|
||||||
|
|
||||||
## [Download the latest release](https://github.com/aliparlakci/bulk-downloader-for-reddit/releases/latest)
|
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
- For **Windows** and **Linux** users, there are executable files to run easily without installing a third party program. But if you are a paranoid like me, you can **[compile it from source code](docs/COMPILE_FROM_SOURCE.md)**.
|
- For **Windows** and **Linux** users, there are executable files to run easily without installing a third party program. But if you are a paranoid like me, you can **[compile it from source code](docs/COMPILE_FROM_SOURCE.md)**.
|
||||||
- In Windows, double click on bulk-downloader-for-reddit file
|
|
||||||
- In Linux, extract files to a folder and open terminal inside it. Type **`./bulk-downloader-for-reddit`**
|
|
||||||
|
|
||||||
- **MacOS** users have to **[compile it from source code](docs/COMPILE_FROM_SOURCE.md)**.
|
- **MacOS** users have to **[compile it from source code](docs/COMPILE_FROM_SOURCE.md)**.
|
||||||
|
|
||||||
### Additional options
|
## Additional options
|
||||||
Script also accepts additional options via command-line arguments, get further information from **[`--help`](docs/COMMAND_LINE_ARGUMENTS.md)**
|
Script also accepts additional options via command-line arguments. Get further information from **[`--help`](docs/COMMAND_LINE_ARGUMENTS.md)**
|
||||||
|
|
||||||
## Setting up the script
|
## Setting up the script
|
||||||
Because this is not a commercial app, you need to create an imgur developer app in order API to work.
|
You need to create an imgur developer app in order API to work. Go to https://api.imgur.com/oauth2/addclient and fill the form (It does not really matter how you fill it). It should redirect you to a page where it shows your **imgur_client_id** and **imgur_client_secret**.
|
||||||
|
|
||||||
### Creating an imgur app
|
|
||||||
* Go to https://api.imgur.com/oauth2/addclient
|
|
||||||
* Enter a name into the **Application Name** field.
|
|
||||||
* Pick **Anonymous usage without user authorization** as an **Authorization type**\*
|
|
||||||
* Enter your email into the Email field.
|
|
||||||
* Correct CHAPTCHA
|
|
||||||
* Click **submit** button
|
|
||||||
|
|
||||||
It should redirect you to a page which shows your **imgur_client_id** and **imgur_client_secret**
|
|
||||||
|
|
||||||
\* Select **OAuth 2 authorization without a callback URL** first then select **Anonymous usage without user authorization** if it says *Authorization callback URL: required*. If this does not work, it is safe to proceed with **OAuth 2 authorization without a callback URL**.
|
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
### What do the dots resemble when getting posts?
|
### What do the dots resemble when getting posts?
|
||||||
- Each dot means that 100 posts are scanned.
|
- Each dot means that 100 posts are scanned.
|
||||||
@@ -48,7 +31,7 @@ It should redirect you to a page which shows your **imgur_client_id** and **imgu
|
|||||||
### Getting posts is taking too long.
|
### Getting posts is taking too long.
|
||||||
- You can press Ctrl+C to interrupt it and start downloading.
|
- You can press Ctrl+C to interrupt it and start downloading.
|
||||||
|
|
||||||
### How downloaded files' names are formatted?
|
### How are filenames formatted?
|
||||||
- Self posts and images that are not belong to an album are formatted as **`[SUBMITTER NAME]_[POST TITLE]_[REDDIT ID]`**.
|
- Self posts and images that are not belong to an album are formatted as **`[SUBMITTER NAME]_[POST TITLE]_[REDDIT ID]`**.
|
||||||
You can use *reddit id* to go to post's reddit page by going to link **reddit.com/[REDDIT ID]**
|
You can use *reddit id* to go to post's reddit page by going to link **reddit.com/[REDDIT ID]**
|
||||||
|
|
||||||
@@ -66,10 +49,19 @@ It should redirect you to a page which shows your **imgur_client_id** and **imgu
|
|||||||
them, there.
|
them, there.
|
||||||
|
|
||||||
## Changes on *master*
|
## Changes on *master*
|
||||||
|
### [06/08/2018](https://github.com/aliparlakci/bulk-downloader-for-reddit/tree/210238d0865febcb57fbd9f0b0a7d3da9dbff384)
|
||||||
|
- Sending headers when requesting a file in order not to be rejected by server
|
||||||
|
|
||||||
|
### [04/08/2018](https://github.com/aliparlakci/bulk-downloader-for-reddit/tree/426089d0f35212148caff0082708a87017757bde)
|
||||||
|
- Disabled printing post types to console
|
||||||
|
|
||||||
|
### [30/07/2018](https://github.com/aliparlakci/bulk-downloader-for-reddit/tree/af294929510f884d92b25eaa855c29fc4fb6dcaa)
|
||||||
|
- Now opens web browser and goes to Imgur when prompts for Imgur credentials
|
||||||
|
|
||||||
### [26/07/2018](https://github.com/aliparlakci/bulk-downloader-for-reddit/tree/1623722138bad80ae39ffcd5fb38baf80680deac)
|
### [26/07/2018](https://github.com/aliparlakci/bulk-downloader-for-reddit/tree/1623722138bad80ae39ffcd5fb38baf80680deac)
|
||||||
- Improved verbose mode
|
- Improved verbose mode
|
||||||
- Minimalized the console output
|
- Minimalized the console output
|
||||||
- Added quit option for auto quitting the program after process finished
|
- Added quit option for auto quitting the program after process finishes
|
||||||
|
|
||||||
### [25/07/2018](https://github.com/aliparlakci/bulk-downloader-for-reddit/tree/1623722138bad80ae39ffcd5fb38baf80680deac)
|
### [25/07/2018](https://github.com/aliparlakci/bulk-downloader-for-reddit/tree/1623722138bad80ae39ffcd5fb38baf80680deac)
|
||||||
- Added verbose mode
|
- Added verbose mode
|
||||||
|
|||||||
1
_config.yml
Normal file
1
_config.yml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
theme: jekyll-theme-cayman
|
||||||
32
script.py
32
script.py
@@ -10,10 +10,11 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
import webbrowser
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
|
|
||||||
from src.downloader import Direct, Gfycat, Imgur, Self, Erome
|
from src.downloader import Direct, Erome, Gfycat, Imgur, Self
|
||||||
from src.errors import *
|
from src.errors import *
|
||||||
from src.parser import LinkDesigner
|
from src.parser import LinkDesigner
|
||||||
from src.searcher import getPosts
|
from src.searcher import getPosts
|
||||||
@@ -22,7 +23,7 @@ from src.tools import (GLOBAL, createLogFile, jsonFile, nameCorrector,
|
|||||||
|
|
||||||
__author__ = "Ali Parlakci"
|
__author__ = "Ali Parlakci"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
__version__ = "1.6.0"
|
__version__ = "1.6.1"
|
||||||
__maintainer__ = "Ali Parlakci"
|
__maintainer__ = "Ali Parlakci"
|
||||||
__email__ = "parlakciali@gmail.com"
|
__email__ = "parlakciali@gmail.com"
|
||||||
|
|
||||||
@@ -38,20 +39,34 @@ def getConfig(configFileName):
|
|||||||
if "reddit_refresh_token" in content:
|
if "reddit_refresh_token" in content:
|
||||||
if content["reddit_refresh_token"] == "":
|
if content["reddit_refresh_token"] == "":
|
||||||
FILE.delete("reddit_refresh_token")
|
FILE.delete("reddit_refresh_token")
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
for key in keys:
|
for key in keys:
|
||||||
try:
|
try:
|
||||||
if content[key] == "":
|
if content[key] == "":
|
||||||
raise KeyError
|
raise KeyError
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print(key,": ")
|
FILE.add({key:input(" "+key+": ")})
|
||||||
FILE.add({key:input()})
|
|
||||||
return jsonFile(configFileName).read()
|
return jsonFile(configFileName).read()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
FILE = jsonFile(configFileName)
|
FILE = jsonFile(configFileName)
|
||||||
configDictionary = {}
|
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)
|
||||||
for key in keys:
|
for key in keys:
|
||||||
configDictionary[key] = input(key + ": ")
|
configDictionary[key] = input(" "+key+": ")
|
||||||
FILE.add(configDictionary)
|
FILE.add(configDictionary)
|
||||||
return FILE.read()
|
return FILE.read()
|
||||||
|
|
||||||
@@ -543,10 +558,9 @@ def download(submissions):
|
|||||||
FAILED_FILE = createLogFile("FAILED")
|
FAILED_FILE = createLogFile("FAILED")
|
||||||
|
|
||||||
for i in range(subsLenght):
|
for i in range(subsLenght):
|
||||||
print(
|
print(f"\n({i+1}/{subsLenght}) – r/{submissions[i]['postSubreddit']}",
|
||||||
f"\n({i+1}/{subsLenght}) – {submissions[i]['postType'].upper()} " \
|
end="")
|
||||||
f"– r/{submissions[i]['postSubreddit']}",end=""
|
print(f" – {submissions[i]['postType'].upper()}",end="",noPrint=True)
|
||||||
)
|
|
||||||
|
|
||||||
if isPostExists(submissions[i]):
|
if isPostExists(submissions[i]):
|
||||||
print("\nIt already exists")
|
print("\nIt already exists")
|
||||||
|
|||||||
@@ -54,6 +54,21 @@ def getFile(fileDir,tempDir,imageURL,indent=0):
|
|||||||
As too long file names seem not working.
|
As too long file names seem not working.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
headers = [
|
||||||
|
("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 " \
|
||||||
|
"(KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"),
|
||||||
|
("Accept", "text/html,application/xhtml+xml,application/xml;" \
|
||||||
|
"q=0.9,*/*;q=0.8"),
|
||||||
|
("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3"),
|
||||||
|
("Accept-Encoding", "none"),
|
||||||
|
("Accept-Language", "en-US,en;q=0.8"),
|
||||||
|
("Connection", "keep-alive")
|
||||||
|
]
|
||||||
|
|
||||||
|
opener = urllib.request.build_opener()
|
||||||
|
opener.addheaders = headers
|
||||||
|
urllib.request.install_opener(opener)
|
||||||
|
|
||||||
if not (os.path.isfile(fileDir)):
|
if not (os.path.isfile(fileDir)):
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ def redditSearcher(posts,SINGLE_POST=False):
|
|||||||
|
|
||||||
allPosts[subCount] = [details]
|
allPosts[subCount] = [details]
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("\nKeyboardInterrupt",end="")
|
print("\nKeyboardInterrupt",noPrint=True)
|
||||||
|
|
||||||
postsFile.add(allPosts)
|
postsFile.add(allPosts)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user