How to create google-drive spreadsheet from .csv file? - c#

I`d like to create spreadsheet from .csv file.
Code:
static void Main()
{
String CLIENT_ID = "<MY ID>";
String CLIENT_SECRET = "<MY SECRET>";
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET);
var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
var service = new DriveService(auth);
File body = new File();
body.Title = "My spread";
body.Description = "A test spread";
body.MimeType = "application/vnd.google-apps.spreadsheet";
byte[] byteArray = System.IO.File.ReadAllBytes("spread.csv");
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
service.Files.Insert(body, stream, "application/vnd.google-apps.spreadsheet").Upload();
}
private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
{
string[] scopes = new string[] { "https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/userinfo.profile" };
IAuthorizationState state = new AuthorizationState(scopes);
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
Uri authUri = arg.RequestUserAuthorization(state);
// Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString());
Console.Write(" Authorization Code: ");
string authCode = Console.ReadLine();
Console.WriteLine();
// Retrieve the access token by using the authorization code:
return arg.ProcessUserAuthorization(authCode, state);
}
After inserting file and clicking on it on google-drive page(logged as owner) I get message
"We're sorry.
The spreadsheet at this URL could not be found. Make sure that you have the right URL and that the owner of the spreadsheet hasn't deleted it"
When I change MimeType to "text/csv" and insert file, after clicking on it, I get message
"No preview available
This item was created with (MyApp'sName), a Google Drive app.
Download this file or use one of the apps you have installed to open it."
I can also right click on this file(that one created with "text/csv" MimeType) and choose option "Export to Google Docs" and this gives me result that I'd like to reach - spreadsheet file with my .csv's file content. But such indirect method doesn`t fully satify me. Is there any method to make spreadsheet file on google drive, with content from .csv file direct from my application?

I don't know c#, but on the basis it mirrors Java, within the line
service.Files.Insert(body, stream,
"application/vnd.google-apps.spreadsheet").Upload();
you need to insert the equivalent of
.setConvert(true)
also ...
the mimetype should be "text/csv"

I've found the answer :)
How to programmatically convert a file into an appropriate Google Documents format:
var service = new DriveService(new BaseClientService.Initializer
{
...
});
...
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, _mimeType);
request.Convert = true;
request.Upload();

Related

C# app "upload file to google drive" request returning as null

I have a C# desktop app which allows the user to backup its to google drive via the google drive api V3.
I have the following method in a class which is used to load the backups
static string[] Scopes = { DriveService.Scope.DriveFile };
static string ApplicationName = "MyApp";
private static string CreateFile(string pFilePath, string parentFolderId, DriveService service)
{
var fileMetaData = new Google.Apis.Drive.v3.Data.File();
fileMetaData.Name = Path.GetFileName(pFilePath);
fileMetaData.MimeType = "application/vnd.google-apps.file";
fileMetaData.Parents = new List<string> { parentFolderId };
FilesResource.CreateMediaUpload request;
using(var stream = new FileStream(pFilePath, FileMode.Open))
{
request = service.Files.Create(fileMetaData, stream, "application/vnd.google-apps.file");
request.Fields = "id";
request.Upload();
}
var file = request.ResponseBody;
return file.Id;
}
Upon reaching request.Upload(), the request doesn't seem to have any issues, but later on after the file declaration, file turns out to be null, so no response body and thus no id either.
Is there something wrong with my request? I tried to see if I could catch an Exception in upload, which the method description claims would be of type IUploadProgress.Exception, but such an interface doesn't actually have an Exception property.
I've already authenticated and I managed to create a folder (which is the ID passed by argument parentFolderId, confirmed to not be null), so I am able to communicate with drive, just that this particular upload isn't working.
This is the code i use How to upload a file to Google Drive with C# .net I use the async method personally
string uploadedFileId;
// Create a new file on Google Drive
await using (var fsSource = new FileStream(UploadFileName, FileMode.Open, FileAccess.Read))
{
// Create a new file, with metadata and stream.
var request = service.Files.Create(fileMetadata, fsSource, "text/plain");
request.Fields = "*";
var results = await request.UploadAsync(CancellationToken.None);
if (results.Status == UploadStatus.Failed)
{
Console.WriteLine($"Error uploading file: {results.Exception.Message}");
}
// the file id of the new file we created
uploadedFileId = request.ResponseBody?.Id;
}
As for your code i think you need execute on the end
request.Upload().Execute;

Can i view and open a file in google drive in browser using C#

