Repository: jonathanTIE/googledrive-copy-downloader
Branch: master
Commit: 08c091ac7fd1
Files: 7
Total size: 15.6 KB
Directory structure:
gitextract_wmit1el9/
├── GoogleAuthManager.py
├── GoogleAuthV1.py
├── GoogleAuthV2.py
├── README.md
├── gDriveCopyDownloader.py
├── gDriveLibrary.py
└── requirements.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: GoogleAuthManager.py
================================================
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from os import path
def create_credential():
from GoogleAuthV1 import auth_and_save_credential
auth_and_save_credential()
# Authentication + token creation
def create_drive_manager():
gAuth = GoogleAuth()
typeOfAuth = None
if not path.exists("credentials.txt"):
typeOfAuth = input("type save if you want to keep a credential file, else type nothing")
bool = True if typeOfAuth == "save" or path.exists("credentials.txt") else False
authorize_from_credential(gAuth, bool)
drive: GoogleDrive = GoogleDrive(gAuth)
return drive
def authorize_from_credential(gAuth, isSaved):
if not isSaved: #no credential.txt wanted
from GoogleAuthV1 import auth_no_save
auth_no_save(gAuth)
if isSaved and not path.exists("credentials.txt"):
create_credential()
gAuth.LoadCredentialsFile("credentials.txt")
if isSaved and gAuth.access_token_expired:
gAuth.LoadCredentialsFile("credentials.txt")
gAuth.Refresh()
print("token refreshed!")
gAuth.SaveCredentialsFile("credentials.txt")
gAuth.Authorize()
print("authorized access to google drive API!")
================================================
FILE: GoogleAuthV1.py
================================================
from pydrive.auth import GoogleAuth
def auth_and_save_credential():
gAuth = GoogleAuth()
gAuth.LocalWebserverAuth()
gAuth.SaveCredentialsFile("credentials.txt")
def auth_no_save(gAuth):
gAuth.LocalWebserverAuth()
================================================
FILE: GoogleAuthV2.py
================================================
from pydrive.auth import GoogleAuth
import webbrowser
# https://realpython.com/flask-google-login/#creating-a-google-client
from flask import Flask, redirect, request, url_for
from flask_login import LoginManager
from oauthlib.oauth2 import WebApplicationClient
import requests
GOOGLE_DISCOVERY_URL = (
"https://accounts.google.com/.well-known/openid-configuration"
)
class FlaskModified(Flask):
def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
with self.app_context():
webbrowser.open('https://127.0.0.1:5000') #default url and port for Flask app
pass
super(FlaskModified, self).run(host=host, port=port, debug=debug, load_dotenv=load_dotenv, **options)
app = FlaskModified(__name__)
gAuth = GoogleAuth()
auth_url = gAuth.GetAuthUrl()
@app.route("/")
def index():
return '<a class="button" href="/login">Google Login</a>'
@app.route("/login")
def login():
return redirect(auth_url)
@app.route("/login/callback")
def callback():
code = request.args.get("code")
print("code : " + code)
gAuth.Auth(code)
return redirect(url_for("index"))
def auth_and_save_credential():
app.run(debug="true", ssl_context="adhoc")
#app.run(debug="true", ssl_context="adhoc")
================================================
FILE: README.md
================================================
# googledrive-copy-downloader
This python script allow you to download google drive files even if the daily limit of download has excedeed using google drive API easily from the download link(s).
It automatically copy the file to the google drive of the account that is provided, download the file and delete it, and it supports multiple links at once.
## How to use :
First, you need to add a Google application credentials(clients_secrets.json) that can access the Google drive API from your account.
To do that, the quickest way is to :
* Go to : https://developers.google.com/drive/api/v3/quickstart/python
* Click on enable drive API
* Download client configuration
* Rename this file client_secrets.json
* Replace the one in the folder with the script (in the same place as the .exe)
* (Optional) After the first launch, you can change settings in the config.ini file (download location, dowloading directly the links from the clipboard or (hasn't been tested) modify folderId with the ID of a folder on a google drive team)
#### You can launch it directly using python :
Use preferably python 3.6, install the requirement on the requirements.txt file with pip and launch gDriveCopyDownloader.py.
#### You can use the release (Windows Only):
You just need to download the .zip, and launch the exe.
#### You can make yourself the .exe :
Use auto-py-to-exe or pyinstaller, select gDriveCopyDownloader as the input.
Then you can follow the instructions on the script. Careful if you store the credentials (to avoid log-in every time), it keeps them in plain text and it can give access to your google drive(If you don't store anything sensitive and you don't care if your google drive is hacked it isn't a problem).
Also, the clipboard feature supports multiple hyperlinks.
### Common issues :
* crash on startup :
Check the How to use section, the client secret could be missing.
* "This app has not been verified yet" or any other issues with client_secrets :
Check the How to use section.
* Space issues :
the script could crash itself if there is not enough space on your google drive, be sure to check the bin.
* Authentication problems :
If you have any app that communicate through localhost:8080 (like Kodi), the authentication with google servers may not works.
### Known limitations :
* clipboard feature only works on Windows.
* There might be somme issues with linux(getting the default download folder for example).
* Currently, the script only support links with that end with : /d/XXXX, /id=XXX and /folders/XXXX .
* The script doesn't display the speed of download in real-time.
* It doesn't work with google files(sheet, docs,...).
================================================
FILE: gDriveCopyDownloader.py
================================================
import os
import GoogleAuthManager
import gDriveLibrary
import configparser
import asyncio
CONFIG = configparser.ConfigParser()
CONFIG.optionxform=str
DATABASE = CONFIG['DEFAULT']
def get_default_download_location():
if os.name == 'nt': # if windows
import winreg
sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}'
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
location = winreg.QueryValueEx(key, downloads_guid)[0]
return location
else:
return os.path.join(os.path.expanduser('~'), 'downloads')
def read_config():
CONFIG.read('config.ini')
def write_config():
if 'ClipboardDetection' not in DATABASE:
DATABASE['ClipboardDetection'] = "0"
with open("config.ini", "w+") as file:
CONFIG.write(file)
def get_location():
read_config()
if 'DownloadPath' in DATABASE and os.path.exists(DATABASE['DownloadPath'] ):
return DATABASE['DownloadPath']
print("Default location is : " + get_default_download_location())
while 1:
otherPath = input("\nif you want another location, write it here or else press enter\n")
if os.path.exists(otherPath):
break
if otherPath == "":
otherPath = get_default_download_location()
break
DATABASE['DownloadPath'] = otherPath
write_config()
return otherPath
def get_folder_id():
if not 'FolderId' in DATABASE:
DATABASE['FolderId'] = 'root'
write_config()
return DATABASE['FolderId']
def Copy_dwnld_from_links(links, drive):
for fileID in gDriveLibrary.extract_files_id(links, drive):
copiedFile = gDriveLibrary.copy_file(drive, fileID, get_folder_id())
gDriveLibrary.download_file(drive, copiedFile, get_location())
gDriveLibrary.delete_file(drive, copiedFile['id'])
async def Check_clipboard_links(drive): #Only works for windows
# Ressource : https://stackoverflow.com/questions/55698762/how-to-copy-html-code-to-clipboard-using-python
if os.name == 'nt':
import win32clipboard
else:
raise OSError("os isn't windows !")
CF_HTML = win32clipboard.RegisterClipboardFormat("HTML Format")
cacheClipboard = ""
while 1:
await asyncio.sleep(1)
win32clipboard.OpenClipboard(0)
try:
src = win32clipboard.GetClipboardData(CF_HTML).decode("UTF-8")
except TypeError:#if not html
try:
src = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT).decode("UTF-8")
except TypeError:
src = ""
win32clipboard.CloseClipboard()
if(src != cacheClipboard): #avoid downloading infinite loop if still in clipboard
cacheClipboard = src
Copy_dwnld_from_links(src, drive)
print(" Some infos : \n"
"You can put the links directly from google drive ('https://drive.google.com') but also those behind a "
"redirection(like the one from igg).\n"
"Temporary files in google drive of your download will be stored on 'Temp folder for script', you can delete it "
"after the downloads. \n"
"Settings are stored in the config.ini file.\n"
"If you want to put the google drive folder in a custom folder(to use your google team account), "
"edit the FolderId field in config.ini and replace 'root' with the google drive team folder id.\n"
"If you use Windows, you can go on config.ini and change ClipboardDetection to ClipboardDetection=1,"
"you just have to Ctrl+C the links to download and it should handle the rest.\n"
"The download percentage status is updated about every 100 MB, so wait a little if it appears to be stuck.\n"
"You can put multiple links at the same time\n")
print("###############")
print("\n Careful, if you choose to save the credentials : "
" An access to your google drive will be/is stored on 'credentials.txt'. \n IT COULD BE USED BY SOMEONE ELSE"
" TO ACCESS, DOWNLOAD OR DELETE FILES FROM YOUR GOOGLE DRIVE. \n I'm not responsible if anything bad happen"
" in your drive.\n")
print("###############")
drive = GoogleAuthManager.create_drive_manager()
get_location() # ask for path if not set
get_folder_id() # create folder id txt file
while 1:
if 'ClipboardDetection' in DATABASE and DATABASE['ClipboardDetection'] == "1" and os.name == 'nt':
print("The script now captures your links from your clipboard !")
asyncio.run(Check_clipboard_links(drive))
else:
links = input("paste the link(s) to download : \n")
Copy_dwnld_from_links(links, drive)
================================================
FILE: gDriveLibrary.py
================================================
"""
Documentation :
explain client secret(how to replace it if needed) : https://developers.google.com/drive/api/v3/quickstart/python
download : the ile is chucked with pieces of ~100MB, need to download at least this amount beore appearing on screen
"""
import re
import os
from googleapiclient.http import MediaIoBaseDownload
from tqdm import tqdm
# get download folder from user :
# https://stackoverflow.com/questions/35851281/python-finding-the-users-downloads-folder
def get_Gdrive_folder_id(drive, driveService, name, parent="root"): # return ID of folder, create it if missing
body = {'title': name,
'mimeType': "application/vnd.google-apps.folder"
}
query = "title='Temp folder for script' and mimeType='application/vnd.google-apps.folder'" \
" and '" + parent + "' in parents and trashed=false"
if parent != "root":
query += "and driveId='" + parent + "' and includeItemsFromAllDrives=true and supportsAllDrives = true"
listFolders = drive.ListFile({'q': query})
for subList in listFolders:
if subList == []: # if folder doesn't exist, create it
folder = driveService.files().insert(body=body).execute()
break
else:
folder = subList[0] # if one folder with the correct name exist, pick it
return folder['id']
def extract_file_ids_from_folder(drive, folderID):
files = drive.ListFile({'q': "'" + folderID + "' in parents"}).GetList()
fileIDs = []
for file in files :
fileIDs.append(file['id'])
return fileIDs
def extract_files_id(links, drive):
# copy of google drive file from google drive link :
links = re.findall(r"\b(?:https?:\/\/)?(?:drive\.google\.com[-_&?=a-zA-Z\/\d]+)",
links) # extract google drive links
try:
fileIDs = [re.search(r"(?<=/d/|id=|rs/).+?(?=/|$)", link)[0] for link in links] # extract the fileIDs
for fileID in fileIDs:
if drive.auth.service.files().get(fileId=fileID).execute()['mimeType'] == "application/vnd.google-apps.folder":
fileIDs.extend(extract_file_ids_from_folder(drive, fileID))
fileIDs.remove(fileID)
return fileIDs
except Exception as error:
print("error : " + str(error))
print("Link is probably invalid")
print(links)
def copy_file(drive, fileId, parentFolder = "root"): #if different parentFolder, input the folder ID
fileOriginMetaData = drive.auth.service.files().get(fileId=fileId).execute()
"""remove 4 last characters of the original file name
and add file extension(should be .rar) in case the file extension is missing from the name """
nameNoExtension = ".".join(fileOriginMetaData['originalFilename'].split(".")[:-1])
newFileName = nameNoExtension + "." + fileOriginMetaData['fileExtension']
print("Name of the file on your google drive and on the disk: " + newFileName)
folderID = get_Gdrive_folder_id(drive, drive.auth.service, "Temp folder for script", parentFolder)
copiedFileMetaData = {"parents": [{"id": str(folderID)}], 'title': newFileName} # ID of destination folder
copiedFile = drive.auth.service.files().copy(
fileId=fileId,
body=copiedFileMetaData
).execute()
return copiedFile
def download_file(drive, file, destFolder):
copiedFileMedia = drive.auth.service.files().get_media(fileId=file['id'])
newFileName = file['title']
defaultPath = destFolder + "\\" + newFileName
fullPath = generate_path_with_unique_filename(destFolder, newFileName)
if defaultPath != fullPath :
print("File already exist in the disk, new path: " + fullPath)
print("Download in progress. File size: " + sizeof_file(int(file['fileSize'])))
step = 104857600//1048576
fsize = int(file['fileSize'])//1048576
file = open(fullPath, "wb+")
downloader = MediaIoBaseDownload(file, copiedFileMedia, chunksize=104857600) # change chunksize here
done = False
pbar = tqdm(desc='Downloading', unit='MB', total=fsize)
while done is False:
status, done = downloader.next_chunk()
pbar.update(step)
pbar.close()
file.close()
print("\nDownload completed : " + newFileName)
def delete_file(drive, id):
drive.auth.service.files().delete(fileId=id).execute()
#https://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
def sizeof_file(num, suffix='B'):
for unit in ['','K','M','G','Ti','Pi','Ei','Zi']:
if abs(num) < 1024.0:
return "%3.1f%s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, 'Yi', suffix)
def generate_path_with_unique_filename(folder, filename):
fullpath = folder + "\\" + filename
if not os.path.exists(fullpath):
return fullpath
fileNumber = 1
while(os.path.exists(fullpath)):
fullpath = folder + "\\" + str(fileNumber) + filename
fileNumber+=1
return fullpath
================================================
FILE: requirements.txt
================================================
altgraph==0.17
auto-py-to-exe==2.6.6
bottle==0.12.18
bottle-websocket==0.2.9
cachetools==4.0.0
certifi==2019.11.28
cffi==1.13.2
chardet==3.0.4
Click==7.0
cryptography==2.8
Eel==0.11.0
Flask==1.1.1
Flask-Login==0.4.1
future==0.18.2
gevent==1.4.0
gevent-websocket==0.10.1
google-api-python-client==1.7.11
google-auth==1.10.0
google-auth-httplib2==0.0.3
greenlet==0.4.15
httplib2==0.15.0
idna==2.8
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
oauth2==1.9.0.post1
oauth2client==4.1.3
oauthlib==3.1.0
pefile==2019.4.18
pyasn1==0.4.8
pyasn1-modules==0.2.7
pycparser==2.19
PyDrive==1.3.1
PyInstaller==3.6
pyOpenSSL==19.1.0
pywin32==227
pywin32-ctypes==0.2.0
PyYAML==5.2
requests==2.22.0
rsa==4.0
six==1.13.0
tqdm==4.43.0
uritemplate==3.0.1
urllib3==1.25.7
Werkzeug==0.16.0
whichcraft==0.6.1
gitextract_wmit1el9/ ├── GoogleAuthManager.py ├── GoogleAuthV1.py ├── GoogleAuthV2.py ├── README.md ├── gDriveCopyDownloader.py ├── gDriveLibrary.py └── requirements.txt
SYMBOL INDEX (26 symbols across 5 files)
FILE: GoogleAuthManager.py
function create_credential (line 6) | def create_credential():
function create_drive_manager (line 12) | def create_drive_manager():
function authorize_from_credential (line 23) | def authorize_from_credential(gAuth, isSaved):
FILE: GoogleAuthV1.py
function auth_and_save_credential (line 2) | def auth_and_save_credential():
function auth_no_save (line 6) | def auth_no_save(gAuth):
FILE: GoogleAuthV2.py
class FlaskModified (line 15) | class FlaskModified(Flask):
method run (line 16) | def run(self, host=None, port=None, debug=None, load_dotenv=True, **op...
function index (line 30) | def index():
function login (line 35) | def login():
function callback (line 40) | def callback():
function auth_and_save_credential (line 47) | def auth_and_save_credential():
FILE: gDriveCopyDownloader.py
function get_default_download_location (line 12) | def get_default_download_location():
function read_config (line 23) | def read_config():
function write_config (line 26) | def write_config():
function get_location (line 32) | def get_location():
function get_folder_id (line 48) | def get_folder_id():
function Copy_dwnld_from_links (line 54) | def Copy_dwnld_from_links(links, drive):
function Check_clipboard_links (line 61) | async def Check_clipboard_links(drive): #Only works for windows
FILE: gDriveLibrary.py
function get_Gdrive_folder_id (line 16) | def get_Gdrive_folder_id(drive, driveService, name, parent="root"): # r...
function extract_file_ids_from_folder (line 35) | def extract_file_ids_from_folder(drive, folderID):
function extract_files_id (line 43) | def extract_files_id(links, drive):
function copy_file (line 60) | def copy_file(drive, fileId, parentFolder = "root"): #if different paren...
function download_file (line 76) | def download_file(drive, file, destFolder):
function delete_file (line 100) | def delete_file(drive, id):
function sizeof_file (line 104) | def sizeof_file(num, suffix='B'):
function generate_path_with_unique_filename (line 111) | def generate_path_with_unique_filename(folder, filename):
Condensed preview — 7 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (17K chars).
[
{
"path": "GoogleAuthManager.py",
"chars": 1236,
"preview": "from pydrive.auth import GoogleAuth\nfrom pydrive.drive import GoogleDrive\nfrom os import path\n\n\ndef create_credential():"
},
{
"path": "GoogleAuthV1.py",
"chars": 228,
"preview": "from pydrive.auth import GoogleAuth\ndef auth_and_save_credential():\n gAuth = GoogleAuth()\n gAuth.LocalWebserverAut"
},
{
"path": "GoogleAuthV2.py",
"chars": 1277,
"preview": "from pydrive.auth import GoogleAuth\nimport webbrowser\n\n# https://realpython.com/flask-google-login/#creating-a-google-cl"
},
{
"path": "README.md",
"chars": 2668,
"preview": "# googledrive-copy-downloader\nThis python script allow you to download google drive files even if the daily limit of dow"
},
{
"path": "gDriveCopyDownloader.py",
"chars": 4723,
"preview": "import os\n\nimport GoogleAuthManager\nimport gDriveLibrary\nimport configparser\nimport asyncio\n\nCONFIG = configparser.Confi"
},
{
"path": "gDriveLibrary.py",
"chars": 5001,
"preview": "\"\"\"\nDocumentation :\nexplain client secret(how to replace it if needed) : https://developers.google.com/drive/api/v3/quic"
},
{
"path": "requirements.txt",
"chars": 792,
"preview": "altgraph==0.17\nauto-py-to-exe==2.6.6\nbottle==0.12.18\nbottle-websocket==0.2.9\ncachetools==4.0.0\ncertifi==2019.11.28\ncffi="
}
]
About this extraction
This page contains the full source code of the jonathanTIE/googledrive-copy-downloader GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 7 files (15.6 KB), approximately 4.2k tokens, and a symbol index with 26 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.