1 // frmActivityMgr.cpp - Activity Manager form.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
19 #include "frmActivityMgr.h"
20 #include <wx/mstream.h>
23 #include <wx/tokenzr.h>
25 #include <wx/filefn.h>
27 #include <curl/curl.h>
29 #include "../bitmaps.h"
31 #include "../common/preferences.h"
32 #include "../frmConflictResolution.h"
33 #include "../frmInvalidSSLCertificate.h"
34 #include "../frmMain.h"
35 #include "../common/events.h"
36 #include "../common/filename.h"
37 #include "../vcard/vcard34conv.h"
38 #include "../vcard/vcard.h"
40 #ifndef FRMACTIVITYMGR_H
41 #define FRMACTIVITYMGR_H
43 DEFINE_EVENT_TYPE(ACTMGR_RESUMEPROC);
44 DEFINE_EVENT_TYPE(ACTMGR_TOGGLECONN);
45 DEFINE_EVENT_TYPE(ACTMGR_STARTTIMER);
46 DEFINE_EVENT_TYPE(ACTMGR_STOPTIMER);
47 DEFINE_EVENT_TYPE(ACTMGR_STARTPROCESSTIMER);
48 DEFINE_EVENT_TYPE(ACTMGR_STOPPROCESSTIMER);
49 DEFINE_EVENT_TYPE(ACTMGR_UPDATESTATUSLABEL);
51 BEGIN_EVENT_TABLE(frmActivityMgr, wxWindow)
52 EVT_COMMAND(wxID_ANY, ACTMGR_RESUMEPROC, frmActivityMgr::ResumeProcessing)
53 EVT_COMMAND(wxID_ANY, ACTMGR_TOGGLECONN, frmActivityMgr::ToggleConnectionStatus)
54 EVT_COMMAND(wxID_ANY, ACTMGR_STARTTIMER, frmActivityMgr::StartTimer)
55 EVT_COMMAND(wxID_ANY, ACTMGR_STOPTIMER, frmActivityMgr::StopTimer)
56 EVT_COMMAND(wxID_ANY, ACTMGR_STARTPROCESSTIMER, frmActivityMgr::StartProcessTimer)
57 EVT_COMMAND(wxID_ANY, ACTMGR_STOPPROCESSTIMER, frmActivityMgr::StopProcessTimer)
58 EVT_COMMAND(wxID_ANY, ACTMGR_UPDATESTATUSLABEL, frmActivityMgr::UpdateStatusLabel)
61 frmActivityMgr::frmActivityMgr( wxWindow* parent )
63 frmActivityMgrADT( parent )
66 wxMemoryInputStream istream(icons_activitywindow_png, sizeof(icons_activitywindow_png));
67 wxImage icons_activitywindow_pngi(istream, wxBITMAP_TYPE_PNG);
68 wxBitmap activityiconbmp(icons_activitywindow_pngi, -1);
70 activityicon.CopyFromBitmap(activityiconbmp);
71 this->SetIcon(activityicon);
73 wxMemoryInputStream istream2(misc_activitysleep_png, sizeof(misc_activitysleep_png));
74 wxImage misc_activitysleep_pngi(istream2, wxBITMAP_TYPE_PNG);
75 wxBitmap sleepiconbmp(misc_activitysleep_pngi, -1);
76 SleepBitmap = sleepiconbmp;
77 bmpActivity->SetBitmap(SleepBitmap);
78 ActProcessTimer.SetupPointers(this);
79 lblDetails->SetLabel(_("No activity."));
81 ActListProcTimer.SetupPointers(&ActivityList, &ActivityListIndex, &ActivityListTaskDetail,
82 &TasksActive, lstActivity, lblDetails, GauProgress, this, &AnimationTimer,
83 &ActProcessTimer, &ActivityListFinDate, &ActivityListConn);
85 AnimationTimer.SetBitmap(bmpActivity);
86 AnimationTimer.SetSleepBitmap(&SleepBitmap);
87 AnimationTimer.SetupPointer(this->GetParent());
89 wxListItem ColumnData;
91 ColumnData.SetText(_("Activity"));
92 ColumnData.SetWidth(175);
93 lstActivity->InsertColumn(0, ColumnData);
95 wxListItem ColumnData2;
97 ColumnData2.SetText(_("Account"));
98 ColumnData2.SetWidth(100);
99 lstActivity->InsertColumn(1, ColumnData2);
101 wxListItem ColumnData3;
102 ColumnData3.SetId(2);
103 ColumnData3.SetText(_("Status"));
104 ColumnData3.SetWidth(100);
105 lstActivity->InsertColumn(2, ColumnData3);
107 //AnimationTimer.StartAnimation();
109 // Create recovery database if it doesn't exist.
111 wxString RecoveryFilename = GetRecoveryDB();
115 if (wxFile::Exists(RecoveryFilename) == FALSE){
117 // Create the recovery database.
119 RecoveryDB.Open(RecoveryFilename.c_str(), wxFile::write);
121 RecoveryDB.Write(wxT("BEGIN:XAB-RECOVERYDB\r\n"), wxConvUTF8);
122 RecoveryDB.Write(wxT("VERSION:1.0\r\n"), wxConvUTF8);
123 RecoveryDB.Write(wxT("COMMENT:Please do not alter or delete this file. DATA LOSS IS POSSIBLE!\r\n"), wxConvUTF8);
124 RecoveryDB.Write(wxT("END:XAB-RECOVERYDB\r\n"), wxConvUTF8);
131 #if wxABI_VERSION < 20900
132 RecoveryDBF.Open(RecoveryFilename.c_str(), wxT("r"));
134 RecoveryDBF.Open(RecoveryFilename, wxT("r"));
137 // Load the recovery database for tasks not done.
139 if (RecoveryDBF.IsOpened() == TRUE){
141 wxString wxSRecoveryDB;
142 wxString RecoveryLine;
144 // Check if we are using wxWidgets version 2.8 or less and
145 // execute the required command accordingly.
147 RecoveryDBF.ReadAll(&wxSRecoveryDB, wxConvAuto());
151 std::map<int, wxString> RecoveryFileLines;
152 std::map<int, wxString>::iterator striter;
154 wxStringTokenizer wSTRecoveryDBLines(wxSRecoveryDB, wxT("\r\n"));
156 int RecoveryLineSeek = 0;
158 while (wSTRecoveryDBLines.HasMoreTokens() == TRUE){
160 RecoveryLine = wSTRecoveryDBLines.GetNextToken();
161 RecoveryFileLines.insert(std::make_pair(RecoveryLineSeek, RecoveryLine));
170 //TestTimer.Start(50, FALSE);
173 void frmActivityMgr::OpenWindow()
178 void frmActivityMgr::CloseWindow( wxCommandEvent& event )
184 void frmActivityMgr::CloseWindow( wxCloseEvent& event )
190 void frmActivityMgr::ProcessTasksThread()
193 if (ProcessTasksData == FALSE){
199 std::map<int,int>::iterator TypeIter;
200 std::map<int,wxString>::iterator StringIter;
201 std::map<int,wxString>::iterator StringDetailIter;
202 std::map<int,wxString>::iterator StringAccountIter;
203 std::map<int,wxString>::iterator StringFilenameIter;
204 std::map<int,wxString>::iterator StringFullFilenameIter;
205 std::map<int,wxString>::iterator StringTaskDetailIter;
206 std::map<int,wxString>::iterator StringETagIter;
207 std::map<int,wxString>::iterator StringETagOrigIter;
208 std::map<int,CardDAV*>::iterator CardDAVIter;
209 std::map<int,long>::iterator LongIter;
210 bool TasksFoundProc = FALSE;
213 for (std::map<int,int>::iterator iter = ActivityList.begin();
214 iter != ActivityList.end(); ++iter){
216 // Check for any queued tasks and start one.
218 if (iter->second > 4){
222 CardDAVIter = ActivityListConn.find(iter->first);
223 TypeIter = ActivityListType.find(iter->first);
224 StringETagIter = ActivityListETag.find(iter->first);
225 StringETagOrigIter = ActivityListETagOriginal.find(iter->first);
226 StringAccountIter = ActivityListAccount.find(iter->first);
227 StringFilenameIter = ActivityListFilename.find(iter->first);
228 StringFullFilenameIter = ActivityListFullFilename.find(iter->first);
235 // 5 = Failed (UI Updated).
236 // 6 = Stopped (UI Updated).
237 // 7 = (Reserved) (UI Updated).
238 // 8 = Completed. (UI Updated).
240 if (iter->second == 0){
242 //CardDAVIter->second.
244 // Wait for process to finish.
247 TasksFoundProc = TRUE;
249 wxString ETagOriginal;
252 wxString ContactFilename;
253 wxString FullFilename;
258 if (TypeIter->second == 1){
259 CardDAVIter->second->GetServerETagValueThread();
260 ETagServer = CardDAVIter->second->ETagValueResult();
263 // Compare the ETags and work out if a conflict has occured.
265 if (TypeIter->second == 1){
267 ETag = StringETagIter->second;
268 ETagOriginal = StringETagOrigIter->second;
269 AccountDir = StringAccountIter->second;
270 ContactFilename = StringFilenameIter->second;
271 FullFilename = StringFullFilenameIter->second;
273 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
275 if (ETag == ETagOriginal){
277 // Compare the ETag with the Server ETag.
279 if (ETagOriginal != ETagServer){
281 // Server ETag is different from original ETag.
282 // This is a conflict which the user will now
288 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
290 vCard34Conv vCard34Obj;
292 wxString ServerContactData;
294 vCard ConvertedV4Data;
296 // Load the client data from the filename given.
298 CardDAVIter->second->GetServerContactData();
299 ServerContactData = CardDAVIter->second->GetPageData();
301 // Process v3 version into v4 version.
303 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
305 vCardConflictObj vCardProcData;
307 vCardProcData.vCardLocalData = &ClientData;
308 vCardProcData.vCardServerData = &ConvertedV4Data;
309 ClientData.LoadFile(FullFilename);
311 //ContactConflictEvent event(ContactConflictCmdEnv);
312 //event.SetData(ContactFilename, Moo1, Moo2);
314 //wxPostEvent(frmMainPtrGet, event);
316 // Setup Conflict Resolution Dialog.
318 // Fetch Data from Server and convert.
320 bool *PauseMode = new bool;
325 qrn.QResponse = &ConflictResult;
326 qrn.PausePtr = PauseMode;
328 vCardProcData.QRNotifData = &qrn;
330 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
331 event.SetClientData(&vCardProcData);
332 wxPostEvent(frmMainPtrGet, event);
337 n1.tv_nsec = 250000000L;*/
339 while (*PauseMode == TRUE){
340 //nanosleep(&n1, &n2);
347 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
349 if (ConflictResult == 0){
356 } else if (ConflictResult == 1){
358 // Decided to use client version.
360 CardDAVIter->second->ProcessData();
364 } else if (ConflictResult == 2){
366 // Decided to use server version.
368 // Download server version.
370 ConvertedV4Data.WriteFile(FullFilename);
378 // Update the data to the server.
380 CardDAVIter->second->ProcessData();
386 if (ETagOriginal != ETagServer){
388 // Server ETag is different from original ETag.
389 // This is a conflict which the user will now
392 frmMain *frmMainPtrGet = (frmMain *)frmMainPtr;
394 //ContactConflictEvent event(ContactConflictCmdEnv);
395 //event.SetData(ContactFilename, Moo1, Moo2);
397 vCard34Conv vCard34Obj;
399 wxString ServerContactData;
401 vCard ConvertedV4Data;
403 // Load the client data from the filename given.
405 CardDAVIter->second->GetServerContactData();
406 ServerContactData = CardDAVIter->second->GetPageData();
407 ClientData.LoadFile(FullFilename);
409 // Process v3 version into v4 version.
411 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
413 vCardConflictObj vCardProcData;
415 vCardProcData.vCardLocalData = &ClientData;
416 vCardProcData.vCardServerData = &ConvertedV4Data;
418 bool *PauseMode = new bool;
423 qrn.QResponse = &ConflictResult;
424 qrn.PausePtr = PauseMode;
426 vCardProcData.QRNotifData = &qrn;
428 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
429 event.SetClientData(&vCardProcData);
430 wxPostEvent(frmMainPtrGet, event);
435 n1.tv_nsec = 250000000L;*/
437 while (*PauseMode == TRUE){
438 //nanosleep(&n1, &n2);
445 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
447 if (ConflictResult == 0){
454 } else if (ConflictResult == 1){
456 // Decided to use client version.
458 CardDAVIter->second->ProcessData();
459 //ETagServer = CardDAVIter->second.GetServerETagValueThread();
460 //ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
464 } else if (ConflictResult == 2){
466 // Decided to use server version.
468 // Write server version to file.
470 ConvertedV4Data.WriteFile(FullFilename);
478 // Update the data to the server.
480 CardDAVIter->second->ProcessData();
486 // Update the ETag DB.
488 CardDAVIter->second->GetServerETagValueThread();
489 ETagServer = CardDAVIter->second->ETagValueResult();
490 ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
493 CardDAVIter->second = NULL;
495 } else if (TypeIter->second == 2) {
497 // Delete the contact from the server and update the ETag DB.
499 AccountDir = StringAccountIter->second;
500 ContactFilename = StringFilenameIter->second;
502 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
504 CardDAVIter->second->SetUploadMode(FALSE);
505 CardDAVIter->second->SetupData(wxT("DELETE"), ContactFilename, wxT(""));
506 //CardDAVIter->second.SetServerFilename();
507 CardDAVIter->second->ProcessData();
508 ETagDBPtr->RemoveETag(ContactFilename);
511 CardDAVIter->second = NULL;
513 } else if (TypeIter->second == 3) {
515 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
517 wxString AccountNameFriendly;
518 wxString PrefFilename = GetUserPrefDir();
520 XABPreferences PrefData(PrefFilename);
523 for (int i = 0; i < PrefData.accounts.GetCount(); i++){
525 wxString AccountDirCheck = PrefData.accounts.GetAccountDirectory(i);
527 AccountDirCheck.Trim();
528 AccountDirCheck.Append(wxT(".carddav"));
530 if (AccountDirCheck == StringAccountIter->second){
532 AccountNameFriendly = PrefData.accounts.GetAccountName(i);
539 bool KeepUpdating = TRUE;
541 while (KeepUpdating == TRUE){
543 StringTaskDetailIter = ActivityListTaskDetail.find(iter->first);
545 AccountDir = StringAccountIter->second;
547 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
549 wxArrayString vCardAdd;
550 wxArrayString vCardDelete;
551 wxArrayString vCardList;
552 wxArrayString vCardUpdateLocal;
553 wxArrayString vCardUpdateRemote;
554 wxArrayString vCardUpdateLog;
555 std::map<wxString,wxString> vCardETag;
556 ContactListData ServerContactList;
558 std::map<wxString,vCardDownloadDataFileClass> vCardDownloadData;
559 //wxArrayString vCardDownload;
560 //std::map<wxString,wxString> vCardDownloadData;
562 // Get the list of vCard files locally.
564 wxString AccountDirFinal;
565 wxString AccountSyncTokenFilename;
566 wxString SyncTokenLoad;
568 #if defined(__HAIKU__)
570 //preffilename = wxT("noo");
572 #elif defined(__WIN32__)
574 AccountDirFinal = GetAccountDir(AccountDir, FALSE);
575 AccountSyncTokenFilename = AccountDirFinal;
576 AccountSyncTokenFilename.Append(wxT("synctoken"));
580 AccountDirFinal = GetAccountDir(AccountDir, FALSE);
581 AccountSyncTokenFilename = AccountDirFinal;
582 AccountSyncTokenFilename.Append(wxT("synctoken"));
586 // Suppress Error Messages.
588 wxLogNull PleaseDoNotDisturb;
591 SyncLoad.Open(AccountSyncTokenFilename, wxT("r"));
593 if (SyncLoad.IsOpened()){
595 SyncLoad.ReadAll(&SyncTokenLoad, wxMBConvUTF8());
600 // Get a list of vCard files from the server.
602 // Get the list of vCard files from the ETagDB.
604 std::map<wxString,ETagData> ETagDBData = ETagDBPtr->GetETagData();
606 bool ExitLoop = FALSE;
608 std::map<wxString,FileSyncData> *SCListData = NULL;
610 while (ExitLoop == FALSE){
612 ServerContactList = CardDAVIter->second->GetContactList(SyncTokenLoad.ToUTF8());
613 SSLCertCollection certcol = CardDAVIter->second->GetCertificateData();
615 // Create a pointer for the std::map<wxString,FileSyncData>.
617 SCListData = &ServerContactList.ListData;
619 // Check if any errors have occured whilst getting the data.
621 int ErrorCode = CardDAVIter->second->GetResultCode();
625 if (ErrorCode == 60 || ErrorCode == 51){
627 // Invalid SSL certificate so bring up a dialog to the user
628 // explaining what has happened and the options available.
630 // Stop all the timers.
632 frmMainPtrGet->PauseAllTimers();
634 // Setup the data to be sent in the wxPostEvent command.
636 SSLInvalidCertNotifObj SSLICNProcData;
638 bool *PauseMode = new bool;
643 qrn.QResponse = &SSLResult;
644 qrn.PausePtr = PauseMode;
646 SSLICNProcData.CertCollection = certcol;
647 SSLICNProcData.QRNotifData = &qrn;
648 SSLICNProcData.AccountName = AccountNameFriendly;
650 wxCommandEvent event(INVALIDSSLCERT);
651 event.SetClientData(&SSLICNProcData);
652 wxPostEvent(frmMainPtrGet, event);
656 // Fall asleep until we get an response.
659 n1.tv_nsec = 250000000L;*/
661 while (*PauseMode == TRUE){
662 //nanosleep(&n1, &n2);
666 // Process the response from the user.
670 // Accept the certificate. Write the certificate into the account
671 // directory (as server.crt) - will overwrite old certificate.
673 frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, CardDAVIter->second->GetCertificateData());
674 WriteServerCertificate(AccountDir, CardDAVIter->second->GetCertificateData());
676 } else if (SSLResult == 2){
678 // Reject the certificate, abort the task and mark as failed.
680 frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, CardDAVIter->second->GetCertificateData());
686 // Resume all the timers.
688 frmMainPtrGet->ResumeAllTimers();
705 if (iter->second == 2 || iter->second == 3 || iter->second == 4){
709 frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, CardDAVIter->second->GetCertificateData());
711 // Look in directory and see which vCards to add and delete
714 // vCard exists but not in ETagDB - Add (and upload).
715 // vCard missing but in ETagDB - Delete (from server).
717 // Start by looking for vCards that are not in the ETagDB.
719 wxDir AccDir(AccountDirFinal);
720 wxString AccDirFilename;
722 bool ContinueProcess = AccDir.GetFirst(&AccDirFilename, wxEmptyString, wxDIR_DEFAULT);
724 // Process the server data.
726 if (SCListData != NULL){
728 for (std::map<wxString, FileSyncData>::iterator fsiter = SCListData->begin();
729 fsiter != SCListData->end(); fsiter++){
731 // Check the mode of the file before adding.
733 // Get the HTTP status of the file from the list.
735 FileSyncData fsd = fsiter->second;
737 if (fsd.DataFlag == 1){
739 // Added or modified contact.
741 //vCardAdd.Add(fsiter->first, 1);
743 vCardDownloadDataFileClass vCardNewData;
744 vCardNewData.DataType = 0;
745 vCardDownloadData.insert(std::make_pair(fsiter->first, vCardNewData));
747 //} else if (fsd.DataFlag == 1){
749 // Contact has been modified on the server.
751 // vCardUpdateLocal.Add(fsiter->first, 1);
754 else if (fsd.DataFlag == 2){
756 // Contact has been deleted.
758 vCardDelete.Add(fsiter->first, 1);
766 // Look for vCards that are missing but in the ETagDB.
768 for (std::map<wxString,ETagData>::iterator etagiter = ETagDBData.begin();
769 etagiter != ETagDBData.end(); etagiter++){
771 // Check if the vCard exists.
773 if (!wxFileExists(AccountDirFinal + etagiter->first)){
775 // vCard doesn't exist so mark for deleting.
777 vCardDelete.Add(etagiter->first, 1);
783 // Compare Server with the ETag DB. Work out which
784 // needs to updated remotely and which needs to be
787 for (std::map<wxString,FileSyncData>::iterator srviter = SCListData->begin();
788 srviter != SCListData->end(); srviter++){
790 if (ETagDBData.find(srviter->first) == ETagDBData.end()){
794 std::map<wxString,ETagData>::iterator lociter = ETagDBData.find(srviter->first);
796 ETagData etd = lociter->second;
797 FileSyncData fsd = srviter->second;
799 wxString ETagSrv = fsd.ETagData;
801 // Compare local ETag with original local ETag.
802 // If different, update to server is required.
804 if (etd.ETagValue != etd.ETagOrigValue){
806 // Check if local original ETag is different from server ETag.
807 // If it is then throw up a conflict resolution dialog.
809 if (etd.ETagOrigValue != ETagSrv){
811 vCard34Conv vCard34Obj;
813 wxString ServerContactData;
814 wxString FullFilename;
816 vCard ConvertedV4Data;
818 // Conflict. Bring up conflict resolution dialog.
820 // Get the server contact data for comparison.
822 CardDAVIter->second->SetServerFilename(srviter->first);
823 CardDAVIter->second->GetServerContactData();
824 ServerContactData = CardDAVIter->second->GetPageData();
826 FullFilename = CreateFilenamePath(AccountDirFinal, srviter->first);
830 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
832 vCardConflictObj vCardProcData;
834 vCardProcData.vCardLocalData = &ClientData;
835 vCardProcData.vCardServerData = &ConvertedV4Data;
837 // Load the client data from the filename given.
839 ClientData.LoadFile(FullFilename);
843 bool *PauseMode = new bool;
846 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
849 qrn.QResponse = &ConflictResult;
850 qrn.PausePtr = PauseMode;
852 vCardProcData.QRNotifData = &qrn;
854 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
855 event.SetClientData(&vCardProcData);
856 wxPostEvent(frmMainPtrGet, event);
861 n1.tv_nsec = 250000000L;*/
863 while (*PauseMode == TRUE){
864 //nanosleep(&n1, &n2);
871 // If replacing local version, store copy for now.
872 // Otherwise upload to server.
874 if (ConflictResult == 0){
880 } else if (ConflictResult == 1){
882 // Decided to use client version.
884 vCardUpdateLocal.Remove(srviter->first);
885 vCardUpdateRemote.Add(srviter->first, 1);
887 } else if (ConflictResult == 2){
889 // Decided to use server version.
890 // Store the converted downloaded copy for
893 //vCardUpdateLocal.Add(srviter->first, 1);
895 vCardDownloadDataFileClass vCardNewData;
896 vCardNewData.DataType = 1;
897 vCardNewData.FileData = ConvertedV4Data.WriteString();
899 ConvertedV4Data.WriteFile(FullFilename);
901 vCardDownloadData.insert(std::make_pair(srviter->first, vCardNewData));
909 // Send vCard to the server.
911 vCardUpdateRemote.Add(srviter->first, 1);
917 // Check if local ETag is different from server ETag.
918 // If different, obtain the vCard from the server.
920 if (etd.ETagOrigValue != ETagSrv){
922 vCardUpdateLocal.Add(srviter->first, 1);
930 // Process the vCards that need to be downloaded and added/overwritten.
932 wxString vCardFilenameFinal;
933 wxString vCardOutputData;
934 wxString vCardInputData;
935 wxString ETagFileData;
938 for (std::map<wxString,vCardDownloadDataFileClass>::iterator additer = vCardDownloadData.begin();
939 additer != vCardDownloadData.end(); additer++){
941 vCardFilenameFinal.Clear();
942 vCardInputData.Clear();
943 vCardOutputData.Clear();
944 ETagFileData.Clear();
946 vCardFilenameFinal = CreateFilenamePath(AccountDirFinal, additer->first);
948 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
950 if (additer->second.DataType == 0){
952 vCard ConvertedV4Data;
954 // Grab the file from the server and write the contact out.
956 vCard34Conv vCard34Obj;
958 CardDAVIter->second->SetServerFilename(additer->first);
959 CardDAVIter->second->GetServerContactData();
960 vCardInputData = CardDAVIter->second->GetPageData();
962 vCard34Obj.ConvertToV4(&vCardInputData, &ConvertedV4Data);
964 ConvertedV4Data.WriteFile(vCardFilenameFinal);
966 // Update the ETagDB.
968 //vCardFile.Open(vCardFilenameFinal, wxT("w"));
970 //if (vCardFile.IsOpened()){
972 // vCardFile.Write(vCardOutputData, wxConvAuto());
973 // vCardFile.Close();
977 // Get the server ETag.
980 CardDAVIter->second->GetServerETagValueThread();
981 ServerETag = CardDAVIter->second->ETagValueResult();
983 // Add to the ETag Database.
985 ETagDBPtr->AddETag(additer->first, ServerETag, ServerETag);
987 } else if (additer->second.DataType == 1){
989 // Write out the contact to the account directory.
991 vCardFilenameFinal = CreateFilenamePath(AccountDirFinal, additer->first);
992 vCardOutputData = additer->second.FileData;
994 vCardFile.Open(vCardFilenameFinal, wxT("w"));
996 if (vCardFile.IsOpened()){
998 vCardFile.Write(vCardOutputData, wxConvAuto());
1003 // Update the ETagDB.
1005 wxString ServerETag;
1006 CardDAVIter->second->GetServerETagValueThread();
1007 ServerETag = CardDAVIter->second->ETagValueResult();
1009 // Add to the ETag Database.
1011 ETagDBPtr->AddETag(additer->first, ServerETag, ServerETag);
1016 // Look for vCard files which aren't in the ETagDB.
1018 while(ContinueProcess){
1020 // Check and make sure that the filename ends in .vcf/.vcard
1021 // Skip any file that beings with a dot.
1023 if (AccDirFilename.Left(1) == wxT(".")){
1025 ContinueProcess = AccDir.GetNext(&AccDirFilename);
1030 if (AccDirFilename.Right(4) != wxT(".vcf") &&
1031 AccDirFilename.Right(6) != wxT(".vcard")){
1033 ContinueProcess = AccDir.GetNext(&AccDirFilename);
1038 // Look in the ETagDB for the file.
1040 bool ETagExists = ETagDBPtr->CheckETagExists(AccDirFilename);
1042 if (ETagExists == FALSE){
1044 // Add the vCard to the list to be added.
1046 vCardAdd.Add(AccDirFilename, 1);
1050 ContinueProcess = AccDir.GetNext(&AccDirFilename);
1054 // Process the vCards to add/update to the server.
1056 for (int vi = 0; vi < vCardAdd.GetCount(); vi++){
1058 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
1059 ETag = ETagDBPtr->GetETag(vCardAdd[vi]);
1060 ETagOriginal = ETagDBPtr->GetETagOriginal(vCardAdd[vi]);
1062 ContactFilename = vCardAdd[vi];
1063 FullFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
1065 ContactFilename.Trim();
1067 if (ETag == ETagOriginal && ETagDBPtr->ETagExists(vCardAdd[vi])){
1069 // Compare the ETag with the Server ETag.
1071 CardDAVIter->second->SetServerFilename(vCardAdd[vi]);
1072 CardDAVIter->second->GetServerETagValueThread();
1073 ETagServer = CardDAVIter->second->ETagValueResult();
1075 if (ETagOriginal != ETagServer){
1077 // Server ETag is different from original ETag.
1078 // This is a conflict which the user will now
1081 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
1083 vCard34Conv vCard34Obj;
1085 wxString ServerContactData;
1087 vCard ConvertedV4Data;
1089 // Load the client data from the filename given.
1091 CardDAVIter->second->GetServerContactData();
1092 ServerContactData = CardDAVIter->second->GetPageData();
1094 // Process v3 version into v4 version.
1096 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
1098 vCardConflictObj vCardProcData;
1100 vCardProcData.vCardLocalData = &ClientData;
1101 vCardProcData.vCardServerData = &ConvertedV4Data;
1102 ClientData.LoadFile(FullFilename);
1104 //ContactConflictEvent event(ContactConflictCmdEnv);
1105 //event.SetData(ContactFilename, Moo1, Moo2);
1107 //wxPostEvent(frmMainPtrGet, event);
1109 // Setup Conflict Resolution Dialog.
1111 // Fetch Data from Server and convert.
1113 bool *PauseMode = new bool;
1118 qrn.QResponse = &ConflictResult;
1119 qrn.PausePtr = PauseMode;
1121 vCardProcData.QRNotifData = &qrn;
1123 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
1124 event.SetClientData(&vCardProcData);
1125 wxPostEvent(frmMainPtrGet, event);
1130 n1.tv_nsec = 250000000L;*/
1132 while (*PauseMode == TRUE){
1133 //nanosleep(&n1, &n2);
1134 SleepFor(250000000);
1140 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
1142 if (ConflictResult == 0){
1149 } else if (ConflictResult == 1){
1151 // Decided to use client version.
1153 CardDAVIter->second->ProcessData();
1157 } else if (ConflictResult == 2){
1159 // Decided to use server version.
1161 // Download server version.
1163 ConvertedV4Data.WriteFile(CreateFilenamePath(AccountDirFinal, vCardAdd[vi]));
1171 // Setup the filename for the contact being added.
1173 wxString wxSFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
1174 wxString wxSCardData;
1178 // Load the data from the file.
1181 wxFCard.Open(wxSFilename, wxT("r"));
1183 if (wxFCard.IsOpened()){
1185 wxFCard.ReadAll(&wxSCardData, wxConvAuto());
1190 // Convert the data to v3.
1192 vCard34Conv vCard34Obj;
1194 vCard34Obj.ConvertToV3(wxSFilename, &TaskData);
1196 // Setup the URL address.
1198 //TaskURL = StringTaskDetailIter->second + wxT("/") + vCardAdd[vi];
1200 // Upload the data to the server.
1202 CardDAVIter->second->SetUploadMode(TRUE);
1203 CardDAVIter->second->SetupData(wxT("PUT"), vCardAdd[vi], TaskData);
1204 CardDAVIter->second->ProcessData();
1206 // Get the Server ETag and put it in the ETag database.
1208 CardDAVIter->second->SetServerFilename(vCardAdd[vi]);
1209 CardDAVIter->second->GetServerETagValueThread();
1210 ETagServer = CardDAVIter->second->ETagValueResult();
1212 ETagDBPtr->AddETag(vCardAdd[vi], ETagServer, ETagServer);
1218 if (ETagOriginal != ETagServer){
1220 // Server ETag is different from original ETag.
1221 // This is a conflict which the user will now
1224 frmMain *frmMainPtrGet = (frmMain *)frmMainPtr;
1226 //ContactConflictEvent event(ContactConflictCmdEnv);
1227 //event.SetData(ContactFilename, Moo1, Moo2);
1229 vCard34Conv vCard34Obj;
1231 wxString ServerContactData;
1233 vCard ConvertedV4Data;
1235 // Load the client data from the filename given.
1237 CardDAVIter->second->GetServerContactData();
1238 ServerContactData = CardDAVIter->second->GetPageData();
1239 ClientData.LoadFile(FullFilename);
1241 // Process v3 version into v4 version.
1243 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
1245 vCardConflictObj vCardProcData;
1247 vCardProcData.vCardLocalData = &ClientData;
1248 vCardProcData.vCardServerData = &ConvertedV4Data;
1250 bool *PauseMode = new bool;
1255 qrn.QResponse = &ConflictResult;
1256 qrn.PausePtr = PauseMode;
1258 vCardProcData.QRNotifData = &qrn;
1260 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
1261 event.SetClientData(&vCardProcData);
1262 wxPostEvent(frmMainPtrGet, event);
1267 n1.tv_nsec = 250000000L;*/
1269 while (*PauseMode == TRUE){
1270 //nanosleep(&n1, &n2);
1271 SleepFor(250000000);
1277 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
1279 if (ConflictResult == 0){
1286 } else if (ConflictResult == 1){
1288 // Decided to use client version.
1290 CardDAVIter->second->ProcessData();
1291 //ETagServer = CardDAVIter->second.GetServerETagValueThread();
1292 //ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
1296 } else if (ConflictResult == 2){
1298 // Decided to use server version.
1300 // Write server version to file.
1302 ConvertedV4Data.WriteFile(CreateFilenamePath(AccountDirFinal, vCardAdd[vi]));
1310 // Setup the filename for the contact being added.
1312 wxString wxSFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
1313 wxString wxSCardData;
1317 // Load the data from the file.
1320 wxFCard.Open(wxSFilename, wxT("r"));
1322 if (wxFCard.IsOpened()){
1324 wxFCard.ReadAll(&wxSCardData, wxConvAuto());
1329 // Convert the data to v3.
1331 vCard34Conv vCard34Obj;
1333 vCard34Obj.ConvertToV3(wxSFilename, &TaskData);
1335 // Setup the URL address.
1337 //TaskURL = StringTaskDetailIter->second + wxT("/") + vCardAdd[vi];
1339 // Upload the data to the server.
1341 CardDAVIter->second->SetUploadMode(TRUE);
1342 CardDAVIter->second->SetupData(wxT("PUT"), vCardAdd[vi], TaskData);
1343 CardDAVIter->second->ProcessData();
1345 // Get the Server ETag and put it in the ETag database.
1347 CardDAVIter->second->SetServerFilename(vCardAdd[vi]);
1348 CardDAVIter->second->GetServerETagValueThread();
1349 ETagServer = CardDAVIter->second->ETagValueResult();
1352 ETagDBPtr->AddETag(vCardAdd[vi], ETagServer, ETagServer);
1360 // Process the vCards to delete locally.
1362 for (int vi = 0; vi < vCardDelete.GetCount(); vi++){
1364 if (!wxRemoveFile(CreateFilenamePath(AccountDirFinal, vCardDelete[vi]))){
1368 ETagDBPtr->RemoveETag(vCardDelete[vi]);
1374 // Process the vCards to delete from the server.
1376 std::map<wxString,wxString> *ETagFilenameMap = ETagDBPtr->GetFilenamePointer();
1379 for (std::map<wxString,wxString>::iterator deliter = ETagFilenameMap->begin();
1380 deliter != ETagFilenameMap->end(); deliter++){
1382 // Look through the ETagDB and find contacts which are marked as DELETED.
1384 if (deliter->second == wxT("DELETED")){
1386 CardDAVIter->second->SetUploadMode(FALSE);
1387 CardDAVIter->second->SetupData(wxT("DELETE"), deliter->first, wxT(""));
1388 CardDAVIter->second->ProcessData();
1390 // Delete the ETag as the file has now been deleted.
1392 ETagDBPtr->RemoveETag(deliter->first);
1398 // Write out the update server sync token.
1400 wxString ServerSyncToken = ServerContactList.SyncToken;
1402 ServerSyncToken.Trim();
1404 if (!ServerSyncToken.IsEmpty()){
1407 SyncWrite.Open(AccountSyncTokenFilename, wxT("w"));
1409 if (SyncWrite.IsOpened()){
1411 SyncWrite.Write(ServerSyncToken, wxConvAuto());
1418 // Check for another sync token. If there is another
1419 // sync token then repeat this. If token matches then stop processing.
1421 if (SyncTokenLoad == ServerSyncToken){
1423 KeepUpdating = FALSE;
1429 // Mark as completed.
1431 wxString AccountNameFinal;
1432 AccountNameFinal = PrefData.accounts.GetAccountDirectory(AccountID);
1433 AccountNameFinal.Append(wxT(".carddav"));
1435 wxCommandEvent reloadevent(RELOADCONTACTLIST);
1436 reloadevent.SetString(AccountNameFinal);
1437 wxPostEvent(this->GetParent(), reloadevent);
1444 // Update the data to the server.
1446 CardDAVIter->second->ProcessData();
1455 n1.tv_nsec = 250000000L;*/
1457 while (iter->second == 1){
1459 SleepFor(250000000);
1460 //nanosleep(&n1, &n2);
1464 if ((iter->second == 4 && TypeIter->second == 0) ||
1465 (iter->second == 8 && TypeIter->second == 0)){
1467 AccountDir = StringAccountIter->second;
1468 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
1470 CardDAVIter->second->GetServerETagValueThread();
1471 ETagServer = CardDAVIter->second->ETagValueResult();
1472 ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
1476 if ((iter->second == 4 && TypeIter->second == 1) ||
1477 (iter->second == 8 && TypeIter->second == 1)){
1479 AccountDir = StringAccountIter->second;
1480 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
1482 CardDAVIter->second->GetServerETagValueThread();
1483 ETagServer = CardDAVIter->second->ETagValueResult();
1484 ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
1494 if (TasksFoundProc == FALSE){
1496 TasksActive = FALSE;
1497 ProcessTasksData = FALSE;
1501 wxCommandEvent eventp(ACTMGR_STARTTIMER);
1502 wxPostEvent(this, eventp);
1504 //AnimationTimer.StartAnimation();
1505 //ActListProcTimer.Start();
1509 wxCommandEvent event(ACTMGR_STARTPROCESSTIMER);
1510 wxPostEvent(this, event);
1512 //ActProcessTimer.Start();
1516 void frmActivityMgr::ProcessTasks()
1519 std::thread ProcessThread(&frmActivityMgr::ProcessTasksThread, this);
1520 ProcessThread.detach();
1524 void frmActivityMgr::SetupPointers(wxETagProcessTimer *ETagTmrPtrInc, void *frmMainPtrInc)
1527 ETagTmrPtr = ETagTmrPtrInc;
1529 frmMainPtr = frmMainPtrInc;
1533 void frmActivityMgr::ResumeProcessing(wxCommandEvent &event){
1535 QRNotif *qrn = (QRNotif *)event.GetClientData();
1537 int *QRes = qrn->QResponse;
1539 *qrn->PausePtr = FALSE;
1541 *QRes = event.GetInt();
1545 void frmActivityMgr::ToggleConnectionStatus( wxCommandEvent &event ){
1547 wxCommandEvent connevent(CONNSTAT_UPDATE);
1549 if (SleepMode == FALSE){
1551 connevent.SetInt(1);
1556 connevent.SetInt(0);
1561 wxPostEvent(GetParent(), connevent);
1565 void frmActivityMgr::WriteServerCertificate(wxString AccountName, SSLCertCollection SSLCertInc){
1567 wxString ServerCertFinal;
1569 // Get the Cert section of the certificate and write it to the file.
1571 ServerCertFinal = GetAccountDir(AccountName, TRUE);
1575 std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertInc.SSLCollection.find(0);
1576 std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
1578 CertFile.Open(ServerCertFinal, wxFile::write);
1580 CertFile.Write(SSLDataIter->second, wxConvUTF8);
1585 void frmActivityMgr::StartTimer(wxCommandEvent& event){
1587 ActListProcTimer.Start(1000, FALSE);
1591 void frmActivityMgr::StopTimer(wxCommandEvent& event){
1593 ActListProcTimer.Stop();
1597 void frmActivityMgr::StartProcessTimer(wxCommandEvent& event){
1599 ActProcessTimer.Start(1000, FALSE);
1603 void frmActivityMgr::StopProcessTimer(wxCommandEvent& event){
1605 ActProcessTimer.Stop();
1609 void frmActivityMgr::UpdateStatusLabel(wxCommandEvent& event){
1611 ActivityMgrLabelUpdate *actmgrudata = (ActivityMgrLabelUpdate*)event.GetClientData();
1613 if (actmgrudata != NULL){
1615 lstActivity->SetItem(actmgrudata->ItemIndex, 2, actmgrudata->ItemLabel);
1617 /*if (!actmgrudata->ItemDes.IsEmpty()){
1618 lstActivity->SetItem(actmgrudata->ItemIndex, 0, actmgrudata->ItemDes);