Пример #1
0
        /// <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;
            }
        }
Пример #2
0
        /// <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;
        }
Пример #3
0
        /// <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();
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        /// <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();
            }
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
 private void SaveCache(string path, DriveFileInfo fileInfo)
 {
     CacheDriveFileInfo.Add(path, fileInfo);
 }
Пример #8
0
 private bool ReadCache(string path, out DriveFileInfo fileInfo)
 {
     return(CacheDriveFileInfo.TryGetValue(path, out fileInfo));
 }
Пример #9
0
        /// <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);
        }
Пример #10
0
        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);
        }