Google Drive API REST V2 insert file into folder file not found - java

I am trying to upload a file into one of my company's Google Drive folders but I haven't managed to achieve this without client intervention. So, whenever I use this:
package sample;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.ParentReference;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class DriveCommandLine_srive
{
private static String CLIENT_ID = "myClientID.apps.googleusercontent.com";
private static String CLIENT_SECRET = "myClientSecret";
private static String REDIRECT_URI = "mything";
public static void main( String[] args ) throws IOException
{
HttpTransport httpTransport = new NetHttpTransport( );
JsonFactory jsonFactory = new JacksonFactory( );
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, Arrays.asList( DriveScopes.DRIVE ) ).setAccessType( "online" ).setApprovalPrompt( "auto" ).build( );
System.out.println("xxxxx : " + DriveScopes.DRIVE);
String url = flow.newAuthorizationUrl( ).setRedirectUri( REDIRECT_URI ).build( );
System.out.println( "Please open the following URL in your browser then type the authorization code:" );
System.out.println( " " + url );
BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
String code = br.readLine( );
GoogleTokenResponse response = flow.newTokenRequest( code ).setRedirectUri( REDIRECT_URI ).execute( );
GoogleCredential credential = new GoogleCredential( ).setFromTokenResponse( response );
// Create a new authorized API client
Drive service = new Drive.Builder( httpTransport, jsonFactory, credential ).build( );
insertFile(service, "Test File Drive", "This is a test file","myCompanysFolderID" , "text/plain", "./data/document.txt");
}
/**
* Insert new file.
*
* #param service Drive API service instance.
* #param title Title of the file to insert, including the extension.
* #param description Description of the file to insert.
* #param parentId Optional parent folder's ID.
* #param mimeType MIME type of the file to insert.
* #param filename Filename of the file to insert.
* #return Inserted file metadata if successful, {#code null} otherwise.
*/
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
}
I manage to successfully upload the file to the company's folder, but I have to authorize it manually and paste the code each time. So, as I want to make this in an automatic way, I changed the authorization "method" to one that uses a service account p12 key to authorize the client. This is the new code after the change:
package sample;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.ParentReference;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class DriveCommandLine2
{
private static final String KEY_FILE_LOCATION = "data/myp12Key.p12";
**//Note: this is the mail from a service account in my dev console, it is different from the OAuth client I use in the previous method.**
private static final String SERVICE_ACCOUNT_EMAIL ="myServiceAccountEmail#appspot.gserviceaccount.com";
/** Application name. */
private static final String APPLICATION_NAME =
"Drive API Java Quickstart";
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
public static void main( String[] args ) throws Exception
{
//Drive service = getServiceManual();
Drive service = initializeDrive();
//insertFile(service, "Test File Drive", "This is a test file","myCompanyFolderID" , "text/plain", "./data/document.txt");
insertFile(service, "Test File Drive", "This is a test file","" , "text/plain", "./data/document.txt");
}
/**
* Insert new file.
*
* #param service Drive API service instance.
* #param title Title of the file to insert, including the extension.
* #param description Description of the file to insert.
* #param parentId Optional parent folder's ID.
* #param mimeType MIME type of the file to insert.
* #param filename Filename of the file to insert.
* #return Inserted file metadata if successful, {#code null} otherwise.
*/
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
/////////////////////
///NEW GOOGLE ANALYTICS AUTH
public static java.io.File convIs2File(InputStream inputStream, java.io.File file)
{
java.io.OutputStream outputStream = null;
try {
// write the inputStream to a FileOutputStream
outputStream = new java.io.FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
System.out.println("Done!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
// outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
private static Drive initializeDrive() throws Exception {
// Initializes an authorized analytics service object.
// Construct a GoogleCredential object with the service account email
// and p12 file downloaded from the developer console.
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
InputStream is = DriveCommandLine2.class.getClassLoader().getResourceAsStream(KEY_FILE_LOCATION);
java.io.File f = java.io.File.createTempFile("myP12Key", ".p12");
java.io.File f_used = convIs2File(is,f);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(f_used)
.setServiceAccountScopes(DriveScopes.all())
.build();
// Construct the Analytics service object.
return new Drive.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
}
}
But when I run this code, I get the following error:
An error occured: com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"location" : "file",
"locationType" : "other",
"message" : "File not found: myCompanyFolderID",
"reason" : "notFound"
} ],
"message" : "File not found: myCompanyFolderID"
}
So, my guess is that in the previous authorization way, I am using my Client_ID and Client_Secrets to authorize my app to insert things into my company's Drive space, so I find myCompanyFolder and I am able to insert the file successfully, however, in the second method, I am trying to insert the file into the service account Drive space that I am not able to access (I know this because when I try to insert it in Drive's root, it works perfectly, however, I am not able to see the file in my root).
So at the end, my question is, is there a way to insert the file into my company's drive folder without doing the manual authorization? That is, how do I authorize my app to upload the file in my company's drive without human interaction?
I think the client_secrets way won't work as I tried it before and it asks me to do it manually the first time I run the code. As I am running my code from a JAR file in a Linux server, this is not practical at all and doesn't work for me.
Thanks!

