Changeset 2930

Show
Ignore:
Timestamp:
12/10/07 15:47:41 (1 year ago)
Author:
cstender
Message:

added support for converting recurrence rules in xmlformat-event to vCalendar

Patch by prahal. Thanks a lot!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • format-plugins/vformat/src/xmlformat-recurrence.c

    r2912 r2930  
    2525/* 
    2626 * Basic Recurrence Rules (vCalendar) 
     27 * 
     28 * The functions below are necessary for converting a vCalendar Recurrence Rule  
     29 * to a xmlformat-event. 
    2730 * 
    2831 * Description: 
     
    145148} 
    146149 
    147 OSyncXMLField *convert_vcal_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, char *rulename, OSyncError **error) 
     150OSyncXMLField *convert_vcal_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, const char *rulename, OSyncError **error) 
    148151{ 
    149152        OSyncXMLField *xmlfield = osync_xmlfield_new(xmlformat, rulename, error); 
     
    212215} 
    213216 
    214 VFormatAttribute *conv_xml_rrule_to_vcal(VFormat *vformat, OSyncXMLField *xmlfield, const char *name, const char *encoding) 
    215 
     217 
    216218/* 
    217         g_assert(vformat); 
    218         g_assert(xmlfield); 
    219         g_assert(name); 
    220  
    221         osync_trace(TRACE_INTERNAL, "Handling \"%s\" xml attribute", name); 
    222         VFormatAttribute *attr = vformat_attribute_new(NULL, name); 
    223         add_values(attr, xmlfield, encoding); 
    224         vformat_add_attribute(vformat, attr); 
    225         return attr; 
    226 */ 
    227         VFormatAttribute *attr = vformat_attribute_new(NULL, name); 
     219 * Basic Recurrence Rules 
     220 * 
     221 * The functions below are necessary for converting a xmlformat-event  
     222 * to a vCalendar Recurrence Rule. 
     223 * 
     224 * Description: 
     225 * convert_rrule_vcal_frequency      get frequency value 
     226 * convert_rrule_vcal_freqmod        get frequency modifier 
     227 * convert_rrule_vcal_countuntil     get count or until value 
     228 * convert_xml_rrule_to_vcal         get interval and call functions above 
     229 */ 
     230 
     231static char *convert_rrule_vcal_frequency(OSyncXMLField *xmlfield, int frequency_state_id) 
     232
     233        const char *frequency = NULL; 
     234        char *frequency_id = NULL; 
     235 
     236        /* set Frequency */ 
     237        frequency = osync_xmlfield_get_key_value(xmlfield, "Frequency"); 
     238 
     239        /* get frequency: only D(1), W(2), MP(3), MD(4), YD(5) and YM(6) are allowed */ 
     240        if (!strcmp(frequency, "DAILY")) { 
     241                frequency_id = "D"; 
     242        } else if (!strcmp(frequency, "WEEKLY")) { 
     243                frequency_id = "W"; 
     244        } else if (!strcmp(frequency, "MONTHLY") && frequency_state_id == 3) { 
     245                frequency_id = "MP"; 
     246        } else if (!strcmp(frequency, "MONTHLY") && frequency_state_id == 4) { 
     247                frequency_id = "MD"; 
     248        } else if (!strcmp(frequency, "YEARLY") && frequency_state_id == 5) { 
     249                frequency_id = "YD"; 
     250        } else if (!strcmp(frequency, "YEARLY") && frequency_state_id == 6) { 
     251                frequency_id = "YM"; 
     252        } else { 
     253                osync_trace(TRACE_INTERNAL, "invalid or missing frequency"); 
     254                return NULL; 
     255        } 
     256 
     257        return frequency_id; 
     258                 
     259
     260 
     261static char *convert_rrule_vcal_freqmod(OSyncXMLField *xmlfield, gchar **rule, int size, int freqstate) 
     262
     263        int i; 
     264        GString *fm_buffer = g_string_new(""); 
     265 
     266        /* for each modifier do... */ 
     267        for(i=1; i < size-1; i++) { 
     268 
     269                int count; 
     270                char sign; 
     271 
     272                if(fm_buffer->len > 0) 
     273                        g_string_append(fm_buffer, ","); 
     274 
     275                /* check frequency modifier */ 
     276                if (sscanf(rule[i], "%d%c" , &count, &sign) == 2) { 
     277 
     278                        /* we need to convert $COUNT- to -$COUNT -> RFC2445 */ 
     279                        if (sign == '-') 
     280                                count = -count; 
     281 
     282                        g_string_append_printf(fm_buffer, "%d", count); 
     283 
     284                        /* if first freqmod is "(-)2" and second one is "TU" we 
     285                         * have to convert it to 2TU */ 
     286                        if (i < size-2 && !sscanf(rule[i+1], "%d", &count)) { 
     287                                g_string_append_printf(fm_buffer, "%s", rule[i+1]); 
     288                                i++; 
     289                        } 
     290 
     291                } else { 
     292                        /* e.g. Day or 'LD' (Last day) */ 
     293                        g_string_append(fm_buffer, rule[i]); 
     294                } 
     295        } 
     296 
     297        return g_string_free(fm_buffer, FALSE); 
     298
     299 
     300static char *convert_rrule_vcal_until(const char *until_utc) 
     301
     302        int offset = 0;  
     303        char *until = NULL; 
     304 
     305 
     306        /* UNTIL: 20070515T120000 */ 
     307        /* It is UTC : change the offset from 0 to the system UTC offset.· 
     308         * vcal doesn't store any TZ information. This means the device have to be 
     309         * in the same Timezone as the host. 
     310         */ 
     311 
     312        struct tm *ttm = osync_time_vtime2tm(until_utc); 
     313        offset = osync_time_timezone_diff(ttm); 
     314        g_free(ttm); 
     315        until = osync_time_vtime2localtime(until_utc, offset); 
     316 
     317        return until; 
     318 
     319
     320 
     321VFormatAttribute *convert_xml_rrule_to_vcal(VFormat *vformat, OSyncXMLField *xmlfield, const char *rulename, const char *encoding) 
     322
     323        VFormatAttribute *attr = vformat_attribute_new(NULL, rulename); 
     324 
     325        int frequency_state_id = 0, counter = 0; 
     326        char *rule = NULL; 
     327 
     328        // Grad the latest key of the field and check if it is a frequency state 
     329        const char *frequency_state = osync_xmlfield_get_nth_key_name(xmlfield, osync_xmlfield_get_key_count(xmlfield)-1); 
     330 
     331         
     332        if (frequency_state) { 
     333                if ( !strcmp(frequency_state, "ByDay")) 
     334                        frequency_state_id = 3; 
     335                else if (!strcmp(frequency_state, "ByMonthDay")) 
     336                        frequency_state_id = 4; 
     337                else if (!strcmp(frequency_state, "ByYearDay")) 
     338                        frequency_state_id = 5; 
     339                else if (!strcmp(frequency_state, "ByMonth")) 
     340                        frequency_state_id = 6; 
     341        } 
     342 
     343        /* get Interval */ 
     344        const char *interval = osync_xmlfield_get_key_value(xmlfield, "Interval"); 
     345 
     346        /* set frequency */ 
     347        const char *frequency = convert_rrule_vcal_frequency(xmlfield, frequency_state_id); 
     348 
     349        if (frequency && interval ) 
     350                rule = g_strdup_printf("%s%s", frequency, interval); 
     351 
     352        // FIXME : handle advanced frequency_mod with a convert_rrule_vcal_freqmod 
     353        // We have a frequency state 
     354        if (frequency_state_id) { 
     355                const char *freq_mod = osync_xmlfield_get_key_value(xmlfield, frequency_state); 
     356                rule = g_strdup_printf("%s %s", rule, freq_mod); 
     357        } 
     358 
     359        const char *until_utc = osync_xmlfield_get_key_value(xmlfield, "Until"); 
     360        if (until_utc) { 
     361                char *until = convert_rrule_vcal_until(until_utc); 
     362                rule = g_strdup_printf("%s %s", rule, until); 
     363        } 
     364 
     365        const char *count = osync_xmlfield_get_key_value(xmlfield, "Count"); 
     366        if (count) { 
     367                rule = g_strdup_printf("%s #%s", rule, count); 
     368        } 
     369 
     370        vformat_attribute_add_value(attr, rule); 
     371 
    228372        vformat_add_attribute(vformat, attr); 
    229373        return attr;     
    230 
     374 
     375}  
     376// End of Basic Recurrence Rule 
     377 
    231378 
    232379 
    233380/* 
    234381 * Basic & Extended Recurrence Rules (iCalendar) 
     382 * 
     383 * The functions below are necessary for converting an iCalendar Recurrence Rule  
     384 * to a xmlformat-event. 
    235385 * 
    236386 * Description: 
     
    238388 */ 
    239389 
    240 OSyncXMLField *convert_ical_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, char *rulename, OSyncError **error)  
     390OSyncXMLField *convert_ical_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, const char *rulename, OSyncError **error)  
    241391{ 
    242392        OSyncXMLField *xmlfield = osync_xmlfield_new(xmlformat, rulename, error); 
     
    338488} 
    339489 
    340 VFormatAttribute *conv_xml_rrule_to_ical(VFormat *vformat, OSyncXMLField *xmlfield, const char *name, const char *encoding) 
     490VFormatAttribute *convert_xml_rrule_to_ical(VFormat *vformat, OSyncXMLField *xmlfield, const char *rulename, const char *encoding) 
    341491{ 
    342492/* 
     
    351501        return attr; 
    352502*/ 
    353         VFormatAttribute *attr = vformat_attribute_new(NULL, name); 
     503        VFormatAttribute *attr = vformat_attribute_new(NULL, rulename); 
    354504        vformat_add_attribute(vformat, attr); 
    355505        return attr; 
  • format-plugins/vformat/src/xmlformat-recurrence.h

    r2912 r2930  
    2424#define XMLFORMAT_RECURRENCE_H_ 
    2525 
    26 OSyncXMLField *convert_vcal_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, char *rulename, OSyncError **error); 
    27 VFormatAttribute *conv_xml_rrule_to_vcal(VFormat *vformat, OSyncXMLField *xmlfield, const char *name, const char *encoding); 
    28 OSyncXMLField *convert_ical_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, char *rulename, OSyncError **error); 
    29 VFormatAttribute *conv_xml_rrule_to_ical(VFormat *vformat, OSyncXMLField *xmlfield, const char *name, const char *encoding); 
     26OSyncXMLField *convert_vcal_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, const char *rulename, OSyncError **error); 
     27VFormatAttribute *convert_xml_rrule_to_vcal(VFormat *vformat, OSyncXMLField *xmlfield, const char *rulename, const char *encoding); 
     28OSyncXMLField *convert_ical_rrule_to_xml(OSyncXMLFormat *xmlformat, VFormatAttribute *attr, const char *rulename, OSyncError **error); 
     29VFormatAttribute *convert_xml_rrule_to_ical(VFormat *vformat, OSyncXMLField *xmlfield, const char *rulename, const char *encoding); 
    3030 
    3131#endif // XMLFORMAT_RECURRENCE_H_ 
  • format-plugins/vformat/src/xmlformat-vcalendar.c

    r2912 r2930  
    10221022{ 
    10231023        osync_trace(TRACE_INTERNAL, "Handling \"RRULE\" xml attribute"); 
    1024         return conv_xml_rrule_to_ical(vevent, xmlfield, "RRULE", encoding);  
     1024        return convert_xml_rrule_to_ical(vevent, xmlfield, "RRULE", encoding);  
    10251025} 
    10261026 
     
    10291029{ 
    10301030        osync_trace(TRACE_INTERNAL, "Handling \"RRULE\" xml attribute"); 
    1031         return conv_xml_rrule_to_vcal(vevent, xmlfield, "RRULE", encoding);  
     1031        return convert_xml_rrule_to_vcal(vevent, xmlfield, "RRULE", encoding);  
    10321032} 
    10331033