Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Added Save function stubs for Pictures, Logos and Sounds tab.
[xestiaab/.git] / source / frmActivityMgr.cpp
1 // frmActivityMgr.cpp - Activity Manager form.
2 //
3 // (c) 2012-2015 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
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.
10 //
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.
15 //
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>
21 #include <wx/file.h>
22 #include <wx/ffile.h>
23 #include <wx/tokenzr.h>
24 #include <wx/dir.h>
25 #include <wx/filefn.h>
26 #include <thread>
27 #include <curl/curl.h>
29 #include "bitmaps.h"
30 #include "enums.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 "common/dirs.h"
38 #include "vcard/vcard34conv.h"
39 #include "vcard/vcard.h"
42 #ifndef FRMACTIVITYMGR_H
43 #define FRMACTIVITYMGR_H
45 DEFINE_EVENT_TYPE(ACTMGR_RESUMEPROC);
46 DEFINE_EVENT_TYPE(ACTMGR_TOGGLECONN);
47 DEFINE_EVENT_TYPE(ACTMGR_STARTTIMER);
48 DEFINE_EVENT_TYPE(ACTMGR_STOPTIMER);
49 DEFINE_EVENT_TYPE(ACTMGR_STARTPROCESSTIMER);
50 DEFINE_EVENT_TYPE(ACTMGR_STOPPROCESSTIMER);
51 DEFINE_EVENT_TYPE(ACTMGR_UPDATESTATUSLABEL);
53 BEGIN_EVENT_TABLE(frmActivityMgr, wxWindow)
54   EVT_COMMAND(wxID_ANY, ACTMGR_RESUMEPROC, frmActivityMgr::ResumeProcessing)
55   EVT_COMMAND(wxID_ANY, ACTMGR_TOGGLECONN, frmActivityMgr::ToggleConnectionStatus)
56   EVT_COMMAND(wxID_ANY, ACTMGR_STARTTIMER, frmActivityMgr::StartTimer)
57   EVT_COMMAND(wxID_ANY, ACTMGR_STOPTIMER, frmActivityMgr::StopTimer)
58   EVT_COMMAND(wxID_ANY, ACTMGR_STARTPROCESSTIMER, frmActivityMgr::StartProcessTimer)
59   EVT_COMMAND(wxID_ANY, ACTMGR_STOPPROCESSTIMER, frmActivityMgr::StopProcessTimer)
60   EVT_COMMAND(wxID_ANY, ACTMGR_UPDATESTATUSLABEL, frmActivityMgr::UpdateStatusLabel)
61 END_EVENT_TABLE()
63 frmActivityMgr::frmActivityMgr( wxWindow* parent )
64 :
65 frmActivityMgrADT( parent )
66 {
68         wxMemoryInputStream istream(icons_activitywindow_png, sizeof(icons_activitywindow_png));
69         wxImage icons_activitywindow_pngi(istream, wxBITMAP_TYPE_PNG);
70         wxBitmap activityiconbmp(icons_activitywindow_pngi, -1);
71         wxIcon activityicon;
72         activityicon.CopyFromBitmap(activityiconbmp);
73         this->SetIcon(activityicon); 
75         wxMemoryInputStream istream2(misc_activitysleep_png, sizeof(misc_activitysleep_png));
76         wxImage misc_activitysleep_pngi(istream2, wxBITMAP_TYPE_PNG);
77         wxBitmap sleepiconbmp(misc_activitysleep_pngi, -1);
78         SleepBitmap = sleepiconbmp;
79         bmpActivity->SetBitmap(SleepBitmap);
80         ActProcessTimer.SetupPointers(this);
81         lblDetails->SetLabel(_("No activity."));
82         
83         ActListProcTimer.SetupPointers(&ActivityList, &ActivityListIndex, &ActivityListTaskDetail, 
84                                         &TasksActive, lstActivity, lblDetails, GauProgress, this, &AnimationTimer,
85                                         &ActProcessTimer, &ActivityListFinDate);
86         
87         AnimationTimer.SetBitmap(bmpActivity);
88         AnimationTimer.SetSleepBitmap(&SleepBitmap);
89         AnimationTimer.SetupPointer(this->GetParent());
90         
91         wxListItem ColumnData;
92         ColumnData.SetId(0);
93         ColumnData.SetText(_("Activity"));
94         ColumnData.SetWidth(175);
95         lstActivity->InsertColumn(0, ColumnData);
96         
97         wxListItem ColumnData2;
98         ColumnData2.SetId(1);
99         ColumnData2.SetText(_("Account"));
100         ColumnData2.SetWidth(100);
101         lstActivity->InsertColumn(1, ColumnData2);
103         wxListItem ColumnData3;
104         ColumnData3.SetId(2);
105         ColumnData3.SetText(_("Status"));
106         ColumnData3.SetWidth(100);
107         lstActivity->InsertColumn(2, ColumnData3);
108         
109         //AnimationTimer.StartAnimation();
110         
111         // Create recovery database if it doesn't exist.
112         
113         wxString RecoveryFilename = GetRecoveryDB();
114         
115         wxFile RecoveryDB;
116         
117         if (wxFile::Exists(RecoveryFilename) == FALSE){
118         
119                 // Create the recovery database.
121                 RecoveryDB.Open(RecoveryFilename.c_str(), wxFile::write);       
122         
123                 RecoveryDB.Write(wxT("BEGIN:XAB-RECOVERYDB\r\n"), wxConvUTF8);
124                 RecoveryDB.Write(wxT("VERSION:1.0\r\n"), wxConvUTF8);
125                 RecoveryDB.Write(wxT("COMMENT:Please do not alter or delete this file. DATA LOSS IS POSSIBLE!\r\n"), wxConvUTF8);
126                 RecoveryDB.Write(wxT("END:XAB-RECOVERYDB\r\n"), wxConvUTF8);
127                 RecoveryDB.Close();
129         }
130         
131         wxFFile RecoveryDBF;
132         
133 #if wxABI_VERSION < 20900
134         RecoveryDBF.Open(RecoveryFilename.c_str(), wxT("r"));
135 #else
136         RecoveryDBF.Open(RecoveryFilename, wxT("r"));
137 #endif  
138         
139         // Load the recovery database for tasks not done.
140         
141         if (RecoveryDBF.IsOpened() == TRUE){
142         
143                 wxString wxSRecoveryDB;
144                 wxString RecoveryLine;
145         
146                 // Check if we are using wxWidgets version 2.8 or less and
147                 // execute the required command accordingly.
148         
149                 RecoveryDBF.ReadAll(&wxSRecoveryDB, wxConvAuto());
150         
151                 // Split the lines.
152         
153                 std::map<int, wxString> RecoveryFileLines;
154                 std::map<int, wxString>::iterator striter;
155         
156                 wxStringTokenizer wSTRecoveryDBLines(wxSRecoveryDB, wxT("\r\n"));
158                 int RecoveryLineSeek = 0;
160                 while (wSTRecoveryDBLines.HasMoreTokens() == TRUE){
162                         RecoveryLine = wSTRecoveryDBLines.GetNextToken();
163                         RecoveryFileLines.insert(std::make_pair(RecoveryLineSeek, RecoveryLine));
164                         RecoveryLineSeek++;             
165         
166                 }
167         
168         }
169         
172         //TestTimer.Start(50, FALSE);
175 int frmActivityMgr::AddTask(int TaskType, wxString TaskDetail, wxString TaskAccount, 
176         wxString TaskURL, wxString TaskFilename, wxString TaskFullFilename, 
177         wxString TaskData){
179         ActivityTaskID++;
181         wxListItem coldata;
182         long itemindex = -1;
183         CardDAV CardDAVConn;
185         coldata.SetId(ActivityTaskID);
186         coldata.SetData(ActivityTaskID);
188         AnimationTimer.StartAnimation();
190         // Get the preferences file.
191         
192         wxString PrefFilename = GetUserPrefDir();
193         
194         XABPreferences PrefData(PrefFilename);
196         wxString AccountName;
197         wxString AccountDir;
198         wxString AccountAddress;
199         int AccountPort = 0;
200         wxString AccountUsername;
201         wxString AccountPassword;
202         bool AccountSSL = FALSE;
203         wxString AccountPrefix;
205         // Look for the account and get the friendly name for the account.
206         
207         for (int i = 0; i < PrefData.accounts.GetCount(); i++){
208         
209                 AccountDir = PrefData.accounts.GetAccountDirectory(i);
210                 
211                 AccountDir.Trim();
212                 AccountDir.Append(wxT(".carddav"));
213         
214                 if (AccountDir == TaskAccount){
215                 
216                         AccountName = PrefData.accounts.GetAccountName(i);
217                         AccountAddress = PrefData.accounts.GetAccountAddress(i);
218                         AccountPort = PrefData.accounts.GetAccountPort(i);
219                         AccountUsername = PrefData.accounts.GetAccountUsername(i);
220                         AccountPassword = PrefData.accounts.GetAccountPassword(i);
221                         AccountPrefix = PrefData.accounts.GetAccountDirPrefix(i);
222                         AccountSSL = PrefData.accounts.GetAccountSSL(i);
223                         
224                         AccountName.Trim();
225                         AccountAddress.Trim();
226                         //AccountPort.Trim();
227                         AccountUsername.Trim();
228                         AccountPassword.Trim();
229                         AccountPrefix.Trim();
230                         break;
231                 
232                 }
233         
234         }
235         
236         CardDAVConn.SetupConnection(AccountAddress, AccountPort, AccountUsername, AccountPassword, AccountSSL, AccountPrefix, AccountDir);
237         CardDAVConn.SetupVariables(&ActivityList, ActivityTaskID);
238         CardDAVConn.SetupResultBools(&BlankBool, &BlankBool);           
240         // TaskType:
241         // 0 - Add a contact.
242         // 1 - Update a contact.
243         // 2 - Delete a contact.
244         // 3 - Account syncronisation.
246         if (TaskType == 0){             
248                 coldata.SetText(_("Adding Contact '") + TaskDetail + _("'"));
249                 itemindex = lstActivity->InsertItem(coldata);
250                 
251                 lstActivity->SetItem(itemindex, 1, AccountName);
252                 lstActivity->SetItem(itemindex, 2, _("Queued"));
253                 
254                 CardDAVConn.SetUploadMode(TRUE);
255                 CardDAVConn.SetupData(wxT("PUT"), TaskURL, TaskData);
256                 
257                 // Setup all of the task details.
259                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
260                 
261                 ActivityListType.insert(std::make_pair(ActivityTaskID, 0));
262                 ActivityListData.insert(std::make_pair(ActivityTaskID, TaskData));
263                 ActivityListConn.insert(std::make_pair(ActivityTaskID, CardDAVConn));
264                 ActivityListIndex.insert(std::make_pair(ActivityTaskID, itemindex));
265                 ActivityListTaskDetail.insert(std::make_pair(ActivityTaskID, TaskDetail));
266                 ActivityListAccount.insert(std::make_pair(ActivityTaskID, TaskAccount));
267                 ActivityListFilename.insert(std::make_pair(ActivityTaskID, TaskFilename));
268                 ActivityListFullFilename.insert(std::make_pair(ActivityTaskID, TaskFullFilename));
269                 
270                 ActivityListETag.insert(std::make_pair(ActivityTaskID, ETagDBPtr->GetETag(TaskFilename)));
271                 ActivityListETagOriginal.insert(std::make_pair(ActivityTaskID, ETagDBPtr->GetETagOriginal(TaskFilename)));
272                 ActivityList.insert(std::make_pair(ActivityTaskID, 0));
273         
274         } else if (TaskType == 1){
275         
276                 coldata.SetText(_("Updating Contact '") + TaskDetail + _("'"));
277                 itemindex = lstActivity->InsertItem(coldata);           
278                 
279                 lstActivity->SetItem(itemindex, 1, AccountName);
280                 lstActivity->SetItem(itemindex, 2, _("Queued"));
281                 
282                 CardDAVConn.SetUploadMode(TRUE);
283                 CardDAVConn.SetupData(wxT("PUT"), TaskURL, TaskData);
284                 CardDAVConn.SetEditMode(TRUE);
285                 
286                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
287                 
288                 ActivityListType.insert(std::make_pair(ActivityTaskID, 1));
289                 ActivityListData.insert(std::make_pair(ActivityTaskID, TaskData));
290                 ActivityListConn.insert(std::make_pair(ActivityTaskID, CardDAVConn));
291                 ActivityListIndex.insert(std::make_pair(ActivityTaskID, itemindex));
292                 ActivityListTaskDetail.insert(std::make_pair(ActivityTaskID, TaskDetail));
293                 ActivityListAccount.insert(std::make_pair(ActivityTaskID, TaskAccount));
294                 ActivityListFilename.insert(std::make_pair(ActivityTaskID, TaskFilename));
295                 ActivityListFullFilename.insert(std::make_pair(ActivityTaskID, TaskFullFilename));
296                 
297                 ActivityListETag.insert(std::make_pair(ActivityTaskID, ETagDBPtr->GetETag(TaskFilename)));
298                 ActivityListETagOriginal.insert(std::make_pair(ActivityTaskID, ETagDBPtr->GetETagOriginal(TaskFilename)));
299                 ActivityList.insert(std::make_pair(ActivityTaskID, 0));
300         
301         } else if (TaskType == 2){
303                 coldata.SetText(_("Deleting Contact '") + TaskDetail + _("'"));
304                 itemindex = lstActivity->InsertItem(coldata);
305                 
306                 lstActivity->SetItem(itemindex, 1, AccountName);
307                 lstActivity->SetItem(itemindex, 2, _("Queued"));
308                 
309                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
310                 
311                 ActivityList.insert(std::make_pair(ActivityTaskID, 0));
312                 ActivityListType.insert(std::make_pair(ActivityTaskID, 2));
313                 ActivityListData.insert(std::make_pair(ActivityTaskID, TaskData));
314                 ActivityListAccount.insert(std::make_pair(ActivityTaskID, TaskAccount));
315                 ActivityListConn.insert(std::make_pair(ActivityTaskID, CardDAVConn));
316                 ActivityListFilename.insert(std::make_pair(ActivityTaskID, TaskFilename));
317                 ActivityListIndex.insert(std::make_pair(ActivityTaskID, itemindex));
318         
319         } else if (TaskType == 3){
321                 coldata.SetText(_("Syncronising All Contacts"));
322                 itemindex = lstActivity->InsertItem(coldata);
323                 
324                 lstActivity->SetItem(itemindex, 1, AccountName);
325                 lstActivity->SetItem(itemindex, 2, _("Queued"));
326                 
327                 ActivityList.insert(std::make_pair(ActivityTaskID, 0));
328                 ActivityListType.insert(std::make_pair(ActivityTaskID, 3));
329                 ActivityListData.insert(std::make_pair(ActivityTaskID, TaskData));
330                 ActivityListConn.insert(std::make_pair(ActivityTaskID, CardDAVConn));
331                 ActivityListTaskDetail.insert(std::make_pair(ActivityTaskID, AccountPrefix));
332                 ActivityListAccount.insert(std::make_pair(ActivityTaskID, TaskAccount));
333                 ActivityListIndex.insert(std::make_pair(ActivityTaskID, itemindex));
334         
335         }
336         
337         ProcessTasksData = TRUE;
338         
339         if (!ActProcessTimer.IsRunning()) {
340         
341                 wxCommandEvent event(ACTMGR_STARTTIMER);
342                 wxPostEvent(this, event);
344                 wxCommandEvent eventp(ACTMGR_STARTPROCESSTIMER);
345                 wxPostEvent(this, eventp);
347                 //ActProcessTimer.Start(1000, FALSE);
348                 //ActListProcTimer.Start(1000, FALSE);
349         
350         }
351         
352         // Update the recovery database.
353         
354         return ActivityTaskID;
358 void frmActivityMgr::RemoveTask(){
360         // Remove task from the recovery database.
364 void frmActivityMgr::StopTask( wxCommandEvent& event ){
366         // Check if activity has been completed already before stopping.
368         long longSelected = -1;
369         int intSelectedData = 0;
370                 
371         longSelected = lstActivity->GetNextItem(longSelected, 
372                 wxLIST_NEXT_ALL,
373                 wxLIST_STATE_SELECTED);
375         intSelectedData = (int)lstActivity->GetItemData(longSelected);
376         
377         if (longSelected == -1){
378                 return;
379         }
380         
381         std::map<int,CardDAV>::iterator CDAVter;
382         
383         CDAVter = ActivityListConn.find(intSelectedData);
384         
385         CDAVter->second.Abort();
386         
387         lstActivity->SetItem(longSelected, 2, _("Stopped"));
391 void frmActivityMgr::StopAllTasks( wxCommandEvent& event ){
393         // Check if activity has been completed already before stopping.
394         
395         // TODO: Look through for '1' and stop the running task(s).
396         
397         long longSelected = -1;
398         int intSelectedData = 0;
399                 
400         longSelected = lstActivity->GetNextItem(longSelected, 
401                 wxLIST_NEXT_ALL,
402                 wxLIST_STATE_SELECTED);
404         intSelectedData = (int)lstActivity->GetItemData(longSelected);
405         
406         if (longSelected == -1){
407                 return;
408         }
409         
410         std::map<int,CardDAV>::iterator CDAVter;
411         
412         CDAVter = ActivityListConn.find(intSelectedData);
413         
414         CDAVter->second.Abort();
415         
416         lstActivity->SetItem(longSelected, 2, _("Stopped"));
417         AnimationTimer.StopAnimation();
418         bmpActivity->SetBitmap(SleepBitmap);
419         lblDetails->SetLabel(_("No activity."));
423 void frmActivityMgr::RetryTask( wxCommandEvent& event ){
425         // Check if activity has been completed already before retrying.
426         
427         long longSelected = -1;
428         int intSelectedData = 0;
429                 
430         longSelected = lstActivity->GetNextItem(longSelected, 
431                 wxLIST_NEXT_ALL,
432                 wxLIST_STATE_SELECTED);
434         intSelectedData = (int)lstActivity->GetItemData(longSelected);
435         
436         if (longSelected == -1){
437                 return;
438         }
439         
440         std::map<int,CardDAV>::iterator CDAVter;
441         
442         CDAVter = ActivityListConn.find(intSelectedData);
443         
444         // Restart the task.
445         
446         //CDAVter->second.Abort();
447         
448         std::map<int,int>::iterator Iter;
449         Iter = ActivityList.find(intSelectedData);
450         
451         Iter->second = 0;
452         
453         AnimationTimer.StartAnimation();
454         
455         if (!ActProcessTimer.IsRunning()) {
456         
457                 ActProcessTimer.Start(150, FALSE);
458                 ActListProcTimer.Start(150, FALSE);
459         
460         }
461         
462         //lstActivity->SetItem(longSelected, 2, _("Processing..."));
466 void frmActivityMgr::OpenWindow()
468         WindowOpen = TRUE;
471 void frmActivityMgr::CloseWindow( wxCommandEvent& event )
473         WindowOpen = FALSE;
474         this->Hide();
477 void frmActivityMgr::CloseWindow( wxCloseEvent& event )
479         WindowOpen = FALSE;
480         this->Hide();
483 void frmActivityMgr::ProcessTasksThread()
485         
486         if (ProcessTasksData == FALSE){
487         
488                 return;
489         
490         }
491         
492         std::map<int,int>::iterator TypeIter;
493         std::map<int,wxString>::iterator StringIter;
494         std::map<int,wxString>::iterator StringDetailIter;
495         std::map<int,wxString>::iterator StringAccountIter;
496         std::map<int,wxString>::iterator StringFilenameIter;
497         std::map<int,wxString>::iterator StringFullFilenameIter;
498         std::map<int,wxString>::iterator StringTaskDetailIter;
499         std::map<int,wxString>::iterator StringETagIter;
500         std::map<int,wxString>::iterator StringETagOrigIter;
501         std::map<int,CardDAV>::iterator CardDAVIter;
502         std::map<int,long>::iterator LongIter;
503         bool TasksFoundProc = FALSE;
504         wxString TaskDetail;
506         for (std::map<int,int>::iterator iter = ActivityList.begin(); 
507          iter != ActivityList.end(); ++iter){
508          
509                 // Check for any queued tasks and start one.
510                 
511                 if (iter->second > 4){
512                         continue;
513                 }
514                 
515                 CardDAVIter = ActivityListConn.find(iter->first);
516                 TypeIter = ActivityListType.find(iter->first);
517                 StringETagIter = ActivityListETag.find(iter->first);
518                 StringETagOrigIter = ActivityListETagOriginal.find(iter->first);
519                 StringAccountIter = ActivityListAccount.find(iter->first);
520                 StringFilenameIter = ActivityListFilename.find(iter->first);
521                 StringFullFilenameIter = ActivityListFullFilename.find(iter->first);
522                 
523                 // 0 = Queued.
524                 // 1 = Processing.
525                 // 2 = Failed.
526                 // 3 = Stopped.
527                 // 4 = Completed.
528                 // 5 = Failed (UI Updated).
529                 // 6 = Stopped (UI Updated).
530                 // 7 = (Reserved) (UI Updated).
531                 // 8 = Completed. (UI Updated). 
532                 
533                 if (iter->second == 0){
534                 
535                         //CardDAVIter->second.
536                         
537                         // Wait for process to finish.
539                         TasksActive = TRUE;
540                         TasksFoundProc = TRUE;
541                         wxString ETag;
542                         wxString ETagOriginal;
543                         wxString ETagServer;
544                         wxString AccountDir;
545                         wxString ContactFilename;
546                         wxString FullFilename;
547                         wxString ETagResult;
549                         iter->second = 1;
550                         
551                         if (TypeIter->second == 1){
552                                 CardDAVIter->second.GetServerETagValueThread();
553                                 ETagServer = CardDAVIter->second.ETagValueResult();
554                         }
555                         
556                         // Compare the ETags and work out if a conflict has occured.
557                         
558                         if (TypeIter->second == 1){
560                                 ETag = StringETagIter->second;
561                                 ETagOriginal = StringETagOrigIter->second;
562                                 AccountDir = StringAccountIter->second;
563                                 ContactFilename = StringFilenameIter->second;
564                                 FullFilename = StringFullFilenameIter->second;
565                                 
566                                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
567                         
568                                 if (ETag == ETagOriginal){
569                         
570                                         // Compare the ETag with the Server ETag.
571                                 
572                                         if (ETagOriginal != ETagServer){
573                                 
574                                                 // Server ETag is different from original ETag.
575                                                 // This is a conflict which the user will now
576                                                 // need to resolve.
577                                         
578                                                 vCard Moo1;
579                                                 vCard Moo2;
580                                         
581                                                 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
582                                         
583                                                 vCard34Conv vCard34Obj;
584                                                 
585                                                 wxString ServerContactData;
586                                                 vCard ClientData;
587                                                 vCard ConvertedV4Data;
588                                         
589                                                 // Load the client data from the filename given.
590                                         
591                                                 CardDAVIter->second.GetServerContactData();
592                                                 ServerContactData = CardDAVIter->second.GetPageData();
593                                                 
594                                                 // Process v3 version into v4 version.
595                                                 
596                                                 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
597                                         
598                                                 vCardConflictObj vCardProcData;
599                                         
600                                                 vCardProcData.vCardLocalData = &ClientData;
601                                                 vCardProcData.vCardServerData = &ConvertedV4Data;
602                                                 ClientData.LoadFile(FullFilename);
604                                                 //ContactConflictEvent event(ContactConflictCmdEnv);
605                                                 //event.SetData(ContactFilename, Moo1, Moo2);
606                                         
607                                                 //wxPostEvent(frmMainPtrGet, event);
608                                         
609                                                 // Setup Conflict Resolution Dialog.
610                                         
611                                                 // Fetch Data from Server and convert.
612                                         
613                                                 bool *PauseMode = new bool;
614                                                 int ConflictResult;
615                                                 QRNotif qrn;
617                                                 *PauseMode = TRUE;                                              
618                                                 qrn.QResponse = &ConflictResult;
619                                                 qrn.PausePtr = PauseMode;
620                                                 
621                                                 vCardProcData.QRNotifData = &qrn;
622                                         
623                                                 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
624                                                 event.SetClientData(&vCardProcData);
625                                                 wxPostEvent(frmMainPtrGet, event);
626                                                 
627                                                 /*timespec n1, n2;
628                                                 
629                                                 n1.tv_sec = 0;
630                                                 n1.tv_nsec = 250000000L;*/
631                                                 
632                                                 while (*PauseMode == TRUE){
633                                                         //nanosleep(&n1, &n2);
634                                                         SleepFor(250000000);
635                                                 }
636                                         
637                                                 delete PauseMode;
638                                                 PauseMode = NULL;
639                                         
640                                                 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
641                                         
642                                                 if (ConflictResult == 0){
643                                         
644                                                         // Decide Later.
645                                         
646                                                         iter->second = 4;
647                                                         continue;
648                                         
649                                                 } else if (ConflictResult == 1){
650                                         
651                                                         // Decided to use client version.
652                                         
653                                                         CardDAVIter->second.ProcessData();
654                                                 
655                                                         iter->second = 4;
656                                         
657                                                 } else if (ConflictResult == 2){
658                                         
659                                                         // Decided to use server version.
660                                                 
661                                                         // Download server version.
662                                                 
663                                                         ConvertedV4Data.WriteFile(FullFilename);
664                                                 
665                                                         iter->second = 4;
666                                         
667                                                 }
668                                 
669                                         } else {
670                                 
671                                                 // Update the data to the server.
672                                         
673                                                 CardDAVIter->second.ProcessData();
674                                 
675                                         }
676                         
677                                 } else {
678                         
679                                         if (ETagOriginal != ETagServer){
680                                 
681                                                 // Server ETag is different from original ETag.
682                                                 // This is a conflict which the user will now
683                                                 // need to resolve.
684                                         
685                                                 frmMain *frmMainPtrGet = (frmMain *)frmMainPtr;
686                                         
687                                                 //ContactConflictEvent event(ContactConflictCmdEnv);
688                                                 //event.SetData(ContactFilename, Moo1, Moo2);
689                                         
690                                                 vCard34Conv vCard34Obj;
691                                                 
692                                                 wxString ServerContactData;
693                                                 vCard ClientData;
694                                                 vCard ConvertedV4Data;
695                                         
696                                                 // Load the client data from the filename given.
697                                         
698                                                 CardDAVIter->second.GetServerContactData();
699                                                 ServerContactData = CardDAVIter->second.GetPageData();
700                                                 ClientData.LoadFile(FullFilename);
701                                                 
702                                                 // Process v3 version into v4 version.
703                                                 
704                                                 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
705                                         
706                                                 vCardConflictObj vCardProcData;
707                                         
708                                                 vCardProcData.vCardLocalData = &ClientData;
709                                                 vCardProcData.vCardServerData = &ConvertedV4Data;
710                                         
711                                                 bool *PauseMode = new bool;
712                                                 int ConflictResult;
713                                                 QRNotif qrn;
715                                                 *PauseMode = TRUE;                                              
716                                                 qrn.QResponse = &ConflictResult;
717                                                 qrn.PausePtr = PauseMode;
718                                                 
719                                                 vCardProcData.QRNotifData = &qrn;
720                                         
721                                                 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
722                                                 event.SetClientData(&vCardProcData);
723                                                 wxPostEvent(frmMainPtrGet, event);
724                                         
725                                                 /*timespec n1, n2;
726                                                 
727                                                 n1.tv_sec = 0;
728                                                 n1.tv_nsec = 250000000L;*/
729                                         
730                                                 while (*PauseMode == TRUE){
731                                                         //nanosleep(&n1, &n2);
732                                                         SleepFor(250000000);
733                                                 }
734                                         
735                                                 delete PauseMode;
736                                                 PauseMode = NULL;
737                                 
738                                                 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
739                                         
740                                                 if (ConflictResult == 0){
741                                         
742                                                         // Decide Later.
743                                         
744                                                         iter->second = 4;
745                                                         continue;
746                                         
747                                                 } else if (ConflictResult == 1){
748                                         
749                                                         // Decided to use client version.
750                                         
751                                                         CardDAVIter->second.ProcessData();
752                                                         //ETagServer = CardDAVIter->second.GetServerETagValueThread();
753                                                         //ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
754                                                 
755                                                         iter->second = 4;
756                                         
757                                                 } else if (ConflictResult == 2){
758                                         
759                                                         // Decided to use server version.
760                                                 
761                                                         // Write server version to file.
762                                                 
763                                                         ConvertedV4Data.WriteFile(FullFilename);
764                                                 
765                                                         iter->second = 4;
766                                         
767                                                 }
768                                 
769                                         } else {
770                                 
771                                                 // Update the data to the server.
772                                         
773                                                 CardDAVIter->second.ProcessData();
774                                 
775                                         }
776                         
777                                 }
778                                 
779                                 // Update the ETag DB.
780                                 
781                                 CardDAVIter->second.GetServerETagValueThread();
782                                 ETagServer = CardDAVIter->second.ETagValueResult();
783                                 ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
784                         
785                                 iter->second = 4;
786                         
787                         } else if (TypeIter->second == 2) {
788                         
789                                 // Delete the contact from the server and update the ETag DB.
790                                 
791                                 AccountDir = StringAccountIter->second;
792                                 ContactFilename = StringFilenameIter->second;
793                                                                 
794                                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
795                                 
796                                 CardDAVIter->second.SetUploadMode(FALSE);
797                                 CardDAVIter->second.SetupData(wxT("DELETE"), ContactFilename, wxT(""));
798                                 //CardDAVIter->second.SetServerFilename();
799                                 CardDAVIter->second.ProcessData();
800                                 ETagDBPtr->RemoveETag(ContactFilename);
801                                 
802                                 iter->second = 4;
803                         
804                         } else if (TypeIter->second == 3) {
805                         
806                                 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
808                                 wxString AccountNameFriendly;
809                                 wxString PrefFilename = GetUserPrefDir();
810         
811                                 XABPreferences PrefData(PrefFilename);
812                                 int AccountID = 0;
814                                 for (int i = 0; i < PrefData.accounts.GetCount(); i++){
815         
816                                         wxString AccountDirCheck = PrefData.accounts.GetAccountDirectory(i);
817                 
818                                         AccountDirCheck.Trim();
819                                         AccountDirCheck.Append(wxT(".carddav"));
820         
821                                         if (AccountDirCheck == StringAccountIter->second){
822                                         
823                                                 AccountNameFriendly = PrefData.accounts.GetAccountName(i);
824                                                 AccountID = i;
825                 
826                                         }
827         
828                                 }
829                         
830                                 bool KeepUpdating = TRUE;
832                                 while (KeepUpdating == TRUE){
834                                         StringTaskDetailIter = ActivityListTaskDetail.find(iter->first);
835                         
836                                         AccountDir = StringAccountIter->second;
838                                         ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
839                                 
840                                         wxArrayString vCardAdd;
841                                         wxArrayString vCardDelete;
842                                         wxArrayString vCardList;
843                                         wxArrayString vCardUpdateLocal;
844                                         wxArrayString vCardUpdateRemote;
845                                         wxArrayString vCardUpdateLog;
846                                         std::map<wxString,wxString> vCardETag;
847                                         ContactListData ServerContactList;
848                                 
849                                         std::map<wxString,vCardDownloadDataFileClass> vCardDownloadData;
850                                         //wxArrayString vCardDownload;
851                                         //std::map<wxString,wxString> vCardDownloadData;
852                                 
853                                         // Get the list of vCard files locally.
854         
855                                         wxString AccountDirFinal;
856                                         wxString AccountSyncTokenFilename;
857                                         wxString SyncTokenLoad;
858         
859 #if defined(__HAIKU__)
860     
861                                             //preffilename = wxT("noo");
863 #elif defined(__WIN32__)
865                                         AccountDirFinal = GetAccountDir(AccountDir, FALSE);
866                                         AccountSyncTokenFilename = AccountDirFinal;
867                                         AccountSyncTokenFilename.Append(wxT("synctoken"));
869 #else
871                                         AccountDirFinal = GetAccountDir(AccountDir, FALSE);
872                                         AccountSyncTokenFilename = AccountDirFinal;
873                                         AccountSyncTokenFilename.Append(wxT("synctoken"));
874         
875 #endif
877                                         // Suppress Error Messages.
878                                 
879                                         wxLogNull PleaseDoNotDisturb;
881                                         wxFFile SyncLoad;
882                                         SyncLoad.Open(AccountSyncTokenFilename, wxT("r"));
883                                 
884                                         if (SyncLoad.IsOpened()){
885                                 
886                                                 SyncLoad.ReadAll(&SyncTokenLoad, wxMBConvUTF8());
887                                                 SyncLoad.Close();
888                                 
889                                         }
891                                         // Get a list of vCard files from the server.
893                                         // Get the list of vCard files from the ETagDB.
894                                 
895                                         std::map<wxString,ETagData> ETagDBData = ETagDBPtr->GetETagData();
896                                         
897                                         CardDAV CardDAVInstance = CardDAVIter->second;
898                                         
899                                         bool ExitLoop = FALSE;
901                                         std::map<wxString,FileSyncData> *SCListData = NULL;
902                                         
903                                         while (ExitLoop == FALSE){
904                                         
905                                                 //ServerContactList = CardDAVInstance.GetContactList(SyncTokenLoad.ToUTF8());
906                                                 ServerContactList = CardDAVIter->second.GetContactList(SyncTokenLoad.ToUTF8());
907                                                 SSLCertCollection certcol = CardDAVIter->second.GetCertificateData();
908                                 
909                                                 // Create a pointer for the std::map<wxString,FileSyncData>.
910                                 
911                                                 SCListData = &ServerContactList.ListData;
912                                 
913                                                 // Check if any errors have occured whilst getting the data.
914                                 
915                                                 int ErrorCode = CardDAVIter->second.GetResultCode();
916                                 
917                                                 if (ErrorCode != 0){
918                                         
919                                                         if (ErrorCode == 60 || ErrorCode == 51){
920                                                 
921                                                                 // Invalid SSL certificate so bring up a dialog to the user
922                                                                 // explaining what has happened and the options available.
923                                                         
924                                                                 // Stop all the timers.
925                                                                 
926                                                                 frmMainPtrGet->PauseAllTimers();
927                                                         
928                                                                 // Setup the data to be sent in the wxPostEvent command.
930                                                                 SSLInvalidCertNotifObj SSLICNProcData;
932                                                                 bool *PauseMode = new bool;
933                                                                 int SSLResult;
934                                                                 QRNotif qrn;
936                                                                 *PauseMode = TRUE;                                              
937                                                                 qrn.QResponse = &SSLResult;
938                                                                 qrn.PausePtr = PauseMode;
939                                                                 
940                                                                 SSLICNProcData.CertCollection = certcol;
941                                                                 SSLICNProcData.QRNotifData = &qrn;
942                                                                 SSLICNProcData.AccountName = AccountNameFriendly;
943                                                         
944                                                                 wxCommandEvent event(INVALIDSSLCERT);
945                                                                 event.SetClientData(&SSLICNProcData);
946                                                                 wxPostEvent(frmMainPtrGet, event);
947                                         
948                                                                 /*timespec n1, n2;
949                                                 
950                                                                 // Fall asleep until we get an response.
951                                                 
952                                                                 n1.tv_sec = 0;
953                                                                 n1.tv_nsec = 250000000L;*/
954                                         
955                                                                 while (*PauseMode == TRUE){
956                                                                         //nanosleep(&n1, &n2);
957                                                                         SleepFor(250000000);
958                                                                 }
959                                                         
960                                                                 // Process the response from the user.
961                                                         
962                                                                 if (SSLResult == 1){
963                                                                 
964                                                                         // Accept the certificate. Write the certificate into the account
965                                                                         // directory (as server.crt) - will overwrite old certificate.
967                                                                         frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, CardDAVIter->second.GetCertificateData());
968                                                                         WriteServerCertificate(AccountDir, CardDAVIter->second.GetCertificateData());
969                                                                 
970                                                                 } else if (SSLResult == 2){
971                                                                 
972                                                                         // Reject the certificate, abort the task and mark as failed.
974                                                                         frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, CardDAVIter->second.GetCertificateData());
975                                                                         iter->second = 2;
976                                                                         break;
977                                                                 
978                                                                 }
979                                                         
980                                                                 // Resume all the timers.
981                                                                 
982                                                                 frmMainPtrGet->ResumeAllTimers();
983                                                 
984                                                         } else {
985                                                         
986                                                                 iter->second = 4;
987                                                                 break;
988                                                         
989                                                         }
990                                         
991                                                 } else {
992                                         
993                                                         ExitLoop = TRUE;
994                                         
995                                                 }
996                                         
997                                         }
998                                         
999                                         if (iter->second == 2 || iter->second == 3 || iter->second == 4){
1000                                                 break;
1001                                         }
1002                                 
1003                                         frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, CardDAVIter->second.GetCertificateData());
1004                                 
1005                                         // Look in directory and see which vCards to add and delete
1006                                 
1007                                         // In short:
1008                                         // vCard exists but not in ETagDB - Add (and upload).
1009                                         // vCard missing but in ETagDB - Delete (from server).
1010                                 
1011                                         // Start by looking for vCards that are not in the ETagDB.
1012                                 
1013                                         wxDir AccDir(AccountDirFinal);
1014                                         wxString AccDirFilename;
1015                                 
1016                                         bool ContinueProcess = AccDir.GetFirst(&AccDirFilename, wxEmptyString, wxDIR_DEFAULT);
1017                                 
1018                                         // Process the server data.
1020                                         if (SCListData != NULL){
1022                                                 for (std::map<wxString, FileSyncData>::iterator fsiter = SCListData->begin();
1023                                                         fsiter != SCListData->end(); fsiter++){
1025                                                         // Check the mode of the file before adding.
1027                                                         // Get the HTTP status of the file from the list.
1029                                                         FileSyncData fsd = fsiter->second;
1031                                                         if (fsd.DataFlag == 1){
1033                                                                 // Added or modified contact.
1035                                                                 //vCardAdd.Add(fsiter->first, 1);
1037                                                                 vCardDownloadDataFileClass vCardNewData;
1038                                                                 vCardNewData.DataType = 0;
1039                                                                 vCardDownloadData.insert(std::make_pair(fsiter->first, vCardNewData));
1041                                                                 //} else if (fsd.DataFlag == 1){
1043                                                                 // Contact has been modified on the server.
1045                                                                 //      vCardUpdateLocal.Add(fsiter->first, 1);
1047                                                         }
1048                                                         else if (fsd.DataFlag == 2){
1050                                                                 // Contact has been deleted.
1052                                                                 vCardDelete.Add(fsiter->first, 1);
1054                                                         }
1056                                                 }
1058                                         }
1059                                 
1060                                         // Look for vCards that are missing but in the ETagDB.
1061         
1062                                         for (std::map<wxString,ETagData>::iterator etagiter = ETagDBData.begin();
1063                                                 etagiter != ETagDBData.end(); etagiter++){
1064                                 
1065                                                 // Check if the vCard exists.
1066                                         
1067                                                 if (!wxFileExists(AccountDirFinal + etagiter->first)){
1068                                         
1069                                                         // vCard doesn't exist so mark for deleting.
1070                                         
1071                                                         vCardDelete.Add(etagiter->first, 1);
1072                                         
1073                                                 }
1074                                 
1075                                         }
1077                                         // Compare Server with the ETag DB. Work out which
1078                                         // needs to updated remotely and which needs to be
1079                                         // updated locally.
1081                                         for (std::map<wxString,FileSyncData>::iterator srviter = SCListData->begin();
1082                                                 srviter != SCListData->end(); srviter++){
1084                                                 if (ETagDBData.find(srviter->first) == ETagDBData.end()){
1085                                                         continue;
1086                                                 }
1087                                         
1088                                                 std::map<wxString,ETagData>::iterator lociter = ETagDBData.find(srviter->first);
1089                                 
1090                                                 ETagData etd = lociter->second;
1091                                                 FileSyncData fsd = srviter->second;
1092                                         
1093                                                 wxString ETagSrv = fsd.ETagData;
1095                                                 // Compare local ETag with original local ETag.
1096                                                 // If different, update to server is required.
1097                                 
1098                                                 if (etd.ETagValue != etd.ETagOrigValue){
1099                                 
1100                                                         // Check if local original ETag is different from server ETag.
1101                                                         // If it is then throw up a conflict resolution dialog.
1102                                 
1103                                                         if (etd.ETagOrigValue != ETagSrv){
1104                                         
1105                                                                 vCard34Conv vCard34Obj;
1106                                                 
1107                                                                 wxString ServerContactData;
1108                                                                 wxString FullFilename;
1109                                                                 vCard ClientData;
1110                                                                 vCard ConvertedV4Data;
1111                                         
1112                                                                 // Conflict. Bring up conflict resolution dialog.
1113                                                         
1114                                                                 // Get the server contact data for comparison.
1115                                                         
1116                                                                 CardDAVIter->second.SetServerFilename(srviter->first);
1117                                                                 CardDAVIter->second.GetServerContactData();
1118                                                                 ServerContactData = CardDAVIter->second.GetPageData();
1119                                                         
1120                                                                 FullFilename = CreateFilenamePath(AccountDirFinal, srviter->first);
1121                                                         
1122                                                                 // Convert it to v4.
1123                                         
1124                                                                 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
1125                                         
1126                                                                 vCardConflictObj vCardProcData;
1127                                         
1128                                                                 vCardProcData.vCardLocalData = &ClientData;
1129                                                                 vCardProcData.vCardServerData = &ConvertedV4Data;
1130                                                         
1131                                                                 // Load the client data from the filename given.
1132                                                         
1133                                                                 ClientData.LoadFile(FullFilename);
1134                                                         
1135                                                                 // Show dialog.
1136                                         
1137                                                                 bool *PauseMode = new bool;
1138                                                                 int ConflictResult;
1139                                                                 QRNotif qrn;
1140                                                                 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
1142                                                                 *PauseMode = TRUE;
1143                                                                 qrn.QResponse = &ConflictResult;
1144                                                                 qrn.PausePtr = PauseMode;
1145                                                 
1146                                                                 vCardProcData.QRNotifData = &qrn;
1147                                         
1148                                                                 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
1149                                                                 event.SetClientData(&vCardProcData);
1150                                                                 wxPostEvent(frmMainPtrGet, event);
1151                                                 
1152                                                                 /*timespec n1, n2;
1153                                                 
1154                                                                 n1.tv_sec = 0;
1155                                                                 n1.tv_nsec = 250000000L;*/
1156                                                 
1157                                                                 while (*PauseMode == TRUE){
1158                                                                         //nanosleep(&n1, &n2);
1159                                                                         SleepFor(250000000);
1160                                                                 }
1161                                         
1162                                                                 delete PauseMode;
1163                                                                 PauseMode = NULL;
1164                                                         
1165                                                                 // If replacing local version, store copy for now.
1166                                                                 // Otherwise upload to server.
1167                                         
1168                                                                 if (ConflictResult == 0){
1169                                         
1170                                                                         // Decide Later.
1171                                         
1172                                                                         continue;
1173                                         
1174                                                                 } else if (ConflictResult == 1){
1175                                         
1176                                                                         // Decided to use client version.
1177                                         
1178                                                                         vCardUpdateLocal.Remove(srviter->first);
1179                                                                         vCardUpdateRemote.Add(srviter->first, 1);                                                               
1180                                         
1181                                                                 } else if (ConflictResult == 2){
1182                                         
1183                                                                         // Decided to use server version.
1184                                                                         // Store the converted downloaded copy for
1185                                                                         // processing later.
1187                                                                         //vCardUpdateLocal.Add(srviter->first, 1);
1188                                                                 
1189                                                                         vCardDownloadDataFileClass vCardNewData;
1190                                                                         vCardNewData.DataType = 1;
1191                                                                         vCardNewData.FileData = ConvertedV4Data.WriteString();
1193                                                                         ConvertedV4Data.WriteFile(FullFilename);
1194                                                                 
1195                                                                         vCardDownloadData.insert(std::make_pair(srviter->first, vCardNewData)); 
1196                                                                 
1197                                                                 
1198                                                                 
1199                                                                 }
1200                                         
1201                                                         } else {
1202                                         
1203                                                                 // Send vCard to the server.
1204                                                 
1205                                                                 vCardUpdateRemote.Add(srviter->first, 1);
1206                                         
1207                                                         }
1208                                 
1209                                                 } else {
1210                                 
1211                                                         // Check if local ETag is different from server ETag.
1212                                                         // If different, obtain the vCard from the server.
1213                                         
1214                                                         if (etd.ETagOrigValue != ETagSrv){
1215                                         
1216                                                                 vCardUpdateLocal.Add(srviter->first, 1);
1217                                         
1218                                                         }
1219                                 
1220                                                 }
1221                         
1222                                         }
1223                                 
1224                                         // Process the vCards that need to be downloaded and added/overwritten.
1225                                 
1226                                         wxString vCardFilenameFinal;
1227                                         wxString vCardOutputData;
1228                                         wxString vCardInputData;
1229                                         wxString ETagFileData;
1230                                         wxFFile vCardFile;
1231                                 
1232                                         for (std::map<wxString,vCardDownloadDataFileClass>::iterator additer = vCardDownloadData.begin();
1233                                                 additer != vCardDownloadData.end(); additer++){
1234                                         
1235                                                 vCardFilenameFinal.Clear();
1236                                                 vCardInputData.Clear();
1237                                                 vCardOutputData.Clear();
1238                                                 ETagFileData.Clear();
1239                                         
1240                                                 vCardFilenameFinal = CreateFilenamePath(AccountDirFinal, additer->first);
1241                                         
1242                                                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
1243                                         
1244                                                 if (additer->second.DataType == 0){
1245                                         
1246                                                         vCard ConvertedV4Data;
1247                                         
1248                                                         // Grab the file from the server and write the contact out.
1249                                         
1250                                                         vCard34Conv vCard34Obj;
1251                                                 
1252                                                         CardDAVIter->second.SetServerFilename(additer->first);
1253                                                         CardDAVIter->second.GetServerContactData();
1254                                                         vCardInputData = CardDAVIter->second.GetPageData();
1255                                                 
1256                                                         vCard34Obj.ConvertToV4(&vCardInputData, &ConvertedV4Data);
1257                                                 
1258                                                         ConvertedV4Data.WriteFile(vCardFilenameFinal);
1259                                                 
1260                                                         // Update the ETagDB.
1261                                                 
1262                                                         //vCardFile.Open(vCardFilenameFinal, wxT("w"));
1263                                 
1264                                                         //if (vCardFile.IsOpened()){
1265                                 
1266                                                         //      vCardFile.Write(vCardOutputData, wxConvAuto());
1267                                                         //      vCardFile.Close();
1268                                 
1269                                                         //}
1270                                                 
1271                                                         // Get the server ETag.
1272                                                 
1273                                                         wxString ServerETag;
1274                                                         CardDAVIter->second.GetServerETagValueThread();
1275                                                         ServerETag = CardDAVIter->second.ETagValueResult();
1276                                                 
1277                                                         // Add to the ETag Database.
1278                                                 
1279                                                         ETagDBPtr->AddETag(additer->first, ServerETag, ServerETag);
1280                                                 
1281                                                 } else if (additer->second.DataType == 1){
1282                                         
1283                                                         // Write out the contact to the account directory.
1284                                         
1285                                                         vCardFilenameFinal = CreateFilenamePath(AccountDirFinal, additer->first);
1286                                                         vCardOutputData = additer->second.FileData;
1287                                                 
1288                                                         vCardFile.Open(vCardFilenameFinal, wxT("w"));
1289                                 
1290                                                         if (vCardFile.IsOpened()){
1291                                 
1292                                                                 vCardFile.Write(vCardOutputData, wxConvAuto());
1293                                                                 vCardFile.Close();
1294                                 
1295                                                         }
1296                                                 
1297                                                         // Update the ETagDB.
1299                                                         wxString ServerETag;
1300                                                         CardDAVIter->second.GetServerETagValueThread();
1301                                                         ServerETag = CardDAVIter->second.ETagValueResult();
1302                                                 
1303                                                         // Add to the ETag Database.
1304                                                 
1305                                                         ETagDBPtr->AddETag(additer->first, ServerETag, ServerETag);
1306                                                                                         
1307                                                 }
1308                                         }
1309         
1310                                         // Look for vCard files which aren't in the ETagDB.
1311         
1312                                         while(ContinueProcess){
1313                                 
1314                                                 // Check and make sure that the filename ends in .vcf/.vcard
1315                                                 // Skip any file that beings with a dot.
1316                                         
1317                                                 if (AccDirFilename.Left(1) == wxT(".")){
1318                                         
1319                                                         ContinueProcess = AccDir.GetNext(&AccDirFilename);
1320                                                         continue;
1321                                         
1322                                                 }
1323                                         
1324                                                 if (AccDirFilename.Right(4) != wxT(".vcf") && 
1325                                                 AccDirFilename.Right(6) != wxT(".vcard")){
1326                                         
1327                                                         ContinueProcess = AccDir.GetNext(&AccDirFilename);
1328                                                         continue;
1329                                         
1330                                                 }
1331                                 
1332                                                 // Look in the ETagDB for the file.
1333                                         
1334                                                 bool ETagExists = ETagDBPtr->CheckETagExists(AccDirFilename);
1335                                         
1336                                                 if (ETagExists == FALSE){
1337                                         
1338                                                         // Add the vCard to the list to be added.
1339                                                 
1340                                                         vCardAdd.Add(AccDirFilename, 1);
1341                                         
1342                                                 }
1343                                         
1344                                                 ContinueProcess = AccDir.GetNext(&AccDirFilename);
1345                                 
1346                                         }
1347                                 
1348                                         // Process the vCards to add/update to the server.
1349                                 
1350                                         for (int vi = 0; vi < vCardAdd.GetCount(); vi++){
1352                                                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
1353                                                 ETag = ETagDBPtr->GetETag(vCardAdd[vi]);
1354                                                 ETagOriginal = ETagDBPtr->GetETagOriginal(vCardAdd[vi]);
1355                                                 
1356                                                 ContactFilename = vCardAdd[vi];
1357                                                 FullFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
1359                                                 ContactFilename.Trim();
1360                         
1361                                                 if (ETag == ETagOriginal && ETagDBPtr->ETagExists(vCardAdd[vi])){
1362                         
1363                                                         // Compare the ETag with the Server ETag.
1364                                                 
1365                                                         CardDAVIter->second.SetServerFilename(vCardAdd[vi]);
1366                                                         CardDAVIter->second.GetServerETagValueThread();
1367                                                         ETagServer = CardDAVIter->second.ETagValueResult();
1368                                 
1369                                                         if (ETagOriginal != ETagServer){
1370                                 
1371                                                                 // Server ETag is different from original ETag.
1372                                                                 // This is a conflict which the user will now
1373                                                                 // need to resolve.
1374                                         
1375                                                                 frmMain *frmMainPtrGet = static_cast<frmMain*>(frmMainPtr);
1376                                         
1377                                                                 vCard34Conv vCard34Obj;
1378                                                 
1379                                                                 wxString ServerContactData;
1380                                                                 vCard ClientData;
1381                                                                 vCard ConvertedV4Data;
1382                                         
1383                                                                 // Load the client data from the filename given.
1384                                         
1385                                                                 CardDAVIter->second.GetServerContactData();
1386                                                                 ServerContactData = CardDAVIter->second.GetPageData();
1387                                                 
1388                                                                 // Process v3 version into v4 version.
1389                                                 
1390                                                                 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
1391                                         
1392                                                                 vCardConflictObj vCardProcData;
1393                                         
1394                                                                 vCardProcData.vCardLocalData = &ClientData;
1395                                                                 vCardProcData.vCardServerData = &ConvertedV4Data;
1396                                                                 ClientData.LoadFile(FullFilename);
1398                                                                 //ContactConflictEvent event(ContactConflictCmdEnv);
1399                                                                 //event.SetData(ContactFilename, Moo1, Moo2);
1400                                         
1401                                                                 //wxPostEvent(frmMainPtrGet, event);
1402                                         
1403                                                                 // Setup Conflict Resolution Dialog.
1404                                         
1405                                                                 // Fetch Data from Server and convert.
1406                                         
1407                                                                 bool *PauseMode = new bool;
1408                                                                 int ConflictResult;
1409                                                                 QRNotif qrn;
1411                                                                 *PauseMode = TRUE;                                              
1412                                                                 qrn.QResponse = &ConflictResult;
1413                                                                 qrn.PausePtr = PauseMode;
1414                                                 
1415                                                                 vCardProcData.QRNotifData = &qrn;
1416                                         
1417                                                                 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
1418                                                                 event.SetClientData(&vCardProcData);
1419                                                                 wxPostEvent(frmMainPtrGet, event);
1420                                                 
1421                                                                 /*timespec n1, n2;
1422                                                 
1423                                                                 n1.tv_sec = 0;
1424                                                                 n1.tv_nsec = 250000000L;*/
1425                                                 
1426                                                                 while (*PauseMode == TRUE){
1427                                                                         //nanosleep(&n1, &n2);
1428                                                                         SleepFor(250000000);
1429                                                                 }
1430                                         
1431                                                                 delete PauseMode;
1432                                                                 PauseMode = NULL;
1433                                         
1434                                                                 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
1435                                         
1436                                                                 if (ConflictResult == 0){
1437                                         
1438                                                                         // Decide Later.
1439                                         
1440                                                                         iter->second = 4;
1441                                                                         continue;
1442                                         
1443                                                                 } else if (ConflictResult == 1){
1444                                         
1445                                                                         // Decided to use client version.
1446                                         
1447                                                                         CardDAVIter->second.ProcessData();
1448                                                 
1449                                                                         iter->second = 4;
1450                                         
1451                                                                 } else if (ConflictResult == 2){
1452                                         
1453                                                                         // Decided to use server version.
1454                                                 
1455                                                                         // Download server version.
1456                                                                 
1457                                                                         ConvertedV4Data.WriteFile(CreateFilenamePath(AccountDirFinal, vCardAdd[vi]));
1458                                                 
1459                                                                         iter->second = 4;
1460                                         
1461                                                                 }
1462                                 
1463                                                         } else {
1464                                 
1465                                                                 // Setup the filename for the contact being added.
1466                                                         
1467                                                                 wxString wxSFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
1468                                                                 wxString wxSCardData;
1469                                                                 wxString TaskData;
1470                                                                 //wxString TaskURL;
1471                                                         
1472                                                                 // Load the data from the file.
1473                                                         
1474                                                                 wxFFile wxFCard;
1475                                                                 wxFCard.Open(wxSFilename, wxT("r"));
1476                                 
1477                                                                 if (wxFCard.IsOpened()){
1478                                 
1479                                                                         wxFCard.ReadAll(&wxSCardData, wxConvAuto());
1480                                                                         wxFCard.Close();
1481                                 
1482                                                                 }
1483                                                         
1484                                                                 // Convert the data to v3.
1485                                                         
1486                                                                 vCard34Conv vCard34Obj;
1487                                                         
1488                                                                 vCard34Obj.ConvertToV3(wxSFilename, &TaskData);
1489                                                         
1490                                                                 // Setup the URL address.
1491                                                         
1492                                                                 //TaskURL = StringTaskDetailIter->second + wxT("/") + vCardAdd[vi];
1494                                                                 // Upload the data to the server.
1495                                         
1496                                                                 CardDAVIter->second.SetUploadMode(TRUE);
1497                                                                 CardDAVIter->second.SetupData(wxT("PUT"), vCardAdd[vi], TaskData);
1498                                                                 CardDAVIter->second.ProcessData();
1499                                                         
1500                                                                 // Get the Server ETag and put it in the ETag database.
1501                                                         
1502                                                                 CardDAVIter->second.SetServerFilename(vCardAdd[vi]);
1503                                                                 CardDAVIter->second.GetServerETagValueThread();
1504                                                                 ETagServer = CardDAVIter->second.ETagValueResult();
1505                                 
1506                                                                 ETagDBPtr->AddETag(vCardAdd[vi], ETagServer, ETagServer);
1507                                 
1508                                                         }
1509                         
1510                                                 } else {
1511                         
1512                                                         if (ETagOriginal != ETagServer){
1513                                 
1514                                                                 // Server ETag is different from original ETag.
1515                                                                 // This is a conflict which the user will now
1516                                                                 // need to resolve.
1517                                         
1518                                                                 frmMain *frmMainPtrGet = (frmMain *)frmMainPtr;
1519                                         
1520                                                                 //ContactConflictEvent event(ContactConflictCmdEnv);
1521                                                                 //event.SetData(ContactFilename, Moo1, Moo2);
1522                                         
1523                                                                 vCard34Conv vCard34Obj;
1524                                                 
1525                                                                 wxString ServerContactData;
1526                                                                 vCard ClientData;
1527                                                                 vCard ConvertedV4Data;
1528                                         
1529                                                                 // Load the client data from the filename given.
1530                                         
1531                                                                 CardDAVIter->second.GetServerContactData();
1532                                                                 ServerContactData = CardDAVIter->second.GetPageData();
1533                                                                 ClientData.LoadFile(FullFilename);
1534                                                 
1535                                                                 // Process v3 version into v4 version.
1536                                                 
1537                                                                 vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
1538                                         
1539                                                                 vCardConflictObj vCardProcData;
1540                                         
1541                                                                 vCardProcData.vCardLocalData = &ClientData;
1542                                                                 vCardProcData.vCardServerData = &ConvertedV4Data;
1543                                         
1544                                                                 bool *PauseMode = new bool;
1545                                                                 int ConflictResult;
1546                                                                 QRNotif qrn;
1548                                                                 *PauseMode = TRUE;                                              
1549                                                                 qrn.QResponse = &ConflictResult;
1550                                                                 qrn.PausePtr = PauseMode;
1551                                                 
1552                                                                 vCardProcData.QRNotifData = &qrn;
1553                                         
1554                                                                 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
1555                                                                 event.SetClientData(&vCardProcData);
1556                                                                 wxPostEvent(frmMainPtrGet, event);
1557                                         
1558                                                                 /*timespec n1, n2;
1559                                                 
1560                                                                 n1.tv_sec = 0;
1561                                                                 n1.tv_nsec = 250000000L;*/
1562                                         
1563                                                                 while (*PauseMode == TRUE){
1564                                                                         //nanosleep(&n1, &n2);
1565                                                                         SleepFor(250000000);
1566                                                                 }
1567                                         
1568                                                                 delete PauseMode;
1569                                                                 PauseMode = NULL;
1570                                         
1571                                                                 //intResult = frmMainPtrGet->ShowConflictDialog(&Moo1, &Moo2);
1572                                         
1573                                                                 if (ConflictResult == 0){
1574                                         
1575                                                                         // Decide Later.
1576                                         
1577                                                                         iter->second = 4;
1578                                                                         continue;
1579                                         
1580                                                                 } else if (ConflictResult == 1){
1581                                         
1582                                                                         // Decided to use client version.
1583                                                                 
1584                                                                         CardDAVIter->second.ProcessData();
1585                                                                         //ETagServer = CardDAVIter->second.GetServerETagValueThread();
1586                                                                         //ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
1587                                                 
1588                                                                         iter->second = 4;
1589                                         
1590                                                                 } else if (ConflictResult == 2){
1591                                         
1592                                                                         // Decided to use server version.
1593                                                 
1594                                                                         // Write server version to file.
1595                                                                 
1596                                                                         ConvertedV4Data.WriteFile(CreateFilenamePath(AccountDirFinal, vCardAdd[vi]));
1597                                                 
1598                                                                         iter->second = 4;
1599                                         
1600                                                                 }
1601                                 
1602                                                         } else {
1603                                 
1604                                                                 // Setup the filename for the contact being added.
1605                                                         
1606                                                                 wxString wxSFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
1607                                                                 wxString wxSCardData;
1608                                                                 wxString TaskData;
1609                                                                 //wxString TaskURL;
1610                                                         
1611                                                                 // Load the data from the file.
1612                                                         
1613                                                                 wxFFile wxFCard;
1614                                                                 wxFCard.Open(wxSFilename, wxT("r"));
1615                                 
1616                                                                 if (wxFCard.IsOpened()){
1617                                 
1618                                                                         wxFCard.ReadAll(&wxSCardData, wxConvAuto());
1619                                                                         wxFCard.Close();
1620                                 
1621                                                                 }
1622                                                         
1623                                                                 // Convert the data to v3.
1624                                                         
1625                                                                 vCard34Conv vCard34Obj;
1626                                                         
1627                                                                 vCard34Obj.ConvertToV3(wxSFilename, &TaskData);
1628                                                         
1629                                                                 // Setup the URL address.
1630                                                         
1631                                                                 //TaskURL = StringTaskDetailIter->second + wxT("/") + vCardAdd[vi];
1633                                                                 // Upload the data to the server.
1634                                         
1635                                                                 CardDAVIter->second.SetUploadMode(TRUE);
1636                                                                 CardDAVIter->second.SetupData(wxT("PUT"), vCardAdd[vi], TaskData);
1637                                                                 CardDAVIter->second.ProcessData();
1638                                                         
1639                                                                 // Get the Server ETag and put it in the ETag database.
1640                                                         
1641                                                                 CardDAVIter->second.SetServerFilename(vCardAdd[vi]);
1642                                                                 CardDAVIter->second.GetServerETagValueThread();
1643                                                                 ETagServer = CardDAVIter->second.ETagValueResult();
1644                                 
1645                                 
1646                                                                 ETagDBPtr->AddETag(vCardAdd[vi], ETagServer, ETagServer);
1647                                 
1648                                                         }
1649                                         
1650                                                 }
1652                                         }                       
1653                                 
1654                                         // Process the vCards to delete locally.
1655                                 
1656                                         for (int vi = 0; vi < vCardDelete.GetCount(); vi++){
1658                                                 if (!wxRemoveFile(CreateFilenamePath(AccountDirFinal, vCardDelete[vi]))){
1660                                                 } else {
1661                                         
1662                                                         ETagDBPtr->RemoveETag(vCardDelete[vi]);
1663                                         
1664                                                 }
1666                                         }
1667                                 
1668                                         // Process the vCards to delete from the server.
1669                                 
1670                                         std::map<wxString,wxString> *ETagFilenameMap = ETagDBPtr->GetFilenamePointer();
1671                                 
1672                                 
1673                                         for (std::map<wxString,wxString>::iterator deliter = ETagFilenameMap->begin();
1674                                                 deliter != ETagFilenameMap->end(); deliter++){
1675                                 
1676                                                 // Look through the ETagDB and find contacts which are marked as DELETED.
1677                                         
1678                                                 if (deliter->second == wxT("DELETED")){
1680                                                         CardDAVIter->second.SetUploadMode(FALSE);
1681                                                         CardDAVIter->second.SetupData(wxT("DELETE"), deliter->first, wxT(""));
1682                                                         CardDAVIter->second.ProcessData();
1683                                         
1684                                                         // Delete the ETag as the file has now been deleted.
1685                                         
1686                                                         ETagDBPtr->RemoveETag(deliter->first);
1687                                         
1688                                                 }
1689                                 
1690                                         }
1691                                 
1692                                         // Write out the update server sync token.
1694                                         wxString ServerSyncToken = ServerContactList.SyncToken;
1695                                 
1696                                         ServerSyncToken.Trim();
1697                                 
1698                                         if (!ServerSyncToken.IsEmpty()){
1699                                 
1700                                                 wxFFile SyncWrite;
1701                                                 SyncWrite.Open(AccountSyncTokenFilename, wxT("w"));
1702                                 
1703                                                 if (SyncWrite.IsOpened()){
1704                                 
1705                                                         SyncWrite.Write(ServerSyncToken, wxConvAuto());
1706                                                         SyncWrite.Close();
1707                                 
1708                                                 }
1709                                 
1710                                         }
1711                                 
1712                                         // Check for another sync token. If there is another 
1713                                         // sync token then repeat this. If token matches then stop processing.
1714                                 
1715                                         if (SyncTokenLoad == ServerSyncToken){
1716                                         
1717                                                 KeepUpdating = FALSE;
1718                                         
1719                                         }
1720                                         
1721                                 }
1722                                 
1723                                 // Mark as completed.
1724                         
1725                                 wxString AccountNameFinal;
1726                                 AccountNameFinal = PrefData.accounts.GetAccountDirectory(AccountID);
1727                                 AccountNameFinal.Append(wxT(".carddav"));
1728                                 
1729                                 wxCommandEvent reloadevent(RELOADCONTACTLIST);
1730                                 reloadevent.SetString(AccountNameFinal);
1731                                 wxPostEvent(this->GetParent(), reloadevent);
1732                                 
1733                                 iter->second = 4;
1734                                 continue;
1735                         
1736                         } else {
1737                         
1738                                 // Update the data to the server.
1739                                         
1740                                 CardDAVIter->second.ProcessData();
1741                                 iter->second = 4;
1742                                 continue;
1743                         
1744                         }
1746                         /*timespec n1, n2;
1747                                                 
1748                         n1.tv_sec = 0;
1749                         n1.tv_nsec = 250000000L;*/
1751                         while (iter->second == 1){
1753                                 SleepFor(250000000);
1754                                 //nanosleep(&n1, &n2);
1755         
1756                         }
1757                         
1758                         if ((iter->second == 4 && TypeIter->second == 0) || 
1759                         (iter->second == 8 && TypeIter->second == 0)){
1761                                 AccountDir = StringAccountIter->second;
1762                                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
1763                                 
1764                                 CardDAVIter->second.GetServerETagValueThread();
1765                                 ETagServer = CardDAVIter->second.ETagValueResult();
1766                                 ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
1767                         
1768                         }
1769                         
1770                         if ((iter->second == 4 && TypeIter->second == 1) || 
1771                         (iter->second == 8 && TypeIter->second == 1)){
1772                         
1773                                 AccountDir = StringAccountIter->second;
1774                                 ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);                 
1776                                 CardDAVIter->second.GetServerETagValueThread();
1777                                 ETagServer = CardDAVIter->second.ETagValueResult();
1778                                 ETagDBPtr->UpdateETag(ContactFilename, ETagServer, ETagServer);
1779                         
1780                         }
1781                         
1782                         break;
1783                         
1784                 }
1786         }
1787         
1788         if (TasksFoundProc == FALSE){
1789         
1790                 TasksActive = FALSE;
1791                 ProcessTasksData = FALSE;
1792         
1793         } else {
1795                 wxCommandEvent eventp(ACTMGR_STARTTIMER);
1796                 wxPostEvent(this, eventp);
1798                 //AnimationTimer.StartAnimation();
1799                 //ActListProcTimer.Start();
1800         
1801         }
1803         wxCommandEvent event(ACTMGR_STARTPROCESSTIMER);
1804         wxPostEvent(this, event);
1806         //ActProcessTimer.Start();
1810 void frmActivityMgr::ProcessTasks()
1813         std::thread ProcessThread(&frmActivityMgr::ProcessTasksThread, this);
1814         ProcessThread.detach();
1818 void frmActivityMgr::SetupPointers(wxETagProcessTimer *ETagTmrPtrInc, void *frmMainPtrInc)
1821         ETagTmrPtr = ETagTmrPtrInc;
1822         
1823         frmMainPtr = frmMainPtrInc;
1827 void frmActivityMgr::ResumeProcessing(wxCommandEvent &event){
1829         QRNotif *qrn = (QRNotif *)event.GetClientData(); 
1830         
1831         int *QRes = qrn->QResponse;
1833         *qrn->PausePtr = FALSE;
1835         *QRes = event.GetInt();
1836         
1839 int frmActivityMgr::GetTaskStatus(int intTaskID){
1841         int intResult = 2;
1842         
1843         if (ActivityList.find(intTaskID) == ActivityList.end()){
1844         
1845                 return intResult;
1846         
1847         }
1848         
1849         std::map<int,int>::iterator taskiter = ActivityList.find(intTaskID);
1850         intResult = taskiter->second;
1851         
1852         return intResult;
1856 void frmActivityMgr::ToggleConnectionStatus( wxCommandEvent &event ){
1858         wxCommandEvent connevent(CONNSTAT_UPDATE);
1859         
1860         if (SleepMode == FALSE){
1861         
1862                 connevent.SetInt(1);
1863                 SleepMode = TRUE;
1864         
1865         } else {
1866         
1867                 connevent.SetInt(0);
1868                 SleepMode = FALSE;
1869         
1870         }
1872         wxPostEvent(GetParent(), connevent);
1876 void frmActivityMgr::WriteServerCertificate(wxString AccountName, SSLCertCollection SSLCertInc){
1878         wxString ServerCertFinal;
1880         // Get the Cert section of the certificate and write it to the file.
1882         ServerCertFinal = GetAccountDir(AccountName, TRUE);
1884         wxFile CertFile;
1885         
1886         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertInc.SSLCollection.find(0);
1887         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
1888         
1889         CertFile.Open(ServerCertFinal, wxFile::write);  
1890         
1891         CertFile.Write(SSLDataIter->second, wxConvUTF8);
1892         CertFile.Close();
1896 void frmActivityMgr::StartTimer(wxCommandEvent& event){
1898         ActListProcTimer.Start(1000, FALSE);
1902 void frmActivityMgr::StopTimer(wxCommandEvent& event){
1904         ActListProcTimer.Stop();
1908 void frmActivityMgr::StartProcessTimer(wxCommandEvent& event){
1910         ActProcessTimer.Start(1000, FALSE);
1914 void frmActivityMgr::StopProcessTimer(wxCommandEvent& event){
1916         ActProcessTimer.Stop();
1920 void frmActivityMgr::UpdateStatusLabel(wxCommandEvent& event){
1922         ActivityMgrLabelUpdate *actmgrudata = (ActivityMgrLabelUpdate*)event.GetClientData();
1923         
1924         if (actmgrudata != NULL){
1925         
1926                 lstActivity->SetItem(actmgrudata->ItemIndex, 2, actmgrudata->ItemLabel);
1927         
1928                 /*if (!actmgrudata->ItemDes.IsEmpty()){
1929                 lstActivity->SetItem(actmgrudata->ItemIndex, 0, actmgrudata->ItemDes);
1930                 }*/
1931         
1932                 delete actmgrudata;
1933                 actmgrudata = NULL;
1934         
1935         }
1939 #endif
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy