Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Added code and unit tests for deleting entries in the CalDAV object
[xestiacalendar/.git] / source / objects / CalDAV / CalDAV-XMLProcessing.cpp
1 // CalDAV-XMLProcessing.cpp - CalDAV Connection Object - XML Processing.
2 //
3 // (c) 2016 Xestia Software Development.
4 //
5 // This file is part of Xestia Calendar.
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 Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "CalDAV.h"
21 using namespace std;
22  
23 string CalDAV::ProcessXMLUserPrincipal(){
25         string UserPrincipalURI;
26         
27         xmlDocPtr xmlCalDAVDoc;
28         xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
30         xmlNodePtr NodeSeek;
31         bool NodeFound = false;
32         
33         // Start with the first node, look for multistatus.
34         
35         for (NodeSeek = xmlCalDAVDoc->children;
36                 NodeSeek != NULL;
37                 NodeSeek = NodeSeek->next)
38         {
39         
40                 if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
41                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
42                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
43                 ){
44                         
45                         NodeFound = true;
46                         break;
47                         
48                 }
49                 
50         }
51         
52         // Look for response.
54         if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
55         NodeFound = MatchXMLNameTransverse(&NodeSeek, "response");
57         // Look for propstat.
58         
59         if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
60         NodeFound = MatchXMLNameTransverse(&NodeSeek, "propstat");
62         // Look for prop.
63         
64         if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
65         NodeFound = MatchXMLNameTransverse(&NodeSeek, "prop");
66         
67         // Look for current-user-principal.
68         
69         if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
70         NodeFound = MatchXMLNameTransverse(&NodeSeek, "current-user-principal");
71         
72         // Look for href.       
73         
74         if (NodeFound == false){ return UserPrincipalURI; } else { NodeFound = false; }
75         NodeFound = MatchXMLNameTransverse(&NodeSeek, "href");
77         // Get the data from href.
78         
79         UserPrincipalURI = FetchXMLData(&NodeSeek);
80         
81         xmlFreeDoc(xmlCalDAVDoc);
82         
83         return UserPrincipalURI;
84         
85 }
87 string CalDAV::ProcessXMLCalendarHome(){
89         string CalendarHomeURI;
90         
91         xmlDocPtr xmlCalDAVDoc;
92         xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
94         xmlNodePtr NodeSeek;
95         bool NodeFound = false;
96         
97         // Start with the first node, look for multistatus.
98         
99         for (NodeSeek = xmlCalDAVDoc->children;
100                 NodeSeek != NULL;
101                 NodeSeek = NodeSeek->next)
102         {
103         
104                 if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
105                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
106                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
107                 ){
108                         
109                         NodeFound = true;
110                         break;
111                         
112                 }
113                 
114         }
115         
116         // Look for response.
118         if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
119         NodeFound = MatchXMLNameTransverse(&NodeSeek, "response");
121         // Look for propstat.
122         
123         if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
124         NodeFound = MatchXMLNameTransverse(&NodeSeek, "propstat");
126         // Look for prop.
127         
128         if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
129         NodeFound = MatchXMLNameTransverse(&NodeSeek, "prop");
130         
131         // Look for calendar-home-set.
132         
133         if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
134         NodeFound = MatchXMLNameTransverse(&NodeSeek, "calendar-home-set");
135         
136         // Look for href.       
137         
138         if (NodeFound == false){ return CalendarHomeURI; } else { NodeFound = false; }
139         NodeFound = MatchXMLNameTransverse(&NodeSeek, "href");
141         // Get the data from href.
142         
143         CalendarHomeURI = FetchXMLData(&NodeSeek);
144         
145         xmlFreeDoc(xmlCalDAVDoc);
146         
147         return CalendarHomeURI;
148         
151 CalDAVCalendarList CalDAV::ProcessXMLCalendarList(){
152         
153         CalDAVCalendarList CalendarList;
154         
155         xmlDocPtr xmlCalDAVDoc;
156         xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
158         xmlNodePtr NodeSeek = NULL;
159         xmlNodePtr NodeResponse = NULL;
160         xmlNodePtr NodeMatch = NULL;
161         xmlNodePtr NodeData = NULL;
162         bool NodeFound = false;
163         int ResponseCount = 0;
164         
165         // Start with the first node, look for multistatus.
166         
167         for (NodeSeek = xmlCalDAVDoc->children;
168                 NodeSeek != NULL;
169                 NodeSeek = NodeSeek->next)
170         {
171         
172                 if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
173                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
174                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
175                 ){
176                 
177                         NodeResponse = NodeSeek->children;      
178                         NodeFound = true;
179                         break;
180                         
181                 }
182                 
183         }
184         
185         for (NodeResponse = NodeSeek->children;
186                 NodeResponse != nullptr;
187                 NodeResponse = NodeResponse->next)
188         {
189         
190                 // Go through each of the responses and find the calendars.
192                 NodeMatch = xmlCopyNode(NodeResponse, 1);
193                 
194                 if (MatchXMLName(&NodeMatch, "response")){
195 \r                       NodeData = xmlCopyNode(NodeMatch, 1);
196                         
197                         // Check the resource type is a calendar.
198                         
199                         if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
200                         if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
201                         if (!MatchXMLNameTransverse(&NodeData, "resourcetype")){ continue; }                    
202                         if (!MatchXMLNameTransverse(&NodeData, "calendar")){ continue; }
203                         
204                         // Get the HREF.
205                         
206                         NodeData = xmlCopyNode(NodeMatch, 1);
207                         
208                         if (!MatchXMLNameTransverse(&NodeData, "href")){ continue; }
209                                                 
210                         string HREFAddress = FetchXMLData(&NodeData);
211                         
212                         // Get the calendar name.
214                         NodeData = xmlCopyNode(NodeMatch, 1);
215                         
216                         if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
217                         if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
218                         if (!MatchXMLNameTransverse(&NodeData, "displayname")){ continue; }
219                         
220                         string CalendarName = FetchXMLData(&NodeData);
221                         
222                         // Get the calendar description.
223                         
224                         NodeData = xmlCopyNode(NodeMatch, 1);
225                         
226                         string CalendarDescription = "";
227                         
228                         if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
229                         if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
230                         if (MatchXMLNameTransverse(&NodeData, "calendar-description")){ 
231                         
232                                 CalendarDescription = FetchXMLData(&NodeData);
233                                 
234                         }
235                         
236                         // Get the calendar colour.
237                         
238                         NodeData = xmlCopyNode(NodeMatch, 1);
240                         Colour CalendarColour;
241                         bool ColourResult = false;
242                         
243                         if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
244                         if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
245                         if (MatchXMLNameTransverse(&NodeData, "calendar-color")){ 
246                         
247                                 string CalendarColourString = "";
248                                 string CalendarColourHexValue = "";
249                                 int ColourNumber;
250                                 bool KeepRunning = true;
251                                 
252                                 CalendarColourString = FetchXMLData(&NodeData);
253                                 
254                                 while(KeepRunning == true){
255                                 
256                                         if (CalendarColourString.substr(0,1) == "#" && CalendarColourString.length() == 9){
257                                                 
258                                                 // Get the red colour.
259                                                 
260                                                 CalendarColourHexValue = CalendarColourString.substr(1,2);
261                                                 if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; }
262                                                 CalendarColour.red = ColourNumber;
263                                                 
264                                                 // Get the green colour.
266                                                 CalendarColourHexValue = CalendarColourString.substr(3,2);
267                                                 if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; }
268                                                 CalendarColour.green = ColourNumber;
269                                                 
270                                                 // Get the blue colour.
271                                                 
272                                                 CalendarColourHexValue = CalendarColourString.substr(5,2);
273                                                 if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; };
274                                                 CalendarColour.blue = ColourNumber;
275                                                 
276                                                 // Get the alpha.
278                                                 CalendarColourHexValue = CalendarColourString.substr(7,2);
279                                                 if (!HexToInt(&CalendarColourHexValue, &ColourNumber)){ break; };
280                                                 CalendarColour.alpha = ColourNumber;
281                                                 
282                                                 ColourResult = true;
283                                                 
284                                         } else {
286                                                 ColourResult = false;
287                                         
288                                         }
289                                         
290                                         break;
291                                         
292                                 }
293                                 
294                         }
295                         
296                         if (ColourResult == false){
297                                         
298                                         CalendarColour.red = 0;
299                                         CalendarColour.blue = 0;
300                                         CalendarColour.green = 0;
301                                         CalendarColour.alpha = 0;
302                                         
303                         }
304                         
305                         // Get the calendar order.
307                         NodeData = xmlCopyNode(NodeMatch, 1);
308                         
309                         int CalendarOrder = 0;
310                         
311                         if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
312                         if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
313                         if (MatchXMLNameTransverse(&NodeData, "calendar-order")){
314                                 
315                                 string CalendarOrderString = FetchXMLData(&NodeData);
316                                 if (!HexToInt(&CalendarOrderString, &CalendarOrder)){
317                                         CalendarOrder = 0;
318                                 }
319                                 
320                         }
321                         
322                         // Get the calendar tag.
323                         
324                         NodeData = xmlCopyNode(NodeMatch, 1);
325                         
326                         string CalendarTag = "";
327                         
328                         if (!MatchXMLNameTransverse(&NodeData, "propstat")){ continue; }
329                         if (!MatchXMLNameTransverse(&NodeData, "prop")){ continue; }
330                         if (MatchXMLNameTransverse(&NodeData, "getctag")){ 
331                                 
332                                 CalendarTag = FetchXMLData(&NodeData);
333                                 
334                         }
335                         
336                         // Insert the calendar information into the
337                         // list if all the information is there.
338                         
339                         CalendarList.Name.insert(make_pair(ResponseCount, CalendarName));
340                         CalendarList.Description.insert(make_pair(ResponseCount, CalendarDescription));
341                         CalendarList.HREF.insert(make_pair(ResponseCount, HREFAddress));
342                         CalendarList.CalColour.insert(make_pair(ResponseCount, CalendarColour));
343                         CalendarList.Order.insert(make_pair(ResponseCount, CalendarOrder));
344                         CalendarList.Tag.insert(make_pair(ResponseCount, CalendarTag));
345                         
346                         ResponseCount++;
347                         
348                 }
349                 
350         }
351         
352         xmlFreeDoc(xmlCalDAVDoc);
353         
354         return CalendarList;
355         
358 string CalDAV::ProcessXMLEntryETag(){
359         
360         string EntryETag;
361         
362         xmlDocPtr xmlCalDAVDoc;
363         xmlCalDAVDoc = xmlReadMemory(ServerData.c_str(), (int)ServerData.size(), "noname.xml", NULL, 0);
365         xmlNodePtr NodeSeek;
366         bool NodeFound = false;
367         
368         // Start with the first node, look for multistatus.
369         
370         for (NodeSeek = xmlCalDAVDoc->children;
371                 NodeSeek != NULL;
372                 NodeSeek = NodeSeek->next)
373         {
374         
375                 if (!xmlStrcmp(NodeSeek->name, (const xmlChar *)"multistatus") ||
376                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"d:multistatus") ||
377                         !xmlStrcmp(NodeSeek->name, (const xmlChar *)"D:multistatus")
378                 ){
379                         
380                         NodeFound = true;
381                         break;
382                         
383                 }
384                 
385         }
386         
387         // Look for response.
388         
389         if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
390         NodeFound = MatchXMLNameTransverse(&NodeSeek, "response");
392         // Look for propstat.
393         
394         if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
395         NodeFound = MatchXMLNameTransverse(&NodeSeek, "propstat");
397         // Look for prop.
398         
399         if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
400         NodeFound = MatchXMLNameTransverse(&NodeSeek, "prop");
401         
402         // Look for calendar-home-set.
403         
404         if (NodeFound == false){ return EntryETag; } else { NodeFound = false; }
405         NodeFound = MatchXMLNameTransverse(&NodeSeek, "getetag");
407         // Get the data from href.
408         
409         EntryETag = FetchXMLData(&NodeSeek);    
410         
411         xmlFreeDoc(xmlCalDAVDoc);       
412         
413         // Check if the entity tag contains quote marks
414         // at the start and end and remove them (if needed).
415         
416         if (EntryETag.substr(0,1) == "\"" && 
417                 EntryETag.substr(EntryETag.size()-1, 1) == "\"" && EntryETag.size() > 2){
418                 
419                 EntryETag.erase(EntryETag.begin());
420                 EntryETag.erase(EntryETag.end()-1);
421                         
422         }
423         
424         return EntryETag;
425         
428 bool CalDAV::MatchXMLNameTransverse(xmlNodePtr *NodePtr, string NodeName){
430         string NodeNameSmallD = "d:" + NodeName;
431         string NodeNameLargeD = "D:" + NodeName;
432         
433         for ((*NodePtr) = (*NodePtr)->children;
434                 (*NodePtr) != NULL;
435                 (*NodePtr) = (*NodePtr)->next)
436         {
437         
438                 if (!xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeName.c_str()) ||
439                         !xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeNameSmallD.c_str()) ||
440                         !xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeNameLargeD.c_str())
441                 ){
442                         
443                         return true;
444                         
445                 }
446                 
447         }
448         
449         return false;
450         
453 bool CalDAV::MatchXMLName(xmlNodePtr *NodePtrOriginal, string NodeName){
455         if (NodePtrOriginal == nullptr){
456                 
457                 return false;
458                 
459         }
460         
461         string NodeNameSmallD = "d:" + NodeName;
462         string NodeNameLargeD = "D:" + NodeName;
463         
464         xmlNodePtr *NodePtr = NodePtrOriginal;
465         
466         if (!xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeName.c_str()) ||
467                 !xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeNameSmallD.c_str()) ||
468                 !xmlStrcmp((*NodePtr)->name, (const xmlChar *)NodeNameLargeD.c_str())
469         ){
470                         
471                 return true;
472                         
473         } else {
474                         
475                 return false;
476                 
477         }
478         
479         return false;
480         
483 string CalDAV::FetchXMLData(xmlNodePtr *NodePtr){
485         for ((*NodePtr) = (*NodePtr)->children;
486                 (*NodePtr) != NULL;
487                 (*NodePtr) = (*NodePtr)->next)
488         {
489                                                                 
490                 return (const char*)(*NodePtr)->content;
491                         
492         }
493         
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