110 lines
3.4 KiB
Python
110 lines
3.4 KiB
Python
#!/usr/bin/python3
|
|
|
|
"""This script allows you to download files of any size from GDrive
|
|
Licensed under GNU GPLv3+ terms.
|
|
(c) 2023, xxx_stroboscope_420_xxx
|
|
"""
|
|
|
|
import sys
|
|
import requests
|
|
|
|
|
|
USAGE_TEXT = """
|
|
Usage: python3 gdown.py <URL> [options]
|
|
-l, --large-file
|
|
Treat downloadable file as large. By default, it is detected automatically.
|
|
--output=<path>
|
|
Path to output file.
|
|
"""
|
|
UA = "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0"
|
|
FILE_TOO_LARGE_TEXT = "is too large for Google to scan for viruses.\
|
|
Would you still like to download this file?"
|
|
|
|
output_file = None
|
|
url = None
|
|
url_id = None
|
|
large = False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print(USAGE_TEXT)
|
|
sys.exit(1)
|
|
|
|
for arg in sys.argv:
|
|
if arg.startswith("--output="):
|
|
output_file = arg[9:]
|
|
elif arg.startswith("-l") or arg.startswith("--large-file"):
|
|
large = True
|
|
else:
|
|
tmp_url = url = arg
|
|
if tmp_url.lower().startswith("https://"):
|
|
tmp_url = tmp_url[8:]
|
|
if tmp_url.lower().startswith("drive.google.com/"):
|
|
tmp_url = tmp_url[17:]
|
|
if tmp_url.lower().startswith("drive/folders/"):
|
|
tmp_url = tmp_url[14:]
|
|
if tmp_url.lower().startswith("file/d/"):
|
|
tmp_url = tmp_url[7:]
|
|
if tmp_url.lower().endswith("?usp=sharing"):
|
|
tmp_url = tmp_url[:-12]
|
|
if tmp_url.lower().endswith("?usp=share_link"):
|
|
tmp_url = tmp_url[:-15]
|
|
if tmp_url.lower().endswith("/view"):
|
|
tmp_url = tmp_url[:-5]
|
|
url_id = tmp_url
|
|
|
|
print(f"Given URL/ID: {url}")
|
|
print(f"Got ID: {url_id}")
|
|
if output_file:
|
|
print(f"Output file: {output_file}")
|
|
|
|
resp_cook = requests.get(
|
|
f"https://docs.google.com/uc?export=download&id={url_id}",
|
|
headers={"User-Agent": UA},
|
|
# verify=False,
|
|
allow_redirects=True,
|
|
timeout=360
|
|
)
|
|
|
|
if "html" in resp_cook.headers.get("content-type"):
|
|
if (not large) and (FILE_TOO_LARGE_TEXT in resp_cook.text):
|
|
print("Detected large file")
|
|
large = True
|
|
elif resp_cook.status_code == 404:
|
|
print("File not found, check your URL and try again")
|
|
sys.exit(3)
|
|
elif large and (not FILE_TOO_LARGE_TEXT in resp_cook.text):
|
|
print("Seems like file isn't large. Remove '-l' key and try again")
|
|
sys.exit(2)
|
|
|
|
if large:
|
|
print("Download in progress, please wait...", end=" ")
|
|
sys.stdout.flush()
|
|
resp_res = requests.get(
|
|
f"https://docs.google.com/uc?export=download&confirm=1&id={url_id}",
|
|
headers={"User-Agent": UA},
|
|
cookies=resp_cook.cookies,
|
|
# verify=False,
|
|
allow_redirects=True,
|
|
timeout=360
|
|
)
|
|
print("done")
|
|
else:
|
|
resp_res = resp_cook
|
|
|
|
if resp_res.headers.get("content-disposition") and (not output_file):
|
|
temp = resp_res.headers.get("content-disposition").split("; ")
|
|
for t in temp:
|
|
if t.startswith("filename="):
|
|
output_file = t[10:-1]
|
|
print(f"Detected file name: {output_file}")
|
|
break
|
|
|
|
if not output_file:
|
|
print("Failed to detect file name, using fallback")
|
|
output_file = "gdown_output"
|
|
|
|
with open(output_file, "wb") as fd:
|
|
fd.write(resp_res.content)
|