The 404: File not found means that the user does not have read access to a file or the file does not exist.
Make sure that you provide the correct access_token when making the request for file metadata. Try to regenerate the authorization code, access_token. You need to authorize and authenticate your requests on the behalf of the user, a key and your client ID will not be enough to access user's document.
The documentation suggest to report to users that they do not have read access to the file or that the file does not exist. Tell them that they should ask the owner for permission to the file.

Related

Load a pdf into S3 using User Defined Java Class in Pentaho

import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import java.io.File;
import java.io.IOException;
public class UploadObject {
public static void main(String[] args) throws IOException {
Regions clientRegion = Regions.US_EAST_1;
String fileObjKeyName = "N.pdf";
String fileName = "C:\\home\\aws\\N.pdf";
//To Test the File Upload
String accessKeyId = "AKIAZGSMNGVXXXZ73VXE";
String secretAccessKey = "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";
String bucketName = "fioprod-s3-addon-us-east-12";
try {
final BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);
//This code expects that you have AWS credentials set up per:
// https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withRegion(clientRegion)
.withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials))
.build();
// Upload a file as a new object with ContentType and title specified.
PutObjectRequest request = new PutObjectRequest(bucketName, fileObjKeyName, new File(fileName));
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("plain/text");
metadata.addUserMetadata("title", "someTitle");
request.setMetadata(metadata);
s3Client.putObject(request);
} catch (AmazonServiceException e) {
// The call was transmitted successfully, but Amazon S3 couldn't process
// it, so it returned an error response.
e.printStackTrace();
} catch (SdkClientException e) {
// Amazon S3 couldn't be contacted for a response, or the client
// couldn't parse the response from Amazon S3.
e.printStackTrace();
}
}
}
The above code works fine to load pdf file into S3 when I run it from IntelliJ IDE. I want this code to move to Pentaho "User Defined Class", when I do that it throws error - " Imported class "com.amazonaws.auth.AWSStaticCredentialsProvider" could not be loaded"
How do I resolve that? My ultimate goal is to load a .pdf or .zip file into S3 using pentaho.
Thank you for your time.
Your have written nice code which is working as well. You just need to keep aws-java-sdk jar to your data-integration/lib location.
You can download sdk jar file from Here
You can look my KTR also from Here where I have included your code and make small changes to workable your code in User-defined-java-class in PDI
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import java.io.File;
import java.io.IOException;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException{
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
Regions clientRegion = Regions.US_EAST_1;
String fileObjKeyName = "N.pdf";
String fileName = "C:\\home\\aws\\N.pdf";
//To Test the File Upload
String accessKeyId = "AKIAZGSMNGVXXXZ73VXE";
String secretAccessKey = "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";
String bucketName = "fioprod-s3-addon-us-east-12";
final BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);
//This code expects that you have AWS credentials set up per:
// https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html
AmazonS3 s3Client = (AmazonS3)AmazonS3ClientBuilder.standard().withRegion(clientRegion).withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials)).build();
// Upload a file as a new object with ContentType and title specified.
PutObjectRequest request = new PutObjectRequest(bucketName, fileObjKeyName, new File(fileName));
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("plain/text");
metadata.addUserMetadata("title", "someTitle");
request.setMetadata(metadata);
s3Client.putObject(request);
putRow(data.outputRowMeta, r);
return true;
}

