/// <summary> /// Scarica un file dal Cloud. /// </summary> /// <param name="FileName">Nome del file da scaricare</param> /// <param name="DestFileName">Nome del file di destinazione</param> /// <returns>Restituisce FileDownloaded se l'operazione ha successo, altrimenti restituisce /// FileDownloadError in caso di errore o FileNotFound se il file non esiste</returns> public async Task <CloudFileStatus> GetFile(string FileName, string DestFileName) { if (!await CheckToken()) { Debug.WriteLine("User is not logged in!"); return(CloudFileStatus.FileDownloadError); } try { DriveFileInfo driveFileInfo = await GetFileInfo(FileName); CloudFileStatus Result = driveFileInfo.Status; if (Result == CloudFileStatus.FileError || Result == CloudFileStatus.FileNotFound) { throw new Exception(string.Format(string.Format("{0}: Unable to download the file {1}. Error: {2}", AppResources.errCloudDownload, FileName, GetLastError()))); } // Posso scaricare il file if (!await DownloadFile(driveFileInfo.FileID, DestFileName)) { Result = CloudFileStatus.FileDownloadError; } return(CloudFileStatus.FileDownloaded); } catch (Exception e) { Debug.WriteLine(string.Format("GetFile error: {0}", e.Message)); throw; } }
/// <summary> /// Constructs a request to download a Google Drive file. /// </summary> /// <param name="driveFile">The remote file information.</param> /// <param name="responseWriter">The stream to wirte a file content.</param> public DriveFileDownloadRequest(DriveFileInfo driveFile, Stream responseWriter) { if (driveFile == null) { throw new ArgumentNullException("driveFile"); } if (responseWriter == null) { throw new ArgumentNullException("responseWriter"); } DriveFile = driveFile; ResponseWriter = responseWriter; }
/// <summary> /// Cancella un file dal Cloud /// </summary> /// <param name="FileName">Nome del file da cancellare</param> /// <returns></returns> public async Task DeleteFile(string FileName) { if (!await CheckToken()) { Debug.WriteLine("User is not logged in"); throw new Exception("Unable to delete the file " + FileName + ". Error: User is not logged in"); } HttpClient AppClient = new HttpClient(); try { DriveFileInfo fileInfo = await GetFileInfo(FileName); if (fileInfo.Status != CloudFileStatus.FileFound) { Debug.WriteLine("Delete file " + FileName + " failed. Status code: " + fileInfo.Status); throw new Exception("Delete file " + FileName + " failed. Status code: " + fileInfo.Status); } AppClient.DefaultRequestHeaders.Clear(); AppClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Account.AccessToken); string Url = URLBase + "/files/" + fileInfo.FileID; HttpResponseMessage Response = await AppClient.DeleteAsync(new Uri(Url)); if (!Response.IsSuccessStatusCode) { Debug.WriteLine("Delete file " + FileName + " failed. Status code: " + Response.StatusCode); throw new Exception("Delete file " + FileName + " failed. Status code: " + Response.StatusCode); } RemoveCache(FileName); Debug.WriteLine("File " + FileName + " deleted"); } catch (Exception Ex) { Debug.WriteLine("Unable to delete the file " + FileName + ". Error: " + Ex.Message); throw new Exception("Unable to delete the file " + FileName + ". Error: " + Ex.Message); } finally { AppClient.Dispose(); } }
private static DriveFileInfo GetDriveFolder(DriveClient client, string rootFolderId, IEnumerable <string> pathItems, bool createIfNotExists = false) { DriveFileInfo currentFolder = null; string currentId = rootFolderId; foreach (var pathItem in pathItems) { var getRequest = new DriveFileListRequest { MaxResults = 4, Query = string.Format("trashed = false and title = '{0}' and mimeType = 'application/vnd.google-apps.folder'", pathItem) }; var getResponse = client.Execute(getRequest); currentFolder = getResponse.Data.Items.FirstOrDefault(); if (currentFolder == null) { if (!createIfNotExists) { break; } var createRequest = new DriveFolderCreateRequest(new DriveFolderShortInfo { Title = pathItem, Parents = new List <DriveParentReferenceInfo> { new DriveParentReferenceInfo { Id = currentId } } }); var createResponse = client.Execute(createRequest); currentFolder = createResponse.Data; } currentId = currentFolder.Id; } return(currentFolder); }
/// <summary> /// Carica un file su GoogleDrive /// </summary> /// <param name="FileName">Nome del file da caricare</param> /// <param name="DestFileName">Nome del file su GoogleDrive</param> /// <returns>Restituisce true se l'operazione va a buon fine, false altrimenti.</returns> public async Task <bool> UploadFile(string FileName, string DestFileName) { if (!await CheckToken()) { Debug.WriteLine("User is not logged in"); return(false); } HttpClient AppClient = new HttpClient(); try { string appDataFolderID = await GetAppDataFolderID(); AppClient.DefaultRequestHeaders.Clear(); AppClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Account.AccessToken); // Verifica se il file esiste già su Cloud DriveFileInfo driveFileInfo = await GetFileInfo(DestFileName); bool update = (driveFileInfo.Status == CloudFileStatus.FileFound); // Cartella di destinazione del file JArray parentsID = new JArray(new[] { appDataFolderID }); if (string.Compare(Path.GetFileName(DestFileName), DestFileName) != 0) { string[] tokens = DestFileName.Split(new[] { Path.DirectorySeparatorChar }); if (tokens.Length > 1) { DriveFileInfo folderInfo = await GetFileInfo(tokens[tokens.Length - 2]); if (folderInfo.Status != CloudFileStatus.FileFound) { throw new Exception("Unable to get the ID of the folder for file " + DestFileName); } parentsID[0] = new JValue(folderInfo.FileID); } } // Metadati per l'upload HttpResponseMessage Response = null; JObject jsonMetadata = new JObject { { "name", new JValue(Path.GetFileName(DestFileName)) }, { "parents", parentsID } }; if (update) { jsonMetadata.Add("id", new JValue(driveFileInfo.FileID)); } // Due modalità diverse a seconda delle dimensioni del file FileInfo fileInfo = new FileInfo(FileName); if (fileInfo.Length > 5 * 1024 * 1024) { string url = URLBaseUpload + "/files?uploadType=resumable"; if (update) { url = URLBaseUpload + "/files/" + driveFileInfo.FileID + "?uploadType=resumable"; } AppClient.DefaultRequestHeaders.Add("X-Upload-Content-Length", fileInfo.Length.ToString()); if (update) { HttpRequestMessage PatchRequest = new HttpRequestMessage(new HttpMethod("PATCH"), new Uri(url)); Response = await AppClient.SendAsync(PatchRequest); } else { StringContent metatdataContent = new StringContent(jsonMetadata.ToString(), Encoding.UTF8, "application/json"); Response = await AppClient.PostAsync(new Uri(url), metatdataContent); } if (!Response.IsSuccessStatusCode) { throw new Exception(string.Format("File {0} not uploaded. Status code: {1}", FileName, Response.StatusCode)); } long read = 0, start = 0; FileStream fileStream = new FileStream(FileName, FileMode.Open); Uri Location = Response.Headers.Location; try { AppClient.DefaultRequestHeaders.Clear(); do { read = Math.Min(256 * 1024, fileStream.Length - start); if (read > 0) { int attempt = 0; do { byte[] buffer = new byte[read]; fileStream.Position = start; await fileStream.ReadAsync(buffer, 0, (int)read); ByteArrayContent chunkData = new ByteArrayContent(buffer); chunkData.Headers.ContentRange = new System.Net.Http.Headers.ContentRangeHeaderValue(start, start + read - 1, fileStream.Length); chunkData.Headers.ContentLength = read; Response = await AppClient.PutAsync(Location, chunkData); if (Response.IsSuccessStatusCode) { break; } if (Response.StatusCode != (System.Net.HttpStatusCode) 308) { await Task.Delay(1000); attempt++; } }while (attempt < 10 && Response.StatusCode != (System.Net.HttpStatusCode) 308); if (attempt >= 10 || (!Response.IsSuccessStatusCode && Response.StatusCode != (System.Net.HttpStatusCode) 308)) { throw new Exception(string.Format("File {0} not uploaded. Status code: {1}", FileName, Response.StatusCode)); } start += read; } }while (read > 0); } catch (HttpRequestException Ex) { Debug.WriteLine("UploadFile error: " + Ex.Message); throw; } finally { fileStream.Dispose(); } } else { // Caricamento per intero. Il file è piccolo string url = URLBaseUpload + "/files?uploadType=multipart"; if (update) { url = URLBaseUpload + "/files/" + driveFileInfo.FileID + "?uploadType=multipart"; } bool fail = false; int attempt = 0; do { FileStream fileStream = new FileStream(FileName, FileMode.Open); try { if (update) { HttpRequestMessage PatchRequest = new HttpRequestMessage(new HttpMethod("PATCH"), new Uri(url)) { Content = new StreamContent(fileStream) }; Response = await AppClient.SendAsync(PatchRequest); } else { MultipartContent multipart = new MultipartContent("related") { new StringContent(jsonMetadata.ToString(), Encoding.UTF8, "application/json"), new StreamContent(fileStream) }; Response = await AppClient.PostAsync(new Uri(url), multipart); } } finally { fileStream.Close(); } if ((fail = !Response.IsSuccessStatusCode)) { attempt++; } }while (attempt < 5 && fail); // Prova al massimo 5 volte if (fail) { throw new Exception(string.Format("File {0} not uploaded. Status code: {1}", FileName, Response.StatusCode)); } } return(true); } catch (FileNotFoundException e) { // File sorgente non trovato Debug.WriteLine(AppResources.errCloudUpload + " file not found. Error: " + e.Message); return(false); } catch (Exception e) { Debug.WriteLine(AppResources.errCloudUpload + " " + e.Message); return(false); } finally { AppClient.Dispose(); } }
/// <summary> /// Verifica se il file esiste e restituisce le informazioni al riguardo. /// </summary> /// <param name="path">Nome del file di cui ottenere informazioni</param> /// <param name="fromRoot">Passare true per ricercare il file o cartella nella root. /// Passare false (default) per cercare il file o cartella nella app data folder.</param> /// <returns>Oggetto con le informazioni sul file e sullo stato della ricerca</returns> private async Task <DriveFileInfo> GetFileInfo(string path, bool fromRoot = false) { const string UrlRoot = URLBase + "/files"; LastError = ""; DriveFileInfo Result = new DriveFileInfo { Status = CloudFileStatus.FileNotFound, FileName = path }; if (!await CheckToken()) { LastError = "User is not logged in!"; Debug.WriteLine(LastError); Result.Status = CloudFileStatus.FileError; return(Result); } // Legge prima in cache if (ReadCache(path, out DriveFileInfo fileInfo)) { return(fileInfo); } // Ottiene la lista dei file nella cartella dedicata all'App HttpClient appClient = new HttpClient(); try { appClient.DefaultRequestHeaders.Clear(); appClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Account.AccessToken); string parentID = (fromRoot ? "root" : await GetAppDataFolderID()); string[] tokens = new[] { path }; if (string.Compare(Path.GetFileName(path), path) != 0) { tokens = path.Split(new[] { Path.DirectorySeparatorChar }); } for (int i = 0; i < tokens.Length; i++) { string filter = "'" + parentID + "' in parents"; string Url = UrlRoot + "?q=" + Uri.EscapeUriString("name='" + tokens[i] + "' and " + filter); Url += "&fields=files(id, name)"; HttpResponseMessage Response = await appClient.GetAsync(new Uri(Url)); if (!Response.IsSuccessStatusCode) { LastError = "Unable to find the file " + path + ". Status code: " + Response.StatusCode; Debug.WriteLine(LastError); Result.Status = CloudFileStatus.FileError; return(Result); } JObject JsonObj = JObject.Parse(await Response.Content.ReadAsStringAsync()); if (JsonObj != null) { if (JsonObj.ContainsKey("files")) { JArray jsonFiles = JsonObj["files"].ToObject <JArray>(); if (jsonFiles.Count == 0) { Result.Status = CloudFileStatus.FileNotFound; return(Result); } if (jsonFiles.Count > 1) { LastError = "Unable to find the file " + path + ". Too many result for token " + tokens[i]; Debug.WriteLine(LastError); Result.Status = CloudFileStatus.FileError; return(Result); } parentID = (jsonFiles[0].ToObject <JObject>())["id"].ToString(); } else { LastError = "Parse error for file " + path + ". Property 'files' not found for token " + tokens[i]; Debug.WriteLine(LastError); Result.Status = CloudFileStatus.FileError; return(Result); } } else { LastError = "Parse error for file " + path + ". Invalid response for token " + tokens[i]; Debug.WriteLine(LastError); Result.Status = CloudFileStatus.FileError; return(Result); } } // Il file esiste Result.FileID = parentID; Result.Status = CloudFileStatus.FileFound; SaveCache(path, Result); } catch (Exception Ex) { LastError = "Unable to find the file " + path + ": " + Ex.Message; Debug.WriteLine(LastError); Result.Status = CloudFileStatus.FileError; return(Result); } finally { appClient.Dispose(); } return(Result); }
private void SaveCache(string path, DriveFileInfo fileInfo) { CacheDriveFileInfo.Add(path, fileInfo); }
private bool ReadCache(string path, out DriveFileInfo fileInfo) { return(CacheDriveFileInfo.TryGetValue(path, out fileInfo)); }
/// <summary> /// Verifica se un determinato file esiste su GoogleDrive. /// </summary> /// <param name="FileName">Nome del file</param> /// <returns>Restituisce FileNotFound se il file non viene trovato, FileFound se esiste /// o FileError in caso di errore. Chiamare la funzione GetLastError per informazioni sull'eventuale /// errore.</returns> public async Task <CloudFileStatus> FileExists(string FileName) { DriveFileInfo fileInfo = await GetFileInfo(FileName); return(fileInfo.Status); }
private async Task <string> GetAppDataFolderID() { if (AppDataFolderID != "") { return(AppDataFolderID); } DriveFileInfo driveFileInfo = await GetFileInfo(AppDataFolder, true); if (driveFileInfo.Status == CloudFileStatus.FileError) { throw new Exception("Unable to access to the App data folder"); } if (driveFileInfo.Status == CloudFileStatus.FileNotFound) { // Crea la cartella HttpClient AppClient = new HttpClient(); try { AppClient.DefaultRequestHeaders.Clear(); AppClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Account.AccessToken); string Url = URLBase + "/files"; JObject jsonMetadata = new JObject { { "name", JValue.CreateString(AppDataFolder) }, { "mimeType", JValue.CreateString(MimeTypeFolder) } }; StringContent Content = new StringContent(jsonMetadata.ToString(), Encoding.UTF8, "application/json"); HttpResponseMessage Response = await AppClient.PostAsync(new Uri(Url), Content); if (!Response.IsSuccessStatusCode) { throw new Exception("Folder " + AppDataFolder + " not created. Status code:" + Response.StatusCode); } JObject jsonCreate = JObject.Parse(await Response.Content.ReadAsStringAsync()); if (jsonCreate != null) { driveFileInfo.Status = CloudFileStatus.FileFound; driveFileInfo.FileID = jsonCreate["id"].ToString(); } else { throw new Exception("Error occurred on parsing responde from Cloud"); } } catch (Exception Ex) { Debug.WriteLine("GetAppDataFolderInfo: unable to create the App data folder"); throw new Exception("Unable to create the App data folder. Error: " + Ex.Message); } finally { AppClient.Dispose(); } } AppDataFolderID = driveFileInfo.FileID; return(AppDataFolderID); }