I have done necessary steps to enable google drive API with my google account.
https://developers.google.com/sheets/api/quickstart/dotnet?refresh=1
Below code only returns the value for the files contain data and editable link.
How can i open the file in google drive in a browser using c# with google drive API?
Can you please share any other solution?
static void Main(string[] args)
{
try
{
static string[] Scopes = { SheetsService.Scope.Spreadsheets };
static string ApplicationName = "Google Sheets API .NET Quickstart";
UserCredential credential;
using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.ReadWrite))
{
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
List<string> ranges = new List<string>();
bool includeGridData = false;
SpreadsheetsResource.GetRequest request = service.Spreadsheets.Get(spreadsheetId);
request.Ranges = ranges;
request.IncludeGridData = includeGridData;
Spreadsheet response = request.Execute();
Console.WriteLine(JsonConvert.SerializeObject(response));
Console.Read();
}
catch (Exception e)
{
var ex = e;
Console.WriteLine(e.Message);
}
}
Thanks,
Sangeetha P.
The Google drive API is a file store api. It allows you to upload, download, delete files. It contains a folder list hierarchy list of your files.
It does not have the ability to open your files and see the continence. To do this in C# you will need to download the file locally and program something in your application that can open the file. The response from this api will be Json. You may be able to download the file as a stream and put it some place but thats really not what you should be doing.
Alternately depending upon the type of file you can check for a weblink or download link parameter in the file metadata. This will open the file in google docs on the users browser if they have permissions enough to see the file.
Google sheets files can be opens using the google sheets api, Google doc files can be opened using the google docs api. These may be better options for you to get a formatted version of the contents of your file. But you will still need to create your own application to showthese files.

Amazon S3 Unable to find credentials in C#

I'm trying to upload an image file to aws s3 storage and get back that image URL. I'm using secret key and access key to create credentials. But when the program runs it it says
"Unable to find credentials" .
Here is my code which i used.
public string sendMyFileToS3(string from,string to, string bucketName, string fileName)
{
BasicAWSCredentials awsCreds = new BasicAWSCredentials(bucketName, fileName);
AmazonS3Client client = new AmazonS3Client(awsCreds);
TransferUtility utility = new TransferUtility(client);
TransferUtilityUploadRequest request = new TransferUtilityUploadRequest();
request.BucketName = bucketName;
request.Key = fileName;
request.FilePath = from;
utility.Upload(request);
string urlString = "";
GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = fileName,
Expires = DateTime.Now.AddYears(2)
};
urlString = client.GetPreSignedURL(request1);
Console.WriteLine(urlString);
File.Move(from, to);
return urlString ;
}
In order to create an S3 Client you need to provide your credentials, the region and endpoint:
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3Config config = new AmazonS3Config();
config.ServiceURL = "s3.amazonaws.com";
config.RegionEndpoint = Amazon.RegionEndpoint.GetBySystemName("us-east-1");
client = new AmazonS3Client(credentials, config);
The possible regions are listed here, and depend on where you created your bucket being us-east-1 the default value.
While the possible endpoints are this three:
s3.amazonaws.com
s3-accelerate.amazonaws.com
s3-accelerate.dualstack.amazonaws.com
The first one being the standard one since the others need you to configure your bucket like it's explained here.
I am going to take a guess and say you have a conflict between the credentials your app is using and other credentials you may have installed onto your dev or test machine, i.e. in the credentials file or your app.config.
I would check and make sure you are only using a single method to provide those credentials to the program.
THis link shows the priority the SDK will look for the credentials:
http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html

Creating folder using Google Drive API gives invalid_grant but can create actual file with same connection