Create shareable link for all files in Dropbox using Dropbox API

I have around 100 files in my Dropbox account I am trying to make shareable link for all of the files using Dropbox API.
Tried using
DbxClient = new DbxClient(config, accessToken);
client.createShareableUrl(path);
but got an error on DbxClient cannot find symbol, or class not found.
import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.v2.*;
import static com.dropbox.core.v2.files.AlphaGetMetadataError.path;
import com.dropbox.core.v2.files.FileMetadata;
import com.dropbox.core.v2.files.ListFolderResult;
import com.dropbox.core.v2.files.Metadata;
import com.dropbox.core.v2.sharing.RequestedVisibility;
import com.dropbox.core.v2.sharing.SharedLinkMetadata;
import com.dropbox.core.v2.sharing.SharedLinkSettings;
import com.dropbox.core.v2.users.FullAccount;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class DBX {
static boolean doYouWantMeToUpload = false;
private static final String ACCESS_TOKEN = "My access token here I removed it";
public static void main(String args[]) throws DbxException, FileNotFoundException, IOException {
// Create Dropbox client
DbxRequestConfig config = DbxRequestConfig.newBuilder("dropbox/java-tutorial").build();
DbxClientV2 client = new DbxClientV2(config, ACCESS_TOKEN);
// Get current account info
FullAccount account = client.users().getCurrentAccount();
System.out.println(account.getName().getDisplayName());
if(doYouWantMeToUpload == true){
// Get files and folder metadata from Dropbox root directory
ListFolderResult result = client.files().listFolder("");
while (true) {
for (Metadata metadata : result.getEntries()) {
System.out.println(metadata.getPathLower());
}
if (!result.getHasMore()) {
break;
}
result = client.files().listFolderContinue(result.getCursor());
}
// Upload "test.txt" to Dropbox
try (InputStream in = new FileInputStream("test.txt")) {
FileMetadata metadata = client.files().uploadBuilder("/test.txt")
.uploadAndFinish(in);
}
// Get shareable link for a file
DbxClient = new DbxClient(config, ACCESS_TOKEN);
client.createShareableUrl(test.txt);
}
}
}
I want to get shareable link for all files in my Dropbox.
I followed these instructions in Dropbox GitHub.
You're attempting to use the old createShareableUrl which is for Dropbox API v1, which is now retired.
You should instead use Dropbox API v2, via DbxClientV2, like you do for the other calls in your code.
Specifically, to create a shared link, you should use createSharedLinkWithSettings. That would look something like:
DbxClientV2 client = new DbxClientV2(config, ACCESS_TOKEN);
client.sharing().createSharedLinkWithSettings(path);

How to get query result in Json form using Java API of Google Bigquery

