Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Updated/Added copyright header and licensing to all source files
[xestiacalendar/.git] / source / objects / CalDAV / CalDAV.cpp
index a94640f..7f268b0 100644 (file)
@@ -1,14 +1,14 @@
 // CalDAV.cpp - CalDAV Connection Object.
 //
-// (c) 2016 Xestia Software Development.
+// (c) 2016-2017 Xestia Software Development.
 //
 // This file is part of Xestia Calendar.
 //
-// Xestia Address Book is free software: you can redistribute it and/or modify
+// Xestia Calendar is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by the
 // Free Software Foundation, version 3 of the license.
 //
-// Xestia Address Book is distributed in the hope that it will be useful,
+// Xestia Calendar is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 // GNU General Public License for more details.
@@ -23,10 +23,7 @@ using namespace std;
 size_t CalDAVReceive(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, string *StringPointer)
 {
        
-       string ReceivedBufferString = "";
-       ReceivedBufferString.append(ReceivedBuffer, NewMemoryBytes);
-       
-       StringPointer->append(ReceivedBufferString);
+       StringPointer->append(ReceivedBuffer, NewMemoryBytes);
        
        return Size * NewMemoryBytes;
        
@@ -476,6 +473,7 @@ CalDAVCalendarList CalDAV::GetCalendars(){
        " <d:prop>\n"
         "  <d:resourcetype />\n"
        "  <d:displayname />\n"
+       "  <d:sync-token />\n"
        "  <x0:calendar-color />\n"
        "  <x0:calendar-order />\n"
        "  <cs:getctag />\n"
@@ -544,8 +542,300 @@ CalDAVCalendarList CalDAV::GetCalendars(){
        
 }
 
+CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF){
+       
+       CalDAVEntryList EntryList;
+       CalDAVSendData EntryListSendData;
+       
+       if (CalendarHREF->size() == 0){
+               
+               return EntryList;
+               
+       }
+       
+       string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
+       
+       string EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+       
+       /*if (CalendarTag == nullptr){*/
+               
+       EntryListRequest += "<c:calendar-query xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+       " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+       " <d:prop>\n"
+       "  <d:getetag />\n"
+       "  <c:calendar-data />\n"
+       " </d:prop>\n"
+       " <c:filter>\n"
+       "  <c:comp-filter name=\"VCALENDAR\" />\n"
+       " </c:filter>\n"
+       "</c:calendar-query>";
+               
+       /*} else {
+
+               EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+               " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"          
+               " <d:sync-token>";
+               EntryListRequest += *CalendarTag;
+               EntryListRequest += "</d:sync-token>\n"
+               " <d:sync-level>1</d:sync-level>\n"
+               " <d:prop>\n"
+               "  <d:getetag />\n"
+               "  <c:calendar-data />\n"
+               " </d:prop>\n"
+               "</d:sync-collection>";
+               
+       }*/
+       
+       EntryListSendData.readptr = &EntryListRequest;
+       EntryListSendData.sizeleft = EntryListRequest.size();
+       
+       struct curl_slist *EntryListRequestHeader = NULL;
+       
+       EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       /*if (CalendarTag != nullptr){
+       
+               EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+               EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+               
+       }*/
+       
+       curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
+       curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryListSendData);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       ServerData.clear();
+       ServerHeader.clear();
+       
+       CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+       
+       //ServerList = ProcessXMLCalendarList();
+       
+       if (ServerResult == CURLE_OK){
+               ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+       } else {
+               ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       ConnectionServerResult.Code = ServerResult;
+       curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+       
+       if (ServerResult != CURLE_OK){
+               
+               return EntryList;
+               
+       }
+       
+       // Process the received XML data into a list of calendars
+       // and locations.
+       
+       EntryList = ProcessXMLEntryList();
+       
+       // Restore the original settings.
+       
+       string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+       
+       curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+       curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+       
+       return EntryList;
+       
+}
+
+CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF, string *CalendarTag){
+       
+       CalDAVEntryList EntryList;
+       CalDAVSendData EntryListSendData;
+       
+       if (CalendarHREF->size() == 0){
+               
+               return EntryList;
+               
+       }
+       
+       string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
+       
+       // First query: Get the list of contacts that need to be updated.
+       
+       string EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+       EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+       " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+       " <d:sync-token>";
+       
+       if (CalendarTag != nullptr){
+       
+               EntryListRequest += *CalendarTag;
+               
+       } else {
+       
+               EntryListRequest += "";
+               
+       }
+
+       EntryListRequest += "</d:sync-token>\n"
+       " <d:sync-level>1</d:sync-level>\n"
+       " <d:prop>\n"
+       "  <d:getetag />\n"
+       " </d:prop>\n"
+       "</d:sync-collection>";
+       
+       EntryListSendData.readptr = &EntryListRequest;
+       EntryListSendData.sizeleft = EntryListRequest.size();
+       
+       struct curl_slist *EntryListRequestHeader = NULL;
+       
+       EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
+       curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryListSendData);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       ServerData.clear();
+       ServerHeader.clear();
+       
+       CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+       
+       if (ServerResult == CURLE_OK){
+               ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+       } else {
+               ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       ConnectionServerResult.Code = ServerResult;
+       curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+       
+       if (ServerResult != CURLE_OK){
+               
+               return EntryList;
+               
+       }
+       
+       EntryList = ProcessXMLSyncTokenList();
+       
+       // Check the last entry matches the HREF and if it 
+       // does then delete it.
+       
+       if (EntryList.HREF.size() > 0) {
+       
+               if (EntryList.HREF.rbegin()->second == *CalendarHREF){
+                       
+                       EntryList.HREF.erase((EntryList.HREF.size() - 1));
+                       EntryList.Tag.erase((EntryList.HREF.size() - 1));
+                       EntryList.Data.erase((EntryList.HREF.size() - 1));
+               
+               }
+       
+       }
+       
+       // Build the list into a new list for getting the new 
+       // calendar data with.
+       
+       EntryListRequest.clear();
+       
+       EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+       EntryListRequest += "<c:calendar-multiget xmlns:d=\"DAV:\" "
+       " xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+       " <d:prop>\n"
+       "  <d:getetag />\n"
+       "  <c:calendar-data />\n"
+       " </d:prop>\n";
+       
+       for (std::map<int,string>::iterator HREFIter = EntryList.HREF.begin(); 
+               HREFIter != EntryList.HREF.end(); HREFIter++){
+               
+               string EntryListHREFString = HREFIter->second;
+                       
+               EntryListRequest += " <d:href>";
+               EntryListRequest += EntryListHREFString;
+               EntryListRequest += "</d:href>\n";
+                       
+       }
+       
+       EntryListRequest += "</c:calendar-multiget>";
+       
+       CalDAVSendData UpdatedEntryListSendData;        
+       
+       UpdatedEntryListSendData.readptr = &EntryListRequest;
+       UpdatedEntryListSendData.sizeleft = EntryListRequest.size();
+       
+       curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
+       curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &UpdatedEntryListSendData);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Get the updated calendar data.
+       
+       ServerData.clear();
+       ServerHeader.clear();
+       EntryList.HREF.clear();
+       EntryList.Tag.clear();
+       EntryList.Data.clear();
+       
+       ServerResult = curl_easy_perform(ConnectionHandle);
+
+       // Check the last entry matches the HREF and if it 
+       // does then delete it.
+       
+       if (ServerResult == CURLE_OK){
+               ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+       } else {
+               ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       ConnectionServerResult.Code = ServerResult;
+       curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+       
+       if (ServerResult != CURLE_OK){
+               
+               return EntryList;
+               
+       }
+       
+       EntryList = ProcessXMLEntryList();
+       
+       // Second query: Get the list of contact data for the contacts that have
+       // beenchanged.
+       
+       // Restore the original settings.
+       
+       string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+       
+       curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+       curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+       
+       return EntryList;
+       
+}
+
 CalDAVServerResult CalDAV::AddCalendar(string CalendarName){
        
+       CalDAVServerResult ServerResult;
+       
+       AddCalendar(&CalendarName, nullptr);
+       
+       return ServerResult;
+       
+}
+
+CalDAVServerResult CalDAV::AddCalendar(string *CalendarName, string *CalendarShortName){
+       
        CalDAVServerResult ServerResult;
        CalDAVSendData CalendarAddSendData;
        
@@ -565,9 +855,19 @@ CalDAVServerResult CalDAV::AddCalendar(string CalendarName){
        
        // Generate the UUID.
        
-       string UUIDValue = GenerateUUID();
-       UUIDValue.erase(UUIDValue.end()-1);
+       string UUIDValue = "";
+       
+       if (CalendarShortName == nullptr){
        
+               UUIDValue = GenerateUUID();
+               UUIDValue.erase(UUIDValue.end()-1);
+
+       } else {
+       
+               UUIDValue = *CalendarShortName;
+               
+       }
+               
        string CalendarHomeURL = CalendarHomeURI;
        CalendarHomeURL.append(UUIDValue);
        CalendarHomeURL.append("/");
@@ -581,7 +881,7 @@ CalDAVServerResult CalDAV::AddCalendar(string CalendarName){
        " <d:set>\n"
        "  <d:prop>\n"
        "   <d:displayname>";
-       CalendarAddRequest += CalendarName;
+       CalendarAddRequest += *CalendarName;
        CalendarAddRequest += "</d:displayname>\n"
        "   <c:supported-calendar-component-set>\n"
        "    <c:comp name=\"VTODO\"/>\n"
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