void Update() { _internetConnectionWatcher.Update(); _mainThreadQueueRunner.PerformQueuedTasks(); // check remote changes for subscribed if (Time.unscaledTime - _lastTimeCheckedForSubscribedItemsChanges > CHECK_REMOTE_UPDATES_INTERVAL_SECONDS) { DropboxSyncUtils.IsOnlineAsync((isOnline) => { if (isOnline) { try { CheckChangesForSubscribedItems(); }catch (Exception ex) { Debug.LogException(ex); } } }); _lastTimeCheckedForSubscribedItemsChanges = Time.unscaledTime; } }
/// <summary> /// Asynchronously retrieves file from Dropbox as byte[] /// </summary> /// <param name="dropboxPath">Path to file on Dropbox or inside of Dropbox App folder (depending on accessToken type). Should start with "/". Example: /DropboxSyncExampleFolder/image.jpg</param> /// <param name="onResult">Result callback</param> /// <param name="onProgress">Callback function that receives progress as float from 0 to 1.</param> /// <param name="useCachedFirst">If True then first tries to get data from cache, if not cached then downloads.</param> /// <param name="useCachedIfOffline">If True and there's no Internet connection then retrieves file from cache if cached, otherwise produces error.</param> /// <param name="receiveUpdates">If true , then when there are remote updates on Dropbox, callback function onResult will be triggered again with updated version of the file.</param> public void GetFileAsBytes(string dropboxPath, Action <DropboxRequestResult <byte[]> > onResult, Action <float> onProgress = null, bool useCachedFirst = false, bool useCachedIfOffline = true, bool receiveUpdates = false) { if (DropboxSyncUtils.IsBadDropboxPath(dropboxPath)) { onResult(DropboxRequestResult <byte[]> .Error( new DBXError("Cant get file: bad path " + dropboxPath, DBXErrorType.BadRequest) ) ); return; } Action returnCachedResult = () => { var cachedFilePath = GetPathInCache(dropboxPath); if (File.Exists(cachedFilePath)) { var bytes = File.ReadAllBytes(cachedFilePath); _mainThreadQueueRunner.QueueOnMainThread(() => { onResult(new DropboxRequestResult <byte[]>(bytes)); }); } else { Log("cache doesnt have file"); _mainThreadQueueRunner.QueueOnMainThread(() => { onResult( DropboxRequestResult <byte[]> .Error( new DBXError("File " + dropboxPath + " is removed on remote", DBXErrorType.RemotePathNotFound) ) ); }); } }; Action subscribeToUpdatesAction = () => { SubscribeToFileChanges(dropboxPath, (fileChange) => { UpdateFileFromRemote(dropboxPath, onSuccess: () => { // return updated cached result returnCachedResult(); }, onProgress: (progress) => { if (onProgress != null) { _mainThreadQueueRunner.QueueOnMainThread(() => { onProgress(progress); }); } }, onError: (error) => { _mainThreadQueueRunner.QueueOnMainThread(() => { onResult(DropboxRequestResult <byte[]> .Error(error)); }); }); }); }; // maybe no need to do any remote requests if ((useCachedFirst) && IsFileCached(dropboxPath)) { Log("GetFile: using cached version"); returnCachedResult(); if (receiveUpdates) { subscribeToUpdatesAction(); } } else { //Log("GetFile: check if online"); // now check if we online DropboxSyncUtils.IsOnlineAsync((isOnline) => { try { if (isOnline) { Log("GetFile: internet available"); // check if have updates and load them UpdateFileFromRemote(dropboxPath, onSuccess: () => { Log("GetFile: state of dropbox file is " + dropboxPath + " is synced now"); // return updated cached result returnCachedResult(); if (receiveUpdates) { subscribeToUpdatesAction(); } }, onProgress: (progress) => { if (onProgress != null) { _mainThreadQueueRunner.QueueOnMainThread(() => { onProgress(progress); }); } }, onError: (error) => { //Log("error"); _mainThreadQueueRunner.QueueOnMainThread(() => { onResult(DropboxRequestResult <byte[]> .Error(error)); }); if (receiveUpdates) { subscribeToUpdatesAction(); } }); } else { Log("GetFile: internet not available"); if (useCachedIfOffline && IsFileCached(dropboxPath)) { Log("GetFile: cannot check for updates - using cached version"); returnCachedResult(); if (receiveUpdates) { subscribeToUpdatesAction(); } } else { if (receiveUpdates) { // try again when internet recovers _internetConnectionWatcher.SubscribeToInternetConnectionRecoverOnce(() => { GetFileAsBytes(dropboxPath, onResult, onProgress, useCachedFirst, useCachedIfOffline, receiveUpdates); }); subscribeToUpdatesAction(); } else { // error _mainThreadQueueRunner.QueueOnMainThread(() => { onResult(DropboxRequestResult <byte[]> .Error( new DBXError("GetFile: No internet connection", DBXErrorType.NetworkProblem) ) ); }); } } } }catch (Exception ex) { Debug.LogException(ex); } }); } }
void MakeDropboxRequest(string url, string jsonParameters, Action <string> onResponse, Action <float> onProgress, Action <DBXError> onWebError) { Log("MakeDropboxRequest url: " + url); DropboxSyncUtils.IsOnlineAsync((isOnline) => { if (!isOnline) { onWebError(new DBXError("No internet connection", DBXErrorType.NetworkProblem)); return; } try { using (var client = new DBXWebClient()){ client.Headers.Set("Authorization", "Bearer " + DropboxAccessToken); client.Headers.Set("Content-Type", "application/json"); client.DownloadProgressChanged += (s, e) => { if (onProgress != null) { Log(string.Format("Downloaded {0} bytes out of {1}", e.BytesReceived, e.TotalBytesToReceive)); if (e.TotalBytesToReceive != -1) { // if download size in known from server // _mainThreadQueueRunner.QueueOnMainThread(() => { onProgress((float)e.BytesReceived / e.TotalBytesToReceive); // }); } else { // return progress is going but unknown // _mainThreadQueueRunner.QueueOnMainThread(() => { onProgress(-1); // }); } } }; client.UploadDataCompleted += (s, e) => { Log("MakeDropboxRequest -> UploadDataCompleted"); _activeWebClientsList.Remove(client); if (e.Error != null) { Log("MakeDropboxRequest -> UploadDataCompleted -> Error"); //LogError("MakeDropboxRequest -> UploadDataCompleted -> Error "+e.Error.Message); if (e.Error is WebException) { Log("MakeDropboxRequest -> UploadDataCompleted -> Error -> WebException"); var webex = e.Error as WebException; try{ var stream = webex.Response.GetResponseStream(); var reader = new StreamReader(stream); var responseStr = reader.ReadToEnd(); var dict = JSON.FromJson <Dictionary <string, object> >(responseStr); var errorSummary = dict["error_summary"].ToString(); // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(errorSummary, DBXError.DropboxAPIErrorSummaryToErrorType(errorSummary))); // }); }catch (Exception ex) { Log("MakeDropboxRequest -> UploadDataCompleted -> Error -> WebException -> try get summary -> Exception: " + ex.Message); // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(e.Error.Message, DBXErrorType.ParsingError)); // }); } } else { // _mainThreadQueueRunner.QueueOnMainThread(() => { Log("MakeDropboxRequest -> UploadDataCompleted -> Error -> not WebException"); if (e.Error != null) { onWebError(new DBXError(e.Error.Message + "\n" + e.Error.StackTrace, DBXErrorType.Unknown)); } else { onWebError(new DBXError("Unknown error", DBXErrorType.Unknown)); } // }); } } else if (e.Cancelled) { onWebError(new DBXError("User canceled request", DBXErrorType.UserCancelled)); } else { // no error var respStr = Encoding.UTF8.GetString(e.Result); // _mainThreadQueueRunner.QueueOnMainThread(() => { onResponse(respStr); // }); } }; var uri = new Uri(url); Log("MakeDropboxRequest:client.UploadDataAsync"); client.UploadDataAsync(uri, "POST", Encoding.Default.GetBytes(jsonParameters)); _activeWebClientsList.Add(client); } } catch (Exception ex) { //onWebError(ex.Message); //Log("caught exeption"); onWebError(new DBXError(ex.Message, DBXErrorType.Unknown)); //Log(ex.Response.ToString()); } }); }
void MakeDropboxUploadRequest(string url, byte[] dataToUpload, string jsonParameters, Action <DBXFile> onResponse, Action <float> onProgress, Action <DBXError> onWebError) { DropboxSyncUtils.IsOnlineAsync((isOnline) => { if (!isOnline) { onWebError(new DBXError("No internet connection", DBXErrorType.NetworkProblem)); return; } try { using (var client = new DBXWebClient()){ client.Headers.Set("Authorization", "Bearer " + DropboxAccessToken); client.Headers.Set("Dropbox-API-Arg", jsonParameters); client.Headers.Set("Content-Type", "application/octet-stream"); client.UploadProgressChanged += (s, e) => { Log(string.Format("Upload {0} bytes out of {1} ({2}%)", e.BytesSent, e.TotalBytesToSend, e.ProgressPercentage)); if (onProgress != null) { // _mainThreadQueueRunner.QueueOnMainThread(() => { var uploadProgress = (float)e.BytesSent / e.TotalBytesToSend; var SERVER_PROCESSING_PERCENTAG_VALUE = 0.99f; if (uploadProgress > SERVER_PROCESSING_PERCENTAG_VALUE && e.ProgressPercentage < 100) { // waiting for server to process uploaded file onProgress(SERVER_PROCESSING_PERCENTAG_VALUE); } else { onProgress(uploadProgress); } // }); } }; client.UploadDataCompleted += (s, e) => { Log("MakeDropboxUploadRequest -> UploadDataCompleted"); _activeWebClientsList.Remove(client); if (e.Error != null) { Log("MakeDropboxUploadRequest -> UploadDataCompleted -> with error"); if (e.Error is WebException) { Log("MakeDropboxUploadRequest -> UploadDataCompleted -> with error -> WebException"); var webex = e.Error as WebException; var stream = webex.Response.GetResponseStream(); var reader = new StreamReader(stream); var responseStr = reader.ReadToEnd(); LogWarning(responseStr); try{ var dict = JSON.FromJson <Dictionary <string, object> >(responseStr); var errorSummary = dict["error_summary"].ToString(); // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(errorSummary, DBXErrorType.DropboxAPIError)); // }); }catch { // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(e.Error.Message, DBXErrorType.ParsingError)); // }); } } else { // _mainThreadQueueRunner.QueueOnMainThread(() => { Log("e.Error is something else"); if (e.Error != null) { onWebError(new DBXError(e.Error.Message, DBXErrorType.Unknown)); } else { onWebError(new DBXError("Unknown error", DBXErrorType.Unknown)); } // }); } } else if (e.Cancelled) { Log("MakeDropboxUploadRequest -> canceled"); // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError("Download was cancelled.", DBXErrorType.UserCancelled)); // }); } else { Log("MakeDropboxUploadRequest -> no error"); //var respStr = Encoding.UTF8.GetString(e.Result); var metadataJsonStr = Encoding.UTF8.GetString(e.Result);; Log(metadataJsonStr); var dict = JSON.FromJson <Dictionary <string, object> >(metadataJsonStr); var fileMetadata = DBXFile.FromDropboxDictionary(dict); // _mainThreadQueueRunner.QueueOnMainThread(() => { onResponse(fileMetadata); // }); } }; var uri = new Uri(url); // don't use UploadFile (https://stackoverflow.com/questions/18539807/how-to-remove-multipart-form-databoundary-from-webclient-uploadfile) client.UploadDataAsync(uri, "POST", dataToUpload); _activeWebClientsList.Add(client); } } catch (WebException ex) { // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(ex.Message, DBXErrorType.Unknown)); // }); } }); }
void MakeDropboxDownloadRequest(string url, string jsonParameters, Action <DBXFile, byte[]> onResponse, Action <float> onProgress, Action <DBXError> onWebError) { DropboxSyncUtils.IsOnlineAsync((isOnline) => { if (!isOnline) { onWebError(new DBXError("No internet connection", DBXErrorType.NetworkProblem)); return; } try { using (var client = new DBXWebClient()){ client.Headers.Set("Authorization", "Bearer " + DropboxAccessToken); client.Headers.Set("Dropbox-API-Arg", jsonParameters); client.DownloadProgressChanged += (s, e) => { if (onProgress != null) { //Log(string.Format("Downloaded {0} bytes out of {1} ({2}%)", e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage)); if (e.TotalBytesToReceive != -1) { // if download size in known from server // _mainThreadQueueRunner.QueueOnMainThread(() => { onProgress((float)e.BytesReceived / e.TotalBytesToReceive); // }); } else { // return progress is going but unknown // _mainThreadQueueRunner.QueueOnMainThread(() => { onProgress(-1); // }); } } }; client.DownloadDataCompleted += (s, e) => { _activeWebClientsList.Remove(client); if (e.Error != null) { if (e.Error is WebException) { var webex = e.Error as WebException; var stream = webex.Response.GetResponseStream(); var reader = new StreamReader(stream); var responseStr = reader.ReadToEnd(); Log(responseStr); try{ var dict = JSON.FromJson <Dictionary <string, object> >(responseStr); var errorSummary = dict["error_summary"].ToString(); // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(errorSummary, DBXError.DropboxAPIErrorSummaryToErrorType(errorSummary))); // }); }catch { // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(e.Error.Message, DBXErrorType.ParsingError)); // }); } } else { // _mainThreadQueueRunner.QueueOnMainThread(() => { Log("e.Error is something else"); if (e.Error != null) { onWebError(new DBXError(e.Error.Message, DBXErrorType.Unknown)); } else { onWebError(new DBXError("Unknown error", DBXErrorType.Unknown)); } // }); } } else if (e.Cancelled) { // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError("Download was cancelled.", DBXErrorType.UserCancelled)); // }); } else { //var respStr = Encoding.UTF8.GetString(e.Result); var metadataJsonStr = client.ResponseHeaders["Dropbox-API-Result"].ToString(); Log(metadataJsonStr); var dict = JSON.FromJson <Dictionary <string, object> >(metadataJsonStr); var fileMetadata = DBXFile.FromDropboxDictionary(dict); // _mainThreadQueueRunner.QueueOnMainThread(() => { onResponse(fileMetadata, e.Result); // }); } }; var uri = new Uri(url); client.DownloadDataAsync(uri); _activeWebClientsList.Add(client); } } catch (WebException ex) { // _mainThreadQueueRunner.QueueOnMainThread(() => { onWebError(new DBXError(ex.Message, DBXErrorType.Unknown)); // }); } }); }