Esempio n. 1
0
        /// <summary>
        /// Deserialise the json returned from the connector and update the database with the parameters read
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static string GetProjectDataFromJSON(string json)
        {
            try
            {
                //Parse JSON
                var settings = new JsonSerializerSettings
                {
                    NullValueHandling    = NullValueHandling.Ignore,
                    StringEscapeHandling = StringEscapeHandling.EscapeHtml
                };
                var projectRoot = JsonConvert.DeserializeObject <Project>(json, settings);

                DataDAO.ProcessJSON((Project)projectRoot);

                return("Data successfully downloaded");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return("Error parsing data" + e);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Synchronises the specified project: Uploads data which do not yet exist on the server, then downloads all changes since the last synchronisation.
        /// This includes authorisation
        /// </summary>
        /// <param name="projectId"></param>
        public async static void SynchroniseDataForProject(string projectId)
        {
            //Refresh token, then synchronise
            var auth = Authentication.AuthParams;

            auth.ShowErrors  = false;
            auth.AllowCancel = false;

            auth.Completed += async(sender, eventArgs) =>
            {
                if (eventArgs.IsAuthenticated == true)
                {
                    Dictionary <String, String> props = eventArgs.Account.Properties;
                    Authentication.SaveTokens(props);

                    string time     = "0000-01-01T00:00:00";
                    var    lastSync = DateTime.Now;
                    DateTime.TryParse(time, out lastSync);
                    var project = Project.FetchProject(projectId);
                    if (project.lastSync != null)
                    {
                        lastSync = project.lastSync.ToUniversalTime();
                        time     = lastSync.ToString("yyyy-MM-ddTHH:mm:ss" + "Z");
                    }
                    var json = DataDAO.PrepareJSONForUpload(lastSync); // Prepare data for upload

                    string url = App.ServerURL + "/api/Project/" + time + "?iamgod=true";

                    try
                    {
                        using (HttpClient client = new HttpClient())
                        {
                            client.Timeout = TimeSpan.FromSeconds(6000); // 10 minutes
                            var token = Preferences.Get("AccessToken", "");
                            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

                            MessagingCenter.Send(new DataDAO(), "SyncMessage", "Waiting for data");
                            var response = await client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json"));  //UPLOAD

                            var jsonbytes = await response.Content.ReadAsByteArrayAsync();

                            var utf8         = Encoding.UTF8;
                            var jsonResponse = utf8.GetString(jsonbytes, 0, jsonbytes.Length); //Response contains updates to data since last sync

                            var settings = new JsonSerializerSettings
                            {
                                NullValueHandling    = NullValueHandling.Ignore,
                                StringEscapeHandling = StringEscapeHandling.EscapeHtml
                            };
                            var returnedObject = JsonConvert.DeserializeObject <ProjectSyncDTO>(jsonResponse, settings);  //Deserialise response


                            if (returnedObject.success == true)
                            {
                                DataDAO.ProcessJSON(returnedObject.projectUpdate); //Update database with downloaded data

                                using (SQLiteConnection conn = new SQLiteConnection(Preferences.Get("databaseLocation", "")))
                                {
                                    project.lastSync = DateTime.Now;
                                    conn.Update(project);

                                    var error               = returnedObject.error;
                                    var deletedRecords      = returnedObject.records.deleted;
                                    var deletedRecords2     = returnedObject.geometries.geometryRecords.deleted;
                                    var deletedRecordsTotal = deletedRecords.Concat(deletedRecords2).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                                    var skippedRecords      = returnedObject.records.skipped;
                                    var skippedRecords2     = returnedObject.geometries.geometryRecords.skipped;
                                    var skippedRecordsTotal = skippedRecords.Concat(skippedRecords2).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                                    var deletedGeometries   = returnedObject.geometries.deleted;
                                    var skippedGeometries   = returnedObject.geometries.skipped;

                                    if (error == null || error == String.Empty)
                                    {
                                        error = "Data successfully downloaded";
                                    }

                                    foreach (var deletedRecord in deletedRecordsTotal)
                                    {
                                        //Delete records from device which have been confirmed by the connector as 'deleted' in the central db
                                        var uid        = deletedRecord.Key.ToString();
                                        var queriedRec = conn.Table <Record>().Where(r => r.recordId == uid).FirstOrDefault();
                                        conn.Delete(queriedRec, true);
                                    }
                                    foreach (var deletedGeometry in deletedGeometries)
                                    {
                                        //Delete geometries from device which have been confirmed by the connector as 'deleted' in the central db
                                        var uid         = deletedGeometry.Key.ToString();
                                        var queriedGeom = conn.Table <ReferenceGeometry>().Where(g => g.geometryId == uid).FirstOrDefault();
                                        conn.Delete(queriedGeom, true);
                                    }

                                    foreach (var skippedGeom in skippedGeometries)
                                    {
                                        if (!skippedGeom.Value.Contains("Changes were made to the associated records"))
                                        {
                                            error = error + System.Environment.NewLine;
                                            error = error + skippedGeom.Key.ToString() + ", " + skippedGeom.Value;
                                        }
                                    }

                                    foreach (var skippedRec in skippedRecordsTotal)
                                    {
                                        error = error + System.Environment.NewLine;
                                        error = error + skippedRec.Key.ToString() + ", " + skippedRec.Value;
                                    }


                                    ShowSyncCompleteMessage(error); //Show any errors in the sync confirmation message
                                }
                            }
                        }
                        MessagingCenter.Send(new Project(), "DataDownloadError", "Data successfully synchronised");
                        App.SetProject(projectId);
                        MessagingCenter.Send <Application, string>(Application.Current, "SyncMessage", "");
                    }
                    catch (Exception e)
                    {
                        // Re Log in
                        Console.WriteLine(e);
                        MessagingCenter.Send(new Project(), "DataDownloadError", @"Error synchronising data");
                        App.Current.MainPage = Login.GetPageToView();
                    }
                }
                else
                {
                    MessagingCenter.Send(new Project(), "DataDownloadError", @"Login failed");
                }
            };

            auth.Error += (sender, eventArgs) =>
            {
                //Careful! This triggers on the iPhone even when login is successful
            };

            await auth.RequestRefreshTokenAsync(Preferences.Get("RefreshToken", ""));
        }