I can setup a Google user content connection with Google API and can get folders and even upload/create files to folders. But the same connection used to create a new regular folder anywhere gives the error invalid_grant with no further information. I am passing in a valid folderId to set as parent. I have tried different scopes and a long shot of syncing my clock like I have seen on other solutions. I can't seem to figure out the issue. Anyone else have seen this?
Here is code that works to upload a file to a folder:
public async Task<string> Upload(string localFilePath, string folderId, string fileName, string refreshToken, string userId)
{
var file = new File();
file.MimeType = GetMimeType(localFilePath);
file.Name = fileName;
file.Parents = new List<string> { folderId };
var driveService = await GetDriveService(refreshToken, userId);
// File's content.
var byteArray = System.IO.File.ReadAllBytes(localFilePath);
var stream = new System.IO.MemoryStream(byteArray);
var request = driveService.Files.Create(file, stream, file.MimeType);
await request.UploadAsync();
return request.ResponseBody.Id;
}
Here is what I've been trying in creating a folder:
public async Task<string> CreateFolder(string folderId, string folderName, string refreshToken, string userId)
{
var newFolderId = string.Empty;
var driveService = await GetDriveService(refreshToken, userId);
FilesResource.ListRequest list = driveService.Files.List();
var file = new File();
file.MimeType = "application/vnd.google-apps.folder";
file.Name = folderName;
file.Parents = new List<string> { folderId };
var request = driveService.Files.Create(file);
request.Fields = "Id";
var newFolder = await request.ExecuteAsync();
return newFolder.Id;
}
And, here is the method in defining driveService:
private async Task<DriveService> GetDriveService(string refreshToken, string userId)
{
var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
clientSecrets: new ClientSecrets { ClientId = "xyz.apps.googleusercontent.com", ClientSecret = "xyz" },
scopes: new string[] { DriveService.Scope.Drive, DriveService.Scope.DriveFile },
dataStore: new MemoryDataStore(userId, refreshToken),
user: userId,
taskCancellationToken: CancellationToken.None);
var driveService = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = "XYZ"
});
return driveService;
}
As mentioned in creating a folder,
In the Drive API, a folder is essentially a file — one identified by the special folder MIME type application/vnd.google-apps.folder. You can create a new folder by inserting a file with this MIME type and a folder title. Do not include an extension when setting a folder title.
Please try using the given code:
File fileMetadata = new File();
fileMetadata.setName("Invoices");
fileMetadata.setMimeType("application/vnd.google-apps.folder");
File file = driveService.files().create(fileMetadata)
.setFields("id")
.execute();
System.out.println("Folder ID: " + file.getId());
I apologize, I am a victim of a copy/paste or fat finger error that I just did not notice unfortunately until now. I am managing multiple cloud connections in this app for similar purposes, and at the beginning of the call in this case to create folder I either copy/pasted or fat fingered an enum value that was improperly requesting to get the saved refreshtoken from a different cloud provider ala one drive or dropbox. Once switched to pull the saved google refreshtoken, it works. Well, at least there is a working example of create folder and upload file above :-) Btw, the line request.Fields = "Id"; needs to be request.Fields = "id"; where id needs to be lower case...otherwise a different error pops up saying the field is invalid. Thanks.

Error, missing TClient parameter

I am following the google QuickStart google Drive .NET api video and I get an error at this point. I followed everything they said, I added all the required dlls. I am running windows 7 on a virutal machine, with Visual Studio 2012, could this be the issue?
After copy pasting their code, I cannot build it.
I get this error :
OAuth2.OAuth2Authenticator<TClient>' requires 1 type arguments
I could not find any info on google about this error , nor about the TClient
What is my missing TClient parameter?
The code
using System;
using System.Diagnostics;
using DotNetOpenAuth.OAuth2;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Util;
namespace GoogleDriveSamples
{
class DriveCommandLineSample
{
static void Main(string[] args)
{
String CLIENT_ID = "YOUR_CLIENT_ID";
String CLIENT_SECRET = "YOUR_CLIENT_SECRET";
// Register the authenticator and create the service
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET);
var auth = new OAuth2Authenticator(provider, GetAuthorization);
var service = new DriveService(auth);
File body = new File();
body.Title = "My document";
body.Description = "A test document";
body.MimeType = "text/plain";
byte[] byteArray = System.IO.File.ReadAllBytes("document.txt");
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "text/plain");
request.Upload();
File file = request.ResponseBody;
Console.WriteLine("File id: " + file.Id);
Console.WriteLine("Press Enter to end this process.");
Console.ReadLine();
}
private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
{
// Get the auth URL:
IAuthorizationState state = new AuthorizationState(new[] { DriveService.Scopes.Drive.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
Uri authUri = arg.RequestUserAuthorization(state);
// Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString());
Console.Write(" Authorization Code: ");
string authCode = Console.ReadLine();
Console.WriteLine();
// Retrieve the access token by using the authorization code:
return arg.ProcessUserAuthorization(authCode, state);
}
}
}
It looks like a setup or configuration issue in your solution. Try following the step-by-step instructions in the video recording of the Google Developers Live session where the .NET Drive quickstart is covered:
http://www.youtube.com/watch?v=uwrJSWqglTc

Categories