I am using Google Bigquery V2 Java API. I am not able to find a way to get query results in JSON format.
In Bigquery Web UI we can see this JSON and Table form of results. see scrrenshot.
Is there any way to get the GetQueryResultsResponse as JSON, using Java API.
One option is to apply the TO_JSON_STRING function to the results of your query. For example,
#standardSQL
SELECT TO_JSON_STRING(t)
FROM (
SELECT x, y
FROM YourTable
WHERE z = 10
) AS t;
If you want all of the table's columns as JSON, you can use a simpler form:
#standardSQL
SELECT TO_JSON_STRING(t)
FROM YourTable AS t
WHERE z = 10;
I'm using a service account to access the BigQuery REST API to get the response in JSON format.
In order to use a service account, you will have to go to credentials (https://console.cloud.google.com/apis/credentials) and choose a project.
You will get a drop down like this:
Create a Service account for your project and download the secret file in the JSON format. Keep the JSON file in your file system and set the path to it. Check below image to set the file path:
So, now all you have to do in is use JAVA client api to consume the Big Query REST API.
Here's is a simple solution that I've been using for my project.
package com.example.bigquery;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import org.apache.log4j.Logger;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpContent;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.http.json.JsonHttpContent;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.common.io.CharStreams;
public class BigQueryDemo {
private static final String QUERY_URL_FORMAT = "https://www.googleapis.com/bigquery/v2/projects/%s/queries" + "?access_token=%s";
private static final String QUERY = "query";
private static final String QUERY_HACKER_NEWS_COMMENTS = "SELECT * FROM [bigquery-public-data:hacker_news.comments] LIMIT 1000";
private static final Logger logger = Logger.getLogger(BigQueryDemo.class);
static GoogleCredential credential = null;
static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
static final JsonFactory JSON_FACTORY = new JacksonFactory();
static {
// Authenticate requests using Google Application Default credentials.
try {
credential = GoogleCredential.getApplicationDefault();
credential = credential.createScoped(Arrays.asList("https://www.googleapis.com/auth/bigquery"));
credential.refreshToken();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void implicit() {
String projectId = credential.getServiceAccountProjectId();
String accessToken = generateAccessToken();
// Set the content of the request.
Dataset dataset = new Dataset().addLabel(QUERY, QUERY_HACKER_NEWS_COMMENTS);
HttpContent content = new JsonHttpContent(JSON_FACTORY, dataset.getLabels());
// Send the request to the BigQuery API.
GenericUrl url = new GenericUrl(String.format(QUERY_URL_FORMAT, projectId, accessToken));
logger.debug("URL: " + url.toString());
String responseJson = getQueryResult(content, url);
logger.debug(responseJson);
}
private static String getQueryResult(HttpContent content, GenericUrl url) {
String responseContent = null;
HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory();
HttpRequest request = null;
try {
request = requestFactory.buildPostRequest(url, content);
request.setParser(JSON_FACTORY.createJsonObjectParser());
request.setHeaders(
new HttpHeaders().set("X-HTTP-Method-Override", "POST").setContentType("application/json"));
HttpResponse response = request.execute();
InputStream is = response.getContent();
responseContent = CharStreams.toString(new InputStreamReader(is));
} catch (IOException e) {
logger.error(e);
}
return responseContent;
}
private static String generateAccessToken() {
String accessToken = null;
if ((System.currentTimeMillis() > credential.getExpirationTimeMilliseconds())) {
accessToken = credential.getRefreshToken();
} else {
accessToken = credential.getAccessToken();
}
System.out.println(accessToken);
return accessToken;
}
}
Following is the Github link to the code: https://github.com/vslala/BigQueryRestSample
It is just a demo project to fetch JSON data from the BQ REST API. Do not use it in your project directly.
Let me know if you have any questions.

File.setTitle method equivalent in Google Drive API v3

Here is an official example:
package com.google.api.services.samples.drive.cmdline;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.media.MediaHttpDownloader;
import com.google.api.client.googleapis.media.MediaHttpUploader;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Preconditions;
import com.google.api.client.util.store.DataStoreFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Collections;
/**
* A sample application that runs multiple requests against the Drive API. The requests this sample
* makes are:
* <ul>
* <li>Does a resumable media upload</li>
* <li>Updates the uploaded file by renaming it</li>
* <li>Does a resumable media download</li>
* <li>Does a direct media upload</li>
* <li>Does a direct media download</li>
* </ul>
*
* #author rmistry#google.com (Ravi Mistry)
*/
public class DriveSample {
/**
* Be sure to specify the name of your application. If the application name is {#code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
private static final String APPLICATION_NAME = "";
private static final String UPLOAD_FILE_PATH = "Enter File Path";
private static final String DIR_FOR_DOWNLOADS = "Enter Download Directory";
private static final java.io.File UPLOAD_FILE = new java.io.File(UPLOAD_FILE_PATH);
/** Directory to store user credentials. */
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/drive_sample");
/**
* Global instance of the {#link DataStoreFactory}. The best practice is to make it a single
* globally shared instance across your application.
*/
private static FileDataStoreFactory dataStoreFactory;
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Global Drive API client. */
private static Drive drive;
/** Authorizes the installed application to access user's protected data. */
private static Credential authorize() throws Exception {
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(DriveSample.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=drive "
+ "into drive-cmdline-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(DriveScopes.DRIVE_FILE)).setDataStoreFactory(dataStoreFactory)
.build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args) {
Preconditions.checkArgument(
!UPLOAD_FILE_PATH.startsWith("Enter ") && !DIR_FOR_DOWNLOADS.startsWith("Enter "),
"Please enter the upload file path and download directory in %s", DriveSample.class);
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
// authorization
Credential credential = authorize();
// set up the global Drive instance
drive = new Drive.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(
APPLICATION_NAME).build();
// run commands
View.header1("Starting Resumable Media Upload");
File uploadedFile = uploadFile(false);
View.header1("Updating Uploaded File Name");
File updatedFile = updateFileWithTestSuffix(uploadedFile.getId());
View.header1("Starting Resumable Media Download");
downloadFile(false, updatedFile);
View.header1("Starting Simple Media Upload");
uploadedFile = uploadFile(true);
View.header1("Starting Simple Media Download");
downloadFile(true, uploadedFile);
View.header1("Success!");
return;
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
System.exit(1);
}
/** Uploads a file using either resumable or direct media upload. */
private static File uploadFile(boolean useDirectUpload) throws IOException {
File fileMetadata = new File();
fileMetadata.setTitle(UPLOAD_FILE.getName());
FileContent mediaContent = new FileContent("image/jpeg", UPLOAD_FILE);
Drive.Files.Insert insert = drive.files().insert(fileMetadata, mediaContent);
MediaHttpUploader uploader = insert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(useDirectUpload);
uploader.setProgressListener(new FileUploadProgressListener());
return insert.execute();
}
/** Updates the name of the uploaded file to have a "drivetest-" prefix. */
private static File updateFileWithTestSuffix(String id) throws IOException {
File fileMetadata = new File();
fileMetadata.setTitle("drivetest-" + UPLOAD_FILE.getName());
Drive.Files.Update update = drive.files().update(id, fileMetadata);
return update.execute();
}
/** Downloads a file using either resumable or direct media download. */
private static void downloadFile(boolean useDirectDownload, File uploadedFile)
throws IOException {
// create parent directory (if necessary)
java.io.File parentDir = new java.io.File(DIR_FOR_DOWNLOADS);
if (!parentDir.exists() && !parentDir.mkdirs()) {
throw new IOException("Unable to create parent directory");
}
OutputStream out = new FileOutputStream(new java.io.File(parentDir, uploadedFile.getTitle()));
MediaHttpDownloader downloader =
new MediaHttpDownloader(httpTransport, drive.getRequestFactory().getInitializer());
downloader.setDirectDownloadEnabled(useDirectDownload);
downloader.setProgressListener(new FileDownloadProgressListener());
downloader.download(new GenericUrl(uploadedFile.getDownloadUrl()), out);
}
}
One problem is that the setTitle method does not exist any more in the latest Java API. How do I set the title of a file now?
Some changes in above code
setTitle has been changed into setName
Drive.Files.Insert -> Drive.Files.Create
drive.files().insert(fileMetadata, mediaContent); -> drive.files().create(fileMetadata, mediaContent)
getTitle() -> getName()
uploadedFile.getDownloadUrl() -> uploadedFile.getWebViewLink()
Following code has all new Method names.
change last part of code and paste
private static File uploadFile(boolean useDirectUpload) throws IOException {
File fileMetadata = new File();
fileMetadata.setName(UPLOAD_FILE.getName());
FileContent mediaContent = new FileContent("image/jpeg", UPLOAD_FILE);
Drive.Files.Create insert = drive.files().create(fileMetadata, mediaContent);
MediaHttpUploader uploader = insert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(useDirectUpload);
uploader.setProgressListener(new FileUploadProgressListener());
return insert.execute();
}
/** Updates the name of the uploaded file to have a "drivetest-" prefix. */
private static File updateFileWithTestSuffix(String id) throws IOException {
File fileMetadata = new File();
fileMetadata.setName("drivetest-" + UPLOAD_FILE.getName());
Drive.Files.Update update = drive.files().update(id, fileMetadata);
return update.execute();
}
/** Downloads a file using either resumable or direct media download. */
private static void downloadFile(boolean useDirectDownload, File uploadedFile)
throws IOException {
// create parent directory (if necessary)
java.io.File parentDir = new java.io.File(DIR_FOR_DOWNLOADS);
if (!parentDir.exists() && !parentDir.mkdirs()) {
throw new IOException("Unable to create parent directory");
}
OutputStream out = new FileOutputStream(new java.io.File(parentDir, uploadedFile.getName()));
MediaHttpDownloader downloader =
new MediaHttpDownloader(httpTransport, drive.getRequestFactory().getInitializer());
downloader.setDirectDownloadEnabled(useDirectDownload);
downloader.setProgressListener(new FileDownloadProgressListener());
downloader.download(new GenericUrl(uploadedFile.getWebViewLink()), out);
}
setTitle has been changed into setName in v3.

Can we use YouTube Analytics Api using Java and Eclipse?

I tried reading google tutorials and doing the YouTube Analytics Api example. But, I am unable to make the code. Can someone help me to make it (using Java and Eclipse) ?
it shows an error in Import file
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtubeAnalytics.YoutubeAnalytics;
import com.google.api.services.youtubeAnalytics.model.ResultTable;
import com.google.api.services.youtubeAnalytics.model.ResultTable.ColumnHeaders;
import com.google.common.collect.Lists;
Example :
package com.google.api.services.samples.youtube.cmdline.youtube_analytics_cmdline_report_sample;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.util.List;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.java6.auth.oauth2.FileCredentialStore;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtubeAnalytics.YoutubeAnalytics;
import com.google.api.services.youtubeAnalytics.model.ResultTable;
import com.google.api.services.youtubeAnalytics.model.ResultTable.ColumnHeaders;
import com.google.common.collect.Lists;
public class Samp {
/**
* Demo displaying YouTube metrics from a user's channel using the YouTube Data and YouTube
* Analytics APIs. It also uses OAuth2 for authorization.
*
* #author Christoph Schwab-Ganser and Jeremy Walker
*/
public class YouTubeAnalyticsReports {
/** Global instance of the HTTP transport. */
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
/** Global instance of Youtube object to make general YouTube API requests. */
private static YouTube youtube;
/** Global instance of YoutubeAnalytics object to make analytic API requests. */
private static YoutubeAnalytics analytics;
/**
* Authorizes the installed application to access user's protected YouTube data.
*
* #param scopes list of scopes needed to access general and analytic YouTube info.
*/
private static Credential authorize(List<String> scopes) throws Exception {
// Load client secrets.
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(
JSON_FACTORY,
YouTubeAnalyticsReports.class.getResourceAsStream("/client_secrets.json"));
// Checks that the defaults have been replaced (Default = "Enter X here").
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.err.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=youtube"
+ "into youtube-analytics-cmdline-report-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
// Set up file credential store.
FileCredentialStore credentialStore =
new FileCredentialStore(
new File(System.getProperty("user.home"),
".credentials/youtube-analytics-api-report.json"),
JSON_FACTORY);
// Set up authorization code flow.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT,
JSON_FACTORY,
clientSecrets,
scopes)
.setCredentialStore(credentialStore).build();
// Authorize.
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
/**
* Authorizes user, gets user's default channel via YouTube Data API, and gets/prints stats on
* user's channel using the YouTube Analytics API.
*
* #param args command line args (not used).
*/
public static void main(String[] args) {
// Scopes required to access YouTube general and analytics information.
List<String> scopes = Lists.newArrayList(
"https://www.googleapis.com/auth/yt-analytics.readonly",
"https://www.googleapis.com/auth/youtube.readonly"
);
try {
Credential credential = authorize(scopes);
// YouTube object used to make all non-analytic API requests.
youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("youtube-analytics-api-report-example")
.build();
// YouTube object used to make all analytic API requests.
analytics = new YoutubeAnalytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("youtube-analytics-api-report-example")
.build();
// Constructs request to get channel id for current user.
YouTube.Channels.List channelRequest = youtube.channels().list("id,snippet");
channelRequest.setMine(true);
channelRequest.setFields("items(id,snippet/title)");
ChannelListResponse channels = channelRequest.execute();
// List of channels associated with user.
List<Channel> listOfChannels = channels.getItems();
// Grab default channel which is always the first item in the list.
Channel defaultChannel = listOfChannels.get(0);
String channelId = defaultChannel.getId();
PrintStream writer = System.out;
if (channelId == null) {
writer.println("No channel found.");
} else {
writer.println("Default Channel: " + defaultChannel.getSnippet().getTitle() +
" ( " + channelId + " )\n");
printData(writer, "Views Over Time.", executeViewsOverTimeQuery(analytics, channelId));
printData(writer, "Top Videos", executeTopVideosQuery(analytics, channelId));
printData(writer, "Demographics", executeDemographicsQuery(analytics, channelId));
}
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
e.printStackTrace();
} catch (Throwable t) {
System.err.println("Throwable: " + t.getMessage());
t.printStackTrace();
}
}
/**
* Returns the views and unique viewers per day.
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeViewsOverTimeQuery(YoutubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2012-01-01", // Start date.
"2012-01-14", // End date.
"views,uniques") // Metrics.
.setDimensions("day")
.setSort("day")
.execute();
}
/**
* Returns the top video by views.
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeTopVideosQuery(YoutubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2012-01-01", // Start date.
"2012-08-14", // End date.
"views,subscribersGained,subscribersLost") // Metrics.
.setDimensions("video")
.setSort("-views")
.setMaxResults(10)
.execute();
}
/**
* Returns the demographics report
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeDemographicsQuery(YoutubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2007-01-01", // Start date.
"2012-08-14", // End date.
"viewerPercentage") // Metrics.
.setDimensions("ageGroup,gender")
.setSort("-viewerPercentage")
.execute();
}
/**
* Prints the output from the API. The channel name is printed along with
* each column name and all the data in the rows.
* #param writer stream to output to
* #param title title of the report
* #param results data returned from the API.
*/
private static void printData(PrintStream writer, String title, ResultTable results) {
writer.println("Report: " + title);
if (results.getRows() == null || results.getRows().isEmpty()) {
writer.println("No results Found.");
} else {
// Print column headers.
for (ColumnHeaders header : results.getColumnHeaders()) {
writer.printf("%30s", header.getName());
}
writer.println();
// Print actual data.
for (List<Object> row : results.getRows()) {
for (int colNum = 0; colNum < results.getColumnHeaders().size(); colNum++) {
ColumnHeaders header = results.getColumnHeaders().get(colNum);
Object column = row.get(colNum);
if ("INTEGER".equals(header.getUnknownKeys().get("dataType"))) {
long l = ((BigDecimal) column).longValue();
writer.printf("%30d", l);
} else if ("FLOAT".equals(header.getUnknownKeys().get("dataType"))) {
writer.printf("%30f", column);
} else if ("STRING".equals(header.getUnknownKeys().get("dataType"))) {
writer.printf("%30s", column);
} else {
// default output.
writer.printf("%30s", column);
}
}
writer.println();
}
writer.println();
}
}
}
}
It would be helpful if you could state what error do you see in Imports?
But assuming you are finding errors in Imports it means you are missing project dependencies in your project path. Find the dependencies in Maven POM.xml. If you are not using Maven to build your project, then please download all the dependent JAR files as mentioned in POM.xml

Categories