Is there any possible way to get the list of files with parent folder name and without making additional queries?
My Files.List() code sample:
var sheets = new List<File>();
var sheetsRequest = Service.Files.List();
sheetsRequest.Fields = "nextPageToken, files(id, name, owners, parents)";
sheetsRequest.Q = $"mimeType = '{mimeType}' and name = '{name}'";
sheetsRequest.PageSize = 500;
var sheetsFeed = await sheetsRequest.ExecuteAsync();
while (sheetsFeed.Files != null)
{
foreach (var file in sheetsFeed.Files)
{
sheets.Add(file);
}
if (sheetsFeed.NextPageToken == null)
break;
sheetsRequest.PageToken = sheetsFeed.NextPageToken;
sheetsFeed = await sheetsRequest.ExecuteAsync();
}
return sheets;
Because for now I making GetFileParentDirAsync call for each File using following method (and it's very slow):
public async Task<string> GetFileParentDirAsync(File file)
{
return await Task.Run(async () =>
{
var folderName = string.Empty;
if (file.Parents?.First() == null) return folderName;
var parentId = file.Parents.First();
var parentRequest = Service.Files.Get(parentId);
var parentResponse = await parentRequest.ExecuteAsync();
folderName = parentResponse.Name;
return folderName;
});
}
Thanks.
Related
I am just trying to learn ASP.NET MVC and am having an issue, well not so much of an issue but lack of understanding any is not working I am trying to update an SQL table, the code below works fine if I want to delete a table but all I want to do is to add another file to the data table
public async Task<IActionResult> DeleteSnTFileFromFileSystem(int id)
{
var file = await context.SnTModels.Where(x => x.Id == id).FirstOrDefaultAsync();
if (file == null)
return null;
var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\wwwroot" + file.FilePath);
if (System.IO.File.Exists(basePath))
{
System.IO.File.Delete(basePath);
}
context.SnTModels.Remove(file);
context.SaveChanges();
TempData["Message"] = $"Removed {file.Name + file.Extension} successfully from File System.";
return RedirectToAction("Scenario");
}
Here is my code to create the table
[HttpPost]
public async Task<IActionResult> SnTUploadToFileSystem(List<IFormFile> files, string description)
{
foreach (var file in files)
{
var subPath = "\\*dir file\\";
var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\wwwroot" + subPath);
bool basePathExists = System.IO.Directory.Exists(basePath);
if (!basePathExists)
Directory.CreateDirectory(basePath);
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
var filePath = Path.Combine(basePath, file.FileName);
var extension = Path.GetExtension(file.FileName);
if (!System.IO.File.Exists(filePath))
{
// saving our file to the file system
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
// creating a model and save this model into the db
var SnTModel = new SnTOnFileSystem
{
CreatedOn = DateTime.UtcNow,
FileType = file.ContentType,
Extension = extension,
Name = fileName,
Description = description,
FilePath = subPath + file.FileName
};
context.SnTModels.Add(SnTModel);
context.SaveChanges();
}
}
TempData["Message"] = "File successfully uploaded to File System.";
return RedirectToAction("Index");
}
Here is the post to update the table
[HttpPost]
public async Task<IActionResult> SnTUpdateToFileSystem(List<IFormFile> files, int id)
{
var file = files[0];
var subPath = "\\Training\\SnT\\Document\\";
var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\wwwroot" + subPath);
bool basePathExists = System.IO.Directory.Exists(basePath);
if (!basePathExists)
Directory.CreateDirectory(basePath);
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
var documentFilePath = Path.Combine(basePath, file.FileName);
var extension = Path.GetExtension(file.FileName);
if (!System.IO.File.Exists(documentFilePath))
{
// saving our file to the file system
using (var stream = new FileStream(documentFilePath, FileMode.OpenOrCreate))
{
await file.CopyToAsync(stream);
}
// creating a model and save this model into the db
var SnTModel = new SnTOnFileSystem
{
Name = fileName,
DocumentFilePath = subPath + file.FileName
};
context.SnTModels.Update(SnTModel);
context.SaveChanges();
}
TempData["Message"] = "Document successfully uploaded to File System.";
return RedirectToAction("Scenario");
}
Using C# and amazon .Net core, able to list all the files with in a amazon S3 folder as below:
public async Task<string> GetMenuUrl(entities.Restaurant restaurant)
{
AmazonS3Client s3Client = new AmazonS3Client(_appSettings.AWSPublicKey, _appSettings.AWSPrivateKey, Amazon.RegionEndpoint.APSoutheast2);
string imagePath;
string restaurantName = trimSpecialCharacters(restaurant.Name);
int restaurantId = restaurant.RestaurantId;
ListObjectsRequest listRequest = new ListObjectsRequest();
ListObjectsResponse listResponse;
imagePath = $"Business_menu/{restaurantId}/";
listRequest.BucketName = _appSettings.AWSS3BucketName;
listRequest.Prefix = imagePath;
do
{
listResponse = await s3Client.ListObjectsAsync(listRequest);
} while (listResponse.IsTruncated);
var files = listResponse.S3Objects.Select(x => x.Key);
var arquivos = files.Select(x => Path.GetFileName(x)).ToList();
return arquivos.ToString();
}
Currently arquivos returns a list containing both the images (image1.jpg, image2.jpg) which is as expected and then I return it as a string.
But when I go to call this method from another function.
public async Task<VenueMenuResponse> GetVenueMenuUrl(int restaurantId)
{
var restaurant = await _context.Restaurant.Where(w => w.RestaurantId == restaurantId).FirstOrDefaultAsync();
var result = await _storyService.GetMenuUrl(restaurant);
var response = new MenuResponse() //just contains string variable called MenuUrl
{
MenuUrl = result
};
return response;
}
It returns this:
{
"menuUrl": "System.Collections.Generic.List`1[System.String]"
}
When I want it to return
{
"menuUrl": "Image1.jpg"
},
{
"menuUrl": "Image2.jpg"
}
You need to iterate thought results and return list of results.
public async Task<IEnumerable<VenueMenuResponse>> GetVenueMenuUrl(int restaurantId)
{
var restaurant = await _context.Restaurant.Where(w => w.RestaurantId == restaurantId).FirstOrDefaultAsync();
var result = await _storyService.GetMenuUrl(restaurant);
var response = result.Select(e => new MenuResponse() //just contains string variable called MenuUrl
{
MenuUrl = e
};
return response;
}
var result = string.Join(", ", fileName);
The default ToString() implementation of List simply prints the name of the type.
This magical line managed to solve things for me. The list was originally outputting just the object instead of the actual content of the list.
I upload image from angular to .net core but the file input I receive always null , with the postman , it's receive exactly. I don't know why ?
Can you help me how to solve it?
Thank you so much !
[HttpPost("upload-file")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
try
{
//var file = Request.Form.Files[0];
var rnd = FileHelper.RandomNumber();
//var file = file;
var folder = "Folder";
var index = file.FileName.LastIndexOf('.');
var onlyName = file.FileName.Substring(0, index);
var fileName = onlyName + rnd;
var extension = Path.GetExtension(file.FileName);
var folderThumb = folder + "Thumbnail";
var fileNameThumb = fileName + "Thumbnail";
var t1 = Task.Run(() => FileHelper.SaveFile(folder, fileName, file));
await Task.WhenAll(t1);
var path = new MediaResponseModel()
{
Url = Url.Action("GetFile", "Media", new { folder = folder, fileName = string.Format("{0}{1}", fileName, extension) }, Request.Scheme),
UrlThumbnail = Url.Action("GetFile", "Media", new { folder = folderThumb, fileName = string.Format("{0}{1}", fileNameThumb, extension) }, Request.Scheme),
Title = onlyName
};
return Ok(path);
}
catch (System.Exception e)
{
throw e;
}
}
handleFileInput(files: FileList) {
const file = files.item(0);
this.fileToUpload = {};
this.fileToUpload.data = files.item(0);
this.fileToUpload.fileName = files.item(0).name;
}
onUpload() {
const formData = new FormData();
formData.append('file', this.fileToUpload.data, this.fileToUpload.name);
this.http.post('http://localhost:56000/api/media/upload-file', formData).subscribe(res => console.log(res));
}
I am currently sending a file to be transcoded to my AWS lambda function. After I send the file, I send a notification to the SQS for some external aplication to start downloading the transcoded files.
The problem is, sometimes, the download of the files happen before the Lambda function completed.
How can I only send the notification to SQS after the Lambda completed.
I tried getting the Job.Status as follow, but not sure how to query it again if Status is not Complete.
Here is my code:
using (var eClient = new AmazonElasticTranscoderClient())
{
var response = await this.S3Client.GetObjectMetadataAsync(s3Event.Bucket.Name, s3Event.Object.Key);
var videoPresets = new List<Preset>();
var presetRequest = new ListPresetsRequest();
ListPresetsResponse presetResponse;
do
{
presetResponse = await eClient.ListPresetsAsync(presetRequest);
videoPresets.AddRange(presetResponse.Presets);
presetRequest.PageToken = presetResponse.NextPageToken;
} while (presetResponse.NextPageToken != null);
var pipelines = new List<Pipeline>();
var pipelineRequest = new ListPipelinesRequest();
ListPipelinesResponse pipelineResponse;
do
{
pipelineResponse = await eClient.ListPipelinesAsync(pipelineRequest);
pipelines.AddRange(pipelineResponse.Pipelines);
pipelineRequest.PageToken = pipelineResponse.NextPageToken;
} while (pipelineResponse.NextPageToken != null);
var pipeLine = s3Event.Bucket.Name.ToLower().Contains("test") ? pipelines.First(p => p.Name.ToLower().Contains("test")) : pipelines.First(p => !p.Name.ToLower().Contains("test"));
//HLS Stuff for Apple
var usablePreset = videoPresets.Where(p => p.Name.Contains("HLS") && !p.Name.Contains("HLS Video")).ToList();
var hlsPresets = new List<Preset>();
foreach (var preset in usablePreset)
{
var resolution = preset.Name.Replace("System preset: HLS ", "");
switch (resolution)
{
case "2M":
case "1M":
case "400k":
hlsPresets.Add(preset);
break;
}
}
var jobReq = new CreateJobRequest
{
PipelineId = pipeLine.Id,
Input = new JobInput() { Key = fileName, },
OutputKeyPrefix = outPutPrefix
//OutputKeyPrefix = "LambdaTest/" + playlistName + "/"
};
var outputs = new List<CreateJobOutput>();
var playlistHLS = new CreateJobPlaylist() { Name = "HLS_" + playlistName, Format = "HLSv3" };
foreach (var preset in hlsPresets)
{
var resolution = preset.Name.Replace("System preset: HLS ", "").Replace(".", "");
var newName = resolution + "_" + playlistName;
var output = new CreateJobOutput() { Key = newName, PresetId = preset.Id, SegmentDuration = "10" };
outputs.Add(output);
playlistHLS.OutputKeys.Add(newName);
}
jobReq.Playlists.Add(playlistHLS);
jobReq.Outputs = outputs;
//var temp = JsonConvert.SerializeObject(jobReq);
var reply = eClient.CreateJobAsync(jobReq);
var transcodingCompleted = reply.Result.Job.Status == "Complete" ? true : false;
do {
//somehow need to query status again
} while (!transcodingCompleted);
if (transcodingCompleted)
await SendAsync(jobReq.OutputKeyPrefix, pipeLine.OutputBucket);
}
The part I am interested in:
var reply = eClient.CreateJobAsync(jobReq);
var transcodingCompleted = reply.Result.Job.Status == "Complete" ? true : false;
do {
//somehow need to query status again
} while (!transcodingCompleted);
if (transcodingCompleted)
await SendAsync(jobReq.OutputKeyPrefix, pipeLine.OutputBucket);
I am working on Windows 10 UWP app and my requirement is to upload 5 images on the server with unique value. So, I have used System.Threading.Tasks.Task.Factory.StartNew().Now, when I checked while debugging, I found that randomly sometimes for 2 images, it sends same unique key. Can someone suggest is it better to use System.Threading.Tasks.Task.Factory.StartNew()?
All the images are sent using a web service. My sample code for this is following
WebServiceUtility serviceUtility = new WebServiceUtility();
List<System.Threading.Tasks.Task> tasks = new List<System.Threading.Tasks.Task>();
var cancelSource = new CancellationTokenSource();
cancellationToken = cancelSource.Token;
System.Threading.Tasks.Task currentTask = null;
List<System.Threading.Tasks.Task> uploadTasks = new List<System.Threading.Tasks.Task>();
List<string> uploadedImageIdList = new List<string>();
foreach (var image in _imageCollection)
{
if (!cancellationToken.IsCancellationRequested)
{
currentTask = await System.Threading.Tasks.Task.Factory.StartNew(async () =>
{
string imageName = string.Empty;
string imagePath = string.Empty;
if (image.IsEvidenceImage)
{
imageName = image.EvidencePath.Split('\\')[1];
imagePath = image.EvidencePath;
}
else
{
imageName = image.EvidencePath.Split('#')[1].Split('\\')[1];
imagePath = image.EvidencePath.Split('#')[1];
}
byte[] _imageAsByteArray = await GetEvidenceFromIsoStore(imagePath);
if (null != _imageAsByteArray && _imageAsByteArray.Length > 0)
{
IRestResponse response = await serviceUtility.UploadImage
(_imageAsByteArray, imageName,
new RequestDataGenerator().generateRequestDataForMediaUpload(
(null != _imageItem.I_IS_PRIMARY && "1".Equals(_imageItem.I_IS_PRIMARY) ? "1" : "0"),
evidenceName
));
if (response != null && response.RawBytes.Length > 0)
{
var successMessage = MCSExtensions.CheckWebserviceResponseCode(response.StatusCode);
if (successMessage.Equals(Constants.STATUS_CODE_SUCCESS))
{
byte[] decryptedevidenceresponse = WebserviceED.finaldecryptedresponse(response.RawBytes);
string responseString = Encoding.UTF8.GetString(decryptedevidenceresponse, 0, decryptedevidenceresponse.Length);
JObject reponseObject = JObject.Parse(responseString);
//Debug.WriteLine("Evidence Upload Response : " + Environment.NewLine);
uploadedimageIdList.Add(reponseObject["P_RET_ID"].ToString());
try
{
if (image.IsEvidenceImage)
{
if (await FileExists(image.EvidencePath))
{
StorageFile file = await localFolder.GetFileAsync(image.EvidencePath);
await file.DeleteAsync();
}
}
else
{
string[] evidenceMedia = image.EvidencePath.Split('#');
foreach (string evidenceItem in evidenceMedia)
{
if (await FileExists(evidenceItem))
{
StorageFile file = await localFolder.GetFileAsync(evidenceItem);
await file.DeleteAsync();
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
else
{
UserMessageUtil.ShowMessage(successMessage);
}
}
}
}, cancellationToken);
uploadTasks.Add(currentTask);
}
}
await System.Threading.Tasks.Task.WhenAll(uploadTasks.ToArray());
Just make it a separate method:
...
foreach (var image in _imageCollection)
{
if (!cancellationToken.IsCancellationRequested)
{
currentTask = UploadAsync(...);
uploadTasks.Add(currentTask);
}
}
await Task.WhenAll(uploadTasks);
async Task UploadAsync(...)
{
string imageName = string.Empty;
string imagePath = string.Empty;
...
}
Or, a bit more simply at the call site:
...
var uploadTasks = _imageCollection.Select(x => UploadAsync(...));
await Task.WhenAll(uploadTasks);