- Download files functionality with resume capability.
- Upload files and even folders without zipping.
- Files on drive provided as InputStream for creating streaming services.
Update your build.gradle file.
repositories {
maven { url 'https://jitpack.io' }
}
implementation 'com.github.siddhantkushwaha:todd:version'
You can use a many steps manual option, or the 6 steps 'Quickstart' workaround.
Manual/customized:
-
Fill in Project Name, like "todd-Testing" or so, leave Location unchanged
-
Change Project ID (optional)
-
Click "CREATE"
-
Wait a couple of seconds until the project is created and open it (click "VIEW")
-
On the APIs pane, click "Go to APIs overview"
-
Click "ENABLE APIS AND SERVICES"
-
Enter "Drive", select "Google Drive API"
-
Click "ENABLE"
-
Go to "Credentials" menu in the left menu bar
-
Click "CONFIGURE CONSENT SCREEN"
-
Choose "External", click "CREATE"
-
Fill in something like "todd" in the "Application name" box
-
At the bottom click "Save"
-
Go to "Credentials" menu in the left menu bar (again)
-
Click "CREATE CREDENTIALS"
-
Select "OAuth client ID"
-
Select "Desktop app" as "Application type"
-
Change the name (optional)
-
Click "Create"
-
Click "OK" in the "OAuth client created" dialog
-
In the "OAuth 2.0 Client IDs" section click on the just create Desktop app line.
-
In the top bar, click "DOWNLOAD JSON"
-
You will get a file like "client_secret_xxxxxx.apps.googleusercontent.com.json", rename it to "credentials.json" and copy this in
src/main/resources
directory.
This will 'abuse' a 'Quickstart' project.
-
Go to https://developers.google.com/drive/api/v3/quickstart/python
-
Click the "Enabled the Drive API"
-
"Desktop app" will already be selected on the "Configure your OAuth client" dialog
-
Click "Create"
-
Click "DOWNLOAD CLIENT CONFIGURATION"
-
You will get a file like "credentials.json", and put this in
src/main/resources
directory.
On the first use, you will get a browser screen that you need to grant access for it, and because we haven't granted out OAuth consent screen (This app isn't verified), we get an extra warning. You can use the "Advanced" link, and use the "Go to yourappname (unsafe)" link.
Should look like this -
{
"installed": {
"client_id": "********.apps.googleusercontent.com",
"project_id": "******",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "*********",
"redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"]
}
}
package com.siddhantkushwaha.server;
import com.siddhantkushwaha.todd.GDrive;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import java.io.*;
import java.util.List;
@RestController
public class GDriveController {
private static final GDrive gDrive = new GDrive();
@GetMapping("/file/{fileId}")
public ResponseEntity<StreamingResponseBody> func(@PathVariable String fileId, @RequestHeader() HttpHeaders requestHeaders) throws FileNotFoundException {
long size = gDrive.getSize(fileId);
System.out.printf("********************* Total Content Length - %s *********************", size);
List<HttpRange> ranges = requestHeaders.getRange();
long start = 0, end = size - 1;
if (!ranges.isEmpty()) {
start = ranges.get(0).getRangeStart(size);
end = ranges.get(0).getRangeEnd(size);
}
System.out.printf("********************* Range: bytes=%s-%s *********************", start, end);
InputStream inputStream = gDrive.downloadAsInputStream(fileId, start, end);
/*
// ***** writeFile writes data from inputSteam to outStream only when requested by client ******
// ***** make sure content supports streaming with partial data ******
fun writeFile(ist: InputStream, fos: OutputStream) {
// write in 2MB chunks, this can be changed
val buffer = ByteArray(1024 * 1024 * 2)
var bufferLength = ist.read(buffer)
while (bufferLength > 0) {
println("Writing..")
fos.write(buffer, 0, bufferLength)
fos.flush()
bufferLength = ist.read(buffer)
}
}
*/
StreamingResponseBody srb = outputStream -> Util.Companion.writeFile(inputStream, outputStream);
HttpHeaders httpHeaders = new HttpHeaders();
long contentLength = (end - start) + 1;
httpHeaders.setContentLength(contentLength);
httpHeaders.set("Content-Range", String.format("bytes %d-%d/%d", start, end, size));
return new ResponseEntity<>(srb, httpHeaders, HttpStatus.PARTIAL_CONTENT);
}
}