private void backgroundWorkerSync_DoWork(object sender, DoWorkEventArgs e) { #if DEBUG /* * string username = "******"; * string key = "7a8d5b8e34fc8339f58cc2c8e8353e7f"; * string baseURL = "http://192.168.0.77:8080/api.dev"; */ string username = "******"; string key = "a2292cc4096d84751539965522655cff"; string baseURL = "http://api.sotubo.pt"; #else string username = "******"; string key = "a2292cc4096d84751539965522655cff"; string baseURL = "http://api.sotubo.pt"; #endif WebClient cl = new WebClient(); cl.Credentials = new NetworkCredential(username, key); cl.Encoding = System.Text.Encoding.UTF8; cl.Headers[HttpRequestHeader.Authorization] = string.Format("Basic {0}:{1}", username, key); cl.Headers[HttpRequestHeader.ContentType] = "application/json;charset=utf-8"; cl.Headers[HttpRequestHeader.Accept] = "application / json, text / plain, */*"; cl.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate"; //RestClient client = new RestClient(); //client.BaseUrl = new Uri("http://api.sotubo.pt"); //client.Authenticator = new HttpBasicAuthenticator("sig", "a2292cc4096d84751539965522655cff"); //client.BaseUrl = new Uri("http://192.168.0.77:8080/api.dev"); //client.Authenticator = new HttpBasicAuthenticator("ncs", "7a8d5b8e34fc8339f58cc2c8e8353e7f"); int campaign_id = -1; bool dirty = false; while (!backgroundWorkerSync.CancellationPending && campaign_id < 0) { try { string response = cl.DownloadString(baseURL + "/mrp/count"); //RestRequest request = new RestRequest(Method.POST); //request.Resource = "mrp/count"; //IRestResponse response = client.Execute(request); if (!string.IsNullOrEmpty(response)) { JObject r = JObject.Parse(response); if (r.ContainsKey("result") && r["result"].Value <Int32>() == 1) { JToken jdata = r["jdata"]; if (jdata != null) { campaign_id = jdata["id"].Value <Int32>(); break; } } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } int t = 60; while (t-- > 0 || backgroundWorkerSync.CancellationPending) { Thread.Sleep(1000); } } SqliteConnector sqlite = DbConnection; if (!backgroundWorkerSync.CancellationPending) { try { string response = cl.DownloadString(baseURL + "/mrp/count/locations"); //RestRequest request = new RestRequest(Method.POST); //request.Resource = "mrp/count"; //IRestResponse response = client.Execute(request); if (!string.IsNullOrEmpty(response)) { JObject r = JObject.Parse(response); if (r.ContainsKey("result") && r["result"].Value <Int32>() == 1) { JArray jdata = r["jdata"] as JArray; if (jdata != null && jdata.Count > 0) { using (SQLiteConnection sqliteCon = sqlite.Connect()) { List <Location> existent = sqlite.GetLocations(sqliteCon); foreach (JObject loc in jdata) { string code = loc["code"].Value <string>(); string description = loc["description"].Value <string>(); Location db = null; for (int i = 0; i < existent.Count; i++) { if (existent[i].Code.Equals(code)) { db = existent[i]; break; } } if (db == null) { //new location record db = new Data.Location(); db.Code = code; db.Description = description; sqlite.Insert(sqliteCon, db); } else { //exists, update it and remove it from existent list so we can later delete it bool changes = false; if (!db.Description.Equals(description)) { db.Description = description; changes = true; } if (changes) { sqlite.Update(sqliteCon, db); } existent.Remove(db); } } //the ones that remain in existent list are to be deleted foreach (Location l in existent) { sqlite.Delete(sqliteCon, l); } } } } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } while (!backgroundWorkerSync.CancellationPending) { dirty = false; try { //sync upstream changes long stamp = Properties.Settings.Default.SyncLastUpdate; //RestRequest request = new RestRequest(Method.POST); //request.Resource = string.Format("mrp/count/sync/{0}/{1}", campaign_id, stamp); //IRestResponse response = client.Execute(request); string response = cl.DownloadString(baseURL + string.Format("/mrp/count/sync/{0}/{1}", campaign_id, stamp)); if (!string.IsNullOrEmpty(response)) { JObject r = JObject.Parse(response); if (r.ContainsKey("result") && r["result"].Value <Int32>() == 1) { JArray jdata = r["jdata"] as JArray; if (jdata != null && jdata.Count > 0) { using (SQLiteConnection sqliteCon = sqlite.Connect()) { foreach (JObject it in jdata) { string hash = it["hash"].Value <string>(); long update_stamp = it["update"].Value <long>(); if (update_stamp > stamp) { stamp = update_stamp; } CountEntry en = new CountEntry(); en.Itmref = it["itmref"].Value <string>(); //en.LabelNumber = nextNumber; en.Value = it["value"].Value <double>(); en.Unit = it["stu"].Value <string>(); en.Hash = it["hash"].Value <string>(); long unixTime = it["time"].Value <long>(); DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); en.Time = epoch.AddSeconds(unixTime); en.IsDeleted = it["deleted"].Value <int>() == 1; if (en.IsDeleted) { en.DeleteKey = DateTime.UtcNow.ToFileTimeUtc(); } en.SyncCode = it["id"].Value <int>(); en.Sync = CountEntry.SyncStatus.POSTED; en.Location = it["location"].Value <string>(); CountEntry ex = sqlite.GetCountEntryByHash(sqliteCon, hash); if (ex == null) { int nextNumber = 0; List <CountEntry> CountEntries = sqlite.GetCountEntries(sqliteCon, en.Itmref); nextNumber = CountEntries.Count + 1; foreach (CountEntry entry in CountEntries) { nextNumber = Math.Max(nextNumber, entry.LabelNumber + 1); } en.LabelNumber = nextNumber; sqlite.Insert(sqliteCon, en); dirty = true; } else { bool changes = false; if (!en.Itmref.Equals(ex.Itmref)) { ex.Itmref = en.Itmref; changes = true; } if (Math.Abs(en.Value - ex.Value) > 0.001) { ex.Value = en.Value; changes = true; } if (!en.Unit.Equals(ex.Unit)) { ex.Unit = en.Unit; changes = true; } if (!en.Hash.Equals(ex.Hash)) { ex.Hash = en.Hash; changes = true; } if (Math.Abs((en.Time - ex.Time).TotalSeconds) > 1) { ex.Time = en.Time; changes = true; } if (!en.IsDeleted.Equals(ex.IsDeleted)) { ex.IsDeleted = en.IsDeleted; changes = true; } if (!en.SyncCode.Equals(ex.SyncCode)) { ex.SyncCode = en.SyncCode; changes = true; } if (!en.Location.Equals(ex.Location)) { ex.Location = en.Location; changes = true; } if (changes) { sqlite.Update(sqliteCon, ex); dirty = true; } } } } } } } if (stamp > Properties.Settings.Default.SyncLastUpdate) { Properties.Settings.Default.SyncLastUpdate = stamp; Properties.Settings.Default.Save(); } //check for dirty records List <CountEntry> hoes = null; using (SQLiteConnection sqliteCon = sqlite.Connect()) { hoes = sqlite.GetDirtyCountEntries(sqliteCon); } if (hoes != null && hoes.Count > 0) { //get current active session if any //request = new RestRequest(Method.POST); //request.Resource = "mrp/count"; //response = client.Execute(request); response = cl.DownloadString(baseURL + "/mrp/count"); if (!string.IsNullOrEmpty(response)) { JObject r = JObject.Parse(response); if (r.ContainsKey("result") && r["result"].Value <Int32>() == 1) { JToken jdata = r["jdata"]; if (jdata != null) { int campaing_id = jdata["id"].Value <Int32>(); //commit changes foreach (CountEntry en in hoes) { Debug.Assert(en.Sync == CountEntry.SyncStatus.NEW); //we are assuming new to know wich ones to update on local DB if (en.IsDeleted && en.SyncCode > 0) { //delete operation //request = new RestRequest(Method.POST); //request.Resource = string.Format("mrp/count/delete/{0}/{1}", campaing_id, en.SyncCode); //response = client.Execute(request); response = cl.DownloadString(baseURL + string.Format("/mrp/count/delete/{0}/{1}", campaing_id, en.SyncCode)); r = JObject.Parse(response); if (r.ContainsKey("result") && r["result"].Value <Int32>() == 1) { en.Sync = CountEntry.SyncStatus.POSTED; } } if (!en.IsDeleted) { string url; //request = new RestRequest(Method.POST); if (en.SyncCode > 0) { //update //request.Resource = string.Format("mrp/count/update/{0}/{1}", campaing_id, en.SyncCode); url = baseURL + string.Format("/mrp/count/update/{0}/{1}", campaing_id, en.SyncCode); } else { //insert //request.Resource = string.Format("mrp/count/create/{0}/", campaing_id); url = baseURL + string.Format("/mrp/count/create/{0}", campaing_id); } Article a = null; using (SQLiteConnection sqliteCon = sqlite.Connect()) { a = sqlite.GetItem(sqliteCon, en.Itmref); } JObject parameters = new JObject(); parameters.Add("itmref", en.Itmref); parameters.Add("itmdes", a == null ? string.Empty : a.Itmdes); //parameters.Add("itmdes", string.Empty); parameters.Add("value", en.Value); parameters.Add("stu", en.Unit); parameters.Add("operator", "000"); parameters.Add("hash", en.Hash); parameters.Add("location", en.Location); parameters.Add("location_data", string.Empty); DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); parameters.Add("time", Convert.ToInt64((en.Time - epoch).TotalSeconds)); //response = client.Execute(request); response = cl.UploadString(url, parameters.ToString()); r = JObject.Parse(response); //ignore result because we want to update local record anyway if (r.ContainsKey("result")) { jdata = r["jdata"]; en.Sync = CountEntry.SyncStatus.POSTED; en.SyncCode = jdata["id"].Value <Int32>(); } } else { en.Sync = CountEntry.SyncStatus.POSTED; } } //update local DB using (SQLiteConnection sqliteCon = sqlite.Connect()) { foreach (CountEntry en in hoes) { if (en.Sync == CountEntry.SyncStatus.POSTED) { sqlite.Update(sqliteCon, en); dirty = true; } } } } } } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } int t = dirty ? 10 : 60; while (t-- > 0 || backgroundWorkerSync.CancellationPending) { Thread.Sleep(1000); } } }